Diff for /gforth/prim between versions 1.191 and 1.203

version 1.191, 2006/03/11 23:05:09 version 1.203, 2006/10/30 16:20:41
Line 809  n = n1*n2; Line 809  n = n1*n2;

/       ( n1 n2 -- n )          core    slash  /       ( n1 n2 -- n )          core    slash
n = n1/n2;  n = n1/n2;
if(FLOORED_DIV && ((n1^n2) < 0) && (n1%n2 != 0)) n--;  if (CHECK_DIVISION_SW && n2 == 0)
throw(BALL_DIVZERO);
if (CHECK_DIVISION_SW && n2 == -1 && n1 == CELL_MIN)
throw(BALL_RESULTRANGE);
if (FLOORED_DIV && ((n1^n2) < 0) && (n1%n2 != 0))
n--;
:  :
/mod nip ;   /mod nip ;

mod     ( n1 n2 -- n )          core  mod     ( n1 n2 -- n )          core
n = n1%n2;  n = n1%n2;
if (CHECK_DIVISION_SW && n2 == 0)
throw(BALL_DIVZERO);
if (CHECK_DIVISION_SW && n2 == -1 && n1 == CELL_MIN)
throw(BALL_RESULTRANGE);
if(FLOORED_DIV && ((n1^n2) < 0) && n!=0) n += n2;  if(FLOORED_DIV && ((n1^n2) < 0) && n!=0) n += n2;
:  :
/mod drop ;   /mod drop ;
Line 822  if(FLOORED_DIV && ((n1^n2) < 0) && n!=0) Line 831  if(FLOORED_DIV && ((n1^n2) < 0) && n!=0)
/mod    ( n1 n2 -- n3 n4 )              core            slash_mod  /mod    ( n1 n2 -- n3 n4 )              core            slash_mod
n4 = n1/n2;  n4 = n1/n2;
n3 = n1%n2; /* !! is this correct? look into C standard! */  n3 = n1%n2; /* !! is this correct? look into C standard! */
if (CHECK_DIVISION_SW && n2 == 0)
throw(BALL_DIVZERO);
if (CHECK_DIVISION_SW && n2 == -1 && n1 == CELL_MIN)
throw(BALL_RESULTRANGE);
if (FLOORED_DIV && ((n1^n2) < 0) && n3!=0) {  if (FLOORED_DIV && ((n1^n2) < 0) && n3!=0) {
n4--;    n4--;
n3+=n2;    n3+=n2;
Line 836  DCell d = mmul(n1,n2); Line 849  DCell d = mmul(n1,n2);
#else  #else
DCell d = (DCell)n1 * (DCell)n2;  DCell d = (DCell)n1 * (DCell)n2;
#endif  #endif
#ifdef BUGGY_LL_DIV  #ifdef ASM_SM_SLASH_REM
DCell r = fmdiv(d,n3);  ASM_SM_SLASH_REM(DLO(d), DHI(d), n3, n4, n5);
n4=DHI(r);  if (((DHI(d)^n3)<0) && n4!=0) {
n5=DLO(r);    if (CHECK_DIVISION && n5 == CELL_MIN)
#else      throw(BALL_RESULTRANGE);
/* assumes that the processor uses either floored or symmetric division */
n5 = d/n3;
n4 = d%n3;
if (FLOORED_DIV && ((DHI(d)^n3)<0) && n4!=0) {
n5--;    n5--;
n4+=n3;    n4+=n3;
}  }
#else
DCell r = fmdiv(d,n3);
n4=DHI(r);
n5=DLO(r);
#endif  #endif
:  :
>r m* r> fm/mod ;   >r m* r> fm/mod ;
Line 859  DCell d = mmul(n1,n2); Line 872  DCell d = mmul(n1,n2);
#else  #else
DCell d = (DCell)n1 * (DCell)n2;  DCell d = (DCell)n1 * (DCell)n2;
#endif  #endif
#ifdef BUGGY_LL_DIV  #ifdef ASM_SM_SLASH_REM
Cell remainder;
ASM_SM_SLASH_REM(DLO(d), DHI(d), n3, remainder, n4);
if (((DHI(d)^n3)<0) && remainder!=0) {
if (CHECK_DIVISION && n4 == CELL_MIN)
throw(BALL_RESULTRANGE);
n4--;
}
#else
DCell r = fmdiv(d,n3);  DCell r = fmdiv(d,n3);
n4=DLO(r);  n4=DLO(r);
#else
/* assumes that the processor uses either floored or symmetric division */
n4 = d/n3;
if (FLOORED_DIV && ((DHI(d)^n3)<0) && (d%n3)!=0) n4--;
#endif  #endif
:  :
*/mod nip ;   */mod nip ;
Line 889  n2 = n1>>1; Line 906  n2 = n1>>1;

fm/mod  ( d1 n1 -- n2 n3 )              core            f_m_slash_mod  fm/mod  ( d1 n1 -- n2 n3 )              core            f_m_slash_mod
""Floored division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, @i{n1}>@i{n2}>=0 or 0>=@i{n2}>@i{n1}.""  ""Floored division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, @i{n1}>@i{n2}>=0 or 0>=@i{n2}>@i{n1}.""
#ifdef BUGGY_LL_DIV
#ifdef ASM_SM_SLASH_REM  #ifdef ASM_SM_SLASH_REM
ASM_SM_SLASH_REM(d1.lo, d1.hi, n1, n2, n3);  ASM_SM_SLASH_REM(DLO(d1), DHI(d1), n1, n2, n3);
if (((DHI(d1)^n1)<0) && n2!=0) {  if (((DHI(d1)^n1)<0) && n2!=0) {
if (CHECK_DIVISION && n3 == CELL_MIN)
throw(BALL_RESULTRANGE);
n3--;    n3--;
n2+=n1;    n2+=n1;
}  }
Line 901  DCell r = fmdiv(d1,n1); Line 919  DCell r = fmdiv(d1,n1);
n2=DHI(r);  n2=DHI(r);
n3=DLO(r);  n3=DLO(r);
#endif /* !defined(ASM_SM_SLASH_REM) */  #endif /* !defined(ASM_SM_SLASH_REM) */
#else
#ifdef ASM_SM_SLASH_REM4
ASM_SM_SLASH_REM4(d1, n1, n2, n3);
if (((DHI(d1)^n1)<0) && n2!=0) {
n3--;
n2+=n1;
}
#else /* !defined(ASM_SM_SLASH_REM4) */
/* assumes that the processor uses either floored or symmetric division */
n3 = d1/n1;
n2 = d1%n1;
/* note that this 1%-3>0 is optimized by the compiler */
if (1%-3>0 && ((DHI(d1)^n1)<0) && n2!=0) {
n3--;
n2+=n1;
}
#endif /* !defined(ASM_SM_SLASH_REM4) */
#endif
:  :
dup >r dup 0< IF  negate >r dnegate r>  THEN   dup >r dup 0< IF  negate >r dnegate r>  THEN
over       0< IF  tuck + swap  THEN   over       0< IF  tuck + swap  THEN
Line 927  if (1%-3>0 && ((DHI(d1)^n1)<0) && n2!=0) Line 927  if (1%-3>0 && ((DHI(d1)^n1)<0) && n2!=0)

sm/rem  ( d1 n1 -- n2 n3 )              core            s_m_slash_rem  sm/rem  ( d1 n1 -- n2 n3 )              core            s_m_slash_rem
""Symmetric division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, sign(@i{n2})=sign(@i{d1}) or 0.""  ""Symmetric division: @i{d1} = @i{n3}*@i{n1}+@i{n2}, sign(@i{n2})=sign(@i{d1}) or 0.""
#ifdef BUGGY_LL_DIV
#ifdef ASM_SM_SLASH_REM  #ifdef ASM_SM_SLASH_REM
ASM_SM_SLASH_REM(d1.lo, d1.hi, n1, n2, n3);  ASM_SM_SLASH_REM(DLO(d1), DHI(d1), n1, n2, n3);
#else /* !defined(ASM_SM_SLASH_REM) */  #else /* !defined(ASM_SM_SLASH_REM) */
DCell r = smdiv(d1,n1);  DCell r = smdiv(d1,n1);
n2=DHI(r);  n2=DHI(r);
n3=DLO(r);  n3=DLO(r);
#endif /* !defined(ASM_SM_SLASH_REM) */  #endif /* !defined(ASM_SM_SLASH_REM) */
#else
#ifdef ASM_SM_SLASH_REM4
ASM_SM_SLASH_REM4(d1, n1, n2, n3);
#else /* !defined(ASM_SM_SLASH_REM4) */
/* assumes that the processor uses either floored or symmetric division */
n3 = d1/n1;
n2 = d1%n1;
/* note that this 1%-3<0 is optimized by the compiler */
if (1%-3<0 && ((DHI(d1)^n1)<0) && n2!=0) {
n3++;
n2-=n1;
}
#endif /* !defined(ASM_SM_SLASH_REM4) */
#endif
:  :
over >r dup >r abs -rot   over >r dup >r abs -rot
dabs rot um/mod   dabs rot um/mod
Line 984  ud = (UDCell)u1 * (UDCell)u2; Line 969  ud = (UDCell)u1 * (UDCell)u2;

um/mod  ( ud u1 -- u2 u3 )              core    u_m_slash_mod  um/mod  ( ud u1 -- u2 u3 )              core    u_m_slash_mod
""ud=u3*u1+u2, u1>u2>=0""  ""ud=u3*u1+u2, u1>u2>=0""
#ifdef BUGGY_LL_DIV
#ifdef ASM_UM_SLASH_MOD  #ifdef ASM_UM_SLASH_MOD
ASM_UM_SLASH_MOD(ud.lo, ud.hi, u1, u2, u3);  ASM_UM_SLASH_MOD(DLO(ud), DHI(ud), u1, u2, u3);
#else /* !defined(ASM_UM_SLASH_MOD) */  #else /* !defined(ASM_UM_SLASH_MOD) */
UDCell r = umdiv(ud,u1);  UDCell r = umdiv(ud,u1);
u2=DHI(r);  u2=DHI(r);
u3=DLO(r);  u3=DLO(r);
#endif /* !defined(ASM_UM_SLASH_MOD) */  #endif /* !defined(ASM_UM_SLASH_MOD) */
#else
#ifdef ASM_UM_SLASH_MOD4
ASM_UM_SLASH_MOD4(ud, u1, u2, u3);
#else /* !defined(ASM_UM_SLASH_MOD4) */
u3 = ud/u1;
u2 = ud%u1;
#endif /* !defined(ASM_UM_SLASH_MOD4) */
#endif
:  :
0 swap [ 8 cells 1 + ] literal 0     0 swap [ 8 cells 1 + ] literal 0
?DO /modstep     ?DO /modstep
Line 1646  n=1; Line 1622  n=1;

\g hostos  \g hostos

key-file        ( wfileid -- n )                gforth  paren_key_file  key-file        ( wfileid -- c )                gforth  paren_key_file
""Read one character @i{c} from @i{wfileid}.  This word disables
buffering for @i{wfileid}.  If you want to read characters from a
terminal in non-canonical (raw) mode, you have to put the terminal in
non-canonical mode yourself (using the C interface); the exception is
@code{stdin}: Gforth automatically puts it into non-canonical mode.""
#ifdef HAS_FILE  #ifdef HAS_FILE
fflush(stdout);  fflush(stdout);
n = key((FILE*)wfileid);  c = key((FILE*)wfileid);
#else  #else
n = key(stdin);  c = key(stdin);
#endif  #endif

key?-file       ( wfileid -- n )                gforth  key_q_file  key?-file       ( wfileid -- f )                gforth  key_q_file
""@i{f} is true if at least one character can be read from @i{wfileid}
without blocking.  If you also want to use @code{read-file} or
@code{read-line} on the file, you have to call @code{key?-file} or
@code{key-file} first (these two words disable buffering).""
#ifdef HAS_FILE  #ifdef HAS_FILE
fflush(stdout);  fflush(stdout);
n = key_query((FILE*)wfileid);  f = key_query((FILE*)wfileid);
#else  #else
n = key_query(stdin);  f = key_query(stdin);
#endif  #endif

\+os  \+os

stdin   ( -- wfileid )  gforth  stdin   ( -- wfileid )  gforth
""The standard input file of the Gforth process.""
wfileid = (Cell)stdin;  wfileid = (Cell)stdin;

stdout  ( -- wfileid )  gforth  stdout  ( -- wfileid )  gforth
""The standard output file of the Gforth process.""
wfileid = (Cell)stdout;  wfileid = (Cell)stdout;

stderr  ( -- wfileid )  gforth  stderr  ( -- wfileid )  gforth
""The standard error output file of the Gforth process.""
wfileid = (Cell)stderr;  wfileid = (Cell)stderr;

form    ( -- urows ucols )      gforth  form    ( -- urows ucols )      gforth
Line 2686  w = ffi_prep_closure((ffi_closure *)a_cl Line 2674  w = ffi_prep_closure((ffi_closure *)a_cl

ffi-2@ ( a_addr -- d )  gforth ffi_2fetch  ffi-2@ ( a_addr -- d )  gforth ffi_2fetch
#ifdef BUGGY_LONG_LONG  #ifdef BUGGY_LONG_LONG
DHI_IS(d, 0);  DHI_IS(d, 0);
#else  #else
Line 2702  ffi-2! ( d a_addr -- ) gforth ffi_2store Line 2690  ffi-2! ( d a_addr -- ) gforth ffi_2store
ffi-arg-int ( -- w )    gforth ffi_arg_int  ffi-arg-int ( -- w )    gforth ffi_arg_int
w = *(int *)(*gforth_clist++);  w = *(int *)(*gforth_clist++);

ffi-arg-long ( -- w )   gforth ffi_arg_long
w = *(long *)(*gforth_clist++);

ffi-arg-longlong ( -- d )       gforth ffi_arg_longlong  ffi-arg-longlong ( -- d )       gforth ffi_arg_longlong
#ifdef BUGGY_LONG_LONG  #ifdef BUGGY_LONG_LONG
DLO_IS(d, (Cell*)(*gforth_clist++));  DLO_IS(d, *(Cell*)(*gforth_clist++));
DHI_IS(d, 0);  DHI_IS(d, -(*(Cell*)(*gforth_clist++)<0));
#else  #else
d = *(DCell*)(*gforth_clist++);  d = *(DCell*)(*gforth_clist++);
#endif  #endif

ffi-arg-dlong ( -- d )  gforth ffi_arg_dlong
#ifdef BUGGY_LONG_LONG
DLO_IS(d, *(Cell*)(*gforth_clist++));
DHI_IS(d, -(*(Cell*)(*gforth_clist++)<0));
#else
d = *(Cell*)(*gforth_clist++);
#endif

ffi-arg-ptr ( -- c_addr )       gforth ffi_arg_ptr  ffi-arg-ptr ( -- c_addr )       gforth ffi_arg_ptr

Line 2734  ffi-ret-longlong ( d -- ) gforth ffi_ret Line 2733  ffi-ret-longlong ( d -- ) gforth ffi_ret
#endif  #endif
return 0;  return 0;

ffi-ret-dlong ( d -- )  gforth ffi_ret_dlong
#ifdef BUGGY_LONG_LONG
*(Cell*)(gforth_ritem) = DLO(d);
#else
*(Cell*)(gforth_ritem) = d;
#endif
return 0;

ffi-ret-long ( n -- )   gforth ffi_ret_long
*(Cell*)(gforth_ritem) = n;
return 0;

ffi-ret-ptr ( c_addr -- )       gforth ffi_ret_ptr  ffi-ret-ptr ( c_addr -- )       gforth ffi_ret_ptr