public void Visit(FuncInvoke ast) { Exec(ast); }
private object NewDo(NewAst ast) { var className = Resolve(ast); var classType = (className as ClassSymbol).Src as ClassAst; var space = new MemorySpace(); var oldSpace = MemorySpaces.Current; MemorySpaces.Current = space; foreach (var symbol in classType.Body.ScopedStatements) { Exec(symbol); } if (classType.Constructor != null) { var funcInvoke = new FuncInvoke(classType.Constructor.Token, ast.Args); funcInvoke.CurrentScope = classType.Body.CurrentScope; Exec(funcInvoke); } MemorySpaces.Current = oldSpace; return space; }
private object InvokeFunction(FuncInvoke funcInvoke) { var method = Resolve(funcInvoke); if (method != null) { var invoker = method as MethodSymbol; if (invoker == null) { invoker = MemorySpaces.Current.Get(method.Name) as MethodSymbol; } // arguments should always be resolved from the current calling space // so make sure the invoking function knows which space it comes from if (funcInvoke.CallingMemory == null) { funcInvoke.CallingMemory = MemorySpaces.Current; } if (funcInvoke.CallingMemory != null && !CollectionUtil.IsNullOrEmpty(funcInvoke.Arguments)) { funcInvoke.Arguments.ForEach(arg => arg.CallingMemory = funcInvoke.CallingMemory); } var oldMemory = MemorySpaces.Current; try { // if we're a lambda and we have some sort of closure // set our working space to be that. if (invoker.Environment != null) { MemorySpaces.Current = invoker.Environment; } var value = InvokeMethodSymbol(invoker, funcInvoke.Arguments); return value; } finally { MemorySpaces.Current = oldMemory; } } throw new UndefinedElementException("Undefined 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; }
public void Visit(FuncInvoke ast) { if (ast.CallingScope != null) { ast.Arguments.ForEach(arg => arg.CallingScope = ast.CallingScope); } ast.Arguments.ForEach(arg => arg.Visit(this)); SetScope(ast); var functionType = Resolve(ast.FunctionName) as MethodSymbol; if (functionType != null && ast.Arguments.Count < functionType.MethodDeclr.Arguments.Count) { var curriedMethod = CreateCurriedMethod(ast, functionType); curriedMethod.Visit(this); var methodSymbol = ScopeUtil.DefineMethod(curriedMethod); Current.Define(methodSymbol); ast.ConvertedExpression = curriedMethod; } else if(ResolvingTypes) { ast.AstSymbolType = ResolveType(ast.FunctionName, ast.CurrentScope); } }
public void Visit(FuncInvoke ast) { ast.FunctionName.Visit(this); ast.Arguments.ForEach(arg => arg.Visit(this)); }