--- gforth/cross.fs 2001/04/08 13:48:11 1.97 +++ gforth/cross.fs 2001/09/04 13:06:06 1.103 @@ -628,168 +628,167 @@ stack-warn [IF] : defempty? ; immediate [THEN] -\ \ GhostNames Ghosts 9may93jaw - -\ second name source to search trough list - -VARIABLE GhostNames -0 GhostNames ! - -: GhostName ( -- addr ) - align here GhostNames @ , GhostNames ! here 0 , - bl word count - \ 2dup type space - string, \ !! cfalign ? - align ; - \ Ghost Builder 06oct92py -\ new version with temp variable 10may93jaw - -VARIABLE VocTemp - -: previous VocTemp @ set-current ; - hex 4711 Constant 4712 Constant 4713 Constant 4714 Constant 4715 Constant -\ Compiler States +1 Constant -Variable comp-state -0 Constant interpreting -1 Constant compiling -2 Constant resolving -3 Constant assembling +Struct -Defer lit, ( n -- ) -Defer alit, ( n -- ) + \ link to next ghost (always the first element) + cell% field >next-ghost -Defer branch, ( target-addr -- ) \ compiles a branch -Defer ?branch, ( target-addr -- ) \ compiles a ?branch -Defer branchmark, ( -- branch-addr ) \ reserves room for a branch -Defer ?branchmark, ( -- branch-addr ) \ reserves room for a ?branch -Defer ?domark, ( -- branch-addr ) \ reserves room for a ?do branch -Defer branchto, ( -- ) \ actual program position is target of a branch (do e.g. alignment) -Defer branchtoresolve, ( branch-addr -- ) \ resolves a forward reference from branchmark -Defer branchfrom, ( -- ) \ ?! -Defer branchtomark, ( -- target-addr ) \ marks a branch destination - -Defer colon, ( tcfa -- ) \ compiles call to tcfa at current position -Defer prim, ( tcfa -- ) \ compiles a primitive invocation - \ at current position -Defer colonmark, ( -- addr ) \ marks a colon call -Defer colon-resolve ( tcfa addr -- ) - -Defer addr-resolve ( target-addr addr -- ) -Defer doer-resolve ( ghost res-pnt target-addr addr -- ghost res-pnt ) - -Defer do, ( -- do-token ) -Defer ?do, ( -- ?do-token ) -Defer for, ( -- for-token ) -Defer loop, ( do-token / ?do-token -- ) -Defer +loop, ( do-token / ?do-token -- ) -Defer next, ( for-token ) + \ type of ghost + cell% field >magic + + \ pointer where ghost is in target, or if unresolved + \ points to the where we have to resolve (linked-list) + cell% field >link -[IFUNDEF] ca>native -defer ca>native -[THEN] + \ execution symantics (while target compiling) of ghost + cell% field >exec -\ ghost structure + cell% field >exec-compile -: >magic ; \ type of ghost -: >link cell+ ; \ pointer where ghost is in target, or if unresolved - \ points to the where we have to resolve (linked-list) -: >exec cell+ cell+ ; \ execution symantics (while target compiling) of ghost -: >comp 3 cells + ; \ compilation semantics -: >end 4 cells + ; \ room for additional tags - \ for builder (create, variable...) words the - \ execution symantics of words built are placed here + cell% field >exec2 -\ resolve structure + cell% field >created -: >next ; \ link to next field -: >tag cell+ ; \ indecates type of reference: 0: call, 1: address, 2: doer -: >taddr cell+ cell+ ; -: >ghost 3 cells + ; -: >file 4 cells + ; -: >line 5 cells + ; + \ the xt of the created ghost word itself + cell% field >ghost-xt + + \ pointer to the counted string of the assiciated + \ assembler label + cell% field >asm-name + + \ mapped primitives have a special address, so + \ we are able to detect them + cell% field >asm-dummyaddr + + \ for builder (create, variable...) words + \ the execution symantics of words built are placed here + \ this is a doer ghost or a dummy ghost + cell% field >do:ghost + + cell% field >ghost-flags + + cell% field >ghost-name + +End-Struct ghost-struct -\ refer variables +Variable ghost-list +0 ghost-list ! Variable executed-ghost \ last executed ghost, needed in tcreate and gdoes> -Variable last-ghost \ last ghost that is created +\ Variable last-ghost \ last ghost that is created Variable last-header-ghost \ last ghost definitions with header -: (refered) ( ghost addr tag -- ) -\G creates a reference to ghost at address taddr - rot >r here r@ >link @ , r> >link ! - ( taddr tag ) , - ( taddr ) , - last-header-ghost @ , - loadfile , - sourceline# , - ; - -\ iForth makes only immediate directly after create -\ make atonce trick! ? +\ space for ghosts resolve structure +\ we create ghosts in a sepearte space +\ and not to the current host dp, because this +\ gives trouble with instant while compiling and creating +\ a ghost for a forward reference +\ BTW: we cannot allocate another memory region +\ because allot will check the overflow!! +Variable cross-space-dp +Create cross-space 250000 allot here 100 allot align +Constant cross-space-end +cross-space cross-space-dp ! +Variable cross-space-dp-orig + +: cross-space-used cross-space-dp @ cross-space - ; + +: >space ( -- ) + dp @ cross-space-dp-orig ! + cross-space-dp @ dp ! ; + +: space> ( -- ) + dp @ dup cross-space-dp ! + cross-space-end u> ABORT" CROSS: cross-space overflow" + cross-space-dp-orig @ dp ! ; + +: execute-exec execute ; +: execute-exec2 execute ; +: execute-exec-compile execute ; + +: NoExec + executed-ghost @ >exec2 @ + ?dup + IF execute-exec2 + ELSE true ABORT" CROSS: Don't execute ghost, or immediate target word" + THEN ; -Variable atonce atonce off +: (ghostheader) ( -- ) + ghost-list linked , 0 , ['] NoExec , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , ; -: NoExec true ABORT" CROSS: Don't execute ghost, or immediate target word" ; +: ghostheader ( -- ) (ghostheader) 0 , ; -: is-forward ( ghost -- ) - colonmark, 0 (refered) ; \ compile space for call +' Ghosts >wordlist Constant ghosts-wordlist -: GhostHeader , 0 , ['] NoExec , ['] is-forward , ; +\ the current wordlist for ghost definitions in the host +ghosts-wordlist Value current-ghosts : Make-Ghost ( "name" -- ghost ) - >in @ GhostName swap >in ! - - dup last-ghost ! - DOES> dup executed-ghost ! >exec @ execute ; + >space + \ save current and create in ghost vocabulary + get-current >r current-ghosts set-current + >in @ Create >in ! + \ some forth systems like iForth need the immediate directly + \ after the word is created + \ restore current + r> set-current + here (ghostheader) + bl word count string, align + space> + \ set ghost-xt field by doing a search + dup >ghost-name count + current-ghosts search-wordlist + 0= ABORT" CROSS: Just created, must be there!" + over >ghost-xt ! + DOES> + dup executed-ghost ! + >exec @ execute-exec ; \ ghost words 14oct92py \ changed: 10may93py/jaw -: gfind ( string -- ghost true/1 / string false ) +Defer search-ghosts + +: (search-ghosts) ( adr len -- cfa true | 0 ) + current-ghosts search-wordlist ; + + ' (search-ghosts) IS search-ghosts + +: gsearch ( addr len -- ghost true | 0 ) + search-ghosts + dup IF swap >body swap THEN ; + +: gfind ( string -- ghost true / string false ) \ searches for string in word-list ghosts - dup count [ ' ghosts >wordlist ] Literal search-wordlist - dup IF >r >body nip r> THEN ; + \ dup count type space + dup >r count gsearch + dup IF rdrop ELSE r> swap THEN ; : gdiscover ( xt -- ghost true | xt false ) - GhostNames + >r ghost-list BEGIN @ dup - WHILE 2dup - cell+ @ dup >magic @ <> - >r >link @ = r> and - IF cell+ @ nip true EXIT THEN + WHILE dup >magic @ <> + IF dup >link @ r@ = + IF rdrop true EXIT THEN + THEN REPEAT - drop false ; - -VARIABLE Already + drop r> false ; -: ghost ( "name" -- ghost ) - Already off - >in @ bl word gfind IF atonce off Already on nip EXIT THEN +: Ghost ( "name" -- ghost ) + >in @ bl word gfind IF nip EXIT THEN drop >in ! Make-Ghost ; : >ghostname ( ghost -- adr len ) - GhostNames - BEGIN @ dup - WHILE 2dup cell+ @ = - UNTIL nip 2 cells + count - ELSE 2drop - \ true abort" CROSS: Ghostnames inconsistent" - s" ?!?!?!" - THEN ; - -: .ghost ( ghost -- ) >ghostname type ; - -\ ' >ghostname ALIAS @name + >ghost-name count ; : forward? ( ghost -- flag ) >magic @ = ; @@ -797,52 +796,133 @@ VARIABLE Already : undefined? ( ghost -- flag ) >magic @ dup = swap = or ; +: immediate? ( ghost -- flag ) + >magic @ = ; + +Variable TWarnings +TWarnings on +Variable Exists-Warnings +Exists-Warnings on + +: exists-warning ( ghost -- ghost ) + TWarnings @ Exists-Warnings @ and + IF dup >ghostname warnhead type ." exists " THEN ; + +\ : HeaderGhost Ghost ; + +Variable reuse-ghosts reuse-ghosts off + +1 [IF] \ FIXME: define when vocs are ready +: HeaderGhost ( "name" -- ghost ) + >in @ + bl word count +\ 2dup type space + current-ghosts search-wordlist + IF >body dup undefined? reuse-ghosts @ or + IF nip EXIT + ELSE exists-warning + THEN + drop >in ! + ELSE >in ! + THEN + \ we keep the execution semantics of the prviously + \ defined words, this is a workaround + \ for the redefined \ until vocs work + Make-Ghost ; +[THEN] + + +: .ghost ( ghost -- ) >ghostname type ; + +\ ' >ghostname ALIAS @name + +: [G'] ( -- ghost : name ) +\G ticks a ghost and returns its address +\ bl word gfind 0= ABORT" CROSS: Ghost don't exists" + ghost state @ IF postpone literal THEN ; immediate + +: ghost>cfa ( ghost -- cfa ) + dup undefined? ABORT" CROSS: forward " >link @ ; + +1 Constant