Académique Documents
Professionnel Documents
Culture Documents
;
***********************************************************************************
*******
;;;;; Interpretador para lenguaje con condicionales, ligadura local, procedimientos
y
;;;;; procedimientos recursivos
;
***********************************************************************************
*******
;
***********************************************************************************
*******
;Especificación Léxica
(define scanner-spec-simple-interpreter
'((white-sp
(whitespace) skip)
(comment
("%" (arbno (not #\newline))) skip)
(identifier
(letter (arbno (or letter digit "?"))) symbol)
(number
(digit (arbno digit)) number)
(number
("-" digit (arbno digit)) number)))
(define grammar-simple-interpreter
'((program (expression) a-program)
(expression (number) lit-exp)
(expression (identifier) var-exp)
(expression
(primitive "(" (separated-list expression ",")")")
primapp-exp)
(expression ("if" expression "then" expression
(arbno "elseif" expression "then" expression) "else" expression)
if-exp)
(expression ("let" (arbno identifier "=" expression) "in" expression)
let-exp)
(expression ("proc" "(" (arbno identifier) ")" expression)
proc-exp)
(expression ( "(" expression (arbno expression) ")")
app-exp)
; características adicionales
(expression ("letrec" (arbno identifier "(" (separated-list identifier ",") ")"
"=" expression) "in" expression)
letrec-exp)
;;;;;;
;Construidos manualmente:
;
;(define-datatype primitive primitive?
; (add-prim)
; (substract-prim)
; (mult-prim)
; (incr-prim)
; (decr-prim))
;Construidos automáticamente:
(define show-the-datatypes
(lambda () (sllgen:list-define-datatypes scanner-spec-simple-interpreter grammar-
simple-interpreter)))
;
***********************************************************************************
********
;Parser, Scanner, Interfaz
(define scan&parse
(sllgen:make-string-parser scanner-spec-simple-interpreter grammar-simple-
interpreter))
(define just-scan
(sllgen:make-string-scanner scanner-spec-simple-interpreter grammar-simple-
interpreter))
(define interpretador
(sllgen:make-rep-loop "--> "
(lambda (pgm) (eval-program pgm))
(sllgen:make-stream-parser
scanner-spec-simple-interpreter
grammar-simple-interpreter)))
;
***********************************************************************************
********
;El Interprete
(define eval-program
(lambda (pgm)
(cases program pgm
(a-program (body)
(eval-expression body (init-env))))))
; Ambiente inicial
;(define init-env
; (lambda ()
; (extend-env
; '(x y z)
; '(4 2 5)
; (empty-env))))
(define init-env
(lambda ()
(extend-env
'(x y z f)
(list 4 2 5 (closure '(y) (primapp-exp (mult-prim) (cons (var-exp 'y) (cons
(primapp-exp (decr-prim) (cons (var-exp 'y) '())) '())))
(empty-env)))
(empty-env))))
;modificar el if-exp para que reciba el arbno para que funcione como elseif
;el if-exp ahora debe recibir 5 args
;invoco la funcion eif-exp y llamo la lista que va a concatenear los
resultados parciales
(if-exp (test-exp true-exp test-exps true-exps false-exp)
(eif-exp (append (list test-exp) test-exps)
(append (list true-exp) true-exps) false-exp env))
(define eval-rand
(lambda (rand env)
(eval-expression rand env)))
;
***********************************************************************************
********
;Procedimientos
(define-datatype procval procval?
(closure
(ids (list-of symbol?))
(body expression?)
(env environment?)))
;
***********************************************************************************
********
;Ambientes
;
***********************************************************************************
*****
;Funciones Auxiliares
(define list-find-position
(lambda (sym los)
(list-index (lambda (sym1) (eqv? sym1 sym)) los)))
(define list-index
(lambda (pred ls)
(cond
((null? ls) #f)
((pred (car ls)) 0)
(else (let ((list-index-r (list-index pred (cdr ls))))
(if (number? list-index-r)
(+ list-index-r 1)
#f))))))
;
***********************************************************************************
*******
;Pruebas
(show-the-datatypes)
just-scan
scan&parse
(just-scan "add1(x)")
(just-scan "add1( x )%cccc")
(just-scan "add1( +(5, x) )%cccc")
(just-scan "add1( +(5, %ccccc x) ")
(scan&parse "add1(x)")
(scan&parse "add1( x )%cccc")
(scan&parse "add1( +(5, x) )%cccc")
(scan&parse "add1( +(5, %cccc
x)) ")
(scan&parse "if -(x,4) then +(y,11) else *(y,10)")
(scan&parse "let
x = -(y,1)
in
let
x = +(x,2)
in
add1(x)")
(lit-exp 200))))
(define un-programa-dificil
(a-program una-expresion-dificil))
(interpretador)