From f238f0cd851a0f9a3ec20388f27d10ea37114fee Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Sat, 5 Feb 2022 19:43:40 -0500 Subject: [compiler.cup] codegen for unary ops, short circuiting &&/|| --- compiler/codegen.cup | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ compiler/parser.cup | 1 - 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/compiler/codegen.cup b/compiler/codegen.cup index 71ffb76..407fab5 100644 --- a/compiler/codegen.cup +++ b/compiler/codegen.cup @@ -155,6 +155,72 @@ fn generate_expr_into_rax(node: Node*) { emit_asm(" setge al\n"); emit_asm(" movzx rax, al\n"); + } else if (node.typ == AST_BWAND) { + generate_expr_into_rax(node.d.binary.rhs); + emit_asm(" push rax\n"); + generate_expr_into_rax(node.d.binary.lhs); + emit_asm(" pop rbx\n"); + emit_asm(" and rax, rbx\n"); + + } else if (node.typ == AST_BWOR) { + generate_expr_into_rax(node.d.binary.rhs); + emit_asm(" push rax\n"); + generate_expr_into_rax(node.d.binary.lhs); + emit_asm(" pop rbx\n"); + emit_asm(" or rax, rbx\n"); + + } else if (node.typ == AST_XOR) { + generate_expr_into_rax(node.d.binary.rhs); + emit_asm(" push rax\n"); + generate_expr_into_rax(node.d.binary.lhs); + emit_asm(" pop rbx\n"); + emit_asm(" xor rax, rbx\n"); + + } else if (node.typ == AST_BWINV) { + generate_expr_into_rax(node.d.unary); + emit_asm(" not rax\n"); + + } else if (node.typ == AST_NEG) { + generate_expr_into_rax(node.d.unary); + emit_asm(" neg rax\n"); + + } else if (node.typ == AST_NOT) { + generate_expr_into_rax(node.d.unary); + emit_asm(" cmp rax, 0\n"); + emit_asm(" sete al\n"); + emit_asm(" movzx rax, al\n"); + + } else if (node.typ == AST_OR) { + // With short circuiting! + let label = ++gen_label_counter; + generate_expr_into_rax(node.d.binary.lhs,); + // If left is true, we can short-circuit + emit_asm(" cmp rax, 0\n"); + emit_asm(" je .or_r"); emit_num(label); emit_asm("\n"); + emit_asm(" mov rax, 1\n"); + emit_asm(" jmp .or_e"); emit_num(label); emit_asm("\n"); + emit_asm(".or_r"); emit_num(label); emit_asm(":\n"); + generate_expr_into_rax(node.d.binary.rhs); + // Booleanize the result + emit_asm(" cmp rax, 0\n"); + emit_asm(" setne al\n"); + emit_asm(".or_e"); emit_num(label); emit_asm(":\n"); + + } else if (node.typ == AST_AND) { + let label = ++gen_label_counter; + generate_expr_into_rax(node.d.binary.lhs); + // If left is false, we can short-circuit + emit_asm(" cmp rax, 0\n"); + emit_asm(" jne .and_r"); emit_num(label); emit_asm("\n"); + emit_asm(" mov rax, 0\n"); + emit_asm(" jmp .and_e"); emit_num(label); emit_asm("\n"); + emit_asm(".and_r"); emit_num(label); emit_asm(":\n"); + generate_expr_into_rax(node.d.binary.rhs); + // Booleanize the result + emit_asm(" cmp rax, 0\n"); + emit_asm(" setne al\n"); + emit_asm(".and_e"); emit_num(label); emit_asm(":\n"); + } else if (is_lvalue(node.typ)) { generate_lvalue_into_rax(node); emit_asm(" mov rax, [rax]\n"); diff --git a/compiler/parser.cup b/compiler/parser.cup index a910865..4d4c67d 100644 --- a/compiler/parser.cup +++ b/compiler/parser.cup @@ -320,7 +320,6 @@ fn parse_conditional_exp(lexer: Lexer*): Node* { fn parse_expression(lexer: Lexer*): Node* { let lhs = parse_conditional_exp(lexer); - putsln(node_type_to_string(lhs.typ)); if (is_lvalue(lhs.typ)) { let token: Token; lexer_peek(lexer, &token); -- cgit v1.2.3