gen: add if guard to cgen
parent
f965a7d0e6
commit
91e47caf38
|
@ -567,8 +567,10 @@ pub:
|
||||||
// `if [x := opt()] {`
|
// `if [x := opt()] {`
|
||||||
pub struct IfGuardExpr {
|
pub struct IfGuardExpr {
|
||||||
pub:
|
pub:
|
||||||
var_name string
|
var_name string
|
||||||
expr Expr
|
expr Expr
|
||||||
|
mut:
|
||||||
|
expr_type table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
// `or { ... }`
|
// `or { ... }`
|
||||||
|
|
|
@ -631,6 +631,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
||||||
return c.if_expr(mut it)
|
return c.if_expr(mut it)
|
||||||
}
|
}
|
||||||
ast.IfGuardExpr {
|
ast.IfGuardExpr {
|
||||||
|
it.expr_type = c.expr(it.expr)
|
||||||
return table.bool_type
|
return table.bool_type
|
||||||
}
|
}
|
||||||
ast.IndexExpr {
|
ast.IndexExpr {
|
||||||
|
|
|
@ -350,7 +350,7 @@ fn (g mut Gen) expr_with_cast(got_type table.Type, exp_type table.Type, expr ast
|
||||||
got_styp := g.typ(got_type)
|
got_styp := g.typ(got_type)
|
||||||
exp_styp := g.typ(exp_type)
|
exp_styp := g.typ(exp_type)
|
||||||
got_idx := table.type_idx(got_type)
|
got_idx := table.type_idx(got_type)
|
||||||
g.write('/* SUM TYPE CAST */ ($exp_styp) {.obj = memdup(&(${got_styp}[]) {')
|
g.write('/* sum type cast */ ($exp_styp) {.obj = memdup(&(${got_styp}[]) {')
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.writeln('}, sizeof($got_styp)), .typ = $got_idx};')
|
g.writeln('}, sizeof($got_styp)), .typ = $got_idx};')
|
||||||
}
|
}
|
||||||
|
@ -683,51 +683,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
g.ident(it)
|
g.ident(it)
|
||||||
}
|
}
|
||||||
ast.IfExpr {
|
ast.IfExpr {
|
||||||
// If expression? Assign the value to a temp var.
|
g.if_expr(it)
|
||||||
// Previously ?: was used, but it's too unreliable.
|
|
||||||
type_sym := g.table.get_type_symbol(it.typ)
|
|
||||||
mut tmp := ''
|
|
||||||
if type_sym.kind != .void {
|
|
||||||
tmp = g.new_tmp_var()
|
|
||||||
// g.writeln('$ti.name $tmp;')
|
|
||||||
}
|
|
||||||
// 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 {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 {
|
ast.IfGuardExpr {
|
||||||
g.write('/* guard */')
|
g.write('/* guard */')
|
||||||
|
@ -1098,6 +1054,69 @@ fn (g mut Gen) ident(node ast.Ident) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (g mut Gen) if_expr(node ast.IfExpr) {
|
||||||
|
// If expression? Assign the value to a temp var.
|
||||||
|
// Previously ?: was used, but it's too unreliable.
|
||||||
|
type_sym := g.table.get_type_symbol(node.typ)
|
||||||
|
mut tmp := ''
|
||||||
|
if type_sym.kind != .void {
|
||||||
|
tmp = g.new_tmp_var()
|
||||||
|
// g.writeln('$ti.name $tmp;')
|
||||||
|
}
|
||||||
|
// one line ?:
|
||||||
|
// TODO clean this up once `is` is supported
|
||||||
|
if node.stmts.len == 1 && node.else_stmts.len == 1 && type_sym.kind != .void {
|
||||||
|
cond := node.cond
|
||||||
|
stmt1 := node.stmts[0]
|
||||||
|
else_stmt1 := node.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 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mut is_guard := false
|
||||||
|
match node.cond {
|
||||||
|
ast.IfGuardExpr {
|
||||||
|
is_guard = true
|
||||||
|
g.write('/* if guard */{${g.typ(it.expr_type)} $it.var_name = ')
|
||||||
|
g.expr(it.expr)
|
||||||
|
g.writeln(';')
|
||||||
|
g.writeln('if (${it.var_name}.ok) {')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.write('if (')
|
||||||
|
g.expr(node.cond)
|
||||||
|
g.writeln(') {')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, stmt in node.stmts {
|
||||||
|
// Assign ret value
|
||||||
|
if i == node.stmts.len - 1 && type_sym.kind != .void {}
|
||||||
|
// g.writeln('$tmp =')
|
||||||
|
g.stmt(stmt)
|
||||||
|
}
|
||||||
|
if is_guard {
|
||||||
|
g.write('}')
|
||||||
|
}
|
||||||
|
g.writeln('}')
|
||||||
|
if node.else_stmts.len > 0 {
|
||||||
|
g.writeln('else { ')
|
||||||
|
for stmt in node.else_stmts {
|
||||||
|
g.stmt(stmt)
|
||||||
|
}
|
||||||
|
g.writeln('}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn (g mut Gen) index_expr(node ast.IndexExpr) {
|
fn (g mut Gen) index_expr(node ast.IndexExpr) {
|
||||||
// TODO else doesn't work with sum types
|
// TODO else doesn't work with sum types
|
||||||
mut is_range := false
|
mut is_range := false
|
||||||
|
|
Loading…
Reference in New Issue