+TheBF Posted March 23, 2017 Share Posted March 23, 2017 (edited) This version works and seems to give the same results as BASIC.It uses an old trick that I use to create easy string lists.It was not as easy as I thought to RPN all those calculations. It really makes the point for the late Julian Noble's "FORmula TRANslator" (FORTRAN)It was an evaluator that let you input infix equations and it spit out Forth. This program also points out a sticky situation with Forth. There is no "standard" way to convert text to a number.Every Forth has one but they seem to all have different names. CAMEL Forth uses ?NUMBER ( c$adr-- n flag) .But without that , I can't make a truly portable "INPUT" statement to put this in a loop like the BASIC version.I can do it, but it will probably not compile on other systems without some editing. This compiles on CAMEL99 and gives correct results according to http://www.calculatorcat.com/date/day-of-week.html DECIMAL : ," ( -- ) [CHAR] " WORD C@ 1+ ALLOT ALIGNED ; IMMEDIATE : [[ 0 C, ; : ]] [[ ; CREATE DAYS [[ ," SUN" ," MON" ," TUES" ," WEDNES" ," THURS" ," FRI" ," SATUR" ]] : NTH ( n adr -- adr') SWAP 0 ?DO COUNT + LOOP ; : DAY. ( n -- $adr ) 1+ DAYS NTH COUNT TYPE ." DAY" ; VARIABLE D VARIABLE M VARIABLE Y : INPUT ( d m y -- ) Y ! M ! D ! ; : (M-2)/12 ( -- n ) M @ 2- 12 / ; ( factored out of below) : YR ( -- ) Y @ (M-2)/12 + Y ! ; ( line 130 a) : MNTH ( -- ) M @ (M-2)/12 12 * - M ! ; ( line 130 b) : MAGIC ( -- n ) YR MNTH D @ M @ 2* + M @ 1+ 6 * 10 / + Y @ + Y @ 4 / + Y @ 100 / - Y @ 400 / + 1+ DUP 7 / 7 * - ; ( line 150) : DOW ( D M Y -- ) CR ." That's a " INPUT MAGIC DAY. ; BUT! the same code on HsForth under Intel DOSBOX gives wrong results. In both cases I am using the machine's native divide instruction.Is that the problem? No idea. (I could not get it to compile on TurboForth because I don't know the equivalent to the ANS word ALIGNED) Edited March 23, 2017 by TheBF 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 23, 2017 Share Posted March 23, 2017 ...This program also points out a sticky situation with Forth. There is no "standard" way to convert text to a number. Every Forth has one but they seem to all have different names. CAMEL Forth uses ?NUMBER ( c$adr-- n flag) . But without that , I can't make a truly portable "INPUT" statement to put this in a loop like the BASIC version. I can do it, but it will probably not compile on other systems without some editing. Yeah...TurboForth uses NUMBER ( addr len -- n|d flag ) the result is in the current radix (number base) and is usually a single number (n) unless the string at addr contains a ‘.’, in which case the result is a double number (d). fbForth and TI Forth use NUMBER ( addr -- d ), which operates on a packed string (string length in first byte) at addr to always produce a double number (d). DPL (“decimal” point location) is updated if a ‘.’ is present in the string at addr. An error message is issued if the string cannot be converted. BUT! the same code on HsForth under Intel DOSBOX gives wrong results. In both cases I am using the machine's native divide instruction. Is that the problem? No idea. Very likely. The TMS9900’s DIV is unsigned. Other CPUs may be signed (some symmetric, some floored, some ...) unsigned or both (I think). (I could not get it to compile on TurboForth because I don't know the equivalent to the ANS word ALIGNED) ANS ALIGNED ( addr -- a-addr ) is =CELLS ( addr -- a-addr ) in fbForth and TI Forth. (a-addr = aligned address.) It is not present in TurboForth, but the high-level Forth equivalent is : =CELLS ( addr -- a-addr ) <---this can obviously be named ALIGNED 1+ $FFFE AND ; ...lee Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 23, 2017 Share Posted March 23, 2017 Thank you for the translation kind sir. I have to do some work and stop playing here. :-) B Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 23, 2017 Author Share Posted March 23, 2017 I'll translate it to TurboForth, Bruce. Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 24, 2017 Author Share Posted March 24, 2017 Here's a super compact one for TurboForth, using VALUEs (I prefer them as you don't get the "noise" of ! and @) 0 value day 0 value month 0 value year : dow ( d m y ) to year to month to day month 2- 12 / year + to year month month 2- 12 / 12 * - to month month 2* day + month 1+ 6 * 10 / + year + year 4 / + year 100 / - year 400 / + 1+ 7 mod case 0 of ." Sunday " endof 1 of ." Monday " endof 2 of ." Tuesday " endof 3 of ." Wednesday " endof 4 of ." Thursday " endof 5 of ." Friday " endof 6 of ." Saturday " endof endcase ; 2 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 24, 2017 Share Posted March 24, 2017 Here it is exactly translated to fbForth 2.0 (well, as near as I could manage it): DECIMAL : ," ( -- ) ASCII " WORD HERE C@ 1+ ALLOT ; IMMEDIATE : [[ 0 C, ; : ]] [[ ; : CREATE_HDR <BUILDS DOES> ; CREATE_HDR DAYS [[ ," SUN" ," MON" ," TUES" ," WEDNES" ," THURS" ," FRI" ," SATUR" ]] : NTH ( n adr -- adr') SWAP 0 DO COUNT + LOOP ; : DAY. ( n -- $adr ) 1+ DAYS NTH COUNT TYPE ." DAY" ; 0 VARIABLE D 0 VARIABLE M 0 VARIABLE Y : INPUT ( d m y -- ) Y ! M ! D ! ; : (M-2)/12 ( -- n ) M @ 2- 12 / ; ( factored out of below) : YR ( -- ) Y @ (M-2)/12 + Y ! ; ( line 130 a) : MNTH ( -- ) M @ (M-2)/12 12 * - M ! ; ( line 130 b) : MAGIC ( -- n ) YR MNTH D @ M @ 2 * + M @ 1+ 6 * 10 / + Y @ + Y @ 4 / + Y @ 100 / - Y @ 400 / + 1+ DUP 7 / 7 * - ; ( line 150) : DOW ( D M Y -- ) CR ." That's a " INPUT MAGIC DAY. ; Changes necessary for fbForth 2.0: ASCII for [CHAR] Added HERE because WORD does not leave anything on the stack, but always puts parsed string at HERE . Removed ALIGNED (not sure what it is doing there because alignment screws up loop in NTH—no alignment necessary until next definition, which aligns itself) Created CREATE_HDR because CREATE in fbForth 2.0 is different (same as figForth) DO for ?DO VARIABLE definitions need initial values on the stack 2 * for 2* ...lee 2 Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 24, 2017 Author Share Posted March 24, 2017 Bruce/Lee (Ha!!!! Bruce Lee! Bruce Fucking Lee!!!!!!) Minimal changes required for TurboForth: : ," ( -- ) ASCII " WORD dup c, dup >r here swap cmove r> allot ; immediate CREATE DAYS ," SUN" ," MON" ," TUES" ," WEDNES" ," THURS" ," FRI" ," SATUR" : NTH ( n adr -- adr') SWAP 0 ?DO COUNT + LOOP ; : DAY. ( n -- $adr ) DAYS NTH COUNT TYPE ." DAY" ; VARIABLE D VARIABLE M VARIABLE Y : INPUT ( d m y -- ) Y ! M ! D ! ; : (M-2)/12 ( -- n ) M @ 2- 12 / ; ( factored out of below) : YR ( -- ) Y @ (M-2)/12 + Y ! ; ( line 130 a) : MNTH ( -- ) M @ (M-2)/12 12 * - M ! ; ( line 130 b) : MAGIC ( -- n ) YR MNTH D @ M @ 2* + M @ 1+ 6 * 10 / + Y @ + Y @ 4 / + Y @ 100 / - Y @ 400 / + 1+ DUP 7 / 7 * - ; ( line 150) : DOW ( D M Y -- ) CR ." That's a " INPUT MAGIC DAY. ; ," modified - needs to move the string that WORD *points to* to here. [[ removed (not required) ]] removed (not required) Note: ?DO isn't in memory at startup, but it's on block 41, hence retained. 2 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 24, 2017 Share Posted March 24, 2017 Re [[ and ]] , I thought to do that as well, but thought Bruce might have had a reason for using them, if only for aesthetics. I am sure he will chime in ere long to shed light on the matter. ...lee Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 25, 2017 Share Posted March 25, 2017 Bruce Lee... Son of a bitch, if you guys write a Forth implementation together, there is no doubt what it should be called.... 2 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 27, 2017 Share Posted March 27, 2017 (edited) Re [[ and ]] , I thought to do that as well, but thought Bruce might have had a reason for using them, if only for aesthetics. I am sure he will chime in ere long to shed light on the matter. ...lee I stole the Nth concept from HsForth and it required a 0 leading and a 0 ending the lists. Never bothered to change it. So creating the [[ ]] just made some syntax candy. Ending the list with 0 means Nth can't go past the end of the list. My lists don't work correctly if I remove the leading 0 byte... hmmm... By the way although Bruce is a very good name, mine is Brian. :-) BF But I was a big Bruce Lee fan! Edited March 27, 2017 by TheBF 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 27, 2017 Share Posted March 27, 2017 Changes necessary for fbForth 2.0: Removed ALIGNED (not sure what it is doing there because alignment screws up loop in NTH—no alignment necessary until next definition, which aligns itself ...lee I put aligned in the string definition to cope with odd length strings. You have challenged my assumptions to the core. Thanks! BF Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 27, 2017 Share Posted March 27, 2017 My lists don't work correctly if I remove the leading 0 byte... hmmm... You also need to remove the “1+” from DAY. . By the way although Bruce is a very good name, mine is Brian. :-) Oops! Wonder where Mark got that idea? ...lee Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 27, 2017 Author Share Posted March 27, 2017 By the way although Bruce is a very good name, mine is Brian. :-) "I'm Brian and so's my wife!" Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 27, 2017 Author Share Posted March 27, 2017 Oops! Wonder where Mark got that idea? ...lee It's just bit-rot. With apologies to Bruce Brian Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted March 27, 2017 Share Posted March 27, 2017 Ending the list with 0 means Nth can't go past the end of the list. Not true. COUNT always increments the string address by 1, even when the character count = 0. At least, that is how it works up through Forth-83. I could find nothing in the ANS-Forth standard that says COUNT must not increment the address if the character count = 0. If the number you pass to NTH is more than one past the last element, it will fail miserably. ...lee Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 27, 2017 Share Posted March 27, 2017 By the way although Bruce is a very good name, mine is Brian. :-) BF But I was a big Bruce Lee fan! https://youtu.be/TruXhuAO4IY 1 Quote Link to comment Share on other sites More sharing options...
Willsy Posted March 27, 2017 Author Share Posted March 27, 2017 ^^^^^^^^^^^^ Quote Link to comment Share on other sites More sharing options...
Opry99er Posted March 27, 2017 Share Posted March 27, 2017 "Stewie and Brian Forth" Many ways to skin a cat. Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 27, 2017 Share Posted March 27, 2017 Not true. COUNT always increments the string address by 1, even when the character count = 0. At least, that is how it works up through Forth-83. I could find nothing in the ANS-Forth standard that says COUNT must not increment the address if the character count = 0. If the number you pass to NTH is more than one past the last element, it will fail miserably. ...lee You are correct again. I had never tested it. B Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.