Selaa lähdekoodia

feat: 列表允许切片赋值

SongZihuan 4 vuotta sitten
vanhempi
sitoutus
d3d74965e4
8 muutettua tiedostoa jossa 113 lisäystä ja 12 poistoa
  1. 1 0
      include/inter.h
  2. 72 0
      ofunc/src/list.c
  3. 4 0
      src/__run.c
  4. 1 0
      src/include/__run.h
  5. 3 0
      src/inter.c
  6. 20 3
      src/parameter.c
  7. 1 1
      src/runbranch.c
  8. 11 8
      src/runoperation.c

+ 1 - 0
include/inter.h

@@ -80,6 +80,7 @@ struct Inter{
         char *object_message;
         char *object_down_assignment;
         char *object_str;
+        char *object_slice_assignment;
         int default_pt_type;
     } data;
 };

+ 72 - 0
ofunc/src/list.c

@@ -53,6 +53,77 @@ ResultType list_slice(OFFICAL_FUNCTIONSIG){
     return result->type;
 }
 
+ResultType list_slice_assignment(OFFICAL_FUNCTIONSIG){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.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;
+    LinkValue *iter_obj = NULL;
+    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) {
+        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;
+    getIter(ap[1].value, 1, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!CHECK_RESULT(result))
+        return result->type;
+    iter_obj = result->value;
+    result->value = NULL;
+    freeResult(result);
+
+    first = 0;
+    second = size;
+    stride = 1;
+    for (vnum *list[]={&first, &second, &stride}, i=0; i < 3; i++) {
+        if (ap[i + 2].value != NULL && ap[i + 2].value->value->type == number)
+            *(list[i]) = ap[i + 2].value->value->data.num.num;
+        else if (ap[i + 2].value != NULL && ap[i + 2].value->value->type != none) {
+            setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            goto return_;
+        }
+    }
+
+    if (!checkSlice(&first, &second, &stride, size, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+        goto return_;
+
+    {
+        for (long i = first; i < second; i += stride) {
+            freeResult(result);
+            getIter(iter_obj, 0, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            if (is_iterStop(result->value, inter)){
+                setResultError(E_TypeException, "Iter Object Too Short", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+                goto return_;
+            }
+            else if (!CHECK_RESULT(result))
+                goto return_;
+            ap[0].value->value->data.list.list[i] = result->value;
+        }
+        freeResult(result);
+        getIter(iter_obj, 0, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (CHECK_RESULT(result)) {
+            setResultError(E_TypeException, "Iter Object Too Long", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            goto return_;
+        } else if (!is_iterStop(result->value, inter))
+            goto return_;
+    }
+    setResult(result, inter, belong);
+    return_:
+    gc_freeTmpLink(&iter_obj->gc_status);
+    return result->type;
+}
+
 ResultType list_down_assignment(OFFICAL_FUNCTIONSIG){
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
                            {.type=only_value, .must=1, .long_arg=false},
@@ -219,6 +290,7 @@ void registeredList(REGISTERED_FUNCTIONSIG){
     {
         LinkValue *object = makeLinkValue(inter->data.list, inter->base_father, inter);
         NameFunc tmp[] = {{inter->data.object_down_assignment, list_down_assignment, object_free_},
+                          {inter->data.object_slice_assignment, list_slice_assignment, object_free_},
                           {NULL, NULL}};
         gc_addTmpLink(&object->gc_status);
         addStrVar("list", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));

+ 4 - 0
src/__run.c

@@ -345,3 +345,7 @@ char *getRepoStr(LinkValue *value, bool is_repot, fline line, char *file, INTER_
         setResultError(E_TypeException, "__repo__/__str__ gets unsupported data", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     return NULL;
 }
+
+bool is_iterStop(LinkValue *value, Inter *inter){
+    return value->value == inter->data.iterstop_exc || checkAttribution(value->value, inter->data.iterstop_exc);
+}

+ 1 - 0
src/include/__run.h

@@ -39,4 +39,5 @@ ResultType elementDownOne(LinkValue *element, LinkValue *index, fline line, char
 ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 char *getRepoStr(LinkValue *value, bool is_repot, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
+bool is_iterStop(LinkValue *value, Inter *inter);
 #endif //VIRTUALMATH___RUN_H

+ 3 - 0
src/inter.c

@@ -98,8 +98,10 @@ void setBaseInterData(struct Inter *inter){
     inter->data.object_father = memStrcpy("__father__");
     inter->data.object_message = memStrcpy("__message__");
     inter->data.object_down_assignment = memStrcpy("__down_assignment__");
+    inter->data.object_slice_assignment = memStrcpy("__slice_assignment__");
     inter->data.object_str = memStrcpy("__str__");
     inter->data.default_pt_type = free_;
+
 }
 
 void freeBaseInterData(struct Inter *inter){
@@ -165,6 +167,7 @@ void freeBaseInterData(struct Inter *inter){
     memFree(inter->data.object_father);
     memFree(inter->data.object_message);
     memFree(inter->data.object_down_assignment);
+    memFree(inter->data.object_slice_assignment);
     memFree(inter->data.object_str);
 
     if (!inter->data.is_stdout)

+ 20 - 3
src/parameter.c

@@ -193,14 +193,20 @@ Argument *listToArgument(LinkValue *list_value, long line, char *file, INTER_FUN
     while (true) {
         freeResult(result);
         getIter(iter, 0, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        if (!CHECK_RESULT(result)) {
+        if (is_iterStop(result->value, inter)){
             freeResult(result);
             break;
         }
+        else if (!CHECK_RESULT(result)) {  // TODO-szh 处理迭代其的result 通过getIter找到迭代器
+            freeArgument(at, true);
+            at = NULL;
+            goto return_;
+        }
         at = connectValueArgument(result->value, at);
     }
-    gc_freeTmpLink(&iter->gc_status);
     setResult(result, inter, belong);
+    return_:
+    gc_freeTmpLink(&iter->gc_status);
     return at;
 }
 
@@ -219,10 +225,15 @@ Argument *dictToArgument(LinkValue *dict_value, long line, char *file, INTER_FUN
 
         freeResult(result);
         getIter(iter, 0, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        if (!CHECK_RESULT(result)) {
+        if (is_iterStop(result->value, inter)){
             freeResult(result);
             break;
         }
+        else if (!CHECK_RESULT(result)) {
+            freeArgument(at, true);
+            at = NULL;
+            goto return_;
+        }
         name_ = result->value;
         result->value = NULL;
         freeResult(result);
@@ -230,6 +241,8 @@ Argument *dictToArgument(LinkValue *dict_value, long line, char *file, INTER_FUN
         elementDownOne(iter, name_, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result)) {
             gc_freeTmpLink(&name_->gc_status);
+            freeArgument(at, true);
+            at = NULL;
             goto return_;
         }
         name = getNameFromValue(name_->value, inter);
@@ -456,6 +469,8 @@ ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTE
             freeResult(result);
             tmp_at = listToArgument(start, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             gc_freeTmpLink(&start->gc_status);
+            if (!CHECK_RESULT(result))
+                goto return_;
             base = connectArgument(tmp_at, base);
         }
         else if (call->type == kwargs_par){
@@ -466,6 +481,8 @@ ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTE
             freeResult(result);
             tmp_at = dictToArgument(start, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             gc_freeTmpLink(&start->gc_status);
+            if (!CHECK_RESULT(result))
+                goto return_;
             base = connectArgument(tmp_at, base);
         }
         freeResult(result);

+ 1 - 1
src/runbranch.c

@@ -420,7 +420,7 @@ ResultType forBranch(INTER_FUNCTIONSIG) {
             LinkValue *element = NULL;
             getIter(iter, 0, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             if (!CHECK_RESULT(result)) {
-                if (result->value->value == inter->data.iterstop_exc || checkAttribution(result->value->value, inter->data.iterstop_exc)){
+                if (is_iterStop(result->value, inter)){
                     freeResult(result);
                     break;
                 } else {

+ 11 - 8
src/runoperation.c

@@ -141,7 +141,7 @@ ResultType assCore(Statement *name, LinkValue *value, bool check_aut, bool setti
 
     if (name->type == base_list && name->u.base_list.type == value_tuple)
         listAss(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-    else if (name->type == slice_ && name->u.slice_.type == SliceType_down_)
+    else if (name->type == slice_)
         downAss(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     else if (name->type == operation && name->u.operation.OperationType == OPT_POINT)
         pointAss(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
@@ -229,30 +229,33 @@ ResultType listAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
 
 ResultType downAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST) {
     LinkValue *iter = NULL;
-    LinkValue *_down_assignment_ = NULL;
+    LinkValue *_func_ = NULL;
     Parameter *pt = name->u.slice_.index;
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(name->u.slice_.element, var_list, result, belong)))
         return result->type;
     iter = result->value;
     result->value = NULL;
     freeResult(result);
-    _down_assignment_ = findAttributes(inter->data.object_down_assignment, false, iter, inter);
-    if (_down_assignment_ != NULL){
+    if (name->u.slice_.type == SliceType_down_)
+        _func_ = findAttributes(inter->data.object_down_assignment, false, iter, inter);
+    else
+        _func_ = findAttributes(inter->data.object_slice_assignment, false, iter, inter);
+    if (_func_ != NULL){
         Argument *arg = makeValueArgument(value);
-        gc_addTmpLink(&_down_assignment_->gc_status);
+        gc_addTmpLink(&_func_->gc_status);
         arg->next = getArgument(pt, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result))
             goto daerror_;
 
         freeResult(result);
-        callBackCore(_down_assignment_, arg, name->line, name->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        callBackCore(_func_, arg, name->line, name->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
         daerror_:
         freeArgument(arg, true);
-        gc_freeTmpLink(&_down_assignment_->gc_status);
+        gc_freeTmpLink(&_func_->gc_status);
     }
     else
-        setResultErrorSt(E_TypeException, "Don't find __down_assignment__", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        setResultErrorSt(E_TypeException, "Don't find __down_assignment__/__slice_assignment__", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     gc_freeTmpLink(&iter->gc_status);
     return result->type;
 }