Eval and code interpretation

This chapter describes the Bigloo evaluator.

Eval compliance

Bigloo includes an interpreter. Unfortunately, the language accepted by the interpreter is a proper subset of that accepted by the compiler. The main differences are:

Compiled code and interpreted code can be mixed together. That is, interpreted code is allowed to call compiled code and vice versa. This connection can be use to circumvent the missing features of the interpreter (see Section see Module Declaration, for a description of how to connect compiled and interpreted code).

By default the evaluator assumes that operators from the standard library (e.g., +, car) are immutable. Hence, it optimizes these operators's calls. This optimization can be disabled using the bigloo-eval-strict-module parameter described in the chapter describing the parameters (see see Parameters).

Eval standard functions

eval exp [env]procedure

This form evaluates exp. The second argument is optional. It can be the evaluation of one of these three function forms:
(scheme-report-environment 5)
(null-environment 5)
(interaction-environment)
.keep

scheme-report-environment versionprocedure

null-environment versionprocedure

interaction-environment versionprocedure

These three procedures have the definitions given in the R5RS so see Eval, scheme-report-environment, 6.5 Eval,r5rs.info,R5RS, for more details.
.keep

byte-code-compile exp [env (default-environment)]bigloo procedure

byte-code-run byte-codebigloo procedure

The function byte-code-compile compiles a Scheme expression into a sequence of byte codes that is implemented as a string. The function byte-code-run execute such a sequence.
.keep

replbigloo procedure

This invokes the read-eval-print loop. Several repl can be embedded.

The repl function can be used to implement custom Bigloo interpreters. For instance, one may write:

(module repl)
(repl)
When compiled, this will deliver an executable containingthe sole Bigloo interpreter.
.keep

set-repl-error-notifier! notifierbigloo procedure

get-repl-error-notifierbigloo procedure

Set or get the procedure used in the REPLs to display errors. The notifier is a procedure of one argument, the error or exception that has been raised. Example:

(set-repl-error-notifier!
   (lambda (e)
      (print "=== error ======)
      (exception-notify e)))
.keep

quit bigloo procedure

This exits from the currently running repl. If the current repl is the first one then this function ends the interpreter.
.keep

set-prompter! procbigloo procedure

The argument proc has to be a procedure of one argument and invoking this function sets the repl prompter. That is, to display its prompt, repl invokes proc giving it the nesting level of the current loop as its argument.
.keep

get-prompterbigloo procedure

Returns the current repl prompter.
.keep

set-repl-printer! procbigloo procedure

The argument proc has to be a procedure accepting one or two arguments. This function sets the repl display function. That is, to display the result of its evaluations, repl invokes proc giving it the evaluated expression as first argument and the current output port (or a file in case of transcript) as second argument. Set-repl-printer! returns the former repl display function.

For instance, one may write:

1:=> (define x (cons 1 2))          X
1:=> (define y (cons x x))          Y
1:=> y                              (#0=(1 . 2) . )
1:=> (set-repl-printer! display)    #<procedure:83b8c70.-2>
1:=> y                              ((1 . 2) 1 . 2)
.keep

native-repl-printerbigloo procedure

Returns the native (default) repl display function.
.keep

expand expbigloo procedure

Returns the value of exp after all macro expansions have been performed.
.keep

expand-once expbigloo procedure

Returns the value of exp after one macro expansion has been performed.
.keep
It is possible to specify files which have to be loaded when the interpreter is invoked. For this, see section see Compiler Description.

If a Bigloo file starts with the line:
 #! bigloo-command-name
and if this file is executable (in the meaning of the system) and if the user tries to execute it, Bigloo will evaluate it. Note also that SRFI-22 support enables to run any Unix interpreter (see SRFIs).

load filenamebigloo procedure

loadq filenamebigloo procedure

Filename should be a string naming an existing file which contains Bigloo source code. This file is searched in the current directory and in all the directories mentioned in the variable *load-path*. The load procedure reads expressions and definitions from the file, evaluating them sequentially. If the file loaded is a module (i.e. if it begins with a regular module clause), load behaves as module initialization. Otherwise, this function returns the result of the last evaluation. The function loadq differs from the function load in the sense that loadq does not print any intermediate evaluations.

Both functions return the full path of the loaded file.
.keep

loada filenamebigloo procedure

Loads an ``access file'', which allows the interpreter to find the modules imported by a loaded module. It returns the full path of the loaded file.
.keep

*load-path*bigloo variable

A list of search paths for the load functions.
.keep

dynamic-load filename #!optional (init init-point)bigloo procedure

Loads a shared library named filename. Returns the value of the last top-level expression.

Important note: The function dynamic-load can only be used from compiled modules linked against dynamic libraries. In particular, the dynamic-load function can be issued from the bigloo command if and only if the option --sharedcompiler=yes has been used when configuring Bigloo. If the bigloo command is not linked against dynamic libraries and if dynamic-load is required inside a read-eval-print loop (REPL) it exists a simple workaround. It consists in implementing a new REPL and linking it against dynamic libraries. This can be done as:

$ cat > new-repl.scm <<EOF
(module new-repl)
(repl)
EOF
$ bigloo new-repl.scm -o new-repl
$ new-repl
1:=> (dynamic-load ...)
1

If init-point is specified and if it is a string and if the library defines a function named init-point, this function is called when the library is loaded. Init-point is a C identifier, not a Scheme identifier. In order to set the C name a Scheme function, use the extern export clause (see Section see C Interface). If the init-point is provided and is not a string, no initialization function is called after the library is loaded. If the init-point value is not provided, once the library is loaded, dynamic-load uses the Bigloo default entry point. Normally you should not provide an init-point to dynamic-load unless you known what you are doing. When producing C code, to force the Bigloo compiler to emit such a default entry point, use the -dload-sym compilation option (see Section see Compiler Description). This option is useless when using the JVM code generator. Let's assume a Linux system and two Bigloo modules. The first:

(module mod1
   (eval (export foo))
   (export (foo x)))

(define (foo x)
   (print "foo: " x))

(foo 4)
The second:

(module mod2
   (import (mod1 "mod1.scm"))
   (eval (export bar))
   (export (bar x)))

(define (bar x)
   (print "bar: " x))

(bar 5)
If these modules are compiled as:

$ bigloo mod1.scm -c -o mod1.o 
$ bigloo mod2.scm -c -o mod2.o -dload-sym
Then, if a shared library is built using these two modules (note that on non Linux systems, a different command line is required):

$ ld -G -o lib.so mod1.o mod2.o
Then, lib.so cant be dynamically loaded and the variables it defines used such as :

$ bigloo -i
(dynamic-load "lib.so")
      foo: 4
       bar: 5
1:=> (foo 6)
      foo: 7
As the example illustrates, when Bigloo modules are dynamically loaded, they are initialized. This initialization is ensure only if dynamic-load is called with exactly one parameter. If dynamic-load is called with two parameters, it is of the responsibility of the program to initialize the dynamically loaded module before using any Scheme reference.

Note: In order to let the loaded module accesses the variables defined by the loader application, special compilation flags must be used (e.g., -rdynamic under the Linux operating system). Dynamic-load is implemented on the top of the dlopen facility. For more information read the dlopen and ld manuals.

.keep

dynamic-unload filenamebigloo procedure

On the operating system that supports this facility, unloads a shared library. Returns #t on success. Returns #f otherwise.
.keep

*dynamic-load-path*bigloo variable

A list of search paths for the dynamic-load functions.
.keep

dynamic-load-symbol filename name #!optional modulebigloo-procedure

dynamic-load-symbol-get dlsymbigloo-procedure

dynamic-load-symbol-set dlsym valbigloo-procedure

The function dynamic-load-symbol looks up for a variable in the dynamic library filename. If found, it returns a custom Bigloo object denoting that variable. Otherwise it returns #f. This function assumes that filename has previously been successfully loaded with dynamic-load. If not, an error is raised. The argument filename must be equal (in the sense of string=? to the argument used to load the library.

The C name of the looked up variable is name is module is not provided. Otherwise, it is the result of calling bigloo-module-mangle with name and module as arguments.

The function dynamic-load-symbol-get returns the value of a dynamically loaded variable.

The function dynamic-load-symbol-set sets the value of a dynamic loaded variable. It assumes that the variable is writable, i.e., that it has not been compiled as a C constant.
.keep

transcript-on filenameprocedure

transcript-off procedure

.keep

Eval command line options

This section presents the Bigloo compiler options that impact the interaction between compiled and interpreted code. The whole list of the Bigloo compiler options can be found in Compiler Description, , The Bigloo command line.

Eval and the foreign interface

To be able to get access to foreign functions within the Bigloo interpreter, some extra measurements have to be taken. The foreign functions have to be present in the interpreter binary, which means you have to compile a custom interpreter. This is described in Section Using C bindings within the interpreter.