Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A toy system inspired by realtalk
function mouse(_, me, when, claim){
when('fox is out', () => {
claim(me, 'wish', 'labelled', 'squeak')
claim(me, 'wish', 'outlined', 'red')
})
}
function fox(_, me, when, claim){
claim('fox is out')
}
function draw_labels(_, me, when, claim){
when(_, 'wish', 'labelled', _, (obj, label) => {
console.log(obj, label)
})
}
function draw_outlines(_, me, when, claim){
when(_, 'wish', 'outlined', _, (obj, color) => {
console.log(obj, '<' + color + '>')
})
}
function label_leprechauns(_, me, when, claim){
when(_, 'is a leprechaun', (lep) => {
claim(lep, 'wish', 'labelled', 'is a leprechaun')
})
}
function leprechaun(_, me, when, claim){
claim(me, 'is a leprechaun')
}
function bob(_, me, when, claim){
claim(me, 'is named Bob')
}
function bob_the_leprechaun(_, me, when, claim){
when(_, 'is named Bob', (person) => {
claim(person, 'is a leprechaun')
})
}
function frog(_, me, when, claim){
claim(me, 'is a frog')
}
function label_frogs(_, me, when, claim){
when(_, 'is a frog', (lep) => {
claim(lep, 'wish', 'labelled', 'is a frog')
})
}
function hungry_snek(_, me, when, claim){
when(_, 'is a frog', (frog) => {
claim(me, 'eats', frog)
claim(frog, 'wish', 'labelled', 'ded')
})
}
function poison_frog(_, me, when, claim){
claim(me, 'is a frog')
claim(me, 'is poison')
}
function poison_behavior(_, me, when, claim){
// nested when clauses for AND
when(_, 'is poison', (poison_frog) => {
when(_, 'eats', poison_frog, (snek) => {
claim(snek, 'wish', 'labelled', 'ded')
})
})
}
function thingy(_, me, when, claim){
claim(me, 'x', 13)
claim(me, 'y', 12)
claim(me, 'wish', 'labelled', 'thingy')
}
function outline_things_nearby(_, me, when, claim){
claim(me, 'x', 10)
claim(me, 'y', 10)
when(me, 'near', _, 'with radius', 10, (page) => {
claim(page, 'wish', 'outlined', 'red')
})
}
function nearby_handler(_, me, when, claim){
when('when', _, 'near', '_', 'with radius', _, (page, radius) => {
claim(page, 'wish', 'labelled', 'has a geofence')
when(page, 'x', _, page_x =>
when(page, 'y', _, page_y => {
// got page xy
when(_, 'x', _, (obj, x) =>
when(obj, 'y', _, y => {
// got obj xy
if(Math.abs(page_x - x) < radius
&& Math.abs(page_y - y) < radius
&& obj !== page){
claim(page, 'near', obj, 'with radius', radius)
}
}))
}))
})
}
// let objects = [ mouse, fox, draw_labels ]
// let objects = [ draw_labels, label_leprechauns, leprechaun, bob, bob_the_leprechaun ]
// let objects = [draw_labels, frog, label_frogs, hungry_snek, poison_frog, poison_behavior]
// let objects = [ mouse, fox, draw_labels, label_leprechauns, leprechaun, bob, bob_the_leprechaun, frog, label_frogs, hungry_snek, poison_frog, poison_behavior]
let objects = [draw_outlines, draw_labels, thingy, outline_things_nearby, nearby_handler]
let wildcard = Symbol('_')
function test(pattern, claim, cb){
if(pattern.length != claim.length) return;
let args = []
for(let i = 0; i < pattern.length; i++){
if(pattern[i] === wildcard){
args.push(claim[i])
}else if(pattern[i] !== claim[i]){
return
}
}
cb(...args)
}
let db = []
let hooks = []
for(let i = 0; i < objects.length; i++){
let me = objects[i],
when = (...args) => {
let cb = args[args.length - 1],
pattern = args.slice(0, -1);
// when generators
claim('when', ...pattern.map(
k => k === wildcard ? '_' : k))
// add a hook
hooks.push([ pattern, cb ])
// for all matches in db
for(let item of db){
test(pattern, item, cb)
}
},
claim = (...args) => {
console.assert(!args.includes(wildcard),
'Claims can not include wildcard');
// add claim to database
db.push(args)
// for all hooks, check for match
for(let [pattern, cb] of hooks){
test(pattern, args, cb)
}
};
me(wildcard, me, when, claim)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.