varaq-wasm-c/compiler.c

436 lines
9.7 KiB
C

#include "compiler.h"
#include "common.h"
#include "tokenizer.h"
#include <math.h>
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;
}