Example #1
0
		/// <summary>
		/// Matches a <c>FunctionDeclaration</c> non-terminal.
		/// </summary>
		/// <returns><c>true</c> if the <c>FunctionDeclaration</c> was matched successfully; otherwise, <c>false</c>.</returns>
		/// <remarks>
		/// The non-terminal can start with: <c>Function</c>.
		/// </remarks>
		protected virtual bool MatchFunctionDeclaration(out Statement statement) {
			statement = null;
			int start = this.LookAheadToken.StartOffset;
			string description = this.GetDescription();
			bool expectsSelf;
			if (!this.Match(LuatTokenId.Function))
				return false;
			Expression name;
			if (!this.MatchFunctionName(out name, out expectsSelf))
				return false;
			Function function;
			if (!this.MatchFunctionBody(out function))
				return false;
			AssignmentStatement assignment = new AssignmentStatement();
			assignment.Variables.Add( name );
			assignment.Values.Add( function );
			
			// Use the preceding comment as the function description
			function.Description = (null != description)
				? description.Trim( '\n', '\r' )
				: null;
			
			function.ExpectsSelf = expectsSelf;
			
			// Mark the LHS expression as being assigned.
			// This alters the way certain variables are resolved.
			name.IsLHSOfAssignment = true;
			
			assignment.StartOffset = start; assignment.EndOffset = this.Token.EndOffset;
			statement = assignment;
			return true;
		}
Example #2
0
		/// <summary>
		/// Matches a <c>AssignmentOrFunctionCall</c> non-terminal.
		/// </summary>
		/// <returns><c>true</c> if the <c>AssignmentOrFunctionCall</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 MatchAssignmentOrFunctionCall(out Statement statement) {
			Expression expression = null;
			statement             = null;
			int start = this.LookAheadToken.StartOffset;
			if (!this.MatchExpressionNoFunction(out expression))
				return false;
			if ( IsFunctionCall( expression ) )
				{
				statement = new ExpressionStatement( expression );
				return true;
			}
			
			AssignmentStatement assignment = new AssignmentStatement();
			statement = assignment;
			
			assignment.Variables.Add( expression );
			while (this.TokenIs(this.LookAheadToken, LuatTokenId.Comma)) {
				if (!this.Match(LuatTokenId.Comma))
					return false;
				if (!this.MatchExpressionNoFunction(out expression))
					return false;
				assignment.Variables.Add( expression );
			}
			if (!this.Match(LuatTokenId.Assignment))
				return false;
			if (!this.MatchExpressionList(assignment.Values))
				return false;
			foreach( Expression variable in assignment.Variables )
				{
				// Mark the LHS expression as being assigned.
				// This alters the way certain variables are resolved.
				variable.IsLHSOfAssignment = true;
				
				if( false == IsVariable( variable ) )
					{
					// First expression was not a variable or a function call.
					// Invalid statement
					string message = "The left-hand side of an assignment must be a variable";
					compilationUnit.SyntaxErrors.Add(new SyntaxError( variable.TextRange, message ) );
				}
			}
			
			assignment.StartOffset = start;
			assignment.EndOffset   = this.Token.EndOffset;
			return true;
		}
Example #3
0
		/// <summary>
		/// Matches a <c>LocalSuffix</c> non-terminal.
		/// </summary>
		/// <returns><c>true</c> if the <c>LocalSuffix</c> was matched successfully; otherwise, <c>false</c>.</returns>
		/// <remarks>
		/// The non-terminal can start with: <c>Function</c>, <c>Identifier</c>.
		/// </remarks>
		protected virtual bool MatchLocalSuffix(out Statement statement) {
			statement = null;
			AssignmentStatement assignment = new AssignmentStatement();
			assignment.IsLocal = true;
			Identifier type = null;
			if (this.TokenIs(this.LookAheadToken, LuatTokenId.Identifier)) {
				if (!this.MatchVariableList(assignment.Variables))
					return false;
				if (this.TokenIs(this.LookAheadToken, LuatTokenId.Colon)) {
					if (!this.Match(LuatTokenId.Colon))
						return false;
					if (!this.MatchIdentifier(out type))
						return false;
				}
				if (this.TokenIs(this.LookAheadToken, LuatTokenId.Assignment)) {
					if (!this.Match(LuatTokenId.Assignment))
						return false;
					if (!this.MatchExpressionList(assignment.Values))
						return false;
				}
			}
			else if (this.TokenIs(this.LookAheadToken, LuatTokenId.Function)) {
				if (!this.Match(LuatTokenId.Function))
					return false;
				Expression variableNode;
				if (!this.MatchVariable(out variableNode))
					return false;
				Function function;
				if (!this.MatchFunctionBody(out function))
					return false;
				VariableExpression variableExpression = variableNode as VariableExpression;
				assignment.Variables.Add( variableNode );
				assignment.Values.Add( function );
			}
			else
				return false;
			foreach ( VariableExpression v in assignment.Variables )
				{
				v.IsLHSOfAssignment = true;
				v.IsLocal           = true;
				v.Type              = type == null ? null : type.Text;
			}
			
			statement = assignment;
			return true;
		}