فهرست منبع

feat: 支持使用$访问超级变量

SongZihuan 4 سال پیش
والد
کامیت
084a0d194f
10فایلهای تغییر یافته به همراه113 افزوده شده و 34 حذف شده
  1. 1 0
      include/__macro.h
  2. 7 2
      include/run.h
  3. 8 5
      include/statement.h
  4. 1 0
      include/var.h
  5. 18 8
      parser/grammar.c
  6. 48 6
      src/__run.c
  7. 7 7
      src/operation.c
  8. 8 1
      src/run.c
  9. 13 1
      src/statement.c
  10. 2 4
      src/value.c

+ 1 - 0
include/__macro.h

@@ -16,6 +16,7 @@
 #define PASS do{}while(0)
 
 #define NUMBER_TYPE long int
+#define NUMBER_FORMAT "ld"
 #define HASH_INDEX unsigned int
 
 #define INTER_FUNCTIONSIG_CORE struct Inter *inter, struct VarList *var_list

+ 7 - 2
include/run.h

@@ -2,6 +2,8 @@
 #define VIRTUALMATH_RUN_H
 #include "__macro.h"
 
+typedef Result (*VarInfo)(char **name, int *times, INTER_FUNCTIONSIG);
+
 Result globalIterStatement(Inter *inter);
 bool operationSafeInterStatement(Result *result, INTER_FUNCTIONSIG);
 bool ifBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG);
@@ -12,7 +14,7 @@ bool tryBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG);
 Result operationStatement(INTER_FUNCTIONSIG);
 Result setFunction(INTER_FUNCTIONSIG);
 Result callFunction(INTER_FUNCTIONSIG);
-Result getBaseVar(INTER_FUNCTIONSIG);
+Result getVar(INTER_FUNCTIONSIG, VarInfo var_info);
 Result getBaseValue(INTER_FUNCTIONSIG);
 Result getList(INTER_FUNCTIONSIG);
 Result ifBranch(INTER_FUNCTIONSIG);
@@ -27,8 +29,11 @@ Result raiseCode(INTER_FUNCTIONSIG);
 
 Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE);
 
-char *setVarName(char *old, bool free_old);
+char *setStrVarName(char *old, bool free_old);
+char *setNumVarName(NUMBER_TYPE num);
+char *getNameFromValue(Value *value);
 Result getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
+Result getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
 Result getVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
 
 #endif //VIRTUALMATH_RUN_H

+ 8 - 5
include/statement.h

@@ -8,6 +8,7 @@ struct Statement{
         base_value,
         base_list,
         base_var,
+        base_svar,
         operation,
         set_function,
         call_function,
@@ -31,11 +32,12 @@ struct Statement{
             char *name;
             struct Statement *times;
         } base_var;
+        struct base_svar{
+            struct Statement *name;
+            struct Statement *times;
+        } base_svar;
         struct {
-            enum BaseListType{
-                list_,
-                tuple_,
-            } type;
+            enum ListType type;
             struct Parameter *list;
         } base_list;
         struct operation{
@@ -137,7 +139,8 @@ void connectStatement(Statement *base, Statement *new);
 Statement *makeOperationStatement(int type);
 Statement *makeBaseValueStatement(LinkValue *value);
 Statement *makeBaseVarStatement(char *name, Statement *times);
-Statement *makeTupleStatement(struct Parameter *pt, enum BaseListType type);
+Statement *makeBaseSVarStatement(Statement *name, Statement *times);
+Statement *makeTupleStatement(struct Parameter *pt, enum ListType type);
 Statement *makeFunctionStatement(Statement *name, Statement *function, struct Parameter *pt);
 Statement *makeCallStatement(Statement *function, struct Parameter *pt);
 Statement *makeIfStatement();

+ 1 - 0
include/var.h

@@ -3,6 +3,7 @@
 
 #define MAX_SIZE (1024)
 #define VARSTR_PREFIX "str_"
+#define VARDEFAULT_PREFIX "default_var"
 
 struct Var{
     char *name;

+ 18 - 8
parser/grammar.c

@@ -666,7 +666,7 @@ void parserTuple(PASERSSIGNATURE){
         syntaxError(pm, syntax_error, 1, "Don't get tuple element");
         goto return_;
     }
-    st = makeTupleStatement(pt, tuple_);
+    st = makeTupleStatement(pt, value_tuple);
     addStatementToken(TUPLE, st, pm);
 
     return_:
@@ -755,7 +755,6 @@ int getOperation(PASERSSIGNATURE, int right_type, Statement **st, char *name){
     delToken(pm);
     return 1;
 }
-
 /**
  * 字面量匹配
  * parserBaseValue:
@@ -769,13 +768,13 @@ void parserBaseValue(PASERSSIGNATURE){
     token_type = readBackToken(pm);
     if(MATHER_NUMBER == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get number\n", NULL);
-        value_token= popAheadToken(pm);
+        value_token = popAheadToken(pm);
         char *stop;
         st = makeBaseValueStatement(makeLinkValue(makeNumberValue(strtol(value_token->data.str, &stop, 10), inter), NULL, inter));
     }
     else if(MATHER_STRING == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get string\n", NULL);
-        value_token= popAheadToken(pm);
+        value_token = popAheadToken(pm);
         st = makeBaseValueStatement(makeLinkValue(makeStringValue(value_token->data.str, inter), NULL, inter));
     }
     else if(MATHER_VAR == token_type){
@@ -783,6 +782,17 @@ void parserBaseValue(PASERSSIGNATURE){
         value_token= popAheadToken(pm);
         st = makeBaseVarStatement(value_token->data.str, NULL);
     }
+    else if(MATHER_SVAR == token_type){
+        Statement *svar_st;
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get super var\n", NULL);
+        value_token = popAheadToken(pm);
+        if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &svar_st, NULL)){
+            freeToken(value_token, true, true);
+            syntaxError(pm, syntax_error, 1, "Don't get super var after $");
+            goto return_;
+        }
+        st = makeBaseSVarStatement(svar_st, NULL);
+    }
     else if(MATHER_LB == token_type){
         int tmp;
         Statement *tmp_st = NULL;
@@ -807,17 +817,17 @@ void parserBaseValue(PASERSSIGNATURE){
             freeToken(var_token, true, false);
         }
         else{
-            if (tmp_st->type == base_list && tmp_st->u.base_list.type == tuple_){
-                tmp_st->u.base_list.type = list_;
+            if (tmp_st->type == base_list && tmp_st->u.base_list.type == value_tuple){
+                tmp_st->u.base_list.type = value_list;
                 st = tmp_st;
             }
             else
-                st = makeTupleStatement(makeOnlyValueParameter(tmp_st), list_);
+                st = makeTupleStatement(makeOnlyValueParameter(tmp_st), value_list);
         }
     }
     else if(MATHER_LP == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
-        value_token= popAheadToken(pm);
+        value_token = popAheadToken(pm);
         int tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RP, &st, "base value");
         if (tmp == 0){
             freeToken(value_token, true, true);

+ 48 - 6
src/__run.c

@@ -4,15 +4,37 @@ Result getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     Result result;
     Result times_tmp;
 
-    *name = setVarName(st->u.base_var.name, false);
+    *name = setStrVarName(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;
+    *times = (int)times_tmp.value->value->data.num.num; // TODO-szh 类型检查
+
+    not_times:
+    setResult(&result, true, inter);
+    return result;
+}
+
+Result getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
+    Result result;
+    Result value;
+    Result times_tmp;
+
+    if (operationSafeInterStatement(&value, CALL_INTER_FUNCTIONSIG(st->u.base_svar.name, var_list)))
+        return value;
+    *name = getNameFromValue(value.value->value);
+
+    if (st->u.base_svar.times == NULL){
+        *times = 0;
+        goto not_times;
+    }
+    if (operationSafeInterStatement(&times_tmp, CALL_INTER_FUNCTIONSIG(st->u.base_svar.times, var_list)))
+        return times_tmp;
+    *times = (int)times_tmp.value->value->data.num.num; // TODO-szh 类型检查
 
     not_times:
     setResult(&result, true, inter);
@@ -23,17 +45,37 @@ 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 if (st->type == base_svar)
+        result = getBaseSVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list));
     else{
-        *name = NULL;
+        if (operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(st, var_list)))
+            return result;
+        *name = getNameFromValue(result.value->value);
         *times = 0;
-        setResultError(&result, inter);
     }
     return result;
 }
 
-char *setVarName(char *old, bool free_old){
+char *setStrVarName(char *old, bool free_old){
     char *name = memStrcat(VARSTR_PREFIX, old);
     if (free_old)
         memFree(old);
     return name;
 }
+
+char *setNumVarName(NUMBER_TYPE num){
+    char name[50];
+    snprintf(name, 50, "%"NUMBER_FORMAT, num);
+    return memStrcpy(name, 0, false, false);
+}
+
+char *getNameFromValue(Value *value){
+    switch (value->type){
+        case string:
+            return setStrVarName(value->data.str.str, false);
+        case number:
+            return setNumVarName(value->data.num.num);
+        default:
+            return memStrcpy(VARDEFAULT_PREFIX, 0, false, false);
+    }
+}

+ 7 - 7
src/operation.c

@@ -145,7 +145,7 @@ Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
     Result result;
     setResultOperation(&result, inter);
     int int_times;
-    if (name->type == base_list){
+    if (name->type == base_list && name->u.base_list.type == value_tuple){
         Result tmp_result;
         Statement *tmp_st = makeStatement();
         tmp_st->type = base_value;
@@ -158,12 +158,12 @@ Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
             return tmp_result;
         }
         tmp_result = setParameterCore(call, name->u.base_list.list, var_list, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-        if (run_continue(tmp_result)) {
+        if (run_continue(tmp_result))
+            result = tmp_result;
+        else{
             Argument *tmp = call;
             result.value->value = makeListValue(&tmp, inter, value_tuple);
         }
-        else
-            result = tmp_result;
         freeArgument(call, false);
         freeParameter(pt, true);
     }
@@ -183,13 +183,13 @@ Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
     return result;
 }
 
-Result getBaseVar(INTER_FUNCTIONSIG) {
+Result getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
     Result result;
     Result tmp;
     char *name = NULL;
     int int_times;
     setResultOperation(&result, inter);
-    tmp = getBaseVarInfo(&name, &int_times, CALL_INTER_FUNCTIONSIG(st, var_list));
+    tmp = var_info(&name, &int_times, CALL_INTER_FUNCTIONSIG(st, var_list));
     if (!run_continue(tmp)) {
         memFree(name);
         return tmp;
@@ -220,7 +220,7 @@ Result getList(INTER_FUNCTIONSIG) {
         return result;
     }
 
-    int type = st->u.base_list.type == tuple_ ? value_tuple : value_list;
+    int type = st->u.base_list.type == value_tuple ? value_tuple : value_list;
     Value *value = makeListValue(&at, inter, type);
     setResultOperation(&result ,inter);
     result.value->value = value;

+ 8 - 1
src/run.c

@@ -14,7 +14,10 @@ Result runStatement(INTER_FUNCTIONSIG) {
             result = getBaseValue(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
         case base_var:
-            result = getBaseVar(CALL_INTER_FUNCTIONSIG(st, var_list));
+            result = getVar(CALL_INTER_FUNCTIONSIG(st, var_list), getBaseVarInfo);
+            break;
+        case base_svar:
+            result = getVar(CALL_INTER_FUNCTIONSIG(st, var_list), getBaseSVarInfo);
             break;
         case base_list:
             result = getList(CALL_INTER_FUNCTIONSIG(st, var_list));
@@ -72,6 +75,10 @@ Result runStatement(INTER_FUNCTIONSIG) {
  */
 Result iterStatement(INTER_FUNCTIONSIG) {
     Result result;
+    if (st == NULL){
+        setResult(&result, true, inter);
+        return result;
+    }
     Statement *base_st = NULL;
 
     while (true) {

+ 13 - 1
src/statement.c

@@ -47,6 +47,14 @@ Statement *makeBaseVarStatement(char *name, Statement *times){
     return tmp;
 }
 
+Statement *makeBaseSVarStatement(Statement *name, Statement *times){
+    Statement *tmp = makeStatement();
+    tmp->type = base_svar;
+    tmp->u.base_svar.name = name;
+    tmp->u.base_svar.times = times;
+    return tmp;
+}
+
 Statement *makeOperationStatement(int type){
     Statement *tmp = makeStatement();
     tmp->type = operation;
@@ -56,7 +64,7 @@ Statement *makeOperationStatement(int type){
     return tmp;
 }
 
-Statement *makeTupleStatement(Parameter *pt, enum BaseListType type) {
+Statement *makeTupleStatement(Parameter *pt, enum ListType type) {
     Statement *tmp = makeStatement();
     tmp->type = base_list;
     tmp->u.base_list.type = type;
@@ -175,6 +183,10 @@ void freeStatement(Statement *st){
                 memFree(st->u.base_var.name);
                 freeStatement(st->u.base_var.times);
                 break;
+            case base_svar:
+                freeStatement(st->u.base_svar.name);
+                freeStatement(st->u.base_svar.times);
+                break;
             case set_function:
                 freeStatement(st->u.set_function.name);
                 freeStatement(st->u.set_function.function);

+ 2 - 4
src/value.c

@@ -138,10 +138,8 @@ void freeLinkValue(LinkValue *value, Inter *inter){
 
 void setResult(Result *ru, bool link, Inter *inter) {
     ru->type = not_return;
-    if (link){
-        // inter->base即None值
+    if (link)
         ru->value = makeLinkValue(inter->base, NULL, inter);
-    }
 }
 
 void setResultError(Result *ru, Inter *inter) {
@@ -157,7 +155,7 @@ void setResultOperation(Result *ru, Inter *inter) {
 void printValue(Value *value, FILE *debug){
     switch (value->type){
         case number:
-            writeLog(debug, INFO, "<%ld>", value->data.num.num);
+            writeLog(debug, INFO, "<%"NUMBER_FORMAT">", value->data.num.num);
             break;
         case string:
             writeLog(debug, INFO, "<'%s'>", value->data.str.str);