6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon Apr 29, 2024 3:15 am

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: back Forth and
PostPosted: Thu Aug 09, 2018 4:18 pm 
Offline

Joined: Wed Jul 18, 2018 12:12 pm
Posts: 96
After reading about 1/2 of 'Starting Forth' I was getting itchy to try some 'real' example code of my own. One little program that I seem to always do in a new language is the 'Guess a number between 1-10' game. I did find a simple random number generator in 'Starting Forth' that I modified to work on my target systems Forth implementation, i.e. a C64 running Durex Forth.

I could generate a random number with a given range and even take guesses at it interactively through interpreter. Great! I thought, how hard can it be to prompt a user for numerical input? Well, it was more difficult than I thought. Partly because of the references I could find being in different Forth implementations which have different inbuilt words. Durex supports the Forth 2012 core standard and not much else. Part of the problem was also getting familiar with the stack comments for each word and what it is telling me. Part of it was wondering why Forth does some things the way it does. For example why do I have to manually save the number of characters received from 'ACCEPT' at the font of the buffer?

Another thing that threw me is pushing a double onto the stack for >NUMBER to have to save the result to. That was not apparent at first but now I see it was clear if I knew how to read the stack comments.

I found good hints at: http://www.softsynth.com/pforth/pf_tut.php#Variables and https://www.forth.com/starting-forth/10 ... operators/

Now to wrap this all up into a single word (yes I did push 0 0 instead of a double, but I'm getting there)

Code:
variable buffer
20 allot
: input$ (-- $adrr )
   ." enter number:"
   inbuffer 1+ 20 accept
   inbuffer c! \char count save
;

: input# ( -- N )
   input$
   0 0 inbuffer count >number 2drop drop
;


Top
 Profile  
Reply with quote  
 Post subject: Re: back Forth and
PostPosted: Thu Aug 09, 2018 7:32 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
You might want to take a look at the built-in definitions like those of NUMBER? QUERY WORD CONVERT DIGIT> EXPECT etc.. There's probably something already there you can use. However, besides just typing in a number, the possibilities are endless. Thinking back, I was surprised that the only times I have ever needed to write a number-input word for applications where the operator was not supposed to have access to the command-line interpreter or to the compiler were where I had them enter the time and date, in designated fields of two digits each and the colons and slashes were skipped over, including with cursor keys and backspace character, and I made it ignore nonsense digits like 6 or greater in the tens of minutes field.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: back Forth and
PostPosted: Thu Aug 09, 2018 8:21 pm 
Offline

Joined: Wed Jul 18, 2018 12:12 pm
Posts: 96
Thanks for the input Garth. Durex Forth has only the bare essentials built in, even NUMBER is in a 'compat' file that has to be included (stuff the developer though might not be essential but were required to be Forth 2012 core compliant.) They have added some other definitions for C64 specific things like sound and video though (that can be INCLUDED). Out of your list only WORD is available.

I suspect that numeric input might not be the norm as it seemed to me mentioned as an afterthought in the references I read. Anyhow, the above does work BUT if ya don't enter a real number it will blow up. It would not be had to implement NUBMER? though, thinking out loud I guess you could do >NUMBER ( ud addr u -- ud addr2 u2 ) . If u2 is >0 then some part of the text was not a number.


Top
 Profile  
Reply with quote  
 Post subject: Re: back Forth and
PostPosted: Sun Aug 12, 2018 5:44 pm 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
Jeff_Birt wrote:
It would not be had to implement NUBMER? though, thinking out loud I guess you could do >NUMBER ( ud addr u -- ud addr2 u2 ) . If u2 is >0 then some part of the text was not a number.
One of the cool things about Forth is that you are allowed to assume that the users know what they are doing, so you don't have to protect them from everything (I remember, though I can't find it at the moment, a quote attributed to Chuck that went something like "we don't let idiots be brain surgeons, why should we let them program computers"). If you're using Forth and not, say, Go, you're probably in a situation where you have to run with scissors anyway. So for the conversion, maybe a word such as
Code:
: convertnumber ( addr u -- n ) 
>r >r 0. r> r>  ( 0 0 addr u )
>number ( ud addr u )
2drop d>s ;
would be a possibility. You can use it with, say
Code:
s" 21" convertnumber
and it should have the single-cell number TOS, or -- and this is the cool part -- a 0 if it was a string. Define the game so that you need to guess a number between 1 and whatever, and the 0 marks some bad input if you really want to check for it.

I agree >NUMBER looks scary at first -- my original reaction was, dude, WTF -- but it basically says "prime the pump with a double-cell number (usually just zero) and take the string. Return what you converted as a double-cell number, and the rest of the string if you found something that wasn't a number". Usually, you just toss out that last part, and convert the double-cell number to single-cell. While we're at it, I'm not sure if you want
Code:
VARIABLE BUFFER
but rather
Code:
CREATE BUFFER  20 ALLOT
because CREATE will then just return the address (your code should work, it's just you expect a buffer to use CREATE). Some systems have BUFFER: to make this easier, see https://forth-standard.org/standard/core/BUFFERColon (but not Gforth, it seems).

So if you want to be fancy, we could start off with
Code:
20 constant buffsize
create buffaddr  buffsize allot

buffaddr buffsize accept ( u )
buffaddr swap ( addr u )
convertnumber ( n )
And then start guessing.


Top
 Profile  
Reply with quote  
 Post subject: Re: back Forth and
PostPosted: Sun Aug 12, 2018 6:31 pm 
Offline

Joined: Wed Jul 18, 2018 12:12 pm
Posts: 96
Quote:
One of the cool things about Forth is that you are allowed to assume that the users know what they are doing, so you don't have to protect them from everything


If I were writing a program for another programmer I might agree if writing a program for general use then making it reasonably stupid proof is always a good thing. I mean NASA wrecked a multi-million dollar probe that had made it all the way to Mars because part of the mission control team was not aware the flight control corrections were supposed to be in imperial units. They 'assumed' metric units were being used and input a course correction that destroyed the probe. (Evidently they were a group that had been brought in recently and not been part of any of the mission briefings.)

How simple would it have been to have the box where you typed in the course correction have the units displayed beside it or to have the system so some sort of basic sanity test on course correction given before they are sent to the probe?

Quote:
Code:
VARIABLE BUFFER

Code:
CREATE BUFFER  20 ALLOT


I was just reading about this today in 'Starting Forth' and finally understood what the difference was. As I undertand it 'VARIABLE BUFFER' has not only the storage element (the cell) but also some boiler plate code related to what a VARIABLE does. Where as, CREATE is just an address marker of sorts (a type of pointer).

The 'guess the number' is a silly little program but it has always taught me about the system, the syntax, I/O etc. After writing this post the other day I implemented a ?NUMBER word which was not very difficult and then thought I should parse the input for a 'q' as the first charecter input and if a 'q' is not found then is goes on to the NUMBER conversion process as this seems more 'FORTHY'.

I really do appreciate the feedback. It helps to see how others might go about solving the problem diffrently than you. What got me on this whoel Forth learning adventure was reading Garth's website where he was doing some 'FORTHY' type stuff in 6502 assembly and I thoght 'that is an interesting way to do that!'


Top
 Profile  
Reply with quote  
 Post subject: Re: back Forth and
PostPosted: Mon Jan 07, 2019 9:19 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 855
scotws wrote:
So for the conversion, maybe a word such as
Code:
: convertnumber ( addr u -- n ) 
>r >r 0. r> r>  ( 0 0 addr u )
>number ( ud addr u )
2drop d>s ;
would be a possibility.

Or if Durex Forth has 2SWAP
Code:
: convertnumber  ( addr u -- n )
   0. 2swap  ( 0 0 addr u )
   >number  ( ud addr u )
   2drop d>s ;

Or for signed numbers
Code:
: convertnumber  ( addr u -- n )
   swap dup c@ [char] - =  ( u addr flag )
   dup >r -  swap  ( addr2 u )
   0. 2swap  ( 0 0 addr2 u )
   >number  ( ud addr2 u )
   2drop d>s
   r> if  negate  then ;

Used like this
Code:
s" -42" convertnumber

or this
Code:
s" 21" convertnumber

I'm away from my desktop, which has the Commodore simulator, so I haven't tested this yet.

Cheers,
Jim


Top
 Profile  
Reply with quote  
 Post subject: Re: back Forth and
PostPosted: Sun May 26, 2019 7:09 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 855
Oops! I forgot about adjusting the count!
This might work better.
Code:
: convertnumber  ( addr u -- n )
   over c@ [char] - =  ( addr u flag )
   dup >r abs /string  ( addr2 u2 )
   0. 2swap  ( 0 0 addr2 u2 )
   >number  ( ud addr2 u2 )
   2drop d>s
   r> if  negate  then ;

This assumes that TRUE on durex Forth is -1 .


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: barrym95838 and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: