From 237d83b2eecc40441ac247c17ec19f4c9ce603f8 Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Thu, 27 Feb 2020 21:12:30 +1100 Subject: [PATCH] v2: more work on AssignStmt & multi ret & initial blank ident --- vlib/v/ast/ast.v | 1 + vlib/v/ast/scope.v | 7 +++++++ vlib/v/checker/checker.v | 27 ++++++++++++++++++++------- vlib/v/parser/parser.v | 18 ++++++++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 6511c4fc8c..1e20f9d8e3 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -388,6 +388,7 @@ pub: left []Ident right []Expr op token.Kind + pos token.Position } // e.g. `[unsafe_fn]` diff --git a/vlib/v/ast/scope.v b/vlib/v/ast/scope.v index 5be3cd1af8..36d1e58844 100644 --- a/vlib/v/ast/scope.v +++ b/vlib/v/ast/scope.v @@ -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') diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 568b806203..771fc8342e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ded6ad3b6f..281e6b1128 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -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() } }