summaryrefslogtreecommitdiff
path: root/test/raytracer/gmllexer.c
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2008-08-09 08:06:33 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2008-08-09 08:06:33 +0000
commit285f5bec5bb03d4e825e5d866e94008088dd6155 (patch)
tree9df69ded9ed4f4049e0b3887fdd99fcdf3b1746f /test/raytracer/gmllexer.c
parenta83f0c1710cc5143dd885e84c94e14f7d3216f93 (diff)
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.c297
1 files changed, 297 insertions, 0 deletions
diff --git a/test/raytracer/gmllexer.c b/test/raytracer/gmllexer.c
new file mode 100644
index 0000000..332126b
--- /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;
+ }
+}
+