285 lines
6.6 KiB
C
285 lines
6.6 KiB
C
function void expr_print(Expr *expr);
|
|
function B32 typespec_print(Typespec *spec);
|
|
|
|
global S64 indent;
|
|
|
|
#define println(...) do{ printf("\n"); print_indent(); printf(__VA_ARGS__); }while(0)
|
|
|
|
|
|
#define AST_CAST(item, T) T *item = (T *)item; assert(item->kind == AST_##Kind
|
|
#define AST_Iter(parent, name, T) for(T *name = (T *)(parent)->first; name; name=(T *)name->next) // , assert(name->kind == AST_##type
|
|
|
|
|
|
function void
|
|
print_indent(){
|
|
for(S64 i = 0; i < indent*2; i++)
|
|
printf(" ");
|
|
}
|
|
|
|
function void
|
|
token_print(Token *token){
|
|
printf("%.*s", (S32)token->len, token->str);
|
|
}
|
|
|
|
function void
|
|
expr_compound_print(Expr_Compound_Field *field){
|
|
switch(field->kind){
|
|
case COMPOUND_Default: {
|
|
expr_print(field->init);
|
|
}break;
|
|
case COMPOUND_Named: {
|
|
printf("[%s] = ", field->name.s.str);
|
|
expr_print(field->init);
|
|
}break;
|
|
case COMPOUND_Index: {
|
|
printf("[");
|
|
expr_print(field->index);
|
|
printf("] = ");
|
|
expr_print(field->init);
|
|
}break;
|
|
default: invalid_codepath;
|
|
}
|
|
}
|
|
|
|
function void
|
|
expr_print(Expr *expr){
|
|
switch(expr->kind) {
|
|
case EK_Int:case EK_String:case EK_Identifier: {
|
|
token_print(expr->token);
|
|
} break;
|
|
|
|
case EK_SizeExpr:{
|
|
printf("size_expr(");
|
|
expr_print(expr->size_expr.expr);
|
|
printf(")");
|
|
}break;
|
|
|
|
case EK_Compound:{
|
|
if(expr->compound.typespec){
|
|
printf("(");
|
|
typespec_print(expr->compound.typespec);
|
|
printf(")");
|
|
}
|
|
printf("{");
|
|
for(Expr_Compound_Field *n = expr->compound.first; n; n=n->next){
|
|
expr_compound_print(n);
|
|
if(n!=expr->compound.last) printf(",");
|
|
}
|
|
printf("}");
|
|
} break;
|
|
|
|
case EK_SizeType:{
|
|
printf("size_type(");
|
|
printf(")");
|
|
}break;
|
|
|
|
case EK_Paren:{
|
|
printf("(");
|
|
expr_print(expr->paren.expr);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_Field:{
|
|
expr_print(expr->field.expr);
|
|
printf(".%s", expr->field.name.s.str);
|
|
} break;
|
|
|
|
case EK_Binary:{
|
|
printf("(");
|
|
expr_print(expr->binary.left);
|
|
token_print(expr->token);
|
|
expr_print(expr->binary.right);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_PostfixUnary:{
|
|
printf("(");
|
|
expr_print(expr->unary.expr);
|
|
token_print(expr->token);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_Unary:{
|
|
printf("(");
|
|
token_print(expr->token);
|
|
expr_print(expr->unary.expr);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_Ternary:{
|
|
printf("(");
|
|
expr_print(expr->ternary.cond);
|
|
printf("?");
|
|
expr_print(expr->ternary.on_true);
|
|
printf(":");
|
|
expr_print(expr->ternary.on_false);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_Cast:{
|
|
printf("(");
|
|
printf("(");
|
|
typespec_print(expr->cast.typespec);
|
|
printf(")");
|
|
expr_print(expr->cast.expr);
|
|
printf(")");
|
|
} break;
|
|
|
|
case EK_Index:{
|
|
expr_print(expr->index.atom);
|
|
printf("[");
|
|
expr_print(expr->index.index);
|
|
printf("]");
|
|
}break;
|
|
|
|
case EK_Call:{
|
|
expr_print(expr->call.atom);
|
|
printf("(");
|
|
for(Expr_Compound_Field *n = expr->call.first; n; n=n->next){
|
|
expr_compound_print(n);
|
|
if(n!=expr->call.last) printf(",");
|
|
}
|
|
printf(")");
|
|
}break;
|
|
default: {invalid_codepath;} break;
|
|
}
|
|
}
|
|
|
|
|
|
function B32
|
|
typespec_print(Typespec *spec){
|
|
switch(spec->kind) {
|
|
case TS_Name: {
|
|
printf("%s", spec->name.s.str);
|
|
} break;
|
|
|
|
case TS_NamedArgument: {
|
|
printf("%s: ", spec->named.name.s.str);
|
|
typespec_print(spec->named.base);
|
|
}break;
|
|
|
|
case TS_Pointer: {
|
|
typespec_print(spec->base);
|
|
printf("*");
|
|
} break;
|
|
|
|
case TS_Array: {
|
|
typespec_print(spec->arr.base);
|
|
printf("[");
|
|
expr_print(spec->arr.size);
|
|
printf("]");
|
|
} break;
|
|
|
|
case TS_Function: {
|
|
printf("(");
|
|
for(Typespec *n = spec->func.first; n; n=n->next){
|
|
typespec_print(n);
|
|
if(n!=spec->func.last)
|
|
printf(", ");
|
|
}
|
|
|
|
printf(")");
|
|
typespec_print(spec->func.ret);
|
|
} break;
|
|
default: {invalid_codepath;} break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function void
|
|
print_assign_expr(Expr *expr){
|
|
if(expr){
|
|
printf(" = ");
|
|
expr_print(expr);
|
|
}
|
|
}
|
|
|
|
function void
|
|
ast_print(AST *in){
|
|
//print_notes(p, node->first_note);
|
|
|
|
switch(in->kind) {
|
|
case AST_Program: {
|
|
AST_Parent *node = (AST_Parent *)in;
|
|
for(AST *n = node->first; n; n=n->next){
|
|
ast_print(n);
|
|
printf("\n");
|
|
}
|
|
} break;
|
|
|
|
case AST_Decl_Const:
|
|
case AST_Decl_Var:{
|
|
Decl_Var *node = (Decl_Var *)in;
|
|
println("%s: ", node->name.s.str);
|
|
if(node->typespec) typespec_print(node->typespec);
|
|
print_assign_expr(node->expr);
|
|
} break;
|
|
|
|
case AST_Decl_Typedef:{
|
|
Decl_Typedef *node = (Decl_Typedef *)in;
|
|
println("typedef %s ", node->name.s.str);
|
|
typespec_print(node->typespec);
|
|
printf(";");
|
|
} break;
|
|
|
|
case AST_Decl_Func:{
|
|
Decl_Func *node = (Decl_Func *)in;
|
|
println("");
|
|
typespec_print(node->ret);
|
|
printf(" %s", node->name.s.str);
|
|
printf("(");
|
|
AST_Iter(node, arg, Decl_Func_Arg){
|
|
printf("%s: ", arg->name.s.str);
|
|
typespec_print(arg->typespec);
|
|
if((AST *)arg != node->last)
|
|
printf(", ");
|
|
}
|
|
printf(");");
|
|
} break;
|
|
|
|
case AST_Decl_Struct:
|
|
case AST_Decl_Union :{
|
|
Decl_Struct *node = (Decl_Struct *)in;
|
|
const char *struct_name = node->kind==AST_Decl_Struct ? "struct" : "union";
|
|
println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:"");
|
|
indent++;
|
|
for(AST *n = node->first; n; n=n->next){
|
|
ast_print(n);
|
|
}
|
|
indent--;
|
|
println("};");
|
|
} break;
|
|
|
|
case AST_Decl_SubStruct:
|
|
case AST_Decl_SubUnion :{
|
|
Decl_Struct *node = (Decl_Struct *)in;
|
|
const char *struct_name = node->kind==AST_Decl_Struct ? "struct" : "union";
|
|
println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:"");
|
|
indent++;
|
|
for(AST *n = node->first; n; n=n->next){
|
|
ast_print(n);
|
|
}
|
|
indent--;
|
|
println("};");
|
|
} break;
|
|
|
|
case AST_Decl_Enum:{
|
|
Decl_Enum *node = (Decl_Enum *)in;
|
|
println("enum %s : ", node->name.s.str);
|
|
typespec_print(node->typespec);
|
|
printf("{");
|
|
indent++;
|
|
AST_Iter(node, n, Decl_Enum_Child){
|
|
//print_notes(p, n->first_note);
|
|
println("%s", n->name.s.str);
|
|
print_assign_expr(n->expr);
|
|
printf(",");
|
|
}
|
|
indent--;
|
|
println("};");
|
|
} break;
|
|
default: {invalid_codepath;} break;
|
|
}
|
|
}
|
|
|