v2: optionals fixes

pull/4123/head
Alexander Medvednikov 2020-03-26 14:58:11 +01:00
parent b288bf2e7c
commit c71d36356b
3 changed files with 21 additions and 8 deletions

View File

@ -20,13 +20,23 @@ pub fn new_scope(parent &Scope, start_pos int) &Scope {
} }
} }
pub fn (s &Scope) find_scope_and_var(name string) ?(&Scope,Var) { pub struct ScopeVar {
pub:
scope &Scope
var Var
}
// pub fn (s &Scope) find_scope_and_var(name string) ?(&Scope,Var) {
pub fn (s &Scope) find_scope_and_var(name string) ?ScopeVar {
if name in s.vars { if name in s.vars {
return s,s.vars[name] // return s,s.vars[name]
return ScopeVar{
s,s.vars[name]}
} }
for sc := s; !isnil(sc.parent); sc = sc.parent { for sc := s; !isnil(sc.parent); sc = sc.parent {
if name in sc.vars { if name in sc.vars {
return sc,sc.vars[name] return ScopeVar{
sc,sc.vars[name]}
} }
} }
return none return none
@ -141,4 +151,3 @@ pub fn (sc &Scope) show(level int) string {
pub fn (sc &Scope) str() string { pub fn (sc &Scope) str() string {
return sc.show(0) return sc.show(0)
} }

View File

@ -327,7 +327,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
// println('CLONE nr args=$method.args.len') // println('CLONE nr args=$method.args.len')
// } // }
for i, arg in method_call_expr.args { for i, arg in method_call_expr.args {
c.expected_type = if method.is_variadic && i >= method.args.len-1 { method.args[method.args.len - 1].typ } else { method.args[i + 1].typ } c.expected_type = if method.is_variadic && i >= method.args.len - 1 { method.args[method.args.len - 1].typ } else { method.args[i + 1].typ }
method_call_expr.args[i].typ = c.expr(arg.expr) method_call_expr.args[i].typ = c.expr(arg.expr)
} }
// TODO: typ optimize.. this node can get processed more than once // TODO: typ optimize.. this node can get processed more than once
@ -820,11 +820,14 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
mut found := true mut found := true
mut var_scope := &ast.Scope(0) mut var_scope := &ast.Scope(0)
mut var := ast.Var{} mut var := ast.Var{}
var_scope,var = start_scope.find_scope_and_var(ident.name) or { // var_scope,var = start_scope.find_scope_and_var(ident.name) or {
mr := start_scope.find_scope_and_var(ident.name) or {
found = false found = false
c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos) c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos)
panic('') panic('')
} }
var_scope = mr.scope
var = mr.var
if found { if found {
// update the variable // update the variable
// we need to do this here instead of var_decl since some // we need to do this here instead of var_decl since some

View File

@ -508,9 +508,9 @@ fn (g mut Gen) expr_with_cast(expr ast.Expr, got_type table.Type, exp_type table
} }
fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
// multi return
// g.write('/*assign_stmt*/') // g.write('/*assign_stmt*/')
if assign_stmt.left.len > assign_stmt.right.len { if assign_stmt.left.len > assign_stmt.right.len {
// multi return
mut return_type := table.void_type mut return_type := table.void_type
match assign_stmt.right[0] { match assign_stmt.right[0] {
ast.CallExpr { ast.CallExpr {
@ -524,6 +524,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
} }
} }
mr_var_name := 'mr_$assign_stmt.pos.pos' mr_var_name := 'mr_$assign_stmt.pos.pos'
g.expr_var_name = mr_var_name
if table.type_is_optional(return_type) { if table.type_is_optional(return_type) {
return_type = table.type_clear_extra(return_type) return_type = table.type_clear_extra(return_type)
mr_styp := g.typ(return_type) mr_styp := g.typ(return_type)
@ -606,11 +607,11 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
g.expr(val) g.expr(val)
} }
} }
g.expr_var_name = ''
} }
g.writeln(';') g.writeln(';')
} }
} }
g.expr_var_name = ''
} }
fn (g mut Gen) gen_fn_decl(it ast.FnDecl) { fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {