[plt-scheme] How get enviroment

From: Daniel Yoo (dyoo at cs.wpi.edu)
Date: Thu Apr 19 14:18:15 EDT 2007

>    (grammar
>      (MODULE ((VARSDEF FUNCDEFS COMMANDS) (make-l-1C:module  $1 $2 $3)))
>
>      (VARSDEF ((VARSDEF1) $1) (() #f))
>      (VARSDEF1 ((VARSDEF2) $1) ((VARSDEF1 VARSDEF2) (append  $1  $2)))
>      (VARSDEF2 ((lxmVAR VARS lxmENDL)  $2))
>      (VARS ((VAR) (list $1)) ((VARS lxmCOMMA VAR) (append  $1 (list $3))))
>      (VAR
>       ((lxmID)  `(apply append-var moduleScope (apply create-var ,$1)))
>       ((lxmID lxmEXPORT) `(append-var moduleScope (create-var ,$1)))
>       ((lxmID lxmSLBRANCH lxmNUMBER lxmSRBRANCH)
>        `(append-var  moduleScope (create-array ,$1 ,$3)))
>       ((lxmID lxmSLBRANCH lxmNUMBER lxmSRBRANCH lxmEXPORT)
>        `(append-var  globalScope (create-array ,$1 ,$3))))
>      )))


Wait, what is this doing?

Ah, ok.  The actions of the grammar here look like plain s-expressions. 
I can sorta see what you're trying to do with eval, but the approach seems 
really bug-prone and prone to heavy confusion.


Why not construct a real abstract syntax tree with structures for the 
nodes, rather than these s-expressions?  You can then write your own 
function to interpret your syntax tree.  Trying to apply EVAL here just 
feels like making the problem much harder on yourself than you need.

I don't know what else is in your language, but it seems to me that 
something like defining two AST structure types, like:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   ;; Definitions for two AST structures.
   (define-struct node:module-append-var (vars))
   (define-struct node:global-append-var (vars))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


plus adjusting your grammar to produce these AST's structures:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     (grammar
      ;; ...
      (VAR
        ((lxmID)  (make-node:module-append-var
                   (list (create-var $1)))))
        ...
       )))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


and finally coupling that with an evaluation function that's aware of the 
ASTs:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (evaluate-ast an-ast module-scope global-scope)
   (cond
     [(node:module-append-var? an-ast)
      ...]
   ...))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

seems the way to go here.


I guess I'm trying to say this: don't use Scheme's EVAL.  It's the wrong 
tool for what you're trying to do.  Have your grammar produce data 
structures, and write your own evaluator on those structures.

For examples of writing interpreters, take a look at the beginning 
chapters of PLAI:

     http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/


Posted on the users mailing list.