mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
262 lines
5.2 KiB
C
262 lines
5.2 KiB
C
// 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:
|
|
TODO
|
|
case TYPE_ERRTYPE:
|
|
break;
|
|
case TYPE_ERR_UNION:
|
|
break;
|
|
case TYPE_TYPEDEF:
|
|
break;
|
|
case TYPE_STRING:
|
|
break;
|
|
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 <stdint.h>\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);
|
|
}
|