Browse Source

feat: 允许使用del语句删除变量或列表/字典值

SongZihuan 4 năm trước cách đây
mục cha
commit
46f9706638
15 tập tin đã thay đổi với 356 bổ sung86 xóa
  1. 3 1
      include/inter.h
  2. 7 0
      include/run.h
  3. 30 25
      include/statement.h
  4. 3 1
      include/token.h
  5. 2 11
      memory/mem.c
  6. 39 9
      ofunc/src/dict.c
  7. 93 0
      ofunc/src/list.c
  8. 4 0
      parser/grammar.c
  9. 1 1
      parser/include/__grammar.h
  10. 1 0
      parser/syntax.c
  11. 6 2
      src/inter.c
  12. 3 0
      src/run.c
  13. 125 9
      src/runoperation.c
  14. 38 25
      src/statement.c
  15. 1 2
      src/var.c

+ 3 - 1
include/inter.h

@@ -81,9 +81,11 @@ struct Inter{
         char *object_self;
         char *object_father;
         char *object_message;
-        char *object_down_assignment;
         char *object_str;
+        char *object_down_assignment;
         char *object_slice_assignment;
+        char *object_down_del;
+        char *object_slice_del;
         int default_pt_type;
     } data;
 };

+ 7 - 0
include/run.h

@@ -71,4 +71,11 @@ ResultType listAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST);
 ResultType assCore(Statement *name, LinkValue *value, bool check_aut, bool setting, INTER_FUNCTIONSIG_NOT_ST);
 ResultType downAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST);
 ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool setting, INTER_FUNCTIONSIG_NOT_ST);
+
+ResultType delOperation(INTER_FUNCTIONSIG);
+ResultType delCore(Statement *name, bool check_aut, INTER_FUNCTIONSIG_NOT_ST);
+ResultType listDel(Statement *name, INTER_FUNCTIONSIG_NOT_ST);
+ResultType varDel(Statement *name, bool check_aut, INTER_FUNCTIONSIG_NOT_ST);
+ResultType pointDel(Statement *name, INTER_FUNCTIONSIG_NOT_ST);
+ResultType downDel(Statement *name, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH_RUN_H

+ 30 - 25
include/statement.h

@@ -10,6 +10,7 @@ struct Statement{
         base_list,
         base_dict,
         base_var,
+        del_,
         base_svar,
         base_lambda,
         operation,
@@ -55,6 +56,9 @@ struct Statement{
             char *name;
             struct Statement *times;
         } base_var;
+        struct{
+            struct Statement *var;
+        } del_;
         struct base_svar{
             struct Statement *name;
             struct Statement *times;
@@ -249,7 +253,7 @@ typedef struct Statement Statement;
 typedef struct StatementList StatementList;
 typedef struct DecorationStatement DecorationStatement;
 
-Statement *makeStatement(long int line, char *file);
+Statement *makeStatement(fline line, char *file);
 void setRunInfo(Statement *st);
 void freeRunInfo(Statement *st);
 void freeStatement(Statement *st);
@@ -257,39 +261,40 @@ Statement *copyStatement(Statement *st);
 Statement *copyStatementCore(Statement *st);
 void connectStatement(Statement *base, Statement *new);
 
-Statement *makeOperationBaseStatement(enum OperationType type, long int line, char *file);
+Statement *makeOperationBaseStatement(enum OperationType type, fline line, char *file);
 Statement *makeOperationStatement(enum OperationType type, Statement *left, Statement *right);
-Statement *makeBaseLinkValueStatement(LinkValue *value, long int line, char *file);
-Statement *makeBaseStrValueStatement(char *value, enum BaseValueType type, long int line, char *file);
-Statement *makeBaseValueStatement(enum BaseValueType type, long int line, char *file);
-Statement *makeBaseVarStatement(char *name, Statement *times, long int line, char *file);
+Statement *makeBaseLinkValueStatement(LinkValue *value, fline line, char *file);
+Statement *makeBaseStrValueStatement(char *value, enum BaseValueType type, fline line, char *file);
+Statement *makeBaseValueStatement(enum BaseValueType type, fline line, char *file);
+Statement *makeBaseVarStatement(char *name, Statement *times, fline line, char *file);
 Statement *makeBaseSVarStatement(Statement *name, Statement *times);
-Statement *makeBaseDictStatement(Parameter *pt, long int line, char *file);
-Statement *makeTupleStatement(Parameter *pt, enum ListType type, long int line, char *file);
+Statement *makeBaseDictStatement(Parameter *pt, fline line, char *file);
+Statement *makeTupleStatement(Parameter *pt, enum ListType type, fline line, char *file);
 Statement *makeClassStatement(Statement *name, Statement *function, Parameter *pt);
 Statement *makeFunctionStatement(Statement *name, Statement *function, struct Parameter *pt);
 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);
-Statement *makeBreakStatement(Statement *times, long int line, char *file);
-Statement *makeWithStatement(long int line, char *file);
-Statement *makeContinueStatement(Statement *times, long int line, char *file);
-Statement *makeRegoStatement(Statement *times, long int line, char *file);
-Statement *makeRestartStatement(Statement *times, long int line, char *file);
-Statement *makeReturnStatement(Statement *value, long int line, char *file);
-Statement *makeYieldStatement(Statement *value, long int line, char *file);
-Statement *makeRaiseStatement(Statement *value, long int line, char *file);
-Statement *makeAssertStatement(Statement *conditions, long int line, char *file);
-Statement *makeIncludeStatement(Statement *file, long int line, char *file_dir);
+Statement *makeForStatement(fline line, char *file);
+Statement *makeIfStatement(fline line, char *file);
+Statement *makeWhileStatement(fline line, char *file);
+Statement *makeTryStatement(fline line, char *file);
+Statement *makeBreakStatement(Statement *times, fline line, char *file);
+Statement *makeWithStatement(fline line, char *file);
+Statement *makeContinueStatement(Statement *times, fline line, char *file);
+Statement *makeRegoStatement(Statement *times, fline line, char *file);
+Statement *makeRestartStatement(Statement *times, fline line, char *file);
+Statement *makeReturnStatement(Statement *value, fline line, char *file);
+Statement *makeYieldStatement(Statement *value, fline line, char *file);
+Statement *makeRaiseStatement(Statement *value, fline line, char *file);
+Statement *makeAssertStatement(Statement *conditions, fline line, char *file);
+Statement *makeIncludeStatement(Statement *file, fline line, char *file_dir);
 Statement *makeImportStatement(Statement *file, Statement *as);
 Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt);
-Statement *makeDefaultVarStatement(Parameter *var, long int line, char *file_dir, enum DefaultType type);
-Statement *makeLabelStatement(Statement *var, Statement *command, char *label, long int line, char *file_dir);
-Statement *makeGotoStatement(Statement *return_, Statement *times, Statement *label, long int line, char *file_dir);
+Statement *makeDefaultVarStatement(Parameter *var, fline line, char *file_dir, enum DefaultType type);
+Statement *makeLabelStatement(Statement *var, Statement *command, char *label, fline line, char *file_dir);
+Statement *makeGotoStatement(Statement *return_, Statement *times, Statement *label, fline line, char *file_dir);
+Statement *makeDelStatement(Statement *var, fline line, char *file_dir);
 Token *setOperationFromToken(Statement **st_ad, Token *left, Token *right, enum OperationType type, bool is_right);
 
 StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code, int type);

+ 3 - 1
include/token.h

@@ -94,8 +94,9 @@
 #define MATHER_GOTO 80
 #define MATHER_LABEL 81
 #define MATHER_PASSVALUE 82
+#define MATHER_DEL 83
 
-#define MATHER_MAX 83
+#define MATHER_MAX 84
 
 // 从-6开始是为了避开status的特殊值,尽管这并没有什么影响
 #define COMMAND -6
@@ -130,6 +131,7 @@
 #define DECORATION -34
 #define SLICE -35
 #define FOR_BRANCH -36
+#define DEL -36
 
 struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配

+ 2 - 11
memory/mem.c

@@ -4,10 +4,7 @@ jmp_buf memVirtualMath_Env;
 bool memVirtualMathUseJmp;
 
 void *memCalloc(size_t num, size_t size){
-    void *tmp = NULL;
-    if (num == 0 || size == 0)
-        return NULL;
-    tmp = calloc(num, size);
+    void *tmp = calloc(num, size);
     if (tmp == NULL) {
         if (memVirtualMathUseJmp)
             longjmp(memVirtualMath_Env, -1);
@@ -18,13 +15,7 @@ void *memCalloc(size_t num, size_t size){
 }
 
 void *memRealloc(void *old, size_t size){
-    void *tmp = NULL;
-    if (size <= 0)
-        return NULL;
-    else if (old == NULL)
-        tmp = memCalloc(1,size);
-    else
-        tmp = realloc(old, size);
+    void *tmp = realloc(old, size);
     if (tmp == NULL) {
         if (memVirtualMathUseJmp)
             longjmp(memVirtualMath_Env, -1);

+ 39 - 9
ofunc/src/dict.c

@@ -4,8 +4,6 @@ ResultType dict_down(OFFICAL_FUNCTIONSIG){
     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 (!CHECK_RESULT(result))
@@ -16,13 +14,44 @@ ResultType dict_down(OFFICAL_FUNCTIONSIG){
         setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         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(E_KeyException, "Key Not Found", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    {
+        LinkValue *element = NULL;
+        char *name = getNameFromValue(ap[1].value->value, inter);
+        element = findVar(name, get_var, inter, ap[0].value->value->data.dict.dict);
+        memFree(name);
+        if (element != NULL)
+            setResultOperationBase(result, copyLinkValue(element, inter));
+        else
+            setResultError(E_KeyException, "Key Not Found", 0, "sys", true,
+                           CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    }
+    return result->type;
+}
+
+ResultType dict_down_del(OFFICAL_FUNCTIONSIG){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.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 (!CHECK_RESULT(result))
+        return result->type;
+    freeResult(result);
+
+    if (ap[0].value->value->type != dict){
+        setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        return error_return;
+    }
+    {
+        LinkValue *element = NULL;
+        char *name = getNameFromValue(ap[1].value->value, inter);
+        element = findVar(name, del_var, inter, ap[0].value->value->data.dict.dict);
+        memFree(name);
+        if (element != NULL)
+            setResult(result, inter, belong);
+        else
+            setResultError(E_KeyException, "Key Not Found", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    }
     return result->type;
 }
 
@@ -177,6 +206,7 @@ void registeredDict(REGISTERED_FUNCTIONSIG){
                       {inter->data.object_repo, dict_repo, object_free_},
                       {inter->data.object_str, dict_str, object_free_},
                       {inter->data.object_down_assignment, dict_down_assignment, object_free_},
+                      {inter->data.object_down_del, dict_down_del, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addStrVar("dict", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));

+ 93 - 0
ofunc/src/list.c

@@ -124,6 +124,64 @@ ResultType list_slice_assignment(OFFICAL_FUNCTIONSIG){
     return result->type;
 }
 
+ResultType list_slice_del(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 != 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;
+
+    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;
+
+    {
+        LinkValue **new = NULL;
+        vnum new_size = size;
+        for (vnum i = first; i < second; i += stride) {
+            ap[0].value->value->data.list.list[i] = NULL;
+            new_size --;
+        }
+        new = memCalloc(new_size, sizeof(LinkValue *));
+        for (vnum i = 0, c = 0; i < size; i++) {
+            if (ap[0].value->value->data.list.list[i] != NULL){
+                new[c] = ap[0].value->value->data.list.list[i];
+                c++;
+            }
+        }
+        memFree(ap[0].value->value->data.list.list);
+        ap[0].value->value->data.list.list = new;
+        ap[0].value->value->data.list.size = new_size;
+    }
+    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},
@@ -157,6 +215,39 @@ ResultType list_down_assignment(OFFICAL_FUNCTIONSIG){
     return result->type;
 }
 
+ResultType list_down_del(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;
+    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 || 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 = ap[0].value->value->data.list.size;
+    index = ap[1].value->value->data.num.num;
+    if (!checkIndex(&index, &size, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+        return result->type;
+    {
+        LinkValue **new = NULL;
+        new = memCalloc(size - 1, sizeof(LinkValue *));
+        memcpy(new, ap[0].value->value->data.list.list, sizeof(LinkValue *) * index);
+        memcpy(new + index, ap[0].value->value->data.list.list + index + 1, sizeof(LinkValue *) * (size - index - 1));
+        memFree(ap[0].value->value->data.list.list);
+        ap[0].value->value->data.list.list = new;
+        ap[0].value->value->data.list.size --;
+    }
+    setResult(result, inter, belong);
+    return result->type;
+}
+
 ResultType list_down(OFFICAL_FUNCTIONSIG){
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
                            {.type=only_value, .must=1, .long_arg=false},
@@ -280,6 +371,8 @@ void registeredList(REGISTERED_FUNCTIONSIG){
                           {inter->data.object_iter, list_iter, object_free_},
                           {inter->data.object_repo, list_repo, object_free_},
                           {inter->data.object_str, list_str, object_free_},
+                          {inter->data.object_down_del, list_down_del, object_free_},
+                          {inter->data.object_slice_del, list_slice_del, object_free_},
                           {NULL, NULL}};
         gc_addTmpLink(&object->gc_status);
         addStrVar("tuple", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));

+ 4 - 0
parser/grammar.c

@@ -167,6 +167,10 @@ void parserCommand(PASERSSIGNATURE){
             status = commandCallControl_(CALLPASERSSIGNATURE, makeIncludeStatement, INCLUDE, &st, true,
                                          "parserInclude: Don't get file after include");
             break;
+        case MATHER_DEL :
+            status = commandCallControl_(CALLPASERSSIGNATURE, makeDelStatement, DEL, &st, true,
+                                         "parserInclude: Don't get operation after del");
+            break;
         case MATHER_FROM :
         case MATHER_IMPORT :
             status = callChildStatement(CALLPASERSSIGNATURE, parserImport, IMPORT, &st, NULL);

+ 1 - 1
parser/include/__grammar.h

@@ -15,7 +15,7 @@
 typedef void (*PasersFunction)(PASERSSIGNATURE);
 typedef int (*GetSymbolFunction)(PASERSSIGNATURE, int, Statement **);
 typedef int (*ChecktLeftToken)(PASERSSIGNATURE, Statement *);
-typedef Statement *(*MakeControlFunction)(Statement *, long int, char *);
+typedef Statement *(*MakeControlFunction)(Statement *, fline, char *);
 typedef int (*TailFunction)(PASERSSIGNATURE, Token *, Statement **);
 
 void parserCommand(PASERSSIGNATURE);

+ 1 - 0
parser/syntax.c

@@ -344,6 +344,7 @@ int getMatherStatus(LexFile *file, LexMathers *mathers) {
         strMatherMacro(MATHER_GOTO, "goto");
         strMatherMacro(MATHER_LABEL, "label");
         strMatherMacro(MATHER_PASSVALUE, "...");
+        strMatherMacro(MATHER_DEL, "del");
 
         status = checkoutMather(mathers, MATHER_MAX);
     }

+ 6 - 2
src/inter.c

@@ -91,9 +91,11 @@ void setBaseInterData(struct Inter *inter){
     inter->data.object_name = memStrcpy("__name__");
     inter->data.object_father = memStrcpy("__father__");
     inter->data.object_message = memStrcpy("__message__");
+    inter->data.object_str = memStrcpy("__str__");
     inter->data.object_down_assignment = memStrcpy("__down_assignment__");
     inter->data.object_slice_assignment = memStrcpy("__slice_assignment__");
-    inter->data.object_str = memStrcpy("__str__");
+    inter->data.object_down_del = memStrcpy("__down_del__");
+    inter->data.object_slice_del = memStrcpy("__slice_del__");
     inter->data.default_pt_type = free_;
 
 }
@@ -165,9 +167,11 @@ void freeBaseInterData(struct Inter *inter){
     memFree(inter->data.object_self);
     memFree(inter->data.object_father);
     memFree(inter->data.object_message);
+    memFree(inter->data.object_str);
     memFree(inter->data.object_down_assignment);
     memFree(inter->data.object_slice_assignment);
-    memFree(inter->data.object_str);
+    memFree(inter->data.object_down_del);
+    memFree(inter->data.object_slice_del);
 
     if (!inter->data.is_stdout)
         fclose(inter->data.inter_stdout);

+ 3 - 0
src/run.c

@@ -98,6 +98,9 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
         case goto_:
             type = gotoLabel(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
             break;
+        case del_:
+            type = delOperation(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
+            break;
         default:
             setResult(result, inter, belong);
             break;

+ 125 - 9
src/runoperation.c

@@ -76,17 +76,12 @@ ResultType blockOperation(INTER_FUNCTIONSIG) {
 ResultType pointOperation(INTER_FUNCTIONSIG) {
     LinkValue *left;
     VarList *object = NULL;
-    VarList *out_var = NULL;
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.left, var_list, result, belong)) || result->value->value->type == none)
         return result->type;
     left = result->value;
-
     setResultCore(result);
-    object = left->value->object.var;
-    for (out_var = object; out_var->next != NULL; out_var = out_var->next)
-        PASS;
-    out_var->next = left->value->object.out_var;
 
+    object = left->value->object.var;
     gc_freeze(inter, var_list, object, true);
     operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, object, result, left));
     if (!CHECK_RESULT(result))
@@ -101,12 +96,126 @@ ResultType pointOperation(INTER_FUNCTIONSIG) {
 
     return_:
     gc_freeze(inter, var_list, object, false);
-    if (out_var != NULL)
-        out_var->next = NULL;
     gc_freeTmpLink(&left->gc_status);
     return result->type;
 }
 
+ResultType delOperation(INTER_FUNCTIONSIG) {
+    Statement *var;
+    setResultCore(result);
+    var = st->u.del_.var;
+    delCore(var, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    return result->type;
+}
+
+ResultType delCore(Statement *name, bool check_aut, INTER_FUNCTIONSIG_NOT_ST) {
+    setResultCore(result);
+    if (name->type == base_list && name->u.base_list.type == value_tuple)
+        listDel(name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    else if (name->type == slice_)
+        downDel(name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    else if (name->type == operation && name->u.operation.OperationType == OPT_POINT)
+        pointDel(name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    else
+        varDel(name, check_aut, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    return result->type;
+}
+
+ResultType listDel(Statement *name, INTER_FUNCTIONSIG_NOT_ST) {
+    setResultCore(result);
+    for (Parameter *pt = name->u.base_list.list; pt != NULL; pt = pt->next){
+        delCore(pt->data.value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        freeResult(result);
+    }
+    setResultBase(result, inter, belong);
+    return result->type;
+}
+
+ResultType varDel(Statement *name, bool check_aut, INTER_FUNCTIONSIG_NOT_ST) {
+    char *str_name = NULL;
+    int int_times = 0;
+    setResultCore(result);
+    getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list, result, belong));
+    if (!CHECK_RESULT(result)) {
+        memFree(str_name);
+        return result->type;
+    }
+    if (check_aut) {
+        LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        if (tmp != NULL) {
+            if ((name->aut == public_aut || name->aut == auto_aut) && (tmp->aut != public_aut && tmp->aut != auto_aut)) {  // TODO-szh 封装位函数
+                setResultErrorSt(E_PermissionsException, "Wrong Permissions: access variables as public", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+                goto return_;
+            }
+            else if ((name->aut == protect_aut) && (tmp->aut == private_aut)) {
+                setResultErrorSt(E_PermissionsException, "Wrong Permissions: access variables as protect", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+                goto return_;
+            }
+        }
+    }
+    findFromVarList(str_name, int_times, del_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    setResult(result, inter, belong);
+    return_:
+    memFree(str_name);
+    return result->type;
+}
+
+ResultType pointDel(Statement *name, INTER_FUNCTIONSIG_NOT_ST) {
+    Result left;
+    VarList *object = NULL;
+
+    setResultCore(result);
+    if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(name->u.operation.left, var_list, result, belong)))
+        return result->type;
+    left = *result;
+    setResultCore(result);
+
+    object = left.value->value->object.var;
+    gc_freeze(inter, var_list, object, true);
+    if (name->u.operation.right->type == OPERATION && name->u.operation.right->u.operation.OperationType == OPT_POINT)
+        pointDel(name->u.operation.right, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, belong));
+    else
+        delCore(name->u.operation.right, true, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, belong));
+    gc_freeze(inter, var_list, object, false);
+
+    freeResult(&left);
+    return result->type;
+}
+
+ResultType downDel(Statement *name, INTER_FUNCTIONSIG_NOT_ST) {
+    LinkValue *iter = NULL;
+    LinkValue *_func_ = NULL;
+    Parameter *pt = name->u.slice_.index;
+
+    setResultCore(result);
+    if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(name->u.slice_.element, var_list, result, belong)))
+        return result->type;
+    iter = result->value;
+    result->value = NULL;
+    freeResult(result);
+    if (name->u.slice_.type == SliceType_down_)
+        _func_ = findAttributes(inter->data.object_down_del, false, iter, inter);
+    else
+        _func_ = findAttributes(inter->data.object_slice_del, false, iter, inter);
+    if (_func_ != NULL){
+        Argument *arg = NULL;
+        gc_addTmpLink(&_func_->gc_status);
+        arg = getArgument(pt, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!CHECK_RESULT(result))
+            goto dderror_;
+        freeResult(result);
+        callBackCore(_func_, arg, name->line, name->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+
+        dderror_:
+        gc_freeTmpLink(&_func_->gc_status);
+        freeArgument(arg, true);
+    }
+    else
+        setResultErrorSt(E_TypeException, "Don't find __down_del__/__slice_del__", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    gc_freeTmpLink(&iter->gc_status);
+    return result->type;
+}
+
 ResultType assOperation(INTER_FUNCTIONSIG) {
     LinkValue *value = NULL;
     if (st->u.operation.left->type == call_function){
@@ -162,6 +271,8 @@ ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool settin
     char *str_name = NULL;
     int int_times = 0;
     LinkValue *var_value = NULL;
+
+    setResultCore(result);
     getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list, result, belong));
     if (!CHECK_RESULT(result)) {
         memFree(str_name);
@@ -208,6 +319,7 @@ ResultType listAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
     Argument *call = NULL;
     Statement *tmp_st = makeBaseLinkValueStatement(value, name->line, name->code_file);
 
+    setResultCore(result);
     pt = makeArgsParameter(tmp_st);
     call = getArgument(pt, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
@@ -231,6 +343,8 @@ ResultType downAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
     LinkValue *iter = NULL;
     LinkValue *_func_ = NULL;
     Parameter *pt = name->u.slice_.index;
+
+    setResultCore(result);
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(name->u.slice_.element, var_list, result, belong)))
         return result->type;
     iter = result->value;
@@ -263,6 +377,8 @@ ResultType downAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
 ResultType pointAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST) {
     Result left;
     VarList *object = NULL;
+
+    setResultCore(result);
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(name->u.operation.left, var_list, result, belong)))
         return result->type;
     left = *result;
@@ -284,7 +400,7 @@ ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
     int int_times = 0;
     char *name = NULL;
 
-    freeResult(result);
+    setResultCore(result);
     var_info(&name, &int_times, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
     if (!CHECK_RESULT(result)) {
         memFree(name);

+ 38 - 25
src/statement.c

@@ -1,6 +1,6 @@
 #include "__virtualmath.h"
 
-Statement *makeStatement(long int line, char *file) {
+Statement *makeStatement(fline line, char *file) {
     Statement *tmp = memCalloc(1, sizeof(Statement));
     tmp->type = start;
     tmp->next = NULL;
@@ -64,7 +64,7 @@ Token *setOperationFromToken(Statement **st_ad, struct Token *left, struct Token
     return new_token;
 }
 
-Statement *makeBaseLinkValueStatement(LinkValue *value, long int line, char *file) {
+Statement *makeBaseLinkValueStatement(LinkValue *value, fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_value;
     tmp->u.base_value.type = link_value;
@@ -74,7 +74,7 @@ Statement *makeBaseLinkValueStatement(LinkValue *value, long int line, char *fil
     return tmp;
 }
 
-Statement *makeBaseStrValueStatement(char *value, enum BaseValueType type, long int line, char *file){
+Statement *makeBaseStrValueStatement(char *value, enum BaseValueType type, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_value;
     tmp->u.base_value.type = type;
@@ -83,7 +83,7 @@ Statement *makeBaseStrValueStatement(char *value, enum BaseValueType type, long
     return tmp;
 }
 
-Statement *makeBaseValueStatement(enum BaseValueType type, long int line, char *file) {
+Statement *makeBaseValueStatement(enum BaseValueType type, fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_value;
     tmp->u.base_value.type = type;
@@ -92,7 +92,7 @@ Statement *makeBaseValueStatement(enum BaseValueType type, long int line, char *
     return tmp;
 }
 
-Statement *makeBaseVarStatement(char *name, Statement *times, long int line, char *file){
+Statement *makeBaseVarStatement(char *name, Statement *times, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_var;
     tmp->u.base_var.name = memStrcpy(name);
@@ -108,14 +108,14 @@ Statement *makeBaseSVarStatement(Statement *name, Statement *times){
     return tmp;
 }
 
-Statement *makeBaseDictStatement(Parameter *pt, long int line, char *file){
+Statement *makeBaseDictStatement(Parameter *pt, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_dict;
     tmp->u.base_dict.dict = pt;
     return tmp;
 }
 
-Statement *makeOperationBaseStatement(enum OperationType type, long int line, char *file){
+Statement *makeOperationBaseStatement(enum OperationType type, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = operation;
     tmp->u.operation.OperationType = type;
@@ -131,7 +131,7 @@ Statement *makeOperationStatement(enum OperationType type, Statement *left, Stat
     return tmp;
 }
 
-Statement *makeTupleStatement(Parameter *pt, enum ListType type, long int line, char *file) {
+Statement *makeTupleStatement(Parameter *pt, enum ListType type, fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_list;
     tmp->u.base_list.type = type;
@@ -184,7 +184,7 @@ Statement *makeSliceStatement(Statement *element, Parameter *index, enum SliceTy
     return tmp;
 }
 
-Statement *makeForStatement(long int line, char *file) {
+Statement *makeForStatement(fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = for_branch;
     tmp->u.for_branch.after_do = NULL;
@@ -195,7 +195,7 @@ Statement *makeForStatement(long int line, char *file) {
     return tmp;
 }
 
-Statement *makeIfStatement(long int line, char *file) {
+Statement *makeIfStatement(fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = if_branch;
     tmp->u.if_branch.if_list = NULL;
@@ -204,7 +204,7 @@ Statement *makeIfStatement(long int line, char *file) {
     return tmp;
 }
 
-Statement *makeWhileStatement(long int line, char *file) {
+Statement *makeWhileStatement(fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = while_branch;
     tmp->u.while_branch.type = while_;
@@ -216,7 +216,7 @@ Statement *makeWhileStatement(long int line, char *file) {
     return tmp;
 }
 
-Statement *makeTryStatement(long int line, char *file) {
+Statement *makeTryStatement(fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = try_branch;
     tmp->u.try_branch.except_list = NULL;
@@ -226,7 +226,7 @@ Statement *makeTryStatement(long int line, char *file) {
     return tmp;
 }
 
-Statement *makeWithStatement(long int line, char *file) {
+Statement *makeWithStatement(fline line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = with_branch;
     tmp->u.with_branch.with_list = NULL;
@@ -235,63 +235,63 @@ Statement *makeWithStatement(long int line, char *file) {
     return tmp;
 }
 
-Statement *makeBreakStatement(Statement *times, long int line, char *file){
+Statement *makeBreakStatement(Statement *times, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = break_cycle;
     tmp->u.break_cycle.times = times;
     return tmp;
 }
 
-Statement *makeContinueStatement(Statement *times, long int line, char *file){
+Statement *makeContinueStatement(Statement *times, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = continue_cycle;
     tmp->u.continue_cycle.times = times;
     return tmp;
 }
 
-Statement *makeRegoStatement(Statement *times, long int line, char *file){
+Statement *makeRegoStatement(Statement *times, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = rego_if;
     tmp->u.rego_if.times = times;
     return tmp;
 }
 
-Statement *makeRestartStatement(Statement *times, long int line, char *file){
+Statement *makeRestartStatement(Statement *times, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = restart;
     tmp->u.restart.times = times;
     return tmp;
 }
 
-Statement *makeReturnStatement(Statement *value, long int line, char *file){
+Statement *makeReturnStatement(Statement *value, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = return_code;
     tmp->u.return_code.value = value;
     return tmp;
 }
 
-Statement *makeYieldStatement(Statement *value, long int line, char *file){
+Statement *makeYieldStatement(Statement *value, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = yield_code;
     tmp->u.yield_code.value = value;
     return tmp;
 }
 
-Statement *makeRaiseStatement(Statement *value, long int line, char *file){
+Statement *makeRaiseStatement(Statement *value, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = raise_code;
     tmp->u.raise_code.value = value;
     return tmp;
 }
 
-Statement *makeAssertStatement(Statement *conditions, long int line, char *file){
+Statement *makeAssertStatement(Statement *conditions, fline line, char *file){
     Statement *tmp = makeStatement(line, file);
     tmp->type = assert;
     tmp->u.assert.conditions = conditions;
     return tmp;
 }
 
-Statement *makeIncludeStatement(Statement *file, long int line, char *file_dir){
+Statement *makeIncludeStatement(Statement *file, fline line, char *file_dir){
     Statement *tmp = makeStatement(line, file_dir);
     tmp->type = include_file;
     tmp->u.include_file.file = file;
@@ -315,7 +315,7 @@ Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt
     return tmp;
 }
 
-Statement *makeDefaultVarStatement(Parameter *var, long int line, char *file_dir, enum DefaultType type) {
+Statement *makeDefaultVarStatement(Parameter *var, fline line, char *file_dir, enum DefaultType type) {
     Statement *tmp = makeStatement(line, file_dir);
     tmp->type = default_var;
     tmp->u.default_var.var = var;
@@ -323,7 +323,7 @@ Statement *makeDefaultVarStatement(Parameter *var, long int line, char *file_dir
     return tmp;
 }
 
-Statement *makeLabelStatement(Statement *var, Statement *command, char *label, long int line, char *file_dir) {
+Statement *makeLabelStatement(Statement *var, Statement *command, char *label, fline line, char *file_dir) {
     Statement *tmp = makeStatement(line, file_dir);
     tmp->type = label_;
     tmp->u.label_.as = var;
@@ -332,7 +332,7 @@ Statement *makeLabelStatement(Statement *var, Statement *command, char *label, l
     return tmp;
 }
 
-Statement *makeGotoStatement(Statement *return_, Statement *times, Statement *label, long int line, char *file_dir) {
+Statement *makeGotoStatement(Statement *return_, Statement *times, Statement *label, fline line, char *file_dir) {
     Statement *tmp = makeStatement(line, file_dir);
     tmp->type = goto_;
     tmp->u.goto_.return_ = return_;
@@ -341,6 +341,13 @@ Statement *makeGotoStatement(Statement *return_, Statement *times, Statement *la
     return tmp;
 }
 
+Statement *makeDelStatement(Statement *var, fline line, char *file_dir) {
+    Statement *tmp = makeStatement(line, file_dir);
+    tmp->type = del_;
+    tmp->u.del_.var = var;
+    return tmp;
+}
+
 void connectStatement(Statement *base, Statement *new){
     for (PASS; base->next != NULL; base = base->next)
         PASS;
@@ -367,6 +374,9 @@ void freeStatement(Statement *st){
                 memFree(st->u.base_var.name);
                 freeStatement(st->u.base_var.times);
                 break;
+            case del_:
+                freeStatement(st->u.del_.var);
+                break;
             case base_svar:
                 freeStatement(st->u.base_svar.name);
                 freeStatement(st->u.base_svar.times);
@@ -524,6 +534,9 @@ Statement *copyStatementCore(Statement *st){
             new->u.base_var.name = memStrcpy(st->u.base_var.name);
             new->u.base_var.times = copyStatement(st->u.base_var.times);
             break;
+        case del_:
+            new->u.del_.var = copyStatement(st->u.del_.var);
+            break;
         case base_svar:
             new->u.base_svar.name = copyStatement(st->u.base_svar.name);
             new->u.base_svar.times = copyStatement(st->u.base_svar.times);

+ 1 - 2
src/var.c

@@ -177,7 +177,6 @@ void updateHashTable(HashTable *update, HashTable *new, Inter *inter) {
 LinkValue *findVar(char *name, VarOperation operating, Inter *inter, HashTable *ht) {
     LinkValue *tmp = NULL;
     vhashn index = time33(name);
-
     for (Var **base = &ht->hashtable[index]; *base != NULL; base = &(*base)->next){
         if (eqString((*base)->name, name)){
             tmp = (*base)->value;
@@ -206,7 +205,7 @@ LinkValue *findFromVarList(char *name, vnum times, VarOperation operating, INTER
     for (vnum i = 0; i < base && var_list->next != NULL; i++)
         var_list = var_list->next;
     if (operating == del_var && var_list != NULL)
-        tmp = findVar(name, true, inter, var_list->hashtable);
+        tmp = findVar(name, del_var, inter, var_list->hashtable);
     else
         for (PASS; var_list != NULL && tmp == NULL; var_list = var_list->next)
             tmp = findVar(name, operating, inter, var_list->hashtable);