SR_POP, SR_ASSIGN, C_REF, C_ASSIGN

This commit is contained in:
Nunuhara Cabbage
2019-10-29 19:58:26 -07:00
parent 470c051124
commit 3ff406cb58
7 changed files with 95 additions and 5 deletions
+4 -4
View File
@@ -123,8 +123,8 @@ const struct instruction instructions[NR_OPCODES] = {
OP(SF_CREATEPIXEL, 0), // TODO
OP(SF_CREATEALPHA, 0), // TODO
OP(SR_POP, 0), // TODO
OP(SR_ASSIGN, 0), // TODO
OP(SR_POP, 0),
OP(SR_ASSIGN, 0),
OP(SR_REF, 1, INSTR_INT),
OP(SR_REFREF, 0), // TODO
OP(A_ALLOC, 0),
@@ -133,8 +133,8 @@ const struct instruction instructions[NR_OPCODES] = {
OP(A_NUMOF, 0),
OP(A_COPY, 0),
OP(A_FILL, 0),
OP(C_REF, 0), // TODO
OP(C_ASSIGN, 0), // TODO
OP(C_REF, 0),
OP(C_ASSIGN, 0),
OP(MSG, 0), // TODO
OP(CALLHLL, 0), // TODO
OP(PUSHSTRUCTPAGE, 0),
+46
View File
@@ -197,3 +197,49 @@ int string_find(const struct string *haystack, const struct string *needle)
}
return -1;
}
int string_get_char(const struct string *str, int i)
{
if ((i = sjis_index(str->text, i)) < 0)
ERROR("String index out of bounds");
if (SJIS_2BYTE(str->text[i]))
return (uint8_t)str->text[i] | ((uint8_t)str->text[i+1] << 8);
return str->text[i];
}
void string_set_char(struct string **_str, int i, unsigned int c)
{
struct string *str = *_str = cow_check(*_str);
int bytes_src, bytes_dst;
if ((i = sjis_index(str->text, i)) < 0)
ERROR("String index out of bounds");
bytes_src = SJIS_2BYTE(c) ? 2 : 1;
bytes_dst = SJIS_2BYTE(str->text[i]) ? 2 : 1;
if (bytes_src == 1 && bytes_dst == 1) {
str->text[i] = c;
} else if (bytes_src == 2 && bytes_dst == 2) {
str->text[i] = c & 0xFF;
str->text[i+1] = (c >> 8) & 0xFF;
} else if (bytes_src == 1 && bytes_dst == 2) {
// shrink 1 byte
str->text[i] = c;
for (int j = i+1; j < str->size; j++) {
str->text[j] = str->text[j+1];
}
str->size--;
} else if (bytes_src == 2 && bytes_dst == 1) {
// grow 1 byte
str = xrealloc(str, sizeof(struct string) + str->size + 1);
str->size++;
*_str = str;
for (int j = str->size; j > i; j--) {
str->text[j] = str->text[j-1];
}
str->text[i] = c & 0xFF;
str->text[i+1] = (c >> 8) & 0xFF;
}
}
+7
View File
@@ -67,4 +67,11 @@ void test_strings(void)
// FTOS
test_bool("(4.2).String()", (f = 4.2, f.String() == "4.200000"), true);
test_bool("(4.222).String(2)", (f = 4.222, f.String(2) == "4.22"), true);
// C_REF
test_equal("abあいう[3]", (s = "abあいう", s[3]), 'い');
// C_ASSIGN
test_string("abあいう[1] = 'c'", (s = "abあいう", s[1] = 'c', s), "acあいう");
test_string("abあいう[3] = 'あ'", (s = "abあいう", s[3] = 'あ', s), "abああう");
test_string("abあいう[1] = 'あ'", (s = "abあいう", s[1] = 'あ', s), "aああいう");
test_string("abあいう[3] = 'c'", (s = "abあいう", s[3] = 'c', s), "abあcう");
}
+6
View File
@@ -50,4 +50,10 @@ void test_structs(void)
test_equal("nested constructor", c.inner.a, 99);
test_equal("nested constructor precedence", c.b, 100);
test_equal("c.set_a(22)", (c.set_a(22), c.a), 22);
my_struct a;
my_struct b;
a.a = 42;
b = a;
test_equal("struct assign", b.a, 42);
}
+1 -1
View File
@@ -29,7 +29,7 @@
#include "utfsjis.h"
#include "s2utbl.h"
// Convert a byte-index to a character-index for a given SJIS string.
// Convert a character-index to a byte-index for a given SJIS string.
int sjis_index(const char *_src, int index)
{
const uint8_t *src = (uint8_t*)_src;
+27
View File
@@ -801,12 +801,39 @@ static void execute_instruction(int16_t opcode)
v = stack_pop().i; // precision
stack_push_string(float_to_string(stack_pop().f, v));
break;
// --- Characters ---
case C_REF:
v = stack_pop().i;
slot = stack_pop().i;
stack_push(string_get_char(heap[slot].s, v));
break;
case C_ASSIGN:
v = stack_pop().i;
i = stack_pop().i;
slot = stack_pop().i;
string_set_char(&heap[slot].s, i, v);
stack_push(v);
break;
//
// --- Structs/Classes ---
//
case SR_REF:
stack_push(vm_copy_page(heap[stack_pop_var()->i].page));
break;
case SR_POP:
heap_unref(stack_pop().i);
break;
case SR_ASSIGN:
stack_pop(); // struct type
b = stack_pop().i;
a = stack_pop().i;
if (a == -1)
EXECUTION_ERROR("Assignment to null-pointer");
if (heap[a].page)
delete_page(heap[a].page);
heap[a].page = copy_page(heap[b].page);
stack_push(b);
break;
//
// -- Arrays --
//
+4
View File
@@ -49,4 +49,8 @@ void string_erase(struct string **s, int index);
// queries
int string_find(const struct string *haystack, const struct string *needle);
// characters
int string_get_char(const struct string *str, int i);
void string_set_char(struct string **_s, int i, unsigned int c);
#endif