v2: more work on AssignStmt & multi ret & initial blank ident

pull/3862/head
Joe Conigliaro 2020-02-27 21:12:30 +11:00
parent cfbd8ab7e7
commit 237d83b2ee
4 changed files with 46 additions and 7 deletions

View File

@ -388,6 +388,7 @@ pub:
left []Ident
right []Expr
op token.Kind
pos token.Position
}
// e.g. `[unsafe_fn]`

View File

@ -44,6 +44,13 @@ pub fn (s &Scope) find_var(name string) ?VarDecl {
return none
}
pub fn (s &Scope) known_var(name string) bool {
if _ := s.find_var(name) {
return true
}
return false
}
pub fn (s mut Scope) register_var(var VarDecl) {
if x := s.find_var(var.name) {
// println('existing var: $var.name')

View File

@ -283,11 +283,28 @@ pub fn (c mut Checker) return_stmt(return_stmt ast.Return) {
}
}
/*
pub fn (c mut Checker) assign_stmt(assign_stmt ast.AssignStmt) {
// multi return
if assign_stmt.left.len > assign_stmt.right.len {
right := c.expr(assign_stmt.right[0])
right_sym := c.table.get_type_symbol(right)
info := right_sym.mr_info()
if right_sym.kind != .multi_return {
c.error('wrong number of vars', assign_stmt.pos)
}
mut scope := c.file.scope.innermost(assign_stmt.pos.pos) or {
c.file.scope
}
for i, ident in assign_stmt.left {
// TODO: check types
scope.override_var(ast.VarDecl{
name: ident.name
typ: info.types[i]
})
}
}
// TODO: multiple assign
}
*/
pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
mut elem_type := table.void_type
@ -330,12 +347,9 @@ fn (c mut Checker) stmt(node ast.Stmt) {
ast.Return {
c.return_stmt(it)
}
/*
ast.AssignStmt {
c.assign_stmt(it)
}
*/
ast.ConstDecl {
for i, expr in it.exprs {
mut field := it.fields[i]
@ -480,7 +494,6 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
mut found := true
mut var_scope := &ast.Scope(0)
mut var := ast.VarDecl{}
// mut var_scope, mut var := start_scope.find_scope_and_var(ident.name) or {
var_scope,var = start_scope.find_scope_and_var(ident.name) or {
found = false
c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos)

View File

@ -458,6 +458,12 @@ pub fn (p mut Parser) parse_ident(is_c bool) ast.Ident {
// p.warn('name ')
// left := p.parse_ident()
name := p.check_name()
if name == '_' {
return ast.Ident{
kind: .blank_ident
pos: p.tok.position()
}
}
mut ident := ast.Ident{
name: name
is_c: is_c
@ -1519,10 +1525,22 @@ pub fn (p mut Parser) assign_stmt() ast.AssignStmt {
op := p.tok.kind
p.next() // :=, =
expr,_ := p.expr(0)
is_decl := op == .decl_assign
for ident in idents {
if is_decl && ident.kind == .blank_ident {
if p.scope.known_var(ident.name) {
p.error('redefinition of `$ident.name`')
}
p.scope.register_var(ast.VarDecl{
name: ident.name
})
}
}
return ast.AssignStmt{
left: idents
right: [expr]
op: op
pos: p.tok.position()
}
}