Selaa lähdekoodia

feat & fix: 提取变量操作的函数

parameterFromVar函数直接访问VarList而不是根据Statement来获取值
避免parameterFromVar引发name not found错误
变量增加前缀, 普通变量的前缀为"str_", 于var.h的VARSTR_PREFIX定义
SongZihuan 4 vuotta sitten
vanhempi
sitoutus
baf447c60c
7 muutettua tiedostoa jossa 106 lisäystä ja 40 poistoa
  1. 5 0
      include/run.h
  2. 3 1
      include/var.h
  3. 1 0
      main.c
  4. 39 0
      src/__run.c
  5. 23 29
      src/operation.c
  6. 24 7
      src/parameter.c
  7. 11 3
      src/var.c

+ 5 - 0
include/run.h

@@ -26,4 +26,9 @@ Result regoIf(INTER_FUNCTIONSIG);
 Result restartCode(INTER_FUNCTIONSIG);
 Result returnCode(INTER_FUNCTIONSIG);
 Result raiseCode(INTER_FUNCTIONSIG);
+
+char *setVarName(char *old, bool free_old);
+Result getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
+Result getVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
+
 #endif //VIRTUALMATH_RUN_H

+ 3 - 1
include/var.h

@@ -22,9 +22,11 @@ typedef struct VarList{
     struct VarList *next;
 } VarList;
 
+#define VARSTR_PREFIX "str_"
+
 VarList *makeVarList(Inter *inter);
 VarList *freeVarList(VarList *vl, bool self);
-LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times);
+LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, bool del_var);
 void addFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, LinkValue *value);
 void freeHashTable(HashTable *ht, Inter *inter);
 

+ 1 - 0
main.c

@@ -119,6 +119,7 @@ void freeArgs(){
 
 /*
  *  TODO-szh 字典
+ *  TODO-szh SuperVar
  *  TODO-szh 运行错误的内存释放检查
  *  TODO-szh syntax错误的内存释放检查
  */

+ 39 - 0
src/__run.c

@@ -0,0 +1,39 @@
+#include "__run.h"
+
+Result getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
+    Result result;
+    Result times_tmp;
+
+    *name = setVarName(st->u.base_var.name, false);
+    if (st->u.base_var.times == NULL){
+        *times = 0;
+        goto not_times;
+    }
+    if (operationSafeInterStatement(&times_tmp, CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list)))
+        return times_tmp;
+    // TODO-szh 类型检查
+    *times = (int)times_tmp.value->value->data.num.num;
+
+    not_times:
+    setResult(&result, true, inter);
+    return result;
+}
+
+Result getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
+    Result result;
+    if (st->type == base_var)
+        result = getBaseVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list));
+    else{
+        *name = NULL;
+        *times = 0;
+        setResultError(&result, inter);
+    }
+    return result;
+}
+
+char *setVarName(char *old, bool free_old){
+    char *name = memStrcat(VARSTR_PREFIX, old);
+    if (free_old)
+        memFree(old);
+    return name;
+}

+ 23 - 29
src/operation.c

@@ -143,24 +143,9 @@ Result assOperation(INTER_FUNCTIONSIG) {
 
 Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
     Result result;
-    Result times;
-    setResult(&result, true, inter);
+    setResultOperation(&result, inter);
     int int_times;
-    if (name->type == base_var){
-        if (name->u.base_var.times == NULL){
-            int_times = 0;
-            goto not_times;
-        }
-
-        if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(name->u.base_var.times, var_list))){
-            return times;
-        }
-
-        int_times = (int)times.value->value->data.num.num;
-        not_times:
-        addFromVarList(name->u.base_var.name, var_list, int_times, value);
-    }
-    else if (name->type == base_list){
+    if (name->type == base_list){
         Result tmp_result;
         Statement *tmp_st = makeStatement();
         tmp_st->type = base_value;
@@ -182,26 +167,35 @@ Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
         freeArgument(call, false);
         freeParameter(pt, true);
     }
+    else{
+        Result tmp;
+        char *str_name = NULL;
+
+        tmp = getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list));
+        if (!run_continue(tmp)) {
+            memFree(str_name);
+            return tmp;
+        }
+        addFromVarList(str_name, var_list, int_times, value);
+        memFree(str_name);
+        result.value = value;
+    }
     return result;
 }
 
 Result getBaseVar(INTER_FUNCTIONSIG) {
     Result result;
-    Result times;
+    Result tmp;
+    char *name = NULL;
     int int_times;
     setResultOperation(&result, inter);
-
-    if (st->u.base_var.times == NULL){
-        int_times = 0;
-        goto not_times;
-    }
-    if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list))){
-        return times;
+    tmp = getBaseVarInfo(&name, &int_times, CALL_INTER_FUNCTIONSIG(st, var_list));
+    if (!run_continue(tmp)) {
+        memFree(name);
+        return tmp;
     }
-    int_times = (int)times.value->value->data.num.num;
-
-    not_times:
-    result.value = findFromVarList(st->u.base_var.name, var_list, int_times);
+    result.value = findFromVarList(name, var_list, int_times, false);
+    memFree(name);
     if (result.value == NULL){
         writeLog_(inter->debug, WARNING, "var not found[%s]\n", st->u.base_var.name);
         setResultError(&result, inter);

+ 24 - 7
src/parameter.c

@@ -221,23 +221,40 @@ Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *va
 Result parameterFromVar(Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE, int *num){
     Parameter *function = *function_ad;
     Result result;
+    setResultOperation(&result, inter);
     bool get;
     while (function != NULL){
-        Result tmp, tmp_ass;
-        get = true;
+        Result tmp;
         Statement *name = function->type == value_par ? function->data.value : function->data.name;
-        if(operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(name, var_list))) {
+        char *str_name = NULL;
+        int int_times;
+        LinkValue *value = NULL;
+        get = true;
+
+        tmp = getBaseVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list));
+        if (!run_continue(tmp)) {
+            memFree(str_name);
+            return tmp;
+        }
+        value = findFromVarList(str_name, var_list, int_times, true);
+        memFree(str_name);
+
+        if(value == NULL) {
             get = false;
-            if (function->type == name_par && !operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(function->data.value, var_list)))
+            if (function->type == name_par && !operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(function->data.value, var_list))) {
+                value = tmp.value;
                 goto not_return;
+            }
+            setResultError(&tmp, inter);
             *function_ad = function;
             return tmp;
         }
         not_return:
-        tmp_ass = assCore(name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
-        if (tmp_ass.type == error_return) {
+
+        tmp = assCore(name, value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
+        if (tmp.type == error_return) {
             *function_ad = function;
-            return tmp_ass;
+            return tmp;
         }
         if (get)
             (*num)++;

+ 11 - 3
src/var.c

@@ -125,31 +125,39 @@ void addVar(char *name, LinkValue *value, VarList *var_list){
     return;
 }
 
-LinkValue *findVar(char *name, VarList *var_list){
+LinkValue *findVar(char *name, VarList *var_list, bool del_var) {
     LinkValue *tmp = NULL;
     HASH_INDEX index = time33(name);
     Var *base = var_list->hashtable->hashtable[index];
+    Var *last = NULL;
     if (base == NULL){
         goto return_;
     }
     while (base != NULL){
         if (eqString(base->name, name)){
             tmp = base->value;
+            if (del_var){
+                if (last == NULL)
+                    var_list->hashtable->hashtable[index] = freeVar(base, true);
+                else
+                    last->next = freeVar(base, true);
+            }
             goto return_;
         }
+        last = base;
         base = base->next;
     }
     return_:
     return tmp;
 }
 
-LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times){
+LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, bool del_var) {
     LinkValue *tmp = NULL;
     for (NUMBER_TYPE i=0; i < times && var_list->next != NULL; i++){
         var_list = var_list->next;
     }
     while (var_list != NULL){
-        tmp = findVar(name, var_list);
+        tmp = findVar(name, var_list, del_var);
         if (tmp != NULL){
             goto return_;
         }