// 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) | |||||
#endif | |||||
#ifdef X | #ifdef X | ||||
X("+", l2_builtin_add) | X("+", l2_builtin_add) | ||||
X("-", l2_builtin_sub) | X("-", l2_builtin_sub) |
struct l2_vm_stack_frame fstack[1024]; | struct l2_vm_stack_frame fstack[1024]; | ||||
l2_word fsptr; | l2_word fsptr; | ||||
l2_word knone, ktrue, kfalse; | |||||
}; | }; | ||||
void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount); | void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount); |
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) \ | |||||
l2_strset_put_copy(&gen->atomset, name); | |||||
#define X(name, f) \ | #define X(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 X | ||||
} | } | ||||
break; | break; | ||||
case L2_VAL_TYPE_ATOM: | case L2_VAL_TYPE_ATOM: | ||||
l2_io_printf(out, "(atom %u)", val->atom); | |||||
if (val->atom == vm->values[vm->ktrue].atom) { | |||||
l2_io_printf(out, "(true)"); | |||||
} else if (val->atom == vm->values[vm->kfalse].atom) { | |||||
l2_io_printf(out, "(false)"); | |||||
} else { | |||||
l2_io_printf(out, "(atom %u)", val->atom); | |||||
} | |||||
break; | break; | ||||
case L2_VAL_TYPE_REAL: | case L2_VAL_TYPE_REAL: |
// 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; \ | |||||
} else { \ | |||||
id = alloc_val(vm); \ | |||||
vm->values[id].flags = L2_VAL_TYPE_ATOM | L2_VAL_CONST; \ | |||||
vm->values[id].atom = key; \ | |||||
} \ | |||||
vm->k = id; \ | |||||
l2_vm_namespace_set(&vm->values[builtins], key++, id); | |||||
#define X(name, f) \ | #define X(name, f) \ | ||||
id = alloc_val(vm); \ | id = alloc_val(vm); \ | ||||
vm->values[id].flags = L2_VAL_TYPE_CFUNCTION; \ | |||||
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); | ||||
#include "builtins.x.h" | #include "builtins.x.h" |