예제 #1
0
        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"),
     });
예제 #3
0
 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);
        }
예제 #5
0
        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);
        }
예제 #7
0
        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));
        }
예제 #9
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()));
 }
예제 #11
0
 public abstract void ConstructAnonymousFunctionExpression(AnonymousFunctionExpression node);
예제 #12
0
 public Expression VisitAnonymousFunction(AnonymousFunctionExpression node)
 {
     return(node);
 }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
 public static ParameterExpression FunctionReference(AnonymousFunctionExpression functionExpression, string name)
 {
     return(ParameterExpression.Make(functionExpression, name));
 }
예제 #16
0
 public virtual object VisitAnonymousFunction(AnonymousFunctionExpression node)
 {
     return(node.Compile(Target.GetType(), this));
 }
예제 #17
0
 internal static ParameterExpression Make(AnonymousFunctionExpression function, string name)
 {
     return(new ParameterExpression(name, function));
 }
예제 #18
0
 internal ParameterExpression(string name, AnonymousFunctionExpression functionExpression = null)
 {
     _name = name;
     this.FunctionReference = functionExpression;
 }