#include "compiler.h" #include "common.h" #include "tokenizer.h" #include Code* signedLEB128(size_t num) { bool more = true; Code* buffer = (Code*)malloc(sizeof(Code)); buffer->count = 0; int n = (int)num; while (more) { uint8_t byte = n & 0x7f; n >>= 7; if ((n == 0 && (byte & 0x40) == 0) || (n == -1 && (byte & 0x40) != 0)) { more = false; } else { byte |= 0x80; } size_t old_count = buffer->count; uint8_t* tmp = (uint8_t*)calloc((old_count + 1), sizeof(uint8_t)); // really slow and bad refactor later memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t)); if (tmp) { buffer->cells = tmp; } buffer->cells[old_count] = byte; buffer->count += 1; } return buffer; } Code* unsignedLEB128(size_t num) { Code* buffer = (Code*)malloc(sizeof(Code)); buffer->count = 0; int n = (int)num; do { uint8_t byte = n & 0x7f; n >>= 7; if (n != 0) { byte |= 0x80; } size_t old_count = buffer->count; uint8_t* tmp = (uint8_t*)calloc((old_count + 1), sizeof(uint8_t)); // really slow and bad refactor later memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t)); if (tmp) { buffer->cells = tmp; } buffer->cells[old_count] = byte; buffer->count += 1; } while (n != 0); return buffer; } Code* generic_append(Code* tape, void* data, size_t data_size) { size_t old_count = tape->count; uint8_t* tmp = (uint8_t*)calloc((old_count + data_size), sizeof(uint8_t)); if (old_count > 0) { memcpy(tmp, tape->cells, tape->count * sizeof(uint8_t)); } if (tmp) { tape->cells = tmp; } memcpy((tape->cells + old_count), (unsigned char*)data, data_size); tape->count += data_size; return tape; } Code* append_byte(Code* tape, uint8_t data) { return generic_append(tape, &data, sizeof(uint8_t)); } Code* append_f64(Code* tape, double data) { return generic_append(tape, &data, sizeof(double)); } Code* append(Code* tape, Code* data) { size_t old_count = tape->count; uint8_t* tmp = (uint8_t*)calloc((old_count + data->count), sizeof(uint8_t)); memcpy(tmp, tape->cells, tape->count * sizeof(uint8_t)); if (tmp) { tape->cells = tmp; } memcpy((tape->cells + old_count), data->cells, data->count * sizeof(uint8_t)); tape->count += data->count; return tape; } Code* encodeString(char* string) { Code* buffer = (Code*)malloc(sizeof(Code)); buffer->cells = (uint8_t*)malloc(sizeof(uint8_t)); buffer->cells[0] = strlen(string); buffer->count = 1; uint8_t* tmp = (uint8_t*)malloc((1 + strlen(string)) * sizeof(char)); memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t)); if (tmp) { buffer->cells = tmp; } memcpy((buffer->cells + 1), string, strlen(string) * sizeof(char)); buffer->count += strlen(string); return buffer; } Code* encodeVector(Code* data) { size_t count = data->override ? data->override_count : data->count; Code* buffer = unsignedLEB128(count); append(buffer, data); return buffer; } Code* createSection(uint8_t section, Code* data) { Code* buffer = (Code*)malloc(sizeof(Code)); buffer->cells = (uint8_t*)malloc(sizeof(uint8_t)); buffer->cells[0] = section; buffer->count = 1; return append(buffer, encodeVector(data)); } Code* compile(char* buffer) { char number[100]; Code* add_args_code = (Code*)calloc(1, sizeof(Code)); Code* add_return_code = (Code*)calloc(1, sizeof(Code)); append_byte(add_return_code, f64); Code* add_function_type = (Code*)calloc(1, sizeof(Code)); append_byte(add_function_type, FUNCTION); append(add_function_type, encodeVector(add_args_code)); append(add_function_type, encodeVector(add_return_code)); add_function_type->override = true; add_function_type->override_count = 1; Code* type_section = createSection(TYPE, encodeVector(add_function_type)); Code* return_type_code = (Code*)calloc(1, sizeof(Code)); append_byte(return_type_code, 0x00); return_type_code->override = true; return_type_code->override_count = 1; Code* func_section = createSection(FUNC, encodeVector(return_type_code)); Code* exp = encodeString("main"); append_byte(exp, EXPORT_FUNC); append_byte(exp, 0x00); exp->override = true; exp->override_count = 1; Code* export_section = createSection(EXPORT, encodeVector(exp)); // Code* code = (Code*)calloc(1, sizeof(Code)); // append_byte(code, F64_CONST); // append_f64(code, 1.0); // append_byte(code, F64_CONST); // append_f64(code, 2.0); // append_byte(code, F64_ADD); Code* code = (Code*)calloc(1, sizeof(Code)); initTokenizer(buffer); Token t = nextToken(); do { // debug_printToken(t); switch (t.type) { case TOKEN_LEFT_PAREN: break; case TOKEN_RIGHT_PAREN: break; case TOKEN_LEFT_BRACE: break; case TOKEN_RIGHT_BRACE: break; case TOKEN_TILDE: break; case TOKEN_SLASH: break; case TOKEN_MINUS: break; case TOKEN_IDENTIFIER: break; case TOKEN_STRING: break; case TOKEN_FLOAT: strncpy(number, t.start, t.length); number[t.length + 1] = '\0'; append_byte(code, F64_CONST); append_f64(code, strtod(number, NULL)); break; case TOKEN_LIST: break; case TOKEN_ERROR: break; case TOKEN_FALSE: break; case TOKEN_TRUE: break; case TOKEN_PI: append_byte(code, F64_CONST); append_f64(code, M_PI); break; case TOKEN_E: append_byte(code, F64_CONST); append_f64(code, M_E); break; case TOKEN_EOF: break; case TOKEN_POP: append_byte(code, DROP); break; case TOKEN_DUP: break; case TOKEN_EXCH: break; case TOKEN_CLEAR: break; case TOKEN_REMEMBER: break; case TOKEN_FORGET: break; case TOKEN_DUMP: break; case TOKEN_NAME: break; case TOKEN_SET: break; case TOKEN_IFYES: break; case TOKEN_IFNO: break; case TOKEN_CHOOSE: break; case TOKEN_EVAL: break; case TOKEN_ESCAPE: break; case TOKEN_REPEAT: break; case TOKEN_SPLIT: break; case TOKEN_CONS: break; case TOKEN_SHATTER: break; case TOKEN_EMPTY: break; case TOKEN_COMPOSE: break; case TOKEN_STREQ: break; case TOKEN_STRCUT: break; case TOKEN_STRMEASURE: break; case TOKEN_STRTIE: break; case TOKEN_EXPLODE: break; case TOKEN_ADD: append_byte(code, F64_ADD); break; case TOKEN_SUB: append_byte(code, F64_SUB); break; case TOKEN_MUL: append_byte(code, F64_MUL); break; case TOKEN_DIV: append_byte(code, F64_DIV); break; case TOKEN_IDIV: break; case TOKEN_MOD: break; case TOKEN_POW: break; case TOKEN_SQRT: append_byte(code, F64_SQRT); break; case TOKEN_ADD1: append_byte(code, F64_CONST); append_f64(code, 1.0); append_byte(code, F64_ADD); break; case TOKEN_SUB1: append_byte(code, F64_CONST); append_f64(code, 1.0); append_byte(code, F64_SUB); break; case TOKEN_SIN: break; case TOKEN_COS: break; case TOKEN_TAN: break; case TOKEN_ATAN: break; case TOKEN_LN: break; case TOKEN_LOG: break; case TOKEN_LOG3: break; case TOKEN_CLIP: break; case TOKEN_SMOOTH: break; case TOKEN_HOWMUCH: break; case TOKEN_SETRAND: break; case TOKEN_RAND: break; case TOKEN_INT: break; case TOKEN_NUMBERIZE: break; case TOKEN_ISOLATE: break; case TOKEN_MIX: break; case TOKEN_CONTRADICT: break; case TOKEN_COMPL: break; case TOKEN_SHIFTRIGHT: break; case TOKEN_SHIFTLEFT: break; case TOKEN_GT: break; case TOKEN_LT: break; case TOKEN_EQ: break; case TOKEN_GE: break; case TOKEN_LE: break; case TOKEN_NE: break; case TOKEN_NULL: break; case TOKEN_NEGATIVE: break; case TOKEN_ISNULL: break; case TOKEN_ISINT: break; case TOKEN_ISNUMBER: break; case TOKEN_AND: break; case TOKEN_OR: break; case TOKEN_XOR: break; case TOKEN_DISP: break; case TOKEN_LISTEN: break; case TOKEN_COMPLAIN: break; case TOKEN_TIME: break; case TOKEN_GARBAGE_COLLECT: break; } t = nextToken(); } while (t.type != TOKEN_EOF); Code* body = (Code*)calloc(1, sizeof(Code)); append_byte(body, EMPTY_ARRAY); append(body, code); append_byte(body, END); Code* function_body = (Code*)calloc(1, sizeof(Code)); append(function_body, encodeVector(body)); function_body->override = true; function_body->override_count = 1; Code* code_section = createSection(CODE, encodeVector(function_body)); Code* tape = (Code*)malloc(sizeof(Code)); tape->cells = calloc(8, sizeof(uint8_t)); tape->cells[0] = 0; tape->cells[1] = 'a'; tape->cells[2] = 's'; tape->cells[3] = 'm'; tape->cells[4] = 1; tape->cells[5] = 0; tape->cells[6] = 0; tape->cells[7] = 0; tape->count = 8; append(tape, type_section); append(tape, func_section); append(tape, export_section); append(tape, code_section); return tape; }