aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/codegen.cup66
-rw-r--r--compiler/parser.cup1
2 files changed, 66 insertions, 1 deletions
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);