Browser-based live demo for the sw-cor24-smalltalk project: a tiny integer-only "Tinytalk" hosted entirely in COR24 BASIC v1, in the spirit of the ~1000-line BASIC-hosted Smalltalk evaluator that Alan Kay's group built in 1972.
Live demo: https://sw-embed.github.io/web-sw-cor24-smalltalk/
Part of the Software Wrighter COR24 Tools Project.
Three nested fetch/decode/execute loops are running at all times in your browser:
Browser (WASM):
pa24r p-code VM <- runs the BASIC interpreter
+- COR24 BASIC v1 <- runs vm.bas + image_dN.bas + dN_*.bas
+- Tinytalk VM <- src/vm.bas: dispatch, send, primitives
+- Smalltalk image <- class table, method dicts, bytecodes
Same architecture as the rest of the web-sw-cor24-* family
(basic, pascal, snobol4, forth, ...): one Yew SPA, one Trunk
build, one p-code VM in WebAssembly. No backend.
The point is not speed (it is slow). The point is to make the mental
model of object-oriented dispatch visible: every step the VM takes
runs through real CLASSOF -> LOOKUP -> ACTIVATE -> primitive-or-frame-push,
hand-coded as GOSUB chains in BASIC.
# Run the dev server (port 9075, exclusive dist/ lock).
./scripts/serve.sh
# Open http://localhost:9075/Pick a demo from the dropdown and hit Run (or Cmd/Ctrl-Enter).
Esc stops a running session. Reset reloads the demo source.
Clear wipes the output panel. For the interactive demo (d5_calc),
an input row appears below the output -- type a value and press Enter
(or click Send).
Seven demos ship with the build, bundled at compile time from
../sw-cor24-smalltalk/{src,examples}/ via build.rs:
| Demo | Result | Description |
|---|---|---|
repl |
varies | Interactive integer calc REPL (default). Selectors: 1=+ 2=- 3=* 4=< 14=max:; 0 quits. |
hello |
hello, world |
Smallest possible v1-dialect demo: Transcript show: 'hello, world'. Transcript cr. First demo to print real text instead of bare integers. |
add |
7 |
3 + 4 via SmallInteger>>+ (primitive method). |
counter |
2 |
Counter class with one instance variable; user-defined init / incr / value; nested user->primitive sends. |
boolean |
42 |
5 < 10 ifTrue: 42 ifFalse: 0 via True/False objects with their own polymorphic ifTrue:ifFalse:. No native IF makes the choice. |
max |
5 |
5 max: 3 via SmallInteger>>max: whose bytecode uses JUMP_IF_FALSE for real conditional control flow inside a Smalltalk method. |
factorial |
120 |
5 fact via recursive SmallInteger>>fact. First proof that the v0 frame stack handles non-trivial nesting. |
bounded |
5 |
BoundedCounter extends Counter, overriding incr to cap at 5; init and value resolve via the superclass walk. First inheritance demo. |
The source pane shows the canonical Smalltalk source (.st) for
each demo. Under the hood, build.rs runs tools/stc.awk (the
COR24 Smalltalk compiler in ../sw-cor24-smalltalk/) to produce
the per-demo image, which is concatenated with vm.bas and the
hand-assembled top-level driver into the BASIC bundle the WASM
runner executes. BASIC is implementation substrate, not surfaced
in the UI.
assets/basic.p24-- the COR24 BASIC v1 interpreter, compiled Pascal-to-p-code, vendored viascripts/vendor-artifacts.shfrom../sw-cor24-basic/build/(or../web-sw-cor24-basic/assets/as fallback).build.rs-- for each demo, runstools/stc.awkfrom the source repo to compileexamples/<demo>.stto its image, then concatenatesimage + vm.bas + examples/<demo>.bas(the hand-assembled top-level driver), stripping trailingRUN/BYEsorunner.rscan append the right ones based on the demo'sinteractiveflag. Also embedsbasic.p24and emitsBUILD_SHA/BUILD_HOST/BUILD_TIMESTAMPfor the footer.src/runner.rs-- portspv24t(the canonical p-code tracer) to Rust/WASM. Loadsbasic.p24into memory, feeds the BASIC bundle into the interpreter as stdin, ticks in 200 K-instruction batches, pauses atINPUTfor interactive demos.src/lib.rs-- YewApp: demo dropdown, read-only Smalltalk source pane, output pane, status bar with a budget escalator, REPL input row, octocat corner, footer with build stamp.src/demos.rs-- static catalog.smalltalkfield isinclude_str!from../sw-cor24-smalltalk/examples/<demo>.st;runtimefield isinclude_str!fromOUT_DIR(the compiled BASIC bundle).scripts/serve.sh-- dev server on port 9075 with an exclusivedist/lock (prevents races between a running server and a straytrunk build).scripts/build-pages.sh-- release build intopages/for GitHub Pages, same lock.
./scripts/build-pages.sh
git add pages/
git commit -m "Release: deploy <date>"
git pushThe --public-url is /web-sw-cor24-smalltalk/ so paths resolve under
https://sw-embed.github.io/web-sw-cor24-smalltalk/.
- sw-cor24-smalltalk -- the Tinytalk VM and per-demo images this site runs.
- sw-cor24-basic -- the COR24 BASIC v1 interpreter source (Pascal -> p-code).
- sw-cor24-pcode --
canonical p-code VM, assembler (
pa24r), tracer (pv24t). - web-sw-cor24-basic, web-sw-cor24-pascal, web-sw-cor24-ocaml, web-sw-cor24-snobol4 -- sibling browser demos in the same family.
- Blog: Software Wrighter Lab
- Discord: Join the community
- YouTube: Software Wrighter
Copyright (c) 2026 Michael A. Wright
MIT. (C) 2026 Michael A Wright. See LICENSE.
