rename cgen module to gen; jsgen

pull/3271/head
Alexander Medvednikov 2019-12-30 08:30:24 +01:00
parent edf8a2cd08
commit f725aa2e8d
9 changed files with 172 additions and 11 deletions

5
v2.v
View File

@ -3,7 +3,7 @@ module main
import ( import (
v.parser v.parser
v.table v.table
v.cgen v.gen
os os
) )
@ -11,6 +11,7 @@ const (
cdefs = ' cdefs = '
#define true 1 #define true 1
#define false 0 #define false 0
typedef int bool;
typedef struct { char* str; } string; typedef struct { char* str; } string;
typedef double f64; typedef double f64;
string tos3(char* s) { return (string){ .str = s }; } string tos3(char* s) { return (string){ .str = s }; }
@ -22,7 +23,7 @@ fn main() {
text := os.read_file(path)? text := os.read_file(path)?
table := &table.Table{} table := &table.Table{}
program := parser.parse_file(text, table) program := parser.parse_file(text, table)
res := cgen.gen(program) res := gen.cgen(program)
mut out := os.create('out.c')? mut out := os.create('out.c')?
out.writeln(cdefs) out.writeln(cdefs)
out.writeln(res) out.writeln(res)

View File

@ -1,4 +1,4 @@
module cgen module gen
import ( import (
strings strings
@ -10,7 +10,7 @@ struct Gen {
out strings.Builder out strings.Builder
} }
pub fn gen(program ast.Program) string { pub fn cgen(program ast.Program) string {
mut g := Gen{ mut g := Gen{
out: strings.new_builder(100) out: strings.new_builder(100)
} }

View File

@ -3,7 +3,7 @@ import (
filepath filepath
v.parser v.parser
v.ast v.ast
v.cgen v.gen
v.table v.table
term term
) )
@ -17,15 +17,15 @@ fn test_c_files() {
vexe := os.getenv('VEXE') vexe := os.getenv('VEXE')
vroot := filepath.dir(vexe) vroot := filepath.dir(vexe)
for i in 1 .. nr_tests + 1 { for i in 1 .. nr_tests + 1 {
text := os.read_file('$vroot/vlib/v/cgen/tests/${i}.v') or { text := os.read_file('$vroot/vlib/v/gen/tests/${i}.v') or {
panic(err) panic(err)
} }
ctext := os.read_file('$vroot/vlib/v/cgen/tests/${i}.c') or { ctext := os.read_file('$vroot/vlib/v/gen/tests/${i}.c') or {
panic(err) panic(err)
} }
table := &table.Table{} table := &table.Table{}
program := parser.parse_file(text, table) program := parser.parse_file(text, table)
res := cgen.gen(program) res := gen.cgen(program)
if compare_texts(res, ctext) { if compare_texts(res, ctext) {
eprintln('${i}... ' + term.green('OK')) eprintln('${i}... ' + term.green('OK'))
} }

160
vlib/v/gen/jsgen.v 100644
View File

@ -0,0 +1,160 @@
module gen
import (
strings
v.ast
term
)
struct JsGen {
out strings.Builder
}
pub fn jsgen(program ast.Program) string {
mut g := JsGen{
out: strings.new_builder(100)
}
for stmt in program.stmts {
g.stmt(stmt)
g.writeln('')
}
return (g.out.str())
}
pub fn (g &JsGen) save() {}
pub fn (g mut JsGen) write(s string) {
g.out.write(s)
}
pub fn (g mut JsGen) writeln(s string) {
g.out.writeln(s)
}
fn (g mut JsGen) stmt(node ast.Stmt) {
match node {
ast.AssignStmt {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
g.writeln(';')
}
ast.FnDecl {
g.write('/** @return { $it.typ.name } **/\nfunction ${it.name}(')
for arg in it.args {
g.write(' /** @type { arg.typ.name } **/ $arg.name')
}
g.writeln(') { ')
for stmt in it.stmts {
g.stmt(stmt)
}
g.writeln('}')
}
ast.Return {
g.write('return ')
g.expr(it.expr)
g.writeln(';')
}
ast.VarDecl {
g.write('var /* $it.typ.name */ $it.name = ')
g.expr(it.expr)
g.writeln(';')
}
ast.ForStmt {
g.write('while (')
g.expr(it.cond)
g.writeln(') {')
for stmt in it.stmts {
g.stmt(stmt)
}
g.writeln('}')
}
ast.StructDecl {
// g.writeln('typedef struct {')
// for field in it.fields {
// g.writeln('\t$field.typ.name $field.name;')
// }
g.writeln('var $it.name = function() {};')
}
ast.ExprStmt {
g.expr(it.expr)
match it.expr {
// no ; after an if expression
ast.IfExpr {}
else {
g.writeln(';')
}
}
}
else {
verror('jsgen.stmt(): bad node')
}
}
}
fn (g mut JsGen) expr(node ast.Expr) {
// println('cgen expr()')
match node {
ast.IntegerLiteral {
g.write(it.val.str())
}
ast.FloatLiteral {
g.write(it.val)
}
ast.UnaryExpr {
g.expr(it.left)
g.write(' $it.op ')
}
ast.StringLiteral {
g.write('tos3("$it.val")')
}
ast.BinaryExpr {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.right)
}
// `user := User{name: 'Bob'}`
ast.StructInit {
g.writeln('/*$it.typ.name*/{')
for i, field in it.fields {
g.write('\t$field : ')
g.expr(it.exprs[i])
g.writeln(', ')
}
g.write('}')
}
ast.CallExpr {
g.write('${it.name}(')
for i, expr in it.args {
g.expr(expr)
if i != it.args.len - 1 {
g.write(', ')
}
}
g.write(')')
}
ast.Ident {
g.write('$it.name')
}
ast.BoolLiteral {
if it.val == true {
g.write('true')
}
else {
g.write('false')
}
}
ast.IfExpr {
g.write('if (')
g.expr(it.cond)
g.writeln(') {')
for stmt in it.stmts {
g.stmt(stmt)
}
g.writeln('}')
}
else {
println(term.red('jsgen.expr(): bad node'))
}
}
}

View File

@ -2,7 +2,7 @@ module parser
import ( import (
v.ast v.ast
v.cgen v.gen
v.table v.table
) )
@ -23,7 +23,7 @@ x := 10
' '
table := &table.Table{} table := &table.Table{}
prog := parse_file(s, table) prog := parse_file(s, table)
res := cgen.gen(prog) res := gen.cgen(prog)
println(res) println(res)
} }
@ -79,7 +79,7 @@ fn test_parse_expr() {
program := ast.Program{ program := ast.Program{
stmts: e stmts: e
} }
res := cgen.gen(program) res := gen.cgen(program)
println('========') println('========')
println(res) println(res)
println('========') println('========')