Advertisement
Guest User

Untitled

a guest
Mar 29th, 2012
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scheme 9.03 KB | None | 0 0
  1. #lang eopl
  2. ;;;;;;;;;;;;;;;; grammatical specification ;;;;;;;;;;;;;;;;
  3.  
  4. (define the-lexical-spec
  5.   '((whitespace (whitespace) skip)
  6.    
  7.     (comment ("%" (arbno (not #\newline))) skip)
  8.    
  9.     (identifier
  10.      (letter (arbno (or letter digit "_" "-" "?"))) symbol)
  11.    
  12.     (number (digit (arbno digit)) number)
  13.    
  14.     (number ("-" digit (arbno digit)) number)
  15.     ))
  16.  
  17. (define the-grammar
  18.   '((program (expression) a-program)
  19.    
  20.     (expression (number) const-exp)
  21.    
  22.     (expression("-" "(" expression "," expression ")")diff-exp)
  23.    
  24.     (expression("*" "(" expression "," expression ")")mult-exp)
  25.    
  26.     (expression("+" "(" expression "," expression ")")add-exp)
  27.    
  28.     (expression("/" "(" expression "," expression ")")div-exp)
  29.    
  30.     (expression("minus" "(" expression ")") minus-exp)
  31.    
  32.     (expression ("zero?" "(" expression ")") zero?-exp)
  33.    
  34.     (expression
  35.      ("if" expression "then" expression "else" expression) if-exp)
  36.    
  37.     (expression (identifier) var-exp)
  38.    
  39.     (expression
  40.      ("let" (arbno identifier "=" expression) "in" expression) let-exp)
  41.    
  42.     (expression
  43.      ("letrec" identifier "(" identifier ")" "=" expression
  44.                "in" expression) letrec-exp)
  45.    
  46.     (expression ("proc" "(" identifier ")" expression) proc-exp)
  47.    
  48.     (expression ("(" expression expression ")") call-exp)
  49.    
  50.     ))
  51.  
  52. ;;;;;;;;;;;;;;;; sllgen boilerplate ;;;;;;;;;;;;;;;;
  53.  
  54. (sllgen:make-define-datatypes the-lexical-spec the-grammar)
  55.  
  56. (define show-the-datatypes
  57.   (lambda () (sllgen:list-define-datatypes the-lexical-spec the-grammar)))
  58.  
  59. (define scan&parse
  60.   (sllgen:make-string-parser the-lexical-spec the-grammar))
  61.  
  62. (define just-scan
  63.   (sllgen:make-string-scanner the-lexical-spec the-grammar))
  64.  
  65. ;;;;;    ENVIRONMENT
  66.  
  67. (define-datatype environment environment?
  68.   (empty-env)
  69.   (extend-env
  70.    (bvar symbol?)
  71.    (bval expval?)
  72.    (saved-env environment?))
  73.   (extend-env-rec
  74.    (id symbol?)
  75.    (bvar symbol?)
  76.    (body expression?)
  77.    (saved-env environment?)))
  78.  
  79. (define (apply-env env search-sym)
  80.     (cases environment env
  81.       (empty-env ()
  82.                  (eopl:error 'apply-env "No binding for ~s" search-sym))
  83.       (extend-env (var val saved-env)
  84.                   (if (eqv? search-sym var)
  85.                       val
  86.                       (apply-env saved-env search-sym)))
  87.       (extend-env-rec (p-name b-var p-body saved-env)
  88.                       (if (eqv? search-sym p-name)
  89.                           (proc-val (procedure b-var p-body env))          
  90.                           (apply-env saved-env search-sym)))))
  91.  
  92.  
  93.  
  94. (define (init-env)
  95.   (extend-env
  96.    'i (num-val 1)
  97.    (extend-env
  98.     'v (num-val 5)
  99.     (extend-env
  100.      'x (num-val 10)
  101.      (empty-env)))))
  102.  
  103.  
  104. ;;;;;;;;;;;;;;;; expressed values ;;;;;;;;;;;;;;;;
  105.  
  106. ;;; an expressed value is either a number, a boolean or a procval.
  107.  
  108. (define-datatype expval expval?
  109.   (num-val
  110.    (value number?))
  111.   (bool-val
  112.    (boolean boolean?))
  113.   (proc-val
  114.    (proc proc?)))
  115.  
  116. ;;; extractors:
  117.  
  118. ;; expval->num : ExpVal -> Int
  119. (define expval->num
  120.   (lambda (v)
  121.     (cases expval v
  122.       (num-val (num) num)
  123.       (else (expval-extractor-error 'num v)))))
  124.  
  125. ;; expval->bool : ExpVal -> Bool
  126. (define expval->bool
  127.   (lambda (v)
  128.     (cases expval v
  129.       (bool-val (bool) bool)
  130.       (else (expval-extractor-error 'bool v)))))
  131.  
  132. ;; expval->proc : ExpVal -> Proc
  133. (define expval->proc
  134.   (lambda (v)
  135.     (cases expval v
  136.       (proc-val (proc) proc)
  137.       (else (expval-extractor-error 'proc v)))))
  138.  
  139. (define expval-extractor-error
  140.   (lambda (variant value)
  141.     (eopl:error 'expval-extractors "Looking for a ~s, found ~s"
  142.                 variant value)))
  143.  
  144.  
  145. ;;;;;;;;;;;;;;;; procedures ;;;;;;;;;;;;;;;;
  146.  
  147. ;; proc? : SchemeVal -> Bool
  148. ;; procedure : Var * Exp * Env -> Proc
  149. (define-datatype proc proc?
  150.   (procedure
  151.    (var symbol?)
  152.    (body expression?)
  153.    (env environment?)))
  154.  
  155.  
  156. ;;;;;;;;;;;;;;;; the interpreter ;;;;;;;;;;;;;;;;
  157.  
  158. ;; value-of-program : Program -> ExpVal
  159. (define (value-of-program pgm)
  160.   (cases program pgm
  161.     (a-program (exp1)
  162.                (value-of exp1 (init-env)))))
  163.  
  164. ;; value-of : Exp * Env -> ExpVal
  165. (define (value-of exp env)
  166.   (cases expression exp
  167.    
  168.     (const-exp (num) (num-val num))
  169.    
  170.     (var-exp (var) (apply-env env var))
  171.    
  172.     (diff-exp (exp1 exp2)
  173.               (display 'diff-exp)
  174.               (newline)
  175.               (display exp1)
  176.               (newline)
  177.               (display exp2)
  178.               (newline)
  179.               (let ((val1 (value-of exp1 env))
  180.                     (val2 (value-of exp2 env)))
  181.                 (let ((num1 (expval->num val1))
  182.                       (num2 (expval->num val2)))
  183.                   (num-val (- num1 num2)))))
  184.     (minus-exp (exp1)
  185.                (let ((val (value-of exp1 env)))
  186.                  (let ((num (expval->num val)))
  187.                    (num-val (* -1 num)))))
  188.    
  189.     (add-exp (exp1 exp2)
  190.              (let ((val1 (value-of exp1 env))
  191.                    (val2 (value-of exp2 env)))
  192.                (let ((num1 (expval->num val1))
  193.                      (num2 (expval->num val2)))
  194.                  (num-val (+ num1 num2)))))
  195.    
  196.     (div-exp (exp1 exp2)
  197.              (let ((val1 (value-of exp1 env))
  198.                    (val2 (value-of exp2 env)))
  199.                (let ((num1 (expval->num val1))
  200.                      (num2 (expval->num val2)))
  201.                  (num-val (/ num1 num2)))))
  202.    
  203.     (mult-exp (exp1 exp2)
  204.               (let ((val1 (value-of exp1 env))
  205.                     (val2 (value-of exp2 env)))
  206.                 (let ((num1 (expval->num val1))
  207.                       (num2 (expval->num val2)))
  208.                   (num-val (* num1 num2)))))
  209.    
  210.     (zero?-exp (exp1)
  211.                (let ((val1 (value-of exp1 env)))
  212.                  (let ((num1 (expval->num val1)))
  213.                    (if (zero? num1)
  214.                        (bool-val #t)
  215.                        (bool-val #f)))))
  216.    
  217.     (if-exp (exp1 exp2 exp3)
  218.             (let ((val1 (value-of exp1 env)))
  219.               (if (expval->bool val1)
  220.                   (value-of exp2 env)
  221.                   (value-of exp3 env))))
  222.    
  223. ;     (let-exp (var exp1 body)
  224. ;              (let (
  225. ;                    [val1 (map (lambda (e) (append (value-of e env)))exp1)])
  226. ;                (display '111)
  227. ;                (newline)
  228. ;                    (let ([env1 (map (lambda (v va) (extend-env v va env)) var val1)])
  229. ;                      (value-of body (car env1)))))
  230.  
  231.     ; let var = exp1 in body
  232.     ; (eval "let x = 3 y = 5 in -(x,1)")
  233.     ; var = (x y)
  234.     ; exp1 = (#(struct:const-exp 3) #(struct:const-exp 5))
  235.     (let-exp (var exp1 body)
  236.              (let
  237.                  ([vals (map (lambda (e) (value-of e env))exp1)])
  238.                (display 'The-next-two-lines-shows-var-and-exp1)
  239.                (newline)
  240.                (display var)
  241.                (newline)
  242.                (display exp1)
  243.                (newline)
  244.                (newline)
  245.                    (let
  246.                        ([env1 (map (lambda (variable value) (extend-env variable value env)) var vals)])
  247.                      (value-of body (car env1)))))
  248.              
  249.     (letrec-exp (p-name param p-body letrec-body)
  250.                 (value-of letrec-body (extend-env-rec p-name
  251.                                                       param
  252.                                                       p-body
  253.                                                       env)))
  254.    
  255.     (proc-exp (var body)
  256.               (proc-val (procedure var body env)))
  257.    
  258.     (call-exp (rator rand)
  259.               (let ((proc (expval->proc (value-of rator env)))
  260.                     (arg (value-of rand env)))
  261.                 (apply-procedure proc arg)))
  262.    
  263.    
  264.     ))
  265.  
  266. ;; apply-procedure : Proc * ExpVal -> ExpVal
  267. (define (apply-procedure proc1 val)
  268.   (cases proc proc1
  269.     (procedure (var body saved-env)
  270.                (value-of body (extend-env var val saved-env)))))
  271.  
  272. ;;;;;;   EVALUATION WRAPPERS
  273.  
  274. ;; parse: String -> a-program
  275. (define (parse p) (scan&parse p))
  276.  
  277. ;; eval : String -> ExpVal
  278. (define (eval string)
  279.   (value-of-program (parse string)))
  280.  
  281. ;;;;; EXAMPLES OF EVALUATION
  282.  
  283. ;  
  284. ;  (eval "+(1, 2)")
  285. ;  (eval "+(minus(1), +(minus(2), minus(0)))")
  286. ;  (eval "/(minus(1), 2)")
  287. ;  (eval "minus(1)")
  288. ;  (eval "minus(-1)")
  289. ;  (eval "if zero?(1) then 1 else 2")
  290. ;  (eval "-(x, v)")
  291. ;  (eval "if zero?(-(x, x)) then x else 2")
  292. ;  (eval "if zero?(-(x, v)) then x else 2")
  293. ;  (eval "let decr = proc (a) -(a, 1) in (decr 30)")
  294. ;  (eval "( proc (g) (g 30) proc (y) -(y, 1))")
  295. ;  (eval "let x = 200
  296. ;           in let f = proc (z) -(z, x)
  297. ;                in let x = 100
  298. ;                     in let g = proc (z) -(z, x)
  299. ;                          in -((f 1), (g 1))")
  300. ;  (eval "let x = 200
  301. ;           in let f = proc (z) -(z, x)
  302. ;                in let x = 100
  303. ;                     in let g = proc (z) -(z, x)
  304. ;                          in -((f 1), (g 1))")
  305. ;  
  306. ;  (eval "letrec fact (n) = if zero?(n) then 1 else *(n, (fact -(n, 1))) in (fact 5)")
  307. ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement