// Copyright (c) 2020 Christoffer Lerno. All rights reserved. // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. #include "compiler_internal.h" #define OUTPUT(x, ...) fprintf(file, x, ## __VA_ARGS__) #define INDENT() indent_line(file, indent) static void indent_line(FILE *file, int indent) { for (int i = 0; i < indent * 3; i++) { fputc(' ', file); } } static void header_gen_decl(FILE *file, int indent, Decl *decl); static void header_gen_method(FILE *file, Context *c, Decl *decl) { fprintf(file, "/* method */\n"); } static void header_gen_function(FILE *file, Context *c, Decl *decl) { fprintf(file, "/* function */\n"); } static void header_print_type(FILE *file, Type *type) { switch (type->type_kind) { case TYPE_POISONED: UNREACHABLE case TYPE_VOID: OUTPUT("void"); return; case TYPE_BOOL: OUTPUT("bool"); return; case TYPE_I8: OUTPUT("int8_t"); return; case TYPE_I16: OUTPUT("int16_t"); return; case TYPE_I32: OUTPUT("int32_t"); return; case TYPE_I64: case TYPE_IXX: OUTPUT("int64_t"); return; case TYPE_I128: TODO case TYPE_U8: OUTPUT("uint8_t"); return; case TYPE_U16: OUTPUT("uint16_t"); return; case TYPE_U32: OUTPUT("uint32_t"); return; case TYPE_U64: OUTPUT("uint64_t"); return; case TYPE_U128: TODO case TYPE_F16: TODO case TYPE_F32: OUTPUT("float"); return; case TYPE_F64: case TYPE_FXX: OUTPUT("double"); return; case TYPE_F128: TODO case TYPE_TYPEID: OUTPUT("c3typeid_t"); return; case TYPE_POINTER: header_print_type(file, type->pointer); OUTPUT("*"); return; case TYPE_ENUM: OUTPUT("enum %s__", type->decl->external_name); return; case TYPE_FUNC: TODO case TYPE_STRUCT: OUTPUT("struct %s__", type->decl->external_name); return; case TYPE_UNION: OUTPUT("union %s__", type->decl->external_name); return; case TYPE_DISTINCT: header_print_type(file, type->decl->distinct_decl.base_type); return; case TYPE_ERRTYPE: break; case TYPE_ERR_UNION: break; case TYPE_TYPEDEF: break; case TYPE_STRLIT: case TYPE_INFERRED_ARRAY: UNREACHABLE case TYPE_ARRAY: break; case TYPE_VARARRAY: break; case TYPE_SUBARRAY: break; case TYPE_TYPEINFO: break; case TYPE_MEMBER: break; case TYPE_VECTOR: break; case TYPE_COMPLEX: break; } TODO } static void header_gen_members(FILE *file, int indent, Decl **members) { VECEACH(members, i) { Decl *member = members[i]; if (member->decl_kind == DECL_VAR) { INDENT(); header_print_type(file, member->type); OUTPUT(" %s;\n", member->name); } else { TODO } } } static void header_gen_struct(FILE *file, int indent, Decl *decl) { if (!indent) { OUTPUT("typedef struct %s__ %s;\n", decl->external_name, decl->external_name); } INDENT(); if (decl->name) { OUTPUT("struct %s__\n{\n", decl->external_name); } else { OUTPUT("struct\n{\n"); } header_gen_members(file, indent + 1, decl->strukt.members); INDENT(); OUTPUT("};\n"); } static void header_gen_union(FILE *file, int indent, Decl *decl) { OUTPUT("typedef union %s__ %s;\n", decl->external_name, decl->external_name); OUTPUT("union %s__\n{\n", decl->external_name); header_gen_members(file, indent, decl->strukt.members); OUTPUT("};\n"); } static void header_gen_enum(FILE *file, int indent, Decl *decl) { TODO } static void header_gen_err(FILE *file, int indent, Decl *decl) { OUTPUT("typedef struct %s_error__ %s_error;\n", decl->external_name, decl->external_name); OUTPUT("struct %s_error__\n{\n", decl->external_name); header_gen_members(file, indent, decl->strukt.members); OUTPUT("};\n"); } static void header_gen_decl(FILE *file, int indent, Decl *decl) { switch (decl->decl_kind) { case DECL_POISONED: case DECL_VAR: case DECL_LABEL: case DECL_ENUM_CONSTANT: case DECL_ARRAY_VALUE: case DECL_IMPORT: case DECL_MACRO: case DECL_GENERIC: case DECL_CT_IF: case DECL_CT_ELSE: case DECL_CT_ELIF: case DECL_CT_SWITCH: case DECL_CT_CASE: case DECL_ATTRIBUTE: case DECL_DEFINE: UNREACHABLE case DECL_FUNC: TODO case DECL_TYPEDEF: case DECL_DISTINCT: TODO case DECL_STRUCT: header_gen_struct(file, indent, decl); return; case DECL_UNION: header_gen_union(file, indent, decl); return; case DECL_ENUM: header_gen_enum(file, indent, decl); return; case DECL_ERR: header_gen_err(file, indent, decl); return; } UNREACHABLE } static void header_gen_var(FILE *file, Context *c, Decl *decl) { fprintf(file, "/* vars */\n"); } void header_gen(Context *context) { const char *filename = strcat_arena(context->file->name, ".h"); FILE *file = fopen(filename, "w"); OUTPUT("#include \n"); OUTPUT("#ifndef __c3__\n"); OUTPUT("#define __c3__\n"); OUTPUT("typedef "); header_print_type(file, type_lowering(type_typeid)); OUTPUT(" c3typeid_t;\n"); OUTPUT("#endif\n"); VECEACH(context->types, i) { header_gen_decl(file, 0, context->types[i]); } VECEACH(context->vars, i) { header_gen_var(file, context, context->vars[i]); } VECEACH(context->methods, i) { header_gen_method(file, context, context->methods[i]); } VECEACH(context->functions, i) { header_gen_function(file, context, context->functions[i]); } fclose(file); }