diff options
author | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2008-08-09 08:06:33 +0000 |
---|---|---|
committer | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2008-08-09 08:06:33 +0000 |
commit | 285f5bec5bb03d4e825e5d866e94008088dd6155 (patch) | |
tree | 9df69ded9ed4f4049e0b3887fdd99fcdf3b1746f /test/raytracer/gmllexer.c | |
parent | a83f0c1710cc5143dd885e84c94e14f7d3216f93 (diff) | |
download | compcert-285f5bec5bb03d4e825e5d866e94008088dd6155.tar.gz compcert-285f5bec5bb03d4e825e5d866e94008088dd6155.zip |
Ajout nouveaux tests
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@708 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'test/raytracer/gmllexer.c')
-rw-r--r-- | test/raytracer/gmllexer.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/test/raytracer/gmllexer.c b/test/raytracer/gmllexer.c new file mode 100644 index 00000000..332126b2 --- /dev/null +++ b/test/raytracer/gmllexer.c @@ -0,0 +1,297 @@ +/* Lexer for GML */ + +#include "config.h" +#include "gmllexer.h" +#include "gml.h" + +#define isdigit(c) (c >= '0' && c <= '9') +#define isalpha(c) ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) +#define isalnum(c) (isdigit(c) || isalpha(c)) +#define isprint(c) (c >= ' ' && c <= 126) + +struct lexeme current_lexeme; + +struct bucket { + int kind; + struct bucket * next; + int op; + char string[1]; +}; + +#define HASHTABLE_SIZE 256 + +static struct bucket * hashtable[HASHTABLE_SIZE] = { NULL, /*all nulls*/}; + +#define BUFFER_SIZE 1024 + +static char buffer[BUFFER_SIZE]; + +#define STORE_BUFFER(pos,c) if (pos < sizeof(buffer) - 1) buffer[pos++] = c + +static inline unsigned int hash_ident(char * s) +{ + unsigned int h; + for (h = 0; *s != 0; s++) h = (h << 4) + h + *s; + return h % HASHTABLE_SIZE; +} + +static void get_ident(int firstchar) +{ + int c, pos; + unsigned int h; + struct bucket * b; + + /* Read characters of the ident */ + buffer[0] = firstchar; + pos = 1; + while (1) { + c = getchar(); + if (! (isalnum(c) || c == '-' || c == '_')) break; + STORE_BUFFER(pos, c); + } + if (c != EOF) ungetc(c, stdin); + buffer[pos] = 0; + /* Hash the ident */ + h = hash_ident(buffer); + /* Look it up in the hash table */ + for (b = hashtable[h]; b != NULL; b = b->next) { + if (strcmp(b->string, buffer) == 0) { + /* Found: return hash table entry */ + current_lexeme.kind = b->kind; + if (b->kind == IDENTIFIER) + current_lexeme.u.s = b->string; + else + current_lexeme.u.op = b->op; + return; + } + } + /* Not found: enter it */ + b = malloc(sizeof(struct bucket) + pos); + b->kind = IDENTIFIER; + strcpy(b->string, buffer); + b->next = hashtable[h]; + hashtable[h] = b; + current_lexeme.kind = IDENTIFIER; + current_lexeme.u.s = b->string; +} + +static void get_binder(void) +{ + int c = getchar(); + if (! isalpha(c)) { + fprintf(stderr, "Bad binder /%c...\n", c); + exit(2); + } + get_ident(c); + if (current_lexeme.kind != IDENTIFIER) { + fprintf(stderr, "Binder /%s rebinds reserved identifier\n", + current_lexeme.u.s); + exit(2); + } + current_lexeme.kind = BINDER; +} + +static int get_number(int firstchar) +{ + int c, pos, is_real; + + pos = 0; + is_real = 0; + c = firstchar; + /* Initial sign */ + if (c == '-') { + STORE_BUFFER(pos, c); + c = getchar(); + if (! isdigit(c)) return -1; + } + /* Decimal number */ + do { + STORE_BUFFER(pos, c); + c = getchar(); + } while (isdigit(c)); + /* Period and fractional part */ + if (c == '.') { + is_real = 1; + STORE_BUFFER(pos, c); + c = getchar(); + if (! isdigit(c)) return -1; + do { + STORE_BUFFER(pos, c); + c = getchar(); + } while (isdigit(c)); + } + /* Exponent */ + if (c == 'e' || c == 'E') { + is_real = 1; + STORE_BUFFER(pos, c); + c = getchar(); + if (c == '-') { + STORE_BUFFER(pos, c); + c = getchar(); + } + if (! isdigit(c)) return -1; + do { + STORE_BUFFER(pos, c); + c = getchar(); + } while (isdigit(c)); + } + if (c != EOF) ungetc(c, stdin); + /* Convert to token */ + buffer[pos] = 0; + if (is_real) { + current_lexeme.kind = REAL; + current_lexeme.u.d = strtod(buffer, NULL); + } else { + current_lexeme.kind = INTEGER; + current_lexeme.u.i = atoi(buffer); + } + return 0; +} + +static int get_string() +{ + int c, pos; + pos = 0; + while (1) { + c = getchar(); + if (c == '"') break; + if (! isprint(c)) return -1; + STORE_BUFFER(pos, c); + } + buffer[pos] = 0; + current_lexeme.kind = STRING; + current_lexeme.u.s = strdup(buffer); + return 0; +} + +void get_lexeme(void) +{ + int c; + + if (current_lexeme.kind != NONE) return; + while (1) { + c = getchar(); + switch (c) { + case EOF: + current_lexeme.kind = END_OF_FILE; break; + case ' ': case '\n': case '\t': case '\r': case 11: + continue; + case '%': + do { c = getchar(); } while (c != '\n' && c != EOF); + continue; + case '/': + get_binder(); break; + case '-': case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (get_number(c) == -1) { + fprintf(stderr, "Bad number\n"); + exit(2); + } + break; + case '"': + if (get_string() == -1) { + fprintf(stderr, "Bad string literal\n"); + exit(2); + } + break; + case '{': + current_lexeme.kind = LBRACE; break; + case '}': + current_lexeme.kind = RBRACE; break; + case '[': + current_lexeme.kind = LBRACKET; break; + case ']': + current_lexeme.kind = RBRACKET; break; + default: + if (isalpha(c)) { + get_ident(c); + } else { + fprintf(stderr, "Illegal character `%c'\n", c); + exit(2); + } + break; + } + return; + } +} + +void discard_lexeme(void) +{ + current_lexeme.kind = NONE; +} + +/* Enter the operators in the hashtable */ + +struct op_init { char * name; int kind; int op; }; + +static struct op_init operators[] = + { { "true", BOOLEAN, 1 }, + { "false", BOOLEAN, 0 }, + { "acos", OPERATOR, Op_acos }, + { "addi", OPERATOR, Op_addi }, + { "addf", OPERATOR, Op_addf }, + { "apply", OPERATOR, Op_apply }, + { "asin", OPERATOR, Op_asin }, + { "clampf", OPERATOR, Op_clampf }, + { "cone", OPERATOR, Op_cone }, + { "cos", OPERATOR, Op_cos }, + { "cube", OPERATOR, Op_cube }, + { "cylinder", OPERATOR, Op_cylinder }, + { "difference", OPERATOR, Op_difference }, + { "divi", OPERATOR, Op_divi }, + { "divf", OPERATOR, Op_divf }, + { "eqi", OPERATOR, Op_eqi }, + { "eqf", OPERATOR, Op_eqf }, + { "floor", OPERATOR, Op_floor }, + { "frac", OPERATOR, Op_frac }, + { "get", OPERATOR, Op_get }, + { "getx", OPERATOR, Op_getx }, + { "gety", OPERATOR, Op_gety }, + { "getz", OPERATOR, Op_getz }, + { "if", OPERATOR, Op_if }, + { "intersect", OPERATOR, Op_intersect }, + { "length", OPERATOR, Op_length }, + { "lessi", OPERATOR, Op_lessi }, + { "lessf", OPERATOR, Op_lessf }, + { "light", OPERATOR, Op_light }, + { "modi", OPERATOR, Op_modi }, + { "muli", OPERATOR, Op_muli }, + { "mulf", OPERATOR, Op_mulf }, + { "negi", OPERATOR, Op_negi }, + { "negf", OPERATOR, Op_negf }, + { "plane", OPERATOR, Op_plane }, + { "point", OPERATOR, Op_point }, + { "pointlight", OPERATOR, Op_pointlight }, + { "real", OPERATOR, Op_real }, + { "render", OPERATOR, Op_render }, + { "rotatex", OPERATOR, Op_rotatex }, + { "rotatey", OPERATOR, Op_rotatey }, + { "rotatez", OPERATOR, Op_rotatez }, + { "scale", OPERATOR, Op_scale }, + { "sin", OPERATOR, Op_sin }, + { "sphere", OPERATOR, Op_sphere }, + { "spotlight", OPERATOR, Op_spotlight }, + { "sqrt", OPERATOR, Op_sqrt }, + { "subi", OPERATOR, Op_subi }, + { "subf", OPERATOR, Op_subf }, + { "translate", OPERATOR, Op_translate }, + { "union", OPERATOR, Op_union }, + { "uscale", OPERATOR, Op_uscale }, + { "print", OPERATOR, Op_print }, + }; + +void init_lexer(void) +{ + int i; + for (i = 0; i < sizeof(operators) / sizeof(struct op_init); i++) { + struct op_init * opi = &(operators[i]); + struct bucket * b = malloc(sizeof(struct bucket) + strlen(opi->name)); + unsigned int h = hash_ident(opi->name); + b->kind = opi->kind; + strcpy(b->string, opi->name); + b->op = opi->op; + b->next = hashtable[h]; + hashtable[h] = b; + } +} + |