diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index a6ae99259c..8caf22565b 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -229,7 +229,7 @@ fn (mut g Gen) mov_reg_to_var(var_offset int, reg Register) { .rsi { g.write8(0x75) } .rdx { g.write8(0x55) } .rcx { g.write8(0x4d) } - else { verror('mov_from_reg $reg') } + else { g.n_error('mov_from_reg $reg') } } g.write8(0xff - var_offset + 1) g.println('mov DWORD PTR[rbp-$var_offset.hex2()],$reg') @@ -251,7 +251,7 @@ fn (mut g Gen) mov_var_to_reg(reg Register, var_offset int) { .rdx { g.write8(0x55) } .rbx { g.write8(0x5d) } .rcx { g.write8(0x4d) } - else { verror('mov_var_to_reg $reg') } + else { g.n_error('mov_var_to_reg $reg') } } g.write8(0xff - var_offset + 1) g.println('mov $reg,DWORD PTR[rbp-$var_offset.hex2()]') @@ -354,7 +354,7 @@ fn (mut g Gen) add8_var(reg Register, var_offset int) { g.write8(0x03) match reg { .eax, .rax { g.write8(0x45) } - else { verror('add8_var') } + else { g.n_error('add8_var') } } g.write8(0xff - var_offset + 1) g.println('add8 $reg,DWORD PTR[rbp-$var_offset.hex2()]') @@ -364,7 +364,7 @@ fn (mut g Gen) sub8_var(reg Register, var_offset int) { g.write8(0x2b) match reg { .eax, .rax { g.write8(0x45) } - else { verror('sub8_var') } + else { g.n_error('sub8_var') } } g.write8(0xff - var_offset + 1) g.println('sub8 $reg,DWORD PTR[rbp-$var_offset.hex2()]') @@ -385,7 +385,7 @@ fn (mut g Gen) mul8_var(reg Register, var_offset int) { g.write8(0xaf) match reg { .eax, .rax { g.write8(0x45) } - else { verror('mul8_var') } + else { g.n_error('mul8_var') } } g.write8(0xff - var_offset + 1) g.println('mul8 $reg,DWORD PTR[rbp-$var_offset.hex2()]') @@ -439,11 +439,11 @@ pub fn (mut g Gen) xor(r Register, v int) { g.println('xor rcx, -1') } else { - verror('unhandled xor') + g.n_error('unhandled xor') } } } else { - verror('unhandled xor') + g.n_error('unhandled xor') } } @@ -495,7 +495,7 @@ fn (mut g Gen) nsyscall_write() int { return 0x2000004 } else { - verror('unsupported exit syscall for this platform') + g.n_error('unsupported exit syscall for this platform') } } return 0 @@ -510,7 +510,7 @@ fn (mut g Gen) nsyscall_exit() int { return 0x2000001 } else { - verror('unsupported exit syscall for this platform') + g.n_error('unsupported exit syscall for this platform') } } return 0 @@ -525,7 +525,7 @@ pub fn (mut g Gen) gen_amd64_exit(expr ast.Expr) { match expr { ast.CallExpr { right := expr.return_type - verror('native exit builtin: Unsupported call $right') + g.n_error('native exit builtin: Unsupported call $right') } ast.Ident { var_offset := g.get_var_offset(expr.name) @@ -535,7 +535,7 @@ pub fn (mut g Gen) gen_amd64_exit(expr ast.Expr) { g.mov(.edi, expr.val.int()) } else { - verror('native builtin exit expects a numeric argument') + g.n_error('native builtin exit expects a numeric argument') } } g.mov(.eax, g.nsyscall_exit()) @@ -560,7 +560,7 @@ fn (mut g Gen) mov(reg Register, val int) { return } else { - verror('unhandled mov $reg, -1') + g.n_error('unhandled mov $reg, -1') } } } @@ -600,7 +600,7 @@ fn (mut g Gen) mov(reg Register, val int) { g.write8(0xe4) } else { - verror('unhandled mov $reg, $reg') + g.n_error('unhandled mov $reg, $reg') } } g.println('xor $reg, $reg') @@ -627,7 +627,7 @@ fn (mut g Gen) mov(reg Register, val int) { g.write8(0xbc) // r11 is 0xbb etc } else { - verror('unhandled mov $reg') + g.n_error('unhandled mov $reg') } } g.write32(val) @@ -731,7 +731,7 @@ fn (mut g Gen) mov_reg(a Register, b Register) { g.write8(0x89) g.write8(0xc6) } else { - verror('unhandled mov_reg combination for $a $b') + g.n_error('unhandled mov_reg combination for $a $b') } g.println('mov $a, $b') } @@ -757,7 +757,7 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) { eprintln('call fn ($n)') addr := g.fn_addr[n] if addr == 0 { - verror('fn addr of `$name` = 0') + g.n_error('fn addr of `$name` = 0') } // Copy values to registers (calling convention) // g.mov(.eax, 0) @@ -778,12 +778,12 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) { g.mov_var_to_reg(native.fn_arg_registers[i], var_offset) } else { - verror('unhandled call_fn (name=$name) node: ' + expr.type_name()) + g.v_error('unhandled call_fn (name=$name) node: $expr.type_name()', node.pos) } } } if node.args.len > 6 { - verror('more than 6 args not allowed for now') + g.v_error('more than 6 args not allowed for now', node.pos) } g.call(int(addr)) g.println('fn call `${name}()`') @@ -835,7 +835,10 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { match node.left_types[i] { 7 { // ast.IndexExpr { ie := node.left[i] as ast.IndexExpr - bracket := name.index('[') or { verror('bracket expected') } + bracket := name.index('[') or { + g.v_error('bracket expected', node.pos) + exit(1) + } var_name := name[0..bracket] mut dest := g.get_var_offset(var_name) index := ie.index as ast.IntegerLiteral @@ -848,7 +851,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { else { tn := node.left[i].type_name() dump(node.left_types) - verror('unhandled assign type: $tn') + g.n_error('unhandled assign type: $tn') } } } @@ -935,7 +938,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { } else { dump(e) - verror('unhandled array init type') + g.n_error('unhandled array init type') } } } @@ -960,7 +963,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { g.mov_var_to_reg(.rax, dest) g.add_reg(.rax, .rdi) } else { - verror('only integers and idents can be used as indexes') + g.n_error('only integers and idents can be used as indexes') } // TODO check if out of bounds access g.mov_reg_to_var(offset, .eax) @@ -977,10 +980,12 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { g.mov_reg_to_var(dest, .rax) g.mov_var_to_reg(.rsi, dest) } + ast.GoExpr { + g.v_error('threads not implemented for the native backend', node.pos) + } else { // dump(node) - g.error_with_pos('native assign_stmt unhandled expr: ' + right.type_name(), - right.position()) + g.v_error('unhandled assign_stmt expression: $right.type_name()', right.position()) } } // } @@ -993,7 +998,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { } // TODO if node.left is ast.InfixExpr { - verror('only simple expressions are supported right now (not more than 2 operands)') + g.n_error('only simple expressions are supported right now (not more than 2 operands)') } match mut node.left { ast.Ident { @@ -1028,7 +1033,7 @@ fn (mut g Gen) gen_assert(assert_node ast.AssertStmt) { } else if ane is ast.InfixExpr { // assert 1==1 ine = ane } else { - verror('Unsupported expression in assert') + g.n_error('Unsupported expression in assert') } cjmp_addr = g.condition(ine, true) g.expr(assert_node.expr) @@ -1094,10 +1099,10 @@ fn (mut g Gen) condition(infix_expr ast.InfixExpr, neg bool) int { // lit := infix_expr.right as ast.IntegerLiteral // g.cmp_var(infix_expr.left.name, lit.val.int()) // +not - verror('unsupported if construction') + g.n_error('unsupported if construction') } else { - verror('unsupported if construction') + g.n_error('unsupported if construction') } } } @@ -1110,16 +1115,16 @@ fn (mut g Gen) condition(infix_expr ast.InfixExpr, neg bool) int { } ast.Ident { // var < var2 - verror('unsupported if construction') + g.n_error('unsupported if construction') } else { - verror('unsupported if construction') + g.n_error('unsupported if construction') } } } else { - dump(infix_expr) - verror('unhandled infix.left') + // dump(infix_expr) + g.n_error('unhandled $infix_expr.left') } } @@ -1131,6 +1136,9 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { branch := node.branches[0] infix_expr := branch.cond as ast.InfixExpr cjmp_addr := g.condition(infix_expr, false) + if node.is_comptime { + g.n_error('ignored comptime') + } g.stmts(branch.stmts) // Now that we know where we need to jump if the condition is false, update the `jne` call. // The value is the relative address, difference between current position and the location @@ -1139,7 +1147,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { g.write32_at(cjmp_addr, int(g.pos() - cjmp_addr - 4)) // 4 is for "00 00 00 00" if node.has_else { - verror('else statements not yet supported') + g.n_error('else statements not yet supported') } } @@ -1155,7 +1163,7 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) { jump_addr = g.cjmp(.jge) } else { - verror('unhandled infix.left') + g.n_error('unhandled infix.left') } } g.stmts(node.stmts) @@ -1256,7 +1264,7 @@ pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int { g.write8(0x45) } else { - verror('allocate_var: bad size $size') + g.n_error('allocate_var: bad size $size') } } // Generate N in `[rbp-N]` diff --git a/vlib/v/gen/native/arm64.v b/vlib/v/gen/native/arm64.v index eb722ebd0e..46b8ffe6a6 100644 --- a/vlib/v/gen/native/arm64.v +++ b/vlib/v/gen/native/arm64.v @@ -61,7 +61,7 @@ fn (mut g Gen) mov_arm(reg Arm64Register, val u64) { g.write32(0xd2800000 + int(r) + (int(val) << 5)) g.println('mov x$r, $val') } else { - verror('mov_arm unsupported values') + g.n_error('mov_arm unsupported values') } /* if 1 ^ (x & ~m) != 0 { @@ -87,7 +87,7 @@ pub fn (mut g Gen) call_fn_arm64(node ast.CallExpr) { // println('call fn $name') addr := g.fn_addr[name] if addr == 0 { - verror('fn addr of `$name` = 0') + g.n_error('fn addr of `$name` = 0') } // Copy values to registers (calling convention) // g.mov_arm(.eax, 0) @@ -110,12 +110,12 @@ pub fn (mut g Gen) call_fn_arm64(node ast.CallExpr) { } */ else { - verror('unhandled call_fn (name=$name) node: ' + expr.type_name()) + g.n_error('unhandled call_fn (name=$name) node: ' + expr.type_name()) } } } if node.args.len > 6 { - verror('more than 6 args not allowed for now') + g.n_error('more than 6 args not allowed for now') } g.call(int(addr)) g.println('fn call `${name}()`') @@ -165,7 +165,7 @@ pub fn (mut c Arm64) gen_exit(mut g Gen, expr ast.Expr) { return_code = expr.val.u64() } else { - verror('native builtin exit expects a numeric argument') + g.n_error('native builtin exit expects a numeric argument') } } match c.g.pref.os { @@ -179,7 +179,7 @@ pub fn (mut c Arm64) gen_exit(mut g Gen, expr ast.Expr) { c.g.mov_arm(.x0, 0) } else { - verror('unsupported os $c.g.pref.os') + g.n_error('unsupported os $c.g.pref.os') } } g.svc() @@ -191,7 +191,7 @@ pub fn (mut g Gen) gen_arm64_exit(expr ast.Expr) { g.mov_arm(.x16, expr.val.u64()) } else { - verror('native builtin exit expects a numeric argument') + g.n_error('native builtin exit expects a numeric argument') } } g.mov_arm(.x0, 0) diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index 8b37908045..b2bf0ee08f 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -87,7 +87,7 @@ pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref &pref.Pref eprintln('Warning: ${file.warnings[0]}') } if file.errors.len > 0 { - verror('Error ${file.errors[0]}') + g.n_error(file.errors[0].str()) } g.stmts(file.stmts) } @@ -109,7 +109,7 @@ pub fn (mut g Gen) generate_header() { } } else { - verror('Error: only `raw`, `linux` and `macos` are supported for -os in -native') + g.n_error('only `raw`, `linux` and `macos` are supported for -os in -native') } } } @@ -222,7 +222,7 @@ fn (mut g Gen) write_string_with_padding(s string, max int) { fn (mut g Gen) get_var_offset(var_name string) int { offset := g.var_offset[var_name] if offset == 0 { - verror('unknown variable `$var_name`') + g.n_error('unknown variable `$var_name`') } return offset } @@ -249,7 +249,7 @@ pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, name string) { else { dump(typeof(expr).name) dump(expr) - verror('expected string as argument for print') + g.n_error('expected string as argument for print') } } } @@ -268,7 +268,7 @@ fn (mut g Gen) println(comment string) { addr := g.debug_pos.hex() // println('$g.debug_pos "$addr"') print(term.red(strings.repeat(`0`, 6 - addr.len) + addr + ' ')) - for i := g.debug_pos; i < g.buf.len; i++ { + for i := g.debug_pos; i < g.pos(); i++ { s := g.buf[i].hex() if s.len == 1 { print(term.blue('0')) @@ -282,7 +282,7 @@ fn (mut g Gen) println(comment string) { } fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { - verror('for-in statement is not yet implemented') + g.v_error('for-in statement is not yet implemented', node.pos) /* if node.is_range { // `for x in 1..10 {` @@ -332,7 +332,7 @@ fn (mut g Gen) stmt(node ast.Stmt) { words := node.val.split(' ') for word in words { if word.len != 2 { - verror('opcodes format: xx xx xx xx') + g.n_error('opcodes format: xx xx xx xx') } b := unsafe { C.strtol(&char(word.str), 0, 16) } // b := word.byte() @@ -346,24 +346,27 @@ fn (mut g Gen) stmt(node ast.Stmt) { // if in main // zero := ast.IntegerLiteral{} // g.gen_exit(zero) - dump(node) - dump(node.types) + // dump(node) + // dump(node.types) mut s := '?' //${node.exprs[0].val.str()}' e0 := node.exprs[0] match e0 { ast.IntegerLiteral { + g.mov64(.rax, e0.val.int()) + } + ast.InfixExpr { // TODO + // verror('expr') } ast.StringLiteral { s = e0.val.str() - eprintln('jlalala $s') + g.expr(node.exprs[0]) + g.mov64(.rax, g.allocate_string(s, 2)) } else { - verror('unknown return type') + g.n_error('unknown return type $e0') } } - g.expr(node.exprs[0]) - g.mov64(.rax, g.allocate_string(s, 2)) // intel specific g.add8(.rsp, 0x20) // XXX depends on scope frame size g.pop(.rbp) @@ -387,7 +390,7 @@ fn (mut g Gen) expr(node ast.Expr) { g.expr(node.expr) } ast.ArrayInit { - verror('array init expr not supported yet') + g.n_error('array init expr not supported yet') } ast.BoolLiteral {} ast.CallExpr { @@ -403,7 +406,11 @@ fn (mut g Gen) expr(node ast.Expr) { ast.FloatLiteral {} ast.Ident {} ast.IfExpr { - g.if_expr(node) + if node.is_comptime { + eprintln('Warning: ignored compile time conditional not yet supported for the native backend.') + } else { + g.if_expr(node) + } } ast.InfixExpr {} ast.IntegerLiteral {} @@ -412,8 +419,11 @@ fn (mut g Gen) expr(node ast.Expr) { } ast.StringLiteral {} ast.StructInit {} + ast.GoExpr { + g.v_error('native backend doesnt support threads yet', node.pos) // token.Position{}) + } else { - println(term.red('native.expr(): unhandled node: ' + node.type_name())) + g.n_error('expr: unhandled node type: $node.type_name()') } } } @@ -436,11 +446,11 @@ fn (mut g Gen) postfix_expr(node ast.PostfixExpr) { } [noreturn] -fn verror(s string) { - util.verror('native gen error', s) +pub fn (mut g Gen) n_error(s string) { + util.verror('native error', s) } -pub fn (mut g Gen) error_with_pos(s string, pos token.Position) { +pub fn (mut g Gen) v_error(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 ...