[racket] compiling for the repl, and SIGSEGV MAPERR errors?
Hi everyone,
I wanted to double check things before I start re-hacking the WeScheme
REPL. I'm trying to work with the mzc-generated bytecode for REPL
interaction expressions. From looking at the implementation of the
module language in drracket/private/module-language.rkt, I've derived
the following code to help me:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket/base
(require compiler/zo-parse)
;; Experiments: trying to figure out how to get the compiler to produce
;; bytecode appropriate with interactive REPLs.
(define ns (module->namespace 'racket/base))
;; compile-an-interaction: any -> compiled-code
(define (compile-an-interaction x)
(parameterize ([current-namespace ns])
(compile (namespace-syntax-introduce
(datum->syntax #f (cons '#%top-interaction x))))))
;; serialize-compiled-code: compiled-code -> bytes
(define (serialize-compiled-code a-compiled-code)
(let ([op (open-output-bytes)])
(write a-compiled-code op)
(get-output-bytes op)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I think that every interaction, like just entering the identifier x
at the REPL, will do something like compile-an-interaction: I expect
it to compile in the context of a module-derived namespace, producing
a compilation-top that refers to module variables.
For example, the interaction of just entering x
> x
should effectively compile to the following compilation-top structure:
;;;
> (zo-parse (open-input-bytes (serialize-compiled-code (compile-an-interaction 'x))))
'#s(compilation-top 0 #s(prefix 0 (x) ()) #s((toplevel expr 0 form 0)
0 0 #f #f))
;;;
The bytecode structure makes it seem that the value of x in the prefix
needs to refer to that in the namespace of some implicit module. Is
that right? I think I'm getting the right bytecode because when I do
the following sequence at the interactions window, it fits with what I
expected to see:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (eval (compile-an-interaction 'x))
reference to an identifier before its definition: x
> (define x 42)
> (eval (compile-an-interaction 'x))
42
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
If I try to evaluate that compiled bytecode in a bad, non-module
context, really bad things happen:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (eval (compile-an-interaction 'x) (make-base-empty-namespace))
SIGSEGV MAPERR si_code 1 fault on addr 0x4
Aborted
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
which I assume is because the context for evaluation, that empty
namespace used by the evaluation, isn't module-based. Is that right?