hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 74f7f6c412cb701802166fe3a9fb3457497a5b58
parent fc6bfab55d16256f2a47f45732d7a0ecc8df15ce
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 21 Apr 2021 12:06:11 -0400

hare::ast: doc improvements

Diffstat:
Mhare/ast/decl.ha | 18++++++++++++------
Mhare/ast/expr.ha | 160+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mhare/ast/ident.ha | 4++--
Mhare/ast/import.ha | 4++--
Mhare/ast/type.ha | 21++++++++++++++++++---
Mhare/ast/unit.ha | 1+
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]);