[racket] How to create 'Internal Definitions' in a scheme interpreter.

From: Pedro Del Gallego (pedro.delgallego at gmail.com)
Date: Sat Jul 24 12:28:17 EDT 2010


I am writing my first interpreter, but  I am struggling with the
definitions of  'define', 'let' and 'letrec'.

Here is the source code intrepreter (> 100 loc) . http://gist.github.com/487501

The problem is that 'define' requires access to the enviroment. I as
understand define is equivalent to these expansions.

==== Top level.
(define (foo)
   (... (bar) ...))

=> Will be

(define foo
        (lambda ()
           (... (bar) ...)))

==== In a lambda environment.

(define (my-proc)
   (define (local-proc-1)
   (define (local-proc-2)

=> Will be

(define my-proc
        (lambda ()
           (letrec ((local-proc-1 (lambda () ...))
                    (local-proc-2 (lambda () ...)))

Can anyone point me how to implement this features. I am trying to
implement them out of the evaluator function, but I guess that if they
need access to the environment, maybe they should be inside of the
evaluator method. Maybe something like this?

    [`(letrec ,binds ,eb)
          (eval-letrec binds eb env)]

    [`(let    ,binds ,eb)
          (eval-let binds eb env)]

; eval for letrec:
(define (eval-letrec bindings body env)
  (let* ((vars (map car bindings))
         (exps (map cadr bindings))
         (fs   (map (lambda _ #f) bindings))
         (env* (extended-env* env vars fs))
         (vals (map (evlis env*) exps)))
    (env-set!* env* vars vals)
    (eval body env*)))

; eval for let:
(define (eval-let bindings body env)
  (let* ((vars (map car bindings))
         (exps (map cadr bindings))
         (vals (map (evlis env) exps))
         (env* (extended-env* env vars vals)))
    (eval body env*)))

(define ? )

I am new in this list, so let me know if this question is "off-topic".

Pedro Del Gallego

Email              :   pedro.delgallego at gmail.com

Posted on the users mailing list.