Annotation of gforth/kernel/basics.fs, revision 1.20

1.1       anton       1: \ kernel.fs    GForth kernel                        17dec92py
                      2: 
1.7       anton       3: \ Copyright (C) 1995,1998 Free Software Foundation, Inc.
1.1       anton       4: 
                      5: \ This file is part of Gforth.
                      6: 
                      7: \ Gforth is free software; you can redistribute it and/or
                      8: \ modify it under the terms of the GNU General Public License
                      9: \ as published by the Free Software Foundation; either version 2
                     10: \ of the License, or (at your option) any later version.
                     11: 
                     12: \ This program is distributed in the hope that it will be useful,
                     13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: \ GNU General Public License for more details.
                     16: 
                     17: \ You should have received a copy of the GNU General Public License
                     18: \ along with this program; if not, write to the Free Software
                     19: \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     20: 
                     21: \ Idea and implementation: Bernd Paysan (py)
                     22: 
1.16      jwilke     23: \ Needs:
                     24: 
                     25: require ./vars.fs
                     26: 
                     27: hex
1.1       anton      28: 
                     29: \ labels for some code addresses
                     30: 
                     31: \- NIL NIL AConstant NIL \ gforth
                     32: 
                     33: \ Aliases
                     34: 
1.4       jwilke     35: [IFUNDEF] r@
1.1       anton      36: ' i Alias r@ ( -- w ; R: w -- w ) \ core r-fetch
1.12      crook      37: \G Copy @var{w} from the return stack to the data stack.
1.4       jwilke     38: [THEN]
1.1       anton      39: 
                     40: \ !! this is machine-dependent, but works on all but the strangest machines
                     41: 
1.10      anton      42: : maxaligned ( addr -- f-addr ) \ gforth
1.1       anton      43:     [ /maxalign 1 - ] Literal + [ 0 /maxalign - ] Literal and ;
                     44: \ !! machine-dependent and won't work if "0 >body" <> "0 >body maxaligned"
                     45: ' maxaligned Alias cfaligned ( addr1 -- addr2 ) \ gforth
                     46: 
                     47: : chars ( n1 -- n2 ) \ core
1.15      crook      48: \G @i{n2} is the number of address units corresponding to @i{n1} chars.""
1.1       anton      49: ; immediate
                     50: 
                     51: 
                     52: \ : A!    ( addr1 addr2 -- ) \ gforth
                     53: \    dup relon ! ;
                     54: \ : A,    ( addr -- ) \ gforth
                     55: \    here cell allot A! ;
                     56: ' ! alias A! ( addr1 addr2 -- ) \ gforth
                     57: 
1.2       anton      58: \ UNUSED                                                17may93jaw
                     59: 
1.4       jwilke     60: has? ec 
                     61: [IF]
                     62: unlock ram-dictionary area nip lock
                     63: Constant dictionary-end
                     64: [ELSE]
1.2       anton      65: : dictionary-end ( -- addr )
                     66:     forthstart [ 3 cells ] Aliteral @ + ;
1.4       jwilke     67: [THEN]
1.2       anton      68: 
1.14      anton      69: : usable-dictionary-end ( -- addr )
                     70:     dictionary-end [ word-pno-size pad-minsize + ] Literal - ;
                     71: 
1.2       anton      72: : unused ( -- u ) \ core-ext
1.13      crook      73:     \G Return the amount of free space remaining (in address units) in
                     74:     \G the region addressed by @code{here}.
1.14      anton      75:     usable-dictionary-end here - ;
1.2       anton      76: 
1.1       anton      77: \ here is used for pad calculation!
                     78: 
                     79: : dp    ( -- addr ) \ gforth
                     80:     dpp @ ;
1.13      crook      81: : here  ( -- addr ) \ core
                     82:     \G Return the address of the next free location in data space.
1.1       anton      83:     dp @ ;
                     84: 
                     85: \ on off                                               23feb93py
                     86: 
1.4       jwilke     87: \ on is used by docol:
1.15      crook      88: : on  ( a-addr -- ) \ gforth
                     89:     \G Set the (value of the) variable  at @i{a-addr} to @code{true}.
1.1       anton      90:     true  swap ! ;
1.15      crook      91: : off ( a-addr -- ) \ gforth
                     92:     \G Set the (value of the) variable at @i{a-addr} to @code{false}.
1.1       anton      93:     false swap ! ;
                     94: 
                     95: \ dabs roll                                           17may93jaw
                     96: 
1.18      crook      97: : dabs ( d1 -- d2 ) \ double d-abs
1.1       anton      98:     dup 0< IF dnegate THEN ;
                     99: 
                    100: : roll  ( x0 x1 .. xn n -- x1 .. xn x0 ) \ core-ext
                    101:   dup 1+ pick >r
                    102:   cells sp@ cell+ dup cell+ rot move drop r> ;
                    103: 
                    104: \ place bounds                                         13feb93py
                    105: 
                    106: : place  ( addr len to -- ) \ gforth
                    107:     over >r  rot over 1+  r> move c! ;
                    108: : bounds ( beg count -- end beg ) \ gforth
                    109:     over + swap ;
                    110: 
                    111: \ (word)                                               22feb93py
                    112: 
                    113: : scan   ( addr1 n1 char -- addr2 n2 ) \ gforth
                    114:     \ skip all characters not equal to char
                    115:     >r
                    116:     BEGIN
                    117:        dup
                    118:     WHILE
                    119:        over c@ r@ <>
                    120:     WHILE
                    121:        1 /string
                    122:     REPEAT  THEN
                    123:     rdrop ;
                    124: : skip   ( addr1 n1 char -- addr2 n2 ) \ gforth
                    125:     \ skip all characters equal to char
                    126:     >r
                    127:     BEGIN
                    128:        dup
                    129:     WHILE
                    130:        over c@ r@  =
                    131:     WHILE
                    132:        1 /string
                    133:     REPEAT  THEN
                    134:     rdrop ;
                    135: 
                    136: \ digit?                                               17dec92py
                    137: 
                    138: : digit?   ( char -- digit true/ false ) \ gforth
                    139:   base @ $100 =
                    140:   IF
                    141:     true EXIT
                    142:   THEN
                    143:   toupper [char] 0 - dup 9 u> IF
1.16      jwilke    144:     [ char A char 9 1 + -  ] literal -
1.1       anton     145:     dup 9 u<= IF
                    146:       drop false EXIT
                    147:     THEN
                    148:   THEN
                    149:   dup base @ u>= IF
                    150:     drop false EXIT
                    151:   THEN
                    152:   true ;
                    153: 
                    154: : accumulate ( +d0 addr digit - +d1 addr )
                    155:   swap >r swap  base @  um* drop rot  base @  um* d+ r> ;
                    156: 
1.18      crook     157: : >number ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 ) \ core to-number
1.13      crook     158:     \G Attempt to convert the character string @var{c-addr1, u1} to an
                    159:     \G unsigned number in the current number base. The double
                    160:     \G @var{ud1} accumulates the result of the conversion to form
                    161:     \G @var{ud2}. Conversion continues, left-to-right, until the whole
                    162:     \G string is converted or a character that is not convertable in
                    163:     \G the current number base is encountered (including + or -). For
                    164:     \G each convertable character, @var{ud1} is first multiplied by
                    165:     \G the value in @code{BASE} and then incremented by the value
                    166:     \G represented by the character. @var{c-addr2} is the location of
                    167:     \G the first unconverted character (past the end of the string if
                    168:     \G the whole string was converted). @var{u2} is the number of
                    169:     \G unconverted characters in the string. Overflow is not detected.
1.1       anton     170:     0
                    171:     ?DO
                    172:        count digit?
                    173:     WHILE
                    174:        accumulate
                    175:     LOOP
                    176:         0
                    177:     ELSE
                    178:        1- I' I -
                    179:        UNLOOP
                    180:     THEN ;
                    181: 
                    182: \ s>d um/mod                                           21mar93py
                    183: 
                    184: : s>d ( n -- d ) \ core                s-to-d
                    185:     dup 0< ;
                    186: 
                    187: : ud/mod ( ud1 u2 -- urem udquot ) \ gforth
                    188:     >r 0 r@ um/mod r> swap >r
                    189:     um/mod r> ;
                    190: 
                    191: \ catch throw                                          23feb93py
                    192: \ bounce                                                08jun93jaw
                    193: 
                    194: \ !! allow the user to add rollback actions    anton
                    195: \ !! use a separate exception stack?           anton
                    196: 
1.5       jwilke    197: has? glocals [IF]
1.12      crook     198: : lp@ ( -- addr ) \ gforth     lp-fetch
1.1       anton     199:  laddr# [ 0 , ] ;
                    200: [THEN]
                    201: 
1.17      anton     202: defer catch ( x1 .. xn xt -- y1 .. ym 0 / z1 .. zn error ) \ exception
                    203: :noname ( ... xt -- ... 0 )
                    204:     execute 0 ;
                    205: is catch
1.1       anton     206: 
1.17      anton     207: defer throw ( y1 .. ym error/0 -- y1 .. ym / z1 .. zn error ) \ exception
1.19      anton     208: :noname ( y1 .. ym error/0 -- y1 .. ym / z1 .. zn error )
                    209:     ?dup if
                    210:        [ here forthstart 9 cells + ! ]
1.20    ! anton     211:        cr .error cr 1 (bye)
1.19      anton     212:     then ;
                    213: is throw
                    214: 
1.1       anton     215: \ (abort")
                    216: 
                    217: : (abort")
                    218:     "lit >r
                    219:     IF
                    220:        r> "error ! -2 throw
                    221:     THEN
                    222:     rdrop ;
1.6       pazsan    223: 
                    224: : abort ( ?? -- ?? ) \ core,exception-ext
1.12      crook     225:     \G Empty the data stack and perform the functions of @code{quit}.
                    226:     \G Since the exception word set is present, this is performed by
                    227:     \G @code{-1 throw}.
1.6       pazsan    228:     -1 throw ;
1.1       anton     229: 
                    230: \ ?stack                                               23feb93py
                    231: 
                    232: : ?stack ( ?? -- ?? ) \ gforth
1.3       jwilke    233:     sp@ sp0 @ u> IF    -4 throw  THEN
1.5       jwilke    234: [ has? floating [IF] ]
1.3       jwilke    235:     fp@ fp0 @ u> IF  -&45 throw  THEN
1.1       anton     236: [ [THEN] ]
                    237: ;
                    238: \ ?stack should be code -- it touches an empty stack!
                    239: 
                    240: \ DEPTH                                                 9may93jaw
                    241: 
1.9       crook     242: : depth ( -- +n ) \ core depth
1.12      crook     243:     \G @var{+n} is the number of values that were on the data stack before
                    244:     \G @var{+n} itself was placed on the stack.
1.3       jwilke    245:     sp@ sp0 @ swap - cell / ;
1.9       crook     246: 
                    247: : clearstack ( ... -- ) \ gforth clear-stack
                    248:     \G remove and discard all/any items from the data stack.
1.3       jwilke    249:     sp0 @ sp! ;
1.1       anton     250: 
                    251: \ Strings                                               22feb93py
                    252: 
                    253: : "lit ( -- addr )
                    254:   r> r> dup count + aligned >r swap >r ;
                    255: 
                    256: \ */MOD */                                              17may93jaw
                    257: 
                    258: \ !! I think */mod should have the same rounding behaviour as / - anton
                    259: : */mod ( n1 n2 n3 -- n4 n5 ) \ core   star-slash-mod
                    260:     >r m* r> sm/rem ;
                    261: 
                    262: : */ ( n1 n2 n3 -- n4 ) \ core star-slash
                    263:     */mod nip ;
                    264: 
                    265: \ HEX DECIMAL                                           2may93jaw
                    266: 
                    267: : decimal ( -- ) \ core
1.9       crook     268:     \G Set the numeric conversion radix (the value of @code{BASE}) to 10
                    269:     \G (decimal).
1.1       anton     270:     a base ! ;
                    271: : hex ( -- ) \ core-ext
1.9       crook     272:     \G Set the numeric conversion radix (the value of @code{BASE}) to 16
                    273:     \G (hexadecimal).
1.1       anton     274:     10 base ! ;
                    275: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>