Both the saccharine and lambda packages need tokenizing and parsing primitives.
This PR extracts shared token infrastructure into a new pkg/token package, then wires both languages up to use it.
Add pkg/token with a generic Token[T] type, Scan, ScanAtom, ScanRune, ScanCharacter, IsVariable, ParseRawToken, and ParseList.
Refactor pkg/saccharine to delegate to pkg/token, removing duplicated scanning and parsing helpers.
Implement Codec.Decode for pkg/lambda (scanner + parser) using the shared token package.
Add iterator.While for predicate-driven iteration.
Rename iterator.Do to iterator.Try to better describe its rollback semantics.
Decisions
The Type constraint (comparable + Name() string) keeps the generic token flexible while ensuring every token type can produce readable error messages.
iterator.Do was renamed to iterator.Try since it describes a try/rollback operation, not a side-effecting "do".
Benefits
Eliminates duplicated token, scanning, and parsing code between languages.
Enables the lambda package to decode (parse) lambda calculus strings, which was previously unimplemented.
Makes it straightforward to add new languages by reusing pkg/token primitives.
Checklist
Code follows conventional commit format.
Branch follows naming convention (<type>/<description>). Always use underscores.
Tests pass (if applicable).
Documentation updated (if applicable).
## Description
Both the `saccharine` and `lambda` packages need tokenizing and parsing primitives.
This PR extracts shared token infrastructure into a new `pkg/token` package, then wires both languages up to use it.
- Add `pkg/token` with a generic `Token[T]` type, `Scan`, `ScanAtom`, `ScanRune`, `ScanCharacter`, `IsVariable`, `ParseRawToken`, and `ParseList`.
- Refactor `pkg/saccharine` to delegate to `pkg/token`, removing duplicated scanning and parsing helpers.
- Implement `Codec.Decode` for `pkg/lambda` (scanner + parser) using the shared token package.
- Add `iterator.While` for predicate-driven iteration.
- Rename `iterator.Do` to `iterator.Try` to better describe its rollback semantics.
### Decisions
- The `Type` constraint (`comparable` + `Name() string`) keeps the generic token flexible while ensuring every token type can produce readable error messages.
- `iterator.Do` was renamed to `iterator.Try` since it describes a try/rollback operation, not a side-effecting "do".
## Benefits
- Eliminates duplicated token, scanning, and parsing code between languages.
- Enables the `lambda` package to decode (parse) lambda calculus strings, which was previously unimplemented.
- Makes it straightforward to add new languages by reusing `pkg/token` primitives.
## Checklist
- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`). Always use underscores.
- [x] Tests pass (if applicable).
- [ ] Documentation updated (if applicable).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
Both the
saccharineandlambdapackages need tokenizing and parsing primitives.This PR extracts shared token infrastructure into a new
pkg/tokenpackage, then wires both languages up to use it.pkg/tokenwith a genericToken[T]type,Scan,ScanAtom,ScanRune,ScanCharacter,IsVariable,ParseRawToken, andParseList.pkg/saccharineto delegate topkg/token, removing duplicated scanning and parsing helpers.Codec.Decodeforpkg/lambda(scanner + parser) using the shared token package.iterator.Whilefor predicate-driven iteration.iterator.Dotoiterator.Tryto better describe its rollback semantics.Decisions
Typeconstraint (comparable+Name() string) keeps the generic token flexible while ensuring every token type can produce readable error messages.iterator.Dowas renamed toiterator.Trysince it describes a try/rollback operation, not a side-effecting "do".Benefits
lambdapackage to decode (parse) lambda calculus strings, which was previously unimplemented.pkg/tokenprimitives.Checklist
<type>/<description>). Always use underscores.