Tya Roadmap
ROADMAP.md is the single source of truth for current TODO, TASK, and roadmap planning.
Pre-v0.1 planning documents and self-host migration notes are archived under docs/archive/pre-v0.1/. They are historical references, not current language or implementation authority.
Self-Host Invariant
The Tya-written compiler fixed point is a maintained invariant. Later language, runtime, CLI, stdlib, and documentation work must not regress selfhost/v01/compiler.tya.
Required evidence:
go test ./tests -run TestSelfhostV01Scripts -count=1
This gate proves that the Tya-written compiler can compile itself to stable stage-2/stage-3 C output, and that the self-hosted stage-2 compiler can compile and run representative programs through the maintained surface.
Current Direction
Tya is implemented as a small compile-to-C language. The latest released specification is v0.23. Frozen release documents live under docs/vX.Y.Z/ and docs/vX.Y/; the latest editable specification, API, stdlib, and naming documents live directly under docs/.
Tya uses semantic versioning. Specification changes happen at the minor version level, such as v0.23 and v0.24. Patch releases such as v0.23.1 must not change language or standard-library semantics.
Latest editable documentation:
The reference implementation is:
Go lexer
Go parser
Go AST
Go checker
Go C emitter
C runtime
specification tests
Go interpreter behavior, ASTMODE, and legacy archived node-string experiments are not specification authority. The maintained selfhost/v01/compiler.tya fixed point must not regress.
Implementation Tooling Policy
The compiler implementation should stay hand-written:
Go lexer
Go parser
Go AST
Go checker
Go C emitter
Do not add a parser generator or large grammar framework. In particular, avoid introducing Participle, goyacc, Pigeon, ANTLR, or Tree-sitter as compiler front-end authority. They may be useful references or future editor tooling, but the active compiler path should remain explicit Go code.
After the Go implementation reaches a complete lexer, parser, AST, checker, and C emitter for the current specification, continue self-host work in the same component order:
Tya lexer
Tya parser
Tya AST
Tya checker
Tya C emitter
Each Tya component must preserve the self-host fixed point before moving to the next component.
Use small test-support dependencies where they make the specification easier to verify:
github.com/google/go-cmp/cmp
github.com/rogpeppe/go-internal/testscript
Use go-cmp for readable token, AST, diagnostic, and generated-output diffs. Use testscript for CLI-level specification tests, especially tya run, tya build, expected stdout/stderr, and negative examples.
Current Roadmap
- [x] Ship v0.24 scripting toolkit and lightweight numerics
- [x] Define v0.24 scope
- [x] Add
docs/v0.24/SPEC.md. - [x] Add
time,random,process,hex,digest,secure_random, andmatrixstandard modules. - [x] Expand
mathwithsqrt,pow,floor,ceil,round,trunc,log,log2,log10,exp,sin,cos,tan,asin,acos,atan,atan2,pi,e. - [x] Keep all native-backed APIs import-only and explicit.
- [x] Use structured
raisefor native operation failures. - [x] Keep byte-array type, streaming digest, HTTP/TCP/UDP/TLS, regex, yaml, xml, markdown, async/threads, subprocess pipes, matrix inverse/eigenvalues, and shell-string parsing out of v0.24.
- [x] Implement the
timemodule - [x] Add
time.now,time.sleep,time.format,time.parse,time.since. - [x] Use UNIX timestamp seconds (float, sub-second precision) as the time value.
- [x] Support
"iso","date","time","unix"format layouts. - [x] Raise on invalid
time.parseinput or negativetime.sleepargument. - [x] Implement the
randommodule (PRNG, seedable) - [x] Add
random.seed,random.int,random.float,random.choice,random.shuffle. - [x] Use a Mersenne Twister or equivalent PRNG; seedable by int or string.
- [x] Raise on empty
random.choiceinput or invalidrandom.intrange. - [x] Expand the
mathmodule - [x] Wire libm functions (
sqrt,pow,floor,ceil,round,trunc,log,log2,log10,exp, trig and inverse trig,atan2). - [x] Expose
math.piandmath.eas numeric constants (not functions). - [x] Raise on
sqrtof negative numbers and on non-positivelogarguments. - [x] Implement the
processmodule - [x] Add
process.run(command, options)returning{exit_code, stdout, stderr}. - [x] Accept array form only (no shell-string).
- [x] Support
cwd,env, andinputoptions. - [x] Buffer stdout/stderr fully into memory.
- [x] Raise only on launch failures; non-zero exit codes are returned in the result.
- [x] Implement the
hexmodule - [x] Add
hex.encode(lowercase) andhex.decode(case-insensitive). - [x] Raise on odd-length or non-hex input to
hex.decode. - [x] Implement the
digestmodule - [x] Add
md5,sha1,sha256,sha384,sha512returning lowercase hex strings. - [x] Implement digests in C without external deps for portability (target macOS and Linux).
- [x] Hash UTF-8 bytes of the input string; do not introduce a byte-array type.
- [x] Implement the
secure_randommodule - [x] Add
bytes,hex,base64,uuid(RFC 4122 v4), andint. - [x] Source entropy from
getentropy(macOS/BSD),getrandom, or/dev/urandomas fallback. - [x] Use rejection sampling in
secure_random.intto avoid modulo bias. - [x] Implement the
matrixmodule (pure Tya) - [x] Represent a matrix as
{rows, cols, data}. - [x] Add
new,zero,identity,at,set,add,sub,scale,mul,transpose,det,equal?. - [x] Implement
detvia cofactor expansion for sizes up to 4x4; raise for larger sizes. - [x] Validate dimensions on construction and per-operation.
- [x] Keep v0.24 documentation and tests aligned
- [x] Update latest docs when v0.24 behavior is implemented.
- [x] Keep
docs/v0.24/aligned with the v0.24 minor specification. - [x] Regenerate HTML documentation with
node scripts/build_docs_pages.js. - [x] Add unittest-form tests for each new module.
- [x] Preserve the
selfhost/v01/compiler.tyafixed point. - [x] Ship v0.25 bit-level operations and byte sequences
- [x] Define v0.25 scope
- [x] Add
docs/v0.25/SPEC.md. - [x] Specify bitwise operators
&,|,^,~,<<,>>on integers. - [x] Specify the
bytesvalue type withb"..."literal,\xHHescapes, indexing returning int, slicing, concat, len. - [x] Specify
file.read_bytesandfile.write_bytes. - [x] Specify bytes-aware updates to
digest,secure_random,hex, andbase64(keep string input compatibility). - [x] Document the
hex.decode/base64.decodereturn-type breaking change (now bytes). - [x] Keep arbitrary-precision integers, fixed-width integer types, mutable byte buffers, character-set conversion, and streaming IO out of v0.25.
- [x] Add bitwise operators
- [x] Lex
&,|,^,~,<<,>>tokens (avoid conflict with existing operators). - [x] Add precedence levels to the parser.
- [x] Reject non-integer operands with structured errors.
- [x] Emit C bitwise operators in codegen on
(long)x.number. - [x] Add eval support for the new operators.
- [x] Add the
bytesvalue type - [x] Add
TYA_BYTESvalue kind with separate length to the C runtime. - [x] Add
bytes,bytes_of,bytes_text,bytes_array,bytes_concat,bytes_slicebuiltins. - [x] Lex and parse
b"..."literals with\xHHescapes. - [x] Wire indexing, length, equality, concat through eval and codegen.
- [x] Update
kindto return"bytes". - [x] Add binary file I/O
- [x] Add
file.read_bytes(path)andfile.write_bytes(path, b)builtins. - [x] Wire stdlib
filemodule wrappers. - [x] Update existing stdlib for bytes
- [x] Make
digest.*accept either string or bytes. - [x] Change
secure_random.bytes(n)to return a bytes value. - [x] Make
hex.encodeaccept either string or bytes;hex.decodereturns bytes. - [x] Make
base64.encodeaccept either string or bytes;base64.decodereturns bytes. - [x] Keep v0.25 documentation and tests aligned
- [x] Update latest docs when v0.25 behavior is implemented.
- [x] Keep
docs/v0.25/aligned with the v0.25 minor specification. - [x] Regenerate HTML documentation with
node scripts/build_docs_pages.js. - [x] Add unittest-form tests for bitwise operators, the bytes type, binary IO, and the migrated digest/secure_random/hex/base64 modules.
- [x] Preserve the
selfhost/v01/compiler.tyafixed point. - [x] Ship v0.26 external packages and version resolution
- [x] Define v0.26 scope
- [x] Add
docs/v0.26/SPEC.md. - [x] Specify the
tya.tomlmanifest (name, version, dependencies, dev-dependencies). - [x] Specify the
tya.locklockfile (deterministic resolved versions, source identity, checksums). - [x] Specify version constraint syntax (
^x.y.z,~x.y.z,>=x.y.z, <a.b.c, exact). - [x] Specify Bundler-style single-version-per-package resolution with backtracking.
- [x] Specify git and path sources; defer central registry to a later version.
- [x] Specify import resolution order: same dir →
tya.tomldeps →TYA_PATH→ bundled stdlib. - [x] Specify the package directory layout (
src/for public modules). - [x] Implement manifest and lockfile parsing
- [x] Parse
tya.tomlvia thetomlstandard module. - [x] Validate manifest fields and version strings.
- [x] Read and write
tya.lockdeterministically. - [x] Implement version constraint resolver
- [x] Implement backtracking dependency resolver picking the highest valid version.
- [x] Detect and report unsolvable constraint sets (diamond conflicts) with source-oriented diagnostics.
- [x] Implement source fetchers
- [x] Add a git fetcher (clone + checkout tag/rev) with caching under
.tya/cache. - [x] Add a path fetcher (symlink or direct read).
- [x] Verify and record checksums in the lockfile.
- [x] Wire dependency loading into module resolution
- [x] Resolve manifest-declared dependencies before
TYA_PATHand bundled stdlib. - [x] Honor the lockfile for reproducible loads.
- [x] Preserve same-directory precedence.
- [x] Add CLI commands
- [x] Add
tya install(resolve and write lockfile, download packages to.tya/packages/). - [x] Add
tya update [pkg](recompute the lockfile for one or all packages). - [x] Add
tya add <pkg> [constraint]andtya remove <pkg>(edittya.toml+ re-resolve). - [x] Add
tya outdated(report newer versions available). - [x] Report missing or conflicting requirements with source-oriented diagnostics.
- [x] Keep v0.26 documentation and tests aligned
- [x] Update latest docs when v0.26 behavior is implemented.
- [x] Keep
docs/v0.26/aligned with the v0.26 minor specification. - [x] Regenerate HTML documentation with
node scripts/build_docs_pages.js. - [x] Add CLI, resolver, fetcher, and lockfile tests.
- [x] Preserve the
selfhost/v01/compiler.tyafixed point. - [x] Ship v0.27 hexadecimal and binary integer literals
- [x] Define v0.27 scope
- [x] Add
docs/v0.27/SPEC.md. - [x] Specify
0xFF/0xffhexadecimal integer literals. - [x] Specify
0b1010binary integer literals. - [x] Specify underscore digit-group separators in decimal, hex, and binary literals.
- [x] Keep octal literals, hex floats, numeric type suffixes, and big-int out of v0.27.
- [x] Implement hex and binary literals
- [x] Lex
0x/0Xfollowed by hex digits (and underscores) into anINTtoken. - [x] Lex
0b/0Bfollowed by binary digits (and underscores) into anINTtoken. - [x] Reject
0x/0bwith no digits, and digits outside the base. - [x] Allow underscore separators in plain decimal integer and float literals.
- [x] Make value handling identical to existing decimal integer literals (no AST change required).
- [x] Keep v0.27 documentation and tests aligned
- [x] Update latest docs when v0.27 behavior is implemented.
- [x] Keep
docs/v0.27/aligned with the v0.27 minor specification. - [x] Regenerate HTML documentation with
node scripts/build_docs_pages.js. - [x] Add lexer and end-to-end tests for hex, binary, and underscore literals.
- [x] Preserve the
selfhost/v01/compiler.tyafixed point. - [ ] Ship v0.28 strict compile-time checks
- [x] Define v0.28 scope
- [x] Add
docs/v0.28/SPEC.md. - [x] Specify shadowing forbidden across nested scopes.
- [x] Specify unused imports as compile errors.
- [x] Specify unused function arguments as compile errors with
_opt-out. - [x] Specify unused private top-level definitions (leading
_) as compile errors. - [x] Keep unused-local-variable check opt-in via
--check-unused. - [x] Keep tab/trailing-whitespace lint, main.tya restriction, and naming-convention expansions out of v0.28.
- [ ] Implement shadowing check
- [ ] Track enclosing scope chain in the checker.
- [ ] Reject any new binding that matches a name visible in a strictly enclosing scope.
- [ ] Allow same-scope reassignment.
- [ ] Treat
_as a non-binding discard; underscore-prefixed names still bind. - [ ] Implement unused-import check
- [ ] Track module/alias bindings introduced by
import. - [ ] Mark them used on any read.
- [ ] Diagnose any unused binding at the importing file's top level.
- [ ] Implement unused-argument check
- [ ] Track parameter names per function.
- [ ] Mark used on any read in the body.
- [ ] Skip names equal to
_and names starting with_. - [ ] Skip parameters of abstract method declarations.
- [ ] Implement unused-private-top-level check
- [ ] Detect top-level bindings whose names start with
_. - [ ] Diagnose if no expression in the file references the name.
- [ ] Migrate the project to satisfy the new checks
- [ ] Audit stdlib, examples, and tests for shadowing / unused imports / unused args / unused private defs and fix or rename to
_. - [ ] Preserve the
selfhost/v01/compiler.tyafixed point. - [ ] Keep v0.28 documentation and tests aligned
- [ ] Update latest docs when v0.28 behavior is implemented.
- [ ] Keep
docs/v0.28/aligned with the v0.28 minor specification. - [ ] Regenerate HTML documentation with
node scripts/build_docs_pages.js. - [ ] Add positive and negative tests for each new check.
Verification Reference
Default verification:
go test ./... -count=1
Focused verification should prefer tests for the touched lexer, parser, checker, C emitter, runtime, examples, stdlib, or docs. The self-host fixed-point gate is part of the maintained project invariant and must stay green.