cgen: more nodes; exit if there are checker errors

pull/3929/head
Alexander Medvednikov 2020-03-03 18:37:38 +01:00
parent 0c67b3cff4
commit 2a99422386
5 changed files with 105 additions and 78 deletions

View File

@ -39,6 +39,9 @@ pub fn (b mut Builder) gen_c(v_files []string) string {
b.parsed_files = parser.parse_files(v_files, b.table) b.parsed_files = parser.parse_files(v_files, b.table)
b.parse_imports() b.parse_imports()
b.checker.check_files(b.parsed_files) b.checker.check_files(b.parsed_files)
if b.checker.nr_errors > 0 {
exit(1)
}
return gen.cgen(b.parsed_files, b.table) return gen.cgen(b.parsed_files, b.table)
} }

View File

@ -12,7 +12,7 @@ import (
) )
const ( const (
max_nr_errors = 350 max_nr_errors = 100
) )
pub struct Checker { pub struct Checker {
@ -235,7 +235,9 @@ pub fn (c mut Checker) call_expr(call_expr ast.CallExpr) table.Type {
if typ_sym.kind == .void && arg_typ_sym.kind == .string { if typ_sym.kind == .void && arg_typ_sym.kind == .string {
continue continue
} }
c.error('!cannot use type `$typ_sym.name` as type `$arg_typ_sym.name` in argument ${i+1} to `$fn_name`', call_expr.pos) if typ_sym.kind == .array_fixed {}
// println('fixed')
c.error('!cannot use type `$typ_sym.str()` as type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`', call_expr.pos)
} }
} }
return f.return_type return f.return_type

View File

@ -262,65 +262,6 @@ fn (g mut Gen) expr(node ast.Expr) {
ast.BoolLiteral { ast.BoolLiteral {
g.write(it.val.str()) g.write(it.val.str())
} }
ast.CharLiteral {
g.write("'$it.val'")
}
ast.EnumVal {
g.write('${it.enum_name}_$it.val')
}
ast.IntegerLiteral {
g.write(it.val.str())
}
ast.FloatLiteral {
g.write(it.val)
}
ast.PostfixExpr {
g.expr(it.expr)
g.write(it.op.str())
}
/*
ast.UnaryExpr {
// probably not :D
if it.op in [.inc, .dec] {
g.expr(it.left)
g.write(it.op.str())
}
else {
g.write(it.op.str())
g.expr(it.left)
}
}
*/
ast.StringLiteral {
g.write('tos3("$it.val")')
}
ast.PrefixExpr {
g.write(it.op.str())
g.expr(it.right)
}
ast.InfixExpr {
g.expr(it.left)
if it.op == .dot {
println('!! dot')
}
g.write(' $it.op.str() ')
g.expr(it.right)
// if typ.name != typ2.name {
// verror('bad types $typ.name $typ2.name')
// }
}
// `user := User{name: 'Bob'}`
ast.StructInit {
type_sym := g.table.get_type_symbol(it.typ)
g.writeln('($type_sym.name){')
for i, field in it.fields {
g.write('\t.$field = ')
g.expr(it.exprs[i])
g.writeln(', ')
}
g.write('}')
}
ast.CallExpr { ast.CallExpr {
name := it.name.replace('.', '__') name := it.name.replace('.', '__')
g.write('${name}(') g.write('${name}(')
@ -336,29 +277,25 @@ fn (g mut Gen) expr(node ast.Expr) {
*/ */
} }
ast.MethodCallExpr { ast.CastExpr {
typ := 'TODO' styp := g.table.type_to_str(it.typ)
name := it.name.replace('.', '__') g.write('($styp)(')
g.write('${typ}_${name}(')
g.expr(it.expr) g.expr(it.expr)
if it.args.len > 0 {
g.write(', ')
}
g.call_args(it.args)
g.write(')') g.write(')')
} }
ast.CharLiteral {
g.write("'$it.val'")
}
ast.EnumVal {
g.write('${it.enum_name}_$it.val')
}
ast.FloatLiteral {
g.write(it.val)
}
ast.Ident { ast.Ident {
name := it.name.replace('.', '__') name := it.name.replace('.', '__')
g.write(name) g.write(name)
} }
ast.SelectorExpr {
g.expr(it.expr)
g.write('.')
g.write(it.field)
}
ast.IndexExpr {
g.index_expr(it)
}
ast.IfExpr { ast.IfExpr {
// If expression? Assign the value to a temp var. // If expression? Assign the value to a temp var.
// Previously ?: was used, but it's too unreliable. // Previously ?: was used, but it's too unreliable.
@ -388,6 +325,23 @@ fn (g mut Gen) expr(node ast.Expr) {
g.writeln('}') g.writeln('}')
} }
} }
ast.IndexExpr {
g.index_expr(it)
}
ast.InfixExpr {
g.expr(it.left)
if it.op == .dot {
println('!! dot')
}
g.write(' $it.op.str() ')
g.expr(it.right)
// if typ.name != typ2.name {
// verror('bad types $typ.name $typ2.name')
// }
}
ast.IntegerLiteral {
g.write(it.val.str())
}
ast.MatchExpr { ast.MatchExpr {
type_sym := g.table.get_type_symbol(it.typ) type_sym := g.table.get_type_symbol(it.typ)
mut tmp := '' mut tmp := ''
@ -406,8 +360,69 @@ fn (g mut Gen) expr(node ast.Expr) {
g.writeln('}') g.writeln('}')
} }
} }
ast.MethodCallExpr {
typ := 'TODO'
name := it.name.replace('.', '__')
g.write('${typ}_${name}(')
g.expr(it.expr)
if it.args.len > 0 {
g.write(', ')
}
g.call_args(it.args)
g.write(')')
}
ast.ParExpr {
g.write('(')
g.expr(it.expr)
g.write(')')
}
ast.PostfixExpr {
g.expr(it.expr)
g.write(it.op.str())
}
ast.PrefixExpr {
g.write(it.op.str())
g.expr(it.right)
}
/*
ast.UnaryExpr {
// probably not :D
if it.op in [.inc, .dec] {
g.expr(it.left)
g.write(it.op.str())
}
else { else {
verror(term.red('cgen.expr(): bad node ' + typeof(node))) g.write(it.op.str())
g.expr(it.left)
}
}
*/
ast.SizeOf {
g.write('sizeof($it.type_name)')
}
ast.StringLiteral {
g.write('tos3("$it.val")')
}
// `user := User{name: 'Bob'}`
ast.StructInit {
type_sym := g.table.get_type_symbol(it.typ)
g.writeln('($type_sym.name){')
for i, field in it.fields {
g.write('\t.$field = ')
g.expr(it.exprs[i])
g.writeln(', ')
}
g.write('}')
}
ast.SelectorExpr {
g.expr(it.expr)
g.write('.')
g.write(it.field)
}
else {
// #printf("node=%d\n", node.typ);
println(term.red('cgen.expr(): bad node ' + typeof(node)))
} }
} }
} }

View File

@ -39,6 +39,7 @@ int main() {
localmod__pub_foo(); localmod__pub_foo();
int ten = localmod__get_int_10(); int ten = localmod__get_int_10();
println(localmod__pub_int_const); println(localmod__pub_int_const);
int g = (int)(3.0);
return 0; return 0;
} }

View File

@ -44,6 +44,7 @@ fn main() {
localmod.pub_foo() localmod.pub_foo()
ten := localmod.get_int_10() ten := localmod.get_int_10()
println(localmod.pub_int_const) println(localmod.pub_int_const)
g := int(3.0)
} }
/* /*
user := User{} user := User{}
@ -81,6 +82,11 @@ fn foo(a int) {
//cloned = nums.clone() //cloned = nums.clone()
//cloned1 := cloned[0] //cloned1 := cloned[0]
//println(cloned1 == 1) //println(cloned1 == 1)
/*
mut strings := ['hi', 'hello']
strings << 'a' + b
*/
} }
fn (u mut User) inc_age(n int) { fn (u mut User) inc_age(n int) {