Advertisement
Guest User

interpretador_inferencia_tipos

a guest
Apr 7th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 35.14 KB | None | 0 0
  1. #lang eopl
  2.  
  3. ;***********************************************************************************************************************
  4. ;***********************************************************************************************************************
  5. ;;;;; Interpretador para lenguaje con condicionales, ligadura local, procedimientos,
  6. ;;;;; procedimientos recursivos y type checker
  7.  
  8. ;; La definición BNF para las expresiones del lenguaje:
  9. ;;
  10. ;;  <program>       ::= <expression>
  11. ;;                      <a-program (exp)>
  12. ;;  <expression>    ::= <number>
  13. ;;                      <lit-exp (datum)>
  14. ;;                  ::= <identifier>
  15. ;;                      <var-exp (id)>
  16. ;;                  ::= <primitive> ({<expression>}*(,))
  17. ;;                      <primapp-exp (prim rands)>
  18. ;;                  ::= if <expresion> then <expresion> else <expression>
  19. ;;                      <if-exp (exp1 exp2 exp23)>
  20. ;;                  ::= let {identifier = <expression>}* in <expression>
  21. ;;                      <let-exp (ids rands body)>
  22. ;;                  ::= proc({<optional-type-exp> <identificador>}*(,)) <expression>
  23. ;;                      <proc-exp (arg-texps ids body)>
  24. ;;                  ::= (<expression> {<expression>}*)
  25. ;;                      <app-exp proc rands>
  26. ;;                  ::= letrec  {<optional-type-exp> identifier ({<optional-type-exp> identifier}*(,)) = <expression>}* in <expression>
  27. ;;                     <letrec-exp result-texps proc-names arg-texpss idss bodies bodyletrec>
  28. ;;  <primitive>     ::= + | - | * | add1 | sub1
  29.  
  30. ;***********************************************************************************************************************
  31. ;***********************************************************************************************************************
  32.  
  33.  
  34. ;***********************************************************************************************************************
  35. ;**********************************************    Especificación Léxica   *********************************************
  36. ;***********************************************************************************************************************
  37.  
  38. (define scanner-spec-simple-interpreter
  39. '((white-sp
  40.    (whitespace) skip)
  41.   (comment
  42.    ("%" (arbno (not #\newline))) skip)
  43.   (identifier
  44.    (letter (arbno (or letter digit "?"))) symbol)
  45.   (number
  46.    (digit (arbno digit)) number)
  47.   (number
  48.    ("-" digit (arbno digit)) number)))
  49.  
  50. ;Especificación Sintáctica (gramática)
  51.  
  52. (define grammar-simple-interpreter
  53.   '((program (expression) a-program)
  54.     (expression (number) lit-exp)
  55.     (expression (identifier) var-exp)
  56.     (expression
  57.      (primitive "(" (separated-list expression ",")")")
  58.      primapp-exp)
  59.     (expression ("if" expression "then" expression "else" expression)
  60.                 if-exp)
  61.     (expression ("let" (arbno identifier "=" expression) "in" expression)
  62.                 let-exp)
  63.     (expression ( "(" expression (arbno expression) ")")
  64.                 app-exp)
  65.    
  66.     ; características adicionales
  67.     (expression ("false") false-exp)
  68.     (expression ("true") true-exp)
  69.     (expression ("proc" "(" (separated-list optional-type-exp identifier ",") ")" expression)
  70.                 proc-exp)
  71.     (expression ("letrec" (arbno optional-type-exp identifier
  72.                                  "(" (separated-list optional-type-exp identifier ",") ")"
  73.                                  "=" expression) "in" expression)
  74.                 letrec-exp)
  75.     ;;;;;;
  76.  
  77.     (primitive ("+") add-prim)
  78.     (primitive ("-") substract-prim)
  79.     (primitive ("*") mult-prim)
  80.     (primitive ("add1") incr-prim)
  81.     (primitive ("sub1") decr-prim)
  82.    
  83.     ; características adicionales
  84.     (primitive ("zero?") zero-test-prim)    
  85.     (type-exp ("int") int-type-exp)
  86.     (type-exp ("bool") bool-type-exp)
  87.     (type-exp ("(" (separated-list type-exp "*") "->" type-exp ")")
  88.               proc-type-exp)
  89.     (optional-type-exp ("?")
  90.       no-type-exp)
  91.     (optional-type-exp (type-exp)
  92.       a-type-exp)
  93.     ;;;;;;;;
  94.     ))
  95.  
  96. ;***********************************************************************************************************************
  97. ;***********************************************************************************************************************
  98.  
  99. ;***********************************************************************************************************************
  100. ;************************       Tipos de datos para la sintaxis abstracta de la gramática      *************************
  101. ;***********************************************************************************************************************
  102.  
  103. ;Construidos manualmente:
  104.  
  105. ;(define-datatype program program?
  106. ;  (a-program
  107. ;   (exp expression?)))
  108. ;
  109. ;(define-datatype expression expression?
  110. ;  (lit-exp
  111. ;   (datum number?))
  112. ;  (var-exp
  113. ;   (id symbol?))
  114. ;  (primapp-exp
  115. ;   (prim primitive?)
  116. ;   (rands (list-of expression?)))
  117. ;  (if-exp
  118. ;   (test-exp expression?)
  119. ;   (true-exp expression?)
  120. ;   (false-exp expression?))
  121. ;  (let-exp
  122. ;   (ids (list-of symbol?))
  123. ;   (rans (list-of expression?))
  124. ;   (body expression?))
  125. ;  (proc-exp
  126. ;   (arg-texps (list-of type-exp?))
  127. ;   (ids (list-of symbol?))
  128. ;   (body expression?))
  129. ;  (app-exp
  130. ;   (proc expression?)
  131. ;   (args (list-of expression?)))
  132. ;  (letrec-exp
  133. ;   (result-texps (list-of type-exp?))
  134. ;   (proc-names (list-of symbol?))
  135. ;   (arg-texpss (list-of type-exp?))
  136. ;   (idss (list-of (list-of symbol?)))
  137. ;   (bodies (list-of expression?))
  138. ;   (body-letrec expression?)))
  139.  
  140. ;
  141. ;(define-datatype primitive primitive?
  142. ;  (add-prim)
  143. ;  (substract-prim)
  144. ;  (mult-prim)
  145. ;  (incr-prim)
  146. ;  (decr-prim)
  147. ;  (zero-test-prim))
  148.  
  149. ;Construidos automáticamente:
  150.  
  151. (sllgen:make-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)
  152.  
  153. (define show-the-datatypes
  154.   (lambda () (sllgen:list-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)))
  155.  
  156. ;***********************************************************************************************************************
  157. ;***********************************************************************************************************************
  158.  
  159.  
  160. ;***********************************************************************************************************************
  161. ;*******************************************    Parser, Scanner, Interfaz     ******************************************
  162. ;***********************************************************************************************************************
  163.  
  164. ;El FrontEnd (Análisis léxico (scanner) y sintáctico (parser) integrados)
  165.  
  166. (define scan&parse
  167.   (sllgen:make-string-parser scanner-spec-simple-interpreter grammar-simple-interpreter))
  168.  
  169. ;El Analizador Léxico (Scanner)
  170.  
  171. (define just-scan
  172.   (sllgen:make-string-scanner scanner-spec-simple-interpreter grammar-simple-interpreter))
  173.  
  174. ;El Interpretador (FrontEnd + Evaluación + señal para lectura )
  175.  
  176. (define interpretador
  177.   (sllgen:make-rep-loop  "--> "
  178.     (lambda (pgm) (eval-program  pgm))
  179.     (sllgen:make-stream-parser
  180.       scanner-spec-simple-interpreter
  181.       grammar-simple-interpreter)))
  182.  
  183. ;El Interpretador + checker (FrontEnd + Evaluación + señal para lectura )
  184.  
  185. (define interpretador-tipos
  186.   (sllgen:make-rep-loop  "--> "
  187.     (lambda (pgm) (aux-interpretador  pgm))
  188.     (sllgen:make-stream-parser
  189.       scanner-spec-simple-interpreter
  190.       grammar-simple-interpreter)))
  191.  
  192. (define aux-interpretador
  193.   (lambda (x)
  194.     (if (type? (type-of-program x)) (eval-program  x) 'error) ))
  195.  
  196. (define interfaz-checker
  197.   (sllgen:make-rep-loop  "-->"
  198.                          (lambda (pgm) (type-to-external-form (type-of-program pgm)))
  199.                          (sllgen:make-stream-parser
  200.                                   scanner-spec-simple-interpreter
  201.                                   grammar-simple-interpreter)))
  202.  
  203. ;***********************************************************************************************************************
  204. ;***********************************************************************************************************************
  205.  
  206.  
  207. ;***********************************************************************************************************************
  208. ;************************************************    El Interprete      ************************************************
  209. ;***********************************************************************************************************************
  210.  
  211. ;eval-program: <programa> -> numero
  212. ; función que evalúa un programa teniendo en cuenta un ambiente dado (se inicializa dentro del programa)
  213.  
  214. (define eval-program
  215.   (lambda (pgm)
  216.     (cases program pgm
  217.       (a-program (body)
  218.                  (eval-expression body (init-env))))))
  219.  
  220. ; Ambiente inicial
  221. ;(define init-env
  222. ;  (lambda ()
  223. ;    (extend-env
  224. ;     '(x y z)
  225. ;     '(4 2 5)
  226. ;     (empty-env))))
  227.  
  228. (define init-env
  229.   (lambda ()
  230.     (extend-env
  231.      '(x y z f)
  232.      (list 4 2 5 (closure '(y) (primapp-exp (mult-prim) (cons (var-exp 'y) (cons (primapp-exp (decr-prim) (cons (var-exp 'y) '())) '())))
  233.                       (empty-env)))
  234.      (empty-env))))
  235.  
  236. ;eval-expression: <expression> <enviroment> -> numero
  237. ; evalua la expresión en el ambiente de entrada
  238. (define eval-expression
  239.   (lambda (exp env)
  240.     (cases expression exp
  241.       (lit-exp (datum) datum)
  242.       (var-exp (id) (apply-env env id))
  243.       (primapp-exp (prim rands)
  244.                    (let ((args (eval-rands rands env)))
  245.                      (apply-primitive prim args)))
  246.       (if-exp (test-exp true-exp false-exp)
  247.               (if (eval-expression test-exp env)
  248.                   (eval-expression true-exp env)
  249.                   (eval-expression false-exp env)))
  250.       (let-exp (ids rands body)
  251.                (let ((args (eval-rands rands env)))
  252.                  (eval-expression body
  253.                                   (extend-env ids args env))))
  254.       (proc-exp (args-texps ids body)
  255.                 (closure ids body env))
  256.       (app-exp (rator rands)
  257.                (let ((proc (eval-expression rator env))
  258.                      (args (eval-rands rands env)))
  259.                  (if (procval? proc)
  260.                      (apply-procedure proc args)
  261.                      (eopl:error 'eval-expression
  262.                                  "Attempt to apply non-procedure ~s" proc))))
  263.       (letrec-exp (result-texps proc-names arg-texpss idss bodies letrec-body)
  264.                   (eval-expression letrec-body
  265.                                    (extend-env-recursively proc-names idss bodies env)))
  266.       (true-exp ()
  267.                 #t)
  268.       (false-exp ()
  269.                  #f))))
  270.  
  271. ; funciones auxiliares para aplicar eval-expression a cada elemento de una
  272. ; lista de operandos (expresiones)
  273. (define eval-rands
  274.   (lambda (rands env)
  275.     (map (lambda (x) (eval-rand x env)) rands)))
  276.  
  277. (define eval-rand
  278.   (lambda (rand env)
  279.     (eval-expression rand env)))
  280.  
  281. ;apply-primitive: <primitiva> <list-of-expression> -> numero
  282. (define apply-primitive
  283.   (lambda (prim args)
  284.     (cases primitive prim
  285.       (add-prim () (+ (car args) (cadr args)))
  286.       (substract-prim () (- (car args) (cadr args)))
  287.       (mult-prim () (* (car args) (cadr args)))
  288.       (incr-prim () (+ (car args) 1))
  289.       (decr-prim () (- (car args) 1))
  290.       (zero-test-prim () (zero? (car args))))))
  291.  
  292. ;true-value?: determina si un valor dado corresponde a un valor booleano falso o verdadero
  293. (define true-value?
  294.   (lambda (x)
  295.     (not (zero? x))))
  296.  
  297. ;***********************************************************************************************************************
  298. ;***********************************************************************************************************************
  299.  
  300.  
  301.  
  302. ;***********************************************************************************************************************
  303. ;*********************************************   Definición tipos     **************************************************
  304. ;***********************************************************************************************************************
  305.  
  306. (define-datatype type type?
  307.   (atomic-type (name symbol?))
  308.   (proc-type
  309.     (arg-types (list-of type?))
  310.     (result-type type?))
  311.   (tvar-type
  312.     (serial-number integer?)
  313.     (container vector?)))
  314.  
  315. ;***********************************************************************************************************************
  316. ;***********************************************************************************************************************
  317.  
  318.  
  319.  
  320. ;***********************************************************************************************************************
  321. ;*************************************************   Type Checker     **************************************************
  322. ;***********************************************************************************************************************
  323.  
  324. ;type-of-program: <programa> -> type
  325. ; función que chequea el tipo de un programa teniendo en cuenta un ambiente dado (se inicializa dentro del programa)
  326. (define type-of-program
  327.   (lambda (pgm)
  328.     (cases program pgm
  329.       (a-program (exp) (type-of-expression exp (empty-tenv))))))
  330.  
  331. ;eval-expression: <expression> <enviroment> -> type
  332. ; chequea el tipo de la expresión en el ambiente de entrada
  333. (define type-of-expression
  334.   (lambda (exp tenv)
  335.     (cases expression exp
  336.       (lit-exp (number)
  337.                int-type)
  338.       (true-exp ()
  339.                 bool-type)
  340.       (false-exp ()
  341.                  bool-type)
  342.       (var-exp (id)
  343.                (apply-tenv tenv id))
  344.       (if-exp (test-exp true-exp false-exp)
  345.               (let ((test-type (type-of-expression test-exp tenv))
  346.                     (false-type (type-of-expression false-exp tenv))
  347.                     (true-type (type-of-expression true-exp tenv)))
  348.                 (check-equal-type! test-type bool-type test-exp)
  349.                 (check-equal-type! true-type false-type exp)
  350.                 true-type))
  351.       (proc-exp (texps ids body)
  352.                 (type-of-proc-exp texps ids body tenv))
  353.       (primapp-exp (prim rands)
  354.                    (type-of-application
  355.                     (type-of-primitive prim)
  356.                     (types-of-expressions rands tenv)
  357.                     prim rands exp))
  358.       (app-exp (rator rands)
  359.                (type-of-application
  360.                 (type-of-expression rator tenv)
  361.                 (types-of-expressions rands tenv)
  362.                 rator rands exp))
  363.       (let-exp (ids rands body)
  364.                (type-of-let-exp ids rands body tenv))
  365.       (letrec-exp (result-texps proc-names texpss idss bodies letrec-body)
  366.                   (type-of-letrec-exp result-texps proc-names texpss idss bodies
  367.                                       letrec-body tenv)))))
  368.  
  369. ;El unificador
  370.  
  371. ;check-equal-type!: <type> <type> <expression> ->
  372. ; verifica si dos tipos son iguales, muestra un mensaje de error en caso de que no lo sean
  373. (define check-equal-type!         ;;; NUEVO      
  374.   (lambda (t1 t2 exp)
  375.     (cond
  376.       ((eqv? t1 t2)  )  
  377.       ((tvar-type? t1) (check-tvar-equal-type! t1 t2 exp))
  378.       ((tvar-type? t2) (check-tvar-equal-type! t2 t1 exp))
  379.       ((and (atomic-type? t1) (atomic-type? t2))
  380.        (if (not
  381.              (eqv?
  382.                (atomic-type->name t1)
  383.                (atomic-type->name t2)))
  384.          (raise-type-error t1 t2 exp)
  385.          #t))
  386.       ((and (proc-type? t1) (proc-type? t2))
  387.        (let ((arg-types1 (proc-type->arg-types t1))
  388.              (arg-types2 (proc-type->arg-types t2))
  389.              (result-type1 (proc-type->result-type t1))
  390.              (result-type2 (proc-type->result-type t2)))
  391.          (if (not
  392.                (= (length arg-types1) (length arg-types2)))
  393.            (raise-wrong-number-of-arguments t1 t2 exp)
  394.            (begin
  395.              (for-each
  396.                (lambda (t1 t2)
  397.                  (check-equal-type! t1 t2 exp))
  398.                arg-types1 arg-types2)
  399.              (check-equal-type!
  400.                result-type1 result-type2 exp)))))
  401.       (else (raise-type-error t1 t2 exp)))))
  402.  
  403. ;check-tvar-equal-type!
  404. ; revisa si una variable de tipo es igual o no contiene un tipo de dado y asigna dicho tipo al contenedor de la variable de tipo
  405. (define check-tvar-equal-type!
  406.   (lambda (tvar ty exp)
  407.     (if (tvar-non-empty? tvar)
  408.       (check-equal-type! (tvar->contents tvar) ty exp)
  409.       (begin
  410.         (check-no-occurrence! tvar ty exp)
  411.         (tvar-set-contents! tvar ty)))))
  412.  
  413. ;check-no-occurrence!
  414. ;revisa si una variable de tipo no ocurre dentro de un tipo
  415.  
  416. (define check-no-occurrence!
  417.   (lambda (tvar ty exp)
  418.     (letrec
  419.       ((loop
  420.          (lambda (ty1)
  421.            (cases type ty1
  422.              (atomic-type (name) #t)
  423.              (proc-type (arg-types result-type)
  424.                (begin
  425.                  (for-each loop arg-types)
  426.                  (loop result-type)))
  427.              (tvar-type (num vec)
  428.                (if (tvar-non-empty? ty1)
  429.                  (loop (tvar->contents ty1))
  430.                  (if (eqv? tvar ty1)
  431.                    (begin  
  432.                     (display "me salgo")
  433.                    (raise-occurrence-check tvar ty exp))
  434.                    #t)))))))
  435.       (loop ty))))
  436.  
  437. ;funciones para despliegue de errores
  438. (define raise-type-error
  439.   (lambda (t1 t2 exp)
  440.     (eopl:error 'check-equal-type!
  441.       "Type mismatch: ~s doesn't match ~s in ~s~%"
  442.       (type-to-external-form t1)
  443.       (type-to-external-form t2)
  444.       exp)))
  445.  
  446. (define raise-wrong-number-of-arguments
  447.   (lambda (t1 t2 exp)
  448.     (eopl:error 'check-equal-type!
  449.       "Different numbers of arguments ~s and ~s in ~s~%"
  450.       (type-to-external-form t1)
  451.       (type-to-external-form t2)
  452.       exp)))
  453.  
  454. (define raise-occurrence-check
  455.   (lambda (tvnum t2 exp)
  456.     (eopl:error 'check-equal-type!
  457.       "Can't unify: ~s occurs in type ~s in expression ~s~%"
  458.       ;tvnum
  459.       (type-to-external-form tvnum)
  460.       (type-to-external-form t2)
  461.       exp)))
  462.  
  463. ;type-to-external-form: <type> -> lista o simbolo
  464. ; recibe un tipo y devuelve una representación del tipo facil de leer
  465. (define type-to-external-form
  466.   (lambda (ty)
  467.     (cases type ty
  468.       (atomic-type (name) name)
  469.       (proc-type (arg-types result-type)
  470.                  (append
  471.                   (arg-types-to-external-form arg-types)
  472.                   '(->)
  473.                   (list (type-to-external-form result-type))))
  474.       (tvar-type (serial-number container) ;;; NUEVO
  475.         (if (tvar-non-empty? ty)
  476.           (type-to-external-form (tvar->contents ty))
  477.           (string->symbol
  478.             (string-append
  479.               "tvar"
  480.               (number->string serial-number))))))))
  481.  
  482. (define arg-types-to-external-form
  483.   (lambda (types)
  484.     (if (null? types)
  485.         '()
  486.         (if (null? (cdr types))
  487.             (list (type-to-external-form (car types)))
  488.             (cons
  489.              (type-to-external-form (car types))
  490.              (cons '*
  491.                    (arg-types-to-external-form (cdr types))))))))
  492.  
  493. ;type-of-proc-exp: (list-of <type-exp>) (list-of <symbol>) <expression> <tenv> -> <type>
  494. ; función auxiliar para determinar el tipo de una expresión de creación de procedimiento
  495. (define type-of-proc-exp
  496.   (lambda (texps ids body tenv)
  497.     (let ((arg-types (expand-optional-type-expressions texps tenv)))
  498.       (let ((result-type
  499.              (type-of-expression body
  500.                                  (extend-tenv ids arg-types tenv))))
  501.         (proc-type arg-types result-type)))))
  502.  
  503. ;type-of-application: <type> (list-of <type>) <symbol> (list-of <symbol>) <expresion> -> <type>
  504. ; función auxiliar para determinar el tipo de una expresión de aplicación
  505. (define type-of-application
  506.   (lambda (rator-type actual-types rator rands exp)
  507.     (let ((result-type (fresh-tvar)))
  508.       (check-equal-type!
  509.         rator-type
  510.         (proc-type actual-types result-type)
  511.         exp)
  512.       result-type)))
  513.  
  514. ;type-of-primitive: <primitive> -> <type>
  515. ; función auxiliar para determinar el tipo de una primitiva
  516. (define type-of-primitive
  517.   (lambda (prim)
  518.     (cases primitive prim
  519.       (add-prim ()
  520.                 (proc-type (list int-type int-type) int-type))
  521.       (substract-prim ()
  522.                       (proc-type (list int-type int-type) int-type))
  523.       (mult-prim ()
  524.                  (proc-type (list int-type int-type) int-type))
  525.       (incr-prim ()
  526.                  (proc-type (list int-type) int-type))
  527.       (decr-prim ()
  528.                  (proc-type (list int-type) int-type))
  529.       (zero-test-prim ()
  530.                       (proc-type (list int-type) bool-type)))))
  531.  
  532. ;types-of-expressions: (list-of <type-exp>) <tenv> -> (list-of <type>)
  533. ; función que mapea la función type-of-expresion a una lista
  534. (define types-of-expressions
  535.   (lambda (rands tenv)
  536.     (map (lambda (exp) (type-of-expression exp tenv)) rands)))
  537.  
  538. ;type-of-primitive: (list-of <symbol>) (list-of <expression>) <expression> <tenv> -> <type>
  539. ; función auxiliar para determinar el tipo de una expresión let
  540. (define type-of-let-exp
  541.   (lambda (ids rands body tenv)
  542.     (let ((tenv-for-body
  543.            (extend-tenv
  544.             ids
  545.             (types-of-expressions rands tenv)
  546.             tenv)))
  547.       (type-of-expression body tenv-for-body))))
  548.  
  549. ;type-of-primitive: (list-of <type-exp>) (list-of <symbol>) (list-of (list-of <type-exp>)) (list-of (list-of <symbol>)) (list-of <expression>) <expression> <tenv> -> <type>
  550. ; función auxiliar para determinar el tipo de una expresión letrec
  551. (define type-of-letrec-exp
  552.   (lambda (result-texps proc-names arg-optional-texpss idss bodies letrec-body tenv)
  553.     (let ((arg-typess (map (lambda (texps)
  554.                              (expand-optional-type-expressions texps tenv))
  555.                            arg-optional-texpss))
  556.           (result-types (expand-optional-type-expressions result-texps tenv)))
  557.       (let ((the-proc-types
  558.              (map proc-type arg-typess result-types)))
  559.         (let ((tenv-for-body
  560.                (extend-tenv proc-names the-proc-types tenv)))
  561.           (for-each
  562.            (lambda (ids arg-types body result-type)
  563.              (check-equal-type!
  564.               (type-of-expression
  565.                body
  566.                (extend-tenv ids arg-types tenv-for-body))
  567.               result-type
  568.               body))
  569.            idss arg-typess bodies result-types)
  570.           (type-of-expression letrec-body tenv-for-body))))))
  571.  
  572. ;***********************************************************************************************************************
  573. ;***********************************************************************************************************************
  574.  
  575.  
  576.  
  577. ;***********************************************************************************************************************
  578. ;*********************************************     Procedimientos     **************************************************
  579. ;***********************************************************************************************************************
  580.  
  581. (define-datatype procval procval?
  582.   (closure
  583.    (ids (list-of symbol?))
  584.    (body expression?)
  585.    (env environment?)))
  586.  
  587. ;apply-procedure: evalua el cuerpo de un procedimientos en el ambiente extendido correspondiente
  588. (define apply-procedure
  589.   (lambda (proc args)
  590.     (cases procval proc
  591.       (closure (ids body env)
  592.                (eval-expression body (extend-env ids args env))))))
  593.  
  594. ;***********************************************************************************************************************
  595. ;***********************************************************************************************************************
  596.  
  597.  
  598. ;***********************************************************************************************************************
  599. ;***********************************************     Ambientes     *****************************************************
  600. ;***********************************************************************************************************************
  601.  
  602. ;definición del tipo de dato ambiente
  603. (define-datatype environment environment?
  604.   (empty-env-record)
  605.   (extended-env-record (syms (list-of symbol?))
  606.                        (vals (list-of scheme-value?))
  607.                        (env environment?))
  608.   (recursively-extended-env-record (proc-names (list-of symbol?))
  609.                                    (idss (list-of (list-of symbol?)))
  610.                                    (bodies (list-of expression?))
  611.                                    (env environment?)))
  612.  
  613. (define scheme-value? (lambda (v) #t))
  614.  
  615. ;empty-env:      -> enviroment
  616. ;función que crea un ambiente vacío
  617. (define empty-env  
  618.   (lambda ()
  619.     (empty-env-record)))       ;llamado al constructor de ambiente vacío
  620.  
  621.  
  622. ;extend-env: <list-of symbols> <list-of numbers> enviroment -> enviroment
  623. ;función que crea un ambiente extendido
  624. (define extend-env
  625.   (lambda (syms vals env)
  626.     (extended-env-record syms vals env)))
  627.  
  628. ;extend-env-recursively: <list-of symbols> <list-of <list-of symbols>> <list-of expressions> environment -> environment
  629. ;función que crea un ambiente extendido para procedimientos recursivos
  630. (define extend-env-recursively
  631.   (lambda (proc-names idss bodies old-env)
  632.     (recursively-extended-env-record
  633.      proc-names idss bodies old-env)))
  634.  
  635. ;función que busca un símbolo en un ambiente
  636. (define apply-env
  637.   (lambda (env sym)
  638.     (cases environment env
  639.       (empty-env-record ()
  640.                         (eopl:error 'empty-env "No binding for ~s" sym))
  641.       (extended-env-record (syms vals old-env)
  642.                            (let ((pos (list-find-position sym syms)))
  643.                              (if (number? pos)
  644.                                  (list-ref vals pos)
  645.                                  (apply-env old-env sym))))
  646.       (recursively-extended-env-record (proc-names idss bodies old-env)
  647.                                        (let ((pos (list-find-position sym proc-names)))
  648.                                          (if (number? pos)
  649.                                              (closure (list-ref idss pos)
  650.                                                       (list-ref bodies pos)
  651.                                                       env)
  652.                                              (apply-env old-env sym)))))))
  653.  
  654. ;***********************************************************************************************************************
  655. ;***********************************************************************************************************************
  656.  
  657.  
  658. ;***********************************************************************************************************************
  659. ;********************************************  Ambientes de tipos  *****************************************************
  660. ;***********************************************************************************************************************
  661.  
  662. (define-datatype type-environment type-environment?
  663.   (empty-tenv-record)
  664.   (extended-tenv-record
  665.     (syms (list-of symbol?))
  666.     (vals (list-of type?))
  667.     (tenv type-environment?)))
  668.  
  669. (define empty-tenv empty-tenv-record)
  670. (define extend-tenv extended-tenv-record)
  671.  
  672. (define apply-tenv
  673.   (lambda (tenv sym)
  674.     (cases type-environment tenv
  675.       (empty-tenv-record ()
  676.         (eopl:error 'apply-tenv "Unbound variable ~s" sym))
  677.       (extended-tenv-record (syms vals env)
  678.         (let ((pos (list-find-position sym syms)))
  679.           (if (number? pos)
  680.             (list-ref vals pos)
  681.             (apply-tenv env sym)))))))
  682.  
  683. ;***********************************************************************************************************************
  684. ;***********************************************************************************************************************
  685.  
  686. ;***********************************************************************************************************************
  687. ;****************************************************  Tipos  **********************************************************
  688. ;***********************************************************************************************************************
  689.  
  690. (define int-type
  691.   (atomic-type 'int))
  692. (define bool-type
  693.   (atomic-type 'bool))
  694.  
  695. ; expand-type-expression: <type-exp> -> <type>
  696. ; determina el tipo denotado por cada expresión de tipo
  697. (define expand-type-expression
  698.   (lambda (texp)
  699.     (cases type-exp texp
  700.       (int-type-exp () int-type)
  701.       (bool-type-exp () bool-type)
  702.       (proc-type-exp (arg-texps result-texp)
  703.                      (proc-type
  704.                       (expand-type-expressions arg-texps)
  705.                       (expand-type-expression result-texp))))))
  706.  
  707. ;mapea la función expand-type-expression a todos los elementos de la lista texps
  708. (define expand-type-expressions
  709.   (lambda (texps)
  710.     (map expand-type-expression texps)))
  711.  
  712.  
  713. ;fresh-tvar: -> type
  714. ;crea un nuevo tipo de variable de tipo
  715. (define fresh-tvar
  716.   (let ((serial-number 0))
  717.     (lambda ()
  718.       (set! serial-number (+ 1 serial-number))
  719.       (tvar-type serial-number (vector '())))))
  720.  
  721. ;tvar-non-empty?: type value -> bool
  722. ;determina si un tipo de variable de tipo está vacío
  723. (define tvar-non-empty?
  724.   (lambda (ty)
  725.     (not (null? (vector-ref (tvar-type->container ty) 0)))))
  726.  
  727. ;mapea la función expand-optional-type-expression a todos los elementos de la lista otexps
  728. (define expand-optional-type-expressions
  729.   (lambda (otexps tenv)
  730.     (map
  731.       (lambda (otexp)
  732.         (expand-optional-type-expression otexp tenv))
  733.       otexps)))
  734.  
  735. ; expand-optional-type-expression: <type-optional-exp> -> <type>
  736. ; determina el tipo denotado por cada expresión de tipo opcional
  737. (define expand-optional-type-expression
  738.   (lambda (otexp tenv)
  739.     (cases optional-type-exp otexp
  740.       (no-type-exp () (fresh-tvar))
  741.       (a-type-exp (texp) (expand-type-expression texp)))))
  742.  
  743.  
  744. ;Selectores y extractores para el tipo abstracto tipo
  745.  
  746. ;tvar->contents: type -> value
  747. ;obtiene el valor almacenado en un tipo de variable de tipo
  748. (define tvar->contents
  749.   (lambda (ty)
  750.     (vector-ref (tvar-type->container ty) 0)))
  751.  
  752. ;tvar-set-contents!: type value -> 0
  753. ;modifica el valor almacenado en un tipo de variable de tipo
  754. (define tvar-set-contents!
  755.   (lambda (ty val)
  756.     (vector-set! (tvar-type->container ty) 0 val)))
  757.  
  758. ;atomic-type?: type -> bool
  759. ; determina si el argumento corresponde a un tipo atómico
  760. (define atomic-type?
  761.   (lambda (ty)
  762.     (cases type ty
  763.       (atomic-type (name) #t)
  764.       (else #f))))
  765.  
  766. ;proc-type?: type -> bool
  767. ; determina si el argumento corresponde a un tipo procedimiento
  768. (define proc-type?
  769.   (lambda (ty)
  770.     (cases type ty
  771.       (proc-type (arg-types result-type) #t)
  772.       (else #f))))
  773.  
  774. ;tvar-type?: type -> bool
  775. ; determina si el argumento corresponde a un tipo de variable de tipo
  776. (define tvar-type?
  777.   (lambda (ty)
  778.     (cases type ty
  779.       (tvar-type (sn cont) #t)
  780.       (else #f))))
  781.  
  782. ;atomic-type->name: type -> symbol
  783. ; retorna el nombre asociado con un tipo atómico
  784. (define atomic-type->name
  785.   (lambda (ty)
  786.     (cases type ty
  787.       (atomic-type (name) name)
  788.       (else (eopl:error 'atomic-type->name
  789.               "Not an atomic type: ~s" ty)))))
  790.  
  791. ;proc-type->arg-types: type -> (list-of type)
  792. ; retorna la lista de los tipos de los argumentos en un tipo procedimiento
  793. (define proc-type->arg-types
  794.   (lambda (ty)
  795.     (cases type ty
  796.       (proc-type (arg-types result-type) arg-types)
  797.       (else (eopl:error 'proc-type->arg-types
  798.               "Not a proc type: ~s" ty)))))
  799.  
  800. ;proc-type->result-type: type -> type
  801. ; retorna el tipo del resultado en un tipo procedimiento
  802. (define proc-type->result-type
  803.   (lambda (ty)
  804.     (cases type ty
  805.       (proc-type (arg-types result-type) result-type)
  806.       (else (eopl:error 'proc-type->arg-types
  807.               "Not a proc type: ~s" ty)))))
  808.  
  809. ;tvar-type->serial-number: type -> integer
  810. ; retorna el número serial asociado a un tipo de variable de tipo
  811. (define tvar-type->serial-number
  812.   (lambda (ty)
  813.     (cases type ty
  814.       (tvar-type (sn c) sn)
  815.       (else (eopl:error 'tvar-type->serial-number
  816.               "Not a tvar-type: ~s" ty)))))
  817.  
  818. ;tvar-type->container: type -> vector
  819. ; retorna el contenedor asociado a un tipo de variable de tipo
  820. (define tvar-type->container
  821.   (lambda (ty)
  822.     (cases type ty
  823.       (tvar-type (sn vec) vec)
  824.       (else (eopl:error 'tvar-type->container
  825.               "Not a tvar-type: ~s" ty)))))
  826.  
  827.  
  828.  
  829.  
  830. ;***********************************************************************************************************************
  831. ;***********************************************************************************************************************
  832.  
  833.  
  834.  
  835. ;***********************************************************************************************************************
  836. ;************************************************    Funciones Auxiliares    ̈*******************************************
  837. ;***********************************************************************************************************************
  838.  
  839. ; funciones auxiliares para encontrar la posición de un símbolo
  840. ; en la lista de símbolos de unambiente
  841.  
  842. (define list-find-position
  843.   (lambda (sym los)
  844.     (list-index (lambda (sym1) (eqv? sym1 sym)) los)))
  845.  
  846. (define list-index
  847.   (lambda (pred ls)
  848.     (cond
  849.       ((null? ls) #f)
  850.       ((pred (car ls)) 0)
  851.       (else (let ((list-index-r (list-index pred (cdr ls))))
  852.               (if (number? list-index-r)
  853.                 (+ list-index-r 1)
  854.                 #f))))))
  855.  
  856. ;***********************************************************************************************************************
  857. ;***********************************************************************************************************************
  858.  
  859.  
  860. ;***********************************************************************************************************************
  861. ;***************************************************    Pruebas    *****************************************************
  862. ;***********************************************************************************************************************
  863.  
  864. (show-the-datatypes)
  865. just-scan
  866. scan&parse
  867. (just-scan "add1(x)")
  868. (just-scan "add1(   x   )%cccc")
  869. (just-scan "add1(  +(5, x)   )%cccc")
  870. (just-scan "add1(  +(5, %ccccc x) ")
  871. (scan&parse "add1(x)")
  872. (scan&parse "add1(   x   )%cccc")
  873. (scan&parse "add1(  +(5, x)   )%cccc")
  874. (scan&parse "add1(  +(5, %cccc
  875. x)) ")
  876. (scan&parse "if -(x,4) then +(y,11) else *(y,10)")
  877. (scan&parse "let
  878. x = -(y,1)
  879. in
  880. let
  881. x = +(x,2)
  882. in
  883. add1(x)")
  884.  
  885.  
  886. (define caso1 (primapp-exp (incr-prim) (list (lit-exp 5))))
  887. (define exp-numero (lit-exp 8))
  888. (define exp-ident (var-exp 'c))
  889. (define exp-app (primapp-exp (add-prim) (list exp-numero exp-ident)))
  890. (define programa (a-program exp-app))
  891. (define una-expresion-dificil (primapp-exp (mult-prim)
  892.                                            (list (primapp-exp (incr-prim)
  893.                                                               (list (var-exp 'v)
  894.                                                                     (var-exp 'y)))
  895.                                                  (var-exp 'x)
  896.                                                  (lit-exp 200))))
  897. (define un-programa-dificil
  898.     (a-program una-expresion-dificil))
  899. (define contador (let ((x 0)) (lambda() (begin (set! x (+ x 1)) x))) )
  900. (contador)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement