Files
smallprojects/meta.c
2026-05-23 15:39:04 +02:00

171 lines
6.6 KiB
C

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#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 \"<invalid-token-kind>\";\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");
}
}