diff --git a/ps5/src/generator.c b/ps5/src/generator.c index d85306f..c73bd2e 100644 --- a/ps5/src/generator.c +++ b/ps5/src/generator.c @@ -166,6 +166,39 @@ static void generate_function_call(node_t* call) // TODO (Task 4.3) } +#define UNARY_OP(OP, INST) \ + if (strcmp(op, (OP)) == 0) { \ + generate_expression(expression->children[0]); \ + INST(RAX); \ + } +#define BINARY_OP(OP, INST) \ + if (strcmp(op, (OP)) == 0) { \ + generate_expression(left); \ + PUSHQ(RAX); \ + generate_expression(right); \ + POPQ(RCX); \ + INST(RCX, RAX); \ + } +#define DIVISION_OP \ + if (strcmp(op, "/") == 0) { \ + generate_expression(expression->children[1]); \ + PUSHQ(RAX); \ + generate_expression(expression->children[0]); \ + CQO; \ + POPQ(RCX); \ + IDIVQ(RCX); \ + } +#define COMPARE_OP(OP, INST) \ + if (strcmp(op, (OP)) == 0) { \ + generate_expression(left); \ + PUSHQ(RAX); \ + generate_expression(right); \ + POPQ(RCX); \ + CMPQ(RAX, RCX); \ + INST(AL); \ + MOVZBQ(AL, RAX); \ + } + // Generates code to evaluate the expression, and place the result in %rax static void generate_expression(node_t* expression) { @@ -187,6 +220,30 @@ static void generate_expression(node_t* expression) EMIT("movq (%s), %s", RAX, RAX); // deref rax break; case OPERATOR: + char *op = expression->data.operator; + switch (expression->n_children) { + case 1: + UNARY_OP("-", NEGQ); + /* logical not "!" is omitted */ + break; + case 2: + node_t *left = expression->children[0]; + node_t *right = expression->children[1]; + BINARY_OP("+", ADDQ); + BINARY_OP("-", SUBQ); + BINARY_OP("*", IMULQ); + DIVISION_OP; // special snowflake + COMPARE_OP("<", SETL); + COMPARE_OP(">", SETG); + COMPARE_OP("<=", SETLE); + COMPARE_OP(">=", SETGE); + COMPARE_OP("==", SETE); + COMPARE_OP("!=", SETNE); + break; + case 3: + /* ternary op "?:" is omitted */ + break; + } break; case FUNCTION_CALL: break;