diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index 248cfd1..b84a870 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -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 genln(...) \ 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 ""_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 &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 compile_to_c_code() { 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 int di = 0; For(pctx->ordered_decls) { diff --git a/core_compiler_includes.cpp b/core_compiler_includes.cpp index 79986d1..69b0c4a 100644 --- a/core_compiler_includes.cpp +++ b/core_compiler_includes.cpp @@ -30,4 +30,5 @@ #include "core_polymorph.cpp" #include "core_typechecking.cpp" #include "core_compiler.cpp" -#include "core_codegen_c_language.cpp" \ No newline at end of file +#include "core_codegen_c_language.cpp" +#include "core_printer.cpp" \ No newline at end of file diff --git a/core_polymorph.cpp b/core_polymorph.cpp index 89ac67b..2aec667 100644 --- a/core_polymorph.cpp +++ b/core_polymorph.cpp @@ -263,15 +263,12 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_VALUE: { Ast_Atom *src = (Ast_Atom *)ast; Ast_Atom *dst = ast_create_copy(parent_scope, Ast_Atom, ast); - - dst->parent_scope = parent_scope; return dst; } break; case AST_INDEX: { Ast_Index *src = (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->index = (Ast_Expr *)ast_copy(src->index, parent_scope); return dst; @@ -280,7 +277,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_UNARY: { Ast_Unary *src = (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); return dst; } break; @@ -288,7 +284,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_BINARY: { Ast_Binary *src = (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->right = (Ast_Expr *)ast_copy(src->right, parent_scope); return dst; @@ -297,7 +292,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_CALL_ITEM: { Ast_Call_Item *src = (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); if (src->call_flags & CALL_INDEX) { 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: { Ast_Call *src = (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->exprs.init(pctx->perm, src->exprs.len); @@ -331,7 +324,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_CONSTANT_ASSERT: { Ast_Builtin *src = (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); return dst; } break; @@ -339,7 +331,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_SWITCH: { Ast_Switch *src = (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->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: { Ast_Switch_Case *src = (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->labels.init(pctx->perm, src->labels.len); @@ -369,7 +359,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_VAR_UNPACK: { Ast_Var_Unpack *src = (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->vars.init(pctx->perm, src->vars.len); @@ -384,7 +373,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_BREAK: { Ast *src = (Ast *)ast; Ast *dst = ast_create_copy(parent_scope, Ast, ast); - dst->parent_scope = parent_scope; return dst; } break; @@ -398,7 +386,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_VAR: { Ast_Decl *src = (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); // omitting polymorphs // omitting polymorph parameters @@ -411,7 +398,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_ARRAY: { Ast_Array *src = (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); return dst; } break; @@ -419,7 +405,6 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope) { case AST_FOR: { Ast_For *src = (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->init = (Ast_Expr *)ast_copy(src->init, 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: { Ast_If *src = (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); For(src->ifs) { 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: { Ast_If_Node *src = (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->init = (Ast_Binary *)ast_copy(src->init, 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: { Ast_Lambda *src = (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); For(src->args) { diff --git a/core_printer.cpp b/core_printer.cpp index e69de29..81babd8 100644 --- a/core_printer.cpp +++ b/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 ""_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 &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; +} \ No newline at end of file