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