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:
402
ref/harec/include/expr.h
Normal file
402
ref/harec/include/expr.h
Normal file
@@ -0,0 +1,402 @@
|
||||
#ifndef HAREC_EXPR_H
|
||||
#define HAREC_EXPR_H
|
||||
#include <stdint.h>
|
||||
#include "lex.h"
|
||||
#include "types.h"
|
||||
|
||||
struct scope;
|
||||
struct scope_object;
|
||||
|
||||
enum expr_type {
|
||||
EXPR_ACCESS,
|
||||
EXPR_ALLOC,
|
||||
EXPR_APPEND,
|
||||
EXPR_ASSERT,
|
||||
EXPR_ASSIGN,
|
||||
EXPR_BINARITHM,
|
||||
EXPR_BINDING,
|
||||
EXPR_BREAK,
|
||||
EXPR_CALL,
|
||||
EXPR_CAST,
|
||||
EXPR_COMPOUND,
|
||||
EXPR_CONTINUE,
|
||||
EXPR_DEFER,
|
||||
EXPR_DEFINE,
|
||||
EXPR_DELETE,
|
||||
EXPR_FOR,
|
||||
EXPR_FREE,
|
||||
EXPR_IF,
|
||||
EXPR_INSERT,
|
||||
EXPR_LEN,
|
||||
EXPR_MEASURE = EXPR_LEN, // for use in AST
|
||||
EXPR_LITERAL,
|
||||
EXPR_MATCH,
|
||||
EXPR_PROPAGATE,
|
||||
EXPR_RETURN,
|
||||
EXPR_SLICE,
|
||||
EXPR_STRUCT,
|
||||
EXPR_SWITCH,
|
||||
EXPR_TUPLE,
|
||||
EXPR_UNARITHM,
|
||||
EXPR_UNDEFINED,
|
||||
EXPR_VAARG,
|
||||
EXPR_VAEND,
|
||||
EXPR_VASTART,
|
||||
EXPR_YIELD,
|
||||
};
|
||||
|
||||
struct expressions {
|
||||
struct expression *expr;
|
||||
struct expressions *next;
|
||||
};
|
||||
|
||||
enum access_type {
|
||||
ACCESS_IDENTIFIER,
|
||||
ACCESS_INDEX,
|
||||
ACCESS_FIELD,
|
||||
ACCESS_TUPLE,
|
||||
};
|
||||
|
||||
struct expression_access {
|
||||
enum access_type type;
|
||||
union {
|
||||
struct scope_object *object;
|
||||
struct {
|
||||
struct expression *array;
|
||||
struct expression *index;
|
||||
bool bounds_checked;
|
||||
};
|
||||
struct {
|
||||
struct expression *_struct;
|
||||
const struct struct_field *field;
|
||||
};
|
||||
struct {
|
||||
struct expression *tuple;
|
||||
const struct type_tuple *tvalue;
|
||||
size_t tindex;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
enum alloc_kind {
|
||||
ALLOC_OBJECT, // alloc(42)
|
||||
ALLOC_CAP, // alloc([], 42)
|
||||
ALLOC_LEN, // alloc([0...], 42)
|
||||
ALLOC_COPY, // alloc(x...);
|
||||
};
|
||||
|
||||
struct expression_alloc {
|
||||
enum alloc_kind kind;
|
||||
const struct type *allocation_result;
|
||||
struct expression *init;
|
||||
struct expression *cap;
|
||||
};
|
||||
|
||||
struct expression_append {
|
||||
struct expression *object;
|
||||
struct expression *value;
|
||||
struct expression *length;
|
||||
bool is_static, is_multi;
|
||||
};
|
||||
|
||||
enum fixed_aborts {
|
||||
ABORT_OOB = 0,
|
||||
ABORT_TYPE_ASSERTION = 1,
|
||||
ABORT_UNREACHABLE = 2,
|
||||
ABORT_CAP_TOO_SMALL = 3,
|
||||
ABORT_ANON_ASSERTION_FAILED = 4,
|
||||
ABORT_PROPAGATE_ERROR_OCCURRED = 5,
|
||||
};
|
||||
|
||||
struct expression_assert {
|
||||
struct expression *cond;
|
||||
struct expression *message;
|
||||
enum fixed_aborts fixed_reason;
|
||||
};
|
||||
|
||||
enum binarithm_operator {
|
||||
BIN_BAND, // &
|
||||
BIN_BOR, // |
|
||||
BIN_DIV, // /
|
||||
BIN_GREATER, // >
|
||||
BIN_GREATEREQ, // >=
|
||||
BIN_LAND, // &&
|
||||
BIN_LEQUAL, // ==
|
||||
BIN_LESS, // <
|
||||
BIN_LESSEQ, // <=
|
||||
BIN_LOR, // ||
|
||||
BIN_LSHIFT, // <<
|
||||
BIN_LXOR, // ^^
|
||||
BIN_MINUS, // -
|
||||
BIN_MODULO, // %
|
||||
BIN_NEQUAL, // !=
|
||||
BIN_PLUS, // +
|
||||
BIN_RSHIFT, // >>
|
||||
BIN_TIMES, // *
|
||||
BIN_BXOR, // ^
|
||||
BIN_LAST = BIN_BXOR,
|
||||
};
|
||||
|
||||
struct expression_assign {
|
||||
enum binarithm_operator op;
|
||||
struct expression *object, *value;
|
||||
};
|
||||
|
||||
struct expression_binarithm {
|
||||
enum binarithm_operator op;
|
||||
struct expression *lvalue, *rvalue;
|
||||
};
|
||||
|
||||
struct binding_unpack {
|
||||
const struct scope_object *object;
|
||||
size_t offset;
|
||||
struct binding_unpack *next;
|
||||
};
|
||||
|
||||
struct expression_binding {
|
||||
const struct scope_object *object;
|
||||
struct binding_unpack *unpack;
|
||||
struct expression *initializer;
|
||||
struct expression_binding *next;
|
||||
};
|
||||
|
||||
enum cast_kind {
|
||||
C_CAST,
|
||||
C_ASSERTION,
|
||||
C_TEST,
|
||||
};
|
||||
|
||||
struct expression_cast {
|
||||
enum cast_kind kind;
|
||||
const struct type *secondary;
|
||||
struct expression *value;
|
||||
bool lowered;
|
||||
};
|
||||
|
||||
struct call_argument {
|
||||
struct expression *value;
|
||||
struct call_argument *next;
|
||||
};
|
||||
|
||||
struct expression_call {
|
||||
struct expression *lvalue;
|
||||
struct call_argument *args;
|
||||
};
|
||||
|
||||
struct expression_compound {
|
||||
const char *label;
|
||||
struct scope *scope;
|
||||
struct expressions exprs;
|
||||
};
|
||||
|
||||
struct array_literal {
|
||||
struct expression *value;
|
||||
struct array_literal *next;
|
||||
};
|
||||
|
||||
// Invariant: these are sorted by field offset
|
||||
struct struct_literal {
|
||||
const struct struct_field *field;
|
||||
struct expression *value;
|
||||
struct struct_literal *next;
|
||||
};
|
||||
|
||||
struct tuple_literal {
|
||||
const struct type_tuple *field;
|
||||
struct expression *value;
|
||||
struct tuple_literal *next;
|
||||
};
|
||||
|
||||
struct tagged_literal {
|
||||
const struct type *tag;
|
||||
struct expression *value;
|
||||
};
|
||||
|
||||
struct expression_literal {
|
||||
// If non-null, ival is an offset from this object's address
|
||||
const struct scope_object *object;
|
||||
union {
|
||||
bool bval;
|
||||
double fval;
|
||||
int64_t ival;
|
||||
uint64_t uval;
|
||||
uint32_t rune;
|
||||
struct {
|
||||
size_t len;
|
||||
char *value;
|
||||
} string;
|
||||
struct {
|
||||
union {
|
||||
// if object is null
|
||||
struct array_literal *array;
|
||||
// if object is non-null
|
||||
size_t offset;
|
||||
};
|
||||
size_t start;
|
||||
size_t len;
|
||||
size_t cap;
|
||||
} slice;
|
||||
struct array_literal *array;
|
||||
struct struct_literal *_struct;
|
||||
struct tuple_literal *tuple;
|
||||
struct tagged_literal tagged;
|
||||
};
|
||||
};
|
||||
|
||||
struct expression_control {
|
||||
const char *label;
|
||||
const struct scope *scope;
|
||||
struct expression *value; // Only set for yield and break
|
||||
};
|
||||
|
||||
struct expression_defer {
|
||||
struct scope *scope;
|
||||
struct expression *deferred;
|
||||
};
|
||||
|
||||
struct expression_delete {
|
||||
struct expression *expr;
|
||||
bool is_static;
|
||||
};
|
||||
|
||||
enum for_kind {
|
||||
FOR_ACCUMULATOR,
|
||||
FOR_EACH_VALUE,
|
||||
FOR_EACH_POINTER,
|
||||
FOR_EACH_ITERATOR,
|
||||
};
|
||||
|
||||
struct expression_for {
|
||||
enum for_kind kind;
|
||||
const char *label;
|
||||
struct scope *scope;
|
||||
struct expression *bindings;
|
||||
struct expression *cond;
|
||||
struct expression *afterthought;
|
||||
struct expression *body;
|
||||
struct expression *else_branch;
|
||||
};
|
||||
|
||||
struct expression_free {
|
||||
struct expression *expr;
|
||||
};
|
||||
|
||||
struct expression_if {
|
||||
struct expression *cond;
|
||||
struct expression *true_branch, *false_branch;
|
||||
};
|
||||
|
||||
struct match_case {
|
||||
const struct scope_object *object; // NULL if not bound
|
||||
const struct type *type; // NULL if default
|
||||
struct expression *value;
|
||||
struct match_case *next;
|
||||
};
|
||||
|
||||
struct expression_len {
|
||||
struct expression *value;
|
||||
};
|
||||
|
||||
struct expression_match {
|
||||
struct expression *value;
|
||||
struct match_case *cases;
|
||||
};
|
||||
|
||||
struct expression_return {
|
||||
struct expression *value;
|
||||
};
|
||||
|
||||
struct expression_slice {
|
||||
struct expression *object;
|
||||
struct expression *start, *end;
|
||||
bool bounds_checked;
|
||||
};
|
||||
|
||||
struct case_option {
|
||||
struct expression *value;
|
||||
struct case_option *next;
|
||||
};
|
||||
|
||||
struct switch_case {
|
||||
struct case_option *options; // NULL for default case
|
||||
struct expression *value;
|
||||
struct switch_case *next;
|
||||
};
|
||||
|
||||
struct expression_switch {
|
||||
struct expression *value;
|
||||
struct switch_case *cases;
|
||||
};
|
||||
|
||||
struct expr_struct_field {
|
||||
const struct struct_field *field;
|
||||
struct expression *value;
|
||||
struct expr_struct_field *next;
|
||||
};
|
||||
|
||||
struct expression_struct {
|
||||
struct expr_struct_field *fields;
|
||||
bool autofill, undefined;
|
||||
};
|
||||
|
||||
struct expression_tuple {
|
||||
struct expression *value;
|
||||
struct expression_tuple *next;
|
||||
};
|
||||
|
||||
enum unarithm_operator {
|
||||
UN_ADDRESS, // &
|
||||
UN_BNOT, // ~
|
||||
UN_DEREF, // *
|
||||
UN_LNOT, // !
|
||||
UN_MINUS, // -
|
||||
};
|
||||
|
||||
struct expression_unarithm {
|
||||
enum unarithm_operator op;
|
||||
struct expression *operand;
|
||||
};
|
||||
|
||||
struct expression_vaarg {
|
||||
struct expression *ap;
|
||||
};
|
||||
|
||||
struct expression {
|
||||
const struct type *result;
|
||||
enum expr_type type;
|
||||
struct location loc; // For fixed aborts
|
||||
union {
|
||||
struct expression_access access;
|
||||
struct expression_alloc alloc;
|
||||
struct expression_append append; // and insert
|
||||
struct expression_assert assert;
|
||||
struct expression_assign assign;
|
||||
struct expression_binarithm binarithm;
|
||||
struct expression_binding binding;
|
||||
struct expression_call call;
|
||||
struct expression_cast cast;
|
||||
struct expression_compound compound;
|
||||
struct expression_defer defer;
|
||||
struct expression_delete delete;
|
||||
struct expression_control control;
|
||||
struct expression_for _for;
|
||||
struct expression_free free;
|
||||
struct expression_if _if;
|
||||
struct expression_len len;
|
||||
struct expression_literal literal;
|
||||
struct expression_match match;
|
||||
struct expression_return _return;
|
||||
struct expression_switch _switch;
|
||||
struct expression_struct _struct;
|
||||
struct expression_slice slice;
|
||||
struct expression_tuple tuple;
|
||||
struct expression_unarithm unarithm;
|
||||
struct expression_vaarg vaarg;
|
||||
void *user;
|
||||
};
|
||||
};
|
||||
|
||||
uint32_t expr_hash(const struct expression *expr);
|
||||
bool expr_equal(const struct expression *a, const struct expression *b);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user