cgen: fix C style loops without an init; fix integer consts

pull/3986/head
Alexander Medvednikov 2020-03-11 02:44:30 +01:00
parent 0d45d21069
commit 22e558aecb
4 changed files with 38 additions and 19 deletions

View File

@ -10,15 +10,15 @@ import (
pub type TypeDecl = AliasTypeDecl | SumTypeDecl pub type TypeDecl = AliasTypeDecl | SumTypeDecl
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr |
CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr |
ConcatExpr | Type | AsCast ConcatExpr | Type | AsCast
pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt |
LineComment | MultiLineComment | AssertStmt | UnsafeStmt LineComment | MultiLineComment | AssertStmt | UnsafeStmt
// pub type Type = StructType | ArrayType // pub type Type = StructType | ArrayType
// pub struct StructType { // pub struct StructType {
@ -165,7 +165,7 @@ mut:
is_c bool is_c bool
muts []bool muts []bool
or_block OrExpr or_block OrExpr
typ table.Type typ table.Type
} }
pub struct MethodCallExpr { pub struct MethodCallExpr {
@ -180,7 +180,7 @@ pub:
mut: mut:
expr_type table.Type // type of `user` expr_type table.Type // type of `user`
receiver_type table.Type // User receiver_type table.Type // User
typ table.Type typ table.Type
} }
pub struct Return { pub struct Return {
@ -384,11 +384,12 @@ pub:
pub struct ForCStmt { pub struct ForCStmt {
pub: pub:
init Stmt // i := 0; init Stmt // i := 0;
cond Expr // i < 10; has_init bool
cond Expr // i < 10;
// inc Stmt // i++; // inc Stmt // i++;
inc Expr // i++; inc Expr // i++;
stmts []Stmt stmts []Stmt
} }
pub struct ReturnStmt { pub struct ReturnStmt {

View File

@ -187,8 +187,12 @@ fn (g mut Gen) stmt(node ast.Stmt) {
} }
ast.ForCStmt { ast.ForCStmt {
g.write('for (') g.write('for (')
g.stmt(it.init) if !it.has_init {
// g.write('; ') g.write('; ')
}
else {
g.stmt(it.init)
}
g.expr(it.cond) g.expr(it.cond)
g.write('; ') g.write('; ')
// g.stmt(it.inc) // 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 // Do not do this when building a module, otherwise the consts
// will not be accessible. // will not be accessible.
ast.CharLiteral, ast.IntegerLiteral { 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.expr(expr)
g.writeln('') g.writeln('')
val := string(g.out.buf[pos..])
// g.out.go_back(val.len)
g.definitions.write(val)
} }
else { else {
styp := g.typ(field.typ) styp := g.typ(field.typ)

View File

@ -15,6 +15,7 @@ typedef struct {
string arg1; string arg1;
} multi_return_int_string; } multi_return_int_string;
// end of definitions #endif // end of definitions #endif
#define pi 3
int pi2; // inited later int pi2; // inited later
void foo(int a); void foo(int a);
void User_inc_age(User* u, int n); 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 ensure_cap(int required, int cap);
void println(string s); void println(string s);
void matches(); void matches();
#define path_sep 10
void end(); void end();
#define localmod__pub_int_const 20
void localmod__pub_foo(); void localmod__pub_foo();
int localmod__get_int_10(); int localmod__get_int_10();
#define pi 3
//3
typedef enum { typedef enum {
Color_red, // 0 Color_red, // 0
@ -165,7 +170,7 @@ void matches() {
; ;
} }
#define path_sep 10 //10
void end() { void end() {
int i = 2; int i = 2;
@ -174,7 +179,7 @@ void end() {
int e = 2 + 3 * 4; int e = 2 + 3 * 4;
} }
#define localmod__pub_int_const 20 //20
void localmod__pub_foo() { void localmod__pub_foo() {
int a = 10; int a = 10;

View File

@ -998,8 +998,10 @@ fn (p mut Parser) for_statement() ast.Stmt {
mut cond := ast.Expr{} mut cond := ast.Expr{}
// mut inc := ast.Stmt{} // mut inc := ast.Stmt{}
mut inc := ast.Expr{} mut inc := ast.Expr{}
mut has_init := false
if p.peek_tok.kind in [.assign, .decl_assign] { if p.peek_tok.kind in [.assign, .decl_assign] {
init = p.assign_stmt() init = p.assign_stmt()
has_init = true
} }
else if p.tok.kind != .semicolon {} else if p.tok.kind != .semicolon {}
// allow `for ;; i++ {` // allow `for ;; i++ {`
@ -1026,6 +1028,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
p.close_scope() p.close_scope()
return ast.ForCStmt{ return ast.ForCStmt{
stmts: stmts stmts: stmts
has_init: has_init
init: init init: init
cond: cond cond: cond
inc: inc inc: inc