#include #include #include #include #include #include #include "base.c" int main() { typedef struct { char *name; char *serialized_operator; bool keyword; } Task; Task kinds[] = { {"EOF"}, {"ERROR"}, {"IDENT"}, {"INT"}, {"FLOAT"}, {"CHAR"}, {"STRING"}, {"LPAREN", .serialized_operator = "("}, {"RPAREN", .serialized_operator = ")"}, {"LBRACKET", .serialized_operator = "["}, {"RBRACKET", .serialized_operator = "]"}, {"LBRACE", .serialized_operator = "{"}, {"RBRACE", .serialized_operator = "}"}, {"COMMA", .serialized_operator = ","}, {"DOT", .serialized_operator = "."}, {"ARROW", .serialized_operator = "->"}, {"ELLIPSIS", .serialized_operator = "..."}, {"COLON", .serialized_operator = ":"}, {"SEMICOLON", .serialized_operator = ";"}, {"QUESTION", .serialized_operator = "?"}, {"HASH", .serialized_operator = "#"}, {"HASHHASH", .serialized_operator = "##"}, {"PLUS", .serialized_operator = "+"}, {"MINUS", .serialized_operator = "-"}, {"STAR", .serialized_operator = "*"}, {"SLASH", .serialized_operator = "/"}, {"PERCENT", .serialized_operator = "%"}, {"INC", .serialized_operator = "++"}, {"DEC", .serialized_operator = "--"}, {"ASSIGN", .serialized_operator = "="}, {"PLUS_ASSIGN", .serialized_operator = "+="}, {"MINUS_ASSIGN", .serialized_operator = "-="}, {"MUL_ASSIGN", .serialized_operator = "*="}, {"DIV_ASSIGN", .serialized_operator = "/="}, {"MOD_ASSIGN", .serialized_operator = "%="}, {"LSHIFT_ASSIGN", .serialized_operator = "<<="}, {"RSHIFT_ASSIGN", .serialized_operator = ">>="}, {"AND_ASSIGN", .serialized_operator = "&="}, {"XOR_ASSIGN", .serialized_operator = "^="}, {"OR_ASSIGN", .serialized_operator = "|="}, {"EQ", .serialized_operator = "=="}, {"NEQ", .serialized_operator = "!="}, {"LT", .serialized_operator = "<"}, {"LEQ", .serialized_operator = "<="}, {"GT", .serialized_operator = ">"}, {"GEQ", .serialized_operator = ">="}, {"NOT", .serialized_operator = "!"}, {"BITNOT", .serialized_operator = "~"}, {"BITAND", .serialized_operator = "&"}, {"BITOR", .serialized_operator = "|"}, {"BITXOR", .serialized_operator = "^"}, {"AND", .serialized_operator = "&&"}, {"OR", .serialized_operator = "||"}, {"LSHIFT", .serialized_operator = "<<"}, {"RSHIFT", .serialized_operator = ">>"}, {"auto", .keyword = true}, {"break", .keyword = true}, {"case", .keyword = true}, {"char", .keyword = true}, {"const", .keyword = true}, {"continue", .keyword = true}, {"default", .keyword = true}, {"do", .keyword = true}, {"double", .keyword = true}, {"else", .keyword = true}, {"enum", .keyword = true}, {"extern", .keyword = true}, {"float", .keyword = true}, {"for", .keyword = true}, {"goto", .keyword = true}, {"if", .keyword = true}, {"inline", .keyword = true}, {"int", .keyword = true}, {"long", .keyword = true}, {"register", .keyword = true}, {"restrict", .keyword = true}, {"return", .keyword = true}, {"short", .keyword = true}, {"signed", .keyword = true}, {"sizeof", .keyword = true}, {"static", .keyword = true}, {"struct", .keyword = true}, {"switch", .keyword = true}, {"typedef", .keyword = true}, {"union", .keyword = true}, {"unsigned", .keyword = true}, {"void", .keyword = true}, {"volatile", .keyword = true}, {"while", .keyword = true}, }; printf("// auto generated by meta.c\n"); printf("typedef enum {\n"); for (int i = 0; i < ilen(kinds); i += 1) { printf(" TOK_%s,\n", kinds[i].name); } printf("} Token_Kind;\n"); printf("char *token_to_op(Token_Kind kind) {\n"); printf(" switch (kind) {\n"); for (int i = 0; i < ilen(kinds); i += 1) { if (kinds[i].serialized_operator) { printf(" case TOK_%s: return \"%s\";\n", kinds[i].name, kinds[i].serialized_operator); } } printf(" default: return 0;\n"); printf(" }\n"); printf("}\n"); printf("char *token_to_name(Token_Kind kind) {\n"); printf(" switch (kind) {\n"); for (int i = 0; i < ilen(kinds); i += 1) { if (kinds[i].name) { printf(" case TOK_%s: return \"%s\";\n", kinds[i].name, kinds[i].name); } } printf(" default: return \"\";\n"); printf(" }\n"); printf("}\n"); { printf("// \n"); printf("// KEYWORDS\n"); printf("// \n"); for (int i = 0; i < ilen(kinds); i += 1) { if (kinds[i].keyword) { printf("char *keyword_%s;\n", kinds[i].name); } } Task *first = NULL; Task *last = NULL; printf("char *lex_first_keyword = NULL;\n"); printf("char *lex_last_keyword = NULL;\n"); printf("char *make_intern(char *string, int len);\n"); printf("#define lex_add_keyword(x) make_intern(x, ilen(x) - 1)\n"); printf("void lex_init_keywords(void) {\n"); for (int i = 0; i < ilen(kinds); i += 1) { if (kinds[i].keyword) { if (!first) first = kinds + i; last = kinds + i; printf(" keyword_%s = lex_add_keyword(\"%s\");\n", kinds[i].name, kinds[i].name); } } printf("#define TOK_FIRST_KEYWORD TOK_%s\n", first->name); printf("#define TOK_LAST_KEYWORD TOK_%s\n", last->name); printf(" lex_first_keyword = keyword_%s;\n", first->name); printf(" lex_last_keyword = keyword_%s;\n", last->name); printf("}\n"); } }