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 curr
for (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 = document
val = 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 out
run(
[ '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);