From ba8e7628a2e0e48ac89a4bd734edde0c0dfc3929 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Thu, 26 Dec 2019 23:38:39 -0500 Subject: more export --- export.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 12 deletions(-) (limited to 'export.c') diff --git a/export.c b/export.c index 571701e..28e03e0 100644 --- a/export.c +++ b/export.c @@ -36,16 +36,70 @@ static void export_ident(Exporter *ex, Identifier i) { export_u64(ex, i->id); } -static bool export_decl(Exporter *ex, Declaration *d) { - if (!ex) { - err_print(d->where, "Trying to export declaration, but a package output was not specified."); +static inline bool type_contains_reference(Type *type) { + assert(type->flags & TYPE_IS_RESOLVED); + switch (type->kind) { + case TYPE_PTR: + case TYPE_SLICE: + case TYPE_FN: + return true; + case TYPE_TUPLE: + arr_foreach(type->tuple, Type, sub) + if (type_contains_reference(sub)) + return true; return false; - } - export_location(ex, d->where); - if (arr_len(d->idents) > 65535) { - err_print(d->where, "Too many identifiers in a declaration (the maximum is 65535)."); + case TYPE_STRUCT: + arr_foreach(type->struc->fields, Field, field) { + if (type_contains_reference(field->type)) + return true; + } + return false; + case TYPE_ARR: + return type_contains_reference(type->arr.of); + case TYPE_BUILTIN: + case TYPE_VOID: + case TYPE_UNKNOWN: + case TYPE_TYPE: return false; + case TYPE_EXPR: break; } + assert(0); + return false; +} + +static void export_type(Exporter *ex, Type *type) { +} + +static void export_val(Exporter *ex, Value val, Type *type) { + assert(!type_contains_reference(type)); + export_type(ex, type); + switch (type->kind) { + case TYPE_VOID: break; + case TYPE_TYPE: + export_type(ex, val.type); + break; + case TYPE_UNKNOWN: + case TYPE_EXPR: + assert(0); + break; + } +} + +static void export_expr(Exporter *ex, Expression *e) { +} + +enum { + DECL_EXPORT_NONE, + DECL_EXPORT_EXPR, + DECL_EXPORT_VAL +}; + +static void export_decl(Exporter *ex, Declaration *d) { + if (d->type.kind == TYPE_UNKNOWN) { + warn_print(d->where, "Can't export declaration of unknown type."); + return; + } + export_location(ex, d->where); export_u16(ex, (U16)arr_len(d->idents)); arr_foreach(d->idents, Identifier, ident) { export_ident(ex, *ident); @@ -57,10 +111,19 @@ static bool export_decl(Exporter *ex, Declaration *d) { export_u8(ex, constness); U8 expr_kind = 0; - if (d->flags & DECL_HAS_EXPR) expr_kind = 1; /* export expression */ - if (d->flags & DECL_FOUND_VAL) expr_kind = 2; /* export value */ - export_u8(ex, expr_kind); - + if (d->flags & DECL_HAS_EXPR) expr_kind = DECL_EXPORT_EXPR; + if (d->flags & DECL_FOUND_VAL) { + if (type_contains_reference(&d->type)) + expr_kind = DECL_EXPORT_EXPR; + else + expr_kind = DECL_EXPORT_VAL; + } - return true; + export_u8(ex, expr_kind); + + if (expr_kind == DECL_EXPORT_EXPR) { + export_expr(ex, &d->expr); + } else if (expr_kind == DECL_EXPORT_VAL) { + export_val(ex, d->val, &d->type); + } } -- cgit v1.2.3