hare::ast+x86_64 +linux

hare::ast provides an abstract syntax tree for Hare code.

Index

Types

type _null = void;
type _type = struct {
	start: lex::location,
	end: lex::location,
	flags: type_flag,
	repr: (alias_type | builtin_type | enum_type | func_type | list_type | pointer_type | struct_type | union_type | tagged_type | tuple_type),
};
type access_expr = (access_identifier | access_index | access_field | access_tuple);
type access_field = struct {
	object: *expr,
	field: str,
};
type access_identifier = ident;
type access_index = struct {
	object: *expr,
	index: *expr,
};
type access_tuple = struct {
	object: *expr,
	value: *expr,
};
type alias_type = struct {
	unwrap: bool,
	ident: ident,
};
type align_expr = *_type;
type alloc_expr = struct {
	init: *expr,
	form: alloc_form,
	capacity: nullable *expr,
};
type alloc_form = enum {
	OBJECT,
	COPY,
};
type append_expr = struct {
	object: *expr,
	value: *expr,
	length: nullable *expr,
	variadic: bool,
	is_static: bool,
};
type array_literal = struct {
	expand: bool,
	values: []*expr,
};
type assert_expr = struct {
	cond: nullable *expr,
	message: nullable *expr,
	is_static: bool,
};
type assign_expr = struct {
	op: (binarithm_op | void),
	object: *expr,
	value: *expr,
};
type binarithm_expr = struct {
	op: binarithm_op,
	lvalue: *expr,
	rvalue: *expr,
};
type binarithm_op = enum {
	BAND, // &
	BOR, // |
	DIV, // /
	GT, // >
	GTEQ, // >=
	LAND, // &&
	LEQUAL, // ==
	LESS, // <
	LESSEQ, // <=
	LOR, // ||
	LSHIFT, // <<
	LXOR, // ^^
	MINUS, // -
	MODULO, // %
	NEQUAL, // !=
	PLUS, // +
	RSHIFT, // >>
	TIMES, // *
	BXOR, // ^
};
type binding = struct {
	name: (str | binding_unpack),
	_type: nullable *_type,
	init: *expr,
};
type binding_expr = struct {
	is_static: bool,
	kind: binding_kind,
	bindings: []binding,
};
type binding_kind = enum {
	CONST,
	DEF,
	LET,
};
type binding_unpack = [](str | void);
type break_expr = label;
type builtin_type = enum {
	BOOL,
	DONE,
	F32,
	F64,
	FCONST,
	I16,
	I32,
	I64,
	I8,
	ICONST,
	INT,
	NEVER,
	NULL,
	OPAQUE,
	RCONST,
	RUNE,
	SIZE,
	STR,
	U16,
	U32,
	U64,
	U8,
	UINT,
	UINTPTR,
	VALIST,
	VOID,
};
type call_expr = struct {
	lvalue: *expr,
	variadic: bool,
	args: []*expr,
};
type cast_expr = struct {
	kind: cast_kind,
	value: *expr,
	_type: *_type,
};
type cast_kind = enum {
	CAST,
	ASSERTION,
	TEST,
};
type compound_expr = struct {
	exprs: []*expr,
	label: label,
};
type continue_expr = label;
type decl = struct {
	exported: bool,
	start: lex::location,
	end: lex::location,
	decl: ([]decl_const | []decl_global | []decl_type | decl_func | assert_expr),
	// Only valid if the lexer has comments enabled
	docs: str,
};
type decl_const = struct {
	ident: ident,
	_type: nullable *_type,
	init: *expr,
};
type decl_func = struct {
	symbol: str,
	ident: ident,
	prototype: *_type,
	body: nullable *expr,
	attrs: fndecl_attr,
};
type decl_global = struct {
	is_const: bool,
	is_threadlocal: bool,
	symbol: str,
	ident: ident,
	_type: nullable *_type,
	init: nullable *expr,
};
type decl_type = struct {
	ident: ident,
	_type: *_type,
};
type defer_expr = *expr;
type delete_expr = struct {
	object: *expr,
	is_static: bool,
};
type enum_field = struct {
	name: str,
	value: nullable *expr,
	loc: lex::location,
	docs: str,
};
type enum_type = struct {
	storage: builtin_type,
	values: []enum_field,
};
type error_assert_expr = *expr;
type expr = struct {
	start: lex::location,
	end: lex::location,
	expr: (access_expr | align_expr | alloc_expr | append_expr | assert_expr | assign_expr | binarithm_expr | binding_expr | break_expr | call_expr | cast_expr | literal_expr | continue_expr | defer_expr | delete_expr | for_expr | free_expr | error_assert_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 | yield_expr),
};
type fndecl_attr = enum {
	NONE,
	FINI,
	INIT,
	TEST,
};
type for_expr = struct {
	kind: for_kind,
	bindings: nullable *expr,
	cond: nullable *expr,
	afterthought: nullable *expr,
	body: *expr,
	label: label,
};
type for_kind = enum {
	ACCUMULATOR,
	EACH_VALUE,
	EACH_POINTER,
	ITERATOR,
};
type free_expr = *expr;
type func_param = struct {
	loc: lex::location,
	name: str,
	_type: *_type,
	default_value: (void | expr),
};
type func_type = struct {
	result: *_type,
	variadism: variadism,
	params: []func_param,
};
type ident = []str;
type if_expr = struct {
	cond: *expr,
	tbranch: *expr,
	fbranch: nullable *expr,
};
type import = struct {
	start: lex::location,
	end: lex::location,
	ident: ident,
	bindings: (void | import_alias | import_members | import_wildcard),
};
type import_alias = str;
type import_members = []str;
type import_wildcard = void;
type insert_expr = append_expr;
type label = str;
type len_contextual = void;
type len_expr = *expr;
type len_slice = void;
type len_unbounded = void;
type list_type = struct {
	length: (*expr | len_slice | len_unbounded | len_contextual),
	members: *_type,
};
type literal_expr = (value | array_literal | number_literal | struct_literal | tuple_literal);
type match_case = struct {
	name: str,
	// null for default case
	_type: nullable *_type,
	exprs: []*expr,
};
type match_expr = struct {
	value: *expr,
	cases: []match_case,
	label: label,
};
type number_literal = struct {
	suff: lex::ltok,
	value: (i64 | u64 | f64),
	// true if negative, false otherwise
	sign: bool,
};
type offset_expr = *expr;
type pointer_flag = enum uint {
	NONE = 0,
	NULLABLE = 1 << 0,
};
type pointer_type = struct {
	referent: *_type,
	flags: pointer_flag,
};
type propagate_expr = *expr;
type return_expr = nullable *expr;
type size_expr = *_type;
type slice_expr = struct {
	object: *expr,
	start: nullable *expr,
	end: nullable *expr,
};
type struct_alias = ident;
type struct_embedded = *_type;
type struct_field = struct {
	name: str,
	_type: *_type,
};
type struct_literal = struct {
	autofill: bool,
	// [] for anonymous
	alias: ident,
	fields: [](struct_value | *struct_literal),
};
type struct_member = struct {
	_offset: nullable *expr,
	member: (struct_field | struct_embedded | struct_alias),
	// Only valid if the lexer has comments enabled
	docs: str,
};
type struct_type = struct {
	packed: bool,
	members: []struct_member,
};
type struct_value = struct {
	name: str,
	_type: nullable *_type,
	init: *expr,
};
type subunit = struct {
	imports: []import,
	decls: []decl,
};
type switch_case = struct {
	// [] for default case
	options: []*expr,
	exprs: []*expr,
};
type switch_expr = struct {
	value: *expr,
	cases: []switch_case,
	label: label,
};
type tagged_type = []*_type;
type tuple_literal = []*expr;
type tuple_type = []*_type;
type type_flag = enum uint {
	NONE = 0,
	CONST = 1 << 0,
	ERROR = 1 << 1,
};
type unarithm_expr = struct {
	op: unarithm_op,
	operand: *expr,
};
type unarithm_op = enum {
	ADDR, // &
	BNOT, // ~
	DEREF, // *
	LNOT, // !
	MINUS, // -
};
type union_type = []struct_member;
type vaarg_expr = struct {
	ap: *expr,
	_type: *_type,
};
type vaend_expr = *expr;
type value = (bool | done | _null | str | rune | void);
type variadic_expr = (vastart_expr | vaarg_expr | vaend_expr);
type variadism = enum {
	NONE,
	C,
	HARE,
};
type vastart_expr = void;
type yield_expr = struct {
	label: label,
	value: nullable *expr,
};

// Undocumented types:
type struct_union_type = (struct_type | union_type);

Constants

def IDENT_MAX: size = 255;

Functions

fn decl_finish(d: decl) void;
fn expr_finish(e: nullable *expr) void;
fn ident_dup(id: ident) ident;
fn ident_eq(a: ident, b: ident) bool;
fn ident_free(ident: ident) void;
fn import_finish(import: import) void;
fn imports_finish(imports: []import) void;
fn subunit_finish(u: subunit) void;
fn type_finish(t: nullable *_type) void;

Types

type _null[link]

type _null = void;

The value "null".

type _type[link]

type _type = struct {
	start: lex::location,
	end: lex::location,
	flags: type_flag,
	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.

foo.bar

type access_identifier[link]

type access_identifier = ident;

An identifier access expression.

foo

type access_index[link]

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

An index access expression.

foo[0]

type access_tuple[link]

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

A tuple field access expression.

foo.1

type alias_type[link]

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

A type alias.

type align_expr[link]

type align_expr = *_type;

An align expression.

align(int)

type alloc_expr[link]

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

An allocation expression.

alloc(foo)
alloc(foo...)
alloc(foo, bar)

type alloc_form[link]

type alloc_form = enum {
	OBJECT,
	COPY,
};

The form of an allocation expression.

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

type append_expr[link]

type append_expr = struct {
	object: *expr,
	value: *expr,
	length: nullable *expr,
	variadic: bool,
	is_static: bool,
};

An append expression.

append(foo, bar);
append(foo, bar...);
append(foo, [0...], bar);

type array_literal[link]

type array_literal = struct {
	expand: bool,
	values: []*expr,
};

An array literal.

[foo, bar, ...]

type assert_expr[link]

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

An assertion expression.

assert(foo)
assert(foo, "error")
abort()
abort("error")

type assign_expr[link]

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

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,
	kind: binding_kind,
	bindings: []binding,
};

A variable binding expression.

let foo: int = bar, ...

type binding_kind[link]

type binding_kind = enum {
	CONST,
	DEF,
	LET,
};

The kind of binding expression being used.

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 {
	BOOL,
	DONE,
	F32,
	F64,
	FCONST,
	I16,
	I32,
	I64,
	I8,
	ICONST,
	INT,
	NEVER,
	NULL,
	OPAQUE,
	RCONST,
	RUNE,
	SIZE,
	STR,
	U16,
	U32,
	U64,
	U8,
	UINT,
	UINTPTR,
	VALIST,
	VOID,
};

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.

foo(bar)

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 {
	CAST,
	ASSERTION,
	TEST,
};

The kind of cast expression being used.

type compound_expr[link]

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

A compound expression.

{
	foo;
	bar;
	// ...
}

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 | assert_expr),
	// Only valid if the lexer has comments enabled
	docs: str,
};

A Hare declaration.

type decl_const[link]

type decl_const = struct {
	ident: ident,
	_type: nullable *_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: nullable *expr,
	attrs: fndecl_attr,
};

A function declaration.

fn main() void = void;

type decl_global[link]

type decl_global = struct {
	is_const: bool,
	is_threadlocal: bool,
	symbol: str,
	ident: ident,
	_type: nullable *_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.

delete(foo[10])
delete(foo[4..42])

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,
	values: []enum_field,
};

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

type error_assert_expr[link]

type error_assert_expr = *expr;

An error assertion expression.

foo!

type expr[link]

type expr = struct {
	start: lex::location,
	end: lex::location,
	expr: (access_expr | align_expr | alloc_expr | append_expr | assert_expr | assign_expr | binarithm_expr | binding_expr | break_expr | call_expr | cast_expr | literal_expr | continue_expr | defer_expr | delete_expr | for_expr | free_expr | error_assert_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 | yield_expr),
};

A Hare expression.

type fndecl_attr[link]

type fndecl_attr = enum {
	NONE,
	FINI,
	INIT,
	TEST,
};

Attributes applicable to a function declaration.

type for_expr[link]

type for_expr = struct {
	kind: for_kind,
	bindings: nullable *expr,
	cond: nullable *expr,
	afterthought: nullable *expr,
	body: *expr,
	label: label,
};

A for loop.

for (let foo = 0; foo < bar; baz) quux
for (let line => next_line()) quux
for (let number .. [1, 2, 3]) quux
for (let ptr &.. [1, 2, 3]) quux

type for_kind[link]

type for_kind = enum {
	ACCUMULATOR,
	EACH_VALUE,
	EACH_POINTER,
	ITERATOR,
};

The kind of for expression being used.

type free_expr[link]

type free_expr = *expr;

A free expression.

free(foo)

type func_param[link]

type func_param = struct {
	loc: lex::location,
	name: str,
	_type: *_type,
	default_value: (void | expr),
};

A parameter to a function type.

type func_type[link]

type func_type = struct {
	result: *_type,
	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,
	ident: ident,
	bindings: (void | import_alias | import_members | import_wildcard),
};

An imported module.

use foo;
use foo = bar;
use foo::{bar, baz};
use foo::*;

type import_alias[link]

type import_alias = str;

An import alias.

use foo = bar;

type import_members[link]

type import_members = []str;

An import members list.

use foo::{bar, baz};

type import_wildcard[link]

type import_wildcard = void;

An import wildcard.

use foo::*;

type insert_expr[link]

type insert_expr = append_expr;

An insert expression.

insert(foo[0], bar);
insert(foo[0], bar...);
insert(foo[0], [0...], bar);

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.

len(foo)

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 literal_expr[link]

type literal_expr = (value | array_literal | number_literal | struct_literal | tuple_literal);

A literal expression.

type match_case[link]

type match_case = struct {
	name: str,
	// null for default case
	_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,
	label: label,
};

A match expression.

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

type number_literal[link]

type number_literal = struct {
	suff: lex::ltok,
	value: (i64 | u64 | f64),
	// true if negative, false otherwise
	sign: bool,
};

An integer or float literal.

type offset_expr[link]

type offset_expr = *expr;

An offset expression.

offset(foo.bar)

type pointer_flag[link]

type pointer_flag = 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_flag,
};

*int

type propagate_expr[link]

type propagate_expr = *expr;

An error propagation expression.

foo?

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.

size(int)

type slice_expr[link]

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

A slicing expression.

foo[bar..baz]

type struct_alias[link]

type struct_alias = ident;

An embedded type alias.

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_literal[link]

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

A struct literal.

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

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 {
	packed: bool,
	members: []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 {
	// [] for default case
	options: []*expr,
	exprs: []*expr,
};

A switch case.

case value => exprs

type switch_expr[link]

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

A switch expression.

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

type tagged_type[link]

type tagged_type = []*_type;

(int | bool)

type tuple_literal[link]

type tuple_literal = []*expr;

A tuple literal.

(foo, bar, ...)

type tuple_type[link]

type tuple_type = []*_type;

(int, bool, ...)

type type_flag[link]

type type_flag = 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.

!example

type unarithm_op[link]

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

A unary operator

type union_type[link]

type union_type = []struct_member;

union { ... }

type vaarg_expr[link]

type vaarg_expr = struct {
	ap: *expr,
	_type: *_type,
};

A vaarg expression.

vaarg(ap, int)

type vaend_expr[link]

type vaend_expr = *expr;

A vaend expression.

vaend(ap)

type value[link]

type value = (bool | done | _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 {
	NONE,
	C,
	HARE,
};

The variadism strategy for a function type.

type vastart_expr[link]

type vastart_expr = void;

A vastart expression.

vastart()

type yield_expr[link]

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

A yield expression.

yield foo

type struct_union_type[link]

Show undocumented member
type struct_union_type = (struct_type | union_type);

Constants

def IDENT_MAX[link]

def IDENT_MAX: size = 255;

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.

Functions

fn decl_finish[link]

fn decl_finish(d: decl) void;

Frees resources associated with a declaration.

fn expr_finish[link]

fn expr_finish(e: 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 imports_finish[link]

fn imports_finish(imports: []import) void;

Frees resources associated with each import in a slice, and then frees the slice itself.

fn subunit_finish[link]

fn subunit_finish(u: subunit) void;

Frees resources associated with a subunit.

fn type_finish[link]

fn type_finish(t: nullable *_type) void;

Frees resources associated with a _type.