Losing EVALUATE when adding custom functions

17 views
Skip to first unread message

Frank Ruben

unread,
Jan 6, 2017, 1:41:32 PM1/6/17
to pforthdev
Hello all,

I'm bundling pForth as an embedded runtime into a C-program, where I at some
places invoke pForth with a C string holding some code to be evaluated by the
pForth runtime and where I then pick the results from the stack.

So I added a function pfEvalCStringAndPop() to pf_core.c, where I push the
string to be interpreted plus its length to the stack, I then call EVALUATE after
searching it via pfExecIfDefined() and finally pop the results from the stack.
This works fine so far - where I welcome any hints to a predefined function to
do the same.

Now I also added the handling of custom functions as described in pf_custom.c
and I found that those custom functions will only be visible when
pfBuildDictionary() is called which again only happens if I pass a non-0 IfInit
parameter to pfDoForth().

But once I set IfInit to non-0, EVALUATE will no longer be found by pfExecIfDefined(),
the call to ffFindC() will now return 0 and pfCatch() will not be executed,
so I cannot have both: my pfEvalCStringAndPop() plus my custom functions.

I could only find the comment "EVALUATE >IN SourceID=(-1) 1111" in pf_inner.c
but I cannot find a definition for EVALUATE, so I have no idea why EVALUATE is
not found in the case that I pass a non-0 IfInit parameter to pfDoForth().

Does anyone have a pointer where to proceed?

Thanks in advance (and thnaks to Phil for pForth!), Frank

Helmut Eller

unread,
Jan 7, 2017, 2:22:54 AM1/7/17
to Frank Ruben, pforthdev
On Fri, Jan 06 2017, Frank Ruben wrote:

> I could only find the comment "EVALUATE >IN SourceID=(-1) 1111" in
> pf_inner.c
> but I cannot find a definition for EVALUATE, so I have no idea why
> EVALUATE is
> not found in the case that I pass a non-0 IfInit parameter to
> pfDoForth().

EVALUATE is defined in Forth (misc1.fth). EVALUATE sets up SOURCE then
calls INTERPRET which corresponds to ffInterpert in C.

> Does anyone have a pointer where to proceed?

I think (I've never done this) the procedure goes like this:

1. Add custom functions to pfcustom.c

2. Create a new dictionary file. In the normal build process
this is done with

pforth -i <loadfile.fth>

where <loadfile.fth> is usually system.fth which loads all the Forth
source files, including EVALUATE, and writes pforth.dic at the end.
The -i command line option corresponds to IfInit=true.

3. Use the new dictionary file, which will also include your custom
functions. I think it's enough to the proper filename of the
dictionary file to pfDoForth. (You could also create a static
dictionary, but that requires one step more).

Helmut

Frank Ruben

unread,
Jan 7, 2017, 10:18:19 AM1/7/17
to pforthdev, frankr...@gmail.com
Thanks for the quick reply, Helmut.

I did embed pForth into my own main() program, e.g. with a different compilation
and a different command line processing. Still my understanding is that the "pForth -i"
should do the same as setting the IfInit parameter to a non-0 value.

Sadly with all my startup changes I cannot simply post one single offensive change.
But also I do not understand how my changes would lead to the dependency between
the custom function import and the need to pass IfInit.

(One more idea would be to merge my compilation and custom function changes into
a standard pForth repo, but this will also be a lot of effort.)

Following the implementation of EVALUATE, I just did replace the EVALUATE call
(I just wrote the code to a temp file and did run it with pfIncludeFile()). This now
works and I can execute code entered as a command line arg, but now I will get
errors just a few cycles later for undefined words in the executed code.

E.g. '--execute 27 .' works, but '--execute 27.13 F.' does not - now it is the 'F.' that is undefined.

So no more workarounds, I need to figure how to make all words available even when
I need the custom file inclusion - so how to not need to set IfInit, but still call CompileCustomFunctions().

Thanks again, Frank

Helmut Eller

unread,
Jan 7, 2017, 11:09:03 AM1/7/17
to Frank Ruben, pforthdev
On Sat, Jan 07 2017, Frank Ruben wrote:

> Sadly with all my startup changes I cannot simply post one single
> offensive change.
> But also I do not understand how my changes would lead to the
> dependency between
> the custom function import and the need to pass IfInit.

Reading through pfDoForth I found this:

#ifdef PF_NO_GLOBAL_INIT
if( LoadCustomFunctionTable() < 0 ) goto error2; /* Init custom 'C' call array. */
#endif

Maybe it would be useful for your use case to define PF_NO_GLOBAL_INIT.

Helmut

Frank Ruben

unread,
Jan 7, 2017, 12:11:59 PM1/7/17
to pforthdev, frankr...@gmail.com
Thanks again - I finally found it: it was a problem with my compilation process...

Since I'm embedding pForth with some other things (I saw that you're interested
in Scheme and CL, and coincidently I also added an S7 scheme to my executable),
I did set-up my own makefile which was supposed to only use a subset of the
pForth compile.

And somehow I screwed up the inclusion of pfdicdat.h under some circumstances,
and in these cases the additional words were missing. Now I heavily simplified
the compilation, and so the words from pfdicdat.h are also available when I
compile with custom functions.

As far as I understand the PF_NO_GLOBAL_INIT, it seems to help to correctly
initialize the C-based executable. I'm running pForth on Linux and here it
works fine w/o that flag.

Have a nice evening, Frank
Reply all
Reply to author
Forward
0 new messages