Browse Source

`or_break` and `or_continue` to `core:odin` packages

gingerBill 1 year ago
parent
commit
41a22bd83d

+ 11 - 0
core/odin/ast/ast.odin

@@ -284,6 +284,13 @@ Or_Return_Expr :: struct {
 	token: tokenizer.Token,
 }
 
+Or_Branch_Expr :: struct {
+	using node: Expr,
+	expr:  ^Expr,
+	token: tokenizer.Token,
+	label: ^Expr,
+}
+
 Type_Assertion :: struct {
 	using node: Expr,
 	expr:  ^Expr,
@@ -563,6 +570,8 @@ strip_or_return_expr :: proc(expr: ^Expr) -> (val: ^Expr) {
 		#partial switch e in val.derived {
 		case ^Or_Return_Expr:
 			inner = e.expr
+		case ^Or_Branch_Expr:
+			inner = e.expr
 		case ^Paren_Expr:
 			inner = e.expr
 		}
@@ -860,6 +869,7 @@ Any_Node :: union {
 	^Ternary_When_Expr,
 	^Or_Else_Expr,
 	^Or_Return_Expr,
+	^Or_Branch_Expr,
 	^Type_Assertion,
 	^Type_Cast,
 	^Auto_Cast,
@@ -943,6 +953,7 @@ Any_Expr :: union {
 	^Ternary_When_Expr,
 	^Or_Else_Expr,
 	^Or_Return_Expr,
+	^Or_Branch_Expr,
 	^Type_Assertion,
 	^Type_Cast,
 	^Auto_Cast,

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

@@ -147,8 +147,8 @@ clone_node :: proc(node: ^Node) -> ^Node {
 		r.expr = clone(r.expr)
 		r.index = clone(r.index)
 	case ^Matrix_Index_Expr:
-		r.expr = clone(r.expr)
-		r.row_index = clone(r.row_index)
+		r.expr         = clone(r.expr)
+		r.row_index    = clone(r.row_index)
 		r.column_index = clone(r.column_index)
 	case ^Deref_Expr:
 		r.expr = clone(r.expr)
@@ -175,6 +175,9 @@ clone_node :: proc(node: ^Node) -> ^Node {
 		r.y    = clone(r.y)
 	case ^Or_Return_Expr:
 		r.expr = clone(r.expr)
+	case ^Or_Branch_Expr:
+		r.expr  = clone(r.expr)
+		r.label = clone(r.label)
 	case ^Type_Assertion:
 		r.expr = clone(r.expr)
 		r.type = clone(r.type)

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

@@ -146,6 +146,11 @@ walk :: proc(v: ^Visitor, node: ^Node) {
 		walk(v, n.y)
 	case ^Or_Return_Expr:
 		walk(v, n.expr)
+	case ^Or_Branch_Expr:
+		walk(v, n.expr)
+		if n.label != nil {
+			walk(v, n.label)
+		}
 	case ^Type_Assertion:
 		walk(v, n.expr)
 		if n.type != nil {

+ 17 - 0
core/odin/parser/parser.odin

@@ -3190,6 +3190,23 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
 
 			operand = oe
 
+		case .Or_Break, .Or_Continue:
+			token := advance_token(p)
+			label: ^ast.Ident
+
+			end := end_pos(token)
+			if p.curr_tok.kind == .Ident {
+				end = end_pos(p.curr_tok)
+				label = parse_ident(p)
+			}
+
+			oe := ast.new(ast.Or_Branch_Expr, operand.pos, end)
+			oe.expr  = operand
+			oe.token = token
+			oe.label = label
+
+			operand = oe
+
 		case .Open_Brace:
 			if !is_lhs && is_literal_type(operand) && p.expr_level >= 0 {
 				operand = parse_literal_value(p, operand)

+ 7 - 0
core/odin/printer/visit.odin

@@ -972,6 +972,13 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) {
 	case ^ast.Or_Return_Expr:
 		visit_expr(p, v.expr)
 		push_generic_token(p, v.token.kind, 1)
+	case ^ast.Or_Branch_Expr:
+		visit_expr(p, v.expr)
+		push_generic_token(p, v.token.kind, 1)
+		if v.label != nil {
+			visit_expr(p, v.label)
+		}
+
 	case ^ast.Selector_Call_Expr:
 		visit_expr(p, v.call.expr)
 		push_generic_token(p, .Open_Paren, 1)