public void AnonymousFunctionDefinition() { Expression expression = parseExpression("(a -> int, b-> Banana) -> Platypus { a + 5; }"); AnonymousFunctionExpression a = assertTypeAndCast <AnonymousFunctionExpression>(expression); Assert.AreEqual("Platypus", a.returnType.name); Assert.IsNotInstanceOfType(a.returnType, typeof(GenericTypeName)); Assert.AreEqual(2, a.arguments.members.Count); Assert.AreEqual(1, a.body.innerExpressions.Count); Assert.AreEqual("a", a.arguments.members[0].name); Assert.AreEqual("int", a.arguments.members[0].typeName.name); Assert.IsNotInstanceOfType(a.arguments.members[0].typeName, typeof(GenericTypeName)); Assert.AreEqual("b", a.arguments.members[1].name); Assert.AreEqual("Banana", a.arguments.members[1].typeName.name); Assert.IsNotInstanceOfType(a.arguments.members[1].typeName, typeof(GenericTypeName)); AdditionExpression d = assertTypeAndCast <AdditionExpression>(a.body.innerExpressions[0]); VariableReferenceExpression e = assertTypeAndCast <VariableReferenceExpression>(d.left); IntegralLiteralExpression f = assertTypeAndCast <IntegralLiteralExpression>(d.right); Assert.AreEqual("a", e.name); Assert.AreEqual(5, f.value); }
public TypeNode Dispatch(ExpressionNode node, List <TypeNode> parameterTypes) { return(node switch { IBinaryNumberOperator n => _numberHelper.VisitBinaryNumOp(n, parameterTypes), IBinaryBooleanOperator n => _booleanHelper.VisitBinaryBoolOp(n, parameterTypes), IBinarySetOperator n => _setHelper.VisitBinarySetOp(n, parameterTypes), SubsetExpression n => _setHelper.VisitSubset(n, parameterTypes), SetExpression n => _setHelper.VisitSet(n, parameterTypes), NotExpression n => _booleanHelper.VisitNot(n, parameterTypes), FunctionCallExpression n => _declarationHelper.VisitFunctionCall(n, parameterTypes), IdentifierExpression n => _declarationHelper.VisitIdentifier(n, parameterTypes), IntegerLiteralExpression _ => _declarationHelper.VisitIntegerLiteral(), RealLiteralExpression _ => _declarationHelper.VisitRealLiteral(), BooleanLiteralExpression _ => _declarationHelper.VisitBooleanLiteral(), StringLiteralExpression _ => _declarationHelper.VisitStringLiteral(), EmptySetLiteralExpression _ => _declarationHelper.VisitEmptySetLiteral(), AdditionExpression n => _commonOperatorHelper.VisitAddition(n, parameterTypes), SubtractionExpression n => _commonOperatorHelper.VisitSubtraction(n, parameterTypes), AbsoluteValueExpression n => _commonOperatorHelper.VisitAbsoluteValue(n, parameterTypes), IRelationOperator n => _commonOperatorHelper.VisitRelationalOperator(n, parameterTypes), IEquivalenceOperator n => _commonOperatorHelper.VisitEquivalenceOperator(n, parameterTypes), NegativeExpression n => _numberHelper.VisitNegative(n, parameterTypes), ElementExpression n => _commonOperatorHelper.VisitElement(n, parameterTypes), ISetGraphField n => _commonOperatorHelper.VisitISetGraphField(n, parameterTypes), IFunctionGraphField n => _commonOperatorHelper.VisitIFunctionGraphField(n, parameterTypes), GraphExpression n => _commonOperatorHelper.VisitGraph(n, parameterTypes), AnonymousFunctionExpression n => _declarationHelper.VisitAnonymousFunction(n, parameterTypes), _ => throw new UnimplementedTypeCheckerException(node, "Dispatch"), });
protected virtual Object[] AnalyseAnonymousFunctionExpression(AnonymousFunctionExpression node, params Object[] args) { foreach (ASTNode arg in node.Arguments) { this.Analyse(arg); } this.Analyse(node.Body); return(null); }
public void VisitAnonymousFunction(AnonymousFunctionExpression node, List <string> parameters) { List <string> newScope = parameters.ToList(); newScope.AddRange(node.Identifiers); if (!StringsAreUnique(newScope)) { throw new IdenticalParameterIdentifiersException(newScope); } _dispatch(node.ReturnValue, newScope); }
private static AnonymousFunctionExpression GetAnonymousFunctionExpression(ASTNode prev, Scope scope, StatementList body) { var expr = new AnonymousFunctionExpression(prev.Parent, scope, new List <LToken> (new[] { new LToken("function", "function", "function", TokenType.Keyword, AdjustRange(prev.Range, "function")), new LToken("end", "end", "end", TokenType.Keyword, AdjustRange(prev.Range, "end")) })); expr.SetBody(body); return(expr); }
private static AnonymousFunctionExpression GetAnonymFunc(ExpressionNode expr, int funcRef, string id, TypeEnum type) { var res = new AnonymousFunctionExpression(new List <string>() { id }, new List <TypeNode>() { GetTypeNode(type) }, expr, 0, 0); res.Reference = funcRef; return(res); }
public override void ConstructAnonymousFunctionExpression(AnonymousFunctionExpression node) { this.Write("function ( "); for (var i = 0; i < node.Arguments.Count; i++) { this.ConstructInternal(node.Arguments[i]); if (i < node.Arguments.Count - 1) { this.Write(", "); } } this.WriteLine(" )"); this.Indent( ); this.ConstructInternal(node.Body); this.Outdent( ); this.WriteIndented("end"); }
public TypeNode VisitAnonymousFunction(AnonymousFunctionExpression node, List <TypeNode> parameterTypes) { List <TypeNode> newScope = new List <TypeNode>(); newScope.AddRange(parameterTypes); newScope.AddRange(node.Types); TypeNode returnType = _getType(node.ReturnValue, newScope); FunctionTypeNode functionType = new FunctionTypeNode(returnType, newScope, 0, 0); int line = node.LineNumber; int letter = node.LineNumber; ConditionNode condition = new ConditionNode(node.ReturnValue, line, letter); FunctionNode function = new FunctionNode(functionType.ToString(), condition, node.Identifiers, functionType, line, letter); node.Reference = _functions.Count; _functions.Add(function); return(new FunctionTypeNode(returnType, node.Types, 0, 0)); }
protected virtual ASTNode FoldAnonymousFunctionExpression(AnonymousFunctionExpression node, params Object[] args) { node.SetArguments(this.FoldNodeList(node.Arguments)); node.SetBody(( StatementList )this.Fold(node.Body)); return(node); }
public Function AnonymousFunction(AnonymousFunctionExpression e, List <object> parameters) { return(new Function(e.Reference, parameters.ToList())); }
public abstract void ConstructAnonymousFunctionExpression(AnonymousFunctionExpression node);
public Expression VisitAnonymousFunction(AnonymousFunctionExpression node) { return(node); }
protected override ASTNode FoldFunctionCallExpression(FunctionCallExpression node, params Object[] args) { // Fold args and base node = ( FunctionCallExpression )base.FoldFunctionCallExpression(node, args); // Fold some functions if (node.Base is VariableExpression varExpr) { if (varExpr.Variable.Name == "RunString" // Assert we have enough arguments for RunString && node.Arguments.Count > 0) { if (!(node.Arguments[0] is StringExpression) || (node.Arguments.Count > 1 && !(node.Arguments[1] is StringExpression)) || (node.Arguments.Count > 2 && !(node.Arguments[2] is BooleanExpression))) { return(node); } var code = (node.Arguments[0] as StringExpression).Value; var name = node.Arguments.Count > 1 ? (node.Arguments[1] as StringExpression).Value : "runstring_" + R.Next( ); // Dispose of useless RunString calls if (code.Trim( ) == "") { return(null); } EnvFile file = this.Environment.ProcessFile(name, code); if (file.Successful && file.AST != null) { file.AST.Scope.InternalData.RemoveValue("isRoot"); file.AST.Scope.InternalData.RemoveValue("isFunction"); // Enclose it in a do...end statement so that it doesn't // breaks other analysers/folders too bad return(GetDoStatement(node, file.AST)); } } // CompileString is almost the same as RunString // except it's an anonymous function definition else if (varExpr.Variable.Name == "CompileString" && node.Arguments.Count > 0) { if (!(node.Arguments[0] is StringExpression) || (node.Arguments.Count > 1 && !(node.Arguments[1] is StringExpression))) { return(node); } var code = (node.Arguments[0] as StringExpression).Value.Trim( ); var id = node.Arguments.Count > 1 ? (node.Arguments[1] as StringExpression).Value : "compilestring_" + R.Next( ); // It'll be an empty function anyways if (code == "") { var scope = new Scope(node.Scope.Parser, node.Scope); return(GetAnonymousFunctionExpression(node, scope, new StatementList(null, scope, new List <LToken> ( )) )); } EnvFile file = this.Environment.ProcessFile(id, code); if (file.Successful && file.AST != null) { file.AST.InternalData.RemoveValue("isRoot"); var scope = new Scope(node.Scope.Parser, node.Scope); AnonymousFunctionExpression func = GetAnonymousFunctionExpression(node, scope, file.AST); // Add ... as argument because idk what // people might pass to it and there're // no ways to specify argument names so // ¯\_(ツ)_/¯ func.AddArgument(new VarArgExpression( func, scope, GetTokenList("...", "...", "...", TokenType.Punctuation, AdjustRange(node.Range, "...")) )); return(func); } } } return(node); }
public static AST GetMultiGraphExample() { AST ast = GetAstSkeleton(); FunctionCallExpression vertices = GetFunctionCallExpression("vertexSet", GetIdentifierExpression("n", 0, true), 1); SetExpression edges = GetSetExpression(GetElementNode("x", "i", -1), GetBoundNode("i", 0, GetAdditionExpression(GetIdentifierExpression("n", 0, true), -1))); AnonymousFunctionExpression src = GetAnonymousFunctionExpression("e", TypeEnum.Element, GetFunctionCallExpression("edgeFunc", GetIdentifierExpression("e", 1, true), 2)); AnonymousFunctionExpression dst = GetAnonymousFunctionExpression("e", TypeEnum.Element, GetFunctionCallExpression("edgeFunc", new List <ExpressionNode>() { GetIdentifierExpression("e", 1, true), GetIdentifierExpression("n", 0, true) }, 3)); GraphExpression graphExpression = GetGraphExpression(vertices, edges, src, dst); FunctionNode graphFunc = GetFunctionNode(graphExpression, "graphFunc", "n", TypeEnum.Integer, TypeEnum.Graph); AddFunctionNode(ast, graphFunc); FunctionNode vertexSet = GetFunctionNode(GetSetExpression(GetElementNode("x", "i", -1), GetBoundNode("i", 0, GetAdditionExpression(GetIdentifierExpression("n", 0, true), -1))), "vertexSet", "n", TypeEnum.Integer, TypeEnum.Set); AddFunctionNode(ast, vertexSet); FunctionNode edgeFunc = GetFunctionNode(GetIdentifierExpression("e", 0, true), "edgeFunc", "e", TypeEnum.Element, TypeEnum.Element); AddFunctionNode(ast, edgeFunc); FunctionNode edgeFunc2 = GetFunctionNode(new List <ConditionNode>() { GetConditionNode(new List <ElementNode>() { GetElementNode("e", "i", 0) }, null, GetElementExpression(GetModuloExpression(GetAdditionExpression(GetIdentifierExpression("i", 2, true), 1), GetIdentifierExpression("n", 1, true)))) }, "edgeFunc", new List <string>() { "e", "n" }, new List <TypeEnum>() { TypeEnum.Element, TypeEnum.Integer }, TypeEnum.Element); AddFunctionNode(ast, edgeFunc2); FunctionNode vLabel = GetFunctionNode(new List <ConditionNode>() { GetConditionNode(new List <ElementNode>() { GetElementNode("e", "i", 0) }, null, GetAdditionExpression(GetStringLiteralExpression("Vertex: "), GetIdentifierExpression("i", 1, true))) }, "vLabel", new List <string>() { "e" }, new List <TypeEnum>() { TypeEnum.Element }, TypeEnum.String); AddFunctionNode(ast, vLabel); FunctionNode eLabel = GetFunctionNode(new List <ConditionNode>() { GetConditionNode(new List <ElementNode>() { GetElementNode("e", "i", 0) }, null, GetAdditionExpression(GetStringLiteralExpression("Edge: "), GetIdentifierExpression("i", 1, true))) }, "eLabel", new List <string>() { "e" }, new List <TypeEnum>() { TypeEnum.Element }, TypeEnum.String); AddFunctionNode(ast, eLabel); ExportNode export = GetExportNode(GetFunctionCallExpression("graphFunc", GetIntegerLiteralExpression(2), 0), "MultiIntegration", GetIdentifierExpression("vLabel", 4, false), GetIdentifierExpression("eLabel", 5, false)); AddExportNode(ast, export); return(ast); }
public static ParameterExpression FunctionReference(AnonymousFunctionExpression functionExpression, string name) { return(ParameterExpression.Make(functionExpression, name)); }
public virtual object VisitAnonymousFunction(AnonymousFunctionExpression node) { return(node.Compile(Target.GetType(), this)); }
internal static ParameterExpression Make(AnonymousFunctionExpression function, string name) { return(new ParameterExpression(name, function)); }
internal ParameterExpression(string name, AnonymousFunctionExpression functionExpression = null) { _name = name; this.FunctionReference = functionExpression; }