RetroForum Welcome, Guest. Please login or register.
September 07, 2010, 05:54:38 AM
Home Help Search Calendar Login Register

RetroForth Discussion  |  Older Boards  |  Development  |  Topic: Changes coming in 8.3 « previous next »
Pages: 1 Go Down Print
Author Topic: Changes coming in 8.3  (Read 2831 times)
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Changes coming in 8.3
« on: November 06, 2005, 03:25:18 PM »

For the 8.3 release, I've been doing a lot of work on the core assembly and bootstrap code. The wordset and features have changed a bit as the result of this, and I'm getting to be pretty happy with the way it's shaping up. (The new core is called Rx)

Changes in Rx so far include:

- No I/O support

All I/O words are defined by the port-specific code and the new (optional) extended bootstrap code. This has let me do a lot of cleanups internally, and means that the core itself is now completely independent from the ports.

- Words for accessing fields in the dictionary

Rx provides a word (>entry) for obtaining the address of a dictionary entry. It also provides several words to access the various fields in the entry. This aids in readability since we have symbolic names as opposed to hard-coded constants now.

- Flags are passed on the stack

The result flags from find, >number, and true, false are now passed on the stack rather than in the carry flag. This means that they can be checked with if. The ?if word is now gone.

- Additional conditionals

I'm adding a few new conditional words, taken from HelFORTH (;then) and HerkForth (if;)

- .inline class

The simple .inline class is now defined in the assembly part of the core and is used for a few of the words. This brings performance back up to the 8.1 level, and is reduces bootstrap time on my machine from 0.013s to 0.004s

Additionally, I've been refactoring and cleaning up the assembly portion. So the core has a few significant changes, but should remain pretty familiar to those who already know RetroForth.


At a higher level is the RetroForth environment. The ports now define the core I/O words, and include retro.forth for things like string output (.") and number output. retro.forth also provides a set of case words which are used later to implement interpret.forth, the interactive interpreter.

As a final note, I'm working to move the I/O words in the main ports to use syscalls and FFI as opposed to being in assembly. It just makes maintenance so much easier on my end Smiley
Logged
Chuck Adams
Contributor
Jr. Member
***

Karma: +0/-0
Offline Offline

Posts: 24


View Profile
Re: Changes coming in 8.3
« Reply #1 on: November 09, 2005, 10:26:34 PM »

>entry looks like a "push" word like >r or a conversion word like ">number".  Wouldn't entry@ be more like an accessor?  Actually if it's accessing a field, perhaps it's time to bite the bullet, add a simple struct mechanism, and define a dict entry struct with named fields.

Now that truth values are moving out of CF and onto the stack, could < and > perhaps grow an alias each so people can have numeric inequality words and still have an available syntax to use when they want ... whatever < and > do? (I know what they do, I'm just having trouble coming up with a one or two word phrase for it)
Logged
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Re: Changes coming in 8.3
« Reply #2 on: November 10, 2005, 12:48:37 AM »

I'm considering renaming the current < and > to { }. This would free up < > for numeric comparisons.
Logged
Giant
Member
**

Karma: +0/-0
Offline Offline

Posts: 10


View Profile
Rx - a couple of outside the box thoughts
« Reply #3 on: November 20, 2005, 11:05:09 PM »

I've been looking over the Rx info... As long as some unorthodox directions are being taken, I have a couple of suggestions: (from years of dealing with Forth-like systems.  I've done very little Forth so pardon my ignorance.  Also pardon the capitalization as I am not sure if the tagging works correctly)
- Compiler state.  The whole state issue can be eliminated like this: all words always compile code; the command line acts as a nameless definition that runs the compiled code as soon as it is compiled and resets the pointers to eliminate it.   This actually cleans up the system conceptually, as you can use the looping constructs and compiling words the same way on the command line as inside definitions.
- Local symbols.  Keeping a clean namespace is important.  I like the loc feature.  However loc lops off the dictionary permanently, rendering all the local words inaccessible. There are times when you want to localize some words and not see them unless you need them specifically. 
I like the idea of vocabulary-like structures where the root word is globally visible and the words 'inside' it need to be explicitly prefixed by the root word.  For instance, the word file can be the root for a set of filesystem-related words; inside it we can put words open, close, etc.  To use them you would state file'open and file'close.  (the searching words are aware of the ' syntax).  This allows us to create 'libraries' of code that is available without polluting the global namespace.
- Extending the class mechanism  I like the class handler words.  However, you can make the system even more flexible by using the localizing/vocabulary scheme above to create class-handler directories containing 'methods' for those classes.  For instance, the class handler FORTH would have the words COMPILE DISPLAY DEFINE etc. inside.  SELF would also have those words - but COMPILE in FORTH would compile a 'call xxx' whereas SELF's COMPILE would jump to the word itself.  VAR's COMPILE perhaps could compile 'mov eax,[varaddr].  Similarly, DISPLAY could be called by the editor to print the name of the word, using a syntax coloring scheme or whatever.  DEFINE for each class would know how to create the definition, etc.  You would never call these directly, but the compiler would be simplified to looking up a word, finding the word COMPILE in the class directory of that word, and calling it.  Dictionary searches are fast enough to make little difference in compilation speed.

I've implemented forth-like systems with these features and found them to be very useful.  I can elaborate on implementation details if anyone cares to hear them.

I can keep going but perhaps this is a good time to stop for now.

« Last Edit: November 20, 2005, 11:37:38 PM by Giant » Logged
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Re: Changes coming in 8.3
« Reply #4 on: November 20, 2005, 11:48:59 PM »

Quote
- Compiler state.  The whole state issue can be eliminated like this: all words always compile code; the command line acts as a nameless definition that runs the compiled code as soon as it is compiled and resets the pointers to eliminate it.   This actually cleans up the system conceptually, as you can use the looping constructs and compiling words the same way on the command line as inside definitions.

I have considered doing this, but I haven't managed to write a Forth implementation using it that was as clean as a two state model. One thing I dislike is having to switch between the "interpreted" heap and the permanent one. Consider something like:

Code:
: foo [ ... some complex, one-time calculation ] literal .... ;

The system has to keep track of the code between [ and ] somewhere. Just compiling, running, and erasing it can work, but what if you did something like:

Code:
: foo [ " hello world!" $, ] .... ;

This actually compiles a string into the current definition. If it was compiled to a separate temporary heap, it won't work, and if compiled into the main heap and then cleaned up it still won't work as expected.

There's also something to be said for parsing words, which use the interpreter. A situation like this:

Code:
create foo '1 1, '2 2, '3 3,

Needs to be interpreted. With just a compile-only, it would compile a call to create, not find 'foo' (giving an error), and then compile the table. At runtime, it would not work as intended.

While not as efficient, having separate interpret/compile cycles takes care of situations like this nicely. Or perhaps I'm just missing something here....
Logged
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Re: Changes coming in 8.3
« Reply #5 on: November 20, 2005, 11:51:51 PM »

Expanding the local namespace concept is something I've also considered. I don't plan to alter loc:/;loc, but I might do a way to have actual local namespaces which keep the definitions around in 8.3. (In fact, this isn't a bad idea... I'll consider how to implement such a thing within the framework that exists. It should be possible.)

Update: I came up with something that seems pretty good to me at least:

Code:
forth
loc:
 : leave last @ swap ! last ! ;
 : .vocab last @ swap dup @ last ! later leave ;
 :: create last @ , as .vocab ;
;loc is voc: ' .self reclass

In use this looks like:

Code:
forth
voc: foo
foo 10 constant a
foo 20 constant b
foo : c a b + . cr ;
foo c
: bar foo c ;
« Last Edit: November 21, 2005, 12:47:46 AM by Charles Childers » Logged
Giant
Member
**

Karma: +0/-0
Offline Offline

Posts: 10


View Profile
Re: Changes coming in 8.3
« Reply #6 on: November 21, 2005, 12:47:49 AM »

State issues...
You are right, there are situations in which a single-state system gets in trouble.  I rarely came across these, and there is always a fairly simple way to get around it.

I still think it is still much more elegant than having the command-line words be different from compiled code words...But maybe it's just me.


Code:
create foo '1 1, '2 2, '3 3,
Right.  Hmm, I did say I worked with Forth-like systems, not Forth... I see what you mean.

However, most of the time the code space is extended with definitions. 
My vote is for a syntax change to
Code:
: foo '1 1, '2 2, '3 3 , ; whatever reclass
It makes the whole thing much cleaner in my opinion (Sorry about bastardizing Forth).

While we are on the subject of bastardization of Forth, one thing I tried and liked (more control given to the programmer) was to explicitly push things on the stack with the , ( words to compile were renamed ).  Therefore the equivalent of 1 2 + is 1 , 2 +   Although it sounds cumbersome, it eliminates a lot of needless push and pop code.  The syntax is quite natural - to put a list of numbers on the stack you say 1 , 2 , 3 , 4 etc.  And if you don't care about what's on TOS, you can simply say 5 for instance and it overwrites it instead of drop 5. I understand that it is probably too much for most Forth programmers and  offer it as an idle curiosity.

I would howerver LOVE to see Rx decoupled enough from Forth to allow me to dabble with bizzare dialects or build up completely different compilers on top.


« Last Edit: November 21, 2005, 01:12:45 AM by Giant » Logged
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Re: Changes coming in 8.3
« Reply #7 on: December 05, 2005, 12:39:09 AM »

I now have support for evaluating the command line in the hosted versions of RetroForth 8.3. This takes care of one of the most commonly requested features. See the blog entry for further information.
Logged
Pages: 1 Go Up Print 
RetroForth Discussion  |  Older Boards  |  Development  |  Topic: Changes coming in 8.3 « previous next »
Jump to:  


Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1 RC2 | SMF © 2001-2005, Lewis Media Valid XHTML 1.0! Valid CSS!