parent
							
								
									4b110756e0
								
							
						
					
					
						commit
						da28bc7026
					
				|  | @ -4,23 +4,24 @@ | |||
| module ast | ||||
| 
 | ||||
| // These methods are used only by vfmt, vdoc, and for debugging.
 | ||||
| import v.table | ||||
| import strings | ||||
| import ( | ||||
| 	v.table | ||||
| 	strings | ||||
| ) | ||||
| 
 | ||||
| pub fn (node &FnDecl) str(t &table.Table) string { | ||||
| 	var f := strings.new_builder(30) | ||||
| 	mut f := strings.new_builder(30) | ||||
| 	if node.is_pub { | ||||
| 		f.write('pub ') | ||||
| 	} | ||||
| 	var receiver := '' | ||||
| 	mut receiver := '' | ||||
| 	if node.is_method { | ||||
| 		var styp := t.type_to_str(node.receiver.typ) | ||||
| 		var m := if node.rec_mut { 'var ' } else { '' } | ||||
| 		mut styp := t.type_to_str(node.receiver.typ) | ||||
| 		mut m := if node.rec_mut { 'mut ' } else { '' } | ||||
| 		if node.rec_mut { | ||||
| 			styp = styp[1..]			// remove &
 | ||||
| 		} | ||||
| 		// receiver = '($node.receiver.name $m$styp) '
 | ||||
| 		receiver = '($m$node.receiver.name $styp) ' | ||||
| 		receiver = '($node.receiver.name $m$styp) ' | ||||
| 		/* | ||||
| 		sym := t.get_type_symbol(node.receiver.typ) | ||||
| 		name := sym.name.after('.') | ||||
|  | @ -31,7 +32,7 @@ pub fn (node &FnDecl) str(t &table.Table) string { | |||
| 		receiver = '($node.receiver.name $m$name) ' | ||||
| */ | ||||
| 	} | ||||
| 	var name := node.name.after('.') | ||||
| 	mut name := node.name.after('.') | ||||
| 	if node.is_c { | ||||
| 		name = 'C.$name' | ||||
| 	} | ||||
|  | @ -45,7 +46,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) | ||||
| 		var s := t.type_to_str(arg.typ) | ||||
| 		mut s := t.type_to_str(arg.typ) | ||||
| 		if arg.is_mut { | ||||
| 			f.write(' mut') | ||||
| 			if s.starts_with('&') { | ||||
|  | @ -159,7 +160,7 @@ pub fn (a CallArg) str() string { | |||
| } | ||||
| 
 | ||||
| pub fn args2str(args []CallArg) string { | ||||
| 	var res := []string | ||||
| 	mut res := []string | ||||
| 	for a in args { | ||||
| 		res << a.str() | ||||
| 	} | ||||
|  | @ -169,7 +170,7 @@ pub fn args2str(args []CallArg) string { | |||
| pub fn (node Stmt) str() string { | ||||
| 	match node { | ||||
| 		AssignStmt { | ||||
| 			var out := '' | ||||
| 			mut out := '' | ||||
| 			for i, ident in it.left { | ||||
| 				var_info := ident.var_info() | ||||
| 				if var_info.is_mut { | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ mut: | |||
| } | ||||
| 
 | ||||
| pub fn fmt(file ast.File, table &table.Table) string { | ||||
| 	var f := Fmt{ | ||||
| 	mut 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 (var f Fmt) write(s string) { | ||||
| pub fn (f mut 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 (var f Fmt) write(s string) { | |||
| 	f.empty_line = false | ||||
| } | ||||
| 
 | ||||
| pub fn (var f Fmt) writeln(s string) { | ||||
| pub fn (f mut 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 (var f Fmt) writeln(s string) { | |||
| 	f.line_len = 0 | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) mod(mod ast.Module) { | ||||
| fn (f mut Fmt) mod(mod ast.Module) { | ||||
| 	f.cur_mod = mod.name | ||||
| 	if mod.is_skipped { | ||||
| 		return | ||||
|  | @ -95,7 +95,7 @@ fn (var f Fmt) mod(mod ast.Module) { | |||
| 	f.writeln('module $mod.name\n') | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) imports(imports []ast.Import) { | ||||
| fn (f mut 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 (var f Fmt) stmts(stmts []ast.Stmt) { | ||||
| fn (f mut Fmt) stmts(stmts []ast.Stmt) { | ||||
| 	f.indent++ | ||||
| 	for stmt in stmts { | ||||
| 		f.stmt(stmt) | ||||
|  | @ -137,7 +137,7 @@ fn (var f Fmt) stmts(stmts []ast.Stmt) { | |||
| 	f.indent-- | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) stmt(node ast.Stmt) { | ||||
| fn (f mut Fmt) stmt(node ast.Stmt) { | ||||
| 	match node { | ||||
| 		ast.AssignStmt { | ||||
| 			for i, ident in it.left { | ||||
|  | @ -205,7 +205,7 @@ fn (var f Fmt) stmt(node ast.Stmt) { | |||
| 				f.write('pub ') | ||||
| 			} | ||||
| 			f.writeln('const (') | ||||
| 			var max := 0 | ||||
| 			mut max := 0 | ||||
| 			for field in it.fields { | ||||
| 				if field.name.len > max { | ||||
| 					max = field.name.len | ||||
|  | @ -379,7 +379,7 @@ fn (var f Fmt) stmt(node ast.Stmt) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) type_decl(node ast.TypeDecl) { | ||||
| fn (f mut Fmt) type_decl(node ast.TypeDecl) { | ||||
| 	match node { | ||||
| 		ast.AliasTypeDecl { | ||||
| 			if it.is_pub { | ||||
|  | @ -393,7 +393,7 @@ fn (var f Fmt) type_decl(node ast.TypeDecl) { | |||
| 				f.write('pub ') | ||||
| 			} | ||||
| 			f.write('type $it.name = ') | ||||
| 			var sum_type_names := []string | ||||
| 			mut sum_type_names := []string | ||||
| 			for t in it.sub_types { | ||||
| 				sum_type_names << f.type_to_str(t) | ||||
| 			} | ||||
|  | @ -406,13 +406,13 @@ fn (var f Fmt) type_decl(node ast.TypeDecl) { | |||
| 	f.writeln('\n') | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) struct_decl(node ast.StructDecl) { | ||||
| fn (f mut Fmt) struct_decl(node ast.StructDecl) { | ||||
| 	if node.is_pub { | ||||
| 		f.write('pub ') | ||||
| 	} | ||||
| 	name := node.name.after('.') | ||||
| 	f.writeln('struct $name {') | ||||
| 	var max := 0 | ||||
| 	mut 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 (var f Fmt) expr(node ast.Expr) { | ||||
| fn (f mut 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 (var f Fmt) expr(node ast.Expr) { | |||
| 		ast.StructInit { | ||||
| 			type_sym := f.table.get_type_symbol(it.typ) | ||||
| 			// f.write('<old name: $type_sym.name>')
 | ||||
| 			var name := short_module(type_sym.name).replace(f.cur_mod + '.', '')			// TODO f.type_to_str?
 | ||||
| 			mut name := short_module(type_sym.name).replace(f.cur_mod + '.', '')			// TODO f.type_to_str?
 | ||||
| 			if name == 'void' { | ||||
| 				name = '' | ||||
| 			} | ||||
|  | @ -731,7 +731,7 @@ fn (var f Fmt) expr(node ast.Expr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) wrap_long_line() { | ||||
| fn (f mut 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 (var f Fmt) wrap_long_line() { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) call_args(args []ast.CallArg) { | ||||
| fn (f mut Fmt) call_args(args []ast.CallArg) { | ||||
| 	for i, arg in args { | ||||
| 		if arg.is_mut { | ||||
| 			f.write('mut ') | ||||
|  | @ -756,7 +756,7 @@ fn (var f Fmt) call_args(args []ast.CallArg) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) or_expr(or_block ast.OrExpr) { | ||||
| fn (f mut 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 (var f Fmt) or_expr(or_block ast.OrExpr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) comment(node ast.Comment) { | ||||
| fn (f mut Fmt) comment(node ast.Comment) { | ||||
| 	if !node.text.contains('\n') { | ||||
| 		is_separate_line := node.text.starts_with('|') | ||||
| 		var s := if is_separate_line { node.text[1..] } else { node.text } | ||||
| 		mut 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 (var f Fmt) if_expr(it ast.IfExpr) { | ||||
| fn (f mut 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 (var f Fmt) if_expr(it ast.IfExpr) { | |||
| 	f.single_line_if = false | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) call_expr(node ast.CallExpr) { | ||||
| fn (f mut Fmt) call_expr(node ast.CallExpr) { | ||||
| 	if node.is_method { | ||||
| 		match node.left { | ||||
| 			ast.Ident { | ||||
|  | @ -870,13 +870,13 @@ fn (var f Fmt) call_expr(node ast.CallExpr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var f Fmt) mark_types_module_as_used(typ table.Type) { | ||||
| fn (f mut 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 (var f Fmt) mark_module_as_used(name string) { | ||||
| fn (f mut Fmt) mark_module_as_used(name string) { | ||||
| 	if !name.contains('.') { | ||||
| 		return | ||||
| 	} | ||||
|  |  | |||
|  | @ -134,7 +134,7 @@ pub fn (g Gen) hashes() string { | |||
| 	return res | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) init() { | ||||
| pub fn (g mut Gen) init() { | ||||
| 	g.definitions.writeln('// Generated by the V compiler') | ||||
| 	g.definitions.writeln('#include <inttypes.h>')	// int64_t etc
 | ||||
| 	g.definitions.writeln(c_builtin_types) | ||||
|  | @ -159,7 +159,7 @@ pub fn (var g Gen) init() { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) finish() { | ||||
| pub fn (g mut Gen) finish() { | ||||
| 	if g.pref.build_mode != .build_module { | ||||
| 		g.stringliterals.writeln('}') | ||||
| 	} | ||||
|  | @ -167,7 +167,7 @@ pub fn (var g Gen) finish() { | |||
| 	g.stringliterals.writeln('') | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) write_typeof_functions() { | ||||
| pub fn (g mut 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 (var g Gen) write_typeof_functions() { | |||
| } | ||||
| 
 | ||||
| // V type to C type
 | ||||
| pub fn (var g Gen) typ(t table.Type) string { | ||||
| pub fn (g mut 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 (var g Gen) typ(t table.Type) string { | |||
| } | ||||
| 
 | ||||
| //
 | ||||
| pub fn (var g Gen) write_typedef_types() { | ||||
| pub fn (g mut Gen) write_typedef_types() { | ||||
| 	for typ in g.table.types { | ||||
| 		match typ.kind { | ||||
| 			.alias { | ||||
|  | @ -263,7 +263,7 @@ pub fn (var g Gen) write_typedef_types() { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) write_multi_return_types() { | ||||
| pub fn (g mut 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 (var g Gen) write_multi_return_types() { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) write_variadic_types() { | ||||
| pub fn (g mut Gen) write_variadic_types() { | ||||
| 	if g.variadic_args.size > 0 { | ||||
| 		g.definitions.writeln('// variadic structs') | ||||
| 	} | ||||
|  | @ -303,7 +303,7 @@ pub fn (var g Gen) write_variadic_types() { | |||
| pub fn (g Gen) save() { | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) write(s string) { | ||||
| pub fn (g mut 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 (var g Gen) write(s string) { | |||
| 	g.empty_line = false | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) writeln(s string) { | ||||
| pub fn (g mut Gen) writeln(s string) { | ||||
| 	if g.indent > 0 && g.empty_line { | ||||
| 		g.out.write(tabs[g.indent]) | ||||
| 	} | ||||
|  | @ -320,16 +320,16 @@ pub fn (var g Gen) writeln(s string) { | |||
| 	g.empty_line = true | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) new_tmp_var() string { | ||||
| pub fn (g mut Gen) new_tmp_var() string { | ||||
| 	g.tmp_count++ | ||||
| 	return 'tmp$g.tmp_count' | ||||
| } | ||||
| 
 | ||||
| pub fn (var g Gen) reset_tmp_count() { | ||||
| pub fn (g mut Gen) reset_tmp_count() { | ||||
| 	g.tmp_count = 0 | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) stmts(stmts []ast.Stmt) { | ||||
| fn (g mut Gen) stmts(stmts []ast.Stmt) { | ||||
| 	g.indent++ | ||||
| 	if g.inside_ternary { | ||||
| 		g.write(' ( ') | ||||
|  | @ -346,7 +346,7 @@ fn (var g Gen) stmts(stmts []ast.Stmt) { | |||
| 	g.indent-- | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) stmt(node ast.Stmt) { | ||||
| fn (g mut Gen) stmt(node ast.Stmt) { | ||||
| 	g.stmt_start_pos = g.out.len | ||||
| 	// println('cgen.stmt()')
 | ||||
| 	// g.writeln('//// stmt start')
 | ||||
|  | @ -522,7 +522,7 @@ fn (var g Gen) stmt(node ast.Stmt) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) write_defer_stmts() { | ||||
| fn (g mut 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 (var g Gen) write_defer_stmts() { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) for_in(it ast.ForInStmt) { | ||||
| fn (g mut 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 (var g Gen) for_in(it ast.ForInStmt) { | |||
| } | ||||
| 
 | ||||
| // use instead of expr() when you need to cast to sum type (can add other casts also)
 | ||||
| fn (var g Gen) expr_with_cast(expr ast.Expr, got_type, exp_type table.Type) { | ||||
| fn (g mut 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 (var g Gen) expr_with_cast(expr ast.Expr, got_type, exp_type table.Type) { | |||
| 	g.expr(expr) | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) gen_assert_stmt(a ast.AssertStmt) { | ||||
| fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) { | ||||
| 	g.writeln('// assert') | ||||
| 	g.inside_ternary = true | ||||
| 	g.write('if (') | ||||
|  | @ -669,7 +669,7 @@ fn (var g Gen) gen_assert_stmt(a ast.AssertStmt) { | |||
| 	g.writeln('}') | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | ||||
| fn (g mut 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 (var g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, add_eq bool) bool { | ||||
| fn (g mut 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 (var g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, ad | |||
| 	return true | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) free_scope_vars(pos int) { | ||||
| fn (g mut Gen) free_scope_vars(pos int) { | ||||
| 	scope := g.file.scope.innermost(pos) | ||||
| 	for _, obj in scope.objects { | ||||
| 		match obj { | ||||
|  | @ -856,7 +856,7 @@ fn (var g Gen) free_scope_vars(pos int) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) expr(node ast.Expr) { | ||||
| fn (g mut Gen) expr(node ast.Expr) { | ||||
| 	// println('cgen expr() line_nr=$node.pos.line_nr')
 | ||||
| 	match node { | ||||
| 		ast.ArrayInit { | ||||
|  | @ -1083,7 +1083,7 @@ fn (var g Gen) expr(node ast.Expr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) typeof_expr(node ast.TypeOf) { | ||||
| fn (g mut 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 (var g Gen) typeof_expr(node ast.TypeOf) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) enum_expr(node ast.Expr) { | ||||
| fn (g mut Gen) enum_expr(node ast.Expr) { | ||||
| 	match node { | ||||
| 		ast.EnumVal { | ||||
| 			g.write(it.val) | ||||
|  | @ -1112,7 +1112,7 @@ fn (var g Gen) enum_expr(node ast.Expr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) assign_expr(node ast.AssignExpr) { | ||||
| fn (g mut Gen) assign_expr(node ast.AssignExpr) { | ||||
| 	// g.write('/*assign_expr*/')
 | ||||
| 	var is_call := false | ||||
| 	var or_stmts := []ast.Stmt | ||||
|  | @ -1188,7 +1188,7 @@ fn (var g Gen) assign_expr(node ast.AssignExpr) { | |||
| 	g.is_assign_rhs = false | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) infix_expr(node ast.InfixExpr) { | ||||
| fn (g mut 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 (var g Gen) infix_expr(node ast.InfixExpr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) match_expr(node ast.MatchExpr) { | ||||
| fn (g mut Gen) match_expr(node ast.MatchExpr) { | ||||
| 	// println('match expr typ=$it.expr_type')
 | ||||
| 	// TODO
 | ||||
| 	if node.cond_type == 0 { | ||||
|  | @ -1454,7 +1454,7 @@ fn (var g Gen) match_expr(node ast.MatchExpr) { | |||
| 	g.inside_ternary = was_inside_ternary | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) ident(node ast.Ident) { | ||||
| fn (g mut Gen) ident(node ast.Ident) { | ||||
| 	if node.name == 'lld' { | ||||
| 		return | ||||
| 	} | ||||
|  | @ -1486,7 +1486,7 @@ fn (var g Gen) ident(node ast.Ident) { | |||
| 	g.write(name) | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) if_expr(node ast.IfExpr) { | ||||
| fn (g mut 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 (var g Gen) if_expr(node ast.IfExpr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) index_expr(node ast.IndexExpr) { | ||||
| fn (g mut 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 (var g Gen) index_expr(node ast.IndexExpr) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) return_statement(node ast.Return) { | ||||
| fn (g mut Gen) return_statement(node ast.Return) { | ||||
| 	g.write('return') | ||||
| 	if g.fn_decl.name == 'main' { | ||||
| 		g.writeln(' 0;') | ||||
|  | @ -1828,7 +1828,7 @@ fn (var g Gen) return_statement(node ast.Return) { | |||
| 	g.writeln(';') | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) const_decl(node ast.ConstDecl) { | ||||
| fn (g mut 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 (var g Gen) const_decl(node ast.ConstDecl) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) const_decl_simple_define(name, val string) { | ||||
| fn (g mut 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 (var g Gen) const_decl_simple_define(name, val string) { | |||
| 	g.definitions.writeln(val) | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) struct_init(struct_init ast.StructInit) { | ||||
| fn (g mut 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 (var g Gen) struct_init(struct_init ast.StructInit) { | |||
| } | ||||
| 
 | ||||
| // { user | name: 'new name' }
 | ||||
| fn (var g Gen) assoc(node ast.Assoc) { | ||||
| fn (g mut Gen) assoc(node ast.Assoc) { | ||||
| 	g.writeln('// assoc') | ||||
| 	if node.typ == 0 { | ||||
| 		return | ||||
|  | @ -1964,7 +1964,7 @@ fn (var g Gen) assoc(node ast.Assoc) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) generate_array_equality_fn(ptr_typ string, styp table.Type, sym &table.TypeSymbol) { | ||||
| fn (g mut 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 (var g Gen) write_init_function() { | ||||
| fn (g mut Gen) write_init_function() { | ||||
| 	g.writeln('void _vinit() {') | ||||
| 	g.writeln('\tbuiltin_init();') | ||||
| 	g.writeln('\tvinit_string_literals();') | ||||
|  | @ -2015,7 +2015,7 @@ fn (var g Gen) write_init_function() { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) write_str_fn_definitions() { | ||||
| fn (g mut 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 (var g Gen) write_builtin_types() { | ||||
| fn (g mut 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 (var g 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 (var g Gen) write_sorted_types() { | ||||
| fn (g mut 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 (var g Gen) write_sorted_types() { | |||
| 	g.write_types(types_sorted) | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) write_types(types []table.TypeSymbol) { | ||||
| fn (g mut 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 (var g Gen) string_inter_literal(node ast.StringInterLiteral) { | ||||
| fn (g mut 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 (var g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| } | ||||
| 
 | ||||
| // `nums.filter(it % 2 == 0)`
 | ||||
| fn (var g Gen) gen_filter(node ast.CallExpr) { | ||||
| fn (g mut 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 (var g Gen) gen_filter(node ast.CallExpr) { | |||
| 	g.write(tmp) | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) insert_before(s string) { | ||||
| fn (g mut 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 (var g 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 (var g Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Type) { | ||||
| fn (g mut 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 (var g Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Typ | |||
| 	g.write('}') | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) type_of_last_statement(stmts []ast.Stmt) (string, string) { | ||||
| fn (g mut 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 (var g Gen) type_of_last_statement(stmts []ast.Stmt) (string, string) { | |||
| 	return last_type, last_expr_result_type | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) type_of_call_expr(node ast.Expr) string { | ||||
| fn (g mut Gen) type_of_call_expr(node ast.Expr) string { | ||||
| 	match node { | ||||
| 		ast.CallExpr { | ||||
| 			return g.typ(it.return_type) | ||||
|  | @ -2408,7 +2408,7 @@ fn (var g Gen) type_of_call_expr(node ast.Expr) string { | |||
| } | ||||
| 
 | ||||
| // `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
 | ||||
| fn (var g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) { | ||||
| fn (g mut 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 (var g Gen) write_tests_main() { | ||||
| pub fn (g mut 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 (var g Gen) comp_if(it ast.CompIf) { | ||||
| fn (g mut 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 (var g Gen) comp_if(it ast.CompIf) { | |||
| 	g.writeln('\n#endif') | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) go_stmt(node ast.GoStmt) { | ||||
| fn (g mut 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 (var g Gen) go_stmt(node ast.GoStmt) { | |||
| } | ||||
| 
 | ||||
| // already generated styp, reuse it
 | ||||
| fn (var g Gen) gen_str_for_type(sym table.TypeSymbol, styp string) { | ||||
| fn (g mut 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 (var g Gen) gen_str_for_type(sym table.TypeSymbol, styp string) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) gen_str_default(sym table.TypeSymbol, styp string) { | ||||
| fn (g mut 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 (var g Gen) gen_str_default(sym table.TypeSymbol, styp string) { | |||
| 	g.definitions.writeln('}') | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) gen_str_for_enum(info table.Enum, styp string) { | ||||
| fn (g mut 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 (var g Gen) gen_str_for_enum(info table.Enum, styp string) { | |||
| 	g.definitions.write('\t\tdefault: return tos3("unknown enum value"); } }\n') | ||||
| } | ||||
| 
 | ||||
| fn (var g Gen) gen_str_for_struct(info table.Struct, styp string) { | ||||
| fn (g mut 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 { | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import v.table | |||
| import v.scanner | ||||
| import v.token | ||||
| 
 | ||||
| pub fn (var p Parser) call_expr(is_c bool, mod string) ast.CallExpr { | ||||
| pub fn (p mut 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 (var p Parser) call_expr(is_c bool, mod string) ast.CallExpr { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) call_args() []ast.CallArg { | ||||
| pub fn (p mut Parser) call_args() []ast.CallArg { | ||||
| 	var args := []ast.CallArg | ||||
| 	for p.tok.kind != .rpar { | ||||
| 		var is_mut := false | ||||
|  | @ -79,7 +79,7 @@ pub fn (var p Parser) call_args() []ast.CallArg { | |||
| 	return args | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) fn_decl() ast.FnDecl { | ||||
| fn (p mut Parser) fn_decl() ast.FnDecl { | ||||
| 	// p.table.clear_vars()
 | ||||
| 	pos := p.tok.position() | ||||
| 	p.open_scope() | ||||
|  | @ -118,7 +118,7 @@ fn (var p 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_with_mut(rec_mut) | ||||
| 		rec_type = p.parse_type() | ||||
| 		if is_amp && rec_mut { | ||||
| 			p.error('use `(f mut Foo)` or `(f &Foo)` instead of `(f mut &Foo)`') | ||||
| 		} | ||||
|  | @ -224,7 +224,7 @@ fn (var p Parser) fn_decl() ast.FnDecl { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) fn_args() ([]table.Arg, bool) { | ||||
| fn (p mut Parser) fn_args() ([]table.Arg, bool) { | ||||
| 	p.check(.lpar) | ||||
| 	var args := []table.Arg | ||||
| 	var is_variadic := false | ||||
|  |  | |||
|  | @ -1,11 +1,12 @@ | |||
| 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 (var p Parser) parse_array_type() table.Type { | ||||
| pub fn (p mut Parser) parse_array_type() table.Type { | ||||
| 	p.check(.lsbr) | ||||
| 	// fixed array
 | ||||
| 	if p.tok.kind == .number { | ||||
|  | @ -19,7 +20,7 @@ pub fn (var p Parser) parse_array_type() table.Type { | |||
| 	// array
 | ||||
| 	p.check(.rsbr) | ||||
| 	elem_type := p.parse_type() | ||||
| 	var nr_dims := 1 | ||||
| 	mut nr_dims := 1 | ||||
| 	for p.tok.kind == .lsbr { | ||||
| 		p.check(.lsbr) | ||||
| 		p.check(.rsbr) | ||||
|  | @ -29,7 +30,7 @@ pub fn (var p Parser) parse_array_type() table.Type { | |||
| 	return table.new_type(idx) | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) parse_map_type() table.Type { | ||||
| pub fn (p mut Parser) parse_map_type() table.Type { | ||||
| 	p.next() | ||||
| 	if p.tok.kind != .lsbr { | ||||
| 		return table.map_type | ||||
|  | @ -47,15 +48,16 @@ pub fn (var p Parser) parse_map_type() table.Type { | |||
| 	return table.new_type(idx) | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) parse_multi_return_type() table.Type { | ||||
| pub fn (p mut Parser) parse_multi_return_type() table.Type { | ||||
| 	p.check(.lpar) | ||||
| 	var mr_types := []table.Type | ||||
| 	mut 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 | ||||
| 		} | ||||
| 	} | ||||
|  | @ -65,12 +67,12 @@ pub fn (var p Parser) parse_multi_return_type() table.Type { | |||
| } | ||||
| 
 | ||||
| // given anon name based off signature when `name` is blank
 | ||||
| pub fn (var p Parser) parse_fn_type(name string) table.Type { | ||||
| pub fn (p mut 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() | ||||
| 	var return_type := table.void_type | ||||
| 	args,is_variadic := p.fn_args() | ||||
| 	mut return_type := table.void_type | ||||
| 	if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() { | ||||
| 		return_type = p.parse_type() | ||||
| 	} | ||||
|  | @ -84,22 +86,14 @@ pub fn (var p Parser) parse_fn_type(name string) table.Type { | |||
| 	return table.new_type(idx) | ||||
| } | ||||
| 
 | ||||
| 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 { | ||||
| pub fn (p mut Parser) parse_type() table.Type { | ||||
| 	// optional
 | ||||
| 	var is_optional := false | ||||
| 	mut is_optional := false | ||||
| 	if p.tok.kind == .question { | ||||
| 		p.next() | ||||
| 		is_optional = true | ||||
| 	} | ||||
| 	var nr_muls := 0 | ||||
| 	mut nr_muls := 0 | ||||
| 	if p.tok.kind == .key_mut { | ||||
| 		nr_muls++ | ||||
| 		p.next() | ||||
|  | @ -108,7 +102,8 @@ pub fn (var p 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() | ||||
|  | @ -118,7 +113,7 @@ pub fn (var p Parser) parse_type() table.Type { | |||
| 		p.next() | ||||
| 		p.check(.dot) | ||||
| 	} | ||||
| 	var typ := p.parse_any_type(is_c, nr_muls > 0) | ||||
| 	mut typ := p.parse_any_type(is_c, nr_muls > 0) | ||||
| 	if is_optional { | ||||
| 		typ = table.type_set(typ, .optional) | ||||
| 	} | ||||
|  | @ -128,12 +123,13 @@ pub fn (var p Parser) parse_type() table.Type { | |||
| 	return typ | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) parse_any_type(is_c, is_ptr bool) table.Type { | ||||
| 	var name := p.tok.lit | ||||
| pub fn (p mut Parser) parse_any_type(is_c, is_ptr bool) table.Type { | ||||
| 	mut name := p.tok.lit | ||||
| 	if is_c { | ||||
| 		name = 'C.$name' | ||||
| 	} else if p.peek_tok.kind == .dot { | ||||
| 		// `module.Type`
 | ||||
| 	} | ||||
| 	// `module.Type`
 | ||||
| 	else if p.peek_tok.kind == .dot { | ||||
| 		// /if !(p.tok.lit in p.table.imports) {
 | ||||
| 		if !p.known_import(name) { | ||||
| 			println(p.table.imports) | ||||
|  | @ -143,10 +139,12 @@ pub fn (var p 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 | ||||
| 	} else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) { | ||||
| 		// `Foo` in module `mod` means `mod.Foo`
 | ||||
| 	} | ||||
| 	// `Foo` in module `mod` means `mod.Foo`
 | ||||
| 	else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) { | ||||
| 		name = p.mod + '.' + name | ||||
| 	} | ||||
| 	// p.warn('get type $name')
 | ||||
|  | @ -226,7 +224,7 @@ pub fn (var p Parser) parse_any_type(is_c, is_ptr bool) table.Type { | |||
| 				// struct / enum / placeholder
 | ||||
| 				else { | ||||
| 					// struct / enum
 | ||||
| 					var idx := p.table.find_type_idx(name) | ||||
| 					mut idx := p.table.find_type_idx(name) | ||||
| 					if idx > 0 { | ||||
| 						return table.new_type(idx) | ||||
| 					} | ||||
|  | @ -235,7 +233,7 @@ pub fn (var p Parser) parse_any_type(is_c, is_ptr bool) table.Type { | |||
| 					// println('NOT FOUND: $name - adding placeholder - $idx')
 | ||||
| 					return table.new_type(idx) | ||||
| 				} | ||||
| 			} | ||||
| 	} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -174,26 +174,26 @@ pub fn (p &Parser) init_parse_fns() { | |||
| 	println('') | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) read_first_token() { | ||||
| pub fn (p mut Parser) read_first_token() { | ||||
| 	// need to call next() twice to get peek token and current token
 | ||||
| 	p.next() | ||||
| 	p.next() | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) open_scope() { | ||||
| pub fn (p mut Parser) open_scope() { | ||||
| 	p.scope = &ast.Scope{ | ||||
| 		parent: p.scope | ||||
| 		start_pos: p.tok.pos | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) close_scope() { | ||||
| pub fn (p mut Parser) close_scope() { | ||||
| 	p.scope.end_pos = p.tok.pos | ||||
| 	p.scope.parent.children << p.scope | ||||
| 	p.scope = p.scope.parent | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) parse_block() []ast.Stmt { | ||||
| pub fn (p mut Parser) parse_block() []ast.Stmt { | ||||
| 	p.open_scope() | ||||
| 	// println('parse block')
 | ||||
| 	stmts := p.parse_block_no_scope() | ||||
|  | @ -202,7 +202,7 @@ pub fn (var p Parser) parse_block() []ast.Stmt { | |||
| 	return stmts | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) parse_block_no_scope() []ast.Stmt { | ||||
| pub fn (p mut 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 (var p Parser) next() { | ||||
| fn (p mut Parser) next() { | ||||
| 	p.tok = p.peek_tok | ||||
| 	p.peek_tok = p.scanner.scan() | ||||
| 	/* | ||||
|  | @ -235,7 +235,7 @@ fn (var p Parser) next() { | |||
| */ | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) check(expected token.Kind) { | ||||
| fn (p mut Parser) check(expected token.Kind) { | ||||
| 	// for p.tok.kind in [.line_comment, .mline_comment] {
 | ||||
| 	// p.next()
 | ||||
| 	// }
 | ||||
|  | @ -246,13 +246,13 @@ fn (var p Parser) check(expected token.Kind) { | |||
| 	p.next() | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) check_name() string { | ||||
| fn (p mut Parser) check_name() string { | ||||
| 	name := p.tok.lit | ||||
| 	p.check(.name) | ||||
| 	return name | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) top_stmt() ast.Stmt { | ||||
| pub fn (p mut Parser) top_stmt() ast.Stmt { | ||||
| 	match p.tok.kind { | ||||
| 		.key_pub { | ||||
| 			match p.peek_tok.kind { | ||||
|  | @ -335,14 +335,14 @@ pub fn (var p Parser) top_stmt() ast.Stmt { | |||
| } | ||||
| 
 | ||||
| // TODO [if vfmt]
 | ||||
| pub fn (var p Parser) check_comment() ast.Comment { | ||||
| pub fn (p mut Parser) check_comment() ast.Comment { | ||||
| 	if p.tok.kind == .comment { | ||||
| 		return p.comment() | ||||
| 	} | ||||
| 	return ast.Comment{} | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) comment() ast.Comment { | ||||
| pub fn (p mut Parser) comment() ast.Comment { | ||||
| 	pos := p.tok.position() | ||||
| 	text := p.tok.lit | ||||
| 	p.next() | ||||
|  | @ -353,7 +353,7 @@ pub fn (var p Parser) comment() ast.Comment { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) stmt() ast.Stmt { | ||||
| pub fn (p mut Parser) stmt() ast.Stmt { | ||||
| 	p.is_stmt_ident = p.tok.kind == .name | ||||
| 	match p.tok.kind { | ||||
| 		.lcbr { | ||||
|  | @ -456,7 +456,7 @@ pub fn (var p Parser) stmt() ast.Stmt { | |||
| } | ||||
| 
 | ||||
| // TODO: is it possible to merge with AssignStmt?
 | ||||
| pub fn (var p Parser) assign_expr(left ast.Expr) ast.AssignExpr { | ||||
| pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr { | ||||
| 	op := p.tok.kind | ||||
| 	p.next() | ||||
| 	pos := p.tok.position() | ||||
|  | @ -477,7 +477,7 @@ pub fn (var p Parser) assign_expr(left ast.Expr) ast.AssignExpr { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) attribute() ast.Attr { | ||||
| fn (p mut 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 (var p Parser) parse_ident(is_c bool) ast.Ident { | ||||
| pub fn (p mut 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 (var p Parser) parse_ident(is_c bool) ast.Ident { | |||
| 	return ident | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) struct_init(short_syntax bool) ast.StructInit { | ||||
| fn (p mut 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 (var p Parser) struct_init(short_syntax bool) ast.StructInit { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) name_expr() ast.Expr { | ||||
| pub fn (p mut Parser) name_expr() ast.Expr { | ||||
| 	var node := ast.Expr{} | ||||
| 	is_c := p.tok.lit == 'C' | ||||
| 	var mod := '' | ||||
|  | @ -723,7 +723,7 @@ pub fn (var p Parser) name_expr() ast.Expr { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| pub fn (var p Parser) expr(precedence int) ast.Expr { | ||||
| pub fn (p mut 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 (var p Parser) expr(precedence int) ast.Expr { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) prefix_expr() ast.PrefixExpr { | ||||
| fn (p mut Parser) prefix_expr() ast.PrefixExpr { | ||||
| 	pos := p.tok.position() | ||||
| 	op := p.tok.kind | ||||
| 	if op == .amp { | ||||
|  | @ -905,7 +905,7 @@ fn (var p Parser) prefix_expr() ast.PrefixExpr { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) index_expr(left ast.Expr) ast.IndexExpr { | ||||
| fn (p mut Parser) index_expr(left ast.Expr) ast.IndexExpr { | ||||
| 	// left == `a` in `a[0]`
 | ||||
| 	p.next()	// [
 | ||||
| 	var has_low := true | ||||
|  | @ -956,13 +956,13 @@ fn (var p Parser) index_expr(left ast.Expr) ast.IndexExpr { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) filter() { | ||||
| fn (p mut Parser) filter() { | ||||
| 	p.scope.register('it', ast.Var{ | ||||
| 		name: 'it' | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) dot_expr(left ast.Expr) ast.Expr { | ||||
| fn (p mut 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 (var p Parser) dot_expr(left ast.Expr) ast.Expr { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) infix_expr(left ast.Expr) ast.Expr { | ||||
| fn (p mut 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 (var p Parser) infix_expr(left ast.Expr) ast.Expr { | |||
| 
 | ||||
| // `.green`
 | ||||
| // `pref.BuildMode.default_mode`
 | ||||
| fn (var p Parser) enum_val() ast.EnumVal { | ||||
| fn (p mut Parser) enum_val() ast.EnumVal { | ||||
| 	p.check(.dot) | ||||
| 	val := p.check_name() | ||||
| 	return ast.EnumVal{ | ||||
|  | @ -1065,7 +1065,7 @@ fn (var p Parser) enum_val() ast.EnumVal { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) for_stmt() ast.Stmt { | ||||
| fn (p mut Parser) for_stmt() ast.Stmt { | ||||
| 	p.check(.key_for) | ||||
| 	pos := p.tok.position() | ||||
| 	p.open_scope() | ||||
|  | @ -1185,7 +1185,7 @@ fn (var p Parser) for_stmt() ast.Stmt { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) if_expr() ast.IfExpr { | ||||
| fn (p mut Parser) if_expr() ast.IfExpr { | ||||
| 	pos := p.tok.position() | ||||
| 	var branches := []ast.IfBranch | ||||
| 	var has_else := false | ||||
|  | @ -1256,7 +1256,7 @@ fn (var p Parser) if_expr() ast.IfExpr { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) string_expr() ast.Expr { | ||||
| fn (p mut 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 (var p Parser) string_expr() ast.Expr { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) array_init() ast.ArrayInit { | ||||
| fn (p mut Parser) array_init() ast.ArrayInit { | ||||
| 	first_pos := p.tok.position() | ||||
| 	var last_pos := token.Position{} | ||||
| 	p.check(.lsbr) | ||||
|  | @ -1402,7 +1402,7 @@ fn (var p Parser) array_init() ast.ArrayInit { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) map_init() ast.MapInit { | ||||
| fn (p mut Parser) map_init() ast.MapInit { | ||||
| 	pos := p.tok.position() | ||||
| 	var keys := []ast.Expr | ||||
| 	var vals := []ast.Expr | ||||
|  | @ -1424,7 +1424,7 @@ fn (var p Parser) map_init() ast.MapInit { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) parse_number_literal() ast.Expr { | ||||
| fn (p mut Parser) parse_number_literal() ast.Expr { | ||||
| 	lit := p.tok.lit | ||||
| 	pos := p.tok.position() | ||||
| 	var node := ast.Expr{} | ||||
|  | @ -1442,7 +1442,7 @@ fn (var p Parser) parse_number_literal() ast.Expr { | |||
| 	return node | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) module_decl() ast.Module { | ||||
| fn (p mut Parser) module_decl() ast.Module { | ||||
| 	var name := 'main' | ||||
| 	is_skipped := p.tok.kind != .key_module | ||||
| 	if !is_skipped { | ||||
|  | @ -1458,7 +1458,7 @@ fn (var p Parser) module_decl() ast.Module { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) parse_import() ast.Import { | ||||
| fn (p mut 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 (var p Parser) parse_import() ast.Import { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) import_stmt() []ast.Import { | ||||
| fn (p mut Parser) import_stmt() []ast.Import { | ||||
| 	p.check(.key_import) | ||||
| 	var imports := []ast.Import | ||||
| 	if p.tok.kind == .lpar { | ||||
|  | @ -1500,7 +1500,7 @@ fn (var p Parser) import_stmt() []ast.Import { | |||
| 	return imports | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) const_decl() ast.ConstDecl { | ||||
| fn (p mut Parser) const_decl() ast.ConstDecl { | ||||
| 	is_pub := p.tok.kind == .key_pub | ||||
| 	if is_pub { | ||||
| 		p.next() | ||||
|  | @ -1535,7 +1535,7 @@ fn (var p Parser) const_decl() ast.ConstDecl { | |||
| } | ||||
| 
 | ||||
| // structs and unions
 | ||||
| fn (var p Parser) struct_decl() ast.StructDecl { | ||||
| fn (p mut Parser) struct_decl() ast.StructDecl { | ||||
| 	is_pub := p.tok.kind == .key_pub | ||||
| 	if is_pub { | ||||
| 		p.next() | ||||
|  | @ -1679,7 +1679,7 @@ fn (var p Parser) struct_decl() ast.StructDecl { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) interface_decl() ast.InterfaceDecl { | ||||
| fn (p mut Parser) interface_decl() ast.InterfaceDecl { | ||||
| 	is_pub := p.tok.kind == .key_pub | ||||
| 	if is_pub { | ||||
| 		p.next() | ||||
|  | @ -1704,7 +1704,7 @@ fn (var p Parser) interface_decl() ast.InterfaceDecl { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) return_stmt() ast.Return { | ||||
| fn (p mut Parser) return_stmt() ast.Return { | ||||
| 	p.next() | ||||
| 	// return expressions
 | ||||
| 	var exprs := []ast.Expr | ||||
|  | @ -1730,7 +1730,7 @@ fn (var p Parser) return_stmt() ast.Return { | |||
| } | ||||
| 
 | ||||
| // left hand side of `=` or `:=` in `a,b,c := 1,2,3`
 | ||||
| fn (var p Parser) parse_assign_lhs() []ast.Ident { | ||||
| fn (p mut 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 (var p Parser) parse_assign_lhs() []ast.Ident { | |||
| } | ||||
| 
 | ||||
| // right hand side of `=` or `:=` in `a,b,c := 1,2,3`
 | ||||
| fn (var p Parser) parse_assign_rhs() []ast.Expr { | ||||
| fn (p mut Parser) parse_assign_rhs() []ast.Expr { | ||||
| 	var exprs := []ast.Expr | ||||
| 	for { | ||||
| 		expr := p.expr(0) | ||||
|  | @ -1772,7 +1772,7 @@ fn (var p Parser) parse_assign_rhs() []ast.Expr { | |||
| 	return exprs | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) assign_stmt() ast.Stmt { | ||||
| fn (p mut Parser) assign_stmt() ast.Stmt { | ||||
| 	is_static := p.tok.kind == .key_static | ||||
| 	if is_static { | ||||
| 		p.next() | ||||
|  | @ -1822,7 +1822,7 @@ fn (var p Parser) assign_stmt() ast.Stmt { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) global_decl() ast.GlobalDecl { | ||||
| fn (p mut 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 (var p Parser) global_decl() ast.GlobalDecl { | |||
| 	return glob | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) match_expr() ast.MatchExpr { | ||||
| fn (p mut 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 (var p Parser) match_expr() ast.MatchExpr { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) enum_decl() ast.EnumDecl { | ||||
| fn (p mut Parser) enum_decl() ast.EnumDecl { | ||||
| 	is_pub := p.tok.kind == .key_pub | ||||
| 	if is_pub { | ||||
| 		p.next() | ||||
|  | @ -2002,7 +2002,7 @@ fn (var p Parser) enum_decl() ast.EnumDecl { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) type_decl() ast.TypeDecl { | ||||
| fn (p mut Parser) type_decl() ast.TypeDecl { | ||||
| 	is_pub := p.tok.kind == .key_pub | ||||
| 	if is_pub { | ||||
| 		p.next() | ||||
|  | @ -2067,7 +2067,7 @@ fn (var p Parser) type_decl() ast.TypeDecl { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (var p Parser) assoc() ast.Assoc { | ||||
| fn (p mut Parser) assoc() ast.Assoc { | ||||
| 	var_name := p.check_name() | ||||
| 	pos := p.tok.position() | ||||
| 	v := p.scope.find_var(var_name) or { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue