L2_OP_RET, | L2_OP_RET, | ||||
/* | /* | ||||
* Allocate an integer from one word. | |||||
* Allocate an atom from one word. | |||||
* Pop <word> | * Pop <word> | ||||
* Alloc integer <var> from <word> | * Alloc integer <var> from <word> | ||||
* Push <var> | * Push <var> | ||||
*/ | */ | ||||
L2_OP_ALLOC_INTEGER_32, | |||||
/* | |||||
* Allocate an integer from two words. | |||||
* Pop <word1> | |||||
* Pop <word2> | |||||
* Alloc integer <var> from <word1> << 32 | <word2> | |||||
* Push <var> | |||||
*/ | |||||
L2_OP_ALLOC_INTEGER_64, | |||||
/* | |||||
* Allocate a real from one word. | |||||
* Pop <word> | |||||
* Alloc real <var> from <word> | |||||
* Push <var> | |||||
*/ | |||||
L2_OP_ALLOC_REAL_32, | |||||
L2_OP_ALLOC_ATOM, | |||||
/* | /* | ||||
* Allocate a real from two words. | * Allocate a real from two words. | ||||
* Alloc real <var> from <high> << 32 | <low> | * Alloc real <var> from <high> << 32 | <low> | ||||
* Push <var> | * Push <var> | ||||
*/ | */ | ||||
L2_OP_ALLOC_REAL_64, | |||||
L2_OP_ALLOC_REAL, | |||||
/* | /* | ||||
* Allocate a buffer from static data. | * Allocate a buffer from static data. |
enum l2_value_type { | enum l2_value_type { | ||||
L2_VAL_TYPE_NONE, | L2_VAL_TYPE_NONE, | ||||
L2_VAL_TYPE_INTEGER, | |||||
L2_VAL_TYPE_ATOM, | |||||
L2_VAL_TYPE_REAL, | L2_VAL_TYPE_REAL, | ||||
L2_VAL_TYPE_BUFFER, | L2_VAL_TYPE_BUFFER, | ||||
L2_VAL_TYPE_ARRAY, | L2_VAL_TYPE_ARRAY, | ||||
// Byte 8: 8 bytes | // Byte 8: 8 bytes | ||||
union { | union { | ||||
int64_t integer; | |||||
l2_word atom; | |||||
double real; | double real; | ||||
struct l2_vm_buffer *buffer; | struct l2_vm_buffer *buffer; | ||||
struct l2_vm_array *array; | struct l2_vm_array *array; |
put(gen, L2_OP_PUSH_2); | put(gen, L2_OP_PUSH_2); | ||||
put(gen, n); | put(gen, n); | ||||
put(gen, n >> 32); | put(gen, n >> 32); | ||||
put(gen, L2_OP_ALLOC_REAL_64); | |||||
put(gen, L2_OP_ALLOC_REAL); | |||||
} | } | ||||
void l2_gen_atom(struct l2_generator *gen, char **str) { | void l2_gen_atom(struct l2_generator *gen, char **str) { | ||||
size_t id = l2_strset_put(&gen->atomset, str); | size_t id = l2_strset_put(&gen->atomset, str); | ||||
put(gen, L2_OP_PUSH); | put(gen, L2_OP_PUSH); | ||||
put(gen, id); | put(gen, id); | ||||
put(gen, L2_OP_ALLOC_INTEGER_32); | |||||
put(gen, L2_OP_ALLOC_ATOM); | |||||
} | } | ||||
void l2_gen_string(struct l2_generator *gen, char **str) { | void l2_gen_string(struct l2_generator *gen, char **str) { |
printf("(none)"); | printf("(none)"); | ||||
break; | break; | ||||
case L2_VAL_TYPE_INTEGER: | |||||
printf("%zi", val->integer); | |||||
case L2_VAL_TYPE_ATOM: | |||||
printf("(atom %u)", val->atom); | |||||
break; | break; | ||||
case L2_VAL_TYPE_REAL: | case L2_VAL_TYPE_REAL: |
printf("NONE\n"); | printf("NONE\n"); | ||||
break; | break; | ||||
case L2_VAL_TYPE_INTEGER: | |||||
printf("INTEGER %zi\n", val->integer); | |||||
case L2_VAL_TYPE_ATOM: | |||||
printf("ATOM %u\n", val->atom); | |||||
break; | break; | ||||
case L2_VAL_TYPE_REAL: | case L2_VAL_TYPE_REAL: | ||||
printf("RET\n"); | printf("RET\n"); | ||||
break; | break; | ||||
case L2_OP_ALLOC_INTEGER_32: | |||||
printf("ALLOC_INTEGER_32\n"); | |||||
case L2_OP_ALLOC_ATOM: | |||||
printf("ALLOC_ATOM\n"); | |||||
break; | break; | ||||
case L2_OP_ALLOC_INTEGER_64: | |||||
printf("ALLOC_INTEGER_64\n"); | |||||
break; | |||||
case L2_OP_ALLOC_REAL_32: | |||||
printf("ALLOC_REAL_32\n"); | |||||
break; | |||||
case L2_OP_ALLOC_REAL_64: | |||||
printf("ALLOC_REAL_64\n"); | |||||
case L2_OP_ALLOC_REAL: | |||||
printf("ALLOC_REAL\n"); | |||||
break; | break; | ||||
case L2_OP_ALLOC_BUFFER_STATIC: | case L2_OP_ALLOC_BUFFER_STATIC: |
} | } | ||||
break; | break; | ||||
case L2_OP_ALLOC_INTEGER_32: | |||||
case L2_OP_ALLOC_ATOM: | |||||
word = alloc_val(vm); | word = alloc_val(vm); | ||||
vm->values[word].flags = L2_VAL_TYPE_INTEGER; | |||||
vm->values[word].integer = vm->stack[--vm->sptr]; | |||||
vm->values[word].flags = L2_VAL_TYPE_ATOM; | |||||
vm->values[word].atom= vm->stack[--vm->sptr]; | |||||
vm->stack[vm->sptr++] = word; | vm->stack[vm->sptr++] = word; | ||||
break; | break; | ||||
case L2_OP_ALLOC_INTEGER_64: | |||||
word = alloc_val(vm); | |||||
vm->values[word].flags = L2_VAL_TYPE_INTEGER; | |||||
vm->values[word].integer = (int64_t)( | |||||
(uint64_t)vm->stack[vm->sptr - 1] << 32 | | |||||
(uint64_t)vm->stack[vm->sptr - 2]); | |||||
vm->sptr -= 2; | |||||
vm->stack[vm->sptr] = word; | |||||
vm->sptr += 1; | |||||
break; | |||||
case L2_OP_ALLOC_REAL_32: | |||||
word = alloc_val(vm); | |||||
vm->values[word].flags = L2_VAL_TYPE_REAL; | |||||
vm->values[word].real = u32_to_float(vm->stack[--vm->sptr]); | |||||
vm->stack[vm->sptr] = word; | |||||
vm->sptr += 1; | |||||
break; | |||||
case L2_OP_ALLOC_REAL_64: | |||||
case L2_OP_ALLOC_REAL: | |||||
word = alloc_val(vm); | word = alloc_val(vm); | ||||
vm->values[word].flags = L2_VAL_TYPE_REAL; | vm->values[word].flags = L2_VAL_TYPE_REAL; | ||||
vm->values[word].real = u32s_to_double(vm->stack[vm->sptr - 1], vm->stack[vm->sptr - 2]); | vm->values[word].real = u32s_to_double(vm->stack[vm->sptr - 1], vm->stack[vm->sptr - 2]); |