[L2Ork-dev] coin-operated scripting language

Jonathan Wilkes jon.w.wilkes at gmail.com
Wed Oct 9 22:48:38 EDT 2019

Hi list,

Ok, I've got a little scripting language prototype coded up
as a Purr Data class.

It's something like this:

[vm var1 var2 etc.;
+ var1 42 10;
/ var2 var1 5;
etc. etc.]

The idea is that you put your parameters on the first line, then
you can refer to them in the body.

At the moment I'm just using this notation: "operator destination
operand1 operand2." It's pretty easy to map another more user-friendly
syntax on
top of that with a Pratt parser or something.

Currently I'm just setting a single parameter from the right inlet of the
object. Once the computation is done, the return value(s) can come out
of the right outlet.

The novel business happens in the left inlet/outlet

[bang, 12(
[vm foo;
+ foo 20 1]
|        |
[vn bar;
- bar 63 bar]

The "bang" tells "vm" to get ready for computation.

The float method then sends 12 "coins" to the inlet. That means
that the object is allowed to do 12 operations before it suspends

Notice in the first [vm] we've only got one explicit operation-- adding
two numbers. There's another implicit operation where the return value
is sent to the right outlet. So even though we had 12 "coins" to start,
our computation only used up 2 of them.

After the right inlet spits out the output, the left outlet spits out the
"change"-- the leftover "coins" that went unused. Thus, the
next "vm" object receives "10" coins to its inlet.

And so on and so forth all the way down the chain.

So what happens if we don't give a "vm" enough coins to compute its
output? It just halts. But you can resume the computation where it left off
by sending more coins to the left inlet. (If you send coins after computation
is finished the "vm" just passes them through.)

AFAICT this lets us deterministically suspend and resume computation in the
control domain without blocking DSP. Consider:

[vm var1;
some large number;
of operations in this;
script to calculate;
some values for a;
physics engine;]

Even though the script may not be able to finish in time for a DSP
deadline, we're only computing 20 operations of the script each block.
That's very unlikely to interrupt the audio. So as long as we can reach
the end of the script in time to update the graphics or whatever we're
trying to achieve, then we should repeatedly hit those deadlines without
a problem.

Additionally, we can afford to be rather sloppy with the features here. We
can allow the users to make loops, even infinite ones, without fear of
locking up the running Purr Data instance. Of course allowing fancier
branches and loops in the scripts increases the likelihood of surprises
wrt the number of operations to compute the output. But Pd users seemed
used to testing weird things until they kind of work.

Anyhow, I'll keep adding ops to this and start looking into some more
friendly syntax.

The real sticking point will be the entry and exit points. I don't think we
want to allow arbitrary and/or dynamically sized lists and arrays to
be read and written. Otherwise we'll have to copy lots of data to protect
against stale references, and that will easily become a performance
bottleneck. But I think there's a way to require statically-sized,
protected data inside the "vm" while still getting pretty expressive
operations in the script.


More information about the L2Ork-dev mailing list