Subversion Repositories Games.Carmageddon

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
20 pmbaty 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
}