Subversion Repositories Games.Carmageddon

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include "lexer.h"
  2. #include "CORE/FW/brprintf.h"
  3. #include "CORE/FW/file.h"
  4. #include "CORE/FW/fwsetup.h"
  5. #include "CORE/FW/resource.h"
  6. #include "CORE/MATH/fixed.h"
  7. #include "CORE/STD/brstdlib.h"
  8. #include "harness/trace.h"
  9.  
  10. // IDA: void __cdecl lexerError(br_lexer *l, char *string)
  11. void lexerError(br_lexer* l, char* string) {
  12.     LOG_TRACE("(%p, \"%s\")", l, string);
  13. }
  14.  
  15. // IDA: br_lexer* __cdecl BrLexerAllocate(br_lexer_keyword *keywords, int nkeywords)
  16. br_lexer* BrLexerAllocate(br_lexer_keyword* keywords, int nkeywords) {
  17.     br_lexer* l;
  18.     LOG_TRACE("(%p, %d)", keywords, nkeywords);
  19.  
  20.     l = BrResAllocate(fw.res, sizeof(br_lexer), BR_MEMORY_LEXER);
  21.     if (l == NULL) {
  22.         return NULL;
  23.     }
  24.     l->keywords = keywords;
  25.     l->nkeywords = nkeywords;
  26.     l->advance = lexerAdvance;
  27.     l->source = NULL;
  28.     l->string_buffer = BrResAllocate(l, 256, BR_MEMORY_LEXER);
  29.     l->string_buffer_size = 256;
  30.     l->error = lexerError;
  31.     return l;
  32. }
  33.  
  34. // IDA: char __cdecl BrLexerCommentSet(br_lexer *l, char eol_comment)
  35. char BrLexerCommentSet(br_lexer* l, char eol_comment) {
  36.     char old;
  37.     LOG_TRACE("(%p, %d)", l, eol_comment);
  38.  
  39.     old = l->eol_comment;
  40.     l->eol_comment = eol_comment;
  41.     return old;
  42. }
  43.  
  44. // IDA: br_lexer_error_cbfn* __cdecl BrLexerErrorSet(br_lexer *l, br_lexer_error_cbfn *error)
  45. br_lexer_error_cbfn* BrLexerErrorSet(br_lexer* l, br_lexer_error_cbfn* error) {
  46.     br_lexer_error_cbfn* old;
  47.     LOG_TRACE("(%p, %p)", l, error);
  48.  
  49.     old = l->error;
  50.     if (error == NULL) {
  51.         l->error = lexerError;
  52.     } else {
  53.         l->error = error;
  54.     }
  55.     return old == lexerError ? NULL : old;
  56. }
  57.  
  58. // IDA: void __cdecl BrLexerFree(br_lexer *l)
  59. void BrLexerFree(br_lexer* l) {
  60.     LOG_TRACE("(%p)", l);
  61.  
  62.     BrResFree(l);
  63. }
  64.  
  65. // IDA: void __cdecl fileGetchar(br_lexer_source *source)
  66. void fileGetchar(br_lexer_source* source) {
  67.     LOG_TRACE("(%p)", source);
  68.  
  69.     source->next = BrFileGetChar(source->ptr);
  70. }
  71.  
  72. // IDA: br_error __cdecl BrLexerPushFile(br_lexer *l, char *file)
  73. br_error BrLexerPushFile(br_lexer* l, char* file) {
  74.     br_lexer_source* s;
  75.     void* f;
  76.     int mode;
  77.     LOG_TRACE("(%p, \"%s\")", l, file);
  78.  
  79.     mode = BR_FS_MODE_TEXT;
  80.     f = BrFileOpenRead(file, 0, NULL, &mode);
  81.     if (f == NULL) {
  82.         return 0x1002;
  83.     }
  84.     s = BrResAllocate(l, sizeof(br_lexer_source), BR_MEMORY_LEXER);
  85.     if (s == NULL) {
  86.         return 0x1003;
  87.     }
  88.     BrResAdd(s, f);
  89.     s->name = file;
  90.     s->line = 1;
  91.     s->getchar = fileGetchar;
  92.     s->ptr = f;
  93.     s->getchar(s);
  94.     s->prev = l->source;
  95.     l->source = s;
  96.     return 0;
  97. }
  98.  
  99. // IDA: void __cdecl stringGetchar(br_lexer_source *source)
  100. void stringGetchar(br_lexer_source* source) {
  101.     char* cp;
  102.     LOG_TRACE9("(%p)", source);
  103.  
  104.     cp = source->ptr;
  105.     if (cp != NULL && *cp != '\0') {
  106.         source->next = *cp;
  107.         source->ptr = cp + 1;
  108.     } else {
  109.         source->next = -1;
  110.     }
  111. }
  112.  
  113. // IDA: br_error __cdecl BrLexerPushString(br_lexer *l, char *string, char *name)
  114. br_error BrLexerPushString(br_lexer* l, char* string, char* name) {
  115.     br_lexer_source* s;
  116.     LOG_TRACE("(%p, \"%s\", \"%s\")", l, string, name);
  117.  
  118.     s = BrResAllocate(l, sizeof(br_lexer_source), BR_MEMORY_LEXER);
  119.     if (s == NULL) {
  120.         return 0x1003;
  121.     }
  122.     s->name = name;
  123.     s->line = 1;
  124.     s->getchar = stringGetchar;
  125.     s->ptr = string;
  126.     s->getchar(s);
  127.     s->prev = l->source;
  128.     l->source = s;
  129.     return 0;
  130. }
  131.  
  132. // IDA: br_lexer_source* __cdecl BrLexerPop(br_lexer *l)
  133. br_lexer_source* BrLexerPop(br_lexer* l) {
  134.     br_lexer_source* s;
  135.     LOG_TRACE("(%p)", l);
  136.  
  137.     s = l->source;
  138.     if (s != NULL) {
  139.         l->source = s->prev;
  140.         BrResFree(s);
  141.     }
  142.     return s;
  143. }
  144.  
  145. // IDA: void __usercall lexerAdvance(br_lexer *l@<EAX>)
  146. void lexerAdvance(br_lexer* l) {
  147.     int n;
  148.     br_boolean got_point;
  149.     LOG_TRACE("(%p)", l);
  150.  
  151.     while (1) {
  152.         if (l->source == NULL) {
  153.             l->current.id = T_EOF;
  154.             return;
  155.         }
  156.         if (l->source->next == -1) {
  157.             BrLexerPop(l);
  158.             continue;
  159.         }
  160.         if (l->eol_comment != '\0' && l->eol_comment == l->source->next) {
  161.             l->source->getchar(l->source);
  162.             while (l->source->next != '\n' && l->source->next != -1) {
  163.                 l->source->getchar(l->source);
  164.             }
  165.             continue;
  166.         }
  167.         if (l->source->next == '\n') {
  168.             l->source->line++;
  169.             l->source->getchar(l->source);
  170.             continue;
  171.         }
  172.         if (l->source->next == '\"') {
  173.             for (n = 0; n < l->string_buffer_size; n++) {
  174.                 l->source->getchar(l->source);
  175.                 l->string_buffer[n] = l->source->next;
  176.                 if ((l->source->next == '\"') || (l->source->next == '\n') || (l->source->next == -1)) {
  177.                     break;
  178.                 }
  179.             }
  180.             if (l->source->next != '\"') {
  181.                 l->current.id = T_ERROR;
  182.                 l->current.v.string = "Unterminated string";
  183.             } else {
  184.                 l->string_buffer[n] = '\0';
  185.                 l->current.id = T_STRING;
  186.                 l->current.v.string = l->string_buffer;
  187.             }
  188.             l->source->getchar(l->source);
  189.             return;
  190.         }
  191.         if (BrIsSpace(l->source->next) || l->source->next == '\x1a') {
  192.             l->source->getchar(l->source);
  193.             continue;
  194.         }
  195.         if (BrIsAlpha(l->source->next) != 0 || l->source->next == '_') {
  196.             l->string_buffer[0] = l->source->next;
  197.             for (n = 1; n < l->string_buffer_size - 1; n++) {
  198.                 l->source->getchar(l->source);
  199.                 if (BrIsAlpha(l->source->next) == 0 && BrIsDigit(l->source->next) == 0 && l->source->next != '_') {
  200.                     break;
  201.                 }
  202.                 l->string_buffer[n] = l->source->next;
  203.             }
  204.             l->string_buffer[n] = '\0';
  205.             l->current.v.string = l->string_buffer;
  206.             for (n = 0; n < l->nkeywords; n++) {
  207.                 if ((l->keywords[n].name[0] == l->string_buffer[0]) && (BrStrCmp(l->keywords[n].name, l->string_buffer) == 0)) {
  208.                     l->current.id = l->keywords[n].id;
  209.                     return;
  210.                 }
  211.             }
  212.             l->current.id = T_IDENT;
  213.             return;
  214.         }
  215.         if (BrIsDigit(l->source->next) != 0) {
  216.             got_point = 0;
  217.             l->string_buffer[0] = l->source->next;
  218.             for (n = 1; n < l->string_buffer_size - 1; n++) {
  219.                 l->source->getchar(l->source);
  220.                 if (l->source->next == '.') {
  221.                     got_point = 1;
  222.                 } else if (!(('0' <= l->source->next && l->source->next <= '9')
  223.                     || ('A' <= l->source->next && l->source->next <= 'F') || (l->source->next == 'X')
  224.                     || ('a' <= l->source->next && l->source->next <= 'f') || (l->source->next == 'x'))) {
  225.                     break;
  226.                 }
  227.                 l->string_buffer[n] = l->source->next;
  228.             }
  229.             l->string_buffer[n] = '\0';
  230.             if (got_point != 0) {
  231.                 l->current.v.real = BrStrToF(l->string_buffer, NULL);
  232.                 l->current.id = T_REAL;
  233.             } else {
  234.                 l->current.v.integer = BrStrToL(l->string_buffer, NULL, 0);
  235.                 l->current.id = T_INTEGER;
  236.             }
  237.             return;
  238.         }
  239.         if (BrIsPrint(l->source->next) != 0) {
  240.             l->current.id = l->source->next;
  241.             l->source->getchar(l->source);
  242.             return;
  243.         }
  244.         l->current.id = T_ERROR;
  245.         l->current.v.string = "Unexpected character";
  246.         l->source->getchar(l->source);
  247.         return;
  248.     }
  249. }
  250.  
  251. // IDA: void __usercall lexerAdvanceDump(br_lexer *l@<EAX>)
  252. void lexerAdvanceDump(br_lexer* l) {
  253.     //char* tname; // Pierre-Marie Baty -- unused variable
  254.     //char* tvalue; // Pierre-Marie Baty -- unused variable
  255.     //char val[40]; // Pierre-Marie Baty -- unused variable
  256.     //char tmp[256]; // Pierre-Marie Baty -- unused variable
  257.     LOG_TRACE("(%p)", l);
  258.  
  259.     NOT_IMPLEMENTED();
  260. }
  261.  
  262. // IDA: br_error __cdecl BrLexerDumpSet(br_lexer *l, br_putline_cbfn *putline, void *putline_arg)
  263. br_error BrLexerDumpSet(br_lexer* l, br_putline_cbfn* putline, void* putline_arg) {
  264.     LOG_TRACE("(%p, %p, %p)", l, putline, putline_arg);
  265.  
  266.     return 0;
  267. }
  268.  
  269. // IDA: void __cdecl BrLexerTokenError(br_lexer *l, br_lexer_token_id t)
  270. void BrLexerTokenError(br_lexer* l, br_lexer_token_id t) {
  271.     int i;
  272.     char tmp[256];
  273.     LOG_TRACE("(%p, %d)", l, t);
  274.  
  275.     if (l->current.id != T_ERROR) {
  276.         switch (t) {
  277.         case T_EOF:
  278.             l->error(l, "expected end of file");
  279.             break;
  280.         case T_ERROR:
  281.             l->error(l, l->current.v.string);
  282.             break;
  283.         case T_IDENT:
  284.             l->error(l, "expected an identifier");
  285.             break;
  286.         case T_STRING:
  287.             l->error(l, "expected a string");
  288.             break;
  289.         case T_INTEGER:
  290.             l->error(l, "expected an integer");
  291.             break;
  292.         case T_REAL:
  293.             l->error(l, "expected a real number");
  294.             break;
  295.         default:
  296.             if (t < 0x80) {
  297.                 if (BrIsPrint(t) != 0) {
  298.                     BrSprintfN(tmp, sizeof(tmp), "expected '%c'", t);
  299.                 } else {
  300.                     BrSprintfN(tmp, sizeof(tmp), "expected unknown token %d", t);
  301.                 }
  302.             } else {
  303.                 for (i = 0; i < l->nkeywords; i++) {
  304.                     if (l->keywords[i].id == t) {
  305.                         break;
  306.                     }
  307.                 }
  308.                 if (i < l->nkeywords) {
  309.                     BrSprintfN(tmp, sizeof(tmp), "expected '%s'", l->keywords[i].name);
  310.                 } else {
  311.                     BrSprintfN(tmp, sizeof(tmp), "expected unknown keyword %d", t);
  312.                 }
  313.             }
  314.             l->error(l, tmp);
  315.             break;
  316.         }
  317.     }
  318.  
  319.     while (l->current.id != t && l->current.id != T_EOF) {
  320.         l->advance(l);
  321.     }
  322. }
  323.  
  324. // IDA: void __cdecl BrLexerPosition(br_lexer *l, char *buf, br_size_t buf_size)
  325. void BrLexerPosition(br_lexer* l, char* buf, br_size_t buf_size) {
  326.     LOG_TRACE("(%p, \"%s\", %d)", l, buf, buf_size);
  327.  
  328.     if ((l->source != NULL) && (l->source->name != NULL)) {
  329.         BrSprintfN(buf, buf_size, "%s:%d ", l->source->name, l->source->line);
  330.     } else {
  331.         *buf = '\0';
  332.     }
  333. }
  334.  
  335. // IDA: br_fixed_ls __cdecl BrParseFixed(br_lexer *l)
  336. br_fixed_ls BrParseFixed(br_lexer* l) {
  337.     br_boolean neg;
  338.     br_fixed_ls x;
  339.     LOG_TRACE("(%p)", l);
  340.  
  341.     if (l->current.id == T_PLUS) {
  342.         l->advance(l);
  343.     }
  344.     neg = l->current.id == T_DASH;
  345.     if (neg) {
  346.         l->advance(l);
  347.     }
  348.     if (l->current.id == T_REAL) {
  349.         x = BrFloatToFixed(l->current.v.real);
  350.         l->advance(l);
  351.     } else if (l->current.id == T_INTEGER) {
  352.         x = BrIntToFixed(l->current.v.integer);
  353.         l->advance(l);
  354.     } else {
  355.         l->error(l, "expecting a fixed");
  356.         l->advance(l);
  357.         x = 0;
  358.     }
  359.     if (neg) {
  360.         x = -x;
  361.     }
  362.     return x;
  363. }
  364.  
  365. // IDA: br_float __cdecl BrParseFloat(br_lexer *l)
  366. br_float BrParseFloat(br_lexer* l) {
  367.     br_boolean neg;
  368.     br_float f;
  369.     LOG_TRACE("(%p)", l);
  370.  
  371.     if (l->current.id == T_PLUS) {
  372.         l->advance(l);
  373.     }
  374.     neg = l->current.id == T_DASH;
  375.     if (neg) {
  376.         l->advance(l);
  377.     }
  378.     if (l->current.id == T_REAL) {
  379.         f = l->current.v.real;
  380.         l->advance(l);
  381.     } else if (l->current.id == T_INTEGER) {
  382.         f = (float)l->current.v.integer;
  383.         l->advance(l);
  384.     } else {
  385.         l->error(l, "expecting a float");
  386.         l->advance(l);
  387.         f = 0.f;
  388.     }
  389.     if (neg) {
  390.         f = -f;
  391.     }
  392.     return f;
  393. }
  394.  
  395. // IDA: br_int_32 __cdecl BrParseInteger(br_lexer *l)
  396. br_int_32 BrParseInteger(br_lexer* l) {
  397.     br_boolean neg;
  398.     br_int_32 i;
  399.     LOG_TRACE("(%p)", l);
  400.  
  401.     if (l->current.id == T_PLUS) {
  402.         l->advance(l);
  403.     }
  404.     neg = l->current.id == T_DASH;
  405.     if (neg) {
  406.         l->advance(l);
  407.     }
  408.     if (l->current.id == T_INTEGER) {
  409.         i = l->current.v.integer;
  410.         l->advance(l);
  411.     } else {
  412.         l->error(l, "expecting an integer");
  413.         l->advance(l);
  414.         i = 0;
  415.     }
  416.     if (neg) {
  417.         i = -i;
  418.     }
  419.     return i;
  420. }
  421.  
  422. // IDA: br_int_32 __cdecl BrParseVectorFixed(br_lexer *l, br_fixed_ls *v, br_int_32 max)
  423. br_int_32 BrParseVectorFixed(br_lexer* l, br_fixed_ls* v, br_int_32 max) {
  424.     int n;
  425.     LOG_TRACE("(%p, %p, %d)", l, v, max);
  426.  
  427.     if (l->current.id == T_LSQUARE) {
  428.         l->advance(l);
  429.     } else {
  430.         BrLexerTokenError(l, T_LSQUARE);
  431.     }
  432.     for (n = 0; n < max; n++) {
  433. #ifdef BRENDER_FIX_BUGS
  434.         if (l->current.id == T_RSQUARE) {
  435.             break;
  436.         }
  437. #endif
  438.         *v = BrParseFixed(l);
  439.         v++;
  440.         if (l->current.id == T_RSQUARE) {
  441.             n++;
  442.             break;
  443.         }
  444.         if (n != max - 1) {
  445.             if (l->current.id == T_COMMA) {
  446.                 l->advance(l);
  447.             } else {
  448.                 BrLexerTokenError(l, T_COMMA);
  449.             }
  450.         }
  451.     }
  452.     if (l->current.id == T_RSQUARE) {
  453.         l->advance(l);
  454.     } else {
  455.         BrLexerTokenError(l, T_RSQUARE);
  456.     }
  457.     return n;
  458. }
  459.  
  460. // IDA: br_int_32 __cdecl BrParseVectorFloat(br_lexer *l, br_float *v, br_int_32 max)
  461. br_int_32 BrParseVectorFloat(br_lexer* l, br_float* v, br_int_32 max) {
  462.     int n;
  463.     LOG_TRACE("(%p, %p, %d)", l, v, max);
  464.  
  465.     if (l->current.id == T_LSQUARE) {
  466.         l->advance(l);
  467.     } else {
  468.         BrLexerTokenError(l, T_LSQUARE);
  469.     }
  470.     for (n = 0; n < max; n++) {
  471. #ifdef BRENDER_FIX_BUGS
  472.         if (l->current.id == T_RSQUARE) {
  473.             break;
  474.         }
  475. #endif
  476.         *v = BrParseFloat(l);
  477.         v++;
  478.         if (l->current.id == T_RSQUARE) {
  479.             n++;
  480.             break;
  481.         }
  482.         if (n != max - 1) {
  483.             if (l->current.id == T_COMMA) {
  484.                 l->advance(l);
  485.             } else {
  486.                 BrLexerTokenError(l, T_COMMA);
  487.             }
  488.         }
  489.     }
  490.     if (l->current.id == T_RSQUARE) {
  491.         l->advance(l);
  492.     } else {
  493.         BrLexerTokenError(l, T_RSQUARE);
  494.     }
  495.     return n;
  496. }
  497.  
  498. // IDA: br_int_32 __cdecl BrParseMatrixFixed(br_lexer *l, br_fixed_ls *m, br_int_32 width, br_int_32 max_h)
  499. br_int_32 BrParseMatrixFixed(br_lexer* l, br_fixed_ls* m, br_int_32 width, br_int_32 max_h) {
  500.     int n;
  501.     LOG_TRACE("(%p, %p, %d, %d)", l, m, width, max_h);
  502.  
  503.     if (l->current.id == T_LSQUARE) {
  504.         l->advance(l);
  505.     } else {
  506.         BrLexerTokenError(l, T_LSQUARE);
  507.     }
  508.     for (n = 0; n < max_h; n++, m = m + width) {
  509. #ifdef BRENDER_FIX_BUGS
  510.         if (l->current.id == T_RSQUARE) {
  511.             break;
  512.         }
  513. #endif
  514.         BrParseVectorFixed(l, m, width);
  515.         if (l->current.id == T_RSQUARE) {
  516.             n++;
  517.             break;
  518.         }
  519.         if (n != max_h - 1) {
  520.             if (l->current.id == T_COMMA) {
  521.                 l->advance(l);
  522.             } else {
  523.                 BrLexerTokenError(l, T_COMMA);
  524.             }
  525.         }
  526.     }
  527.     if (l->current.id == T_RSQUARE) {
  528.         l->advance(l);
  529.     } else {
  530.         BrLexerTokenError(l, T_RSQUARE);
  531.     }
  532.     return n;
  533. }
  534.  
  535. // IDA: br_int_32 __cdecl BrParseMatrixFloat(br_lexer *l, br_float *m, br_int_32 width, br_int_32 max_h)
  536. br_int_32 BrParseMatrixFloat(br_lexer* l, br_float* m, br_int_32 width, br_int_32 max_h) {
  537.     int n;
  538.     LOG_TRACE("(%p, %p, %d, %d)", l, m, width, max_h);
  539.  
  540.     if (l->current.id == T_LSQUARE) {
  541.         l->advance(l);
  542.     } else {
  543.         BrLexerTokenError(l, T_LSQUARE);
  544.     }
  545.     for (n = 0; n < max_h; n++, m = m + width) {
  546. #ifdef BRENDER_FIX_BUGS
  547.         if (l->current.id == T_RSQUARE) {
  548.             break;
  549.         }
  550. #endif
  551.         BrParseVectorFloat(l, m, width);
  552.         if (l->current.id == T_RSQUARE) {
  553.             n++;
  554.             break;
  555.         }
  556.         if (n != max_h - 1) {
  557.             if (l->current.id == T_COMMA) {
  558.                 l->advance(l);
  559.             } else {
  560.                 BrLexerTokenError(l, T_COMMA);
  561.             }
  562.         }
  563.     }
  564.     if (l->current.id == T_RSQUARE) {
  565.         l->advance(l);
  566.     } else {
  567.         BrLexerTokenError(l, T_RSQUARE);
  568.     }
  569.     return n;
  570. }
  571.