Browse Source

Merge pull request #805 from DanielGavin/master

small fixes to the parser
gingerBill 4 years ago
parent
commit
a574ebe5ec

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

@@ -325,6 +325,7 @@ If_Stmt :: struct {
 	init:      ^Stmt,
 	init:      ^Stmt,
 	cond:      ^Expr,
 	cond:      ^Expr,
 	body:      ^Stmt,
 	body:      ^Stmt,
+	else_pos:  tokenizer.Pos,
 	else_stmt: ^Stmt,
 	else_stmt: ^Stmt,
 }
 }
 
 
@@ -490,7 +491,7 @@ unparen_expr :: proc(expr: ^Expr) -> (val: ^Expr) {
 	}
 	}
 	for {
 	for {
 		e, ok := val.derived.(Paren_Expr);
 		e, ok := val.derived.(Paren_Expr);
-		if !ok {
+		if !ok || e.expr == nil {
 			break;
 			break;
 		}
 		}
 		val = e.expr;
 		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;
 	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 {
 	if p.tok.ch <= 0 {
 		return true;
 		return true;
 	}
 	}
@@ -625,6 +625,8 @@ parse_if_stmt :: proc(p: ^Parser) -> ^ast.If_Stmt {
 		skip_possible_newline_for_literal(p);
 		skip_possible_newline_for_literal(p);
 	}
 	}
 
 
+	else_tok := p.curr_tok.pos;
+
 	if allow_token(p, .Else) {
 	if allow_token(p, .Else) {
 		#partial switch p.curr_tok.kind {
 		#partial switch p.curr_tok.kind {
 		case .If:
 		case .If:
@@ -650,6 +652,7 @@ parse_if_stmt :: proc(p: ^Parser) -> ^ast.If_Stmt {
 	if_stmt.cond      = cond;
 	if_stmt.cond      = cond;
 	if_stmt.body      = body;
 	if_stmt.body      = body;
 	if_stmt.else_stmt = else_stmt;
 	if_stmt.else_stmt = else_stmt;
+	if_stmt.else_pos = else_tok;
 	return if_stmt;
 	return if_stmt;
 }
 }
 
 
@@ -784,6 +787,7 @@ parse_case_clause :: proc(p: ^Parser, is_type_switch: bool) -> ^ast.Case_Clause
 	cc.list = list;
 	cc.list = list;
 	cc.terminator = terminator;
 	cc.terminator = terminator;
 	cc.body = stmts;
 	cc.body = stmts;
+	cc.case_pos = tok.pos;
 	return cc;
 	return cc;
 }
 }
 
 
@@ -845,6 +849,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 		ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body.end);
 		ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body.end);
 		ts.tag  = tag;
 		ts.tag  = tag;
 		ts.body = body;
 		ts.body = body;
+		ts.switch_pos = tok.pos;
 		return ts;
 		return ts;
 	} else {
 	} else {
 		cond := convert_stmt_to_expr(p, tag, "switch expression");
 		cond := convert_stmt_to_expr(p, tag, "switch expression");
@@ -852,6 +857,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 		ts.init = init;
 		ts.init = init;
 		ts.cond = cond;
 		ts.cond = cond;
 		ts.body = body;
 		ts.body = body;
+		ts.switch_pos = tok.pos;
 		return ts;
 		return ts;
 	}
 	}
 }
 }
@@ -1155,7 +1161,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 
 
 		end := end_pos(tok);
 		end := end_pos(tok);
 		if len(results) > 0 {
 		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);
 		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;
 		return true;
 	case .In, .Not_In:
 	case .In, .Not_In:
 		return true;
 		return true;
+	case .If:
+		return true;
 	}
 	}
 	return false;
 	return false;
 }
 }

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

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