Re: How would you do this in forth?
- From: Jonah Thomas <jethomas5@xxxxxxxxx>
- Date: Fri, 3 Apr 2009 23:21:00 -0400
ember@xxxxxxxxxxxxxx wrote:
I've been teaching myself Forth over the last few months or so, and
I've noticed that I am having some problems expressing how to search
through an array!
ie find ( sc -- [i -1][0] ) search through an array of string
constants, return the index and true if found, false if its not in
there.
I'm not a complete lost cause, I mean I know what I'm trying to do
alright, it's just when I start coding it, what starts out as a fairly
simple idea just turns into an ugly mess and I spend far more time
than I want to just getting it to work, as most of the times I've
tried to do it it's just meant to be a quick and dirty solution.
So, am I missing the obvious or is there a better solution? Am I
looking at the problem at to low a level or something? I'm sure I've
never had a problem with this kind of thing in other languages, but
maybe I just don't know what the idiomatic forth is for this kind of
problem.
Here's my code, I'm using Albert van der Horst's lina/ciforth. To put
it in context, I wanted two words for symbol handling:
intern ( -- n ) - parse a symbol and put it in the symbol table if its
not there.
symbol ( n -- sc ) - gets it's name back again.
I thought I'd just code up a quick array based solution before making
a hash table or something, but it seems like a lot of code for what
I'm trying to do :(
CREATE symbols 100 ALLOT
0 symbols !
: symbol ( n -- sc )
CELLS symbols + @ $@ ;
: count+1 symbols 1 OVER +! @ ;
: (intern) ( sc -- n )
$, count+1 DUP CELLS symbols + ROT SWAP ! ;
\ ^^^ cant use dictionary
: at-start 2DUP 0 ;
: not-at-end ( i -- i f )
symbols @ OVER = INVERT ;
: not-yet >R 2DUP R> ;
: got-it: >R 2DROP R> ; : yes -1 ; : no 0 ;
: oh-dear DROP 2DROP 2DROP no ;
: next-symbol? ( sc i -- i+1 f )
1+ DUP >R symbol COMPARE R> SWAP 0= ;
: found ( sc -- [i -1][0] )
at-start BEGIN not-at-end WHILE next-symbol? IF
got-it: yes EXIT ELSE not-yet THEN REPEAT
oh-dear ;
: intern ( P:"symbol" -- n )
(WORD) 2DUP found IF got-it: EXIT ELSE (intern) THEN ;
You might try doing "found" with a DO LOOP instead of BEGIN WHILE REPEAT
.. Then you don't have to test for the end, it will go to the end and
stop without you having to think about that again after the loop starts.
If I doesn't have to be on the stack then not-yet and got-it: become
just 2DUP and 2DROP .
That isn't the only way to simplify your code, but that's a way that
might tend to steer you in the right direction more than mislead you.
.
- Follow-Ups:
- Re: How would you do this in forth?
- From: ember
- Re: How would you do this in forth?
- References:
- How would you do this in forth?
- From: ember
- How would you do this in forth?
- Prev by Date: Re: How to make Forth interesting?
- Next by Date: Re: How to make Forth interesting?
- Previous by thread: How would you do this in forth?
- Next by thread: Re: How would you do this in forth?
- Index(es):
Relevant Pages
|