예제 #1
0
        /// <summary>
        /// Initializes a new instance of <see cref="Case"/> AST node.
        /// </summary>
        /// <param name="expression">The target expression of the case node.</param>
        /// <param name="caseList">Series of cases for the case node.</param>
        public Case(Node expression, ExpressionList caseList)
        {
            this.expression = expression;
            this.caseList   = caseList;

            NormalizeCases();
        }
예제 #2
0
        /// <summary>
        /// Updates the properties of the <see cref="Operator"/> based on the <paramref name="expressionList"/> parameter.
        /// </summary>
        /// <param name="op">The <see cref="Operator"/> to update.</param>
        /// <param name="expressionList">The list of arguments wrapped in an <see cref="ExpressionList"/>.</param>
        /// <exception cref="ParseException"></exception>
        /// <returns>Returns the updated <see cref="Operator"/>.</returns>
        public static Node BuiltinOpInvoke(Operator op, ExpressionList expressionList)
        {
            switch (expressionList.Length)
            {
            case 1:
                op.RightArgument = expressionList[0];
                break;

            case 2:
                op.RightArgument = expressionList[1];
                op.LeftArgument  = expressionList[0];
                break;

            default:
                if (!(op is EachOperator))
                {
                    throw new ParseException("Valence", false);
                }

                EachOperator eachOp = (EachOperator)op;
                eachOp.IsGeneralApply = true;
                eachOp.RightArgument  = expressionList;
                break;
            }

            return(op);
        }
예제 #3
0
        public override bool Equals(object obj)
        {
            if (!(obj is ExpressionList))
            {
                return(false);
            }
            ExpressionList other = (ExpressionList)obj;

            if (this.nodeList.Count != other.nodeList.Count)
            {
                return(false);
            }
            List <Node> myList    = this.nodeList.ToList <Node>();
            List <Node> otherList = other.nodeList.ToList <Node>();

            for (int i = 0; i < myList.Count; i++)
            {
                if (!myList[i].Equals(otherList[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of <see cref="Case"/> AST node.
        /// </summary>
        /// <param name="expression">The target expression of the case node.</param>
        /// <param name="caseList">Series of cases for the case node.</param>
        public Case(Node expression, ExpressionList caseList)
        {
            this.expression = expression;
            this.caseList = caseList;

            NormalizeCases();
        }
예제 #5
0
 /// <summary>
 /// Initializes a new instance of <see cref="UserDefFunction"/> AST node.
 /// </summary>
 /// <param name="name">The name of the user defined function.</param>
 /// <param name="parameters">The parameters for the user defined function.</param>
 /// <param name="codeblock">The codeblock for the user defined function.</param>
 /// <param name="code">The string representation of the user defined function.</param>
 public UserDefFunction(Identifier name, ExpressionList parameters, Node codeblock, string code)
 {
     this.name = name;
     this.parameters = parameters;
     this.codeblock = codeblock;
     this.code = code;
 }
예제 #6
0
 /// <summary>
 /// Initializes a new instance of <see cref="UserDefFunction"/> AST node.
 /// </summary>
 /// <param name="name">The name of the user defined function.</param>
 /// <param name="parameters">The parameters for the user defined function.</param>
 /// <param name="codeblock">The codeblock for the user defined function.</param>
 /// <param name="code">The string representation of the user defined function.</param>
 public UserDefFunction(Identifier name, ExpressionList parameters, Node codeblock, string code)
 {
     this.name       = name;
     this.parameters = parameters;
     this.codeblock  = codeblock;
     this.code       = code;
 }
예제 #7
0
        /// <summary>
        /// Build an <see cref="ExpressionList"/> AST Node with an initial set of <see cref="Node"/>s
        /// </summary>
        /// <remarks>
        /// The order of input nodes are preserved, thus each node is added to the end of
        /// the Expression List.
        /// </remarks>
        /// <param name="nodes">Series of <see cref="Node"/>s.</param>
        /// <returns>Returns an <see cref="ExpersisonList"/> containing the give nodes</returns>
        public static ExpressionList ExpressionList(params Node[] nodes)
        {
            ExpressionList list = new ExpressionList();

            foreach (Node node in nodes)
            {
                list.AddLast(node);
            }
            return(list);
        }
예제 #8
0
        private static string ToDot(string parent, ExpressionList node)
        {
            string name = String.Format("ExpressionList{0}", counter++);

            foreach (Node item in node.Items)
            {
                string nodeName = ToDot(name, item);
                text.AppendFormat("  {0} -> {1};\n", name, nodeName);
            }

            return(name);
        }
예제 #9
0
        /// <summary>
        /// Builds a Node representing a <see cref="MonadicFunction"/> or a <see cref="DyadicFunction"/> based on the
        /// number of arguments in the <paramref name="expressionList"/> parameter.
        /// </summary>
        /// <remarks>
        /// Returned nodes based on the ExpressionList parameter (number of nodes inside the list):
        ///  - 1: MonadicFunction
        ///  - 2: DyadicFunction
        ///  - other cases: Create parse valence error
        /// </remarks>
        /// <param name="token">The <see cref="Token"/> representing the built-in function.</param>
        /// <param name="expressionList">List of arguments for the built-in function.</param>
        /// <exception cref="ParseException">Throws exception if the number of arguments is incorrect.</exception>
        /// <returns></returns>
        public static Node BuiltinInvoke(Token token, ExpressionList expressionList)
        {
            switch (expressionList.Length)
            {
                case 1:
                    return new MonadicFunction(token, expressionList[0]);
                case 2:
                    return new DyadicFunction(token, expressionList[0], expressionList[1]);

                default:
                    throw new ParseException("valence?", false);
            }
        }
예제 #10
0
        /// <summary>
        /// Builds a Node representing a <see cref="MonadicFunction"/> or a <see cref="DyadicFunction"/> based on the
        /// number of arguments in the <paramref name="expressionList"/> parameter.
        /// </summary>
        /// <remarks>
        /// Returned nodes based on the ExpressionList parameter (number of nodes inside the list):
        ///  - 1: MonadicFunction
        ///  - 2: DyadicFunction
        ///  - other cases: Create parse valence error
        /// </remarks>
        /// <param name="token">The <see cref="Token"/> representing the built-in function.</param>
        /// <param name="expressionList">List of arguments for the built-in function.</param>
        /// <exception cref="ParseException">Throws exception if the number of arguments is incorrect.</exception>
        /// <returns></returns>
        public static Node BuiltinInvoke(Token token, ExpressionList expressionList)
        {
            switch (expressionList.Length)
            {
            case 1:
                return(new MonadicFunction(token, expressionList[0]));

            case 2:
                return(new DyadicFunction(token, expressionList[0], expressionList[1]));

            default:
                throw new ParseException("valence?", false);
            }
        }
예제 #11
0
        /// <summary>
        /// Builds a <see cref="UserDefFunction">user defined function</see>.
        /// </summary>
        /// <param name="name">The name of the user defined function.</param>
        /// <param name="parameters">The parameters for the user defined function.</param>
        /// <param name="codeblock">The codeblock for the user defined function.</param>
        /// <param name="code">The string representation of the user defined function.</param>
        /// <returns>Returns a  <see cref="UserDefFunction">user defined function</see>.</returns>
        public static UserDefFunction UserDefFunction(Node name, ExpressionList parameters, Node codeblock, string code = "")
        {
            Debug.Assert(name is Identifier);

            foreach (Node item in parameters.Items)
            {
                if (!(item is Identifier))
                {
                    throw new ParseException(":header?", false);
                }
            }

            return(new UserDefFunction((Identifier)name, parameters, codeblock, code));
        }
예제 #12
0
 /// <summary>
 /// Builds a <see cref="Node"/> representing an indexing expression.
 /// </summary>
 /// <param name="item">The target of the indexing.</param>
 /// <param name="indexExpression">The indexer expressions.</param>
 /// <returns>Returns a <see cref="Indexing"/> AST node.</returns>
 public static Indexing Indexing(Node item, ExpressionList indexExpression)
 {
     return new Indexing(item, indexExpression);
 }
예제 #13
0
 /// <summary>
 /// Builds a <see cref="Case"/> node.
 /// </summary>
 /// <param name="expression">The target expression of the <see cref="Case"/> node.</param>
 /// <param name="caseList">Series of cases for the <see cref="Case"/> node.</param>
 /// <returns>Returns the <see cref="Case"/> node.</returns>
 public static Case Case(Node expression, ExpressionList caseList)
 {
     return new Case(expression, caseList);
 }
예제 #14
0
 /// <summary>
 /// Initializes a new instance of <see cref="Indexing"/> AST node.
 /// </summary>
 /// <param name="item">The target of the indexing.</param>
 /// <param name="indexExpression">The indexer expressions.</param>
 public Indexing(Node item, ExpressionList indexExpression)
 {
     this.item            = item;
     this.indexExpression = indexExpression;
 }
예제 #15
0
 /// <summary>
 /// Builds a <see cref="Node"/> representing an indexing expression.
 /// </summary>
 /// <param name="item">The target of the indexing.</param>
 /// <param name="indexExpression">The indexer expressions.</param>
 /// <returns>Returns a <see cref="Indexing"/> AST node.</returns>
 public static Indexing Indexing(Node item, ExpressionList indexExpression)
 {
     return(new Indexing(item, indexExpression));
 }
예제 #16
0
        /// <summary>
        /// Updates the properties of the <see cref="Operator"/> based on the <paramref name="expressionList"/> parameter.
        /// </summary>
        /// <param name="op">The <see cref="Operator"/> to update.</param>
        /// <param name="expressionList">The list of arguments wrapped in an <see cref="ExpressionList"/>.</param>
        /// <exception cref="ParseException"></exception>
        /// <returns>Returns the updated <see cref="Operator"/>.</returns>
        public static Node BuiltinOpInvoke(Operator op, ExpressionList expressionList)
        {
            switch (expressionList.Length)
            {
                case 1:
                    op.RightArgument = expressionList[0];
                    break;
                case 2:
                    op.RightArgument = expressionList[1];
                    op.LeftArgument = expressionList[0];
                    break;
                default:
                    if (!(op is EachOperator))
                    {
                        throw new ParseException("Valence", false);
                    }

                    EachOperator eachOp = (EachOperator)op;
                    eachOp.IsGeneralApply = true;
                    eachOp.RightArgument = expressionList;
                    break;
            }

            return op;
        }
예제 #17
0
 /// <summary>
 /// Build an <see cref="ExpressionList"/> AST Node with an initial set of <see cref="Node"/>s
 /// </summary>
 /// <remarks>
 /// The order of input nodes are preserved, thus each node is added to the end of
 /// the Expression List.
 /// </remarks>
 /// <param name="nodes">Series of <see cref="Node"/>s.</param>
 /// <returns>Returns an <see cref="ExpersisonList"/> containing the give nodes</returns>
 public static ExpressionList ExpressionList(params Node[] nodes)
 {
     ExpressionList list = new ExpressionList();
     foreach (Node node in nodes)
     {
         list.AddLast(node);
     }
     return list;
 }
예제 #18
0
 /// <summary>
 /// Builds a <see cref="Case"/> node.
 /// </summary>
 /// <param name="expression">The target expression of the <see cref="Case"/> node.</param>
 /// <param name="caseList">Series of cases for the <see cref="Case"/> node.</param>
 /// <returns>Returns the <see cref="Case"/> node.</returns>
 public static Case Case(Node expression, ExpressionList caseList)
 {
     return(new Case(expression, caseList));
 }
예제 #19
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            DLR.Expression func, result;

            if (this.function is Token)
            {
                Node wrappedFunction = new BuiltInFunction((Token)this.function);
                func = wrappedFunction.Generate(scope);
            }
            else
            {
                func = this.function.Generate(scope);
            }

            DLR.ParameterExpression environment = scope.GetRuntimeExpression();

            DLR.ParameterExpression functionParam = DLR.Expression.Variable(typeof(AType), "$$functionParam");
            DLR.ParameterExpression rightParam    = DLR.Expression.Variable(typeof(AType), "$$rightParam");
            DLR.ParameterExpression valueParam    = DLR.Expression.Variable(typeof(AType), "$$valueParam");

            // TODO: rewrite this
            if (this.IsGeneralApply)
            {
                ExpressionList argumnets = (ExpressionList)this.rightarg;
                LinkedList <DLR.Expression> callArguments = new LinkedList <DLR.Expression>();

                // 2. Add the parameters in !reverse! order
                foreach (Node item in argumnets.Items)
                {
                    callArguments.AddFirst(item.Generate(scope));
                }

                // 0. Add A+ environment as first argument for user defined functions
                callArguments.AddFirst(environment);

                // 1. Construct the method body
                callArguments.AddFirst(functionParam.Property("NestedItem"));

                result = DLR.Expression.Block(
                    new DLR.ParameterExpression[] { functionParam, valueParam },
                    DLR.Expression.Assign(functionParam, func),
                    DLR.Expression.IfThenElse(
                        DLR.Expression.PropertyOrField(functionParam, "IsFunctionScalar"),
                        DLR.Expression.Assign(
                            valueParam,
                            AST.UserDefInvoke.BuildInvoke(scope.GetRuntime(), callArguments)
                            ),
                        DLR.Expression.Throw(
                            DLR.Expression.New(
                                typeof(Error.Valence).GetConstructor(new Type[] { typeof(string) }),
                                DLR.Expression.Constant("apply")
                                )
                            )
                        ),
                    valueParam
                    );
            }
            else if (isDyadic)
            {
                DLR.Expression          right     = this.rightarg.Generate(scope);
                DLR.Expression          left      = this.leftarg.Generate(scope);
                DLR.ParameterExpression leftParam = DLR.Expression.Variable(typeof(AType), "$$leftParam");

                result = DLR.Expression.Block(
                    new DLR.ParameterExpression[] { functionParam, rightParam, leftParam, valueParam },
                    DLR.Expression.Assign(functionParam, func),
                    DLR.Expression.Assign(rightParam, right),
                    DLR.Expression.Assign(leftParam, left),
                    DLR.Expression.IfThenElse(
                        DLR.Expression.IsTrue(
                            DLR.Expression.PropertyOrField(functionParam, "IsFunctionScalar")
                            ),
                        DLR.Expression.Assign(
                            valueParam,
                            DLR.Expression.Call(
                                DLR.Expression.Constant(DyadicOperatorInstance.Apply),
                                DyadicOperatorInstance.Apply.GetType().GetMethod("Execute"),
                                functionParam, rightParam, leftParam, environment
                                )
                            ),
                        DLR.Expression.Assign(
                            valueParam,
                            DLR.Expression.Call(
                                DLR.Expression.Constant(DyadicOperatorInstance.Each),
                                DyadicOperatorInstance.Each.GetType().GetMethod("Execute"),
                                functionParam, rightParam, leftParam, environment
                                )
                            )
                        ),
                    valueParam
                    );
            }
            else
            {
                DLR.Expression right = this.rightarg.Generate(scope);
                result = DLR.Expression.Block(
                    new DLR.ParameterExpression[] { functionParam, rightParam, valueParam },
                    DLR.Expression.Assign(functionParam, func),
                    DLR.Expression.Assign(rightParam, right),
                    DLR.Expression.IfThenElse(
                        DLR.Expression.IsTrue(
                            DLR.Expression.PropertyOrField(functionParam, "IsFunctionScalar")
                            ),
                        DLR.Expression.Assign(
                            valueParam,
                            DLR.Expression.Call(
                                DLR.Expression.Constant(MonadicOperatorInstance.Apply),
                                MonadicOperatorInstance.Apply.GetType().GetMethod("Execute"),
                                functionParam, rightParam, environment
                                )
                            ),
                        DLR.Expression.Assign(
                            valueParam,
                            DLR.Expression.Call(
                                DLR.Expression.Constant(MonadicOperatorInstance.Each),
                                MonadicOperatorInstance.Each.GetType().GetMethod("Execute"),
                                functionParam, rightParam, environment
                                )
                            )
                        ),
                    valueParam
                    );
            }

            return(result);
        }
예제 #20
0
 /// <summary>
 /// Initializes a new instance of <see cref="UserDefInvoke"/> AST node.
 /// </summary>
 /// <param name="method">The identifier of the user defined function to invoke.</param>
 /// <param name="arguments">The arguments for the user defined function.</param>
 public UserDefInvoke(Identifier method, ExpressionList arguments)
 {
     this.method = method;
     this.arguments = arguments;
 }
예제 #21
0
        private static string ToDot(string parent, ExpressionList node)
        {
            string name = String.Format("ExpressionList{0}", counter++);

            foreach (Node item in node.Items)
            {
                string nodeName = ToDot(name, item);
                text.AppendFormat("  {0} -> {1};\n", name, nodeName);
            }

            return name;
        }
예제 #22
0
 /// <summary>
 /// Initializes a new instance of <see cref="UserDefInvoke"/> AST node.
 /// </summary>
 /// <param name="method">The identifier of the user defined function to invoke.</param>
 /// <param name="arguments">The arguments for the user defined function.</param>
 public UserDefInvoke(Identifier method, ExpressionList arguments)
 {
     this.method    = method;
     this.arguments = arguments;
 }
예제 #23
0
 /// <summary>
 /// Initializes a new instance of <see cref="Indexing"/> AST node.
 /// </summary>
 /// <param name="item">The target of the indexing.</param>
 /// <param name="indexExpression">The indexer expressions.</param>
 public Indexing(Node item, ExpressionList indexExpression)
 {
     this.item = item;
     this.indexExpression = indexExpression;
 }
예제 #24
0
        /// <summary>
        /// Builds a <see cref="UserDefFunction">user defined function</see>.
        /// </summary>
        /// <param name="name">The name of the user defined function.</param>
        /// <param name="parameters">The parameters for the user defined function.</param>
        /// <param name="codeblock">The codeblock for the user defined function.</param>
        /// <param name="code">The string representation of the user defined function.</param>
        /// <returns>Returns a  <see cref="UserDefFunction">user defined function</see>.</returns>
        public static UserDefFunction UserDefFunction(Node name, ExpressionList parameters, Node codeblock, string code = "")
        {
            Debug.Assert(name is Identifier);

            foreach (Node item in parameters.Items)
            {
                if (!(item is Identifier))
                {
                    throw new ParseException(":header?", false);
                }
            }

            return new UserDefFunction((Identifier)name, parameters, codeblock, code);
        }