After reading Chapter 5 of SICP, I too started writing my own Scheme interpreter, but to be implemented in Fortran. Shortly after starting, I found the 1980s style C code for Minischeme (written by Atsushi Moriwaki and Akira Kida, following Matsuda and Saigo's article Programming of LISP, archive No 5 1987, 6-42). Minischeme (or miniscm) is also the basis for Dimitrios Souflis's Tinyscheme. I settled for porting the C code from both these projects (but mainly miniscm) across into Fortran so I could use it as an embedded language for my other Fortran projects.
The resulting interpreter passes most tests from R4RS and R5RS test suites, but lacks vectors and bignums. The types of numbers are long integers and reals. An internal peculiarity is that characters are implemented as single character Fortran strings. A memory cell is:
type mcell integer :: iflag integer (kind=8) :: value integer :: slength character, dimension(:), allocatable :: svalue integer :: keynum integer :: car integer :: cdr end type mcell
The file fscheme_mod.f95 contains the module scheme_lang, along with a few other dependencies, extracted from my sib-pair.f95 code by a simple awk script. This has been then hand edited to remove the extra commands used to access Sib-pair data structures. The last few lines (which you will have to revise) is a minimal main program demonstrating how to call up the Scheme read-eval-print loop:
program stub use scheme_lang integer :: plevel = 0, typ = 1 ! 1=interactive 2,3=batch call init_scheme() call repl_scheme(typ, plevel) end program stub
gfortran -cpp fscheme_mod.f95
will give you a runnable interpreter, from whose command line "(help)" will list the available commands.
Compile with -DEGGX to add the commands calling the EGGX/ProCALL graphical library ( http://www.ir.isas.jaxa.jp/~cyamauch/eggx_procall/), which allows plotting and building simple GUIs etc under X Windows. You will need to compile the library and add -leggx -lX11 to your compile command.
Compile with -DJAPI to add the commands calling the JAPI (java application programming interface) library (http://www.japi.de). JAPI allows Fortran code to interface the Java AWT (Abstract Windowing Toolkit), so one can build GUIs etc.
Adding a new Scheme function to call your Fortran code is straightforward enough.
call mk_proc(OP_NEWFUN, 'my-new-fun')
else if (op == OP_NEWFUN) then call your_fortran_code(i) s_return(mk_number(i))
%% (my-new-fun) 42
Look at the code for examples of passing lists to and from Fortran. For example,
else if (op == OP_DIR) then call list_files(get_string(car(scm_args)), files) n=size(files) res=nil if (n > 0) then do i=1, n res=append_one_string(trim(files(i)), res) end do deallocate(files) end if call s_return(res)
calls the Fortran code list_files(), which uses C interoperability to call POSIX readdir, and then converts the resulting Fortran character array into a Scheme list.
read_scheme_image() and save_scheme_image() are used by Fortran code to read and save images of the interpreter.