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() { pub fn (mut b Builder) resolve_deps() {
graph := b.import_graph() graph := b.import_graph()
deps_resolved := graph.resolve() 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()) 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 // TODO: error, when v itself does not have v.table -> v.ast -> v.table cycles anymore
return return

View File

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

View File

@ -5,11 +5,15 @@ module x64
import v.ast import v.ast
import v.util import v.util
import v.token
import v.errors
import v.pref
import term import term
import strings import strings
pub struct Gen { pub struct Gen {
out_name string out_name string
pref &pref.Preferences // Preferences shared from V struct
mut: mut:
buf []byte buf []byte
sect_header_name_pos int sect_header_name_pos int
@ -23,6 +27,8 @@ mut:
var_offset map[string]int // local var stack offset var_offset map[string]int // local var stack offset
stack_var_pos int stack_var_pos int
debug_pos int debug_pos int
errors []errors.Error
warnings []errors.Warning
} }
// string_addr map[string]i64 // string_addr map[string]i64
@ -72,10 +78,11 @@ enum Size {
_64 _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{ mut g := Gen{
sect_header_name_pos: 0 sect_header_name_pos: 0
out_name: out_name out_name: out_name
pref: pref
} }
g.generate_elf_header() g.generate_elf_header()
for file in files { for file in files {
@ -306,6 +313,8 @@ fn (mut g Gen) mov_from_reg(var_offset int, reg Register) {
match reg { match reg {
.edi, .rdi { g.write8(0x7d) } .edi, .rdi { g.write8(0x7d) }
.rsi { g.write8(0x75) } .rsi { g.write8(0x75) }
.rdx { g.write8(0x55) }
.rcx { g.write8(0x4d) }
else { verror('mov_from_reg $reg') } else { verror('mov_from_reg $reg') }
} }
g.write8(0xff - var_offset + 1) g.write8(0xff - var_offset + 1)
@ -537,6 +546,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
g.ret() g.ret()
} }
ast.StructDecl {} ast.StructDecl {}
ast.UnsafeStmt {
g.stmts(it.stmts)
}
else { else {
println('x64.stmt(): bad node: ' + typeof(node)) println('x64.stmt(): bad node: ' + typeof(node))
} }
@ -572,7 +584,7 @@ fn (mut g Gen) expr(node ast.Expr) {
ast.StructInit {} ast.StructInit {}
ast.BoolLiteral {} ast.BoolLiteral {}
else { 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) g.allocate_var(ident.name, 4, 0)
} }
else { 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) { fn verror(s string) {
util.verror('x64 gen error', s) 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() { fn main() {
print('hello from x64') println('hello from x64')
} }

View File

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