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 {
|
||||
c.expected_type = ast.void_type
|
||||
}
|
||||
is_decl := node.op == .decl_assign
|
||||
right_first := node.right[0]
|
||||
node.left_types = []
|
||||
mut right_len := node.right.len
|
||||
mut right_type0 := ast.void_type
|
||||
for i, right in node.right {
|
||||
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)
|
||||
if i == 0 {
|
||||
right_type0 = right_type
|
||||
|
@ -66,7 +71,6 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||
return
|
||||
}
|
||||
|
||||
is_decl := node.op == .decl_assign
|
||||
for i, left in node.left {
|
||||
if left is ast.CallExpr {
|
||||
// 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