undar-lang/arch/web/main.c

95 lines
1.8 KiB
C

#include "../../libc.h"
#include "../../compiler.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <emscripten.h>
#define MEM_SIZE (1 << 16)
size_t
List_size(List *list)
{
size_t total = 0;
Node *curr = list->head;
while(curr) {
total += curr->size;
curr = curr->next;
}
return total;
}
void
list2buffer(List *list, char *buffer, size_t *offset)
{
Node *curr = list->head;
while(curr) {
char *tmp_str = node_value(curr);
memcpy(buffer + *offset, tmp_str, curr->size);
*offset += curr->size;
curr = curr->next;
}
}
EMSCRIPTEN_KEEPALIVE
char *
undar_compile(int emitter_type, char *source)
{
typedef enum { UXN, RER } EmitterType;
char uxn_temp_strbuf[32];
u8 tape[MEM_SIZE];
Arena a = {tape, 0, MEM_SIZE};
u8 et;
Emitter e;
switch(emitter_type) {
case 0:
e = rer_emitter();
et = RER;
break;
case 1:
e = uxn_emitter();
et = UXN;
break;
default:
return NULL;
}
List *code = List_init(&a);
List *msize = List_init(&a);
List *memory = List_init(&a);
compile(&a, code, memory, &e, source);
switch(et) {
case UXN: {
sprintf(uxn_temp_strbuf, "@mem_length_ #%04x\n @mem_ ", memory->count);
StrBuf_append(&a, msize, uxn_temp_strbuf);
break;
}
default: {
sprintf(uxn_temp_strbuf, "@mem_length_ #%04x\n @mem_ ", memory->count);
StrBuf_append(&a, msize, uxn_temp_strbuf);
break;
}
}
size_t code_size = List_size(code);
size_t m_size = List_size(msize);
size_t mem_size = List_size(memory);
size_t total_size = code_size + m_size + mem_size + 1;
char *result = (char *)malloc(total_size);
if(result == NULL) return NULL;
size_t offset = 0;
list2buffer(code, result, &offset);
list2buffer(msize, result, &offset);
list2buffer(memory, result, &offset);
result[offset] = '\0';
afree(&a);
return result;
}