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); } } }
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); }
private CodeStatementCollection GenerateImperativeRetStatement(UnaryOperatorExpression node) { return new CodeStatementCollection(new[] { CodeHelper.Return(GenerateImperativeExpression(node.Operand)) }); }
private CodeStatementCollection GenerateImperativeStatement(UnaryOperatorExpression node) { switch (node.Operator) { case AphidTokenType.retKeyword: return GenerateImperativeRetStatement(node); default: throw new NotImplementedException(); } }
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 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(); } }
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; }
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; }
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; }