--- gforth/prim 2001/06/16 22:53:36 1.83 +++ gforth/prim 2002/09/24 16:16:43 1.98 @@ -53,15 +53,18 @@ \ your code does not fall through, the results are not stored into the \ stack. Use different names on both sides of the '--', if you change a \ value (some stores to the stack are optimized away). -\ -\ +\ +\ For superinstructions the syntax is: +\ +\ forth-name [/ c-name] = forth-name forth-name ... +\ \ \ The stack variables have the following types: \ \ name matches type \ f.* Bool \ c.* Char -\ [nw].* Cell +\ [nw].* Cell \ u.* UCell \ d.* DCell \ ud.* UDCell @@ -101,6 +104,7 @@ \E inst-stream stack-prefix # \E \E set-current +\E store-optimization on \ \ @@ -179,8 +183,9 @@ SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); define(condbranch, $1 ( `#'ndisp $2 ) $3 $4 SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); -TAIL; +INST_TAIL; } +SUPER_CONTINUE; $5 \+glocals @@ -188,8 +193,9 @@ $5 $1-lp+!`#' ( `#'ndisp `#'nlocals $2 ) $3_lp_plus_store_number $4 lp += nlocals; SET_IP((Xt *)(((Cell)(IP-2))+ndisp)); -TAIL; +INST_TAIL; } +SUPER_CONTINUE; \+ ) @@ -214,8 +220,9 @@ if (f==0) { sp++; IF_spTOS(spTOS = sp[0]); SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); - TAIL; + INST_TAIL; } +SUPER_CONTINUE; ?dup-0=-?branch ( #ndisp f -- ) new question_dupe_zero_equals_question_branch ""The run-time procedure compiled by @code{?DUP-0=-IF}."" @@ -228,6 +235,7 @@ if (f!=0) { SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); NEXT; } +SUPER_CONTINUE; \+ \f[THEN] @@ -307,8 +315,9 @@ nlimit=0; (?do) ( #ndisp nlimit nstart -- R:nlimit R:nstart ) gforth paren_question_do if (nstart == nlimit) { SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); - TAIL; + INST_TAIL; } +SUPER_CONTINUE; : 2dup = IF r> swap rot >r >r @@ -322,8 +331,9 @@ if (nstart == nlimit) { (+do) ( #ndisp nlimit nstart -- R:nlimit R:nstart ) gforth paren_plus_do if (nstart >= nlimit) { SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); - TAIL; + INST_TAIL; } +SUPER_CONTINUE; : swap 2dup r> swap >r swap >r @@ -337,8 +347,9 @@ if (nstart >= nlimit) { (u+do) ( #ndisp ulimit ustart -- R:ulimit R:ustart ) gforth paren_u_plus_do if (ustart >= ulimit) { SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); - TAIL; + INST_TAIL; } +SUPER_CONTINUE; : swap 2dup r> swap >r swap >r @@ -352,8 +363,9 @@ if (ustart >= ulimit) { (-do) ( #ndisp nlimit nstart -- R:nlimit R:nstart ) gforth paren_minus_do if (nstart <= nlimit) { SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); - TAIL; + INST_TAIL; } +SUPER_CONTINUE; : swap 2dup r> swap >r swap >r @@ -367,8 +379,9 @@ if (nstart <= nlimit) { (u-do) ( #ndisp ulimit ustart -- R:ulimit R:ustart ) gforth paren_u_minus_do if (ustart <= ulimit) { SET_IP((Xt *)(((Cell)(IP-1))+ndisp)); - TAIL; + INST_TAIL; } +SUPER_CONTINUE; : swap 2dup r> swap >r swap >r @@ -1347,7 +1360,6 @@ a_addr = (Cell *)DOES_CODE(xt); code-address! ( c_addr xt -- ) gforth code_address_store ""Create a code field with code address @i{c-addr} at @i{xt}."" MAKE_CF(xt, c_addr); -CACHE_FLUSH(xt,(size_t)PFA(0)); : ! ; @@ -1355,7 +1367,6 @@ does-code! ( a_addr xt -- ) gforth does ""Create a code field at @i{xt} for a child of a @code{DOES>}-word; @i{a-addr} is the start of the Forth code after @code{DOES>}."" MAKE_DOES_CF(xt, a_addr); -CACHE_FLUSH(xt,(size_t)PFA(0)); : dodoes: over ! cell+ ! ; @@ -1363,7 +1374,6 @@ does-handler! ( a_addr -- ) gforth does_ ""Create a @code{DOES>}-handler at address @i{a-addr}. Normally, @i{a-addr} points just behind a @code{DOES>}."" MAKE_DOES_HANDLER(a_addr); -CACHE_FLUSH((caddr_t)a_addr,DOES_HANDLER_SIZE); : drop ; @@ -1466,7 +1476,7 @@ c_addr2 = getenv(cstr(c_addr1,u1,1)); u2 = (c_addr2 == NULL ? 0 : strlen(c_addr2)); open-pipe ( c_addr u wfam -- wfileid wior ) gforth open_pipe -wfileid=(Cell)popen(cstr(c_addr,u,1),fileattr[wfam]); /* ~ expansion of 1st arg? */ +wfileid=(Cell)popen(cstr(c_addr,u,1),pfileattr[wfam]); /* ~ expansion of 1st arg? */ wior = IOR(wfileid==0); /* !! the man page says that errno is not set reliably */ close-pipe ( wfileid -- wretval wior ) gforth close_pipe @@ -1608,7 +1618,7 @@ if (wior) clearerr((FILE *)wfileid); read-line ( c_addr u1 wfileid -- u2 flag wior ) file read_line -""this is only for backward compatibility"" +/* this may one day be replaced with : read-line (read-line) nip ; */ Cell c; flag=-1; for(u2=0; u20. +If the attempt succeeds, store file name to the buffer at @i{c-addr} +and return @i{ior}=0, @i{flag}=true and @i{u2} equal to the size of the file name. +If the length of the file name is greater than @i{u1}, +store first @i{u1} characters from file name into the buffer and +indicate "name too long" with @i{ior}, @i{flag}=true, and @i{u2}=@i{u1}."" struct dirent * dent; dent = readdir((DIR *)wdirid); wior = 0; @@ -2186,6 +2209,7 @@ if(dent == NULL) { } close-dir ( wdirid -- wior ) gforth close_dir +""Close the directory specified by @i{dir-id}."" wior = IOR(closedir((DIR *)wdirid)); filename-match ( c_addr1 u1 c_addr2 u2 -- flag ) gforth match_file @@ -2385,14 +2409,52 @@ peephole-opt ( xt1 xt2 wpeeptable -- xt they cannot be combined, xt is 0."" xt = peephole_opt(xt1, xt2, wpeeptable); -call ( #a_callee -- R:a_retaddr ) +call ( #a_callee -- R:a_retaddr ) new ""Call callee (a variant of docol with inline argument)."" +#ifdef DEBUG + { + CFA_TO_NAME((((Cell *)a_callee)-2)); + fprintf(stderr,"%08lx: call %08lx %.*s\n",(Cell)ip,(Cell)a_callee, + len,name); + } +#endif a_retaddr = (Cell *)IP; SET_IP((Xt *)a_callee); -useraddr ( #u -- a_addr ) +useraddr ( #u -- a_addr ) new a_addr = (Cell *)(up+u); +compile-prim ( xt1 -- xt2 ) new compile_prim +xt2 = (Xt)compile_prim((Label)xt1); + +\ lit@ / lit_fetch = lit @ + +lit@ ( #a_addr -- w ) new lit_fetch +w = *a_addr; + +lit-perform ( #a_addr -- ) new lit_perform +ip=IP; +SUPER_END; +EXEC(*(Xt *)a_addr); + +\ lit+ / lit_plus = lit + + +lit+ ( n1 #n2 -- n ) new lit_plus +n=n1+n2; + +does-exec ( #a_cfa -- R:nest a_pfa ) new does_exec +a_pfa = PFA(a_cfa); +nest = (Cell)ip; +IF_spTOS(spTOS = sp[0]); +#ifdef DEBUG + { + CFA_TO_NAME(a_cfa); + fprintf(stderr,"%08lx: does %08lx %.*s\n", + (Cell)ip,(Cell)a_cfa,len,name); + } +#endif +SET_IP(DOES_CODE1(a_cfa)); + include(peeprules.vmg) \+