///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// public UnaryExpression(OperatorType operatorType, Expression expression, TextRange textRange) : this( textRange ) { // Initialize parameters this.operatorType = operatorType; this.Expression = expression; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Initializes a new instance of the <c>IndexExpression</c> class. /// </summary> /// <param name="lhs">The LHS expression.</param> /// <param name="rhs">The RHS index.</param> /// <param name="textRange">The <see cref="TextRange"/> of the AST node.</param> public IndexExpression(Expression lhs, IToken indexToken, LuatAstNodeBase rhs) : this(new TextRange( lhs.StartOffset, rhs.EndOffset ) ) { // Initialize parameters this.LHS = lhs; this.IndexToken = indexToken; this.RHS = rhs; }
public IndexExpression(Expression lhs, IToken indexToken, LuatAstNodeBase rhs, TextRange textRange) : this( textRange ) { // Initialize parameters this.LHS = lhs; this.IndexToken = indexToken; this.RHS = rhs; }
/// <summary> /// Adds an expression to the unresolved list /// </summary> /// <param name="script"></param> /// <param name="expression"></param> /// <returns></returns> public bool AddUnresolvedExpression(LuatScript script, Expression expression) { LinkedListNode<Expression> node = expression.ListNode[script]; if (node.List == script.UnresolvedExpressions) { return false; } if (null != node.List) { if (node.List != script.ResolvedExpressions) { throw new Exception("Expression is part of an unknown list"); } node.List.Remove(node); } script.UnresolvedExpressions.AddFirst(node); return true; }
/// <summary> /// Matches a <c>Function</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Function</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Function</c>. /// </remarks> protected virtual bool MatchFunction(out Expression expression) { expression = null; if (!this.Match(LuatTokenId.Function)) return false; Function function; if (!this.MatchFunctionBody(out function)) return false; expression = function; return true; }
protected bool IsFunctionCall( Expression expression ) { return expression is FunctionCall; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Initializes a new instance of the <c>ExpressionStatement</c> class. /// </summary> /// <param name="owner">indicating the binary operator type.</param> /// <param name="name">The name of the function.</param> /// <param name="parameters">Parameters to the function.</param> public ExpressionStatement(Expression exp) : this(new TextRange( exp.StartOffset, exp.EndOffset ) ) { // Initialize parameters this.Exp = exp; }
/// <summary> /// Matches a <c>Parenthesis</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Parenthesis</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>OpenParenthesis</c>. /// </remarks> protected virtual bool MatchParenthesis(out Expression expression) { expression = null; if (!this.Match(LuatTokenId.OpenParenthesis)) return false; int start = this.Token.StartOffset; if (!this.MatchExpression(out expression)) return false; if (!this.Match(LuatTokenId.CloseParenthesis)) return false; TextRange textRange = new TextRange( start, this.Token.EndOffset ); expression = new ParenthesizedExpression( expression, textRange ); return true; }
/// <summary> /// Matches a <c>Variable</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Variable</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Identifier</c>. /// </remarks> protected virtual bool MatchVariable(out Expression expression) { expression = null; Identifier identifier; if (!this.MatchIdentifier(out identifier)) return false; expression = new VariableExpression( identifier ); return true; }
/// <summary> /// Matches a <c>ExpressionInner</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>ExpressionInner</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Function</c>, <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>Identifier</c>, <c>TripleDot</c>, <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>Subtraction</c>, <c>Not</c>, <c>Hash</c>, <c>String</c>. /// </remarks> protected virtual bool MatchExpressionInner(out Expression expression) { expression = null; string description = this.GetDescription(); if (this.IsInMultiMatchSet(2, this.LookAheadToken)) { if (!this.MatchExpressionNoFunction(out expression)) return false; } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.Function)) { if (!this.MatchFunction(out expression)) return false; } else return false; expression.Description = description; return true; }
/// <summary> /// Matches a <c>Primary</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Primary</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>String</c>. /// </remarks> protected virtual bool MatchPrimary(out Expression expression) { expression = null; if (this.TokenIs(this.LookAheadToken, LuatTokenId.Nil)) { if (!this.Match(LuatTokenId.Nil)) return false; expression = new NilExpression( this.Token.TextRange ); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.False)) { if (!this.Match(LuatTokenId.False)) return false; expression = new BooleanExpression( false, this.Token.TextRange); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.True)) { if (!this.Match(LuatTokenId.True)) return false; expression = new BooleanExpression( true, this.Token.TextRange); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.Number)) { if (!this.Match(LuatTokenId.Number)) return false; expression = new NumberExpression( Convert.ToDouble(this.TokenText), this.Token.TextRange ); } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.String)) { if (!this.MatchStringExpression(out expression)) return false; } else return false; return true; }
/// <summary> /// Matches a <c>Expression</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Expression</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Function</c>, <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>Identifier</c>, <c>TripleDot</c>, <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>Subtraction</c>, <c>Not</c>, <c>Hash</c>, <c>String</c>. /// </remarks> protected virtual bool MatchExpression(out Expression expression) { expression = null; int start = this.LookAheadToken.StartOffset; if (!this.MatchExpressionInner(out expression)) { expression = new IncompleteExpression( expression, new TextRange( start, this.Token.EndOffset ) ); } return true; }
/// <summary> /// Matches a <c>ExpressionNoFunctionInner</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>ExpressionNoFunctionInner</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>Identifier</c>, <c>TripleDot</c>, <c>Nil</c>, <c>False</c>, <c>True</c>, <c>Number</c>, <c>Subtraction</c>, <c>Not</c>, <c>Hash</c>, <c>String</c>. /// </remarks> protected virtual bool MatchExpressionNoFunctionInner(out Expression expression) { expression = null; if (this.IsInMultiMatchSet(6, this.LookAheadToken)) { if (!this.MatchPrimary(out expression)) return false; } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.TripleDot)) { if (!this.Match(LuatTokenId.TripleDot)) return false; expression = new NilExpression( this.Token.TextRange ); } else if (((this.TokenIs(this.LookAheadToken, LuatTokenId.OpenParenthesis)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenCurlyBrace)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.Identifier)))) { if (this.TokenIs(this.LookAheadToken, LuatTokenId.Identifier)) { if (!this.MatchVariable(out expression)) return false; } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenCurlyBrace)) { if (!this.MatchTableConstructor(out expression)) return false; } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenParenthesis)) { if (!this.MatchParenthesis(out expression)) return false; } else return false; while (this.IsInMultiMatchSet(7, this.LookAheadToken)) { if (((this.TokenIs(this.LookAheadToken, LuatTokenId.Dot)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenSquareBracket)))) { if (!this.MatchIndex(ref expression)) return false; } else if (this.IsInMultiMatchSet(8, this.LookAheadToken)) { if (!this.MatchCallSuffix(ref expression)) return false; } else return false; } } else if (((this.TokenIs(this.LookAheadToken, LuatTokenId.Subtraction)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.Not)) || (this.TokenIs(this.LookAheadToken, LuatTokenId.Hash)))) { int start = this.LookAheadToken.StartOffset; OperatorType operatorType; if (!this.MatchUnaryOp(out operatorType)) return false; Expression rhs = null; if (!this.MatchExpression(out rhs)) return false; expression = new UnaryExpression( operatorType, rhs, new TextRange( start, this.Token.EndOffset) ); } else return false; while (this.IsInMultiMatchSet(9, this.LookAheadToken)) { OperatorType operatorType; if (!this.MatchBinaryOp(out operatorType)) return false; Expression rhs = null; if (!this.MatchExpression(out rhs)) return false; expression = new BinaryExpression( operatorType, expression, rhs ); } return true; }
/// <summary> /// Matches a <c>TableConstructor</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>TableConstructor</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>OpenCurlyBrace</c>. /// </remarks> protected virtual bool MatchTableConstructor(out Expression expression) { expression = null; int start = this.LookAheadToken.StartOffset; if (!this.Match(LuatTokenId.OpenCurlyBrace)) return false; TableConstructor table = new TableConstructor(); if (this.IsInMultiMatchSet(4, this.LookAheadToken)) { if (!this.MatchFieldList(table.Fields)) return false; } if (!this.Match(LuatTokenId.CloseCurlyBrace)) return false; table.StartOffset = start; table.EndOffset = this.Token.EndOffset; expression = table; return true; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// public BinaryExpression(OperatorType operatorType, Expression lhs, Expression rhs) : this( new TextRange( lhs.StartOffset, rhs.EndOffset ) ) { // Initialize parameters this.operatorType = operatorType; this.LeftExpression = lhs; this.RightExpression = rhs; }
/// <summary> /// Matches a <c>Index</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>Index</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Dot</c>, <c>OpenSquareBracket</c>. /// </remarks> protected virtual bool MatchIndex(ref Expression expression) { LuatAstNodeBase index; IToken indexToken; int start = expression.StartOffset; if (this.TokenIs(this.LookAheadToken, LuatTokenId.OpenSquareBracket)) { if (!this.Match(LuatTokenId.OpenSquareBracket)) return false; indexToken = this.Token; Expression indexExpression = null; if (!this.MatchExpression(out indexExpression)) return false; index = indexExpression; if (!this.Match(LuatTokenId.CloseSquareBracket)) return false; expression.EndOffset = this.Token.EndOffset; // Expand to encompass ']' } else if (this.TokenIs(this.LookAheadToken, LuatTokenId.Dot)) { if (!this.Match(LuatTokenId.Dot)) return false; indexToken = this.Token; Identifier indexIdentifier = null; if (!this.MatchIdentifier(out indexIdentifier)) { this.RaiseError( this.Token.EndOffset - 1, "Expected identifier." ); } index = indexIdentifier; } else return false; expression = new IndexExpression( expression, indexToken, index, new TextRange( start, this.Token.EndOffset ) ); return true; }
protected bool IsVariable( Expression expression ) { return expression is VariableExpression || expression is IndexExpression; }
/// <summary> /// Matches a <c>StringExpression</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>StringExpression</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>String</c>. /// </remarks> protected virtual bool MatchStringExpression(out Expression expression) { expression = null; if (!this.Match(LuatTokenId.String)) return false; string text = this.TokenText; if ( text.StartsWith("\"") ) { text = text.Substring( 1 ); } if ( text.EndsWith("\"") ) { text = text.Substring( 0, text.Length - 1 ); } expression = new StringExpression(text, this.Token.TextRange); return true; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// public Field(IAstNode key, Expression value, TextRange textRange) : this(textRange) { this.Key = key; this.Value = value; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// public FunctionCall(Expression owner, Identifier name) : this(new TextRange( owner.StartOffset, owner == null ? name.EndOffset : owner.EndOffset ) ) { // Initialize parameters this.Owner = owner; this.Name = name; }
/// <summary> /// Matches a <c>CallSuffix</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>CallSuffix</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Colon</c>, <c>OpenParenthesis</c>, <c>OpenCurlyBrace</c>, <c>String</c>. /// </remarks> protected virtual bool MatchCallSuffix(ref Expression expression) { Identifier name = null; bool bPassesSelf = false; if (this.TokenIs(this.LookAheadToken, LuatTokenId.Colon)) { if (!this.Match(LuatTokenId.Colon)) return false; bPassesSelf = true; this.MatchIdentifier(out name); } FunctionCall functionCall = new FunctionCall( expression, name ); LuatAstNodeBase arguments; this.MatchArguments(out arguments); functionCall.Arguments = arguments; functionCall.EndOffset = this.Token.EndOffset; functionCall.PassesSelf = bPassesSelf; expression = functionCall; return true; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Initializes a new instance of the <c>ParenthesizedExpression</c> class. /// </summary> /// <param name="expression">The <see cref="Expression"/> affected by the checked modifier.</param> /// <param name="textRange">The <see cref="TextRange"/> of the AST node.</param> public ParenthesizedExpression(Expression expression, TextRange textRange) : this(textRange) { // Initialize parameters this.Expression = expression; }
public UnresolvedExpression(LuatScript script, Expression expression) { Script = script; Expression = expression; }
/// <summary> /// Matches a <c>FunctionName</c> non-terminal. /// </summary> /// <returns><c>true</c> if the <c>FunctionName</c> was matched successfully; otherwise, <c>false</c>.</returns> /// <remarks> /// The non-terminal can start with: <c>Identifier</c>. /// </remarks> protected virtual bool MatchFunctionName(out Expression expression, out bool expectsSelf) { expression = null; Identifier identifier; IToken indexToken; expectsSelf = false; if (!this.MatchIdentifier(out identifier)) return false; expression = new VariableExpression( identifier ); while (this.TokenIs(this.LookAheadToken, LuatTokenId.Dot)) { if (!this.Match(LuatTokenId.Dot)) return false; indexToken = this.Token; if (!this.MatchIdentifier(out identifier)) return false; expression = new IndexExpression( expression, indexToken, identifier ); } if (this.TokenIs(this.LookAheadToken, LuatTokenId.Colon)) { if (!this.Match(LuatTokenId.Colon)) return false; indexToken = this.Token; expectsSelf = true; if (!this.MatchIdentifier(out identifier)) return false; expression = new IndexExpression( expression, indexToken, identifier ); } return true; }