diff options
Diffstat (limited to 'src/execute.c')
-rw-r--r-- | src/execute.c | 365 |
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); } |