Browse Source

Add extra error handling for parsing slices

gingerBill 6 years ago
parent
commit
308300c1fc
2 changed files with 30 additions and 10 deletions
  1. 10 2
      core/odin/parser/parser.odin
  2. 20 8
      src/parser.cpp

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

@@ -2482,11 +2482,19 @@ parse_atom_expr :: proc(p: ^Parser, operand: ^ast.Expr, lhs: bool) -> ^ast.Expr
 			p.expr_level += 1;
 			p.expr_level += 1;
 			open := expect_token(p, token.Open_Bracket);
 			open := expect_token(p, token.Open_Bracket);
 
 
-			if p.curr_tok.kind != token.Colon {
+			switch p.curr_tok.kind {
+			case token.Colon, token.Ellipsis, token.Range_Half:
+				// NOTE(bill): Do not err yet
+				break;
+			case:
 				indicies[0] = parse_expr(p, false);
 				indicies[0] = parse_expr(p, false);
 			}
 			}
 
 
-			if p.curr_tok.kind == token.Colon {
+			switch p.curr.tok.kind {
+			case token.Ellipsis, token.Range_Half:
+				error(p, p.curr_tok.pos, "expected a colon, not a range");
+				fallthrough;
+			case token.Colon:
 				interval = advance_token(p);
 				interval = advance_token(p);
 				is_slice_op = true;
 				is_slice_op = true;
 				if (p.curr_tok.kind != token.Close_Bracket && p.curr_tok.kind != token.EOF) {
 				if (p.curr_tok.kind != token.Close_Bracket && p.curr_tok.kind != token.EOF) {

+ 20 - 8
src/parser.cpp

@@ -2245,31 +2245,43 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
 
 
 			Token open = {}, close = {}, interval = {};
 			Token open = {}, close = {}, interval = {};
 			Ast *indices[2] = {};
 			Ast *indices[2] = {};
-			Token ellipsis = {};
-			bool is_ellipsis = false;
+			bool is_interval = false;
 
 
 			f->expr_level++;
 			f->expr_level++;
 			open = expect_token(f, Token_OpenBracket);
 			open = expect_token(f, Token_OpenBracket);
 
 
-			if (f->curr_token.kind != Token_Colon) {
+			switch (f->curr_token.kind) {
+			case Token_Ellipsis:
+			case Token_RangeHalf:
+				// NOTE(bill): Do not err yet
+			case Token_Colon:
+				break;
+			default:
 				indices[0] = parse_expr(f, false);
 				indices[0] = parse_expr(f, false);
+				break;
 			}
 			}
 
 
-			if (f->curr_token.kind == Token_Colon) {
-				ellipsis = advance_token(f);
-				is_ellipsis = true;
+			switch (f->curr_token.kind) {
+			case Token_Ellipsis:
+			case Token_RangeHalf:
+				syntax_error(f->curr_token, "Expected a colon, not a range");
+				/* fallthrough */
+			case Token_Colon:
+				interval = advance_token(f);
+				is_interval = true;
 				if (f->curr_token.kind != Token_CloseBracket &&
 				if (f->curr_token.kind != Token_CloseBracket &&
 				    f->curr_token.kind != Token_EOF) {
 				    f->curr_token.kind != Token_EOF) {
 					indices[1] = parse_expr(f, false);
 					indices[1] = parse_expr(f, false);
 				}
 				}
+				break;
 			}
 			}
 
 
 
 
 			f->expr_level--;
 			f->expr_level--;
 			close = expect_token(f, Token_CloseBracket);
 			close = expect_token(f, Token_CloseBracket);
 
 
-			if (is_ellipsis) {
-				operand = ast_slice_expr(f, operand, open, close, ellipsis, indices[0], indices[1]);
+			if (is_interval) {
+				operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
 			} else {
 			} else {
 				operand = ast_index_expr(f, operand, indices[0], open, close);
 				operand = ast_index_expr(f, operand, indices[0], open, close);
 			}
 			}