220 lines
5.2 KiB
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;
|
|
}
|
|
}
|
|
|
|
|