cgen: remaining nodes; match type fix; v2.c is now generated

pull/3937/head
Alexander Medvednikov 2020-03-04 15:48:43 +01:00
parent 8458ea40f0
commit 37453945d0
8 changed files with 85 additions and 53 deletions

View File

@ -831,7 +831,7 @@ fn (p mut Parser) factor() string {
is_sum_type := type_of_var in p.table.sum_types
if is_sum_type && vname.len > 0 {
// TODO: make this work for arbitrary sumtype expressions, not just simple vars
p.gen('tos3(__SumTypeNames__${type_of_var}[${vname}.typ - 1])')
p.gen('${vname}.typ == 0 ? tos3("typeof(): typ == 0") : tos3(__SumTypeNames__${type_of_var}[${vname}.typ - 1])')
}else{
p.gen('tos3("$type_of_var")')
}

View File

@ -340,7 +340,7 @@ pub fn (v mut V) compile2() {
println(v.files)
}
mut b := v.new_v2()
b.build_c(v.files, v.pref.out_name)
b.build_c(v.files, v.out_name_c)// v.pref.out_name + '.c')
v.cc()
}

View File

@ -5,10 +5,12 @@ module wyhash
pub fn rand_u64(seed &u64) u64 {
mut seed0 := seed
// QTODO
unsafe{
mut seed1 := *seed0
seed1+=wyp0
*seed0 = seed1
return wymum(seed1^wyp1, seed1)
}
//return 0
}

View File

@ -18,18 +18,14 @@ pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprS
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 {
// fields []Field
// fields []Field
// }
// pub struct ArrayType {}
pub struct Type {
pub:
typ table.Type
typ table.Type
}
// | IncDecStmt k
@ -333,12 +329,12 @@ mut:
pub struct MatchExpr {
pub:
tok_kind token.Kind
cond Expr
branches []MatchBranch
pos token.Position
tok_kind token.Kind
cond Expr
branches []MatchBranch
pos token.Position
mut:
typ table.Type
expr_type table.Type // type of `x` in `match x {`
}
pub struct MatchBranch {
@ -348,7 +344,6 @@ pub:
pos token.Position
}
pub struct CompIf {
pub:
cond Expr
@ -477,11 +472,11 @@ pub:
pub struct ArrayInit {
pub:
pos token.Position
exprs []Expr
pos token.Position
exprs []Expr
mut:
elem_type table.Type
typ table.Type
typ table.Type
}
pub struct MapInit {

View File

@ -42,10 +42,15 @@ pub fn (b mut Builder) gen_c(v_files []string) string {
if b.checker.nr_errors > 0 {
exit(1)
}
return gen.cgen(b.parsed_files, b.table)
// println('starting cgen...')
res := gen.cgen(b.parsed_files, b.table)
println('cgen done')
// println(res)
return res
}
pub fn (b mut Builder) build_c(v_files []string, out_file string) {
println('build_c($out_file)')
os.write_file(out_file, b.gen_c(v_files))
}

View File

@ -16,13 +16,13 @@ const (
)
pub struct Checker {
table &table.Table
table &table.Table
mut:
file ast.File
nr_errors int
errors []string
expected_type table.Type
fn_return_type table.Type // current function's return type
file ast.File
nr_errors int
errors []string
expected_type table.Type
fn_return_type table.Type // current function's return type
}
pub fn new_checker(table &table.Table) Checker {
@ -466,10 +466,10 @@ fn (c mut Checker) stmt(node ast.Stmt) {
typ := c.expr(it.expr)
it.typ = typ
}
else {
// println('checker.stmt(): unhandled node')
// println('checker.stmt(): unhandled node (${typeof(node)})')
}
else {}
// println('checker.stmt(): unhandled node')
// println('checker.stmt(): unhandled node (${typeof(node)})')
// }
}
}
@ -577,11 +577,10 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
}
*/
else {
// println('checker.expr(): unhandled node')
// TODO: find nil string bug triggered with typeof
// println('checker.expr(): unhandled node (${typeof(node)})')
}
else {}
// println('checker.expr(): unhandled node')
// TODO: find nil string bug triggered with typeof
// println('checker.expr(): unhandled node (${typeof(node)})')
}
return table.void_type
}
@ -670,12 +669,15 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
}
pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
t := c.expr(node.cond)
c.expected_type = t
expr_type := c.expr(node.cond)
if expr_type == 0 {
c.error('match 0 expr type', node.pos)
}
c.expected_type = expr_type
mut ret_type := table.void_type
for branch in node.branches {
for expr in branch.exprs {
c.expected_type = t
c.expected_type = expr_type
typ := c.expr(expr)
typ_sym := c.table.get_type_symbol(typ)
// TODO:
@ -695,10 +697,11 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
// node.typ = typ
// return typ
else {}
}
}
}
}
node.typ = t
node.expr_type = expr_type
// println('!m $expr_type')
return ret_type
}

View File

@ -76,10 +76,10 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// }
// g.writeln(';')
// }
println('assign')
g.write('') // /*assign*/')
}
ast.AssertStmt {
println('// assert')
g.write('// assert')
// TODO
}
ast.Attr {
@ -105,6 +105,9 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.stmts(it.stmts)
g.writeln('#endif')
}
ast.DeferStmt {
g.writeln('// defer')
}
ast.EnumDecl {
g.writeln('typedef enum {')
for i, val in it.vals {
@ -193,6 +196,9 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// TODO
g.writeln('__global')
}
ast.GotoLabel {
g.writeln('$it.name:')
}
ast.HashStmt {
g.writeln('#$it.name')
}
@ -227,6 +233,9 @@ fn (g mut Gen) stmt(node ast.Stmt) {
}
g.writeln('} $it.name;')
}
ast.TypeDecl {
g.writeln('// type')
}
ast.UnsafeStmt {
g.stmts(it.stmts)
}
@ -243,7 +252,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
}
fn (g mut Gen) expr(node ast.Expr) {
// println('cgen expr()')
// println('cgen expr() line_nr=$node.pos.line_nr')
match node {
ast.ArrayInit {
type_sym := g.table.get_type_symbol(it.typ)
@ -254,11 +263,17 @@ fn (g mut Gen) expr(node ast.Expr) {
}
g.write('\n})')
}
ast.AsCast {
g.write('/* as */')
}
ast.AssignExpr {
g.expr(it.left)
g.write(' $it.op.str() ')
g.expr(it.val)
}
ast.Assoc {
g.write('/* assoc */')
}
ast.BoolLiteral {
g.write(it.val.str())
}
@ -310,10 +325,8 @@ fn (g mut Gen) expr(node ast.Expr) {
g.writeln(') {')
for i, stmt in it.stmts {
// Assign ret value
if i == it.stmts.len - 1 && type_sym.kind != .void {
// g.writeln('$tmp =')
println(1)
}
if i == it.stmts.len - 1 && type_sym.kind != .void {}
// g.writeln('$tmp =')
g.stmt(stmt)
}
g.writeln('}')
@ -325,6 +338,9 @@ fn (g mut Gen) expr(node ast.Expr) {
g.writeln('}')
}
}
ast.IfGuardExpr {
g.write('/* guard */')
}
ast.IndexExpr {
g.index_expr(it)
}
@ -343,7 +359,13 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write(it.val.str())
}
ast.MatchExpr {
type_sym := g.table.get_type_symbol(it.typ)
// println('match expr typ=$it.expr_type')
// TODO
if it.expr_type == 0 {
g.writeln('// match 0')
return
}
type_sym := g.table.get_type_symbol(it.expr_type)
mut tmp := ''
if type_sym.kind != .void {
tmp = g.new_tmp_var()
@ -356,7 +378,7 @@ fn (g mut Gen) expr(node ast.Expr) {
for i, expr in branch.exprs {
g.write('$tmp == ')
g.expr(expr)
if i < branch.exprs.len-1 {
if i < branch.exprs.len - 1 {
g.write(' || ')
}
}
@ -376,6 +398,9 @@ fn (g mut Gen) expr(node ast.Expr) {
g.call_args(it.args)
g.write(')')
}
ast.None {
g.write('0')
}
ast.ParExpr {
g.write('(')
g.expr(it.expr)
@ -425,6 +450,9 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write('.')
g.write(it.field)
}
ast.Type {
g.write('/* Type */')
}
else {
// #printf("node=%d\n", node.typ);
println(term.red('cgen.expr(): bad node ' + typeof(node)))
@ -467,6 +495,6 @@ fn (g mut Gen) call_args(args []ast.Expr) {
}
fn verror(s string) {
println(s)
exit(1)
println('cgen error: $s')
// exit(1)
}

View File

@ -182,6 +182,7 @@ pub fn (t &Table) find_type(name string) ?TypeSymbol {
[inline]
pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
// println('get_type_symbol $typ')
idx := type_idx(typ)
if idx > 0 {
return &t.types[idx]
@ -400,8 +401,7 @@ pub fn (t &Table) check(got, expected Type) bool {
}
// TODO: actually check for & handle pointers with name_expr
// see hack in checker IndexExpr line #691
if (got_type_sym.kind == .byte && exp_type_sym.kind == .byteptr) ||
(exp_type_sym.kind == .byte && got_type_sym.kind == .byteptr) {
if (got_type_sym.kind == .byte && exp_type_sym.kind == .byteptr) || (exp_type_sym.kind == .byte && got_type_sym.kind == .byteptr) {
return true
}
// TODO
@ -424,8 +424,7 @@ pub fn (t &Table) check(got, expected Type) bool {
return true
}
// type alias
if (got_type_sym.kind == .alias && got_type_sym.parent_idx == exp_idx) ||
(exp_type_sym.kind == .alias && exp_type_sym.parent_idx == got_idx) {
if (got_type_sym.kind == .alias && got_type_sym.parent_idx == exp_idx) || (exp_type_sym.kind == .alias && exp_type_sym.parent_idx == got_idx) {
return true
}
// sum type