varaq-wasm-c/compiler.c

341 lines
8.3 KiB
C

#include "compiler.h"
#include "common.h"
#include "tokenizer.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 *
append_byte (Code *tape, uint8_t data)
{
size_t old_count = tape->count;
uint8_t *tmp = (uint8_t *)calloc ((old_count + 1), sizeof (uint8_t));
if (old_count > 0)
{
memcpy (tmp, tape->cells, tape->count * sizeof (uint8_t));
}
if (tmp)
{
tape->cells = tmp;
}
tape->cells[old_count] = data;
tape->count += 1;
return tape;
}
Code *
append_f64 (Code *tape, double data)
{
size_t old_count = tape->count;
uint8_t *tmp
= (uint8_t *)calloc ((old_count + sizeof (data)), 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, sizeof (data));
tape->count += sizeof (data);
return tape;
}
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 *
demo_function_compile ()
{
Code *add_args_code = (Code *)calloc (1, sizeof (Code));
append_byte (add_args_code, f32);
append_byte (add_args_code, f32);
Code *add_return_code = (Code *)calloc (1, sizeof (Code));
append_byte (add_return_code, f32);
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, LOCAL_GET);
append (code, unsignedLEB128 (0));
append_byte (code, LOCAL_GET);
append (code, unsignedLEB128 (1));
append_byte (code, F32_ADD);
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;
}
Code *
demo_add_compile ()
{
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, 6.7);
append_byte (code, F64_CONST);
append_f64 (code, 8.5);
append_byte (code, F64_ADD);
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;
}
Code *
compile (char *buffer)
{
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;
initTokenizer (buffer);
Token t = nextToken ();
while (t.type != TOKEN_EOF)
{
debug_printToken (t);
t = nextToken ();
}
return tape;
}