native: support comparing two idents and avoid printing idents (#13686)

pull/13698/head
pancake 2022-03-08 18:52:30 +01:00 committed by GitHub
parent 10474f35f6
commit 3f1e232c9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 4 deletions

View File

@ -135,6 +135,15 @@ fn (mut g Gen) cmp_reg(reg Register, reg2 Register) {
g.println('cmp $reg, $reg2') g.println('cmp $reg, $reg2')
} }
fn (mut g Gen) cmp_var_reg(var_name string, reg Register) {
g.write8(0x48) // 83 for 1 byte?
g.write8(0x39)
g.write8(0x45)
offset := g.get_var_offset(var_name)
g.write8(0xff - offset + 1)
g.println('cmp var `$var_name`, $reg')
}
fn (mut g Gen) cmp_var(var_name string, val int) { fn (mut g Gen) cmp_var(var_name string, val int) {
g.write8(0x81) // 83 for 1 byte? g.write8(0x81) // 83 for 1 byte?
g.write8(0x7d) g.write8(0x7d)
@ -1007,7 +1016,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
g.mov_reg_to_var(offset, .rax) g.mov_reg_to_var(offset, .rax)
} }
ast.InfixExpr { ast.InfixExpr {
eprintln('assign') // eprintln('assign')
// dump(node.left[i]) // dump(node.left[i])
offset := g.get_var_offset('i') // node.left[i]) offset := g.get_var_offset('i') // node.left[i])
g.mov_reg_to_var(offset, native.fn_arg_registers[i]) g.mov_reg_to_var(offset, native.fn_arg_registers[i])
@ -1407,6 +1416,7 @@ fn (mut g Gen) condition(infix_expr ast.InfixExpr, neg bool) int {
// 3 < 4 // 3 < 4
a0 := infix_expr.left.val.int() a0 := infix_expr.left.val.int()
// a0 := (infix_expr.left as ast.IntegerLiteral).val.int() // a0 := (infix_expr.left as ast.IntegerLiteral).val.int()
// XXX this will not compile
a1 := (infix_expr.right as ast.IntegerLiteral).val.int() a1 := (infix_expr.right as ast.IntegerLiteral).val.int()
// TODO. compute at compile time // TODO. compute at compile time
g.mov(.eax, a0) g.mov(.eax, a0)
@ -1507,8 +1517,20 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
start := g.pos() start := g.pos()
match mut infix_expr.left { match mut infix_expr.left {
ast.Ident { ast.Ident {
lit := infix_expr.right as ast.IntegerLiteral match infix_expr.right {
g.cmp_var(infix_expr.left.name, lit.val.int()) ast.Ident {
var_offset := g.get_var_offset(infix_expr.right.name)
g.mov_var_to_reg(.rax, var_offset)
g.cmp_var_reg(infix_expr.left.name, .rax)
}
ast.IntegerLiteral {
lit := infix_expr.right as ast.IntegerLiteral
g.cmp_var(infix_expr.left.name, lit.val.int())
}
else {
g.n_error('unhandled expression type')
}
}
match infix_expr.left.tok_kind { match infix_expr.left.tok_kind {
.lt { .lt {
jump_addr = g.cjmp(.jge) jump_addr = g.cjmp(.jge)

View File

@ -300,8 +300,13 @@ pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, name string) {
g.gen_print_reg(.rax, 3, fd) g.gen_print_reg(.rax, 3, fd)
} }
ast.Ident { ast.Ident {
g.expr(expr) g.n_error('Printing idents is not yet supported in the native backend')
/*
vo := g.get_var_offset(expr.name)
g.mov_var_to_reg(.rax, vo)
//g.expr(expr)
g.gen_print_reg(.rax, 3, fd) g.gen_print_reg(.rax, 3, fd)
*/
} }
ast.IntegerLiteral { ast.IntegerLiteral {
g.learel(.rax, g.allocate_string('$expr.val\n', 3, .rel32)) g.learel(.rax, g.allocate_string('$expr.val\n', 3, .rel32))

View File

@ -0,0 +1,8 @@
fn main() {
a := 123
b := 456
for a < b {
println('a < b')
exit(0)
}
}

View File

@ -0,0 +1 @@
a < b