Changelog
All notable changes to Korrin are recorded here. The format follows
Keep a Changelog. Korrin is pre-1.0 and
uses 0.MINOR.PATCH; while the major version is 0, any release may contain
breaking changes, which are called out under Changed / Removed.
Unreleased
Milestone 5 is complete: packaging (git-based dependencies, no central
registry) and a community package index. Milestone 4 is complete: a real
language server for VS Code. Milestone 3 is complete: a bytecode compiler and
virtual machine, alongside the tree-walking interpreter rather than replacing
it. Milestone 2 is complete: string interpolation, methods on the built-in
types, exceptions, modules, and the first standard-library modules (math,
io). Milestone 1's entries are further below.
Added — Milestone 5
-
Packages. A bare
import "name"now also checks installed dependencies, alongside the built-in module table it already checked (ADR 0032). A package is a git repository, pinned by tag, branch, or commit in a newkorrin.tomlmanifest, resolved into a newkorrin.lock, and checked out locally under.korrin/packages/— no central registry or hosting of any kind (ADR 0031).# korrin.toml [package] name = "app" version = "0.1.0" [dependencies] greet = { git = "https://github.com/alice/korrin-greet", tag = "v1.0.0" }A package's own dependencies must be empty — packages are leaf-only in this milestone, so there is no dependency-graph solver and no risk of a name collision beyond what TOML already forbids. A dependency name that collides with a built-in module is refused at
add/installtime, not silently shadowed. See specification §12. -
korrin pkg, new subcommands on the existingkorrinbinary:add <git-url> [--tag|--branch|--rev] [--name],remove <name>,install,update [name],list. Implemented by the newkorrin-pkglibrary crate — manifest/lockfile parsing (toml_edit) and git access by shelling out to the installedgitbinary, not a linked git library (ADR 0033). -
A community package index,
korrin-packages/: a second static site alongside this one, listing packages from one JSON file per submission underdata/packages/. Submitting a package is a pull request, not a form — there is no submission backend (ADR 0034).
Added — Milestone 4
-
korrin-lsp, a Language Server Protocol implementation for Korrin: live diagnostics, hover, and go-to-definition, over stdio, synchronous with no async runtime. (ADR 0026, 0027, 0028, 0029.)Diagnostics are the same lex/parse/resolve checks
korrin runperforms, shown live as you type instead of after the fact. Hover, over a builtin function or astr/list/mapmethod, is pulled directly fromdocs/spec/08-builtins.md, embedded into the binary at compile time. Go to definition resolves a local variable, parameter, function, class, or import alias to where it was bound, within the current file (reaching into an imported file is not yet supported).Install with
cargo install --path crates/korrin-lsp. -
A real VS Code extension, in
editors/vscode/: the existing syntax-highlighting grammar now startskorrin-lspand shows what it sends, plus Korrin: Run File / Korrin: Run File (bytecode VM) commands that run the active file in an integrated terminal. (ADR 0030 — this is also where Node and TypeScript enter the repository's tooling, scoped to this one directory.)
Added — Milestone 3
-
A bytecode compiler and virtual machine. Korrin now has a second execution engine. A program is compiled once into flat instruction sequences, one per function, and run by a VM that finds local variables by slot instead of by name. It is roughly 1.7x faster on call-heavy code and 1.5x on local-variable-heavy loops, and about 15% slower on a tight loop over module globals, where slots buy nothing and its operand stack still costs something. (ADR 0022, 0023, 0025.)
korrin run --vm file.korruns a program through it;korrin::run_vmandrun_file_vmare the embedding equivalents. The interpreter remains whatkorrin runandkorrin::runuse. -
korrin bytecode file.korprints the compiled instructions, one chunk per function, alongside the existingkorrin tokensandkorrin ast. -
The tree-walking interpreter is now a permanent differential-testing oracle. Every golden program, every runnable specification example, and every module fixture runs under both engines on each build, and their output must match byte for byte. (ADR 0024.)
-
New
E04xxdiagnostics for the bytecode's operand-width limits (E0401throughE0404): more than 65 535 locals or constants, or more than 255 arguments. Reaching one takes a generated program.
Changed — Milestone 3
-
Name resolution is lexical. The nearest-binding rule is unchanged — assigning to a name an outer scope already binds still updates that outer binding, with no keyword — but "does an outer binding exist?" is now answered from the enclosing program text rather than from the live scope chain. This is what makes local variables compilable to slots. The two engines differ only for a program that reads an outer name after a call that would have created it and before the text that does. (ADR 0022.)
-
Native functions no longer name an execution engine. Builtins, built-in methods, and standard-library functions receive
&mut dyn Hostinstead of&mut Interpreter, whereHostis the four capabilities any engine offers them: output, command-line arguments, a line of input, and a call back into Korrin. One implementation of each now serves both the tree-walking interpreter and the bytecode VM. (ADR 0021.)For embedders this changes the public
NativeFnPtrandNativeMethodFntypes, and movesInterpreter::call_valueonto theHosttrait. No Korrin program behaves differently. -
The
inputbuiltin reads throughHost::read_linerather than reaching forstd::io::stdin()directly, which also makes it testable for the first time.
Added — Milestone 2
-
String interpolation. Every string literal is a template:
"hi {name}"splices thestr()value of each{ expr }hole, evaluated left to right.{{/}}are literal braces. Holes are full expressions and need no escaping for nested strings ("{m["k"]}"). (ADR 0015, specification §1.7 and §4.2.) -
Methods on
str,list, andmap. The.operator now works on the built-in types. New vocabulary:str:len,upper,lower,trim,split,replace,find,contains,starts_with,ends_with,slice,repeat.list:len,push,pop,insert,remove_at,index_of,contains,slice,reverse,sort,join.map:len,keys,values,has,get,remove,pairs.
(ADR 0016, specification §8.2–8.4.)
-
Exceptions.
raise <value>unwinds until atry:/except [name]:/finally:catches it, or it reaches the top level asE0312. Any value may be raised;Error(message?)is the built-in exception type, with.messageand.code. Built-in runtime faults (E0301–E0313) are now catchable — anexceptbinds them as anErrorcarrying the faulting code.finallyruns on every exit path, includingreturn/break/continue. (ADR 0017, specification §5.10–5.11 and §9.6.) -
Keywords
try,except,finally,raise(19 → 23). Parser errorE0107for atrywith no clause, or a danglingexcept/finally. -
Modules.
import "./util"runs a Korrin file (resolved relative to the importing file,.korimplied) and binds a module object —type()is"module", members aremod.name, top-level_names are private.import "./x" as yrenames. Modules load once and are cached;importing the same module twice yields the same object. A circular import isE0315; a module that will not resolve, read, or compile isE0314.import "math"(no./) loads a built-in module. Newkorrin::run_fileAPI;korrin runresolves relative imports against the file's directory. (ADR 0018, specification §11.) -
mathstandard-library module.import "math":sqrt,pow,floor,ceil,round,abs,min,max, and the constantspiande. (ADR 0019, specification §11.4.) -
iostandard-library module.import "io":read_file(path),write_file(path, text), andargs()(command-line arguments). Failures raise a catchableE0316.korrin run script.kor a b cpassesa b ctoio.args(). NewInterpreter::set_args. (ADR 0020, specification §11.5.) -
Keywords
import,as(23 → 25). Parser errorE0108for a malformedimportor a strayas.
Changed — Milestone 2
-
Breaking: a literal
{in a string must now be written{{. No existing Korrin code, spec example, or guide example was affected. -
Breaking: the collection built-in functions are removed in favour of methods (ADR 0016):
Removed Replacement len(x)x.len()append(xs, v)xs.push(v)pop(xs)xs.pop()keys(m)/values(m)m.keys()/m.values()has(m, k)m.has(k)get(m, k, default?)m.get(k, default?)remove(m, k)m.remove(k)print,type,str,int,float,bool,range, andinputremain functions.
Added — Milestone 1
-
Project scaffold: Cargo workspace (
korrinlibrary +korrin-clibinary), toolchain pin, CI, lint configuration. -
Documentation backbone: ADR process and the initial decision records (0000–0013), specification and guide skeletons, contributor docs.
-
spanmodule: byte-offsetSpanandSpanned<T>. -
diagnosticsmodule:Diagnostic,ErrorCode,Severity,SourceMap, andariadne-backed rendering. -
lexermodule: full tokenizer with the indentation state machine (INDENT/DEDENT/NEWLINE), bracket-aware and operator-aware newline suppression, all literal forms, and local error recovery. Specification section 01 (lexical structure) written to match. -
astmodule: expression and statement node types, all span-carrying, plus an S-expressiondumpfor debugging and tests. -
parsermodule: recursive-descent statements + Pratt-parsed expressions, non-associative comparisons, error recovery that reports multiple problems. the grammar (specification section 02) and sections 04, 05 written to match. -
resolvermodule: static validation pass (return/break/continue/superplacement, duplicate parameters, self-inheritance). -
interpretermodule: tree-walking evaluator — values, environments, the nearest-binding rule, closures, classes with single inheritance andsuper, checked integer arithmetic, on-demand stack growth with a recursion backstop. -
builtinsmodule:print,len,type,str,int,float,bool,range,input, and the collection functionsappend,pop,keys,values,has,get,remove. Specification section 08 written to match. -
korrin::runembedding API andInterpreterfor REPL use. -
korrinbinary:run,tokens, andastsubcommands, plus an interactive REPL with multi-line input and expression echo. -
Runnable example programs under
crates/korrin/examples/. -
CI-enforced documentation harnesses:
tests/spec.rsexecutes every runnable example in the specification and the guide,tests/builtins.rschecks builtin/spec agreement both ways,tests/adr.rschecks ADR structure, index completeness, and numbering. -
Golden end-to-end program corpus (
tests/programs/), property tests (tests/properties.rs: the front end never panics), and CLI black-box tests. -
The complete specification (sections 01–10) and the learn-by-example guide.
-
mdBook skeleton (
docs/book.toml,docs/SUMMARY.md) for the eventual site. -
VS Code syntax-highlighting extension (
editors/vscode/) and a workspace.vscode/settings.jsonthat falls back to Python highlighting for.kor. -
playground.kor— a runnable scratch file for experimenting. -
branding/— the Korrin mark, wordmark, favicon, and usage notes. -
korrin-web/— the website: a static landing page plus the full guide, specification, and design notes rendered fromdocs/by mdBook (themed to the Korrin identity).scripts/deploy-site.shbuilds and deploys it to Cloudflare Pages.
Changed — Milestone 1
selfis no longer a keyword; it is a conventional identifier (the name of a method's first parameter). The reserved-word count is now 19. See ADR 0006.- Scoping is function-level, not block-level: a name first assigned inside an
if/while/forbody stays visible afterwards. See ADR 0011. - The grammar moved from a standalone
korrin.ebnffile into specification §2 — one source, and it renders in the documentation site.