Delete previous progress
This commit is contained in:
415
print.c
415
print.c
@@ -1,415 +0,0 @@
|
||||
|
||||
function void
|
||||
tokens_print(Tokens tokens){
|
||||
lex_print("\n== Token count = %d\n", (S32)tokens.len);
|
||||
for(Token *t = tokens.tokens; t != tokens.tokens + tokens.len; t++){
|
||||
lex_print("%s \"%.*s\"\n", token_kind_string[t->kind].str, (S32)t->len, t->str);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
token_print(Token *token){
|
||||
lex_print("%.*s", (S32)token->len, token->str);
|
||||
}
|
||||
|
||||
function void
|
||||
expr_print(Expr *expr){
|
||||
switch(expr->kind) {
|
||||
case EK_Atom: {
|
||||
token_print(expr->token);
|
||||
} break;
|
||||
|
||||
case EK_Binary:{
|
||||
lex_print("(");
|
||||
expr_print(expr->binary.left);
|
||||
token_print(expr->token);
|
||||
expr_print(expr->binary.right);
|
||||
lex_print(")");
|
||||
} break;
|
||||
case EK_Unary:{
|
||||
lex_print("(");
|
||||
token_print(expr->token);
|
||||
expr_print(expr->unary.expr);
|
||||
lex_print(")");
|
||||
} break;
|
||||
|
||||
case EK_Ternary:{
|
||||
lex_print("(");
|
||||
expr_print(expr->ternary.cond);
|
||||
lex_print("?");
|
||||
expr_print(expr->ternary.on_true);
|
||||
lex_print(":");
|
||||
expr_print(expr->ternary.on_false);
|
||||
lex_print(")");
|
||||
} break;
|
||||
case EK_List:{
|
||||
lex_print("(");
|
||||
for(Expr *n = expr->list.first; n; n=n->next){
|
||||
expr_print(n);
|
||||
if(n!=expr->list.last) lex_print(",");
|
||||
}
|
||||
lex_print(")");
|
||||
}break;
|
||||
|
||||
case EK_Cast:{
|
||||
lex_print("(");
|
||||
lex_print("(");
|
||||
//type_print(expr->cast.type);
|
||||
lex_print(")");
|
||||
expr_print(expr->cast.expr);
|
||||
lex_print(")");
|
||||
} break;
|
||||
|
||||
case EK_Index:{
|
||||
expr_print(expr->index.atom);
|
||||
lex_print("[");
|
||||
expr_print(expr->index.index);
|
||||
lex_print("]");
|
||||
}break;
|
||||
|
||||
case EK_Call:{
|
||||
expr_print(expr->call.atom);
|
||||
expr_print(expr->call.list);
|
||||
}break;
|
||||
default: {invalid_codepath;} break;
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
print_indent(S64 indent){
|
||||
for(S64 i = 0; i < indent; i++){
|
||||
lex_print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function AST_Node *
|
||||
ast_get_basis_type(AST_Node *node){
|
||||
switch(node->kind) {
|
||||
case AK_Struct: case AK_Union: case AK_Enum: case AK_BaseType:{return node;} break;
|
||||
case AK_Function:{return node;} break;
|
||||
case AK_Typedef:{return node;} break;
|
||||
case AK_Array: case AK_Pointer:{return ast_get_basis_type(node->pointer);} break;
|
||||
default: invalid_codepath;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function void
|
||||
ast_print_pointers(AST_Node *node){
|
||||
if(node->kind == AK_Pointer){
|
||||
lex_print("*");
|
||||
ast_print_pointers(node->pointer);
|
||||
}
|
||||
else if(node->kind == AK_Array){
|
||||
ast_print_pointers(node->pointer);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
ast_print_arrays(AST_Node *node){
|
||||
if(node->kind == AK_Pointer){
|
||||
ast_print_arrays(node->pointer);
|
||||
}
|
||||
else if(node->kind == AK_Array){
|
||||
lex_print("[");
|
||||
expr_print(node->expr);
|
||||
lex_print("]");
|
||||
ast_print_arrays(node->pointer);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
ast_print_var(AST_Node *node);
|
||||
function void
|
||||
ast_print_func_params(AST_Node *node){
|
||||
for(AST_Node *n = node->first_child; n; n=n->next){
|
||||
ast_print_var(n);
|
||||
if(n != node->last_child) lex_print(", ");
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
ast_print_var(AST_Node *node){
|
||||
AST_Node *basis_type = ast_get_basis_type(node->variable_type);
|
||||
if(basis_type->kind == AK_Function){
|
||||
lex_print("%s (*%s)(", basis_type->func_return_type->name.s.str, node->name.s.str);
|
||||
ast_print_func_params(basis_type);
|
||||
lex_print(")");
|
||||
}
|
||||
else{
|
||||
lex_print("%s ", basis_type->name.s.str);
|
||||
ast_print_pointers(node->variable_type);
|
||||
lex_print("%s", node->name.s.str);
|
||||
ast_print_arrays(node->variable_type);
|
||||
}
|
||||
|
||||
if(node->expr){
|
||||
lex_print(" = ");
|
||||
expr_print(node->expr);
|
||||
}
|
||||
}
|
||||
|
||||
function AST_Node *
|
||||
ast_find_note(AST_Node *node, String string){
|
||||
for(AST_Node *n = node->first_note; n; n=n->next){
|
||||
if(string_compare(n->name.s, string)){
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function String
|
||||
ast_find_string(AST_Node *node, String string, String default_val){
|
||||
AST_Node *find = ast_find_note(node, string);
|
||||
if(find){
|
||||
if(find->expr->kind == EK_Atom){
|
||||
return find->expr->token->string;
|
||||
}
|
||||
}
|
||||
return default_val;
|
||||
}
|
||||
|
||||
global Arena todo_arena;
|
||||
|
||||
function void
|
||||
ast__print(AST_Node *node, S64 indent){
|
||||
switch(node->kind){
|
||||
|
||||
case AK_List:{
|
||||
for(AST_Node *n = node->first_child; n; n=n->next){
|
||||
ast__print(n, indent);
|
||||
lex_print("\n");
|
||||
}
|
||||
} break;
|
||||
|
||||
case AK_Union:
|
||||
case AK_Struct:{
|
||||
const char *type = node->kind == AK_Struct ? "struct":"union";
|
||||
if(indent == 0) lex_print("typedef %s %s %s;\n", type, node->name.s.str, node->name.s.str);
|
||||
lex_print("%s %s{\n", type, indent == 0 ? node->name.s.str:(U8 *)"");
|
||||
for(AST_Node *n = node->first_child; n; n=n->next){
|
||||
AST_Node *using_note = ast_find_note(n, lit("using"));
|
||||
AST_Node *array_note = ast_find_note(n, lit("array"));
|
||||
AST_Node *sllqueue_note = ast_find_note(n, lit("sllqueue"));
|
||||
if(using_note) {
|
||||
assert(n->kind == AK_Variable);
|
||||
lex_print("union{\n");
|
||||
ast__print(n, indent+2);
|
||||
lex_print("\n");
|
||||
Intern_String name = n->variable_type->name;
|
||||
n->variable_type->name = (Intern_String){0};
|
||||
assert(n->variable_type->kind == AK_Struct || n->variable_type->kind == AK_Union);
|
||||
ast__print(n->variable_type, indent+2);
|
||||
n->variable_type->name = name;
|
||||
lex_print("\n}");
|
||||
}
|
||||
else if(array_note){
|
||||
AST_Node *cap = ast_find_note(n, lit("cap"));
|
||||
AST_Node *len = ast_find_note(n, lit("len"));
|
||||
ast__print(n, indent+2);
|
||||
lex_print("\nS64 len;\nS64 cap;");
|
||||
}
|
||||
else if(sllqueue_note){
|
||||
lex_print("%s *first_%s;\n", n->variable_type->name.s.str, string_to_lower(&todo_arena, n->name.s).str);
|
||||
lex_print("%s *last_%s;\n", n->variable_type->name.s.str, string_to_lower(&todo_arena, n->name.s).str);
|
||||
}
|
||||
else {
|
||||
ast__print(n, indent+2);
|
||||
}
|
||||
lex_print("\n");
|
||||
}
|
||||
|
||||
lex_print("}");
|
||||
lex_print("%s;", indent == 0 ? (U8 *)"":node->name.s.str?node->name.s.str:(U8*)"");
|
||||
if(indent == 0) lex_new_line();
|
||||
} break;
|
||||
|
||||
case AK_Variable:{
|
||||
if(indent == 0) lex_print("global ");
|
||||
ast_print_var(node);
|
||||
lex_print(";");
|
||||
} break;
|
||||
|
||||
case AK_Typedef:{
|
||||
lex_print("typedef ");
|
||||
ast_print_var(node);
|
||||
lex_print(";");
|
||||
} break;
|
||||
|
||||
case AK_Enum:{
|
||||
print_indent(indent);
|
||||
lex_print("typedef enum %s{\n", node->name.s.str);
|
||||
AST_Node *prefix = ast_find_note(node, lit("prefix"));
|
||||
|
||||
for(AST_Node *n = node->first_child; n; n=n->next){
|
||||
print_indent(indent+2);
|
||||
if(prefix){
|
||||
expr_print(prefix->expr);
|
||||
}
|
||||
lex_print("%s", n->name.s.str);
|
||||
if(n->expr){
|
||||
lex_print(" = ");
|
||||
expr_print(n->expr);
|
||||
}
|
||||
lex_print(",\n");
|
||||
}
|
||||
|
||||
print_indent(indent);
|
||||
lex_print("}%s;\n", node->name.s.str);
|
||||
} break;
|
||||
|
||||
default: invalid_codepath;
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
ast_print(AST_Node *node){
|
||||
ast__print(node, 0);
|
||||
}
|
||||
|
||||
function B32
|
||||
intern_is_empty(Intern_String string){
|
||||
if(string.s.str == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef struct String_Map{
|
||||
String replace;
|
||||
String with;
|
||||
}String_Map;
|
||||
|
||||
function B32
|
||||
token_is_number(Token *token){
|
||||
B32 result = token->kind == TK_Int;
|
||||
return result;
|
||||
}
|
||||
|
||||
function void
|
||||
print_string_replaced(String string, String_Map *maps, SizeU count){
|
||||
Tokens tokens = lex_stream(string, lit("Replace"));
|
||||
for(S64 i = 0; i < tokens.len; i++){
|
||||
Token *t = tokens.tokens + i;
|
||||
if(t->kind == TK_At) continue;
|
||||
for(String_Map *map = maps; map != maps+count; map++){
|
||||
if(string_compare(map->replace, t->string)){
|
||||
t->string = map->with;
|
||||
}
|
||||
}
|
||||
|
||||
lex_print("%.*s", (S32)t->string.len, t->string.str);
|
||||
if(t->kind == TK_Keyword) lex_print(" ");
|
||||
if(t->kind == TK_Identifier &&
|
||||
(t[1].kind== TK_Identifier || token_is_number(t+1))) lex_print(" ");
|
||||
if(t->kind == TK_OpenBrace) lex_print("\n");
|
||||
if(t->kind == TK_CloseBrace) lex_print("\n");
|
||||
if(t->kind == TK_Semicolon) lex_print("\n");
|
||||
}
|
||||
free(tokens.tokens);
|
||||
|
||||
}
|
||||
|
||||
function void
|
||||
gen_struct(AST_Node *n, Intern_String shadow_type_name){
|
||||
for(AST_Node *member = n->first_child; member; member=member->next){
|
||||
AST_Node *using_note = ast_find_note(member, lit("using"));
|
||||
AST_Node *array_note = ast_find_note(member, lit("array"));
|
||||
AST_Node *sllqueue_note = ast_find_note(member, lit("sllqueue"));
|
||||
if(using_note){
|
||||
gen_struct(member->variable_type, n->name);
|
||||
}
|
||||
if(array_note){
|
||||
AST_Node *array_type = ast_get_basis_type(member->variable_type);
|
||||
|
||||
Intern_String type_name = n->name;
|
||||
if(!intern_is_empty(shadow_type_name))
|
||||
type_name = shadow_type_name;
|
||||
|
||||
|
||||
String_Map maps[] = {
|
||||
{lit("function"), lit("function\n")},
|
||||
{lit("base_type"), type_name.s},
|
||||
{lit("base_type_lower"), string_to_lower(&todo_arena, type_name.s)},
|
||||
{lit("var_type"), array_type->name.s},
|
||||
{lit("var_type_lower"), string_to_lower(&todo_arena, array_type->name.s)},
|
||||
{lit("var_name"), member->name.s},
|
||||
{lit("var_name_lower"), string_to_lower(&todo_arena, member->name.s)},
|
||||
{lit("len"), ast_find_string(array_note, lit("len"), lit("len"))},
|
||||
{lit("cap"), ast_find_string(array_note, lit("cap"), lit("cap"))},
|
||||
{lit("data"), ast_find_string(array_note, lit("data"), lit("data"))},
|
||||
};
|
||||
|
||||
|
||||
String a
|
||||
= lit("function var_type *base_type@_array_push_empty(base_type *a){"
|
||||
"if(a->cap == 0){\n"
|
||||
" a->cap = 1024;\n"
|
||||
" a->tokens = malloc(sizeof(var_type)*a->cap);\n"
|
||||
"}\n"
|
||||
"else if(a->len+1 > a->cap){\n"
|
||||
" a->cap *= 2;\n"
|
||||
" a->tokens = realloc(a->tokens, sizeof(var_type)*a->cap);\n"
|
||||
"}\n"
|
||||
|
||||
"var_type *result = a->tokens + a->len++;\n"
|
||||
"memory_zero(result, sizeof(*result));\n"
|
||||
"return result;}");
|
||||
print_string_replaced(a, maps, buff_cap(maps));
|
||||
}
|
||||
if(sllqueue_note){
|
||||
String default_first = lit("first");
|
||||
String default_last = lit("last");
|
||||
String default_next = lit("next");
|
||||
if(!string_compare(member->name.s, lit("default"))){
|
||||
default_first = string_fmt(&todo_arena, "first_%s", member->name.s.str);
|
||||
default_last = string_fmt(&todo_arena, "last_%s", member->name.s.str);
|
||||
default_next = string_fmt(&todo_arena, "next_%s", member->name.s.str);
|
||||
}
|
||||
|
||||
String_Map maps[] = {
|
||||
{lit("function"), lit("function\n")},
|
||||
{lit("base_type"), n->name.s},
|
||||
{lit("base_type_lower"), string_to_lower(&todo_arena, n->name.s)},
|
||||
{lit("var_type"), member->variable_type->name.s},
|
||||
{lit("var_type_lower"), string_to_lower(&todo_arena, member->variable_type->name.s)},
|
||||
{lit("var_name"), member->name.s},
|
||||
{lit("var_name_lower"), string_to_lower(&todo_arena, member->name.s)},
|
||||
{lit("next"), ast_find_string(sllqueue_note, lit("next"), default_next)},
|
||||
{lit("first"), ast_find_string(sllqueue_note, lit("first"), default_first)},
|
||||
{lit("last"), ast_find_string(sllqueue_note, lit("last"), default_last)},
|
||||
};
|
||||
|
||||
String string =
|
||||
lit(
|
||||
"function void "
|
||||
"base_type_lower@_@var_name_lower@_push(base_type *parent, var_type *child){"
|
||||
"if(parent->first == 0){"
|
||||
"parent->first = parent->last = child;"
|
||||
"}"
|
||||
"else{"
|
||||
"parent->last = parent->last->next = child;"
|
||||
"}"
|
||||
"}"
|
||||
|
||||
"function var_type * "
|
||||
"base_type_lower@_@var_name_lower@_pop_first(base_type *parent){"
|
||||
" if(parent->first == parent->last){"
|
||||
" var_type *node = parent->first;"
|
||||
" parent->first = parent->last = 0;"
|
||||
" return node;"
|
||||
" }"
|
||||
" else if(parent->first){"
|
||||
" var_type *node = parent->first;"
|
||||
" parent->first = parent->first->next;"
|
||||
" }"
|
||||
"return 0;"
|
||||
"}"
|
||||
|
||||
|
||||
);
|
||||
print_string_replaced(string, maps, buff_cap(maps));
|
||||
lex_print("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user