diff --git a/src/compiler.h b/src/compiler.h index 7d728d3a..8d57d153 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -337,7 +337,18 @@ public: } void exprLambda() { - throw SyntaxError(path, parser->previous, "lambda is not implemented yet"); + _Func func; + func.name = ""; + __compileFunctionArgs(func); + consume(TK(":")); + func.code = std::make_shared(); + 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(")")); }