فهرست منبع

feat: 允许迭代字典

允许按key迭代字典
双星号表达式使用迭代实现
SongZihuan 4 سال پیش
والد
کامیت
c56479ee0b
12فایلهای تغییر یافته به همراه292 افزوده شده و 25 حذف شده
  1. 3 0
      include/inter.h
  2. 1 0
      include/ofunc.h
  3. 1 1
      include/parameter.h
  4. 2 2
      include/var.h
  5. 7 0
      ofunc/include/dictiter.h
  6. 87 7
      ofunc/src/dict.c
  7. 133 0
      ofunc/src/dictiter.c
  8. 2 2
      src/__run.c
  9. 5 0
      src/inter.c
  10. 2 0
      src/ofunc.c
  11. 42 6
      src/parameter.c
  12. 7 7
      src/var.c

+ 3 - 0
include/inter.h

@@ -23,6 +23,7 @@ struct Inter{
         struct Value *function;
         struct Value *none;
         struct Value *list_iter;
+        struct Value *dict_iter;
         FILE *debug;
         FILE *error;
         char *log_dir;  // 记录log文件夹的位置
@@ -45,6 +46,8 @@ struct Inter{
         char *object_del;
         char *object_down;
         char *object_slice;
+        char *object_iter;
+        char *object_next;
         int default_pt_type;
     } data;
 };

+ 1 - 0
include/ofunc.h

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

+ 1 - 1
include/parameter.h

@@ -76,7 +76,7 @@ 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, long line, char *file, INTER_FUNCTIONSIG_NOT_ST);
-Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE);
+Argument *dictToArgument(LinkValue *dict_value, long line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 
 ResultType setParameterCore(long int line, char *file, Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST);
 ResultType setParameter(long int line, char *file, Parameter *call_base, Parameter *function_base, VarList *function_var, LinkValue *function_father, INTER_FUNCTIONSIG_NOT_ST);

+ 2 - 2
include/var.h

@@ -47,9 +47,9 @@ VarList *makeVarList(Inter *inter, bool make_hash);
 VarList *freeVarList(VarList *vl);
 
 HASH_INDEX time33(char *key);
-LinkValue *findVar(char *name, int operating, INTER_FUNCTIONSIG_CORE);
+LinkValue *findVar(char *name, int operating, Inter *inter, HashTable *ht);
 LinkValue *findFromVarList(char *name, NUMBER_TYPE times, int operating, INTER_FUNCTIONSIG_CORE);
-void addVar(char *name, LinkValue *value, LinkValue *name_, INTER_FUNCTIONSIG_CORE);
+void addVar(char *name, LinkValue *value, LinkValue *name_, Inter *inter, HashTable *ht);
 void updateHashTable(HashTable *update, HashTable *new, Inter *inter);
 void addFromVarList(char *name, LinkValue *name_, NUMBER_TYPE times, LinkValue *value, INTER_FUNCTIONSIG_CORE);
 

+ 7 - 0
ofunc/include/dictiter.h

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

+ 87 - 7
ofunc/src/dict.c

@@ -1,17 +1,97 @@
 #include "__ofunc.h"
 
+ResultType dict_down(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    char *name = NULL;
+    LinkValue *element = 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[0].value->value->type != dict){
+        setResultError(result, inter, "TypeException", "Get Not Support Type", 0, "sys", belong, true);
+        return error_return;
+    }
+    name = getNameFromValue(ap[1].value->value, inter);
+    element = findVar(name, 0, inter, ap[0].value->value->data.dict.dict);
+    memFree(name);
+    if (element != NULL)
+        setResultOperationBase(result, copyLinkValue(element, inter));
+    else
+        setResultError(result, inter, "KeyException", "Key Not Found", 0, "sys", belong, true);
+    return result->type;
+}
+
+ResultType dict_keys(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    Argument *list = NULL;
+    Argument *backup = NULL;
+    LinkValue *element = 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[0].value->value->type != dict){
+        setResultError(result, inter, "TypeException", "Get Not Support Type", 0, "sys", belong, true);
+        return error_return;
+    }
+    for (int index=0; index < MAX_SIZE; index++){
+        Var *tmp = ap[0].value->value->data.dict.dict->hashtable[index];
+        for (PASS; tmp != NULL; tmp = tmp->next)
+            list = connectValueArgument(copyLinkValue(tmp->name_, inter), list);
+    }
+    backup = list;
+    element = makeLinkValue(makeListValue(&list, inter, value_list), belong, inter);
+    setResultOperationBase(result, element);
+    freeArgument(backup, true);
+    return result->type;
+}
+
+ResultType dict_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 != dict){
+        setResultError(result, inter, "TypeException", "Don't get a dict", 0, "sys", belong, true);
+        return error_return;
+    }
+    {
+        Argument *dict_iter_arg = makeValueArgument(ap[0].value);
+        LinkValue *iter_dict = makeLinkValue(inter->data.dict_iter, inter->base_father, inter);
+        gc_addTmpLink(&iter_dict->gc_status);
+        callBackCore(iter_dict, dict_iter_arg, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&iter_dict->gc_status);
+        freeArgument(dict_iter_arg, true);
+    }
+    return result->type;
+}
+
 void registeredDict(RegisteredFunctionSig){
     LinkValue *object = makeLinkValue(inter->data.dict, inter->base_father, inter);
-//    VarList *object_var = object->value->object.var;
-//    VarList *object_backup = NULL;
-//    NameFunc tmp[] = {{NULL, NULL}};
+    VarList *object_var = object->value->object.var;
+    VarList *object_backup = NULL;
+    NameFunc tmp[] = {{"__down__", dict_down, object_free_},
+                      {"keys", dict_keys, object_free_},
+                      {"__iter__", dict_iter, object_free_},
+                      {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addStrVar("dict", 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;
+    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);
 }

+ 133 - 0
ofunc/src/dictiter.c

@@ -0,0 +1,133 @@
+#include "__ofunc.h"
+
+ResultType dictiter_init(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=name_value, .name="dict_", .must=1, .long_arg=false},
+                           {.must=-1}};
+    LinkValue *list = NULL;
+    LinkValue *list_iter = 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 != dict){
+        setResultError(result, inter, "TypeException", "Don't get a dict to dictiter", 0, "sys", belong, true);
+        return error_return;
+    }
+    {
+        LinkValue *keys = findAttributes("keys", false, ap[1].value, inter);
+        Argument *list_arg = NULL;
+        LinkValue *listiter_class = NULL;
+
+        if (keys == NULL){
+            setResultError(result, inter, "TypeExcepyion", "Don't Find keys", 0, "sys", belong, true);
+            return error_return;
+        }
+
+        gc_addTmpLink(&keys->gc_status);
+        freeResult(result);
+        callBackCore(keys, NULL, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&keys->gc_status);
+        if (!run_continue(result)) {
+            return error_return;
+        }
+        list = result->value;
+        result->value = NULL;
+
+        listiter_class = makeLinkValue(inter->data.list_iter, inter->base_father, inter);
+        gc_addTmpLink(&listiter_class->gc_status);
+
+        list_arg = makeValueArgument(list);
+        freeResult(result);
+        callBackCore(listiter_class, list_arg, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        freeArgument(list_arg, true);
+
+        if (!run_continue(result)) {
+            gc_freeTmpLink(&listiter_class->gc_status);
+            gc_freeTmpLink(&list->gc_status);
+            return error_return;
+        }
+
+        list_iter = result->value;
+        result->value = NULL;
+        freeResult(result);
+        gc_freeTmpLink(&list->gc_status);
+        gc_freeTmpLink(&listiter_class->gc_status);
+    }
+    addAttributes("__list", false, list_iter, ap[0].value, inter);
+    addAttributes("__dict", false, ap[1].value, ap[0].value, inter);
+    gc_freeTmpLink(&list_iter->gc_status);
+    setResult(result, inter, belong);
+    return result->type;
+}
+
+ResultType dictiter_next(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    LinkValue *list_ = NULL;
+    LinkValue *list_next = 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);
+    if (list_ == NULL){
+        setResultError(result, inter, "TypeException", "Don't get a list to listiter from dictiter", 0, "sys", belong, true);
+        return error_return;
+    }
+
+    list_next = findAttributes(inter->data.object_next, false, list_, inter);
+    if (list_next == NULL){
+        setResultError(result, inter, "TypeException", "Don't find __next__", 0, "sys", belong, true);
+        return error_return;
+    }
+
+    callBackCore(list_next, NULL, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    return result->type;
+}
+
+ResultType dictiter_down(OfficialFunctionSig){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    LinkValue *dict_ = NULL;
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!run_continue(result))
+        return result->type;
+    dict_ = findAttributes("__dict", false, ap[0].value, inter);
+    if (dict_->value->type != dict){
+        setResultError(result, inter, "TypeException", "Don't get a dict to dictiter", 0, "sys", belong, true);
+        return error_return;
+    }
+
+    freeResult(result);
+    elementDownOne(dict_, ap[1].value, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    return result->type;
+}
+
+void registeredDictIter(RegisteredFunctionSig){
+    LinkValue *object = makeLinkValue(inter->data.dict_iter, inter->base_father, inter);
+    VarList *object_var = object->value->object.var;
+    VarList *object_backup = NULL;
+    NameFunc tmp[] = {{"__init__", dictiter_init, object_free_},
+                      {"__next__", dictiter_next, object_free_},
+                      {"__down__", dictiter_down, object_free_},
+                      {NULL, NULL}};
+    gc_addTmpLink(&object->gc_status);
+    addStrVar("dictiter", 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 makeBaseDictIter(Inter *inter){
+    Value *dict_iter = makeBaseChildClass(inter->data.vobject, inter);
+    gc_addStatementLink(&dict_iter->gc_status);
+    inter->data.dict_iter = dict_iter;
+}

+ 2 - 2
src/__run.c

@@ -256,9 +256,9 @@ ResultType getIter(LinkValue *value, int status, long int line, char *file, INTE
     LinkValue *_func_ = NULL;
     setResultCore(result);
     if (status == 1)
-        _func_ = findAttributes("__iter__", false, value, inter);
+        _func_ = findAttributes(inter->data.object_iter, false, value, inter);
     else
-        _func_ = findAttributes("__next__", false, value, inter);
+        _func_ = findAttributes(inter->data.object_next, false, value, inter);
 
     if (_func_ != NULL){
         gc_addTmpLink(&_func_->gc_status);

+ 5 - 0
src/inter.c

@@ -70,6 +70,8 @@ void setBaseInterData(struct Inter *inter){
     inter->data.object_del = memStrcpy("__del__");
     inter->data.object_down = memStrcpy("__down__");
     inter->data.object_slice = memStrcpy("__slice__");
+    inter->data.object_iter = memStrcpy("__iter__");
+    inter->data.object_next = memStrcpy("__next__");
     inter->data.default_pt_type = free_;
 }
 
@@ -85,6 +87,7 @@ void freeBaseInterData(struct Inter *inter){
     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.dict_iter->gc_status);
     gc_freeStatementLink(&inter->data.none->gc_status);
     memFree(inter->data.var_num_prefix);
     memFree(inter->data.var_str_prefix);
@@ -105,6 +108,8 @@ void freeBaseInterData(struct Inter *inter){
     memFree(inter->data.object_del);
     memFree(inter->data.object_down);
     memFree(inter->data.object_slice);
+    memFree(inter->data.object_iter);
+    memFree(inter->data.object_next);
 
     memFree(inter->data.log_dir);
     if (inter->data.log_dir != NULL) {

+ 2 - 0
src/ofunc.c

@@ -12,6 +12,7 @@ static Registered base_func_list[] = {registeredIOFunction,
                                       registeredDict,
                                       registeredList,
                                       registeredListIter,
+                                      registeredDictIter,
                                       NULL};
 
 void registeredBaseFunction(struct LinkValue *father, Inter *inter){
@@ -30,4 +31,5 @@ void registeredFunctionName(Inter *inter){
     makeBaseDict(inter);
     makeBaseList(inter);
     makeBaseListIter(inter);
+    makeBaseDictIter(inter);
 }

+ 42 - 6
src/parameter.c

@@ -204,12 +204,42 @@ Argument *listToArgument(LinkValue *list_value, long line, char *file, INTER_FUN
     return at;
 }
 
-Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE){
+Argument *dictToArgument(LinkValue *dict_value, long line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
     Argument *at = NULL;
-    Var *tmp = NULL;
-    for (int i = 0; i < MAX_SIZE; i++)
-        for (tmp = dict_value->value->data.dict.dict->hashtable[i]; tmp != NULL; tmp = tmp->next)
-            at = connectCharNameArgument(tmp->value, tmp->name_, tmp->name, at);
+    LinkValue *iter = NULL;
+    setResultCore(result);
+    getIter(dict_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) {
+        LinkValue *name_ = NULL;
+        char *name = NULL;
+
+        freeResult(result);
+        getIter(iter, 0, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!run_continue(result)) {
+            freeResult(result);
+            break;
+        }
+        name_ = result->value;
+        result->value = NULL;
+        freeResult(result);
+
+        elementDownOne(iter, name_, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!run_continue(result)) {
+            gc_freeTmpLink(&name_->gc_status);
+            goto return_;
+        }
+        name = getNameFromValue(name_->value, inter);
+        at = connectCharNameArgument(result->value, name_, name, at);
+        gc_freeTmpLink(&name_->gc_status);
+        memFree(name);
+    }
+    setResult(result, inter, belong);
+    return_:
+    gc_freeTmpLink(&iter->gc_status);
     return at;
 }
 
@@ -430,7 +460,13 @@ ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTE
             base = connectArgument(tmp_at, base);
         }
         else if (call->type == kwargs_par){
-            Argument *tmp_at = dictToArgument(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 = dictToArgument(start, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            gc_freeTmpLink(&start->gc_status);
             base = connectArgument(tmp_at, base);
         }
         freeResult(result);

+ 7 - 7
src/var.c

@@ -162,9 +162,9 @@ void addVarCore(Var **base, char *name, LinkValue *value, LinkValue *name_, Inte
     }
 }
 
-void addVar(char *name, LinkValue *value, LinkValue *name_, INTER_FUNCTIONSIG_CORE) {
+void addVar(char *name, LinkValue *value, LinkValue *name_, Inter *inter, HashTable *ht) {
     HASH_INDEX index = time33(name);
-    addVarCore(&var_list->hashtable->hashtable[index], name, value, name_, inter);
+    addVarCore(&ht->hashtable[index], name, value, name_, inter);
 }
 
 void updateHashTable(HashTable *update, HashTable *new, Inter *inter) {
@@ -174,11 +174,11 @@ void updateHashTable(HashTable *update, HashTable *new, Inter *inter) {
 }
 
 
-LinkValue *findVar(char *name, int operating, INTER_FUNCTIONSIG_CORE) {  // TODO-szh int operating 使用枚举体
+LinkValue *findVar(char *name, int operating, Inter *inter, HashTable *ht) {  // TODO-szh int operating 使用枚举体
     LinkValue *tmp = NULL;
     HASH_INDEX index = time33(name);
 
-    for (Var **base = &var_list->hashtable->hashtable[index]; *base != NULL; base = &(*base)->next){
+    for (Var **base = &ht->hashtable[index]; *base != NULL; base = &(*base)->next){
         if (eqString((*base)->name, name)){
             tmp = (*base)->value;
             if (operating == 1) {
@@ -207,10 +207,10 @@ LinkValue *findFromVarList(char *name, NUMBER_TYPE times, int operating, INTER_F
     for (NUMBER_TYPE i = 0; i < base && var_list->next != NULL; i++)
         var_list = var_list->next;
     if (operating == 1 && var_list != NULL)
-        tmp = findVar(name, true, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        tmp = findVar(name, true, inter, var_list->hashtable);
     else
         for (PASS; var_list != NULL && tmp == NULL; var_list = var_list->next)
-            tmp = findVar(name, operating, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            tmp = findVar(name, operating, inter, var_list->hashtable);
     return tmp;
 }
 
@@ -218,7 +218,7 @@ void addFromVarList(char *name, LinkValue *name_, NUMBER_TYPE times, LinkValue *
     NUMBER_TYPE base = findDefault(var_list->default_var, name) + times;
     for (NUMBER_TYPE i = 0; i < base && var_list->next != NULL; i++)
         var_list = var_list->next;
-    addVar(name, value, name_, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    addVar(name, value, name_, inter, var_list->hashtable);
 }
 
 VarList *pushVarList(VarList *base, Inter *inter){