Browse Source

Improve core:odin/ast ast.Range_Stmt to use generic number of `vals` rather than the fixed two to aid with parsing errors

gingerBill 4 years ago
parent
commit
bec42e8dd3
4 changed files with 8 additions and 23 deletions
  1. 1 2
      core/odin/ast/ast.odin
  2. 1 2
      core/odin/ast/clone.odin
  3. 4 5
      core/odin/ast/walk.odin
  4. 2 14
      core/odin/parser/parser.odin

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

@@ -402,8 +402,7 @@ Range_Stmt :: struct {
 	using node: Stmt,
 	using node: Stmt,
 	label:     ^Expr,
 	label:     ^Expr,
 	for_pos:   tokenizer.Pos,
 	for_pos:   tokenizer.Pos,
-	val0:      ^Expr,
-	val1:      ^Expr,
+	vals:      []^Expr,
 	in_pos:    tokenizer.Pos,
 	in_pos:    tokenizer.Pos,
 	expr:      ^Expr,
 	expr:      ^Expr,
 	body:      ^Stmt,
 	body:      ^Stmt,

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

@@ -192,8 +192,7 @@ clone_node :: proc(node: ^Node) -> ^Node {
 		r.body = clone(r.body);
 		r.body = clone(r.body);
 	case Range_Stmt:
 	case Range_Stmt:
 		r.label = auto_cast clone(r.label);
 		r.label = auto_cast clone(r.label);
-		r.val0 = clone(r.val0);
-		r.val1 = clone(r.val1);
+		r.vals = clone(r.vals);
 		r.expr = clone(r.expr);
 		r.expr = clone(r.expr);
 		r.body = clone(r.body);
 		r.body = clone(r.body);
 	case Case_Clause:
 	case Case_Clause:

+ 4 - 5
core/odin/ast/walk.odin

@@ -209,11 +209,10 @@ walk :: proc(v: ^Visitor, node: ^Node) {
 		if n.label != nil {
 		if n.label != nil {
 			walk(v, n.label);
 			walk(v, n.label);
 		}
 		}
-		if n.val0 != nil {
-			walk(v, n.val0);
-		}
-		if n.val1 != nil {
-			walk(v, n.val1);
+		for val in n.vals {
+			if val != nil {
+				walk(v, val);
+			}
 		}
 		}
 		walk(v, n.expr);
 		walk(v, n.expr);
 		walk(v, n.body);
 		walk(v, n.body);

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

@@ -738,18 +738,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 
 
 	if is_range {
 	if is_range {
 		assign_stmt := cond.derived.(ast.Assign_Stmt);
 		assign_stmt := cond.derived.(ast.Assign_Stmt);
-		val0, val1: ^ast.Expr;
-
-		switch len(assign_stmt.lhs) {
-		case 1:
-			val0 = assign_stmt.lhs[0];
-		case 2:
-			val0 = assign_stmt.lhs[0];
-			val1 = assign_stmt.lhs[1];
-		case:
-			error(p, cond.pos, "expected either 1 or 2 identifiers");
-			return ast.new(ast.Bad_Stmt, tok.pos, body.end);
-		}
+		vals := assign_stmt.lhs[:];
 
 
 		rhs: ^ast.Expr;
 		rhs: ^ast.Expr;
 		if len(assign_stmt.rhs) > 0 {
 		if len(assign_stmt.rhs) > 0 {
@@ -758,8 +747,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 
 
 		range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end);
 		range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end);
 		range_stmt.for_pos = tok.pos;
 		range_stmt.for_pos = tok.pos;
-		range_stmt.val0 = val0;
-		range_stmt.val1 = val1;
+		range_stmt.vals = vals;
 		range_stmt.in_pos = assign_stmt.op.pos;
 		range_stmt.in_pos = assign_stmt.op.pos;
 		range_stmt.expr = rhs;
 		range_stmt.expr = rhs;
 		range_stmt.body = body;
 		range_stmt.body = body;