Repository navigation
Releases: synodlang/compiler
Release list
v0.3.0
Implements Synod 0.3. synod version prints language 0.3, synod new writes synod 0.3, and trace headers say "synod":"0.3". A synod.mod that says an older version (synod 0.2) is still accepted, and the version line does not gate features; a newer one (synod 0.4) is an error.
Changed
- The embedded
look/basicfollowsstd: message tags show only mid-flight. Scene ids and goldens change; traces are unchanged. look.Flightmoves the flown shape from the edge ofato the edge ofb, 8 clear of each box (thePlacesize model, group extents, proportional clamp when the cards are close, halfway between the clipped ends when dropped; straight up above the shape when both are at one position). Scenes with flights change; traces are unchanged. The embedded std followsstd.- The
ringlayout is wider and sits higher: radii 380 and 170 (growth up to 1.4 in height), and the ring, row and grid layouts centre on (520, 315), 10 above the scene centre, since state rows hang below the cards. An even number of cards turns half a slot counter-clockwise, son1is at the left or top left. Scenes change; traces are unchanged. sim.StateRowsgives each row at most 24 characters (StateRowMax): a longer one keeps its first 23 and ends in…. Look-only, so traces keep full values. The embedded std and the vendored examples followstdandexamples.- The fit test also checks a mid-scene key, that every state row has at most 24 characters, that rows clear other cards and icons by 8, and that no two labels overlap.
- The embedded
look/basicwrites the lesson note at the top of the canvas (y40). The fit test measures notes and reasons against cards, rows, heads, icons, counters and each other, with no exclusion, and counts a counter as a box. - The embedded and vendored
paxoskeeps its promise, accepted proposal and round onstd/disk; only the paxos trace gainsdisk.Writtenevents, every other trace is byte-identical. - Scenes use a 1040 by 650 canvas with its centre at (520, 325),
look.Orbithas radius 200, and theringlayout is an ellipse (radii 300 and 150, turned half a slot for an even number of cards, growing up to 1.4 with the number of cards). Default-theme scenes change once; traces are unchanged. The embedded std and the vendored examples followstdandexamples. look.Place s beside tputsson the right oftwhen its box lies inside the canvas there (tat the position it settles at) and on the left oftotherwise, with the same gap and sizes; the side is chosen when thePlaceruns. Scenes with a note beside a card at the right edge change; traces are unchanged. The fit test also checks every label at each of its own key times.
Fixed
synod new demois refused likemain,timeandsim, with or without--lib: the packagedemocollided withdemo/demo.synod, the main program, which overwrote the library.synod check(andfmt,doc) over a folder that holds two module folders with the samemodulepath, such ascounter/synod.modandproj/counter/synod.mod, panicked while lowering because both modules' packages shared one import path. It now reportserror[duplicate-name]: module "counter" is declared by two folders, counter and proj/counterat the secondsynod.mod, with the hint to check one module folder at a time, and exits 1.
v0.2.7
Implements Synod 0.2. The documentation is now checked against the compiler, and synod get downloads are byte-exact.
Added
internal/formsandinternal/forms/cmd/doccheck(not linked intosynodorsynod.wasm): the catalog of the forms ofspec/02, the types ofspec/04, the contexts ofspec/05and the std packages, checked against the spec text, anddoccheck, which checks the tutorial and the Library examples ofdsl(decisions 104 and 105): coverage, order of introduction,synod newandexamples/raftcopies, golden summaries, "why" programs and one runnable example per std phrase. Adocsjob in CI runs it once the pinneddslhas a tutorial.
Changed
synod explain --json:example.filesholds every file the example is checked or run with, the impliedsynod.modincluded (decision 111). The text form,--catalogand the MCP tool are unchanged.
Fixed
synod getchecks out modules byte for byte (no line-ending, filter or attribute conversion), refuses symbolic links by tree mode and tolerates twosynod getprocesses racing on the store.
v0.2.6
Implements Synod 0.2. Tools for people and agents: synod doc and synod explain answer questions from the command line, synod new and synod get start a module and fetch what it requires, and synod mcp serves the lot to agents that have no shell.
Added
synod doc [package]: prints a package's phrases, records andNodefields from its source, or lists the visible packages.--jsonprintssynod-doc/1,--scope filegives the scope of one file for editors,--overlay filereads unsaved buffers and--catalogprints the std catalog as Markdown.synod explain [code]: explains a diagnostic code with an example and its fix, or lists the 38 codes.--jsonprintssynod-explain/1;--catalogprints the table of codes, meanings and fixes as Markdown.synod new <dir> [--module path] [--lib]: creates a module withsynod.mod,.gitignore, a package folder and ademo.synodmain file that checks and runs.synod get [module@version]: makesvendor/andsynod.summatch the build list, downloading what the store lacks withgitand verifying the commit and the tree hash.synod mcp [--root dir]: a stdio MCP server with the toolsdoc,explain,check,run_summaryandfmt; each gives the text of the matching command.
Changed
- The embedded std matches std v0.2.2: every phrase, record and field has a doc comment, and these comments are what
synod docprints. synod versionlists the new formats:formats synod-trace/1 synod-scene/1 synod-check/1 synod-doc/1 synod-explain/1. The same list is insynod.version()of the WebAssembly build.
v0.2.5
Implements Synod 0.2. Editors and learning modes: synod check can read unsaved
buffers and still colors a file that does not parse, lesson.Ask can offer
choices, and a run-time error inside std now points at the user's own code.
Added
synod check --overlay <file>(synod-overlay/1): checks each listed.synodfile orsynod.modas if it held the content of another file; diagnostics and tokens keep the original path and positions. A missing overlay, a bad format or a key that is not an existing file is exit 2.synod check --json --tokenslists lexical tokens (language,value,commentandname, withoutdef) for a file that fails to lex or parse, for every other file of its package and for extra main files, so an editor keeps its highlighting while the user types.lesson.Ask [q: text] choosing [c: list of text]for Predict: 2 to 6 distinct, non-empty choices, else abad-argumentrun-time error.scene.jsonshapes carrynodeandmsg(the node or message a shape stands for), andpausemarkers carrychoiceswhen the question has choices.
Changed
- A run-time error raised while std code runs is reported at the position in user code of the call that entered std, in the trace (
sim.Failed), thefailed atandlook failed atlines, the scene'sfailedmarker and the rich form; the std position is kept as a note (decision 89).lesson.Ask … choosingwith bad choices now points at thelesson.Askcall, not atstd/lesson/lesson.synod. - The trace record
lesson.Askedgains the fieldChoices({}for a plainlesson.Ask), so every trace and summary of a program with a question changes.
v0.2.4
Implements Synod 0.2. The compiler now also runs in the browser: synod.wasm
checks, formats, runs and draws programs with exactly the same output as the
command line, ready for the website's interactive examples.
Added
synod.wasm, the compiler for WebAssembly (GOOS=js GOARCH=wasm, built fromcmd/synod-wasm): a globalsynodwith the synchronous functionscheck,run,formatandversion. They take the program as afilesobject and return the CLI's check.json, status, summary, trace and scene as text, byte-identical to the native build; they never throw (errors are{code, message}with exit code 2). std is embedded; other modules come infilesundervendor/.- Release assets
synod-<tag>.wasm(about 8.4 MiB, 2.2 MiB gzipped) andsynod-<tag>-wasm_exec.js(from the Go toolchain that built the module), both listed inSHA256SUMS.go run ./internal/release/cmd/wasm -tag <tag> -out distbuilds them and fails over the size budget (9.5 MiB, 2.75 MiB gzipped). - CI runs the runtest and driver goldens compiled to WebAssembly under Node, diffs the trace and scene hashes against Linux, and compares the JS API running in Node with the native API and the goldens (
internal/wasmtest).
Changed
- The call-depth limit is 500 nested calls on every target (it was 10000), in the simulator and in the scene builder (
value.MaxCallDepth): the WebAssembly build overflows the JS stack of plain Node at about 3000 nested calls, and browsers can have smaller stacks. Therun-limitmessage is stillmore than <limit> nested calls. synod checkandsynod fmtskip folders namedvendorwhen they walk a folder, liketestdata,.xand_x; an explicit file or folder argument is still processed.
v0.2.3
Implements Synod 0.2, now complete. synod run draws the run: next to the
trace it writes scene.json, the animation the player will show. Programs
without their own look are drawn by the default look: node cards with their
state, messages flying between nodes, crashes, broken invariants and
captions.
Added
synod runwritesout/scene.json(synod-scene/1) next to the trace and printsscene <length>, <n> shapes -> out/scene.json(the length in seconds, such as147.98s) after the existing status lines. The scene is written for every run, also aftersim.Failed;--summaryprints the same text as before and writes the scene silently.--scene file(-for stdout, with the status lines on stderr;--trace -and--scene -together exit 2),--pace x(0.25 to 4, up to three decimals) and--mode ordered|proportional.--watchand--json-eventsstill exit 2.- The scene builder runs the observers of the program's looks over the facts of the run. A program that does not use
std/lookis drawn bystd/look/basic: node cards, state rows, message flights, thesim.Brokenborder and lesson captions. - A fault inside a look is a look failure, not part of the trace:
look failed at <time>: <pos>: error[<code>]: <message>, exit 1, and a partial scene with afailedmarker. trace.Decodereadstrace.jsonlback into facts;Build(facts)equalsBuild(Decode(Encode(facts))).- std:
look.Flight,net.Id,net.Type,sim.StateRows, andlook.Tweenof"x"and"y"to a shape;look.Travel,look.Removeandstd/look/basicare ordinary Synod. - Golden
scene.jsonfor every example, scene determinism over 20 seeds, scene hashes in the cross-OS CI job,FuzzScenein the weekly fuzz run, andBenchmarkScenePing5000. - The
runfuzz target and the generator now also build scenes, with generated looks.
Changed
- The status of a failed run is followed by the scene line, so the rich
failed at …goldens oftestdata/run/errorsend with it.
v0.2.2
Implements Synod 0.2. Errors now look like a good compiler's: on a terminal,
every compile-time and run-time error shows the source line, underlines the
exact problem, points at related places ("first defined here", "called from
node context here", "this is 0") and shows the fix as a diff. Piped output,
which agents and CI read, is unchanged byte for byte.
Added
--style rich|shortand--color auto|always|neveronsynod fmt,checkandrun(both--flag valueand--flag=value; a bad value exits 2). Rich output draws the source line with markers, labels, notes and help under the unchanged first line; it is the default when the destination is a terminal. Piped or redirected output stays the one-line form byte for byte. Color needsNO_COLORunset or empty andTERMother thandumb; the flags beat the environment.--jsonignores both flags.synod runfailures render a snippet under thefailed at …line in rich style.check.jsondiagnostics gainend, andlabel,labels,help(with edits) andnoteswhen present; the format stayssynod-check/1.- A diagnostic without a position prints as
path: error[code]: message. - Fixes shown under
help:for missing parentheses, imports to add, remove
or rename, the package header, canonical form, receivers,sim.Nobody,
"did you mean" names and more; each is tested to remove its error. - Hidden control and bidi characters in source are neutralised in snippets,
so a file cannot inject terminal escapes. - Golden cases of
testdata/checkhaveexpect-rich.txtandexpect.jsonnext toexpect.txt;testdata/run/errorscases haveexpect-rich.txt.
v0.2.1
Implements Synod 0.2. synod run simulates a program deterministically and writes its trace.
Added
synod run <folder>checks the folder's main file and runs it in the
deterministic simulator: simulated time, nodes with crash and restart,
a network with latency, loss, partitions and targeted drops, per-node
disk, and thealwaysinvariants checked after every step. It writes
out/trace.jsonl(synod-trace/1) and prints one status line. The same
program and seed give a byte-identical trace on every platform.--seed n(or--seed=n, a whole number from 0 to 2^53) replaces the
seed of the run; it wins oversim.Seed. Without either the seed is 1.--trace filechooses the trace file (parents are created);--trace -
writes the trace to stdout and the status line to stderr.--summaryprints a compact text summary of the run (steps that
recorded facts, invariant results, final state of every node) instead of
the status line, for agents.- Every native phrase of the std catalog works:
sim,net,time,
random,lists,maps,math,text,disk. Thelookphrases and
the observers wait for a later release;--scene,--pace,--mode,
--watchand--json-eventsare recognized and exit 2 with
not implemented yet. - Run-time errors, reported as the last
sim.Failedline of the trace,
failed at <time>: <pos>: error[<code>]: <message>and exit 1:
missing-key,index-range,division-by-zero,nobody,disk-type,
time-limit(10 minutes of simulated time),bad-argument,
number-rangeandrun-limit(steps at one instant, call depth,
collection size). - Exit codes of
synod run: 0 for a run that ended (also when analways
broke, which is a result, not an error), 1 for diagnostics or a failed
run, 2 for usage and I/O errors.
Changed
sim.Seedandmath.Hashare specified completely in the std catalog
(domain and precedence of the seed; the exact FNV-1a based hash).- Demo seeds that did not tell their story under the final simulator
semantics were changed (gossip 15, paxos 105, twopc 1, cassandra 4) and
the ring demo places other keys; see "Notes for implementers" in the
examples.
v0.2.0
synod check now understands whole programs: it loads modules, finds the
phrase every sentence calls, and checks types and contexts, reporting every
compile-time error of specification v0.2.1. Running programs
(synod run) comes in the next release.
Added
- Language types and their acceptance rules (
list of T,map of K to V,
node typesNodeandp.Node). - The standard library, embedded in the binary: every phrase of the std
catalog, with native declarations and the phrases written in Synod. - Module loader:
synod.mod, package graph, main files next to their
library,std/imports, remote modules from the
module'svendor/folder, import cycles. - Fixes that need the package loaded, for
synod fmt: record settings
order, name case, and a dropped own-package qualifier. synod checknow checks whole programs, not just their form. It finds
the phrase every sentence calls, checks the types of values (arguments,
operands, list and map items, node types such asraft.Node, and
results), infers the type of{}from how it is used, and reports
every error code of the specification:type-mismatch,ambiguous-empty,
missing-result,value-as-statement,action-as-value,context
(what may run in node, main, check and look code) andforeign-state
(node code that touches another node's state). Every example and every
std package checks clean.
Changed
synod fmtapplies the fixes above when the package loads; a file in a
package that does not load is formatted as before.- Diagnostic paths are shown relative to the working directory when inside it.
- CI and release workflows use the Node 24 versions of GitHub Actions.
v0.1.0
The first release: the front end of the Synod compiler. It reads, checks
the form of, and formats Synod source for specification v0.2.0. Running
programs (synod run) comes in a later release.
Added
synod fmt [paths…]rewrites.synodfiles into canonical form;
--checklists the files that would change and exits 1.synod check [paths…]reports syntax, indentation, header and
canonical-form errors, with a hint showing the canonical line;
--jsonprints thesynod-check/1format.synod versionprints the language, compiler and format versions; the
compiler line shows the release tag and the commit it was built from.- Lexer and parser for the whole structure grammar: indentation blocks,
comments, continuation lines (else,otherwise), holes, typed
collections, members, import paths. - Canonical formatting: numbers, durations and colors respelled; single-item
parentheses removed;not (…)rewritten to the direct operator; imports
hoisted and sorted; blank lines and comments laid out. - Binaries for macOS (arm64, amd64, universal), Linux (amd64, arm64) and
Windows (amd64, arm64); install with Homebrew
(brew install synodlang/tap/synod), Scoop,install.shor
go install. See https://synodlang.github.io/install/.
Known limitations
- Binaries are not code-signed: macOS and Windows warn when they are
downloaded with a browser. Package managers andinstall.shavoid this. - Phrase resolution, types and contexts are not checked yet.