public AphidObject Deserialize(string obj)
        {
            var lexer = new AphidObjectLexer(obj);
            var tokens = lexer.GetTokens();
            tokens.Add(new AphidToken(AphidTokenType.EndOfStatement, null, 0));
            var ast = new AphidParser(tokens).Parse();

            if (ast.Count != 1)
            {
                throw new AphidRuntimeException("Invalid Aphid object string: {0}", obj);
            }

            ast[0] = new UnaryOperatorExpression(AphidTokenType.retKeyword, ast[0]);
            var objInterpreter = new AphidInterpreter();
            objInterpreter.Interpret(ast);
            return objInterpreter.GetReturnValue();
        }
        private object InterpretUnaryOperatorExpression(UnaryOperatorExpression expression)
        {
            if (!expression.IsPostfix)
            {
                switch (expression.Operator)
                {
                    case AphidTokenType.retKeyword:
                        SetReturnValue(ValueHelper.Wrap(InterpretExpression(expression.Operand)));
                        _isReturning = true;
                        return null;

                    case AphidTokenType.NotOperator:
                        return new AphidObject(!(bool)ValueHelper.Unwrap(InterpretExpression(expression.Operand) as AphidObject));

                    default:
                        throw CreateUnaryOperatorException(expression);
                }
            }
            else
            {
                switch (expression.Operator)
                {
                    case AphidTokenType.IncrementOperator:
                        var obj = InterpretExpression(expression.Operand) as AphidObject;
                        obj.Value = ((decimal)obj.Value) + 1;
                        return obj;

                    case AphidTokenType.ExistsOperator:
                        if (expression.Operand is IdentifierExpression)
                        {
                            return ValueHelper.Wrap(InterpretIdentifierExpression(expression.Operand as IdentifierExpression) != null);
                        }
                        else if (expression.Operand is BinaryOperatorExpression)
                        {
                            var objRef = InterpretBinaryOperatorExpression(expression.Operand as BinaryOperatorExpression, true) as AphidRef;
                            return new AphidObject(objRef.Object.ContainsKey(objRef.Name));
                        }
                        else
                        {
                            throw new AphidRuntimeException("Unknown ? operand");
                        }
                    //var obj = InterpretExpression(

                    default:
                        throw CreateUnaryOperatorException(expression);
                }
            }
        }
Example #3
0
        private AphidObject InterpretUnaryOperatorExpression(UnaryOperatorExpression expression)
        {
            if (!expression.IsPostfix)
            {
                switch (expression.Operator)
                {
                    case AphidTokenType.AdditionOperator:
                        return (AphidObject)InterpretExpression(expression.Operand);

                    case AphidTokenType.MinusOperator:
                        var val = ValueHelper.Unwrap(InterpretExpression(expression.Operand));

                        if (!(val is decimal))
                        {
                            throw new AphidRuntimeException(
                                "Unary operator '-' expects number, {0} was provided instead.",
                                val.GetType());
                        }

                        return ValueHelper.Wrap((decimal)val * -1);

                    case AphidTokenType.retKeyword:
                        SetReturnValue(ValueHelper.Wrap(InterpretExpression(expression.Operand)));
                        _isReturning = true;
                        return null;

                    case AphidTokenType.deleteKeyword:
                        var operand = ((IdentifierExpression)expression.Operand).Identifier;
                        return new AphidObject(_currentScope.TryResolveAndRemove(operand));

                    case AphidTokenType.NotOperator:
                        return new AphidObject(!(bool)ValueHelper.Unwrap(InterpretExpression(expression.Operand) as AphidObject));

                    case AphidTokenType.IncrementOperator:
                        var obj = InterpretExpression(expression.Operand) as AphidObject;
                        obj.Value = ((decimal)obj.Value) + 1;
                        return obj;

                    case AphidTokenType.DecrementOperator:
                        obj = InterpretExpression(expression.Operand) as AphidObject;
                        obj.Value = ((decimal)obj.Value) - 1;
                        return obj;

                    case AphidTokenType.DistinctOperator:
                        obj = ((AphidObject)InterpretExpression(expression.Operand));
                        var list = obj.Value as List<AphidObject>;

                        if (list == null)
                        {
                            throw CreateUnaryOperatorException(expression);
                        }

                        return new AphidObject(list.Distinct(_comparer).ToList());

                    default:
                        throw CreateUnaryOperatorException(expression);
                }
            }
            else
            {
                switch (expression.Operator)
                {
                    case AphidTokenType.IncrementOperator:
                        var obj = InterpretExpression(expression.Operand) as AphidObject;
                        var v = obj.Value;
                        obj.Value = ((decimal)obj.Value) + 1;
                        return new AphidObject(v);

                    case AphidTokenType.DecrementOperator:
                        obj = InterpretExpression(expression.Operand) as AphidObject;
                        v = obj.Value;
                        obj.Value = ((decimal)obj.Value) - 1;
                        return new AphidObject(v);

                    case AphidTokenType.definedKeyword:
                        if (expression.Operand is IdentifierExpression)
                        {
                            return ValueHelper.Wrap(InterpretIdentifierExpression(expression.Operand as IdentifierExpression) != null);
                        }
                        else if (expression.Operand is BinaryOperatorExpression)
                        {
                            var objRef = InterpretBinaryOperatorExpression(expression.Operand as BinaryOperatorExpression, true) as AphidRef;
                            return new AphidObject(objRef.Object.ContainsKey(objRef.Name));
                        }
                        else
                        {
                            throw new AphidRuntimeException("Unknown ? operand");
                        }

                    //var obj = InterpretExpression(

                    default:
                        throw CreateUnaryOperatorException(expression);
                }
            }
        }
 private AphidRuntimeException CreateUnaryOperatorException(UnaryOperatorExpression expression)
 {
     throw new AphidRuntimeException("Unknown operator {0} in expression {1}", expression.Operator, expression);
 }
Example #5
0
 private CodeStatementCollection GenerateImperativeRetStatement(UnaryOperatorExpression node)
 {
     return new CodeStatementCollection(new[]
     {
         CodeHelper.Return(GenerateImperativeExpression(node.Operand))
     });
 }
Example #6
0
        private CodeStatementCollection GenerateImperativeStatement(UnaryOperatorExpression node)
        {
            switch (node.Operator)
            {
                case AphidTokenType.retKeyword:
                    return GenerateImperativeRetStatement(node);

                default:
                    throw new NotImplementedException();
            }
        }
Example #7
0
 private AphidExpression ParseQueryExpression()
 {
     var exp = ParseRangeExpression();
     var inQuery = true;
     for (
     ; true;
     ) {
         if ((((((this._currentToken.TokenType == AphidTokenType.AggregateOperator)
                     || (this._currentToken.TokenType == AphidTokenType.AnyOperator))
                     || (this._currentToken.TokenType == AphidTokenType.SelectManyOperator))
                     || (this._currentToken.TokenType == AphidTokenType.SelectOperator))
                     || (this._currentToken.TokenType == AphidTokenType.WhereOperator))) {
             var t = this._currentToken.TokenType;
             NextToken();
             exp = new BinaryOperatorExpression(exp, t, ParseRangeExpression());
         }
         else {
             if ((this._currentToken.TokenType == AphidTokenType.DistinctOperator)) {
                 exp = new UnaryOperatorExpression(this._currentToken.TokenType, exp);
                 NextToken();
             }
             else {
                 inQuery = false;
             }
         }
         if ((inQuery == false)) {
     break;
         }
     }
     return exp;
 }
Example #8
0
        private CodeExpression GenerateImperativeExpression(UnaryOperatorExpression node, bool isCondition = false)
        {
            if (!node.IsPostfix)
            {
                switch (node.Operator)
                {
                    case AphidTokenType.NotOperator:
                        var exp = GenerateImperativeExpression(node.Operand, isCondition);

                        return CodeHelper.BinOpExp(
                            exp,
                            CodeBinaryOperatorType.ValueEquality,
                            CodeHelper.False());

                    default:
                        throw new NotImplementedException();
                }
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Example #9
0
 private AphidExpression ParseFactorExpression()
 {
     AphidExpression exp = default(AphidExpression);
     if ((this._currentToken.TokenType == AphidTokenType.LeftBrace)) {
         exp = ParseObjectExpression();
     }
     else {
         if ((this._currentToken.TokenType == AphidTokenType.LeftBracket)) {
             exp = ParseArrayExpression();
         }
         else {
             if ((this._currentToken.TokenType == AphidTokenType.LeftParenthesis)) {
                 NextToken();
                 exp = ParseExpression();
                 Match(AphidTokenType.RightParenthesis);
             }
             else {
                 if ((this._currentToken.TokenType == AphidTokenType.String)) {
                     exp = ParseStringExpression();
                 }
                 else {
                     if ((this._currentToken.TokenType == AphidTokenType.Number)) {
                         exp = ParseNumberExpression();
                     }
                     else {
                         if ((this._currentToken.TokenType == AphidTokenType.Identifier)) {
                             exp = ParseIdentifierExpression();
                             if ((this._currentToken.TokenType == AphidTokenType.definedKeyword)) {
                                 NextToken();
                                 exp = new UnaryOperatorExpression(AphidTokenType.definedKeyword, exp, true);
                             }
                         }
                         else {
                             if ((this._currentToken.TokenType == AphidTokenType.functionOperator)) {
                                 exp = ParseFunctionExpression();
                             }
                             else {
                                 if (((this._currentToken.TokenType == AphidTokenType.retKeyword)
                                             || (this._currentToken.TokenType == AphidTokenType.deleteKeyword))) {
                                     exp = ParseUnaryExpression();
                                 }
                                 else {
                                     if ((this._currentToken.TokenType == AphidTokenType.trueKeyword)) {
                                         exp = new BooleanExpression(true);
                                         NextToken();
                                     }
                                     else {
                                         if ((this._currentToken.TokenType == AphidTokenType.falseKeyword)) {
                                             exp = new BooleanExpression(false);
                                             NextToken();
                                         }
                                         else {
                                             if ((this._currentToken.TokenType == AphidTokenType.thisKeyword)) {
                                                 exp = new ThisExpression();
                                                 NextToken();
                                             }
                                             else {
                                                 if ((this._currentToken.TokenType == AphidTokenType.LoadScriptOperator)) {
                                                     exp = ParseLoadScriptExpression();
                                                 }
                                                 else {
                                                     if ((this._currentToken.TokenType == AphidTokenType.LoadLibraryOperator)) {
                                                         exp = ParseLoadLibraryExpression();
                                                     }
                                                     else {
                                                         if ((this._currentToken.TokenType == AphidTokenType.nullKeyword)) {
                                                             exp = new NullExpression();
                                                             NextToken();
                                                         }
                                                         else {
                                                             if ((this._currentToken.TokenType == AphidTokenType.breakKeyword)) {
                                                                 exp = new BreakExpression();
                                                                 NextToken();
                                                             }
                                                             else {
                                                                 if ((this._currentToken.TokenType == AphidTokenType.HexNumber)) {
                                                                     exp = new NumberExpression(System.Convert.ToInt64(_currentToken.Lexeme.Substring(2), 16));
                                                                     NextToken();
                                                                 }
                                                                 else {
                                                                     if ((this._currentToken.TokenType == AphidTokenType.BinaryNumber)) {
                                                                         exp = new NumberExpression(BinaryNumber.Parse(_currentToken.Lexeme.Substring(2)));
                                                                         NextToken();
                                                                     }
                                                                     else {
                                                                         if ((this._currentToken.TokenType == AphidTokenType.PatternMatchingOperator)) {
                                                                             exp = ParsePatternMatchingExpression();
                                                                         }
                                                                         else {
                                                                             throw new AphidParserException(_currentToken);
                                                                         }
                                                                     }
                                                                 }
                                                             }
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return exp;
 }
        private List<AphidExpression> MutateMemberExpression(BinaryOperatorExpression memberExpression)
        {
            var path = FlattenMembers(memberExpression);
            var register = path.First();

            if (!IsRegister(register))
            {
                throw new InvalidOperationException();
            }

            var registerType = _registerTypeTable[register];
            var offset = _typeResolver.ResolveOffset(registerType, path.Skip(1).ToArray());

            var exp = new UnaryOperatorExpression(
                AphidTokenType.MultiplicationOperator,
                new BinaryOperatorExpression(
                    new IdentifierExpression(register),
                    AphidTokenType.AdditionOperator,
                    new NumberExpression(offset)))
            {
                IsPostfix = false,
            };

            return new List<AphidExpression> { exp };
        }
        public byte[] AssembleUnaryOperation(UnaryOperatorExpression expression)
        {
            var b = new byte[5];

            switch (expression.Operator)
            {
                case AphidTokenType.IncrementOperator:
                case AphidTokenType.DecrementOperator:
                    b[0] = (byte)InstructionOpcode.Ext;
                    b[1] = expression.Operator == AphidTokenType.IncrementOperator ?
                        (byte)InstructionSubOpcode.Inc_R : (byte)InstructionSubOpcode.Dec_R;

                    b[2] = (byte)OpcodeTable.RegisterTable[((IdentifierExpression)expression.Operand).Identifier];
                    break;

                default:
                    throw new InvalidOperationException();
            }

            return b;
        }
Example #12
0
        public AphidExpression ParseQueryExpression()
        {
            AphidExpression exp = ParseRangeExpression();
            var inQuery = true;

            do
            {
                switch (_currentToken.TokenType)
                {
                    case AphidTokenType.AggregateOperator:
                    case AphidTokenType.AnyOperator:
                    case AphidTokenType.SelectManyOperator:
                    case AphidTokenType.SelectOperator:
                    case AphidTokenType.WhereOperator:
                        var t = _currentToken.TokenType;
                        NextToken();
                        exp = new BinaryOperatorExpression(exp, t, ParseRangeExpression());
                        break;

                    case AphidTokenType.DistinctOperator:
                        exp = new UnaryOperatorExpression(_currentToken.TokenType, exp);
                        NextToken();
                        break;

                    default:
                        inQuery = false;
                        break;
                }
            }
            while (inQuery);

            return exp;
        }
Example #13
0
        public AphidExpression ParseFactor()
        {
            AphidExpression exp;
            switch (_currentToken.TokenType)
            {
                case AphidTokenType.LeftBrace:
                    exp = ParseObjectExpression();
                    break;

                case AphidTokenType.LeftBracket:
                    exp = ParseArrayExpression();
                    break;

                case AphidTokenType.LeftParenthesis:
                    NextToken();
                    exp = ParseExpression();
                    Match(AphidTokenType.RightParenthesis);
                    break;

                case AphidTokenType.String:
                    exp = ParseStringExpression();
                    break;

                case AphidTokenType.Number:
                    exp = ParseNumberExpression();
                    break;

                case AphidTokenType.Identifier:
                    exp = ParseIdentifierExpression();

                    if (_currentToken.TokenType == AphidTokenType.definedKeyword)
                    {
                        NextToken();
                        exp = new UnaryOperatorExpression(AphidTokenType.definedKeyword, exp) { IsPostfix = true };
                    }

                    break;

                case AphidTokenType.functionOperator:
                    exp = ParseFunctionExpression();
                    break;

                //case AphidTokenType.forKeyword:
                //    exp = ParseForExpression();
                //    break;

                case AphidTokenType.retKeyword:
                case AphidTokenType.deleteKeyword:
                    exp = ParseUnaryExpression();
                    break;

                case AphidTokenType.trueKeyword:
                    exp = new BooleanExpression(true);
                    NextToken();
                    break;

                case AphidTokenType.falseKeyword:
                    exp = new BooleanExpression(false);
                    NextToken();
                    break;

                case AphidTokenType.thisKeyword:
                    exp = new ThisExpression();
                    NextToken();
                    break;

                //case AphidTokenType.extendKeyword:
                //    exp = ParseExtendExpression();
                //    break;

                //case AphidTokenType.ifKeyword:
                //    exp = ParseIfExpression();
                //    break;

                case AphidTokenType.LoadScriptOperator:
                    exp = ParseLoadScriptExpression();
                    break;

                case AphidTokenType.LoadLibraryOperator:
                    exp = ParseLoadLibraryExpression();
                    break;

                case AphidTokenType.nullKeyword:
                    exp = new NullExpression();
                    NextToken();
                    break;

                case AphidTokenType.breakKeyword:
                    exp = new BreakExpression();
                    NextToken();
                    break;

                case AphidTokenType.HexNumber:
                    exp = new NumberExpression((decimal)Convert.ToInt64(_currentToken.Lexeme.Substring(2), 16));
                    NextToken();
                    break;

                case AphidTokenType.BinaryNumber:
                    exp = new NumberExpression(BinaryNumber.Parse(_currentToken.Lexeme.Substring(2)));
                    NextToken();
                    break;

                case AphidTokenType.MultiplicationOperator:
                case AphidTokenType.PatternMatchingOperator:
                    var matchExp = new PatternMatchingExpression();
                    NextToken();
                    Match(AphidTokenType.LeftParenthesis);
                    matchExp.TestExpression = ParseExpression();
                    Match(AphidTokenType.RightParenthesis);

                    while (true)
                    {
                        var tests = new List<AphidExpression>();

                        while (true)
                        {
                            tests.Add(ParseExpression());

                            if (_currentToken.TokenType == AphidTokenType.Comma)
                            {
                                NextToken();
                            }
                            else
                            {
                                break;
                            }
                        }

                        if (_currentToken.TokenType == AphidTokenType.ColonOperator)
                        {
                            NextToken();

                            var b = ParseExpression();

                            foreach (var t in tests)
                            {
                                matchExp.Patterns.Add(new Tuple<AphidExpression, AphidExpression>(t, b));
                            }
                        }
                        else
                        {
                            matchExp.Patterns.Add(new Tuple<AphidExpression, AphidExpression>(null, tests[0]));
                        }

                        if (_currentToken.TokenType == AphidTokenType.Comma)
                        {
                            NextToken();
                        }
                        else
                        {
                            break;
                        }
                    }

                    exp = matchExp;
                    break;

                default:
                    throw new AphidParserException(_currentToken);
            }

            return exp;
        }