@ -61,27 +61,14 @@ static const int precedence_lookup[] = {
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					11 ,  11 ,  11 ,  11  // unary operators
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				static  bool  read_file ( const  std : : filesystem: : path  & path ,  std : : string  & data  ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				static  bool  read_file ( const  std : : string & path ,  std : : string  & data ,  reshadefx : : preprocessor : : include_read_file_callback  & cb  ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					std : : ifstream file ( path ,  std : : ios : : binary )  ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( !  file) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					std : : string file_data  ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( ! cb( path ,   file_data)  ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Read file contents into memory
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					std : : error_code  ec ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					const  uintmax_t  file_size  =  std : : filesystem : : file_size ( path ,  ec ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( ec ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					std : : string  file_data ( static_cast < size_t > ( file_size  +  1 ) ,  ' \0 ' ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( ! file . read ( file_data . data ( ) ,  file_size ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// No longer need to have a handle open to the file, since all data was read, so can safely close it
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					file . close ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Append a new line feed to the end of the input string to avoid issues with parsing
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					file_data .  back( )  =  ' \n ' ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					file_data . push_back ( ' \n ' ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Remove BOM (0xefbbbf means 0xfeff)
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( file_data . size ( )  > =  3  & & 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -94,6 +81,33 @@ static bool read_file(const std::filesystem::path &path, std::string &data)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  true ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				bool  reshadefx : : preprocessor : : stdfs_read_file_callback ( const  std : : string  & path ,  std : : string  & data ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  std : : ifstream  file ( std : : filesystem : : path ( path ) ,  std : : ios : : binary ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  ( ! file ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  // Read file contents into memory
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  std : : error_code  ec ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  const  uintmax_t  file_size  =  std : : filesystem : : file_size ( path ,  ec ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  ( ec ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					data . reserve ( file_size  +  1 ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					data . resize ( static_cast < size_t > ( file_size ) ,  ' \0 ' ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  if  ( ! file . read ( data . data ( ) ,  file_size ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  // No longer need to have a handle open to the file, since all data was read, so can safely close it
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				  file . close ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  true ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				bool  reshadefx : : preprocessor : : stdfs_file_exists_callback ( const  std : : string  & path ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  std : : filesystem : : exists ( std : : filesystem : : path ( path ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				template  < char  ESCAPE_CHAR  =  ' \\ ' > 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				static  std : : string  escape_string ( std : : string  s ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -103,16 +117,25 @@ static std::string escape_string(std::string s)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				reshadefx : : preprocessor : : preprocessor ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					:  _file_exists_cb ( stdfs_file_exists_callback ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					,  _read_file_cb ( stdfs_read_file_callback ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				reshadefx : : preprocessor : : ~ preprocessor ( ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				void  reshadefx : : preprocessor : : add_include_path ( const  std : : filesystem : : path  & path ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				void  reshadefx : : preprocessor : : set_include_callbacks ( include_file_exists_callback  file_exists , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                                    include_read_file_callback  read_file ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					_file_exists_cb  =  file_exists ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					_read_file_cb  =  read_file ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				void  reshadefx : : preprocessor : : add_include_path ( const  std : : string  & path ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					assert ( ! path . empty ( ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					_include_paths . push_back ( path ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					_include_paths . push_back ( std: : filesystem : :  path( path ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				bool  reshadefx : : preprocessor : : add_macro_definition ( const  std : : string  & name ,  const  macro  & macro ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -120,15 +143,15 @@ bool reshadefx::preprocessor::add_macro_definition(const std::string &name, cons
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  _macros . emplace ( name ,  macro ) . second ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				bool  reshadefx : : preprocessor : : append_file ( const  std : : filesystem: : path   & path ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				bool  reshadefx : : preprocessor : : append_file ( const  std : : string  & path ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					std : : string  source_code ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( ! read_file ( path ,  source_code  )) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( ! read_file ( path ,  source_code , _read_file_cb  )) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  append_string ( std : : move ( source_code ) ,  path ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				bool  reshadefx : : preprocessor : : append_string ( std : : string  source_code ,  const  std : : filesystem: : path  & path  ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				bool  reshadefx : : preprocessor : : append_string ( std : : string  source_code ,  const  std : : string & path  /* = std::string() */  ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Enforce all input strings to end with a line feed
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					assert ( ! source_code . empty ( )  & &  source_code . back ( )  = =  ' \n ' ) ; 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -138,7 +161,7 @@ bool reshadefx::preprocessor::append_string(std::string source_code, const std::
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// Give this push a name, so that lexer location starts at a new line
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// This is necessary in case this string starts with a preprocessor directive, since the lexer only reports those as such if they appear at the beginning of a new line
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					// But without a name, the lexer location is set to the last token location, which most likely will not be at the start of the line
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					push ( std : : move ( source_code ) ,  path . empty ( )  ?  " unknown "  :  path .u8string ( )  ); 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					push ( std : : move ( source_code ) ,  path . empty ( )  ?  " unknown "  :  path  ); 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					parse ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					return  _success ; 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -667,10 +690,9 @@ void reshadefx::preprocessor::parse_include()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					std : : filesystem : : path  file_path  =  std : : filesystem : : u8path ( _output_location . source ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					file_path . replace_filename ( file_name ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					std : : error_code  ec ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( ! std : : filesystem : : exists ( file_path ,  ec ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if  ( ! _file_exists_cb ( file_path . u8string ( ) ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						for  ( const  std : : filesystem : : path  & include_path  :  _include_paths ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  ( std: : filesystem : : exists ( file_path  =  include_path  /  file_name ,  ec  ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  ( _file_exists_cb( ( file_path  =  include_path  /  file_name ) . u8string ( )  ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					const  std : : string  file_path_string  =  file_path . u8string ( ) ; 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -687,7 +709,7 @@ void reshadefx::preprocessor::parse_include()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					else 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  ( ! read_file ( file_path ,  input ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if  ( ! read_file ( file_path _string ,  input ,  _read_file_cb ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							return  error ( keyword_location ,  " could not open included file ' "  +  file_name . u8string ( )  +  ' \' ' ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						_file_cache . emplace ( file_path_string ,  input ) ; 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -863,13 +885,12 @@ bool reshadefx::preprocessor::evaluate_expression()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								if  ( has_parentheses  & &  ! expect ( tokenid : : parenthesis_close ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
									return  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								std : : error_code  ec ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								if  ( ! std : : filesystem : : exists ( file_path ,  ec ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								if  ( ! _file_exists_cb ( file_path . u8string ( ) ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
									for  ( const  std : : filesystem : : path  & include_path  :  _include_paths ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
										if  ( std: : filesystem : : exists ( file_path  =  include_path  /  file_name ,  ec  ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
										if  ( _file_exists_cb( ( file_path  =  include_path  /  file_name ) . u8string ( )  ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
											break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								rpn [ rpn_index + + ]  =  {  std: : filesystem : : exists ( file_path ,  ec  )  ?  1  :  0 ,  false  } ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								rpn [ rpn_index + + ]  =  {  _file_exists_cb( file_path . u8string ( )  )  ?  1  :  0 ,  false  } ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
								continue ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
							if  ( _token . literal_as_string  = =  " defined " )