From 89532247e625e8cde6b3300ee1b7c100dc7a4600 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 31 May 2010 19:21:12 -0400 Subject: [PATCH] Handle #pragma (or at least, don't fail on them). --- mojoshader_compiler.c | 25 +++++++ mojoshader_internal.h | 4 +- mojoshader_lexer.c | 136 ++++++++++++++++++++--------------- mojoshader_lexer.re | 1 + mojoshader_parser_hlsl.lemon | 1 + mojoshader_preprocessor.c | 26 ++++++- 6 files changed, 131 insertions(+), 62 deletions(-) diff --git a/mojoshader_compiler.c b/mojoshader_compiler.c index fcc0c694..1cc0c190 100644 --- a/mojoshader_compiler.c +++ b/mojoshader_compiler.c @@ -2266,6 +2266,8 @@ static int convert_to_lemon_token(Context *ctx, const char *token, 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 @@ static void parse_source(Context *ctx, const char *filename, } // 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 @@ static void parse_source(Context *ctx, const char *filename, 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) { diff --git a/mojoshader_internal.h b/mojoshader_internal.h index 28de3f5e..3ce2afdb 100644 --- a/mojoshader_internal.h +++ b/mojoshader_internal.h @@ -425,7 +425,8 @@ typedef enum // 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 @@ typedef enum 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. diff --git a/mojoshader_lexer.c b/mojoshader_lexer.c index 5cfb20f1..efdf53ef 100644 --- a/mojoshader_lexer.c +++ b/mojoshader_lexer.c @@ -1229,18 +1229,20 @@ Token preprocessor_lexer(IncludeState *s) } 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 @@ Token preprocessor_lexer(IncludeState *s) 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,32 +1302,36 @@ Token preprocessor_lexer(IncludeState *s) 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; @@ -1333,7 +1340,7 @@ Token preprocessor_lexer(IncludeState *s) 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 @@ Token preprocessor_lexer(IncludeState *s) 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 @@ Token preprocessor_lexer(IncludeState *s) 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,16 +1400,16 @@ Token preprocessor_lexer(IncludeState *s) 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; @@ -1411,25 +1418,36 @@ Token preprocessor_lexer(IncludeState *s) 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 @@ Token preprocessor_lexer(IncludeState *s) 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 @@ Token preprocessor_lexer(IncludeState *s) } goto bad_chars; } -yy277: +yy284: ++YYCURSOR; { goto bad_chars; } } diff --git a/mojoshader_lexer.re b/mojoshader_lexer.re index 47a33650..1cf1b973 100644 --- a/mojoshader_lexer.re +++ b/mojoshader_lexer.re @@ -212,6 +212,7 @@ ppdirective: 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 { diff --git a/mojoshader_parser_hlsl.lemon b/mojoshader_parser_hlsl.lemon index 440e8541..e0ff5669 100644 --- a/mojoshader_parser_hlsl.lemon +++ b/mojoshader_parser_hlsl.lemon @@ -84,6 +84,7 @@ compilation_units(A) ::= compilation_units(B) compilation_unit(C). { if (C) { C- %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); } diff --git a/mojoshader_preprocessor.c b/mojoshader_preprocessor.c index 08794f38..df038fb4 100644 --- a/mojoshader_preprocessor.c +++ b/mojoshader_preprocessor.c @@ -44,6 +44,7 @@ typedef struct Context 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 @@ void MOJOSHADER_print_debug_token(const char *subsystem, const char *token, 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 @@ static inline const char *_preprocessor_nexttoken(Preprocessor *_ctx, 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 @@ static inline const char *_preprocessor_nexttoken(Preprocessor *_ctx, 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 @@ const MOJOSHADER_preprocessData *MOJOSHADER_preprocess(const char *filename, } // 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)