Handle #pragma (or at least, don't fail on them).
authorRyan C. Gordon <icculus@icculus.org>
Mon, 31 May 2010 19:21:12 -0400
changeset 910 3ee487d85ecb
parent 909 1859faa45249
child 911 e35fface51db
Handle #pragma (or at least, don't fail on them).
mojoshader_compiler.c
mojoshader_internal.h
mojoshader_lexer.c
mojoshader_lexer.re
mojoshader_parser_hlsl.lemon
mojoshader_preprocessor.c
--- a/mojoshader_compiler.c	Tue Apr 06 16:03:27 2010 -0400
+++ b/mojoshader_compiler.c	Mon May 31 19:21:12 2010 -0400
@@ -2266,6 +2266,8 @@
         case ((Token) ';'): return TOKEN_HLSL_SEMICOLON;
         case ((Token) '{'): return TOKEN_HLSL_LBRACE;
         case ((Token) '}'): return TOKEN_HLSL_RBRACE;
+        //case ((Token) TOKEN_PP_PRAGMA): return TOKEN_HLSL_PRAGMA;
+        //case ((Token) '\n'): return TOKEN_HLSL_NEWLINE;
 
         case ((Token) TOKEN_IDENTIFIER):
             #define tokencmp(t) ((tokenlen == strlen(t)) && (memcmp(token, t, tokenlen) == 0))
@@ -2449,6 +2451,8 @@
     } // for
 
     // Run the preprocessor/lexer/parser...
+    int is_pragma = 0;   // !!! FIXME: remove this later when we can parse #pragma.
+    int skipping = 0; // !!! FIXME: remove this later when we can parse #pragma.
     do {
         token = preprocessor_nexttoken(pp, &tokenlen, &tokenval);
 
@@ -2476,6 +2480,27 @@
             continue;
         } // else if
 
+        else if (tokenval == TOKEN_PP_PRAGMA)
+        {
+            assert(!is_pragma);
+            is_pragma = 1;
+            skipping = 1;
+            continue;
+        }
+
+        else if (tokenval == ((Token) '\n'))
+        {
+            assert(is_pragma);
+            is_pragma = 0;
+            skipping = 0;
+            continue;
+        }
+
+        else if (skipping)
+        {
+            continue;
+        }
+
         lemon_token = convert_to_lemon_token(ctx, token, tokenlen, tokenval);
         switch (lemon_token)
         {
--- a/mojoshader_internal.h	Tue Apr 06 16:03:27 2010 -0400
+++ b/mojoshader_internal.h	Mon May 31 19:21:12 2010 -0400
@@ -425,7 +425,8 @@
     //  is reported. It happens for things like missing #includes, etc.
     TOKEN_PREPROCESSING_ERROR,
 
-    // These are all caught by the preprocessor. Caller won't ever see them.
+    // These are all caught by the preprocessor. Caller won't ever see them,
+    //  except TOKEN_PP_PRAGMA.
     //  They control the preprocessor (#includes new files, etc).
     TOKEN_PP_INCLUDE,
     TOKEN_PP_LINE,
@@ -438,6 +439,7 @@
     TOKEN_PP_ELIF,
     TOKEN_PP_ENDIF,
     TOKEN_PP_ERROR,  // caught, becomes TOKEN_PREPROCESSING_ERROR
+    TOKEN_PP_PRAGMA,
     TOKEN_INCOMPLETE_COMMENT,  // caught, becomes TOKEN_PREPROCESSING_ERROR
     TOKEN_PP_UNARY_MINUS,  // used internally, never returned.
     TOKEN_PP_UNARY_PLUS,   // used internally, never returned.
--- a/mojoshader_lexer.c	Tue Apr 06 16:03:27 2010 -0400
+++ b/mojoshader_lexer.c	Mon May 31 19:21:12 2010 -0400
@@ -1229,18 +1229,20 @@
 	}
 	yyaccept = 0;
 	yych = *(YYMARKER = ++YYCURSOR);
-	if (yych <= 'e') {
+	if (yych <= 'h') {
 		if (yych <= 0x1F) {
 			if (yych == '\t') goto yy214;
 		} else {
 			if (yych <= ' ') goto yy214;
-			if (yych >= 'd') goto yy214;
+			if (yych <= 'c') goto yy207;
+			if (yych <= 'e') goto yy214;
 		}
 	} else {
-		if (yych <= 'k') {
-			if (yych == 'i') goto yy214;
+		if (yych <= 'o') {
+			if (yych <= 'i') goto yy214;
+			if (yych == 'l') goto yy214;
 		} else {
-			if (yych <= 'l') goto yy214;
+			if (yych <= 'p') goto yy214;
 			if (yych == 'u') goto yy214;
 		}
 	}
@@ -1277,21 +1279,22 @@
 	if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
 	yych = *YYCURSOR;
 yy214:
-	if (yych <= 'e') {
-		if (yych <= 0x1F) {
+	if (yych <= 'h') {
+		if (yych <= ' ') {
 			if (yych == '\t') goto yy213;
+			if (yych >= ' ') goto yy213;
 		} else {
-			if (yych <= ' ') goto yy213;
 			if (yych <= 'c') goto yy215;
-			if (yych <= 'd') goto yy219;
-			goto yy216;
+			if (yych <= 'd') goto yy220;
+			if (yych <= 'e') goto yy217;
 		}
 	} else {
-		if (yych <= 'k') {
-			if (yych == 'i') goto yy217;
+		if (yych <= 'o') {
+			if (yych <= 'i') goto yy218;
+			if (yych == 'l') goto yy221;
 		} else {
-			if (yych <= 'l') goto yy220;
-			if (yych == 'u') goto yy218;
+			if (yych <= 'p') goto yy216;
+			if (yych == 'u') goto yy219;
 		}
 	}
 yy215:
@@ -1299,33 +1302,37 @@
 	if (yyaccept <= 0) {
 		goto yy207;
 	} else {
-		goto yy238;
+		goto yy239;
 	}
 yy216:
 	yych = *++YYCURSOR;
+	if (yych == 'r') goto yy272;
+	goto yy215;
+yy217:
+	yych = *++YYCURSOR;
 	if (yych <= 'm') {
-		if (yych == 'l') goto yy254;
+		if (yych == 'l') goto yy255;
 		goto yy215;
 	} else {
-		if (yych <= 'n') goto yy255;
-		if (yych == 'r') goto yy256;
+		if (yych <= 'n') goto yy256;
+		if (yych == 'r') goto yy257;
 		goto yy215;
 	}
-yy217:
-	yych = *++YYCURSOR;
-	if (yych == 'f') goto yy237;
-	if (yych == 'n') goto yy236;
-	goto yy215;
 yy218:
 	yych = *++YYCURSOR;
-	if (yych == 'n') goto yy231;
+	if (yych == 'f') goto yy238;
+	if (yych == 'n') goto yy237;
 	goto yy215;
 yy219:
 	yych = *++YYCURSOR;
-	if (yych == 'e') goto yy225;
+	if (yych == 'n') goto yy232;
 	goto yy215;
 yy220:
 	yych = *++YYCURSOR;
+	if (yych == 'e') goto yy226;
+	goto yy215;
+yy221:
+	yych = *++YYCURSOR;
 	if (yych != 'i') goto yy215;
 	yych = *++YYCURSOR;
 	if (yych != 'n') goto yy215;
@@ -1333,7 +1340,7 @@
 	if (yych != 'e') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_LINE); }
-yy225:
+yy226:
 	yych = *++YYCURSOR;
 	if (yych != 'f') goto yy215;
 	yych = *++YYCURSOR;
@@ -1344,7 +1351,7 @@
 	if (yych != 'e') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_DEFINE); }
-yy231:
+yy232:
 	yych = *++YYCURSOR;
 	if (yych != 'd') goto yy215;
 	yych = *++YYCURSOR;
@@ -1353,36 +1360,36 @@
 	if (yych != 'f') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_UNDEF); }
-yy236:
+yy237:
 	yych = *++YYCURSOR;
-	if (yych == 'c') goto yy248;
+	if (yych == 'c') goto yy249;
 	goto yy215;
-yy237:
+yy238:
 	yyaccept = 1;
 	yych = *(YYMARKER = ++YYCURSOR);
-	if (yych == 'd') goto yy240;
-	if (yych == 'n') goto yy239;
-yy238:
-	{ RET(TOKEN_PP_IF); }
+	if (yych == 'd') goto yy241;
+	if (yych == 'n') goto yy240;
 yy239:
+	{ RET(TOKEN_PP_IF); }
+yy240:
 	yych = *++YYCURSOR;
-	if (yych == 'd') goto yy244;
+	if (yych == 'd') goto yy245;
 	goto yy215;
-yy240:
+yy241:
 	yych = *++YYCURSOR;
 	if (yych != 'e') goto yy215;
 	yych = *++YYCURSOR;
 	if (yych != 'f') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_IFDEF); }
-yy244:
+yy245:
 	yych = *++YYCURSOR;
 	if (yych != 'e') goto yy215;
 	yych = *++YYCURSOR;
 	if (yych != 'f') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_IFNDEF); }
-yy248:
+yy249:
 	yych = *++YYCURSOR;
 	if (yych != 'l') goto yy215;
 	yych = *++YYCURSOR;
@@ -1393,17 +1400,17 @@
 	if (yych != 'e') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_INCLUDE); }
-yy254:
-	yych = *++YYCURSOR;
-	if (yych == 'i') goto yy265;
-	if (yych == 's') goto yy266;
-	goto yy215;
 yy255:
 	yych = *++YYCURSOR;
-	if (yych == 'd') goto yy261;
+	if (yych == 'i') goto yy266;
+	if (yych == 's') goto yy267;
 	goto yy215;
 yy256:
 	yych = *++YYCURSOR;
+	if (yych == 'd') goto yy262;
+	goto yy215;
+yy257:
+	yych = *++YYCURSOR;
 	if (yych != 'r') goto yy215;
 	yych = *++YYCURSOR;
 	if (yych != 'o') goto yy215;
@@ -1411,25 +1418,36 @@
 	if (yych != 'r') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_ERROR); }
-yy261:
+yy262:
 	yych = *++YYCURSOR;
 	if (yych != 'i') goto yy215;
 	yych = *++YYCURSOR;
 	if (yych != 'f') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_ENDIF); }
-yy265:
+yy266:
 	yych = *++YYCURSOR;
-	if (yych == 'f') goto yy269;
+	if (yych == 'f') goto yy270;
 	goto yy215;
-yy266:
+yy267:
 	yych = *++YYCURSOR;
 	if (yych != 'e') goto yy215;
 	++YYCURSOR;
 	{ RET(TOKEN_PP_ELSE); }
-yy269:
+yy270:
 	++YYCURSOR;
 	{ RET(TOKEN_PP_ELIF); }
+yy272:
+	yych = *++YYCURSOR;
+	if (yych != 'a') goto yy215;
+	yych = *++YYCURSOR;
+	if (yych != 'g') goto yy215;
+	yych = *++YYCURSOR;
+	if (yych != 'm') goto yy215;
+	yych = *++YYCURSOR;
+	if (yych != 'a') goto yy215;
+	++YYCURSOR;
+	{ RET(TOKEN_PP_PRAGMA); }
 }
 
 
@@ -1442,24 +1460,24 @@
 	yych = *YYCURSOR;
 	if (yych <= '#') {
 		if (yych <= '\r') {
-			if (yych <= 0x00) goto yy275;
-			if (yych <= 0x08) goto yy277;
+			if (yych <= 0x00) goto yy282;
+			if (yych <= 0x08) goto yy284;
 		} else {
-			if (yych <= 0x1F) goto yy277;
-			if (yych == '"') goto yy277;
+			if (yych <= 0x1F) goto yy284;
+			if (yych == '"') goto yy284;
 		}
 	} else {
 		if (yych <= '@') {
-			if (yych <= '$') goto yy277;
-			if (yych >= '@') goto yy277;
+			if (yych <= '$') goto yy284;
+			if (yych >= '@') goto yy284;
 		} else {
-			if (yych == '`') goto yy277;
-			if (yych >= 0x7F) goto yy277;
+			if (yych == '`') goto yy284;
+			if (yych >= 0x7F) goto yy284;
 		}
 	}
 	++YYCURSOR;
 	{ cursor--; RET(TOKEN_BAD_CHARS); }
-yy275:
+yy282:
 	++YYCURSOR;
 	{
                         if (eoi)
@@ -1472,7 +1490,7 @@
                         }
                         goto bad_chars;
                     }
-yy277:
+yy284:
 	++YYCURSOR;
 	{ goto bad_chars; }
 }
--- a/mojoshader_lexer.re	Tue Apr 06 16:03:27 2010 -0400
+++ b/mojoshader_lexer.re	Mon May 31 19:21:12 2010 -0400
@@ -212,6 +212,7 @@
         PP "elif"       { RET(TOKEN_PP_ELIF); }
         PP "endif"      { RET(TOKEN_PP_ENDIF); }
         PP "error"      { RET(TOKEN_PP_ERROR); }
+        PP "pragma"     { RET(TOKEN_PP_PRAGMA); }
         WHITESPACE      { goto ppdirective; }
 
         ANY             {
--- a/mojoshader_parser_hlsl.lemon	Tue Apr 06 16:03:27 2010 -0400
+++ b/mojoshader_parser_hlsl.lemon	Mon May 31 19:21:12 2010 -0400
@@ -84,6 +84,7 @@
 
 %type compilation_unit { CompilationUnit * }
 %destructor compilation_unit { delete_compilation_unit(ctx, $$); }
+//compilation_unit(A) ::= PRAGMA . { A = NULL; }   // !!! FIXME: deal with pragmas.
 compilation_unit(A) ::= variable_declaration(B). { A = new_global_variable(ctx, B); }
 compilation_unit(A) ::= function_signature(B) SEMICOLON. { A = new_function(ctx, B, NULL); }
 compilation_unit(A) ::= function_signature(B) statement_block(C). { A = new_function(ctx, B, C); }
--- a/mojoshader_preprocessor.c	Tue Apr 06 16:03:27 2010 -0400
+++ b/mojoshader_preprocessor.c	Mon May 31 19:21:12 2010 -0400
@@ -44,6 +44,7 @@
     char failstr[256];
     int recursion_count;
     int asm_comments;
+    int parsing_pragma;
     Conditional *conditional_pool;
     IncludeState *include_stack;
     IncludeState *include_pool;
@@ -161,6 +162,7 @@
         TOKENCASE(TOKEN_PP_ELIF);
         TOKENCASE(TOKEN_PP_ENDIF);
         TOKENCASE(TOKEN_PP_ERROR);
+        TOKENCASE(TOKEN_PP_PRAGMA);
         TOKENCASE(TOKEN_INCOMPLETE_COMMENT);
         TOKENCASE(TOKEN_BAD_CHARS);
         TOKENCASE(TOKEN_EOI);
@@ -2194,6 +2196,11 @@
             continue;  // will return at top of loop.
         } // else if
 
+        else if (token == TOKEN_PP_PRAGMA)
+        {
+            ctx->parsing_pragma = 1;
+        } // else if
+
         if (token == TOKEN_IDENTIFIER)
         {
             if (handle_pp_identifier(ctx))
@@ -2203,8 +2210,13 @@
         else if (token == ((Token) '\n'))
         {
             print_debug_lexing_position(state);
-            // preprocessor is line-oriented, nothing else gets newlines.
-            continue;  // get the next thing.
+            if (ctx->parsing_pragma)  // let this one through.
+                ctx->parsing_pragma = 0;
+            else
+            {
+                // preprocessor is line-oriented, nothing else gets newlines.
+                continue;  // get the next thing.
+            } // else
         } // else if
 
         assert(!skipping);
@@ -2383,6 +2395,16 @@
             } // if
         } // if
 
+        else if (token == ((Token) '\n'))
+        {
+            if (!out_of_memory)
+            {
+                out_of_memory =
+                    (!add_to_buffer(&buffer, endline, sizeof (endline), m, d));
+            } // if
+            isnewline = 1;
+        } // else if
+
         else if (token == ((Token) '{'))
         {
             if (!out_of_memory)