浏览代码

feat: 拓展了base_svar的用法

$(xx)若变量xx不存在,则直接返回值为xx
$:(xx)若变量xx不存在,则报错(原用法)
SongZihuan 4 年之前
父节点
当前提交
689c547af2

+ 2 - 1
VirtulMathCore/include/statement.h

@@ -64,6 +64,7 @@ struct Statement{
             struct Statement *name;
             struct Statement *times;
             bool run;
+            bool is_var;
         } base_svar;
         struct {
             enum ListType type;
@@ -296,7 +297,7 @@ Statement *makeBaseLinkValueStatement(LinkValue *value, fline line, char *file);
 Statement *makeBaseStrValueStatement(wchar_t *value, enum BaseValueType type, fline line, char *file);
 Statement *makeBaseValueStatement(enum BaseValueType type, fline line, char *file);
 Statement *makeBaseVarStatement(wchar_t *name, Statement *times, fline line, char *file);
-Statement *makeBaseSVarStatement(Statement *name, Statement *times);
+Statement *makeBaseSVarStatement(Statement *name, Statement *times, bool is_var);
 Statement *makeBaseDictStatement(Parameter *pt, fline line, char *file);
 Statement *makeTupleStatement(Parameter *pt, enum ListType type, fline line, char *file);
 Statement *makeClassStatement(Statement *name, Statement *function, Parameter *pt);

+ 2 - 1
VirtulMathCore/parser/grammar.c

@@ -1580,12 +1580,13 @@ void parserBaseValue(P_FUNC){
             break;
         case MATHER_SVAR: {
             Statement *svar_st = NULL;
+            bool is_var = checkToken(pm, MATHER_COLON);
             if (!callChildStatement(CP_FUNC, parserBaseValue, T_BASEVALUE, &svar_st, NULL)) {
                 syntaxError(pm, syntax_error, value_token->line, 1, "Don't get super var after $");
                 freeToken(value_token, true);
                 goto return_;
             }
-            st = makeBaseSVarStatement(svar_st, NULL);
+            st = makeBaseSVarStatement(svar_st, NULL, is_var);
             break;
         }
         case MATHER_LB: {

+ 2 - 3
VirtulMathCore/src/__run.c

@@ -115,11 +115,10 @@ wchar_t *getNameFromValue(Value *value, struct Inter *inter) {
         case V_dict: {
             POINTERHASHMACRO(value->data.dict.dict, dict);  // 因为有声明变量, 因此需要大括号
         }
-        case V_class:{
+        case V_class: {
             POINTERHASHMACRO(value, class);
         }
-        default:
-        obj: {
+        default: {
             POINTERHASHMACRO(value, obj);
         }
     }

+ 44 - 33
VirtulMathCore/src/runoperation.c

@@ -524,6 +524,45 @@ ResultType pointAss(Statement *name, LinkValue *value, FUNC_NT) {
     return result->type;
 }
 
+static ResultType setNameException(LinkValue *val, wchar_t *name, fline line, char *file, FUNC_NT) {
+    Result tmp;
+    LinkValue *_attr_;
+    wchar_t *message = memWidecat(L"Variable not found: ", name, false, false);
+    setResultCore(&tmp);
+    gc_addTmpLink(&val->gc_status);
+
+    setResultError(E_NameExceptiom, message, line, file, true, CNEXT_NT);
+    addAttributes(inter->data.mag_func[M_VAL], false, val, line, file, true, CFUNC_NT(var_list, &tmp, result->value));
+    if (!RUN_TYPE(tmp.type)) {
+        freeResult(result);
+        *result = tmp;
+        goto return_;
+    }
+
+    freeResult(&tmp);
+    _attr_ = findAttributes(inter->data.mag_func[M_ATTR], false, LINEFILE, true, CFUNC_NT(var_list, &tmp, belong));
+    if (!RUN_TYPE(tmp.type)) {
+        freeResult(result);
+        *result = tmp;
+        goto return_;
+    }
+
+    freeResult(&tmp);
+    if (_attr_ != NULL) {
+        Argument *arg = makeValueArgument(result->value);
+        freeResult(result);
+        gc_addTmpLink(&_attr_->gc_status);
+        callBackCore(_attr_, arg, line, file, 0, CFUNC_NT(var_list, result, belong));
+        gc_freeTmpLink(&_attr_->gc_status);
+        freeArgument(arg, true);
+    }
+
+    return_:
+    gc_freeTmpLink(&val->gc_status);
+    memFree(message);
+    return result->type;
+}
+
 ResultType getVar(FUNC, VarInfo var_info) {
     int int_times = 0;
     wchar_t *name = NULL;
@@ -541,40 +580,12 @@ ResultType getVar(FUNC, VarInfo var_info) {
     result->value = NULL;
     freeResult(result);
     var = findFromVarList(name, int_times, get_var, CFUNC_CORE(var_list));
-    if (var == NULL) {
-        wchar_t *message = memWidecat(L"Variable not found: ", name, false, false);
-        setResultErrorSt(E_NameExceptiom, message, true, st, CNEXT_NT);
-        {
-            Result tmp;
-            LinkValue *_attr_;
-            setResultCore(&tmp);
-            addAttributes(inter->data.mag_func[M_VAL], false, val, st->line, st->code_file, true, CFUNC_NT(var_list, &tmp, result->value));
-            if (!RUN_TYPE(tmp.type)) {
-                freeResult(result);
-                *result = tmp;
-                goto out;
-            }
 
-            freeResult(&tmp);
-            _attr_ = findAttributes(inter->data.mag_func[M_ATTR], false, LINEFILE, true, CFUNC_NT(var_list, &tmp, belong));
-            if (!RUN_TYPE(tmp.type)) {
-                freeResult(result);
-                *result = tmp;
-                goto out;
-            }
-            freeResult(&tmp);
-            if (_attr_ != NULL) {
-                Argument *arg = makeValueArgument(result->value);
-                freeResult(result);
-                gc_addTmpLink(&_attr_->gc_status);
-                callBackCore(_attr_, arg, st->line, st->code_file, 0, CFUNC_NT(var_list, result, belong));
-                gc_freeTmpLink(&_attr_->gc_status);
-                freeArgument(arg, true);
-            }
-
-        }
-        out:
-        memFree(message);
+    if (var == NULL) {
+        if (st->type == base_svar && !st->u.base_svar.is_var) {
+            setResultOperationBase(result, val);
+        } else
+            setNameException(val, name, st->line, st->code_file, CNEXT_NT);
     } else if (checkAut(st->aut, var->aut, st->line, st->code_file, NULL, true, CNEXT_NT)) {
         bool run = st->type == base_var ? st->u.base_var.run : st->type == base_svar ? st->u.base_svar.run : false;
         if (!run || !runVarFunc(var, st->line, st->code_file, CNEXT_NT))

+ 3 - 1
VirtulMathCore/src/statement.c

@@ -104,12 +104,13 @@ Statement *makeBaseVarStatement(wchar_t *name, Statement *times, fline line, cha
     return tmp;
 }
 
-Statement *makeBaseSVarStatement(Statement *name, Statement *times){
+Statement *makeBaseSVarStatement(Statement *name, Statement *times, bool is_var) {
     Statement *tmp = makeStatement(name->line, name->code_file);
     tmp->type = base_svar;
     tmp->u.base_svar.name = name;
     tmp->u.base_svar.times = times;
     tmp->u.base_svar.run = true;
+    tmp->u.base_svar.is_var = is_var;
     return tmp;
 }
 
@@ -553,6 +554,7 @@ Statement *copyStatementCore(Statement *st){
             new->u.base_svar.name = copyStatement(st->u.base_svar.name);
             new->u.base_svar.times = copyStatement(st->u.base_svar.times);
             new->u.base_svar.run = st->u.base_svar.run;
+            new->u.base_svar.is_var = st->u.base_svar.is_var;
             break;
         case base_lambda:
             new->u.base_lambda.function = copyStatement(st->u.base_lambda.function);