341 lines
8.3 KiB
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;
|
|
}
|