commit 74f7f6c412cb701802166fe3a9fb3457497a5b58
parent fc6bfab55d16256f2a47f45732d7a0ecc8df15ce
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 21 Apr 2021 12:06:11 -0400
hare::ast: doc improvements
Diffstat:
6 files changed, 159 insertions(+), 49 deletions(-)
diff --git a/hare/ast/decl.ha b/hare/ast/decl.ha
@@ -1,7 +1,9 @@
use hare::lex;
-// let foo: int = 0;
-// const foo: int = 0;
+// A global declaration.
+//
+// let foo: int = 0;
+// const foo: int = 0;
export type decl_global = struct {
is_const: bool,
symbol: str,
@@ -10,13 +12,15 @@ export type decl_global = struct {
init: nullable *expr,
};
-// type foo = int;
+// A type declaration.
+//
+// type foo = int;
export type decl_type = struct {
ident: ident,
_type: _type,
};
-// Represents the @fini/@init/@test attributes associated with a function
+// Represents the @fini/@init/@test attributes associated with a function.
export type fndecl_attrs = enum {
NONE,
FINI,
@@ -24,6 +28,8 @@ export type fndecl_attrs = enum {
TEST,
};
+// A function declaration.
+//
// fn main() void = void;
export type decl_func = struct {
symbol: str,
@@ -33,7 +39,7 @@ export type decl_func = struct {
attrs: fndecl_attrs,
};
-// A declaration
+// A Hare declaration.
export type decl = struct {
exported: bool,
loc: lex::location,
@@ -43,7 +49,7 @@ export type decl = struct {
docs: str,
};
-// Frees resources associated with a declaration
+// Frees resources associated with a declaration.
export fn decl_free(d: decl) void = match (d.decl) {
g: []decl_global => {
for (let i = 0z; i < len(g); i += 1) {
diff --git a/hare/ast/expr.ha b/hare/ast/expr.ha
@@ -1,50 +1,70 @@
use hare::lex;
-// foo
+// An identifier access expression.
+//
+// foo
export type access_identifier = ident;
-// foo[0]
+// An index access expression.
+//
+// foo[0]
export type access_index = struct {
object: *expr,
index: *expr,
};
-// foo.bar
+// A struct field access expression.
+//
+// foo.bar
export type access_field = struct {
object: *expr,
field: str,
};
-// foo.1
+// A tuple field access expression.
+//
+// foo.1
export type access_tuple = struct {
object: *expr,
value: *expr,
};
+// An access expression.
export type access_expr =
(access_identifier | access_index | access_field | access_tuple);
-// alloc(foo)
+// An allocation expression.
+//
+// alloc(foo)
export type alloc_expr = struct {
init: *expr,
capacity: nullable *expr,
};
-// append(foo, bar, (more), baz...)
+// An append expression.
+//
+// append(foo, bar, (more), baz...)
export type append_expr = struct {
object: *expr,
variadic: nullable *expr,
values: []*expr,
};
-// assert(foo), assert(foo, "error"), abort(), abort("error")
+// An assertion expression.
+//
+// assert(foo)
+// assert(foo, "error")
+// abort()
+// abort("error")
export type assert_expr = struct {
cond: nullable *expr,
message: nullable *expr,
is_static: bool,
};
-// foo = bar
+// An assignment expression.
+//
+// foo = bar
export type assign_expr = struct {
op: (binarithm_op | void),
object: *expr,
@@ -76,90 +96,123 @@ export type binarithm_op = enum {
BXOR, // ^
};
-// foo * bar
+// A binary arithmetic expression.
+//
+// foo * bar
export type binarithm_expr = struct {
op: binarithm_op,
lvalue: *expr,
rvalue: *expr,
};
-// foo: int = bar
+// A single variable biding.
+//
+// foo: int = bar
export type binding = struct {
name: str,
_type: nullable *_type,
init: *expr,
};
-// let foo: int = bar, ...
+// A variable binding expression.
+//
+// let foo: int = bar, ...
export type binding_expr = struct {
is_static: bool,
is_const: bool,
bindings: []binding,
};
-// break :label
+// A break expression. The label is set to empty string if absent.
+//
+// break :label
export type break_expr = label;
-// foo(bar)
+// A function call expression.
+//
+// foo(bar)
export type call_expr = struct {
lvalue: *expr,
variadic: bool,
args: []*expr,
};
-// TODO: Should this be rehomed with the checked AST?
+// The kind of cast expression being used.
export type cast_kind = enum {
+ // TODO: Should this be rehomed with the checked AST?
CAST,
ASSERTION,
TEST,
};
-// foo: int
+// A cast expression.
+//
+// foo: int
+// foo as int
+// foo is int
export type cast_expr = struct {
kind: cast_kind,
value: *expr,
_type: *_type,
};
-// [foo, bar, ...]
+// An array constant.
+//
+// [foo, bar, ...]
export type array_constant = struct {
expand: bool,
values: []*expr,
};
+// A single struct field and value.
+//
+// foo: int = 10
export type struct_value = struct {
name: str,
_type: nullable *_type,
init: *expr,
};
-// struct { foo: int = bar, struct { baz = quux }, ... }
+// A struct constant.
+//
+// struct { foo: int = bar, struct { baz = quux }, ... }
export type struct_constant = struct {
autofill: bool,
alias: ident, // [] for anonymous
fields: [](struct_value | *struct_constant),
};
-// (foo, bar, ...)
+// A tuple constant.
+//
+// (foo, bar, ...)
export type tuple_constant = []*expr;
// The value "null".
export type _null = void;
-// A constant
+// A constant expression.
export type constant_expr = (void | bool | _null | lex::value | array_constant |
struct_constant | tuple_constant);
-// continue :label
+// A continue expression. The label is set to empty string if absent.
+//
+// continue :label
export type continue_expr = label;
-// defer foo
+// A deferred expression.
+//
+// defer foo
export type defer_expr = *expr;
-// delete(foo)
+// A delete expression.
+//
+// delete(foo[10])
+// delete(foo[4..42])
export type delete_expr = *expr;
-// :label for (let foo = 0; foo < bar; baz) quux
+// A for loop. The label is set to empty string if absent.
+//
+// :label for (let foo = 0; foo < bar; baz) quux
export type for_expr = struct {
label: label,
bindings: nullable *expr,
@@ -168,10 +221,14 @@ export type for_expr = struct {
body: *expr,
};
-// free(foo)
+// A free expression.
+//
+// free(foo)
export type free_expr = *expr;
-// if (foo) bar else baz
+// An if or if..else expression.
+//
+// if (foo) bar else baz
export type if_expr = struct {
cond: *expr,
tbranch: *expr,
@@ -181,50 +238,78 @@ export type if_expr = struct {
// :label. The ":" character is not included.
export type label = str;
-// len(foo)
+// A length expression.
+//
+// len(foo)
export type len_expr = *expr;
-// { foo; bar; ... }
+// An expression list.
+//
+// {
+// foo;
+// bar;
+// // ...
+// }
export type list_expr = []*expr;
+// A match case.
+//
+// name: type => expr
export type match_case = struct {
name: str,
_type: *_type,
value: *expr,
};
-// match (foo) { int => bar, ... }
+// A match expression.
+//
+// match (foo) { _: int => bar, ... }
export type match_expr = struct {
value: *expr,
cases: []match_case,
default: nullable *expr,
};
-// offset(foo.bar)
+// An offset expression.
+//
+// offset(foo.bar)
export type offset_expr = void; // TODO
-// foo?
+// An error propagation expression.
+//
+// foo?
export type propagate_expr = *expr;
-// return foo
+// A return statement.
+//
+// return foo
export type return_expr = nullable *expr;
-// size(int)
+// A size expression.
+//
+// size(int)
export type size_expr = *_type;
-// foo[bar..baz]
+// A slicing expression.
+//
+// foo[bar..baz]
export type slice_expr = struct {
object: *expr,
start: nullable *expr,
end: nullable *expr,
};
+// A switch case.
+//
+// value => expr
export type switch_case = struct {
options: []*expr, // [] for *
value: *expr,
};
-// switch (foo) { bar => baz, ... }
+// A switch expression.
+//
+// switch (foo) { bar => baz, ... }
export type switch_expr = struct {
value: *expr,
cases: []switch_case,
@@ -241,13 +326,15 @@ export type unarithm_op = enum {
PLUS, // +
};
-// Unary arithmetic
+// A unary arithmetic expression.
+//
+// !example
export type unarithm_expr = struct {
op: unarithm_op,
operand: *expr,
};
-// An expression
+// A Hare expression.
export type 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 |
@@ -255,6 +342,7 @@ export type expr = (access_expr | alloc_expr | append_expr | assert_expr |
size_expr | offset_expr | propagate_expr | return_expr | slice_expr |
switch_expr | unarithm_expr);
+// Frees resources associated with a Hare [[expr]]ession.
export fn expr_free(e: (expr | nullable *expr)) void = match (e) {
e: nullable *expr => match (e) {
null => void,
diff --git a/hare/ast/ident.ha b/hare/ast/ident.ha
@@ -7,7 +7,7 @@ export type ident = []str;
// In other words, the length of "a::b::c" is 5.
export def IDENT_MAX: size = 255;
-// Frees resources associated with an identifier.
+// Frees resources associated with an [[ident]]ifier.
export fn ident_free(ident: ident) void = {
for (let i = 0z; i < len(ident); i += 1) {
free(ident[i]);
@@ -15,7 +15,7 @@ export fn ident_free(ident: ident) void = {
free(ident);
};
-// Returns true if two idents are identical.
+// Returns true if two [[ident]]s are identical.
export fn ident_eq(a: ident, b: ident) bool = {
if (len(a) != len(b)) {
return false;
diff --git a/hare/ast/import.ha b/hare/ast/import.ha
@@ -13,10 +13,10 @@ export type import_objects = struct {
objects: []str,
};
-// An imported module
+// An imported module.
export type import = (import_module | import_alias | import_objects);
-// Frees resources associated with an import.
+// Frees resources associated with an [[import]].
export fn import_free(import: import) void = {
match (import) {
m: import_module => ident_free(m: ident),
diff --git a/hare/ast/type.ha b/hare/ast/type.ha
@@ -1,17 +1,18 @@
use hare::lex;
-// foo
+// A type alias.
export type alias_type = struct {
unwrap: bool,
ident: ident,
};
-// int, bool, ...
+// A built-in primitive type (int, bool, str, etc).
export type builtin_type = enum {
BOOL, CHAR, F32, F64, FCONST, I16, I32, I64, I8, ICONST, INT, NULL,
RUNE, SIZE, STR, U16, U32, U64, U8, UINT, UINTPTR, VOID,
};
+// An enumeration field (and optional value).
export type enum_field = struct {
name: str,
value: nullable *expr,
@@ -23,16 +24,19 @@ export type enum_type = struct {
values: []enum_field,
};
+// The variadism strategy for a function type.
export type variadism = enum {
NONE,
C,
HARE,
};
+// The attributes associated with a function type.
export type func_attrs = enum uint {
NORETURN = 1 << 0,
};
+// A parameter to a function type.
export type func_param = struct {
loc: lex::location,
name: str,
@@ -47,8 +51,13 @@ export type func_type = struct {
params: []func_param,
};
+// The length for a list type which is a slice (e.g. []int).
export type len_slice = void;
+
+// The length for a list type which is unbounded (e.g. [*]int).
export type len_unbounded = void;
+
+// The length for a list type which is inferred from context (e.g. [_]int).
export type len_contextual = void;
// []int, [*]int, [_]int, [foo]int
@@ -57,6 +66,7 @@ export type list_type = struct {
members: *_type,
};
+// Flags which apply to a pointer type.
export type pointer_flags = enum uint {
NULLABLE = 1 << 0,
};
@@ -67,13 +77,16 @@ export type pointer_type = struct {
flags: pointer_flags,
};
+// A single field of a struct type.
export type struct_field = struct {
name: str,
_type: *_type,
};
+// An embedded struct type.
export type struct_embedded = *_type;
+// An embedded type alias.
export type struct_alias = ident;
// struct { @offset(10) foo: int, struct { bar: int }, baz::quux }
@@ -94,12 +107,13 @@ export type tagged_type = []*_type;
// (int, bool, ...)
export type tuple_type = []*_type;
+// Flags which apply to types.
export type type_flags = enum uint {
CONST = 1 << 0,
ERROR = 1 << 1,
};
-// A type
+// A Hare type.
export type _type = struct {
loc: lex::location,
flags: type_flags,
@@ -132,6 +146,7 @@ fn struct_type_free(t: (struct_type | union_type)) void = {
free(membs);
};
+// Frees resources associated with a [[_type]].
export fn type_free(t: (_type | nullable *_type)) void = match (t) {
t: nullable *_type => match (t) {
null => void,
diff --git a/hare/ast/unit.ha b/hare/ast/unit.ha
@@ -4,6 +4,7 @@ export type subunit = struct {
decls: []decl,
};
+// Frees resources associated with a [[subunit]].
export fn subunit_free(u: subunit) void = {
for (let i = 0z; i < len(u.imports); i += 1) {
import_free(u.imports[i]);