Beispiel #1
0
 private AphidExpression ParseAdditionExpression()
 {
     var operand = ParseTermExpression();
     for (
     ; ((this._currentToken.TokenType == AphidTokenType.AdditionOperator)
                 || (this._currentToken.TokenType == AphidTokenType.MinusOperator));
     ) {
         var op = this._currentToken.TokenType;
         NextToken();
         operand = new BinaryOperatorExpression(operand, op, ParseTermExpression());
     }
     return operand;
 }
Beispiel #2
0
 private static bool OperandsAre(BinaryOperatorExpression binOp, AphidExpressionType type) =>
 binOp.LeftOperand.Type == type && binOp.RightOperand.Type == type;
 private AphidObject InterpretOrExpression(BinaryOperatorExpression expression)
 {
     var left = (bool)ValueHelper.Unwrap(InterpretExpression(expression.LeftOperand));
     var right = (bool)ValueHelper.Unwrap(InterpretExpression(expression.RightOperand));
     return new AphidObject(left || right);
 }
        private AphidObject InterpretEqualityExpression(BinaryOperatorExpression expression)
        {
            var left = InterpretExpression(expression.LeftOperand) as AphidObject;
            var right = InterpretExpression(expression.RightOperand) as AphidObject;

            bool val = left.Value != null ?
                left.Value.Equals(right.Value) :
                (null == right.Value && left.Count == 0 && right.Count == 0);

            if (expression.Operator == AphidTokenType.NotEqualOperator)
            {
                val = !val;
            }

            return new AphidObject(val);
        }
        private object InterpetAssignmentExpression(BinaryOperatorExpression expression, bool returnRef = false)
        {
            var value = InterpretExpression(expression.RightOperand);
            if (expression.LeftOperand is IdentifierExpression)
            {
                var id = (expression.LeftOperand as IdentifierExpression).Identifier;
                var destObj = InterpretIdentifierExpression(expression.LeftOperand as IdentifierExpression);

                if (destObj == null)
                {
                    _currentScope.Variables.Add(id, ValueHelper.Wrap(value));
                }
                else
                {
                    destObj.Value = ValueHelper.Unwrap(value);
                }
            }
            else
            {
                var objRef = InterpretBinaryOperatorExpression(expression.LeftOperand as BinaryOperatorExpression, true) as AphidRef;

                if (objRef.Object == null)
                {
                    throw new AphidRuntimeException("Undefined variable {0}", expression.LeftOperand);
                }
                else if (objRef.Object.ContainsKey(objRef.Name))
                {
                    objRef.Object[objRef.Name].Value = ValueHelper.Unwrap(value);
                }
                else
                {
                    objRef.Object.Add(objRef.Name, ValueHelper.Wrap(value));
                }
            }

            return value;
        }
Beispiel #6
0
        private object InterpretMemberExpression(BinaryOperatorExpression expression, bool returnRef = false)
        {
            var obj = InterpretExpression(expression.LeftOperand) as AphidObject;

            string key;

            if (expression.RightOperand is IdentifierExpression)
            {
                key = (expression.RightOperand as IdentifierExpression).Identifier;
            }
            else if (expression.RightOperand is StringExpression)
            {
                key = (string)ValueHelper.Unwrap(InterpretStringExpression(expression.RightOperand as StringExpression));
            }
            else if (expression.RightOperand is DynamicMemberExpression)
            {
                var memberExp = expression.RightOperand as DynamicMemberExpression;
                key = ValueHelper.Unwrap(InterpretExpression(memberExp.MemberExpression)).ToString();
            }
            else
            {
                throw new AphidRuntimeException("Unexpected expression {0}", expression.RightOperand);
            }

            if (returnRef)
            {
                return new AphidRef() { Name = key, Object = obj };
            }
            else
            {
                AphidObject val;

                if (obj == null)
                {
                    throw new AphidRuntimeException("Undefined member {0} in expression {1}",
                        expression.LeftOperand,
                        expression);
                }
                else if (!obj.TryResolve(key, out val))
                {
                    var t = obj.GetValueType();
                    var extKey = TypeExtender.GetName(t, key);

                    if (!_currentScope.TryResolve(extKey, out val))
                    {
                        throw new AphidRuntimeException("Undefined member {0} in expression {1}", key, expression);
                    }

                    var function = ((AphidFunction)val.Value).Clone();
                    function.ParentScope = new AphidObject { Parent = _currentScope };
                    function.ParentScope.Add(function.Args[0], obj);
                    function.Args = function.Args.Skip(1).ToArray();
                    val = new AphidObject(function);
                }

                return val;
            }
        }
Beispiel #7
0
        private object InterpretBinaryOperatorExpression(BinaryOperatorExpression expression, bool returnRef = false)
        {
            switch (expression.Operator)
            {
                case AphidTokenType.AdditionOperator:
                    return OperatorHelper.Add(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.MinusOperator:
                    return OperatorHelper.Subtract(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.MultiplicationOperator:
                    return OperatorHelper.Multiply(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.DivisionOperator:
                    return OperatorHelper.Divide(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.MemberOperator:
                    return InterpretMemberExpression(expression, returnRef);

                case AphidTokenType.AssignmentOperator:
                    return InterpetAssignmentExpression(expression, returnRef);

                case AphidTokenType.PlusEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.Add, expression);

                case AphidTokenType.MinusEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.Subtract, expression);

                case AphidTokenType.MultiplicationEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.Multiply, expression);

                case AphidTokenType.DivisionEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.Divide, expression);

                case AphidTokenType.ModulusEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.Mod, expression);

                case AphidTokenType.BinaryAndEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.BinaryAnd, expression);

                case AphidTokenType.OrEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.BinaryOr, expression);

                case AphidTokenType.XorEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.Xor, expression);

                case AphidTokenType.ShiftLeftEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.BinaryShiftLeft, expression);

                case AphidTokenType.ShiftRightEqualOperator:
                    return InterprentOperatorAndAssignmentExpression(OperatorHelper.BinaryShiftRight, expression);

                case AphidTokenType.NotEqualOperator:
                case AphidTokenType.EqualityOperator:
                    return InterpretEqualityExpression(expression);

                case AphidTokenType.LessThanOperator:
                    return CompareDecimals(expression, (x, y) => x < y);

                case AphidTokenType.LessThanOrEqualOperator:
                    return CompareDecimals(expression, (x, y) => x <= y);

                case AphidTokenType.GreaterThanOperator:
                    return CompareDecimals(expression, (x, y) => x > y);

                case AphidTokenType.GreaterThanOrEqualOperator:
                    return CompareDecimals(expression, (x, y) => x >= y);

                case AphidTokenType.AndOperator:
                    return InterpretAndExpression(expression);

                case AphidTokenType.OrOperator:
                    return InterpretOrExpression(expression);

                case AphidTokenType.ModulusOperator:
                    return OperatorHelper.Mod(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.ShiftLeft:
                    return OperatorHelper.BinaryShiftLeft(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.ShiftRight:
                    return OperatorHelper.BinaryShiftRight(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.BinaryAndOperator:
                    return OperatorHelper.BinaryAnd(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.BinaryOrOperator:
                    return OperatorHelper.BinaryOr(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.XorOperator:
                    return OperatorHelper.Xor(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.PipelineOperator:
                    return InterpretCallExpression(new CallExpression(expression.RightOperand, expression.LeftOperand));

                case AphidTokenType.RangeOperator:
                    return OperatorHelper.Range(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.SelectOperator:
                    var collection = (List<AphidObject>)((AphidObject)InterpretExpression(expression.LeftOperand)).Value;
                    var value = ((AphidObject)InterpretExpression(expression.RightOperand)).Value;
                    var func = value as AphidFunction;

                    if (func != null)
                    {
                        return new AphidObject(collection.Select(x => CallFunction(func, x)).ToList());
                    }

                    var func2 = value as AphidInteropFunction;

                    if (func2 != null)
                    {
                        return new AphidObject(collection.Select(x => CallInteropFunction(func2, x)).ToList());
                    }

                    throw new InvalidOperationException();

                case AphidTokenType.SelectManyOperator:
                    collection = (List<AphidObject>)((AphidObject)InterpretExpression(expression.LeftOperand)).Value;
                    value = ((AphidObject)InterpretExpression(expression.RightOperand)).Value;
                    func = value as AphidFunction;

                    if (func != null)
                    {
                        return new AphidObject(collection.SelectMany(x => (List<AphidObject>)CallFunction(func, x).Value).ToList());
                    }

                    func2 = value as AphidInteropFunction;

                    if (func2 != null)
                    {
                        return new AphidObject(collection.SelectMany(x => (List<AphidObject>)CallInteropFunction(func2, x).Value).ToList());
                    }

                    throw new InvalidOperationException();

                case AphidTokenType.AggregateOperator:
                    collection = (List<AphidObject>)((AphidObject)InterpretExpression(expression.LeftOperand)).Value;
                    value = ((AphidObject)InterpretExpression(expression.RightOperand)).Value;
                    func = value as AphidFunction;

                    if (func != null)
                    {
                        return collection.Aggregate((x, y) => CallFunction(func, x, y));
                    }

                    func2 = value as AphidInteropFunction;

                    if (func2 != null)
                    {
                        return collection.Aggregate((x, y) => CallInteropFunction(func2, x, y));
                    }

                    throw new InvalidOperationException();

                case AphidTokenType.AnyOperator:
                    collection = (List<AphidObject>)((AphidObject)InterpretExpression(expression.LeftOperand)).Value;
                    value = ((AphidObject)InterpretExpression(expression.RightOperand)).Value;
                    func = (AphidFunction)((AphidObject)InterpretExpression(expression.RightOperand)).Value;

                    if (func != null)
                    {
                        return new AphidObject(collection.Any(x => (bool)CallFunction(func, x).Value));
                    }

                    func2 = value as AphidInteropFunction;

                    if (func2 != null)
                    {
                        return new AphidObject(collection.Any(x => (bool)CallInteropFunction(func2, x).Value));
                    }

                    throw new InvalidOperationException();

                case AphidTokenType.WhereOperator:
                    collection = (List<AphidObject>)((AphidObject)InterpretExpression(expression.LeftOperand)).Value;
                    value = ((AphidObject)InterpretExpression(expression.RightOperand)).Value;
                    func = (AphidFunction)((AphidObject)InterpretExpression(expression.RightOperand)).Value;

                    if (func != null)
                    {
                        return new AphidObject(collection.Where(x => (bool)CallFunction(func, x).Value).ToList());
                    }

                    func2 = value as AphidInteropFunction;

                    if (func2 != null)
                    {
                        return new AphidObject(collection.Where(x => (bool)CallInteropFunction(func2, x).Value).ToList());
                    }

                    throw new InvalidOperationException();

                default:
                    throw new AphidRuntimeException("Unknown operator {0} in expression {1}", expression.Operator, expression);
            }
        }
Beispiel #8
0
        private AphidObject InterprentOperatorAndAssignmentExpression(
            Func<AphidObject, AphidObject, AphidObject> performOperation,
            BinaryOperatorExpression expression)
        {
            var left = InterpretExpression(expression.LeftOperand) as AphidObject;
            var value = performOperation(left, InterpretExpression(expression.RightOperand) as AphidObject);
            left.Value = value.Value;

            return left;
        }
Beispiel #9
0
 private AphidExpression ParseXorExpression()
 {
     var operand = ParseBinaryAndExpression();
     for (
     ; (this._currentToken.TokenType == AphidTokenType.XorOperator);
     ) {
         var op = this._currentToken.TokenType;
         NextToken();
         operand = new BinaryOperatorExpression(operand, op, ParseBinaryAndExpression());
     }
     return operand;
 }
Beispiel #10
0
 private AphidExpression ParseTermExpression()
 {
     var operand = ParsePrefixUnaryOperatorExpression();
     for (
     ; (((this._currentToken.TokenType == AphidTokenType.MultiplicationOperator)
                 || (this._currentToken.TokenType == AphidTokenType.DivisionOperator))
                 || (this._currentToken.TokenType == AphidTokenType.ModulusOperator));
     ) {
         var op = this._currentToken.TokenType;
         NextToken();
         operand = new BinaryOperatorExpression(operand, op, ParsePrefixUnaryOperatorExpression());
     }
     return operand;
 }
Beispiel #11
0
 private AphidExpression ParseAssignmentExpression()
 {
     var operand = ParsePipelineExpression();
     for (
     ; (((((((((((this._currentToken.TokenType == AphidTokenType.AssignmentOperator)
                 || (this._currentToken.TokenType == AphidTokenType.PlusEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.MinusEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.MultiplicationEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.DivisionEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.ModulusEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.BinaryAndEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.OrEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.XorEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.ShiftLeftEqualOperator))
                 || (this._currentToken.TokenType == AphidTokenType.ShiftRightEqualOperator));
     ) {
         var op = this._currentToken.TokenType;
         NextToken();
         operand = new BinaryOperatorExpression(operand, op, ParsePipelineExpression());
     }
     return operand;
 }
Beispiel #12
0
 private AphidExpression ParseShiftExpression()
 {
     var operand = ParseAdditionExpression();
     for (
     ; ((this._currentToken.TokenType == AphidTokenType.ShiftLeft)
                 || (this._currentToken.TokenType == AphidTokenType.ShiftRight));
     ) {
         var op = this._currentToken.TokenType;
         NextToken();
         operand = new BinaryOperatorExpression(operand, op, ParseAdditionExpression());
     }
     return operand;
 }
Beispiel #13
0
 private AphidExpression ParseRangeExpression()
 {
     var operand = ParseConditionalExpression();
     for (
     ; (this._currentToken.TokenType == AphidTokenType.RangeOperator);
     ) {
         var op = this._currentToken.TokenType;
         NextToken();
         operand = new BinaryOperatorExpression(operand, op, ParseConditionalExpression());
     }
     return operand;
 }
Beispiel #14
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;
 }
Beispiel #15
0
 private AphidExpression ParsePipelineExpression()
 {
     var operand = ParseQueryExpression();
     for (
     ; (this._currentToken.TokenType == AphidTokenType.PipelineOperator);
     ) {
         var op = this._currentToken.TokenType;
         NextToken();
         operand = new BinaryOperatorExpression(operand, op, ParseQueryExpression());
     }
     return operand;
 }
Beispiel #16
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;
 }
Beispiel #17
0
        private object InterpetAssignmentExpression(BinaryOperatorExpression expression, bool returnRef = false)
        {
            var value = InterpretExpression(expression.RightOperand);
            var value2 = value as AphidObject;
            var idExp = expression.LeftOperand as IdentifierExpression;
            ArrayAccessExpression arrayAccessExp;
            if (idExp != null)
            {
                var id = idExp.Identifier;
                var destObj = InterpretIdentifierExpression(idExp);

                if (destObj == null)
                {
                    destObj = new AphidObject();

                    _currentScope.Add(id, destObj);
                }
                else
                {
                    destObj.Clear();
                }

                if (value2 != null)
                {
                    destObj.Value = value2.Value;
                    destObj.Parent = value2.Parent;

                    foreach (var x in value2)
                    {
                        destObj.Add(x.Key, x.Value);
                    }
                }
                else
                {
                    destObj.Value = value;
                }
            }
            else if ((arrayAccessExp = expression.LeftOperand as ArrayAccessExpression) != null)
            {
                var obj = InterpretArrayAccessExpression(arrayAccessExp);
                obj.Value = ValueHelper.Unwrap(value);
            }
            else
            {
                var objRef = InterpretBinaryOperatorExpression(expression.LeftOperand as BinaryOperatorExpression, true) as AphidRef;

                if (objRef.Object == null)
                {
                    throw new AphidRuntimeException("Undefined variable {0}", expression.LeftOperand);
                }
                else if (objRef.Object.ContainsKey(objRef.Name))
                {
                    objRef.Object[objRef.Name].Value = ValueHelper.Unwrap(value);
                    //ValueHelper.Wrap(value).CopyTo(objRef.Object[objRef.Name]);
                }
                else
                {
                    objRef.Object.Add(objRef.Name, ValueHelper.Wrap(value));
                }
            }

            return value;
        }
        // Todo:
        // Handle Rx = Rx + y
        // Handle Rx = *Ry + z
        protected override List<AphidExpression> MutateCore(AphidExpression expression, out bool hasChanged)
        {
            hasChanged = false;

            var binOpExp = expression as BinaryOperatorExpression;

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

            var binOpOperand = binOpExp.RightOperand as BinaryOperatorExpression;

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

            hasChanged = true;
            AphidExpression left = binOpOperand.LeftOperand, right = binOpOperand.RightOperand;

            if (right is IdentifierExpression && !(left is IdentifierExpression))
            {
                var tmp = left;
                left = right;
                right = tmp;
            }

            var destinationExp = binOpExp.LeftOperand as IdentifierExpression;

            if (destinationExp == null)
            {
                throw new InvalidOperationException();
            }

            var operandLeftOperand = left as IdentifierExpression;

            if (operandLeftOperand.Identifier.StartsWith("in"))
            {
                var assignmentExp = new BinaryOperatorExpression(
                    destinationExp,
                    AphidTokenType.AssignmentOperator,
                    operandLeftOperand);

                var operationExp = new BinaryOperatorExpression(
                    destinationExp,
                    MutateOperator(binOpOperand.Operator),
                    right);

                return new List<AphidExpression> { assignmentExp, operationExp };
            }
            else
            {
                var operationExp = new BinaryOperatorExpression(
                    left,
                    MutateOperator(binOpOperand.Operator),
                    right);

                var assignmentExp = new BinaryOperatorExpression(
                    destinationExp,
                    AphidTokenType.AssignmentOperator,
                    left);

                return new List<AphidExpression> { operationExp, assignmentExp };
            }
        }
Beispiel #19
0
        private AphidObject InterpretAndExpression(BinaryOperatorExpression expression)
        {
            var left = (bool)ValueHelper.Unwrap(InterpretExpression(expression.LeftOperand));

            if (!left)
            {
                return new AphidObject(false);
            }
            else
            {
                return new AphidObject((bool)ValueHelper.Unwrap(InterpretExpression(expression.RightOperand)));
            }
        }
Beispiel #20
0
        private CodeMemberMethod Generate(BinaryOperatorExpression node)
        {
            switch (node.Operator)
            {
                case AphidTokenType.AssignmentOperator:

                    switch (node.RightOperand.Type)
                    {
                        case AphidNodeType.FunctionExpression:
                            return GenerateImperativeMethod(node);

                        default:
                            throw new NotImplementedException();
                        //return GenerateParseRuleFunction(node);
                    }

                default:
                    throw new NotImplementedException();
            }
        }
Beispiel #21
0
        private AphidObject InterpretEqualityExpression(BinaryOperatorExpression expression)
        {
            var left = (AphidObject)InterpretExpression(expression.LeftOperand);
            var right = (AphidObject)InterpretExpression(expression.RightOperand);

            bool val;

            if (left == null)
            {
                throw CreateUndefinedMemberException(expression, expression.LeftOperand);
            }
            else if (right == null)
            {
                throw CreateUndefinedMemberException(expression, expression.RightOperand);
            }
            else if (left.Value != null)
            {
                val = left.Value.Equals(right.Value);
            }
            else if (right.Value != null)
            {
                val = right.Value.Equals(left.Value);
            }
            else
            {
                val = left.Count == 0 && right.Count == 0;
            }

            if (expression.Operator == AphidTokenType.NotEqualOperator)
            {
                val = !val;
            }

            return new AphidObject(val);
        }
Beispiel #22
0
        private CodeStatementCollection GenerateImperativeAssignStatement(BinaryOperatorExpression node)
        {
            //if (node.RightOperand.Type == AphidNodeType.CallExpression)
            //{
            //    var call = (CallExpression)node.RightOperand;

            //    if (call.FunctionExpression.Type == AphidNodeType.IdentifierExpression &&
            //        ((IdentifierExpression)call.FunctionExpression).Identifier == "NextToken")
            //    {
            //        var assignStatements = GenerateImperativeStatement(new BinaryOperatorExpression(
            //            node.LeftOperand,
            //            node.Operator,
            //            new IdentifierExpression(_tokenTypeId)));

            //        var statements = assignStatements
            //            .OfType<CodeStatement>()
            //            .Concat(new CodeStatement[] { GetNextTokenStatement(), })
            //            .ToArray();

            //        return new CodeStatementCollection(statements);
            //    }
            //}

            if (node.LeftOperand.Type == AphidNodeType.IdentifierExpression)
            {
                var id = ((IdentifierExpression)node.LeftOperand).Identifier;
                AphidObject obj;
                if (!_scope.TryResolve(id, out obj))
                {
                    _scope.Add(id, new AphidObject());

                    return new CodeStatementCollection(new[]
                    {
                        CodeHelper.VarDecl(id, GenerateImperativeExpression(node.RightOperand))
                    });
                }
            }

            var leftExp = GenerateImperativeExpression(node.LeftOperand);
            var assignStmt = CodeHelper.Assign(leftExp, GenerateImperativeExpression(node.RightOperand));

            return new CodeStatementCollection(new[] { assignStmt });
        }
 private AphidObject CompareDecimals(BinaryOperatorExpression expression, Func<decimal, decimal, bool> equal)
 {
     return new AphidObject(
         equal(
             (decimal)ValueHelper.Unwrap(InterpretExpression(expression.LeftOperand)),
             (decimal)ValueHelper.Unwrap(InterpretExpression(expression.RightOperand))));
 }
Beispiel #24
0
        private CodeExpression GenerateImperativeExpression(BinaryOperatorExpression node, bool isCondition = false)
        {
            var opTable = new Dictionary<AphidTokenType, CodeBinaryOperatorType>
            {
                { AphidTokenType.OrOperator, CodeBinaryOperatorType.BooleanOr },
                { AphidTokenType.AndOperator, CodeBinaryOperatorType.BooleanAnd },
                { AphidTokenType.BinaryOrOperator, CodeBinaryOperatorType.BooleanOr },
                { AphidTokenType.BinaryAndOperator, CodeBinaryOperatorType.BooleanAnd },
                { AphidTokenType.EqualityOperator, CodeBinaryOperatorType.ValueEquality },
                { AphidTokenType.NotEqualOperator, CodeBinaryOperatorType.IdentityInequality },
            };

            switch (node.Operator)
            {
                case AphidTokenType.MemberOperator:
                    if (node.RightOperand.Type != AphidNodeType.IdentifierExpression)
                    {
                        throw new NotImplementedException();
                    }

                    return CodeHelper.PropRef(
                        GenerateImperativeExpression(node.LeftOperand),
                        ((IdentifierExpression)node.RightOperand).Identifier);

                default:
                    return CodeHelper.BinOpExp(
                        GenerateImperativeExpression(node.LeftOperand, isCondition),
                        opTable[node.Operator],
                        GenerateImperativeExpression(node.RightOperand, isCondition));
            }
        }
        private object InterpretBinaryOperatorExpression(BinaryOperatorExpression expression, bool returnRef = false)
        {
            switch (expression.Operator)
            {
                case AphidTokenType.AdditionOperator:
                    return _opHelper.Add(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.MinusOperator:
                    return _opHelper.Subtract(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.MultiplicationOperator:
                    return _opHelper.Multiply(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.DivisionOperator:
                    return _opHelper.Divide(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.MemberOperator:
                    return InterpretMemberExpression(expression, returnRef);

                case AphidTokenType.AssignmentOperator:
                    return InterpetAssignmentExpression(expression, returnRef);

                case AphidTokenType.NotEqualOperator:
                case AphidTokenType.EqualityOperator:
                    return InterpretEqualityExpression(expression);

                case AphidTokenType.LessThanOperator:
                    return CompareDecimals(expression, (x, y) => x < y);

                case AphidTokenType.LessThanOrEqualOperator:
                    return CompareDecimals(expression, (x, y) => x <= y);

                case AphidTokenType.GreaterThanOperator:
                    return CompareDecimals(expression, (x, y) => x > y);

                case AphidTokenType.GreaterThanOrEqualOperator:
                    return CompareDecimals(expression, (x, y) => x >= y);

                case AphidTokenType.AndOperator:
                    return InterpretAndExpression(expression);

                case AphidTokenType.OrOperator:
                    return InterpretOrExpression(expression);

                case AphidTokenType.ModulusOperator:
                    return _opHelper.Mod(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.ShiftLeft:
                    return _opHelper.BinaryShiftLeft(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.ShiftRight:
                    return _opHelper.BinaryShiftRight(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.BinaryAndOperator:
                    return _opHelper.BinaryAnd(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.BinaryOrOperator:
                    return _opHelper.BinaryOr(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.XorOperator:
                    return _opHelper.Xor(
                        InterpretExpression(expression.LeftOperand) as AphidObject,
                        InterpretExpression(expression.RightOperand) as AphidObject);

                case AphidTokenType.PipelineOperator:
                    return InterpretCallExpression(new CallExpression(expression.RightOperand, expression.LeftOperand));

                default:
                    throw new AphidRuntimeException("Unknown operator {0} in expression {1}", expression.Operator, expression);
            }
        }
Beispiel #26
0
        private CodeMemberMethod GenerateImperativeMethod(BinaryOperatorExpression node)
        {
            _scope.Clear();

            if (node.LeftOperand.Type != AphidNodeType.IdentifierExpression)
            {
                throw new NotImplementedException();
            }

            var funcId = (IdentifierExpression)node.LeftOperand;
            var func = (FunctionExpression)node.RightOperand;

            CodeStatement[] body;

            if (!func.Body.Any())
            {
                return null;
                //return new CodeStatementCollection();
                body = new CodeStatement[0];
            }
            else
            {
                body = func.Body
                    .SelectMany(x => GenerateImperativeStatement(x).OfType<CodeStatement>())
                    .ToArray();
            }

            var methodAttrs = ParseMethodAttributes(funcId);
            var typeRef = CodeHelper.TypeRef(methodAttrs.Type);

            var method = new System.CodeDom.CodeMemberMethod()
            {
                Name = funcId.Identifier,
                ReturnType = methodAttrs.IsList ? GetListTypeRef(typeRef) : typeRef,
            };

            if (methodAttrs.IsRoot)
            {
                method.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            }

            method.Statements.AddRange(body);

            return method;

            //var str = CSharpHelper.GenerateCode(method);

            //return new CodeStatementCollection(body);
        }
        private object InterpretMemberExpression(BinaryOperatorExpression expression, bool returnRef = false)
        {
            var obj = InterpretExpression(expression.LeftOperand) as AphidObject;

            string key;

            if (expression.RightOperand is IdentifierExpression)
            {
                key = (expression.RightOperand as IdentifierExpression).Identifier;
            }
            else if (expression.RightOperand is StringExpression)
            {
                key = (string)ValueHelper.Unwrap(InterpretStringExpression(expression.RightOperand as StringExpression));
            }
            else if (expression.RightOperand is DynamicMemberExpression)
            {
                var memberExp = expression.RightOperand as DynamicMemberExpression;
                key = ValueHelper.Unwrap(InterpretExpression(memberExp.MemberExpression)).ToString();
            }
            else
            {
                throw new AphidRuntimeException("Unexpected expression {0}", expression.RightOperand);
            }

            if (returnRef)
            {
                return new AphidRef() { Name = key, Object = obj };
            }
            else
            {
                AphidObject val;

                if (!obj.TryGetValue(key, out val))
                {
                    throw new AphidRuntimeException("Undefined member {0} in expression {1}", key, expression);
                }

                return val;
            }
        }
Beispiel #28
0
        private CodeStatementCollection GenerateImperativeStatement(BinaryOperatorExpression node)
        {
            switch (node.Operator)
            {
                case AphidTokenType.AssignmentOperator:
                    return GenerateImperativeAssignStatement(node);

                default:
                    throw new NotImplementedException();
            }
        }
Beispiel #29
0
 public AphidMacro(string name, FunctionExpression declaration, BinaryOperatorExpression originalExpression)
 {
     Name               = name;
     Declaration        = declaration;
     OriginalExpression = originalExpression;
 }
Beispiel #30
0
        private CodeStatementCollection GenerateParseRuleBody(BinaryOperatorExpression node)
        {
            switch (node.Operator)
            {
                case AphidTokenType.AdditionOperator:
                    return new CodeStatementCollection(
                        GenerateMatchStatement(node.LeftOperand)
                            .OfType<CodeStatement>()
                            .Concat(GenerateMatchStatement(node.RightOperand)
                                .OfType<CodeStatement>())
                            .ToArray());

                default:
                    throw new NotImplementedException();
            }
        }
Beispiel #31
0
 public AphidMacro(string name, FunctionExpression declaration, BinaryOperatorExpression originalExpression)
 {
     Name = name;
     Declaration = declaration;
     OriginalExpression = originalExpression;
 }
Beispiel #32
0
        private CodeStatementCollection GenerateParseRuleFunction(BinaryOperatorExpression node)
        {
            if (node.LeftOperand.Type != AphidNodeType.IdentifierExpression)
            {
                throw new NotImplementedException();
            }

            var idExp = (IdentifierExpression)node.LeftOperand;

            if (idExp.Attributes.Count != 1)
            {
                throw new NotImplementedException();
            }

            _currenType = idExp.Attributes.First().Identifier;
            var id = idExp.Identifier;
            var funcName = _parsePrefix + id;
            _locals.Clear();
            _locals.Add(_nodeLocal, _baseType);
            var body = GenerateParseRuleBody(node.RightOperand);
            body.Add(CodeHelper.Return(_nodeLocal));
            var localDecls = GenerateLocals();

            var statements = localDecls
                .Cast<CodeStatement>()
                .Concat(body.Cast<CodeStatement>())
                .ToArray();

            return new CodeStatementCollection(statements);

            //var code = string.Join("", statements);

            //File.WriteAllText(@"c:\temp\test.cs", code);
            //Environment.Exit(0);
            //return null;
        }