Let me propose this: 1. Define the grammar properly. In particular, distinguish the grammar for expressions from those for definitions. For example,
Expr is one of: -- Variable -- (+ Expr Expr) -- (local (Definition*) Expr) -- ... Definition is one of: -- (define Variable Expr) -- (define-struct Variable (Variable*)) 2. Then follow the design recipe from HtDP. Design one recursive function per grammar but also define the outputs you wish to get from each: eval-for-expr : Expr -> ValueExpr eval-for-definition* : [Listof Definition] -> ValueDefinition I leave this to you as an exercise, but I recommend thinking of definitions as operators on environments. 3. The ideas are embedded in our textbook HtDP. (See htdp.org) On Jul 24, 2010, at 12:28 PM, Pedro Del Gallego wrote: > Hi, > > 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) > ...) > (local-proc-1) > (local-proc-1)) > > => Will be > > (define my-proc > (lambda () > (letrec ((local-proc-1 (lambda () ...)) > (local-proc-2 (lambda () ...))) > (local-proc-1) > (local-proc-2))) > > 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". > > > Thx. > -- > ------------------------------------- > Pedro Del Gallego > > Email : pedro.delgall...@gmail.com > _________________________________________________ > For list-related administrative tasks: > http://lists.racket-lang.org/listinfo/users _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users