Advertisement
cardel

Interpretador paso por referencia

Sep 10th, 2020
2,597
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 10.46 KB | None | 0 0
  1. #lang eopl
  2. ;.
  3.  
  4. ;;procedimientos
  5. ;.
  6. ;Asignación (lenguaje imperativo)
  7. ;.
  8. (define especificacion-lexica
  9.   '(
  10.     (espacio-blanco (whitespace) skip)
  11.     (comentario ("%" (arbno (not #\newline))) skip)
  12.     (identificador (letter (arbno (or letter digit "?"))) symbol)
  13.     (numero (digit (arbno digit)) number)
  14.     (numero ("-" digit (arbno digit)) number)
  15.     (numero (digit (arbno digit) "." digit (arbno digit)) number)
  16.     (numero ("-" digit (arbno digit) "."  digit (arbno digit)) number)
  17.     ))
  18.  
  19.  
  20. (define especificacion-gramatical
  21.   '(
  22.     (programa (expresion) a-program)
  23.     (expresion (numero) lit-exp)
  24.     (expresion (identificador) var-exp)
  25.     (expresion (primitiva "(" (separated-list expresion ",") ")") primapp-exp)
  26.     (expresion ("if" expresion "then" expresion "else" expresion) if-exp)
  27.     (expresion ("let" (arbno identificador "=" expresion) "in" expresion) let-exp)
  28.     (expresion ("proc" "(" (separated-list identificador ",") ")" expresion) proc-exp)
  29.     (expresion ("(" expresion (arbno expresion) ")") app-exp)
  30.     ;;Letrec
  31.     (expresion ("letrec" (arbno identificador "(" (separated-list identificador ",") ")" "=" expresion)
  32.                  "in" expresion) letrec-exp)
  33.     ;;asignación
  34.     (expresion ("set" identificador "=" expresion) set-exp)
  35.     (expresion ("begin" expresion (arbno ";" expresion) "end") begin-exp)
  36.     (primitiva ("+") sum-prim)
  37.     (primitiva ("-") menos-prim)
  38.     (primitiva ("*") multiplicacion-prim)
  39.     (primitiva ("add1") sucesor-prim)
  40.     (primitiva ("sub1") antecesor-prim)
  41.     ))
  42.  
  43. (define-datatype procval procval?
  44.   (closure (larg (list-of symbol?))
  45.            (body expresion?)
  46.            (old-env ambiente?)))
  47.  
  48. (sllgen:make-define-datatypes especificacion-lexica especificacion-gramatical)
  49.  
  50. (define interpretador
  51.   (sllgen:make-rep-loop
  52.    "=>"
  53.    (lambda (pgm) (evaluar-programa pgm))
  54.    (sllgen:make-stream-parser especificacion-lexica especificacion-gramatical)
  55.    ))
  56.  
  57. (define-datatype ambiente ambiente?
  58.   (ambiente-vacio)
  59.   (ambiente-extendido (lvar (list-of symbol?))
  60.                       (lvalor vector?)
  61.                       (amb ambiente?))
  62.  
  63.   )
  64.  
  65. (define ambiente-extendido-recursivo
  66.   (lambda (proc-names idds bodies old-env)
  67.     (let* (
  68.            (len (length proc-names))
  69.            (vec (make-vector len))
  70.            (env (ambiente-extendido proc-names vec old-env))
  71.            )
  72.       (letrec
  73.         (
  74.          (actualizar-vector
  75.           (lambda (pos lidds lbodies)
  76.             (cond
  77.               [(null? lidds) env]
  78.               [else
  79.                (begin
  80.                  (vector-set! vec pos (direct-target (closure (car lidds) (car lbodies) env)))
  81.                  (actualizar-vector (+ pos 1) (cdr lidds) (cdr lbodies))
  82.                  )]
  83.               )
  84.             )
  85.           )
  86.          )
  87.         (actualizar-vector 0 idds bodies)
  88.         ))))
  89.            
  90.  
  91. (define scheme-value?
  92.   (lambda (l)
  93.     #true))
  94.  
  95. (define apply-env
  96.   (lambda (amb sym)
  97.     (de-ref (apply-env-ref amb sym))))
  98.  
  99. ;;Esta nueva función retorna es una referencia asociada a una variable
  100. (define apply-env-ref
  101.   (lambda (amb sym)
  102.     (cases ambiente amb
  103.       (ambiente-vacio () (eopl:error "No pude encontrar la variable ~s" sym))
  104.       (ambiente-extendido (lids vec old-env)
  105.                          (letrec
  106.                              (
  107.                               (buscar-ambiente
  108.                                (lambda (pos lids)
  109.                                  (cond
  110.                                    [(null? lids) (apply-env-ref old-env sym)]
  111.                                    [(equal? sym (car lids))
  112.                                     (a-ref pos vec)]
  113.                                    [else  (buscar-ambiente (+ pos 1) (cdr lids))])))
  114.                               )
  115.                            (buscar-ambiente 0 lids))
  116.                          )
  117.       )
  118.     )
  119.   )
  120.  
  121.  
  122. (define ambiente-inicial
  123.   (ambiente-extendido '(x y z) (list->vector '(1 2 3))
  124.                       (ambiente-extendido '(a b c) (list->vector '(4 5 6)) (ambiente-vacio))))
  125.  
  126. (define evaluar-programa
  127.   (lambda (pgm)
  128.     (cases programa pgm
  129.       (a-program (exp) (evaluar-expresion exp ambiente-inicial)))))
  130.  
  131. (define evaluar-expresion
  132.   (lambda (exp amb)
  133.     (cases expresion exp
  134.       (lit-exp (num) num)
  135.       (var-exp (id) (apply-env amb id))
  136.       (if-exp (condicion true-exp false-exp)
  137.               (if
  138.                (true-value? (evaluar-expresion condicion amb))
  139.                (evaluar-expresion true-exp amb)
  140.                (evaluar-expresion false-exp amb)
  141.               ))
  142.       (let-exp (ids rands body)
  143.               (let
  144.                   (
  145.                   (randsnum (map (lambda (x) (direct-target (evaluar-expresion x amb)) ) rands))
  146.                   )
  147.            
  148.               (evaluar-expresion body (ambiente-extendido ids (list->vector randsnum) amb))))
  149.       (letrec-exp (proc-names idss bodies body)
  150.          (evaluar-expresion body (ambiente-extendido-recursivo proc-names idss bodies amb))
  151.       )
  152.       (proc-exp (lid body)
  153.                 (closure lid body amb))
  154.       (app-exp (rator rands)
  155.                (let
  156.                    (
  157.                     (proc (evaluar-expresion rator amb))
  158.                     (lrands (map (lambda (x) (evaluar-rand-pref x amb)) rands))
  159.                     )
  160.                  (if
  161.                   (procval? proc)
  162.                   (aplicar-procedimiento proc lrands)
  163.                   (eopl:error "Usted esta intentando aplicar un valor que no es un procedimiento")
  164.                   )
  165.                  ))
  166.       ;;Asignación
  167.       (set-exp (id rhs-exp)
  168.                (begin
  169.                  (setref! ;;Cambiamos el valor de la referencia
  170.                   (apply-env-ref amb id) ;;Retorna una referencia
  171.                   (evaluar-expresion rhs-exp amb)
  172.                   )
  173.                  1 ; Valor que significa que la expresión se hizo correctamente
  174.                  )
  175.                )
  176.       (begin-exp (exp exps)
  177.                  (if (null? exps)
  178.                      (evaluar-expresion exp amb)                    
  179.                      (letrec
  180.                          (
  181.                          ;;¿Que debo hacer aca?
  182.                          ;;Evaluar exp, y luego evlauar la lista, retornando el ultimo de la lista
  183.                          (evaluar-expresiones-begin
  184.                           (lambda (lst)
  185.                             (cond
  186.                               [(null? (cdr lst)) (evaluar-expresion (car lst) amb)]
  187.                               [else
  188.                                (begin
  189.                                  (evaluar-expresion (car lst) amb)
  190.                                  (evaluar-expresiones-begin (cdr lst)))]
  191.                               )
  192.                             )
  193.                           )
  194.                          )
  195.                        (begin
  196.                          (evaluar-expresion exp amb)
  197.                          (evaluar-expresiones-begin exps))
  198.                        )
  199.                      )
  200.                  )
  201.       (primapp-exp (prim lexp)
  202.                    (let
  203.                        (
  204.                         (lnum (map (lambda (x) (evaluar-expresion x amb)) lexp))
  205.                         )
  206.                      (aplicar-primitiva prim lnum)
  207.                    )
  208.       )
  209.     )
  210.   )
  211. )
  212.  
  213. (define true-value?
  214.   (lambda (num)
  215.     (not (zero? num))))
  216.  
  217. (define aplicar-primitiva
  218.   (lambda (prim lnum)
  219.     (cases primitiva prim
  220.       (sum-prim () (operar + 0 lnum))
  221.       (menos-prim () (operar - 0 lnum))
  222.       (multiplicacion-prim () (operar * 1 lnum))
  223.       (sucesor-prim  ()(+ 1 (car lnum)))
  224.       (antecesor-prim  () (- (car lnum) 1))
  225.       )))
  226.      
  227.  
  228. (define operar
  229.   (lambda (op acc lst)
  230.     (cond
  231.       [(null? lst) acc]
  232.       [else (op (car lst) (operar op acc (cdr lst)))]
  233.       )
  234.     ))
  235.  
  236. (define aplicar-procedimiento
  237.   (lambda (rator rands)
  238.     (cases procval rator
  239.       (closure (lid body old-env)
  240.                (evaluar-expresion body (ambiente-extendido lid (list->vector rands) old-env))))))
  241.  
  242.  
  243.  
  244. ;;REFERENCIAS
  245. (define-datatype referencia referencia?
  246.   (a-ref (pos number?)
  247.          (vec vector?)))
  248.  
  249.  
  250. (define de-ref
  251.   (lambda (ref)
  252.     (cases target (primitive-deref ref)
  253.       (direct-target (val) val)
  254.       (indirect-target (ref1)
  255.                        (cases target  (primitive-deref ref1)
  256.                          (direct-target (val) val)
  257.                          (indirect-target (p)
  258.                                           (eopl:error "Usted es un referencia ilegal: ~s" ref1)))))))
  259.  
  260.  
  261. (define primitive-deref
  262.   (lambda (ref)
  263.     (cases referencia ref
  264.       (a-ref (pos vec)
  265.              (vector-ref vec pos)))))
  266.  
  267. (define setref!
  268.   (lambda  (ref newexp)
  269.     (let
  270.         (
  271.          (ref
  272.           (cases target (primitive-deref ref)
  273.             (direct-target (exp) ref)
  274.             (indirect-target (ref1) ref1))
  275.           ))
  276.       (primitive-setref! ref (direct-target newexp))
  277.       )))
  278.  
  279.  
  280. (define primitive-setref!
  281.   (lambda (ref val)
  282.     (cases referencia ref
  283.       (a-ref (pos vec)
  284.         (vector-set! vec pos val)))))
  285. ;;PASO POR REFERENCIA
  286.  
  287. (define-datatype target target?
  288.   (direct-target (expval expval?))
  289.   (indirect-target (ref ref-to-direct-target?)))
  290.  
  291. (define expval?
  292.   (lambda (exp)
  293.     (or (procval? exp) (number? exp))))
  294.  
  295. (define ref-to-direct-target?
  296.   (lambda (exp)
  297.     (if (referencia? exp)
  298.         (cases referencia exp
  299.           (a-ref (vec pos)
  300.                  ;;Error del video (vector-ref vec pos)
  301.                  (cases target (vector-ref pos vec)
  302.                    (direct-target (v) #T)
  303.                    (indirect-target (v) (eopl:error "No se puede pasar una referencia entre procedimientos"))
  304.                    )
  305.                  )
  306.           )
  307.         #F)
  308.     )
  309.   )
  310.  
  311. (define evaluar-rand-pref
  312.   (lambda (x amb)
  313.     (cases expresion x
  314.       (var-exp (id)
  315.                (indirect-target
  316.                 (let(
  317.                      (ref (apply-env-ref amb id))
  318.                     )
  319.  
  320.                   (cases target (primitive-deref ref)
  321.                     (direct-target (exp) ref)
  322.                     ;;Cuando pasas de un procedimiento que recibe una variable a otro
  323.                     ;;Se toma la referencia al target directo :D
  324.                     (indirect-target (ref1) ref1)
  325.                     )
  326.                   )
  327.                 ))
  328.       (else
  329.        (direct-target (evaluar-expresion x amb)))
  330.       )))
  331.  
  332. (interpretador)
  333.    
  334.  
  335.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement