checker: print multiple errors; none
							parent
							
								
									d91945cc99
								
							
						
					
					
						commit
						ec3d67c19f
					
				|  | @ -148,7 +148,9 @@ fn (m map) get(key string, out voidptr) bool { | |||
| 	mut node := m.root | ||||
| 	for { | ||||
| 		mut i := node.size - 1 | ||||
| 		for i >= 0 && key < node.keys[i] { i-- } | ||||
| 		for i >= 0 && key < node.keys[i] { | ||||
| 			i-- | ||||
| 		} | ||||
| 		if i != -1 && key == node.keys[i] { | ||||
| 			C.memcpy(out, node.values[i], m.value_bytes) | ||||
| 			return true | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ import ( | |||
| pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | 	 | ||||
| FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | 	 | ||||
| AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | 	 | ||||
| CastExpr | EnumVal | Assoc | SizeOf | ||||
| CastExpr | EnumVal | Assoc | SizeOf | None | ||||
| 
 | ||||
| pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | 	 | ||||
| ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | 	 | ||||
|  | @ -473,6 +473,10 @@ pub: | |||
| 	text string | ||||
| } | ||||
| 
 | ||||
| pub struct None { | ||||
| pub: | ||||
| 	foo int // todo
 | ||||
| } | ||||
| // string representaiton of expr
 | ||||
| pub fn (x Expr) str() string { | ||||
| 	match x { | ||||
|  |  | |||
|  | @ -11,11 +11,16 @@ import ( | |||
| 	filepath | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	max_nr_errors = 10 | ||||
| ) | ||||
| 
 | ||||
| pub struct Checker { | ||||
| 	table     &table.Table | ||||
| mut: | ||||
| 	file_name string | ||||
| 	scope     &ast.Scope | ||||
| 	nr_errors int | ||||
| } | ||||
| 
 | ||||
| pub fn new_checker(table &table.Table) Checker { | ||||
|  | @ -86,11 +91,16 @@ pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type { | |||
| 	left_type := c.expr(infix_expr.left) | ||||
| 	right_type := c.expr(infix_expr.right) | ||||
| 	if !c.table.check(right_type, left_type) { | ||||
| 		left_type_sym := c.table.get_type_symbol(left_type) | ||||
| 		right_type_sym := c.table.get_type_symbol(right_type) | ||||
| 		left := c.table.get_type_symbol(left_type) | ||||
| 		right := c.table.get_type_symbol(right_type) | ||||
| 		// array << elm
 | ||||
| 		// the expressions have different types (array_x and x)
 | ||||
| 		if left.kind == .array && infix_expr.op == .left_shift { | ||||
| 			return table.void_type | ||||
| 		} | ||||
| 		// if !c.table.check(&infix_expr.right_type, &infix_expr.right_type) {
 | ||||
| 		// c.error('infix expr: cannot use `$infix_expr.right_type.name` as `$infix_expr.left_type.name`', infix_expr.pos)
 | ||||
| 		c.error('infix expr: cannot use `$right_type_sym.name` as `$left_type_sym.name`', infix_expr.pos) | ||||
| 		c.error('infix expr: cannot use `$right.name` (right) as `$left.name`', infix_expr.pos) | ||||
| 	} | ||||
| 	if infix_expr.op.is_relational() { | ||||
| 		return table.bool_type | ||||
|  | @ -367,6 +377,9 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { | |||
| 		ast.CastExpr { | ||||
| 			return it.typ | ||||
| 		} | ||||
| 		ast.None { | ||||
| 			return  table.none_type | ||||
| 		} | ||||
| 		else {} | ||||
| 	} | ||||
| 	return table.void_type | ||||
|  | @ -570,14 +583,15 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type { | |||
| 		else if typ_sym.kind in [.byteptr, .string] { | ||||
| 			return table.byte_type | ||||
| 		} | ||||
| 		//else {
 | ||||
| 		//	return table.int_type
 | ||||
| 		//}
 | ||||
| 		// else {
 | ||||
| 		// return table.int_type
 | ||||
| 		// }
 | ||||
| 	} | ||||
| 	return typ | ||||
| } | ||||
| 
 | ||||
| pub fn (c &Checker) error(s string, pos token.Position) { | ||||
| pub fn (c mut Checker) error(s string, pos token.Position) { | ||||
| 	c.nr_errors++ | ||||
| 	print_backtrace() | ||||
| 	mut path := c.file_name | ||||
| 	// Get relative path
 | ||||
|  | @ -585,7 +599,7 @@ pub fn (c &Checker) error(s string, pos token.Position) { | |||
| 	if path.starts_with(workdir) { | ||||
| 		path = path.replace(workdir, '') | ||||
| 	} | ||||
| 	final_msg_line := '$path:$pos.line_nr: checker error: $s' | ||||
| 	final_msg_line := '$path:$pos.line_nr: checker error #$c.nr_errors: $s' | ||||
| 	eprintln(final_msg_line) | ||||
| 	/* | ||||
| 	if colored_output { | ||||
|  | @ -595,5 +609,8 @@ pub fn (c &Checker) error(s string, pos token.Position) { | |||
| 	} | ||||
| 	*/ | ||||
| 
 | ||||
| 	exit(1) | ||||
| 	println('\n\n') | ||||
| 	if c.nr_errors >= max_nr_errors { | ||||
| 		exit(1) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -128,31 +128,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) { | |||
| 			f.writeln('') | ||||
| 		} | ||||
| 		ast.FnDecl { | ||||
| 			mut receiver := '' | ||||
| 			if it.is_method { | ||||
| 				sym := f.table.get_type_symbol(it.receiver.typ) | ||||
| 				name := sym.name.after('.') | ||||
| 				m := if it.rec_mut { 'mut ' } else { '' } | ||||
| 				receiver = '($it.receiver.name ${m}$name) ' | ||||
| 			} | ||||
| 			f.write('fn ${receiver}${it.name}(') | ||||
| 			for i, arg in it.args { | ||||
| 				is_last_arg := i == it.args.len - 1 | ||||
| 				should_add_type := is_last_arg || it.args[i + 1].typ != arg.typ | ||||
| 				f.write(arg.name) | ||||
| 				if should_add_type { | ||||
| 					arg_typ_sym := f.table.get_type_symbol(arg.typ) | ||||
| 					f.write(' ${arg_typ_sym.name}') | ||||
| 				} | ||||
| 				if !is_last_arg { | ||||
| 					f.write(', ') | ||||
| 				} | ||||
| 			} | ||||
| 			f.write(')') | ||||
| 			if it.typ != table.void_type { | ||||
| 				sym := f.table.get_type_symbol(it.typ) | ||||
| 				f.write(' ' + sym.name) | ||||
| 			} | ||||
| 			f.write(it.str(f.table)) | ||||
| 			f.writeln(' {') | ||||
| 			f.stmts(it.stmts) | ||||
| 			f.writeln('}\n') | ||||
|  |  | |||
|  | @ -68,3 +68,7 @@ fn fn_with_3_args(arg1 string, arg2 int, arg3 User) int { | |||
| fn (this User) fn_with_receiver() { | ||||
| 	println('') | ||||
| } | ||||
| 
 | ||||
| //fn get_user() ?User {
 | ||||
| 
 | ||||
| //}
 | ||||
|  |  | |||
|  | @ -72,3 +72,7 @@ return 0 | |||
| fn    (this User) fn_with_receiver() { | ||||
| println('') | ||||
| } | ||||
| 
 | ||||
| //fn get_user() ? User {
 | ||||
| 
 | ||||
| //}
 | ||||
|  |  | |||
|  | @ -134,6 +134,8 @@ const ( | |||
| ) | ||||
| 
 | ||||
| fn end() { | ||||
| 	//mut a := [1,2,3]
 | ||||
| 	//(a << 4) + 2
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -56,7 +56,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { | |||
| 		pref: &pref.Preferences{} | ||||
| 		scope: scope | ||||
| 		// scope: &ast.Scope{start_pos: 0, parent: 0}
 | ||||
| 		 | ||||
| 
 | ||||
| 	} | ||||
| 	p.init_parse_fns() | ||||
| 	p.read_first_token() | ||||
|  | @ -320,7 +320,7 @@ pub fn (p mut Parser) stmt() ast.Stmt { | |||
| 			return ast.ExprStmt{ | ||||
| 				expr: expr | ||||
| 				// typ: typ
 | ||||
| 				 | ||||
| 
 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | @ -638,6 +638,8 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) { | |||
| 		} | ||||
| 		.key_none { | ||||
| 			p.next() | ||||
| 			typ = table.none_type | ||||
| 			node = ast.None {} | ||||
| 		} | ||||
| 		.key_sizeof { | ||||
| 			p.next() // sizeof
 | ||||
|  | @ -1072,10 +1074,10 @@ fn (p mut Parser) if_expr() ast.Expr { | |||
| 		stmts: stmts | ||||
| 		else_stmts: else_stmts | ||||
| 		// typ: typ
 | ||||
| 		 | ||||
| 
 | ||||
| 		pos: pos | ||||
| 		// left: left
 | ||||
| 		 | ||||
| 
 | ||||
| 	} | ||||
| 	return node | ||||
| } | ||||
|  | @ -1463,10 +1465,10 @@ fn (p mut Parser) var_decl() ast.VarDecl { | |||
| 	node := ast.VarDecl{ | ||||
| 		name: name | ||||
| 		expr: expr // p.expr(token.lowest_prec)
 | ||||
| 		 | ||||
| 
 | ||||
| 		is_mut: is_mut | ||||
| 		// typ: typ
 | ||||
| 		 | ||||
| 
 | ||||
| 		pos: p.tok.position() | ||||
| 	} | ||||
| 	p.scope.register_var(node) | ||||
|  | @ -1585,7 +1587,7 @@ fn (p mut Parser) match_expr() ast.Expr { | |||
| 		blocks: blocks | ||||
| 		match_exprs: match_exprs | ||||
| 		// typ: typ
 | ||||
| 		 | ||||
| 
 | ||||
| 		cond: cond | ||||
| 	} | ||||
| 	return node | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ pub const ( | |||
| 	string_type_idx = 17 | ||||
| 	array_type_idx = 18 | ||||
| 	map_type_idx = 19 | ||||
| 	none_type_idx = 20 | ||||
| ) | ||||
| 
 | ||||
| pub const ( | ||||
|  | @ -81,6 +82,7 @@ pub enum Kind { | |||
| 	sum_type | ||||
| 	alias | ||||
| 	unresolved | ||||
| 	none_ | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
|  | @ -236,6 +238,10 @@ pub fn (t mut Table) register_builtin_type_symbols() { | |||
| 		kind: .map | ||||
| 		name: 'map' | ||||
| 	}) | ||||
| 	t.register_type_symbol(TypeSymbol{ | ||||
| 		kind: .none_ | ||||
| 		name: 'none' | ||||
| 	}) | ||||
| 	// TODO: remove
 | ||||
| 	t.register_type_symbol(TypeSymbol{ | ||||
| 		parent_idx: map_type_idx | ||||
|  |  | |||
|  | @ -2,9 +2,12 @@ | |||
| // Use of this source code is governed by an MIT license
 | ||||
| // that can be found in the LICENSE file.
 | ||||
| module table | ||||
| // import (
 | ||||
| // v.ast
 | ||||
| // )
 | ||||
| 
 | ||||
| import ( | ||||
| 	v.token | ||||
| 	// v.ast
 | ||||
| ) | ||||
| 
 | ||||
| pub struct Table { | ||||
| 	// struct_fields map[string][]string
 | ||||
| pub mut: | ||||
|  | @ -361,6 +364,10 @@ pub fn (t &Table) check(got, expected Type) bool { | |||
| 	got_idx := type_idx(got) | ||||
| 	exp_idx := type_idx(expected) | ||||
| 	// println('check: $got_type_sym.name, $exp_type_sym.name')
 | ||||
| 	if got_type_sym.kind == .none_ { | ||||
| 		// TODO
 | ||||
| 		return true | ||||
| 	} | ||||
| 	if exp_type_sym.kind == .voidptr { | ||||
| 		return true | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,87 +1,87 @@ | |||
| module table | ||||
| 
 | ||||
| pub type Type int | ||||
| 
 | ||||
| // return underlying TypeSymbol idx
 | ||||
| [inline] | ||||
| pub fn type_idx(t Type) int { | ||||
|     return i16(int(t) >> 16) & 0xffffffff | ||||
| 	return i16(int(t)>>16) & 0xffffffff | ||||
| } | ||||
| 
 | ||||
| // return nr_muls
 | ||||
| [inline] | ||||
| pub fn type_nr_muls(t Type) int { | ||||
|     return i16(int(t) & 0xffffffff) | ||||
| 	return i16(int(t) & 0xffffffff) | ||||
| } | ||||
| 
 | ||||
| // return true if pointer (nr_muls>0)
 | ||||
| [inline] | ||||
| pub fn type_is_ptr(t Type) bool { | ||||
|     return type_nr_muls(t) > 0 | ||||
| 	return type_nr_muls(t) > 0 | ||||
| } | ||||
| 
 | ||||
| // increments nr_nuls on Type and return it
 | ||||
| [inline] | ||||
| pub fn type_to_ptr(t Type) Type { | ||||
|     return type_idx(t) << i16(16) | (type_nr_muls(t)+1) | ||||
| 	return type_idx(t)<<i16(16) | (type_nr_muls(t) + 1) | ||||
| } | ||||
| 
 | ||||
| // decrement nr_muls on Type and return it
 | ||||
| [inline] | ||||
| pub fn type_deref(t Type) Type { | ||||
|     idx := type_idx(t) | ||||
|     nr_muls := type_nr_muls(t) | ||||
|     if nr_muls == 0 { | ||||
|         panic('deref: $idx is not a pointer') | ||||
|     } | ||||
|     return idx << i16(16) | (nr_muls+-1) | ||||
| 	idx := type_idx(t) | ||||
| 	nr_muls := type_nr_muls(t) | ||||
| 	if nr_muls == 0 { | ||||
| 		panic('deref: $idx is not a pointer') | ||||
| 	} | ||||
| 	return idx<<i16(16) | (nr_muls + -1) | ||||
| } | ||||
| 
 | ||||
| // new type with idx of TypeSymbol, not pointer (nr_muls=0)
 | ||||
| [inline] | ||||
| pub fn new_type(idx int) Type { | ||||
|     if idx > 32767 || idx < -32767 { | ||||
|         panic('new_type_id: idx must be between -32767 & 32767') | ||||
|     } | ||||
|     return idx << i16(16) | ||||
| 	if idx > 32767 || idx < -32767 { | ||||
| 		panic('new_type_id: idx must be between -32767 & 32767') | ||||
| 	} | ||||
| 	return idx<<i16(16) | ||||
| } | ||||
| 
 | ||||
| // return Type idx of TypeSymbol & specify if ptr (nr_muls)
 | ||||
| [inline] | ||||
| pub fn new_type_ptr(idx, nr_muls int) Type { | ||||
|     if idx > 32767 || idx < -32767 { | ||||
|         panic('typ_ptr: idx must be between -32767 & 32767') | ||||
|     } | ||||
|     if nr_muls > 32767 || nr_muls < -0 { | ||||
|         panic('typ_ptr: nr_muls must be between 0 & 32767') | ||||
|     } | ||||
|     return idx << i16(16) | nr_muls | ||||
| 	if idx > 32767 || idx < -32767 { | ||||
| 		panic('typ_ptr: idx must be between -32767 & 32767') | ||||
| 	} | ||||
| 	if nr_muls > 32767 || nr_muls < -0 { | ||||
| 		panic('typ_ptr: nr_muls must be between 0 & 32767') | ||||
| 	} | ||||
| 	return idx<<i16(16) | nr_muls | ||||
| } | ||||
| 
 | ||||
| // true if the type of unresolved expression
 | ||||
| [inline] | ||||
| pub fn type_is_unresolved(t Type) bool { | ||||
|     return type_idx(t) < 0 | ||||
| 	return type_idx(t) < 0 | ||||
| } | ||||
| 
 | ||||
| pub const ( | ||||
|     void_type    = new_type(void_type_idx) | ||||
|     voidptr_type = new_type(voidptr_type_idx) | ||||
|     byteptr_type = new_type(byteptr_type_idx) | ||||
|     charptr_type = new_type(charptr_type_idx) | ||||
|     i8_type      = new_type(i8_type_idx) | ||||
|     int_type     = new_type(int_type_idx) | ||||
|     i16_type     = new_type(i16_type_idx) | ||||
|     i64_type     = new_type(i64_type_idx) | ||||
|     byte_type    = new_type(byte_type_idx) | ||||
|     u16_type     = new_type(u16_type_idx) | ||||
|     u32_type     = new_type(u32_type_idx) | ||||
|     u64_type     = new_type(u64_type_idx) | ||||
|     f32_type     = new_type(f32_type_idx) | ||||
|     f64_type     = new_type(f64_type_idx) | ||||
|     char_type    = new_type(char_type_idx) | ||||
|     bool_type    = new_type(bool_type_idx) | ||||
|     string_type  = new_type(string_type_idx) | ||||
|     array_type   = new_type(array_type_idx) | ||||
|     map_type     = new_type(map_type_idx) | ||||
| 	void_type = new_type(void_type_idx) | ||||
| 	voidptr_type = new_type(voidptr_type_idx) | ||||
| 	byteptr_type = new_type(byteptr_type_idx) | ||||
| 	charptr_type = new_type(charptr_type_idx) | ||||
| 	i8_type = new_type(i8_type_idx) | ||||
| 	int_type = new_type(int_type_idx) | ||||
| 	i16_type = new_type(i16_type_idx) | ||||
| 	i64_type = new_type(i64_type_idx) | ||||
| 	byte_type = new_type(byte_type_idx) | ||||
| 	u16_type = new_type(u16_type_idx) | ||||
| 	u32_type = new_type(u32_type_idx) | ||||
| 	u64_type = new_type(u64_type_idx) | ||||
| 	f32_type = new_type(f32_type_idx) | ||||
| 	f64_type = new_type(f64_type_idx) | ||||
| 	char_type = new_type(char_type_idx) | ||||
| 	bool_type = new_type(bool_type_idx) | ||||
| 	string_type = new_type(string_type_idx) | ||||
| 	array_type = new_type(array_type_idx) | ||||
| 	map_type = new_type(map_type_idx) | ||||
| 	none_type = new_type(none_type_idx) | ||||
| ) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue