Files
ww/ref/harec/include/check.h
Hojun-Cho 8e3752f5ea ref: vendor harec checker sources (#20)
ref/hare/ ships only ast/lex/parse/module/unparse — no checker. Every
bail-fix landing in A.6.2.1 (helper bail audit, N_IDENT bail audit,
enum fold) needs a `ref/harec/...` cite anchor so divergence rationale
isn't claimed against memory. PLAN.md L16, L35.

Snapshot of upstream commit ee640c6b2c17f57e8014d277a3028b262ffb7952
(`rt/+openbsd/start.ha: remove outdated comment about crt0`). 20 files:
5 src (check.c, eval.c, scope.c, types.c, type_store.c), 14 transitive
include/ headers (no parser/codegen surface), and COPYING.

License GPLv3 (COPYING included). Vendored as read-only reference per
CLAUDE.md rule 6 — no redistribution as binary, no edits.
2026-05-21 23:03:11 +09:00

170 lines
3.7 KiB
C

#ifndef HARE_CHECK_H
#define HARE_CHECK_H
#include <stdbool.h>
#include <stdnoreturn.h>
#include "ast.h"
#include "identifier.h"
#include "scope.h"
#include "types.h"
#include "type_store.h"
#include "util.h"
struct expression;
#define MODCACHE_BUCKETS 256
struct modcache {
struct ident *ident;
struct scope *scope;
struct modcache *next;
};
struct errors {
struct location loc;
char *msg;
struct errors *next;
};
struct context {
type_store *store;
struct modcache **modcache;
const struct type *fntype;
struct ident *ns;
struct scope *unit;
struct scope *scope;
struct scope *defines;
const char *mainsym;
struct ident *mainident;
bool is_test;
int id;
struct errors *errors;
struct errors **next;
struct declarations *decls;
struct ast_types *unresolved;
struct intern_table *itbl;
};
struct constant_decl {
const struct type *type;
const struct expression *value;
};
struct function_decl {
const struct type *type;
struct expression *body;
struct scope *scope;
unsigned int flags; // enum func_decl_flags
};
struct global_decl {
const struct type *type;
struct expression *value; // EXPR_LITERAL
bool threadlocal;
};
enum decl_type {
DECL_FUNC,
DECL_TYPE,
DECL_GLOBAL,
DECL_CONST,
};
struct declaration {
enum decl_type decl_type;
int file;
struct ident *ident;
const char *symbol;
bool exported; // XXX: this bool takes up 8 bytes and i am in pain
union {
struct constant_decl constant;
struct function_decl func;
struct global_decl global;
const struct type *type;
};
};
struct declarations {
struct declaration decl;
struct declarations *next;
};
struct unit {
struct ident *ns;
struct declarations *declarations;
struct identifiers *imports;
};
enum idecl_type {
IDECL_DECL,
IDECL_ENUM_FLD,
};
// Keeps track of enum specific context required for enum field resolution
struct incomplete_enum_field {
struct ast_enum_field *field;
struct scope *enum_scope;
};
// Keeps track of context required to resolve a declaration or an enum field
// Extends the scope_object struct so it can be inserted into a scope
struct incomplete_decl {
struct scope *imports; // the scope of this declaration's subunit
enum idecl_type type;
bool in_progress;
bool dealias_in_progress;
union {
struct ast_decl decl;
struct incomplete_enum_field *field;
};
};
struct ident *mkident(struct context *ctx, struct ident *ident,
const char *symbol);
void append_decl(struct context *ctx, struct declaration *decl);
void mkstrliteral(struct expression *expr, const char *fmt, ...) FORMAT(2, 3);
char *gen_typename(const struct type *type);
struct expression *lower_implicit_cast(struct context *ctx,
const struct type *to, struct expression *expr);
typedef void (*resolvefn)(struct context *, struct scope_object *obj);
void resolve_dimensions(struct context *ctx, struct scope_object *obj);
void resolve_type(struct context *ctx, struct scope_object *obj);
void wrap_resolver(struct context *ctx,
struct scope_object *obj, resolvefn resolver);
struct scope *check(type_store *ts,
bool is_test,
const char *mainsym,
struct ident *mainident,
const struct ast_decls *defines,
const struct ast_unit *aunit,
struct unit *unit,
struct intern_table *itbl);
struct scope *check_internal(type_store *ts,
struct modcache **cache,
bool is_test,
const char *mainsym,
struct ident *mainident,
const struct ast_decls *defines,
const struct ast_unit *aunit,
struct unit *unit,
struct intern_table *itbl,
bool scan_only);
void check_expression(struct context *ctx,
const struct ast_expression *aexpr,
struct expression *expr,
const struct type *hint);
void error(struct context *ctx, struct location loc,
struct expression *expr, const char *fmt, ...) FORMAT(4, 5);
#endif