Files
corelang/print.c

220 lines
5.2 KiB
C

function void print_decl(Parser *p, Decl *node);
function B32 print_typespec(Parser *p, Typespec *spec);
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(Parser *p, Expr *expr){
switch(expr->kind) {
case EK_Atom: {
token_print(expr->token);
} break;
case EK_Sizeof:{
lex_print("sizeof(");
if(expr->size_of.kind == SIZEOF_Expr){
expr_print(p, expr->size_of.expr);
}
else{
assert(expr->size_of.kind == SIZEOF_Type);
print_typespec(p, expr->size_of.type);
}
lex_print(")");
}break;
case EK_Binary:{
lex_print("(");
expr_print(p, expr->binary.left);
token_print(expr->token);
expr_print(p, expr->binary.right);
lex_print(")");
} break;
case EK_Unary:{
lex_print("(");
token_print(expr->token);
expr_print(p, expr->unary.expr);
lex_print(")");
} break;
case EK_Ternary:{
lex_print("(");
expr_print(p, expr->ternary.cond);
lex_print("?");
expr_print(p, expr->ternary.on_true);
lex_print(":");
expr_print(p, expr->ternary.on_false);
lex_print(")");
} break;
case EK_List:{
lex_print("(");
for(Expr *n = expr->list.first; n; n=n->next){
expr_print(p, n);
if(n!=expr->list.last) lex_print(",");
}
lex_print(")");
}break;
case EK_Cast:{
lex_print("(");
lex_print("(");
print_typespec(p, expr->cast.type);
lex_print(")");
expr_print(p, expr->cast.expr);
lex_print(")");
} break;
case EK_Index:{
expr_print(p, expr->index.atom);
lex_print("[");
expr_print(p, expr->index.index);
lex_print("]");
}break;
case EK_Call:{
expr_print(p, expr->call.atom);
lex_print("(");
expr_print(p, expr->call.list);
lex_print(")");
}break;
default: {invalid_codepath;} break;
}
}
global S64 indent;
function B32
print_typespec(Parser *p, Typespec *spec){
switch(spec->kind) {
case TS_Name: {
lex_print("%s", spec->name.s.str);
} break;
case TS_Struct:{
print_decl(p, spec->struct_spec);
return false;
} break;
case TS_Pointer: {
print_typespec(p, spec->base);
lex_print("*");
} break;
case TS_Array: {
print_typespec(p, spec->array_spec.base);
lex_print("[");
expr_print(p, spec->array_spec.size);
lex_print("]");
} break;
case TS_Function: {
lex_print("(");
for(Typespec *n = spec->function_spec.first; n; n=n->next){
print_typespec(p,n);
if(n!=spec->function_spec.last)
lex_print(", ");
}
lex_print(")");
print_typespec(p,spec->function_spec.ret);
} break;
default: {invalid_codepath;} break;
}
return true;
}
function void
print_assign_expr(Parser *p, Expr *expr){
if(expr){
lex_print(" = ");
expr_print(p, expr);
}
}
function void
print_note_list(Parser *p, Note *note){
if(note){
lex_print("(");
for(Note *n = note; n; n=n->next){
lex_print("%s", n->name.s.str);
print_note_list(p,n->first);
print_assign_expr(p, n->expr);
}
lex_print(")");
}
}
function void
print_notes(Parser *p, Note *note){
for(Note *n = note; n; n=n->next){
lex_print("@%s", n->name.s.str);
print_note_list(p,n->first);
print_assign_expr(p,n->expr);
lex_print(" ");
}
}
function void
print_decl(Parser *p, Decl *node){
print_notes(p, node->first_note);
switch(node->kind) {
case DECL_List: {
for(Decl *n = node->list.first; n; n=n->next){
print_decl(p,n);
lex_new_line();
}
} break;
case DECL_Variable:{
lex_print("%s: ", node->name.s.str);
B32 r = print_typespec(p, node->variable_decl.type);
print_assign_expr(p,node->variable_decl.expr);
if(r) lex_print(";");
} break;
case DECL_Typedef:{
lex_print("typedef %s ", node->name.s.str);
print_typespec(p, node->typedef_decl.type);
lex_print(";");
} break;
case DECL_Struct:
case DECL_Union :{
const char *struct_name = node->kind==DECL_Struct ? "struct" : "union";
lex_print("%s %s{\n", struct_name, node->name.s.str?(char*)node->name.s.str:"");
for(Decl *n = node->struct_decl.first; n; n=n->next){
print_decl(p, n);
lex_print("\n");
}
lex_print("};\n");
} break;
case DECL_Enum:{
lex_print("enum %s : ", node->name.s.str);
print_typespec(p, node->enum_decl.typespec);
lex_print("{\n");
for(Decl_Enum_Child *n = node->enum_decl.first; n; n=n->next){
print_notes(p, n->first_note);
lex_print("%s", n->name.s.str);
print_assign_expr(p, n->expr);
lex_print(",\n");
}
lex_print("};\n");
} break;
default: {invalid_codepath;} break;
}
}