mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-29 17:34:34 +00:00
fix nil exceptions with incomplete code parse
This makes the parser more fault tolerant because the different parse_foo procs return nil when in an invalid state, which is fine most of the time but when creating a node it would crash accessing its position.
This commit is contained in:
@@ -7,7 +7,7 @@ import "core:reflect"
|
||||
import "core:odin/tokenizer"
|
||||
_ :: intrinsics
|
||||
|
||||
new :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
|
||||
new_from_positions :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
|
||||
n, _ := mem.new(T)
|
||||
n.pos = pos
|
||||
n.end = end
|
||||
@@ -23,6 +23,15 @@ new :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T {
|
||||
return n
|
||||
}
|
||||
|
||||
new_from_pos_and_end_node :: proc($T: typeid, pos: tokenizer.Pos, end: ^Node) -> ^T {
|
||||
return new(T, pos, end != nil ? end.end : {})
|
||||
}
|
||||
|
||||
new :: proc {
|
||||
new_from_positions,
|
||||
new_from_pos_and_end_node,
|
||||
}
|
||||
|
||||
clone :: proc{
|
||||
clone_node,
|
||||
clone_expr,
|
||||
|
||||
@@ -786,8 +786,11 @@ parse_if_stmt :: proc(p: ^Parser) -> ^ast.If_Stmt {
|
||||
else_stmt = ast.new(ast.Bad_Stmt, p.curr_tok.pos, end_pos(p.curr_tok))
|
||||
}
|
||||
}
|
||||
|
||||
end := body.end
|
||||
|
||||
end: tokenizer.Pos
|
||||
if body != nil {
|
||||
end = body.end
|
||||
}
|
||||
if else_stmt != nil {
|
||||
end = else_stmt.end
|
||||
}
|
||||
@@ -850,7 +853,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
body = parse_body(p)
|
||||
}
|
||||
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end)
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body)
|
||||
range_stmt.for_pos = tok.pos
|
||||
range_stmt.in_pos = in_tok.pos
|
||||
range_stmt.expr = rhs
|
||||
@@ -910,7 +913,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
rhs = assign_stmt.rhs[0]
|
||||
}
|
||||
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body.end)
|
||||
range_stmt := ast.new(ast.Range_Stmt, tok.pos, body)
|
||||
range_stmt.for_pos = tok.pos
|
||||
range_stmt.vals = vals
|
||||
range_stmt.in_pos = assign_stmt.op.pos
|
||||
@@ -920,7 +923,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
}
|
||||
|
||||
cond_expr := convert_stmt_to_expr(p, cond, "boolean expression")
|
||||
for_stmt := ast.new(ast.For_Stmt, tok.pos, body.end)
|
||||
for_stmt := ast.new(ast.For_Stmt, tok.pos, body)
|
||||
for_stmt.for_pos = tok.pos
|
||||
for_stmt.init = init
|
||||
for_stmt.cond = cond_expr
|
||||
@@ -976,7 +979,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
lhs[0] = new_blank_ident(p, tok.pos)
|
||||
rhs[0] = parse_expr(p, true)
|
||||
|
||||
as := ast.new(ast.Assign_Stmt, tok.pos, rhs[0].end)
|
||||
as := ast.new(ast.Assign_Stmt, tok.pos, rhs[0])
|
||||
as.lhs = lhs
|
||||
as.op = in_tok
|
||||
as.rhs = rhs
|
||||
@@ -1010,14 +1013,14 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
body.stmts = clauses[:]
|
||||
|
||||
if is_type_switch {
|
||||
ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body.end)
|
||||
ts := ast.new(ast.Type_Switch_Stmt, tok.pos, body)
|
||||
ts.tag = tag
|
||||
ts.body = body
|
||||
ts.switch_pos = tok.pos
|
||||
return ts
|
||||
} else {
|
||||
cond := convert_stmt_to_expr(p, tag, "switch expression")
|
||||
ts := ast.new(ast.Switch_Stmt, tok.pos, body.end)
|
||||
ts := ast.new(ast.Switch_Stmt, tok.pos, body)
|
||||
ts.init = init
|
||||
ts.cond = cond
|
||||
ts.body = body
|
||||
@@ -1044,7 +1047,7 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind:
|
||||
if p.curr_tok.kind == .Eq {
|
||||
eq := expect_token(p, .Eq)
|
||||
value := parse_value(p)
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value.end)
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value)
|
||||
fv.field = elem
|
||||
fv.sep = eq.pos
|
||||
fv.value = value
|
||||
@@ -1137,7 +1140,7 @@ parse_foreign_block :: proc(p: ^Parser, tok: tokenizer.Token) -> ^ast.Foreign_Bl
|
||||
body.stmts = decls[:]
|
||||
body.close = close.pos
|
||||
|
||||
decl := ast.new(ast.Foreign_Block_Decl, tok.pos, body.end)
|
||||
decl := ast.new(ast.Foreign_Block_Decl, tok.pos, body)
|
||||
decl.docs = docs
|
||||
decl.tok = tok
|
||||
decl.foreign_library = foreign_library
|
||||
@@ -1248,7 +1251,7 @@ parse_unrolled_for_loop :: proc(p: ^Parser, inline_tok: tokenizer.Token) -> ^ast
|
||||
return ast.new(ast.Bad_Stmt, inline_tok.pos, end_pos(p.prev_tok))
|
||||
}
|
||||
|
||||
range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body.end)
|
||||
range_stmt := ast.new(ast.Inline_Range_Stmt, inline_tok.pos, body)
|
||||
range_stmt.inline_pos = inline_tok.pos
|
||||
range_stmt.for_pos = for_tok.pos
|
||||
range_stmt.val0 = val0
|
||||
@@ -1304,7 +1307,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
case ^ast.Return_Stmt:
|
||||
error(p, s.pos, "you cannot defer a return statement")
|
||||
}
|
||||
ds := ast.new(ast.Defer_Stmt, tok.pos, stmt.end)
|
||||
ds := ast.new(ast.Defer_Stmt, tok.pos, stmt)
|
||||
ds.stmt = stmt
|
||||
return ds
|
||||
|
||||
@@ -1341,8 +1344,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
if tok.kind != .Fallthrough && p.curr_tok.kind == .Ident {
|
||||
label = parse_ident(p)
|
||||
}
|
||||
end := label.end if label != nil else end_pos(tok)
|
||||
s := ast.new(ast.Branch_Stmt, tok.pos, end)
|
||||
s := ast.new(ast.Branch_Stmt, tok.pos, label)
|
||||
s.tok = tok
|
||||
s.label = label
|
||||
expect_semicolon(p, s)
|
||||
@@ -1366,7 +1368,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
if p.curr_tok.kind != .Colon {
|
||||
end := list[len(list)-1]
|
||||
expect_semicolon(p, end)
|
||||
us := ast.new(ast.Using_Stmt, tok.pos, end.end)
|
||||
us := ast.new(ast.Using_Stmt, tok.pos, end)
|
||||
us.list = list
|
||||
return us
|
||||
}
|
||||
@@ -1416,13 +1418,13 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
bd.tok = tok
|
||||
bd.name = name
|
||||
ce := parse_call_expr(p, bd)
|
||||
es := ast.new(ast.Expr_Stmt, ce.pos, ce.end)
|
||||
es := ast.new(ast.Expr_Stmt, ce.pos, ce)
|
||||
es.expr = ce
|
||||
return es
|
||||
|
||||
case "force_inline", "force_no_inline":
|
||||
expr := parse_inlining_operand(p, true, tag)
|
||||
es := ast.new(ast.Expr_Stmt, expr.pos, expr.end)
|
||||
es := ast.new(ast.Expr_Stmt, expr.pos, expr)
|
||||
es.expr = expr
|
||||
return es
|
||||
case "unroll":
|
||||
@@ -1444,7 +1446,8 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
|
||||
return ast.new(ast.Bad_Stmt, tok.pos, end_pos(tag))
|
||||
case:
|
||||
stmt := parse_stmt(p)
|
||||
te := ast.new(ast.Tag_Stmt, tok.pos, stmt.pos)
|
||||
end := stmt.pos if stmt != nil else end_pos(tok)
|
||||
te := ast.new(ast.Tag_Stmt, tok.pos, end)
|
||||
te.op = tok
|
||||
te.name = name
|
||||
te.stmt = stmt
|
||||
@@ -1572,7 +1575,7 @@ convert_stmt_to_body :: proc(p: ^Parser, stmt: ^ast.Stmt) -> ^ast.Stmt {
|
||||
error(p, stmt.pos, "expected a non-empty statement")
|
||||
}
|
||||
|
||||
bs := ast.new(ast.Block_Stmt, stmt.pos, stmt.end)
|
||||
bs := ast.new(ast.Block_Stmt, stmt.pos, stmt)
|
||||
bs.open = stmt.pos
|
||||
bs.stmts = make([]^ast.Stmt, 1)
|
||||
bs.stmts[0] = stmt
|
||||
@@ -1741,7 +1744,7 @@ parse_var_type :: proc(p: ^Parser, flags: ast.Field_Flags) -> ^ast.Expr {
|
||||
error(p, tok.pos, "variadic field missing type after '..'")
|
||||
type = ast.new(ast.Bad_Expr, tok.pos, end_pos(tok))
|
||||
}
|
||||
e := ast.new(ast.Ellipsis, type.pos, type.end)
|
||||
e := ast.new(ast.Ellipsis, type.pos, type)
|
||||
e.expr = type
|
||||
return e
|
||||
}
|
||||
@@ -1808,7 +1811,7 @@ parse_ident_list :: proc(p: ^Parser, allow_poly_names: bool) -> []^ast.Expr {
|
||||
if is_blank_ident(ident) {
|
||||
error(p, ident.pos, "invalid polymorphic type definition with a blank identifier")
|
||||
}
|
||||
poly_name := ast.new(ast.Poly_Type, tok.pos, ident.end)
|
||||
poly_name := ast.new(ast.Poly_Type, tok.pos, ident)
|
||||
poly_name.type = ident
|
||||
append(&list, poly_name)
|
||||
} else {
|
||||
@@ -2154,7 +2157,7 @@ parse_inlining_operand :: proc(p: ^Parser, lhs: bool, tok: tokenizer.Token) -> ^
|
||||
e.inlining = pi
|
||||
case:
|
||||
error(p, tok.pos, "'%s' must be followed by a procedure literal or call", tok.text)
|
||||
return ast.new(ast.Bad_Expr, tok.pos, expr.end)
|
||||
return ast.new(ast.Bad_Expr, tok.pos, expr)
|
||||
}
|
||||
return expr
|
||||
}
|
||||
@@ -2204,7 +2207,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
case .Distinct:
|
||||
tok := advance_token(p)
|
||||
type := parse_type(p)
|
||||
dt := ast.new(ast.Distinct_Type, tok.pos, type.end)
|
||||
dt := ast.new(ast.Distinct_Type, tok.pos, type)
|
||||
dt.tok = tok.kind
|
||||
dt.type = type
|
||||
return dt
|
||||
@@ -2215,7 +2218,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
switch name.text {
|
||||
case "type":
|
||||
type := parse_type(p)
|
||||
hp := ast.new(ast.Helper_Type, tok.pos, type.end)
|
||||
hp := ast.new(ast.Helper_Type, tok.pos, type)
|
||||
hp.tok = tok.kind
|
||||
hp.type = type
|
||||
return hp
|
||||
@@ -2319,7 +2322,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tag_call := parse_call_expr(p, tag)
|
||||
type := parse_type(p)
|
||||
|
||||
rt := ast.new(ast.Relative_Type, tok.pos, type.end)
|
||||
rt := ast.new(ast.Relative_Type, tok.pos, type)
|
||||
rt.tag = tag_call
|
||||
rt.type = type
|
||||
return rt
|
||||
@@ -2328,7 +2331,8 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
return parse_inlining_operand(p, lhs, name)
|
||||
case:
|
||||
expr := parse_expr(p, lhs)
|
||||
te := ast.new(ast.Tag_Expr, tok.pos, expr.pos)
|
||||
end := expr.pos if expr != nil else end_pos(tok)
|
||||
te := ast.new(ast.Tag_Expr, tok.pos, end)
|
||||
te.op = tok
|
||||
te.name = name.text
|
||||
te.expr = expr
|
||||
@@ -2456,7 +2460,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
case .Pointer:
|
||||
tok := expect_token(p, .Pointer)
|
||||
elem := parse_type(p)
|
||||
ptr := ast.new(ast.Pointer_Type, tok.pos, elem.end)
|
||||
ptr := ast.new(ast.Pointer_Type, tok.pos, elem)
|
||||
ptr.pointer = tok.pos
|
||||
ptr.elem = elem
|
||||
return ptr
|
||||
@@ -2470,7 +2474,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tok := expect_token(p, .Pointer)
|
||||
close := expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
t := ast.new(ast.Multi_Pointer_Type, open.pos, elem.end)
|
||||
t := ast.new(ast.Multi_Pointer_Type, open.pos, elem)
|
||||
t.open = open.pos
|
||||
t.pointer = tok.pos
|
||||
t.close = close.pos
|
||||
@@ -2480,7 +2484,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
tok := expect_token(p, .Dynamic)
|
||||
close := expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
da := ast.new(ast.Dynamic_Array_Type, open.pos, elem.end)
|
||||
da := ast.new(ast.Dynamic_Array_Type, open.pos, elem)
|
||||
da.open = open.pos
|
||||
da.dynamic_pos = tok.pos
|
||||
da.close = close.pos
|
||||
@@ -2500,7 +2504,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
}
|
||||
close := expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
at := ast.new(ast.Array_Type, open.pos, elem.end)
|
||||
at := ast.new(ast.Array_Type, open.pos, elem)
|
||||
at.open = open.pos
|
||||
at.len = count
|
||||
at.close = close.pos
|
||||
@@ -2514,7 +2518,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
expect_token(p, .Close_Bracket)
|
||||
value := parse_type(p)
|
||||
|
||||
mt := ast.new(ast.Map_Type, tok.pos, value.end)
|
||||
mt := ast.new(ast.Map_Type, tok.pos, value)
|
||||
mt.tok_pos = tok.pos
|
||||
mt.key = key
|
||||
mt.value = value
|
||||
@@ -2755,7 +2759,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
expect_token(p, .Close_Bracket)
|
||||
elem := parse_type(p)
|
||||
|
||||
mt := ast.new(ast.Matrix_Type, tok.pos, elem.end)
|
||||
mt := ast.new(ast.Matrix_Type, tok.pos, elem)
|
||||
mt.tok_pos = tok.pos
|
||||
mt.row_count = row_count
|
||||
mt.column_count = column_count
|
||||
@@ -2893,7 +2897,7 @@ parse_elem_list :: proc(p: ^Parser) -> []^ast.Expr {
|
||||
eq := expect_token(p, .Eq)
|
||||
value := parse_value(p)
|
||||
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value.end)
|
||||
fv := ast.new(ast.Field_Value, elem.pos, value)
|
||||
fv.field = elem
|
||||
fv.sep = eq.pos
|
||||
fv.value = value
|
||||
@@ -2962,7 +2966,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr {
|
||||
}
|
||||
|
||||
value := parse_value(p)
|
||||
fv := ast.new(ast.Field_Value, arg.pos, value.end)
|
||||
fv := ast.new(ast.Field_Value, arg.pos, value)
|
||||
fv.field = arg
|
||||
fv.sep = eq.pos
|
||||
fv.value = value
|
||||
@@ -2993,7 +2997,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr {
|
||||
|
||||
o := ast.unparen_expr(operand)
|
||||
if se, ok := o.derived.(^ast.Selector_Expr); ok && se.op.kind == .Arrow_Right {
|
||||
sce := ast.new(ast.Selector_Call_Expr, ce.pos, ce.end)
|
||||
sce := ast.new(ast.Selector_Call_Expr, ce.pos, ce)
|
||||
sce.expr = o
|
||||
sce.call = ce
|
||||
return sce
|
||||
@@ -3101,7 +3105,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
|
||||
case .Ident:
|
||||
field := parse_ident(p)
|
||||
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field.end)
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field)
|
||||
sel.expr = operand
|
||||
sel.op = tok
|
||||
sel.field = field
|
||||
@@ -3127,7 +3131,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
|
||||
type.op = question
|
||||
type.expr = nil
|
||||
|
||||
ta := ast.new(ast.Type_Assertion, operand.pos, type.end)
|
||||
ta := ast.new(ast.Type_Assertion, operand.pos, type)
|
||||
ta.expr = operand
|
||||
ta.type = type
|
||||
|
||||
@@ -3145,7 +3149,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a
|
||||
case .Ident:
|
||||
field := parse_ident(p)
|
||||
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field.end)
|
||||
sel := ast.new(ast.Selector_Expr, operand.pos, field)
|
||||
sel.expr = operand
|
||||
sel.op = tok
|
||||
sel.field = field
|
||||
@@ -3225,7 +3229,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
close := expect_token(p, .Close_Paren)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
tc := ast.new(ast.Type_Cast, tok.pos, expr.end)
|
||||
tc := ast.new(ast.Type_Cast, tok.pos, expr)
|
||||
tc.tok = tok
|
||||
tc.open = open.pos
|
||||
tc.type = type
|
||||
@@ -3237,7 +3241,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
op := advance_token(p)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
ac := ast.new(ast.Auto_Cast, op.pos, expr.end)
|
||||
ac := ast.new(ast.Auto_Cast, op.pos, expr)
|
||||
ac.op = op
|
||||
ac.expr = expr
|
||||
return ac
|
||||
@@ -3247,8 +3251,8 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
.And:
|
||||
op := advance_token(p)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr.end)
|
||||
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr)
|
||||
ue.op = op
|
||||
ue.expr = expr
|
||||
return ue
|
||||
@@ -3258,7 +3262,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
error(p, op.pos, "unary '%s' operator is not supported", op.text)
|
||||
expr := parse_unary_expr(p, lhs)
|
||||
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr.end)
|
||||
ue := ast.new(ast.Unary_Expr, op.pos, expr)
|
||||
ue.op = op
|
||||
ue.expr = expr
|
||||
return ue
|
||||
@@ -3266,7 +3270,7 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
|
||||
case .Period:
|
||||
op := advance_token(p)
|
||||
field := parse_ident(p)
|
||||
ise := ast.new(ast.Implicit_Selector_Expr, op.pos, field.end)
|
||||
ise := ast.new(ast.Implicit_Selector_Expr, op.pos, field)
|
||||
ise.field = field
|
||||
return ise
|
||||
|
||||
@@ -3407,7 +3411,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
|
||||
error(p, p.curr_tok.pos, "no right-hand side in assignment statement")
|
||||
return ast.new(ast.Bad_Stmt, start_tok.pos, end_pos(p.curr_tok))
|
||||
}
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1].end)
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1])
|
||||
stmt.lhs = lhs
|
||||
stmt.op = op
|
||||
stmt.rhs = rhs
|
||||
@@ -3424,7 +3428,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
|
||||
rhs := make([]^ast.Expr, 1)
|
||||
rhs[0] = expr
|
||||
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1].end)
|
||||
stmt := ast.new(ast.Assign_Stmt, lhs[0].pos, rhs[len(rhs)-1])
|
||||
stmt.lhs = lhs
|
||||
stmt.op = op
|
||||
stmt.rhs = rhs
|
||||
@@ -3466,7 +3470,7 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt {
|
||||
error(p, op.pos, "postfix '%s' statement is not supported", op.text)
|
||||
}
|
||||
|
||||
es := ast.new(ast.Expr_Stmt, lhs[0].pos, lhs[0].end)
|
||||
es := ast.new(ast.Expr_Stmt, lhs[0].pos, lhs[0])
|
||||
es.expr = lhs[0]
|
||||
return es
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user