#include <string.h>
#include "gmqcc.h"
+/*
+ * Keywords are multichar, punctuation lexing is a bit more complicated
+ * than keyword lexing.
+ */
static const char *const lex_keywords[] = {
"do", "else", "if", "while",
"break", "continue", "return", "goto",
- "for"
+ "for", "typedef",
+
+ /* types */
+ "int",
+ "void",
+ "string",
+ "float",
+ "vector",
+ "entity",
};
-struct lex_file *lex_open(const char *name) {
+struct lex_file *lex_open(FILE *fp) {
struct lex_file *lex = mem_a(sizeof(struct lex_file));
if (lex) {
- lex->file = fopen(name, "r");
+ lex->file = fp;
fseek(lex->file, 0, SEEK_END);
lex->length = ftell(lex->file);
lex->size = lex->length; /* copy, this is never changed */
while (isspace(ch) && ch != '\n')
ch = lex_getch(file);
- if (ch == '\n')
+ if (ch == '\n') {
+ file->line ++;
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"," ");
+ return error(ERROR_LEX, "malformatted comment at line %d", file->line);
else
lex_addch(ch, file);
}
/* valid identifier */
if (ch > 0 && (ch == '_' || isalpha(ch))) {
lex_clear(file);
- while (ch > 0 && (isalpha(ch) || isdigit(ch) || ch == '_')) {
+ while (ch > 0 && (isalpha(ch) || ch == '_')) {
lex_addch(ch, file);
ch = lex_getsource(file);
}
if (!strncmp(file->lastok, lex_keywords[it], sizeof(lex_keywords[it])))
return it;
+ /* 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;
+
return LEX_IDENT;
}
return ch;
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;
}