|
|
@@ -487,7 +487,9 @@ void l2_vm_step(struct l2_vm *vm) { |
|
|
|
l2_word key = read(vm); \ |
|
|
|
l2_word val = vm->stack[vm->sptr - 1]; \ |
|
|
|
struct l2_vm_value *ns = &vm->values[vm->fstack[vm->fsptr - 1].ns]; \ |
|
|
|
l2_vm_namespace_replace(vm, ns, key, val); // TODO: error if returns -1 |
|
|
|
if (l2_vm_namespace_replace(vm, ns, key, val) < 0) { \ |
|
|
|
vm->stack[vm->sptr - 1] = l2_vm_error(vm, "Variable not found"); \ |
|
|
|
} |
|
|
|
case L2_OP_STACK_FRAME_REPLACE_U4: { X(read_u4le); } break; |
|
|
|
case L2_OP_STACK_FRAME_REPLACE_U1: { X(read_u1le); } break; |
|
|
|
#undef X |
|
|
@@ -633,9 +635,15 @@ void l2_vm_step(struct l2_vm *vm) { |
|
|
|
|
|
|
|
#define X(read) \ |
|
|
|
l2_word key = read(vm); \ |
|
|
|
l2_word arr = vm->stack[--vm->sptr]; \ |
|
|
|
/* TODO: Error if out of bounds or incorrect type */ \ |
|
|
|
vm->stack[vm->sptr++] = vm->values[arr].array->data[key]; |
|
|
|
l2_word arr_id = vm->stack[--vm->sptr]; \ |
|
|
|
struct l2_vm_value *arr = &vm->values[arr_id]; \ |
|
|
|
if (l2_vm_value_type(arr) != L2_VAL_TYPE_ARRAY) { \ |
|
|
|
vm->stack[vm->sptr++] = l2_vm_type_error(vm, arr); \ |
|
|
|
} else if (key >= arr->extra.arr_length) { \ |
|
|
|
vm->stack[vm->sptr++] = l2_vm_error(vm, "Index out of range"); \ |
|
|
|
} else { \ |
|
|
|
vm->stack[vm->sptr++] = arr->array->data[key]; \ |
|
|
|
} |
|
|
|
case L2_OP_ARRAY_LOOKUP_U4: { X(read_u4le); } break; |
|
|
|
case L2_OP_ARRAY_LOOKUP_U1: { X(read_u1le); } break; |
|
|
|
#undef X |
|
|
@@ -643,9 +651,15 @@ void l2_vm_step(struct l2_vm *vm) { |
|
|
|
#define X(read) \ |
|
|
|
l2_word key = read(vm); \ |
|
|
|
l2_word val = vm->stack[vm->sptr - 1]; \ |
|
|
|
l2_word arr = vm->stack[vm->sptr - 2]; \ |
|
|
|
/* TODO: Error if out of bounds or incorrect type */ \ |
|
|
|
vm->values[arr].array->data[key] = val; |
|
|
|
l2_word arr_id = vm->stack[vm->sptr - 2]; \ |
|
|
|
struct l2_vm_value *arr = &vm->values[arr_id]; \ |
|
|
|
if (l2_vm_value_type(arr) != L2_VAL_TYPE_ARRAY) { \ |
|
|
|
vm->stack[vm->sptr - 1] = l2_vm_type_error(vm, arr); \ |
|
|
|
} else if (key >= arr->extra.arr_length) { \ |
|
|
|
vm->stack[vm->sptr - 1] = l2_vm_error(vm, "Index out of range"); \ |
|
|
|
} else { \ |
|
|
|
arr->array->data[key] = val; \ |
|
|
|
} |
|
|
|
case L2_OP_ARRAY_SET_U4: { X(read_u4le); } break; |
|
|
|
case L2_OP_ARRAY_SET_U1: { X(read_u1le); } break; |
|
|
|
|
|
|
@@ -656,18 +670,22 @@ void l2_vm_step(struct l2_vm *vm) { |
|
|
|
|
|
|
|
struct l2_vm_value *key = &vm->values[key_id]; |
|
|
|
struct l2_vm_value *container = &vm->values[container_id]; |
|
|
|
if ( |
|
|
|
l2_vm_value_type(key) == L2_VAL_TYPE_REAL && |
|
|
|
l2_vm_value_type(container) == L2_VAL_TYPE_ARRAY) { |
|
|
|
// TODO: Error if out of bounds |
|
|
|
vm->stack[vm->sptr++] = container->array->data[(size_t)key->real]; |
|
|
|
} else if ( |
|
|
|
l2_vm_value_type(key) == L2_VAL_TYPE_ATOM && |
|
|
|
l2_vm_value_type(container) == L2_VAL_TYPE_NAMESPACE) { |
|
|
|
// TODO: Error if out of bounds |
|
|
|
vm->stack[vm->sptr++] = l2_vm_namespace_get(vm, container, key->atom); |
|
|
|
if (l2_vm_value_type(container) == L2_VAL_TYPE_ARRAY) { |
|
|
|
if (l2_vm_value_type(key) != L2_VAL_TYPE_REAL) { |
|
|
|
vm->stack[vm->sptr++] = l2_vm_type_error(vm, key); |
|
|
|
} else if (key->real >= container->extra.arr_length) { |
|
|
|
vm->stack[vm->sptr++] = l2_vm_error(vm, "Index out of range"); |
|
|
|
} else { |
|
|
|
vm->stack[vm->sptr++] = container->array->data[(l2_word)key->real]; |
|
|
|
} |
|
|
|
} else if (l2_vm_value_type(container) == L2_VAL_TYPE_NAMESPACE) { |
|
|
|
if (l2_vm_value_type(key) != L2_VAL_TYPE_ATOM) { |
|
|
|
vm->stack[vm->sptr++] = l2_vm_type_error(vm, key); |
|
|
|
} else { |
|
|
|
vm->stack[vm->sptr++] = l2_vm_namespace_get(vm, container, key->atom); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// TODO: error |
|
|
|
vm->stack[vm->sptr++] = l2_vm_type_error(vm, container); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
@@ -682,18 +700,22 @@ void l2_vm_step(struct l2_vm *vm) { |
|
|
|
struct l2_vm_value *key = &vm->values[key_id]; |
|
|
|
struct l2_vm_value *container = &vm->values[container_id]; |
|
|
|
|
|
|
|
if ( |
|
|
|
l2_vm_value_type(key) == L2_VAL_TYPE_REAL && |
|
|
|
l2_vm_value_type(container) == L2_VAL_TYPE_ARRAY) { |
|
|
|
// TODO: Error if out of bounds |
|
|
|
container->array->data[(size_t)key->real] = val; |
|
|
|
} else if ( |
|
|
|
l2_vm_value_type(key) == L2_VAL_TYPE_ATOM && |
|
|
|
l2_vm_value_type(container) == L2_VAL_TYPE_NAMESPACE) { |
|
|
|
// TODO: Error if out of bounds |
|
|
|
l2_vm_namespace_set(container, key->atom, val); |
|
|
|
if (l2_vm_value_type(container) == L2_VAL_TYPE_ARRAY) { |
|
|
|
if (l2_vm_value_type(key) != L2_VAL_TYPE_REAL) { |
|
|
|
vm->stack[vm->sptr - 1] = l2_vm_type_error(vm, key); |
|
|
|
} else if (key->real >= container->extra.arr_length) { |
|
|
|
vm->stack[vm->sptr - 1] = l2_vm_error(vm, "Index out of range"); |
|
|
|
} else { |
|
|
|
container->array->data[(size_t)key->real] = val; |
|
|
|
} |
|
|
|
} else if (l2_vm_value_type(container) == L2_VAL_TYPE_NAMESPACE) { |
|
|
|
if (l2_vm_value_type(key) != L2_VAL_TYPE_ATOM) { |
|
|
|
vm->stack[vm->sptr - 1] = l2_vm_type_error(vm, key); |
|
|
|
} else { |
|
|
|
l2_vm_namespace_set(container, key->atom, val); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// TODO: error |
|
|
|
vm->stack[vm->sptr - 1] = l2_vm_type_error(vm, container); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |