checker: remove hack and enforce type checking
							parent
							
								
									fa5fcee584
								
							
						
					
					
						commit
						a8c92e6dff
					
				| 
						 | 
				
			
			@ -151,9 +151,10 @@ TODO
 | 
			
		|||
*/
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn v_calloc(n int) byteptr {
 | 
			
		||||
	return C.calloc(n, 1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn vcalloc(n int) byteptr {
 | 
			
		||||
	if n <= 0 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,15 @@
 | 
			
		|||
module builtin
 | 
			
		||||
 | 
			
		||||
// <string.h>
 | 
			
		||||
fn C.memcpy(byteptr, byteptr, int) voidptr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fn C.memmove(byteptr, byteptr, int) voidptr
 | 
			
		||||
fn C.calloc(int)  byteptr
 | 
			
		||||
// fn C.malloc(int) byteptr
 | 
			
		||||
fn C.malloc(int) byteptr
 | 
			
		||||
fn C.realloc(a byteptr, b int) byteptr
 | 
			
		||||
fn C.free(ptr voidptr)
 | 
			
		||||
fn C.exit(code int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fn C.qsort(voidptr, int, int, voidptr)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,6 +149,7 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
 | 
			
		|||
 | 
			
		||||
pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
 | 
			
		||||
	// println('checker: infix expr(op $infix_expr.op.str())')
 | 
			
		||||
	c.expected_type = table.void_type
 | 
			
		||||
	left_type := c.expr(infix_expr.left)
 | 
			
		||||
	infix_expr.left_type = left_type
 | 
			
		||||
	c.expected_type = left_type
 | 
			
		||||
| 
						 | 
				
			
			@ -156,29 +157,35 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
 | 
			
		|||
	infix_expr.right_type = right_type
 | 
			
		||||
	right := c.table.get_type_symbol(right_type)
 | 
			
		||||
	left := c.table.get_type_symbol(left_type)
 | 
			
		||||
	if infix_expr.op == .key_in && !(right.kind in [.array, .map, .string]) {
 | 
			
		||||
		c.error('`in` can only be used with an array/map/string.', infix_expr.pos)
 | 
			
		||||
	}
 | 
			
		||||
	if infix_expr.op == .left_shift {
 | 
			
		||||
		if left.kind != .array && !left.is_int() {
 | 
			
		||||
			//c.error('<< can only be used with numbers and arrays', infix_expr.pos)
 | 
			
		||||
			c.error('incompatible types: $left.name << $right.name', infix_expr.pos)
 | 
			
		||||
			return table.void_type
 | 
			
		||||
		}
 | 
			
		||||
		if left.kind == .array && infix_expr.op == .left_shift {
 | 
			
		||||
		if left.kind == .array {
 | 
			
		||||
			// `array << elm`
 | 
			
		||||
			// the expressions have different types (array_x and x)
 | 
			
		||||
			if right.kind != .array && !c.table.check(c.table.value_type(left_type), right_type) {
 | 
			
		||||
				c.error('incompatible types: $left.name << $right.name', infix_expr.pos)
 | 
			
		||||
			if c.table.check(c.table.value_type(left_type), right_type) {
 | 
			
		||||
				// []T << T
 | 
			
		||||
				return table.void_type
 | 
			
		||||
			}
 | 
			
		||||
			if right.kind == .array && c.table.check(c.table.value_type(left_type), c.table.value_type(right_type)) {
 | 
			
		||||
				// []T << []T
 | 
			
		||||
				return table.void_type
 | 
			
		||||
			}
 | 
			
		||||
			c.error('incompatible types: $left.name << $right.name', infix_expr.pos)
 | 
			
		||||
			return table.void_type
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if !c.table.check(right_type, left_type) {
 | 
			
		||||
		// `elm in array`
 | 
			
		||||
		if right.kind in [.array, .map] && infix_expr.op == .key_in {
 | 
			
		||||
			return table.bool_type
 | 
			
		||||
	if infix_expr.op == .key_in {
 | 
			
		||||
		if !(right.kind in [.array, .map, .string]) {
 | 
			
		||||
			c.error('`in` can only be used with an array/map/string.', infix_expr.pos)
 | 
			
		||||
		}
 | 
			
		||||
		// fot type-unresolved consts
 | 
			
		||||
		return table.bool_type
 | 
			
		||||
	}
 | 
			
		||||
	if !c.table.check(right_type, left_type) {
 | 
			
		||||
		// for type-unresolved consts
 | 
			
		||||
		if left_type == table.void_type || right_type == table.void_type {
 | 
			
		||||
			return table.void_type
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +198,7 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn (c mut Checker) assign_expr(assign_expr mut ast.AssignExpr) {
 | 
			
		||||
	c.expected_type = table.void_type
 | 
			
		||||
	left_type := c.expr(assign_expr.left)
 | 
			
		||||
	c.expected_type = left_type
 | 
			
		||||
	assign_expr.left_type = left_type
 | 
			
		||||
| 
						 | 
				
			
			@ -291,17 +299,6 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
 | 
			
		|||
		if fn_name == 'typeof' {
 | 
			
		||||
			return table.string_type
 | 
			
		||||
		}
 | 
			
		||||
		// start hack: until v1 is fixed and c definitions are added for these
 | 
			
		||||
		if fn_name in ['C.calloc', 'C.malloc', 'C.exit', 'C.free'] {
 | 
			
		||||
			for arg in call_expr.args {
 | 
			
		||||
				c.expr(arg.expr)
 | 
			
		||||
			}
 | 
			
		||||
			if fn_name in ['C.calloc', 'C.malloc'] {
 | 
			
		||||
				return table.byteptr_type
 | 
			
		||||
			}
 | 
			
		||||
			return table.void_type
 | 
			
		||||
		}
 | 
			
		||||
		// end hack
 | 
			
		||||
		// look for function in format `mod.fn` or `fn` (main/builtin)
 | 
			
		||||
		mut f := table.Fn{}
 | 
			
		||||
		mut found := false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue