v2: parse builtin successfully
							parent
							
								
									2ce6b190dd
								
							
						
					
					
						commit
						bb60b3081f
					
				|  | @ -367,7 +367,7 @@ pub fn (b []byte) hex() string { | |||
| 	mut hex := malloc(b.len * 2 + 1) | ||||
| 	mut ptr := &hex[0] | ||||
| 	for i := 0; i < b.len; i++ { | ||||
| 		ptr += C.sprintf(charptr(ptr), '%02x', b[i]) | ||||
| 		ptr += C.sprintf(ptr as charptr, '%02x', b[i]) | ||||
| 	} | ||||
| 	return string(hex) | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import ( | |||
| 	v.ast | ||||
| 	v.table | ||||
| 	v.token | ||||
| 	os | ||||
| ) | ||||
| 
 | ||||
| pub struct Checker { | ||||
|  | @ -140,11 +141,13 @@ pub fn (c &Checker) call_expr(call_expr ast.CallExpr) table.TypeRef { | |||
| 	fn_name := call_expr.name | ||||
| 	if f := c.table.find_fn(fn_name) { | ||||
| 		// return_ti := f.return_ti
 | ||||
| 		if call_expr.args.len < f.args.len { | ||||
| 			c.error('too few arguments in call to `$fn_name`', call_expr.pos) | ||||
| 		} | ||||
| 		else if call_expr.args.len > f.args.len { | ||||
| 			c.error('too many arguments in call to `$fn_name`', call_expr.pos) | ||||
| 		if !f.is_c { | ||||
| 			if call_expr.args.len < f.args.len { | ||||
| 				c.error('too few arguments in call to `$fn_name`', call_expr.pos) | ||||
| 			} | ||||
| 			else if call_expr.args.len > f.args.len { | ||||
| 				c.error('too many arguments in call to `$fn_name`', call_expr.pos) | ||||
| 			} | ||||
| 		} | ||||
| 		for i, arg in f.args { | ||||
| 			arg_expr := call_expr.args[i] | ||||
|  | @ -179,6 +182,11 @@ pub fn (c &Checker) selector_expr(selector_expr ast.SelectorExpr) table.TypeRef | |||
| 			} | ||||
| 			return field.typ | ||||
| 		} | ||||
| 		.array { | ||||
| 			if field_name == 'len' { | ||||
| 				return c.table.type_ref(table.int_type_idx) | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
| 			c.error('`$typ.typ.name` is not a struct', selector_expr.pos) | ||||
| 		} | ||||
|  | @ -404,7 +412,13 @@ pub fn (c &Checker) index_expr(node ast.IndexExpr) table.TypeRef { | |||
| 
 | ||||
| pub fn (c &Checker) error(s string, pos token.Position) { | ||||
| 	print_backtrace() | ||||
| 	final_msg_line := '$c.file_name:$pos.line_nr: error: $s' | ||||
| 	mut path := c.file_name | ||||
| 	// Get relative path
 | ||||
| 	workdir := os.getwd() + os.path_separator | ||||
| 	if path.starts_with(workdir) { | ||||
| 		path = path.replace(workdir, '') | ||||
| 	} | ||||
| 	final_msg_line := '$path:$pos.line_nr: checker error: $s' | ||||
| 	eprintln(final_msg_line) | ||||
| 	/* | ||||
| 	if colored_output { | ||||
|  |  | |||
|  | @ -97,6 +97,7 @@ fn multi_return() (int,string) { | |||
| } | ||||
| 
 | ||||
| fn variadic(a ...int) { | ||||
| 	//a := path_sep
 | ||||
| } | ||||
| 
 | ||||
| fn ensure_cap(required int, cap int) { | ||||
|  | @ -105,4 +106,10 @@ fn ensure_cap(required int, cap int) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| const ( | ||||
| 	path_sep = 10 | ||||
| ) | ||||
| */ | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,table.TypeRef) { | |||
| 		name: fn_name | ||||
| 		args: args | ||||
| 		// tok: tok
 | ||||
| 		 | ||||
| 		pos: tok.position() | ||||
| 	} | ||||
| 	if p.tok.kind == .key_orelse { | ||||
|  | @ -166,6 +167,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | |||
| 			name: name | ||||
| 			args: args | ||||
| 			return_type: typ | ||||
| 			is_c: is_c | ||||
| 		}) | ||||
| 	} | ||||
| 	mut stmts := []ast.Stmt | ||||
|  | @ -184,4 +186,3 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | |||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,25 +26,25 @@ type PostfixParseFn fn()ast.Expr | |||
| 
 | ||||
| 
 | ||||
| struct Parser { | ||||
| 	scanner     &scanner.Scanner | ||||
| 	file_name   string | ||||
| 	scanner         &scanner.Scanner | ||||
| 	file_name       string | ||||
| mut: | ||||
| 	tok         token.Token | ||||
| 	peek_tok    token.Token | ||||
| 	tok             token.Token | ||||
| 	peek_tok        token.Token | ||||
| 	// vars []string
 | ||||
| 	table       &table.Table | ||||
| 	return_type table.TypeRef // current function's return type
 | ||||
| 	table           &table.Table | ||||
| 	return_type     table.TypeRef // current function's return type
 | ||||
| 	// scope_level int
 | ||||
| 	// var_idx     int
 | ||||
| 	is_c        bool | ||||
| 	is_c            bool | ||||
| 	//
 | ||||
| 	// prefix_parse_fns []PrefixParseFn
 | ||||
| 	inside_if   bool | ||||
| 	pref        &pref.Preferences // Preferences shared from V struct
 | ||||
| 	builtin_mod bool | ||||
| 	mod         string | ||||
| 	unresolved  []ast.Expr | ||||
| 	unresolved_idxs  map[string]int | ||||
| 	inside_if       bool | ||||
| 	pref            &pref.Preferences // Preferences shared from V struct
 | ||||
| 	builtin_mod     bool | ||||
| 	mod             string | ||||
| 	unresolved      []ast.Expr | ||||
| 	unresolved_idxs map[string]int | ||||
| } | ||||
| 
 | ||||
| // for tests
 | ||||
|  | @ -302,9 +302,12 @@ fn (p mut Parser) range_expr(low ast.Expr) ast.Expr { | |||
| 		p.next() | ||||
| 	} | ||||
| 	p.check(.dotdot) | ||||
| 	high,typ := p.expr(0) | ||||
| 	if typ.typ.kind != .int { | ||||
| 		p.error('non-integer index `$typ.typ.name`') | ||||
| 	mut high := ast.Expr{} | ||||
| 	if p.tok.kind != .rsbr { | ||||
| 		high,_ = p.expr(0) | ||||
| 		// if typ.typ.kind != .int {
 | ||||
| 		// p.error('non-integer index `$typ.typ.name`')
 | ||||
| 		// }
 | ||||
| 	} | ||||
| 	node := ast.RangeExpr{ | ||||
| 		low: low | ||||
|  | @ -343,7 +346,13 @@ pub fn (p mut Parser) assign_stmt() ast.AssignStmt { | |||
| 
 | ||||
| pub fn (p &Parser) error(s string) { | ||||
| 	print_backtrace() | ||||
| 	final_msg_line := '$p.file_name:$p.tok.line_nr: error: $s' | ||||
| 	mut path := p.file_name | ||||
| 	// Get relative path
 | ||||
| 	workdir := os.getwd() + os.path_separator | ||||
| 	if path.starts_with(workdir) { | ||||
| 		path = path.replace(workdir, '') | ||||
| 	} | ||||
| 	final_msg_line := 'xxx$path:$p.tok.line_nr: error: $s' | ||||
| 	if colored_output { | ||||
| 		eprintln(term.bold(term.red(final_msg_line))) | ||||
| 	} | ||||
|  | @ -374,7 +383,7 @@ pub fn (p &Parser) warn(s string) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn(p mut Parser) parse_ident(is_c bool) (ast.Ident, table.TypeRef) { | ||||
| pub fn (p mut Parser) parse_ident(is_c bool) (ast.Ident,table.TypeRef) { | ||||
| 	mut node := ast.Ident{} | ||||
| 	mut typ := p.table.type_ref(table.void_type_idx) | ||||
| 	// p.warn('name ')
 | ||||
|  | @ -387,7 +396,7 @@ pub fn(p mut Parser) parse_ident(is_c bool) (ast.Ident, table.TypeRef) { | |||
| 	if var := p.table.find_var(name) { | ||||
| 		known_var = true | ||||
| 		typ = var.typ | ||||
| 	}  | ||||
| 	} | ||||
| 	// variable
 | ||||
| 	if known_var || p.tok.kind in [.comma, .decl_assign, .assign] { | ||||
| 		// println('#### IDENT: $var.name: $var.typ.typ.name - $var.typ.idx')
 | ||||
|  | @ -396,14 +405,17 @@ pub fn(p mut Parser) parse_ident(is_c bool) (ast.Ident, table.TypeRef) { | |||
| 			typ: typ | ||||
| 			// name: ident.name
 | ||||
| 			// expr: p.expr(0)// var.expr
 | ||||
| 			 | ||||
| 		} | ||||
| 		return ident, typ | ||||
| 	}else{ | ||||
| 		return ident,typ | ||||
| 	} | ||||
| 	else { | ||||
| 		if is_c { | ||||
| 			typ = p.table.type_ref(table.int_type_idx) | ||||
| 			ident.info = ast.IdentVar{ | ||||
| 				typ: typ | ||||
| 				// name: ident.name
 | ||||
| 				 | ||||
| 			} | ||||
| 			return ident,typ | ||||
| 		} | ||||
|  | @ -414,18 +426,20 @@ pub fn(p mut Parser) parse_ident(is_c bool) (ast.Ident, table.TypeRef) { | |||
| 			ident.info = ast.IdentVar{ | ||||
| 				typ: typ | ||||
| 				// name: ident.name
 | ||||
| 				 | ||||
| 			} | ||||
| 			node = ident | ||||
| 		}else{ | ||||
| 			// Function object (not a call), e.g. `onclick(my_click)`
 | ||||
| 			p.table.find_fn(name) or { | ||||
| 				// ident.info = ast.IdentVar
 | ||||
| 				p.error('parse_ident: unknown identifier `$name`') | ||||
| 				exit(0) | ||||
| 			} | ||||
| 			// p.next()
 | ||||
| 		} | ||||
| 	} | ||||
| 	return node, typ | ||||
| 	return node,typ | ||||
| } | ||||
| 
 | ||||
| pub fn (p mut Parser) name_expr() (ast.Expr,table.TypeRef) { | ||||
|  | @ -484,7 +498,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.TypeRef) { | |||
| 	} | ||||
| 	else { | ||||
| 		mut ident := ast.Ident{} | ||||
| 		ident, typ = p.parse_ident(is_c) | ||||
| 		ident,typ = p.parse_ident(is_c) | ||||
| 		node = ident | ||||
| 	} | ||||
| 	return node,typ | ||||
|  | @ -622,6 +636,7 @@ fn (p mut Parser) index_expr(left ast.Expr) ast.Expr { | |||
| 		index: index_expr | ||||
| 		pos: p.tok.position() | ||||
| 		// typ: typ
 | ||||
| 		 | ||||
| 	} | ||||
| 	return node | ||||
| 	// return node,typ
 | ||||
|  | @ -707,7 +722,7 @@ fn (p mut Parser) for_statement() ast.Stmt { | |||
| 		p.error('`mut` is not required in for loops') | ||||
| 	} | ||||
| 	// for i := 0; i < 10; i++ {
 | ||||
| 	else if p.peek_tok.kind in [.decl_assign, .assign, .semicolon] { | ||||
| 	else if p.peek_tok.kind in [.decl_assign, .assign, .semicolon] || p.tok.kind == .semicolon { | ||||
| 		mut init := ast.Stmt{} | ||||
| 		mut cond := ast.Expr{} | ||||
| 		mut inc := ast.Stmt{} | ||||
|  | @ -727,7 +742,9 @@ fn (p mut Parser) for_statement() ast.Stmt { | |||
| 		} | ||||
| 		p.check(.semicolon) | ||||
| 		if p.tok.kind != .semicolon { | ||||
| 			mut typ := table.TypeRef{typ:0} | ||||
| 			mut typ := table.TypeRef{ | ||||
| 				typ: 0 | ||||
| 			} | ||||
| 			cond,typ = p.expr(0) | ||||
| 		} | ||||
| 		p.check(.semicolon) | ||||
|  | @ -836,7 +853,7 @@ fn (p mut Parser) string_expr() (ast.Expr,table.TypeRef) { | |||
| 	} | ||||
| 	if p.peek_tok.kind != .str_dollar { | ||||
| 		p.next() | ||||
| 		return node, p.table.type_ref(table.string_type_idx) | ||||
| 		return node,p.table.type_ref(table.string_type_idx) | ||||
| 	} | ||||
| 	// Handle $ interpolation
 | ||||
| 	for p.tok.kind == .str { | ||||
|  | @ -850,7 +867,7 @@ fn (p mut Parser) string_expr() (ast.Expr,table.TypeRef) { | |||
| 			p.next() | ||||
| 		} | ||||
| 	} | ||||
| 	return node, p.table.type_ref(table.string_type_idx) | ||||
| 	return node,p.table.type_ref(table.string_type_idx) | ||||
| } | ||||
| 
 | ||||
| fn (p mut Parser) array_init() (ast.Expr,table.TypeRef) { | ||||
|  | @ -1011,6 +1028,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl { | |||
| 		fields << table.Field{ | ||||
| 			name: field_name | ||||
| 			// type_idx: ti.idx
 | ||||
| 			 | ||||
| 			typ: typ | ||||
| 		} | ||||
| 		// println('struct field $ti.name $field_name')
 | ||||
|  | @ -1072,16 +1090,17 @@ pub fn (p mut Parser) assign_stmt() ast.AssignStmt { | |||
| 	// TODO: multiple return & multiple assign
 | ||||
| 	mut idents := []ast.Ident | ||||
| 	for { | ||||
| 		ident, _ := p.parse_ident(false) | ||||
| 		ident,_ := p.parse_ident(false) | ||||
| 		idents << ident | ||||
| 		if p.tok.kind == .comma { | ||||
| 			p.check(.comma) | ||||
| 		} else { | ||||
| 		} | ||||
| 		else { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	p.next() // :=, =
 | ||||
| 	expr, _ := p.expr(0) | ||||
| 	expr,_ := p.expr(0) | ||||
| 	return ast.AssignStmt{ | ||||
| 		left: idents | ||||
| 		right: [expr] | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ pub: | |||
| 	name        string | ||||
| 	args        []Var | ||||
| 	return_type TypeRef | ||||
| 	is_c        bool | ||||
| } | ||||
| 
 | ||||
| pub struct Var { | ||||
|  | @ -37,7 +38,7 @@ pub: | |||
| 	is_global   bool | ||||
| 	scope_level int | ||||
| mut: | ||||
| 	typ       TypeRef | ||||
| 	typ         TypeRef | ||||
| } | ||||
| 
 | ||||
| pub fn new_table() &Table { | ||||
|  | @ -88,6 +89,7 @@ pub fn (t mut Table) register_global(name string, typ TypeRef) { | |||
| 		// mod: p.mod
 | ||||
| 		// is_mut: true
 | ||||
| 		// idx: -1
 | ||||
| 		 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -222,7 +224,8 @@ pub fn (t mut Table) new_tmp_var() string { | |||
| pub fn (t &Table) struct_has_field(s &Type, name string) bool { | ||||
| 	if !isnil(s.parent) { | ||||
| 		println('struct_has_field($s.name, $name) types.len=$t.types.len s.parent=$s.parent.name') | ||||
| 	} else { | ||||
| 	} | ||||
| 	else { | ||||
| 		println('struct_has_field($s.name, $name) types.len=$t.types.len s.parent=none') | ||||
| 	} | ||||
| 	// for typ in t.types {
 | ||||
|  | @ -237,7 +240,8 @@ pub fn (t &Table) struct_has_field(s &Type, name string) bool { | |||
| pub fn (t &Table) struct_find_field(s &Type, name string) ?Field { | ||||
| 	if !isnil(s.parent) { | ||||
| 		println('struct_find_field($s.name, $name) types.len=$t.types.len s.parent=$s.parent.name') | ||||
| 	} else { | ||||
| 	} | ||||
| 	else { | ||||
| 		println('struct_find_field($s.name, $name) types.len=$t.types.len s.parent=none') | ||||
| 	} | ||||
| 	info := s.info as Struct | ||||
|  | @ -296,7 +300,7 @@ pub fn (t mut Table) register_type(typ Type) int { | |||
| 				// panic('cannot register type `$typ.name`, another type with this name exists')
 | ||||
| 				return -1 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	} | ||||
| 	typ_idx := t.types.len | ||||
| 	t.types << typ | ||||
|  | @ -312,7 +316,7 @@ pub fn (t &Table) known_type(name string) bool { | |||
| } | ||||
| 
 | ||||
| pub fn (t mut Table) find_or_register_map(key_type TypeRef, value_type TypeRef) int { | ||||
| 	name := map_name(&key_type, &value_type)  | ||||
| 	name := map_name(&key_type, &value_type) | ||||
| 	// existing
 | ||||
| 	existing_idx := t.type_idxs[name] | ||||
| 	if existing_idx > 0 { | ||||
|  | @ -352,7 +356,7 @@ pub fn (t mut Table) find_or_register_array(elem_type TypeRef, nr_dims int) int | |||
| } | ||||
| 
 | ||||
| pub fn (t mut Table) find_or_register_array_fixed(elem_type TypeRef, size int, nr_dims int) int { | ||||
| 	name := array_fixed_name(&elem_type, size, nr_dims)  | ||||
| 	name := array_fixed_name(&elem_type, size, nr_dims) | ||||
| 	// existing
 | ||||
| 	existing_idx := t.type_idxs[name] | ||||
| 	if existing_idx > 0 { | ||||
|  | @ -428,6 +432,9 @@ pub fn (t &Table) check(got, expected &TypeRef) bool { | |||
| 	if expected.typ.kind == .voidptr { | ||||
| 		return true | ||||
| 	} | ||||
| 	if expected.typ.kind == .byteptr && got.typ.kind == .voidptr { | ||||
| 		return true | ||||
| 	} | ||||
| 	// if expected.name == 'array' {
 | ||||
| 	// return true
 | ||||
| 	// }
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue