Advertisement
Guest User

Untitled

a guest
Feb 27th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 9.22 KB | None | 0 0
  1. #lang eopl
  2.  
  3. ;******************************************************************************************
  4. ;;;;; Interpretador para lenguaje con condicionales, ligadura local y procedimientos
  5.  
  6. ;; La definición BNF para las expresiones del lenguaje:
  7. ;;
  8. ;;  <program>       ::= <expression>
  9. ;;                      <a-program (exp)>
  10. ;;  <expression>    ::= <number>
  11. ;;                      <lit-exp (datum)>
  12. ;;                  ::= <identifier>
  13. ;;                      <var-exp (id)>
  14. ;;                  ::= <primitive> ({<expression>}*(,))
  15. ;;                      <primapp-exp (prim rands)>
  16. ;;                  ::= if <expresion> then <expresion> else <expression>
  17. ;;                      <if-exp (exp1 exp2 exp23)>
  18. ;;                  ::= let {identifier = <expression>}* in <expression>
  19. ;;                      <let-exp (ids rands body)>
  20. ;;                  ::= proc({<identificador>}*(,)) <expression>
  21. ;;                      <proc-exp (ids body)>
  22. ;;                  ::= (<expression> {<expression>}*)
  23. ;;                      <app-exp proc rands>
  24. ;;  <primitive>     ::= + | - | * | add1 | sub1
  25.  
  26. ;******************************************************************************************
  27.  
  28. ;******************************************************************************************
  29. ;Especificación Léxica
  30.  
  31. (define scanner-spec-simple-interpreter
  32. '((white-sp
  33.    (whitespace) skip)
  34.   (comment
  35.    ("%" (arbno (not #\newline))) skip)
  36.   (identifier
  37.    (letter (arbno (or letter digit "?"))) symbol)
  38.   (number
  39.    (digit (arbno digit)) number)
  40.   (number
  41.    ("-" digit (arbno digit)) number)))
  42.  
  43. ;Especificación Sintáctica (gramática)
  44.  
  45. (define grammar-simple-interpreter
  46.   '((program (expression) a-program)
  47.     (expression (number) lit-exp)
  48.     (expression (identifier) var-exp)
  49.     (expression
  50.      (primitive "(" (separated-list expression ",")")")
  51.      primapp-exp)
  52.     (expression ("if" expression "then" expression "else" expression)
  53.                 if-exp)
  54.     (expression ("let" (arbno identifier "=" expression) "in" expression)
  55.                 let-exp)
  56.    
  57.     ; características adicionales
  58.     (expression ("proc" "(" (separated-list identifier ",") ")" expression)
  59.                 proc-exp)
  60.     (expression ( "(" expression (arbno expression) ")")
  61.                 app-exp)
  62.     ;;;;;;
  63.  
  64.     (primitive ("+") add-prim)
  65.     (primitive ("-") substract-prim)
  66.     (primitive ("*") mult-prim)
  67.     (primitive ("add1") incr-prim)
  68.     (primitive ("sub1") decr-prim)))
  69.  
  70.  
  71. ;Tipos de datos para la sintaxis abstracta de la gramática
  72.  
  73. ;Construidos manualmente:
  74.  
  75. ;(define-datatype program program?
  76. ;  (a-program
  77. ;   (exp expression?)))
  78. ;
  79. ;(define-datatype expression expression?
  80. ;  (lit-exp
  81. ;   (datum number?))
  82. ;  (var-exp
  83. ;   (id symbol?))
  84. ;  (primapp-exp
  85. ;   (prim primitive?)
  86. ;   (rands (list-of expression?)))
  87. ;  (if-exp
  88. ;   (test-exp expression?)
  89. ;   (true-exp expression?)
  90. ;   (false-exp expression?))
  91. ;  (let-exp
  92. ;   (ids (list-of symbol?))
  93. ;   (rans (list-of expression?))
  94. ;   (body expression?))
  95. ;  (proc-exp
  96. ;   (ids (list-of symbol?))
  97. ;   (body expression?))
  98. ;  (app-exp
  99. ;   (proc expression?)
  100. ;   (args (list-of expression?))))
  101.  
  102. ;
  103. ;(define-datatype primitive primitive?
  104. ;  (add-prim)
  105. ;  (substract-prim)
  106. ;  (mult-prim)
  107. ;  (incr-prim)
  108. ;  (decr-prim))
  109.  
  110. ;Construidos automáticamente:
  111.  
  112. (sllgen:make-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)
  113.  
  114. (define show-the-datatypes
  115.   (lambda () (sllgen:list-define-datatypes scanner-spec-simple-interpreter grammar-simple-interpreter)))
  116.  
  117. ;*******************************************************************************************
  118. ;Parser, Scanner, Interfaz
  119.  
  120. ;El FrontEnd (Análisis léxico (scanner) y sintáctico (parser) integrados)
  121.  
  122. (define scan&parse
  123.   (sllgen:make-string-parser scanner-spec-simple-interpreter grammar-simple-interpreter))
  124.  
  125. ;El Analizador Léxico (Scanner)
  126.  
  127. (define just-scan
  128.   (sllgen:make-string-scanner scanner-spec-simple-interpreter grammar-simple-interpreter))
  129.  
  130. ;El Interpretador (FrontEnd + Evaluación + señal para lectura )
  131.  
  132. (define interpretador
  133.   (sllgen:make-rep-loop  "--> "
  134.     (lambda (pgm) (eval-program  pgm))
  135.     (sllgen:make-stream-parser
  136.       scanner-spec-simple-interpreter
  137.       grammar-simple-interpreter)))
  138.  
  139. ;*******************************************************************************************
  140. ;El Interprete
  141.  
  142. ;eval-program: <programa> -> numero
  143. ; función que evalúa un programa teniendo en cuenta un ambiente dado (se inicializa dentro del programa)
  144.  
  145. (define eval-program
  146.   (lambda (pgm)
  147.     (cases program pgm
  148.       (a-program (body)
  149.                  (eval-expression body (init-env))))))
  150.  
  151. ; Ambiente inicial
  152. ;(define init-env
  153. ;  (lambda ()
  154. ;    (extend-env
  155. ;     '(x y z)
  156. ;     '(4 2 5)
  157. ;     (empty-env))))
  158. (define init-env
  159.   (lambda ()
  160.     (extend-env
  161.      '(x y)
  162.      (list 4 2) (empty-env))))
  163.  
  164. ;eval-expression: <expression> <enviroment> -> numero
  165. ; evalua la expresión en el ambiente de entrada
  166. (define eval-expression
  167.   (lambda (exp env)
  168.     (cases expression exp
  169.       (lit-exp (datum) datum)
  170.       (var-exp (id) (apply-env env id))
  171.       (primapp-exp (prim rands)
  172.                    (let ((args (eval-rands rands env)))
  173.                      (apply-primitive prim args)))
  174.       (if-exp (test-exp true-exp false-exp)
  175.               (if (true-value? (eval-expression test-exp env))
  176.                   (eval-expression true-exp env)
  177.                   (eval-expression false-exp env)))
  178.       (let-exp (ids rands body)
  179.                (let ((args (eval-rands rands env)))
  180.                  (eval-expression body
  181.                                   (extend-env ids args env))))
  182.       (proc-exp (ids body)
  183.                 (closure ids body env))
  184.       (app-exp (rator rands)
  185.                (let ((proc (eval-expression rator env))
  186.                      (args (eval-rands rands env)))
  187.                  (if (procval? proc)
  188.                      (apply-procedure proc args)
  189.                      (eopl:error 'eval-expression
  190.                                  "Attempt to apply non-procedure ~s" proc)))))))
  191.  
  192. ; funciones auxiliares para aplicar eval-expression a cada elemento de una
  193. ; lista de operandos (expresiones)
  194. (define eval-rands
  195.   (lambda (rands env)
  196.     (map (lambda (x) (eval-rand x env)) rands)))
  197.  
  198. (define eval-rand
  199.   (lambda (rand env)
  200.     (eval-expression rand env)))
  201.  
  202. ;apply-primitive: <primitiva> <list-of-expression> -> numero
  203. (define apply-primitive
  204.   (lambda (prim args)
  205.     (cases primitive prim
  206.       (add-prim () (+ (car args) (cadr args)))
  207.       (substract-prim () (- (car args) (cadr args)))
  208.       (mult-prim () (* (car args) (cadr args)))
  209.       (incr-prim () (+ (car args) 1))
  210.       (decr-prim () (- (car args) 1)))))
  211.  
  212. ;true-value?: determina si un valor dado corresponde a un valor booleano falso o verdadero
  213. (define true-value?
  214.   (lambda (x)
  215.     (not (zero? x))))
  216.  
  217. ;*******************************************************************************************
  218. ;Procedimientos
  219. (define-datatype procval procval?
  220.   (closure
  221.    (ids (list-of symbol?))
  222.    (body expression?)
  223.    (env environment?)))
  224.  
  225. ;apply-procedure: evalua el cuerpo de un procedimientos en el ambiente extendido correspondiente
  226. (define apply-procedure
  227.   (lambda (proc args)
  228.     (cases procval proc
  229.       (closure (ids body env)
  230.                (eval-expression body (extend-env ids args env))))))
  231.  
  232. ;*******************************************************************************************
  233. ;Ambientes
  234.  
  235. ;definición del tipo de dato ambiente
  236. (define-datatype environment environment?
  237.   (empty-env-record)
  238.   (extended-env-record (syms (list-of symbol?))
  239.                        (vals (list-of scheme-value?))
  240.                        (env environment?)))
  241.  
  242. (define scheme-value? (lambda (v) #t))
  243.  
  244. ;empty-env:      -> enviroment
  245. ;función que crea un ambiente vacío
  246. (define empty-env  
  247.   (lambda ()
  248.     (empty-env-record)))       ;llamado al constructor de ambiente vacío
  249.  
  250.  
  251. ;extend-env: <list-of symbols> <list-of numbers> enviroment -> enviroment
  252. ;función que crea un ambiente extendido
  253. (define extend-env
  254.   (lambda (syms vals env)
  255.     (extended-env-record syms vals env)))
  256.  
  257. ;función que busca un símbolo en un ambiente
  258. (define apply-env
  259.   (lambda (env sym)
  260.     (cases environment env
  261.       (empty-env-record ()
  262.                         (eopl:error 'apply-env "No binding for ~s" sym))
  263.       (extended-env-record (syms vals env)
  264.                            (let ((pos (list-find-position sym syms)))
  265.                              (if (number? pos)
  266.                                  (list-ref vals pos)
  267.                                  (apply-env env sym)))))))
  268.  
  269.  
  270. ;****************************************************************************************
  271. ;Funciones Auxiliares
  272.  
  273. ; funciones auxiliares para encontrar la posición de un símbolo
  274. ; en la lista de símbolos de unambiente
  275.  
  276. (define list-find-position
  277.   (lambda (sym los)
  278.     (list-index (lambda (sym1) (eqv? sym1 sym)) los)))
  279.  
  280. (define list-index
  281.   (lambda (pred ls)
  282.     (cond
  283.       ((null? ls) #f)
  284.       ((pred (car ls)) 0)
  285.       (else (let ((list-index-r (list-index pred (cdr ls))))
  286.               (if (number? list-index-r)
  287.                 (+ list-index-r 1)
  288.                 #f))))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement