aboutsummaryrefslogtreecommitdiff
path: root/src/interpret.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-06-25 23:25:29 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-06-25 23:25:29 +0300
commit01052811be08444458576dda994d15f8823560ea (patch)
treec52f2d72ef0ef703e755fcf05ee5d3a02f050acc /src/interpret.c
parent449ca1e570aa421992bbe98c6928def1ba8896fd (diff)
downloadposthaste-01052811be08444458576dda994d15f8823560ea.tar.gz
posthaste-01052811be08444458576dda994d15f8823560ea.zip
initial rewrite to use ejit
+ Doesn't actually link yet due to missing stuff from ejit, will have to add them (tomorrow?)
Diffstat (limited to 'src/interpret.c')
-rw-r--r--src/interpret.c407
1 files changed, 0 insertions, 407 deletions
diff --git a/src/interpret.c b/src/interpret.c
deleted file mode 100644
index 580303e..0000000
--- a/src/interpret.c
+++ /dev/null
@@ -1,407 +0,0 @@
-#include <math.h>
-#include <stdio.h>
-
-#include <posthaste/execute.h>
-#include <posthaste/lower.h>
-#include <posthaste/utils.h>
-#include <posthaste/date.h>
-#include <posthaste/vec.h>
-
-static int64_t load(struct loc l, size_t sp, struct vec *stack,
- struct vec *globals)
-{
- /* extra runtime branches is another reason this bytecode instruction
- * set is slow to interpret. To get rid of this if (), one
- * option would be to add LOAD/STORE_GLOBAL instructions that move data
- * between the global array and the stack, but this would make the JIT
- * slower */
- if (l.l)
- return vect_at(int64_t, *stack, l.o + sp);
-
- return vect_at(int64_t, *globals, l.o);
-}
-
-static void store(struct loc l, int64_t v, size_t sp, struct vec *stack,
- struct vec *globals)
-{
- if (l.l) {
- vect_at(int64_t, *stack, l.o + sp) = v;
- return;
- }
-
- vect_at(int64_t, *globals, l.o) = v;
-}
-
-static int64_t interpret_func(struct fn *f, struct vec *args, size_t sp,
- struct vec *stack, struct vec *globals)
-{
- /* move args to formal locations */
- size_t formal = 0;
- foreach_vec(ai, *args) {
- int64_t a = vect_at(int64_t, *args, ai);
- vect_at(int64_t, *stack, sp + formal) = a;
- formal += 1;
- }
-
- vec_reset(args);
-
- /* load/store from location, selecting between global array and stack. Assumes
- * parameter names, generally frowned upon. */
-#define get(l) \
- load(l, sp, stack, globals)
-
-#define put(l, v) \
- store(l, v, sp, stack, globals)
-
- /* use computed gotos to avoid extra overhead of loops/switch statements.
- * Usually I'm not a huge fan of massive single functions and from a
- * stylistic viewpoint maybe prefer breaking each instruction out into
- * its own procedure, but this at least saves a bit of typing */
-#define LINK(x) [x] = &&CASE_##x
- static void *labels[] = {
- LINK(LABEL),
- LINK(CALL),
- LINK(MOVE),
- LINK(ADD),
- LINK(SUB),
- LINK(MUL),
- LINK(DIV),
- LINK(ARG),
- LINK(RETVAL),
- LINK(PRINT_STRING),
- LINK(PRINT_INT),
- LINK(PRINT_BOOL),
- LINK(PRINT_DATE),
- LINK(PRINT_NEWLINE),
- LINK(PRINT_SPACE),
- LINK(DATE_ADD),
- LINK(DATE_SUB),
- LINK(DATE_DIFF),
- LINK(STORE_DAY),
- LINK(STORE_MONTH),
- LINK(STORE_YEAR),
- LINK(LOAD_DAY),
- LINK(LOAD_MONTH),
- LINK(LOAD_YEAR),
- LINK(LOAD_WEEKDAY),
- LINK(LOAD_WEEKNUM),
- LINK(TODAY),
- LINK(RET),
- LINK(STOP),
- LINK(CONST),
- LINK(EQ),
- LINK(LT),
- LINK(NEG),
- LINK(B),
- LINK(BZ),
- LINK(J),
- };
-#undef LINK
-
-#define JUMP() i = vect_at(struct insn, insns, pc); goto *labels[i.k];
-#define DISPATCH() pc++; JUMP();
-
-#define CASE(x) CASE_##x
-
- size_t pc = 0;
- int64_t retval = 0;
- struct vec insns = f->insns;
- struct insn i = {0};
- /* jump to first instruction */
- JUMP();
-
- CASE(STOP) : {return 0;}
- CASE(RET) : {return get(i.i0);}
-
- CASE(LABEL) : {DISPATCH();}
- CASE(RETVAL) : {put(i.o, retval); DISPATCH();}
-
- CASE(J) : {pc = i.v; JUMP();}
-
- CASE(B) : {
- int64_t i0 = get(i.i0);
- if (i0) {
- pc = i.v;
- JUMP();
- }
-
- DISPATCH();
- }
-
- CASE(BZ) : {
- int64_t i0 = get(i.i0);
- if (!i0) {
- pc = i.v;
- JUMP();
- }
-
- DISPATCH();
- }
-
- CASE(ARG) : {
- int64_t a = get(i.i0);
- vect_append(int64_t, *args, &a);
- DISPATCH();
- }
-
- CASE(CALL) : {
- struct fn *cf = find_fn(i.v);
- assert(cf);
-
- retval = interpret_func(cf, args, sp + f->max_sp + 1, stack,
- globals);
- DISPATCH();
- }
-
- CASE(MOVE) : {
- int64_t i0 = get(i.i0);
- put(i.o, i0);
- DISPATCH();
- }
-
-
- CASE(ADD) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 + i1;
- put(i.o, o);
- DISPATCH();
- }
-
- CASE(SUB) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 - i1;
- put(i.o, o);
- DISPATCH();
- }
-
- CASE(MUL) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 * i1;
- put(i.o, o);
- DISPATCH();
- }
-
- CASE(DIV) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 / i1;
- put(i.o, o);
- DISPATCH();
- }
-
- CASE(CONST) : {
- put(i.o, i.v);
- DISPATCH();
- }
-
- CASE(PRINT_DATE) : {
- int64_t i0 = get(i.i0);
- char str[11] = {0};
- date_to_string(str, i0);
- printf("%s", str);
- DISPATCH();
- }
-
- CASE(PRINT_INT) : {
- int64_t i0 = get(i.i0);
- printf("%lli", (long long)i0);
- DISPATCH();
- }
-
- CASE(PRINT_BOOL) : {
- int64_t i0 = get(i.i0);
- printf("%s", i0 ? "true" : "false");
- DISPATCH();
- }
-
- CASE(PRINT_STRING) : {
- int64_t i0 = get(i.i0);
- printf("%s", (const char *)i0);
- DISPATCH();
- }
-
- CASE(PRINT_NEWLINE) : {
- putchar('\n');
- DISPATCH();
- }
-
- CASE(PRINT_SPACE) : {
- putchar(' ');
- DISPATCH();
- }
-
- CASE(LOAD_DAY) : {
- int64_t i0 = get(i.i0);
- unsigned day = 0;
- date_split((ph_date_t)i0, NULL, NULL, &day);
- put(i.o, (int64_t)day);
- DISPATCH();
- }
-
- CASE(LOAD_MONTH) : {
- int64_t i0 = get(i.i0);
- unsigned month = 0;
- date_split((ph_date_t)i0, NULL, &month, NULL);
- put(i.o, (int64_t)month);
- DISPATCH();
- }
-
- CASE(LOAD_YEAR) : {
- int64_t i0 = get(i.i0);
- unsigned year = 0;
- date_split((ph_date_t)i0, &year, NULL, NULL);
- put(i.o, (int64_t)year);
- DISPATCH();
- }
-
- CASE(LOAD_WEEKDAY) : {
- int64_t i0 = get(i.i0);
- struct tm time = tm_from_date((ph_date_t)i0);
- put(i.o, (int64_t)time.tm_wday);
- DISPATCH();
- }
-
- CASE(LOAD_WEEKNUM) : {
- int64_t i0 = get(i.i0);
- struct tm time = tm_from_date((ph_date_t)i0);
- put(i.o, time.tm_yday / 7);
- DISPATCH();
- }
-
- CASE(STORE_DAY) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
-
- unsigned year = 0;
- unsigned month = 0;
- date_split((ph_date_t)i0, &year, &month, NULL);
- ph_date_t date = date_from_numbers(year, month, i1);
- put(i.o, (int64_t)date);
- DISPATCH();
- }
-
- CASE(STORE_MONTH) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
-
- unsigned year = 0;
- unsigned day = 0;
- date_split((ph_date_t)i0, &year, NULL, &day);
- ph_date_t date = date_from_numbers(year, i1, day);
- put(i.o, (int64_t)date);
- DISPATCH();
- }
-
- CASE(STORE_YEAR) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
-
- unsigned month = 0;
- unsigned day = 0;
- date_split((ph_date_t)i0, NULL, &month, &day);
- ph_date_t date = date_from_numbers(i1, month, day);
- put(i.o, (int64_t)date);
- DISPATCH();
- }
-
- CASE(DATE_ADD) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
-
- struct tm time = tm_from_date((ph_date_t)i0);
- time.tm_mday += i1;
- mktime(&time);
-
- ph_date_t date = date_from_tm(time);
- put(i.o, (int64_t)date);
- DISPATCH();
- }
-
- CASE(DATE_SUB) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
-
- struct tm time = tm_from_date((ph_date_t)i0);
- time.tm_mday -= i1;
- mktime(&time);
-
- ph_date_t date = date_from_tm(time);
- put(i.o, (int64_t)date);
- DISPATCH();
- }
-
- CASE(DATE_DIFF) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
-
- struct tm time0 = tm_from_date((ph_date_t)i0);
- struct tm time1 = tm_from_date((ph_date_t)i1);
-
- /* close enough at least */
- time_t t0 = mktime(&time0);
- time_t t1 = mktime(&time1);
- double seconds = difftime(t0, t1);
- int64_t days = round(seconds / 86400);
- put(i.o, days);
- DISPATCH();
- }
-
- CASE(TODAY) : {
- ph_date_t date = current_date();
- put(i.o, (int64_t)date);
- DISPATCH();
- }
-
- CASE(EQ) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t b = i0 == i1;
- put(i.o, b);
- DISPATCH();
- }
-
- CASE(LT) : {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t b = i0 < i1;
- put(i.o, b);
- DISPATCH();
- }
-
- CASE(NEG) : {
- int64_t i0 = get(i.i0);
- put(i.o, -i0);
- DISPATCH();
- }
-
-#undef CASE
-#undef JUMP
-#undef DISPATCH
-#undef get
-#undef put
-}
-
-void interpret()
-{
- struct fn *f = find_fn(0);
- assert(f);
-
- struct vec stack = vec_create(sizeof(int64_t));
- /* arbitrary amount of stack space, could potentially even be expanded
- * if we run out but that's currently not implemented */
- vec_reserve(&stack, 65535);
-
- struct vec globals = vec_create(sizeof(int64_t));
- vec_reserve(&globals, num_globals());
-
- struct vec args = vec_create(sizeof(int64_t));
-
- interpret_func(f, &args, 0, &stack, &globals);
-
- vec_destroy(&args);
- vec_destroy(&stack);
- vec_destroy(&globals);
-}