Diff for /gforth/prim between versions 1.191 and 1.201

version 1.191, 2006/03/11 23:05:09 version 1.201, 2006/10/30 15:29:48
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 842  n4=DHI(r); Line 855  n4=DHI(r);
n5=DLO(r);  n5=DLO(r);
#else  #else
/* assumes that the processor uses either floored or symmetric division */  /* assumes that the processor uses either floored or symmetric division */
n5 = d/n3;  DCell d5 = d/n3;
n4 = d%n3;  n4 = d%n3;
if (CHECK_DIVISION_SW && n3 == 0)
throw(BALL_DIVZERO);
if (FLOORED_DIV && ((DHI(d)^n3)<0) && n4!=0) {  if (FLOORED_DIV && ((DHI(d)^n3)<0) && n4!=0) {
n5--;    d5--;
n4+=n3;    n4+=n3;
}  }
n5 = d5;
if (CHECK_DIVISION && d5 != n5)
throw(BALL_RESULTRANGE);
#endif  #endif
:  :
>r m* r> fm/mod ;   >r m* r> fm/mod ;
Line 864  DCell r = fmdiv(d,n3); Line 882  DCell r = fmdiv(d,n3);
n4=DLO(r);  n4=DLO(r);
#else  #else
/* assumes that the processor uses either floored or symmetric division */  /* assumes that the processor uses either floored or symmetric division */
n4 = d/n3;  DCell d4 = d/n3;
if (FLOORED_DIV && ((DHI(d)^n3)<0) && (d%n3)!=0) n4--;  if (CHECK_DIVISION_SW && n3 == 0)
throw(BALL_DIVZERO);
if (FLOORED_DIV && ((DHI(d)^n3)<0) && (d%n3)!=0)
d4--;
n4 = d4;
if (CHECK_DIVISION && d4 != n4)
throw(BALL_RESULTRANGE);
#endif  #endif
:  :
*/mod nip ;   */mod nip ;
Line 889  n2 = n1>>1; Line 913  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
#ifdef BUGGY_LL_DIV
ASM_SM_SLASH_REM(d1.lo, d1.hi, n1, n2, n3);  ASM_SM_SLASH_REM(d1.lo, d1.hi, 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;
}  }
#else /* !defined(ASM_SM_SLASH_REM) */
DCell r = fmdiv(d1,n1);
n2=DHI(r);
n3=DLO(r);
#endif /* !defined(ASM_SM_SLASH_REM) */
#else  #else
#ifdef ASM_SM_SLASH_REM4
ASM_SM_SLASH_REM4(d1, n1, n2, n3);  ASM_SM_SLASH_REM4(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;
}  }
#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  #endif
#else /* !defined(ASM_SM_SLASH_REM) */
DCell r = fmdiv(d1,n1);
n2=DHI(r);
n3=DLO(r);
:  :
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 940  n3=DLO(r); Line 957  n3=DLO(r);
ASM_SM_SLASH_REM4(d1, n1, n2, n3);  ASM_SM_SLASH_REM4(d1, n1, n2, n3);
#else /* !defined(ASM_SM_SLASH_REM4) */  #else /* !defined(ASM_SM_SLASH_REM4) */
/* assumes that the processor uses either floored or symmetric division */  /* assumes that the processor uses either floored or symmetric division */
n3 = d1/n1;  DCell d3 = d1/n1;
n2 = d1%n1;  n2 = d1%n1;
if (CHECK_DIVISION_SW && n1 == 0)
throw(BALL_DIVZERO);
/* note that this 1%-3<0 is optimized by the compiler */  /* note that this 1%-3<0 is optimized by the compiler */
if (1%-3<0 && ((DHI(d1)^n1)<0) && n2!=0) {  if (1%-3<0 && ((DHI(d1)^n1)<0) && n2!=0) {
n3++;    d3++;
n2-=n1;    n2-=n1;
}  }
n3 = d3;
if (CHECK_DIVISION && d3 != n3)
throw(BALL_RESULTRANGE);
#endif /* !defined(ASM_SM_SLASH_REM4) */  #endif /* !defined(ASM_SM_SLASH_REM4) */
#endif  #endif
:  :
Line 996  u3=DLO(r); Line 1018  u3=DLO(r);
#ifdef ASM_UM_SLASH_MOD4  #ifdef ASM_UM_SLASH_MOD4
ASM_UM_SLASH_MOD4(ud, u1, u2, u3);  ASM_UM_SLASH_MOD4(ud, u1, u2, u3);
#else /* !defined(ASM_UM_SLASH_MOD4) */  #else /* !defined(ASM_UM_SLASH_MOD4) */
u3 = ud/u1;  UDCell ud3 = ud/u1;
u2 = ud%u1;  u2 = ud%u1;
if (CHECK_DIVISION_SW && u1 == 0)
throw(BALL_DIVZERO);
u3 = ud3;
if (CHECK_DIVISION && ud3 != u3)
throw(BALL_RESULTRANGE);
#endif /* !defined(ASM_UM_SLASH_MOD4) */  #endif /* !defined(ASM_UM_SLASH_MOD4) */
#endif  #endif
:  :
Line 1646  n=1; Line 1673  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 2725  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 2741  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 2784  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