浏览代码

feat: 允许使用for循环语句遍历列表

单星号表达式使用__iter__和__next__
SongZihuan 4 年之前
父节点
当前提交
2d3f210238
共有 21 个文件被更改,包括 556 次插入103 次删除
  1. 1 0
      include/inter.h
  2. 1 0
      include/ofunc.h
  3. 1 2
      include/parameter.h
  4. 1 0
      include/run.h
  5. 7 2
      include/statement.h
  6. 1 0
      include/token.h
  7. 1 0
      main.c
  8. 7 0
      ofunc/include/listiter.h
  9. 25 0
      ofunc/src/list.c
  10. 73 0
      ofunc/src/listiter.c
  11. 2 1
      ofunc/src/object.c
  12. 91 1
      parser/grammar.c
  13. 1 0
      parser/include/__grammar.h
  14. 46 0
      src/__run.c
  15. 5 0
      src/include/__run.h
  16. 59 48
      src/inter.c
  17. 2 0
      src/ofunc.c
  18. 26 45
      src/parameter.c
  19. 3 0
      src/run.c
  20. 185 0
      src/runbranch.c
  21. 18 4
      src/statement.c

+ 1 - 0
include/inter.h

@@ -22,6 +22,7 @@ struct Inter{
         struct Value *dict;
         struct Value *function;
         struct Value *none;
+        struct Value *list_iter;
         FILE *debug;
         FILE *error;
         char *log_dir;  // 记录log文件夹的位置

+ 1 - 0
include/ofunc.h

@@ -12,6 +12,7 @@
 #include "list.h"
 #include "dict.h"
 #include "function.h"
+#include "listiter.h"
 
 struct Argument;
 struct VarList;

+ 1 - 2
include/parameter.h

@@ -75,7 +75,7 @@ Parameter *connectNameParameter(struct Statement *value, struct Statement *name,
 Parameter *connectArgsParameter(struct Statement *st, Parameter *base);
 Parameter *connectKwargsParameter(struct Statement *st, Parameter *base);
 void freeParameter(Parameter *pt, bool free_st);
-Argument *listToArgument(LinkValue *list_value, INTER_FUNCTIONSIG_CORE);
+Argument *listToArgument(LinkValue *list_value, long line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE);
 
 ResultType setParameterCore(long int line, char *file, Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST);
@@ -93,7 +93,6 @@ Inherit *setFatherCore(Inherit *father_tmp);
 Inherit *setFather(Argument *call);
 bool checkFormal(Parameter *pt);
 
-bool checkArgument(int c_value, int c_name, int type_value, int type_name, Argument *arg);
 Argument *parserValueArgument(ArgumentParser *ap, Argument *arg, int *status, ArgumentParser **bak);
 int parserNameArgument(ArgumentParser ap[], Argument *arg, ArgumentParser **bak, INTER_FUNCTIONSIG_NOT_ST);
 int parserArgumentUnion(ArgumentParser ap[], Argument *arg, INTER_FUNCTIONSIG_NOT_ST);

+ 1 - 0
include/run.h

@@ -49,6 +49,7 @@ ResultType setDefault(INTER_FUNCTIONSIG);
 
 ResultType ifBranch(INTER_FUNCTIONSIG);
 ResultType whileBranch(INTER_FUNCTIONSIG);
+ResultType forBranch(INTER_FUNCTIONSIG);
 ResultType withBranch(INTER_FUNCTIONSIG);
 ResultType tryBranch(INTER_FUNCTIONSIG);
 ResultType breakCycle(INTER_FUNCTIONSIG);

+ 7 - 2
include/statement.h

@@ -126,9 +126,9 @@ struct Statement{
             struct Statement *finally;
         } while_branch;
         struct {
-            struct Statement *var;  // first do
-            struct Statement *iter;  // after do
             struct StatementList *for_list;  // for循环体
+            struct Statement *first_do;
+            struct Statement *after_do;
             struct Statement *else_list;  // else分支(无condition)
             struct Statement *finally;
         } for_branch;
@@ -216,6 +216,9 @@ struct Statement{
                 LinkValue *_exit_;
                 LinkValue *_enter_;
             } with_;
+            struct{
+                LinkValue *iter;
+            } for_;
         } branch;
     } info;
     long int line;
@@ -229,6 +232,7 @@ struct StatementList{
         do_b,
         while_b,
         except_b,
+        for_b,
     } type;
     struct Statement *condition;
     struct Statement *var;
@@ -268,6 +272,7 @@ Statement *makeFunctionStatement(Statement *name, Statement *function, struct Pa
 Statement *makeLambdaStatement(Statement *function, Parameter *pt);
 Statement *makeCallStatement(Statement *function, struct Parameter *pt);
 Statement *makeSliceStatement(Statement *element, Parameter *index, enum SliceType type);
+Statement *makeForStatement(long int line, char *file);
 Statement *makeIfStatement(long int line, char *file);
 Statement *makeWhileStatement(long int line, char *file);
 Statement *makeTryStatement(long int line, char *file);

+ 1 - 0
include/token.h

@@ -129,6 +129,7 @@
 #define LABEL -33
 #define DECORATION -34
 #define SLICE -35
+#define FOR_BRANCH -36
 
 #define printTokenEnter(tk, debug, type, message) do{ \
 writeLog(debug, type, message, NULL); \

+ 1 - 0
main.c

@@ -21,6 +21,7 @@ int main(int argc, char *argv[]) {
 
 
 /** TODO-szh List
+ * 赋值权限认证
  * 官方函数
  * 官方类
  * for 循环

+ 7 - 0
ofunc/include/listiter.h

@@ -0,0 +1,7 @@
+#ifndef VIRTUALMATH_LISTITER_H
+#define VIRTUALMATH_LISTITER_H
+#include "__macro.h"
+
+void registeredListIter(RegisteredFunctionSig);
+void makeBaseListIter(Inter *inter);
+#endif //VIRTUALMATH_LISTITER_H

+ 25 - 0
ofunc/src/list.c

@@ -147,6 +147,30 @@ ResultType list_down(OfficialFunctionSig){
     return result->type;
 }
 
+ResultType list_iter(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!run_continue(result))
+        return result->type;
+    freeResult(result);
+
+    if (ap[0].value->value->type != list){
+        setResultError(result, inter, "TypeException", "Don't get a list", 0, "sys", belong, true);
+        return error_return;
+    }
+    {
+        Argument *list_iter_arg = makeValueArgument(ap[0].value);
+        LinkValue *iter_list = makeLinkValue(inter->data.list_iter, inter->base_father, inter);
+        gc_addTmpLink(&iter_list->gc_status);
+        callBackCore(iter_list, list_iter_arg, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&iter_list->gc_status);
+        freeArgument(list_iter_arg, true);
+    }
+    return result->type;
+}
+
 void registeredList(RegisteredFunctionSig){
     LinkValue *object = makeLinkValue(inter->data.list, inter->base_father, inter);
     VarList *object_var = object->value->object.var;
@@ -154,6 +178,7 @@ void registeredList(RegisteredFunctionSig){
     NameFunc tmp[] = {{"__down__", list_down, object_free_},
                       {"__slice__", list_slice, object_free_},
                       {"__down_assignment__", list_down_assignment, object_free_},
+                      {"__iter__", list_iter, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addStrVar("list", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));

+ 73 - 0
ofunc/src/listiter.c

@@ -0,0 +1,73 @@
+#include "__ofunc.h"
+
+ResultType listiter_init(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=name_value, .name="list_", .must=1, .long_arg=false},
+                           {.must=-1}};
+    LinkValue *index = NULL;
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!run_continue(result))
+        return result->type;
+    freeResult(result);
+    if (ap[1].value->value->type != list){
+        setResultError(result, inter, "TypeException", "Don't get a list to listiter", 0, "sys", belong, true);
+        return error_return;
+    }
+
+    index = makeLinkValue(makeNumberValue(0, inter), ap[0].value, inter);
+    addAttributes("__list", false, ap[1].value, ap[0].value, inter);
+    addAttributes("__index", false, index, ap[0].value, inter);
+    return result->type;
+}
+
+ResultType listiter_next(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    LinkValue *list_ = NULL;
+    LinkValue *index = NULL;
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!run_continue(result))
+        return result->type;
+    list_ = findAttributes("__list", false, ap[0].value, inter);
+    index = findAttributes("__index", false, ap[0].value, inter);
+    if (list_->value->type != list || index->value->type != number){
+        setResultError(result, inter, "TypeException", "Don't get a list to listiter", 0, "sys", belong, true);
+        return error_return;
+    }
+
+    freeResult(result);
+    elementDownOne(list_, index, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!run_continue(result))
+        setResultError(result, inter, "StopIterException", "Stop Iter", 0, "sys", belong, true);
+    else {
+        index->value->data.num.num ++;
+        addAttributes("__index", false, index, ap[0].value, inter);
+    }
+    return result->type;
+}
+
+void registeredListIter(RegisteredFunctionSig){
+    LinkValue *object = makeLinkValue(inter->data.list_iter, inter->base_father, inter);
+    VarList *object_var = object->value->object.var;
+    VarList *object_backup = NULL;
+    NameFunc tmp[] = {{"__init__", listiter_init, object_free_},
+                      {"__next__", listiter_next, object_free_},
+                      {NULL, NULL}};
+    gc_addTmpLink(&object->gc_status);
+    addStrVar("listiter", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+
+    object_backup = object_var->next;
+    object_var->next = inter->var_list;
+    iterNameFunc(tmp, object, CALL_INTER_FUNCTIONSIG_CORE(object_var));
+    object_var->next = object_backup;
+
+    gc_freeTmpLink(&object->gc_status);
+}
+
+void makeBaseListIter(Inter *inter){
+    Value *list_iter = makeBaseChildClass(inter->data.vobject, inter);
+    gc_addStatementLink(&list_iter->gc_status);
+    inter->data.list_iter = list_iter;
+}

+ 2 - 1
ofunc/src/object.c

@@ -38,7 +38,8 @@ ResultType object_new_(OfficialFunctionSig){
             goto return_;
         }
         freeResult(&_init_result);
-    }
+    } else if (arg != NULL)
+        setResultError(result, inter, "ArgumentException", "Too many Exception", 0, "sys", belong, true);
 
     return_:
     return result->type;

+ 91 - 1
parser/grammar.c

@@ -123,6 +123,9 @@ void parserCommand(PASERSSIGNATURE){
         case MATHER_IF :
             status = commandCallBack_(CALLPASERSSIGNATURE, parserIf, IF_BRANCH, &st, "Command: call if\n");
             break;
+        case MATHER_FOR :
+            status = commandCallBack_(CALLPASERSSIGNATURE, parserFor, FOR_BRANCH, &st, "Command: call for\n");
+            break;
         case MATHER_WHILE :
             status = commandCallBack_(CALLPASERSSIGNATURE, parserWhile, WHILE_BRANCH, &st, "Command: call while\n");
             break;
@@ -491,10 +494,15 @@ void parserDo(PASERSSIGNATURE){
                 break;
             }
             case MATHER_WHILE:
-                if (!callChildStatement(CALLPASERSSIGNATURE, parserWhile, WHILE_BRANCH, &st, "Don't get a if code after do"))
+                if (!callChildStatement(CALLPASERSSIGNATURE, parserWhile, WHILE_BRANCH, &st, "Don't get a while code after do"))
                     goto error_;
                 st->u.while_branch.first = do_code;
                 break;
+            case MATHER_FOR:
+                if (!callChildStatement(CALLPASERSSIGNATURE, parserFor, FOR_BRANCH, &st, "Don't get a for code after do"))
+                    goto error_;
+                st->u.for_branch.first_do = do_code;
+                break;
             case MATHER_DO: {
                 long int tmp_line = delToken(pm);
                 if (readBackToken(pm) != MATHER_WHILE){
@@ -528,6 +536,88 @@ void parserDo(PASERSSIGNATURE){
     return;
 }
 
+void parserFor(PASERSSIGNATURE){
+    Statement *st = NULL;
+    Statement *else_st = NULL;
+    Statement *finally_st = NULL;
+    Statement *do_st = NULL;
+    StatementList *sl = NULL;
+    long int line = delToken(pm);
+    {
+        Statement *code_tmp = NULL, *var_tmp = NULL, *iter_tmp = NULL;
+        if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &var_tmp, "Don't get a for var"))
+            goto error_;
+        if (!checkToken(pm, MATHER_IN)){
+            freeStatement(var_tmp);
+            syntaxError(pm, syntax_error, line, 1, "Don't get in after for");
+            goto error_;
+        }
+        if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &iter_tmp, "Don't get a for condition")) {
+            freeStatement(var_tmp);
+            goto error_;
+        }
+        if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a for code", line)) {
+            freeStatement(iter_tmp);
+            freeStatement(var_tmp);
+            goto error_;
+        }
+        sl = makeStatementList(iter_tmp, var_tmp, code_tmp, for_b);
+    }
+
+    again:
+    switch (readBackToken(pm)) {
+        case MATHER_DO: {
+            if (do_st != NULL || else_st != NULL)
+                goto default_;
+            long int tmp_line = delToken(pm);
+            if (!callParserCode(CALLPASERSSIGNATURE, &do_st, "Don't get a for...do code", tmp_line))
+                goto error_;
+            goto again;
+        }
+        case MATHER_ELSE: {
+            long int tmp_line = delToken(pm);
+            if (else_st != NULL) {
+                syntaxError(pm, syntax_error, tmp_line, 1, "get else after else\n");
+                goto error_;
+            }
+            if (!callParserCode(CALLPASERSSIGNATURE, &else_st, "Don't get a for...else code", tmp_line))
+                goto error_;
+            goto again;
+        }
+        case MATHER_FINALLY: {
+            long int tmp_line = delToken(pm);
+            if (!callParserCode(CALLPASERSSIGNATURE, &finally_st, "Don't get a for...finally code", tmp_line))
+                goto error_;
+            break;
+        }
+        case MATHER_ENTER:
+            delToken(pm);
+            goto again;
+        case MATHER_SEMICOLON:
+            break;
+        default: {
+            default_:
+            addLexToken(pm, MATHER_ENTER);
+            break;
+        }
+    }
+
+    st = makeForStatement(line, pm->file);
+    st->u.for_branch.for_list = sl;
+    st->u.for_branch.else_list = else_st;
+    st->u.for_branch.finally = finally_st;
+    st->u.for_branch.after_do = do_st;
+    addStatementToken(FOR_BRANCH, st, pm);
+    return;
+
+    error_:
+    freeStatement(else_st);
+    freeStatement(finally_st);
+    freeStatement(do_st);
+    freeStatementList(sl);
+    return;
+}
+
 void parserWith(PASERSSIGNATURE){
     Statement *st = NULL;
     Statement *code_tmp = NULL;

+ 1 - 0
parser/include/__grammar.h

@@ -22,6 +22,7 @@ void parserCommand(PASERSSIGNATURE);
 void parserControl(PASERSSIGNATURE, MakeControlFunction callBack, int type, bool must_operation, char *message);
 void parserDef(PASERSSIGNATURE);
 void parserDo(PASERSSIGNATURE);
+void parserFor(PASERSSIGNATURE);
 void parserWith(PASERSSIGNATURE);
 void parserIf(PASERSSIGNATURE);
 void parserWhile(PASERSSIGNATURE);

+ 46 - 0
src/__run.c

@@ -224,3 +224,49 @@ LinkValue *findAttributes(char *name, bool free_old, LinkValue *value, Inter *in
         attr->belong = value;
     return attr;
 }
+
+void addAttributes(char *name, bool free_old, LinkValue *value, LinkValue *belong, Inter *inter){
+    addStrVar(name, free_old, value, belong, inter, belong->value->object.var);
+}
+
+ResultType elementDownOne(LinkValue *element, LinkValue *index, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
+    LinkValue *_func_ = NULL;
+    setResultCore(result);
+    gc_addTmpLink(&element->gc_status);
+    gc_addTmpLink(&index->gc_status);
+
+    _func_ = findAttributes(inter->data.object_down, false, element, inter);
+    if (_func_ != NULL){
+        Argument *arg = NULL;
+        gc_addTmpLink(&_func_->gc_status);
+        arg = makeValueArgument(index);
+        callBackCore(_func_,arg, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&_func_->gc_status);
+        freeArgument(arg, true);
+    }
+    else
+        setResultError(result, inter, "TypeException", "Don't find __down__", line, file, belong, true);
+
+    gc_freeTmpLink(&element->gc_status);
+    gc_freeTmpLink(&index->gc_status);
+    return result->type;
+}
+
+ResultType getIter(LinkValue *value, int status, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
+    LinkValue *_func_ = NULL;
+    setResultCore(result);
+    if (status == 1)
+        _func_ = findAttributes("__iter__", false, value, inter);
+    else
+        _func_ = findAttributes("__next__", false, value, inter);
+
+    if (_func_ != NULL){
+        gc_addTmpLink(&_func_->gc_status);
+        callBackCore(_func_, NULL, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&_func_->gc_status);
+    }
+    else
+        setResultError(result, inter, "IterException", "Object Not Iterable", line, file, belong, true);
+
+    return result->type;
+}

+ 5 - 0
src/include/__run.h

@@ -25,6 +25,8 @@ void updateFunctionYield(Statement *function_st, Statement *node);
 void updateBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, enum StatementInfoStatus status);
 void newWithBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status,
                         Inter *inter, LinkValue *value, LinkValue *_exit_, LinkValue *_enter_);
+void newForBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status,
+                       Inter *inter, LinkValue *iter);
 
 ResultType setFunctionArgument(struct Argument **arg, LinkValue *function_value, long line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 void freeFunctionArgument(Argument *arg, Argument *base);
@@ -32,4 +34,7 @@ LinkValue *findStrVar(char *name, bool free_old, INTER_FUNCTIONSIG_CORE);
 LinkValue *checkStrVar(char *name, bool free_old, INTER_FUNCTIONSIG_CORE);
 void addStrVar(char *name, bool free_old, LinkValue *value, LinkValue *father, INTER_FUNCTIONSIG_CORE);
 LinkValue *findAttributes(char *name, bool free_old, LinkValue *value, Inter *inter);
+void addAttributes(char *name, bool free_old, LinkValue *value, LinkValue *belong, Inter *inter);
+ResultType elementDownOne(LinkValue *element, LinkValue *index, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST);
+ResultType getIter(LinkValue *value, int status, long int line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH___RUN_H

+ 59 - 48
src/inter.c

@@ -50,6 +50,7 @@ void setBaseInterData(struct Inter *inter){
     inter->data.num = NULL;
     inter->data.str = NULL;
     inter->data.none = NULL;
+    inter->data.list_iter = NULL;
     inter->data.var_str_prefix = memStrcpy("str_");
     inter->data.var_num_prefix = memStrcpy("num_");
     inter->data.var_none = memStrcpy("none");
@@ -83,6 +84,8 @@ void freeBaseInterData(struct Inter *inter){
     gc_freeStatementLink(&inter->data.pass_->gc_status);
     gc_freeStatementLink(&inter->data.list->gc_status);
     gc_freeStatementLink(&inter->data.dict->gc_status);
+    gc_freeStatementLink(&inter->data.list_iter->gc_status);
+    gc_freeStatementLink(&inter->data.none->gc_status);
     memFree(inter->data.var_num_prefix);
     memFree(inter->data.var_str_prefix);
     memFree(inter->data.var_object_prefix);
@@ -165,23 +168,24 @@ void mergeInter(Inter *new, Inter *base){
 /* ***********************DEBUG 专用函数*********************************** */
 
 void printGC(Inter *inter){
-    long int st_lv = 0;
-    long int tmp_lv = 0;
-    long int st_v = 0;
-    long int tmp_v = 0;
-    long int tmp_h = 0;
-    printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter, &tmp_lv, &st_lv);
-    printValueGC("\nprintValueGC TAG : freeInter", inter, &tmp_v, &st_v);
+    long int lv_st = 0;
+    long int lv_tmp = 0;
+    long int v_st = 0;
+    long int v_tmp = 0;
+    long int h_tmp = 0;
+    printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter, &lv_tmp, &lv_st);
+    printValueGC("\nprintValueGC TAG : freeInter", inter, &v_tmp, &v_st);
     printVarGC("\nprintVarGC TAG : freeInter", inter);
-    printHashTableGC("\nprintHashTableGC TAG : freeInter", inter, &tmp_h);
+    printHashTableGC("\nprintHashTableGC TAG : freeInter", inter, &h_tmp);
     printf("\n");
-    printf("linkvalue tmp link   = %ld\n", tmp_lv);
-    printf("linkvalue tmp link   = %ld\n", tmp_v);
-    printf("hashtable tmp link   = %ld\n", tmp_h);
-    printf("statement tmp link   = %ld\n", st_lv);
-    printf("statement tmp link   = %ld\n", st_v);
-    printf("      tmp link count = %ld\n", tmp_lv + tmp_v + tmp_h);
-    printf("statement link count = %ld\n", st_lv + st_v);
+
+    printf("linkvalue tmp       link = %ld\n", lv_tmp);
+    printf("linkvalue statement link = %ld\n", lv_st);
+    printf("    value tmp       link = %ld\n", v_tmp);
+    printf("    value statement link = %ld\n", v_st);
+    printf("hashtable tmp       link = %ld\n", h_tmp);
+    printf("      tmp link     count = %ld\n", lv_tmp + v_tmp + h_tmp);
+    printf("statement link     count = %ld\n", lv_st + v_st);
 
 }
 
@@ -193,11 +197,13 @@ void printLinkValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
     while (base != NULL) {
         tmp += labs(base->gc_status.tmp_link);
         st += labs(base->gc_status.statement_link);
-        printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
-        printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
-        printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
-        printLinkValue(base, "value = ", "\n", stdout);
-        printf("-------------------------------------------\n");
+        if (base->gc_status.tmp_link != 0 || base->gc_status.statement_link != 0) {
+            printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
+            printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
+            printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
+            printLinkValue(base, "value = ", "\n", stdout);
+            printf("-------------------------------------------\n");
+        }
         base = base->gc_next;
     }
     printf("tmp link = %ld\n", tmp);
@@ -205,8 +211,9 @@ void printLinkValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
     printf("printLinkValueGC TAG : END\n");
     if (tmp_link != NULL)
         *tmp_link = tmp;
-    if (st_link != NULL)
-        *st_link = tmp;
+    if (st_link != NULL) {
+        *st_link = st;
+    }
 }
 
 void printValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
@@ -217,12 +224,14 @@ void printValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
     while (base != NULL) {
         tmp += labs(base->gc_status.tmp_link);
         st += labs(base->gc_status.statement_link);
-        printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
-        printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
-        printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
-        printf("value = ");
-        printValue(base, stdout, true);
-        printf("\n-------------------------------------------\n");
+        if (base->gc_status.tmp_link != 0 || base->gc_status.statement_link != 0) {
+            printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
+            printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
+            printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
+            printf("value = ");
+            printValue(base, stdout, true);
+            printf("\n-------------------------------------------\n");
+        }
         base = base->gc_next;
     }
     printf("tmp link = %ld\n", tmp);
@@ -231,21 +240,25 @@ void printValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
     if (tmp_link != NULL)
         *tmp_link = tmp;
     if (st_link != NULL)
-        *st_link = tmp;
+        *st_link = st;
 }
 
 void printVarGC(char *tag, Inter *inter){
     Var *base = inter->base_var;
     printf("%s\n", tag);
     while (base != NULL) {
-        printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
-        printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
-        printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
-        printf("value :\n");
-        printLinkValue(base->name_, "name_: ", "\n", stdout);
-        printLinkValue(base->value, "value_: ", "\n", stdout);
+        if (base->gc_status.tmp_link != 0) {
+            printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
+            printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
+            printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
+        }
+
         printf("str_name = %s\n", base->name);
-        printf("-------------------------------------------\n");
+        printf("name = ");
+        printValue(base->name_->value,stdout, false);
+        printf("\nvalue = ");
+        printValue(base->value->value,stdout, false);
+        printf("\n-------------------------------------------\n");
         base = base->gc_next;
     }
     printf("printVarGC TAG : END\n");
@@ -257,10 +270,12 @@ void printHashTableGC(char *tag, Inter *inter, long *tmp_link) {
     printf("%s\n", tag);
     while (base != NULL) {
         tmp += labs(base->gc_status.tmp_link);
-        printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
-        printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
-        printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
-        printf("-------------------------------------------\n");
+        if (base->gc_status.tmp_link != 0) {
+            printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
+            printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
+            printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
+            printf("-------------------------------------------\n");
+        }
         base = base->gc_next;
     }
     printf("tmp link = %ld\n", tmp);
@@ -272,20 +287,16 @@ void printHashTableGC(char *tag, Inter *inter, long *tmp_link) {
 void printToken(Token *tk) {
     if (tk->token_type >= 0) {
         char *tmp = tk->data.str, *second_tmp = tk->data.second_str;
-        if (!strcmp(tmp, "\n")) {
+        if (!strcmp(tmp, "\n"))
             tmp = "\\n";
-        }
-        if (!strcmp(second_tmp, "\n")) {
+        if (!strcmp(second_tmp, "\n"))
             second_tmp = "\\n";
-        }
-        if (tmp[0] == EOF) {
+        if (tmp[0] == EOF)
             tmp = "(EOF)";
-        }
         printf("<token str = ('%s','%s'), type = %d>", tmp, second_tmp, tk->token_type);
     }
-    else{
+    else
         printf("<token statement, type = %d>", tk->token_type);
-    }
 
 }
 

+ 2 - 0
src/ofunc.c

@@ -11,6 +11,7 @@ static Registered base_func_list[] = {registeredIOFunction,
                                       registeredFunction,
                                       registeredDict,
                                       registeredList,
+                                      registeredListIter,
                                       NULL};
 
 void registeredBaseFunction(struct LinkValue *father, Inter *inter){
@@ -28,4 +29,5 @@ void registeredFunctionName(Inter *inter){
     makeBaseFunction(inter);
     makeBaseDict(inter);
     makeBaseList(inter);
+    makeBaseListIter(inter);
 }

+ 26 - 45
src/parameter.c

@@ -1,6 +1,5 @@
 #include "__run.h"
 
-static bool compareNumber(int a, int b, int type);
 
 #define returnResult(result) do{ \
 if (!run_continue(result)) { \
@@ -182,10 +181,26 @@ void freeParameter(Parameter *pt, bool free_st) {
     }
 }
 
-Argument *listToArgument(LinkValue *list_value, INTER_FUNCTIONSIG_CORE){
+Argument *listToArgument(LinkValue *list_value, long line, char *file, INTER_FUNCTIONSIG_NOT_ST){
     Argument *at = NULL;
-    for (int i=0;i<list_value->value->data.list.size;i++)
-        at = connectValueArgument(list_value->value->data.list.list[i], at);
+    LinkValue *iter = NULL;
+    setResultCore(result);
+    getIter(list_value, 1, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!run_continue(result))
+        return NULL;
+    iter = result->value;
+    result->value = NULL;
+    while (true) {
+        freeResult(result);
+        getIter(iter, 0, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!run_continue(result)) {
+            freeResult(result);
+            break;
+        }
+        at = connectValueArgument(result->value, at);
+    }
+    gc_freeTmpLink(&iter->gc_status);
+    setResult(result, inter, belong);
     return at;
 }
 
@@ -405,7 +420,13 @@ ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTE
                 base = connectStatementNameArgument(result->value, call->data.name, base);
         }
         else if (call->type == args_par){
-            Argument *tmp_at = listToArgument(result->value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            LinkValue *start = NULL;
+            Argument *tmp_at = NULL;
+            start = result->value;
+            result->value = NULL;
+            freeResult(result);
+            tmp_at = listToArgument(start, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            gc_freeTmpLink(&start->gc_status);
             base = connectArgument(tmp_at, base);
         }
         else if (call->type == kwargs_par){
@@ -615,29 +636,6 @@ bool checkFormal(Parameter *pt) {
     return true;
 }
 
-/**
- *
- * @param c_value value_类型的参数的最大值
- * @param c_name name_类型参数的最大值
- * @param type_value c_value [<= < == > >=] c_value_
- * @param type_name c_name [<= < == > >=] c_name_
- * @param arg
- * @return
- */
-bool checkArgument(int c_value, int c_name, int type_value, int type_name, Argument *arg) {
-    int c_value_ = 0;
-    int c_name_ = 0;
-    for (PASS; arg != NULL; arg = arg->next){
-        if (arg->type == value_arg)
-            c_value_++;
-        else
-            c_name_++;
-    }
-    if ((c_value == -1 || compareNumber(c_value, c_value_, type_value)) && (c_name == -1 || compareNumber(c_name, c_name_, type_name)))
-        return true;
-    return false;
-}
-
 int parserArgumentUnion(ArgumentParser ap[], Argument *arg, INTER_FUNCTIONSIG_NOT_ST){
     setResultCore(result);
     if (ap->type != only_name){
@@ -780,20 +778,3 @@ ArgumentParser *parserArgumentNameDefault(ArgumentParser *ap){
     }
     return ap;
 }
-
-static bool compareNumber(int a, int b, int type){
-    switch (type) {
-        case -2:
-            return a <= b;
-        case -1:
-            return a < b;
-        case 0:
-            return a == b;
-        case 1:
-            return a > b;
-        case 2:
-            return a >= b;
-        default:
-            return false;
-    }
-}

+ 3 - 0
src/run.c

@@ -50,6 +50,9 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
         case while_branch:
             type = whileBranch(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
             break;
+        case for_branch:
+            type = forBranch(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
+            break;
         case with_branch:
             type = withBranch(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
             break;

+ 185 - 0
src/runbranch.c

@@ -56,6 +56,13 @@ void newWithBranchYield(Statement *branch_st, Statement *node, StatementList *sl
 
 }
 
+void newForBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status,
+                        Inter *inter, LinkValue *iter){
+    newBranchYield(branch_st, node, sl_node, new_var, status, inter);
+    branch_st->info.branch.for_.iter = iter;
+
+}
+
 void updateBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, enum StatementInfoStatus status){
     branch_st->info.node = node->type == yield_code ? node->next : node;
     branch_st->info.branch.sl_node = sl_node;
@@ -325,6 +332,184 @@ ResultType whileBranch(INTER_FUNCTIONSIG) {
     return result->type;
 }
 
+ResultType forBranch(INTER_FUNCTIONSIG) {
+    StatementList *for_list = st->u.for_branch.for_list;
+    Statement *first = st->u.for_branch.first_do;
+    Statement *after = st->u.for_branch.after_do;
+    Statement *else_st = st->u.for_branch.else_list;
+    Statement *finally = st->u.for_branch.finally;
+    LinkValue *iter = NULL;
+    Statement *info_vl = NULL;
+    Statement *after_vl = NULL;
+    bool set_result = true;
+    bool is_break = false;
+    bool do_while = st->u.while_branch.type == do_while_;
+    int yield_run = false;
+    enum StatementInfoStatus result_from = info_vl_branch;
+
+    Result finally_tmp;
+    setResultCore(result);
+    setResultCore(&finally_tmp);
+
+    yield_run = popStatementVarList(st, &var_list, var_list, inter);
+    if (yield_run && st->info.branch.status == info_first_do)
+        first = st->info.node;
+    else if (yield_run && st->info.branch.status == info_vl_branch){
+        first = NULL;
+        info_vl = st->info.node;
+        iter = st->info.branch.for_.iter;
+        goto do_for;
+    }
+    else if (yield_run && st->info.branch.status == info_after_do){
+        first = NULL;
+        after_vl = st->info.node;
+        iter = st->info.branch.for_.iter;
+        goto do_for;
+    }
+    else if (yield_run && st->info.branch.status == info_else_branch){
+        else_st = st->info.node;
+        goto run_else;
+    }
+    else if (yield_run && st->info.branch.status == info_finally_branch){
+        finally = st->info.node;
+        goto not_else;
+    }
+
+    if (first != NULL && cycleBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(first, var_list, result, belong))) {
+        result_from = info_first_do;
+        set_result = false;
+    }
+    else if (first != NULL)
+        freeResult(result);
+
+    {
+        LinkValue *tmp = NULL;  // TODD-szh 要释放
+        if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(for_list->condition, var_list, result, belong))){
+            set_result = false;
+            goto not_else;
+        }
+        tmp = result->value;
+        result->value = NULL;
+        freeResult(result);
+
+        getIter(tmp, 1, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&tmp->gc_status);
+        if (!run_continue(result)) {
+            set_result = false;
+            goto not_else;
+        }
+        iter = result->value;
+        result->value = NULL;
+    }
+
+    do_for:
+    while (!is_break){
+        Statement *for_st = for_list->code;
+        Statement *after_st = after;
+        freeResult(result);
+        if (info_vl != NULL){
+            for_st = info_vl;
+            info_vl = NULL;
+            goto do_for_st;
+        }
+        else if (after_vl != NULL){
+            after_st = after_vl;
+            after_vl = NULL;
+            goto do_after;
+        }
+
+        {
+            LinkValue *element = NULL;
+            getIter(iter, 0, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            if (!run_continue(result)) {
+                freeResult(result);
+                break;
+            }
+            element = result->value;
+            result->value = NULL;
+            freeResult(result);
+            assCore(for_list->var, element, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            gc_freeTmpLink(&element->gc_status);
+            if (!run_continue(result)){
+                set_result = false;
+                goto not_else;
+            }
+            freeResult(result);
+        }
+
+        do_for_st:
+        if (cycleBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(for_st, var_list, result, belong))){
+            result_from = info_vl_branch;
+            set_result = false;
+            goto not_else;
+        }
+        else if (result->type == break_return)
+            is_break = true;
+
+        freeResult(result);
+        if (after_st == NULL)
+            continue;
+        do_after:
+        if (cycleBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(after_st, var_list, result, belong))){
+            result_from = info_after_do;
+            set_result = false;
+            goto not_else;
+        }
+        else if (result->type == break_return) {
+            freeResult(result);
+            goto not_else;
+        }
+        freeResult(result);
+    }
+
+    run_else:
+    if (!is_break && else_st != NULL && cycleBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(else_st, var_list, result, belong))) {
+        result_from = info_else_branch;
+        set_result = false;
+    }
+    else
+        freeResult(result);
+
+    not_else:
+    if (finally != NULL && cycleBranchSafeInterStatement(CALL_INTER_FUNCTIONSIG(finally, var_list, &finally_tmp, belong))){
+        if (!set_result)
+            freeResult(result);
+        set_result = false;
+        result_from = info_finally_branch;
+        *result = finally_tmp;
+    }
+    else
+        freeResult(&finally_tmp);
+
+    if (yield_run) {
+        if (result->type == yield_return)
+            if (result_from == info_finally_branch) {
+                freeRunInfo(st);
+                newBranchYield(st, result->node, for_list, var_list, result_from, inter);
+            } else
+                updateBranchYield(st, result->node, for_list, result_from);
+        else
+            freeRunInfo(st);
+        iter = NULL;
+    } else {
+        if (result->type == yield_return)
+            if (result_from == info_finally_branch)
+                newBranchYield(st, result->node, for_list, var_list, result_from, inter);
+            else {
+                newForBranchYield(st, result->node, for_list, var_list, result_from, inter, iter);
+                iter = NULL;
+            }
+        else {
+            popVarList(var_list);
+        }
+    }
+    if (iter != NULL)
+        gc_freeTmpLink(&iter->gc_status);
+    if (set_result)
+        setResult(result, inter, belong);
+    return result->type;
+}
+
 ResultType withBranch(INTER_FUNCTIONSIG) {
     StatementList *with_list = st->u.with_branch.with_list;
     Statement *else_st = st->u.with_branch.else_list;

+ 18 - 4
src/statement.c

@@ -20,6 +20,7 @@ void setRunInfo(Statement *st){
     st->info.branch.with_.value = NULL;
     st->info.branch.with_._exit_ = NULL;
     st->info.branch.with_._enter_ = NULL;
+    st->info.branch.for_.iter = NULL;
 }
 
 void freeRunInfo(Statement *st) {
@@ -33,6 +34,8 @@ void freeRunInfo(Statement *st) {
         gc_freeTmpLink(&st->info.branch.with_._exit_->gc_status);
     if (st->info.branch.with_._enter_ != NULL)
         gc_freeTmpLink(&st->info.branch.with_._enter_->gc_status);
+    if (st->info.branch.for_.iter != NULL)
+        gc_freeTmpLink(&st->info.branch.for_.iter->gc_status);
     setRunInfo(st);
 }
 
@@ -181,6 +184,17 @@ Statement *makeSliceStatement(Statement *element, Parameter *index, enum SliceTy
     return tmp;
 }
 
+Statement *makeForStatement(long int line, char *file) {
+    Statement *tmp = makeStatement(line, file);
+    tmp->type = for_branch;
+    tmp->u.for_branch.after_do = NULL;
+    tmp->u.for_branch.first_do = NULL;
+    tmp->u.for_branch.for_list = NULL;
+    tmp->u.for_branch.else_list = NULL;
+    tmp->u.for_branch.finally = NULL;
+    return tmp;
+}
+
 Statement *makeIfStatement(long int line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = if_branch;
@@ -401,8 +415,8 @@ void freeStatement(Statement *st){
                 break;
             case for_branch:
                 freeStatementList(st->u.for_branch.for_list);
-                freeStatement(st->u.for_branch.var);
-                freeStatement(st->u.for_branch.iter);
+                freeStatement(st->u.for_branch.after_do);
+                freeStatement(st->u.for_branch.first_do);
                 freeStatement(st->u.for_branch.else_list);
                 freeStatement(st->u.for_branch.finally);
                 break;
@@ -560,8 +574,8 @@ Statement *copyStatementCore(Statement *st){
             break;
         case for_branch:
             new->u.for_branch.for_list = copyStatementList(st->u.for_branch.for_list);
-            new->u.for_branch.var = copyStatement(st->u.for_branch.var);
-            new->u.for_branch.iter = copyStatement(st->u.for_branch.iter);
+            new->u.for_branch.after_do = copyStatement(st->u.for_branch.after_do);
+            new->u.for_branch.first_do = copyStatement(st->u.for_branch.first_do);
             new->u.for_branch.else_list = copyStatement(st->u.for_branch.else_list);
             new->u.for_branch.finally = copyStatement(st->u.for_branch.finally);
             break;