#include"value.h" #include"table.h" #include"parse.h" #include"vm.h" #include"lexer.h" #include"str.h" #include"dump.h" #include #include static size_t native_print(LVM *lvm, void *ud, size_t argn, set_LValueU *heap, LRegSet *regset) { if(lvalue_tag(regset->regs[0]) == LTAG_STRING) { LString *lstr = (void*) (regset->regs[0].u & ~LTAG_MASK); printf("%.*s\n", (int) lstr->length, lstr->data); } else if(lvalue_tag(regset->regs[0]) == LTAG_I32) { printf("%i\n", lvalue_to_int32(regset->regs[0])); } else if(lvalue_tag(regset->regs[0]) == LTAG_TABLE) { printf("table: 0x%lx\n", (uintptr_t) (regset->regs[0].u & ~LTAG_MASK)); } else if(lvalue_tag(regset->regs[0]) == LTAG_FUNCTION) { printf("function: 0x%lx\n", (uintptr_t) (regset->regs[0].u & ~LTAG_MASK)); } else if(regset->regs[0].u == LTAG_NIL) { printf("nil\n"); } else if(regset->regs[0].u == LTAG_TRUE) { printf("true\n"); } else if(regset->regs[0].u == LTAG_FALSE) { printf("false\n"); } else if(!isnan(regset->regs[0].f)) { printf("%f\n", regset->regs[0].f); } return 0; } static size_t table_insert(LVM *lvm, void *ud, size_t argn, set_LValueU *heap, LRegSet *regset) { LTable *tbl = (LTable*) (regset->regs[0].u & ~LTAG_MASK); ltable_insert(tbl, regset->regs[1], 0); return 0; } // This function is intended for small-medium runtimes, since the caller thread's heap is not touchable during this call. static size_t threads_parallel(LVM *lvm, void *ud, size_t argn, set_LValueU *heap, LRegSet *regset) { size_t no = lvalue_to_int32(regset->regs[0]); LFunc *func = (LFunc*) (regset->regs[1].u & ~LTAG_MASK); atomic_fetch_sub(&lvm->active_thread_count, 1); #pragma omp parallel for for(size_t i = 0; i < no; i++) { LRegSet regset = {}; lvm_reset_regs(®set); lvm_run(lvm, func, 0, ®set); } atomic_fetch_add(&lvm->active_thread_count, 1); return 0; } static char* read_full_file(const char *fn) { FILE *f = fn ? fopen(fn, "rb") : stdin; fseek(f, 0, SEEK_END); size_t filesize = ftell(f); fseek(f, 0, SEEK_SET); char *buf = malloc(filesize + 1); fread(buf, 1, filesize, f); buf[filesize] = '\0'; if(fn) fclose(f); return buf; } int main(int argc, char **argv) { LTable *env = ltable_new(128); ltable_set(env, lvalue_from_string(lstring_newz("print")), lvalue_from_func(lvm_func_from_native(native_print, NULL))); LTable *table = ltable_new(16); { ltable_set(table, lvalue_from_string(lstring_newz("insert")), lvalue_from_func(lvm_func_from_native(table_insert, NULL))); } ltable_set(env, lvalue_from_string(lstring_newz("table")), lvalue_from_table(table)); LTable *threads = ltable_new(16); { ltable_set(threads, lvalue_from_string(lstring_newz("parallel")), lvalue_from_func(lvm_func_from_native(threads_parallel, NULL))); } ltable_set(env, lvalue_from_string(lstring_newz("threads")), lvalue_from_table(threads)); LTable *math = ltable_new(16); { ltable_set(math, lvalue_from_string(lstring_newz("pi")), (LValue) {.f = 3.141592653589793238463}); } ltable_set(env, lvalue_from_string(lstring_newz("math")), lvalue_from_table(math)); //const char *bufs = "for i = 1, 10000 do print(i) if i % 3 == 0 then print(\"Fizz\") end if i % 5 == 0 then print(\"Buzz\") end end"; //const char *bufs = "local t = {a = 9} print(t.a)"; //const char *bufs = "z = 5 print(z)"; //const char *bufs = "local i = 0 while i ~= 1500000 do print(i) i = i + 1 end"; //const char *bufs = "for i = 1, 1000 do print(print) end"; char *bufs = read_full_file(argv[1]); vec_Token toks = ltokenize(bufs, strlen(bufs)); free(bufs); LUnit *unit = lparse(toks.size, toks.data, env); lfreetoks(&toks); //dump(unit->funcs[0].lua_instrs); LVM lvm = {}; lvm_init(&lvm); LRegSet regset = {.parent = NULL}; lvm_reset_regs(®set); lvm_run(&lvm, &unit->funcs[0], 0, ®set); lvm_destroy(&lvm); }