1
0
Fork 0
undar-lang-old/src/tools/gen_keywords.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;
}