v/vlib/compiler2/cgen/cgen.v

87 lines
1.3 KiB
V

module cgen
import (
strings
compiler2.ast
)
struct Gen {
out strings.Builder
}
pub fn gen(program ast.Program) {
mut g := Gen{out:strings.new_builder(100)}
for expr in program.exprs {
g.expr(expr)
g.writeln('')
}
println(g.out.str())
}
pub fn (g &Gen) save() {
}
pub fn (g mut Gen) write(s string) {
g.out.write(s)
}
pub fn (g mut Gen) writeln(s string) {
g.out.writeln(s)
}
struct Type {
name string
}
const (
string_type = Type{'string'}
int_type = Type{'int'}
void_type = Type{'void'}
)
fn (g mut Gen) expr(node ast.Expr) Type {
//println('cgen expr()')
match node {
ast.IntegerLiteral {
g.write(it.val.str())
return int_type
}
ast.UnaryExpr {
g.expr(it.left)
g.write(' $it.op ')
}
ast.StringLiteral {
g.write('"$it.val"')
return string_type
}
ast.BinaryExpr {
typ := g.expr(it.left)
match it.op {
.plus { g.write(' + ') }
.minus { g.write(' - ') }
.mul { g.write(' * ') }
.div { g.write(' / ') }
else {}
}
typ2 := g.expr(it.right)
if typ.name != typ2.name {
println('bad types $typ.name $typ2.name')
}
return typ
}
ast.VarDecl {
g.write('var $it.name = ')
g.expr(it.expr)
g.writeln(';')
return void_type
}
else {
println('bad node')
}
}
return void_type
}