From e3687dc2575a3748fda49995c2bb90f514a77bd4 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 8 Mar 2020 22:11:56 +0100 Subject: [PATCH] checker: check C args --- vlib/builtin/array.v | 22 ++++++++++++---------- vlib/v/checker/checker.v | 12 ++++++------ vlib/v/gen/cgen.v | 2 ++ vlib/v/gen/tests/1.c | 1 + vlib/v/gen/tests/1.vv | 3 +++ 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 407f46318a..b5cb6b1db0 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -311,18 +311,20 @@ fn (a mut array) push(val voidptr) { // `val` is array.data // TODO make private, right now it's used by strings.Builder -pub fn (a mut array) push_many(val voidptr, size int) { - // handle `arr << arr` - if a.data == val { - copy := a.clone() - a.ensure_cap(a.len + size) +pub fn (a3 mut array) push_many(val voidptr, size int) { + if a3.data == val { + // handle `arr << arr` + copy := a3.clone() + a3.ensure_cap(a3.len + size) + C.printf("%d", a3.len*2) + println(a3.len*2) //C.memcpy(a.data, copy.data, copy.element_size * copy.len) - C.memcpy(a.data + a.element_size * a.len, copy.data, a.element_size * size) + C.memcpy(a3.data + a3.element_size * a3.len, copy.data, a3.element_size * size) } else { - a.ensure_cap(a.len + size) - C.memcpy(a.data + a.element_size * a.len, val, a.element_size * size) + a3.ensure_cap(a3.len + size) + C.memcpy(a3.data + a3.element_size * a3.len, val, a3.element_size * size) } - a.len += size + a3.len += size } // array.reverse returns a new array with the elements of @@ -578,7 +580,7 @@ pub fn compare_f32(a, b &f32) int { return 0 } -// a.pointers() returns a new array, where each element +// a.pointers() returns a new array, where each element // is the address of the corresponding element in a. pub fn (a array) pointers() []voidptr { mut res := []voidptr diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 9ccd8d9752..215c4fe00d 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -207,6 +207,9 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { c.error('unknown fn: $fn_name', call_expr.pos) } if f.is_c || call_expr.is_c { + for expr in call_expr.args { + c.expr(expr) + } return f.return_type } if call_expr.args.len < f.args.len { @@ -303,6 +306,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr) pub fn (c mut Checker) selector_expr(selector_expr mut ast.SelectorExpr) table.Type { typ := c.expr(selector_expr.expr) selector_expr.expr_type = typ + // println('sel expr line_nr=$selector_expr.pos.line_nr typ=$selector_expr.expr_type') typ_sym := c.table.get_type_symbol(typ) field_name := selector_expr.field if field := typ_sym.find_field(field_name) { @@ -322,10 +326,6 @@ pub fn (c mut Checker) selector_expr(selector_expr mut ast.SelectorExpr) table.T } } if typ_sym.kind != .struct_ { - if field_name == 'default_mode' { - // TODO - return table.bool_type - } c.error('`$typ_sym.name` is not a struct', selector_expr.pos) } else { @@ -632,7 +632,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { } pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type { - // println('IDENT: $it.name - $it.pos.pos') + // println('IDENT: $ident.name - $ident.pos.pos') if ident.kind == .variable { // println('===========================') // c.scope.print_vars(0) @@ -656,7 +656,7 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type { // update the variable // we need to do this here instead of var_decl since some // vars are registered manually for things like for loops etc - // NOTE: or consider making those declerations part of those ast nodes + // NOTE: or consider making those declarations part of those ast nodes mut typ := var.typ // set var type on first use if typ == 0 { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 2d992b1e15..9740bcc2b1 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -622,6 +622,8 @@ fn (g mut Gen) expr(node ast.Expr) { g.write('sizeof($it.type_name)') } ast.StringLiteral { + // In C calls we have to generate C strings + // `C.printf("hi")` => `printf("hi");` if g.is_c_call { g.write('"$it.val"') } diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index 33e492e5c3..f9ff171db6 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -94,6 +94,7 @@ i < 10; i++) { } void User_inc_age(User* u, int n) { + printf("%d", u->age); u->age += n; } diff --git a/vlib/v/gen/tests/1.vv b/vlib/v/gen/tests/1.vv index 0d632c7f57..b423dbdb2e 100644 --- a/vlib/v/gen/tests/1.vv +++ b/vlib/v/gen/tests/1.vv @@ -91,7 +91,10 @@ fn foo(a int) { } +fn C.printf() + fn (u mut User) inc_age(n int) { + C.printf("%d", u.age) u.age += n }