mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-22 23:18:01 +03:00
Merge pull request #135 from kichikuou/s_mod
Fix S_MOD for bool and long int
This commit is contained in:
+10
-1
@@ -114,7 +114,16 @@ bool library_function_exists(int libno, int fno);
|
||||
void init_libraries(void);
|
||||
void exit_libraries(void);
|
||||
|
||||
struct string *string_format(struct string *fmt, union vm_value arg, enum ain_data_type type);
|
||||
// NOTE: This can probably be merged with ain_data_type, since the values are
|
||||
// disjoint.
|
||||
enum string_format_type {
|
||||
STRFMT_INT = 2,
|
||||
STRFMT_FLOAT = 3,
|
||||
STRFMT_STRING = 4,
|
||||
STRFMT_BOOL = 48,
|
||||
STRFMT_LONG_INT = 56,
|
||||
};
|
||||
struct string *string_format(struct string *fmt, union vm_value arg, enum string_format_type type);
|
||||
|
||||
void vm_stack_trace(void);
|
||||
_Noreturn void _vm_error(const char *fmt, ...);
|
||||
|
||||
+20
-13
@@ -37,10 +37,17 @@ struct fmt_spec {
|
||||
enum fmt_type type;
|
||||
int precision;
|
||||
int padding;
|
||||
bool zero_pad;
|
||||
bool zero_pad;
|
||||
bool zenkaku;
|
||||
};
|
||||
|
||||
static inline bool is_integer_type(enum string_format_type t)
|
||||
{
|
||||
return t == STRFMT_INT
|
||||
|| t == STRFMT_BOOL
|
||||
|| t == STRFMT_LONG_INT;
|
||||
}
|
||||
|
||||
static int read_number(const char **_fmt)
|
||||
{
|
||||
int n = 0;
|
||||
@@ -54,7 +61,7 @@ static int read_number(const char **_fmt)
|
||||
return n;
|
||||
}
|
||||
|
||||
static bool parse_fmt_spec(const char **_fmt, struct fmt_spec *spec, enum ain_data_type target)
|
||||
static bool parse_fmt_spec(const char **_fmt, struct fmt_spec *spec, enum string_format_type target)
|
||||
{
|
||||
bool r = false;
|
||||
const char *fmt = (*_fmt) + 1;
|
||||
@@ -64,33 +71,33 @@ static bool parse_fmt_spec(const char **_fmt, struct fmt_spec *spec, enum ain_da
|
||||
switch (*fmt) {
|
||||
case 'd':
|
||||
spec->type = FMT_INT;
|
||||
r = target == AIN_INT;
|
||||
r = is_integer_type(target);
|
||||
goto end;
|
||||
case 'D':
|
||||
spec->type = FMT_INT;
|
||||
spec->zenkaku = true;
|
||||
r = target == AIN_INT;
|
||||
r = is_integer_type(target);
|
||||
goto end;
|
||||
case 'f':
|
||||
spec->type = FMT_FLOAT;
|
||||
r = target == AIN_FLOAT;
|
||||
r = target == STRFMT_FLOAT;
|
||||
goto end;
|
||||
case 'F':
|
||||
spec->type = FMT_FLOAT;
|
||||
spec->zenkaku = true;
|
||||
r = target == AIN_FLOAT;
|
||||
r = target == STRFMT_FLOAT;
|
||||
goto end;
|
||||
case 's':
|
||||
spec->type = FMT_STRING;
|
||||
r = target == AIN_STRING;
|
||||
r = target == STRFMT_STRING;
|
||||
goto end;
|
||||
case 'c':
|
||||
spec->type = FMT_CHAR;
|
||||
r = target == AIN_INT;
|
||||
r = is_integer_type(target);
|
||||
goto end;
|
||||
case 'b':
|
||||
spec->type = FMT_BOOL;
|
||||
r = target == AIN_INT;
|
||||
r = is_integer_type(target);
|
||||
goto end;
|
||||
case '0':
|
||||
spec->zero_pad = true;
|
||||
@@ -154,9 +161,8 @@ static void append_fmt(struct string **s, struct fmt_spec *spec, union vm_value
|
||||
}
|
||||
}
|
||||
|
||||
struct string *string_format(struct string *fmt, union vm_value arg, enum ain_data_type type)
|
||||
struct string *string_format(struct string *fmt, union vm_value arg, enum string_format_type type)
|
||||
{
|
||||
struct string *out = string_ref(&EMPTY_STRING);
|
||||
for (const char *s = fmt->text; *s; s++) {
|
||||
if (*s != '%')
|
||||
continue;
|
||||
@@ -164,11 +170,12 @@ struct string *string_format(struct string *fmt, union vm_value arg, enum ain_da
|
||||
size_t size = s - fmt->text;
|
||||
struct fmt_spec spec;
|
||||
if (parse_fmt_spec(&s, &spec, type)) {
|
||||
struct string *out = string_ref(&EMPTY_STRING);
|
||||
string_append_cstr(&out, fmt->text, size);
|
||||
append_fmt(&out, &spec, arg);
|
||||
string_append_cstr(&out, s, strlen(s));
|
||||
break;
|
||||
return out;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
return string_ref(fmt);
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ static void DrawDungeon14_SetRasterScroll(int surface, int type)
|
||||
{
|
||||
struct dungeon_context *ctx = dungeon_get_context(surface);
|
||||
if (!ctx || !ctx->renderer)
|
||||
return true;
|
||||
return;
|
||||
return dungeon_renderer_set_raster_scroll(ctx->renderer, type);
|
||||
}
|
||||
|
||||
@@ -421,7 +421,7 @@ static void DrawDungeon14_SetRasterAmp(int surface, float amp)
|
||||
{
|
||||
struct dungeon_context *ctx = dungeon_get_context(surface);
|
||||
if (!ctx || !ctx->renderer)
|
||||
return true;
|
||||
return;
|
||||
return dungeon_renderer_set_raster_amp(ctx->renderer, amp);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1008,7 +1008,7 @@ bool PE_SetLoopCG_by_index(int parts_no, int cg_no, int nr_frames, int frame_tim
|
||||
static struct cg *load_loop_cg_by_name(int no, void *data)
|
||||
{
|
||||
int unused_no;
|
||||
struct string *cg_name = string_format((struct string*)data, (union vm_value){.i=no}, AIN_INT);
|
||||
struct string *cg_name = string_format((struct string*)data, (union vm_value){.i=no}, STRFMT_INT);
|
||||
struct cg *cg = asset_cg_load_by_name(cg_name->text, &unused_no);
|
||||
free_string(cg_name);
|
||||
return cg;
|
||||
|
||||
@@ -1532,7 +1532,7 @@ static enum opcode execute_instruction(enum opcode opcode)
|
||||
union vm_value val = stack_pop();
|
||||
int fmt = stack_pop().i;
|
||||
int dst = heap_alloc_slot(VM_STRING);
|
||||
heap[dst].s = string_format(heap[fmt].s, val, type + 8);
|
||||
heap[dst].s = string_format(heap[fmt].s, val, type);
|
||||
heap_unref(fmt);
|
||||
stack_push(dst);
|
||||
break;
|
||||
|
||||
@@ -5,6 +5,7 @@ void test_strings(void)
|
||||
int i;
|
||||
float f;
|
||||
string s;
|
||||
bool b;
|
||||
test_bool("\"a\" == \"a\"", "a" == "a", true);
|
||||
test_bool("\"a\" != \"b\"", "a" == "b", false);
|
||||
test_bool("\"a\" < \"b\"", "a" < "b", true);
|
||||
@@ -86,8 +87,10 @@ void test_strings(void)
|
||||
// char
|
||||
test_string("abc%cdef % 'あ'", "abc%cdef" % 'あ', "abcあdef");
|
||||
// bool
|
||||
test_string("abc%bdef % 1", "abc%bdef" % 1, "abctruedef");
|
||||
test_string("abc%bdef % 0", "abc%bdef" % 0, "abcfalsedef");
|
||||
test_string("abc%bdef % 1", "abc%bdef" % (b = 1), "abctruedef");
|
||||
test_string("abc%bdef % 0", "abc%bdef" % (b = 0), "abcfalsedef");
|
||||
// type mismatch
|
||||
test_string("%s % 42", "%s" % 42, "%s");
|
||||
|
||||
// I_STRING
|
||||
test_bool("(42).String()", (i = 42, i.String() == "42"), true);
|
||||
|
||||
Reference in New Issue
Block a user