I'm working on a REPL for a #lang in which one can make definitions. One
writes
$x := 5
and this gets parsed into an S-expression like
(assignment "x" 5)
The #lang is not based on S-expressions, but I believe that that's
irrelevant (though I may be wrong). Naturally enough, I've set up the
expander for my #lang so that S-expressions like the previous one get
elaborated into a plain Racket define:
(define x 5)
The #lang works in DrRacket, and at the command line, too. The
difficulty is the REPL, which is based on the same expander but a
slightly modified reader. The problem shows up when one writes
> $x := 5
in the REPL. There, I get
define: not allowed in an expression context
This makes sense to me because what's actually being evaluated in the
REPL setting is
(#%top-interaction assignment "a" 1)
The define to which the assignment S-expression elaborates does indeed
seem to be in an expression context. (Or, at least, it's not toplevel;
the #%top-interaction makes sure of that.)
Is there any way around this? Not being able to assign values to
variables in the REPL is a blocker for me. I see a few options on the
table for this issue:
* Tweak current-eval (used by read-eval-print-loop). Doing this might
open the door to bypassing #%top-interaction. What would that look
like? Would one just destructure the given form to eval, checking
whether it looks like a #%top-interaction, in which case throw it away
and hand the rest to the "real" eval?
* Change what assignment means. Thus, (assignment "a" 5) would no
longer expand to (define a 5), but to something else, e.g., a set! or
box-set! that modifies an environment that I maintain by hand.
* Roll my own poor man's read-eval-print-loop. Of course, then I'd truly
be in the driver's seat, but that option would clearly be a
duplication of work the read-eval-print-loop is doing, and I really
don't want to do that.
Perhaps I'm missing something here. Any suggestions?