| // 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" |