Пример #1
0
		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// OBJECT
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		public UnaryExpression(OperatorType operatorType, Expression expression, TextRange textRange) : this( textRange )
			{
			// Initialize parameters
			this.operatorType	= operatorType;
			this.Expression		= expression;
		}
Пример #2
0
		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// 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;
		}
Пример #3
0
		public IndexExpression(Expression lhs, IToken indexToken, LuatAstNodeBase rhs, TextRange textRange) : this( textRange ) {
			// Initialize parameters
			this.LHS        = lhs;
			this.IndexToken = indexToken;
			this.RHS        = rhs;
		}
Пример #4
0
        /// <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;
        }
Пример #5
0
		/// <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;
		}
Пример #6
0
		protected bool IsFunctionCall( Expression expression )
		{
			return expression is FunctionCall;
		}
Пример #7
0
		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// 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;
		}
Пример #8
0
		/// <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;
		}
Пример #9
0
		/// <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;
		}
Пример #10
0
		/// <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;
		}
Пример #11
0
		/// <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;
		}
Пример #12
0
		/// <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;
		}
Пример #13
0
		/// <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;
		}
Пример #14
0
		/// <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;
		}
Пример #15
0
		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// 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;
		}
Пример #16
0
		/// <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;
		}
Пример #17
0
		protected bool IsVariable( Expression expression )
		{
			return expression is VariableExpression ||
			       expression is IndexExpression;
		}
Пример #18
0
		/// <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;
		}
Пример #19
0
		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// OBJECT
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		public Field(IAstNode key, Expression value, TextRange textRange) : this(textRange) {
			this.Key   = key;
			this.Value = value;
		}
Пример #20
0
		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// 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;
		}
Пример #21
0
		/// <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;
		}
Пример #22
0
		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// 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;
		}
Пример #23
0
 public UnresolvedExpression(LuatScript script, Expression expression)
 {
     Script = script;
     Expression = expression;
 }
Пример #24
0
		/// <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;
		}