From 37453945d072152aedf33b35af53a00fcd1e0c9b Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 4 Mar 2020 15:48:43 +0100 Subject: [PATCH] cgen: remaining nodes; match type fix; v2.c is now generated --- vlib/compiler/expression.v | 2 +- vlib/compiler/main.v | 2 +- vlib/hash/wyhash/rand.v | 2 ++ vlib/v/ast/ast.v | 25 ++++++++----------- vlib/v/builder/builder.v | 7 +++++- vlib/v/checker/checker.v | 43 +++++++++++++++++--------------- vlib/v/gen/cgen.v | 50 +++++++++++++++++++++++++++++--------- vlib/v/table/table.v | 7 +++--- 8 files changed, 85 insertions(+), 53 deletions(-) diff --git a/vlib/compiler/expression.v b/vlib/compiler/expression.v index a6a47bbb34..5f9db45316 100644 --- a/vlib/compiler/expression.v +++ b/vlib/compiler/expression.v @@ -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")') } diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index 201b44c594..c60e2238b6 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -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() } diff --git a/vlib/hash/wyhash/rand.v b/vlib/hash/wyhash/rand.v index 3f6e9a86b6..a22edc8ef6 100644 --- a/vlib/hash/wyhash/rand.v +++ b/vlib/hash/wyhash/rand.v @@ -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 } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index de724b9b7a..67236ea3f2 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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 { diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 5d0237c340..5029b045fc 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -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)) } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index da6c708c8f..62fd439a26 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index b8030734d8..c107389690 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -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) } diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 565587ff95..f7cf5de05f 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -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