Re: "tweetable" "symbolic" hex COM loader
Dave Long <[email protected]> Fri, 18 Oct 2013 19:35:40 +0200
| Newsgroups | gmane.culture.people.kragen.discuss |
|---|---|
| Message-ID | <[email protected]> |
>> The global assembler label is a remarkably powerful tool. I =
>> wonder, though, if
>> it might be a bit too powerful; perhaps the Forth approach (two =
>> separate
>> stack-based mechanisms for backward and forward jumps, plus an =
>> updatable symbol
>> table for calls to earlier-defined routines, giving each symbol a =
>> scope from
>> its own definition until the next definition of the same name) is =
>> actually
>> better.
>
> Good point. This time I went with the decision for global labels =
> in order to maximize straight-line code; taking the second pass =
> means there's no requirement for dispatching[3]. MIXAL apparently =
> makes a "single" pass by backpatching, so it's single pass over the =
> input but random access in the output; given enough stack one can =
> also claim to make a "single" recursive pass, reading on the way =
> down and writing on the way back up, but that's still fairly close =
> to two monotonic passes. One great temptation to use the power of =
> the global labels is that other tools (such as a stack-based =
> control-structure preprocessor) can then simply be streaming =
> transformers.
Having been inspired by Darius' https://github.com/darius/regexercise =
and http://swtch.com/~rsc/regexp/regexp2.html , I was recently =
reminded of this latter (streaming transformer) principle.
Based on Cox' description of the Thompson construction (and dim =
memories of the Dragon book), I bashed out a nondeterministic regex =
machine in an evening. (Thompson, naturally, takes a route[0] that =
comes naturally to language implementers[1]) It initially seemed a =
bit wasteful, for we extract the tree structure once while parsing, =
flatten everything down to a list of VM ops, and then essentially =
implicitly reconstruct the tree when following the epsilon =
transitions. So the next version wound up very similar to Doug =
McIlroy's recent Haskell interpretation:
> The construction method descends from Ken Thompson=92s classic construc-
> tion.(1968) The present method differs from the earlier =
> construction and deriva-
> tives thereof (Aho et al., 1986; Thompson, 2000) in dispensing with =
> epsilon moves.
> Epsilon moves do not appear as either transitory or permanent =
> artifacts of the
> construction process. There is no separate transitive-closure =
> calculation to remove
> them, and no capability to simulate them. Only the tiny function bp =
> remains as a
> Cheshire grin of epsilons past.
as even in an eager language, one can simply unfold the regex string =
to a parse tree, fold that down to an NFA, and finally refold against =
the input strings.
However, upon reflection, Thompson's version actually shows masterful =
use of lost edges[2]. Both McIlroy (16pp) and I had to come up with =
a set of equations that effectively evaluated the transitive closure =
while building the transition matrix, while Thompson (4pp) simply =
relies upon the equivalence of the transitive closure and transitive =
reduction, working with the latter so he can do almost everything =
locally, implicitly, and in bounded space. (In order to debug my =
equations, I cross checked them against a transitive closure -- at =
which point I realized that my constituent equations and tree folding =
took some 20 odd lines, while the powerful global transitive closure =
tool was only 3)
-Dave
PS: anyone care to write the Javascript interpetation of Thompson's =
version, in which the automaton runs as subroutine-threaded code, =
JIT'ing new code[3] for each new state? At least we're on larger =
machines now, even inside a browser, so we don't have to self-modify =
and throw away each state when swapping to a new one!
[0] Ken Thompson, "Regular Expression Search Algorithm", CACM v11 no6 =
1968
which finishes with the observation that:
> It is also easy to
> incorporate new operators in the regular expression rou-
> tine. Examples include: not, exclusive or, intersection, etc.
Exclusive or would seem to give one the "quantum" equivalent of a =
search, in that it would be possible for two otherwise matching =
searches to interfere destructively, thereby failing. I guess it =
would be one way to stress-test how disjoint one's patterns actually =
are: if the test suites passed with exclusive-or substituted for =
inclusive, one could be confident that any ambiguities were lurking =
elsewhere. (or at least, that the patterns are triply ambiguous!)
[1] Actually, he's rather hard core. Anyone can write an interpreted =
VM; many BitBLTs back in the day where compiled onto the stack, =
specialized for each call; Thompson JITs code to evaluate an =
arbitrary subset of states *for each input character*.
[2] [FoRK] hard edges, soft edges, lost edges
http://www.xent.com/pipermail/fork/Week-of-Mon-20101122/058148.html
[3] javascript turns out to be a congenial host for forth; I have a =
simple version which I hope to post here once the exposition has been =
clarified a bit, in which (as long as we're willing to --a la Ueli =
Steck-- travel light, without overbyte), the following set of =
definitions brings us quickly up the direct route, from the =
dictionary and two stacks mentioned above to subroutines (':' and =
';'), alternation ('IF', 'THEN'), repetition ('REPEAT','AGAIN'), and =
even rudimentary objects/closures ('CREATE','DOES>').
' DO: , LABEL : [/] LIT DO: , LABEL [/] ' [/] ,
: ; LIT NEXT , [/] ' [/] , IMM
: REF> HERE HERE , ;
: <DEF HERE !~ ;
: IF LIT JZ , REF> ; IMM
: THEN <DEF ; IMM
: REPEAT R> HERE >R >R ; IMM
: AGAIN LIT JMP , R> R> , >R ; IMM
: CREATE LIT NEXT , LABEL ;
: DOES> LIT LIT , REF> LIT DOES! , LIT NEXT , LIT DOES: , <DEF ; IMM
-- =
To unsubscribe: http://lists.canonical.org/mailman/listinfo/kragen-discuss