Plot project
This commit is contained in:
52
a/emit_asm_x64.c
Normal file
52
a/emit_asm_x64.c
Normal file
@@ -0,0 +1,52 @@
|
||||
void emit_expr(FILE *file, Ast *n) {
|
||||
switch (n->kind) {
|
||||
case AST_INT: {
|
||||
fprintf(file, " mov rax, %lu\n", n->u);
|
||||
} break;
|
||||
case AST_BINARY: {
|
||||
emit_expr(file, n->l);
|
||||
fprintf(file, " push rax\n");
|
||||
emit_expr(file, n->r);
|
||||
fprintf(file, " pop rcx\n");
|
||||
|
||||
if (n->op == TOK_PLUS) {
|
||||
fprintf(file, " add rax, rcx\n");
|
||||
} else if (n->op == TOK_STAR) {
|
||||
fprintf(file, " imul rax, rcx\n");
|
||||
} else if (n->op == TOK_MINUS) {
|
||||
fprintf(file, " mov rdx, rax\n");
|
||||
fprintf(file, " mov rax, rcx\n");
|
||||
fprintf(file, " sub rax, rdx\n");
|
||||
} else {
|
||||
panicf("error");
|
||||
}
|
||||
} break;
|
||||
default: panicf("error");
|
||||
}
|
||||
}
|
||||
|
||||
void emit_program(FILE *file, Ast *n) {
|
||||
fprintf(file, ".intel_syntax noprefix\n");
|
||||
fprintf(file, ".global main\n");
|
||||
fprintf(file, "main:\n");
|
||||
emit_expr(file, n);
|
||||
fprintf(file, " ret\n");
|
||||
}
|
||||
|
||||
void emit_expr_test(char *expr, int value) {
|
||||
Token_Array tokens = lex_file("expr", expr, strlen(expr));
|
||||
Parser parser = {tokens.data, tokens.data + tokens.len};
|
||||
Ast *ast = parse_expr(&parser, 0);
|
||||
FILE *file = fopen("out.s", "w");
|
||||
emit_program(file, ast);
|
||||
fclose(file);
|
||||
int result = system("clang out.s -o out");
|
||||
assert(result == 0);
|
||||
result = system("./out");
|
||||
assert(WEXITSTATUS(result) == value);
|
||||
}
|
||||
|
||||
void emit_x64_test(void) {
|
||||
emit_expr_test("10+5*2-10", 10+5*2-10);
|
||||
printf("x64 tests passed\n");
|
||||
}
|
||||
Reference in New Issue
Block a user