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.
This commit is contained in:
96
ref/harec/include/scope.h
Normal file
96
ref/harec/include/scope.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef HAREC_SCOPE_H
|
||||
#define HAREC_SCOPE_H
|
||||
#include "expr.h"
|
||||
#include "identifier.h"
|
||||
|
||||
#define SCOPE_BUCKETS 4096
|
||||
|
||||
enum object_type {
|
||||
O_BIND,
|
||||
O_CONST,
|
||||
O_DECL,
|
||||
O_SCAN,
|
||||
O_TYPE,
|
||||
};
|
||||
|
||||
enum scope_object_flags {
|
||||
SO_THREADLOCAL = 1 << 0,
|
||||
SO_FOR_EACH_SUBJECT = 1 << 1,
|
||||
};
|
||||
|
||||
struct scope_object {
|
||||
enum object_type otype;
|
||||
// name is the name of the object within this scope (for lookups)
|
||||
// ident is the global identifier (these may be different in some cases)
|
||||
struct ident *name;
|
||||
struct ident *ident;
|
||||
enum scope_object_flags flags;
|
||||
|
||||
union {
|
||||
const struct type *type;
|
||||
struct expression *value; // For O_CONST
|
||||
};
|
||||
// Cannot be in union because type and idecl are needed at the same time
|
||||
struct incomplete_decl *idecl;
|
||||
|
||||
struct scope_object *lnext; // Linked list
|
||||
struct scope_object *mnext; // Hash map
|
||||
};
|
||||
|
||||
enum scope_class {
|
||||
SCOPE_COMPOUND,
|
||||
SCOPE_DEFER,
|
||||
SCOPE_ENUM,
|
||||
SCOPE_FUNC,
|
||||
SCOPE_LOOP,
|
||||
SCOPE_MATCH,
|
||||
SCOPE_SUBUNIT,
|
||||
SCOPE_UNIT,
|
||||
SCOPE_DEFINES,
|
||||
};
|
||||
|
||||
struct yield { // and break
|
||||
struct expression **expression;
|
||||
struct yield *next;
|
||||
};
|
||||
|
||||
struct scope {
|
||||
enum scope_class class;
|
||||
const char *label;
|
||||
struct scope *parent;
|
||||
|
||||
const struct type *hint;
|
||||
struct type_tagged_union results;
|
||||
struct yield *yields;
|
||||
|
||||
// Linked list in insertion order
|
||||
// Used for function parameters and enum values, where order matters
|
||||
struct scope_object *objects;
|
||||
struct scope_object **next;
|
||||
|
||||
// Hash map in reverse insertion order
|
||||
// Used for lookups, and accounts for shadowing
|
||||
struct scope_object *buckets[SCOPE_BUCKETS];
|
||||
};
|
||||
|
||||
struct scopes {
|
||||
struct scope *scope;
|
||||
struct scopes *next;
|
||||
};
|
||||
|
||||
struct scope *scope_push(struct scope **stack, enum scope_class class);
|
||||
struct scope *scope_pop(struct scope **stack);
|
||||
|
||||
struct scope *scope_lookup_class(struct scope *scope, enum scope_class class);
|
||||
struct scope *scope_lookup_label(struct scope *scope, const char *label);
|
||||
|
||||
void scope_free(struct scope *scope);
|
||||
void scope_free_all(struct scopes *scopes);
|
||||
|
||||
struct scope_object *scope_insert(struct scope *scope,
|
||||
enum object_type otype, struct ident *ident, struct ident *name,
|
||||
const struct type *type, struct expression *value);
|
||||
|
||||
struct scope_object *scope_lookup(struct scope *scope, struct ident *ident);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user