You will need at some point to specify the arity of your functions. You can call quotations "dynamically" like this... but if the stack checker can't infer what the quotation's stack effect is, you need to specify in the ``call(`` what the effect is so that it will be checked at runtime:
IN: scratchpad : foo ( x quot -- y ) call( x -- y ) ; IN: scratchpad 2 [ sq ] foo . 4 Seems like you would just need to specify in your opcode map what the arity of your words are and do something like: CONSTANT: ops H{ { "add" { [ + ] 2 } } { "sq" { [ sq ] 1 } } } : foo ( stack opcode -- output ) '[ _ ops at first2 { { 1 [ call( x -- y ) ] } { 2 [ call( x y -- z ) ] } } case ] with-datastack ; IN: scratchpad { 2 } "sq" foo . { 4 } IN: scratchpad { 2 3 } "add" foo . { 5 } There are a few other ways / approaches but basically that's an idea for you... Hope it helps! On Fri, May 31, 2019 at 8:47 AM Luca Di Sera <bloodtype.si...@gmail.com> wrote: > I'm working on an implementation of the lc3 -vm ( > https://justinmeiners.github.io/lc3-vm/ ). > > This a basic didactical architecture. > > In the code, I have a TUPLE: that is used to keep the state of the vm. > > TUPLE: lc3 { ram array } { registers array } { pc integer } { cond >> bit-array } ; >> > > An instance of this TUPLE is passed around by some of the code to execute > instructions and change the internal state. > > Instructions are coded as 16bit values where the highest 4 bits represent > an op-code that identifies the instruction to execute and the rest of the > bits contain informations about the necessary data to execute it. > In my code I'm using a map of pairs to dispatch to the correct ( quotated- > ) words depending on the opcode. > > CONSTANT: OPCODE_MAP H{ >> { 0 { [ parse-br ] [ eval-br ] } } >> { 1 "add" } >> { 2 "ld" } >> { 3 "st" } >> { 4 "jsr" } >> { 5 "and" } >> { 6 "ldr" } >> { 7 "str" } >> { 8 "rti" } >> { 9 "not" } >> { 10 "ldi" } >> { 11 "sti" } >> { 12 "jmp" } >> { 14 "lea" } >> { 15 "trap" } >> } >> >> : parser-evaluator ( opcode -- parser evaluator ) >> OPCODE_MAP at [ first ] [ second ] bi ; >> > > The strings are there as temporary values that I still have to build. > > Not all instructions encode informations in the same way. Some of them may > include 4 pieces of informations of different width and type and some > others may contain more or less of them. > To correctly retrieve informations and to execute the correct instruction > I'm using those parser-evaluator pairs. > > All parsers, which cut instructions into the correct pieces of > informations, expects the stack to have an instruction at its top to > consume while pushing a variable number of values in its place. > All evaluators, which actually execute the given instruction modifying the > state of an lc3, expects n values on the stack to consume and will > push-out a modified lc3. > > Now, those parser-evaluator pairs are call( [ed] at runtime. > After many tries, I was able to construct a piece of code that would > compile ( Stack-effects are not completely clear to me yet ). > Unfortunately, when a parser-evaluator pair is actually called the program > will stop as the expressed stack effect of call( is considered incorrect. > > : _eval ( lc3 parser: ( instruction -- ..a ) evaluator: ( ..a -- lc3 ) -- >> lc3 ) >> [ call( instruction -- ..a ) ] [ call( ..a -- lc3 ) ] bi* ; inline >> > > (U) Quotation: [ set-namestack init-catchstack self quot>> call => stop ] >> (O) Word: listener-thread >> (O) Word: listener >> (O) Word: (listener) >> (O) Word: listener-step >> (U) Quotation: [ >> [ ~quotation~ dip swap ~quotation~ dip ] dip swap >> [ call get-datastack ] dip => swap [ set-datastack ] dip >> ] >> (U) Quotation: [ call => get-datastack ] >> (O) Word: eval >> (O) Word: wrong-values >> (O) Method: M\ object throw >> (U) Quotation: [ >> OBJ-CURRENT-THREAD special-object error-thread set-global >> current-continuation => error-continuation set-global >> [ original-error set-global ] [ rethrow ] bi >> ] >> > > After some tries, I'm at a kind of roadblock that I seem unable to > untangle. > How can I express, if at all possible, this kind of polymorphism in factor > ? What are some alternative ways to produce the same effect ? > > For reference this is the relevant code: > > USING: lc3-vm.core.lc3.private lc3-vm.core.lc3 sequences bit-arrays locals >> kernel assocs ; >> IN: lc3-vm.core.instructions >> >> <PRIVATE >> >> CONSTANT: OPCODE_LENGHT 4 >> >> : instruction>opcode ( instruction -- instruction opcode ) >> OPCODE_LENGHT cut* bit-array>integer ; >> >> : parse-br ( instruction -- n z p offset ) >> 1 cut 1 cut 1 cut [ [ first ] tri@ ] dip bit-array>integer ; >> >> : n-and-cond-n? ( lc3 n -- ? ) >> [ cond-n? ] dip and ; >> >> : z-and-cond-z? ( lc3 z -- ? ) >> [ cond-z? ] dip and ; >> >> : p-and-cond-p? ( lc3 p -- ? ) >> [ cond-p? ] dip and ; >> >> :: br-should-jump ( lc3 n z p -- ? ) >> lc3 n n-and-cond-n? lc3 z z-and-cond-z? lc3 p p-and-cond-p? or or ; >> >> :: eval-br ( lc3 n z p offset -- lc3 ) >> lc3 n z p br-should-jump [ lc3 offset jump-by ] [ lc3 ] if ; >> >> CONSTANT: OPCODE_MAP H{ >> { 0 { [ parse-br ] [ eval-br ] } } >> { 1 "add" } >> { 2 "ld" } >> { 3 "st" } >> { 4 "jsr" } >> { 5 "and" } >> { 6 "ldr" } >> { 7 "str" } >> { 8 "rti" } >> { 9 "not" } >> { 10 "ldi" } >> { 11 "sti" } >> { 12 "jmp" } >> { 14 "lea" } >> { 15 "trap" } >> } >> >> : parser-evaluator ( opcode -- parser evaluator ) >> OPCODE_MAP at [ first ] [ second ] bi ; >> >> >> : _eval ( lc3 parser: ( instruction -- ..a ) evaluator: ( ..a -- lc3 ) -- >> lc3 ) >> [ call( instruction -- ..a ) ] [ call( ..a -- lc3 ) ] bi* ; inline >> >> PRIVATE> >> >> ALIAS: instruction 16bit >> >> : eval ( instruction -- lc3 ) >> instruction>opcode parser-evaluator _eval ; >> > > A preemptive thanks to anyone who will take the time to help me get a > better understanding of this issue. > > Best Regards, > Di Sera Luca > _______________________________________________ > Factor-talk mailing list > Factor-talk@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/factor-talk >
_______________________________________________ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk