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; }
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; }
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; } }
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); } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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 }; } }
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))); } }
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(); } }
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); }
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)))); }
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); } }
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; } }
private CodeStatementCollection GenerateImperativeStatement(BinaryOperatorExpression node) { switch (node.Operator) { case AphidTokenType.AssignmentOperator: return GenerateImperativeAssignStatement(node); default: throw new NotImplementedException(); } }
public AphidMacro(string name, FunctionExpression declaration, BinaryOperatorExpression originalExpression) { Name = name; Declaration = declaration; OriginalExpression = originalExpression; }
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(); } }
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; }