Commit Graph

21 Commits

Author SHA1 Message Date
361f529bdc docs: document remaining packages and simplify AST types (#45)
## Summary

- Added doc comments across the codebase: `pkg/lambda`, `pkg/saccharine`, `pkg/codec`, `pkg/engine`, `pkg/iterator`, `pkg/set`, `pkg/convert`, `internal/registry`, and `cmd/lambda`.
- Made lambda and saccharine expression structs use public fields instead of getters, matching `go/ast` conventions.
- Removed superfluous constructors for saccharine and lambda expression/statement types in favor of struct literals.
- Consolidated saccharine token constructors into a single `NewToken` function.
- Removed the unused `trace` package.

## Test plan

- [x] `go build ./...` passes.
- [x] `go test ./...` passes.
- [ ] Verify `go doc` output renders correctly for documented packages.

Reviewed-on: #45
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-02-10 01:15:41 +00:00
bbe027e9f4 style: restructure cli and registry packages (#43)
## Description

The `internal/cli` package had grown to contain both CLI utilities (source/destination I/O) and registry-level abstractions (repr, conversion, engine, marshaler).
This PR separates concerns by moving registry types into `internal/registry` and keeping only CLI I/O types in `internal/cli`.
It also simplifies several core abstractions and aligns naming conventions.

- Move `Source`, `Destination` from `internal/config` to `internal/cli`.
- Move `Repr`, `Conversion`, `Engine`, `Process`, `Codec` from `internal/cli` to `internal/registry`.
- Rename "marshalers" to "codecs" throughout the codebase.
- Simplify `codec.Codec[T, U]` to `codec.Codec[T]` (string-based marshaling only).
- Add `codec.Conversion[T, U]` as a function type alias.
- Change `engine.Engine[T]` from an interface to a function type.
- Merge `Engine.Load()` + `Process.Set()` into a single `Engine.Load(Repr)` call.
- Convert `Saccharine2Lambda` from a struct to standalone conversion functions.
- Replace registry methods (`MustAddMarshaler`, `MustAddEngine`, `MustAddConversions`) with generic free functions (`RegisterCodec`, `RegisterEngine`, `RegisterConversion`).
- Remove unused `internal/config` package (`Config`, `GetLogger`, `ParseFromArgs`).
- Remove unused `pkg/emitter` package.
- Rename `Id()` to `ID()` per Go conventions.
- Add documentation comments and enable `checkPublicInterface` lint rule.
- Rename `reduce_one.go` to `reduce_once.go`.

### Decisions

- `Engine[T]` is now a function type (`func(T) (Process[T], error)`) rather than an interface, since the only method was `Load`.
- `Codec[T, U]` was split into `Codec[T]` (string marshaling) and `Conversion[T, U]` (type-to-type conversion function), which better reflects how they are actually used.
- Registration uses free generic functions (`RegisterCodec`, `RegisterEngine`, `RegisterConversion`) instead of methods on `Registry`, enabling type inference at the call site.

## Benefits

- Clearer separation of concerns between CLI I/O and the registry's internal type system.
- Simpler abstractions: fewer interfaces, fewer wrapper types, fewer indirections.
- Removing unused packages (`config`, `emitter`) reduces maintenance burden.
- Naming conventions (`ID`, codecs, `reduce_once`) are more idiomatic.

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`).
- [x] Tests pass (if applicable).
- [x] Documentation updated (if applicable).

Reviewed-on: #43
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-02-07 05:39:32 +00:00
a3ee34732e refactor: rewrite CLI and internal architecture (#41)
## Description

The old architecture used a monolithic `main()` with a custom arg parser, an event-emitter-based runtime, and a plugin system for optional features.
This PR rewrites the CLI and internal architecture to be modular, extensible, and built around a registry of interchangeable components.

- Replace custom CLI arg parsing with Cobra subcommands (`convert`, `reduce`, `engine list`).
- Introduce a registry system (`internal/registry`) for marshalers, codecs, and engines, with BFS-based conversion path resolution.
- Add type-erased adapter layer (`internal/cli`) with `Repr`, `Engine`, `Process`, `Marshaler`, and `Conversion` interfaces wrapping generic `pkg/` types.
- Replace the event-emitter-based `Runtime` with a simpler `Engine`/`Process` model (`pkg/engine`).
- Add generic `Codec[T, U]` and `Marshaler[T]` interfaces (`pkg/codec`).
- Merge `saccharine/token` sub-package into `saccharine` and rename scanner functions from `parse*` to `scan*`.
- Make saccharine-to-lambda conversion bidirectional (encode and decode).
- Add `lambda.Marshaler` and `saccharine.Marshaler` implementing `codec.Marshaler`.
- Remove old infrastructure: `pkg/runtime`, `pkg/expr`, `internal/plugins`, `internal/statistics`.
- Add `make lint` target and update golangci-lint config.

### Decisions

- Cobra was chosen for the CLI framework to support nested subcommands and standard flag handling.
- The registry uses BFS to find conversion paths between representations, allowing multi-hop conversions without hardcoding routes.
- Type erasure via `cli.Repr` (wrapping `any`) enables the registry to work with heterogeneous types while keeping `pkg/` generics type-safe.
- The old plugin/event system was removed entirely rather than adapted, since the new `Process` model can support hooks differently in the future.

## Benefits

- Subcommands make the CLI self-documenting and easier to extend with new functionality.
- The registry pattern decouples representations, conversions, and engines, making it trivial to add new ones.
- BFS conversion routing means adding a single codec automatically enables transitive conversions.
- Simpler `Engine`/`Process` model reduces complexity compared to the event-emitter runtime.
- Consolidating the `token` sub-package reduces import depth and package sprawl.

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`). Always use underscores.
- [ ] Tests pass (if applicable).
- [ ] Documentation updated (if applicable).

Reviewed-on: #41
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-02-07 03:25:32 +00:00
335ce95c50 feat: add comment support to saccharine language (#25)
## Description

The saccharine language previously lacked comment support, preventing proper code documentation.
This PR implements '#' comment syntax similar to Python.
Comments can appear on their own line or at the end of a line, with all content after '#' ignored until the next newline or EOF.
The tokenizer now detects '#' and skips characters appropriately without creating tokens.

### Decisions

Comments are silently consumed during tokenization rather than being preserved as tokens, keeping the token stream clean for the parser.
The implementation preserves newlines after comments by using the iterator's Back() method, allowing them to be processed as soft breaks.

## Benefits

Developers can now document their saccharine code with inline and full-line comments.
The implementation is minimal and efficient, adding no overhead to the token stream.
Tests verify that comments work correctly in various positions without breaking code execution.

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`). Always use underscores.
- [x] Tests pass (if applicable).
- [x] Documentation updated (if applicable).

Closes #24

Reviewed-on: #25
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-01-13 02:00:00 +00:00
Max
2499921679 style: moved functions around 2025-12-30 15:58:14 -05:00
Max
412d3924eb docs: document methods 2025-12-29 20:44:55 -05:00
Max
aabe92f2dc fix: cannot omit final newline 2025-12-29 20:17:50 -05:00
Max
ee9e71d58e fix: no ds store 2025-12-28 02:07:46 -05:00
Max
0945cedf51 feat: only compute all free variables during a-conversion 2025-12-28 02:07:14 -05:00
Max
4d81aca0b2 feat: fun little program 2025-12-28 00:53:43 -05:00
Max
f038d0a685 feat: parse saccharine, conversion incoming 2025-12-27 23:36:44 -05:00
Max
14fc4b30da feat: cleaner parsing functions 2025-12-27 20:46:10 -05:00
Max
c37e96770f feat: tokenizer accepts braces, line terminator, and equal sign 2025-12-27 19:52:18 -05:00
Max
0e185fbf41 feat: expression 2025-12-27 03:43:19 -05:00
Max
bf0edfc593 style: renamed token index to column 2025-12-27 02:43:17 -05:00
Max
1896cd652d feat: better error messages 2025-12-27 02:39:56 -05:00
Max
884180de92 feat: error for when there is more source code than parsed 2025-12-27 02:08:18 -05:00
Max
5841023dde fix: no log errors 2025-12-27 01:18:52 -05:00
Max
a05a63627e feat: better recursive descent 2025-12-27 01:18:06 -05:00
Max
e3629acb45 feat: stuff 2025-12-26 03:37:05 -05:00
Max
d427703afe wip: new folder structure, overhaul language 2025-12-26 02:39:15 -05:00