#include #include #include #include "compile.h" #include "hashtable.h" #include "parse.h" int currentMangleId = 0; int currentLitId = 0; int includeStrlen = 0; litData_t** literalData; litData_t* init_str_data(char* value) { litData_t* litData = malloc(sizeof(litData_t)); litData->litType = STRING; char* vp = malloc((strlen(value) + 1) * sizeof(char)); strcpy(vp, value); litData->data = vp; litData->id = currentLitId; return litData; } char* compile_to_asm(sym_t* symbol) { literalData = malloc(sizeof(litData_t) * 100); //100 literals char* header = ".global _start\n.text\n_start: "; char* program = compile_to_asm_internal(symbol, currentMangleId); char* dataH = ".data\n"; char* data = build_data(); char* footer = "mov $60, %rax\n" "xorl %rdi, %rdi\n" "syscall\n"; char* funcs = lib_funcs(); //build this last so it can consider contents of program char* final = malloc(sizeof(char) * (strlen(header) + strlen(funcs) + strlen(program) + strlen(dataH) + strlen(data) + strlen(footer) + 1)); strcpy(final, header); strcat(final, program); strcat(final, footer); strcat(final, funcs); strcat(final, dataH); strcat(final, data); return final; } char* build_data() { //TODO: fix LABEL and non-STRING types int l = 0; char* out = ""; for (int i = 0; i < currentLitId; i++) { int lv = strlen((char*)literalData[i]->data); int resl = 15 + lv; char* line = malloc(sizeof(char) * (resl + 1)); snprintf(line, resl + 1, "%cAA: .asciz \"%s\"\n", i + 65, (char*)literalData[i]->data); if (i == 0) { out = malloc(sizeof(char) * (resl + 1)); } else { out = realloc(out, sizeof(char) * (l + resl + 1)); } strcpy(out + l, line); l += resl; } return out; } char* lib_funcs() { if (includeStrlen) { return "strlen: xor %rax, %rax\n" "dec %rax\n" "strlen_count: inc %rax\n" "cmpb $0x0, (%rdi,%rax,1)\n" "jne strlen_count\n" "ret\n"; } else { return ""; } } char* compile_to_asm_internal(sym_t* symbol, int mangleId) { char* out; if (symbol->province == LITERAL) { /* store the symbol in .data */ if (symbol->litType == STRING) { /* temporary implementation */ literalData[currentLitId] = init_str_data((char*)symbol->name); out = malloc(sizeof(char) * 16); snprintf(out, 16, "mov $%cAA, \%rax\n", currentLitId + 65); currentLitId++; return out; } /*if (symbol->litType == INT) { return init_sym_int(*((int*)symbol->name)); } else if (symbol->litType == FLOAT) { return init_sym_float(*((float*)symbol->name)); } else if (symbol->litType == STRING) { return init_sym_str((char*)symbol->name); } else { return NULL; }*/ } else if (symbol->province == KEY_REF) { /* TODO: mangle */ char* ir = try_comp_internal(symbol, ++currentMangleId); if (ir != NULL) { out = ir; } else { } return out; /*sym_t* returnV = NULL; hashtable_t* newScope = init_hashtable(50, parentScope); sym_t* ir = try_comp_internal(symbol, newScope); if (ir != NULL) { returnV = ir; } else { pair_t p = hashtable_get_pair_recurse(parentScope, (char*)symbol->name); if (p.key != NULL) { sym_t* nextSym = (sym_t*)p.value; if (symbol->argCount > 0) { returnV = eval_with_args(nextSym, symbol->args, symbol->argCount, newScope); } else { returnV = eval(nextSym, newScope); } } else { printf("key %s not found in any scope\n", (char*)symbol->name); } } destroy_hashtable(newScope); return returnV; */ } else { printf("no symbol province\n"); return NULL; } } char* comp_all(sym_t** symbols, int count, int mangleId) { int l = 0; char* out; for (int i = 0; i < count; i++) { char* res = compile_to_asm_internal(symbols[i], mangleId); int resl = strlen(res); if (i == 0) { out = malloc(sizeof(char) * (resl + 1)); } else { out = realloc(out, sizeof(char) * (l + resl + 1)); } strcpy(out + l, res); l += resl; } return out; } char* try_comp_internal(sym_t* symbol, int mangleId) { unsigned int hash = get_hash((char*)symbol->name); if (hash == get_hash("root")) { //todo--add return wrapper for last return comp_all(symbol->args, symbol->argCount, mangleId); } else if (hash == get_hash("print")) { includeStrlen = 1; /* execute the argument to receive rax--return value */ char* pre = compile_to_asm_internal(symbol->args[0], mangleId); char* body = "mov %rax, %rsi\n" "mov %rsi, %rdi\n" "call strlen\n" "mov %rax, %rdx\n" "mov $1, %rax\n" "mov $1, %rdi\n" "syscall\n"; pre = realloc(pre, sizeof(char) * (strlen(pre) + strlen(body) + 1)); strcat(pre, body); return pre; } else { return NULL; } }