The objective
We had three conditions for the language of the script.
- Small. In our use, each character of a script has a cost. A game or a form must fit in approximately 1000 characters, before compression.
- Known to LLMs. An LLM writes most of our scripts. Thus the language must have many public examples, and it must not change.
- Not full-page JavaScript. A script comes from a person that we do not fully trust. It must get only the functions that the host page gives to it.
JavaScript is the best for the second condition, and the worst for the other two. A new language of our own is good for the first and the third condition, but no LLM knows it.
Why REBOL 2
Carl Sassenrath made REBOL in 1997. Before that, he designed the kernel of the Amiga operating system. REBOL has
dialects. A dialect is a small language in a block of data, and it does one job. The layout dialect
describes a window. The parse dialect describes a grammar. The draw dialect describes
shapes.
This is a full Pong game for WebRebol. It has 1064 characters.
score: 0 speed: 4x3
step: does [
ball/offset: ball/offset + speed
if any [ball/offset/y < 0 ball/offset/y > 290] [speed: speed * 1x-1]
if ball/offset/x > 390 [speed: speed * -1x1]
if all [
speed/x < 0
ball/offset/x < 18
ball/offset/x > 4
ball/offset/y + 10 > paddle/offset/y
ball/offset/y < (paddle/offset/y + 60)
] [
speed: speed * -1x1
score: score + 1
label/text: form score
]
if ball/offset/x < -10 [score: 0 label/text: "0" ball/offset: 200x150 speed: 4x3]
show court
]
court: layout [
origin 0x0 space 0x0
box 400x300 20.20.40 rate 60 on-time [step] on-key [
if all [key = "ArrowUp" paddle/offset/y > 0] [paddle/offset: paddle/offset - 0x20]
if all [key = "ArrowDown" paddle/offset/y < 240] [paddle/offset: paddle/offset + 0x20]
]
at 10x120 paddle: box 8x60 white
at 200x150 ball: box 10x10 yellow css [border-radius 5]
at 150x8 label: text 100x30 "0" css [color 255.255.255 font-size 22 text-align "center"]
]
view court
The script has no element queries, no event listener functions, and no style sheet. The
layout block puts the faces on the page, and the blocks after a face are its actions.
REBOL 2 is also a stable target. Its last release, 2.7.8, came in 2011, and the language does not change. Many REBOL 2 scripts and documents are public, thus LLMs write it sufficiently well. The newer relatives, Red and Ren-C, continue to change, and LLMs mix their rules.
Not full-page JavaScript
WebRebol does not change a script into JavaScript, and it does not use eval. It is a machine with
an explicit stack that reads REBOL values. A script can use only the words that the session gives to it.
- The Core words give no access to the
windowobject, the cookies, or the storage of the page. - The Core words cannot open a network connection. WebRebol has no network function at this time.
- A script that does not end cannot stop the page. The machine does a limited number of steps, and then it gives control back to the browser.
- The store of the session is immutable data. The host page can keep the state before an action, and it can go back to that state.
element accepts all tags and all
attributes. Thus a script can make an element that runs JavaScript or that loads a remote address. A filter
for tags and attributes is the next work. Until then, run only the scripts that you trust.
The explicit stack has a second purpose. A browser page cannot block, but REBOL functions such as
view, wait and input do block. In WebRebol, such a function stops the
machine with a request. An edge module does the work, and the machine continues with the answer.
How we know that it is REBOL
We do not trust our memory of REBOL, and we do not trust the memory of an LLM. The REBOL 2.7.8 program runs on the development computer, and it is the reference.
| Comparison | Result |
|---|---|
| Cases of the project, recorded from REBOL 2.7.8 | All 2435 cases agree. |
| The public REBOL core test suite | 4347 of 4586 tests give the same outcome (94.8%). |
| Load of downloaded REBOL scripts | 529 of 538 scripts agree. |
| Core functions | 382 of 443 have a first version. |
Most of the 61 functions that remain are not possible in a browser: email, sockets, and the start of other programs. The comparison also found defects in REBOL itself. For example, REBOL 2.7.8 for 64-bit Linux gives MD5 results that are not correct. WebRebol does not copy such a defect. A separate list records each one.
WebRebol has no code of REBOL Technologies. REBOL Technologies did not publish the source of its interpreter. We wrote each function again from its behavior, and the functions that REBOL writes in REBOL are new text.
View: from desktop windows to the page
REBOL View draws its own windows on a desktop. WebRebol keeps the REBOL part and replaces the drawing part.
- The layout is the same.
layoutgives a tree of faces with the same positions and sizes as REBOL View 2.7.8. REBOL View runs in Docker and measures the character widths of each font. WebRebol uses those numbers. - A face is a DOM element.
viewchanges each face into an element with CSS. A button is abuttonelement, and a field is aninputelement. The page changes only the elements that are different after an action. - Events are REBOL blocks. A face can have an action, a timer (
rate), keyboard events and pointer events. Thefeelobject and itsengagefunction operate as in REBOL. - Pictures. The
drawdialect gives SVG shapes. Animage!value shows on a canvas, and a script can draw on it and save it as a PNG file. - The look is CSS. The object
themeand the facetcssgive CSS to a style or to one face. The functions that make the elements are REBOL code, and a script can replace them.
theme/font-family: "Georgia"
append theme/css [button [border-radius 6 background-color 20.120.60]]
view layout [button "OK" button "Special" css [background-color 150.40.40]]
Files: a disk that the host page owns
REBOL scripts read and write files. A browser page has no file system, and a script must not read the files of the computer.
WebRebol has a disk in memory. It is a table of full paths, and each entry is a folder or a file with its
bytes. read, write, load, save, do, the
directory functions and file ports operate on this table.
WebRebol has no storage code. The host page gives the disk to a session, and it gets the changed disk back at the end. The page then saves the disk as it prefers, for example in an encrypted store. In Node.js, the disk is a folder.
import { interpretWithEdge } from "./src/edge/drive.mjs";
const machine = await interpretWithEdge('write %note.txt "hello"', 5000, disk);
const nextDisk = machine.store.disk;
Web Crypto in REBOL words
REBOL 2 has checksum and a small set of old ciphers. A browser has Web Crypto, and Web Crypto is modern. WebRebol adds words for all its algorithms.
key: crypto-derive "a passphrase" crypto-random 16 600000
sealed: crypto-encrypt "a secret text" key
to-string crypto-decrypt sealed key ; "a secret text"
mine: crypto-key-pair/method 'x25519
yours: crypto-key-pair/method 'x25519
secret: crypto-agree second mine first yours
The words include digests, AES-GCM, key pairs (ECDSA, Ed25519, RSA), PBKDF2, HKDF, ECDH and X25519. Web Crypto is asynchronous, but a script is not. The machine waits while the browser does the work.
compress and decompress use the compression streams of the browser in the same
manner. Thus WebRebol has no compression library.
Music: ABC notation and Web Audio
We also wanted sound. LLMs know ABC notation well, because large public collections of tunes use it. Thus the music words read ABC.
score: abc-to-score {X:1^/L:1/4^/Q:1/4=120^/K:G^/G A B c | [GBd]4 |}
play-audio/with score [sine 1 0.6 sine 2 0.25 fade 0.3 gap 0.1]
- The ABC reader is REBOL code that uses
parse. A score is a plain block of notes with a start, a length and a pitch. - An instrument is a block of generators (
sine,square,saw,triangle), each with a harmonic number and a level. play-audiosends the notes to Web Audio. Each note is an oscillator with a periodic wave and an envelope, and the browser keeps the timing.- A second route uses no Web Audio. REBOL code calculates the samples and makes a WAV file. REBOL 2.7.8 runs the same music code, and it gives the same sample bytes.
The limits
- Speed. The interpreter is slow. A loop of 8000 steps with arithmetic takes approximately 0.4 seconds. This is sufficient for a form or a small game, but not for heavy calculation.
- Memory. The store does not remove a series that the script does not use. A long session uses more memory with time.
- View is not complete. WebRebol does not have some styles, some draw commands and most effects.
- The page elements have no filter. See the gap in the section "Not full-page JavaScript".
- No network. We plan
httpwithfetch. Sockets and email are not possible in a page. - An AI agent wrote most of the code. We gave the direction and the rules, and the tests against REBOL 2.7.8 decided what is correct.
The alternatives
| Tool | The reason that we did not use it |
|---|---|
| JavaScript | It is the best known to LLMs, but a script is long, and it gets the full power of the page unless you isolate it. |
| Ren-C | It runs a Rebol dialect in a browser with WebAssembly. It is not REBOL 2, it has no layout dialect, and it continues to change. |
| Lua or Janet | The two are good small languages, but they have no dialect for a page. Each script must build its page with function calls. |
| A language of our own | No LLM knows it, and it has no reference program to test against. |
If your objective is only an interactive page, use JavaScript. WebRebol is the correct tool when the size of the script and the limits on its power are important.
Try it
git clone https://github.com/rheophile10/webrebol
cd webrebol
node bin/serve.mjs
Then open http://localhost:8017/. The start page has games, a paint program, the music page and
an editor. Only Node.js is necessary. The project has no packages to install.
References
- rheophile10/webrebol โ the source (MIT)
- REBOL โ the language and the REBOL 2.7.8 downloads
- rebolsource/rebol-test โ the public REBOL core test suite
- Ren-C ยท Red โ the newer relatives of REBOL
- ABC notation โ the text notation for music
- Web Crypto ยท Web Audio โ the browser functions that WebRebol uses