// 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; | ||||
} | } |