Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2019
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 15.54 KB | None | 0 0
  1. #lang eopl
  2.  
  3. ;^;;;;;;;;;;;;;;; grammatical specification ;;;;;;;;;;;;;;;;
  4.  
  5. (define the-lexical-spec
  6.   '((whitespace (whitespace) skip)
  7.     (comment ("%" (arbno (not #\newline))) skip)
  8.     (identifier
  9.       (letter (arbno (or letter digit "_" "-" "?")))
  10.       symbol)
  11.     (number (digit (arbno digit)) number)))
  12.  
  13. (define the-grammar
  14.   '((program ((arbno class-decl) expression) a-program)
  15.  
  16.     (expression (number) lit-exp)
  17.     (expression (identifier) var-exp)  
  18.     (expression
  19.       (primitive "(" (separated-list expression ",") ")")
  20.       primapp-exp)
  21.     (expression
  22.       ("if" expression "then" expression "else" expression)
  23.       if-exp)
  24.    (expression
  25.       ("let" (arbno  identifier "=" expression) "in" expression)
  26.       let-exp)
  27.     (expression
  28.       ("proc" "(" (separated-list identifier ",") ")" expression)
  29.       proc-exp)
  30.     (expression
  31.       ("(" expression (arbno expression) ")")
  32.       app-exp)
  33.     (expression                        
  34.       ("letrec"
  35.         (arbno identifier "(" (separated-list identifier ",") ")"
  36.           "=" expression)
  37.         "in" expression)
  38.       letrec-exp)
  39.     (expression ("set" identifier "=" expression) varassign-exp)
  40.     (expression
  41.       ("begin" expression (arbno ";" expression) "end")
  42.       begin-exp)
  43.  
  44.     (primitive ("+")     add-prim)
  45.     (primitive ("-")     subtract-prim)
  46.     (primitive ("*")     mult-prim)
  47.     (primitive ("add1")  incr-prim)
  48.     (primitive ("sub1")  decr-prim)
  49.     (primitive ("zero?") zero-test-prim)
  50.     (primitive ("list") list-prim)
  51.     (primitive ("cons") cons-prim)
  52.     (primitive ("nil")  nil-prim)
  53.     (primitive ("car")  car-prim)
  54.     (primitive ("cdr")  cdr-prim)
  55.     (primitive ("null?") null?-prim)
  56.  
  57. ;^;;;;;;;;;;;;;;; new productions for oop ;;;;;;;;;;;;;;;;
  58.  
  59.     (class-decl                        
  60.       ("class" identifier
  61.         "extends" identifier                  
  62.          (arbno "field" identifier)
  63.          (arbno method-decl)
  64.          )
  65.       a-class-decl)
  66.  
  67.     (method-decl
  68.       ("method" identifier
  69.         "("  (separated-list identifier ",") ")" ; method ids
  70.         expression
  71.         )
  72.       a-method-decl)
  73.  
  74.     (expression
  75.       ("new" identifier "(" (separated-list expression ",") ")")
  76.       new-object-exp)
  77.  
  78.     (expression
  79.       ("send" expression identifier
  80.         "("  (separated-list expression ",") ")")
  81.       method-app-exp)
  82.  
  83.     (expression                                
  84.       ("super" identifier    "("  (separated-list expression ",") ")")
  85.       super-call-exp)
  86.  
  87.     (expression                                
  88.       ("get" expression identifier )
  89.       get-exp)
  90.  
  91.     (expression                                
  92.       ("showEnv")
  93.       show-env-exp)
  94.  
  95. ;^;;;;;;;;;;;;;;; end new productions for oop ;;;;;;;;;;;;;;;;
  96.  
  97.     ))
  98.  
  99. (sllgen:make-define-datatypes the-lexical-spec the-grammar)
  100.  
  101. (define list-the-datatypes
  102.   (lambda () (sllgen:list-define-datatypes the-lexical-spec the-grammar)))
  103.  
  104. (define scan&parse
  105.   (sllgen:make-string-parser the-lexical-spec the-grammar))
  106.  
  107. (define just-scan
  108.   (sllgen:make-string-scanner the-lexical-spec the-grammar))
  109.  
  110. ;^;;;;;;;;;;;;;;; the interpreter ;;;;;;;;;;;;;;;;
  111.  
  112. (define eval-program
  113.   (lambda (pgm)
  114.     (cases program pgm
  115.       (a-program (c-decls exp)
  116.         (elaborate-class-decls! c-decls) ;\new1
  117.         (eval-expression exp (empty-env))))))
  118.  
  119. (define eval-expression
  120.   (lambda (exp env)
  121.     (cases expression exp
  122.       (lit-exp (datum) datum)
  123.       (var-exp (id) (apply-env env id))
  124.       (primapp-exp (prim rands)
  125.         (let ((args (eval-rands rands env)))
  126.           (apply-primitive prim args)))
  127.       (if-exp (test-exp true-exp false-exp)
  128.         (if (true-value? (eval-expression test-exp env))
  129.           (eval-expression true-exp env)
  130.           (eval-expression false-exp env)))
  131.       (let-exp (ids rands body)
  132.         (let ((args (eval-rands rands env)))
  133.           (eval-expression body (extend-env ids args env))))
  134.       (proc-exp (ids body)
  135.         (closure ids body env))
  136.       (app-exp (rator rands)
  137.         (let ((proc (eval-expression rator env))
  138.               (args (eval-rands      rands env)))
  139.           (if (procval? proc)
  140.             (apply-procval proc args)
  141.             (eopl:error 'eval-expression
  142.               "Attempt to apply non-procedure ~s" proc))))
  143.       (letrec-exp (proc-names idss bodies letrec-body)
  144.         (eval-expression letrec-body
  145.           (extend-env-recursively proc-names idss bodies env)))
  146.       (varassign-exp (id rhs-exp)
  147.         (setref!
  148.           (apply-env-ref env id)
  149.           (eval-expression rhs-exp env))
  150.         1)
  151. ;&
  152.       (begin-exp (exp1 exps)
  153.         (let loop ((acc (eval-expression exp1 env))
  154.                    (exps exps))
  155.           (if (null? exps) acc
  156.             (loop (eval-expression (car exps) env) (cdr exps)))))
  157. ;^;;;;;;;;;;;;;;; begin new cases for chap 5 ;;;;;;;;;;;;;;;;
  158.       (new-object-exp (class-name rands)
  159.         (let ((args (eval-rands rands env))
  160.               (obj (new-object class-name)))
  161.           (find-method-and-apply
  162.             'initialize class-name obj args)
  163.           obj))
  164.       (method-app-exp (obj-exp method-name rands)
  165.         (let ((args (eval-rands rands env))
  166.               (obj (eval-expression obj-exp env)))
  167.           (find-method-and-apply
  168.             method-name (object->class-name obj) obj args)))
  169.       (super-call-exp (method-name rands)
  170.         (let ((args (eval-rands rands env))
  171.               (obj (apply-env env 'self)))
  172.           (find-method-and-apply
  173.             method-name (apply-env env '%super) obj args)))
  174.       (get-exp (class identifier)
  175.         (let ( [ e-class (eval-expression class env) ] )
  176.           (let ( [ ids (part->field-ids (car e-class)) ] [ values (part->fields (car e-class)) ] )
  177.             (let findField ( [pos 0] )
  178.               (if (equal? identifier (list-ref ids pos))
  179.                 (vector-ref values pos)
  180.                 (findField (+ pos 1))
  181.               )
  182.             )
  183.           )
  184.         )
  185.       )
  186.       (show-env-exp () env)
  187. ;^;;;;;;;;;;;;;;; end new cases for chap 5 ;;;;;;;;;;;;;;;;
  188.     )))
  189.      
  190.  
  191. (define eval-rands
  192.   (lambda (exps env)
  193.     (map
  194.       (lambda (exp) (eval-expression exp env))
  195.       exps)))
  196.  
  197. (define apply-primitive
  198.   (lambda (prim args)
  199.     (cases primitive prim
  200.       (add-prim  () (+ (car args) (cadr args)))
  201.       (subtract-prim () (- (car args) (cadr args)))
  202.       (mult-prim  () (* (car args) (cadr args)))
  203.       (incr-prim  () (+ (car args) 1))
  204.       (decr-prim  () (- (car args) 1))
  205.       (zero-test-prim () (if (zero? (car args)) 1 0))
  206.       (list-prim () args)               ;already a list
  207.       (nil-prim () '())
  208.       (car-prim () (car (car args)))
  209.       (cdr-prim () (cdr (car args)))
  210.       (cons-prim () (cons (car args) (cadr args)))
  211.       (null?-prim () (if (null? (car args)) 1 0))
  212.       )))
  213.  
  214. (define init-env
  215.   (lambda ()
  216.     (empty-env)))
  217.  
  218. ;^;;;;;;;;;;;;;;; booleans ;;;;;;;;;;;;;;;;
  219.  
  220. (define true-value?
  221.   (lambda (x)
  222.     (not (zero? x))))
  223.  
  224.  
  225. ;;;;;;;;;;;;;;;; declarations ;;;;;;;;;;;;;;;;
  226.  
  227.  
  228. (define class-decl->class-name
  229.   (lambda (c-decl)
  230.     (cases class-decl c-decl
  231.       (a-class-decl (class-name super-name field-ids m-decls)
  232.         class-name))))
  233.  
  234. (define class-decl->super-name
  235.   (lambda (c-decl)
  236.     (cases class-decl c-decl
  237.       (a-class-decl (class-name super-name field-ids m-decls)
  238.         super-name))))
  239.  
  240. (define class-decl->field-ids
  241.   (lambda (c-decl)
  242.     (cases class-decl c-decl
  243.       (a-class-decl (class-name super-name field-ids m-decls)
  244.         field-ids))))
  245.  
  246. (define class-decl->method-decls
  247.   (lambda (c-decl)
  248.     (cases class-decl c-decl
  249.       (a-class-decl (class-name super-name field-ids m-decls)
  250.         m-decls))))
  251.  
  252. (define method-decl->method-name
  253.   (lambda (md)
  254.     (cases method-decl md
  255.       (a-method-decl (method-name ids body) method-name))))
  256.  
  257. (define method-decl->ids
  258.   (lambda (md)
  259.     (cases method-decl md
  260.       (a-method-decl (method-name ids body) ids))))
  261.  
  262. (define method-decl->body
  263.   (lambda (md)
  264.     (cases method-decl md
  265.       (a-method-decl (method-name ids body) body))))
  266.  
  267. (define method-decls->method-names
  268.   (lambda (mds)
  269.     (map method-decl->method-name mds)))
  270.        
  271. ;^;;;;;;;;;;;;;;; procedures ;;;;;;;;;;;;;;;;
  272.  
  273. (define-datatype procval procval?
  274.   (closure
  275.     (ids (list-of symbol?))
  276.     (body expression?)
  277.     (env environment?)))
  278.  
  279. (define apply-procval
  280.   (lambda (proc args)
  281.     (cases procval proc
  282.       (closure (ids body env)
  283.         (eval-expression body (extend-env ids args env))))))
  284.                
  285. ;^;;;;;;;;;;;;;;; references ;;;;;;;;;;;;;;;;
  286.  
  287. (define-datatype reference reference?
  288.   (a-ref
  289.     (position integer?)
  290.     (vec vector?)))
  291.  
  292. (define deref
  293.   (lambda (ref)
  294.     (cases reference ref
  295.       (a-ref (pos vec)
  296.              (vector-ref vec pos)))))
  297.  
  298. (define setref!
  299.   (lambda (ref val)
  300.     (cases reference ref
  301.       (a-ref (pos vec)
  302.         (vector-set! vec pos val)))
  303.     1))
  304.  
  305. ;^;;;;;;;;;;;;;;; environments ;;;;;;;;;;;;;;;;
  306.  
  307. (define-datatype environment environment?
  308.   (empty-env-record)
  309.   (extended-env-record
  310.     (syms (list-of symbol?))
  311.     (vec vector?)              ; can use this for anything.
  312.     (env environment?))
  313.   )
  314.  
  315. (define empty-env
  316.   (lambda ()
  317.     (empty-env-record)))
  318.  
  319. (define extend-env
  320.   (lambda (syms vals env)
  321.     (extended-env-record syms (list->vector vals) env)))
  322.  
  323. (define apply-env-ref
  324.   (lambda (env sym)
  325.     (cases environment env
  326.       (empty-env-record ()
  327.         (eopl:error 'apply-env-ref "No binding for ~s" sym))
  328.       (extended-env-record (syms vals env)
  329.         (let ((pos (rib-find-position sym syms)))
  330.           (if (number? pos)
  331.               (a-ref pos vals)
  332.               (apply-env-ref env sym)))))))
  333.  
  334. (define apply-env
  335.   (lambda (env sym)
  336.     (deref (apply-env-ref env sym))))
  337.  
  338. (define extend-env-recursively
  339.   (lambda (proc-names idss bodies old-env)
  340.     (let ((len (length proc-names)))
  341.       (let ((vec (make-vector len)))
  342.         (let ((env (extended-env-record proc-names vec old-env)))
  343.           (for-each
  344.             (lambda (pos ids body)
  345.               (vector-set! vec pos (closure ids body env)))
  346.             (iota len) idss bodies)
  347.           env)))))
  348.  
  349. (define rib-find-position
  350.   (lambda (sym los)
  351.     (list-find-position sym los)))
  352.  
  353. (define list-find-position
  354.   (lambda (sym los)
  355.     (list-index (lambda (sym1) (eqv? sym1 sym)) los)))
  356.  
  357. (define list-index
  358.   (lambda (pred ls)
  359.     (cond
  360.       ((null? ls) #f)
  361.       ((pred (car ls)) 0)
  362.       (else (let ((list-index-r (list-index pred (cdr ls))))
  363.               (if (number? list-index-r)
  364.                 (+ list-index-r 1)
  365.                 #f))))))
  366.  
  367. (define iota
  368.   (lambda (end)
  369.     (let loop ((next 0))
  370.       (if (>= next end) '()
  371.         (cons next (loop (+ 1 next)))))))
  372.  
  373. (define difference
  374.   (lambda (set1 set2)
  375.     (cond
  376.       ((null? set1) '())
  377.       ((memv (car set1) set2)
  378.        (difference (cdr set1) set2))
  379.       (else (cons (car set1) (difference (cdr set1) set2))))))
  380.  
  381.  
  382. ;^; new for ch 5
  383. (define extend-env-refs
  384.   (lambda (syms vec env)
  385.     (extended-env-record syms vec env)))
  386.  
  387. ;^; waiting for 5-4-2.  Brute force code.
  388. (define list-find-last-position
  389.   (lambda (sym los)
  390.     (let loop
  391.       ((los los) (curpos 0) (lastpos #f))
  392.       (cond
  393.         ((null? los) lastpos)
  394.         ((eqv? sym (car los))
  395.          (loop (cdr los) (+ curpos 1) curpos))
  396.         (else (loop (cdr los) (+ curpos 1) lastpos))))))
  397.  
  398.  
  399. ;; evaluar
  400. (define aux
  401.    (lambda (x)
  402.      x))
  403.  
  404. (define-datatype part part?
  405.   (a-part
  406.     (class-name symbol?)
  407.     (fields vector?)))
  408.  
  409. (define new-object
  410.   (lambda (class-name)
  411.     (if (eqv? class-name 'object)
  412.       '()
  413.       (let ((c-decl (lookup-class class-name)))
  414.         (cons
  415.           (make-first-part c-decl)
  416.           (new-object (class-decl->super-name c-decl)))))))
  417.  
  418. (define make-first-part
  419.   (lambda (c-decl)
  420.     (a-part
  421.       (class-decl->class-name c-decl)
  422.       (make-vector (length (class-decl->field-ids c-decl))))))
  423.  
  424. ;;;;;;;;;;;;;;;; methods ;;;;;;;;;;;;;;;;
  425.  
  426. ;;; methods are represented by their declarations.  They are closed
  427. ;;; over their fields at application time, by apply-method.
  428.  
  429. (define find-method-and-apply
  430.   (lambda (m-name host-name self args)
  431.     (if (eqv? host-name 'object)
  432.       (eopl:error 'find-method-and-apply
  433.         "No method for name ~s" m-name)
  434.       (let ((m-decl (lookup-method-decl m-name
  435.                       (class-name->method-decls host-name))))
  436.         (if (method-decl? m-decl)
  437.           (apply-method m-decl host-name self args)
  438.           (find-method-and-apply m-name
  439.             (class-name->super-name host-name)
  440.             self args))))))
  441.  
  442. (define view-object-as
  443.   (lambda (parts class-name)
  444.     (if (eqv? (part->class-name (car parts)) class-name)
  445.       parts
  446.       (view-object-as (cdr parts) class-name))))
  447.  
  448. (define apply-method
  449.   (lambda (m-decl host-name self args)
  450.     (let ((ids (method-decl->ids m-decl))
  451.           (body (method-decl->body m-decl))
  452.           (super-name (class-name->super-name host-name)))
  453.       (eval-expression body
  454.         (extend-env
  455.           (cons '%super (cons 'self ids))
  456.           (cons super-name (cons self args))
  457.           (build-field-env
  458.             (view-object-as self host-name)))))))
  459.  
  460. (define build-field-env
  461.   (lambda (parts)
  462.     (if (null? parts)
  463.       (empty-env)
  464.       (extend-env-refs
  465.         (part->field-ids (car parts))
  466.         (part->fields    (car parts))
  467.         (build-field-env (cdr parts))))))
  468.  
  469. ;;;;;;;;;;;;;;;; method environments ;;;;;;;;;;;;;;;;
  470.  
  471. ;; find a method in a list of method-decls, else return #f
  472.  
  473. (define lookup-method-decl
  474.   (lambda (m-name m-decls)
  475.     (cond
  476.       ((null? m-decls) #f)
  477.       ((eqv? m-name (method-decl->method-name (car m-decls)))
  478.        (car m-decls))
  479.       (else (lookup-method-decl m-name (cdr m-decls))))))
  480.      
  481. ;;;;;;;;;;;;;;;; class environments ;;;;;;;;;;;;;;;;
  482.  
  483. ;;; we'll just use the list of class-decls.
  484.  
  485. (define the-class-env '())
  486.  
  487. (define elaborate-class-decls!
  488.   (lambda (c-decls)
  489.     (set! the-class-env c-decls)))
  490.  
  491. (define lookup-class
  492.   (lambda (name)
  493.     (let loop ((env the-class-env))
  494.       (cond
  495.         ((null? env)
  496.          (eopl:error 'lookup-class
  497.            "Unknown class ~s" name))
  498.         ((eqv? (class-decl->class-name (car env)) name) (car env))
  499.         (else (loop (cdr env)))))))
  500.  
  501. ;;;;;;;;;;;;;;;; selectors of all sorts ;;;;;;;;;;;;;;;;
  502.  
  503. (define part->class-name
  504.   (lambda (prt)
  505.     (cases part prt
  506.       (a-part (class-name fields)
  507.         class-name))))
  508.  
  509. (define part->fields
  510.   (lambda (prt)
  511.     (cases part prt
  512.       (a-part (class-name fields)
  513.         fields))))
  514.  
  515. (define part->field-ids
  516.   (lambda (part)
  517.     (class-decl->field-ids (part->class-decl part))))
  518.  
  519. (define part->class-decl
  520.   (lambda (part)
  521.     (lookup-class (part->class-name part))))
  522.  
  523. (define part->method-decls
  524.   (lambda (part)
  525.     (class-decl->method-decls (part->class-decl part))))
  526.  
  527. (define part->super-name
  528.   (lambda (part)
  529.     (class-decl->super-name (part->class-decl part))))
  530.  
  531. (define class-name->method-decls
  532.   (lambda (class-name)
  533.     (class-decl->method-decls (lookup-class class-name))))
  534.  
  535. (define class-name->super-name
  536.   (lambda (class-name)
  537.     (class-decl->super-name (lookup-class class-name))))
  538.  
  539. (define object->class-name
  540.   (lambda (parts)
  541.     (part->class-name (car parts))))
  542.  
  543. ;;
  544.  
  545. (define read-eval-print
  546.   (sllgen:make-rep-loop  "-->" eval-program
  547.                          (sllgen:make-stream-parser
  548.                                   the-lexical-spec
  549.                                   the-grammar)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement