Advertisement
Guest User

interpretador_objetos_simple Archivo

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