9.3 KiB
self-hosting
- milestone: Honey compiles its production compiler, then that compiler compiles itself again and builds/runs the example programs.
current boundary
directory packages support file-local import namespaces and postfix declaration
selection through the interpreter and native backend. concrete 8/16/32/64-bit
integers, checked numeric conversions, records/tuples, construction/defaults,
enums, distinct/alias types, overlapping untagged/tagged unions, field reads/writes
and exhaustive statement/value matching work through both execution paths.
source data pointers/references support aliasing, mutation, calls and aggregate
storage; explicit callback signatures, many-pointer addition, mutable/sentinel
slices, optionals and layout/cast/memory builtins work through both execution paths.
native scalar/pointer c_func declarations support allocator-required libc calls;
executed foreign calls remain diagnostic traps in the interpreter.
explicit fallible channels, composed error sets, try/catch and scoped LIFO
defer/errdefer run through both paths; source errors are values, not diagnostic
traps or compiler infrastructure failures.
cached generic specialization and type-producing procedures support explicit/inferred
compile-time arguments and generated record/array storage through both paths.
ordinary procedures can compute integer/boolean/string compile-time arguments using
mutable locals, loops and recursive calls; general aggregate/type-valued execution,
reflection and generic library acceptance remain open.
the driver retains frontend storage and source provenance through
@source/compilation, with compilation-wide AST node identities.
file commands retain single-file behavior; directory commands compile the
package's production files and load its dependencies in separate scopes.
completed milestone: scalar-function packages
verified: compile and run a small multi-file directory package importing a second
package of scalar functions, through both the interpreter and native backend.
using the existing standard library is a later acceptance gate: even std/mem
needs records, pointers, generics and C calls.
- retain source/package identity and source ownership across the compilation; keep one identifier pool and unambiguous declaration IDs.
- load directory packages once per canonical path, with deterministic file discovery, package scopes and root-only entry selection. follow Bro's existing relative and project-root
@import rules; diagnose cycles rather than recurse indefinitely. - finish postfix namespace selection and resolve file-local import aliases without injecting dependency names into the importing package; bare and aliased import declarations are already parsed for dependency discovery.
- reuse ordinary scalar signature checking, function values and IR calls for selected declarations; namespaces have no runtime representation.
- preserve originating filenames and spans in dependency diagnostics and native runtime traps; retain demand-driven diagnostic recovery.
- verify sibling source files, transitive/shared imports, same-spelled declarations in different packages, alias conflicts, missing packages/members, argument errors and dependency-file diagnostics. preserve existing single-file commands.
visibility follows Bro's public-by-default contract; unsupported visibility attributes must be diagnosed, never ignored. the scalar-function milestone did not include record fields or imported types; those now work for the record/tuple slice. test discovery and FFI remain outside these completed slices.
subsequent dependency gates
- concrete data models: required integer widths/conversions, records/tuples and construction, fields, enums, distinct/alias types, unions and matching. examples:
source/lexer/token.hon,source/sema/resolve.hon,std/mem/mem.hon.- native integer widths (
i8–i64,u8–u64,isize/usize) and checked explicit numeric conversions, including float truncation/range checks and integer-to-float rounding. preserve exact types through arrays, calls and range captures; retain strict implicit conversion rules. - records/tuples, typed/contextual/anonymous construction, field defaults and reads/writes, nested aggregate value copies, imported record types and constructors through interpreter/native execution.
- nominal enums and distinct types, transparent declaration/type aliases, overlapping untagged/tagged unions, contextual payload construction, active-field checks and exhaustive scalar/enum/tagged-union matching through interpreter/native execution. pointer captures, inline specialization and yielding value blocks remain with their respective later gates; error-set composition is covered below.
- native integer widths (
- memory representation: source pointers/references, mutable and sentinel slices, optionals, layout/cast builtins and allocator-required libc calls. internal IR array addresses are not source pointers. examples:
std/mem/mem.hon,std/arraylist/arraylist.hon.- source data pointers/references:
@T/*T,mut, address-taking and dereference, pointer-aware fields/indexing, array.len/.ptr, readonly weakening, location equality, recursive pointer-linked records and shared pointees across interpreter/native calls and aggregate copies. - function-pointer signatures: explicit
@proc(...) Result, structural signature checking, callbacks in parameters/results/records/arrays, vtable calls and imported signature aliases; many-pointer+ usizearithmetic preserves pointee type, mutability, stride and location identity through interpreter/native execution. - mutable/sentinel slices with checked bounds, borrowed aliases and string views; optional values/pointers/callbacks, null checks, unwrap and conditional/loop captures; target layout, pointer/const casts and typed memory copy/set through interpreter/native execution. scalar/pointer C ABI declarations build/run allocator callbacks using
malloc,realloc,freeandposix_memalign; arbitrary interpreter FFI, generic standard-library compilation and native startup/IO remain with later gates.
- source data pointers/references:
- fallible results and cleanup: explicit
T ! E, error-set composition,try/catch,defer/errdefer, error captures and matched error residuals through interpreter/native execution; infrastructure errors remain distinct from diagnostic traps. falliblevoidmay complete on fallthrough; unhandled entry errors exit with status1. inferredT!signatures and yielding catch blocks remain with inference/value-control-flow work. examples:source/main.hon,source/sema/check/check.hon. - generic specialization and compile-time execution/reflection sufficient for existing
ArrayList, hash maps,enummap,metaandio.print; include type/value parameters and compile-time generated storage.- specialization checkpoint: explicit/inferred type and integer/boolean/string/callback/null value parameters, cached concrete runtime calls, nominal type-producing procedures, generated record/array storage and recursive data pointers through interpreter/native execution. preserve declared value types, source diagnostics and repeatable compilation; runtime values cannot supply compile-time arguments.
- compile-time execution checkpoint: ordinary procedure calls with constant inputs and integer/boolean/string results reuse checking, typed IR and bounded interpreter execution. mutable scalar locals, range/while loops, break/continue, nested/generic/recursive calls, exact numeric types, runtime traps and dependency-file provenance survive argument erasure through interpreter/native execution. runtime parameters and mutable global dependencies are rejected; recompilation retains no prior execution state.
- remaining gate: general aggregate/type-valued compile-time execution, explicit compile-time expressions, compile-time branch/inline expansion and reflection (
typeinfo!,field!,struct_type!, generated type/default arrays), plus existing-library acceptance. required collection/index iteration, expression-valued control flow, compound updates, formatting parsing and imported C-binding support may interleave with later gates.
- remaining source constructs: collection/index iteration, expression-valued control flow and
yield, compound updates and multiline strings. examples:source/parser/parse.hon,source/llvm/runtime.hon. - standard-library milestone: compile/run a multi-package program exercising existing allocation and IO, including error cleanup; no replacement miniature standard library.
- native driver integration: required C ABI declarations,
process.Initstartup arguments/IO, actual CLI exit statuses, file loading, temporary files and spawning Clang. Honey-generated programs currently accept only parameterlessmainand print its result; Bro's bootstrap startup support is not Honey backend support. - self-hosting proof: bootstrap-built Honey builds the production compiler (excluding test-only imports); that executable rebuilds the compiler; the rebuilt compiler passes representative interpreter/native examples and CLI/error scenarios without Bro at runtime.
the gates may require interleaving (notably allocation, errors and generics). extend checking, IR and native emission together; accepting syntax alone does not complete a gate. additional targets, a package registry, a replacement linker and interpreter execution of arbitrary FFI are not prerequisites.