Sunday, May 2, 2010

Prefixes

The Rx Core now has prefixes, and they're better than ever before. For those who aren't familiar with them from Retro 9.x, a prefix is a single character that is placed before a name. The notfound handler will check to see if a word exists without the prefix; if so, it passes the xt of the word on the stack to a prefix handler word.

Ok, so in Retro we have five basic prefixes: @ ! + - & these correspond to fetch, store, increment by, decrement by, and address of.

@ and ! correspond to @ and ! (pretty obvious); + and - corespond to +! and -!; and & corresponds to either ' or ['].

Their usage is intended to help cleanup code flow a bit. We can do things like:

&words execute ( execute 'words' )
@here ( return the value at 'here' )
@foo +bar ( increment 'bar' by the value in 'foo' )

If you want to define more prefixes, it's easy to do. For instance, say we want a prefix that returns the dictionary header of a word. notfound will give us the xt, so we can lay down a stub:

: __~ ( a-d ) ; immediate prefix

Note the two _ characters. This is a common attribute of prefix names: the must be three characters long, and start with two underscores. The word prefix moves our word to the prefixes vocabulary. This isn't necessary, but does prove useful by making it easy to disable prefixes globally.

Ok, so filling in the details:

: __~ ( a-d ) xt->d ; immediate prefix

At first glance this looks ok. Testing it reveals a problem:

: __~ ( a-d ) xt->d ; immediate prefix
: foo ~words ;
foo .s
reset
foo .s

To fix this we need to compile as a literal into a definition. Still pretty easy as far as things go because .data will do this for us:

: __~ ( a-d ) xt->d .data ; immediate prefix
: foo ~words ;
foo .s
reset
foo .s

Now we have a working prefix. Take a look at at the implementation of the default prefixes to get ideas on implementing more complex ones. Careful use can enable significant cleanups to messy code, but in some cases it will be better to use discrete words to aid overall readability. Like all advanced features, prefixes should be learned, then used where they will help.

No comments: