Implement DUP_U2, SP_INC, DELETE, R_ASSIGN

Reference assignment.
This commit is contained in:
Nunuhara Cabbage
2019-10-31 21:37:47 -07:00
parent 2d395cf8e5
commit 9db69f8012
4 changed files with 61 additions and 6 deletions
+17
View File
@@ -79,6 +79,23 @@ enum ain_data_type {
case AIN_ARRAY_LONG_INT: \
case AIN_ARRAY_DELEGATE
#define AIN_REF_TYPE \
AIN_REF_INT: \
case AIN_REF_FLOAT: \
case AIN_REF_STRING: \
case AIN_REF_STRUCT: \
case AIN_REF_ARRAY_INT: \
case AIN_REF_ARRAY_FLOAT: \
case AIN_REF_ARRAY_STRING: \
case AIN_REF_ARRAY_STRUCT: \
case AIN_REF_FUNC_TYPE: \
case AIN_REF_ARRAY_FUNC_TYPE: \
case AIN_REF_BOOL: \
case AIN_REF_ARRAY_BOOL: \
case AIN_REF_LONG_INT: \
case AIN_REF_ARRAY_LONG_INT: \
case AIN_REF_ARRAY_DELEGATE
struct ain_variable {
char *name;
int32_t data_type;
+5 -5
View File
@@ -155,9 +155,9 @@ const struct instruction instructions[NR_OPCODES] = {
OP(I_STRING, 0),
JMP(CALLFUNC2, 0),
OP(DUP2_X1, 0),
OP(R_ASSIGN, 0), // TODO
OP(R_ASSIGN, 0),
OP(FT_ASSIGNS, 0), // TODO
OP(ASSERT, 0), // TODO
OP(ASSERT, 0),
OP(S_LT, 0),
OP(S_GT, 0),
OP(S_LTE, 0),
@@ -165,12 +165,12 @@ const struct instruction instructions[NR_OPCODES] = {
OP(S_LENGTH2, 0), // TODO
OP(S_LENGTHBYTE2, 0), // TODO
OP(NEW, 0), // TODO
OP(DELETE, 0), // TODO
OP(DELETE, 0),
OP(CHECKUDO, 0), // TODO
OP(A_REF, 0),
OP(DUP, 0),
OP(DUP_U2, 0), // TODO
OP(SP_INC, 0), // TODO
OP(DUP_U2, 0),
OP(SP_INC, 0),
OP(SP_DEC, 0), // TODO
OP(ENDFUNC, 1, INSTR_FUN),
OP(R_EQUALE, 0), // TODO
+8
View File
@@ -90,6 +90,13 @@ int test_string_switch_default(string s)
return -1;
}
ref int gi;
void set_page_ref(int v)
{
gi <- v;
}
void test_lang(void)
{
int i;
@@ -112,4 +119,5 @@ void test_lang(void)
test_equal("string switch", test_string_switch("b"), 1);
test_equal("string switch (no default)", test_string_switch("d"), 100);
test_equal("string switch (default)", test_string_switch_default("d"), 100);
test_equal("local ref escape", (set_page_ref(42), gi), 42);
}
+31 -1
View File
@@ -210,7 +210,7 @@ static union vm_value *stack_pop_var(void)
int32_t page_index = stack_pop().i;
int32_t heap_index = stack_pop().i;
if (!heap[heap_index].page || page_index >= heap[heap_index].page->nr_vars)
EXECUTION_ERROR("Out of bounds page index");
EXECUTION_ERROR("Out of bounds page index: %d/%d", heap_index, page_index);
return &heap[heap_index].page->values[page_index];
}
@@ -320,6 +320,10 @@ static void system_call(int32_t code)
case 0x0: // system.Exit(int nResult)
sys_exit(stack_pop().i);
break;
case 0x3: // system.LockPeek()
case 0x4: // system.UnlockPeek()
stack_push(1);
break;
case 0x6: // system.Output(string szText)
str = stack_peek_string(0);
utf = sjis2utf(str->text, str->size);
@@ -432,11 +436,18 @@ static void execute_instruction(int16_t opcode)
stack_push(b);
stack_push(c);
break;
case DUP_U2:
// AB -> ABA
stack_push(stack_peek(1).i);
break;
case SWAP:
a = stack_peek(1).i;
stack_set(1, stack_peek(0));
stack_set(0, a);
break;
//
// --- Variables ---
//
case PUSHGLOBALPAGE:
stack_push(0);
break;
@@ -481,6 +492,23 @@ static void execute_instruction(int16_t opcode)
case SH_LOCALCREATE: // VARNO, STRUCTNO
create_struct(get_argument(1), local_ptr(get_argument(0)));
break;
case R_ASSIGN:
varno = stack_pop().i;
pageno = stack_pop().i;
dst_i = stack_pop().i;
dst = stack_pop().i;
heap[dst].page->values[dst_i].i = pageno;
heap[dst].page->values[dst_i+1].i = varno;
stack_push(pageno);
stack_push(varno);
break;
case DELETE:
if ((slot = stack_pop().i) != -1)
heap_unref(slot);
break;
case SP_INC:
heap_ref(stack_pop().i);
break;
//
// --- Control Flow ---
//
@@ -1028,6 +1056,8 @@ void vm_execute_ain(struct ain *program)
case AIN_STRING:
heap[0].page->values[i].i = heap_alloc_slot(VM_STRING);
break;
case AIN_REF_TYPE:
heap[0].page->values[i].i = -1;
default:
break;
}