fix(v4.0.0): .R U.R and D.R print no trailing space
FORTH-79's reference .R right-justifies the number in its field and prints nothing after it; v3 printed a space. . U. and D. still print their one space. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b137678691
commit
01b5bbb23f
+31
-17
@@ -56,6 +56,7 @@ static int failures = 0, checks = 0;
|
||||
#define HLD ((v4_cell)(V4_NODE_WORDS - 35u))
|
||||
#define BASE ((v4_cell)(V4_NODE_WORDS - 34u))
|
||||
#define FIELD ((v4_cell)(V4_NODE_WORDS - 36u)) /* (W): the field width of the .R words */
|
||||
#define TRAIL ((v4_cell)(V4_NODE_WORDS - 46u)) /* (W)+1 in the document: whether a blank follows the number */
|
||||
#define HCAP 63
|
||||
#define QP ((v4_cell)(V4_NODE_WORDS - 40u)) /* (QP): Q.PRINT's BASE, |q| and sign */
|
||||
#define DP ((v4_cell)(V4_NODE_WORDS - 44u)) /* (DP): DUMP's BASE, address, count, column */
|
||||
@@ -301,7 +302,7 @@ static void build_pictured(void)
|
||||
static void build_output(void)
|
||||
{
|
||||
v4_asm_ref a, b, c, d, done1, done2;
|
||||
v4_cell l, l_tail, l_line;
|
||||
v4_cell l, l_tail, l_rbody, l_ubody, l_dbody, l_line;
|
||||
|
||||
/* : C@ ( baddr -- c ) call-free, 5.3
|
||||
* dup 2/ 2/ a! 3 and k A: word address
|
||||
@@ -380,16 +381,21 @@ static void build_output(void)
|
||||
HERE_(b);
|
||||
O(DROP); O(SEMI);
|
||||
|
||||
/* : .R ( n width -- )
|
||||
* (W) b! !b dup push -if A inv 1 + A: 0 <# #S pop SIGN #> baddr u
|
||||
/* : .R ( n width -- ) FORTH-79: no blank after it
|
||||
* 0 (W) 1 + b! !b
|
||||
* BODY: (W) b! !b dup push -if A inv 1 + A: 0 <# #S pop SIGN #> baddr u
|
||||
* TAIL: (W) b! @b -if POS drop jump OUT width < 0
|
||||
* POS: over - SPACES
|
||||
* OUT: TYPE jump SPACE
|
||||
* OUT: TYPE (W) 1 + b! @b if DONE drop jump SPACE
|
||||
* DONE: drop ;
|
||||
* The width waits in the variable (W), on neither stack, so the picture
|
||||
* runs as deep as it does on its own. A negative width is dropped before
|
||||
* the subtraction, which could otherwise wrap. U.R and D.R jump to TAIL,
|
||||
* and SPACE returns to the caller. */
|
||||
* the subtraction, which could otherwise wrap. (W)+1 says whether a blank
|
||||
* follows the number: `.` sets it and enters at BODY with a width of 0;
|
||||
* `.R` clears it. U.R and D.R jump to TAIL. */
|
||||
w_dotr = v4_asm_label(&as);
|
||||
LIT(0); VSET(TRAIL);
|
||||
l_rbody = v4_asm_label(&as);
|
||||
VSET(FIELD); O(DUP); O(PUSH);
|
||||
a = FWD(MINUS_IF); O(INV); LIT(1); O(ADD); HERE_(a);
|
||||
LIT(0); CALL(w_begin); CALL(w_hashs); O(RPOP); CALL(w_sign); CALL(w_end);
|
||||
@@ -400,30 +406,37 @@ static void build_output(void)
|
||||
O(OVER); SUB_INLINE(); CALL(w_spaces);
|
||||
HERE_(b);
|
||||
l_out = v4_asm_label(&as);
|
||||
CALL(w_type); JUMP(w_space);
|
||||
CALL(w_type); VGET(TRAIL); a = FWD(IF);
|
||||
O(DROP); JUMP(w_space);
|
||||
HERE_(a);
|
||||
O(DROP); O(SEMI);
|
||||
|
||||
/* : . ( n -- ) 0 jump .R */
|
||||
/* : . ( n -- ) -1 (W) 1 + b! !b 0 jump BODY a blank after it */
|
||||
w_dot = v4_asm_label(&as);
|
||||
LIT(0); JUMP(w_dotr);
|
||||
LIT(-1); VSET(TRAIL); LIT(0); JUMP(l_rbody);
|
||||
|
||||
/* : U.R ( u width -- ) (W) b! !b 0 <# #S #> jump TAIL */
|
||||
/* : U.R ( u width -- ) 0 (W) 1 + b! !b UBODY: (W) b! !b 0 <# #S #> jump TAIL */
|
||||
w_udotr = v4_asm_label(&as);
|
||||
LIT(0); VSET(TRAIL);
|
||||
l_ubody = v4_asm_label(&as);
|
||||
VSET(FIELD); LIT(0); CALL(w_begin); CALL(w_hashs); CALL(w_end); JUMP(l_tail);
|
||||
|
||||
/* : U. ( u -- ) 0 jump U.R */
|
||||
/* : U. ( u -- ) -1 (W) 1 + b! !b 0 jump UBODY */
|
||||
w_udot = v4_asm_label(&as);
|
||||
LIT(0); JUMP(w_udotr);
|
||||
LIT(-1); VSET(TRAIL); LIT(0); JUMP(l_ubody);
|
||||
|
||||
/* : D.R ( d width -- )
|
||||
* (W) b! !b dup push -if A DNEGATE A: <# #S pop SIGN #> jump TAIL */
|
||||
* 0 (W) 1 + b! !b DBODY: (W) b! !b dup push -if A DNEGATE A: <# #S pop SIGN #> jump TAIL */
|
||||
w_ddotr = v4_asm_label(&as);
|
||||
LIT(0); VSET(TRAIL);
|
||||
l_dbody = v4_asm_label(&as);
|
||||
VSET(FIELD); O(DUP); O(PUSH);
|
||||
a = FWD(MINUS_IF); CALL(w_dnegate); HERE_(a);
|
||||
CALL(w_begin); CALL(w_hashs); O(RPOP); CALL(w_sign); CALL(w_end); JUMP(l_tail);
|
||||
|
||||
/* : D. ( d -- ) 0 jump D.R */
|
||||
/* : D. ( d -- ) -1 (W) 1 + b! !b 0 jump DBODY */
|
||||
w_ddot = v4_asm_label(&as);
|
||||
LIT(0); JUMP(w_ddotr);
|
||||
LIT(-1); VSET(TRAIL); LIT(0); JUMP(l_dbody);
|
||||
/* ---- the words under test ---- */
|
||||
|
||||
/* : CR ( -- ) 10 jump EMIT */
|
||||
@@ -445,7 +458,7 @@ static void build_output(void)
|
||||
* pop 15 FOR 2/ UNEXT HIMASK and high cell of |q| >> 16
|
||||
* #S (QP) 3 + b! @b SIGN #>
|
||||
* (QP) b! @b BASE b! !b
|
||||
* jump OUT TYPE jump SPACE, in .R
|
||||
* -1 (W) 1 + b! !b jump OUT TYPE and a blank, in .R
|
||||
* frac * 100000 / 65536 is frac * 3125 / 2048, which stays inside a
|
||||
* 32-bit cell; times 3125 is times 5 five times. HIMASK clears the top
|
||||
* 16 bits, making the 2/ shift a logical one. */
|
||||
@@ -476,6 +489,7 @@ static void build_output(void)
|
||||
LIT((v4_cell)(MAXU >> 16)); O(AND);
|
||||
CALL(w_hashs); VGET(QP + 3); CALL(w_sign); CALL(w_end);
|
||||
VGET(QP); VSET(BASE);
|
||||
LIT(-1); VSET(TRAIL);
|
||||
JUMP(l_out);
|
||||
|
||||
/* : (DB) ( -- c ) (DP) 1 + b! @b (DP) 3 + b! @b + jump C@
|
||||
@@ -793,7 +807,7 @@ int main(void)
|
||||
build_pictured();
|
||||
build_output();
|
||||
CHECK(v4_asm_ok(&as), "printing words assemble");
|
||||
CHECK(v4_asm_label(&as) < XVAR, "code stays below the variables");
|
||||
CHECK(v4_asm_label(&as) < TRAIL, "code stays below the variables");
|
||||
printf(" code: %ld of %u words\n", (long)v4_asm_label(&as) - CODE0, (unsigned)V4_NODE_WORDS);
|
||||
|
||||
/* 128 bytes to dump: every kind of byte, with v3's twenty at 0xD0. */
|
||||
|
||||
Reference in New Issue
Block a user