diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index 8503f723df..e78a82f470 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -4,24 +4,23 @@ module ast // These methods are used only by vfmt, vdoc, and for debugging. -import ( - v.table - strings -) +import v.table +import strings pub fn (node &FnDecl) str(t &table.Table) string { - mut f := strings.new_builder(30) + var f := strings.new_builder(30) if node.is_pub { f.write('pub ') } - mut receiver := '' + var receiver := '' if node.is_method { - mut styp := t.type_to_str(node.receiver.typ) - mut m := if node.rec_mut { 'mut ' } else { '' } + var styp := t.type_to_str(node.receiver.typ) + var m := if node.rec_mut { 'var ' } else { '' } if node.rec_mut { styp = styp[1..] // remove & } - receiver = '($node.receiver.name $m$styp) ' + // receiver = '($node.receiver.name $m$styp) ' + receiver = '($m$node.receiver.name $styp) ' /* sym := t.get_type_symbol(node.receiver.typ) name := sym.name.after('.') @@ -32,7 +31,7 @@ pub fn (node &FnDecl) str(t &table.Table) string { receiver = '($node.receiver.name $m$name) ' */ } - mut name := node.name.after('.') + var name := node.name.after('.') if node.is_c { name = 'C.$name' } @@ -46,7 +45,7 @@ pub fn (node &FnDecl) str(t &table.Table) string { should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || (node.is_variadic && i == node.args.len - 2) f.write(arg.name) - mut s := t.type_to_str(arg.typ) + var s := t.type_to_str(arg.typ) if arg.is_mut { f.write(' mut') if s.starts_with('&') { @@ -160,7 +159,7 @@ pub fn (a CallArg) str() string { } pub fn args2str(args []CallArg) string { - mut res := []string + var res := []string for a in args { res << a.str() } @@ -170,7 +169,7 @@ pub fn args2str(args []CallArg) string { pub fn (node Stmt) str() string { match node { AssignStmt { - mut out := '' + var out := '' for i, ident in it.left { var_info := ident.var_info() if var_info.is_mut { diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index b40389b787..400e16f170 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -31,7 +31,7 @@ mut: } pub fn fmt(file ast.File, table &table.Table) string { - mut f := Fmt{ + var f := Fmt{ out: strings.new_builder(1000) out_imports: strings.new_builder(200) table: table @@ -67,7 +67,7 @@ fn (f mut Fmt) find_comment(line_nr int) { } } */ -pub fn (f mut Fmt) write(s string) { +pub fn (var f Fmt) write(s string) { if f.indent > 0 && f.empty_line { f.out.write(tabs[f.indent]) f.line_len += f.indent * 4 @@ -77,7 +77,7 @@ pub fn (f mut Fmt) write(s string) { f.empty_line = false } -pub fn (f mut Fmt) writeln(s string) { +pub fn (var f Fmt) writeln(s string) { if f.indent > 0 && f.empty_line { // println(f.indent.str() + s) f.out.write(tabs[f.indent]) @@ -87,7 +87,7 @@ pub fn (f mut Fmt) writeln(s string) { f.line_len = 0 } -fn (f mut Fmt) mod(mod ast.Module) { +fn (var f Fmt) mod(mod ast.Module) { f.cur_mod = mod.name if mod.is_skipped { return @@ -95,7 +95,7 @@ fn (f mut Fmt) mod(mod ast.Module) { f.writeln('module $mod.name\n') } -fn (f mut Fmt) imports(imports []ast.Import) { +fn (var f Fmt) imports(imports []ast.Import) { if f.did_imports || imports.len == 0 { return } @@ -129,7 +129,7 @@ fn (f Fmt) imp_stmt_str(imp ast.Import) string { return '${imp.mod}${imp_alias_suffix}' } -fn (f mut Fmt) stmts(stmts []ast.Stmt) { +fn (var f Fmt) stmts(stmts []ast.Stmt) { f.indent++ for stmt in stmts { f.stmt(stmt) @@ -137,7 +137,7 @@ fn (f mut Fmt) stmts(stmts []ast.Stmt) { f.indent-- } -fn (f mut Fmt) stmt(node ast.Stmt) { +fn (var f Fmt) stmt(node ast.Stmt) { match node { ast.AssignStmt { for i, ident in it.left { @@ -205,7 +205,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) { f.write('pub ') } f.writeln('const (') - mut max := 0 + var max := 0 for field in it.fields { if field.name.len > max { max = field.name.len @@ -379,7 +379,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) { } } -fn (f mut Fmt) type_decl(node ast.TypeDecl) { +fn (var f Fmt) type_decl(node ast.TypeDecl) { match node { ast.AliasTypeDecl { if it.is_pub { @@ -393,7 +393,7 @@ fn (f mut Fmt) type_decl(node ast.TypeDecl) { f.write('pub ') } f.write('type $it.name = ') - mut sum_type_names := []string + var sum_type_names := []string for t in it.sub_types { sum_type_names << f.type_to_str(t) } @@ -406,13 +406,13 @@ fn (f mut Fmt) type_decl(node ast.TypeDecl) { f.writeln('\n') } -fn (f mut Fmt) struct_decl(node ast.StructDecl) { +fn (var f Fmt) struct_decl(node ast.StructDecl) { if node.is_pub { f.write('pub ') } name := node.name.after('.') f.writeln('struct $name {') - mut max := 0 + var max := 0 for field in node.fields { if field.name.len > max { max = field.name.len @@ -457,7 +457,7 @@ fn (f &Fmt) type_to_str(t table.Type) string { return res.replace(f.cur_mod + '.', '') } -fn (f mut Fmt) expr(node ast.Expr) { +fn (var f Fmt) expr(node ast.Expr) { match node { ast.ArrayInit { if it.exprs.len == 0 && it.typ != 0 && it.typ != table.void_type { @@ -685,7 +685,7 @@ fn (f mut Fmt) expr(node ast.Expr) { ast.StructInit { type_sym := f.table.get_type_symbol(it.typ) // f.write('') - mut name := short_module(type_sym.name).replace(f.cur_mod + '.', '') // TODO f.type_to_str? + var name := short_module(type_sym.name).replace(f.cur_mod + '.', '') // TODO f.type_to_str? if name == 'void' { name = '' } @@ -731,7 +731,7 @@ fn (f mut Fmt) expr(node ast.Expr) { } } -fn (f mut Fmt) wrap_long_line() { +fn (var f Fmt) wrap_long_line() { if f.line_len > max_len { if f.out.buf[f.out.buf.len - 1] == ` ` { f.out.go_back(1) @@ -741,7 +741,7 @@ fn (f mut Fmt) wrap_long_line() { } } -fn (f mut Fmt) call_args(args []ast.CallArg) { +fn (var f Fmt) call_args(args []ast.CallArg) { for i, arg in args { if arg.is_mut { f.write('mut ') @@ -756,7 +756,7 @@ fn (f mut Fmt) call_args(args []ast.CallArg) { } } -fn (f mut Fmt) or_expr(or_block ast.OrExpr) { +fn (var f Fmt) or_expr(or_block ast.OrExpr) { if or_block.stmts.len > 0 { f.writeln(' or {') f.stmts(or_block.stmts) @@ -764,10 +764,10 @@ fn (f mut Fmt) or_expr(or_block ast.OrExpr) { } } -fn (f mut Fmt) comment(node ast.Comment) { +fn (var f Fmt) comment(node ast.Comment) { if !node.text.contains('\n') { is_separate_line := node.text.starts_with('|') - mut s := if is_separate_line { node.text[1..] } else { node.text } + var s := if is_separate_line { node.text[1..] } else { node.text } if s == '' { s = '//' } else { @@ -800,7 +800,7 @@ fn short_module(name string) string { return vals[vals.len - 2] + '.' + vals[vals.len - 1] } -fn (f mut Fmt) if_expr(it ast.IfExpr) { +fn (var f Fmt) if_expr(it ast.IfExpr) { single_line := it.branches.len == 2 && it.has_else && it.branches[0].stmts.len == 1 && it.branches[1].stmts.len == 1 && (it.is_expr || f.is_assign) f.single_line_if = single_line @@ -833,7 +833,7 @@ fn (f mut Fmt) if_expr(it ast.IfExpr) { f.single_line_if = false } -fn (f mut Fmt) call_expr(node ast.CallExpr) { +fn (var f Fmt) call_expr(node ast.CallExpr) { if node.is_method { match node.left { ast.Ident { @@ -870,13 +870,13 @@ fn (f mut Fmt) call_expr(node ast.CallExpr) { } } -fn (f mut Fmt) mark_types_module_as_used(typ table.Type) { +fn (var f Fmt) mark_types_module_as_used(typ table.Type) { sym := f.table.get_type_symbol(typ) f.mark_module_as_used(sym.name) } // `name` is a function (`foo.bar()`) or type (`foo.Bar{}`) -fn (f mut Fmt) mark_module_as_used(name string) { +fn (var f Fmt) mark_module_as_used(name string) { if !name.contains('.') { return } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index b2a0abc397..39528bb129 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -134,7 +134,7 @@ pub fn (g Gen) hashes() string { return res } -pub fn (g mut Gen) init() { +pub fn (var g Gen) init() { g.definitions.writeln('// Generated by the V compiler') g.definitions.writeln('#include ') // int64_t etc g.definitions.writeln(c_builtin_types) @@ -159,7 +159,7 @@ pub fn (g mut Gen) init() { } } -pub fn (g mut Gen) finish() { +pub fn (var g Gen) finish() { if g.pref.build_mode != .build_module { g.stringliterals.writeln('}') } @@ -167,7 +167,7 @@ pub fn (g mut Gen) finish() { g.stringliterals.writeln('') } -pub fn (g mut Gen) write_typeof_functions() { +pub fn (var g Gen) write_typeof_functions() { g.writeln('') g.writeln('// >> typeof() support for sum types') for typ in g.table.types { @@ -191,7 +191,7 @@ pub fn (g mut Gen) write_typeof_functions() { } // V type to C type -pub fn (g mut Gen) typ(t table.Type) string { +pub fn (var g Gen) typ(t table.Type) string { nr_muls := table.type_nr_muls(t) sym := g.table.get_type_symbol(t) var styp := sym.name.replace('.', '__') @@ -224,7 +224,7 @@ pub fn (g mut Gen) typ(t table.Type) string { } // -pub fn (g mut Gen) write_typedef_types() { +pub fn (var g Gen) write_typedef_types() { for typ in g.table.types { match typ.kind { .alias { @@ -263,7 +263,7 @@ pub fn (g mut Gen) write_typedef_types() { } } -pub fn (g mut Gen) write_multi_return_types() { +pub fn (var g Gen) write_multi_return_types() { g.definitions.writeln('// multi return structs') for typ in g.table.types { // sym := g.table.get_type_symbol(typ) @@ -284,7 +284,7 @@ pub fn (g mut Gen) write_multi_return_types() { } } -pub fn (g mut Gen) write_variadic_types() { +pub fn (var g Gen) write_variadic_types() { if g.variadic_args.size > 0 { g.definitions.writeln('// variadic structs') } @@ -303,7 +303,7 @@ pub fn (g mut Gen) write_variadic_types() { pub fn (g Gen) save() { } -pub fn (g mut Gen) write(s string) { +pub fn (var g Gen) write(s string) { if g.indent > 0 && g.empty_line { g.out.write(tabs[g.indent]) // g.line_len += g.indent * 4 @@ -312,7 +312,7 @@ pub fn (g mut Gen) write(s string) { g.empty_line = false } -pub fn (g mut Gen) writeln(s string) { +pub fn (var g Gen) writeln(s string) { if g.indent > 0 && g.empty_line { g.out.write(tabs[g.indent]) } @@ -320,16 +320,16 @@ pub fn (g mut Gen) writeln(s string) { g.empty_line = true } -pub fn (g mut Gen) new_tmp_var() string { +pub fn (var g Gen) new_tmp_var() string { g.tmp_count++ return 'tmp$g.tmp_count' } -pub fn (g mut Gen) reset_tmp_count() { +pub fn (var g Gen) reset_tmp_count() { g.tmp_count = 0 } -fn (g mut Gen) stmts(stmts []ast.Stmt) { +fn (var g Gen) stmts(stmts []ast.Stmt) { g.indent++ if g.inside_ternary { g.write(' ( ') @@ -346,7 +346,7 @@ fn (g mut Gen) stmts(stmts []ast.Stmt) { g.indent-- } -fn (g mut Gen) stmt(node ast.Stmt) { +fn (var g Gen) stmt(node ast.Stmt) { g.stmt_start_pos = g.out.len // println('cgen.stmt()') // g.writeln('//// stmt start') @@ -522,7 +522,7 @@ fn (g mut Gen) stmt(node ast.Stmt) { } } -fn (g mut Gen) write_defer_stmts() { +fn (var g Gen) write_defer_stmts() { for defer_stmt in g.defer_stmts { g.writeln('// defer') if defer_stmt.ifdef.len > 0 { @@ -536,7 +536,7 @@ fn (g mut Gen) write_defer_stmts() { } } -fn (g mut Gen) for_in(it ast.ForInStmt) { +fn (var g Gen) for_in(it ast.ForInStmt) { if it.is_range { // `for x in 1..10 {` i := g.new_tmp_var() @@ -616,7 +616,7 @@ fn (g mut Gen) for_in(it ast.ForInStmt) { } // use instead of expr() when you need to cast to sum type (can add other casts also) -fn (g mut Gen) expr_with_cast(expr ast.Expr, got_type, exp_type table.Type) { +fn (var g Gen) expr_with_cast(expr ast.Expr, got_type, exp_type table.Type) { // cast to sum type if exp_type != table.void_type { exp_sym := g.table.get_type_symbol(exp_type) @@ -638,7 +638,7 @@ fn (g mut Gen) expr_with_cast(expr ast.Expr, got_type, exp_type table.Type) { g.expr(expr) } -fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) { +fn (var g Gen) gen_assert_stmt(a ast.AssertStmt) { g.writeln('// assert') g.inside_ternary = true g.write('if (') @@ -669,7 +669,7 @@ fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) { g.writeln('}') } -fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { +fn (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { // g.write('/*assign_stmt*/') if assign_stmt.is_static { g.write('static ') @@ -782,7 +782,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { } } -fn (g mut Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, add_eq bool) bool { +fn (var g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, add_eq bool) bool { var is_ident := false match val { ast.Ident { @@ -815,7 +815,7 @@ fn (g mut Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, ad return true } -fn (g mut Gen) free_scope_vars(pos int) { +fn (var g Gen) free_scope_vars(pos int) { scope := g.file.scope.innermost(pos) for _, obj in scope.objects { match obj { @@ -856,7 +856,7 @@ fn (g mut Gen) free_scope_vars(pos int) { } } -fn (g mut Gen) expr(node ast.Expr) { +fn (var g Gen) expr(node ast.Expr) { // println('cgen expr() line_nr=$node.pos.line_nr') match node { ast.ArrayInit { @@ -1083,7 +1083,7 @@ fn (g mut Gen) expr(node ast.Expr) { } } -fn (g mut Gen) typeof_expr(node ast.TypeOf) { +fn (var g Gen) typeof_expr(node ast.TypeOf) { sym := g.table.get_type_symbol(node.expr_type) if sym.kind == .sum_type { // When encountering a .sum_type, typeof() should be done at runtime, @@ -1101,7 +1101,7 @@ fn (g mut Gen) typeof_expr(node ast.TypeOf) { } } -fn (g mut Gen) enum_expr(node ast.Expr) { +fn (var g Gen) enum_expr(node ast.Expr) { match node { ast.EnumVal { g.write(it.val) @@ -1112,7 +1112,7 @@ fn (g mut Gen) enum_expr(node ast.Expr) { } } -fn (g mut Gen) assign_expr(node ast.AssignExpr) { +fn (var g Gen) assign_expr(node ast.AssignExpr) { // g.write('/*assign_expr*/') var is_call := false var or_stmts := []ast.Stmt @@ -1188,7 +1188,7 @@ fn (g mut Gen) assign_expr(node ast.AssignExpr) { g.is_assign_rhs = false } -fn (g mut Gen) infix_expr(node ast.InfixExpr) { +fn (var g Gen) infix_expr(node ast.InfixExpr) { // println('infix_expr() op="$node.op.str()" line_nr=$node.pos.line_nr') // g.write('/*infix*/') // if it.left_type == table.string_type_idx { @@ -1350,7 +1350,7 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) { } } -fn (g mut Gen) match_expr(node ast.MatchExpr) { +fn (var g Gen) match_expr(node ast.MatchExpr) { // println('match expr typ=$it.expr_type') // TODO if node.cond_type == 0 { @@ -1454,7 +1454,7 @@ fn (g mut Gen) match_expr(node ast.MatchExpr) { g.inside_ternary = was_inside_ternary } -fn (g mut Gen) ident(node ast.Ident) { +fn (var g Gen) ident(node ast.Ident) { if node.name == 'lld' { return } @@ -1486,7 +1486,7 @@ fn (g mut Gen) ident(node ast.Ident) { g.write(name) } -fn (g mut Gen) if_expr(node ast.IfExpr) { +fn (var g Gen) if_expr(node ast.IfExpr) { // println('if_expr pos=$node.pos.line_nr') // g.writeln('/* if is_expr=$node.is_expr */') // If expression? Assign the value to a temp var. @@ -1558,7 +1558,7 @@ fn (g mut Gen) if_expr(node ast.IfExpr) { } } -fn (g mut Gen) index_expr(node ast.IndexExpr) { +fn (var g Gen) index_expr(node ast.IndexExpr) { // TODO else doesn't work with sum types var is_range := false match node.index { @@ -1750,7 +1750,7 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) { } } -fn (g mut Gen) return_statement(node ast.Return) { +fn (var g Gen) return_statement(node ast.Return) { g.write('return') if g.fn_decl.name == 'main' { g.writeln(' 0;') @@ -1828,7 +1828,7 @@ fn (g mut Gen) return_statement(node ast.Return) { g.writeln(';') } -fn (g mut Gen) const_decl(node ast.ConstDecl) { +fn (var g Gen) const_decl(node ast.ConstDecl) { for i, field in node.fields { name := c_name(field.name) // TODO hack. Cut the generated value and paste it into definitions. @@ -1860,7 +1860,7 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) { } } -fn (g mut Gen) const_decl_simple_define(name, val string) { +fn (var g Gen) const_decl_simple_define(name, val string) { // Simple expressions should use a #define // so that we don't pollute the binary with unnecessary global vars // Do not do this when building a module, otherwise the consts @@ -1869,7 +1869,7 @@ fn (g mut Gen) const_decl_simple_define(name, val string) { g.definitions.writeln(val) } -fn (g mut Gen) struct_init(struct_init ast.StructInit) { +fn (var g Gen) struct_init(struct_init ast.StructInit) { var info := table.Struct{} var is_struct := false sym := g.table.get_type_symbol(struct_init.typ) @@ -1935,7 +1935,7 @@ fn (g mut Gen) struct_init(struct_init ast.StructInit) { } // { user | name: 'new name' } -fn (g mut Gen) assoc(node ast.Assoc) { +fn (var g Gen) assoc(node ast.Assoc) { g.writeln('// assoc') if node.typ == 0 { return @@ -1964,7 +1964,7 @@ fn (g mut Gen) assoc(node ast.Assoc) { } } -fn (g mut Gen) generate_array_equality_fn(ptr_typ string, styp table.Type, sym &table.TypeSymbol) { +fn (var g Gen) generate_array_equality_fn(ptr_typ string, styp table.Type, sym &table.TypeSymbol) { g.array_fn_definitions << ptr_typ g.definitions.writeln('bool ${ptr_typ}_arr_eq(array_${ptr_typ} a, array_${ptr_typ} b) {') g.definitions.writeln('\tif (a.len != b.len) {') @@ -1989,7 +1989,7 @@ fn verror(s string) { util.verror('cgen error', s) } -fn (g mut Gen) write_init_function() { +fn (var g Gen) write_init_function() { g.writeln('void _vinit() {') g.writeln('\tbuiltin_init();') g.writeln('\tvinit_string_literals();') @@ -2015,7 +2015,7 @@ fn (g mut Gen) write_init_function() { } } -fn (g mut Gen) write_str_fn_definitions() { +fn (var g Gen) write_str_fn_definitions() { // _STR function can't be defined in vlib g.writeln(' string _STR(const char *fmt, ...) { @@ -2056,7 +2056,7 @@ const ( builtins = ['string', 'array', 'KeyValue', 'DenseArray', 'map', 'Option'] ) -fn (g mut Gen) write_builtin_types() { +fn (var g Gen) write_builtin_types() { var builtin_types := []table.TypeSymbol // builtin types // builtin types need to be on top // everything except builtin will get sorted @@ -2069,7 +2069,7 @@ fn (g mut Gen) write_builtin_types() { // C struct definitions, ordered // Sort the types, make sure types that are referenced by other types // are added before them. -fn (g mut Gen) write_sorted_types() { +fn (var g Gen) write_sorted_types() { var types := []table.TypeSymbol // structs that need to be sorted for typ in g.table.types { if !(typ.name in builtins) { @@ -2084,7 +2084,7 @@ fn (g mut Gen) write_sorted_types() { g.write_types(types_sorted) } -fn (g mut Gen) write_types(types []table.TypeSymbol) { +fn (var g Gen) write_types(types []table.TypeSymbol) { for typ in types { if typ.name.starts_with('C.') { continue @@ -2190,7 +2190,7 @@ fn (g Gen) sort_structs(typesa []table.TypeSymbol) []table.TypeSymbol { return types_sorted } -fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) { +fn (var g Gen) string_inter_literal(node ast.StringInterLiteral) { g.write('_STR("') // Build the string with % for i, val in node.vals { @@ -2305,7 +2305,7 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) { } // `nums.filter(it % 2 == 0)` -fn (g mut Gen) gen_filter(node ast.CallExpr) { +fn (var g Gen) gen_filter(node ast.CallExpr) { tmp := g.new_tmp_var() s := g.out.after(g.stmt_start_pos) // the already generated part of current statement g.out.go_back(s.len) @@ -2333,7 +2333,7 @@ fn (g mut Gen) gen_filter(node ast.CallExpr) { g.write(tmp) } -fn (g mut Gen) insert_before(s string) { +fn (var g Gen) insert_before(s string) { cur_line := g.out.after(g.stmt_start_pos) g.out.go_back(cur_line.len) g.writeln(s) @@ -2344,7 +2344,7 @@ fn (g mut Gen) insert_before(s string) { // If the user is not using the optional return value. We need to pass a temp var // to access its fields (`.ok`, `.error` etc) // `os.cp(...)` => `Option bool tmp = os__cp(...); if (!tmp.ok) { ... }` -fn (g mut Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Type) { +fn (var g Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Type) { mr_styp := g.typ(return_type) mr_styp2 := mr_styp[7..] // remove Option_ g.writeln(';') // or') @@ -2367,7 +2367,7 @@ fn (g mut Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Typ g.write('}') } -fn (g mut Gen) type_of_last_statement(stmts []ast.Stmt) (string, string) { +fn (var g Gen) type_of_last_statement(stmts []ast.Stmt) (string, string) { var last_type := '' var last_expr_result_type := '' if stmts.len > 0 { @@ -2395,7 +2395,7 @@ fn (g mut Gen) type_of_last_statement(stmts []ast.Stmt) (string, string) { return last_type, last_expr_result_type } -fn (g mut Gen) type_of_call_expr(node ast.Expr) string { +fn (var g Gen) type_of_call_expr(node ast.Expr) string { match node { ast.CallExpr { return g.typ(it.return_type) @@ -2408,7 +2408,7 @@ fn (g mut Gen) type_of_call_expr(node ast.Expr) string { } // `a in [1,2,3]` => `a == 1 || a == 2 || a == 3` -fn (g mut Gen) in_optimization(left ast.Expr, right ast.ArrayInit) { +fn (var g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) { is_str := right.elem_type == table.string_type for i, array_expr in right.exprs { if is_str { @@ -2625,7 +2625,7 @@ fn (g Gen) type_default(typ table.Type) string { */ } -pub fn (g mut Gen) write_tests_main() { +pub fn (var g Gen) write_tests_main() { g.definitions.writeln('int g_test_oks = 0;') g.definitions.writeln('int g_test_fails = 0;') $if windows { @@ -2712,7 +2712,7 @@ fn (g Gen) is_importing_os() bool { return 'os' in g.table.imports } -fn (g mut Gen) comp_if(it ast.CompIf) { +fn (var g Gen) comp_if(it ast.CompIf) { ifdef := comp_if_to_ifdef(it.val) if it.is_not { g.writeln('\n#ifndef ' + ifdef) @@ -2744,7 +2744,7 @@ fn (g mut Gen) comp_if(it ast.CompIf) { g.writeln('\n#endif') } -fn (g mut Gen) go_stmt(node ast.GoStmt) { +fn (var g Gen) go_stmt(node ast.GoStmt) { tmp := g.new_tmp_var() // x := node.call_expr as ast.CallEpxr // TODO match node.call_expr { @@ -2815,7 +2815,7 @@ fn (g mut Gen) go_stmt(node ast.GoStmt) { } // already generated styp, reuse it -fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) { +fn (var g Gen) gen_str_for_type(sym table.TypeSymbol, styp string) { if sym.has_method('str') || styp in g.str_types { return } @@ -2836,7 +2836,7 @@ fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) { } } -fn (g mut Gen) gen_str_default(sym table.TypeSymbol, styp string) { +fn (var g Gen) gen_str_default(sym table.TypeSymbol, styp string) { var convertor := '' var typename := '' if sym.parent_idx in table.integer_type_idxs { @@ -2866,7 +2866,7 @@ fn (g mut Gen) gen_str_default(sym table.TypeSymbol, styp string) { g.definitions.writeln('}') } -fn (g mut Gen) gen_str_for_enum(info table.Enum, styp string) { +fn (var g Gen) gen_str_for_enum(info table.Enum, styp string) { s := styp.replace('.', '__') g.definitions.write('string ${s}_str($styp it) {\n\tswitch(it) {\n') for i, val in info.vals { @@ -2875,7 +2875,7 @@ fn (g mut Gen) gen_str_for_enum(info table.Enum, styp string) { g.definitions.write('\t\tdefault: return tos3("unknown enum value"); } }\n') } -fn (g mut Gen) gen_str_for_struct(info table.Struct, styp string) { +fn (var g Gen) gen_str_for_struct(info table.Struct, styp string) { // TODO: short it if possible // generates all definitions of substructs for i, field in info.fields { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index a59627072e..acb3e21b6d 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -8,7 +8,7 @@ import v.table import v.scanner import v.token -pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr { +pub fn (var p Parser) call_expr(is_c bool, mod string) ast.CallExpr { first_pos := p.tok.position() tok := p.tok name := p.check_name() @@ -59,7 +59,7 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr { return node } -pub fn (p mut Parser) call_args() []ast.CallArg { +pub fn (var p Parser) call_args() []ast.CallArg { var args := []ast.CallArg for p.tok.kind != .rpar { var is_mut := false @@ -79,7 +79,7 @@ pub fn (p mut Parser) call_args() []ast.CallArg { return args } -fn (p mut Parser) fn_decl() ast.FnDecl { +fn (var p Parser) fn_decl() ast.FnDecl { // p.table.clear_vars() pos := p.tok.position() p.open_scope() @@ -118,7 +118,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { // } // TODO: talk to alex, should mut be parsed with the type like this? // or should it be a property of the arg, like this ptr/mut becomes indistinguishable - rec_type = p.parse_type() + rec_type = p.parse_type_with_mut(rec_mut) if is_amp && rec_mut { p.error('use `(f mut Foo)` or `(f &Foo)` instead of `(f mut &Foo)`') } @@ -224,7 +224,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { } } -fn (p mut Parser) fn_args() ([]table.Arg, bool) { +fn (var p Parser) fn_args() ([]table.Arg, bool) { p.check(.lpar) var args := []table.Arg var is_variadic := false diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 346cde8891..940c48b36e 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -1,12 +1,11 @@ module parser + // Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. -import ( - v.table -) +import v.table -pub fn (p mut Parser) parse_array_type() table.Type { +pub fn (var p Parser) parse_array_type() table.Type { p.check(.lsbr) // fixed array if p.tok.kind == .number { @@ -20,7 +19,7 @@ pub fn (p mut Parser) parse_array_type() table.Type { // array p.check(.rsbr) elem_type := p.parse_type() - mut nr_dims := 1 + var nr_dims := 1 for p.tok.kind == .lsbr { p.check(.lsbr) p.check(.rsbr) @@ -30,7 +29,7 @@ pub fn (p mut Parser) parse_array_type() table.Type { return table.new_type(idx) } -pub fn (p mut Parser) parse_map_type() table.Type { +pub fn (var p Parser) parse_map_type() table.Type { p.next() if p.tok.kind != .lsbr { return table.map_type @@ -48,16 +47,15 @@ pub fn (p mut Parser) parse_map_type() table.Type { return table.new_type(idx) } -pub fn (p mut Parser) parse_multi_return_type() table.Type { +pub fn (var p Parser) parse_multi_return_type() table.Type { p.check(.lpar) - mut mr_types := []table.Type + var mr_types := []table.Type for { mr_type := p.parse_type() mr_types << mr_type if p.tok.kind == .comma { p.check(.comma) - } - else { + } else { break } } @@ -67,12 +65,12 @@ pub fn (p mut Parser) parse_multi_return_type() table.Type { } // given anon name based off signature when `name` is blank -pub fn (p mut Parser) parse_fn_type(name string) table.Type { +pub fn (var p Parser) parse_fn_type(name string) table.Type { // p.warn('parse fn') p.check(.key_fn) line_nr := p.tok.line_nr - args,is_variadic := p.fn_args() - mut return_type := table.void_type + args, is_variadic := p.fn_args() + var return_type := table.void_type if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() { return_type = p.parse_type() } @@ -86,14 +84,22 @@ pub fn (p mut Parser) parse_fn_type(name string) table.Type { return table.new_type(idx) } -pub fn (p mut Parser) parse_type() table.Type { +pub fn (var p Parser) parse_type_with_mut(is_mut bool) table.Type { + typ := p.parse_type() + if is_mut { + return table.type_set_nr_muls(typ, 1) + } + return typ +} + +pub fn (var p Parser) parse_type() table.Type { // optional - mut is_optional := false + var is_optional := false if p.tok.kind == .question { p.next() is_optional = true } - mut nr_muls := 0 + var nr_muls := 0 if p.tok.kind == .key_mut { nr_muls++ p.next() @@ -102,8 +108,7 @@ pub fn (p mut Parser) parse_type() table.Type { for p.tok.kind in [.and, .amp] { if p.tok.kind == .and { nr_muls += 2 - } - else { + } else { nr_muls++ } p.next() @@ -113,7 +118,7 @@ pub fn (p mut Parser) parse_type() table.Type { p.next() p.check(.dot) } - mut typ := p.parse_any_type(is_c, nr_muls > 0) + var typ := p.parse_any_type(is_c, nr_muls > 0) if is_optional { typ = table.type_set(typ, .optional) } @@ -123,13 +128,12 @@ pub fn (p mut Parser) parse_type() table.Type { return typ } -pub fn (p mut Parser) parse_any_type(is_c, is_ptr bool) table.Type { - mut name := p.tok.lit +pub fn (var p Parser) parse_any_type(is_c, is_ptr bool) table.Type { + var name := p.tok.lit if is_c { name = 'C.$name' - } - // `module.Type` - else if p.peek_tok.kind == .dot { + } else if p.peek_tok.kind == .dot { + // `module.Type` // /if !(p.tok.lit in p.table.imports) { if !p.known_import(name) { println(p.table.imports) @@ -139,12 +143,10 @@ pub fn (p mut Parser) parse_any_type(is_c, is_ptr bool) table.Type { p.check(.dot) // prefix with full module name = '${p.imports[name]}.$p.tok.lit' - } - else if p.expr_mod != '' { + } else if p.expr_mod != '' { name = p.expr_mod + '.' + name - } - // `Foo` in module `mod` means `mod.Foo` - else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) { + } else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) { + // `Foo` in module `mod` means `mod.Foo` name = p.mod + '.' + name } // p.warn('get type $name') @@ -224,7 +226,7 @@ pub fn (p mut Parser) parse_any_type(is_c, is_ptr bool) table.Type { // struct / enum / placeholder else { // struct / enum - mut idx := p.table.find_type_idx(name) + var idx := p.table.find_type_idx(name) if idx > 0 { return table.new_type(idx) } @@ -233,7 +235,7 @@ pub fn (p mut Parser) parse_any_type(is_c, is_ptr bool) table.Type { // println('NOT FOUND: $name - adding placeholder - $idx') return table.new_type(idx) } - } + } } } } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 378dcc8eb1..9bb5886e85 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -174,26 +174,26 @@ pub fn (p &Parser) init_parse_fns() { println('') } -pub fn (p mut Parser) read_first_token() { +pub fn (var p Parser) read_first_token() { // need to call next() twice to get peek token and current token p.next() p.next() } -pub fn (p mut Parser) open_scope() { +pub fn (var p Parser) open_scope() { p.scope = &ast.Scope{ parent: p.scope start_pos: p.tok.pos } } -pub fn (p mut Parser) close_scope() { +pub fn (var p Parser) close_scope() { p.scope.end_pos = p.tok.pos p.scope.parent.children << p.scope p.scope = p.scope.parent } -pub fn (p mut Parser) parse_block() []ast.Stmt { +pub fn (var p Parser) parse_block() []ast.Stmt { p.open_scope() // println('parse block') stmts := p.parse_block_no_scope() @@ -202,7 +202,7 @@ pub fn (p mut Parser) parse_block() []ast.Stmt { return stmts } -pub fn (p mut Parser) parse_block_no_scope() []ast.Stmt { +pub fn (var p Parser) parse_block_no_scope() []ast.Stmt { p.check(.lcbr) var stmts := []ast.Stmt if p.tok.kind != .rcbr { @@ -224,7 +224,7 @@ fn (p mut Parser) next_with_comment() { p.peek_tok = p.scanner.scan() } */ -fn (p mut Parser) next() { +fn (var p Parser) next() { p.tok = p.peek_tok p.peek_tok = p.scanner.scan() /* @@ -235,7 +235,7 @@ fn (p mut Parser) next() { */ } -fn (p mut Parser) check(expected token.Kind) { +fn (var p Parser) check(expected token.Kind) { // for p.tok.kind in [.line_comment, .mline_comment] { // p.next() // } @@ -246,13 +246,13 @@ fn (p mut Parser) check(expected token.Kind) { p.next() } -fn (p mut Parser) check_name() string { +fn (var p Parser) check_name() string { name := p.tok.lit p.check(.name) return name } -pub fn (p mut Parser) top_stmt() ast.Stmt { +pub fn (var p Parser) top_stmt() ast.Stmt { match p.tok.kind { .key_pub { match p.peek_tok.kind { @@ -335,14 +335,14 @@ pub fn (p mut Parser) top_stmt() ast.Stmt { } // TODO [if vfmt] -pub fn (p mut Parser) check_comment() ast.Comment { +pub fn (var p Parser) check_comment() ast.Comment { if p.tok.kind == .comment { return p.comment() } return ast.Comment{} } -pub fn (p mut Parser) comment() ast.Comment { +pub fn (var p Parser) comment() ast.Comment { pos := p.tok.position() text := p.tok.lit p.next() @@ -353,7 +353,7 @@ pub fn (p mut Parser) comment() ast.Comment { } } -pub fn (p mut Parser) stmt() ast.Stmt { +pub fn (var p Parser) stmt() ast.Stmt { p.is_stmt_ident = p.tok.kind == .name match p.tok.kind { .lcbr { @@ -456,7 +456,7 @@ pub fn (p mut Parser) stmt() ast.Stmt { } // TODO: is it possible to merge with AssignStmt? -pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr { +pub fn (var p Parser) assign_expr(left ast.Expr) ast.AssignExpr { op := p.tok.kind p.next() pos := p.tok.position() @@ -477,7 +477,7 @@ pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr { return node } -fn (p mut Parser) attribute() ast.Attr { +fn (var p Parser) attribute() ast.Attr { p.check(.lsbr) if p.tok.kind == .key_if { p.next() @@ -544,7 +544,7 @@ pub fn (p &Parser) warn_with_pos(s string, pos token.Position) { eprintln(ferror) } -pub fn (p mut Parser) parse_ident(is_c bool) ast.Ident { +pub fn (var p Parser) parse_ident(is_c bool) ast.Ident { // p.warn('name ') pos := p.tok.position() var name := p.check_name() @@ -568,7 +568,7 @@ pub fn (p mut Parser) parse_ident(is_c bool) ast.Ident { return ident } -fn (p mut Parser) struct_init(short_syntax bool) ast.StructInit { +fn (var p Parser) struct_init(short_syntax bool) ast.StructInit { typ := if short_syntax { table.void_type } else { p.parse_type() } p.expr_mod = '' // sym := p.table.get_type_symbol(typ) @@ -614,7 +614,7 @@ fn (p mut Parser) struct_init(short_syntax bool) ast.StructInit { return node } -pub fn (p mut Parser) name_expr() ast.Expr { +pub fn (var p Parser) name_expr() ast.Expr { var node := ast.Expr{} is_c := p.tok.lit == 'C' var mod := '' @@ -723,7 +723,7 @@ pub fn (p mut Parser) name_expr() ast.Expr { return node } -pub fn (p mut Parser) expr(precedence int) ast.Expr { +pub fn (var p Parser) expr(precedence int) ast.Expr { // println('\n\nparser.expr()') var typ := table.void_type var node := ast.Expr{} @@ -889,7 +889,7 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr { return node } -fn (p mut Parser) prefix_expr() ast.PrefixExpr { +fn (var p Parser) prefix_expr() ast.PrefixExpr { pos := p.tok.position() op := p.tok.kind if op == .amp { @@ -905,7 +905,7 @@ fn (p mut Parser) prefix_expr() ast.PrefixExpr { } } -fn (p mut Parser) index_expr(left ast.Expr) ast.IndexExpr { +fn (var p Parser) index_expr(left ast.Expr) ast.IndexExpr { // left == `a` in `a[0]` p.next() // [ var has_low := true @@ -956,13 +956,13 @@ fn (p mut Parser) index_expr(left ast.Expr) ast.IndexExpr { } } -fn (p mut Parser) filter() { +fn (var p Parser) filter() { p.scope.register('it', ast.Var{ name: 'it' }) } -fn (p mut Parser) dot_expr(left ast.Expr) ast.Expr { +fn (var p Parser) dot_expr(left ast.Expr) ast.Expr { p.next() var name_pos := p.tok.position() field_name := p.check_name() @@ -1035,7 +1035,7 @@ fn (p mut Parser) dot_expr(left ast.Expr) ast.Expr { return node } -fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr { +fn (var p Parser) infix_expr(left ast.Expr) ast.Expr { op := p.tok.kind // mut typ := p. // println('infix op=$op.str()') @@ -1056,7 +1056,7 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr { // `.green` // `pref.BuildMode.default_mode` -fn (p mut Parser) enum_val() ast.EnumVal { +fn (var p Parser) enum_val() ast.EnumVal { p.check(.dot) val := p.check_name() return ast.EnumVal{ @@ -1065,7 +1065,7 @@ fn (p mut Parser) enum_val() ast.EnumVal { } } -fn (p mut Parser) for_stmt() ast.Stmt { +fn (var p Parser) for_stmt() ast.Stmt { p.check(.key_for) pos := p.tok.position() p.open_scope() @@ -1185,7 +1185,7 @@ fn (p mut Parser) for_stmt() ast.Stmt { } } -fn (p mut Parser) if_expr() ast.IfExpr { +fn (var p Parser) if_expr() ast.IfExpr { pos := p.tok.position() var branches := []ast.IfBranch var has_else := false @@ -1256,7 +1256,7 @@ fn (p mut Parser) if_expr() ast.IfExpr { } } -fn (p mut Parser) string_expr() ast.Expr { +fn (var p Parser) string_expr() ast.Expr { is_raw := p.tok.kind == .name && p.tok.lit == 'r' is_cstr := p.tok.kind == .name && p.tok.lit == 'c' if is_raw || is_cstr { @@ -1317,7 +1317,7 @@ fn (p mut Parser) string_expr() ast.Expr { return node } -fn (p mut Parser) array_init() ast.ArrayInit { +fn (var p Parser) array_init() ast.ArrayInit { first_pos := p.tok.position() var last_pos := token.Position{} p.check(.lsbr) @@ -1402,7 +1402,7 @@ fn (p mut Parser) array_init() ast.ArrayInit { } } -fn (p mut Parser) map_init() ast.MapInit { +fn (var p Parser) map_init() ast.MapInit { pos := p.tok.position() var keys := []ast.Expr var vals := []ast.Expr @@ -1424,7 +1424,7 @@ fn (p mut Parser) map_init() ast.MapInit { } } -fn (p mut Parser) parse_number_literal() ast.Expr { +fn (var p Parser) parse_number_literal() ast.Expr { lit := p.tok.lit pos := p.tok.position() var node := ast.Expr{} @@ -1442,7 +1442,7 @@ fn (p mut Parser) parse_number_literal() ast.Expr { return node } -fn (p mut Parser) module_decl() ast.Module { +fn (var p Parser) module_decl() ast.Module { var name := 'main' is_skipped := p.tok.kind != .key_module if !is_skipped { @@ -1458,7 +1458,7 @@ fn (p mut Parser) module_decl() ast.Module { } } -fn (p mut Parser) parse_import() ast.Import { +fn (var p Parser) parse_import() ast.Import { pos := p.tok.position() var mod_name := p.check_name() var mod_alias := mod_name @@ -1481,7 +1481,7 @@ fn (p mut Parser) parse_import() ast.Import { } } -fn (p mut Parser) import_stmt() []ast.Import { +fn (var p Parser) import_stmt() []ast.Import { p.check(.key_import) var imports := []ast.Import if p.tok.kind == .lpar { @@ -1500,7 +1500,7 @@ fn (p mut Parser) import_stmt() []ast.Import { return imports } -fn (p mut Parser) const_decl() ast.ConstDecl { +fn (var p Parser) const_decl() ast.ConstDecl { is_pub := p.tok.kind == .key_pub if is_pub { p.next() @@ -1535,7 +1535,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl { } // structs and unions -fn (p mut Parser) struct_decl() ast.StructDecl { +fn (var p Parser) struct_decl() ast.StructDecl { is_pub := p.tok.kind == .key_pub if is_pub { p.next() @@ -1679,7 +1679,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl { } } -fn (p mut Parser) interface_decl() ast.InterfaceDecl { +fn (var p Parser) interface_decl() ast.InterfaceDecl { is_pub := p.tok.kind == .key_pub if is_pub { p.next() @@ -1704,7 +1704,7 @@ fn (p mut Parser) interface_decl() ast.InterfaceDecl { } } -fn (p mut Parser) return_stmt() ast.Return { +fn (var p Parser) return_stmt() ast.Return { p.next() // return expressions var exprs := []ast.Expr @@ -1730,7 +1730,7 @@ fn (p mut Parser) return_stmt() ast.Return { } // left hand side of `=` or `:=` in `a,b,c := 1,2,3` -fn (p mut Parser) parse_assign_lhs() []ast.Ident { +fn (var p Parser) parse_assign_lhs() []ast.Ident { var idents := []ast.Ident for { is_mut := p.tok.kind == .key_mut || p.tok.kind == .key_var @@ -1758,7 +1758,7 @@ fn (p mut Parser) parse_assign_lhs() []ast.Ident { } // right hand side of `=` or `:=` in `a,b,c := 1,2,3` -fn (p mut Parser) parse_assign_rhs() []ast.Expr { +fn (var p Parser) parse_assign_rhs() []ast.Expr { var exprs := []ast.Expr for { expr := p.expr(0) @@ -1772,7 +1772,7 @@ fn (p mut Parser) parse_assign_rhs() []ast.Expr { return exprs } -fn (p mut Parser) assign_stmt() ast.Stmt { +fn (var p Parser) assign_stmt() ast.Stmt { is_static := p.tok.kind == .key_static if is_static { p.next() @@ -1822,7 +1822,7 @@ fn (p mut Parser) assign_stmt() ast.Stmt { } } -fn (p mut Parser) global_decl() ast.GlobalDecl { +fn (var p Parser) global_decl() ast.GlobalDecl { if !p.pref.translated && !p.pref.is_live && !p.builtin_mod && !p.pref.building_v && p.mod != 'ui' && p.mod != 'gg2' && p.mod != 'uiold' && !os.getwd().contains('/volt') && !p.pref.enable_globals { p.error('use `v --enable-globals ...` to enable globals') @@ -1862,7 +1862,7 @@ fn (p mut Parser) global_decl() ast.GlobalDecl { return glob } -fn (p mut Parser) match_expr() ast.MatchExpr { +fn (var p Parser) match_expr() ast.MatchExpr { match_first_pos := p.tok.position() p.check(.key_match) is_mut := p.tok.kind in [.key_mut, .key_var] @@ -1955,7 +1955,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr { } } -fn (p mut Parser) enum_decl() ast.EnumDecl { +fn (var p Parser) enum_decl() ast.EnumDecl { is_pub := p.tok.kind == .key_pub if is_pub { p.next() @@ -2002,7 +2002,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl { } } -fn (p mut Parser) type_decl() ast.TypeDecl { +fn (var p Parser) type_decl() ast.TypeDecl { is_pub := p.tok.kind == .key_pub if is_pub { p.next() @@ -2067,7 +2067,7 @@ fn (p mut Parser) type_decl() ast.TypeDecl { } } -fn (p mut Parser) assoc() ast.Assoc { +fn (var p Parser) assoc() ast.Assoc { var_name := p.check_name() pos := p.tok.position() v := p.scope.find_var(var_name) or {