| // X macro: Define a macro named X, then include this file, then undef X. | // X macro: Define a macro named X, then include this file, then undef X. | ||||
| #ifdef Y | |||||
| Y("none", knone) | |||||
| Y("true", ktrue) | |||||
| Y("false", kfalse) | |||||
| #ifdef XNAME | |||||
| XNAME("none", knone) | |||||
| #endif | #endif | ||||
| #ifdef X | |||||
| X("+", l2_builtin_add) | |||||
| X("-", l2_builtin_sub) | |||||
| X("*", l2_builtin_mul) | |||||
| X("/", l2_builtin_div) | |||||
| X("==", l2_builtin_eq) | |||||
| X("!=", l2_builtin_neq) | |||||
| X("<", l2_builtin_lt) | |||||
| X("<=", l2_builtin_lteq) | |||||
| X(">", l2_builtin_gt) | |||||
| X(">=", l2_builtin_gteq) | |||||
| X("&&", l2_builtin_land) | |||||
| X("||", l2_builtin_lor) | |||||
| X("??", l2_builtin_first) | |||||
| X("print", l2_builtin_print) | |||||
| X("len", l2_builtin_len) | |||||
| X("if", l2_builtin_if) | |||||
| X("loop", l2_builtin_loop) | |||||
| X("while", l2_builtin_while) | |||||
| #ifdef XATOM | |||||
| XATOM("true", ktrue) | |||||
| XATOM("false", kfalse) | |||||
| #endif | |||||
| #ifdef XFUNCTION | |||||
| XFUNCTION("+", l2_builtin_add) | |||||
| XFUNCTION("-", l2_builtin_sub) | |||||
| XFUNCTION("*", l2_builtin_mul) | |||||
| XFUNCTION("/", l2_builtin_div) | |||||
| XFUNCTION("==", l2_builtin_eq) | |||||
| XFUNCTION("!=", l2_builtin_neq) | |||||
| XFUNCTION("<", l2_builtin_lt) | |||||
| XFUNCTION("<=", l2_builtin_lteq) | |||||
| XFUNCTION(">", l2_builtin_gt) | |||||
| XFUNCTION(">=", l2_builtin_gteq) | |||||
| XFUNCTION("&&", l2_builtin_land) | |||||
| XFUNCTION("||", l2_builtin_lor) | |||||
| XFUNCTION("??", l2_builtin_first) | |||||
| XFUNCTION("print", l2_builtin_print) | |||||
| XFUNCTION("len", l2_builtin_len) | |||||
| XFUNCTION("if", l2_builtin_if) | |||||
| XFUNCTION("loop", l2_builtin_loop) | |||||
| XFUNCTION("while", l2_builtin_while) | |||||
| #endif | #endif |
| #include "vm.h" | #include "vm.h" | ||||
| #define X(name, f) \ | |||||
| #define XFUNCTION(name, f) \ | |||||
| l2_word f(struct l2_vm *vm, l2_word argc, l2_word *argv); | l2_word f(struct l2_vm *vm, l2_word argc, l2_word *argv); | ||||
| #include "../builtins.x.h" | #include "../builtins.x.h" | ||||
| #undef X | |||||
| #undef XFUNCTION |
| l2_bufio_writer_init(&gen->writer, w); | l2_bufio_writer_init(&gen->writer, w); | ||||
| // Register atoms for all builtins | // Register atoms for all builtins | ||||
| #define Y(name, k) \ | |||||
| #define XNAME(name, k) \ | |||||
| l2_strset_put_copy(&gen->atomset, name); | l2_strset_put_copy(&gen->atomset, name); | ||||
| #define X(name, f) \ | |||||
| #define XATOM(name, k) \ | |||||
| l2_strset_put_copy(&gen->atomset, name); | |||||
| #define XFUNCTION(name, f) \ | |||||
| l2_strset_put_copy(&gen->atomset, name); | l2_strset_put_copy(&gen->atomset, name); | ||||
| #include "builtins.x.h" | #include "builtins.x.h" | ||||
| #undef Y | |||||
| #undef X | |||||
| #undef XNAME | |||||
| #undef XATOM | |||||
| #undef XFUNCTION | |||||
| } | } | ||||
| void l2_gen_flush(struct l2_generator *gen) { | void l2_gen_flush(struct l2_generator *gen) { |
| vm->fstack[vm->fsptr].sptr = 0; | vm->fstack[vm->fsptr].sptr = 0; | ||||
| vm->fsptr += 1; | vm->fsptr += 1; | ||||
| // None is always at 0 | |||||
| vm->knone = 0; | |||||
| vm->values[vm->knone].flags = L2_VAL_TYPE_NONE | L2_VAL_CONST; | |||||
| // Define a C function variable for every builtin | // Define a C function variable for every builtin | ||||
| l2_word id; | l2_word id; | ||||
| l2_word key = 1; | l2_word key = 1; | ||||
| #define Y(name, k) \ | |||||
| if (strcmp(#k, "knone") == 0) { \ | |||||
| id = 0; \ | |||||
| l2_vm_namespace_set(&vm->values[builtins], key, id); \ | |||||
| } else { \ | |||||
| id = alloc_val(vm); \ | |||||
| vm->values[id].flags = L2_VAL_TYPE_ATOM | L2_VAL_CONST; \ | |||||
| vm->values[id].atom = key; \ | |||||
| } \ | |||||
| #define XNAME(name, k) \ | |||||
| l2_vm_namespace_set(&vm->values[builtins], key, vm->k); \ | |||||
| key += 1; | |||||
| #define XATOM(name, k) \ | |||||
| id = alloc_val(vm); \ | |||||
| vm->values[id].flags = L2_VAL_TYPE_ATOM | L2_VAL_CONST; \ | |||||
| vm->values[id].atom = key; \ | |||||
| vm->k = id; \ | vm->k = id; \ | ||||
| key += 1; | key += 1; | ||||
| #define X(name, f) \ | |||||
| #define XFUNCTION(name, f) \ | |||||
| id = alloc_val(vm); \ | id = alloc_val(vm); \ | ||||
| vm->values[id].flags = L2_VAL_TYPE_CFUNCTION | L2_VAL_CONST; \ | vm->values[id].flags = L2_VAL_TYPE_CFUNCTION | L2_VAL_CONST; \ | ||||
| vm->values[id].cfunc = f; \ | vm->values[id].cfunc = f; \ | ||||
| l2_vm_namespace_set(&vm->values[builtins], key++, id); | |||||
| l2_vm_namespace_set(&vm->values[builtins], key, id); \ | |||||
| key += 1; | |||||
| #include "builtins.x.h" | #include "builtins.x.h" | ||||
| #undef Y | |||||
| #undef X | |||||
| #undef XNAME | |||||
| #undef XATOM | |||||
| #undef XFUNCTION | |||||
| vm->gc_start = id + 1; | vm->gc_start = id + 1; | ||||
| } | } |