91 lines
3.0 KiB
C
91 lines
3.0 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
typedef enum {
|
|
TOKEN_IDENTIFIER,
|
|
TOKEN_KEYWORD_TYPE,
|
|
TOKEN_KEYWORD_FN,
|
|
TOKEN_KEYWORD_LET,
|
|
TOKEN_KEYWORD_CONST,
|
|
TOKEN_KEYWORD_IF,
|
|
TOKEN_KEYWORD_ELSE,
|
|
TOKEN_KEYWORD_WHILE,
|
|
TOKEN_KEYWORD_FOR,
|
|
TOKEN_KEYWORD_RETURN,
|
|
TOKEN_KEYWORD_USE,
|
|
TOKEN_OPERATOR_IS
|
|
} TokenType;
|
|
|
|
typedef struct {
|
|
const char *keyword;
|
|
TokenType token;
|
|
} Keyword;
|
|
|
|
Keyword keywords[] = {
|
|
{"type", TOKEN_KEYWORD_TYPE},
|
|
{"fn", TOKEN_KEYWORD_FN},
|
|
{"let", TOKEN_KEYWORD_LET},
|
|
{"const", TOKEN_KEYWORD_CONST},
|
|
{"if", TOKEN_KEYWORD_IF},
|
|
{"else", TOKEN_KEYWORD_ELSE},
|
|
{"while", TOKEN_KEYWORD_WHILE},
|
|
{"for", TOKEN_KEYWORD_FOR},
|
|
{"return", TOKEN_KEYWORD_RETURN},
|
|
{"use", TOKEN_KEYWORD_USE},
|
|
{"is", TOKEN_OPERATOR_IS},
|
|
};
|
|
|
|
void emit_keyword_header(FILE *out) {
|
|
fprintf(out, "#ifndef KEYWORDS_H\n");
|
|
fprintf(out, "#define KEYWORDS_H\n\n");
|
|
fprintf(out, "#include \"lexer.h\"\n\n");
|
|
|
|
fprintf(out, "static TokenType check_keyword(int start, int length, const char *rest, TokenType type) {\n");
|
|
fprintf(out, " if ((lexer.current - lexer.start) == start + length &&\n");
|
|
fprintf(out, " memcmp(lexer.start + start, rest, length) == 0) return type;\n");
|
|
fprintf(out, " return TOKEN_IDENTIFIER;\n");
|
|
fprintf(out, "}\n\n");
|
|
|
|
fprintf(out, "static TokenType identifier_type(void) {\n");
|
|
fprintf(out, " switch (lexer.start[0]) {\n");
|
|
|
|
for (char ch = 'a'; ch <= 'z'; ++ch) {
|
|
int printed = 0;
|
|
for (int i = 0; i < sizeof(keywords) / sizeof(Keyword); ++i) {
|
|
const char *kw = keywords[i].keyword;
|
|
if (kw[0] == ch) {
|
|
if (!printed) {
|
|
fprintf(out, " case '%c':\n", ch);
|
|
printed = 1;
|
|
}
|
|
|
|
int len = (int)strlen(kw);
|
|
fprintf(out, " return check_keyword(%d, %d, \"%s\", %s);\n",
|
|
1, len - 1, kw + 1,
|
|
(keywords[i].token == TOKEN_IDENTIFIER ? "TOKEN_IDENTIFIER" :
|
|
keywords[i].token == TOKEN_OPERATOR_IS ? "TOKEN_OPERATOR_IS" :
|
|
keywords[i].token == TOKEN_KEYWORD_RETURN ? "TOKEN_KEYWORD_RETURN" :
|
|
keywords[i].token == TOKEN_KEYWORD_WHILE ? "TOKEN_KEYWORD_WHILE" :
|
|
keywords[i].token == TOKEN_KEYWORD_CONST ? "TOKEN_KEYWORD_CONST" :
|
|
keywords[i].token == TOKEN_KEYWORD_TYPE ? "TOKEN_KEYWORD_TYPE" :
|
|
keywords[i].token == TOKEN_KEYWORD_FN ? "TOKEN_KEYWORD_FN" :
|
|
keywords[i].token == TOKEN_KEYWORD_IF ? "TOKEN_KEYWORD_IF" :
|
|
keywords[i].token == TOKEN_KEYWORD_FOR ? "TOKEN_KEYWORD_FOR" :
|
|
keywords[i].token == TOKEN_KEYWORD_LET ? "TOKEN_KEYWORD_LET" :
|
|
keywords[i].token == TOKEN_KEYWORD_ELSE ? "TOKEN_KEYWORD_ELSE" :
|
|
keywords[i].token == TOKEN_KEYWORD_USE ? "TOKEN_KEYWORD_USE" : "TOKEN_IDENTIFIER"));
|
|
}
|
|
}
|
|
}
|
|
|
|
fprintf(out, " }\n return TOKEN_IDENTIFIER;\n");
|
|
fprintf(out, "}\n\n");
|
|
|
|
fprintf(out, "#endif // KEYWORDS_H\n");
|
|
}
|
|
|
|
int main(void) {
|
|
emit_keyword_header(stdout);
|
|
return 0;
|
|
}
|