Browse Source

feat: 允许使用f(x) = x * 2的方式定义函数

加入了形参后置检查
应用于import语句和f(x)函数赋值式定义语句的左值
SongZihuan 4 years ago
parent
commit
c36f150417
10 changed files with 97 additions and 55 deletions
  1. 1 0
      include/parameter.h
  2. 1 1
      include/token.h
  3. 0 1
      main.c
  4. 14 12
      parser/__grammar.c
  5. 39 25
      parser/grammar.c
  6. 3 2
      parser/include/__grammar.h
  7. 3 4
      parser/token.c
  8. 15 0
      src/parameter.c
  9. 19 7
      src/runoperation.c
  10. 2 3
      src/statement.c

+ 1 - 0
include/parameter.h

@@ -76,4 +76,5 @@ ResultType argumentToParameter(Argument **call_ad, Parameter **function_ad, VarL
 
 FatherValue *setFatherCore(FatherValue *father_tmp);
 FatherValue *setFather(Argument *call, INTER_FUNCTIONSIG_NOT_ST);
+bool checkFormal(Parameter *pt);
 #endif //VIRTUALMATH_PARAMETER_H

+ 1 - 1
include/token.h

@@ -156,7 +156,7 @@ TokenMessage *makeTokenMessage(char *file_dir);
 void freeTokenMessage(TokenMessage *tm, bool self, bool free_st);
 
 Token *makeToken(long int line);
-long freeToken(Token *tk, bool self, bool free_st);
+long freeToken(Token *tk, bool free_st);
 Token *makeLexToken(int type, char *str, char *second_str, long int line);
 Token *makeStatementToken(int type, struct Statement *st);
 

+ 0 - 1
main.c

@@ -21,7 +21,6 @@ int main(int argc, char *argv[]) {
 
 
 /** TODO-szh List
- * 匿名函数
  * f(x) = x * 2 表达式
  * 合适形参检查
  * 装饰器

+ 14 - 12
parser/__grammar.c

@@ -13,7 +13,7 @@
  * @param self_name 输出值名称(log)
  * @param is_right 表达式是否从右运算到左
  */
-inline void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunction getSymbol,
+inline void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunction getSymbol, ChecktLeftToken checkleft,
                          int call_type, int self_type, char *call_name, char *self_name, bool is_right) {
     bool is_right_ = false;
     while(true){
@@ -23,7 +23,6 @@ inline void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunc
         long int line = 0;
 
         if (readBackToken(pm) != self_type){
-            
             if (!callChildStatement(CALLPASERSSIGNATURE, callBack, call_type, &st, NULL))
                 goto return_;
             addStatementToken(self_type, st, pm);
@@ -31,8 +30,11 @@ inline void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunc
         }
         left_token = popNewToken(pm->tm);
         line = left_token->line;
+        if (checkleft != NULL && !checkleft(CALLPASERSSIGNATURE, left_token->data.st)) {
+            freeToken(left_token, true);
+            goto return_;
+        }
 
-        
         if (getSymbol(CALLPASERSSIGNATURE, readBackToken(pm), &st))
             delToken(pm);
         else{
@@ -43,7 +45,7 @@ inline void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunc
         callBack(CALLPASERSSIGNATURE);  // 获得右值
         if (!call_success(pm) || readBackToken(pm) != call_type){  // 若非正确数值
             syntaxError(pm, syntax_error, line, 3, "ERROR from ", self_name, "(get right)");
-            freeToken(left_token, true, true);
+            freeToken(left_token, true);
             freeStatement(st);
             goto return_;
         }
@@ -87,12 +89,12 @@ inline void tailOperation(PASERSSIGNATURE, PasersFunction callBack, TailFunction
             goto return_;
         }
         else if(tail_status == 0) {
-            freeToken(left_token, true, true);
+            freeToken(left_token, true);
             goto return_;
         }
 
         addStatementToken(self_type, st, pm);
-        freeToken(left_token, true, false);
+        freeToken(left_token, false);
         
     }
     return_: return;
@@ -133,7 +135,7 @@ void syntaxError(ParserMessage *pm, int status, long int line, int num, ...) {
 int readBackToken(ParserMessage *pm){
     Token *tmp = popNewToken(pm->tm);
     if (tmp->token_type == -2){
-        freeToken(tmp, true, false);
+        freeToken(tmp, false);
         syntaxError(pm, lexical_error, tmp->line, 1, "lexical make some error");
     }
     addBackToken(pm->tm->ts, tmp);
@@ -156,7 +158,7 @@ bool commandCallControl_(PASERSSIGNATURE, MakeControlFunction callBack, int type
         return false;
     tmp_token = popNewToken(pm->tm);
     *st = tmp_token->data.st;
-    freeToken(tmp_token, true, false);
+    freeToken(tmp_token, false);
     return true;
 }
 
@@ -175,7 +177,7 @@ bool callParserCode(PASERSSIGNATURE, Statement **st, char *message, long int lin
     }
     tmp = popNewToken(pm->tm);
     *st = tmp->data.st;
-    freeToken(tmp, true, false);
+    freeToken(tmp, false);
     return true;
 }
 
@@ -211,7 +213,7 @@ bool callChildStatement(PASERSSIGNATURE, PasersFunction callBack, int type, Stat
     if (!status)
         return false;
     *st = tmp->data.st;
-    freeToken(tmp, true, false);
+    freeToken(tmp, false);
     return true;
 }
 
@@ -331,13 +333,13 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
             else
                 status = s_2;
         }
-        freeToken(tmp, true, false);
+        freeToken(tmp, false);
     }
     *pt = new_pt;
     return true;
 
     error_:
-    freeToken(tmp, true, true);
+    freeToken(tmp, true);
     freeParameter(new_pt, true);
     *pt = NULL;
     return false;

+ 39 - 25
parser/grammar.c

@@ -55,16 +55,16 @@ void parserCommandList(PASERSSIGNATURE, bool global, Statement *st) {
             else  if(stop != MATHER_EOF){
                 if (global) {
                     syntaxError(pm, command_list_error, command_token->line, 1, "ERROR from parserCommand list(get stop)");
-                    freeToken(command_token, true, true);
+                    freeToken(command_token, true);
                 }
                 else{
                     connectStatement(st, command_token->data.st);
-                    freeToken(command_token, true, false);
+                    freeToken(command_token, false);
                 }
                 goto return_;
             }
             connectStatement(st, command_token->data.st);
-            freeToken(command_token, true, false);
+            freeToken(command_token, false);
         }
     }
     return_: return;
@@ -203,17 +203,23 @@ void parserImport(PASERSSIGNATURE) {
         }
         if (checkToken(pm, MATHER_MUL))  // 导入所有
             goto mul_;
-        if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, true, true, MATHER_COMMA, MATHER_ASSIGNMENT) || pt == NULL) {
-            syntaxError(pm, syntax_error, line, 1, "Don't get any value for import");
+        if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT) || pt == NULL) {
+            syntaxError(pm, syntax_error, line, 1, "Don't get any value to import");
             freeStatement(opt);
             goto return_;
         }
-        if (checkToken(pm, MATHER_AS) && (!parserParameter(CALLPASERSSIGNATURE, &as, true, true, false, MATHER_COMMA, MATHER_ASSIGNMENT) || as == NULL)) {
+        if (checkToken(pm, MATHER_AS) && (!parserParameter(CALLPASERSSIGNATURE, &as, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT) || as == NULL)) {
             freeParameter(pt, true);
             syntaxError(pm, syntax_error, opt->line, 1, "Don't get any value after import");
             freeStatement(opt);
             goto return_;
         }
+        else if (checkFormal(pt)){
+            freeParameter(pt, true);
+            syntaxError(pm, syntax_error, opt->line, 1, "Don't get success value to import");
+            freeStatement(opt);
+            goto return_;
+        }
 
 
         mul_:
@@ -272,7 +278,7 @@ void parserControl(PASERSSIGNATURE, MakeControlFunction callBack, int type, bool
     }
     tmp = popNewToken(pm->tm);
     opt = tmp->data.st;
-    freeToken(tmp, true, false);
+    freeToken(tmp, false);
     st = callBack(opt, line, pm->file);
     addStatementToken(type, st, pm);
     return_:
@@ -693,6 +699,14 @@ void parserOperation(PASERSSIGNATURE){
  * | parserAssignment ASSIGNMENT parserTuple [2]
  * 注意:在链接statement的时候, 模式[2]相当于 parserTuple ASSIGNMENT parserAssignment
  */
+bool checkAssignmentLeft(PASERSSIGNATURE, Statement *left){
+    if (left->type == call_function && !checkFormal(left->u.call_function.parameter)){
+        syntaxError(pm, syntax_error, left->line, 1, "Don't get success function definition from Assignmen");
+        return false;
+    }
+    return true;
+}
+
 bool switchAssignment(PASERSSIGNATURE, int symbol, Statement **st){
     switch (symbol) {
         case MATHER_ASSIGNMENT:
@@ -704,7 +718,7 @@ bool switchAssignment(PASERSSIGNATURE, int symbol, Statement **st){
     return true;
 }
 void parserAssignment(PASERSSIGNATURE){
-    return twoOperation(CALLPASERSSIGNATURE, parserTuple, switchAssignment, TUPLE, ASSIGNMENT,
+    return twoOperation(CALLPASERSSIGNATURE, parserTuple, switchAssignment, checkAssignmentLeft, TUPLE, ASSIGNMENT,
                         "polynomial", "assignment", true);
 }
 
@@ -769,7 +783,7 @@ bool switchPolynomial(PASERSSIGNATURE, int symbol, Statement **st){
     return true;
 }
 void parserPolynomial(PASERSSIGNATURE){
-    return twoOperation(CALLPASERSSIGNATURE, parserFactor, switchPolynomial, FACTOR, POLYNOMIAL,
+    return twoOperation(CALLPASERSSIGNATURE, parserFactor, switchPolynomial, NULL, FACTOR, POLYNOMIAL,
                         "factor", "polynomial", false);
 }
 
@@ -794,7 +808,7 @@ bool switchFactor(PASERSSIGNATURE, int symbol, Statement **st){
     return true;
 }
 void parserFactor(PASERSSIGNATURE){
-    return twoOperation(CALLPASERSSIGNATURE, parserCallBack, switchFactor, CALLBACK, FACTOR,
+    return twoOperation(CALLPASERSSIGNATURE, parserCallBack, switchFactor, NULL, CALLBACK, FACTOR,
                         "call back", "factor", false);
 }
 
@@ -849,7 +863,7 @@ bool switchPoint(PASERSSIGNATURE, int symbol, Statement **st){
     return true;
 }
 void parserPoint(PASERSSIGNATURE){
-    return twoOperation(CALLPASERSSIGNATURE, parserBaseValue, switchPoint, BASEVALUE, POINT,
+    return twoOperation(CALLPASERSSIGNATURE, parserBaseValue, switchPoint, NULL, BASEVALUE, POINT,
                         "base value", "point", false);
 }
 
@@ -911,7 +925,7 @@ void parserBaseValue(PASERSSIGNATURE){
         Parameter *pt = NULL;
         Statement *lambda_st = NULL;
         if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a lambda parameter");
             goto return_;
         }
@@ -920,7 +934,7 @@ void parserBaseValue(PASERSSIGNATURE){
             goto not_lambda_st;
         }
         if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &lambda_st, "Don't get a lambda operation")){
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             goto return_;
         }
         not_lambda_st:
@@ -931,7 +945,7 @@ void parserBaseValue(PASERSSIGNATURE){
     else if (MATHER_SVAR == value_token->token_type){
         Statement *svar_st = NULL;
         if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &svar_st, NULL)){
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get super var after $");
             goto return_;
         }
@@ -942,12 +956,12 @@ void parserBaseValue(PASERSSIGNATURE){
         Statement *tmp_st = NULL;
         tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RB, &tmp_st, "base value");
         if (tmp == 0){
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get operation from Base Value");
             goto return_;
         }
         else if(tmp == -1){
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get ] from list/var");
             goto return_;
         }
@@ -955,7 +969,7 @@ void parserBaseValue(PASERSSIGNATURE){
             Token *var_token;
             var_token = popNewToken(pm->tm);
             st = makeBaseVarStatement(var_token->data.str, tmp_st, var_token->line, pm->file);
-            freeToken(var_token, true, false);
+            freeToken(var_token, false);
         }
         else{
             if (tmp_st == NULL)
@@ -971,12 +985,12 @@ void parserBaseValue(PASERSSIGNATURE){
     else if (MATHER_LP == value_token->token_type){
         int tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RP, &st, "base value");
         if (tmp == 0){
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get operation from Base Value");
             goto return_;
         }
         else if(tmp == -1){
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get ) from Base Value");
             goto return_;
         }
@@ -984,12 +998,12 @@ void parserBaseValue(PASERSSIGNATURE){
     else if (MATHER_LC == value_token->token_type){
         Parameter *pt = NULL;
         if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, true, MATHER_COMMA, MATHER_COLON)) {
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a dict parameter");
             goto return_;
         }
         if (!checkToken(pm, MATHER_RC)) {
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             freeParameter(pt, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a } after dict");
             goto return_;
@@ -1000,7 +1014,7 @@ void parserBaseValue(PASERSSIGNATURE){
         Statement *block = NULL;
         if (!callParserCode(CALLPASERSSIGNATURE, &block, "Don't get a while code", value_token->line)) {
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get block command");
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             goto return_;
         }
         st = makeOperationStatement(OPT_BLOCK, block, NULL);
@@ -1008,12 +1022,12 @@ void parserBaseValue(PASERSSIGNATURE){
     else if (MATHER_PROTECT == value_token->token_type || MATHER_PRIVATE == value_token->token_type || MATHER_PUBLIC == value_token->token_type){
         if (MATHER_COLON != readBackToken(pm)){
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a : after aut token");
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             goto return_;
         }
         delToken(pm);
         if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &st, "Don't get Base Value after aut token")){
-            freeToken(value_token, true, true);
+            freeToken(value_token, true);
             goto return_;
         }
         switch (value_token->token_type) {
@@ -1032,7 +1046,7 @@ void parserBaseValue(PASERSSIGNATURE){
         backToken_(pm, value_token);
         goto return_;
     }
-    freeToken(value_token, true, false);
+    freeToken(value_token, false);
     addStatementToken(BASEVALUE, st, pm);
 
     return_:

+ 3 - 2
parser/include/__grammar.h

@@ -6,7 +6,7 @@
 #define CALLPASERSSIGNATURE pm, inter /*pasers函数调用的统一实参*/
 
 #define addStatementToken(type, st, pm) addBackToken(pm->tm->ts, makeStatementToken(type, st))
-#define delToken(pm) (freeToken(popNewToken(pm->tm), true, false))
+#define delToken(pm) (freeToken(popNewToken(pm->tm), false))
 #define backToken_(pm, token) addBackToken(pm->tm->ts, (token))
 #define addLexToken(pm, type) backToken_(pm, makeLexToken(type, NULL, NULL, 0))
 #define addToken_ backToken_
@@ -14,6 +14,7 @@
 
 typedef void (*PasersFunction)(PASERSSIGNATURE);
 typedef int (*GetSymbolFunction)(PASERSSIGNATURE, int, Statement **);
+typedef int (*ChecktLeftToken)(PASERSSIGNATURE, Statement *);
 typedef Statement *(*MakeControlFunction)(Statement *, long int, char *);
 typedef int (*TailFunction)(PASERSSIGNATURE, Token *, Statement **);
 
@@ -52,7 +53,7 @@ bool callChildToken(PASERSSIGNATURE, PasersFunction callBack, int type, Token **
 bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_list, bool is_dict,
                      int sep,int ass);
 
-void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunction getSymbol,
+void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunction getSymbol, ChecktLeftToken checkleft,
                   int call_type, int self_type, char *call_name, char *self_name, bool is_right);
 void tailOperation(PASERSSIGNATURE, PasersFunction callBack, TailFunction tailFunction, int call_type, int self_type,
                    char *call_name, char *self_name);

+ 3 - 4
parser/token.c

@@ -26,7 +26,7 @@ Token *makeStatementToken(int type, struct Statement *st){
     return tmp;
 }
 
-long freeToken(Token *tk, bool self, bool free_st) {
+long freeToken(Token *tk, bool free_st) {
     long int line = 0;
     freeBase(tk, return_);
     line = tk->line;
@@ -34,8 +34,7 @@ long freeToken(Token *tk, bool self, bool free_st) {
     memFree(tk->data.second_str);
     if (free_st)
         freeStatement(tk->data.st);
-    if (self)
-        memFree(tk);
+    memFree(tk);
     return_:
     return line;
 }
@@ -51,7 +50,7 @@ void freeToekStream(TokenStream *ts, bool free_st) {
     freeBase(ts, return_);
     for (Token *tmp = ts->token_list, *tmp_next=NULL; tmp != NULL; tmp = tmp_next){
         tmp_next = tmp->next;
-        freeToken(tmp, true, free_st);
+        freeToken(tmp, free_st);
     }
     memFree(ts);
     return_:

+ 15 - 0
src/parameter.c

@@ -591,3 +591,18 @@ FatherValue *setFatherCore(FatherValue *father_tmp) {
     }
     return base_father;
 }
+
+
+bool checkFormal(Parameter *pt) {
+    enum {
+        Formal_1,
+        Formal_2,
+    } status = Formal_1;
+    for (PASS; pt != NULL; pt = pt->next){
+        if (status == Formal_1 && (pt->type == name_par || pt->type == args_par))
+                status = Formal_2;
+        else if (status == Formal_2 && (pt->type == value_par || pt->type == args_par) || pt->type == kwargs_par && pt->next != NULL)
+            return false;
+    }
+    return true;
+}

+ 19 - 7
src/runoperation.c

@@ -207,17 +207,27 @@ ResultType pointOperation(INTER_FUNCTIONSIG) {
 
 ResultType assOperation(INTER_FUNCTIONSIG) {
     LinkValue *value = NULL;
-    if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, var_list, result, father)))
-        return result->type;
-    value = result->value;
+    if (st->u.operation.left->type == call_function){
+        VarList *function_var = NULL;
+        Value *function_value = NULL;
+        LinkValue *tmp = NULL;
+        function_var = copyVarList(var_list, false, inter);
+        function_value = makeFunctionValue(st->u.operation.right, st->u.operation.left->u.call_function.parameter, function_var, inter);
+        tmp = makeLinkValue(function_value, father, inter);
+        assCore(st->u.operation.left->u.call_function.function, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    }
+    else{
+        if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, var_list, result, father)))
+            return result->type;
+        value = result->value;
 
-    freeResult(result);
-    assCore(st->u.operation.left, value, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
+        freeResult(result);
+        assCore(st->u.operation.left, value, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
+    }
     return result->type;
 }
 
 ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
-    int int_times;
     setResultCore(result);
     gc_addTmpLink(&value->gc_status);
 
@@ -249,6 +259,7 @@ ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
         pointAss(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
     else{
         char *str_name = NULL;
+        int int_times = 0;
         getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list, result, father));
         if (!run_continue(result)) {
             memFree(str_name);
@@ -273,12 +284,13 @@ ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
 
 ResultType pointAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST) {
     Result left;
+    VarList *object = NULL;
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(name->u.operation.left, var_list, result, father)))
         return result->type;
     left = *result;
     setResultCore(result);
 
-    VarList *object = left.value->value->object.var;
+    object = left.value->value->object.var;
     gc_freeze(inter, var_list, object, true);
     if (name->u.operation.right->type == OPERATION && name->u.operation.right->u.operation.OperationType == OPT_POINT)
         pointAss(name->u.operation.right, value, CALL_INTER_FUNCTIONSIG_NOT_ST(object, result, father));

+ 2 - 3
src/statement.c

@@ -15,7 +15,6 @@ Token *setOperationFromToken(Statement **st_ad, struct Token *left, struct Token
     Statement *st = *st_ad, *left_st = left->data.st;
     if (is_right && left->data.st->type == operation &&
         left_st->u.operation.OperationType == st->u.operation.OperationType){
-
         st->u.operation.left = left_st->u.operation.right;
         left_st->u.operation.right = st;
         st->u.operation.right = right->data.st;
@@ -30,8 +29,8 @@ Token *setOperationFromToken(Statement **st_ad, struct Token *left, struct Token
     new_token->data.st = st;
     st->line = left->line;
 
-    freeToken(left, true, false);
-    freeToken(right, true, false);
+    freeToken(left, false);
+    freeToken(right, false);
     *st_ad = st;
     return new_token;
 }