Browse Source

Merge branch 'master' of https://github.com/odin-lang/Odin

gingerBill 4 years ago
parent
commit
9eb12889f4

+ 2 - 1
core/odin/ast/ast.odin

@@ -325,6 +325,7 @@ If_Stmt :: struct {
 	init:      ^Stmt,
 	cond:      ^Expr,
 	body:      ^Stmt,
+	else_pos:  tokenizer.Pos,
 	else_stmt: ^Stmt,
 }
 
@@ -490,7 +491,7 @@ unparen_expr :: proc(expr: ^Expr) -> (val: ^Expr) {
 	}
 	for {
 		e, ok := val.derived.(Paren_Expr);
-		if !ok {
+		if !ok || e.expr == nil {
 			break;
 		}
 		val = e.expr;

+ 8 - 2
core/odin/parser/parser.odin

@@ -121,7 +121,7 @@ parse_file :: proc(p: ^Parser, file: ^ast.File) -> bool {
 	}
 
 	p.file = file;
-	tokenizer.init(&p.tok, file.src, file.fullpath);
+	tokenizer.init(&p.tok, file.src, file.fullpath, p.err);
 	if p.tok.ch <= 0 {
 		return true;
 	}
@@ -625,6 +625,8 @@ parse_if_stmt :: proc(p: ^Parser) -> ^ast.If_Stmt {
 		body = parse_block_stmt(p, false);
 	}
 
+	else_tok := p.curr_tok.pos;
+
 	if allow_token(p, .Else) {
 		#partial switch p.curr_tok.kind {
 		case .If:
@@ -651,6 +653,7 @@ parse_if_stmt :: proc(p: ^Parser) -> ^ast.If_Stmt {
 	if_stmt.cond      = cond;
 	if_stmt.body      = body;
 	if_stmt.else_stmt = else_stmt;
+	if_stmt.else_pos = else_tok;
 	return if_stmt;
 }
 
@@ -785,6 +788,7 @@ parse_case_clause :: proc(p: ^Parser, is_type_switch: bool) -> ^ast.Case_Clause
 	cc.list = list;
 	cc.terminator = terminator;
 	cc.body = stmts;
+	cc.case_pos = tok.pos;
 	return cc;
 }
 
@@ -846,6 +850,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 		ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body.end);
 		ts.tag  = tag;
 		ts.body = body;
+		ts.switch_pos = tok.pos;
 		return ts;
 	} else {
 		cond := convert_stmt_to_expr(p, tag, "switch expression");
@@ -853,6 +858,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 		ts.init = init;
 		ts.cond = cond;
 		ts.body = body;
+		ts.switch_pos = tok.pos;
 		return ts;
 	}
 }
@@ -1156,7 +1162,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 
 		end := end_pos(tok);
 		if len(results) > 0 {
-			end = results[len(results)-1].pos;
+			end = results[len(results)-1].end;
 		}
 
 		rs := ast.new(ast.Return_Stmt, tok.pos, end);

+ 2 - 0
core/odin/tokenizer/token.odin

@@ -317,6 +317,8 @@ is_operator :: proc(kind: Token_Kind) -> bool {
 		return true;
 	case .In, .Not_In:
 		return true;
+	case .If:
+		return true;
 	}
 	return false;
 }

+ 1 - 1
core/odin/tokenizer/tokenizer.odin

@@ -266,7 +266,7 @@ scan_escape :: proc(t: ^Tokenizer) -> bool {
 	n: int;
 	base, max: u32;
 	switch t.ch {
-	case 'a', 'b', 'e', 'f', 'n', 't', 'v', '\\', '\'', '\"':
+	case 'a', 'b', 'e', 'f', 'n', 't', 'v', 'r', '\\', '\'', '\"':
 		advance_rune(t);
 		return true;
 

+ 27 - 0
default.nix

@@ -0,0 +1,27 @@
+{ pkgs ? import <nixpkgs> { } }:
+let
+  odin-unwrapped = pkgs.llvmPackages_11.stdenv.mkDerivation (rec {
+    name = "odin-unwrapped";
+    src = ./.;
+    dontConfigure = true;
+    nativeBuildInputs = [ pkgs.git ];
+    buildPhase = ''
+      make debug SHELL=${pkgs.llvmPackages_11.stdenv.shell}
+    '';
+    installPhase = ''
+      mkdir -p $out/bin
+      cp odin $out/bin/odin
+      cp -r core $out/bin/core
+    '';
+  });
+  path = builtins.map (path: path + "/bin") (with pkgs.llvmPackages_11; [
+    bintools
+    llvm
+    clang
+    lld
+  ]);
+in
+pkgs.writeScriptBin "odin" ''
+  #!${pkgs.llvmPackages_11.stdenv.shell} 
+  PATH="${(builtins.concatStringsSep ":" path)}" exec ${odin-unwrapped}/bin/odin $@
+''