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;
        }
예제 #2
0
        public Expression ParseCallExpression()
        {
            var function = ParseMemberExpression();

            while (_currentToken.TokenType == AphidTokenType.LeftParenthesis)
            {
                NextToken();
                if (_currentToken.TokenType == AphidTokenType.RightParenthesis)
                {
                    NextToken();
                    function = new CallExpression(function);
                }
                else
                {
                    var args = ParseTuple();
                    Match(AphidTokenType.RightParenthesis);
                    function = new CallExpression(function, args);
                }
            }

            return(function);
        }
예제 #3
0
        protected override List <Exp> MutateCore(
            Exp expression,
            out bool hasChanged)
        {
            CallExpression       callExp;
            IdentifierExpression idExp;

            if (expression.Type != ET.CallExpression ||
                (callExp = ((CallExpression)expression)).FunctionExpression.Type != ET.IdentifierExpression ||
                (idExp = (IdentifierExpression)callExp.FunctionExpression).Attributes.Count == 0)
            {
                hasChanged = false;

                return(null);
            }


            var nestedCallExp = new CallExpression(idExp.Attributes[0]);

            for (var i = 0; i < idExp.Attributes.Count - 1; i++)
            {
                nestedCallExp = new CallExpression(idExp.Attributes[i + 1], new List <Exp> {
                    nestedCallExp
                });
            }


            hasChanged = true;

            return(new List <Exp> {
                new CallExpression(
                    callExp.FunctionExpression,
                    new List <Exp>(callExp.Args)
                {
                    nestedCallExp
                })
            });
        }
예제 #4
0
        public Expression ParseCallExpression(Expression expression)
        {
            while (_currentToken.TokenType == AphidTokenType.LeftParenthesis)
            {
                NextToken();
                if (_currentToken.TokenType == AphidTokenType.RightParenthesis)
                {
                    NextToken();
                    expression = new CallExpression(expression);
                }
                else
                {
                    var args = ParseTuple();
                    Match(AphidTokenType.RightParenthesis);
                    expression = new CallExpression(expression, args);
                }
            }

            return expression;
        }
예제 #5
0
        public Expression ParseCallExpression()
        {
            var function = ParseMemberExpression();

            while (_currentToken.TokenType == AphidTokenType.LeftParenthesis)
            {
                NextToken();
                if (_currentToken.TokenType == AphidTokenType.RightParenthesis)
                {
                    NextToken();
                    function = new CallExpression(function);
                }
                else
                {
                    var args = ParseTuple();
                    Match(AphidTokenType.RightParenthesis);
                    function = new CallExpression(function, args);
                }
            }

            return function;
        }
 public PartialFunctionExpression(CallExpression call)
 {
     Call = call;
 }
        private object InterpretCallExpression(CallExpression expression)
        {
            var value = InterpretExpression(expression.FunctionExpression);

            object funcExp = ValueHelper.Unwrap(value);

            var func = funcExp as AphidInteropFunction;

            if (func == null)
            {
                var func2 = funcExp as AphidFunction;

                if (func2 == null)
                {
                    throw new AphidRuntimeException("Could not find function {0}", expression.FunctionExpression);
                }

                return CallFunctionCore(func2, expression.Args.Select(x => ValueHelper.Wrap(InterpretExpression(x))));
            }
            else
            {
                Func<Expression, object> selector;

                if (func.UnwrapParameters)
                {
                    selector = x => ValueHelper.Unwrap(InterpretExpression(x));
                }
                else
                {
                    selector = x => InterpretExpression(x);
                }

                var args = expression.Args.Select(selector).ToArray();

                var retVal = ValueHelper.Wrap(func.Invoke(this, args));

                if (retVal.Value is List<AphidObject> ||
                    retVal.Value is string)
                {
                    CallInitFunction(retVal);
                    //InitList(retVal);
                }

                return retVal;
            }
        }
예제 #8
0
        private AphidObject InterpretCallExpression(CallExpression expression)
        {
            var value = InterpretExpression(expression.FunctionExpression);

            object funcExp = ValueHelper.Unwrap(value);

            var func = funcExp as AphidInteropFunction;

            if (func == null)
            {
                var func2 = funcExp as AphidFunction;

                if (func2 == null)
                {
                    throw new AphidRuntimeException("Could not find function {0}", expression.FunctionExpression);
                }

                return CallFunctionCore(func2, expression.Args.Select(x => ValueHelper.Wrap(InterpretExpression(x))));
            }
            else
            {
                Func<AphidExpression, object> selector;

                if (func.UnwrapParameters)
                {
                    selector = x => ValueHelper.Unwrap(InterpretExpression(x));
                }
                else
                {
                    selector = x =>
                    {
                        var r = InterpretExpression(x);

                        if (r == null)
                        {
                            throw new AphidRuntimeException(
                                "Could not find variable {0} in call expression {1}",
                                x,
                                expression);
                        }

                        return r;
                    };
                }

                var args = expression.Args.Select(selector).ToArray();

                return ValueHelper.Wrap(func.Invoke(this, args));
            }
        }
예제 #9
0
        public byte[] AssembleCallExpression(CallExpression expression)
        {
            var b = new byte[5];
            var funcName = ((IdentifierExpression)expression.FunctionExpression).Identifier;

            switch (funcName)
            {
                case InstructionMnemonic.Out0:
                case InstructionMnemonic.Out1:
                case InstructionMnemonic.Out2:
                case InstructionMnemonic.Out3:
                    var id = expression.Args.Cast<IdentifierExpression>().Single().Identifier;
                    b[0] = (byte)InstructionOpcode.Ext;
                    b[1] = (byte)InstructionSubOpcode.Out;
                    b[2] = byte.Parse(funcName[3].ToString());
                    b[3] = (byte)OpcodeTable.RegisterTable[id];

                    break;

                case InstructionMnemonic.Goto:
                case InstructionMnemonic.GotoTrue:
                case InstructionMnemonic.GotoFalse:
                    id = expression.Args.Cast<IdentifierExpression>().Single().Identifier;

                    InstructionOpcode oc;

                    switch (funcName)
                    {
                        case InstructionMnemonic.Goto:
                            oc = InstructionOpcode.Goto_Const;
                            break;

                        case InstructionMnemonic.GotoTrue:
                            oc = InstructionOpcode.Goto_Eq;
                            break;

                        case InstructionMnemonic.GotoFalse:
                            oc = InstructionOpcode.Goto_NotEq;
                            break;

                        default:
                            throw new InvalidOperationException();
                    }

                    b[0] = (byte)oc;

                    if (!_labels.ContainsKey(id))
                    {
                        _needLabelAddresses.Add(new KeyValuePair<string, byte[]>(id, b));
                        //throw new InvalidOperationException();
                    }
                    else
                    {
                        GetBytes(_labels[id]).CopyTo(b, 1);
                    }

                    break;

                case InstructionMnemonic.Read:
                case InstructionMnemonic.Write:
                    var id2 = ((IdentifierExpression)expression.Args.ToArray()[0]).Identifier;
                    var id3 = ((IdentifierExpression)expression.Args.ToArray()[1]).Identifier;
                    b[0] = (byte)InstructionOpcode.ExtMultiStage;

                    switch (funcName)
                    {
                        case InstructionMnemonic.Read:
                            b[1] = (byte)InstructionMultiStageSubOpcode.Read;
                            break;

                        case InstructionMnemonic.Write:
                            b[1] = (byte)InstructionMultiStageSubOpcode.Write;
                            break;

                        default:
                            throw new InvalidOperationException();
                    }

                    b[2] = (byte)OpcodeTable.RegisterTable[id2];
                    b[3] = (byte)OpcodeTable.RegisterTable[id3];
                    break;

                case InstructionMnemonic.Error:
                    b = new[]
                    {
                        (byte)InstructionOpcode.Error,
                        (byte)InstructionOpcode.Error,
                        (byte)InstructionOpcode.Error,
                        (byte)InstructionOpcode.Error,
                        (byte)InstructionOpcode.Error,
                    };
                    break;

                case InstructionMnemonic.Data:
                    var exp = expression.Args.Single();

                    if (exp is StringExpression)
                    {
                        return StringParser
                            .Parse(((StringExpression)exp).Value)
                            .Select(x => (byte)x)
                            .ToArray();
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }

                case InstructionMnemonic.Push:
                case InstructionMnemonic.Pop:
                    exp = expression.Args.Single();

                    if (exp is IdentifierExpression)
                    {
                        var ppId = ((IdentifierExpression)exp).Identifier;

                        if (OpcodeTable.RegisterTable.ContainsKey(ppId))
                        {
                            b[0] = (byte)InstructionOpcode.ExtMultiStage;

                            switch (funcName)
                            {
                                case InstructionMnemonic.Push:
                                    b[1] = (byte)InstructionMultiStageSubOpcode.Push_R;
                                    break;

                                case InstructionMnemonic.Pop:
                                    b[1] = (byte)InstructionMultiStageSubOpcode.Pop_R;
                                    break;

                                default:
                                    throw new InvalidOperationException();
                            }

                            b[2] = (byte)OpcodeTable.RegisterTable[ppId];
                        }
                        else
                        {
                            switch (funcName)
                            {
                                case InstructionMnemonic.Push:
                                    b[0] = (byte)InstructionOpcode.Push_Const;
                                    break;

                                default:
                                    throw new InvalidOperationException();
                            }

                            if (_labels.ContainsKey(ppId))
                            {
                                GetBytes(_labels[ppId]).CopyTo(b, 1);
                            }
                            else
                            {
                                _needLabelAddresses.Add(new KeyValuePair<string, byte[]>(ppId, b));
                            }
                        }
                    }
                    else if (exp is NumberExpression)
                    {
                        b[0] = (byte)InstructionOpcode.Push_Const;

                        BitConverter
                            .GetBytes(GetUInt(exp))
                            .Reverse()
                            .ToArray()
                            .CopyTo(b, 1);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    break;

                case InstructionMnemonic.Call:
                    exp = expression.Args.Single();
                    var idArg = ((IdentifierExpression)exp).Identifier;

                    if (OpcodeTable.RegisterTable.ContainsKey(idArg))
                    {
                        b[0] = (byte)InstructionOpcode.ExtMultiStage;
                        b[1] = (byte)InstructionMultiStageSubOpcode.Call_R;
                        b[2] = (byte)OpcodeTable.RegisterTable[idArg];
                    }
                    else
                    {
                        b[0] = (byte)InstructionOpcode.Call_Const;

                        if (_labels.ContainsKey(idArg))
                        {
                            GetBytes(_labels[idArg]).CopyTo(b, 1);
                        }
                        else
                        {
                            _needLabelAddresses.Add(new KeyValuePair<string, byte[]>(
                                idArg, b));
                        }
                    }

                    break;

                case InstructionMnemonic.Return:
                    if (expression.Args.Any())
                    {
                        throw new NotImplementedException();
                    }

                    b[0] = (byte)InstructionOpcode.ExtMultiStage;
                    b[1] = (byte)InstructionMultiStageSubOpcode.Return;

                    break;

                default:
                    throw new InvalidOperationException();
            }

            return b;
        }
예제 #10
0
        private CodeStatementCollection GenerateMatchZeroOrMany(CallExpression node)
        {
            if (node.Args.Count() != 2)
            {
                throw new NotImplementedException();
            }

            var peek = node.Args.First();
            string peekVarName;
            var peekCode = GeneratePeek(peek, out peekVarName);

            var statements = new List<CodeStatement>();

            if (peekVarName != null)
            {
                _locals.Add(peekVarName, _config.TokenType);
                statements.Add(CodeHelper.Assign(peekVarName, GetCurrentTokenType()));
                statements.Add(GetNextTokenStatement());
                var type = _ruleTypes[_currenType];
            }

            var match = node.Args.Skip(1).First();
            var matchCode = GenerateMatchStatement(match);
            statements.AddRange(matchCode.OfType<CodeStatement>());

            var whileStmt = CodeHelper.While(
                peekCode,
                statements.ToArray());

            return new CodeStatementCollection(new CodeStatement[] { whileStmt });
        }
예제 #11
0
        private CodeStatementCollection GenerateMatchStatement(CallExpression node)
        {
            if (node.FunctionExpression.Type != AphidNodeType.IdentifierExpression)
            {
                throw new NotImplementedException();
            }

            var name = ((IdentifierExpression)node.FunctionExpression).Identifier;

            switch (name)
            {
                case "ZeroOrMany":
                    return GenerateMatchZeroOrMany(node);

                default:
                    throw new NotImplementedException();
            }
        }
예제 #12
0
        private CodeStatementCollection GenerateImperativeStatement(CallExpression node)
        {
            switch (node.FunctionExpression.Type)
            {
                case AphidNodeType.IdentifierExpression:
                    var name = ((IdentifierExpression)node.FunctionExpression).Identifier;

                    switch (name)
                    {
                        case _nextTokenFunc:
                            return new CodeStatementCollection(new[] { GetNextTokenStatement() });

                        case _matchFunc:
                            return new CodeStatementCollection(new[]
                            {
                                CodeHelper.Stmt(
                                    CodeHelper.Invoke(
                                        _matchFunc,
                                        GenerateImperativeExpression(node.Args.Single())))
                            });

                        default:
                            return new CodeStatementCollection(new[]
                            {
                                new CodeExpressionStatement(GenerateImperativeExpression(node))
                            });
                    }

                default:
                    var funcExp = GenerateImperativeExpression(node.FunctionExpression);

                    if (funcExp is CodePropertyReferenceExpression)
                    {
                        var prop = (CodePropertyReferenceExpression)funcExp;
                        var parameters = node.Args.Select(x => GenerateImperativeExpression(x, false)).ToArray();

                        return new CodeStatementCollection(new[]
                        {
                            CodeHelper.Stmt(CodeHelper.Invoke(
                                prop.TargetObject,
                                prop.PropertyName,
                                parameters))
                        });
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
            }
        }
예제 #13
0
        private CodeExpression GenerateImperativeExpression(CallExpression node)
        {
            if (node.FunctionExpression.Type != AphidNodeType.IdentifierExpression &&
                node.FunctionExpression.Type != AphidNodeType.BinaryOperatorExpression &&
                ((BinaryOperatorExpression)node.FunctionExpression).Operator != AphidTokenType.MemberOperator)
            {
                throw new NotImplementedException();
            }

            string id;
            ReferenceType funcType;

            if (node.FunctionExpression.Type == AphidNodeType.IdentifierExpression)
            {
                id = ((IdentifierExpression)node.FunctionExpression).Identifier;
                funcType = ResolveType(id);
            }
            else
            {
                var ids = Flatten(node.FunctionExpression)
                    .Cast<IdentifierExpression>()
                    .Select(x => x.Identifier);

                id = string.Join(".", ids);
                funcType = ReferenceType.ExternalFunction;
            }

            var args = node.Args.Select(x => GenerateImperativeExpression(x)).ToArray();

            switch (funcType)
            {
                case ReferenceType.RuleClass:
                    return new CodeObjectCreateExpression(id, args);

                case ReferenceType.RuleDeclaration:
                    return CodeHelper.Invoke(id, args);

                case ReferenceType.ExternalFunction:
                    return CodeHelper.Invoke(id, args);

                default:
                    throw new NotImplementedException();
            }
        }
예제 #14
0
 private AphidExpression ParseMemberExpression()
 {
     var factor = ParseFactorCallExpression();
     for (
     ; (this._currentToken.TokenType == AphidTokenType.MemberOperator);
     ) {
         NextToken();
         AphidExpression exp = default(AphidExpression);
         if ((this._currentToken.TokenType == AphidTokenType.Identifier)) {
             exp = new IdentifierExpression(this._currentToken.Lexeme);
             NextToken();
         }
         else {
             if ((this._currentToken.TokenType == AphidTokenType.String)) {
                 exp = ParseStringExpression();
             }
             else {
                 if ((this._currentToken.TokenType == AphidTokenType.LeftBrace)) {
                     NextToken();
                     exp = new DynamicMemberExpression(ParseExpression());
                     Match(AphidTokenType.RightBrace);
                 }
                 else {
                     throw new AphidParserException(_currentToken);
                 }
             }
         }
         factor = new BinaryOperatorExpression(factor, AphidTokenType.MemberOperator, exp);
         for (
         ; (this._currentToken.TokenType == AphidTokenType.LeftParenthesis);
         ) {
             NextToken();
             if ((this._currentToken.TokenType == AphidTokenType.RightParenthesis)) {
                 NextToken();
                 factor = new CallExpression(factor);
             }
             else {
                 var args = ParseTuple();
                 Match(AphidTokenType.RightParenthesis);
                 factor = new CallExpression(factor, args);
             }
         }
         if ((this._currentToken.TokenType == AphidTokenType.definedKeyword)) {
             NextToken();
             return new UnaryOperatorExpression(AphidTokenType.definedKeyword, factor, true);
         }
     }
     return factor;
 }
예제 #15
0
 private AphidExpression ParseFactorCallExpression()
 {
     var function = ParseFactorExpression();
     for (
     ; (this._currentToken.TokenType == AphidTokenType.LeftParenthesis);
     ) {
         NextToken();
         if ((this._currentToken.TokenType == AphidTokenType.RightParenthesis)) {
             NextToken();
             function = new CallExpression(function);
         }
         else {
             var args = ParseTuple();
             Match(AphidTokenType.RightParenthesis);
             function = new CallExpression(function, args);
         }
     }
     return function;
 }
 public PartialFunctionExpression(CallExpression call)
 {
     Call = call;
 }
        private AphidMacro GetMacro(CallExpression call, AphidMacro[] macros)
        {
            var idExp = call.FunctionExpression as IdentifierExpression;

            if (idExp == null)
            {
                return null;
            }

            return macros.SingleOrDefault(x => x.Name == idExp.Identifier);
        }