Пример #1
0
		public bool HandleIfDef( Token body, int line )
		{
			if ( this.EnableOutput )
			{
				this.Error( line, "Too many embedded #if directives", null );
				return false;
			}

			var cpp = new GLSLESPreprocessor( body, line );

			Token t = cpp.GetToken( false );

			if ( t.Type != Token.Kind.Keyword )
			{
				this.Error( line, "Expecting a macro name after #ifdef, got", t );
				return false;
			}

			this.EnableOutput = false; //has to be set to false 32 times before this matters

			do
			{
				t = cpp.GetToken( false );
			} while ( t.Type == Token.Kind.Whitespace || t.Type == Token.Kind.Comment || t.Type == Token.Kind.Linecomment );

			if ( t.Type != Token.Kind.EOS )
			{
				this.Error( line, "Warning: Ignoring garbage after directive", t );
			}

			return true;
		}
Пример #2
0
		protected override void LoadFromSource()
		{
			var cpp = new GLSLESPreprocessor();

			//Pass all user-defined macros to preprocessor
			if ( this.preprocessorDefines.Length > 0 )
			{
				int pos = 0;
				while ( pos != this.preprocessorDefines.Length )
				{
					//Find delims
					int endpos = this.preprocessorDefines.IndexOf( ";,=", pos );

					if ( endpos != -1 )
					{
						int macroNameStart = pos;
						int macroNameLen = endpos - pos;
						pos = endpos;

						//Check definition part
						if ( this.preprocessorDefines[ pos ] == '=' )
						{
							//Set up a definition, skip delim
							++pos;
							int macroValStart = pos;
							int macroValLen;

							endpos = this.preprocessorDefines.IndexOf( ";,", pos );
							if ( endpos == -1 )
							{
								macroValLen = this.preprocessorDefines.Length - pos;
								pos = endpos;
							}
							else
							{
								macroValLen = endpos - pos;
								pos = endpos + 1;
							}
							cpp.Define( this.preprocessorDefines + macroNameStart, macroNameLen, this.preprocessorDefines + macroValStart, macroValLen );
						}
						else
						{
							//No definition part, define as "1"
							++pos;
							cpp.Define( this.preprocessorDefines + macroNameStart, macroNameLen, 1 );
						}
					}
					else
					{
						pos = endpos;
					}
				}
				int outSize = 0;
				string src = source;
				int srcLen = source.Length;
				string outVal = cpp.Parse( src, srcLen, out outSize );
				if ( outVal == null || outSize == 0 )
				{
					//Failed to preprocess, break out
					throw new AxiomException( "Failed to preprocess shader " + base.Name );
				}

				source = new string( outVal.ToCharArray(), 0, outSize );
			}
		}
Пример #3
0
		public bool HandleUnDef( Token body, int line )
		{
			var cpp = new GLSLESPreprocessor( body, line );

			Token t = cpp.GetToken( false );

			if ( t.Type != Token.Kind.Keyword )
			{
				this.Error( line, "Expecting a macro name after #undef, got", t );
				return false;
			}

			//Don't barf if macro does not exist = standard C behavior
			this.Undef( t.String, t.Length );

			do
			{
				t = cpp.GetToken( false );
			} while ( t.Type == Token.Kind.Whitespace || t.Type == Token.Kind.Comment || t.Type == Token.Kind.Linecomment );

			if ( t.Type != Token.Kind.EOS )
			{
				this.Error( line, "Warning: Ignoring garbage after directive", t );
			}

			return true;
		}
Пример #4
0
		public bool HandleDefine( Token body, int line )
		{
			var cpp = new GLSLESPreprocessor( body, line );

			Token t = cpp.GetToken( false );

			if ( t.Type != Token.Kind.Keyword )
			{
				this.Error( line, "Macro name expected after #define", null );
				return false;
			}

			var m = new Macro( t );
			m.Body = body;
			t = cpp.GetArguments( m.NumArgs, m.Args, false );
			while ( t.Type == Token.Kind.Whitespace )
			{
				t = cpp.GetToken( false );
			}

			switch ( t.Type )
			{
				case Token.Kind.Newline:
				case Token.Kind.EOS:
					//Assing "" to token
					t = new Token( Token.Kind.Text, string.Empty, 0 );
					break;

				case Token.Kind.Error:
					m = null;
					return false;

				default:
					t.Type = Token.Kind.Text;
					t.Length = cpp.SourceEnd - t.String.Length;
					break;
			}

			m.Value = t;
			m.Next = this.MacroList;
			this.MacroList = m;
			return true;
		}
Пример #5
0
			public Token Expand( int numArgs, Token[] args, Macro macros )
			{
				this.Expanding = true;

				var cpp = new GLSLESPreprocessor();
				cpp.MacroList = macros;
				//Define a new macro for every argument
				int i;
				for ( i = 0; i < numArgs; i++ )
				{
					cpp.Define( this.Args[ i ].String, this.Args[ i ].Length, args[ i ].String, args[ i ].Length );
				}
				//The rest arguments are empty
				for ( ; i < this.NumArgs; i++ )
				{
					cpp.Define( this.Args[ i ].String, this.Args[ i ].Length, string.Empty, 0 );
				}
				//Now run the macro expansion through the supplimentary preprocessor
				Token xt = cpp.Parse( this.Value );

				this.Expanding = false;

				//Remove the extra macros we have defined
				for ( i = this.NumArgs - 1; i >= 0; i-- )
				{
					cpp.Undef( this.Args[ i ].String, this.Args[ i ].Length );
				}

				cpp.MacroList = null;

				return xt;
			}
Пример #6
0
		public static Token ExpandDefined( GLSLESPreprocessor parent, int numArgs, Token[] args )
		{
			if ( numArgs != 1 )
			{
				parent.Error( parent.Line, "The defined() function takes exactly one argument", null );
				return new Token( Token.Kind.Error );
			}

			string v = ( parent.IsDefined( args[ 0 ] ) != null ) ? "1" : "0";
			return new Token( Token.Kind.Number, v, 1 );
		}
Пример #7
0
		public bool GetValue( Token token, out long value, int line )
		{
			value = 0;
			Token r;
			Token vt = token;

			if ( ( vt.Type == Token.Kind.Keyword || vt.Type == Token.Kind.Text || vt.Type == Token.Kind.Number ) && ( vt.String == string.Empty || vt.String == null ) )
			{
				this.Error( line, "Trying to evaluate an empty expression", null );
				return false;
			}

			if ( vt.Type == Token.Kind.Text )
			{
				var cpp = new GLSLESPreprocessor( token, line );
				cpp.MacroList = this.MacroList;

				Token t = cpp.GetExpression( out r, line, 0 );

				cpp.MacroList = null;

				if ( t.Type == Token.Kind.Error )
				{
					return false;
				}

				if ( t.Type != Token.Kind.EOS )
				{
					this.Error( line, "Garbage afer expression", t );
					return false;
				}

				vt = r;
			}

			Macro m;
			switch ( vt.Type )
			{
				case Token.Kind.EOS:
				case Token.Kind.Error:
					return false;

				case Token.Kind.Text:
				case Token.Kind.Number:
					if ( !vt.GetValue( out value ) )
					{
						this.Error( line, "Not a numeric expression", vt );
						return false;
					}
					break;
				case Token.Kind.Keyword:
					//Try to expand the macro
					m = this.IsDefined( vt );
					if ( m != null && !m.Expanding )
					{
						Token x = this.ExpandMacro( vt );
						m.Expanding = true;
						bool rc = this.GetValue( x, out value, line );
						m.Expanding = false;
						return rc;
					}
					//Undefined macro, "expand to 0 mimic cpp behaviour
					value = 0;
					break;
				default:
					this.Error( line, "Unexpected token", vt );
					break;
			}

			return true;
		}