Sorting in Colorforth

9 Comments

I've written a small Colorforth application, a demonstration of selection sort. All it does right now is display a randomized array, sort its contents and display the result. With a little extra work it could be made to 'animate' the sort.

The code is laid out in two blocks, one containing the initialization and sorting words, while the display words are in the next block. To run the code, load both blocks and invoke the demo word. Doing so will continually display the current state of the array until you launch a different application. Then invoke init to randomize the array, followed by sort to perform selection sort.

Here's the first block:

Selection sort in Colorforth - block 1

Colorforthers will recognize the array/nums combination as the idiom for statically allocating space for an array and obtaining its address. This array consists of 3 cells, enough to fit 12 byte-sized values. Why limit the demo to sorting 12 numbers? — mainly because that's how many lines of large font text can fit on my screen.

I scarfed the 1@/1! macros from other blocks that came as part of the CF system. Their purpose is to insert machine code for accessing byte-addressed memory locations (as opposed to CF's more usual cell-addressing.) They are used here in order to define the pair of words n@/n! which permit indexed access to the array of numbers.

There follow a few words for initializing the array. init uses the system clock to seed the random number generator and randomize the array. rand is a pseudo-random generator I read about in the Wikipedia article on Park-Miller RNGs, which, incidentally, says that this very RNG was used in the ZX Spectrum.

If it was good enough for Sir Clive then it's good enough for me, is what I always say.

randnums is how the array actually gets randomized. Its for loop runs though the indices from 11 down to zero, obtaining a random number and depositing it into the current index (only the lowest byte of the random number will get stored by 1!)

sort carries out an ascending sort. For each location from the first up to the penultimate, it determines the index of the minimum value seen between the current index and the end of the array. This value gets moved into its sorted location by the exchange word.

The workhorse of this algorithm is compare. The word's stack comment shown in the code has this meaning: given an index (i), and an array item (min) located at another index (mini), compare will return whichever is the lesser between min and the content of i. It will also return that value's index, either mini or i.

i- holds a special place in my heart as it's my first CF macro. Here's why it's useful. CF's for/next loop counts down from some N to 1. But there were a couple of words in the present program, sort included, where I found myself writing for loops that count up from zero to some N-1, using the phrase "N i negate +" to obtain the loop control variable. The macro in question allows this kind of thing to be shortened to "N i-"

Since all this macro is required to do is substitute itself by the phrase "i - + 1 +" it ought to be definable using cyan words exclusively (as opposed to green words which are executed for their side-effects at macroexpansion time.) Not so, I found, because constants like 1 cannot be rendered in cyan. However, a little rummaging around the CF distribution turned up a solution in the form of the "lit," macro which forces literals to be compiled.

On to the second block:

Selection sort in Colorforth - block 2

The demo word programs a background task to continually refresh the screen with a real-time display of the current sequence of values in the array. Each number is shown in large font with 3 digits, and the entire sequence is laid out in a single column.

digit breaks up a non-negative value into a specified number of decimal digits represented as CF character codes (24 is the code of the zero character.)

So that wraps up my commentary on the code. I might get around to making the interface more interactive. The basic idea may be to offer the user keys to directly invoke the minimum and exchange words.

John Drake

Cool application! Please consider joining the ColorForth Google group. Good discussion going on there.

http://groups.google.com/group/Color-Forth

2009-10-01 17:33

Ikram

John: Thanks for the pointer. I have just signed up for the group.

2009-10-01 22:43

Ray St. Marie

Hello Ikram and also Hi to John,

Very nice sort!

I am about to code it up and test it out and love on it a bit. I just used a situation like you coded the "i-" for and I am about to replace my situation. That's a sweetie right there. I _knew_ it would look something like that. With the "lit," and all I mean, but I just never got it right.

You did, though. And I'm glad. Well, done!

2009-10-31 02:59

Ikram

Ray: glad to hear you found this to be of some use.

Agree with you that macros can be tricky to get right. For instance I've been toying around with CF ever since I found Pavlyuk's Windows version in 2004, but couldn't be bothered to compose any macros till this "i-" thing came up.

Most CF macros seem to be written for the purpose of inserting machine code - I'm thinking especially of those mysterious hexadecimals in blocks 20 & 22. But as someone who's primarily a Lisp programmer, I'm more accustomed to macros being used for abstracting complex syntax. That's one reason I felt like writing the "i-" macro. Another is that, to define "i-" as an ordinary Forth word would require mucking about with the return stack. A little beyond my abilities at this stage.

2009-11-01 01:48

Ray

Gosh, Ikram, I meant to keep a copy of that last before I posted. If you find no use for it, could you consider e-mailing me ( sheesh lol) a copy of it. :-)
Thanks
Ray

2009-11-19 01:28

Ray

As you are a lisp programmer, Ikram, you might like, http://colorforthray.info/new_site/colisphorth.html .
I would love to discuss this with you and we can consider adding eq() equal() atom() eval(), on and on... :-)

Ray

2009-11-19 01:33

Ikram

Hi Ray, I've just been browsing though the source for Colisphorth. Great, you seem to have implemented the main primitive words for working with linked lists. I can see that building an interpreter for a Lisp-like language on top of all that would be an interesting direction to take.

During my misspent youth, I made a couple of abortive attempts at implementing Lisps. Each time, I'd get bogged down in the messy details and give up in frustration, usually over how to bootstrap the system or how to do garbage collection. So you'll understand why I find it hard to summon up the enthusiasm for another project!

If you're interested in taking Colisphorth further, I can recommend a fantastic book by Christian Quiennec: Lisp in Small Pieces. It's a guide for constructing Lisps, starting with a tiny interpreter and building up.

2009-11-19 23:49

Ray

LOL I figured it out! This wiki has dropped at least two posts that I have made to you that puts my other posts out of context.

I had written a big o'l analysis of your sort, not the sort part but the colorForth that implements it, with modifications for a more generic usage and total elimiation of array tables and breakdown of incrementor/decrementor patterns and 1 macro that makes nearly all of the colorForth...two days effort... lol gone to the bit bucket.

Thank you for the book recomendation. Respect your not wanting to start a project, totally agree and frankly I was asking for discussion. lol The project is not a project really.

Best wishes for you and yours.
Ray

2009-11-20 00:41

Ikram

Yikes! I've been putting off that Habari upgrade for too long.

2009-11-20 01:29