-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
90c0448
commit 31ce8ff
Showing
18 changed files
with
8,643 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,3 +50,9 @@ modules.order | |
Module.symvers | ||
Mkfile.old | ||
dkms.conf | ||
|
||
config.h | ||
|
||
Makefile | ||
|
||
wsi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
CC=@CC@ | ||
CFLAGS=@DISTRO@ | ||
OBJ=wsi.o disasm.o run.o parse.o compile.o tcc.o | ||
|
||
.PHONY: clean fix-libtcc | ||
|
||
%.o: %.c | ||
$(CC) $(CFLAGS) -c -o $@ $< | ||
|
||
wsi: $(OBJ) | ||
$(CC) $(CFLAGS) -o $@ $^ @LIBS@ | ||
|
||
clean: | ||
rm -f *.o *~ config.log config.status | ||
rm -rf autom4te.cache/ | ||
|
||
fix-libtcc: | ||
mkdir /usr/lib/x86_64-linux-gnu/tcc/ | ||
cp /usr/lib/x86_64-linux-gnu/libtcc.a /usr/lib/x86_64-linux-gnu/tcc/libtcc1.a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
#ifndef _COMMON_H | ||
#define _COMMON_H | ||
|
||
#include "config.h" | ||
|
||
#include <stdio.h> | ||
#include "whitespace.h" | ||
|
||
struct parse_result_t parse(FILE * input, void (*error)(char * s), void (*warn)(char * s)); | ||
void disasm(FILE * output, vector(struct instruction_t) program); | ||
void disasm_single(FILE * output, struct instruction_t * it); | ||
int32_t run(struct parse_result_t program, struct state * state, void(*fatal)(char *)); | ||
char * compile(struct parse_result_t program); | ||
|
||
#ifdef JIT | ||
|
||
#ifndef HAVE_LIBTCC_H | ||
#error JIT compiler used without libtcc.h present. | ||
#endif | ||
|
||
void run_jit(struct parse_result_t program, void(*fatal)(char *)); | ||
|
||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdarg.h> | ||
#include <string.h> | ||
#include <assert.h> | ||
#include <stdint.h> | ||
|
||
#include "vector.h" | ||
#include "common.h" | ||
|
||
static void append_code(char ** buf, char * format, ...) { | ||
va_list args, args2; | ||
va_start(args, format); | ||
va_copy(args2, args); | ||
uint32_t buflen = *buf ? strlen(*buf) : 0; | ||
uint32_t length = 1 + buflen + vsnprintf(NULL, 0, format, args); | ||
va_end(args); | ||
if(*buf) | ||
*buf = realloc(*buf, length); | ||
else | ||
*buf = malloc(length); | ||
assert(*buf); | ||
vsnprintf(*buf + buflen, length - buflen, format, args2); | ||
va_end(args2); | ||
} | ||
|
||
#define emit(x) append_code(&code, x) | ||
#define emitf(x,...) append_code(&code, x, __VA_ARGS__) | ||
|
||
char * compile(struct parse_result_t program) { | ||
unsigned callid = vector_size(program.labels); | ||
char * code = NULL; | ||
emit( | ||
"#include \"vector.h\"\n" | ||
"#ifndef DURING_JIT\n" | ||
"\t#include <stdlib.h>\n" | ||
"\t#include <stdio.h>\n" | ||
"\t#include <stdint.h>\n" | ||
"#else\n" | ||
"\tint putchar(int);\n" | ||
"\tint getchar(void);\n" | ||
"\tint printf(char * fmt, ...);\n" | ||
"\tint scanf(char * fmt, ...);\n" | ||
"\ttypedef int int32_t;\n" | ||
"\t#define NULL ((void *) 0)\n" | ||
"#endif\n" | ||
"\n" | ||
"static vector(int32_t) stack;\n" | ||
"static vector(int32_t) heap;\n" | ||
"static vector(int32_t) callstack;\n" | ||
"static int32_t lhs, rhs, tmp, ip;\n" | ||
"\n" | ||
"#define AT(x, y) vector_end(x)[-y]\n" | ||
"#define BILOAD \\\n" | ||
"\trhs = AT(stack, 1); \\\n" | ||
"\tlhs = AT(stack, 2); \\\n" | ||
"\tvector_pop_back(stack); \\\n" | ||
"\tvector_pop_back(stack)\n" | ||
"\n" | ||
"int main(void) {\n" | ||
"\tbranch: switch(ip) {\n" | ||
"case 0:\n" | ||
); | ||
|
||
vector_foreach(struct instruction_t, ins, program.program) { | ||
switch(ins->type) { | ||
case GETC: | ||
emit( | ||
"\trhs = AT(stack, 1);\n" | ||
"\tvector_pop_back(stack);\n" | ||
"\twhile(vector_size(heap) <= (unsigned) rhs)\n" | ||
"\t\tvector_push_back(heap, 0);\n" | ||
"\theap[rhs] = getchar();\n" | ||
); | ||
break; | ||
case PUTC: | ||
emit( | ||
"\tputchar(AT(stack, 1));\n" | ||
"\tvector_pop_back(stack);\n" | ||
); | ||
break; | ||
case GETN: | ||
emit( | ||
"\trhs = AT(stack, 1);\n" | ||
"\tvector_pop_back(stack);\n" | ||
"\twhile(vector_size(heap) <= (unsigned) rhs)\n" | ||
"\t\tvector_push_back(heap, 0);\n" | ||
"\tscanf(\"%%d\", &tmp);\n" | ||
"\theap[rhs] = tmp;\n" | ||
); | ||
break; | ||
case PUTN: | ||
emit( | ||
"\tprintf(\"%%d\", AT(stack, 1));\n" | ||
"\tvector_pop_back(stack);\n" | ||
); | ||
break; | ||
case PSH: | ||
emitf("\tvector_push_back(stack, %d);\n", ins->data); | ||
break; | ||
case DUP: | ||
emit("\tvector_push_back(stack, AT(stack, 1));\n"); | ||
break; | ||
case XCHG: | ||
emit( | ||
"\ttmp = AT(stack, 2);\n" | ||
"\tAT(stack, 2) = AT(stack, 1);\n" | ||
"\tAT(stack, 1) = tmp;\n" | ||
); | ||
break; | ||
case DROP: | ||
emit("\tvector_pop_back(stack);\n"); | ||
break; | ||
case ADD: | ||
emit("\tBILOAD; vector_push_back(stack, lhs + rhs);\n"); | ||
break; | ||
case SUB: | ||
emit("\tBILOAD; vector_push_back(stack, lhs - rhs);\n"); | ||
break; | ||
case DIV: | ||
emit("\tBILOAD; vector_push_back(stack, lhs / rhs);\n"); | ||
break; | ||
case MUL: | ||
emit("\tBILOAD; vector_push_back(stack, lhs * rhs);\n"); | ||
break; | ||
case MOD: | ||
emit("\tBILOAD; vector_push_back(stack, lhs %% rhs);\n"); | ||
break; | ||
case END: | ||
emit("\treturn 0;\n"); | ||
break; | ||
case STO: | ||
emit( | ||
"\tBILOAD;\n" | ||
"\twhile(vector_size(heap) <= (unsigned) lhs)\n" | ||
"\t\tvector_push_back(heap, 0);\n" | ||
"\theap[lhs] = rhs;\n" | ||
); | ||
break; | ||
case RCL: | ||
emit( | ||
"\tlhs = AT(stack, 1);\n" | ||
"\tvector_pop_back(stack);\n" | ||
"\tif(vector_size(heap) <= (unsigned) lhs)\n" | ||
"\t\tvector_push_back(stack, 0);\n" | ||
"\telse\n" | ||
"\t\tvector_push_back(stack, heap[lhs]);\n" | ||
); | ||
break; | ||
case LBL: | ||
emitf("case %d:\n", ins->data); | ||
break; | ||
case JMP: | ||
emitf( | ||
"\tip = %d;\n" | ||
"\tgoto branch;\n" | ||
, ins->data); | ||
break; | ||
case BZ: | ||
emitf( | ||
"\tlhs = AT(stack, 1);\n" | ||
"\tvector_pop_back(stack);\n" | ||
"\tif(lhs == 0) {\n" | ||
"\t\tip = %d;\n" | ||
"\t\tgoto branch;\n" | ||
"\t}\n" | ||
, ins->data); | ||
break; | ||
case BLTZ: | ||
emitf( | ||
"\tlhs = AT(stack, 1);\n" | ||
"\tvector_pop_back(stack);\n" | ||
"\tif(lhs < 0) {\n" | ||
"\t\tip = %d;\n" | ||
"\t\tgoto branch;\n" | ||
"\t}\n" | ||
, ins->data); | ||
break; | ||
case CALL: | ||
emitf( | ||
"\tvector_push_back(callstack, %d);\n" | ||
"\tip = %d;\n" | ||
"\tgoto branch;\n" | ||
"case %d:\n" | ||
, callid + 1, ins->data, callid + 1); | ||
callid++; | ||
break; | ||
case RET: | ||
emit( | ||
"\tip = AT(callstack, 1);\n" | ||
"\tvector_pop_back(callstack);\n" | ||
"\tgoto branch;\n" | ||
); | ||
break; | ||
} | ||
} | ||
|
||
emit( | ||
"\t}\n" | ||
"}\n" | ||
); | ||
|
||
return code; | ||
} |
Oops, something went wrong.