Explorar el Código

impl lambda

Update compiler.h
blueloveTH hace 3 años
padre
commit
56c2ef36db
Se han modificado 1 ficheros con 45 adiciones y 30 borrados
  1. 45 30
      src/compiler.h

+ 45 - 30
src/compiler.h

@@ -337,7 +337,18 @@ public:
     }
 
     void exprLambda() {
-        throw SyntaxError(path, parser->previous, "lambda is not implemented yet");
+        _Func func;
+        func.name = "<lambda>";
+        __compileFunctionArgs(func);
+        consume(TK(":"));
+        func.code = std::make_shared<CodeObject>();
+        func.code->co_name = func.name;
+        func.code->co_filename = path;
+        this->codes.push(func.code);
+        EXPR_TUPLE();
+        emitCode(OP_RETURN_VALUE);
+        this->codes.pop();
+        emitCode(OP_LOAD_CONST, getCode()->addConst(vm->PyFunction(func)));
     }
 
     void exprAssign() {
@@ -771,6 +782,38 @@ __LISTCOMP:
         emitCode(OP_BUILD_CLASS, clsNameIdx);
     }
 
+    void __compileFunctionArgs(_Func& func){
+        int state = 0;      // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
+        do {
+            if(state == 3){
+                throw SyntaxError(path, parser->previous, "**kwargs should be the last argument");
+            }
+
+            matchNewLines();
+            if(match(TK("*"))){
+                if(state < 1) state = 1;
+                else throw SyntaxError(path, parser->previous, "*args should be placed before **kwargs");
+            }
+            else if(match(TK("**"))){
+                state = 3;
+            }
+
+            consume(TK("@id"));
+            const _Str& name = parser->previous.str();
+            if(func.hasName(name)) throw SyntaxError(path, parser->previous, "duplicate argument name");
+
+            if(state == 0 && peek() == TK("=")) state = 2;
+
+            switch (state)
+            {
+                case 0: func.args.push_back(name); break;
+                case 1: func.starredArg = name; state+=1; break;
+                case 2: consume(TK("=")); func.kwArgs[name] = consumeLiteral(); break;
+                case 3: func.doubleStarredArg = name; break;
+            }
+        } while (match(TK(",")));
+    }
+
     void compileFunction(){
         if(isCompilingClass){
             if(match(TK("pass"))) return;
@@ -781,35 +824,7 @@ __LISTCOMP:
         func.name = parser->previous.str();
 
         if (match(TK("(")) && !match(TK(")"))) {
-            int state = 0;      // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
-            do {
-                if(state == 3){
-                    throw SyntaxError(path, parser->previous, "**kwargs should be the last argument");
-                }
-
-                matchNewLines();
-                if(match(TK("*"))){
-                    if(state < 1) state = 1;
-                    else throw SyntaxError(path, parser->previous, "*args should be placed before **kwargs");
-                }
-                else if(match(TK("**"))){
-                    state = 3;
-                }
-
-                consume(TK("@id"));
-                const _Str& name = parser->previous.str();
-                if(func.hasName(name)) throw SyntaxError(path, parser->previous, "duplicate argument name");
-
-                if(state == 0 && peek() == TK("=")) state = 2;
-
-                switch (state)
-                {
-                    case 0: func.args.push_back(name); break;
-                    case 1: func.starredArg = name; state+=1; break;
-                    case 2: consume(TK("=")); func.kwArgs[name] = consumeLiteral(); break;
-                    case 3: func.doubleStarredArg = name; break;
-                }
-            } while (match(TK(",")));
+            __compileFunctionArgs(func);
             consume(TK(")"));
         }