public static INode Modify(INode node, ModifierFunc modifier)
        {
            switch (node)
            {
            case Program p:
                p.Statements = p.Statements.
                               Select(statement => (IStatement)Modify(statement, modifier)).
                               ToList();
                break;

            case ExpressionStatement es:
                es.Expression = (IExpression)Modify(es.Expression, modifier);
                break;

            case InfixExpression ie:
                ie.Left  = (IExpression)Modify(ie.Left, modifier);
                ie.Right = (IExpression)Modify(ie.Right, modifier);
                break;

            case PrefixExpression pe:
                pe.Right = (IExpression)Modify(pe.Right, modifier);
                break;

            case IndexExpression ie:
                ie.Left  = (IExpression)Modify(ie.Left, modifier);
                ie.Index = (IExpression)Modify(ie.Index, modifier);
                break;

            case IfExpression ie:
                ie.Condition   = (IExpression)Modify(ie.Condition, modifier);
                ie.Consequence = (BlockStatement)Modify(ie.Consequence, modifier);
                if (ie.Alternative != null)
                {
                    ie.Alternative = (BlockStatement)Modify(ie.Alternative, modifier);
                }
                break;

            case BlockStatement bs:
                bs.Statements = bs.Statements.Select(x => (IStatement)Modify(x, modifier)).ToList();
                break;

            case ReturnStatement rs:
                rs.ReturnValue = (IExpression)Modify(rs.ReturnValue, modifier);
                break;

            case LetStatement ls:
                ls.Value = (IExpression)Modify(ls.Value, modifier);
                break;

            case FunctionLiteral fl:
                fl.Parameters = fl.Parameters.Select(x => (Identifier)Modify(x, modifier)).ToList();
                fl.Body       = (BlockStatement)Modify(fl.Body, modifier);
                break;

            case ArrayLiteral al:
                al.Elements = al.Elements.Select(x => (IExpression)Modify(x, modifier)).ToList();
                break;

            case HashLiteral hl:
                hl.Pairs = hl.Pairs.
                           Select(x => ((IExpression)Modify(x.Key, modifier), (IExpression)Modify(x.Value, modifier))).
                           ToDictionary(x => x.Item1, x => x.Item2);
                break;
            }

            return(modifier(node));
        }
Exemple #2
0
        public static INode Modify(INode node, ModifierFunc modifier)
        {
            if (node is Program program)
            {
                for (var i = 0; i < program.Statements.Count; i++)
                {
                    var statement = program.Statements[i];
                    program.Statements[i] = Modify(statement, modifier) as IStatement;
                }
            }
            else if (node is ExpressionStatement expression)
            {
                expression.Expression = Modify(expression.Expression, modifier) as IExpression;
            }
            else if (node is InfixExpression infix)
            {
                infix.Left  = Modify(infix.Left, modifier) as IExpression;
                infix.Right = Modify(infix.Right, modifier) as IExpression;
            }
            else if (node is PrefixExpression prefix)
            {
                prefix.Right = Modify(prefix.Right, modifier) as IExpression;
            }
            else if (node is IndexExpression index)
            {
                index.Left  = Modify(index.Left, modifier) as IExpression;
                index.Index = Modify(index.Index, modifier) as IExpression;
            }
            else if (node is IfExpression ife)
            {
                ife.Condition   = Modify(ife.Condition, modifier) as IExpression;
                ife.Consequence = Modify(ife.Consequence, modifier) as BlockStatement;
                if (ife.Alternative != null)
                {
                    ife.Alternative = Modify(ife.Alternative, modifier) as BlockStatement;
                }
            }
            else if (node is BlockStatement block)
            {
                for (var i = 0; i < block.Statements.Count; i++)
                {
                    var statement = block.Statements[i];
                    block.Statements[i] = Modify(statement, modifier) as IStatement;
                }
            }
            else if (node is ReturnStatement ret)
            {
                ret.ReturnValue = Modify(ret.ReturnValue, modifier) as IExpression;
            }
            else if (node is LetStatement let)
            {
                let.Value = Modify(let.Value, modifier) as IExpression;
            }
            else if (node is FunctionLiteral function)
            {
                for (var i = 0; i < function.Parameters.Count; i++)
                {
                    var statement = function.Parameters[i];
                    function.Parameters[i] = Modify(statement, modifier) as Identifier;
                }
                function.Body = Modify(function.Body, modifier) as BlockStatement;
            }
            else if (node is ArrayLiteral array)
            {
                for (var i = 0; i < array.Elements.Count; i++)
                {
                    var statement = array.Elements[i];
                    array.Elements[i] = Modify(statement, modifier) as IExpression;
                }
            }
            else if (node is HashLiteral hash)
            {
                var newPairs = new Dictionary <IExpression, IExpression>();
                foreach (var pair in hash.Pairs)
                {
                    var newKey = Modify(pair.Key, modifier) as IExpression;
                    var newVal = Modify(pair.Value, modifier) as IExpression;
                    newPairs.Add(newKey, newVal);
                }
                hash.Pairs = newPairs;
            }

            return(modifier(node));
        }
Exemple #3
0
        public static INode Modify(INode node, ModifierFunc modifier)
        {
            if (node is Program p)
            {
                for (var i = 0; i < p.Statements.Length; i++)
                {
                    p.Statements[i] = (IStatement)Modify(p.Statements[i], modifier);
                }
            }
            else if (node is ExpressionStatement es)
            {
                es.Expression = (IExpression)Modify(es.Expression, modifier);
            }
            else if (node is InfixExpression ie)
            {
                ie.Left  = (IExpression)Modify(ie.Left, modifier);
                ie.Right = (IExpression)Modify(ie.Right, modifier);
            }
            else if (node is PrefixExpression pe)
            {
                pe.Right = (IExpression)Modify(pe.Right, modifier);
            }
            else if (node is IndexExpression idxe)
            {
                idxe.Left  = (IExpression)Modify(idxe.Left, modifier);
                idxe.Index = (IExpression)Modify(idxe.Index, modifier);
            }
            else if (node is IfExpression ife)
            {
                ife.Condition  = (IExpression)Modify(ife.Condition, modifier);
                ife.Consequent = (BlockStatement)Modify(ife.Consequent, modifier);
                if (ife.Alternative != null)
                {
                    ife.Alternative = (BlockStatement)Modify(ife.Alternative, modifier);
                }
            }
            else if (node is BlockStatement bs)
            {
                for (var i = 0; i < bs.Statements.Length; i++)
                {
                    bs.Statements[i] = (IStatement)Modify(bs.Statements[i], modifier);
                }
            }
            else if (node is ReturnStatement rs)
            {
                rs.ReturnValue = (IExpression)Modify(rs.ReturnValue, modifier);
            }
            else if (node is LetStatement ls)
            {
                ls.Value = (IExpression)Modify(ls.Value, modifier);
            }
            else if (node is FunctionLiteral fl)
            {
                for (var i = 0; i < fl.Parameters.Length; i++)
                {
                    fl.Parameters[i] = (Identifier)Modify(fl.Parameters[i], modifier);
                }
                fl.Body = (BlockStatement)Modify(fl.Body, modifier);
            }
            else if (node is ArrayLiteral al)
            {
                for (var i = 0; i < al.Elements.Length; i++)
                {
                    al.Elements[i] = (IExpression)Modify(al.Elements[i], modifier);
                }
            }
            else if (node is HashLiteral hl)
            {
                var newPairs = new Dictionary <IExpression, IExpression>();
                foreach (var kvp in hl.Pairs)
                {
                    var newKey = (IExpression)Modify(kvp.Key, modifier);
                    var newVal = (IExpression)Modify(kvp.Value, modifier);
                    newPairs[newKey] = newVal;
                }
                hl.Pairs = newPairs;
            }

            return(modifier(node));
        }