x64 gen: improve error handling for unknown nodes

pull/4931/head^2
Delyan Angelov 2020-05-17 15:45:11 +03:00
parent 4a70d2fe51
commit 627400723c
5 changed files with 38 additions and 7 deletions

View File

@ -95,7 +95,8 @@ pub fn (mut b Builder) parse_imports() {
pub fn (mut b Builder) resolve_deps() {
graph := b.import_graph()
deps_resolved := graph.resolve()
if !deps_resolved.acyclic {
is_main_to_builtin := deps_resolved.nodes.len == 1 && deps_resolved.nodes[0].name == 'main' && deps_resolved.nodes[0].deps.len == 1 && deps_resolved.nodes[0].deps[0] == 'builtin'
if !deps_resolved.acyclic && !is_main_to_builtin {
eprintln('warning: import cycle detected between the following modules: \n' + deps_resolved.display_cycles())
// TODO: error, when v itself does not have v.table -> v.ast -> v.table cycles anymore
return

View File

@ -21,7 +21,7 @@ pub fn (mut b Builder) build_x64(v_files []string, out_file string) {
t2 := time.ticks()
check_time := t2 - t1
b.info('CHECK: ${check_time}ms')
x64.gen(b.parsed_files, out_file)
x64.gen(b.parsed_files, out_file, b.pref)
t3 := time.ticks()
gen_time := t3 - t2
b.info('x64 GEN: ${gen_time}ms')

View File

@ -5,11 +5,15 @@ module x64
import v.ast
import v.util
import v.token
import v.errors
import v.pref
import term
import strings
pub struct Gen {
out_name string
pref &pref.Preferences // Preferences shared from V struct
mut:
buf []byte
sect_header_name_pos int
@ -23,6 +27,8 @@ mut:
var_offset map[string]int // local var stack offset
stack_var_pos int
debug_pos int
errors []errors.Error
warnings []errors.Warning
}
// string_addr map[string]i64
@ -72,10 +78,11 @@ enum Size {
_64
}
pub fn gen(files []ast.File, out_name string) {
pub fn gen(files []ast.File, out_name string, pref &pref.Preferences) {
mut g := Gen{
sect_header_name_pos: 0
out_name: out_name
pref: pref
}
g.generate_elf_header()
for file in files {
@ -306,6 +313,8 @@ fn (mut g Gen) mov_from_reg(var_offset int, reg Register) {
match reg {
.edi, .rdi { g.write8(0x7d) }
.rsi { g.write8(0x75) }
.rdx { g.write8(0x55) }
.rcx { g.write8(0x4d) }
else { verror('mov_from_reg $reg') }
}
g.write8(0xff - var_offset + 1)
@ -537,6 +546,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
g.ret()
}
ast.StructDecl {}
ast.UnsafeStmt {
g.stmts(it.stmts)
}
else {
println('x64.stmt(): bad node: ' + typeof(node))
}
@ -572,7 +584,7 @@ fn (mut g Gen) expr(node ast.Expr) {
ast.StructInit {}
ast.BoolLiteral {}
else {
// println(term.red('x64.expr(): bad node'))
println(term.red('x64.expr(): unhandled node: ' + typeof(node)))
}
}
}
@ -624,7 +636,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
g.allocate_var(ident.name, 4, 0)
}
else {
verror('assign_stmt unhandled expr')
g.error_with_pos('assign_stmt unhandled expr: ' + typeof(node.right[0]), node.right[0].position())
}
}
}
@ -741,3 +753,22 @@ fn (mut g Gen) postfix_expr(node ast.PostfixExpr) {
fn verror(s string) {
util.verror('x64 gen error', s)
}
pub fn (mut g Gen) error_with_pos(s string, pos token.Position) {
// TODO: store a file index in the Position too,
// so that the file path can be retrieved from the pos, instead
// of guessed from the pref.path ...
mut kind := 'error:'
if g.pref.output_mode == .stdout {
ferror := util.formatted_error(kind, s, g.pref.path, pos)
eprintln(ferror)
exit(1)
} else {
g.errors << errors.Error{
file_path: g.pref.path
pos: pos
reporter: .gen
message: s
}
}
}

View File

@ -1,3 +1,3 @@
fn main() {
print('hello from x64')
println('hello from x64')
}

View File

@ -1,2 +1 @@
hello from x64