From 4161cfcdb8a981e06b18092c4e98be7980ed23cc Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 5 Mar 2020 00:43:02 +0100 Subject: [PATCH] cgen: lots of fixes --- vlib/compiler/cc.v | 1 + vlib/v/ast/ast.v | 19 +++++----- vlib/v/checker/checker.v | 3 +- vlib/v/gen/cgen.v | 82 +++++++++++++++++++++++++++++----------- vlib/v/gen/tests/1.c | 18 +++------ vlib/v/gen/tests/2.c | 4 +- vlib/v/gen/tests/2.vv | 2 +- vlib/v/gen/tests/4.c | 14 +++---- vlib/v/parser/parser.v | 28 +++++++------- 9 files changed, 104 insertions(+), 67 deletions(-) diff --git a/vlib/compiler/cc.v b/vlib/compiler/cc.v index 42ad656885..e349be0e7e 100644 --- a/vlib/compiler/cc.v +++ b/vlib/compiler/cc.v @@ -199,6 +199,7 @@ fn (v mut V) cc() { } if debug_mode { a << debug_options + a << ' -ferror-limit=5000 ' } if v.pref.is_prod { a << optimization_options diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 347e85dad6..1ed878d9fe 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 { @@ -375,7 +375,8 @@ pub struct ForCStmt { pub: init Stmt // i := 0; cond Expr // i < 10; - inc Stmt // i++; + //inc Stmt // i++; + inc Expr// i++; stmts []Stmt } @@ -388,7 +389,7 @@ pub struct ReturnStmt { // #include etc pub struct HashStmt { pub: - name string + val string } // filter(), map() diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 62fd439a26..cde13f773a 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -444,7 +444,8 @@ fn (c mut Checker) stmt(node ast.Stmt) { ast.ForCStmt { c.stmt(it.init) c.expr(it.cond) - c.stmt(it.inc) + // c.stmt(it.inc) + c.expr(it.inc) for stmt in it.stmts { c.stmt(stmt) } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index c1a15046aa..1a60d166d3 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -54,7 +54,7 @@ pub fn (g mut Gen) init() { for i, mr_typ in info.types { field_type_sym := g.table.get_type_symbol(mr_typ) type_name := field_type_sym.name.replace('.', '__') - g.definitions.writeln('\t$type_name arg_${i+1};') + g.definitions.writeln('\t$type_name arg${i};') } g.definitions.writeln('} $name;\n') // g.typedefs.writeln('typedef struct $name $name;') @@ -115,11 +115,12 @@ fn (g mut Gen) stmt(node ast.Stmt) { // TODO } ast.Attr { - g.writeln('[$it.name]') + g.writeln('//[$it.name]') } ast.BranchStmt { // continue or break - g.writeln(it.tok.str()) + g.write(it.tok.kind.str()) + g.writeln(';') } ast.ConstDecl { for i, field in it.fields { @@ -132,10 +133,10 @@ fn (g mut Gen) stmt(node ast.Stmt) { } ast.CompIf { // TODO - g.write('#ifdef ') + g.writeln('//#ifdef ') g.expr(it.cond) g.stmts(it.stmts) - g.writeln('#endif') + g.writeln('//#endif') } ast.DeferStmt { g.writeln('// defer') @@ -218,7 +219,8 @@ fn (g mut Gen) stmt(node ast.Stmt) { // g.write('; ') g.expr(it.cond) g.write('; ') - g.stmt(it.inc) + //g.stmt(it.inc) + g.expr(it.inc) g.writeln(') {') for stmt in it.stmts { g.stmt(stmt) @@ -226,7 +228,16 @@ fn (g mut Gen) stmt(node ast.Stmt) { g.writeln('}') } ast.ForInStmt { - g.writeln('for') + if it.is_range { + i := g.new_tmp_var() + g.write('for (int $i = ') + g.expr(it.cond) + g.write('; $i < ') + g.expr(it.high) + g.writeln('; $i++) { ') + // g.stmts(it.stmts) TODO + g.writeln('}') + } } ast.ForStmt { g.write('while (') @@ -245,7 +256,8 @@ fn (g mut Gen) stmt(node ast.Stmt) { g.writeln('$it.name:') } ast.HashStmt { - g.writeln('#$it.name') + // #include etc + g.writeln('#$it.val') } ast.Import {} ast.Return { @@ -303,7 +315,9 @@ fn (g mut Gen) expr(node ast.Expr) { match node { ast.ArrayInit { type_sym := g.table.get_type_symbol(it.typ) - g.writeln('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($type_sym.name), {\t') + elem_sym := g.table.get_type_symbol(it.elem_type) + g.write('new_array_from_c_array($it.exprs.len, $it.exprs.len, sizeof($type_sym.name), ') + g.writeln('(${elem_sym.name}[]){\t') for expr in it.exprs { g.expr(expr) g.write(', ') @@ -325,7 +339,11 @@ fn (g mut Gen) expr(node ast.Expr) { g.write(it.val.str()) } ast.CallExpr { - name := it.name.replace('.', '__') + mut name := it.name.replace('.', '__') + if it.is_c { + // Skip "C__" + name = name[3..] + } g.write('${name}(') g.call_args(it.args) g.write(')') @@ -367,22 +385,42 @@ fn (g mut Gen) expr(node ast.Expr) { tmp = g.new_tmp_var() // g.writeln('$ti.name $tmp;') } - g.write('if (') - g.expr(it.cond) - g.writeln(') {') - for i, stmt in it.stmts { - // Assign ret value - if i == it.stmts.len - 1 && type_sym.kind != .void {} - // g.writeln('$tmp =') - g.stmt(stmt) + // one line ?: + // TODO clean this up once `is` is supported + if it.stmts.len == 1 && it.else_stmts.len == 1 && type_sym.kind != .void { + cond := it.cond + stmt1 := it.stmts[0] + else_stmt1 := it.else_stmts[0] + match stmt1 { + ast.ExprStmt { + g.expr(cond) + g.write(' ? ') + expr_stmt := stmt1 as ast.ExprStmt + g.expr(expr_stmt.expr) + g.write(' : ') + g.stmt(else_stmt1) + } + else {} + } } - g.writeln('}') - if it.else_stmts.len > 0 { - g.writeln('else { ') - for stmt in it.else_stmts { + else { + g.write('if (') + g.expr(it.cond) + g.writeln(') {') + for i, stmt in it.stmts { + // Assign ret value + if i == it.stmts.len - 1 && type_sym.kind != .void {} + // g.writeln('$tmp =') g.stmt(stmt) } g.writeln('}') + if it.else_stmts.len > 0 { + g.writeln('else { ') + for stmt in it.else_stmts { + g.stmt(stmt) + } + g.writeln('}') + } } } ast.IfGuardExpr { diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index d891e1b3af..503e5a6cb3 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -47,23 +47,22 @@ void foo(int a) { while (true) { } for (int i = 0; -i < 10; i++; -) { +i < 10; i++) { } - array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), { + array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), (void[]){ 1, 2, 3, }); array_int nums2 = array_slice(nums, 0, 2); int number = nums[0]; - array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), { + array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (void[]){ true, false, }); - array_User users = new_array_from_c_array(1, 1, sizeof(array_User), { + array_User users = new_array_from_c_array(1, 1, sizeof(array_User), (void[]){ (User){ }, }); bool b = bools[0]; - array_string mystrings = new_array_from_c_array(2, 2, sizeof(array_string), { + array_string mystrings = new_array_from_c_array(2, 2, sizeof(array_string), (void[]){ tos3("a"), tos3("b"), }); string s = mystrings[0]; @@ -116,12 +115,7 @@ multi_return_int_string multi_return() { void variadic(variadic_int a) { int x = path_sep; - int y = if (true) { -1; -} -else { -0; -} + int y = true ? 1 : 0; ; } diff --git a/vlib/v/gen/tests/2.c b/vlib/v/gen/tests/2.c index 7b2c674c42..cd4f16e04c 100644 --- a/vlib/v/gen/tests/2.c +++ b/vlib/v/gen/tests/2.c @@ -65,8 +65,8 @@ void function2() { } void init_array() { - array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), { - 1, 2, 3, + array_int nums = new_array_from_c_array(3, 3, sizeof(array_int), (void[]){ + 4, 2, 3, }); } diff --git a/vlib/v/gen/tests/2.vv b/vlib/v/gen/tests/2.vv index ab53242700..e0dee60fe9 100644 --- a/vlib/v/gen/tests/2.vv +++ b/vlib/v/gen/tests/2.vv @@ -61,7 +61,7 @@ fn function2() { } fn init_array() { - nums := [1,2,3] + nums := [4,2,3] } diff --git a/vlib/v/gen/tests/4.c b/vlib/v/gen/tests/4.c index 22870f62ea..9b6335bedf 100644 --- a/vlib/v/gen/tests/4.c +++ b/vlib/v/gen/tests/4.c @@ -24,14 +24,14 @@ int main() { d = tos3("hello"); string e = tos3("hello"); e = testb(111); - e = tos3("world"); - array_int f = new_array_from_c_array(4, 4, sizeof(array_int), { + e = tos3("world"); + array_int f = new_array_from_c_array(4, 4, sizeof(array_int), (void[]){ testa(), 2, 3, 4, - }); - array_string g = new_array_from_c_array(2, 2, sizeof(array_string), { - testb(1), tos3("hello"), - }); - array_Foo arr_foo = new_array_from_c_array(1, 1, sizeof(array_Foo), { + }); + array_string g = new_array_from_c_array(2, 2, sizeof(array_string), (void[]){ + testb(1), tos3("hello"), + }); + array_Foo arr_foo = new_array_from_c_array(1, 1, sizeof(array_Foo), (void[]){ a, }); Foo af_idx_el = arr_foo[0]; diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 6f4c9aad45..afa45ceeb4 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -58,7 +58,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { pref: &pref.Preferences{} scope: scope // scope: &ast.Scope{start_pos: 0, parent: 0} - + } p.init_parse_fns() p.read_first_token() @@ -82,7 +82,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment parent: 0 } // comments_mode: comments_mode - + } p.read_first_token() // p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0} @@ -359,7 +359,7 @@ pub fn (p mut Parser) stmt() ast.Stmt { return ast.ExprStmt{ expr: expr // typ: typ - + } } } @@ -662,7 +662,7 @@ pub fn (p mut Parser) name_expr() ast.Expr { p.expr_mod = '' return ast.EnumVal{ enum_name: enum_name // lp.prepend_mod(enum_name) - + val: val pos: p.tok.position() } @@ -1052,7 +1052,8 @@ fn (p mut Parser) for_statement() ast.Stmt { else if p.peek_tok.kind in [.decl_assign, .assign, .semicolon] || p.tok.kind == .semicolon { mut init := ast.Stmt{} mut cond := ast.Expr{} - mut inc := ast.Stmt{} + //mut inc := ast.Stmt{} + mut inc := ast.Expr{} if p.peek_tok.kind in [.assign, .decl_assign] { init = p.var_decl_and_assign_stmt() } @@ -1074,7 +1075,8 @@ fn (p mut Parser) for_statement() ast.Stmt { } p.check(.semicolon) if p.tok.kind != .lcbr { - inc = p.stmt() + //inc = p.stmt() + inc,_ = p.expr(0) } stmts := p.parse_block() p.close_scope() @@ -1236,11 +1238,11 @@ fn (p mut Parser) if_expr() ast.Expr { stmts: stmts else_stmts: else_stmts // typ: typ - + pos: pos has_else: has_else // left: left - + } return node } @@ -1630,12 +1632,12 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt { return ast.VarDecl{ name: ident.name // name2: name2 - + expr: expr // p.expr(token.lowest_prec) - + is_mut: info0.is_mut // typ: typ - + pos: p.tok.position() } // return p.var_decl(ident[0], exprs[0]) @@ -1662,9 +1664,10 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt { // pub fn (p mut Parser) assign_stmt() ast.AssignStmt {} // fn (p mut Parser) var_decl() ast.VarDecl {} fn (p mut Parser) hash() ast.HashStmt { + val := p.tok.lit p.next() return ast.HashStmt{ - name: p.tok.lit + val: val } } @@ -1747,7 +1750,6 @@ fn (p mut Parser) match_expr() ast.MatchExpr { branches << ast.MatchBranch{ exprs: exprs stmts: stmts - } p.close_scope() if p.tok.kind == .rcbr {