Browse Source

feat: 字符串切片和下标读取操作

SongZihuan 4 năm trước cách đây
mục cha
commit
049bd0c11a
4 tập tin đã thay đổi với 142 bổ sung62 xóa
  1. 2 1
      ofunc/include/__ofunc.h
  2. 39 0
      ofunc/src/__ofunc.c
  3. 26 61
      ofunc/src/list.c
  4. 75 0
      ofunc/src/str.c

+ 2 - 1
ofunc/include/__ofunc.h

@@ -9,5 +9,6 @@ LinkValue *registeredFunctionCore(OfficialFunction of, char *name, struct LinkVa
 void iterNameFunc(NameFunc list[],struct LinkValue *father, INTER_FUNCTIONSIG_CORE);
 void iterClassFunc(NameFunc list[], LinkValue *father, INTER_FUNCTIONSIG_CORE);
 Value *makeBaseChildClass(Value *inherit, Inter *inter);
-
+bool checkIndex(vnum *index, const vnum *size, INTER_FUNCTIONSIG_NOT_ST);
+bool checkSlice(vnum *first, vnum *second, vnum *stride, vnum size, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH___OFUNC_H

+ 39 - 0
ofunc/src/__ofunc.c

@@ -43,3 +43,42 @@ Value *makeBaseChildClass(Value *inherit, Inter *inter) {
     num = makeClassValue(copyVarList(inter->var_list, false, inter), inter, father_value);
     return num;
 }
+
+bool checkIndex(vnum *index, const vnum *size, INTER_FUNCTIONSIG_NOT_ST){
+    setResultCore(result);
+    if (*index < 0)
+        *index = *size + *index;
+    if (*index >= *size){
+        setResultError(E_IndexException, "Index too max", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return false;
+    } else if (*index < 0){
+        setResultError(E_IndexException, "Index too small", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return false;
+    }
+    return true;  // true - 保持result为setResultCore的结果
+}
+
+bool checkSlice(vnum *first, vnum *second, vnum *stride, vnum size, INTER_FUNCTIONSIG_NOT_ST){
+    setResultCore(result);
+    *first = *first < 0 ? *first + size : *first;
+    *second = *second < 0 ? *second + size : *second;
+    if (*second > size || *first >= size){
+        setResultError(E_IndexException, "Index too max", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return false;
+    } else if (*first < 0 || *second <= 0){
+        setResultError(E_IndexException, "Index too small", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return false;
+    }
+
+    if (stride < 0){
+        long tmp = *first;
+        *stride = -*stride;
+        *first = *second;
+        *second = tmp;
+    }
+    if (*stride == 0 || *first > *second){
+        setResultError(E_StrideException, "Stride Error", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return false;
+    }
+    return true;
+}

+ 26 - 61
ofunc/src/list.c

@@ -6,61 +6,37 @@ ResultType list_slice(OFFICAL_FUNCTIONSIG){
                            {.type=only_value, .must=0, .long_arg=false},
                            {.type=only_value, .must=0, .long_arg=false},
                            {.must=-1}};
-    long size;
-    long first;
-    long second;
-    long stride;
+    vnum size;
+    vnum first;
+    vnum second;
+    vnum stride;
     setResultCore(result);
     parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
         return result->type;
     freeResult(result);
 
-    if (ap[0].value->value->type != list)
-        goto type_error;
-    size = ap[0].value->value->data.list.size;
-    if (ap[1].value == NULL || ap[1].value->value->type == none)
-        first = 0;
-    else if (ap[1].value->value->type == number)
-        first = ap[1].value->value->data.num.num;
-    else
-        goto type_error;
-
-    if (ap[2].value == NULL || ap[2].value->value->type == none)
-        second = size;
-    else if (ap[2].value->value->type == number)
-        second = ap[2].value->value->data.num.num;
-    else
-        goto type_error;
-
-    if (ap[3].value == NULL || ap[3].value->value->type == none)
-        stride = 1;
-    else if (ap[3].value->value->type == number)
-        stride = ap[3].value->value->data.num.num;
-    else
-        goto type_error;
-
-    first = first < 0 ? first + size : first;
-    second = second < 0 ? second + size : second;
-    if (second > size || first >= size){
-        setResultError(E_IndexException, "Index too max", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        return error_return;
-    } else if (first < 0 || second <= 0){
-        setResultError(E_IndexException, "Index too small", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (ap[0].value->value->type != list) {
+        setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
+    size = ap[0].value->value->data.list.size;
 
-    if (stride < 0){
-        long tmp = first;
-        stride = -stride;
-        first = second;
-        second = tmp;
-    }
-    if (stride == 0 || first > second){
-        setResultError(E_StrideException, "Stride Error", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        return error_return;
+    first = 0;
+    second = size;
+    stride = 1;
+    for (vnum *list[]={&first, &second, &stride}, i=0; i < 3; i++) {
+        if (ap[i + 1].value != NULL && ap[i + 1].value->value->type == number)
+            *(list[i]) = ap[i + 1].value->value->data.num.num;
+        else if (ap[i + 1].value != NULL && ap[i + 1].value->value->type != none) {
+            setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            return error_return;
+        }
     }
 
+    if (!checkSlice(&first, &second, &stride, size, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+        return result->type;
+
     {
         Argument *new_list = NULL;
         Argument *back_up = NULL;
@@ -75,10 +51,6 @@ ResultType list_slice(OFFICAL_FUNCTIONSIG){
         freeArgument(back_up, true);
     }
     return result->type;
-
-    type_error:
-    setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-    return error_return;
 }
 
 ResultType list_down_assignment(OFFICAL_FUNCTIONSIG){
@@ -86,8 +58,8 @@ ResultType list_down_assignment(OFFICAL_FUNCTIONSIG){
                            {.type=only_value, .must=1, .long_arg=false},
                            {.type=only_value, .must=1, .long_arg=false},
                            {.must=-1}};
-    long size;
-    long index;
+    vnum size;
+    vnum index;
     setResultCore(result);
     parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
@@ -118,8 +90,8 @@ ResultType list_down(OFFICAL_FUNCTIONSIG){
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
                            {.type=only_value, .must=1, .long_arg=false},
                            {.must=-1}};
-    long size;
-    long index;
+    vnum size;
+    vnum index;
     LinkValue *element = NULL;
     setResultCore(result);
     parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
@@ -133,15 +105,8 @@ ResultType list_down(OFFICAL_FUNCTIONSIG){
     }
     size = ap[0].value->value->data.list.size;
     index = ap[1].value->value->data.num.num;
-    if (index < 0)
-        index = size + index;
-    if (index >= size){
-        setResultError(E_IndexException, "Index too max", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        return error_return;
-    } else if (index < 0){
-        setResultError(E_IndexException, "Index too small", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        return error_return;
-    }
+    if (!checkIndex(&index, &size, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+        return result->type;
     element = ap[0].value->value->data.list.list[index];
     setResultOperationBase(result, copyLinkValue(element, inter));
     return result->type;

+ 75 - 0
ofunc/src/str.c

@@ -22,9 +22,84 @@ ResultType str_init(OFFICAL_FUNCTIONSIG){
     return result->type;
 }
 
+ResultType str_slice(OFFICAL_FUNCTIONSIG){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=only_value, .must=1, .long_arg=false},
+                           {.type=only_value, .must=0, .long_arg=false},
+                           {.type=only_value, .must=0, .long_arg=false},
+                           {.must=-1}};
+    vnum size;
+    vnum first;
+    vnum second;
+    vnum stride;
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!CHECK_RESULT(result))
+        return result->type;
+    freeResult(result);
+
+    if (ap[0].value->value->type != string) {
+        setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return error_return;
+    }
+    size = memStrlen(ap[0].value->value->data.str.str);
+
+    first = 0;
+    second = size;
+    stride = 1;
+    for (vnum *list[]={&first, &second, &stride}, i=0; i < 3; i++) {
+        if (ap[i + 1].value != NULL && ap[i + 1].value->value->type == number)
+            *(list[i]) = ap[i + 1].value->value->data.num.num;
+        else if (ap[i + 1].value != NULL && ap[i + 1].value->value->type != none) {
+            setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            return error_return;
+        }
+    }
+
+    if (!checkSlice(&first, &second, &stride, size, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+        return result->type;
+
+    {
+        char *str = NULL;
+        for (vnum i = first; i < second; i += stride)
+            str = memStrCharcpy(str, 1, true, true, ap[0].value->value->data.str.str[i]);
+        setResultOperationBase(result, makeLinkValue(makeStringValue(str, inter), belong, inter));
+        memFree(str);
+    }
+    return result->type;
+}
+
+ResultType str_down(OFFICAL_FUNCTIONSIG){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    vnum size;
+    vnum index;
+    char element[2] = {};
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!CHECK_RESULT(result))
+        return result->type;
+    freeResult(result);
+
+    if (ap[0].value->value->type != string || ap[1].value->value->type != number){
+        setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return error_return;
+    }
+    size = memStrlen(ap[0].value->value->data.str.str);
+    index = ap[1].value->value->data.num.num;
+    if (!checkIndex(&index, &size, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+        return result->type;
+    *element = ap[0].value->value->data.str.str[index];
+    setResultOperationBase(result, makeLinkValue(makeStringValue(element, inter), belong, inter));
+    return result->type;
+}
+
 void registeredStr(REGISTERED_FUNCTIONSIG){
     LinkValue *object = makeLinkValue(inter->data.str, inter->base_father, inter);
     NameFunc tmp[] = {{inter->data.object_init, str_init, object_free_},
+                      {inter->data.object_down, str_down, object_free_},
+                      {inter->data.object_slice, str_slice, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addStrVar("str", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));