static const char *const lex_keywords[] = {
"do", "else", "if", "while",
"break", "continue", "return", "goto",
- "for", "typedef",
-
- /* types */
- "int",
- "void",
- "string",
- "float",
- "vector",
- "entity",
+ "for", "typedef"
};
struct lex_file *lex_open(FILE *fp) {
struct lex_file *lex = mem_a(sizeof(struct lex_file));
- if (lex) {
- lex->file = fp;
- fseek(lex->file, 0, SEEK_END);
- lex->length = ftell(lex->file);
- lex->size = lex->length; /* copy, this is never changed */
- fseek(lex->file, 0, SEEK_SET);
- lex->last = 0;
+ if (!lex || !fp)
+ return NULL;
- memset(lex->peek, 0, sizeof(lex->peek));
- }
+ lex->file = fp;
+ fseek(lex->file, 0, SEEK_END);
+ lex->length = ftell(lex->file);
+ lex->size = lex->length; /* copy, this is never changed */
+ fseek(lex->file, 0, SEEK_SET);
+ lex->last = 0;
+
+ memset(lex->peek, 0, sizeof(lex->peek));
return lex;
}
-int lex_close(struct lex_file *file) {
- int ret = -1;
- if (file) {
- ret = fclose(file->file);
- mem_d(file);
- }
- return ret;
+void lex_close(struct lex_file *file) {
+ if (!file) return;
+
+ fclose(file->file); /* may already be closed */
+ mem_d(file);
}
static void lex_addch(int ch, struct lex_file *file) {
while (isspace(ch) && ch != '\n')
ch = lex_getch(file);
- if (ch == '\n') {
- file->line ++;
+ if (ch == '\n')
return ch;
- }
-
lex_unget(ch, file);
return ' ';
}
lex_addch(ch, file);
while ((ch = lex_getch(file)) != '*') {
if (ch == EOF)
- return error(ERROR_LEX, "malformatted comment at line %d", file->line);
+ return error(ERROR_LEX, "malformatted comment at line", "");
else
lex_addch(ch, file);
}
if (!strncmp(file->lastok, lex_keywords[it], sizeof(lex_keywords[it])))
return it;
+ /* try a type? */
+ #define TEST_TYPE(X) \
+ do { \
+ if (!strncmp(X, "float", sizeof("float"))) \
+ return TOKEN_FLOAT; \
+ if (!strncmp(X, "vector", sizeof("vector"))) \
+ return TOKEN_VECTOR; \
+ if (!strncmp(X, "string", sizeof("string"))) \
+ return TOKEN_STRING; \
+ if (!strncmp(X, "entity", sizeof("entity"))) \
+ return TOKEN_ENTITY; \
+ if (!strncmp(X, "void" , sizeof("void"))) \
+ return TOKEN_VOID; \
+ } while(0)
+
+ TEST_TYPE(file->lastok);
+
/* try the hashtable for typedefs? */
if (typedef_find(file->lastok))
- for (it = 0; it < sizeof(lex_keywords)/sizeof(*lex_keywords); it++)
- if (!strncmp(typedef_find(file->lastok)->name, lex_keywords[it], sizeof(lex_keywords[it])))
- return it;
-
+ TEST_TYPE(typedef_find(file->lastok)->name);
+
return LEX_IDENT;
}
return ch;
memset(file->peek, 0, sizeof(file->peek ));
memset(file->lastok, 0, sizeof(file->lastok));
}
-
-int lex_debug(struct lex_file *file) {
- int list_do = 0;
- int list_else = 0;
- int list_if = 0;
- int list_while = 0;
- int list_break = 0;
- int list_continue = 0;
- int list_return = 0;
- int list_goto = 0;
- int list_for = 0;
- int token = 0;
- printf("===========================\nTOKENS: \n===========================\n");
- while ((token = lex_token(file)) != ERROR_LEX && file->length >= 0) {
- if (token != -1) {
- switch (token) {
- case 0: list_do ++; break;
- case 1: list_else ++; break;
- case 2: list_if ++; break;
- case 3: list_while ++; break;
- case 4: list_break ++; break;
- case 5: list_continue++; break;
- case 6: list_return ++; break;
- case 7: list_goto ++; break;
- case 8: list_for ++; break;
- }
- }
- if (token >= 33 && token <= 126)
- putchar(token);
- }
- printf("\n===========================\nBRANCHES \n===========================\n");
- printf("\t if % 8d\n", list_if);
- printf("\t else % 8d\n", list_else);
- printf("===========================\nLOOPS \n===========================\n");
- printf("\t for % 8d\n", list_for);
- printf("\t while % 8d\n", list_while);
- printf("\t do % 8d\n", list_do);
- printf("===========================\nSTATEMENTS \n===========================\n");
- printf("\t break % 8d\n", list_break);
- printf("\t continue % 8d\n", list_continue);
- printf("\t return % 8d\n", list_return);
- printf("\t goto % 8d\n", list_goto);
- printf("===========================\nIDENTIFIERS\n===========================\n");
- lex_reset(file);
- while ((token = lex_token(file)) != ERROR_LEX && file->length >= 0)
- if (token == LEX_IDENT)
- printf("%s ", file->lastok);
- fputc('\n', stdout);
- lex_reset(file);
- return 1;
-}