#include #include 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; }