From: Jérémie Astor Date: Tue, 3 May 2022 12:31:56 +0000 (+0200) Subject: :art: string array access X-Git-Tag: nightly~275^2~5 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=6b681d5e7d4691d3caa1ff89eb5478bd6a36c7ee;p=gwion.git :art: string array access --- diff --git a/src/lib/string.c b/src/lib/string.c index 91bf1551..8fc945b7 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -14,6 +14,7 @@ #include "specialid.h" #include "gwi.h" #include "gack.h" +#include "array.h" #define describe_string_logical(name, action) \ static INSTR(String_##name) { \ @@ -167,30 +168,6 @@ static MFUN(string_trim) { *(M_Object *)RETURN = new_string(shred->info->vm->gwion, c); } -static MFUN(string_charAt) { - const m_str str = STRING(o); - const m_int i = *(m_int *)MEM(SZ_INT); - const m_uint len = strlen(str); - if (i < 0 || (m_uint)i >= len) - *(m_uint *)RETURN = -1; - else - *(m_uint *)RETURN = str[i]; -} - -static MFUN(string_setCharAt) { - const m_str str = STRING(o); - const m_int i = *(m_int *)MEM(SZ_INT); - const m_int c = *(m_int *)MEM(SZ_INT * 2); - const m_uint len = strlen(str); - if (i < 0 || (m_uint)i >= len) - *(m_uint *)RETURN = -1; - else { - str[i] = c; - STRING(o) = s_name(insert_symbol(shred->info->vm->gwion->st, str)); - *(m_uint *)RETURN = c; - } -} - static MFUN(string_insert) { char str[strlen(STRING(o)) + 1]; strcpy(str, STRING(o)); @@ -417,6 +394,59 @@ static MFUN(string_atoi2) { **(m_uint**)MEM(SZ_INT) = endptr - str; } */ + +ANN Type check_array_access(const Env env, const Array_Sub array); + +static OP_CHECK(opck_string_access) { + const Array_Sub array = (Array_Sub)data; + const Exp exp = array->exp; + if(!exp->next) + return env->gwion->type[et_char]; + struct Array_Sub_ next = { exp->next, env->gwion->type[et_char], array->depth - 1 }; + return check_array_access(env, &next); +} + +static INSTR(string_at) { + POP_REG(shred, SZ_INT); + const m_str str = STRING(*(M_Object*)REG(-SZ_INT)); + const m_int i = *(m_int *)REG(0); + const m_uint len = strlen(str); + if (i < 0 || (m_uint)i >= len) { + handle(shred, "invalid string access"); + return; + } else + *(m_int *)REG(-SZ_INT) = str[i]; +} + +static INSTR(string_at_set) { + POP_REG(shred, SZ_INT); + const m_str str = STRING((*(M_Object*)REG(-SZ_INT))); + const m_int i = *(m_int *)REG(0); + const m_uint len = strlen(str); + if (i < 0 || (m_uint)i >= len) { + handle(shred, "StringAccessException"); + return; + } + const m_int c = *(m_int*)REG(-SZ_INT*2); + if(c == '\0') { + handle(shred, "StringAccessException"); + return; + } + *(char**)REG(-SZ_INT) = str + i; + memcpy(REG(-SZ_INT*2 + 1), str + i + 1, SZ_INT - 1); +} + + +static OP_EMIT(opem_string_access) { + struct ArrayAccessInfo *info = (struct ArrayAccessInfo*)data; + const Exp exp = info->array.exp; + const Exp next = exp->next; + CHECK_BB(emit_exp(emit, exp)); + exp->next = next; + emit_add_instr(emit, !info->is_var ? string_at : string_at_set); + return GW_OK; +} + GWION_IMPORT(string) { const Type t_string = gwi_class_ini(gwi, "string", NULL); gwi->gwion->type[et_string] = t_string; // use func @@ -442,15 +472,6 @@ GWION_IMPORT(string) { gwi_func_ini(gwi, "string", "trim"); GWI_BB(gwi_func_end(gwi, string_trim, ae_flag_none)) - gwi_func_ini(gwi, "char", "charAt"); - gwi_func_arg(gwi, "int", "pos"); - GWI_BB(gwi_func_end(gwi, string_charAt, ae_flag_none)) - - gwi_func_ini(gwi, "char", "charAt"); - gwi_func_arg(gwi, "int", "pos"); - gwi_func_arg(gwi, "char", "c"); - GWI_BB(gwi_func_end(gwi, string_setCharAt, ae_flag_none)) - gwi_func_ini(gwi, "string", "insert"); gwi_func_arg(gwi, "int", "pos"); gwi_func_arg(gwi, "string", "str"); @@ -524,6 +545,11 @@ GWION_IMPORT(string) { GWI_BB(gwi_class_end(gwi)) + GWI_BB(gwi_oper_ini(gwi, "int", "string", NULL)) + GWI_BB(gwi_oper_add(gwi, opck_string_access)) + GWI_BB(gwi_oper_emi(gwi, opem_string_access)) + GWI_BB(gwi_oper_end(gwi, "@array", NULL)) + GWI_BB(gwi_oper_ini(gwi, "string", "string", "bool")) GWI_BB(gwi_oper_add(gwi, opck_string_eq)) GWI_BB(gwi_oper_end(gwi, "==", String_eq)) diff --git a/tests/string/charAt.gw b/tests/string/charAt.gw deleted file mode 100644 index 93eb65ab..00000000 --- a/tests/string/charAt.gw +++ /dev/null @@ -1,7 +0,0 @@ -<<< "".charAt(-1) >>>; -<<< "".charAt(2) >>>; -<<< " test String ".charAt(2) >>>; - -<<< "test".charAt(-1, 'c') >>>; -<<< "test".charAt(12, 'c') >>>; -<<< "test".charAt(2, 'c') >>>; diff --git a/tests/string/string_access.gw b/tests/string/string_access.gw new file mode 100644 index 00000000..62dc13f8 --- /dev/null +++ b/tests/string/string_access.gw @@ -0,0 +1,5 @@ +#! [contains] tezt +"test" => var string t; +<<< t[2] >>>; +'z' => t[2]; +<<< t >>>;