Core printing
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
|
// @todo @cleanup
|
||||||
|
// :PrinterCleanup
|
||||||
|
// Instead of relying on global state, this probably should
|
||||||
|
// use a String_Builder or some kind of Builder context + macros
|
||||||
#define gen(...) pctx->gen.addf(__VA_ARGS__)
|
#define gen(...) pctx->gen.addf(__VA_ARGS__)
|
||||||
#define genln(...) \
|
#define genln(...) \
|
||||||
do { \
|
do { \
|
||||||
@@ -825,92 +828,16 @@ gen_ast(Ast *ast) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CORE_Static String
|
|
||||||
core_type_to_string(Ast_Type *type) {
|
|
||||||
switch (type->kind) {
|
|
||||||
case TYPE_NONE: return "<NONE>"_s; break;
|
|
||||||
case TYPE_S64: return "S64"_s; break;
|
|
||||||
case TYPE_S32: return "S32"_s; break;
|
|
||||||
case TYPE_S16: return "S16"_s; break;
|
|
||||||
case TYPE_S8: return "S8"_s; break;
|
|
||||||
case TYPE_INT: return "int"_s; break;
|
|
||||||
case TYPE_CHAR: return "char"_s; break;
|
|
||||||
case TYPE_U64: return "U64"_s; break;
|
|
||||||
case TYPE_U32: return "U32"_s; break;
|
|
||||||
case TYPE_U16: return "U16"_s; break;
|
|
||||||
case TYPE_U8: return "U8"_s; break;
|
|
||||||
case TYPE_F32: return "F32"_s; break;
|
|
||||||
case TYPE_F64: return "F64"_s; break;
|
|
||||||
case TYPE_BOOL: return "Bool"_s; break;
|
|
||||||
case TYPE_STRING: return "String"_s; break;
|
|
||||||
case TYPE_VOID: return "void"_s; break;
|
|
||||||
case TYPE_POINTER: {
|
|
||||||
String base = core_type_to_string(type->base);
|
|
||||||
return pctx->fmt("*%Q", base);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TYPE_LAMBDA: {
|
|
||||||
String_Builder *b = &pctx->helper_builder;
|
|
||||||
b->addf("(");
|
|
||||||
Array<Ast_Type *> &args = type->func.args;
|
|
||||||
For(args) {
|
|
||||||
String t = core_type_to_string(it);
|
|
||||||
b->addf("%Q", t);
|
|
||||||
if (!args.is_last(&it)) b->addf(", ");
|
|
||||||
}
|
|
||||||
b->addf(")");
|
|
||||||
if (type->func.ret) {
|
|
||||||
String t = core_type_to_string(type->func.ret);
|
|
||||||
b->addf("%Q", t);
|
|
||||||
}
|
|
||||||
String result = string_flatten(pctx->perm, b);
|
|
||||||
return result;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TYPE_STRUCT:
|
|
||||||
case TYPE_UNION:
|
|
||||||
case TYPE_ENUM: {
|
|
||||||
// @fixme: we probably want a string on Ast_Type
|
|
||||||
// so that we don't have to reach into Ast_Decl
|
|
||||||
// for Structs Enums etc.
|
|
||||||
Ast_Decl *decl = (Ast_Decl *)type->ast;
|
|
||||||
return decl->name.s;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TYPE_ARRAY: {
|
|
||||||
String base = core_type_to_string(type->base);
|
|
||||||
return pctx->fmt("[%u]%Q", type->arr.size, base);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TYPE_SLICE: {
|
|
||||||
String base = core_type_to_string(type->base);
|
|
||||||
return pctx->fmt("[]%Q", base);
|
|
||||||
} break;
|
|
||||||
case TYPE_TUPLE: {
|
|
||||||
invalid_codepath;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TYPE_TYPE: return "Type"_s; break;
|
|
||||||
case TYPE_UNTYPED_BOOL: return "UntypedBool"_s; break;
|
|
||||||
case TYPE_UNTYPED_INT: return "UntypedInt"_s; break;
|
|
||||||
case TYPE_UNTYPED_FLOAT: return "UntypedFloat"_s; break;
|
|
||||||
case TYPE_UNTYPED_STRING: return "UntypedString"_s; break;
|
|
||||||
|
|
||||||
case TYPE_COMPLETING: invalid_codepath; break;
|
|
||||||
case TYPE_INCOMPLETE: invalid_codepath; break;
|
|
||||||
case TYPE_POLYMORPH:
|
|
||||||
invalid_codepath;
|
|
||||||
break;
|
|
||||||
|
|
||||||
invalid_default_case;
|
|
||||||
}
|
|
||||||
invalid_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CORE_Static String
|
CORE_Static String
|
||||||
compile_to_c_code() {
|
compile_to_c_code() {
|
||||||
pctx->time.code_generation = os_time();
|
pctx->time.code_generation = os_time();
|
||||||
|
|
||||||
|
String core_stringify(Ast *);
|
||||||
|
For(pctx->ordered_decls) {
|
||||||
|
String r = core_stringify(it);
|
||||||
|
printf("%s\n", r.str);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int di = 0;
|
int di = 0;
|
||||||
For(pctx->ordered_decls) {
|
For(pctx->ordered_decls) {
|
||||||
|
|||||||
@@ -30,4 +30,5 @@
|
|||||||
#include "core_polymorph.cpp"
|
#include "core_polymorph.cpp"
|
||||||
#include "core_typechecking.cpp"
|
#include "core_typechecking.cpp"
|
||||||
#include "core_compiler.cpp"
|
#include "core_compiler.cpp"
|
||||||
#include "core_codegen_c_language.cpp"
|
#include "core_codegen_c_language.cpp"
|
||||||
|
#include "core_printer.cpp"
|
||||||
@@ -263,15 +263,12 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_VALUE: {
|
case AST_VALUE: {
|
||||||
Ast_Atom *src = (Ast_Atom *)ast;
|
Ast_Atom *src = (Ast_Atom *)ast;
|
||||||
Ast_Atom *dst = ast_create_copy(parent_scope, Ast_Atom, ast);
|
Ast_Atom *dst = ast_create_copy(parent_scope, Ast_Atom, ast);
|
||||||
|
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
return dst;
|
return dst;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_INDEX: {
|
case AST_INDEX: {
|
||||||
Ast_Index *src = (Ast_Index *)ast;
|
Ast_Index *src = (Ast_Index *)ast;
|
||||||
Ast_Index *dst = ast_create_copy(parent_scope, Ast_Index, ast);
|
Ast_Index *dst = ast_create_copy(parent_scope, Ast_Index, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
||||||
dst->index = (Ast_Expr *)ast_copy(src->index, parent_scope);
|
dst->index = (Ast_Expr *)ast_copy(src->index, parent_scope);
|
||||||
return dst;
|
return dst;
|
||||||
@@ -280,7 +277,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_UNARY: {
|
case AST_UNARY: {
|
||||||
Ast_Unary *src = (Ast_Unary *)ast;
|
Ast_Unary *src = (Ast_Unary *)ast;
|
||||||
Ast_Unary *dst = ast_create_copy(parent_scope, Ast_Unary, ast);
|
Ast_Unary *dst = ast_create_copy(parent_scope, Ast_Unary, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
||||||
return dst;
|
return dst;
|
||||||
} break;
|
} break;
|
||||||
@@ -288,7 +284,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_BINARY: {
|
case AST_BINARY: {
|
||||||
Ast_Binary *src = (Ast_Binary *)ast;
|
Ast_Binary *src = (Ast_Binary *)ast;
|
||||||
Ast_Binary *dst = ast_create_copy(parent_scope, Ast_Binary, ast);
|
Ast_Binary *dst = ast_create_copy(parent_scope, Ast_Binary, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->left = (Ast_Expr *)ast_copy(src->left, parent_scope);
|
dst->left = (Ast_Expr *)ast_copy(src->left, parent_scope);
|
||||||
dst->right = (Ast_Expr *)ast_copy(src->right, parent_scope);
|
dst->right = (Ast_Expr *)ast_copy(src->right, parent_scope);
|
||||||
return dst;
|
return dst;
|
||||||
@@ -297,7 +292,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_CALL_ITEM: {
|
case AST_CALL_ITEM: {
|
||||||
Ast_Call_Item *src = (Ast_Call_Item *)ast;
|
Ast_Call_Item *src = (Ast_Call_Item *)ast;
|
||||||
Ast_Call_Item *dst = ast_create_copy(parent_scope, Ast_Call_Item, ast);
|
Ast_Call_Item *dst = ast_create_copy(parent_scope, Ast_Call_Item, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->item = (Ast_Expr *)ast_copy(src->item, parent_scope);
|
dst->item = (Ast_Expr *)ast_copy(src->item, parent_scope);
|
||||||
if (src->call_flags & CALL_INDEX) {
|
if (src->call_flags & CALL_INDEX) {
|
||||||
dst->index = (Ast_Expr *)ast_copy(src->index, parent_scope);
|
dst->index = (Ast_Expr *)ast_copy(src->index, parent_scope);
|
||||||
@@ -312,7 +306,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_CALL: {
|
case AST_CALL: {
|
||||||
Ast_Call *src = (Ast_Call *)ast;
|
Ast_Call *src = (Ast_Call *)ast;
|
||||||
Ast_Call *dst = ast_create_copy(parent_scope, Ast_Call, ast);
|
Ast_Call *dst = ast_create_copy(parent_scope, Ast_Call, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->name = (Ast_Expr *)ast_copy(src->name, parent_scope);
|
dst->name = (Ast_Expr *)ast_copy(src->name, parent_scope);
|
||||||
|
|
||||||
dst->exprs.init(pctx->perm, src->exprs.len);
|
dst->exprs.init(pctx->perm, src->exprs.len);
|
||||||
@@ -331,7 +324,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_CONSTANT_ASSERT: {
|
case AST_CONSTANT_ASSERT: {
|
||||||
Ast_Builtin *src = (Ast_Builtin *)ast;
|
Ast_Builtin *src = (Ast_Builtin *)ast;
|
||||||
Ast_Builtin *dst = ast_create_copy(parent_scope, Ast_Builtin, ast);
|
Ast_Builtin *dst = ast_create_copy(parent_scope, Ast_Builtin, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
||||||
return dst;
|
return dst;
|
||||||
} break;
|
} break;
|
||||||
@@ -339,7 +331,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_SWITCH: {
|
case AST_SWITCH: {
|
||||||
Ast_Switch *src = (Ast_Switch *)ast;
|
Ast_Switch *src = (Ast_Switch *)ast;
|
||||||
Ast_Switch *dst = ast_create_copy(parent_scope, Ast_Switch, ast);
|
Ast_Switch *dst = ast_create_copy(parent_scope, Ast_Switch, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->value = (Ast_Expr *)ast_copy(src->value, parent_scope);
|
dst->value = (Ast_Expr *)ast_copy(src->value, parent_scope);
|
||||||
dst->default_scope = (Ast_Scope *)ast_copy(src->default_scope, parent_scope);
|
dst->default_scope = (Ast_Scope *)ast_copy(src->default_scope, parent_scope);
|
||||||
|
|
||||||
@@ -355,7 +346,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_SWITCH_CASE: {
|
case AST_SWITCH_CASE: {
|
||||||
Ast_Switch_Case *src = (Ast_Switch_Case *)ast;
|
Ast_Switch_Case *src = (Ast_Switch_Case *)ast;
|
||||||
Ast_Switch_Case *dst = ast_create_copy(parent_scope, Ast_Switch_Case, ast);
|
Ast_Switch_Case *dst = ast_create_copy(parent_scope, Ast_Switch_Case, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
|
|
||||||
dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope);
|
dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope);
|
||||||
dst->labels.init(pctx->perm, src->labels.len);
|
dst->labels.init(pctx->perm, src->labels.len);
|
||||||
@@ -369,7 +359,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_VAR_UNPACK: {
|
case AST_VAR_UNPACK: {
|
||||||
Ast_Var_Unpack *src = (Ast_Var_Unpack *)ast;
|
Ast_Var_Unpack *src = (Ast_Var_Unpack *)ast;
|
||||||
Ast_Var_Unpack *dst = ast_create_copy(parent_scope, Ast_Var_Unpack, ast);
|
Ast_Var_Unpack *dst = ast_create_copy(parent_scope, Ast_Var_Unpack, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
|
|
||||||
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
||||||
dst->vars.init(pctx->perm, src->vars.len);
|
dst->vars.init(pctx->perm, src->vars.len);
|
||||||
@@ -384,7 +373,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_BREAK: {
|
case AST_BREAK: {
|
||||||
Ast *src = (Ast *)ast;
|
Ast *src = (Ast *)ast;
|
||||||
Ast *dst = ast_create_copy(parent_scope, Ast, ast);
|
Ast *dst = ast_create_copy(parent_scope, Ast, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
return dst;
|
return dst;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -398,7 +386,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_VAR: {
|
case AST_VAR: {
|
||||||
Ast_Decl *src = (Ast_Decl *)ast;
|
Ast_Decl *src = (Ast_Decl *)ast;
|
||||||
Ast_Decl *dst = ast_create_copy(parent_scope, Ast_Decl, ast);
|
Ast_Decl *dst = ast_create_copy(parent_scope, Ast_Decl, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
// dst->overload_op_info = ast_create_copy(parent_scope, Ast_Operator_Info, src->overload_op_info);
|
// dst->overload_op_info = ast_create_copy(parent_scope, Ast_Operator_Info, src->overload_op_info);
|
||||||
// omitting polymorphs
|
// omitting polymorphs
|
||||||
// omitting polymorph parameters
|
// omitting polymorph parameters
|
||||||
@@ -411,7 +398,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_ARRAY: {
|
case AST_ARRAY: {
|
||||||
Ast_Array *src = (Ast_Array *)ast;
|
Ast_Array *src = (Ast_Array *)ast;
|
||||||
Ast_Array *dst = ast_create_copy(parent_scope, Ast_Array, ast);
|
Ast_Array *dst = ast_create_copy(parent_scope, Ast_Array, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
||||||
return dst;
|
return dst;
|
||||||
} break;
|
} break;
|
||||||
@@ -419,7 +405,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_FOR: {
|
case AST_FOR: {
|
||||||
Ast_For *src = (Ast_For *)ast;
|
Ast_For *src = (Ast_For *)ast;
|
||||||
Ast_For *dst = ast_create_copy(parent_scope, Ast_For, ast);
|
Ast_For *dst = ast_create_copy(parent_scope, Ast_For, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope);
|
dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope);
|
||||||
dst->init = (Ast_Expr *)ast_copy(src->init, parent_scope);
|
dst->init = (Ast_Expr *)ast_copy(src->init, parent_scope);
|
||||||
dst->cond = (Ast_Expr *)ast_copy(src->cond, parent_scope);
|
dst->cond = (Ast_Expr *)ast_copy(src->cond, parent_scope);
|
||||||
@@ -430,7 +415,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_IF: {
|
case AST_IF: {
|
||||||
Ast_If *src = (Ast_If *)ast;
|
Ast_If *src = (Ast_If *)ast;
|
||||||
Ast_If *dst = ast_create_copy(parent_scope, Ast_If, ast);
|
Ast_If *dst = ast_create_copy(parent_scope, Ast_If, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->ifs.init(pctx->perm, src->ifs.len);
|
dst->ifs.init(pctx->perm, src->ifs.len);
|
||||||
For(src->ifs) {
|
For(src->ifs) {
|
||||||
auto copy = (Ast_If_Node *)ast_copy(it, parent_scope);
|
auto copy = (Ast_If_Node *)ast_copy(it, parent_scope);
|
||||||
@@ -443,7 +427,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_IF_NODE: {
|
case AST_IF_NODE: {
|
||||||
Ast_If_Node *src = (Ast_If_Node *)ast;
|
Ast_If_Node *src = (Ast_If_Node *)ast;
|
||||||
Ast_If_Node *dst = ast_create_copy(parent_scope, Ast_If_Node, ast);
|
Ast_If_Node *dst = ast_create_copy(parent_scope, Ast_If_Node, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
dst->expr = (Ast_Expr *)ast_copy(src->expr, parent_scope);
|
||||||
dst->init = (Ast_Binary *)ast_copy(src->init, parent_scope);
|
dst->init = (Ast_Binary *)ast_copy(src->init, parent_scope);
|
||||||
dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope);
|
dst->scope = (Ast_Scope *)ast_copy(src->scope, parent_scope);
|
||||||
@@ -465,7 +448,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) {
|
|||||||
case AST_LAMBDA_EXPR: {
|
case AST_LAMBDA_EXPR: {
|
||||||
Ast_Lambda *src = (Ast_Lambda *)ast;
|
Ast_Lambda *src = (Ast_Lambda *)ast;
|
||||||
Ast_Lambda *dst = ast_create_copy(parent_scope, Ast_Lambda, ast);
|
Ast_Lambda *dst = ast_create_copy(parent_scope, Ast_Lambda, ast);
|
||||||
dst->parent_scope = parent_scope;
|
|
||||||
|
|
||||||
dst->args.init(pctx->perm, src->args.len);
|
dst->args.init(pctx->perm, src->args.len);
|
||||||
For(src->args) {
|
For(src->args) {
|
||||||
|
|||||||
360
core_printer.cpp
360
core_printer.cpp
@@ -0,0 +1,360 @@
|
|||||||
|
|
||||||
|
// @todo @cleanup ??
|
||||||
|
// :PrinterCleanup
|
||||||
|
// Instead of relying on global state, this probably should
|
||||||
|
// use a String_Builder or some kind of Builder context + macros
|
||||||
|
|
||||||
|
CORE_Static String
|
||||||
|
core_type_to_string(Ast_Type *type) {
|
||||||
|
switch (type->kind) {
|
||||||
|
case TYPE_NONE: return "<NONE>"_s; break;
|
||||||
|
case TYPE_S64: return "S64"_s; break;
|
||||||
|
case TYPE_S32: return "S32"_s; break;
|
||||||
|
case TYPE_S16: return "S16"_s; break;
|
||||||
|
case TYPE_S8: return "S8"_s; break;
|
||||||
|
case TYPE_INT: return "int"_s; break;
|
||||||
|
case TYPE_CHAR: return "char"_s; break;
|
||||||
|
case TYPE_U64: return "U64"_s; break;
|
||||||
|
case TYPE_U32: return "U32"_s; break;
|
||||||
|
case TYPE_U16: return "U16"_s; break;
|
||||||
|
case TYPE_U8: return "U8"_s; break;
|
||||||
|
case TYPE_F32: return "F32"_s; break;
|
||||||
|
case TYPE_F64: return "F64"_s; break;
|
||||||
|
case TYPE_BOOL: return "Bool"_s; break;
|
||||||
|
case TYPE_STRING: return "String"_s; break;
|
||||||
|
case TYPE_VOID: return "void"_s; break;
|
||||||
|
case TYPE_POINTER: {
|
||||||
|
String base = core_type_to_string(type->base);
|
||||||
|
return pctx->fmt("*%Q", base);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_LAMBDA: {
|
||||||
|
String_Builder *b = &pctx->helper_builder;
|
||||||
|
b->addf("(");
|
||||||
|
Array<Ast_Type *> &args = type->func.args;
|
||||||
|
For(args) {
|
||||||
|
String t = core_type_to_string(it);
|
||||||
|
b->addf("%Q", t);
|
||||||
|
if (!args.is_last(&it)) b->addf(", ");
|
||||||
|
}
|
||||||
|
b->addf(")");
|
||||||
|
if (type->func.ret) {
|
||||||
|
String t = core_type_to_string(type->func.ret);
|
||||||
|
b->addf("%Q", t);
|
||||||
|
}
|
||||||
|
String result = string_flatten(pctx->perm, b);
|
||||||
|
return result;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
case TYPE_UNION:
|
||||||
|
case TYPE_ENUM: {
|
||||||
|
// @fixme: we probably want a string on Ast_Type
|
||||||
|
// so that we don't have to reach into Ast_Decl
|
||||||
|
// for Structs Enums etc.
|
||||||
|
Ast_Decl *decl = (Ast_Decl *)type->ast;
|
||||||
|
return decl->name.s;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_ARRAY: {
|
||||||
|
String base = core_type_to_string(type->base);
|
||||||
|
return pctx->fmt("[%u]%Q", type->arr.size, base);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_SLICE: {
|
||||||
|
String base = core_type_to_string(type->base);
|
||||||
|
return pctx->fmt("[]%Q", base);
|
||||||
|
} break;
|
||||||
|
case TYPE_TUPLE: {
|
||||||
|
invalid_codepath;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_TYPE: return "Type"_s; break;
|
||||||
|
case TYPE_UNTYPED_BOOL: return "UntypedBool"_s; break;
|
||||||
|
case TYPE_UNTYPED_INT: return "UntypedInt"_s; break;
|
||||||
|
case TYPE_UNTYPED_FLOAT: return "UntypedFloat"_s; break;
|
||||||
|
case TYPE_UNTYPED_STRING: return "UntypedString"_s; break;
|
||||||
|
|
||||||
|
case TYPE_COMPLETING: invalid_codepath; break;
|
||||||
|
case TYPE_INCOMPLETE: invalid_codepath; break;
|
||||||
|
case TYPE_POLYMORPH:
|
||||||
|
invalid_codepath;
|
||||||
|
break;
|
||||||
|
|
||||||
|
invalid_default_case;
|
||||||
|
}
|
||||||
|
invalid_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void core__stringify(Ast *ast) {
|
||||||
|
if (!ast) return;
|
||||||
|
switch (ast->kind) {
|
||||||
|
case AST_SCOPE: {
|
||||||
|
Ast_Scope *n = (Ast_Scope *)ast;
|
||||||
|
|
||||||
|
global_indent += 1;
|
||||||
|
For(n->decls) {
|
||||||
|
genln("");
|
||||||
|
core__stringify(it);
|
||||||
|
}
|
||||||
|
For(n->stmts) {
|
||||||
|
genln("");
|
||||||
|
core__stringify(it);
|
||||||
|
}
|
||||||
|
global_indent -= 1;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_MODULE: invalid_codepath; break;
|
||||||
|
case AST_FILE: invalid_codepath; break;
|
||||||
|
|
||||||
|
case AST_IDENT: {
|
||||||
|
Ast_Atom *n = (Ast_Atom *)ast;
|
||||||
|
gen("%Q", n->intern_val);
|
||||||
|
} break;
|
||||||
|
case AST_VALUE: {
|
||||||
|
Ast_Atom *n = (Ast_Atom *)ast;
|
||||||
|
gen("@%Q", n->pos->string);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_INDEX: {
|
||||||
|
Ast_Index *n = (Ast_Index *)ast;
|
||||||
|
core__stringify(n->expr);
|
||||||
|
gen("[");
|
||||||
|
core__stringify(n->index);
|
||||||
|
gen("]");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_UNARY: {
|
||||||
|
Ast_Unary *n = (Ast_Unary *)ast;
|
||||||
|
gen("%Q", n->pos->string);
|
||||||
|
core__stringify(n->expr);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_BINARY: {
|
||||||
|
Ast_Binary *n = (Ast_Binary *)ast;
|
||||||
|
core__stringify(n->left);
|
||||||
|
gen("%Q", n->pos->string);
|
||||||
|
core__stringify(n->right);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_CALL_ITEM: {
|
||||||
|
Ast_Call_Item *n = (Ast_Call_Item *)ast;
|
||||||
|
if (n->call_flags & CALL_INDEX) {
|
||||||
|
core__stringify(n->index);
|
||||||
|
gen(" = ");
|
||||||
|
}
|
||||||
|
else if (n->call_flags & CALL_NAME) {
|
||||||
|
core__stringify(n->name);
|
||||||
|
gen(" = ");
|
||||||
|
}
|
||||||
|
core__stringify(n->item);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_CALL: {
|
||||||
|
Ast_Call *n = (Ast_Call *)ast;
|
||||||
|
core__stringify(n->name);
|
||||||
|
gen("(");
|
||||||
|
For(n->exprs) {
|
||||||
|
core__stringify(it);
|
||||||
|
if (!n->exprs.is_last(&it)) gen(",");
|
||||||
|
}
|
||||||
|
gen(")");
|
||||||
|
} break;
|
||||||
|
case AST_COMPOUND: {
|
||||||
|
Ast_Call *n = (Ast_Call *)ast;
|
||||||
|
core__stringify(n->name);
|
||||||
|
|
||||||
|
gen("{");
|
||||||
|
global_indent += 1;
|
||||||
|
For(n->exprs) {
|
||||||
|
genln("");
|
||||||
|
core__stringify(it);
|
||||||
|
gen(",");
|
||||||
|
}
|
||||||
|
global_indent -= 1;
|
||||||
|
genln("}");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_TYPE_OF:
|
||||||
|
gen("TypeOf");
|
||||||
|
goto builtin;
|
||||||
|
case AST_LENGTH_OF:
|
||||||
|
gen("LengthOf");
|
||||||
|
goto builtin;
|
||||||
|
case AST_ALIGN_OF:
|
||||||
|
gen("AlignOf");
|
||||||
|
goto builtin;
|
||||||
|
case AST_SIZE_OF:
|
||||||
|
gen("SizeOf");
|
||||||
|
goto builtin;
|
||||||
|
case AST_RUNTIME_ASSERT:
|
||||||
|
gen("Assert");
|
||||||
|
goto builtin;
|
||||||
|
case AST_CONSTANT_ASSERT:
|
||||||
|
gen("#Assert");
|
||||||
|
goto builtin;
|
||||||
|
builtin : {
|
||||||
|
Ast_Builtin *n = (Ast_Builtin *)ast;
|
||||||
|
|
||||||
|
gen("(");
|
||||||
|
core__stringify(n->expr);
|
||||||
|
gen(")");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_SWITCH: {
|
||||||
|
Ast_Switch *n = (Ast_Switch *)ast;
|
||||||
|
|
||||||
|
core__stringify(n->value);
|
||||||
|
For(n->cases) {
|
||||||
|
core__stringify(it);
|
||||||
|
}
|
||||||
|
core__stringify(n->default_scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_SWITCH_CASE: {
|
||||||
|
Ast_Switch_Case *n = (Ast_Switch_Case *)ast;
|
||||||
|
|
||||||
|
For(n->labels) {
|
||||||
|
core__stringify(it);
|
||||||
|
}
|
||||||
|
core__stringify(n->scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_VAR_UNPACK: {
|
||||||
|
Ast_Var_Unpack *n = (Ast_Var_Unpack *)ast;
|
||||||
|
For(n->vars) {
|
||||||
|
core__stringify(it);
|
||||||
|
if (!n->vars.is_last(&it)) gen(",");
|
||||||
|
}
|
||||||
|
gen(" = ");
|
||||||
|
core__stringify(n->expr);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_PASS: {
|
||||||
|
genln("pass");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_BREAK: {
|
||||||
|
genln("break");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_NAMESPACE: {
|
||||||
|
Ast_Decl *n = (Ast_Decl *)ast;
|
||||||
|
gen("%Q :: NAMESPACE", n->name);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_UNION:
|
||||||
|
case AST_STRUCT: {
|
||||||
|
Ast_Decl *n = (Ast_Decl *)ast;
|
||||||
|
genln("%Q :: %s", n->name, n->kind == AST_STRUCT ? "struct" : "union");
|
||||||
|
core__stringify(n->scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_ENUM: {
|
||||||
|
Ast_Decl *n = (Ast_Decl *)ast;
|
||||||
|
genln("%Q :: enum", n->name);
|
||||||
|
core__stringify(n->scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_LAMBDA: {
|
||||||
|
Ast_Decl *n = (Ast_Decl *)ast;
|
||||||
|
genln("%Q :: ", n->name);
|
||||||
|
core__stringify(n->lambda); // @cleanup
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// @cleanup: what is this used for?
|
||||||
|
case AST_TYPE: {
|
||||||
|
invalid_codepath;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_CONST: {
|
||||||
|
Ast_Decl *n = (Ast_Decl *)ast;
|
||||||
|
gen("%Q :: CONST value @todo", n->name);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_VAR: {
|
||||||
|
Ast_Decl *n = (Ast_Decl *)ast;
|
||||||
|
gen("%Q: %Q", n->name, core_type_to_string(n->type));
|
||||||
|
if (n->expr) {
|
||||||
|
gen(" = ");
|
||||||
|
core__stringify(n->expr);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_ARRAY: {
|
||||||
|
Ast_Array *n = (Ast_Array *)ast;
|
||||||
|
|
||||||
|
gen("[");
|
||||||
|
core__stringify(n->expr);
|
||||||
|
gen("]");
|
||||||
|
core__stringify(n->base);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_FOR: {
|
||||||
|
Ast_For *n = (Ast_For *)ast;
|
||||||
|
gen("for ");
|
||||||
|
core__stringify(n->init);
|
||||||
|
if (n->cond) gen(", ");
|
||||||
|
core__stringify(n->cond);
|
||||||
|
if (n->iter) gen(", ");
|
||||||
|
core__stringify(n->iter);
|
||||||
|
core__stringify(n->scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_IF: {
|
||||||
|
Ast_If *n = (Ast_If *)ast;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
For(n->ifs) {
|
||||||
|
if (i == 0) gen("if ");
|
||||||
|
else if (it->expr) gen("elif ");
|
||||||
|
else gen("else ");
|
||||||
|
|
||||||
|
core__stringify(it->expr);
|
||||||
|
if (it->init) gen(", ");
|
||||||
|
core__stringify(it->init);
|
||||||
|
core__stringify(it->scope);
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_RETURN: {
|
||||||
|
Ast_Return *n = (Ast_Return *)ast;
|
||||||
|
gen("return ");
|
||||||
|
For(n->expr) {
|
||||||
|
core__stringify(it);
|
||||||
|
if (!n->expr.is_last(&it)) gen(", ");
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AST_LAMBDA_EXPR: {
|
||||||
|
Ast_Lambda *n = (Ast_Lambda *)ast;
|
||||||
|
|
||||||
|
gen("(");
|
||||||
|
For(n->args) {
|
||||||
|
core__stringify(it);
|
||||||
|
if (!n->args.is_last(&it)) gen(", ");
|
||||||
|
}
|
||||||
|
gen(")");
|
||||||
|
|
||||||
|
if (n->ret.len) gen(": ");
|
||||||
|
For(n->ret) {
|
||||||
|
core__stringify(it);
|
||||||
|
if (!n->ret.is_last(&it)) gen(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
core__stringify(n->scope);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: assert(!"Invalid default case");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String core_stringify(Ast *ast) {
|
||||||
|
core__stringify(ast);
|
||||||
|
String result = string_flatten(pctx->perm, &pctx->gen);
|
||||||
|
pctx->gen.reset();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user