Selaa lähdekoodia

feat: 新增逻辑, 比较等运算符

可以解析并执行指定函数
还未设置对应类的函数实现

link #1
SongZihuan 4 vuotta sitten
vanhempi
sitoutus
76b0c12702

+ 22 - 2
VirtulMathCore/include/inter.h

@@ -6,7 +6,7 @@ struct Result;
 #define BASEOBJSZIE (17)
 #define VARNAMESIZE (8)
 #define BASEEXCESIZE (19)
-#define MAGFUNCSIZE (27)
+#define MAGFUNCSIZE (45)
 
 #define B_OBJECT (0)
 #define B_VOBJECT (1)
@@ -63,7 +63,27 @@ struct Result;
 #define M_ATTR (25)
 #define M_VAL (26)
 
-// TODO-szh 添加val
+#define M_INTDIV (27)
+#define M_MOD (28)
+#define M_POW (29)
+
+#define M_BAND (30)
+#define M_BOR (31)
+#define M_BXOR (32)
+#define M_BNOT (33)
+#define M_BL (34)
+#define M_BR (35)
+
+#define M_EQ (36)
+#define M_MOREEQ (37)
+#define M_LESSEQ (38)
+#define M_MORE (39)
+#define M_LESS (40)
+#define M_NOTEQ (41)
+
+#define M_AND (42)
+#define M_OR (43)
+#define M_NOT (44)
 
 struct Inter{
     struct Value *base;

+ 24 - 3
VirtulMathCore/include/statement.h

@@ -83,9 +83,30 @@ struct Statement{
                 OPT_MUL = 3,
                 OPT_DIV = 4,
                 OPT_ASS = 5,
-                OPT_POINT = 6,
-                OPT_BLOCK = 7,
-                OPT_LINK = 8,
+                OPT_POINT = 6,  // 成员运算
+                OPT_BLOCK = 7,  // 代码块
+                OPT_LINK = 8,  // 获取外部成员 TODO-szh 该名为OUTPOINT
+                OPT_INTDIV = 9,
+                OPT_MOD = 10,
+                OPT_POW = 11,
+
+                OPT_BAND = 12,
+                OPT_BOR = 13,
+                OPT_BXOR = 14,
+                OPT_BNOT = 15,
+                OPT_BL = 16,
+                OPT_BR = 17,
+
+                OPT_EQ = 18,
+                OPT_MOREEQ = 19,
+                OPT_LESSEQ = 20,
+                OPT_MORE = 21,
+                OPT_LESS = 22,
+                OPT_NOTEQ = 23,
+
+                OPT_AND = 24,
+                OPT_OR = 25,
+                OPT_NOT = 26,
             } OperationType;
             struct Statement *left;
             struct Statement *right;

+ 12 - 0
VirtulMathCore/include/token.h

@@ -129,6 +129,18 @@
 #define T_DECORATION (-34)
 #define T_FOR_BRANCH (-35)
 #define T_DEL (-36)
+#define T_POW (-37)
+#define T_BITMOVE (-38)
+#define T_COMPARE (-39)
+#define T_COMPARE2 (-40)
+
+#define T_BAND (-41)
+#define T_BOR (-42)
+#define T_BXOR (-43)
+#define T_AND (-44)
+#define T_OR (-45)
+
+#define T_NOT (-46)
 
 struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配

+ 2 - 0
VirtulMathCore/ofunc/src/vobject.c

@@ -30,6 +30,8 @@ void vobject_sub_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         makeDouValue(left->data.dou.num - right->data.int_.num, LINEFILE, CNEXT_NT);
     else if (left->type == V_dou && right->type == V_dou)
         makeDouValue(left->data.dou.num - right->data.dou.num, LINEFILE, CNEXT_NT);
+    else if (left->type == V_pointer && right->type == V_pointer)
+        makeIntValue((char *)left->data.pointer.pointer - (char *)right->data.pointer.pointer, LINEFILE, CNEXT_NT);
     else
         setResultError(E_TypeException, CUL_ERROR(Sub), LINEFILE, true, CNEXT_NT);
 }

+ 4 - 5
VirtulMathCore/parser/__grammar.c

@@ -142,8 +142,7 @@ bool callParserAs(P_FUNC, Statement **st, char *message){
     return true;
 }
 
-bool callChildToken(P_FUNC, PasersFunction callBack, int type, Token **tmp, char *message,
-                    int error_type) {
+bool callChildToken(P_FUNC, PasersFunction callBack, int type, Token **tmp, char *message, int error_type) {
     *tmp = NULL;
     callBack(CP_FUNC);
     if (!call_success(pm) || readBackToken(pm) != type) {
@@ -226,10 +225,10 @@ bool parserParameter(P_FUNC, Parameter **pt, bool enter, bool is_formal, bool is
         else if (!is_list && checkToken(pm, MATHER_POW))  // is_formal关闭对*args的支持
             status = s_4;
 
-        parserPolynomial(CP_FUNC);
+        parserOr(CP_FUNC);
         if (!call_success(pm))
             goto error_;
-        if (readBackToken(pm) != T_POLYNOMIAL) {
+        if (readBackToken(pm) != T_OR) {
             if (status == s_3) {
                 long int line = pm->tm->ts->token_list->line;
                 syntaxError(pm, syntax_error, line, 1, "Don't get a parameter after *");
@@ -271,7 +270,7 @@ bool parserParameter(P_FUNC, Parameter **pt, bool enter, bool is_formal, bool is
             new_pt = connectValueParameter(tmp->data.st, new_pt, is_sep == 1);
         else if (pt_type == name_par){
             Statement *tmp_value;
-            if (!callChildStatement(CP_FUNC, parserPolynomial, T_POLYNOMIAL, &tmp_value, "Don't get a parameter value"))
+            if (!callChildStatement(CP_FUNC, parserOr, T_OR, &tmp_value, "Don't get a parameter value"))
                 goto error_;
             new_pt = connectNameParameter(tmp_value, tmp->data.st, new_pt);
             if (!checkToken(pm, sep))

+ 156 - 4
VirtulMathCore/parser/grammar.c

@@ -1136,7 +1136,7 @@ void parserTuple(P_FUNC){
         goto parserPt;
     }
 
-    if (!callChildToken(CP_FUNC, parserPolynomial, T_POLYNOMIAL, &tmp, NULL, syntax_error))
+    if (!callChildToken(CP_FUNC, parserOr, T_OR, &tmp, NULL, syntax_error))
         goto return_;
     if (readBackToken(pm) != MATHER_COMMA){
         tmp->token_type = T_TUPLE;
@@ -1158,6 +1158,118 @@ void parserTuple(P_FUNC){
     return;
 }
 
+bool switchOr(P_FUNC, int symbol, Statement **st){
+    if (symbol != MATHER_BOOLOR)
+        return false;
+    *st = makeOperationBaseStatement(OPT_OR, 0, pm->file);
+    return true;
+}
+
+void parserOr(P_FUNC){
+    return twoOperation(CP_FUNC, parserAnd, switchOr, NULL, T_AND, T_OR, "and", "or", false);
+}
+
+bool switchAnd(P_FUNC, int symbol, Statement **st){
+    if (symbol != MATHER_BOOLAND)
+        return false;
+    *st = makeOperationBaseStatement(OPT_AND, 0, pm->file);
+    return true;
+}
+
+void parserAnd(P_FUNC){
+    return twoOperation(CP_FUNC, parserBxor, switchAnd, NULL, T_BXOR, T_AND, "bit xor", "and", false);
+}
+
+bool switchBxor(P_FUNC, int symbol, Statement **st){
+    if (symbol != MATHER_BITXOR)
+        return false;
+    *st = makeOperationBaseStatement(OPT_BXOR, 0, pm->file);
+    return true;
+}
+
+void parserBxor(P_FUNC){
+    return twoOperation(CP_FUNC, parserBor, switchBxor, NULL, T_BOR, T_BXOR, "bit or", "bit xor", false);
+}
+
+bool switchBor(P_FUNC, int symbol, Statement **st){
+    if (symbol != MATHER_BITOR)
+        return false;
+    *st = makeOperationBaseStatement(OPT_BOR, 0, pm->file);
+    return true;
+}
+
+void parserBor(P_FUNC){
+    return twoOperation(CP_FUNC, parserBand, switchBor, NULL, T_BAND, T_BOR, "bit and", "bit or", false);
+}
+
+bool switchBand(P_FUNC, int symbol, Statement **st){
+    if (symbol != MATHER_BITAND)
+        return false;
+    *st = makeOperationBaseStatement(OPT_BAND, 0, pm->file);
+    return true;
+}
+
+void parserBand(P_FUNC){
+    return twoOperation(CP_FUNC, parserCompare2, switchBand, NULL, T_COMPARE2, T_BAND, "compare2", "bit and", false);
+}
+
+bool switchCompare2(P_FUNC, int symbol, Statement **st){
+    switch (symbol) {
+        case MATHER_EQ:
+            *st = makeOperationBaseStatement(OPT_EQ, 0, pm->file);
+            break;
+        case MATHER_NOTEQ:
+            *st = makeOperationBaseStatement(OPT_NOTEQ, 0, pm->file);
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+void parserCompare2(P_FUNC) {
+    return twoOperation(CP_FUNC, parserCompare, switchCompare2, NULL, T_COMPARE, T_COMPARE2, "compare", "compare2", false);
+}
+
+bool switchCompare(P_FUNC, int symbol, Statement **st){
+    switch (symbol) {
+        case MATHER_MORE:
+            *st = makeOperationBaseStatement(OPT_MORE, 0, pm->file);
+            break;
+        case MATHER_MOREEQ:
+            *st = makeOperationBaseStatement(OPT_MOREEQ, 0, pm->file);
+            break;
+        case MATHER_LESS:
+            *st = makeOperationBaseStatement(OPT_LESS, 0, pm->file);
+            break;
+        case MATHER_LESSEQ:
+            *st = makeOperationBaseStatement(OPT_LESSEQ, 0, pm->file);
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+void parserCompare(P_FUNC) {
+    return twoOperation(CP_FUNC, parserBitMove, switchCompare, NULL, T_BITMOVE, T_COMPARE, "bit move", "compare", false);
+}
+
+bool switchBitMove(P_FUNC, int symbol, Statement **st){
+    switch (symbol) {
+        case MATHER_BITLEFT:
+            *st = makeOperationBaseStatement(OPT_BL, 0, pm->file);
+            break;
+        case MATHER_BITRIGHT:
+            *st = makeOperationBaseStatement(OPT_BR, 0, pm->file);
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+void parserBitMove(P_FUNC) {
+    return twoOperation(CP_FUNC, parserPolynomial, switchBitMove, NULL, T_POLYNOMIAL, T_BITMOVE, "polynomial", "bit move", false);
+}
+
 /**
  * 多项式匹配
  * parserPolynomial:
@@ -1198,14 +1310,54 @@ bool switchFactor(P_FUNC, int symbol, Statement **st){
         case MATHER_DIV:
             *st = makeOperationBaseStatement(OPT_DIV, 0, pm->file);
             break;
+        case MATHER_INTDIV:
+            *st = makeOperationBaseStatement(OPT_INTDIV, 0, pm->file);
+            break;
+        case MATHER_PER:
+            *st = makeOperationBaseStatement(OPT_MOD, 0, pm->file);
+            break;
         default:
             return false;
     }
     return true;
 }
 void parserFactor(P_FUNC){
-    return twoOperation(CP_FUNC, parserCallBack, switchFactor, NULL, T_CALLFUNC, T_FACTOR,
-                        "call back", "factor", false);
+    return twoOperation(CP_FUNC, parserPow, switchFactor, NULL, T_POW, T_FACTOR, "pow", "factor", false);
+}
+
+bool switchPow(P_FUNC, int symbol, Statement **st){
+    if (symbol != MATHER_POW)
+        return false;
+    *st = makeOperationBaseStatement(OPT_POW, 0, pm->file);
+    return true;
+}
+
+void parserPow(P_FUNC){
+    return twoOperation(CP_FUNC, parserNot, switchPow, NULL, T_NOT, T_POW, "not", "pow", false);
+}
+
+void parserNot(P_FUNC){
+    struct Statement *st = NULL, **pst = &st;
+    while(true){
+        Token *left_token = popNewToken(pm->tm);
+        if (left_token->token_type == MATHER_BOOLNOT)
+            *pst = makeOperationBaseStatement(OPT_NOT, left_token->line, pm->file);
+        else if (left_token->token_type == MATHER_BITNOT)
+            *pst = makeOperationBaseStatement(OPT_BNOT, left_token->line, pm->file);
+        else {
+            backToken_(pm, left_token);
+            if (callChildStatement(CP_FUNC, parserCallBack, T_CALLFUNC, pst, NULL))
+                break;
+            else {
+                freeStatement(st);
+                return;
+            }
+        }
+        pst = &(*pst)->u.operation.left;
+        freeToken(left_token, true);
+    }
+    addStatementToken(T_NOT, st, pm);
+    return;
 }
 
 /**
@@ -1241,7 +1393,7 @@ bool tailSlice(P_FUNC, Token *left_token, Statement **st){
     enum SliceType type;  // 0-slice  1-down
     long int line = delToken(pm);
 
-    if (!callChildToken(CP_FUNC, parserPolynomial, T_POLYNOMIAL, &tmp, "Don't get slice/down element", syntax_error))
+    if (!callChildToken(CP_FUNC, parserOr, T_OR, &tmp, "Don't get slice/down element", syntax_error))
         return false;
     else if (readBackToken(pm) == MATHER_COLON)
         type = SliceType_slice_;

+ 11 - 0
VirtulMathCore/parser/include/__grammar.h

@@ -32,6 +32,17 @@ void parserPolynomial(P_FUNC);
 void parserBaseValue(P_FUNC);
 void parserCallBack(P_FUNC);
 void parserFactor(P_FUNC);
+void parserPow(P_FUNC);
+void parserNot(P_FUNC);
+void parserBitMove(P_FUNC);
+void parserCompare(P_FUNC);
+void parserCompare2(P_FUNC);
+void parserBand(P_FUNC);
+void parserBor(P_FUNC);
+void parserBxor(P_FUNC);
+void parserAnd(P_FUNC);
+void parserOr(P_FUNC);
+
 void parserAssignment(P_FUNC);
 void parserTuple(P_FUNC);
 void parserImport(P_FUNC);

+ 2 - 0
VirtulMathCore/src/include/__run.h

@@ -34,4 +34,6 @@ int run_init(LinkValue *obj, Argument *arg, fline line, char *file, FUNC_NT);
 bool setBoolAttrible(bool value, wchar_t *var, fline line, char *file, LinkValue *obj, FUNC_NT);
 bool runVarFunc(LinkValue *var, fline line, char *file, FUNC_NT);
 bool setVarFunc(LinkValue *var, LinkValue *new, fline line, char *file, FUNC_NT);
+
+ResultType runOperationFromValue(LinkValue *self, LinkValue *arg, wchar_t *name, fline line, char *file, FUNC_NT);
 #endif //VIRTUALMATH___RUN_H

+ 23 - 0
VirtulMathCore/src/inter.c

@@ -90,11 +90,34 @@ void setBaseInterData(struct Inter *inter){
     inter->data.mag_func[M_ATTR] = setName("__attr__");
     inter->data.mag_func[M_VAL] = setName("__val__");
 
+    inter->data.mag_func[M_INTDIV] = setName("__intdiv__");
+    inter->data.mag_func[M_MOD] = setName("__mod__");
+    inter->data.mag_func[M_POW] = setName("__pow__");
+
+    inter->data.mag_func[M_BAND] = setName("__bitand__");
+    inter->data.mag_func[M_BOR] = setName("__bitor__");
+    inter->data.mag_func[M_BXOR] = setName("__bitxor__");
+    inter->data.mag_func[M_BNOT] = setName("__bitnot__");
+    inter->data.mag_func[M_BL] = setName("__bitleft__");
+    inter->data.mag_func[M_BR] = setName("__bitright__");
+
+    inter->data.mag_func[M_EQ] = setName("__eq__");
+    inter->data.mag_func[M_MOREEQ] = setName("__moreeq__");
+    inter->data.mag_func[M_LESSEQ] = setName("__lesseq__");
+    inter->data.mag_func[M_MORE] = setName("__more__");
+    inter->data.mag_func[M_LESS] = setName("__less__");
+    inter->data.mag_func[M_NOTEQ] = setName("__noteq__");
+
+    inter->data.mag_func[M_AND] = setName("__and__");
+    inter->data.mag_func[M_OR] = setName("__or__");
+    inter->data.mag_func[M_NOT] = setName("__not__");
+
     inter->data.default_pt_type = free_;
 }
 
 void freeBaseInterData(struct Inter *inter){
     gc_freeStatementLink(&inter->base_belong->gc_status);
+
     for (int i=0; i < BASEOBJSZIE; i ++)
         gc_freeStatementLink(&inter->data.base_obj[i]->gc_status);
 

+ 74 - 23
VirtulMathCore/src/runoperation.c

@@ -2,6 +2,7 @@
 
 static bool getLeftRightValue(Result *left, Result *right, FUNC);
 static ResultType operationCore(FUNC, wchar_t *name);
+ResultType operationCore2(FUNC, wchar_t *name);
 ResultType assOperation(FUNC);
 ResultType pointOperation(FUNC);
 ResultType blockOperation(FUNC);
@@ -13,21 +14,39 @@ ResultType blockOperation(FUNC);
  * @param var_list
  * @return
  */
+
+#define OPT_CASE(TYPE) case OPT_##TYPE: operationCore(CNEXT, inter->data.mag_func[M_##TYPE]); break
+#define OPT_CASE2(TYPE) case OPT_##TYPE: operationCore2(CNEXT, inter->data.mag_func[M_##TYPE]); break
 ResultType operationStatement(FUNC) {
     setResultCore(result);
     switch (st->u.operation.OperationType) {
-        case OPT_ADD:
-            operationCore(CNEXT, inter->data.mag_func[M_ADD]);
-            break;
-        case OPT_SUB:
-            operationCore(CNEXT, inter->data.mag_func[M_SUB]);
-            break;
-        case OPT_MUL:
-            operationCore(CNEXT, inter->data.mag_func[M_MUL]);
-            break;
-        case OPT_DIV:
-            operationCore(CNEXT, inter->data.mag_func[M_DIV]);
-            break;
+        OPT_CASE(ADD);
+        OPT_CASE(SUB);
+        OPT_CASE(MUL);
+        OPT_CASE(DIV);
+        OPT_CASE(INTDIV);
+        OPT_CASE(MOD);
+        OPT_CASE(POW);
+
+
+        OPT_CASE(BAND);
+        OPT_CASE(BOR);
+        OPT_CASE(BXOR);
+        OPT_CASE2(BNOT);
+        OPT_CASE(BL);
+        OPT_CASE(BR);
+
+        OPT_CASE(EQ);
+        OPT_CASE(MOREEQ);
+        OPT_CASE(LESSEQ);
+        OPT_CASE(MORE);
+        OPT_CASE(LESS);
+        OPT_CASE(NOTEQ);
+
+        OPT_CASE(AND);
+        OPT_CASE(OR);
+        OPT_CASE2(NOT);
+
         case OPT_ASS:
             assOperation(CNEXT);
             break;
@@ -44,6 +63,7 @@ ResultType operationStatement(FUNC) {
     }
     return result->type;
 }
+#undef OPT_CASE
 
 static void updateBlockYield(Statement *block_st, Statement *node){
     block_st->info.node = node->type == yield_code ? node->next : node;
@@ -609,12 +629,12 @@ ResultType setDefault(FUNC){
 }
 
 bool getLeftRightValue(Result *left, Result *right, FUNC){
-    if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)) || result->value->value->type == V_none)
+    if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)))
         return true;
     *left = *result;
     setResultCore(result);
 
-    if (operationSafeInterStatement(CFUNC(st->u.operation.right, var_list, result, belong)) || result->value->value->type == V_none)
+    if (operationSafeInterStatement(CFUNC(st->u.operation.right, var_list, result, belong)))
         return true;
     *right = *result;
     setResultCore(result);
@@ -624,33 +644,64 @@ bool getLeftRightValue(Result *left, Result *right, FUNC){
 ResultType operationCore(FUNC, wchar_t *name) {
     Result left;
     Result right;
-    LinkValue *_func_ = NULL;
     setResultCore(&left);
     setResultCore(&right);
+    setResultCore(result);
 
     if (getLeftRightValue(&left, &right, CNEXT))  // 不需要释放result
         return result->type;
 
-    _func_ = findAttributes(name, false, LINEFILE, true, CFUNC_NT(var_list, result, left.value));
+    runOperationFromValue(left.value, right.value, name, st->line, st->code_file, CNEXT_NT);
+
+
+    freeResult(&left);
+    freeResult(&right);
+    return result->type;
+}
+
+ResultType operationCore2(FUNC, wchar_t *name) {
+    LinkValue *left;
+    setResultCore(result);
+
+    if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)))
+        return result->type;
+    left = result->value;
+    result->value = NULL;  // 不使用freeResult, 不需要多余的把result.value设置为none
+
+    runOperationFromValue(left, NULL, name, st->line, st->code_file, CNEXT_NT);
+    gc_freeTmpLink(&left->gc_status);
+    return result->type;
+}
+
+ResultType runOperationFromValue(LinkValue *self, LinkValue *arg, wchar_t *name, fline line, char *file, FUNC_NT) {
+    LinkValue *_func_;
+    gc_addTmpLink(&self->gc_status);
+    if (arg != NULL)
+        gc_addTmpLink(&arg->gc_status);
+    setResultCore(result);
+
+    _func_ = findAttributes(name, false, LINEFILE, true, CFUNC_NT(var_list, result, self));
     if (!CHECK_RESULT(result))
         goto return_;
     freeResult(result);
 
     if (_func_ != NULL){
-        Argument *arg = makeValueArgument(right.value);
+        Argument *f_arg = NULL;
+        if (arg != NULL)
+            f_arg = makeValueArgument(arg);
         gc_addTmpLink(&_func_->gc_status);
-        callBackCore(_func_, arg, st->line, st->code_file, 0, CNEXT_NT);
+        callBackCore(_func_, f_arg, line, file, 0, CNEXT_NT);
         gc_freeTmpLink(&_func_->gc_status);
-        freeArgument(arg, true);
+        freeArgument(f_arg, true);
     }
     else {
         wchar_t *message = memWidecat(L"Object not support ", name, false, false);
-        setResultErrorSt(E_TypeException, message, true, st, CNEXT_NT);
+        setResultError(E_TypeException, message, line, file, true, CNEXT_NT);
         memFree(message);
     }
-
     return_:
-    freeResult(&left);
-    freeResult(&right);
+    gc_freeTmpLink(&self->gc_status);
+    if (arg != NULL)
+        gc_freeTmpLink(&arg->gc_status);
     return result->type;
 }