Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Less use of heads #15

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open

Less use of heads #15

wants to merge 49 commits into from

Conversation

nickd4
Copy link

@nickd4 nickd4 commented Apr 30, 2022

Background: The heads table is like a cut-down version of the Forth dictionary, that only records the entry point of each word, rather than the entry point, name and backlink. Heads are needed for mapping token numbers in *.seed files to addresses.

As mentioned in the previous PR, I wanted to make it so that heads are not created during seedForthInteractive -- because now that execution tokens are simply addresses, heads are not needed once we have loaded and started the *.seed file.

To do this, I have modified the new and create words so that creation of heads is now a caller responsibility. The revised new and create words simply return the here address as it was before creating the code field of the newly created token.

For reference see, for example, /i386/seedForth-i386.pre where it defines the new and create words. The updated way:

: new ( -- xt )
   here  lit enter , ;

: create ( -- xt )
   0 , \ dummy does> field
   here lit dovar , ;

And then see /common/seedForth.pre where it refers to the new word. The updated way:

: fun ( -- )
   new h,  compiler ;

It's pleasing that we can now do something sensible with the address returned by new, rather than the old new drop.

Inserting a call to h, after create is harder. Consider the seedForth code in /common/seedForthRuntime.seedsource:

Definer Variable ( <name> -- )    create ( x ) drop 0 , ;

Compare with the corresponding textual Forth code in /common/runtime.forth which is used with seedForthInteractive:

: Variable ( <name> )
    Create 0 , ;

My analysis is that Definer is a seedForthism, which does not exist in standard Forth, and which behaves like :, but gives the tokenizer a hook so that it can capture the name of the new word being defined, here Variable, create a token for it, and thus keep the token numbering in sync. And we can see that the usage is identical, i.e. the two definitions are the same, except that : is replaced with Definer in the seedForth source. To preserve this equivalence, what I've done is to have the tokenizer insert the sequence here h, in the start of the Definer-body, somewhat as if the user had executed the following definition:

Definer Variable ( <name> -- )    here h,  create ( x ) drop 0 , ;

Of course we could make this a user responsibility, in which case the user would have to write this (somewhat more pleasing):

Definer Variable ( <name> -- )    create ( x ) h, 0 , ;

But, I considered it too difficult for the user if they have to deviate too much from standard Forth. What do you think about it?

Update: I have just noticed that the create ( x ) drop sequence is also a seedForthism, as compared with standard Forth where Create doesn't seem to return an execution token (see the /common/runtime.forth snippet I showed above). Because of this we might have some more latitude to change things, such as requiring the user to call create (x) h,. But I'm not sure.

…to bss rather than text section which avoids the need to call mprotect(), rename things
… be wrapped with PROGRAM / END, also removes automatic bye token that was generated by END
…time.seedsource, so that we can run textual forth code without the tests or the banner
… writes to stderr, fix self-hosted tokenizer termination issue (was debugged with eemit)
…ng the nonstandard words on top of gForth's standard words, produces redefinition warnings
…seedForth-i386.pre containing some compiler words so we can do special handling for DTC
…sticated tracing and symbolic debug (via annotated trace) system used to debug the 65C02 port, the trace is also available for the Z80 port and can be used for comparison
…e caller's responsibility to do so if they need to, in the case of "new" this is done by replacing "new drop" with "new h," in the seedForth kernel, whereas in the case of "create" it is done by having the tokenizer prefix the body of the user's Definer-definition with "here h," -- or could make the latter a user responsibility
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants