Why a custom interpreter?

With all that functionality exposed, it should be fairly easy to lump the entire Eiffel program into a shared module and use it just like any other Python module. Unfortunately, that caused problems with file descriptors. We are still sorting that one out, but for one reason or another the standard Python interpreter simply would not mix and match file descriptors, in particular stdin, stdout, and stderr--any attempt to use any of the above (for input, output, or reassignment) would result in an instant crash and core dump--hardly a fitting end to our quest for Eiffel scripting!

We were never quite able to determine what the problem was, but we did determine a fix--albeit a rather strange one. The solution lay in creating a custom interpreter for Python that incorporated our Eiffel code as a built-in module. Really, nothing much changed except for the Setup.in file and make target:

Example 12-1. Setup.in and Make target for the custom interpreter

Setup.in:

eiffel_glue eiffel-glue_wrap.c test*.c (1)

Makefile target:

python lib.a : $(EIFFEL_GLUEMODULE_SOURCES) (1)
        rm -rf temp; \
        mkdir temp; \
        cp $(EIFFEL_GLUEMODULE_SOURCES) temp; \
        cp test* temp; \
        cd temp; \
        make -f Makefile.pre.in boot; \
        make static; \ (2)
        cp lib.a ..; \(3)
        cp python ..; \(4)
        cd ..; \
        rm -rf temp
(1)
Note the lack of a "*shared*" line, since we are building a static interpreter
(1)(3)(4)
We're creating both python and lib.a files, not a shared library
(2)
We must specify that we're making a static version of the interpreter and library

With that done, we get a very hefty interpreter, python, and a somewhat more reasonable lib.a. To see how they're used, let's take a peek at a sample program.