Pārlūkot izejas kodu

feat: 支持使用lambda匿名函数

SongZihuan 4 gadi atpakaļ
vecāks
revīzija
5f53686fff
9 mainītis faili ar 75 papildinājumiem un 5 dzēšanām
  1. 1 0
      include/run.h
  2. 6 0
      include/statement.h
  3. 2 1
      include/token.h
  4. 3 1
      main.c
  5. 26 2
      parser/grammar.c
  6. 1 0
      parser/syntax.c
  7. 3 0
      src/run.c
  8. 17 1
      src/runcall.c
  9. 16 0
      src/statement.c

+ 1 - 0
include/run.h

@@ -22,6 +22,7 @@ bool tryBranchSafeInterStatement(INTER_FUNCTIONSIG);
 ResultType operationStatement(INTER_FUNCTIONSIG);
 ResultType setClass(INTER_FUNCTIONSIG);
 ResultType setFunction(INTER_FUNCTIONSIG);
+ResultType setLambda(INTER_FUNCTIONSIG);
 ResultType callBack(INTER_FUNCTIONSIG);
 ResultType callClass(LinkValue *class_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST);
 ResultType callFunction(LinkValue *function_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST);

+ 6 - 0
include/statement.h

@@ -13,6 +13,7 @@ struct Statement{
         base_dict,
         base_var,
         base_svar,
+        base_lambda,
         operation,
         set_function,
         set_class,
@@ -59,6 +60,10 @@ struct Statement{
         struct {
             struct Parameter *dict;
         } base_dict;
+        struct {
+            struct Parameter *parameter;
+            struct Statement *function;
+        } base_lambda;
         struct operation{
             enum OperationType{
                 OPT_ADD = 1,
@@ -200,6 +205,7 @@ Statement *makeBaseDictStatement(Parameter *pt, long int line, char *file);
 Statement *makeTupleStatement(Parameter *pt, enum ListType type, long int line, char *file);
 Statement *makeClassStatement(Statement *name, Statement *function, Parameter *pt);
 Statement *makeFunctionStatement(Statement *name, Statement *function, struct Parameter *pt);
+Statement *makeLambdaStatement(Statement *function, Parameter *pt);
 Statement *makeCallStatement(Statement *function, struct Parameter *pt);
 Statement *makeIfStatement(long int line, char *file);
 Statement *makeWhileStatement(long int line, char *file);

+ 2 - 1
include/token.h

@@ -88,8 +88,9 @@
 #define MATHER_RAISE 74
 #define MATHER_FROM 75
 #define MATHER_ASSERT 76
+#define MATHER_LAMBDA 77
 
-#define MATHER_MAX 77
+#define MATHER_MAX 78
 
 // 从-6开始是为了避开status的特殊值,尽管这并没有什么影响
 #define COMMAND -6

+ 3 - 1
main.c

@@ -22,7 +22,9 @@ int main(int argc, char *argv[]) {
 
 /** TODO-szh List
  * 匿名函数
- * 字面量后缀
+ * f(x) = x * 2 表达式
+ * 合适形参检查
+ * 装饰器
  * 官方函数
  * 官方类
  * do 语句

+ 26 - 2
parser/grammar.c

@@ -319,8 +319,7 @@ void parserIf(PASERSSIGNATURE){
             }
 
             not_del:
-            if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp,
-                                    "Don't get a if condition"))
+            if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &condition_tmp, "Don't get a if condition"))
                 goto error_;
 
             if (!callParserAs(CALLPASERSSIGNATURE, &var_tmp, "Don't get a while var")) {
@@ -860,6 +859,12 @@ void parserPoint(PASERSSIGNATURE){
  * parserBaseValue:
  * | MATHER_NUMBER
  * | MATHER_STRING
+ * | MATHER_VAR
+ * | MATHER_LAMBDA parserParameter MATHER_COLON parserOperation
+ * | MATHER_LP parserOperation MATHER_LP
+ * | MATHER_LP parserOperation MATHER_LP -> list
+ * | MATHER_LP parserOperation MATHER_LP MATHER_VAR
+ * | MATHER_LC parserParameter(dict) MATHER_LC
  */
 int getOperation(PASERSSIGNATURE, int right_type, Statement **st, char *name){
     *st = NULL;
@@ -902,6 +907,25 @@ void parserBaseValue(PASERSSIGNATURE){
             st = makeCallStatement(sencod_var, makeValueParameter(tmp));
         }
     }
+    else if (MATHER_LAMBDA == value_token->token_type){
+        Parameter *pt = NULL;
+        Statement *lambda_st = NULL;
+        if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
+            freeToken(value_token, true, true);
+            syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a lambda parameter");
+            goto return_;
+        }
+        if (!checkToken(pm, MATHER_COLON)){
+            lambda_st = makeStatement(value_token->line, pm->file);
+            goto not_lambda_st;
+        }
+        if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &lambda_st, "Don't get a lambda operation")){
+            freeToken(value_token, true, true);
+            goto return_;
+        }
+        not_lambda_st:
+        st = makeLambdaStatement(lambda_st, pt);
+    }
     else if (MATHER_VAR == value_token->token_type)
         st = makeBaseVarStatement(value_token->data.str, NULL, value_token->line, pm->file);
     else if (MATHER_SVAR == value_token->token_type){

+ 1 - 0
parser/syntax.c

@@ -247,6 +247,7 @@ int getMatherStatus(LexFile *file, LexMathers *mathers) {
         strMatherMacro(MATHER_RAISE, "raise");
         strMatherMacro(MATHER_FROM, "from");
         strMatherMacro(MATHER_ASSERT, "assert");
+        strMatherMacro(MATHER_LAMBDA, "lambda");
 
         status = checkoutMather(mathers, MATHER_MAX);
     }

+ 3 - 0
src/run.c

@@ -26,6 +26,9 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
         case base_dict:
             type = getDict(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
             break;
+        case base_lambda:
+            type = setLambda(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
+            break;
         case operation:
             type = operationStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
             if (run_continue_type(type))

+ 17 - 1
src/runcall.c

@@ -44,13 +44,29 @@ ResultType setClass(INTER_FUNCTIONSIG) {
 
 ResultType setFunction(INTER_FUNCTIONSIG) {
     LinkValue *tmp = NULL;
+    Value *function_value = NULL;
+    VarList *function_var = NULL;
     setResultCore(result);
 
-    tmp = makeLinkValue(makeFunctionValue(st->u.set_function.function, st->u.set_function.parameter, copyVarList(var_list, false, inter), inter), father, inter);
+    function_var = copyVarList(var_list, false, inter);
+    function_value = makeFunctionValue(st->u.set_function.function, st->u.set_function.parameter, function_var, inter);
+    tmp = makeLinkValue(function_value, father, inter);
     assCore(st->u.set_function.name, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     if (run_continue(result))
         setResult(result, inter, father);
+    return result->type;
+}
+
+ResultType setLambda(INTER_FUNCTIONSIG) {
+    Value *function_value = NULL;
+    VarList *function_var = NULL;
+    setResultCore(result);
 
+    result->type = operation_return;
+    function_var = copyVarList(var_list, false, inter);
+    function_value = makeFunctionValue(st->u.base_lambda.function, st->u.base_lambda.parameter, function_var, inter);
+    result->value = makeLinkValue(function_value, father, inter);
+    gc_addTmpLink(&result->value->gc_status);
     return result->type;
 }
 

+ 16 - 0
src/statement.c

@@ -120,6 +120,14 @@ Statement *makeFunctionStatement(Statement *name, Statement *function, Parameter
     return tmp;
 }
 
+Statement *makeLambdaStatement(Statement *function, Parameter *pt) {
+    Statement *tmp = makeStatement(function->line, function->code_file);
+    tmp->type = base_lambda;
+    tmp->u.base_lambda.function = function;
+    tmp->u.base_lambda.parameter = pt;
+    return tmp;
+}
+
 Statement *makeCallStatement(Statement *function, Parameter *pt) {
     Statement *tmp = makeStatement(function->line, function->code_file);
     tmp->type = call_function;
@@ -271,6 +279,10 @@ void freeStatement(Statement *st){
                 freeStatement(st->u.base_svar.name);
                 freeStatement(st->u.base_svar.times);
                 break;
+            case base_lambda:
+                freeStatement(st->u.base_lambda.function);
+                freeParameter(st->u.base_lambda.parameter, true);
+                break;
             case set_function:
                 freeStatement(st->u.set_function.name);
                 freeStatement(st->u.set_function.function);
@@ -403,6 +415,10 @@ 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);
             break;
+        case base_lambda:
+            new->u.base_lambda.function = copyStatement(st->u.base_lambda.function);
+            new->u.base_lambda.parameter = copyParameter(st->u.base_lambda.parameter);
+            break;
         case set_function:
             new->u.set_function.name = copyStatement(st->u.set_function.name);
             new->u.set_function.function = copyStatement(st->u.set_function.function);