mojoshader_preprocessor.c
changeset 798 5dd67cc04cf9
parent 755 6a7aa96c51c7
child 813 a8ec84003cd2
equal deleted inserted replaced
797:58d15db2881e 798:5dd67cc04cf9
   304 } // add_to_buffer
   304 } // add_to_buffer
   305 
   305 
   306 
   306 
   307 static char *flatten_buffer(Buffer *buffer, MOJOSHADER_malloc m, void *d)
   307 static char *flatten_buffer(Buffer *buffer, MOJOSHADER_malloc m, void *d)
   308 {
   308 {
   309     char *retval = m(buffer->total_bytes + 1, d);
   309     char *retval = (char *) m(buffer->total_bytes + 1, d);
   310     if (retval == NULL)
   310     if (retval == NULL)
   311         return NULL;
   311         return NULL;
   312     BufferList *item = &buffer->head;
   312     BufferList *item = &buffer->head;
   313     char *ptr = retval;
   313     char *ptr = retval;
   314     while (item != NULL)
   314     while (item != NULL)
   488 } // find_define_by_token
   488 } // find_define_by_token
   489 
   489 
   490 
   490 
   491 static void put_all_defines(Context *ctx)
   491 static void put_all_defines(Context *ctx)
   492 {
   492 {
   493     int i;
   493     size_t i;
   494     for (i = 0; i < STATICARRAYLEN(ctx->define_hashtable); i++)
   494     for (i = 0; i < STATICARRAYLEN(ctx->define_hashtable); i++)
   495     {
   495     {
   496         Define *bucket = ctx->define_hashtable[i];
   496         Define *bucket = ctx->define_hashtable[i];
   497         ctx->define_hashtable[i] = NULL;
   497         ctx->define_hashtable[i] = NULL;
   498         while (bucket)
   498         while (bucket)
   649                             const MOJOSHADER_preprocessorDefine *defines,
   649                             const MOJOSHADER_preprocessorDefine *defines,
   650                             unsigned int define_count, int asm_comments,
   650                             unsigned int define_count, int asm_comments,
   651                             MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
   651                             MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
   652 {
   652 {
   653     int okay = 1;
   653     int okay = 1;
   654     int i = 0;
   654     unsigned int i = 0;
   655 
   655 
   656     // the preprocessor is internal-only, so we verify all these are != NULL.
   656     // the preprocessor is internal-only, so we verify all these are != NULL.
   657     assert(m != NULL);
   657     assert(m != NULL);
   658     assert(f != NULL);
   658     assert(f != NULL);
   659     assert(open_callback != NULL);
   659     assert(open_callback != NULL);
   944 
   944 
   945 
   945 
   946 static void handle_pp_define(Context *ctx)
   946 static void handle_pp_define(Context *ctx)
   947 {
   947 {
   948     IncludeState *state = ctx->include_stack;
   948     IncludeState *state = ctx->include_stack;
       
   949     int done = 0;
   949 
   950 
   950     if (lexer(state) != TOKEN_IDENTIFIER)
   951     if (lexer(state) != TOKEN_IDENTIFIER)
   951     {
   952     {
   952         fail(ctx, "Macro names must be identifiers");
   953         fail(ctx, "Macro names must be identifiers");
   953         return;
   954         return;
   972     lexer(state);
   973     lexer(state);
   973     state->report_whitespace = 0;
   974     state->report_whitespace = 0;
   974 
   975 
   975     int params = 0;
   976     int params = 0;
   976     char **idents = NULL;
   977     char **idents = NULL;
       
   978     MOJOSHADER_malloc m = ctx->malloc;
       
   979     void *d = ctx->malloc_data;
       
   980     static const char space = ' ';
   977 
   981 
   978     if (state->tokenval == ((Token) ' '))
   982     if (state->tokenval == ((Token) ' '))
   979         lexer(state);  // skip it.
   983         lexer(state);  // skip it.
   980     else if (state->tokenval == ((Token) '('))
   984     else if (state->tokenval == ((Token) '('))
   981     {
   985     {
  1045     pushback(state);
  1049     pushback(state);
  1046 
  1050 
  1047     Buffer buffer;
  1051     Buffer buffer;
  1048     init_buffer(&buffer);
  1052     init_buffer(&buffer);
  1049 
  1053 
  1050     MOJOSHADER_malloc m = ctx->malloc;
       
  1051     void *d = ctx->malloc_data;
       
  1052     static const char space = ' ';
       
  1053 
       
  1054     state->report_whitespace = 1;
  1054     state->report_whitespace = 1;
  1055     int done = 0;
       
  1056     while ((!done) && (!ctx->out_of_memory))
  1055     while ((!done) && (!ctx->out_of_memory))
  1057     {
  1056     {
  1058         const Token token = lexer(state);
  1057         const Token token = lexer(state);
  1059         switch (token)
  1058         switch (token)
  1060         {
  1059         {
  1193     if (ctx->recursion_count++ >= 256)
  1192     if (ctx->recursion_count++ >= 256)
  1194     {
  1193     {
  1195         fail(ctx, "Recursing macros");
  1194         fail(ctx, "Recursing macros");
  1196         return 0;
  1195         return 0;
  1197     } // if
  1196     } // if
       
  1197 
       
  1198     const char *fname = NULL;
       
  1199     const char *val = NULL;
       
  1200     size_t vallen = 0;
  1198 
  1201 
  1199     IncludeState *state = ctx->include_stack;
  1202     IncludeState *state = ctx->include_stack;
  1200     char *sym = (char *) alloca(state->tokenlen+1);
  1203     char *sym = (char *) alloca(state->tokenlen+1);
  1201     memcpy(sym, state->token, state->tokenlen);
  1204     memcpy(sym, state->token, state->tokenlen);
  1202     sym[state->tokenlen] = '\0';
  1205     sym[state->tokenlen] = '\0';
  1309                 goto handle_pp_identifier_failed;
  1312                 goto handle_pp_identifier_failed;
  1310             } // if
  1313             } // if
  1311         } // if
  1314         } // if
  1312     } // if
  1315     } // if
  1313 
  1316 
  1314     const char *val = def->definition;
  1317     val = def->definition;
  1315     const size_t vallen = strlen(val);
  1318     vallen = strlen(val);
  1316     const char *fname = state->filename;
  1319     fname = state->filename;
  1317     if (!push_source(ctx, fname, val, vallen, state->line, NULL, params))
  1320     if (!push_source(ctx, fname, val, vallen, state->line, NULL, params))
  1318     {
  1321     {
  1319         assert(ctx->out_of_memory);
  1322         assert(ctx->out_of_memory);
  1320         goto handle_pp_identifier_failed;
  1323         goto handle_pp_identifier_failed;
  1321     } // if
  1324     } // if
  1347         { 10, ((Token) '%') }, { 10, ((Token) '/') }, { 10, ((Token) '*') },
  1350         { 10, ((Token) '%') }, { 10, ((Token) '/') }, { 10, ((Token) '*') },
  1348         { 11, TOKEN_PP_UNARY_PLUS }, { 11, TOKEN_PP_UNARY_MINUS },
  1351         { 11, TOKEN_PP_UNARY_PLUS }, { 11, TOKEN_PP_UNARY_MINUS },
  1349         { 11, ((Token) '!') }, { 11, ((Token) '~') },
  1352         { 11, ((Token) '!') }, { 11, ((Token) '~') },
  1350     };
  1353     };
  1351 
  1354 
  1352     int i;
  1355     size_t i;
  1353     for (i = 0; i < STATICARRAYLEN(ops); i++)
  1356     for (i = 0; i < STATICARRAYLEN(ops); i++)
  1354     {
  1357     {
  1355         if (ops[i].token == token)
  1358         if (ops[i].token == token)
  1356             return ops[i].precedence;
  1359             return ops[i].precedence;
  1357     } // for
  1360     } // for
  1367 } RpnTokens;
  1370 } RpnTokens;
  1368 
  1371 
  1369 static long interpret_rpn(const RpnTokens *tokens, int tokencount, int *error)
  1372 static long interpret_rpn(const RpnTokens *tokens, int tokencount, int *error)
  1370 {
  1373 {
  1371     long stack[128];
  1374     long stack[128];
  1372     int stacksize = 0;
  1375     size_t stacksize = 0;
  1373 
  1376 
  1374     *error = 1;
  1377     *error = 1;
  1375 
  1378 
  1376     #define NEED_X_TOKENS(x) do { if (stacksize < x) return 0; } while (0)
  1379     #define NEED_X_TOKENS(x) do { if (stacksize < x) return 0; } while (0)
  1377 
  1380 
  1447 static int reduce_pp_expression(Context *ctx)
  1450 static int reduce_pp_expression(Context *ctx)
  1448 {
  1451 {
  1449     RpnTokens output[128];
  1452     RpnTokens output[128];
  1450     Token stack[64];
  1453     Token stack[64];
  1451     Token previous_token = TOKEN_UNKNOWN;
  1454     Token previous_token = TOKEN_UNKNOWN;
  1452     int outputsize = 0;
  1455     size_t outputsize = 0;
  1453     int stacksize = 0;
  1456     size_t stacksize = 0;
  1454     int matched = 0;
  1457     int matched = 0;
  1455     int done = 0;
  1458     int done = 0;
  1456 
  1459 
  1457     #define ADD_TO_OUTPUT(op, val) \
  1460     #define ADD_TO_OUTPUT(op, val) \
  1458         assert(outputsize < STATICARRAYLEN(output)); \
  1461         assert(outputsize < STATICARRAYLEN(output)); \