cgen: v2 compiles itself - defer stmt / if * in opt parens.

pull/4127/head
Joe Conigliaro 2020-03-27 17:21:22 +11:00
parent 8de027c4b4
commit 7ce7151ad2
3 changed files with 40 additions and 3 deletions

View File

@ -527,6 +527,11 @@ pub:
pub struct DeferStmt { pub struct DeferStmt {
pub: pub:
stmts []Stmt stmts []Stmt
mut:
// TODO: handle this differently
// v1 excludes non current os ifdefs so
// the defer's never get added in the first place
ifdef string
} }
pub struct UnsafeStmt { pub struct UnsafeStmt {

View File

@ -560,6 +560,9 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.stmts(it.else_stmts) c.stmts(it.else_stmts)
} }
} }
ast.DeferStmt {
c.stmts(it.stmts)
}
ast.ConstDecl { ast.ConstDecl {
for i, expr in it.exprs { for i, expr in it.exprs {
mut field := it.fields[i] mut field := it.fields[i]

View File

@ -43,6 +43,8 @@ mut:
is_test bool is_test bool
expr_var_name string expr_var_name string
assign_op token.Kind // *=, =, etc (for array_set) assign_op token.Kind // *=, =, etc (for array_set)
defer_stmts []ast.DeferStmt
defer_ifdef string
} }
const ( const (
@ -293,24 +295,33 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.const_decl(it) g.const_decl(it)
} }
ast.CompIf { ast.CompIf {
ifdef := comp_if_to_ifdef(it.val)
if it.is_not { if it.is_not {
g.writeln('\n#ifndef ' + comp_if_to_ifdef(it.val)) g.writeln('\n#ifndef ' + ifdef)
g.writeln('// #if not $it.val') g.writeln('// #if not $it.val')
} }
else { else {
g.writeln('\n#ifdef ' + comp_if_to_ifdef(it.val)) g.writeln('\n#ifdef ' + ifdef)
g.writeln('// #if $it.val') g.writeln('// #if $it.val')
} }
// NOTE: g.defer_ifdef is needed for defers called witin an ifdef
// in v1 this code would be completely excluded
g.defer_ifdef = if it.is_not { '#ifndef ' + ifdef } else { '#ifdef ' + ifdef }
// println('comp if stmts $g.file.path:$it.pos.line_nr') // println('comp if stmts $g.file.path:$it.pos.line_nr')
g.stmts(it.stmts) g.stmts(it.stmts)
g.defer_ifdef = ''
if it.has_else { if it.has_else {
g.writeln('#else') g.writeln('#else')
g.defer_ifdef = if it.is_not { '#ifdef ' + ifdef } else { '#ifndef ' + ifdef }
g.stmts(it.else_stmts) g.stmts(it.else_stmts)
g.defer_ifdef = ''
} }
g.writeln('#endif') g.writeln('#endif')
} }
ast.DeferStmt { ast.DeferStmt {
g.writeln('// defer') mut defer_stmt := *it
defer_stmt.ifdef = g.defer_ifdef
g.defer_stmts << defer_stmt
} }
ast.EnumDecl { ast.EnumDecl {
g.writeln('//') g.writeln('//')
@ -392,6 +403,19 @@ fn (g mut Gen) stmt(node ast.Stmt) {
} }
ast.Import {} ast.Import {}
ast.Return { ast.Return {
if g.defer_stmts.len > 0 {
for defer_stmt in g.defer_stmts {
g.writeln('// defer')
if defer_stmt.ifdef.len > 0 {
g.writeln(defer_stmt.ifdef)
g.stmts(defer_stmt.stmts)
g.writeln('#endif')
}
else {
g.stmts(defer_stmt.stmts)
}
}
}
g.return_statement(it) g.return_statement(it)
} }
ast.StructDecl { ast.StructDecl {
@ -732,6 +756,7 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
g.writeln('return 0;') g.writeln('return 0;')
} }
g.writeln('}') g.writeln('}')
g.defer_stmts = []
g.fn_decl = 0 g.fn_decl = 0
} }
@ -1210,7 +1235,9 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
// `a in [1,2,3]` optimization => `a == 1 || a == 2 || a == 3` // `a in [1,2,3]` optimization => `a == 1 || a == 2 || a == 3`
// avoids an allocation // avoids an allocation
// g.write('/*in opt*/') // g.write('/*in opt*/')
g.write('(')
g.in_optimization(node.left, it) g.in_optimization(node.left, it)
g.write(')')
return return
} }
else {} else {}
@ -1433,6 +1460,7 @@ fn (g mut Gen) if_expr(node ast.IfExpr) {
// TODO: make sure only one stmt in each branch // TODO: make sure only one stmt in each branch
if node.is_expr && node.branches.len >= 2 && node.has_else && type_sym.kind != .void { if node.is_expr && node.branches.len >= 2 && node.has_else && type_sym.kind != .void {
g.inside_ternary = true g.inside_ternary = true
g.write('(')
for i, branch in node.branches { for i, branch in node.branches {
if i > 0 { if i > 0 {
g.write(' : ') g.write(' : ')
@ -1443,6 +1471,7 @@ fn (g mut Gen) if_expr(node ast.IfExpr) {
} }
g.stmts(branch.stmts) g.stmts(branch.stmts)
} }
g.write(')')
g.inside_ternary = false g.inside_ternary = false
} }
else { else {