|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.