214 lines
5.0 KiB
C
214 lines
5.0 KiB
C
|
|
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->typedef_type;} 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 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__print(n, indent+2);
|
|
lex_print("\n");
|
|
}
|
|
|
|
lex_print("}");
|
|
lex_print("%s;\n", indent == 0 ? (U8 *)"":node->name.s.str?node->name.s.str:(U8*)"");
|
|
} break;
|
|
|
|
case AK_Variable:{
|
|
if(indent == 0) lex_print("global ");
|
|
ast_print_var(node);
|
|
lex_print(";");
|
|
} break;
|
|
|
|
case AK_Typedef:{
|
|
lex_print("typedef ");
|
|
lex_print("%s;", node->name.s.str);
|
|
} break;
|
|
|
|
case AK_Enum:{
|
|
print_indent(indent);
|
|
lex_print("enum %s{\n", node->name.s.str);
|
|
|
|
for(AST_Node *n = node->first_child; n; n=n->next){
|
|
print_indent(indent+2);
|
|
lex_print("%s", n->name.s.str);
|
|
if(n->expr){
|
|
lex_print(" = ");
|
|
expr_print(n->expr);
|
|
}
|
|
lex_print(",\n");
|
|
}
|
|
|
|
print_indent(indent);
|
|
lex_print("}\n");
|
|
} break;
|
|
|
|
default: invalid_codepath;
|
|
}
|
|
}
|
|
|
|
function void
|
|
ast_print(AST_Node *node){
|
|
ast__print(node, 0);
|
|
}
|