Concatenative JavaScript
const vars = {}
const as = s => v => vars[s] = v
const def = s => v => {
vars[s] = v
}const set = (last, prop, val) => {
last[prop] = val
}const put = (last, prop, val) => {
last[prop] = val
return last}const of = k => run.last[k]
const $ = k => () => vars[k]
const run = (prog, log) => {
run.stack = []
let currfor (let i = 0; i < prog.length; i++) {
let val = prog[i]
if (val != null && val === $) {
run.stack.push(val())
} else if (typeof val === 'function') {
let ctx = null
if (document.body[val.name]) {
ctx = document.body
val = val.bind(ctx)
} else if (document[val.name]) {
ctx = documentval = val.bind(ctx)
}if (log) console.log('exec',
val.name == 'bound ' ? '\u03BB' : val.name, run.stack)
curr = val.apply(ctx, run.stack)
if (curr != run.stack) {
run.stack = curr != null ? [curr] : []
if (typeof curr === 'object') {
run.last = curr
}}} else {
if (val != null) run.stack.push(val)
}}}const showStack = () => {
console.log('- stack:', run.stack)
console.log(' -> last object', run.last)
return run.stack
}const _ = new Proxy({}, {
get: (o, key) => (() => (...a) =>
run.last[key].apply(run.last, a)
)()
})
// try it outrun([ 'div',
document.createElement,
document.body.appendChild,
as`myDiv`,'innerHTML', 'mini <b>concatenative</b>', set,
'style', of, 'color', 'green', set,
'just logging the element', $`myDiv`, console.log,
'canvas', document.createElement,
document.body.appendChild,
'width', 500, put,
'height', 500, put,
def`myCanvas`,'2d',
_.getContext,
'fillStyle', 'red', set,
100, 30, _.translate,
0, 0, 10, 100, _.fillRect,
20, 0, 10, 100, _.fillRect,
.2, _.rotate,
-30, 25, 100, 10, _.fillRect,
-20, 55, 100, 10, _.fillRect,
{},
'name', 'zevan', put,
'age', 82, put,
JSON.stringify,
as`person`,showStack
])console.log(vars);
I recently spent some time reading about and playing with the FORTH language. I keep finding myself creating weird vaguely FORTH inspired snippets now… This one processes an array that’s in a concatenative format like this:
[ 'hello world', Date.now(), console.log ]
Arguments are collected on a stack and passed to a function when a function is hit in the array. There are some odd helper functions for setting properties, setting nested properties, running functions with a specific context etc…
Here is GPT4’s mostly correct explanation of what it does
This is a rather unusual piece of JavaScript code that creates a simple “programming language” based on the concept of a stack machine, and runs a “program” in this language. It resembles some sort of DSL (domain-specific language) or script-like construct.
Here are what the main components do:
vars: This is a dictionary that stores variables defined in the program.as: This is a function that takes a stringsand returns a function that takes a valuev, storingvinvarsunder the keys.def: Similar toas, it defines a variable invars.set: This function is used to set the property of an object. It takes the objectlast, the property nameprop, and the valueval, and assignsvalto the propertypropof the objectlast.put: Similar toset, it sets the property of an object and returns the updated object.of: This function gets the property with namekof the last object returned by the program.$: This function is a getter for variables invars.run: This is the main function that runs the program. The program is an array of actions, where an action can be a function, an object with anameof ‘get’ (which pushes the result of calling the function onto the stack), or a value (which is pushed onto the stack).showStack: This function logs the current state of the stack and the last object returned._: This creates a new Proxy object that allows arbitrary methods to be called on the last object returned by the program.The
runfunction is then called with a list of actions to perform. The actions include creating adivandcanvaselement, appending them to thebodyof the document, setting their properties, and drawing on thecanvas. It also creates an object with anameandage, converts it to JSON, and stores it in a variable. Finally, it shows the state of the stack and logs all the variables.