checker: fix match expr with assign sumtype variable (#13614)
parent
bc16c61f6f
commit
81c787ef91
|
@ -11,12 +11,17 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
defer {
|
defer {
|
||||||
c.expected_type = ast.void_type
|
c.expected_type = ast.void_type
|
||||||
}
|
}
|
||||||
|
is_decl := node.op == .decl_assign
|
||||||
right_first := node.right[0]
|
right_first := node.right[0]
|
||||||
node.left_types = []
|
node.left_types = []
|
||||||
mut right_len := node.right.len
|
mut right_len := node.right.len
|
||||||
mut right_type0 := ast.void_type
|
mut right_type0 := ast.void_type
|
||||||
for i, right in node.right {
|
for i, right in node.right {
|
||||||
if right in [ast.CallExpr, ast.IfExpr, ast.LockExpr, ast.MatchExpr] {
|
if right in [ast.CallExpr, ast.IfExpr, ast.LockExpr, ast.MatchExpr] {
|
||||||
|
if right in [ast.IfExpr, ast.MatchExpr] && node.left.len == node.right.len && !is_decl
|
||||||
|
&& node.left[i] in [ast.Ident, ast.SelectorExpr] && !node.left[i].is_blank_ident() {
|
||||||
|
c.expected_type = c.expr(node.left[i])
|
||||||
|
}
|
||||||
right_type := c.expr(right)
|
right_type := c.expr(right)
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
right_type0 = right_type
|
right_type0 = right_type
|
||||||
|
@ -66,7 +71,6 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
is_decl := node.op == .decl_assign
|
|
||||||
for i, left in node.left {
|
for i, left in node.left {
|
||||||
if left is ast.CallExpr {
|
if left is ast.CallExpr {
|
||||||
// ban `foo() = 10`
|
// ban `foo() = 10`
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
fn test_match_expr_with_assign_sumtype() {
|
||||||
|
parse_args(['1', '+', '-', '*', '/', ' ']) or { println(err) }
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Operator {
|
||||||
|
add
|
||||||
|
subtract
|
||||||
|
multiply
|
||||||
|
divide
|
||||||
|
}
|
||||||
|
|
||||||
|
type Value = Operator | int
|
||||||
|
|
||||||
|
struct Expression {
|
||||||
|
left ?&Expression = none
|
||||||
|
val Value
|
||||||
|
right ?&Expression = none
|
||||||
|
}
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
expecting
|
||||||
|
parse_num
|
||||||
|
parse_operator
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tokenise(args string) ?[]Value {
|
||||||
|
mut rv := []Value{}
|
||||||
|
|
||||||
|
mut state := State.expecting
|
||||||
|
mut cur_value := Value(0)
|
||||||
|
for i in args.runes() {
|
||||||
|
match state {
|
||||||
|
.expecting {
|
||||||
|
match i {
|
||||||
|
`0`...`9` {
|
||||||
|
state = .parse_num
|
||||||
|
cur_value = int(i.str().parse_uint(10, 8) ?)
|
||||||
|
}
|
||||||
|
`+`, `-`, `*`, `/` {
|
||||||
|
state = .parse_operator
|
||||||
|
cur_value = match i {
|
||||||
|
`+` {
|
||||||
|
Operator.add
|
||||||
|
}
|
||||||
|
`-` {
|
||||||
|
Operator.subtract
|
||||||
|
}
|
||||||
|
`*` {
|
||||||
|
Operator.multiply
|
||||||
|
}
|
||||||
|
`/` {
|
||||||
|
Operator.divide
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Value(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
` ` {
|
||||||
|
state = .expecting
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return error('invalid token $i')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.parse_num {
|
||||||
|
match i {
|
||||||
|
`0`...`9` {
|
||||||
|
cur_value = 10 + int(i.str().parse_uint(10, 8) ?)
|
||||||
|
}
|
||||||
|
`+`, `-`, `*`, `/` {
|
||||||
|
state = .parse_operator
|
||||||
|
rv << cur_value
|
||||||
|
cur_value = match i {
|
||||||
|
`+` { Operator.add }
|
||||||
|
`-` { Operator.subtract }
|
||||||
|
`*` { Operator.multiply }
|
||||||
|
`/` { Operator.divide }
|
||||||
|
else { Value(0) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
` ` {
|
||||||
|
state = .expecting
|
||||||
|
rv << cur_value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return error('invalid token $i')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.parse_operator {
|
||||||
|
match i {
|
||||||
|
`0`...`9` {
|
||||||
|
state = .parse_num
|
||||||
|
rv << cur_value
|
||||||
|
cur_value = int(i.str().parse_uint(10, 8) ?)
|
||||||
|
}
|
||||||
|
` ` {
|
||||||
|
state = .expecting
|
||||||
|
rv << cur_value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return error('invalid token $i')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_args(argv []string) ?Expression {
|
||||||
|
rv := Expression{
|
||||||
|
val: 1
|
||||||
|
}
|
||||||
|
tokens := tokenise(argv.join(' ')) ?
|
||||||
|
|
||||||
|
println(tokens)
|
||||||
|
assert '$tokens' == '[Value(1), Value(add), Value(subtract), Value(multiply), Value(divide)]'
|
||||||
|
|
||||||
|
return rv
|
||||||
|
}
|
Loading…
Reference in New Issue