diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 362b2e3ff2..2660eab63a 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -8,15 +8,15 @@ import ( v.table ) -pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | -FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | -AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | -CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | +pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | +FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | +AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | +CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | ConcatExpr | Type | AsCast -pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | -ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | -HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | +pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | +ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | +HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | LineComment | MultiLineComment | AssertStmt | UnsafeStmt // pub type Type = StructType | ArrayType // pub struct StructType { @@ -278,8 +278,9 @@ pub: op token.Kind pos token.Position left Expr - left_type table.Type right Expr + mut: + left_type table.Type right_type table.Type } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index d23822c06e..dfca62f9fc 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -120,9 +120,10 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type return struct_init.typ } -pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) 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())') left_type := c.expr(infix_expr.left) + infix_expr.left_type = left_type c.expected_type = left_type right_type := c.expr(infix_expr.right) if !c.table.check(right_type, left_type) { @@ -429,7 +430,7 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { else { c.error('expecting `int` for fixed size', array_init.pos) } - } + } idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size, 1) array_type := table.new_type(idx) array_init.typ = array_type @@ -569,7 +570,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { return c.index_expr(mut it) } ast.InfixExpr { - return c.infix_expr(it) + return c.infix_expr(mut it) } ast.IntegerLiteral { return table.int_type @@ -808,7 +809,7 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { else {} } if !is_range { - node.container_type = typ + node.container_type = typ typ_sym := c.table.get_type_symbol(typ) index_type := c.expr(node.index) index_type_sym := c.table.get_type_symbol(index_type) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index bfcff3582a..8eb9ae0cb2 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -476,15 +476,23 @@ fn (g mut Gen) expr(node ast.Expr) { g.index_expr(it) } ast.InfixExpr { - g.expr(it.left) - // if it.op == .dot { - // println('!! dot') - // } - g.write(' $it.op.str() ') - g.expr(it.right) - // if typ.name != typ2.name { - // verror('bad types $typ.name $typ2.name') + // if it.left_type == table.string_type_idx { + // g.write('/*$it.left_type str*/') // } + if it.op == .plus && it.left_type == table.string_type_idx { + g.write('string_add(') + g.expr(it.left) + g.write(', ') + g.expr(it.right) + } + else { + // if it.op == .dot { + // println('!! dot') + // } + g.expr(it.left) + g.write(' $it.op.str() ') + g.expr(it.right) + } } ast.IntegerLiteral { g.write(it.val.str()) diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index 300f6cc1f6..825c9a99c5 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -88,6 +88,8 @@ i < 10; i++) { bool b2 = array_get(bools, 0) || true; bool b3 = get_bool() || true; int f = array_int_first(nums); + string d = tos3("d"); + println(string_add(s + d)); } void User_inc_age(User u, int n) { diff --git a/vlib/v/gen/tests/1.vv b/vlib/v/gen/tests/1.vv index 36d9190ab5..52e59279a9 100644 --- a/vlib/v/gen/tests/1.vv +++ b/vlib/v/gen/tests/1.vv @@ -78,6 +78,8 @@ fn foo(a int) { b2 := bools[0] || true b3 := get_bool() || true f := nums.first() + d := 'd' + println(s + d) //cloned = nums.clone() //cloned1 := cloned[0] //println(cloned1 == 1) diff --git a/vlib/v/gen/tests/4.c b/vlib/v/gen/tests/4.c index dffbee6898..dea218e977 100644 --- a/vlib/v/gen/tests/4.c +++ b/vlib/v/gen/tests/4.c @@ -18,9 +18,9 @@ multi_return_int_string mr_test(); int testa(); string testb(int a); int testc(int a); -int Foo_testa(Foo f); -int Foo_testb(Foo f); -int Bar_testa(Bar b); +int Foo_testa(Foo* f); +int Foo_testb(Foo* f); +int Bar_testa(Bar* b); int main() { Bar b = (Bar){ @@ -71,16 +71,16 @@ int testc(int a) { return a; } -int Foo_testa(Foo f) { +int Foo_testa(Foo* f) { int a = Foo_testb(f); a = 1; return 4; } -int Foo_testb(Foo f) { +int Foo_testb(Foo* f) { return 4; } -int Bar_testa(Bar b) { +int Bar_testa(Bar* b) { return 4; }