mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-08 22:59:57 +03:00
Implement SWITCH, STRSWITCH
This commit is contained in:
+4
-4
@@ -141,8 +141,8 @@ const struct instruction instructions[NR_OPCODES] = {
|
||||
JMP(CALLMETHOD, 1, INSTR_FUN),
|
||||
OP(SH_GLOBALREF, 1, INSTR_INT),
|
||||
OP(SH_LOCALREF, 1, INSTR_INT),
|
||||
OP(SWITCH, 0), // TODO
|
||||
OP(STRSWITCH, 0), // TODO
|
||||
JMP(SWITCH, 1),
|
||||
JMP(STRSWITCH, 1),
|
||||
OP(FUNC, 1, INSTR_FUN),
|
||||
OP(_EOF, 1, INSTR_FILE),
|
||||
OP(CALLSYS, 1, INSTR_INT),
|
||||
@@ -175,8 +175,8 @@ const struct instruction instructions[NR_OPCODES] = {
|
||||
OP(ENDFUNC, 1, INSTR_FUN),
|
||||
OP(R_EQUALE, 0), // TODO
|
||||
OP(R_NOTE, 0), // TODO
|
||||
OP(SH_LOCALCREATE, 2), // TODO
|
||||
OP(SH_LOCALDELETE, 1), // TODO
|
||||
OP(SH_LOCALCREATE, 2),
|
||||
OP(SH_LOCALDELETE, 1),
|
||||
OP(STOI, 0), // TODO
|
||||
OP(A_PUSHBACK, 0),
|
||||
OP(A_POPBACK, 0),
|
||||
|
||||
@@ -48,6 +48,48 @@ int arithmetic_sub(int a, int b)
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int test_switch(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0: return 0;
|
||||
case 1: return 1;
|
||||
case 2: return 2;
|
||||
}
|
||||
return 100;
|
||||
}
|
||||
|
||||
int test_switch_default(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0: return 0;
|
||||
case 1: return 1;
|
||||
case 2: return 2;
|
||||
default: return 100;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int test_string_switch(string s)
|
||||
{
|
||||
switch (s) {
|
||||
case "a": return 0;
|
||||
case "b": return 1;
|
||||
case "c": return 2;
|
||||
}
|
||||
return 100;
|
||||
}
|
||||
|
||||
int test_string_switch_default(string s)
|
||||
{
|
||||
switch (s) {
|
||||
case "a": return 0;
|
||||
case "b": return 1;
|
||||
case "c": return 2;
|
||||
default: return 100;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void test_lang(void)
|
||||
{
|
||||
int i;
|
||||
@@ -64,4 +106,10 @@ void test_lang(void)
|
||||
test_equal("array pass-by-value", (ar[1][1] = 2, array_set_local(ar, 1, 1, 42), ar[1][1]), 2);
|
||||
test_equal("conditional", (i = 1, i ? 42 : 0), 42);
|
||||
test_equal("functype", (f = &arithmetic_sub, f(7, 2)), 5);
|
||||
test_equal("switch", test_switch(2), 2);
|
||||
test_equal("switch (no default)", test_switch(3), 100);
|
||||
test_equal("switch (default)", test_switch_default(3), 100);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ int main(void)
|
||||
if (total_failed > 0) {
|
||||
system.Output(string(total_failed) + " tests failed.\n");
|
||||
} else {
|
||||
system.Output("All tests passed.\n");
|
||||
system.Output("All tests passed „¤|�æ|„¢\n");
|
||||
}
|
||||
system.Exit(total_failed > 0);
|
||||
return 0;
|
||||
|
||||
@@ -337,6 +337,36 @@ static void system_call(int32_t code)
|
||||
}
|
||||
}
|
||||
|
||||
void exec_switch(int no, int val)
|
||||
{
|
||||
struct ain_switch *s = &ain->switches[no];
|
||||
for (int i = 0; i < s->nr_cases; i++) {
|
||||
if (s->cases[i].value == val) {
|
||||
instr_ptr = s->cases[i].address;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (s->default_address > 0)
|
||||
instr_ptr = s->default_address;
|
||||
else
|
||||
instr_ptr += instruction_width(SWITCH);
|
||||
}
|
||||
|
||||
void exec_strswitch(int no, struct string *str)
|
||||
{
|
||||
struct ain_switch *s = &ain->switches[no];
|
||||
for (int i = 0; i < s->nr_cases; i++) {
|
||||
if (!strcmp(str->text, ain->strings[s->cases[i].value]->text)) {
|
||||
instr_ptr = s->cases[i].address;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (s->default_address > 0)
|
||||
instr_ptr = s->default_address;
|
||||
else
|
||||
instr_ptr += instruction_width(STRSWITCH);
|
||||
}
|
||||
|
||||
static void execute_instruction(int16_t opcode)
|
||||
{
|
||||
int32_t a, b, c, v, pageno, varno, slot;
|
||||
@@ -485,6 +515,14 @@ static void execute_instruction(int16_t opcode)
|
||||
else
|
||||
instr_ptr += instruction_width(IFNZ);
|
||||
break;
|
||||
case SWITCH:
|
||||
exec_switch(get_argument(0), stack_pop().i);
|
||||
break;
|
||||
case STRSWITCH:
|
||||
slot = stack_pop().i;
|
||||
exec_strswitch(get_argument(0), heap[slot].s);
|
||||
heap_unref(slot);
|
||||
break;
|
||||
//
|
||||
// --- Arithmetic ---
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user