Here's a question for those who really grok x86 . I'm working to implement my abstraction of a life spent in APL , more recently K , into Forth and chose Ron Aaron's Reva Forth because it was practical and built directly in a machine language , the WinTel in my notebook and on my desk .
I'm definitely working at my Peter Principle limit .
Here are my relevant notes from yesterday :
| ======================== | Mon.Sep,20150928 | ======================== |
| ... weird issue w simply nested fns remains
text> "lf tokcut rho | |>| 1432 | works
: tst "lf tokcut ; text> tst rho | works not
: tst "lf dup drop tokcut ; text> tst rho | works
: tst dup drop "lf tokcut ; text> tst rho | works not
Without even knowing anything else , how can a " dup drop " have any effect ? How for that matter can a call and a return have any effect ?
Here are some details . I've uploaded a copy of 4th.CoSy as of the 29th to
http://cosy.com/CoSy/4th.CoSy.html , 4thCoSy1509.zip , for anyone who wants to try the whole thing , and , since a basic use of CoSy is as a daily log , of which programming is just part of life , you can see the rather messy path of development leading up to the present .
One of the core concepts of APLs is "atomic apply" . In CoSy , nouns generically are reference counted list of lists with modulo indexing . Think of them as trees or bushes with individual items as leafs or "atoms" . And many verbs apply "atomically" . That is , the verb applies to each atom , or for a "dyadic" verb , each corresponding pair of atoms ( leafs ) . For example , in current 4th.CoSy :
i( 0 -1 )i 10 _i iota +i
0 0 2 2 4 4 6 6 8 8
But when lists are nested more deeply , the function has to recursively go out to the simple lists to apply to corresponding leafs . My friend Morten Kromberg recently gave an excellent Google Tech Talk on APL ,
https://youtu.be/PlM9BXfu7UY , specifically market leader , Dyalog , which he and his wife Gitte run . I recommend Morten's talk for a much deeper introduction to the nature and thrust of APL .
In properly implementing the recursive atomic apply "adverb" , as Ken Iverson would call it because it takes verbs as arguments , the desire for a "stack frame" vocabulary to simplify the writing and reading of these ubiquitous sorts of recursive verbs arose . It's in implementing the notions of George B. Lyons : Stack Frames and Local Variables :
http://www.forth.com/archive/jfar/vol3/no1/article3.pdf that this bug emerged .
Here's the vocabulary :
s0 cell- dup constant s1 dup dup ! variable, SFptr
| initialize StackFrame pointer
| I'm not sure what SFptr gets initialized to matters
| | relies for stopping on the 0th stack cell being set to itself
: SF+ | puts previous esi on the stack and saves current
esi@ cell- SFptr xchg ;
: SFx cells SFptr @ + ; | ( n -- n offset by current pointer )
: SF@ SFx @ ; : SF! SFx ! ; | Fetch and store relative to current pointer
: SF- | ( ... n -- drop n ) restores previous stack pointer and drops n items beyond current pointer .
>aux SFptr @ dup @ SFptr ! cell+ esi! aux> ndrop ;
These rely on the words ' esi@ and ' esi! which are the most complicated x86 I've ever written :) .
: esi@ inline{ 8D 76 FC 89 F0 } ; | lea esi,[esi-04] mov eax, esi
| esi contains the current stack ptr ,
| , ie , the address of the item which was ToS when it was called .
: esi! asm{ mov esi, eax } drop ;
| |(| esi@ esi! |)| ends up doing nothing |
: ndrop ( ... n -- drops n cells from stk ) | optimized from ' drop loop .
esi@ swap 1+ cells + esi! ;
| don't understand why :| : ndrop 1+ cells esi@ + esi! ; |: doesn't work .
Here are the definitions of ' dup and ' drop in Reva :
see dup see drop
00427A79 8D 76 FC lea esi,[esi-04]
00427A7C 89 06 mov [esi],eax
00427A7E C3 ret
0042799E 8B 06 mov eax,[esi]
004279A0 8D 76 04 lea esi,[esi+04]
004279A3 C3 ret
That pretty much defines the structure of the stack .
The problem could conceivably be in the reference incrementing and decrementing functions which call ' SF+ and ' SF- on entry and exit of functions . But I figure someone who really groks x86 can either point out how : dupdrop dup drop ; can have any effect wherever in the code . I probably could finesse the problem by sprinkling dupdrop in the right places in my code , but that's no substitute for understanding and eliminating the cause .
Thanks for any help .
Peace thru Freedom
Bob A