From a8c92e6dff40e3618b582c3397101d7322597b7b Mon Sep 17 00:00:00 2001 From: lutherwenxu Date: Tue, 7 Apr 2020 09:27:06 +0800 Subject: [PATCH] checker: remove hack and enforce type checking --- vlib/builtin/builtin.v | 3 ++- vlib/builtin/cfns.v | 5 ++++- vlib/v/checker/checker.v | 41 +++++++++++++++++++--------------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index 139e234ad9..7755dddb49 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -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 { diff --git a/vlib/builtin/cfns.v b/vlib/builtin/cfns.v index 3af7aeed08..b616319b62 100644 --- a/vlib/builtin/cfns.v +++ b/vlib/builtin/cfns.v @@ -1,12 +1,15 @@ module builtin + // 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) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index f59f1f7c9c..7f3916b228 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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