165 lines
4.5 KiB
C++
165 lines
4.5 KiB
C++
struct Token {
|
|
char* s;
|
|
int len;
|
|
};
|
|
|
|
FUNCTION bool is_alphabetic(char w) {
|
|
bool result = (w >= 'a' && w <= 'z') || (w >= 'A' && w <= 'Z');
|
|
return result;
|
|
}
|
|
|
|
FUNCTION bool is_number(char w) {
|
|
bool result = w >= '0' && w <= '9';
|
|
return result;
|
|
}
|
|
|
|
FUNCTION bool is_whitespace(char w) {
|
|
bool result = w == '\n' || w == ' ' || w == '\t' || w == '\v' || w == '\r';
|
|
return result;
|
|
}
|
|
|
|
FUNCTION int string_len(char* a) {
|
|
int result = 0;
|
|
while (*a++ != 0) result++;
|
|
return result;
|
|
}
|
|
|
|
FUNCTION bool equals(Token a, const char* b) {
|
|
int len = string_len((char*)b);
|
|
if (a.len != len) return false;
|
|
for (int i = 0; i < len; i++) {
|
|
if (a.s[i] != b[i]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool combinations[64][8] = { { 0, 0 }, { 1, 1 }, { 0, 1 }, { 1, 0 } };
|
|
int combinations_to_make = 4;
|
|
|
|
struct Lexer {
|
|
char* stream;
|
|
char* data;
|
|
char output[10000];
|
|
|
|
Token next() {
|
|
while (is_whitespace(*stream)) stream++;
|
|
Token result = {};
|
|
result.s = stream++;
|
|
if (is_alphabetic(*result.s)) {
|
|
while (is_alphabetic(*stream) || *stream == '_') stream++;
|
|
}
|
|
result.len = (int)(stream - result.s);
|
|
return result;
|
|
}
|
|
|
|
bool match(const char* str, Token* out = 0) {
|
|
Lexer l = *this;
|
|
Token token = next();
|
|
if (out) *out = token;
|
|
if (equals(token, str)) {
|
|
return true;
|
|
}
|
|
*this = l;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
struct Section {
|
|
char* begin, * end;
|
|
char* name, * name_end;
|
|
int if_clause_i;
|
|
bool is_else;
|
|
};
|
|
|
|
FUNCTION void generate_stuff() {
|
|
char* data = os.read_file("main.cpp");
|
|
FILE* f = fopen("raster_functions.cpp", "w");
|
|
ASSERT(f);
|
|
Section sections[100] = {};
|
|
int sections_count = 0;
|
|
int if_clause_count = 0;
|
|
Lexer lexer = { data, data };
|
|
for (;;) {
|
|
Token token = lexer.next();
|
|
if (*token.s == 0) break;
|
|
|
|
if (equals(token, "FUNCTION") &&
|
|
lexer.match("void") &&
|
|
lexer.match("draw_triangle", &token)) {
|
|
Section* section = sections + sections_count++;
|
|
section->begin = token.s + token.len;
|
|
int indent = 1;
|
|
while (lexer.next().s[0] != '{');
|
|
for (; ; ) {
|
|
token = lexer.next();
|
|
if (token.s[0] == '{') indent++;
|
|
else if (token.s[0] == '}') indent--;
|
|
else if (token.s[0] == '#') {
|
|
if (lexer.match("if")) {
|
|
section->end = token.s;
|
|
|
|
if_clause_count++;
|
|
token = lexer.next();
|
|
section = sections + sections_count++;
|
|
section->if_clause_i = if_clause_count;
|
|
section->is_else = false;
|
|
section->name = token.s;
|
|
section->name_end = token.s + token.len;
|
|
section->begin = section->name_end;
|
|
}
|
|
else if (lexer.match("else")) {
|
|
section->end = token.s;
|
|
char* name = section->name;
|
|
char* name_end = section->name_end;
|
|
|
|
section = sections + sections_count++;
|
|
section->is_else = true;
|
|
section->if_clause_i = if_clause_count;
|
|
section->name = name;
|
|
section->name_end = name_end;
|
|
section->begin = token.s + 5;
|
|
}
|
|
else if (lexer.match("endif")) {
|
|
section->end = token.s;
|
|
section = sections + sections_count++;
|
|
section->begin = token.s + 6;
|
|
}
|
|
}
|
|
|
|
if (indent == 0) {
|
|
section->end = token.s + 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int ci = 0; ci < combinations_to_make; ci++) {
|
|
// @Note: Figure out function name
|
|
fprintf(f, "\nFUNCTION void draw_triangle");
|
|
for (int i = 0; i < sections_count; i++) {
|
|
section = sections + i;
|
|
if (section->name && section->is_else == !combinations[ci][section->if_clause_i - 1]) {
|
|
fprintf(f, "_%.*s_", (int)(section->name_end - section->name), section->name);
|
|
fprintf(f, "%s", section->is_else ? "off" : "on");
|
|
}
|
|
}
|
|
// @Note: Figure out function content
|
|
for (int i = 0; i < sections_count; i++) {
|
|
section = sections + i;
|
|
if (!section->name) {
|
|
fprintf(f, "%.*s %.*s", (int)(section->name_end - section->name), section->name, (int)(section->end - section->begin), section->begin);
|
|
}
|
|
else {
|
|
if (section->is_else == !combinations[ci][section->if_clause_i - 1]) {
|
|
fprintf(f, "// %.*s %.*s", (int)(section->name_end - section->name), section->name, (int)(section->end - section->begin), section->begin);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose(f);
|
|
}
|
|
}
|
|
} |