diff --git a/vlib/math/unsafe.v b/vlib/math/unsafe.v index 87200d2248..55b2dfc85c 100644 --- a/vlib/math/unsafe.v +++ b/vlib/math/unsafe.v @@ -6,7 +6,7 @@ module math // with the sign bit of f and the result in the same bit position. // f32_bits(f32_from_bits(x)) == x. pub fn f32_bits(f f32) u32 { - p := *u32(&f) + p := &u32(&f) return *p } @@ -15,7 +15,7 @@ pub fn f32_bits(f f32) u32 { // and the result in the same bit position. // f32_from_bits(f32_bits(x)) == x. pub fn f32_from_bits(b u32) f32 { - p := *f32(&b) + p := &f32(&b) return *p } @@ -23,7 +23,7 @@ pub fn f32_from_bits(b u32) f32 { // with the sign bit of f and the result in the same bit position, // and f64_bits(f64_from_bits(x)) == x. pub fn f64_bits(f f64) u64 { - p := *u64(&f) + p := &u64(&f) return *p } @@ -32,7 +32,7 @@ pub fn f64_bits(f f64) u64 { // and the result in the same bit position. // f64_from_bits(f64_bits(x)) == x. pub fn f64_from_bits(b u64) f64 { - p := *f64(&b) + p := &f64(&b) return *p } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 7abe349870..9794f1bdbb 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -163,6 +163,7 @@ mut: name string args []Expr arg_types []table.Type + expr_types []table.Type is_c bool muts []bool or_block OrExpr @@ -183,6 +184,7 @@ mut: receiver_type table.Type // User return_type table.Type arg_types []table.Type + expr_types []table.Type } pub struct Return { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 52a2bcbc9c..7b84da073a 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -22,7 +22,7 @@ mut: errors []string expected_type table.Type fn_return_type table.Type // current function's return type - // is_amp bool + is_amp bool } pub fn new_checker(table &table.Table) Checker { @@ -86,6 +86,9 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type info := typ_sym.info as table.Struct if struct_init.fields.len == 0 { // Short syntax TODO check + if c.is_amp { + return table.type_to_ptr(struct_init.typ) + } return struct_init.typ } if struct_init.exprs.len > info.fields.len { @@ -117,6 +120,10 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type } else {} } + if c.is_amp { + println('XAXAXAX') + return table.type_to_ptr(struct_init.typ) + } return struct_init.typ } @@ -239,11 +246,14 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { return f.return_type } mut arg_types := []table.Type + mut expr_types := []table.Type for i, arg_expr in call_expr.args { arg := if f.is_variadic && i >= f.args.len - 1 { f.args[f.args.len - 1] } else { f.args[i] } c.expected_type = arg.typ typ := c.expr(arg_expr) - arg_types << typ + expr_types << typ + // arg_types << typ // arg.typ + arg_types << arg.typ typ_sym := c.table.get_type_symbol(typ) arg_typ_sym := c.table.get_type_symbol(arg.typ) if !c.table.check(typ, arg.typ) { @@ -261,6 +271,7 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { } } call_expr.arg_types = arg_types + call_expr.expr_types = expr_types return f.return_type } @@ -271,6 +282,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr) typ_sym := c.table.get_type_symbol(typ) name := method_call_expr.name mut arg_types := []table.Type + mut expr_types := []table.Type // println('method call $name $method_call_expr.pos.line_nr') if typ_sym.kind == .array && name in ['filter', 'clone', 'repeat'] { if name == 'filter' { @@ -307,11 +319,12 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr) for i, arg_expr in method_call_expr.args { c.expected_type = method.args[i + 1].typ arg_types << c.expected_type - c.expr(arg_expr) + expr_types << c.expr(arg_expr) } method_call_expr.receiver_type = method.args[0].typ method_call_expr.return_type = method.return_type method_call_expr.arg_types = arg_types + method_call_expr.expr_types = expr_types return method.return_type } c.error('type `$typ_sym.name` has no method `$name`', method_call_expr.pos) @@ -643,7 +656,12 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { return c.postfix_expr(it) } ast.PrefixExpr { - return c.expr(it.right) + if it.op == .amp { + c.is_amp = true + } + res := c.expr(it.right) + c.is_amp = false + return res } ast.None { return table.none_type @@ -888,10 +906,6 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { return info.value_type } else if typ_sym.kind in [.byteptr, .string] { - // TODO: hack need to handle &a[0] comment to see wyahsh errors - if typ_sym.kind == .byteptr { - return table.type_to_ptr(table.byte_type) - } return table.byte_type } else if table.type_is_ptr(typ) { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 171e577b8c..94553bd89f 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -67,6 +67,7 @@ pub fn (g &Gen) styp(t string) string { } */ + pub fn (g mut Gen) write_typedef_types() { for typ in g.table.types { match typ.kind { @@ -95,7 +96,7 @@ pub fn (g mut Gen) write_typedef_types() { else { continue } - } + } } } @@ -524,7 +525,7 @@ fn (g mut Gen) expr(node ast.Expr) { g.write('))') } else { - g.call_args(it.args, it.muts, it.arg_types) + g.call_args(it.args, it.muts, it.arg_types, it.expr_types) g.write(')') } g.is_c_call = false @@ -730,8 +731,12 @@ fn (g mut Gen) expr(node ast.Expr) { if table.type_is_ptr(it.receiver_type) && !table.type_is_ptr(it.expr_type) { // The receiver is a reference, but the caller provided a value // Add `&` automatically. + // TODO same logic in call_args() g.write('&') } + else if !table.type_is_ptr(it.receiver_type) && table.type_is_ptr(it.expr_type) { + g.write('/*rec*/*') + } g.expr(it.expr) if it.args.len > 0 { g.write(', ') @@ -748,7 +753,7 @@ fn (g mut Gen) expr(node ast.Expr) { } */ // /////// - g.call_args(it.args, it.muts, it.arg_types) + g.call_args(it.args, it.muts, it.arg_types, it.expr_types) g.write(')') } ast.None { @@ -1018,17 +1023,22 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) { } } -fn (g mut Gen) call_args(args []ast.Expr, muts []bool, arg_types []table.Type) { +fn (g mut Gen) call_args(args []ast.Expr, muts []bool, arg_types []table.Type, expr_types []table.Type) { for i, expr in args { if arg_types.len > 0 { // typ := arg_types[i] - arg_is_ptr := table.type_is_ptr(arg_types[i]) + arg_is_ptr := table.type_is_ptr(arg_types[i]) || arg_types[i] == table.voidptr_type_idx + expr_is_ptr := i < expr_types.len && table.type_is_ptr(expr_types[i]) if muts[i] && !arg_is_ptr { g.write('&/*mut*/') } - else if arg_is_ptr { + else if arg_is_ptr && !expr_is_ptr { g.write('&/*q*/') } + else if !arg_is_ptr && expr_is_ptr { + // Dereference a pointer if a value is required + g.write('*/*d*/') + } } g.expr(expr) if i != args.len - 1 { diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index 8809186bab..d54e919ae3 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -59,7 +59,7 @@ int main() { println(int_str(localmod__pub_int_const)); int g = ((int)(3.0)); byte* bytes = ((byte*)(0)); - User user_ptr = (User*)memdup(&(User){}, sizeof(User)); + User* user_ptr = (User*)memdup(&(User){}, sizeof(User)); return 0; } diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 6433904503..f4950a931c 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -32,9 +32,8 @@ pub fn type_nr_muls(t Type) int { // 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 // || t == voidptr_type_idx } - // set nr_muls on Type and return it [inline] pub fn type_set_nr_muls(t Type, nr_muls int) Type {