version 1.64, 2000/11/10 10:04:20
|
version 1.69, 2001/01/09 16:11:35
|
Line 74
|
Line 74
|
\ xt.* XT |
\ xt.* XT |
\ wid.* WID |
\ wid.* WID |
\ f83name.* F83Name * |
\ f83name.* F83Name * |
|
|
|
\E get-current prefixes set-current |
|
\E |
|
\E s" Bool" single data-stack type-prefix f |
|
\E s" Char" single data-stack type-prefix c |
|
\E s" Cell" single data-stack type-prefix n |
|
\E s" Cell" single data-stack type-prefix w |
|
\E s" UCell" single data-stack type-prefix u |
|
\E s" DCell" double data-stack type-prefix d |
|
\E s" UDCell" double data-stack type-prefix ud |
|
\E s" Float" single fp-stack type-prefix r |
|
\E s" Cell *" single data-stack type-prefix a_ |
|
\E s" Char *" single data-stack type-prefix c_ |
|
\E s" Float *" single data-stack type-prefix f_ |
|
\E s" DFloat *" single data-stack type-prefix df_ |
|
\E s" SFloat *" single data-stack type-prefix sf_ |
|
\E s" Xt" single data-stack type-prefix xt |
|
\E s" WID" single data-stack type-prefix wid |
|
\E s" struct F83Name *" single data-stack type-prefix f83name |
|
\E |
|
\E return-stack stack-prefix R: |
|
\E inst-stream stack-prefix # |
|
\E |
|
\E set-current |
|
|
\ |
\ |
\ |
\ |
\ |
\ |
Line 104 undefine(`index')
|
Line 129 undefine(`index')
|
undefine(`shift') |
undefine(`shift') |
|
|
noop ( -- ) gforth |
noop ( -- ) gforth |
; |
|
: |
: |
; |
; |
|
|
lit ( -- w ) gforth |
lit ( #w -- w ) gforth |
w = (Cell)NEXT_INST; |
|
INC_IP(1); |
|
: |
: |
r> dup @ swap cell+ >r ; |
r> dup @ swap cell+ >r ; |
|
|
Line 132 EXEC(*(Xt *)a_addr);
|
Line 154 EXEC(*(Xt *)a_addr);
|
\fhas? skipbranchprims 0= [IF] |
\fhas? skipbranchprims 0= [IF] |
\+glocals |
\+glocals |
|
|
branch-lp+!# ( -- ) gforth branch_lp_plus_store_number |
branch-lp+!# ( #ndisp #nlocals -- ) gforth branch_lp_plus_store_number |
/* this will probably not be used */ |
/* this will probably not be used */ |
branch_adjust_lp: |
lp += nlocals; |
lp += (Cell)(IP[1]); |
SET_IP((Xt *)(((Cell)(IP-2))+ndisp)); |
goto branch; |
|
|
|
\+ |
\+ |
|
|
branch ( -- ) gforth |
branch ( #ndisp -- ) gforth |
branch: |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
SET_IP((Xt *)(((Cell)IP)+(Cell)NEXT_INST)); |
|
: |
: |
r> dup @ + >r ; |
r> dup @ + >r ; |
|
|
\ condbranch(forthname,restline,code,forthcode) |
\ condbranch(forthname,stackeffect,restline,code,forthcode) |
\ this is non-syntactical: code must open a brace that is closed by the macro |
\ this is non-syntactical: code must open a brace that is closed by the macro |
define(condbranch, |
define(condbranch, |
$1 $2 |
$1 ( `#'ndisp $2 ) $3 |
$3 SET_IP((Xt *)(((Cell)IP)+(Cell)NEXT_INST)); |
$4 SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
NEXT; |
TAIL; |
} |
} |
else |
$5 |
INC_IP(1); |
|
$4 |
|
|
|
\+glocals |
\+glocals |
|
|
$1-lp+!# $2_lp_plus_store_number |
$1-lp+!`#' ( `#'ndisp `#'nlocals $2 ) $3_lp_plus_store_number |
$3 goto branch_adjust_lp; |
$4 lp += nlocals; |
|
SET_IP((Xt *)(((Cell)(IP-2))+ndisp)); |
|
TAIL; |
} |
} |
else |
|
INC_IP(2); |
|
|
|
\+ |
\+ |
) |
) |
|
|
condbranch(?branch,( f -- ) f83 question_branch, |
condbranch(?branch,f --,f83 question_branch, |
if (f==0) { |
if (f==0) { |
IF_spTOS(spTOS = sp[0]); |
|
,: |
,: |
0= dup \ !f !f |
0= dup \ !f !f |
r> dup @ \ !f !f IP branchoffset |
r> dup @ \ !f !f IP branchoffset |
Line 183 if (f==0) {
|
Line 200 if (f==0) {
|
|
|
\+xconds |
\+xconds |
|
|
?dup-?branch ( f -- f ) new question_dupe_question_branch |
?dup-?branch ( #ndisp f -- f ) new question_dupe_question_branch |
""The run-time procedure compiled by @code{?DUP-IF}."" |
""The run-time procedure compiled by @code{?DUP-IF}."" |
if (f==0) { |
if (f==0) { |
sp++; |
sp++; |
IF_spTOS(spTOS = sp[0]); |
IF_spTOS(spTOS = sp[0]); |
SET_IP((Xt *)(((Cell)IP)+(Cell)NEXT_INST)); |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
NEXT; |
TAIL; |
} |
} |
else |
|
INC_IP(1); |
|
|
|
?dup-0=-?branch ( f -- ) new question_dupe_zero_equals_question_branch |
?dup-0=-?branch ( #ndisp f -- ) new question_dupe_zero_equals_question_branch |
""The run-time procedure compiled by @code{?DUP-0=-IF}."" |
""The run-time procedure compiled by @code{?DUP-0=-IF}."" |
/* the approach taken here of declaring the word as having the stack |
/* the approach taken here of declaring the word as having the stack |
effect ( f -- ) and correcting for it in the branch-taken case costs a |
effect ( f -- ) and correcting for it in the branch-taken case costs a |
Line 202 few cycles in that case, but is easy to
|
Line 217 few cycles in that case, but is easy to
|
invocation */ |
invocation */ |
if (f!=0) { |
if (f!=0) { |
sp--; |
sp--; |
SET_IP((Xt *)(((Cell)IP)+(Cell)NEXT_INST)); |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
NEXT; |
NEXT; |
} |
} |
else |
|
INC_IP(1); |
|
|
|
\+ |
\+ |
\f[THEN] |
\f[THEN] |
\fhas? skiploopprims 0= [IF] |
\fhas? skiploopprims 0= [IF] |
|
|
condbranch((next),( -- ) cmFORTH paren_next, |
condbranch((next),R:n1 -- R:n2,cmFORTH paren_next, |
if ((*rp)--) { |
n2=n1-1; |
|
if (n1) { |
,: |
,: |
r> r> dup 1- >r |
r> r> dup 1- >r |
IF dup @ + >r ELSE cell+ >r THEN ;) |
IF dup @ + >r ELSE cell+ >r THEN ;) |
|
|
condbranch((loop),( -- ) gforth paren_loop, |
condbranch((loop),R:nlimit R:n1 -- R:nlimit R:n2,gforth paren_loop, |
Cell index = *rp+1; |
n2=n1+1; |
Cell limit = rp[1]; |
if (n2 != nlimit) { |
if (index != limit) { |
|
*rp = index; |
|
,: |
,: |
r> r> 1+ r> 2dup = |
r> r> 1+ r> 2dup = |
IF >r 1- >r cell+ >r |
IF >r 1- >r cell+ >r |
ELSE >r >r dup @ + >r THEN ;) |
ELSE >r >r dup @ + >r THEN ;) |
|
|
condbranch((+loop),( n -- ) gforth paren_plus_loop, |
condbranch((+loop),n R:nlimit R:n1 -- R:nlimit R:n2,gforth paren_plus_loop, |
/* !! check this thoroughly */ |
/* !! check this thoroughly */ |
Cell index = *rp; |
|
/* sign bit manipulation and test: (x^y)<0 is equivalent to (x<0) != (y<0) */ |
/* sign bit manipulation and test: (x^y)<0 is equivalent to (x<0) != (y<0) */ |
/* dependent upon two's complement arithmetic */ |
/* dependent upon two's complement arithmetic */ |
Cell olddiff = index-rp[1]; |
Cell olddiff = n1-nlimit; |
|
n2=n1+n; |
if ((olddiff^(olddiff+n))>=0 /* the limit is not crossed */ |
if ((olddiff^(olddiff+n))>=0 /* the limit is not crossed */ |
|| (olddiff^n)>=0 /* it is a wrap-around effect */) { |
|| (olddiff^n)>=0 /* it is a wrap-around effect */) { |
#ifdef i386 |
|
*rp += n; |
|
#else |
|
*rp = index + n; |
|
#endif |
|
IF_spTOS(spTOS = sp[0]); |
|
,: |
,: |
r> swap |
r> swap |
r> r> 2dup - >r |
r> r> 2dup - >r |
Line 252 if ((olddiff^(olddiff+n))>=0 /* the li
|
Line 258 if ((olddiff^(olddiff+n))>=0 /* the li
|
|
|
\+xconds |
\+xconds |
|
|
condbranch((-loop),( u -- ) gforth paren_minus_loop, |
condbranch((-loop),u R:nlimit R:n1 -- R:nlimit R:n2,gforth paren_minus_loop, |
/* !! check this thoroughly */ |
UCell olddiff = n1-nlimit; |
Cell index = *rp; |
n2=n1-u; |
UCell olddiff = index-rp[1]; |
|
if (olddiff>u) { |
if (olddiff>u) { |
#ifdef i386 |
|
*rp -= u; |
|
#else |
|
*rp = index - u; |
|
#endif |
|
IF_spTOS(spTOS = sp[0]); |
|
,) |
,) |
|
|
condbranch((s+loop),( n -- ) gforth paren_symmetric_plus_loop, |
condbranch((s+loop),n R:nlimit R:n1 -- R:nlimit R:n2,gforth paren_symmetric_plus_loop, |
""The run-time procedure compiled by S+LOOP. It loops until the index |
""The run-time procedure compiled by S+LOOP. It loops until the index |
crosses the boundary between limit and limit-sign(n). I.e. a symmetric |
crosses the boundary between limit and limit-sign(n). I.e. a symmetric |
version of (+LOOP)."" |
version of (+LOOP)."" |
/* !! check this thoroughly */ |
/* !! check this thoroughly */ |
Cell index = *rp; |
Cell diff = n1-nlimit; |
Cell diff = index-rp[1]; |
|
Cell newdiff = diff+n; |
Cell newdiff = diff+n; |
if (n<0) { |
if (n<0) { |
diff = -diff; |
diff = -diff; |
newdiff = -newdiff; |
newdiff = -newdiff; |
} |
} |
|
n2=n1+n; |
if (diff>=0 || newdiff<0) { |
if (diff>=0 || newdiff<0) { |
#ifdef i386 |
|
*rp += n; |
|
#else |
|
*rp = index + n; |
|
#endif |
|
IF_spTOS(spTOS = sp[0]); |
|
,) |
,) |
|
|
\+ |
\+ |
|
|
unloop ( -- ) core |
unloop ( R:w1 R:w2 -- ) core |
rp += 2; |
/* !! alias for 2rdrop */ |
: |
: |
r> rdrop rdrop >r ; |
r> rdrop rdrop >r ; |
|
|
(for) ( ncount -- ) cmFORTH paren_for |
(for) ( ncount -- R:nlimit R:ncount ) cmFORTH paren_for |
/* or (for) = >r -- collides with unloop! */ |
/* or (for) = >r -- collides with unloop! */ |
*--rp = 0; |
nlimit=0; |
*--rp = ncount; |
|
: |
: |
r> swap 0 >r >r >r ; |
r> swap 0 >r >r >r ; |
|
|
(do) ( nlimit nstart -- ) gforth paren_do |
(do) ( nlimit nstart -- R:nlimit R:nstart ) gforth paren_do |
/* or do it in high-level? 0.09/0.23% */ |
|
*--rp = nlimit; |
|
*--rp = nstart; |
|
: |
: |
r> swap rot >r >r >r ; |
r> swap rot >r >r >r ; |
|
|
(?do) ( nlimit nstart -- ) gforth paren_question_do |
(?do) ( #ndisp nlimit nstart -- R:nlimit R:nstart ) gforth paren_question_do |
*--rp = nlimit; |
|
*--rp = nstart; |
|
if (nstart == nlimit) { |
if (nstart == nlimit) { |
IF_spTOS(spTOS = sp[0]); |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
goto branch; |
TAIL; |
} |
|
else { |
|
INC_IP(1); |
|
} |
} |
: |
: |
2dup = |
2dup = |
Line 327 else {
|
Line 311 else {
|
|
|
\+xconds |
\+xconds |
|
|
(+do) ( nlimit nstart -- ) gforth paren_plus_do |
(+do) ( #ndisp nlimit nstart -- R:nlimit R:nstart ) gforth paren_plus_do |
*--rp = nlimit; |
|
*--rp = nstart; |
|
if (nstart >= nlimit) { |
if (nstart >= nlimit) { |
IF_spTOS(spTOS = sp[0]); |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
goto branch; |
TAIL; |
} |
|
else { |
|
INC_IP(1); |
|
} |
} |
: |
: |
swap 2dup |
swap 2dup |
Line 347 else {
|
Line 326 else {
|
cell+ |
cell+ |
THEN >r ; |
THEN >r ; |
|
|
(u+do) ( ulimit ustart -- ) gforth paren_u_plus_do |
(u+do) ( #ndisp ulimit ustart -- R:ulimit R:ustart ) gforth paren_u_plus_do |
*--rp = ulimit; |
|
*--rp = ustart; |
|
if (ustart >= ulimit) { |
if (ustart >= ulimit) { |
IF_spTOS(spTOS = sp[0]); |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
goto branch; |
TAIL; |
} |
|
else { |
|
INC_IP(1); |
|
} |
} |
: |
: |
swap 2dup |
swap 2dup |
Line 367 else {
|
Line 341 else {
|
cell+ |
cell+ |
THEN >r ; |
THEN >r ; |
|
|
(-do) ( nlimit nstart -- ) gforth paren_minus_do |
(-do) ( #ndisp nlimit nstart -- R:nlimit R:nstart ) gforth paren_minus_do |
*--rp = nlimit; |
|
*--rp = nstart; |
|
if (nstart <= nlimit) { |
if (nstart <= nlimit) { |
IF_spTOS(spTOS = sp[0]); |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
goto branch; |
TAIL; |
} |
|
else { |
|
INC_IP(1); |
|
} |
} |
: |
: |
swap 2dup |
swap 2dup |
Line 387 else {
|
Line 356 else {
|
cell+ |
cell+ |
THEN >r ; |
THEN >r ; |
|
|
(u-do) ( ulimit ustart -- ) gforth paren_u_minus_do |
(u-do) ( #ndisp ulimit ustart -- R:ulimit R:ustart ) gforth paren_u_minus_do |
*--rp = ulimit; |
|
*--rp = ustart; |
|
if (ustart <= ulimit) { |
if (ustart <= ulimit) { |
IF_spTOS(spTOS = sp[0]); |
SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); |
goto branch; |
TAIL; |
} |
|
else { |
|
INC_IP(1); |
|
} |
} |
: |
: |
swap 2dup |
swap 2dup |
Line 412 else {
|
Line 376 else {
|
\ don't make any assumptions where the return stack is!! |
\ don't make any assumptions where the return stack is!! |
\ implement this in machine code if it should run quickly! |
\ implement this in machine code if it should run quickly! |
|
|
i ( -- n ) core |
i ( R:n -- R:n n ) core |
n = *rp; |
|
: |
: |
\ rp@ cell+ @ ; |
\ rp@ cell+ @ ; |
r> r> tuck >r >r ; |
r> r> tuck >r >r ; |
|
|
i' ( -- w ) gforth i_tick |
i' ( R:w R:w2 -- R:w R:w2 w ) gforth i_tick |
""loop end value"" |
|
w = rp[1]; |
|
: |
: |
\ rp@ cell+ cell+ @ ; |
\ rp@ cell+ cell+ @ ; |
r> r> r> dup itmp ! >r >r >r itmp @ ; |
r> r> r> dup itmp ! >r >r >r itmp @ ; |
variable itmp |
variable itmp |
|
|
j ( -- n ) core |
j ( R:n R:d1 -- n R:n R:d1 ) core |
n = rp[2]; |
|
: |
: |
\ rp@ cell+ cell+ cell+ @ ; |
\ rp@ cell+ cell+ cell+ @ ; |
r> r> r> r> dup itmp ! >r >r >r >r itmp @ ; |
r> r> r> r> dup itmp ! >r >r >r >r itmp @ ; |
[IFUNDEF] itmp variable itmp [THEN] |
[IFUNDEF] itmp variable itmp [THEN] |
|
|
k ( -- n ) gforth |
k ( R:n R:d1 R:d2 -- n R:n R:d1 R:d2 ) gforth |
n = rp[4]; |
|
: |
: |
\ rp@ [ 5 cells ] Literal + @ ; |
\ rp@ [ 5 cells ] Literal + @ ; |
r> r> r> r> r> r> dup itmp ! >r >r >r >r >r >r itmp @ ; |
r> r> r> r> r> r> dup itmp ! >r >r >r >r >r >r itmp @ ; |
Line 973 fp = f_addr;
|
Line 932 fp = f_addr;
|
|
|
\+ |
\+ |
|
|
;s ( -- ) gforth semis |
;s ( R:w -- ) gforth semis |
""The primitive compiled by @code{EXIT}."" |
""The primitive compiled by @code{EXIT}."" |
SET_IP((Xt *)(*rp++)); |
SET_IP((Xt *)w); |
|
|
>r ( w -- ) core to_r |
>r ( w -- R:w ) core to_r |
""@code{( R: -- w )}"" |
|
*--rp = w; |
|
: |
: |
(>r) ; |
(>r) ; |
: (>r) rp@ cell+ @ rp@ ! rp@ cell+ ! ; |
: (>r) rp@ cell+ @ rp@ ! rp@ cell+ ! ; |
|
|
r> ( -- w ) core r_from |
r> ( R:w -- w ) core r_from |
""@code{( R: w -- )}"" |
|
w = *rp++; |
|
: |
: |
rp@ cell+ @ rp@ @ rp@ cell+ ! (rdrop) rp@ ! ; |
rp@ cell+ @ rp@ @ rp@ cell+ ! (rdrop) rp@ ! ; |
Create (rdrop) ' ;s A, |
Create (rdrop) ' ;s A, |
|
|
rdrop ( -- ) gforth |
rdrop ( R:w -- ) gforth |
""@code{( R: w -- )}"" |
|
rp++; |
|
: |
: |
r> r> drop >r ; |
r> r> drop >r ; |
|
|
2>r ( w1 w2 -- ) core-ext two_to_r |
2>r ( w1 w2 -- R:w1 R:w2 ) core-ext two_to_r |
""@code{( R: -- w1 w2 )}"" |
|
*--rp = w1; |
|
*--rp = w2; |
|
: |
: |
swap r> swap >r swap >r >r ; |
swap r> swap >r swap >r >r ; |
|
|
2r> ( -- w1 w2 ) core-ext two_r_from |
2r> ( R:w1 R:w2 -- w1 w2 ) core-ext two_r_from |
""@code{( R: w1 w2 -- )}"" |
|
w2 = *rp++; |
|
w1 = *rp++; |
|
: |
: |
r> r> swap r> swap >r swap ; |
r> r> swap r> swap >r swap ; |
|
|
2r@ ( -- w1 w2 ) core-ext two_r_fetch |
2r@ ( R:w1 R:w2 -- R:w1 R:w2 w1 w2 ) core-ext two_r_fetch |
""@code{( R: w1 w2 -- w1 w2 )}"" |
|
w2 = rp[0]; |
|
w1 = rp[1]; |
|
: |
: |
i' j ; |
i' j ; |
|
|
2rdrop ( -- ) gforth two_r_drop |
2rdrop ( R:w1 R:w2 -- ) gforth two_r_drop |
""@code{( R: w1 w2 -- )}"" |
|
rp+=2; |
|
: |
: |
r> r> drop r> drop >r ; |
r> r> drop r> drop >r ; |
|
|
Line 2049 df_addr = (DFloat *)((((Cell)c_addr)+(si
|
Line 1991 df_addr = (DFloat *)((((Cell)c_addr)+(si
|
\+ |
\+ |
\+glocals |
\+glocals |
|
|
@local# ( -- w ) gforth fetch_local_number |
@local# ( #noffset -- w ) gforth fetch_local_number |
w = *(Cell *)(lp+(Cell)NEXT_INST); |
w = *(Cell *)(lp+noffset); |
INC_IP(1); |
|
|
|
@local0 ( -- w ) new fetch_local_zero |
@local0 ( -- w ) new fetch_local_zero |
w = *(Cell *)(lp+0*sizeof(Cell)); |
w = *(Cell *)(lp+0*sizeof(Cell)); |
Line 2067 w = *(Cell *)(lp+3*sizeof(Cell));
|
Line 2008 w = *(Cell *)(lp+3*sizeof(Cell));
|
|
|
\+floating |
\+floating |
|
|
f@local# ( -- r ) gforth f_fetch_local_number |
f@local# ( #noffset -- r ) gforth f_fetch_local_number |
r = *(Float *)(lp+(Cell)NEXT_INST); |
r = *(Float *)(lp+noffset); |
INC_IP(1); |
|
|
|
f@local0 ( -- r ) new f_fetch_local_zero |
f@local0 ( -- r ) new f_fetch_local_zero |
r = *(Float *)(lp+0*sizeof(Float)); |
r = *(Float *)(lp+0*sizeof(Float)); |
Line 2079 r = *(Float *)(lp+1*sizeof(Float));
|
Line 2019 r = *(Float *)(lp+1*sizeof(Float));
|
|
|
\+ |
\+ |
|
|
laddr# ( -- c_addr ) gforth laddr_number |
laddr# ( #noffset -- c_addr ) gforth laddr_number |
/* this can also be used to implement lp@ */ |
/* this can also be used to implement lp@ */ |
c_addr = (Char *)(lp+(Cell)NEXT_INST); |
c_addr = (Char *)(lp+noffset); |
INC_IP(1); |
|
|
|
lp+!# ( -- ) gforth lp_plus_store_number |
lp+!# ( #noffset -- ) gforth lp_plus_store_number |
""used with negative immediate values it allocates memory on the |
""used with negative immediate values it allocates memory on the |
local stack, a positive immediate argument drops memory from the local |
local stack, a positive immediate argument drops memory from the local |
stack"" |
stack"" |
lp += (Cell)NEXT_INST; |
lp += noffset; |
INC_IP(1); |
|
|
|
lp- ( -- ) new minus_four_lp_plus_store |
lp- ( -- ) new minus_four_lp_plus_store |
lp += -sizeof(Cell); |
lp += -sizeof(Cell); |
Line 2237 flag = FLAG(!fnmatch(pattern, string, 0)
|
Line 2175 flag = FLAG(!fnmatch(pattern, string, 0)
|
newline ( -- c_addr u ) gforth |
newline ( -- c_addr u ) gforth |
""String containing the newline sequence of the host OS"" |
""String containing the newline sequence of the host OS"" |
char newline[] = { |
char newline[] = { |
#ifdef unix |
#if defined(unix) || defined(__MACH__) |
|
/* Darwin/MacOS X sets __MACH__, but not unix. */ |
'\n' |
'\n' |
#else |
#else |
'\r','\n' |
'\r','\n' |