Annotation of qemu/roms/openbios/forth/device/fcode.fs, revision 1.1.1.1

1.1       root        1: \ tag: FCode implementation functions
                      2: \ 
                      3: \ this code implements IEEE 1275-1994 ch. 5.3.3
                      4: \ 
                      5: \ Copyright (C) 2003 Stefan Reinauer
                      6: \ 
                      7: \ See the file "COPYING" for further information about
                      8: \ the copyright and warranty status of this work.
                      9: \ 
                     10: 
                     11: hex 
                     12: 
                     13: 0    value fcode-sys-table \ table with built-in fcodes (0-0x7ff)
                     14: 
                     15: true value ?fcode-offset16 \ fcode offsets are 16 instead of 8 bit?
                     16: 1    value fcode-spread    \ fcode spread (1, 2 or 4)
                     17: 0    value fcode-table     \ pointer to fcode table
                     18: false value ?fcode-verbose  \ do verbose fcode execution?
                     19: 
                     20: defer _fcode-debug?        \ If true, save names for FCodes with headers
                     21: true value fcode-headers?  \ If true, possibly save names for FCodes.
                     22: 
                     23: 0 value fcode-stream-start \ start address of fcode stream
                     24: 0 value fcode-stream       \ current fcode stream address
                     25: 
                     26: variable fcode-end         \ state variable, if true, fcode program terminates.
                     27: defer fcode-c@             \ get byte
                     28: 
                     29: : fcode-push-state ( -- <state information> )
                     30:   ?fcode-offset16
                     31:   fcode-spread
                     32:   fcode-table
                     33:   fcode-headers?
                     34:   fcode-stream-start
                     35:   fcode-stream
                     36:   fcode-end @
                     37:   ['] fcode-c@ behavior
                     38: ;
                     39: 
                     40: : fcode-pop-state ( <state information> -- )
                     41:   to fcode-c@
                     42:   fcode-end !
                     43:   to fcode-stream
                     44:   to fcode-stream-start
                     45:   to fcode-headers?
                     46:   to fcode-table
                     47:   to fcode-spread
                     48:   to ?fcode-offset16
                     49: ;
                     50:   
                     51: \ 
                     52: \ fcode access helper functions
                     53: \ 
                     54: 
                     55: \ fcode-ptr
                     56: \   convert FCode number to pointer to xt in FCode table.
                     57: 
                     58: : fcode-ptr ( u16 -- *xt )
                     59:   cells
                     60:   fcode-table ?dup if + exit then
                     61:   
                     62:   \ we are not parsing fcode at the moment
                     63:   dup 800 cells u>= abort" User FCODE# referenced."
                     64:   fcode-sys-table +
                     65: ;
                     66:   
                     67: \ fcode>xt
                     68: \   get xt according to an FCode#
                     69: 
                     70: : fcode>xt ( u16 -- xt )
                     71:   fcode-ptr @
                     72:   ;
                     73: 
                     74: \ fcode-num8
                     75: \   get 8bit from FCode stream, taking spread into regard.
                     76: 
                     77: : fcode-num8 ( -- c ) ( F: c -- )
                     78:   fcode-stream
                     79:   dup fcode-spread + to fcode-stream 
                     80:   fcode-c@
                     81:   ;
                     82: 
                     83: \ fcode-num8-signed ( -- c ) ( F: c -- )
                     84: \   get 8bit signed from FCode stream
                     85: 
                     86: : fcode-num8-signed
                     87:   fcode-num8
                     88:   dup 80 and 0> if
                     89:      ff invert or
                     90:   then
                     91:   ;
                     92: 
                     93: \ fcode-num16
                     94: \   get 16bit from FCode stream
                     95: 
                     96: : fcode-num16 ( -- num16 )
                     97:   fcode-num8 fcode-num8 swap bwjoin
                     98:   ;
                     99: 
                    100: \ fcode-num16-signed ( -- c ) ( F: c -- )
                    101: \   get 16bit signed from FCode stream
                    102: 
                    103: : fcode-num16-signed
                    104:   fcode-num16
                    105:   dup 8000 and 0> if
                    106:      ffff invert or
                    107:   then
                    108:   ;
                    109: 
                    110: \ fcode-num32
                    111: \   get 32bit from FCode stream
                    112: 
                    113: : fcode-num32 ( -- num32 )
                    114:   fcode-num8 fcode-num8
                    115:   fcode-num8 fcode-num8
                    116:   swap 2swap swap bljoin
                    117:   ;
                    118:  
                    119: \ fcode#
                    120: \   Get an FCode# from FCode stream
                    121: 
                    122: : fcode# ( -- fcode# )
                    123:   fcode-num8
                    124:   dup 1 f between if
                    125:     fcode-num8 swap bwjoin
                    126:   then
                    127:   ;
                    128: 
                    129: \ fcode-offset
                    130: \   get offset from FCode stream.
                    131: 
                    132: : fcode-offset ( -- offset )
                    133:   ?fcode-offset16 if
                    134:     fcode-num16-signed
                    135:   else
                    136:     fcode-num8-signed
                    137:   then
                    138: 
                    139:   \ Display offset in verbose mode
                    140:   ?fcode-verbose if
                    141:     dup ."        (offset) " . cr
                    142:   then
                    143:   ;
                    144: 
                    145: \ fcode-string
                    146: \   get a string from FCode stream, store in pocket.
                    147: 
                    148: : fcode-string ( -- addr len )
                    149:   pocket dup
                    150:   fcode-num8
                    151:   dup rot c!
                    152:   2dup bounds ?do
                    153:     fcode-num8 i c!
                    154:   loop
                    155: 
                    156:   \ Display string in verbose mode
                    157:   ?fcode-verbose if
                    158:     2dup ."        (const) " type cr
                    159:   then
                    160:   ;
                    161:     
                    162: \ fcode-header
                    163: \   retrieve FCode header from FCode stream
                    164: 
                    165: : fcode-header
                    166:   fcode-num8
                    167:   fcode-num16
                    168:   fcode-num32
                    169:   ?fcode-verbose if
                    170:     ." Found FCode header:" cr rot
                    171:     ."   Format   : " u. cr swap
                    172:     ."   Checksum : " u. cr
                    173:     ."   Length   : " u. cr
                    174:   else
                    175:     3drop
                    176:   then
                    177:   \ TODO checksum
                    178:   ;
                    179: 
                    180: \ writes currently created word as fcode# read from stream
                    181: \ 
                    182: 
                    183: : fcode! ( F:FCode# -- )
                    184:   here fcode#
                    185: 
                    186:   \ Display fcode# in verbose mode
                    187:   ?fcode-verbose if
                    188:     dup ."        (fcode#) " . cr
                    189:   then
                    190:   fcode-ptr !
                    191:   ;
                    192: 
                    193:   
                    194: \ 
                    195: \ 5.3.3.1 Defining new FCode functions.
                    196: \ 
                    197: 
                    198: \ instance ( -- )   
                    199: \   Mark next defining word as instance specific.
                    200: \  (defined in bootstrap.fs)
                    201: 
                    202: \ instance-init ( wid buffer -- )
                    203: \   Copy template from specified wordlist to instance
                    204: \ 
                    205: 
                    206: : instance-init
                    207:   swap
                    208:   begin @ dup 0<> while
                    209:     dup /n + @ instance-cfa? if         \ buffer dict
                    210:       2dup 2 /n* + @ +                  \ buffer dict dest
                    211:       over 3 /n* + @                    \ buffer dict dest size
                    212:       2 pick 4 /n* +                    \ buffer dict dest size src
                    213:       -rot
                    214:       move
                    215:     then
                    216:   repeat
                    217:   2drop
                    218:   ;
                    219: 
                    220: 
                    221: \ new-token ( F:/FCode#/ -- ) 
                    222: \   Create a new unnamed FCode function
                    223: 
                    224: : new-token 
                    225:   0 0 header
                    226:   fcode!
                    227:   ;
                    228: 
                    229:   
                    230: \ named-token (F:FCode-string FCode#/ -- )
                    231: \   Create a new possibly named FCode function.
                    232: 
                    233: : named-token 
                    234:   fcode-string
                    235:   _fcode-debug? not if
                    236:     2drop 0 0
                    237:   then
                    238:   header
                    239:   fcode!
                    240:   ;
                    241: 
                    242:   
                    243: \ external-token (F:/FCode-string FCode#/ -- )
                    244: \   Create a new named FCode function
                    245: 
                    246: : external-token 
                    247:   fcode-string header
                    248:   fcode!
                    249:   ;
                    250: 
                    251:   
                    252: \ b(;) ( -- ) 
                    253: \   End an FCode colon definition.
                    254: 
                    255: : b(;)
                    256:   ['] ; execute
                    257:   ; immediate
                    258: 
                    259: 
                    260: \ b(:) ( -- ) ( E: ... -- ??? )
                    261: \   Defines type of new FCode function as colon definition.
                    262: 
                    263: : b(:)
                    264:   1 , ]
                    265:   ;
                    266: 
                    267: 
                    268: \ b(buffer:) ( size -- ) ( E:  -- a-addr )  
                    269: \   Defines type of new FCode function as buffer:.
                    270: 
                    271: : b(buffer:)
                    272:   4 , allot
                    273:   reveal
                    274:   ;
                    275: 
                    276: \ b(constant) ( nl -- ) ( E: -- nl )
                    277: \   Defines type of new FCode function as constant.
                    278: 
                    279: : b(constant)
                    280:   3 , , 
                    281:   reveal
                    282:   ;
                    283: 
                    284: 
                    285: \ b(create) ( -- ) ( E: -- a-addr )
                    286: \   Defines type of new FCode function as create word.
                    287: 
                    288: : b(create)
                    289:   6 , 
                    290:   ['] noop ,
                    291:   reveal
                    292:   ;
                    293: 
                    294: 
                    295: \ b(defer) ( -- ) ( E: ... -- ??? )  
                    296: \   Defines type of new FCode function as defer word.
                    297: 
                    298: : b(defer)
                    299:   5 ,
                    300:   ['] (undefined-defer) ,
                    301:   ['] (semis) ,
                    302:   reveal
                    303:   ;
                    304: 
                    305: 
                    306: \ b(field) ( offset size -- offset+size ) ( E: addr -- addr+offset )
                    307: \   Defines type of new FCode function as field.
                    308: 
                    309: : b(field)
                    310:   6 ,
                    311:   ['] noop ,
                    312:   reveal
                    313:     over ,
                    314:     +
                    315:   does>
                    316:     @ +
                    317:   ;
                    318: 
                    319:   
                    320: \ b(value) ( x -- ) (E: -- x )
                    321: \   Defines type of new FCode function as value.
                    322:   
                    323: : b(value)
                    324:   3 , , reveal
                    325:   ;
                    326: 
                    327: 
                    328: \ b(variable) ( -- ) ( E: -- a-addr )
                    329: \   Defines type of new FCode function as variable.
                    330: 
                    331: : b(variable)
                    332:   4 , 0 ,
                    333:   reveal
                    334:   ;
                    335:   
                    336:   
                    337: \ (is-user-word) ( name-str name-len xt -- ) ( E: ... -- ??? )
                    338: \   Create a new named user interface command.
                    339: 
                    340: : (is-user-word)
                    341:   ;
                    342: 
                    343:   
                    344: \ get-token ( fcode# -- xt immediate? )
                    345: \   Convert FCode number to function execution token.
                    346: 
                    347: : get-token
                    348:   fcode>xt dup immediate?
                    349:   ;
                    350: 
                    351: 
                    352: \ set-token ( xt immediate? fcode# -- )
                    353: \   Assign FCode number to existing function.
                    354:   
                    355: : set-token
                    356:   nip \ TODO we use the xt's immediate state for now.
                    357:   fcode-ptr !
                    358:   ;
                    359: 
                    360:   
                    361:   
                    362: 
                    363: \ 
                    364: \ 5.3.3.2 Literals
                    365: \ 
                    366: 
                    367: 
                    368: \ b(lit) ( -- n1 ) 
                    369: \   Numeric literal FCode. Followed by FCode-num32.
                    370: 
                    371: 64bit? [IF]
                    372: : b(lit)
                    373:   fcode-num32 32>64
                    374:   state @ if
                    375:     ['] (lit) , ,
                    376:   then
                    377:   ; immediate
                    378: [ELSE]
                    379: : b(lit)
                    380:   fcode-num32 
                    381:   state @ if
                    382:     ['] (lit) , ,
                    383:   then
                    384:   ; immediate
                    385: [THEN]
                    386: 
                    387: 
                    388: \ b(') ( -- xt )  
                    389: \   Function literal FCode. Followed by FCode#
                    390: 
                    391: : b(')
                    392:   fcode# fcode>xt
                    393:   state @ if
                    394:     ['] (lit) , , 
                    395:   then
                    396:   ; immediate
                    397: 
                    398:   
                    399: \ b(") ( -- str len )
                    400: \   String literal FCode. Followed by FCode-string.
                    401:   
                    402: : b(")
                    403:   fcode-string
                    404:   state @ if
                    405:     \ only run handle-text in compile-mode,
                    406:     \ otherwise we would waste a pocket.
                    407:     handle-text
                    408:   then
                    409:   ; immediate
                    410: 
                    411: 
                    412: \ 
                    413: \ 5.3.3.3 Controlling values and defers
                    414: \ 
                    415: 
                    416: \ behavior ( defer-xt -- contents-xt )
                    417: \ defined in bootstrap.fs
                    418: 
                    419: \ b(to) ( new-value -- )
                    420: \   FCode for setting values and defers. Followed by FCode#.
                    421: 
                    422: : b(to)
                    423:   fcode# fcode>xt 
                    424:   1 handle-lit
                    425:   ['] (to)
                    426:   state @ if 
                    427:     ,
                    428:   else
                    429:     execute
                    430:   then
                    431:   ; immediate
                    432: 
                    433: 
                    434: 
                    435: \ 
                    436: \ 5.3.3.4 Control flow
                    437: \ 
                    438: 
                    439: 
                    440: \ offset16 ( -- )
                    441: \   Makes subsequent FCode-offsets use 16-bit (not 8-bit) form.
                    442: 
                    443: : offset16
                    444:   true to ?fcode-offset16
                    445:   ;
                    446: 
                    447: 
                    448: \ bbranch ( -- )
                    449: \   Unconditional branch FCode. Followed by FCode-offset.
                    450:   
                    451: : bbranch
                    452:   fcode-offset 0< if \ if we jump backwards, we can forsee where it goes
                    453:     ['] dobranch ,
                    454:     resolve-dest
                    455:     execute-tmp-comp
                    456:   else
                    457:     setup-tmp-comp ['] dobranch ,
                    458:     here 0
                    459:     0 ,
                    460:     2swap
                    461:   then
                    462:   ; immediate
                    463: 
                    464: 
                    465: \ b?branch ( continue? -- )
                    466: \   Conditional branch FCode. Followed by FCode-offset.
                    467: 
                    468: : b?branch
                    469:   fcode-offset 0< if \ if we jump backwards, we can forsee where it goes
                    470:     ['] do?branch ,
                    471:     resolve-dest
                    472:     execute-tmp-comp
                    473:   else
                    474:     setup-tmp-comp ['] do?branch ,
                    475:     here 0
                    476:     0 ,
                    477:   then 
                    478:   ; immediate
                    479: 
                    480:   
                    481: \ b(<mark) ( -- )
                    482: \   Target of backward branches.
                    483: 
                    484: : b(<mark)
                    485:   setup-tmp-comp
                    486:   here 1
                    487:   ; immediate
                    488: 
                    489:   
                    490: \ b(>resolve) ( -- )
                    491: \   Target of forward branches.
                    492: 
                    493: : b(>resolve)
                    494:   resolve-orig
                    495:   execute-tmp-comp
                    496:   ; immediate
                    497: 
                    498:   
                    499: \ b(loop) ( -- )
                    500: \   End FCode do..loop. Followed by FCode-offset.
                    501: 
                    502: : b(loop)
                    503:   fcode-offset drop
                    504:   postpone loop
                    505:   ; immediate
                    506: 
                    507:   
                    508: \ b(+loop) ( delta -- )
                    509: \   End FCode do..+loop. Followed by FCode-offset.
                    510: 
                    511: : b(+loop)
                    512:   fcode-offset drop
                    513:   postpone +loop
                    514:   ; immediate
                    515: 
                    516:   
                    517: \ b(do) ( limit start -- )
                    518: \   Begin FCode do..loop. Followed by FCode-offset.
                    519: 
                    520: : b(do)
                    521:   fcode-offset drop
                    522:   postpone do
                    523:   ; immediate
                    524: 
                    525:   
                    526: \ b(?do) ( limit start -- )
                    527: \   Begin FCode ?do..loop. Followed by FCode-offset.
                    528: 
                    529: : b(?do)
                    530:   fcode-offset drop
                    531:   postpone ?do
                    532:   ; immediate
                    533: 
                    534:   
                    535: \ b(leave) ( -- )
                    536: \   Exit from a do..loop.
                    537:   
                    538: : b(leave)
                    539:   postpone leave
                    540:   ; immediate
                    541: 
                    542:   
                    543: \ b(case) ( sel -- sel )
                    544: \   Begin a case (multiple selection) statement.
                    545: 
                    546: : b(case)
                    547:   postpone case
                    548:   ; immediate
                    549: 
                    550:   
                    551: \ b(endcase) ( sel | <nothing> -- )
                    552: \   End a case (multiple selection) statement.
                    553: 
                    554: : b(endcase)
                    555:   postpone endcase
                    556:   ; immediate
                    557:   
                    558: 
                    559: \ b(of) ( sel of-val -- sel | <nothing> )
                    560: \   FCode for of in case statement. Followed by FCode-offset.
                    561: 
                    562: : b(of)
                    563:   fcode-offset drop
                    564:   postpone of
                    565:   ; immediate
                    566: 
                    567: \ b(endof) ( -- )
                    568: \   FCode for endof in case statement. Followed by FCode-offset.
                    569: 
                    570: : b(endof)
                    571:   fcode-offset drop
                    572:   postpone endof
                    573:   ; immediate

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.