From 22e558aecb68b3882901b4be072944961cd6ade7 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 11 Mar 2020 02:44:30 +0100 Subject: [PATCH] cgen: fix C style loops without an init; fix integer consts --- vlib/v/ast/ast.v | 27 ++++++++++++++------------- vlib/v/gen/cgen.v | 16 +++++++++++++--- vlib/v/gen/tests/1.c | 11 ++++++++--- vlib/v/parser/parser.v | 3 +++ 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 575fc9c604..c6355ad93a 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -10,15 +10,15 @@ import ( pub type TypeDecl = AliasTypeDecl | SumTypeDecl -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 = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | -ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | -HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | +pub type Stmt = 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 { @@ -165,7 +165,7 @@ mut: is_c bool muts []bool or_block OrExpr - typ table.Type + typ table.Type } pub struct MethodCallExpr { @@ -180,7 +180,7 @@ pub: mut: expr_type table.Type // type of `user` receiver_type table.Type // User - typ table.Type + typ table.Type } pub struct Return { @@ -384,11 +384,12 @@ pub: pub struct ForCStmt { pub: - init Stmt // i := 0; - cond Expr // i < 10; + init Stmt // i := 0; + has_init bool + cond Expr // i < 10; // inc Stmt // i++; - inc Expr // i++; - stmts []Stmt + inc Expr // i++; + stmts []Stmt } pub struct ReturnStmt { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index ad71c9f020..cf03b071f7 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -187,8 +187,12 @@ fn (g mut Gen) stmt(node ast.Stmt) { } ast.ForCStmt { g.write('for (') - g.stmt(it.init) - // g.write('; ') + if !it.has_init { + g.write('; ') + } + else { + g.stmt(it.init) + } g.expr(it.cond) g.write('; ') // g.stmt(it.inc) @@ -925,9 +929,15 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) { // Do not do this when building a module, otherwise the consts // will not be accessible. ast.CharLiteral, ast.IntegerLiteral { - g.write('#define $name ') + g.definitions.write('#define $name ') + // TODO hack. Cut the generated value and paste it into definitions. + g.write('//') + pos := g.out.len g.expr(expr) g.writeln('') + val := string(g.out.buf[pos..]) + // g.out.go_back(val.len) + g.definitions.write(val) } else { styp := g.typ(field.typ) diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index 8b7cf64133..cb13a248b5 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -15,6 +15,7 @@ typedef struct { string arg1; } multi_return_int_string; // end of definitions #endif +#define pi 3 int pi2; // inited later void foo(int a); void User_inc_age(User* u, int n); @@ -27,10 +28,14 @@ void variadic(variadic_int a); void ensure_cap(int required, int cap); void println(string s); void matches(); +#define path_sep 10 void end(); +#define localmod__pub_int_const 20 void localmod__pub_foo(); int localmod__get_int_10(); -#define pi 3 + +//3 + typedef enum { Color_red, // 0 @@ -165,7 +170,7 @@ void matches() { ; } -#define path_sep 10 +//10 void end() { int i = 2; @@ -174,7 +179,7 @@ void end() { int e = 2 + 3 * 4; } -#define localmod__pub_int_const 20 +//20 void localmod__pub_foo() { int a = 10; diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index a917d6a019..371cb8d73d 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -998,8 +998,10 @@ fn (p mut Parser) for_statement() ast.Stmt { mut cond := ast.Expr{} // mut inc := ast.Stmt{} mut inc := ast.Expr{} + mut has_init := false if p.peek_tok.kind in [.assign, .decl_assign] { init = p.assign_stmt() + has_init = true } else if p.tok.kind != .semicolon {} // allow `for ;; i++ {` @@ -1026,6 +1028,7 @@ fn (p mut Parser) for_statement() ast.Stmt { p.close_scope() return ast.ForCStmt{ stmts: stmts + has_init: has_init init: init cond: cond inc: inc