Advertisement
Guest User

Untitled

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