aboutsummaryrefslogtreecommitdiff
path: root/src/execute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/execute.c')
-rw-r--r--src/execute.c365
1 files changed, 4 insertions, 361 deletions
diff --git a/src/execute.c b/src/execute.c
index ace4adc..7da1a1a 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1,373 +1,16 @@
-#include <math.h>
-#include <stdio.h>
-
#include <posthaste/execute.h>
#include <posthaste/lower.h>
-#include <posthaste/date.h>
#include <posthaste/vec.h>
-#define UNUSED(x) (void)x
-
-#define DEF(x) \
- static void exec_##x(struct insn i, size_t sp, struct vec *stack, \
- struct vec *globals)
-
-static int64_t load(struct loc l, size_t sp, struct vec *stack,
- struct vec *globals)
-{
- 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;
-}
-
-#define get(l) \
- load(l, sp, stack, globals)
-
-#define put(l, v) \
- store(l, v, sp, stack, globals)
-
-DEF(MOVE) {
- int64_t i0 = get(i.i0);
- put(i.o, i0);
-}
-
-DEF(ADD) {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 + i1;
- put(i.o, o);
-}
-
-DEF(SUB) {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 - i1;
- put(i.o, o);
-}
-
-DEF(MUL) {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 * i1;
- put(i.o, o);
-}
-
-DEF(DIV) {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t o = i0 / i1;
- put(i.o, o);
-}
-
-DEF(PRINT_DATE) {
- int64_t i0 = get(i.i0);
- char str[11] = {0};
- date_to_string(str, i0);
- printf("%s", str);
-}
-
-DEF(PRINT_INT) {
- int64_t i0 = get(i.i0);
- printf("%lli", (long long)i0);
-}
-
-DEF(PRINT_STRING) {
- int64_t i0 = get(i.i0);
- printf("%s", (const char *)i0);
-}
-
-DEF(PRINT_BOOL) {
- int64_t i0 = get(i.i0);
- printf("%s", i0 ? "true" : "false");
-}
-
-DEF(PRINT_NEWLINE) {
- UNUSED(i);
- UNUSED(sp);
- UNUSED(stack);
- UNUSED(globals);
- printf("\n");
-}
-
-DEF(PRINT_SPACE) {
- UNUSED(i);
- UNUSED(sp);
- UNUSED(stack);
- UNUSED(globals);
- printf(" ");
-}
-
-DEF(CONST) {
- put(i.o, i.v);
-}
-
-DEF(EQ) {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t b = i0 == i1;
- put(i.o, b);
-}
-
-DEF(LT) {
- int64_t i0 = get(i.i0);
- int64_t i1 = get(i.i1);
- int64_t b = i0 < i1;
- put(i.o, b);
-}
-
-DEF(NEG) {
- int64_t i0 = get(i.i0);
- put(i.o, -i0);
-}
-
-DEF(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);
-}
-
-DEF(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);
-}
-
-DEF(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);
-}
-
-DEF(LOAD_WEEKDAY) {
- int64_t i0 = get(i.i0);
- struct tm time = tm_from_date((ph_date_t)i0);
-
- const char *day = "Sunday";
- switch (time.tm_wday) {
- case 0: day = "Sunday"; break;
- case 1: day = "Monday"; break;
- case 2: day = "Tuesday"; break;
- case 3: day = "Wednesday"; break;
- case 4: day = "Thursday"; break;
- case 5: day = "Friday"; break;
- case 6: day = "Saturday"; break;
- }
-
- put(i.o, (int64_t)day);
-}
-
-DEF(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);
-}
-
-DEF(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);
-}
-
-DEF(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);
-}
-
-DEF(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);
-}
-
-DEF(TODAY) {
- ph_date_t date = current_date();
- put(i.o, (int64_t)date);
-}
-
-DEF(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);
-}
-
-DEF(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);
-}
-
-DEF(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);
-}
-
-static int64_t exec_func(struct fn *f, struct vec *args, size_t sp,
- struct vec *stack, struct vec *globals)
-{
- /* move args to formal locations */
- size_t i = 0;
- foreach_vec(ai, *args) {
- int64_t a = vect_at(int64_t, *args, ai);
- vect_at(int64_t, *stack, sp + i) = a;
- i += 1;
- }
-
- vec_reset(args);
-
- size_t pc = 0;
- int64_t retval = 0;
- struct vec insns = f->insns;
- while (1) {
- struct insn i = vect_at(struct insn, insns, pc);
-
-#define DO(x) case x: exec_##x(i, sp, stack, globals); break;
- switch (i.k) {
- /* special cases first */
- case LABEL: break;
- case STOP: return 0;
- case RET: return get(i.i0);
- case RETVAL: put(i.o, retval); break;
- case J: pc = i.v; continue;
- case B: {
- int64_t i0 = get(i.i0);
- if (i0) {
- pc = i.v;
- continue;
- }
-
- break;
- }
-
- case BZ: {
- int64_t i0 = get(i.i0);
- if (!i0) {
- pc = i.v;
- continue;
- }
-
- break;
- }
-
- case ARG: {
- int64_t a = get(i.i0);
- vect_append(int64_t, *args, &a);
- break;
- }
-
- case CALL: {
- struct fn *cf = find_fn(i.v);
- assert(cf);
-
- retval = exec_func(cf, args, sp + f->max_sp, stack,
- globals);
- break;
- }
-
- DO(MOVE);
- DO(ADD);
- DO(SUB);
- DO(MUL);
- DO(DIV);
- DO(CONST);
- DO(PRINT_DATE);
- DO(PRINT_INT);
- DO(PRINT_BOOL);
- DO(PRINT_STRING);
- DO(PRINT_NEWLINE);
- DO(PRINT_SPACE);
- DO(LOAD_DAY);
- DO(LOAD_MONTH);
- DO(LOAD_YEAR);
- DO(LOAD_WEEKDAY);
- DO(LOAD_WEEKNUM);
- DO(STORE_DAY);
- DO(STORE_MONTH);
- DO(STORE_YEAR);
- DO(DATE_ADD);
- DO(DATE_SUB);
- DO(DATE_DIFF);
- DO(TODAY);
- DO(EQ);
- DO(LT);
- DO(NEG);
- }
-#undef DO
-
- pc += 1;
- }
-}
-
void execute()
{
- struct fn *main = find_fn(0);
- assert(main);
-
- struct vec stack = vec_create(sizeof(int64_t));
- /* arbitrary amount */
- vec_reserve(&stack, 65535);
+ struct fn *f = find_fn(0);
+ void (*p)(int64_t *globals) = f->arena;
struct vec globals = vec_create(sizeof(int64_t));
- /* should really take the value calculated during lowering */
- vec_reserve(&globals, 65535);
-
- struct vec args = vec_create(sizeof(int64_t));
+ vec_reserve(&globals, num_globals());
- exec_func(main, &args, 0, &stack, &globals);
+ p(globals.buf);
- vec_destroy(&args);
- vec_destroy(&stack);
vec_destroy(&globals);
}