Эх сурвалжийг харах

feat: 新增变量, 常量和常量表达式折叠

SongZihuan 4 жил өмнө
parent
commit
5bfd930bd7

+ 1 - 0
vmcore/include/statement.h

@@ -55,6 +55,7 @@ struct Statement{
         struct base_var{
             wchar_t *name;
             struct Statement *times;
+            struct Var *link;  // link 模式
             bool run;
         } base_var;
         struct{

+ 3 - 2
vmcore/include/var.h

@@ -55,8 +55,9 @@ VarList *makeVarList(Inter *inter, bool make_hash, HashTable *hs);
 VarList *freeVarList(VarList *vl);
 
 vhashn time33(wchar_t *key);
-LinkValue *findVar(wchar_t *name, VarOperation operating, Inter *inter, HashTable *ht);
-LinkValue *findFromVarList(wchar_t *name, vint times, VarOperation operating, FUNC_CORE);
+LinkValue *findVar(wchar_t *name, VarOperation operating, Var **re, HashTable *ht);
+LinkValue *findFromVarList(wchar_t *name, vint times, Var **re, VarOperation operating, struct Inter *inter,
+                           struct VarList *var_list);
 void addVar(wchar_t *name, LinkValue *value, LinkValue *name_, Inter *inter, HashTable *ht);
 void updateHashTable(HashTable *update, HashTable *new, Inter *inter);
 void addFromVarList(wchar_t *name, LinkValue *name_, vint times, LinkValue *value, FUNC_CORE);

+ 2 - 2
vmcore/ofunc/src/dict.c

@@ -50,7 +50,7 @@ ResultType dict_down(O_FUNC){
     {
         LinkValue *element = NULL;
         wchar_t *name = getNameFromValue(ap[1].value->value, inter->data.var_deep, inter);
-        element = findVar(name, read_var, inter, ap[0].value->value->data.dict.dict);
+        element = findVar(name, read_var, NULL, ap[0].value->value->data.dict.dict);
         if (element != NULL)
             setResultOperationBase(result, element);
         else {
@@ -80,7 +80,7 @@ ResultType dict_down_del(O_FUNC){
     {
         LinkValue *element = NULL;
         wchar_t *name = getNameFromValue(ap[1].value->value, inter->data.var_deep, inter);
-        element = findVar(name, del_var, inter, ap[0].value->value->data.dict.dict);
+        element = findVar(name, del_var, NULL, ap[0].value->value->data.dict.dict);
         if (element != NULL)
             setResult(result, inter);
         else{

+ 1 - 1
vmcore/ofunc/src/function.c

@@ -87,7 +87,7 @@ ResultType function_set(O_FUNC){  // 针对FFI设置vaargs
         addAttributes(L"vaargs", false, list, LINEFILE, true, CFUNC_NT(var_list, result, func));
         gc_freeTmpLink(&list->gc_status);
     } else
-        findFromVarList(L"vaargs", 0, del_var, CFUNC_CORE(var_list));
+        findFromVarList(L"vaargs", 0, NULL, del_var, CFUNC_CORE(var_list));
 
     if (CHECK_RESULT(result))
         setResultOperation(result, func);

+ 4 - 5
vmcore/src/__run.c

@@ -219,7 +219,6 @@ ResultType setFunctionArgument(Argument **arg, Argument **base, LinkValue *_func
             return R_error;
     }
 
-    // TODO-szh 检查此处把self设置为NULL后出现错误
     if (pt_type != fp_cls && pt_type != fp_no_ && pt_type != fp_func_ && pt_type != fp_func_cls && self == NULL)
         goto error;
     if ((pt_type == fp_cls || pt_type == fp_func_cls || pt_type == fp_cls_obj || pt_type == fp_cls_class) && cls == NULL)
@@ -402,7 +401,7 @@ void freeFunctionArgument(Argument *arg, Argument *base) {
 LinkValue *findStrVar(wchar_t *name, bool free_old, fline line, char *file, bool nowrun, FUNC_NT){
     LinkValue *tmp = NULL;
     wchar_t *name_ = setStrVarName(name, free_old, inter);
-    tmp = findFromVarList(name_, 0, read_var, CFUNC_CORE(var_list));
+    tmp = findFromVarList(name_, 0, NULL, read_var, CFUNC_CORE(var_list));
     memFree(name_);
     if (tmp != NULL && nowrun) {
         setResultCore(result);
@@ -419,7 +418,7 @@ LinkValue *findStrVarOnly(wchar_t *name, bool free_old, FUNC_CORE) {
 LinkValue *checkStrVar(wchar_t *name, bool free_old, FUNC_CORE){
     LinkValue *tmp = NULL;
     wchar_t *name_ = setStrVarName(name, free_old, inter);
-    tmp = findFromVarList(name_, 0, read_var, CFUNC_CORE(var_list));
+    tmp = findFromVarList(name_, 0, NULL, read_var, CFUNC_CORE(var_list));
     memFree(name_);
     return tmp;
 }
@@ -440,7 +439,7 @@ void addStrVar(wchar_t *name, bool free_old, bool setting, LinkValue *value, fli
     gc_addTmpLink(&value->gc_status);
 
     if (run) {
-        LinkValue *tmp = findFromVarList(name, 0, read_var, CFUNC_CORE(var_list));
+        LinkValue *tmp = findFromVarList(name, 0, NULL, read_var, CFUNC_CORE(var_list));
         if (tmp != NULL && !setVarFunc(tmp, value, line, file, CNEXT_NT))
             goto return_;
     }
@@ -473,7 +472,7 @@ bool addAttributes(wchar_t *name, bool free_old, LinkValue *value, fline line, c
     setResultCore(result);
 
     if (run) {
-        LinkValue *tmp = findFromVarList(name, 0, read_var, CFUNC_CORE(belong->value->object.var));
+        LinkValue *tmp = findFromVarList(name, 0, NULL, read_var, CFUNC_CORE(belong->value->object.var));
         if (tmp != NULL && !setVarFunc(tmp, value, line, file, CFUNC_NT(belong->value->object.var, result, belong)))
             goto return_;
     }

+ 1 - 1
vmcore/src/parameter.c

@@ -358,7 +358,7 @@ ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, vint
         }
 
         freeResult(result);
-        value = findFromVarList(str_name, int_times, del_var, CFUNC_CORE(var_list));  // 形式参数取值不需要执行变量式函数
+        value = findFromVarList(str_name, int_times, NULL, del_var, CFUNC_CORE(var_list));  // 形式参数取值不需要执行变量式函数
         memFree(str_name);
 
         if(value == NULL) {

+ 41 - 14
vmcore/src/runoperation.c

@@ -252,12 +252,12 @@ ResultType varDel(Statement *name, bool check_aut, FUNC_NT) {
         return result->type;
     }
     if (check_aut) {
-        LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CFUNC_CORE(var_list));
+        LinkValue *tmp = findFromVarList(str_name, int_times, NULL, read_var, CFUNC_CORE(var_list));
         freeResult(result);
         if (tmp != NULL && !checkAut(name->aut, tmp->aut, name->line, name->code_file, NULL, false, CNEXT_NT))
             goto return_;
     }
-    get = findFromVarList(str_name, int_times, del_var, CFUNC_CORE(var_list));
+    get = findFromVarList(str_name, int_times, NULL, del_var, CFUNC_CORE(var_list));
     if (get != NULL)
         setResult(result, inter);
     else {  // 变量没有删除成功
@@ -397,7 +397,7 @@ ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool settin
     if (name->aut != auto_aut)  // 当左值设定访问权限的时候, 覆盖右值的权限
         value->aut = name->aut;
 
-    tmp = findFromVarList(str_name, int_times, read_var, CFUNC_CORE(var_list));
+    tmp = findFromVarList(str_name, int_times, NULL, read_var, CFUNC_CORE(var_list));
     if (check_aut) {
         if (tmp != NULL && !checkAut(value->aut, tmp->aut, name->line, name->code_file, NULL, false, CNEXT_NT))
             goto error_;
@@ -557,23 +557,34 @@ ResultType getVar(FUNC, VarInfo var_info) {
     int int_times = 0;
     wchar_t *name = NULL;
     LinkValue *var;
-    LinkValue *val;
+    LinkValue *name_;
+    Var *re_var;
 
     setResultCore(result);
-    var_info(&name, &int_times, CNEXT);
-    if (!CHECK_RESULT(result)) {
-        memFree(name);
-        return result->type;
-    }
 
-    GET_RESULT(val, result);
-    var = findFromVarList(name, int_times, read_var, CFUNC_CORE(var_list));
+    if (st->type == base_var && st->u.base_var.link != NULL) {
+        var = st->u.base_var.link->value;
+        name_ = st->u.base_var.link->name_;
+        gc_addTmpLink(&name_->gc_status);
+    } else {
+        var_info(&name, &int_times, CNEXT);
+        if (!CHECK_RESULT(result)) {
+            memFree(name);
+            return result->type;
+        }
+        GET_RESULT(name_, result);
+        var = findFromVarList(name, int_times, &re_var, read_var, CFUNC_CORE(var_list));
+        if (re_var != NULL && (st->u.base_var.times == NULL || st->u.base_var.times->type == base_value)) {  // 变量折叠 TODO-szh 增加开关 处理del var的情况
+            gc_addStatementLink(&re_var->gc_status);
+            st->u.base_var.link = re_var;
+        }
+    }
 
     if (var == NULL) {
         if (st->type == base_svar && !st->u.base_svar.is_var) {
-            setResultOperationBase(result, val);
+            setResultOperationBase(result, name_);
         } else
-            setNameException(val, name, st->line, st->code_file, CNEXT_NT);
+            setNameException(name_, name, st->line, st->code_file, CNEXT_NT);
     } else if (checkAut(st->aut, var->aut, st->line, st->code_file, name, true, CNEXT_NT)) {  // 默认访问权限为pri
         if (var->belong != NULL && var->belong->value != belong->value && checkAttribution(belong->value, var->belong->value)) { // 检查var所属于的对象是否位左值的父亲(若是则需要重新设定belong)
             var = COPY_LINKVALUE(var, inter);
@@ -585,7 +596,7 @@ ResultType getVar(FUNC, VarInfo var_info) {
             setResultOperationBase(result, var);
     }
 
-    gc_freeTmpLink(&val->gc_status);
+    gc_freeTmpLink(&name_->gc_status);
     memFree(name);
     return result->type;
 }
@@ -623,6 +634,12 @@ ResultType getBaseValue(FUNC) {
                 break;
         }
         result->value->belong = belong;
+        // 常量折叠 TODO-szh 增设开关
+        memFree(st->u.base_value.str);
+        st->u.base_value.type = link_value;
+        st->u.base_value.value = result->value;
+        st->u.base_value.str = NULL;
+        gc_addStatementLink(&result->value->gc_status);
     }
     return result->type;
 }
@@ -744,6 +761,16 @@ static ResultType operationCore(FUNC, wchar_t *name, enum OperationType type) {
     } else
         default_mode: runOperationFromValue(left.value, right.value, name, st->line, st->code_file, CNEXT_NT);
 
+    if (st->u.operation.left->type == base_value && st->u.operation.right->type == base_value) {  // 常量表达式折叠 TODO-szh 添加开关
+        freeStatement(st->u.operation.left);
+        freeStatement(st->u.operation.right);
+        st->type = base_value;
+        st->u.base_value.str = NULL;
+        st->u.base_value.value = result->value;
+        st->u.base_value.type = link_value;
+        gc_addStatementLink(&result->value->gc_status);
+    }
+
     freeResult(&left);
     freeResult(&right);
     return result->type;

+ 7 - 0
vmcore/src/statement.c

@@ -99,6 +99,7 @@ Statement *makeBaseVarStatement(wchar_t *name, Statement *times, fline line, cha
     tmp->type = base_var;
     tmp->u.base_var.name = memWidecpy(name);
     tmp->u.base_var.times = times;
+    tmp->u.base_var.link = NULL;
     tmp->u.base_var.run = true;
     return tmp;
 }
@@ -381,6 +382,8 @@ void freeStatement(Statement *st){
             case base_var:
                 memFree(st->u.base_var.name);
                 freeStatement(st->u.base_var.times);
+                if (st->u.base_var.link != NULL)
+                    gc_freeStatementLink(&st->u.base_var.link->gc_status);
                 break;
             case del_:
                 freeStatement(st->u.del_.var);
@@ -545,6 +548,10 @@ Statement *copyStatementCore(Statement *st){
             new->u.base_var.name = memWidecpy(st->u.base_var.name);
             new->u.base_var.times = copyStatement(st->u.base_var.times);
             new->u.base_var.run = st->u.base_var.run;
+            if (st->u.base_var.link != NULL) {
+                new->u.base_var.link = st->u.base_var.link;
+                gc_addStatementLink(&new->u.base_var.link->gc_status);
+            }
             break;
         case del_:
             new->u.del_.var = copyStatement(st->u.del_.var);

+ 6 - 4
vmcore/src/var.c

@@ -161,7 +161,7 @@ void updateHashTable(HashTable *update, HashTable *new, Inter *inter) {
 }
 
 
-LinkValue *findVar(wchar_t *name, VarOperation operating, Inter *inter, HashTable *ht) {
+LinkValue *findVar(wchar_t *name, VarOperation operating, Var **re, HashTable *ht) {
     LinkValue *tmp = NULL;
     vhashn index = time33(name);
     for (Var **base = &ht->hashtable[index]; *base != NULL; base = &(*base)->next){
@@ -172,6 +172,8 @@ LinkValue *findVar(wchar_t *name, VarOperation operating, Inter *inter, HashTabl
                 (*base)->next = NULL;
                 *base = next;
             }
+            if (re != NULL)
+                *re = *base;  // 返回值
             goto return_;
         }
     }
@@ -186,16 +188,16 @@ LinkValue *findVar(wchar_t *name, VarOperation operating, Inter *inter, HashTabl
  * @param var_list
  * @return
  */
-LinkValue *findFromVarList(wchar_t *name, vint times, VarOperation operating, FUNC_CORE) {
+LinkValue *findFromVarList(wchar_t *name, vint times, Var **re, VarOperation operating, FUNC_CORE) {  // TODO-szh 去掉对inter的依赖
     LinkValue *tmp = NULL;
     vint base = findDefault(var_list->default_var, name) + times;
     for (vint i = 0; i < base && var_list->next != NULL; i++)
         var_list = var_list->next;
     if (operating == del_var && var_list != NULL)
-        tmp = findVar(name, del_var, inter, var_list->hashtable);
+        tmp = findVar(name, del_var, re, var_list->hashtable);
     else {
         for (PASS; var_list != NULL && tmp == NULL; var_list = var_list->next)
-            tmp = findVar(name, operating, inter, var_list->hashtable);
+            tmp = findVar(name, operating, re, var_list->hashtable);
     }
     return tmp;
 }