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.
445 lines
8.8 KiB
C
445 lines
8.8 KiB
C
#ifndef HARE_AST_H
|
|
#define HARE_AST_H
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include "expr.h"
|
|
#include "identifier.h"
|
|
#include "lex.h"
|
|
#include "types.h"
|
|
|
|
struct ast_type;
|
|
|
|
enum ast_import_mode {
|
|
IMPORT_NORMAL, // use foo::bar;
|
|
IMPORT_ALIAS, // use foo = bar::baz;
|
|
IMPORT_MEMBERS, // use foo::{bar, baz};
|
|
IMPORT_WILDCARD, // use foo::bar::*;
|
|
};
|
|
|
|
struct ast_import_members {
|
|
struct location loc;
|
|
struct ident *name;
|
|
struct ast_import_members *next;
|
|
};
|
|
|
|
struct ast_imports {
|
|
enum ast_import_mode mode;
|
|
struct ident *ident;
|
|
union {
|
|
const char *alias;
|
|
struct ast_import_members *members;
|
|
};
|
|
struct ast_imports *next;
|
|
};
|
|
|
|
struct ast_array_type {
|
|
struct ast_expression *length; // NULL for unbounded arrays
|
|
struct ast_type *members;
|
|
bool contextual;
|
|
};
|
|
|
|
struct ast_slice_type {
|
|
struct ast_type *members;
|
|
};
|
|
|
|
struct ast_enum_field {
|
|
struct location loc;
|
|
struct ident *name;
|
|
struct ast_expression *value;
|
|
struct ast_enum_field *next;
|
|
};
|
|
|
|
struct ast_enum_type {
|
|
enum type_storage storage;
|
|
struct ast_enum_field *values;
|
|
};
|
|
|
|
struct ast_function_parameters {
|
|
struct location loc;
|
|
struct ident *name;
|
|
struct ast_type *type;
|
|
struct ast_expression *default_value;
|
|
struct ast_function_parameters *next;
|
|
};
|
|
|
|
struct ast_function_type {
|
|
struct ast_type *result;
|
|
struct ast_function_parameters *params;
|
|
enum variadism variadism;
|
|
};
|
|
|
|
struct ast_pointer_type {
|
|
struct ast_type *referent;
|
|
bool nullable;
|
|
};
|
|
|
|
struct ast_tagged_union_type {
|
|
struct ast_type *type;
|
|
bool unwrap;
|
|
struct ast_tagged_union_type *next;
|
|
};
|
|
|
|
struct ast_tuple_type {
|
|
struct ast_type *type;
|
|
struct ast_tuple_type *next;
|
|
};
|
|
|
|
struct ast_struct_union_field {
|
|
struct ast_struct_union_field *next;
|
|
const char *name; // null if embed, may be "_"
|
|
struct ast_type *type;
|
|
};
|
|
|
|
struct ast_struct_union_type {
|
|
struct ast_struct_union_field fields;
|
|
bool packed;
|
|
};
|
|
|
|
struct ast_type {
|
|
struct location loc;
|
|
enum type_storage storage;
|
|
union {
|
|
struct ast_array_type array;
|
|
struct ast_type *error;
|
|
struct ast_function_type func;
|
|
struct ast_pointer_type pointer;
|
|
struct ast_slice_type slice;
|
|
struct ast_struct_union_type struct_union;
|
|
struct ast_tagged_union_type tagged;
|
|
struct ast_tuple_type tuple;
|
|
struct {
|
|
struct ident *alias;
|
|
// Only valid for enums
|
|
struct ast_enum_type _enum;
|
|
};
|
|
};
|
|
};
|
|
|
|
struct ast_types {
|
|
const struct ast_type *type;
|
|
struct ast_types *next;
|
|
};
|
|
|
|
struct ast_expression_list {
|
|
struct ast_expression *expr;
|
|
struct ast_expression_list *next;
|
|
};
|
|
|
|
struct ast_expression_access {
|
|
enum access_type type;
|
|
union {
|
|
struct ident *ident;
|
|
struct {
|
|
struct ast_expression *array;
|
|
struct ast_expression *index;
|
|
};
|
|
struct {
|
|
struct ast_expression *_struct;
|
|
const char *field;
|
|
};
|
|
struct {
|
|
struct ast_expression *tuple;
|
|
struct ast_expression *value;
|
|
};
|
|
};
|
|
};
|
|
|
|
struct ast_expression_alloc {
|
|
enum alloc_kind kind;
|
|
struct ast_expression *init;
|
|
struct ast_expression *cap;
|
|
};
|
|
|
|
struct ast_expression_append {
|
|
struct ast_expression *object;
|
|
struct ast_expression *value;
|
|
struct ast_expression *length;
|
|
bool is_static, is_multi;
|
|
};
|
|
|
|
struct ast_expression_assert {
|
|
struct ast_expression *cond;
|
|
struct ast_expression *message;
|
|
bool is_static;
|
|
};
|
|
|
|
struct ast_expression_assign {
|
|
enum binarithm_operator op;
|
|
// object == NULL for discarding assignment (`_ = foo`)
|
|
struct ast_expression *object, *value;
|
|
};
|
|
|
|
struct ast_expression_binarithm {
|
|
enum binarithm_operator op;
|
|
struct ast_expression *lvalue, *rvalue;
|
|
};
|
|
|
|
struct ast_binding_names {
|
|
struct ident *name; // NULL for _
|
|
struct ast_binding_names *next;
|
|
};
|
|
|
|
struct ast_expression_binding {
|
|
// more than one name means tuple unpacking,
|
|
// otherwise it's a regular binding
|
|
struct ast_binding_names names;
|
|
struct ast_type *type;
|
|
bool is_static;
|
|
struct ast_expression *initializer;
|
|
struct ast_expression_binding *next;
|
|
};
|
|
|
|
struct ast_expression_call {
|
|
struct ast_expression *lvalue;
|
|
struct ast_expression_list *args;
|
|
bool variadic; // last argument is a variadic argument list
|
|
};
|
|
|
|
struct ast_expression_cast {
|
|
enum cast_kind kind;
|
|
struct ast_expression *value;
|
|
struct ast_type *type;
|
|
};
|
|
|
|
struct ast_expression_literal {
|
|
enum type_storage storage;
|
|
union {
|
|
int64_t ival;
|
|
uint64_t uval;
|
|
double fval;
|
|
uint32_t rune;
|
|
bool bval;
|
|
struct {
|
|
size_t len;
|
|
char *value;
|
|
} string;
|
|
struct {
|
|
struct ast_expression_list *exprs;
|
|
bool expand;
|
|
} array;
|
|
};
|
|
};
|
|
|
|
struct ast_expression_control {
|
|
const char *label; // Never set for return.
|
|
struct ast_expression *value; // Never set for continue
|
|
};
|
|
|
|
struct ast_expression_defer {
|
|
struct ast_expression *deferred;
|
|
};
|
|
|
|
struct ast_expression_delete {
|
|
struct ast_expression *expr;
|
|
bool is_static;
|
|
};
|
|
|
|
struct ast_expression_for {
|
|
enum for_kind kind;
|
|
const char *label;
|
|
struct ast_expression *bindings;
|
|
struct ast_expression *cond;
|
|
struct ast_expression *afterthought;
|
|
struct ast_expression *body;
|
|
struct ast_expression *else_branch;
|
|
};
|
|
|
|
struct ast_expression_free {
|
|
struct ast_expression *expr;
|
|
};
|
|
|
|
struct ast_expression_if {
|
|
struct ast_expression *cond;
|
|
struct ast_expression *true_branch, *false_branch;
|
|
};
|
|
|
|
struct ast_expression_compound {
|
|
const char *label;
|
|
struct location label_loc;
|
|
struct ast_expression_list list;
|
|
};
|
|
|
|
struct ast_match_case {
|
|
struct ident *name; // May be null
|
|
struct ast_type *type;
|
|
struct ast_expression_list exprs;
|
|
struct ast_match_case *next;
|
|
};
|
|
|
|
struct ast_expression_match {
|
|
const char *label;
|
|
struct ast_expression *value;
|
|
struct ast_match_case *cases;
|
|
};
|
|
|
|
enum measure_operator {
|
|
M_ALIGN,
|
|
M_LEN,
|
|
M_SIZE,
|
|
M_OFFSET,
|
|
};
|
|
|
|
struct ast_expression_measure {
|
|
enum measure_operator op;
|
|
union {
|
|
struct ast_expression *value;
|
|
struct ast_type *type;
|
|
// TODO: Field selection
|
|
};
|
|
};
|
|
|
|
struct ast_expression_propagate {
|
|
struct ast_expression *value;
|
|
bool abort;
|
|
};
|
|
|
|
struct ast_expression_slice {
|
|
struct ast_expression *object;
|
|
struct ast_expression *start, *end;
|
|
};
|
|
|
|
struct ast_case_option {
|
|
struct ast_expression *value;
|
|
struct ast_case_option *next;
|
|
};
|
|
|
|
struct ast_switch_case {
|
|
struct ast_case_option *options; // NULL for *
|
|
struct ast_expression_list exprs;
|
|
struct ast_switch_case *next;
|
|
};
|
|
|
|
struct ast_expression_switch {
|
|
const char *label;
|
|
struct ast_expression *value;
|
|
struct ast_switch_case *cases;
|
|
};
|
|
|
|
struct ast_field_value {
|
|
const char *name;
|
|
struct ast_type *type;
|
|
struct ast_expression *initializer;
|
|
struct ast_field_value *next;
|
|
};
|
|
|
|
struct ast_expression_struct {
|
|
bool autofill;
|
|
bool undefined;
|
|
struct ident *type;
|
|
struct ast_field_value *fields;
|
|
};
|
|
|
|
struct ast_expression_tuple {
|
|
struct ast_expression *expr;
|
|
struct ast_expression_tuple *next;
|
|
};
|
|
|
|
struct ast_expression_unarithm {
|
|
enum unarithm_operator op;
|
|
struct ast_expression *operand;
|
|
};
|
|
|
|
struct ast_expression_vaarg {
|
|
struct ast_expression *ap;
|
|
struct ast_type *type;
|
|
};
|
|
|
|
struct ast_expression {
|
|
struct location loc;
|
|
enum expr_type type;
|
|
union {
|
|
struct ast_expression_access access;
|
|
struct ast_expression_alloc alloc;
|
|
struct ast_expression_append append; // also insert
|
|
struct ast_expression_assert assert;
|
|
struct ast_expression_assign assign;
|
|
struct ast_expression_binarithm binarithm;
|
|
struct ast_expression_binding binding;
|
|
struct ast_expression_call call;
|
|
struct ast_expression_cast cast;
|
|
struct ast_expression_compound compound;
|
|
struct ast_expression_control control;
|
|
struct ast_expression_defer defer;
|
|
struct ast_expression_delete delete;
|
|
struct ast_expression_for _for;
|
|
struct ast_expression_free free;
|
|
struct ast_expression_if _if;
|
|
struct ast_expression_literal literal;
|
|
struct ast_expression_match match;
|
|
struct ast_expression_measure measure;
|
|
struct ast_expression_propagate propagate;
|
|
struct ast_expression_slice slice;
|
|
struct ast_expression_struct _struct;
|
|
struct ast_expression_switch _switch;
|
|
struct ast_expression_tuple tuple;
|
|
struct ast_expression_unarithm unarithm;
|
|
struct ast_expression_vaarg vaarg;
|
|
};
|
|
};
|
|
|
|
struct ast_global_decl {
|
|
const char *symbol;
|
|
bool threadlocal;
|
|
struct ident *ident;
|
|
struct ast_type *type;
|
|
struct ast_expression *init;
|
|
};
|
|
|
|
struct ast_type_decl {
|
|
struct ident *ident;
|
|
struct ast_type *type;
|
|
};
|
|
|
|
enum func_decl_flags {
|
|
FN_FINI = 1 << 0,
|
|
FN_INIT = 1 << 1,
|
|
FN_TEST = 1 << 2,
|
|
};
|
|
|
|
struct ast_function_decl {
|
|
const char *symbol;
|
|
struct ident *ident;
|
|
struct ast_function_type prototype;
|
|
struct ast_expression *body;
|
|
enum func_decl_flags flags;
|
|
};
|
|
|
|
enum ast_decl_type {
|
|
ADECL_FUNC,
|
|
ADECL_TYPE,
|
|
ADECL_GLOBAL,
|
|
ADECL_CONST,
|
|
ADECL_ASSERT,
|
|
};
|
|
|
|
struct ast_decl {
|
|
struct location loc;
|
|
enum ast_decl_type decl_type;
|
|
bool exported;
|
|
union {
|
|
struct ast_global_decl global;
|
|
struct ast_global_decl constant;
|
|
struct ast_type_decl type;
|
|
struct ast_function_decl function;
|
|
struct ast_expression_assert assert;
|
|
};
|
|
};
|
|
|
|
struct ast_decls {
|
|
struct ast_decl decl;
|
|
struct ast_decls *next;
|
|
};
|
|
|
|
struct ast_subunit {
|
|
struct ast_imports *imports;
|
|
struct ast_decls *decls;
|
|
struct ast_subunit *next;
|
|
};
|
|
|
|
struct ast_unit {
|
|
struct ident *ns;
|
|
struct ast_subunit subunits;
|
|
};
|
|
|
|
#endif
|