| :: get cause 1 | :stack: A :pattern: . a . b . variable c . d . variable e :index: ( 0 1 2 3 4 ) | :: get cause 2 | :stack: A :pattern: . stride . test :index: ( 0 1 ) | :: get cause 3 | :stack: B :pattern: . other . cause . match . variable c :index: ( 0 1 2 3 ) | :: get effect 1 | :stack: out_A :items: . output . one . variable c :index: ( 0 1 2 ) | :: get effect 2 | :stack: out_B :items: . output . 2 . variable e :index: ( 0 1 2 ) | :: get rule 1 | :causes: ( 1 2 3 ) :effects: ( 1 2 ) | :: get cause 4 | :stack: ohnoes :pattern: . a . second . rule :index: ( 0 1 2 ) | :: get effect 3 | :stack: x :items: . what . shall . we . do :index: ( 0 1 2 3 ) | :: get rule 2 | :causes: ( 4 ) :effects: ( 3 ) || :rules: ( 1 2 ) |------------------------------| |- handle incrementing -| |------------------------------| | :@math: add 0 1 | :@math: 1 | :@math: add 1 1 | :@math: 2 | :@math: add 2 1 | :@math: 3 | :@math: add 3 1 | :@math: 4 | :@math: add 4 1 | :@math: 5 | :@math: add 5 1 | :@math: 6 | :@math: add 6 1 | :@math: 7 | :@math: add 7 1 | :@math: 8 | :@math: add 8 1 | :@math: 9 | :@math: add 9 1 | :@math: 10 | :@math: add 10 1 | :@math: 11 | :@math: add 11 1 | :@math: 12 | :@math: add 12 1 | :@math: 13 | :@math: add 13 1 | :@math: 14 | :@math: add 14 1 | :@math: 15 | :@math: add 1 $x | :@math: add $x 1 |------------------------------| |# run with > nova -d mathpolyfill.nv data.nv emitter.nv < #| | :: process rule :rules: $ruleid | :: get rule $ruleid :current rule id: $ruleid :: process causes :: clear causes temp state :: check stack depths :: process effects :: clear rule temp state | :: clear rule temp state? :stack: $stack | | :: clear rule temp state? :vars: variable $x = index $y of stack $z at depth $q | | :: clear rule temp state | | :: process causes? :causes: $causeid | :: get cause $causeid :length: 0 :: check stack :: process pattern :: check fact lengths :: pop cause | :: process causes | |:: check stack depths| | :: check fact lengths :stack: $stack? :current stride depth: $depth ? :length: $length | :check fact lengths: check stack $stack depth $depth has length $length | :: clear causes temp state :current stride depth: $n | | :: check stack :stack: $stack? | :: add stack $stack | :: pop cause :stack: $stack | :pop causes: pop $stack |------------------------------| | :: add stack $stack? :current stride depth: $n | | :: add stack $stack :@math: $depth | :current stride depth: $depth :strides: check stack $stack has at least depth $depth :: strides temp -> strides | :: add stack $stack? :strides: check stack $stack has at least depth $depth | :@math: add $depth 1 | :: add stack $stack? :strides: check stack $different has at least depth $depth | :strides temp: check stack $different has at least depth $depth | :: add stack $stack | :current stride depth: 1 :strides temp: check stack $stack has at least depth 1 :: strides temp -> strides | :: strides temp -> strides? :strides temp: check stack $stack has at least depth $depth | :strides: check stack $stack has at least depth $depth | :: strides temp -> strides | |------------------------------| | :: increment length :length: $old :@math: $n | :length: $n | :: increment length? :length: $n? | :@math: add $n 1 | :: process pattern? :stack: $stack? :pattern: variable $name :index: $i :current stride depth: $depth? | :: do variable $name at index $i of stack $stack at depth $depth :: increment length |- var is already declared -| | :: do variable $name at index $i of stack $stack at depth $depth :vars: variable $name = index $j of stack $stack2 at depth $depth2? | :check vars: check index $i of top of stack $stack at depth $depth equals value of var $name :: vars temp -> vars |# can also do this to give more information #| :check vars: check index $i of top of stack $stack at depth $depth equals var $name stack $stack2 depth $depth2 index $index2 |- not the right var, check next -| | :: do variable $name at index $i of stack $stack at depth $depth? :vars: variable $different = index $j of stack $stack2 at depth $depth2 | :vars temp: variable $different = index $j of stack $stack2 at depth $depth2 |- variable isn't declared yet, so declare it -| | :: do variable $name at index $i of stack $stack at depth $depth | :set vars: declare variable $name = index $i of stack $stack at depth $depth :vars: variable $name = index $i of stack $stack at depth $depth :: vars temp -> vars | :: vars temp -> vars :vars temp: variable $name = index $i of stack $stack at depth $depth | :vars: variable $name = index $i of stack $stack at depth $depth | :: vars temp -> vars | | :: process pattern? :stack: $stack? :pattern: $symbol :index: $i :current stride depth: $depth? | :check facts: check stack $stack at depth $depth matches symbol $symbol at index $i :: increment length | :: process pattern | |--------------------| | :: process effects? :effects: $effectid | :: get effect $effectid :: push effects start :: process items :: push effects end | :: process effects | | :: push effects start | :push effects: start fact to push | :: push effects end | :push effects: end fact to push | :: process items? :stack: $stack? :items: $symbol :index: $i | :push effects: symbol $symbol | :: process items? :stack: $stack? :items: variable $name :index: $i | :push effects: variable $name | :: process items | | :emit: rule header $ruleid | :out: rule header $ruleid | :emit: check stack heights? :strides: check stack $stack has at least depth $depth | :out: check stack $stack has at least depth $depth | :emit: check stack heights | | :emit: check facts lengths? :check fact lengths: check stack $stack depth $depth has length $length | :out: check stack $stack depth $depth has length $length | :emit: check facts lengths | | :emit: check facts constant symbol matches? :check facts: check stack $stack at depth $depth matches symbol $symbol at index $index | :out: check stack $stack at depth $depth matches symbol $symbol at index $index | :emit: check facts constant symbol matches | | :emit: set variables? :set vars: declare variable $name = index $i of stack $stack at depth $depth | :out: declare variable $name = index $i of stack $stack at depth $depth | :emit: set variables | | :emit: check variables equality? :check vars: check index $i of top of stack $stack at depth $depth equals value of var $name | :out: check index $i of top of stack $stack at depth $depth equals value of var $name | :emit: check variables equality | | :emit: pop causes ? :pop causes: $a $b | :out: $a $b | :emit: pop causes | | :emit: push effects -> push effects reversed? :push effects: $a $b | :push effects reversed: $a $b | :emit: push effects -> push effects reversed? :push effects: $a $b $c $d | :push effects reversed: $a $b $c $d | :emit: push effects -> push effects reversed | | :emit: push effects reversed -> out? :push effects reversed: $a $b $c $d | :out: $a $b $c $d | :emit: push effects reversed -> out? :push effects reversed: $a $b | :out: $a $b | :emit: push effects reversed -> out | | :emit: push effects | :emit: push effects -> push effects reversed :emit: push effects reversed -> out | :emit: rule footer | :out: rule footer | :: emit rule :current rule id: $ruleid | :: emitting rule :emit: . rule header $ruleid . check stack heights . check facts lengths . check facts constant symbol matches . set variables . check variables equality . pop causes . push effects . rule footer | :: emitting rule | |- :vim:sw=3:ts=3:et: -| | :: translate? :out: rule header $ruleid | :@js: f('final out', `function rule${$ruleid} () {`); f('rule functions', `rule${$ruleid}`); | :: translate? :out: check stack $stack has at least depth $depth | :@js: f('final out', `if ( stack["${$stack}"].length < ${$depth} ) return false;`) | :: translate? :out: check stack $stack depth $depth has length $length | :@js: f('final out', `if ( stack["${$stack}"][${$depth}].length != ${$length} ) return false;`) | :: translate? :out: check stack $stack at depth $depth matches symbol $symbol at index $index | :@js: f('final out', `if ( stack["${$stack}"][${$depth}][${$index}] != "${$symbol}" ) return false;`) | :: translate? :out: declare variable $name = index $index of stack $stack at depth $depth | :@js: f('final out', `let ${$name} = stack["${$stack}"][${$depth}][${$index}];`) | :: translate? :out: check index $i of top of stack $stack at depth $depth equals value of var $name | :@js: f('final out', `if ( stack["${$stack}"][${$depth}][${$i}] != ${$name} ) return false;`) | :: translate? :out: start fact to push | :final out: f( | :: translate? :out: symbol $symbol | :@js: f('final out',`"${$symbol}",`) | :: translate? :out: variable $varname | :@js: f('final out',`${$varname},`) | :: translate? :out: pop $stack | :@js: f('final out',`stack["${$stack}"].pop();`) | :: translate? :out: end fact to push | :final out: ); | :: translate? :out: rule footer | :final out: } :final out: [] | :: emit file header | :final out: [/* stub */] :final out: [] | :: translate | |#========#| | :: breakpoint | | :: breakpoint | :@js: me.gas = 0; || :: emit file header :: output :: process, emit, and output rules :: emit step function ::output :: output main loop | :: process, emit, and output rules ? :rules: $n?| :: breakpoint :: process rule :: breakpoint :: emit rule :: breakpoint :: translate :: breakpoint :: output :: breakpoint | :: process, emit, and output rules | |# in reverse order because we are pushing directly to the final out stack #| | :: emit step function | :: emit step function footer :: emit rule function names :: emit step function header | :: emit step function header | :final out: [function step () {] | :: emit rule function names? :rule functions: $fname | :@js: f('final out',`if (${$fname}()) return true;`) | :: emit rule function names | | :: emit step function footer | :final out: } :final out: [] | :: output main loop | :: output :final out: . [function run() {] . [ while (step()) {] . [ // nop] . [ }] . [}] |#===============#| || '@include' lib/platforms/browser_dom.nv || :DOM: ( > ) |#===============#| | :: output :current dom element: $out? | :@js: $out.value += (stacks['final out'].map(x=>x.join('')).toReversed().join('\n')+'\n'); delete stacks['final out'];