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 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 {

View File

@ -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)

View File

@ -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;

View File

@ -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