Sfoglia il codice sorgente

feat: 支持错误类型

SongZihuan 4 anni fa
parent
commit
5141371626

+ 18 - 0
include/inter.h

@@ -30,6 +30,24 @@ struct Inter{
         struct Value *list_iter;
         struct Value *dict_iter;
 
+        struct Value *base_exc;
+        struct Value *exc;
+        struct Value *type_exc;
+        struct Value *arg_exc;
+        struct Value *per_exc;
+        struct Value *name_exc;
+        struct Value *goto_exc;
+        struct Value *result_exc;
+        struct Value *assert_exc;
+
+        struct Value *key_exc;
+        struct Value *index_exc;
+        struct Value *stride_exc;
+        struct Value *super_exc;
+        struct Value *iterstop_exc;
+        struct Value *import_exc;
+        struct Value *include_exp;
+
         char *var_str_prefix;
         char *var_num_prefix;
         char *var_bool_prefix;

+ 1 - 0
include/ofunc.h

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

+ 2 - 2
include/run.h

@@ -68,7 +68,7 @@ ResultType fromImportFile(INTER_FUNCTIONSIG);
 
 ResultType pointAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST);
 ResultType listAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST);
-ResultType assCore(Statement *name, LinkValue *value, bool check_aut, 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, INTER_FUNCTIONSIG_NOT_ST);
+ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool setting, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH_RUN_H

+ 23 - 3
include/value.h

@@ -70,7 +70,7 @@ struct Value{
                 value_list,
             } type;
             struct LinkValue **list;
-            vnum size;  // TODO-szh typedef NUMBER_TYPE
+            vnum size;
         } list;
         struct Dict{
             struct HashTable *dict;
@@ -126,12 +126,32 @@ struct Inherit{
     struct Inherit *next;
 };
 
+enum BaseErrorType{
+    E_BaseException,
+    E_Exception,
+    E_TypeException,
+    E_ArgumentException,
+    E_PermissionsException,
+    E_GotoException,
+    E_ResultException,
+    E_NameExceptiom,
+    E_AssertException,
+    E_KeyException,
+    E_IndexException,
+    E_StrideException,
+    E_StopIterException,
+    E_SuperException,
+    E_ImportException,
+    E_IncludeException,
+};
+
 typedef struct Value Value;
 typedef struct LinkValue LinkValue;
 typedef struct Result Result;
 typedef struct Error Error;
 typedef struct Inherit Inherit;
 typedef enum ResultType ResultType;
+typedef enum BaseErrorType BaseErrorType;
 
 Value *makeObject(Inter *inter, VarList *object, VarList *out_var, Inherit *inherit);
 void freeValue(Value **Value);
@@ -152,8 +172,8 @@ Value *makeDictValue(struct Argument **arg_ad, bool new_hash, INTER_FUNCTIONSIG_
 void setResultCore(Result *ru);
 void setResult(Result *ru, Inter *inter, LinkValue *belong);
 void setResultBase(Result *ru, Inter *inter, LinkValue *belong);
-void setResultErrorSt(Result *ru, Inter *inter, char *error_type, char *error_message, Statement *st, LinkValue *belong, bool new);
-void setResultError(Result *ru, Inter *inter, char *error_type, char *error_message, fline line, char *file, LinkValue *belong, bool new);
+void setResultErrorSt(BaseErrorType type, char *error_message, bool new, INTER_FUNCTIONSIG);
+void setResultError(BaseErrorType type, char *error_message, fline line, char *file, bool new, INTER_FUNCTIONSIG_NOT_ST);
 void setResultOperationNone(Result *ru, Inter *inter, LinkValue *belong);
 void setResultOperation(Result *ru, LinkValue *value);
 void setResultOperationBase(Result *ru, LinkValue *value);

+ 16 - 12
main.c

@@ -1,24 +1,28 @@
 #include "__virtualmath.h"
 
-jmp_buf ctrl_c;
-bool set_ctrl_c = false;
-void sighandler(int signum);
+jmp_buf ctrlC_ENV;
+bool ctrlCUseJmp = false;
+void signalStop(int signum);
 
 int main(int argc, char *argv[]) {
     Inter *inter = NULL;
+    memVirtualMathUseJmp = true;
+    if (setjmp(memVirtualMath_Env) == -1){
+        fprintf(stderr, "ERROR: Fatal memory error encountered, May be caused by insufficient memory!\n");
+        return 1;
+    }
+
     if (getArgs(argc, argv))
         goto args_error;
-
     inter = makeInter(args.out_file, args.error_file, NULL);
 
-    if (setjmp(ctrl_c) == -1 || setjmp(memVirtualMath_Env) == -1) {
+    ctrlCUseJmp = true;
+    signal(SIGINT, signalStop);
+    if (setjmp(ctrlC_ENV) == -1) {
         freeArgs();
         freeInter(inter, true);
-        return 1;
+        return 2;
     }
-    memVirtualMathUseJmp = true;
-    set_ctrl_c = true;
-    signal(SIGINT, sighandler);
 
     for (ResultType status = not_return; status != error_return && argv[optind] != NULL; optind++)
         status = runCodeBlock(argv[optind], inter);
@@ -37,9 +41,9 @@ int main(int argc, char *argv[]) {
 }
 
 
-void sighandler(int signum) {
-    if (set_ctrl_c)
-        longjmp(ctrl_c, -1);
+void signalStop(int signum) {
+    if (ctrlCUseJmp)
+        longjmp(ctrlC_ENV, -1);
     else
         exit(1);
 }

+ 0 - 2
ofunc/include/bool.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_BOOL_H
 #define VIRTUALMATH_BOOL_H
-#include "__macro.h"
-
 void registeredBool(REGISTERED_FUNCTIONSIG);
 void makeBaseBool(Inter *inter);
 #endif //VIRTUALMATH_BOOL_H

+ 0 - 2
ofunc/include/dict.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_DICT_H
 #define VIRTUALMATH_DICT_H
-#include "__macro.h"
-
 void registeredDict(REGISTERED_FUNCTIONSIG);
 void makeBaseDict(Inter *inter);
 #endif //VIRTUALMATH_DICT_H

+ 0 - 1
ofunc/include/dictiter.h

@@ -1,6 +1,5 @@
 #ifndef VIRTUALMATH_DICTITER_H
 #define VIRTUALMATH_DICTITER_H
-#include "__macro.h"
 
 void registeredDictIter(REGISTERED_FUNCTIONSIG);
 void makeBaseDictIter(Inter *inter);

+ 6 - 0
ofunc/include/error_.h

@@ -0,0 +1,6 @@
+#ifndef VIRTUALMATH_ERROR__H
+#define VIRTUALMATH_ERROR__H
+void makeExcIter(Inter *inter);
+void registeredExcIter(REGISTERED_FUNCTIONSIG);
+
+#endif //VIRTUALMATH_ERROR__H

+ 0 - 2
ofunc/include/function.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_FUNCTION_H
 #define VIRTUALMATH_FUNCTION_H
-#include "__macro.h"
-
 void registeredFunction(REGISTERED_FUNCTIONSIG);
 void makeBaseFunction(Inter *inter);
 #endif //VIRTUALMATH_FUNCTION_H

+ 0 - 2
ofunc/include/io.h

@@ -1,6 +1,4 @@
 #ifndef VIRTUALMATH_IO_H
 #define VIRTUALMATH_IO_H
-#include "__base.h"
-
 void registeredIOFunction(REGISTERED_FUNCTIONSIG);
 #endif //VIRTUALMATH_IO_H

+ 0 - 2
ofunc/include/list.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_LIST_H
 #define VIRTUALMATH_LIST_H
-#include "__macro.h"
-
 void registeredList(REGISTERED_FUNCTIONSIG);
 void makeBaseList(Inter *inter);
 #endif //VIRTUALMATH_BOOL_H

+ 0 - 2
ofunc/include/listiter.h

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

+ 0 - 2
ofunc/include/num.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_NUM_H
 #define VIRTUALMATH_NUM_H
-#include "__macro.h"
-
 void registeredNum(REGISTERED_FUNCTIONSIG);
 void makeBaseNum(Inter *inter);
 #endif //VIRTUALMATH_NUM_H

+ 0 - 2
ofunc/include/object.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_OBJECT_H
 #define VIRTUALMATH_OBJECT_H
-#include "__macro.h"
-
 void registeredObject(REGISTERED_FUNCTIONSIG);
 void makeBaseObject(Inter *inter);
 #endif //VIRTUALMATH_OBJECT_H

+ 0 - 2
ofunc/include/pass.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_PASS_H
 #define VIRTUALMATH_PASS_H
-#include "__macro.h"
-
 void registeredEllipisis(REGISTERED_FUNCTIONSIG);
 void makeBaseEllipisis(Inter *inter);
 #endif //VIRTUALMATH_PASS_H

+ 0 - 2
ofunc/include/str.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_STR_H
 #define VIRTUALMATH_STR_H
-#include "__macro.h"
-
 void registeredStr(REGISTERED_FUNCTIONSIG);
 void makeBaseStr(Inter *inter);
 #endif //VIRTUALMATH_STR_H

+ 0 - 3
ofunc/include/sys.h

@@ -1,7 +1,4 @@
 #ifndef VIRTUALMATH_SYS_H
 #define VIRTUALMATH_SYS_H
-#include "__macro.h"
-
-
 void registeredSysFunction(REGISTERED_FUNCTIONSIG);
 #endif //VIRTUALMATH_SYS_H

+ 0 - 2
ofunc/include/vobject.h

@@ -1,7 +1,5 @@
 #ifndef VIRTUALMATH_VOBJECT_H
 #define VIRTUALMATH_VOBJECT_H
-#include "__macro.h"
-
 void registeredVObject(REGISTERED_FUNCTIONSIG);
 void makeBaseVObject(Inter *inter);
 #endif //VIRTUALMATH_VOBJECT_H

+ 1 - 1
ofunc/src/__ofunc.c

@@ -2,7 +2,7 @@
 
 LinkValue *registeredFunctionCore(OfficialFunction of, char *name, LinkValue *belong, INTER_FUNCTIONSIG_CORE) {
     LinkValue *value = makeLinkValue(makeCFunctionValue(of, var_list, inter), belong, inter);
-    addStrVar(name, false, value, belong, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    addStrVar(name, false, true, value, belong, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     return value;
 }
 

+ 1 - 1
ofunc/src/bool.c

@@ -6,7 +6,7 @@ void registeredBool(REGISTERED_FUNCTIONSIG){
 //    VarList *object_backup = NULL;
 //    NameFunc tmp[] = {{NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("bool", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("bool", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
 //    object_backup = object_var->next;
 //    object_var->next = inter->var_list;

+ 5 - 5
ofunc/src/dict.c

@@ -13,7 +13,7 @@ ResultType dict_down(OFFICAL_FUNCTIONSIG){
     freeResult(result);
 
     if (ap[0].value->value->type != dict){
-        setResultError(result, inter, "TypeException", "Get Not Support Type", 0, "sys", belong, true);
+        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);
@@ -22,7 +22,7 @@ ResultType dict_down(OFFICAL_FUNCTIONSIG){
     if (element != NULL)
         setResultOperationBase(result, copyLinkValue(element, inter));
     else
-        setResultError(result, inter, "KeyException", "Key Not Found", 0, "sys", belong, true);
+        setResultError(E_KeyException, "Key Not Found", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     return result->type;
 }
 
@@ -38,7 +38,7 @@ ResultType dict_keys(OFFICAL_FUNCTIONSIG){
         return result->type;
     freeResult(result);
     if (ap[0].value->value->type != dict){
-        setResultError(result, inter, "TypeException", "Get Not Support Type", 0, "sys", belong, true);
+        setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
     for (int index=0; index < MAX_SIZE; index++){
@@ -63,7 +63,7 @@ ResultType dict_iter(OFFICAL_FUNCTIONSIG){
     freeResult(result);
 
     if (ap[0].value->value->type != dict){
-        setResultError(result, inter, "TypeException", "Don't get a dict", 0, "sys", belong, true);
+        setResultError(E_TypeException, "Don't get a dict", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
     {
@@ -86,7 +86,7 @@ void registeredDict(REGISTERED_FUNCTIONSIG){
                       {"__iter__", dict_iter, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("dict", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("dict", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
     object_backup = object_var->next;
     object_var->next = inter->var_list;

+ 6 - 6
ofunc/src/dictiter.c

@@ -12,7 +12,7 @@ ResultType dictiter_init(OFFICAL_FUNCTIONSIG){
         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);
+        setResultError(E_TypeException, "Don't get a dict to dictiter", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
     {
@@ -21,7 +21,7 @@ ResultType dictiter_init(OFFICAL_FUNCTIONSIG){
         LinkValue *listiter_class = NULL;
 
         if (keys == NULL){
-            setResultError(result, inter, "TypeExcepyion", "Don't Find keys", 0, "sys", belong, true);
+            setResultError(E_TypeException, "Don't Find keys", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             return error_return;
         }
 
@@ -73,13 +73,13 @@ ResultType dictiter_next(OFFICAL_FUNCTIONSIG){
         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);
+        setResultError(E_TypeException, "Don't get a list to listiter from dictiter", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         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);
+        setResultError(E_TypeException, "Don't find __next__", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
@@ -98,7 +98,7 @@ ResultType dictiter_down(OFFICAL_FUNCTIONSIG){
         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);
+        setResultError(E_TypeException, "Don't get a dict to dictiter", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
@@ -116,7 +116,7 @@ void registeredDictIter(REGISTERED_FUNCTIONSIG){
                       {"__down__", dictiter_down, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("dictiter", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("dictiter", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
     object_backup = object_var->next;
     object_var->next = inter->var_list;

+ 88 - 0
ofunc/src/error_.c

@@ -0,0 +1,88 @@
+#include "__ofunc.h"
+
+static Value *makeException(Value *father, Inter *inter){
+    Value *exc = makeBaseChildClass(father, inter);
+    gc_addStatementLink(&exc->gc_status);
+    return exc;
+}
+
+static void addException(char *name, Value *exc, LinkValue *belong, Inter *inter){
+    addStrVar(name, false, true, makeLinkValue(exc, inter->base_father, inter),
+              belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+}
+
+ResultType base_exception_init(OFFICAL_FUNCTIONSIG){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=name_value, .name="message", .must=0, .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);
+    addAttributes("__message__", false, ap[1].value, ap[0].value, inter);  // TODO-szh 设置inter的__mesage__
+    setResultBase(result, inter, belong);
+    return result->type;
+}
+
+void registeredExcIter(REGISTERED_FUNCTIONSIG){
+    struct {
+        char *name;
+        Value *value;
+    } setList[] = {{"Exception", inter->data.exc},
+                   {"TypeException", inter->data.type_exc},
+                   {"ArgumentException", inter->data.arg_exc},
+                   {"PermissionsException", inter->data.per_exc},
+                   {"ResultException", inter->data.result_exc},
+                   {"GotoException", inter->data.goto_exc},
+                   {"NameException", inter->data.name_exc},
+                   {"AssertException", inter->data.assert_exc},
+                   {"IndexException", inter->data.index_exc},
+                   {"KeyException", inter->data.key_exc},
+                   {"StrideException", inter->data.stride_exc},
+                   {"IncludeException", inter->data.include_exp},
+                   {"ImportException", inter->data.import_exc},
+                   {"IterStopException", inter->data.iterstop_exc},
+                   {"SuperException", inter->data.super_exc},
+                   {NULL, NULL}};
+    {
+        LinkValue *object = makeLinkValue(inter->data.base_exc, inter->base_father, inter);
+        VarList *object_var = object->value->object.var;
+        VarList *object_backup = NULL;
+        NameFunc tmp[] = {{"__init__", base_exception_init, object_free_},
+                          {NULL, NULL}};
+        gc_addTmpLink(&object->gc_status);
+        addStrVar("BaseException", false, true, 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;  // TODO-szh 操作内嵌到 iterNameFunc
+
+        gc_freeTmpLink(&object->gc_status);
+    }
+    for (int i=0; setList[i].name != NULL; i++)
+        addException(setList[i].name, setList[i].value, belong, inter);
+}
+
+void makeExcIter(Inter *inter){
+    inter->data.base_exc = makeException(inter->data.object, inter);
+    inter->data.exc = makeException(inter->data.base_exc, inter);
+
+    inter->data.type_exc = makeException(inter->data.exc, inter);
+    inter->data.arg_exc = makeException(inter->data.exc, inter);
+    inter->data.per_exc = makeException(inter->data.exc, inter);
+    inter->data.result_exc = makeException(inter->data.exc, inter);
+    inter->data.goto_exc = makeException(inter->data.exc, inter);
+    inter->data.name_exc = makeException(inter->data.exc, inter);
+    inter->data.assert_exc = makeException(inter->data.exc, inter);
+
+    inter->data.key_exc = makeException(inter->data.exc, inter);
+    inter->data.index_exc = makeException(inter->data.exc, inter);
+    inter->data.stride_exc = makeException(inter->data.exc, inter);
+
+    inter->data.iterstop_exc = makeException(inter->data.exc, inter);
+    inter->data.super_exc = makeException(inter->data.exc, inter);
+    inter->data.import_exc = makeException(inter->data.exc, inter);
+    inter->data.include_exp = makeException(inter->data.exc, inter);
+}

+ 1 - 1
ofunc/src/function.c

@@ -6,7 +6,7 @@ void registeredFunction(REGISTERED_FUNCTIONSIG){
 //    VarList *object_backup = NULL;
 //    NameFunc tmp[] = {{NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("function", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("function", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
 //    object_backup = object_var->next;
 //    object_var->next = inter->var_list;

+ 12 - 12
ofunc/src/list.c

@@ -43,10 +43,10 @@ ResultType list_slice(OFFICAL_FUNCTIONSIG){
     first = first < 0 ? first + size : first;
     second = second < 0 ? second + size : second;
     if (second > size || first >= size){
-        setResultError(result, inter, "IndexException", "Index too max", 0, "sys", belong, true);
+        setResultError(E_IndexException, "Index too max", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     } else if (first < 0 || second <= 0){
-        setResultError(result, inter, "IndexException", "Index too small", 0, "sys", belong, true);
+        setResultError(E_IndexException, "Index too small", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
@@ -57,7 +57,7 @@ ResultType list_slice(OFFICAL_FUNCTIONSIG){
         second = tmp;
     }
     if (stride == 0 || first > second){
-        setResultError(result, inter, "StrideException", "Stride Error", 0, "sys", belong, true);
+        setResultError(E_StrideException, "Stride Error", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
@@ -77,7 +77,7 @@ ResultType list_slice(OFFICAL_FUNCTIONSIG){
     return result->type;
 
     type_error:
-    setResultError(result, inter, "TypeException", "Get Not Support Type", 0, "sys", belong, true);
+    setResultError(E_TypeException, "Get Not Support Type", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     return error_return;
 }
 
@@ -95,7 +95,7 @@ ResultType list_down_assignment(OFFICAL_FUNCTIONSIG){
     freeResult(result);
 
     if (ap[0].value->value->type != list || ap[2].value->value->type != number){
-        setResultError(result, inter, "TypeException", "Get Not Support Type", 0, "sys", belong, true);
+        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;
@@ -103,10 +103,10 @@ ResultType list_down_assignment(OFFICAL_FUNCTIONSIG){
     if (index < 0)
         index = size + index;
     if (index >= size){
-        setResultError(result, inter, "IndexException", "Index too max", 0, "sys", belong, true);
+        setResultError(E_IndexException, "Index too max", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     } else if (index < 0){
-        setResultError(result, inter, "IndexException", "Index too small", 0, "sys", belong, true);
+        setResultError(E_IndexException, "Index too small", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
     ap[0].value->value->data.list.list[index] = ap[1].value;
@@ -128,7 +128,7 @@ ResultType list_down(OFFICAL_FUNCTIONSIG){
     freeResult(result);
 
     if (ap[0].value->value->type != list || ap[1].value->value->type != number){
-        setResultError(result, inter, "TypeException", "Get Not Support Type", 0, "sys", belong, true);
+        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;
@@ -136,10 +136,10 @@ ResultType list_down(OFFICAL_FUNCTIONSIG){
     if (index < 0)
         index = size + index;
     if (index >= size){
-        setResultError(result, inter, "IndexException", "Index too max", 0, "sys", belong, true);
+        setResultError(E_IndexException, "Index too max", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     } else if (index < 0){
-        setResultError(result, inter, "IndexException", "Index too small", 0, "sys", belong, true);
+        setResultError(E_IndexException, "Index too small", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
     element = ap[0].value->value->data.list.list[index];
@@ -157,7 +157,7 @@ ResultType list_iter(OFFICAL_FUNCTIONSIG){
     freeResult(result);
 
     if (ap[0].value->value->type != list){
-        setResultError(result, inter, "TypeException", "Don't get a list", 0, "sys", belong, true);
+        setResultError(E_TypeException, "Don't get a list", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
     {
@@ -181,7 +181,7 @@ void registeredList(REGISTERED_FUNCTIONSIG){
                       {"__iter__", list_iter, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("list", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("list", false, true, 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));

+ 4 - 4
ofunc/src/listiter.c

@@ -11,7 +11,7 @@ ResultType listiter_init(OFFICAL_FUNCTIONSIG){
         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);
+        setResultError(E_TypeException, "Don't get a list to listiter", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
@@ -33,14 +33,14 @@ ResultType listiter_next(OFFICAL_FUNCTIONSIG){
     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);
+        setResultError(E_TypeException, "Don't get a list to listiter", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
     freeResult(result);
     elementDownOne(list_, index, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
-        setResultError(result, inter, "StopIterException", "Stop Iter", 0, "sys", belong, true);
+        setResultError(E_StopIterException, "Stop Iter", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     else {
         index->value->data.num.num ++;
         addAttributes("__index", false, index, ap[0].value, inter);
@@ -56,7 +56,7 @@ void registeredListIter(REGISTERED_FUNCTIONSIG){
                       {"__next__", listiter_next, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("listiter", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("listiter", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
     object_backup = object_var->next;
     object_var->next = inter->var_list;

+ 1 - 1
ofunc/src/num.c

@@ -6,7 +6,7 @@ void registeredNum(REGISTERED_FUNCTIONSIG){
 //    VarList *object_backup = NULL;
 //    NameFunc tmp[] = {{NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("num", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("num", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
 //    object_backup = object_var->next;
 //    object_var->next = inter->var_list;

+ 3 - 3
ofunc/src/object.c

@@ -10,7 +10,7 @@ ResultType object_new_(OFFICAL_FUNCTIONSIG){
     int status = 1;
     arg = parserValueArgument(ap, arg, &status, NULL);
     if (status != 1){
-        setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", belong, true);
+        setResultError(E_ArgumentException, "Too less Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
@@ -39,7 +39,7 @@ ResultType object_new_(OFFICAL_FUNCTIONSIG){
         }
         freeResult(&_init_result);
     } else if (arg != NULL)
-        setResultError(result, inter, "ArgumentException", "Too many Exception", 0, "sys", belong, true);
+        setResultError(E_ArgumentException, "Too many Exception", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     return_:
     return result->type;
@@ -51,7 +51,7 @@ void registeredObject(REGISTERED_FUNCTIONSIG){
     VarList *object_backup = NULL;
     NameFunc tmp[] = {{"__new__", object_new_, class_static_}, {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("object", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("object", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
     object_backup = object_var->next;
     object_var->next = inter->var_list;

+ 1 - 1
ofunc/src/pass.c

@@ -6,7 +6,7 @@ void registeredEllipisis(REGISTERED_FUNCTIONSIG){
 //    VarList *object_backup = NULL;
 //    NameFunc tmp[] = {{NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("ellipsis", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("ellipsis", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
 //    object_backup = object_var->next;
 //    object_var->next = inter->var_list;

+ 1 - 1
ofunc/src/str.c

@@ -6,7 +6,7 @@ void registeredStr(REGISTERED_FUNCTIONSIG){
 //    VarList *object_backup = NULL;
 //    NameFunc tmp[] = {{NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("str", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("str", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
 //    object_backup = object_var->next;
 //    object_var->next = inter->var_list;

+ 2 - 2
ofunc/src/sys.c

@@ -21,7 +21,7 @@ ResultType vm_super(OFFICAL_FUNCTIONSIG){
             result->type = operation_return;
             gc_addTmpLink(&result->value->gc_status);
         } else
-            setResultError(result, inter, "SuperException", "Don't get next father", 0, "sys", belong, true);
+            setResultError(E_SuperException, "Don't get next father", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return result->type;
     }
 
@@ -39,7 +39,7 @@ ResultType vm_super(OFFICAL_FUNCTIONSIG){
         gc_addTmpLink(&result->value->gc_status);
     }
     else
-        setResultError(result, inter, "SuperException", "Don't get next father", 0, "sys", belong, true);
+        setResultError(E_SuperException, "Don't get next father", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     return result->type;
 }

+ 11 - 11
ofunc/src/vobject.c

@@ -1,8 +1,8 @@
 #include "__ofunc.h"
 
-typedef void (*base_opt)(LinkValue *, Result *, struct Inter *, Value *, Value *);
+typedef void (*base_opt)(LinkValue *, Result *, struct Inter *, VarList *var_list, Value *, Value *);
 
-void vobject_add_base(LinkValue *belong, Result *result, struct Inter *inter, Value *left, Value *right) {
+void vobject_add_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
     setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
     if (left->type == number && right->type == number)
         result->value->value = makeNumberValue(left->data.num.num + right->data.num.num, inter);
@@ -12,18 +12,18 @@ void vobject_add_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         memFree(new_string);
     }
     else
-        setResultError(result, inter, "TypeException", "Get Not Support Value", 0, "sys", belong, true);
+        setResultError(E_TypeException, "Get Not Support Value", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 }
 
-void vobject_sub_base(LinkValue *belong, Result *result, struct Inter *inter, Value *left, Value *right) {
+void vobject_sub_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
     setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
     if (left->type == number && right->type == number)
         result->value->value = makeNumberValue(left->data.num.num - right->data.num.num, inter);
     else
-        setResultError(result, inter, "TypeException", "Get Not Support Value", 0, "sys", belong, true);
+        setResultError(E_TypeException, "Get Not Support Value", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 }
 
-void vobject_mul_base(LinkValue *belong, Result *result, struct Inter *inter, Value *left, Value *right) {
+void vobject_mul_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
     setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
     if (left->type == number && right->type == number)
         result->value->value = makeNumberValue(left->data.num.num * right->data.num.num, inter);
@@ -39,17 +39,17 @@ void vobject_mul_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         memFree(new_string);
     }
     else
-        setResultError(result, inter, "TypeException", "Get Not Support Value", 0, "sys", belong, true);
+        setResultError(E_TypeException, "Get Not Support Value", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 }
 
-void vobject_div_base(LinkValue *belong, Result *result, struct Inter *inter, Value *left, Value *right) {
+void vobject_div_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
     setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
     if (left->type == number && right->type == number) {
         lldiv_t div_result = lldiv(left->data.num.num, right->data.num.num);
         result->value->value = makeNumberValue(div_result.quot, inter);
     }
     else
-        setResultError(result, inter, "TypeException", "Get Not Support Value", 0, "sys", belong, true);
+        setResultError(E_TypeException, "Get Not Support Value", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 }
 
 ResultType vobject_opt_core(OFFICAL_FUNCTIONSIG, base_opt func){
@@ -69,7 +69,7 @@ ResultType vobject_opt_core(OFFICAL_FUNCTIONSIG, base_opt func){
     left = ap[0].value->value;
     right = ap[1].value->value;
 
-    func(belong, result, inter, left, right);
+    func(belong, result, inter, var_list, left, right);
 
     return result->type;
 }
@@ -100,7 +100,7 @@ void registeredVObject(REGISTERED_FUNCTIONSIG){
                       {"__div__", vobject_div, object_free_},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
-    addStrVar("vobject", false, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    addStrVar("vobject", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
 
     object_backup = object_var->next;
     object_var->next = inter->var_list;

+ 1 - 0
parser/grammar.c

@@ -158,6 +158,7 @@ void parserCommand(PASERSSIGNATURE){
             break;
         case MATHER_RAISE :
             status = commandCallControl_(CALLPASERSSIGNATURE, makeRaiseStatement, RAISE, &st, false, NULL);
+            break;
         case MATHER_ASSERT :
             status = commandCallControl_(CALLPASERSSIGNATURE, makeAssertStatement, ASSERT, &st, true,
                                          "parserAssert: Don't get conditions after assert");

+ 19 - 9
src/__run.c

@@ -12,7 +12,7 @@ ResultType getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list, result, belong)))
         return result->type;
     if (!isType(result->value->value, number)){
-        setResultErrorSt(result, inter, "TypeException", "Don't get a number value", st, belong, true);
+        setResultErrorSt(E_TypeException, "Don't get a number value", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return result->type;
     }
     *times = (int)result->value->value->data.num.num;
@@ -35,7 +35,7 @@ ResultType getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.times, var_list, result, belong)))
         return result->type;
     if (!isType(result->value->value, number)){
-        setResultErrorSt(result, inter, "TypeException", "Don't get a number value", st, belong, true);
+        setResultErrorSt(E_TypeException, "Don't get a number value", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return result->type;
     }
     *times = (int)result->value->value->data.num.num;
@@ -140,7 +140,7 @@ ResultType setFunctionArgument(Argument **arg, LinkValue *function_value, fline
     enum FunctionPtType pt_type = function_value->value->data.function.function_data.pt_type;
     setResultCore(result);
     if (function_value->belong == NULL){
-        setResultError(result, inter, "ArgumentException", "Don't get self", line, file, belong, true);
+        setResultError(E_ArgumentException, "Don't get self", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return error_return;
     }
 
@@ -211,10 +211,12 @@ LinkValue *checkStrVar(char *name, bool free_old, INTER_FUNCTIONSIG_CORE){
     return tmp;
 }
 
-void addStrVar(char *name, bool free_old, LinkValue *value, LinkValue *belong, INTER_FUNCTIONSIG_CORE){
+void addStrVar(char *name, bool free_old, bool setting, LinkValue *value, LinkValue *belong, INTER_FUNCTIONSIG_CORE){
     char *var_name = setStrVarName(name, free_old, inter);
-    LinkValue *name_ = makeLinkValue(makeStringValue(var_name, inter), belong, inter);
+    LinkValue *name_ = makeLinkValue(makeStringValue(name, inter), belong, inter);
     addFromVarList(var_name, name_, 0, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    if (setting)
+        newObjectSetting(name_, value, inter);
     memFree(var_name);
 }
 
@@ -225,10 +227,18 @@ LinkValue *findAttributes(char *name, bool free_old, LinkValue *value, Inter *in
     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);
+void addAttributes(char *name, bool free_old, LinkValue *value, LinkValue *belong, Inter *inter) {
+    addStrVar(name, free_old, false, value, belong, inter, belong->value->object.var);
 }
 
+void newObjectSetting(LinkValue *name, LinkValue *belong, Inter *inter) {
+    addAttributes("__name__", false, name, belong, inter);
+    addAttributes("__self__", false, belong, belong, inter);
+    if (belong->value->object.inherit != NULL)
+        addAttributes("__father__", false, belong->value->object.inherit->value, belong, inter);
+}
+
+
 ResultType elementDownOne(LinkValue *element, LinkValue *index, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
     LinkValue *_func_ = NULL;
     setResultCore(result);
@@ -245,7 +255,7 @@ ResultType elementDownOne(LinkValue *element, LinkValue *index, fline line, char
         freeArgument(arg, true);
     }
     else
-        setResultError(result, inter, "TypeException", "Don't find __down__", line, file, belong, true);
+        setResultError(E_TypeException, "Don't find __down__", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     gc_freeTmpLink(&element->gc_status);
     gc_freeTmpLink(&index->gc_status);
@@ -266,7 +276,7 @@ ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_F
         gc_freeTmpLink(&_func_->gc_status);
     }
     else
-        setResultError(result, inter, "IterException", "Object Not Iterable", line, file, belong, true);
+        setResultError(E_TypeException, "Object Not Iterable", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     return result->type;
 }

+ 2 - 2
src/include/__run.h

@@ -16,7 +16,6 @@ ResultType getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
 ResultType getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
 ResultType getVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
 
-Statement *getRunInfoStatement(Statement *funtion_st);
 bool popStatementVarList(Statement *funtion_st, VarList **function_var, VarList *out_var, Inter *inter);
 
 void newFunctionYield(Statement *funtion_st, Statement *node, VarList *new_var, Inter *inter);
@@ -32,9 +31,10 @@ ResultType setFunctionArgument(struct Argument **arg, LinkValue *function_value,
 void freeFunctionArgument(Argument *arg, Argument *base);
 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);
+void addStrVar(char *name, bool free_old, bool setting, 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);
+void newObjectSetting(LinkValue *name, LinkValue *belong, Inter *inter);
 ResultType elementDownOne(LinkValue *element, LinkValue *index, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH___RUN_H

+ 24 - 5
src/inter.c

@@ -96,6 +96,25 @@ void freeBaseInterData(struct Inter *inter){
     gc_freeStatementLink(&inter->data.list_iter->gc_status);
     gc_freeStatementLink(&inter->data.dict_iter->gc_status);
     gc_freeStatementLink(&inter->data.none->gc_status);
+
+    gc_freeStatementLink(&inter->data.base_exc->gc_status);
+    gc_freeStatementLink(&inter->data.exc->gc_status);
+    gc_freeStatementLink(&inter->data.type_exc->gc_status);
+    gc_freeStatementLink(&inter->data.arg_exc->gc_status);
+    gc_freeStatementLink(&inter->data.per_exc->gc_status);
+    gc_freeStatementLink(&inter->data.result_exc->gc_status);
+    gc_freeStatementLink(&inter->data.goto_exc->gc_status);
+    gc_freeStatementLink(&inter->data.name_exc->gc_status);
+    gc_freeStatementLink(&inter->data.assert_exc->gc_status);
+
+    gc_freeStatementLink(&inter->data.key_exc->gc_status);
+    gc_freeStatementLink(&inter->data.index_exc->gc_status);
+    gc_freeStatementLink(&inter->data.stride_exc->gc_status);
+    gc_freeStatementLink(&inter->data.iterstop_exc->gc_status);
+    gc_freeStatementLink(&inter->data.super_exc->gc_status);
+    gc_freeStatementLink(&inter->data.import_exc->gc_status);
+    gc_freeStatementLink(&inter->data.include_exp->gc_status);
+
     memFree(inter->data.var_num_prefix);
     memFree(inter->data.var_str_prefix);
     memFree(inter->data.var_object_prefix);
@@ -120,7 +139,7 @@ void freeBaseInterData(struct Inter *inter){
 
     if (!inter->data.is_stdout)
         fclose(inter->data.inter_stdout);
-    if (!inter->data.inter_stderr)
+    if (!inter->data.is_stderr)
         fclose(inter->data.inter_stderr);
 }
 
@@ -162,13 +181,13 @@ void mergeInter(Inter *new, Inter *base){
     freeBaseInterData(new);
 
     for (base_value = &base->base; *base_value != NULL; base_value = &(*base_value)->gc_next)
-            PASS;
+        PASS;
     for (base_linkValue = &base->link_base; *base_linkValue != NULL; base_linkValue = &(*base_linkValue)->gc_next)
-            PASS;
+        PASS;
     for (base_hash = &base->hash_base; *base_hash != NULL; base_hash = &(*base_hash)->gc_next)
-            PASS;
+        PASS;
     for (base_var = &base->base_var; *base_var != NULL; base_var = &(*base_var)->gc_next)
-            PASS;
+        PASS;
 
     *base_value = new->base;
     *base_linkValue = new->link_base;

+ 2 - 0
src/ofunc.c

@@ -13,6 +13,7 @@ static Registered base_func_list[] = {registeredIOFunction,
                                       registeredList,
                                       registeredListIter,
                                       registeredDictIter,
+                                      registeredExcIter,
                                       NULL};
 
 void registeredBaseFunction(struct LinkValue *father, Inter *inter){
@@ -32,4 +33,5 @@ void registeredFunctionName(Inter *inter){
     makeBaseList(inter);
     makeBaseListIter(inter);
     makeBaseDictIter(inter);
+    makeExcIter(inter);
 }

+ 20 - 21
src/parameter.c

@@ -263,7 +263,7 @@ ResultType defaultParameter(Parameter **function_ad, vnum *num, INTER_FUNCTIONSI
 
         value = result->value;
         freeResult(result);
-        assCore(function->data.name, value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(function->data.name, value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result))
             goto return_;
     }
@@ -292,7 +292,7 @@ ResultType argumentToVar(Argument **call_ad, vnum *num, INTER_FUNCTIONSIG_NOT_ST
             continue;
         }
         freeResult(result);
-        assCore(call->data.name, call->data.value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(call->data.name, call->data.value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result))
             goto return_;
     }
@@ -351,24 +351,23 @@ ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, vnum
                 value = result->value;
                 goto not_return;
             }
-            setResultErrorSt(result, inter, "ArgumentException", "Too less Argument", name, belong, true);
+            setResultErrorSt(E_ArgumentException, "Too less Argument", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             goto reutnr_;
         }
         else if ((name->aut == public_aut || name->aut == auto_aut) && (value->aut != public_aut && value->aut != auto_aut)) {
-            setResultErrorSt(result, inter, "PermissionsException", "Wrong Permissions: access Argument as public",
-                             name,
-                             belong, true);
+            setResultErrorSt(E_PermissionsException, "Wrong Permissions: access Argument as public", true,
+                             name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             goto reutnr_;
         }
         else if ((name->aut == protect_aut) && (value->aut == private_aut)) {
-            setResultErrorSt(result, inter, "PermissionsException", "Wrong Permissions: access variables as protect",
-                             name, belong, true);
+            setResultErrorSt(E_PermissionsException, "Wrong Permissions: access variables as protect", true,
+                             name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             goto reutnr_;
         }
 
         not_return:
         freeResult(result);
-        assCore(name, value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
+        assCore(name, value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
 
         if (!CHECK_RESULT(result)) {
             *function_ad = function;
@@ -403,7 +402,7 @@ ResultType argumentToParameter(Argument **call_ad, Parameter **function_ad, VarL
 
     for (PASS; call != NULL && function != NULL && (call->type == value_arg) && function->type != args_par; call = call->next, function = function->next){
         Statement *name = function->type == value_par ? function->data.value : function->data.name;
-        assCore(name, call->data.value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
+        assCore(name, call->data.value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
         if (!CHECK_RESULT(result))
             goto return_;
         freeResult(result);
@@ -598,7 +597,7 @@ ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *f
             }
             case mul_par: {
                 LinkValue *tmp = makeLinkValue(makeListValue(&call, inter, value_tuple), belong, inter);
-                assCore(function->data.value, tmp, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
+                assCore(function->data.value, tmp, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
                 returnResult(result);
                 function = function->next;
                 break;
@@ -608,20 +607,20 @@ ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *f
                 returnResult(result);
                 freeResult(result);
 
-                assCore(function->data.value, tmp, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
+                assCore(function->data.value, tmp, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, belong));
                 returnResult(result);
                 function = function->next;
                 break;
             }
             case error_to_less:
-                setResultError(result, inter, "ArgumentException", "Too less argument", line, file, belong, true);
+                setResultError(E_ArgumentException, "Too less argument", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 goto return_;
             case error_to_more:
             to_more:
-                setResultError(result, inter, "ArgumentException", "Too more argument", line, file, belong, true);
+                setResultError(E_ArgumentException, "Too more argument", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 goto return_;
             case error_kw:
-                setResultError(result, inter, "ArgumentException", "Value argument for double star", line, file, belong, true);
+                setResultError(E_ArgumentException, "Value argument for double star", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 goto return_;
             default:
                 goto break_;
@@ -679,7 +678,7 @@ int parserArgumentUnion(ArgumentParser ap[], Argument *arg, INTER_FUNCTIONSIG_NO
         int status = 1;
         arg = parserValueArgument(ap, arg, &status, &bak);
         if (status != 1){
-            setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", belong, true);
+            setResultError(E_ArgumentException, "Too less Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             return 0;
         }
         ap = bak;
@@ -689,7 +688,7 @@ int parserArgumentUnion(ArgumentParser ap[], Argument *arg, INTER_FUNCTIONSIG_NO
         int status;
 
         if (arg != NULL && arg->type != name_arg) {
-            setResultError(result, inter, "ArgumentException", "Too many Argument", 0, "sys", belong, true);
+            setResultError(E_ArgumentException, "Too many Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             return -6;
         }
 
@@ -698,20 +697,20 @@ int parserArgumentUnion(ArgumentParser ap[], Argument *arg, INTER_FUNCTIONSIG_NO
             return -1;
         if (status == -3){
             if (parserArgumentNameDefault(ap)->must != -1){
-                setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", belong, true);
+                setResultError(E_ArgumentException, "Too less Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 return -7;
             }
         }
         else if (status == 0){
-            setResultError(result, inter, "ArgumentException", "Too many Argument", 0, "sys", belong, true);
+            setResultError(E_ArgumentException, "Too many Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             return -2;
         } else if (status == -4){
-            setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", belong, true);
+            setResultError(E_ArgumentException, "Too less Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             return -3;
         }
     } else{
         if (arg != NULL) {
-            setResultError(result, inter, "ArgumentException", "Too many Argument", 0, "sys", belong, true);
+            setResultError(E_ArgumentException, "Too many Argument", 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             return -4;
         }
     }

+ 3 - 3
src/run.c

@@ -134,7 +134,7 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
             if (type == goto_return && result->times == 0){
                 Statement *label_st = checkLabel(st, result->label);
                 if (label_st == NULL){
-                    setResultErrorSt(result, inter, "GotoException", "Don't find label", st, belong, true);
+                    setResultErrorSt(E_GotoException, "Don't find label", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                     type = error_return;
                     break;
                 }
@@ -175,7 +175,7 @@ ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
             if (type == goto_return){
                 Statement *label_st = checkLabel(st, result->label);
                 if (label_st == NULL){
-                    setResultErrorSt(result, inter, "GotoException", "Don't find label", st, belong, true);
+                    setResultErrorSt(E_GotoException, "Don't find label", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                     type = error_return;
                     break;
                 }
@@ -206,7 +206,7 @@ bool operationSafeInterStatement(INTER_FUNCTIONSIG){
     if (RUN_TYPE(type))
         return false;
     else if (type != return_code && type != error_return)
-        setResultErrorSt(result, inter, "ResultException", "Get Not Support Result", st, belong, true);
+        setResultErrorSt(E_ResultException, "Get Not Support Result", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     return true;
 }
 

+ 17 - 12
src/runbranch.c

@@ -2,7 +2,7 @@
 
 static bool checkNumber(INTER_FUNCTIONSIG){
     if (!isType(result->value->value, number)) {
-        setResultErrorSt(result, inter, "TypeException", "Don't get a number value", st, belong, true);
+        setResultErrorSt(E_TypeException, "Don't get a number value", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return false;
     }
     return true;
@@ -10,7 +10,7 @@ static bool checkNumber(INTER_FUNCTIONSIG){
 
 static bool checkString(INTER_FUNCTIONSIG){
     if (!isType(result->value->value, string)) {
-        setResultErrorSt(result, inter, "TypeException", "Don't get a string value", st, belong, true);
+        setResultErrorSt(E_TypeException, "Don't get a string value", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return false;
     }
     return true;
@@ -120,7 +120,7 @@ ResultType ifBranch(INTER_FUNCTIONSIG) {
             condition_value = result->value;
             freeResult(result);
             if (if_list->var != NULL) {
-                assCore(if_list->var, condition_value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+                assCore(if_list->var, condition_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 if (!CHECK_RESULT(result)){
                     set_result = false;
                     goto not_else;
@@ -259,7 +259,7 @@ ResultType whileBranch(INTER_FUNCTIONSIG) {
         condition_value = result->value;
         freeResult(result);
         if (while_list->var != NULL){
-            assCore(while_list->var, condition_value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            assCore(while_list->var, condition_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             if (!CHECK_RESULT(result)){
                 set_result = false;
                 goto not_else;
@@ -422,13 +422,18 @@ ResultType forBranch(INTER_FUNCTIONSIG) {
             LinkValue *element = NULL;
             getIter(iter, 0, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             if (!CHECK_RESULT(result)) {
-                freeResult(result);
-                break;
+                if (result->value->value == inter->data.iterstop_exc || checkAttribution(result->value->value, inter->data.iterstop_exc)){
+                    freeResult(result);
+                    break;
+                } else {
+                    set_result = false;
+                    goto not_else;
+                }
             }
             element = result->value;
             result->value = NULL;
             freeResult(result);
-            assCore(for_list->var, element, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+            assCore(for_list->var, element, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
             gc_freeTmpLink(&element->gc_status);
             if (!CHECK_RESULT(result)){
                 set_result = false;
@@ -575,7 +580,7 @@ ResultType withBranch(INTER_FUNCTIONSIG) {
                 _enter_ = NULL;
                 _exit_ = NULL;
                 value = NULL;
-                setResultErrorSt(result, inter, "EnterException", "Get Not Support Value to Enter with", st, belong, true);
+                setResultErrorSt(E_TypeException, "Get Not Support Value to Enter with", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 set_result = false;
                 goto run_finally;
             }
@@ -594,7 +599,7 @@ ResultType withBranch(INTER_FUNCTIONSIG) {
             new = pushVarList(var_list, inter);
             enter_value = result->value;
             freeResult(result);
-            assCore(with_list->var, enter_value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(new, result, belong));
+            assCore(with_list->var, enter_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(new, result, belong));
             if (!CHECK_RESULT(result)) {
                 set_result = false;
                 popVarList(new);
@@ -743,7 +748,7 @@ ResultType tryBranch(INTER_FUNCTIONSIG) {
     error_value = result->value;
     freeResult(result);
     if (except_list->var != NULL){
-        assCore(except_list->var, error_value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(except_list->var, error_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result)){
             set_result = false;
             goto not_else;
@@ -940,7 +945,7 @@ ResultType assertCode(INTER_FUNCTIONSIG){
     if (checkBool(result->value->value))
         setResult(result, inter, belong);
     else
-        setResultErrorSt(result, inter, "AssertException", "Raise by user", st, belong, true);
+        setResultErrorSt(E_AssertException, "Assertion check error", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     return result->type;
 }
 
@@ -989,7 +994,7 @@ ResultType runLabel(INTER_FUNCTIONSIG) {
     freeResult(result);
     var_list = pushVarList(var_list, inter);
     if (st->u.label_.as != NULL)
-        assCore(st->u.label_.as, goto_value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(st->u.label_.as, goto_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     gc_freeTmpLink(&goto_value->gc_status);
     if (st->u.label_.as != NULL && !CHECK_RESULT(result))
         goto return_;

+ 7 - 7
src/runcall.c

@@ -38,7 +38,7 @@ ResultType setClass(INTER_FUNCTIONSIG) {
         freeResult(result);
     }
 
-    assCore(st->u.set_class.name, tmp, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    assCore(st->u.set_class.name, tmp, false, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (CHECK_RESULT(result))
         setResult(result, inter, belong);
 
@@ -47,7 +47,7 @@ ResultType setClass(INTER_FUNCTIONSIG) {
 
     error_:
     gc_freeTmpLink(&tmp->gc_status);
-    setResultErrorSt(result, inter, NULL, NULL, st, belong, false);
+    setResultErrorSt(E_BaseException, NULL, false, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     return result->type;
 }
 
@@ -70,7 +70,7 @@ ResultType setFunction(INTER_FUNCTIONSIG) {
         result->value = NULL;
         freeResult(result);
     }
-    assCore(st->u.set_function.name, tmp, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    assCore(st->u.set_function.name, tmp, false, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
         goto error_;
     setResult(result, inter, belong);
@@ -119,7 +119,7 @@ ResultType elementSlice(INTER_FUNCTIONSIG) {
         gc_freeTmpLink(&_func_->gc_status);
     }
     else
-        setResultErrorSt(result, inter, "TypeException", "Don't find __down__/__slice__", st, belong, true);
+        setResultErrorSt(E_TypeException, "Don't find __down__/__slice__", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     gc_freeTmpLink(&element->gc_status);
     return result->type;
@@ -167,7 +167,7 @@ ResultType callBackCore(LinkValue *function_value, Argument *arg, fline line, ch
         callClass(function_value, arg, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     else
         callObject(function_value, arg, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-    setResultError(result, inter, NULL, NULL, line, file, belong, false);
+    setResultError(E_BaseException, NULL, line, file, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     gc_freeTmpLink(&function_value->gc_status);
     return result->type;
@@ -183,7 +183,7 @@ ResultType callClass(LinkValue *class_value, Argument *arg, fline line, char *fi
         gc_freeTmpLink(&_new_->gc_status);
     }
     else
-        setResultError(result, inter, "ClassException", "Don't find __new__", line, file, belong, true);
+        setResultError(E_TypeException, "Don't find __new__", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     return result->type;
 }
@@ -198,7 +198,7 @@ ResultType callObject(LinkValue *object_value, Argument *arg, fline line, char *
         gc_freeTmpLink(&_call_->gc_status);
     }
     else
-        setResultError(result, inter, "TypeException", "Object is not callable", line, file, belong, true);
+        setResultError(E_TypeException, "Object is not callable", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     return result->type;
 }

+ 10 - 10
src/runfile.c

@@ -10,7 +10,7 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
         return result->type;
 
     if (!isType(result->value->value, string)){
-        setResultErrorSt(result, inter, "TypeException", "Don't get a string value", st, belong, true);
+        setResultErrorSt(E_TypeException, "Don't get a string value", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
@@ -18,7 +18,7 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
     freeResult(result);
 
     if (checkFile(file_dir) != 1){
-        setResultErrorSt(result, inter, "IncludeFileException", "File is not readable", st, belong, true);
+        setResultErrorSt(E_IncludeException, "File is not readable", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
@@ -26,13 +26,13 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
     pm = makeParserMessage(file_dir);
     parserCommandList(pm, inter, true, false, new_st);
     if (pm->status != success){
-        setResultErrorSt(result, inter, "IncludeSyntaxException", pm->status_message, st, belong, true);
+        setResultErrorSt(E_IncludeException, pm->status_message, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
     functionSafeInterStatement(CALL_INTER_FUNCTIONSIG(new_st, var_list, result, belong));
     if (!CHECK_RESULT(result))
-        setResultErrorSt(result, inter, NULL, NULL, st, belong, false);
+        setResultErrorSt(E_BaseException, NULL, false, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     return_:
     freeStatement(new_st);
@@ -49,14 +49,14 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
         goto return_;
 
     if (!isType(result->value->value, string)) {
-        setResultErrorSt(result, inter, "TypeException", "Don't get a string value", st, belong, true);
+        setResultErrorSt(E_ImportException, "Don't get a string value", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
     *file_dir = result->value->value->data.str.str;
     freeResult(result);
     if (checkFile(*file_dir) != 1) {
-        setResultErrorSt(result, inter, "ImportFileException", "File is not readable", st, belong, true);
+        setResultErrorSt(E_ImportException, "File is not readable", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
@@ -72,7 +72,7 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
     parserCommandList(pm, import_inter, true, false, run_st);
     if (pm->status != success) {
         freeInter(import_inter, false);
-        setResultErrorSt(result, inter, "ImportSyntaxException", pm->status_message, st, belong, true);
+        setResultErrorSt(E_TypeException, pm->status_message, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
@@ -80,7 +80,7 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
     if (!CHECK_RESULT(result)) {
         freeInter(import_inter, false);
         result->value = makeLinkValue(inter->base, belong, inter);  // 重新设定none值
-        setResultErrorSt(result, inter, NULL, NULL, st, belong, false);
+        setResultErrorSt(E_BaseException, NULL, false, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
@@ -111,9 +111,9 @@ ResultType importFile(INTER_FUNCTIONSIG) {
         import_value = makeLinkValue(import_obj, belong, inter);
     }
     if (st->u.import_file.as != NULL)
-        assCore(st->u.import_file.as, import_value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(st->u.import_file.as, import_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     else
-        addStrVar(splitDir(file_dir), true, import_value, belong, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        addStrVar(splitDir(file_dir), true, true, import_value, belong, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     setResult(result, inter, belong);
 
     return_:

+ 26 - 23
src/runoperation.c

@@ -92,11 +92,9 @@ ResultType pointOperation(INTER_FUNCTIONSIG) {
     if (!CHECK_RESULT(result))
         goto return_;
     else if ((left->aut == public_aut || left->aut == auto_aut) && (result->value->aut != public_aut && result->value->aut != auto_aut))
-        setResultErrorSt(result, inter, "PermissionsException", "Wrong Permissions: access variables as public", st,
-                         belong, true);
+        setResultErrorSt(E_PermissionsException, "Wrong Permissions: access variables as public", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     else if ((left->aut == protect_aut) && (result->value->aut == private_aut))
-        setResultErrorSt(result, inter, "PermissionsException", "Wrong Permissions: access variables as protect", st,
-                         belong, true);
+        setResultErrorSt(E_PermissionsException, "Wrong Permissions: access variables as protect", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     if (result->value->belong == NULL || result->value->belong->value != left->value && checkAttribution(left->value, result->value->belong->value))
         result->value->belong = left;
@@ -123,7 +121,7 @@ ResultType assOperation(INTER_FUNCTIONSIG) {
             freeStatement(return_st);
         }
         tmp = makeLinkValue(function_value, belong, inter);
-        assCore(st->u.operation.left->u.call_function.function, tmp, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(st->u.operation.left->u.call_function.function, tmp, false, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     }
     else{
         if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, var_list, result, belong)))
@@ -131,12 +129,13 @@ ResultType assOperation(INTER_FUNCTIONSIG) {
         value = result->value;
 
         freeResult(result);
-        assCore(st->u.operation.left, value, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(st->u.operation.left, value, false, false,
+                CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     }
     return result->type;
 }
 
-ResultType assCore(Statement *name, LinkValue *value, bool check_aut, INTER_FUNCTIONSIG_NOT_ST){
+ResultType assCore(Statement *name, LinkValue *value, bool check_aut, bool setting, INTER_FUNCTIONSIG_NOT_ST) {
     setResultCore(result);
     gc_addTmpLink(&value->gc_status);
 
@@ -147,13 +146,19 @@ ResultType assCore(Statement *name, LinkValue *value, bool check_aut, INTER_FUNC
     else if (name->type == operation && name->u.operation.OperationType == OPT_POINT)
         pointAss(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     else
-        varAss(name, value, check_aut, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        varAss(name, value, check_aut, setting, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
     gc_freeTmpLink(&value->gc_status);
     return result->type;
 }
 
-ResultType varAss(Statement *name, LinkValue *value, bool check_aut, INTER_FUNCTIONSIG_NOT_ST) {
+void varAssCore(char *name, LinkValue *name_, vnum times, LinkValue *value, bool setting, INTER_FUNCTIONSIG_CORE) {
+    addFromVarList(name, name_, times, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    if (setting)
+        newObjectSetting(name_, value, inter);
+}
+
+ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool setting, INTER_FUNCTIONSIG_NOT_ST) {
     char *str_name = NULL;
     int int_times = 0;
     LinkValue *var_value = NULL;
@@ -169,26 +174,24 @@ ResultType varAss(Statement *name, LinkValue *value, bool check_aut, INTER_FUNCT
         LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (tmp != NULL) {
             if ((value->aut == public_aut || value->aut == auto_aut) && (tmp->aut != public_aut && tmp->aut != auto_aut)) {
-                setResultErrorSt(result, inter, "PermissionsException", "Wrong Permissions: access variables as public",
-                                 name, belong, true);
+                setResultErrorSt(E_PermissionsException, "Wrong Permissions: access variables as public", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 goto return_;
             }
             else if ((value->aut == protect_aut) && (tmp->aut == private_aut)) {
-                setResultErrorSt(result, inter, "PermissionsException",
-                                 "Wrong Permissions: access variables as protect", name, belong, true);
+                setResultErrorSt(E_PermissionsException, "Wrong Permissions: access variables as protect", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
                 goto return_;
             }
             else
-                goto set_var;
+                varAssCore(str_name, result->value, int_times, var_value, setting, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         } else
-            set_var: addFromVarList(str_name, result->value, int_times, var_value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            varAssCore(str_name, result->value, int_times, var_value, setting, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     } else {
         if (name->aut != auto_aut) {
             LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
             if (tmp != NULL)
                 tmp->aut = name->aut;
         }
-        addFromVarList(str_name, result->value, int_times, var_value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        varAssCore(str_name, result->value, int_times, var_value, setting, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     }
     freeResult(result);
     result->type = operation_return;
@@ -233,7 +236,7 @@ ResultType downAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
     iter = result->value;
     result->value = NULL;
     freeResult(result);
-    _down_assignment_ = findAttributes("__down_assignment__", false, iter, inter);
+    _down_assignment_ = findAttributes("__down_assignment__", false, iter, inter);  // TODO-szh __down_assignment__
     if (_down_assignment_ != NULL){
         Argument *arg = makeValueArgument(value);
         gc_addTmpLink(&_down_assignment_->gc_status);
@@ -249,7 +252,7 @@ ResultType downAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
         gc_freeTmpLink(&_down_assignment_->gc_status);
     }
     else
-        setResultErrorSt(result, inter, "TypeException", "Don't find __down_assignment__", name, belong, true);
+        setResultErrorSt(E_TypeException, "Don't find __down_assignment__", true, name, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     gc_freeTmpLink(&iter->gc_status);
     return result->type;
 }
@@ -267,7 +270,7 @@ ResultType pointAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
     if (name->u.operation.right->type == OPERATION && name->u.operation.right->u.operation.OperationType == OPT_POINT)
         pointAss(name->u.operation.right, value, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, belong));
     else
-        assCore(name->u.operation.right, value, true, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, belong));
+        assCore(name->u.operation.right, value, true, false, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, belong));
     gc_freeze(inter, var_list, object, false);
 
     freeResult(&left);
@@ -290,19 +293,19 @@ ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
     result->value = findFromVarList(name, int_times, get_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (result->value == NULL) {
         char *info = memStrcat("Name Not Found: ", name, false, false);
-        setResultErrorSt(result, inter, "NameException", info, st, belong, true);
+        setResultErrorSt(E_NameExceptiom, info, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         memFree(info);
     }
     else if ((st->aut == public_aut) && (result->value->aut != public_aut && result->value->aut != auto_aut)){
         setResultCore(result);
         char *info = memStrcat("Wrong Permissions: access variables as public ", name, false, false);
-        setResultErrorSt(result, inter, "PermissionsException", info, st, belong, true);
+        setResultErrorSt(E_PermissionsException, info, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         memFree(info);
     }
     else if ((st->aut == protect_aut) && (result->value->aut == private_aut)){
         setResultCore(result);
         char *info = memStrcat("Wrong Permissions: access variables as protect ", name, false, false);
-        setResultErrorSt(result, inter, "PermissionsException", info, st, belong, true);
+        setResultErrorSt(E_PermissionsException, info, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         memFree(info);
     }
     else
@@ -449,7 +452,7 @@ ResultType operationCore(INTER_FUNCTIONSIG, char *name) {
     }
     else {
         char *message = memStrcat("Don't find ", name, false, false);
-        setResultErrorSt(result, inter, "TypeException", message, st, belong, true);
+        setResultErrorSt(E_TypeException, message, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         memFree(message);
     }
 

+ 87 - 11
src/value.c

@@ -255,22 +255,98 @@ void setResultBase(Result *ru, Inter *inter, LinkValue *belong) {
     gc_addTmpLink(&ru->value->gc_status);
 }
 
-void setResultErrorSt(Result *ru, Inter *inter, char *error_type, char *error_message, Statement *st, LinkValue *belong, bool new) {
-    setResultError(ru, inter, error_type, error_message, st->line, st->code_file, belong, new);
+void setResultErrorSt(BaseErrorType type, char *error_message, bool new, Statement *st, INTER_FUNCTIONSIG_NOT_ST) {
+    setResultError(type, error_message, st->line, st->code_file, new, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+}
+
+Value *findBaseError(BaseErrorType type, Inter *inter){
+    switch (type) {
+        case E_BaseException:
+            return inter->data.base_exc;
+        case E_Exception:
+            return inter->data.exc;
+        case E_TypeException:
+            return inter->data.type_exc;
+        case E_ArgumentException:
+            return inter->data.arg_exc;
+        case E_PermissionsException:
+            return inter->data.per_exc;
+        case E_GotoException:
+            return inter->data.goto_exc;
+        case E_ResultException:
+            return inter->data.result_exc;
+        case E_NameExceptiom:
+            return inter->data.name_exc;
+        case E_AssertException:
+            return inter->data.assert_exc;
+        case E_IndexException:
+            return inter->data.index_exc;
+        case E_KeyException:
+            return inter->data.key_exc;
+        case E_StrideException:
+            return inter->data.stride_exc;
+        case E_StopIterException:
+            return inter->data.iterstop_exc;
+        case E_SuperException:
+            return inter->data.super_exc;
+        case E_ImportException:
+            return inter->data.import_exc;
+        case E_IncludeException:
+            return inter->data.include_exp;
+        default:
+            return NULL;
+    }
+}
+
+char *getErrorInfo(LinkValue *exc, int type, Inter *inter){
+    char *str_name = type == 1 ? "__name__" : "__message__";
+    LinkValue *_info_ = findAttributes(str_name, false, exc, inter);
+    if (_info_ != NULL && _info_->value->type == string)
+        return memStrcpy(_info_->value->data.str.str);
+    else
+        return type == 1 ? memStrcpy("Error Type: Unknown") : memStrcpy("Error Message: Unknown");
+}
+
+void callException(LinkValue *exc, char *message, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
+    LinkValue *_new_ = findAttributes(inter->data.object_new, false, exc, inter);
+    char *type = NULL;
+    char *error_message = NULL;
+    setResultCore(result);
+    gc_addTmpLink(&exc->gc_status);
+
+    if (_new_ != NULL){
+        Argument *arg = makeValueArgument(makeLinkValue(makeStringValue(message, inter), belong, inter));
+        gc_addTmpLink(&_new_->gc_status);
+        callBackCore(_new_, arg, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        gc_freeTmpLink(&_new_->gc_status);
+        freeArgument(arg, true);
+        type = getErrorInfo(result->value, 1, inter);
+        error_message = getErrorInfo(result->value, 2, inter);
+    }
+    else {
+        result->value = exc;
+        gc_addTmpLink(&result->value->gc_status);
+    }
+
+    result->type = error_return;
+    result->error = connectError(makeError(type, error_message, line, file), result->error);
+    memFree(type);
+    memFree(error_message);
+    gc_freeTmpLink(&exc->gc_status);
 }
 
-void setResultError(Result *ru, Inter *inter, char *error_type, char *error_message, fline line, char *file, LinkValue *belong, bool new) {
-    if (!new && ru->type != error_return)
+void setResultError(BaseErrorType type, char *error_message, fline line, char *file, bool new, INTER_FUNCTIONSIG_NOT_ST) {
+    if (!new && result->type != error_return)
         return;
     if (new) {
-        setResult(ru, inter, belong);
-        ru->type = error_return;
-    }
-    else{
-        error_type = NULL;
-        error_message = NULL;
+        Value *exc = findBaseError(type, inter);
+        if (exc == NULL)
+            exc = inter->data.base_exc;
+        freeResult(result);
+        callException(makeLinkValue(exc, belong, inter), error_message, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     }
-    ru->error = connectError(makeError(error_type, error_message, line, file), ru->error);
+    else
+        result->error = connectError(makeError(NULL, NULL, line, file), result->error);
 }
 
 void setResultOperationNone(Result *ru, Inter *inter, LinkValue *belong) {