/* * Outputs C declarations for types and functions. * * Copyright © 2020-2025 Samuel Lidén Borell * * SPDX-License-Identifier: EUPL-1.2+ */ #include #include "compiler.h" #include "out.h" static void emit_func_ident(struct Func *func) { struct Type *class_ = func->class_; if (class_) { if (class_->outer) { assert(class_->outer->outer == NULL); emit_ident(&class_->outer->ident); outc('_'); } emit_ident(&class_->ident); outc('_'); } emit_ident(&func->ident); } /** Emits a list of field or variable declarations */ static void emit_datadef_list(struct Var *var_list) { struct Var *var; for (var = var_list; var; var = var->next) { indent(); emit_typeref_prefix(var->typeref); emit_ident(&var->ident); emit_typeref_suffix(var->typeref); outf(";\n"); } } static void emit_param_list(struct Var *var_list) { struct Var *var; for (var = var_list; var; var = var->next) { emit_typeref_prefix(var->typeref); emit_ident(&var->ident); emit_typeref_suffix(var->typeref); if (var->next) { outf(", "); } } } static void emit_func_decl(struct Func *func, bool is_pre_decl) { if (func->num_returns >= 2) { /* XXX perhaps the return types should be named by their contents, and de-duplicated with #ifdefs? (note: for generic types, there are two cases for parameters: bound and unbound) */ if (is_pre_decl) { beginf("struct "); emit_func_ident(func); outf("__Return {\n"); emit_datadef_list(func->returns); endf("};\n"); } outf("struct "); emit_func_ident(func); outf("__Return "); emit_func_ident(func); } else if (func->num_returns == 1) { emit_typeref_prefix(func->returns[0].typeref); emit_func_ident(func); emit_typeref_suffix(func->returns[0].typeref); } else { assert(func->num_returns == 0); outf("void "); emit_func_ident(func); } outc('('); if (func->num_params == 0) { outf("void"); } else { emit_param_list(func->params); } outc(')'); } void predeclare_type(struct Type *type) { emit_type(type); outf(";\n"); } void define_type(struct Type *type) { outc('\n'); emit_type(type); outf(" {\n"); indentlevel++; /* TODO for each field emit_typeref_prefix(field->typeref); emit_ident(&field->ident); emit_typeref_suffix(field->typeref); */ endf("};\n"); } void predeclare_funcs(struct Func *funcs_list) { struct Func *func; for (func = funcs_list; func; func = func->next) { emit_func_decl(func, true); outf(";\n"); } } void define_funcs(struct Func *funcs_list) { struct Func *func; for (func = funcs_list; func; func = func->next) { outc('\n'); emit_func_decl(func, false); beginf("\n{\n"); emit_datadef_list(func->vardecls); /* TODO for multiple return values: define variable of __Return type */ emit_statements_inside(func->code); endf("}\n"); } }