private Ast Lambda() { TokenStream.Take(TokenType.Fun); var arguments = GetArgumentList(true); TokenStream.Take(TokenType.DeRef); var lines = GetStatementsInScope(TokenType.LBracket, TokenType.RBracket); var method = new LambdaDeclr(arguments, lines); return method; }
private LambdaDeclr CreateCurriedMethod(FuncInvoke ast, MethodSymbol functionType) { var srcMethod = functionType.MethodDeclr; var fixedAssignments = new List<VarDeclrAst>(); var count = 0; foreach (var argValue in ast.Arguments) { var srcArg = srcMethod.Arguments[count] as VarDeclrAst; var token = new Token(srcArg.DeclarationType.Token.TokenType, argValue.Token.TokenValue); var declr = new VarDeclrAst(token, srcArg.Token, new Expr(argValue.Token)); // if we're creating a curry using a variable then we need to resolve the variable type // otherwise we can make a symbol for the literal var newArgType = argValue.Token.TokenType == TokenType.Word ? ast.CurrentScope.Resolve(argValue).Type : ScopeUtil.CreateSymbolType(argValue); // create a symbol type for the target we're invoking on so we can do type checking var targetArgType = ScopeUtil.CreateSymbolType(srcArg.DeclarationType); if (!TokenUtil.EqualOrPromotable(newArgType, targetArgType)) { throw new InvalidSyntax(String.Format("Cannot pass argument {0} of type {1} to partial function {2} as argument {3} of type {4}", argValue.Token.TokenValue, newArgType.TypeName, srcMethod.MethodName.Token.TokenValue, srcArg.VariableName.Token.TokenValue, targetArgType.TypeName)); } fixedAssignments.Add(declr); count++; } var newBody = fixedAssignments.Concat(srcMethod.Body.ScopedStatements).ToList(); var curriedMethod = new LambdaDeclr(srcMethod.Arguments.Skip(ast.Arguments.Count).ToList(), new ScopeDeclr(newBody)); SetScope(curriedMethod); return curriedMethod; }