hare::ast +linux +x86_64



type _null;
type _type;
type access_expr;
type access_field;
type access_identifier;
type access_index;
type access_tuple;
type alias_type;
type alloc_expr;
type alloc_form;
type append_expr;
type array_constant;
type assert_expr;
type assign_expr;
type binarithm_expr;
type binarithm_op;
type binding;
type binding_expr;
type binding_unpack;
type break_expr;
type builtin_type;
type call_expr;
type cast_expr;
type cast_kind;
type compound_expr;
type constant_expr;
type continue_expr;
type decl;
type decl_const;
type decl_func;
type decl_global;
type decl_type;
type defer_expr;
type delete_expr;
type enum_field;
type enum_type;
type expr;
type fndecl_attrs;
type for_expr;
type free_expr;
type func_attrs;
type func_param;
type func_type;
type ident;
type if_expr;
type import;
type import_mode;
type insert_expr;
type label;
type len_contextual;
type len_expr;
type len_slice;
type len_unbounded;
type list_type;
type match_case;
type match_expr;
type number_constant;
type offset_expr;
type pointer_flags;
type pointer_type;
type propagate_expr;
type return_expr;
type size_expr;
type slice_expr;
type struct_alias;
type struct_constant;
type struct_embedded;
type struct_field;
type struct_member;
type struct_type;
type struct_value;
type subunit;
type switch_case;
type switch_expr;
type tagged_type;
type tuple_constant;
type tuple_type;
type type_flags;
type unarithm_expr;
type unarithm_op;
type union_type;
type vaarg_expr;
type vaend_expr;
type value;
type variadic_expr;
type variadism;
type vastart_expr;
type yield_expr;


const IDENT_MAX: size;


fn decl_finish(decl) void;
fn expr_finish((expr | nullable *expr)) void;
fn ident_dup(ident) ident;
fn ident_eq(ident, ident) bool;
fn ident_free(ident) void;
fn import_finish(import) void;
fn subunit_finish(subunit) void;
fn type_finish((_type | nullable *_type)) void;


type _null[link]

type _null = void;

The value "null".

type _type[link]

type _type = struct {
	start: lex::location,
	end: lex::location,
	flags: type_flags,
	repr: (alias_type | builtin_type | enum_type | func_type | list_type |
	pointer_type | struct_type | union_type | tagged_type | tuple_type),

A Hare type.

type access_expr[link]

type access_expr = (access_identifier | access_index | access_field | access_tuple);

An access expression.

type access_field[link]

type access_field = struct {
	object: *expr,
	field: str,

A struct field access expression.


type access_identifier[link]

type access_identifier = ident;

An identifier access expression.


type access_index[link]

type access_index = struct {
	object: *expr,
	index: *expr,

An index access expression.


type access_tuple[link]

type access_tuple = struct {
	object: *expr,
	value: *expr,

A tuple field access expression.


type alias_type[link]

type alias_type = struct {
	unwrap: bool,
	ident: ident,

A type alias.

type alloc_expr[link]

type alloc_expr = struct {
	init: *expr,
	form: alloc_form,
	capacity: nullable *expr,

An allocation expression.

alloc(foo, bar)

type alloc_form[link]

type alloc_form = enum {


The form of an allocation expression.

alloc(foo)    // OBJECT
alloc(foo...) // COPY

type append_expr[link]

type append_expr = struct {
	object: *expr,
	variadic: nullable *expr,
	values: []*expr,
	is_static: bool,

An append expression.

append(foo, bar, (more), baz...)

type array_constant[link]

type array_constant = struct {
	expand: bool,
	values: []*expr,

An array constant.

[foo, bar, ...]

type assert_expr[link]

type assert_expr = struct {
	cond: nullable *expr,
	message: nullable *expr,
	is_static: bool,

An assertion expression.

assert(foo, "error")

type assign_expr[link]

type assign_expr = struct {
	op: (binarithm_op | void),
	object: *expr,
	value: *expr,
	indirect: bool,

An assignment expression.

foo = bar

type binarithm_expr[link]

type binarithm_expr = struct {
	op: binarithm_op,
	lvalue: *expr,
	rvalue: *expr,

A binary arithmetic expression.

foo * bar

type binarithm_op[link]

type binarithm_op = enum {
	BAND, // &
BOR, // |
DIV, // /
GT, // >
GTEQ, // >=
LAND, // &&
LEQUAL, // ==
LESS, // <
LESSEQ, // <=
LOR, // ||
LSHIFT, // <<
LXOR, // ^^
MINUS, // -
MODULO, // %
NEQUAL, // !=
PLUS, // +
RSHIFT, // >>
TIMES, // *
BXOR, // ^

A binary arithmetic operator

type binding[link]

type binding = struct {
	name: (str | binding_unpack),
	_type: nullable *_type,
	init: *expr,

A single variable biding.

foo: int = bar
(foo, foo2): int = bar

type binding_expr[link]

type binding_expr = struct {
	is_static: bool,
	is_const: bool,
	bindings: []binding,

A variable binding expression.

let foo: int = bar, ...

type binding_unpack[link]

type binding_unpack = [](str | void);

Tuple unpacking binding.

(foo, _, bar)

type break_expr[link]

type break_expr = label;

A break expression. The label is set to empty string if absent.

break :label

type builtin_type[link]

type builtin_type = enum {


A built-in primitive type (int, bool, str, etc).

type call_expr[link]

type call_expr = struct {
	lvalue: *expr,
	variadic: bool,
	args: []*expr,

A function call expression.


type cast_expr[link]

type cast_expr = struct {
	kind: cast_kind,
	value: *expr,
	_type: *_type,

A cast expression.

foo: int
foo as int
foo is int

type cast_kind[link]

type cast_kind = enum {


The kind of cast expression being used.

type compound_expr[link]

type compound_expr = struct {
	exprs: []*expr,
	label: label,

A compound expression.

	// ...

type constant_expr[link]

type constant_expr = (value | array_constant | number_constant | struct_constant | tuple_constant);

A constant expression.

type continue_expr[link]

type continue_expr = label;

A continue expression. The label is set to empty string if absent.

continue :label

type decl[link]

type decl = struct {
	exported: bool,
	start: lex::location,
	end: lex::location,
	decl: ([]decl_const | []decl_global | []decl_type | decl_func),
	// Only valid if the lexer has comments enabled
docs: str, };

A Hare declaration.

type decl_const[link]

type decl_const = struct {
	ident: ident,
	_type: _type,
	init: *expr,

A constant declaration.

def foo: int = 0;

type decl_func[link]

type decl_func = struct {
	symbol: str,
	ident: ident,
	prototype: _type,
	body: (expr | void),
	attrs: fndecl_attrs,

A function declaration.

fn main() void = void;

type decl_global[link]

type decl_global = struct {
	is_const: bool,
	symbol: str,
	ident: ident,
	_type: _type,
	init: nullable *expr,

A global declaration.

let foo: int = 0;
const foo: int = 0;

type decl_type[link]

type decl_type = struct {
	ident: ident,
	_type: _type,

A type declaration.

type foo = int;

type defer_expr[link]

type defer_expr = *expr;

A deferred expression.

defer foo

type delete_expr[link]

type delete_expr = struct {
	object: *expr,
	is_static: bool,

A delete expression.


type enum_field[link]

type enum_field = struct {
	name: str,
	value: nullable *expr,
	loc: lex::location,
	docs: str,

An enumeration field (and optional value).

type enum_type[link]

type enum_type = struct {
	storage: builtin_type,
	// Must be an integer type
values: []enum_field, };

enum { FOO = 0, BAR, ... }

type expr[link]

type expr = struct {
	start: lex::location,
	end: lex::location,
	expr: (access_expr | alloc_expr | append_expr | assert_expr | assign_expr |
	binarithm_expr | binding_expr | break_expr | call_expr | cast_expr |
	constant_expr | continue_expr | defer_expr | delete_expr |
	for_expr | free_expr | if_expr | insert_expr | compound_expr |
	match_expr | len_expr | size_expr | offset_expr | propagate_expr |
	return_expr | slice_expr | switch_expr | unarithm_expr | variadic_expr |

A Hare expression.

type fndecl_attrs[link]

type fndecl_attrs = enum {


Attributes applicable to a function declaration.

type for_expr[link]

type for_expr = struct {
	bindings: nullable *expr,
	cond: *expr,
	afterthought: nullable *expr,
	body: *expr,

A for loop.

for (let foo = 0; foo < bar; baz) quux

type free_expr[link]

type free_expr = *expr;

A free expression.


type func_attrs[link]

type func_attrs = enum uint {
	NONE = 0,
	NORETURN = 1 << 0,


The attributes associated with a function type.

type func_param[link]

type func_param = struct {
	loc: lex::location,
	name: str,
	_type: *_type,

A parameter to a function type.

type func_type[link]

type func_type = struct {
	result: *_type,
	attrs: func_attrs,
	variadism: variadism,
	params: []func_param,

fn(foo: int, baz: int...) int

type ident[link]

type ident = []str;

Identifies a single object, e.g. foo::bar::baz.

type if_expr[link]

type if_expr = struct {
	cond: *expr,
	tbranch: *expr,
	fbranch: nullable *expr,

An if or if..else expression.

if (foo) bar else baz

type import[link]

type import = struct {
	start: lex::location,
	end: lex::location,
	mode: import_mode,
	ident: ident,
	alias: str,
	objects: []((str | void),

An imported module.

type import_mode[link]

type import_mode = enum uint {
	IDENT = 0, // use module;
ALIAS = 1 << 0, // use alias = module;
MEMBERS = 1 << 1, // use module::{foo, bar, baz};
WILDCARD = 1 << 2, // use module::*;

Variants of the import statement

type insert_expr[link]

type insert_expr = struct {
	object: *expr,
	variadic: nullable *expr,
	values: []*expr,
	is_static: bool,

An insert expression.

insert(foo[0], bar, (more), baz...)

type label[link]

type label = str;

:label. The ":" character is not included.

type len_contextual[link]

type len_contextual = void;

The length for a list type which is inferred from context (e.g. [_]int).

type len_expr[link]

type len_expr = *expr;

A length expression.


type len_slice[link]

type len_slice = void;

The length for a list type which is a slice (e.g. []int).

type len_unbounded[link]

type len_unbounded = void;

The length for a list type which is unbounded (e.g. [*]int).

type list_type[link]

type list_type = struct {
	length: (*expr | len_slice | len_unbounded | len_contextual),
	members: *_type,

[]int, [*]int, [_]int, [foo]int

type match_case[link]

type match_case = struct {
	name: str,
	_type: nullable *_type,
	exprs: []*expr,

A match case.

case type => exprs
case let name: type => exprs

type match_expr[link]

type match_expr = struct {
	value: *expr,
	cases: []match_case,
	default: []*expr,

A match expression.

match (foo) { case int => bar; ... }

type number_constant[link]

type number_constant = struct {
	suff: lex::ltok,
	value: (i64 | u64 |
	sign: bool,

An integer or float constant.

type offset_expr[link]

type offset_expr = *expr;

An offset expression.


type pointer_flags[link]

type pointer_flags = enum uint {
	NONE = 0,
	NULLABLE = 1 << 0,


Flags which apply to a pointer type.

type pointer_type[link]

type pointer_type = struct {
	referent: *_type,
	flags: pointer_flags,


type propagate_expr[link]

type propagate_expr = struct {
	is_abort: bool,
	expr: *expr,

An error propagation expression.


type return_expr[link]

type return_expr = nullable *expr;

A return statement.

return foo

type size_expr[link]

type size_expr = *_type;

A size expression.


type slice_expr[link]

type slice_expr = struct {
	object: *expr,
	start: nullable *expr,
	end: nullable *expr,

A slicing expression.


type struct_alias[link]

type struct_alias = ident;

An embedded type alias.

type struct_constant[link]

type struct_constant = struct {
	autofill: bool,
	alias: ident,
	// [] for anonymous
fields: [](struct_value | *struct_constant), };

A struct constant.

struct { foo: int = bar, struct { baz = quux }, ... }

type struct_embedded[link]

type struct_embedded = *_type;

An embedded struct type.

type struct_field[link]

type struct_field = struct {
	name: str,
	_type: *_type,

A single field of a struct type.

type struct_member[link]

type struct_member = struct {
	_offset: nullable *expr,
	member: (struct_field | struct_embedded | struct_alias),
	// Only valid if the lexer has comments enabled
docs: str, };

struct { @offset(10) foo: int, struct { bar: int }, baz::quux }

type struct_type[link]

type struct_type = []struct_member;

struct { ... }

type struct_value[link]

type struct_value = struct {
	name: str,
	_type: nullable *_type,
	init: *expr,

A single struct field and value.

foo: int = 10

type subunit[link]

type subunit = struct {
	imports: []import,
	decls: []decl,

A sub-unit, typically representing a single source file.

type switch_case[link]

type switch_case = struct {
	options: []*expr,
	// [] for default case
exprs: []*expr, };

A switch case.

case value => exprs

type switch_expr[link]

type switch_expr = struct {
	value: *expr,
	cases: []switch_case,

A switch expression.

switch (foo) { case bar => baz; ... }

type tagged_type[link]

type tagged_type = []*_type;

(int | bool)

type tuple_constant[link]

type tuple_constant = []*expr;

A tuple constant.

(foo, bar, ...)

type tuple_type[link]

type tuple_type = []*_type;

(int, bool, ...)

type type_flags[link]

type type_flags = enum uint {
	NONE = 0,
	CONST = 1 << 0,
	ERROR = 1 << 1,


Flags which apply to types.

type unarithm_expr[link]

type unarithm_expr = struct {
	op: unarithm_op,
	operand: *expr,

A unary arithmetic expression.


type unarithm_op[link]

type unarithm_op = enum {
	ADDR, // &
BNOT, // ~
DEREF, // *
LNOT, // !
MINUS, // -
PLUS, // +

A unary operator

type union_type[link]

type union_type = []struct_member;

union { ... }

type vaarg_expr[link]

type vaarg_expr = *expr;

A vaarg expression.


type vaend_expr[link]

type vaend_expr = *expr;

A vaend expression.


type value[link]

type value = (bool | _null | str |
rune | void);

A scalar value.

type variadic_expr[link]

type variadic_expr = (vastart_expr | vaarg_expr | vaend_expr);

A C-style variadic expression.

type variadism[link]

type variadism = enum {


The variadism strategy for a function type.

type vastart_expr[link]

type vastart_expr = void;

A vastart expression.


type yield_expr[link]

type yield_expr = struct {
	label: label,
	value: nullable *expr,

A yield expression.

yield foo


def IDENT_MAX[link]

def IDENT_MAX: size;

Maximum length of an identifier, as the sum of the lengths of its parts plus one for each namespace deliniation.

In other words, the length of "a::b::c" is 5.


fn decl_finish[link]

fn decl_finish(d: decl) void;

Frees resources associated with a declaration.

fn expr_finish[link]

fn expr_finish(e: (expr | nullable *expr)) void;

Frees resources associated with a Hare expression.

fn ident_dup[link]

fn ident_dup(id: ident) ident;

Duplicates an ident.

fn ident_eq[link]

fn ident_eq(a: ident, b: ident) bool;

Returns true if two idents are identical.

fn ident_free[link]

fn ident_free(ident: ident) void;

Frees resources associated with an identifier.

fn import_finish[link]

fn import_finish(import: import) void;

Frees resources associated with an import.

fn subunit_finish[link]

fn subunit_finish(u: subunit) void;

Frees resources associated with a subunit.

fn type_finish[link]

fn type_finish(t: (_type | nullable *_type)) void;

Frees resources associated with a _type.