parser/checker/gen: match shaddow cond var & as support: p1
parent
7be952605b
commit
68143b7b22
|
@ -442,6 +442,7 @@ pub:
|
|||
branches []MatchBranch
|
||||
pos token.Position
|
||||
is_mut bool // `match mut ast_node {`
|
||||
var_name string
|
||||
pub mut:
|
||||
is_expr bool // returns a value
|
||||
return_type table.Type
|
||||
|
|
|
@ -126,22 +126,33 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: remove sponge - put back match
|
||||
if !needs_braces {
|
||||
mut sub_expr := lit.exprs[i]
|
||||
for {
|
||||
match sub_expr {
|
||||
Ident {
|
||||
break
|
||||
}
|
||||
SelectorExpr {
|
||||
sub_expr = it.expr
|
||||
continue
|
||||
}
|
||||
else {
|
||||
needs_braces = true
|
||||
break
|
||||
}
|
||||
if sub_expr is Ident { break }
|
||||
else if sub_expr is SelectorExpr {
|
||||
se := sub_expr as SelectorExpr
|
||||
sub_expr = se.expr
|
||||
continue
|
||||
}
|
||||
else {
|
||||
needs_braces = true
|
||||
break
|
||||
}
|
||||
// match sub_expr {
|
||||
// Ident {
|
||||
// break
|
||||
// }
|
||||
// SelectorExpr {
|
||||
// sub_expr = it.expr
|
||||
// continue
|
||||
// }
|
||||
// else {
|
||||
// needs_braces = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
if needs_fspec {
|
||||
|
|
|
@ -93,13 +93,15 @@ pub fn (c &Checker) check_basic(got, expected table.Type) bool {
|
|||
return true
|
||||
}
|
||||
// sum type
|
||||
if got_type_sym.kind == .sum_type {
|
||||
sum_info := got_type_sym.info as table.SumType
|
||||
// TODO: handle `match SumType { &PtrVariant {} }` currently just checking base
|
||||
if expected.set_nr_muls(0) in sum_info.variants {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// TODO: there is a bug when casting sumtype the other way if its pointer
|
||||
// so until fixed at least show v (not C) error `x(variant) = y(SumType*)`
|
||||
// if got_type_sym.kind == .sum_type {
|
||||
// sum_info := got_type_sym.info as table.SumType
|
||||
// // TODO: handle `match SumType { &PtrVariant {} }` currently just checking base
|
||||
// if expected.set_nr_muls(0) in sum_info.variants {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
if exp_type_sym.kind == .sum_type {
|
||||
sum_info := exp_type_sym.info as table.SumType
|
||||
// TODO: handle `match SumType { &PtrVariant {} }` currently just checking base
|
||||
|
|
|
@ -170,19 +170,19 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
|
|||
}
|
||||
}
|
||||
ast.TypeDecl {
|
||||
type_decl := stmt as ast.TypeDecl
|
||||
if type_decl is ast.AliasTypeDecl {
|
||||
alias_decl := type_decl as ast.AliasTypeDecl
|
||||
// type_decl := stmt as ast.TypeDecl
|
||||
if it is ast.AliasTypeDecl {
|
||||
alias_decl := it as ast.AliasTypeDecl
|
||||
if alias_decl.is_pub {
|
||||
c.warn('type alias `$alias_decl.name` $no_pub_in_main_warning', alias_decl.pos)
|
||||
}
|
||||
} else if type_decl is ast.SumTypeDecl {
|
||||
sum_decl := type_decl as ast.SumTypeDecl
|
||||
} else if it is ast.SumTypeDecl {
|
||||
sum_decl := it as ast.SumTypeDecl
|
||||
if sum_decl.is_pub {
|
||||
c.warn('sum type `$sum_decl.name` $no_pub_in_main_warning', sum_decl.pos)
|
||||
}
|
||||
} else if type_decl is ast.FnTypeDecl {
|
||||
fn_decl := type_decl as ast.FnTypeDecl
|
||||
} else if it is ast.FnTypeDecl {
|
||||
fn_decl := it as ast.FnTypeDecl
|
||||
if fn_decl.is_pub {
|
||||
c.warn('type alias `$fn_decl.name` $no_pub_in_main_warning', fn_decl.pos)
|
||||
}
|
||||
|
|
|
@ -1227,7 +1227,9 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
}
|
||||
|
||||
fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
|
||||
match val {
|
||||
// TODO: remove sponge
|
||||
tmp_val := val
|
||||
match tmp_val {
|
||||
ast.Ident {
|
||||
mut has_var := false
|
||||
for lx in left {
|
||||
|
@ -1987,6 +1989,10 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
|
|||
g.write('\t$it_type* it = ($it_type*)')
|
||||
g.expr(node.cond)
|
||||
g.writeln('.obj; // ST it')
|
||||
if node.var_name.len > 0 {
|
||||
// for now we just copy it
|
||||
g.writeln('\t$it_type* $node.var_name = it;')
|
||||
}
|
||||
}
|
||||
else {
|
||||
verror('match sum type')
|
||||
|
|
|
@ -559,8 +559,7 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
|
|||
match expr {
|
||||
ast.IntegerLiteral {
|
||||
// `foo(2)` => `mov edi,0x2`
|
||||
int_lit := expr as ast.IntegerLiteral
|
||||
g.mov(fn_arg_registers[i], int_lit.val.int())
|
||||
g.mov(fn_arg_registers[i], it.val.int())
|
||||
}
|
||||
ast.Ident {
|
||||
// `foo(x)` => `mov edi,DWORD PTR [rbp-0x8]`
|
||||
|
|
|
@ -99,6 +99,11 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
|||
cond_pos := p.tok.position()
|
||||
cond := p.expr(0)
|
||||
p.inside_match = false
|
||||
mut var_name := ''
|
||||
if p.tok.kind == .key_as {
|
||||
p.next()
|
||||
var_name = p.check_name()
|
||||
}
|
||||
p.check(.lcbr)
|
||||
mut branches := []ast.MatchBranch{}
|
||||
for {
|
||||
|
@ -114,6 +119,20 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
|||
} else if p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot) &&
|
||||
(p.tok.lit in table.builtin_type_names || (p.tok.lit[0].is_capital() && !p.tok.lit.is_upper()) ||
|
||||
p.peek_tok.kind == .dot) {
|
||||
if var_name.len == 0 {
|
||||
match cond {
|
||||
ast.Ident {
|
||||
// shadow match cond variable
|
||||
var_name = it.name
|
||||
}
|
||||
// ast.SelectorExpr {
|
||||
// p.error('expecting `as` (eg. `match user.attribute as user_attr`) when matching struct fields')
|
||||
// }
|
||||
else {
|
||||
// p.error('only variables can be used in sum types matches')
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sum type match
|
||||
typ := p.parse_type()
|
||||
exprs << ast.Type{
|
||||
|
@ -126,32 +145,23 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
|||
is_used: true
|
||||
is_mut: is_mut
|
||||
})
|
||||
if var_name.len > 0 {
|
||||
// Register shadow variable or `as` variable with actual type
|
||||
p.scope.register(var_name, ast.Var{
|
||||
name: var_name
|
||||
typ: typ.to_ptr()
|
||||
pos: cond_pos
|
||||
is_used: true
|
||||
is_mut: is_mut
|
||||
})
|
||||
}
|
||||
// TODO
|
||||
if p.tok.kind == .comma {
|
||||
p.next()
|
||||
p.parse_type()
|
||||
}
|
||||
is_sum_type = true
|
||||
// Make sure a variable used for the sum type match
|
||||
mut var_name := ''
|
||||
match cond {
|
||||
ast.Ident {
|
||||
var_name = it.name
|
||||
}
|
||||
else {
|
||||
// p.error('only variables can be used in sum types matches')
|
||||
}
|
||||
}
|
||||
if var_name != '' {
|
||||
// Register a shadow variable with the actual type
|
||||
// (this replaces the old `it`)
|
||||
// TODO doesn't work right now (fixed, uncomment when merging)
|
||||
// p.scope.register(var_name, ast.Var{
|
||||
// name: var_name
|
||||
// typ: typ.to_ptr()
|
||||
// })
|
||||
// println(var_name)
|
||||
}
|
||||
|
||||
} else {
|
||||
// Expression match
|
||||
for {
|
||||
|
@ -200,5 +210,6 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
|||
is_sum_type: is_sum_type
|
||||
pos: pos
|
||||
is_mut: is_mut
|
||||
var_name: var_name
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,11 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||
node = p.index_expr(node)
|
||||
p.is_stmt_ident = is_stmt_ident
|
||||
} else if p.tok.kind == .key_as {
|
||||
// sum type match `match x as alias` so return early
|
||||
if p.inside_match {
|
||||
return node
|
||||
}
|
||||
// sum type as cast `x := SumType as Variant`
|
||||
pos := p.tok.position()
|
||||
p.next()
|
||||
typ = p.parse_type()
|
||||
|
|
Loading…
Reference in New Issue