コード例 #1
0
ファイル: IncludeMutator.cs プロジェクト: robocoder/aphid
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            var loadExp = expression as LoadScriptExpression;

            if (loadExp == null)
            {
                hasChanged = false;

                return null;
            }

            hasChanged = true;

            var scriptExp = loadExp.FileExpression as StringExpression;

            if (scriptExp == null)
            {
                throw new AphidRuntimeException(
                    "Invalid load script operand '{0}'.",
                    loadExp.FileExpression);
            }

            var script = _loader.FindScriptFile(StringParser.Parse(scriptExp.Value));

            if (!File.Exists(script))
            {
                throw new AphidRuntimeException("Could not find script '{0}'.", scriptExp.Value);
            }

            var tokens = new AphidLexer(File.ReadAllText(script)).GetTokens();
            return new AphidParser(tokens) { UseImplicitReturns = UseImplicitReturns }.Parse();
        }
コード例 #2
0
        public byte[] Assemble(AphidExpression expression)
        {
            if (expression is BinaryOperatorExpression)
            {
                return AssembleBinaryOperation(expression as BinaryOperatorExpression);
            }
            else if (expression is IdentifierExpression)
            {
                AddLabel(expression as IdentifierExpression);

                return null;
            }
            else if (expression is UnaryOperatorExpression)
            {
                return AssembleUnaryOperation(expression as UnaryOperatorExpression);
            }
            else if (expression is CallExpression)
            {
                return AssembleCallExpression(expression as CallExpression);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
コード例 #3
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            hasChanged = false;

            if (!IsStatement || expression.Type != AphidNodeType.IdentifierExpression)
            {
                return null;
            }

            var id = expression.ToIdentifier();
            var attributes = AphidAttributeParser.Parse<DeclarativeStatementAttributes>(id);
            var nameId = new IdentifierExpression(attributes.Name);

            if (_tokenTypes.Contains(id.Identifier))
            {
                hasChanged = true;

                var match = new CallExpression(
                    new IdentifierExpression("Match"),
                    new IdentifierExpression(id.Identifier));

                return attributes.Name == null ?
                    new List<AphidExpression> { match, } :
                    new List<AphidExpression>
                    {
                        new BinaryOperatorExpression(
                            nameId,
                            AphidTokenType.AssignmentOperator,
                            new IdentifierExpression("TokenType")),
                        match,
                    };
            }
            else if (_parseFunctions.Contains(id.Identifier))
            {
                hasChanged = true;
                var call = new CallExpression(new IdentifierExpression(id.Identifier));

                return attributes.Name == null ?
                    new List<AphidExpression> { call } :
                    new List<AphidExpression>
                    {
                        new BinaryOperatorExpression(
                            nameId,
                            AphidTokenType.AssignmentOperator,
                            call)
                    };
            }
            else if (id.Identifier == "NextToken")
            {
                hasChanged = true;

                return new List<AphidExpression>
                {
                    new CallExpression(new IdentifierExpression(id.Identifier))
                };
            }

            return null;
        }
コード例 #4
0
 public TernaryOperatorExpression(
     AphidTokenType op,
     AphidExpression firstOperand,
     AphidExpression secondOperand,
     AphidExpression thirdOperand)
 {
     Operator = op;
     FirstOperand = firstOperand;
     SecondOperand = secondOperand;
     ThirdOperand = thirdOperand;
 }
コード例 #5
0
 public ForExpression(
     AphidExpression initialization,
     AphidExpression condition,
     AphidExpression afterthought,
     List<AphidExpression> body)
 {
     Initialization = initialization;
     Condition = condition;
     Afterthought = afterthought;
     Body = body;
 }
コード例 #6
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            var idExp = expression as IdentifierExpression;

            AphidExpression argument;

            if (idExp == null || !_arguments.TryGetValue(idExp.Identifier, out argument))
            {
                hasChanged = false;

                return null;
            }

            hasChanged = true;

            return new List<AphidExpression> { argument };
        }
コード例 #7
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            hasChanged = false;

            switch (expression.Type)
            {
                case AphidNodeType.BinaryOperatorExpression:
                    var binOpExp = (BinaryOperatorExpression)expression;

                    if (binOpExp.Operator == AphidTokenType.AssignmentOperator &&
                        binOpExp.LeftOperand.Type == AphidNodeType.IdentifierExpression &&
                        binOpExp.RightOperand.Type == AphidNodeType.ObjectExpression)
                    {
                        hasChanged = true;

                        _typeResolver.InterpretType(
                            (IdentifierExpression)binOpExp.LeftOperand,
                            (ObjectExpression)binOpExp.RightOperand);

                        return new List<AphidExpression>();
                    }
                    else if (binOpExp.Operator == AphidTokenType.MemberOperator)
                    {
                        hasChanged = true;

                        return MutateMemberExpression(binOpExp);
                    }

                    break;

                case AphidNodeType.IdentifierExpression:

                    var id = (IdentifierExpression)expression;

                    if (IsRegister(id.Identifier) && id.Attributes.Any())
                    {
                        var type = _typeResolver.GetType(id);
                        _registerTypeTable.Add(id.Identifier, type);
                    }

                    break;
            }

            return null;
        }
コード例 #8
0
        private string[] FlattenMembers(AphidExpression memberExpression)
        {
            switch (memberExpression.Type)
            {
                case AphidNodeType.IdentifierExpression:
                    return new[] { ((IdentifierExpression)memberExpression).Identifier };

                case AphidNodeType.BinaryOperatorExpression:
                    var binOpExp = (BinaryOperatorExpression)memberExpression;

                    return FlattenMembers(binOpExp.LeftOperand)
                        .Concat(FlattenMembers(binOpExp.RightOperand))
                        .ToArray();

                default:
                    throw new InvalidOperationException();
            }
        }
コード例 #9
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            if (!(expression is LoadScriptExpression))
            {
                hasChanged = false;

                return null;
            }

            hasChanged = true;

            var str = ((StringExpression)((LoadScriptExpression)expression).FileExpression).Value;
            str = StringParser.Parse(str);

            var strFile = new AphidLoader(null).FindScriptFile(str);

            return AphidParser.Parse(File.ReadAllText(strFile));
        }
コード例 #10
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            BinaryOperatorExpression binOpExp;

            if (expression.Type != AphidNodeType.BinaryOperatorExpression ||
                (binOpExp = (BinaryOperatorExpression)expression).Operator != AphidTokenType.PipelineOperator)
            {
                hasChanged = false;

                return null;
            }

            hasChanged = true;

            return new List<AphidExpression>
            {
                new CallExpression(binOpExp.RightOperand, binOpExp.LeftOperand)
            };
        }
コード例 #11
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            var call = expression as CallExpression;
            string funcName = null;

            if (call != null)
            {
                var id = call.FunctionExpression as IdentifierExpression;

                if (id != null)
                {
                    funcName = id.Identifier;
                }
            }

            if (funcName == null || _mnemonics.Contains(funcName))
            {
                hasChanged = false;

                return null;
            }

            var mutated = new List<AphidExpression>();
            mutated.AddRange(call.Args.Reverse().Select(CreatePush));
            mutated.Add(new CallExpression(
                new IdentifierExpression(InstructionMnemonic.Call),
                call.FunctionExpression));

            var argSize = call.Args.Count() * 4;

            if (argSize != 0)
            {
                mutated.Add(new BinaryOperatorExpression(
                    new IdentifierExpression("r0"),
                    AphidTokenType.PlusEqualOperator,
                    new NumberExpression(argSize)));
            }

            hasChanged = true;

            return mutated;
        }
コード例 #12
0
ファイル: AphidMacroMutator.cs プロジェクト: robocoder/aphid
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            var callExp = expression as CallExpression;

            if (callExp == null)
            {
                hasChanged = false;

                return null;
            }

            var callIdExp = callExp.FunctionExpression as IdentifierExpression;

            AphidMacro macro;

            if (callIdExp == null || !_macros.TryGetValue(callIdExp.Identifier, out macro))
            {
                hasChanged = false;

                return null;
            }

            hasChanged = true;

            var argTable = callExp.Args
                .Select((x, i) => new
                {
                    Name = (IdentifierExpression)macro.Declaration.Args[i],
                    Value = x,
                })
                .ToDictionary(x => x.Name.Identifier, x => x.Value);

            var bodyMutator = new AphidMacroBodyMutator(argTable);
            var mutatedBody = bodyMutator.Mutate(macro.Declaration.Body);

            return mutatedBody;
        }
コード例 #13
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            hasChanged = false;

            CallExpression call;
            IdentifierExpression id;

            // Todo: handle member access e.g. decimal.Parse
            if (expression.Type == AphidNodeType.CallExpression &&
                (call = expression.ToCall()).FunctionExpression.Type == AphidNodeType.IdentifierExpression &&
                _parseFunctions.Contains(call.FunctionExpression.ToIdentifier().Identifier))
            {
                _skip = true;
            }
            //else if (expression.Type == AphidNodeType.BinaryOperatorExpression &&
            //    (binOp = expression.ToBinaryOperator()).LeftOperand.Type == AphidNodeType.IdentifierExpression &&
            //    _parseFunctions.Contains(binOp.LeftOperand.ToIdentifier().Identifier))
            //{
            //    _skip = true;
            //}
            else if (expression.Type == AphidNodeType.IdentifierExpression &&
                _parseFunctions.Contains((id = expression.ToIdentifier()).Identifier))
            {
                if (_skip)
                {
                    _skip = false;
                }
                else
                {
                    hasChanged = true;

                    return new List<AphidExpression> { new CallExpression(id) };
                }
            }

            return null;
        }
コード例 #14
0
ファイル: PlusEqualMutator.cs プロジェクト: robocoder/aphid
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            BinaryOperatorExpression binOpExp;

            if (expression.Type != AphidNodeType.BinaryOperatorExpression ||
                (binOpExp = expression.ToBinaryOperator()).Operator != AphidTokenType.PlusEqualOperator)
            {
                hasChanged = false;

                return null;
            }

            hasChanged = true;

            return new List<AphidExpression>
            {
                new CallExpression(
                    new BinaryOperatorExpression(
                        binOpExp.LeftOperand,
                        AphidTokenType.MemberOperator,
                        new IdentifierExpression("Add")),
                    binOpExp.RightOperand)
            };
        }
コード例 #15
0
ファイル: SwitchExpression.cs プロジェクト: robocoder/aphid
 public SwitchExpression(AphidExpression expression, List<SwitchCase> cases, List<AphidExpression> defaultCase)
 {
     Expression = expression;
     Cases = cases;
     DefaultCase = defaultCase;
 }
コード例 #16
0
 public PatternMatchingExpression(AphidExpression testExpression, List<PatternExpression> patterns)
 {
     TestExpression = testExpression;
     Patterns = patterns;
 }
コード例 #17
0
 public static TryExpression ToTry(this AphidExpression expression) => (TryExpression)expression;
コード例 #18
0
 public static WhileExpression ToWhile(this AphidExpression expression) => (WhileExpression)expression;
コード例 #19
0
ファイル: CallExpression.cs プロジェクト: robocoder/aphid
 public CallExpression(AphidExpression functionExpression)
     : this(functionExpression, new AphidExpression[0])
 {
 }
コード例 #20
0
 public static ForEachExpression ToForEach(this AphidExpression expression) => (ForEachExpression)expression;
コード例 #21
0
ファイル: AphidMutator.cs プロジェクト: robocoder/aphid
 protected abstract List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged);
コード例 #22
0
 public static NumberExpression ToNumber(this AphidExpression expression) => (NumberExpression)expression;
コード例 #23
0
 public static ArrayAccessExpression ToArrayAccess(this AphidExpression expression) => (ArrayAccessExpression)expression;
コード例 #24
0
 public static DynamicMemberExpression ToDynamicMember(this AphidExpression expression) => (DynamicMemberExpression)expression;
コード例 #25
0
 public static IfExpression ToIf(this AphidExpression expression) => (IfExpression)expression;
コード例 #26
0
 public static StringExpression ToString(this AphidExpression expression) => (StringExpression)expression;
コード例 #27
0
 public IfExpression(AphidExpression condition, List<AphidExpression> body, List<AphidExpression> elseBody)
     : base(AphidTokenType.ifKeyword, condition, body)
 {
     ElseBody = elseBody;
 }
コード例 #28
0
 internal PartialFunctionExpression(
     AphidExpressionContext context,
     AphidExpression call)
     : this(context, (CallExpression)call)
 {
 }
コード例 #29
0
 protected virtual void EndExpression(AphidExpression expression)
 {
 }
コード例 #30
0
 public static ArrayExpression ToArray(this AphidExpression expression) => (ArrayExpression)expression;
コード例 #31
0
 public static BinaryOperatorExpression ToBinaryOperator(this AphidExpression expression) => (BinaryOperatorExpression)expression;
コード例 #32
0
 public static UnaryOperatorExpression ToUnaryOperator(this AphidExpression expression) => (UnaryOperatorExpression)expression;
コード例 #33
0
 public static BooleanExpression ToBoolean(this AphidExpression expression) => (BooleanExpression)expression;
コード例 #34
0
 public static SwitchExpression ToSwitch(this AphidExpression expression) => (SwitchExpression)expression;
コード例 #35
0
ファイル: CallExpression.cs プロジェクト: robocoder/aphid
 public CallExpression(AphidExpression functionExpression, IEnumerable<AphidExpression> args)
 {
     FunctionExpression = functionExpression;
     Args = args;
 }
コード例 #36
0
        public (int, int) ResolvePosition(List <AphidExpression> ast, AphidExpression expression)
        {
            if (expression == null)
            {
                Program.Log("Resolving line for expression null");
                return(0, 0);
            }

            var lineIndexes = GetLineIndexes(expression.Code);

            //Program.Log(
            //    "Line indexes: {0}",
            //    JsonSerializer.Serialize(lineIndexes));

            IndexTable = new AphidIndexVisitor().GetIndexTable(ast);

            if (lineIndexes.Length == 0)
            {
                return(0, 0);
            }
            //Program.Log(
            //    "Index table: {0}",
            //    JsonSerializer.Serialize(IndexTable.Select(x => x.Key).ToArray()));

            var lineMatch = lineIndexes
                            .Select((x, i) => new { Index = x, Line = i })
                            .FirstOrDefault(x => x.Index >= expression.Index);

            if (lineMatch != null)
            {
                int line, col;
                if (expression.Index == 0)
                {
                    line = 1;
                    col  = 1;
                }
                else
                {
                    line = lineMatch.Line;
                    col  = expression.Index - lineIndexes[lineMatch.Line - 1];
                }

                Program.Log(
                    "Expression {0} at index {1} resolved to line {2} col {3}",
                    expression,
                    expression.Index,
                    lineMatch.Line,
                    col);

                return(line, col);
            }
            else
            {
                Program.Log(
                    "Expression {0} at index {1} guessed to be on to line {2}",
                    expression,
                    expression.Index,
                    lineIndexes.Length);



                return(lineIndexes.Length, expression.Index - lineIndexes[lineIndexes.Length - 1]);
            }
        }
コード例 #37
0
ファイル: CallExpression.cs プロジェクト: robocoder/aphid
 public CallExpression(AphidExpression functionExpression, AphidExpression expression)
     : this(functionExpression, new[] { expression })
 {
 }
コード例 #38
0
ファイル: ForUnrollMutator.cs プロジェクト: 5l1v3r1/Aphid
        protected override List <AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            hasChanged = false;

            if (expression.Type != AphidExpressionType.ForExpression)
            {
                return(null);
            }

            hasChanged = true;

            var forExp = (ForExpression)expression;

            if (forExp.Initialization.Type != AphidExpressionType.BinaryOperatorExpression)
            {
                throw new InvalidOperationException();
            }

            var initExp = (BinaryOperatorExpression)forExp.Initialization;

            if (initExp.Operator != AphidTokenType.AssignmentOperator ||
                initExp.LeftOperand.Type != AphidExpressionType.IdentifierExpression ||
                initExp.RightOperand.Type != AphidExpressionType.NumberExpression)
            {
                throw new InvalidOperationException();
            }

            var id          = ((IdentifierExpression)initExp.LeftOperand).Identifier;
            var interpreter = new AphidInterpreter();

            interpreter.Interpret(new List <AphidExpression> {
                initExp
            });

            var key = "$condition_" + Guid.NewGuid().ToString().Replace('-', '_');

            interpreter.Interpret(
                new List <AphidExpression>
            {
                new IdentifierExpression(
                    key,
                    new List <IdentifierExpression>
                {
                    new IdentifierExpression(AphidName.Var)
                })
            });

            var condition = new BinaryOperatorExpression(
                new IdentifierExpression(key).WithPositionFrom(forExp.Condition),
                AphidTokenType.AssignmentOperator,
                forExp.Condition)
                            .WithPositionFrom(forExp.Condition);

            bool conditionResult;
            var  unrolled = new List <AphidExpression>();

            while (true)
            {
                interpreter.Interpret(new List <AphidExpression> {
                    condition
                });
                conditionResult = (bool)interpreter.CurrentScope[key].Value;

                if (!conditionResult)
                {
                    break;
                }

                var value = (decimal)interpreter.CurrentScope[id].Value;

                var replaceMutator = new ReplacementMutator(
                    x =>
                    x.Type == AphidExpressionType.IdentifierExpression &&
                    ((IdentifierExpression)x).Identifier == id,
                    x => new List <AphidExpression> {
                    new NumberExpression(value)
                });

                unrolled.AddRange(replaceMutator.MutateRecursively(forExp.Body));

                interpreter.Interpret(new List <AphidExpression> {
                    forExp.Afterthought
                });
            }

            return(unrolled);
        }
コード例 #39
0
 private static string GetType(AphidExpression expression) =>
 expression?.Type.ToString();
コード例 #40
0
 public static ThisExpression ToThis(this AphidExpression expression) => (ThisExpression)expression;
コード例 #41
0
 public PartialFunctionExpression(AphidExpression call)
     : this((CallExpression)call)
 {
 }
コード例 #42
0
 private static bool IsValid(AphidExpression expression) =>
 expression?.Context != null &&
 expression.Index != -1 &&
 expression.Length > 0;
コード例 #43
0
 public LoadScriptExpression(AphidExpression fileExpression)
 {
     FileExpression = fileExpression;
 }
コード例 #44
0
 private static bool HasType(AphidExpression expression) =>
 expression != null;
コード例 #45
0
 private static void AppendCode(StringBuilder sb, AphidExpression expression) =>
 sb.AppendFormat(" '{0}'", expression.ToString().Trim());
コード例 #46
0
 private static void AppendFrom(StringBuilder sb, AphidExpression expression) =>
 sb.AppendFormat(" from {0}", FormatType(expression, isStmt: true));
コード例 #47
0
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            hasChanged = false;

            if (IsStatement && expression.Type == AphidNodeType.IdentifierExpression)
            {
                var idExp = expression.ToIdentifier();
                var currentId = ParserIdentifier.FromIdentifierExpression(idExp);
                ParserIdentifier inferredId;

                if (!_idTable.TryResolve(idExp.Identifier, out inferredId))
                {
                    _idTable.Add(idExp.Identifier, currentId);
                    hasChanged = true;
                }
                else
                {
                    if (!currentId.IsList && inferredId.IsList)
                    {
                        currentId.IsList = inferredId.IsList;
                        currentId.Type = inferredId.Type;
                        hasChanged = true;

                        return new List<AphidExpression>
                        {
                            new BinaryOperatorExpression(
                                currentId.ToIdentifierExpression(),
                                AphidTokenType.AssignmentOperator,
                                new IdentifierExpression(
                                    currentId.Type ?? _config.BaseClass,
                                    new List<IdentifierExpression> { new IdentifierExpression("list") }))
                        };
                    }
                }
            }

            CallExpression funcExp;
            BinaryOperatorExpression binOpExp;

            if (expression.Type == AphidNodeType.CallExpression &&
                (funcExp = expression.ToCall()).FunctionExpression.Type == AphidNodeType.BinaryOperatorExpression &&
                ((binOpExp = funcExp.FunctionExpression.ToBinaryOperator()).Operator == AphidTokenType.MemberOperator) &&
                binOpExp.LeftOperand.Type == AphidNodeType.IdentifierExpression &&
                binOpExp.RightOperand.Type == AphidNodeType.IdentifierExpression &&
                binOpExp.RightOperand.ToIdentifier().Identifier == "Add")
            {
                var id = binOpExp.LeftOperand.ToIdentifier().Identifier;
                ParserIdentifier ids;

                if (!_idTable.TryResolve(id, out ids))
                {
                    _idTable.Add(id, ids = new ParserIdentifier() { Name = id });
                }

                if (!ids.IsList)
                {
                    ids.IsList = true;

                    if (ids.Type == null)
                    {
                        ids.Type = _config.BaseClass;
                    }

                    hasChanged = true;
                }
            }

            UnaryOperatorExpression unOpExp;

            if (expression.Type == AphidNodeType.UnaryOperatorExpression &&
                (unOpExp = expression.ToUnaryOperator()).Operator == AphidTokenType.retKeyword)
            {
                if (unOpExp.Operand.Type == AphidNodeType.IdentifierExpression)
                {
                    var retId = unOpExp.Operand.ToIdentifier();

                    if (!_returnIds.Contains(retId.Identifier))
                    {
                        hasChanged = true;
                        _returnIds.Add(retId.Identifier);
                    }
                }
            }
            //else if (expression.Type == AphidNodeType.BinaryOperatorExpression &&
            //    (binOpExp = expression.ToBinaryOperator()).

            return new List<AphidExpression> { expression };
            //throw new NotImplementedException();
        }
コード例 #48
0
        private static void TryAppendFile(StringBuilder sb, AphidExpression expression, AphidExpression statement)
        {
            var file =
                expression?.Filename != null ?
                expression.Filename :
                statement?.Filename != null ?
                statement.Filename :
                null;

            if (file != null)
            {
                sb.AppendFormat(" in script {0}", file);
            }
        }
コード例 #49
0
 public WhileExpression(AphidExpression condition, List<AphidExpression> body)
     : base(AphidTokenType.whileKeyword, condition, body)
 {
 }
コード例 #50
0
 public static PatternMatchingExpression ToPatternMatching(this AphidExpression expression) => (PatternMatchingExpression)expression;
コード例 #51
0
ファイル: AphidMutator.cs プロジェクト: robocoder/aphid
 private AphidExpression MutateSingle(AphidExpression expression)
 {
     return Mutate(expression).Single();
 }
コード例 #52
0
 private bool IsMember(AphidExpression expression) =>
 expression?.Type == AphidExpressionType.BinaryOperatorExpression &&
 Ancestors.Count >= 1 &&
 Ancestors.Peek().Type == AphidExpressionType.ObjectExpression;
コード例 #53
0
ファイル: AphidMutator.cs プロジェクト: robocoder/aphid
        private List<AphidExpression> Mutate(AphidExpression expression)
        {
            bool hasChanged;
            var mutated = MutateCore(expression, out hasChanged);

            if (hasChanged)
            {
                HasMutated = true;
                return mutated.SelectMany(Mutate).ToList();
            }

            IsStatement = false;
            var expanded = new List<AphidExpression>();

            switch (expression.Type)
            {
                case AphidNodeType.IdentifierExpression:
                    var id = (IdentifierExpression)expression;

                    expanded.Add(new IdentifierExpression(
                        id.Identifier,
                        id.Attributes
                            .Select(x => (IdentifierExpression)Mutate(x).Single())
                            .ToList()));
                    break;

                case AphidNodeType.CallExpression:
                    var call = (CallExpression)expression;

                    expanded.Add(new CallExpression(
                        Mutate(call.FunctionExpression).Single(),
                        call.Args.Select(x => Mutate(x).Single()).ToArray()));

                    break;

                case AphidNodeType.UnaryOperatorExpression:
                    var unOp = (UnaryOperatorExpression)expression;

                    expanded.Add(new UnaryOperatorExpression(
                        unOp.Operator,
                        Mutate(unOp.Operand).Single())
                        {
                            IsPostfix = unOp.IsPostfix
                        });

                    break;

                case AphidNodeType.BinaryOperatorExpression:
                    var binOp = (BinaryOperatorExpression)expression;

                    expanded.Add(new BinaryOperatorExpression(
                        Mutate(binOp.LeftOperand).Single(),
                        binOp.Operator,
                        Mutate(binOp.RightOperand).Single()));

                    break;

                case AphidNodeType.SwitchExpression:
                    var switchExp = (SwitchExpression)expression;

                    expanded.Add(new SwitchExpression()
                    {
                        Expression = MutateSingle(switchExp.Expression),
                        Cases = switchExp.Cases
                            .Select(x => new SwitchCase()
                            {
                                Cases = x.Cases.Select(MutateSingle).ToList(),
                                Body = Mutate(x.Body),
                            })
                            .ToList(),
                        DefaultCase = Mutate(switchExp.DefaultCase),
                    });

                    break;

                case AphidNodeType.IfExpression:
                    var ifExp = (IfExpression)expression;

                    expanded.Add(new IfExpression(
                        Mutate(ifExp.Condition).Single(),
                        Mutate(ifExp.Body),
                        Mutate(ifExp.ElseBody)));

                    break;

                case AphidNodeType.ForExpression:
                    var forExp = (ForExpression)expression;

                    expanded.Add(new ForExpression(
                        Mutate(forExp.Initialization).Single(),
                        Mutate(forExp.Condition).Single(),
                        Mutate(forExp.Afterthought).Single(),
                        Mutate(forExp.Body)));

                    break;

                case AphidNodeType.ForEachExpression:
                    var forEachExp = (ForEachExpression)expression;

                    expanded.Add(
                        new ForEachExpression(
                            Mutate(forEachExp.Collection).Single(),
                            Mutate(forEachExp.Element).Single(),
                            Mutate(forEachExp.Body)));

                    break;

                case AphidNodeType.WhileExpression:
                    var cfExp = (WhileExpression)expression;
                    expanded.Add(new WhileExpression(Mutate(cfExp.Condition).Single(), Mutate(cfExp.Body)));
                    break;

                case AphidNodeType.DoWhileExpression:
                    var dwExp = (DoWhileExpression)expression;
                    expanded.Add(new DoWhileExpression(Mutate(dwExp.Condition).Single(), Mutate(dwExp.Body)));
                    break;

                case AphidNodeType.LoadScriptExpression:
                    var lsExp = (LoadScriptExpression)expression;
                    expanded.Add(new LoadScriptExpression(Mutate(lsExp.FileExpression).Single()));
                    break;

                case AphidNodeType.LoadLibraryExpression:
                    var llExp = (LoadLibraryExpression)expression;
                    expanded.Add(new LoadLibraryExpression(Mutate(llExp.LibraryExpression).Single()));
                    break;

                case AphidNodeType.FunctionExpression:
                    var funcExp = (FunctionExpression)expression;

                    expanded.Add(new FunctionExpression()
                    {
                        Args = funcExp.Args.Select(x => Mutate(x).Single()).ToList(),
                        Body = Mutate(funcExp.Body)
                    });

                    break;

                case AphidNodeType.ArrayExpression:
                    var arrayExp = (ArrayExpression)expression;

                    expanded.Add(new ArrayExpression()
                    {
                        Elements = arrayExp.Elements.Select(x => Mutate(x).Single()).ToList()
                    });

                    break;

                case AphidNodeType.ArrayAccessExpression:
                    var arrayAccessExp = (ArrayAccessExpression)expression;

                    expanded.Add(new ArrayAccessExpression(
                        Mutate(arrayAccessExp.ArrayExpression).Single(),
                        Mutate(arrayAccessExp.KeyExpression).Single()));

                    break;

                case AphidNodeType.ObjectExpression:
                    var pairs = ((ObjectExpression)expression).Pairs
                        .Select(x => (BinaryOperatorExpression)Mutate(x).Single())
                        .ToList();

                    expanded.Add(new ObjectExpression(pairs));
                    break;

                case AphidNodeType.ExtendExpression:
                    var extendExp = (ExtendExpression)expression;

                    expanded.Add(new ExtendExpression(
                        extendExp.ExtendType,
                        (ObjectExpression)Mutate(extendExp.Object).Single()));

                    break;

                case AphidNodeType.TernaryOperatorExpression:
                    var terExp = (TernaryOperatorExpression)expression;

                    expanded.Add(
                        new TernaryOperatorExpression(
                            terExp.Operator,
                            Mutate(terExp.FirstOperand).Single(),
                            Mutate(terExp.SecondOperand).Single(),
                            Mutate(terExp.ThirdOperand).Single()));

                    break;

                case AphidNodeType.DynamicMemberExpression:
                    var dynExp = (DynamicMemberExpression)expression;

                    expanded.Add(
                        new DynamicMemberExpression(
                            Mutate(dynExp.MemberExpression).Single()));

                    break;

                default:
                    if (expression is IParentNode)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        expanded.Add(expression);
                    }

                    break;
            }

            return expanded;
        }
コード例 #54
0
 private static bool IsArray(AphidExpression expression) =>
 expression?.Type == AphidExpressionType.ArrayExpression;
コード例 #55
0
 public PartialFunctionExpression(AphidExpression call)
     : this((CallExpression)call)
 {
 }
コード例 #56
0
 private static bool IsRef(AphidExpression expression) =>
 expression.Type == AphidExpressionType.IdentifierExpression ||
 expression.Type == AphidExpressionType.BinaryOperatorExpression;
コード例 #57
0
 public LoadLibraryExpression(AphidExpression libraryExpression)
 {
     LibraryExpression = libraryExpression;
 }
コード例 #58
0
 public DynamicMemberExpression(AphidExpression memberExpression)
 {
     MemberExpression = memberExpression;
 }
コード例 #59
0
 public ControlFlowExpression(AphidTokenType type, AphidExpression condition, List<AphidExpression> body)
 {
     ControlFlowType = type;
     Condition = condition;
     Body = body;
 }
コード例 #60
0
 public static TernaryOperatorExpression ToTernaryOperator(this AphidExpression expression) => (TernaryOperatorExpression)expression;