Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 35.07 KB | None | 0 0
  1. #lang racket
  2. (require eopl)
  3. (require racket/string); string-trim
  4. #|--------------------INTEGRANTES---------------------------
  5.  Diana Sofía Navas   1629571
  6.  Luis David Restrepo 1427086
  7.  Walter Santacruz    1630645
  8.  Víctor Vargas       1842274
  9.  ----------------------------------------------------------|#
  10.  
  11. (define lexical-spec
  12. '((white-sp (whitespace) skip)
  13.   (comment ("#" (arbno (not #\newline))) skip)
  14.   (identifier ((arbno "@") letter (arbno (or letter digit "_" "?" "=" ))) symbol)
  15.   (number (digit (arbno digit)) number)
  16.   (number ("-" digit (arbno digit)) number)
  17.   (text ("\"" (or letter whitespace)
  18.               (arbno (or letter digit whitespace ":" "?" "=" "'")) "\"") string)
  19.   )
  20. )
  21.  
  22. (define grammar-spec
  23.   '( ;;Representa un programa de ruby    
  24.      (ruby-program ("ruby" exp-batch "end") a-program)
  25.      ;; Parte 2: Ruby con objetos
  26.      ;; cambiar a: (ruby-program ("ruby" (arbno class-decl) exp-batch "end") a-program)
  27.      
  28.      ;;Exp-batch: Representa una cerradura de expresiones
  29.      (exp-batch (expression (arbno expression)) a-batch)
  30.  
  31.      ;;Expresión:
  32.      (expression (simple-exp) a-simple-exp)
  33.      ;Declare-exp: al menos uno o más identificadores (deben inicializarse en 'nil)
  34.      (expression ("declare" identifier (arbno "," identifier) ";") declare-exp)
  35.      ;Puts-exp: al menos un valor compuesto para imprimir
  36.      (expression ("puts" (separated-list comp-value ",") ";") puts-exp)
  37.  
  38.      (expression ("if" comp-value (arbno "then") exp-batch
  39.                        (arbno "elsif" comp-value (arbno "then") exp-batch)
  40.                        (arbno "else" exp-batch) "end") if-exp)
  41.      
  42.      (expression ("unless" comp-value (arbno "then")
  43.                            exp-batch
  44.                            (arbno "else" exp-batch) "end") unless-exp)
  45.  
  46.      (expression ("while" comp-value (arbno "do") exp-batch "end") while-exp)
  47.      (expression ("until" comp-value (arbno "do") exp-batch "end") until-exp)
  48.  
  49.      (expression ("for" identifier "in" comp-value (arbno "do") exp-batch "end") for-exp)
  50.  
  51.      (expression ("def" identifier "(" (separated-list identifier ",") ")"
  52.                   exp-batch                  
  53.                   "end") function-exp)
  54.      (expression ("return" comp-value ";") return-exp)
  55.  
  56.      ;;Expresión simple
  57.      (simple-exp (simple-value complement ";") val-exp)
  58.      
  59.      ;;Complemento
  60.      (complement ("=" comp-value calls) assign)
  61.      (complement (assign-op comp-value calls) assign-and)
  62.      (complement (calls) comp-calls)
  63.  
  64.      ;;Calls
  65.      ;; 0 o muchas llamadas
  66.      (calls ((arbno call)) some-calls)
  67.  
  68.      ;;Call
  69.      (call (arguments) arguments-call)
  70.      ;; (call ("." identifier arguments) a-method-call) ;; Parte 2: Ruby con Objetos
  71.  
  72.      ;;Argumentos
  73.      ;; llamar una función puede tener 0 argumentos o muchos
  74.      (arguments ("(" (separated-list comp-value ",") ")") some-arguments)
  75.      ;; almenos 1 argumento para llamar acceder a un elemento en un arreglo
  76.      ;; máximo 2, ejemplo: a=[1,2,3]; a[1] #output 2; a[1,2] #output [2,3];
  77.      ;;                    a[1,2,3] #output Error
  78.      (arguments ("[" comp-value (arbno "," comp-value) "]") arr-arguments)
  79.  
  80.      ;;Valores compuestos
  81.      (comp-value (value) a-value)
  82.      (comp-value (un-op comp-value) unop-value)
  83.      
  84.      (value (simple-value) a-s-val)
  85.      (value ("(" comp-value val-compl ")") compl-val)
  86.  
  87.      ;;Complemento para valores
  88.      ;; llamadas a un valor:
  89.      ;; Ejemplo: sirve para ("hola"+(mundo())) donde mundo() retorna "mundo"
  90.      (val-compl (calls) val-call)
  91.      ;; operacion inorden con otro valor
  92.      (val-compl (bin-op comp-value) binop-val)
  93.  
  94.      ;; Valores simples
  95.      (simple-value (identifier) id-val)
  96.      (simple-value (number) int-val)
  97.      (simple-value (text) str-val)
  98.      (simple-value ("true") true-val)
  99.      (simple-value ("false") false-val)
  100.      (simple-value ("nil") nil-val)
  101.      ;; arreglo con 0 o muchos valores
  102.      (simple-value ("["(separated-list comp-value ",")"]") arr-val)
  103.      
  104.      ;;Operacion Inorden
  105.      (bin-op ("+") add)
  106.      (bin-op ("-") diff)
  107.      (bin-op ("*") mult)
  108.      (bin-op ("/") div)
  109.      (bin-op ("%") mod)
  110.      (bin-op ("**") pow)
  111.      (bin-op (">") great)
  112.      (bin-op (">=") great-eq)
  113.      (bin-op ("<") less)
  114.      (bin-op ("<=") less-eq)
  115.      (bin-op ("==") equal)
  116.      (bin-op ("!=") not-equal)
  117.      (bin-op ("and") and-op)
  118.      (bin-op ("&&") and-op)
  119.      (bin-op ("or") or-op)
  120.      (bin-op ("||") or-op)
  121.      ;;Rangos:
  122.      ;; Solo admite 2 argumentos, no se puede operar más de 1 vez
  123.      ;;Inclusivo: va hasta el limite superior
  124.      (bin-op ("..") in-range)
  125.      ;;Exclusivo: va hasta un step antes del limite superior
  126.      (bin-op ("...") ex-range)
  127.      ;; Ejemplo: (1..5) => (1 2 3 4 5)
  128.      ;; Ejemplo: (1...5) => (1 2 3 4)
  129.      ;; Ejemplo: ((1..5) .. 6) => Error
  130.      (bin-op ("step") st-range)
  131.      ;; Ejemplo: ((1..5) step 2) => (1 3 5)
  132.      ;; Ejemplo: ((1..5) step -1) => Error
  133.      ;; Ejemplo: ((-1..-5) step -2) => (-1 -3 -5)
  134.      ;; Ejemplo: ((1..-5) step 2) => Error
  135.      
  136.      ;;Operación asignación
  137.      (assign-op ("+=") add-eq)
  138.      (assign-op ("-=") diff-eq)
  139.      (assign-op ("*=") mult-eq)
  140.      (assign-op ("/=") div-eq)
  141.      (assign-op ("**=") pow-eq)
  142.  
  143.      ;;Operación unitaria
  144.      (un-op ("not") not-op)
  145.      (un-op ("!") not-op)
  146.  
  147.      ;;##############################################
  148.      ;; Parte 2: Ruby con objetos
  149.      ;(class-decl ("class" identifier
  150.      ;                     (arbno "<" identifier)
  151.      ;                     "attr" (separated-list ":" identifier ",") ";"
  152.      ;                     (arbno method-decl) "end") a-class-decl)
  153.  
  154.      ;(method-decl ("def" identifier "(" (separated-list identifier ",") ")"
  155.      ;             exp-batch                  
  156.      ;             "end") a-method-decl)
  157.  
  158.   )
  159. )
  160.  
  161. ;Construidos automáticamente:
  162. (sllgen:make-define-datatypes lexical-spec grammar-spec)
  163.  
  164. (define show-the-datatypes
  165.   (lambda () (sllgen:list-define-datatypes lexical-spec grammar-spec)))
  166.  
  167. ;*******************************************************************************************
  168. ;Parser, Scanner, Interfaz
  169.  
  170. ;El FrontEnd (Análisis léxico (scanner) y sintáctico (parser) integrados)
  171.  
  172. (define scan&parse
  173.   (sllgen:make-string-parser lexical-spec grammar-spec))
  174.  
  175. ;El Analizador Léxico (Scanner)
  176.  
  177. (define scan
  178.   (sllgen:make-string-scanner lexical-spec grammar-spec))
  179.  
  180. ;El Interpretador (FrontEnd + Evaluación + señal para lectura )
  181.  
  182. (define interpretador
  183.   (sllgen:make-rep-loop  "--> "
  184.     (lambda (pgm) (eval-program pgm))
  185.     (sllgen:make-stream-parser
  186.       lexical-spec
  187.       grammar-spec)))
  188.  
  189. ;*******************************************************************************************
  190. ;*******************************************************************************************
  191. ;Procedimientos
  192. (define-datatype procval procval?
  193.   (closure
  194.    (ids (list-of symbol?))
  195.    (body exp-batch?)
  196.    (env environment?)
  197.    ))
  198.  
  199. ;apply-procedure: evalua el cuerpo de un procedimientos en el ambiente extendido correspondiente
  200. (define apply-procedure
  201.   (lambda (proc args env)
  202.     (cases procval proc
  203.       (closure (ids body env)
  204.                (eval-proc-batch body (extend-env ids args env))))))
  205.  
  206. ;*******************************************************************************************
  207.  
  208. (define (eval-program pgm)
  209.   (cases ruby-program pgm
  210.     (a-program (a-batch) (eval-exp-batch a-batch (empty-env)))
  211.     )
  212.   )
  213.  
  214. (define is-last-exp-a-func
  215.   (lambda (exps)  
  216.     (if (empty? exps)
  217.         #f
  218.         (if (empty? (cdr exps))
  219.             (if (is-function-exp? (car exps))
  220.                 (get-function-name (car exps))
  221.                 #f)            
  222.             (is-last-exp-a-func (cdr exps))))))
  223.  
  224. (define (get-function-name exp)
  225.   (cases expression exp
  226.     (function-exp (name ids batch) name)
  227.     (else "")))
  228.  
  229. (define (eval-exp-batch batch env)
  230.   (cases exp-batch batch
  231.     (a-batch (exp exps) (let ((result (eval-expressions (cons exp exps) env)))
  232.                           (if (or (environment? result) (void? result))
  233.                               (let ((is-func (is-last-exp-a-func (cons exp exps))))
  234.                                 (if (eqv? is-func #f)
  235.                                     (begin (display "=> ") 'nil)
  236.                                     is-func))
  237.                               result)))))
  238.  
  239. (define (eval-proc-batch batch env)
  240.   (cases exp-batch batch
  241.     (a-batch (exp exps)        
  242.               (eval-expressions (cons exp exps) env))))
  243.  
  244. (define (is-return-exp? exp)
  245.   (cases expression exp
  246.     (return-exp (comp-value) #t)
  247.     (else #f)))
  248.  
  249. (define (is-function-exp? exp)
  250.   (cases expression exp
  251.     (function-exp (name ids batch) #t)
  252.     (else #f)))
  253.  
  254. (define (eval-expressions exps env)
  255.  (if (or (empty? (cdr exps)) (is-return-exp? (car exps)))                
  256.      (eval-expression (car exps) env)    
  257.      (let ((next-env (eval-expression (car exps) env)))
  258.        (if (environment? next-env) (eval-expressions (cdr exps) next-env)
  259.            (eval-expressions (cdr exps) env)))))
  260.  
  261. (define (eval-expression exp env)
  262.   (cases expression exp
  263.     (a-simple-exp (simple-exp) (eval-simple-exp simple-exp env))
  264.  
  265.     (declare-exp (id ids) (extend-env (cons id ids) (map (lambda (x) "nil") (cons id ids)) env))
  266.    
  267.     (puts-exp (vals)
  268.               (for-each (lambda (arg)
  269.                           (if (check-apply-env env arg) (pretty-display (apply-env env arg))
  270.                           (pretty-display arg)))
  271.                         (map (lambda(x) (eval-comp-value x env)) vals)))
  272.  
  273.     (if-exp (if-comp if-batch elsif-comps elsif-batchs else-batch) (if (eqv? "true" (eval-comp-value if-comp env))
  274.                                                                        (eval-exp-batch if-batch env)
  275.                                                                        (if (or (empty? elsif-comps) (empty? elsif-batchs))
  276.                                                                            (if (empty? else-batch)
  277.                                                                                (void)
  278.                                                                                (eval-exp-batch (car else-batch) env))
  279.                                                                            (eval-expression (if-exp (car elsif-comps) (car elsif-batchs) (cdr elsif-comps) (cdr elsif-batchs) else-batch) env))))
  280.  
  281.     (unless-exp (comp-bool batch else-batch) (if (eqv? "false" (eval-comp-value comp-bool env))
  282.                                                  (eval-exp-batch batch env)
  283.                                                  (if (empty? else-batch)
  284.                                                      (void)
  285.                                                      (eval-exp-batch (car else-batch) env))))
  286.  
  287.     (function-exp (name ids batch) (a-recursive-env name ids batch env))
  288.      
  289.     (while-exp (comp-bool batch) (if (eqv? "true" (eval-comp-value comp-bool env))
  290.                                      (let ((new-env(eval-exp-batch batch env)))
  291.                                        (if (environment? new-env)
  292.                                            (eval-expression (while-exp comp-bool batch) new-env)
  293.                                            (eval-expression (while-exp comp-bool batch) env)))
  294.                                      (void)))
  295.  
  296.     (until-exp (comp-bool batch) (if (eqv? "false" (eval-comp-value comp-bool env))
  297.                                      (let ((new-env(eval-exp-batch batch env)))
  298.                                        (if (environment? new-env)
  299.                                            (eval-expression (until-exp comp-bool batch) new-env)
  300.                                            (eval-expression (until-exp comp-bool batch) env)))
  301.                                      (void)))  
  302.  
  303.     (return-exp (comp-value) (eval-comp-value comp-value env))
  304.  
  305.     (for-exp (id comp-value exp-batch)
  306.              (for-each (lambda (x)
  307.                          (eval-exp-batch exp-batch (extend-env (list id) (list x) env)))
  308.                        (eval-comp-value comp-value env)))
  309.    
  310.     (else "TO DO")))
  311.  
  312. (define (eval-simple-exp s-exp env)
  313.   (cases simple-exp s-exp
  314.     (val-exp (simple-value complement) (apply-complement simple-value complement env))))
  315.  
  316. (define (eval-calls-args cls left-value env)
  317.   (cases calls cls
  318.     (some-calls (calls) (if (empty? calls)
  319.                             '()
  320.                             (cons (eval-call (car calls) left-value env)
  321.                                   (eval-calls-args (some-calls (cdr calls)) left-value env))))))
  322.  
  323. (define eval-calls
  324.   (lambda (cls left-value env)
  325.     (let ((args (eval-calls-args cls left-value env))
  326.           (left-value-evaluated (if (simple-value? left-value)
  327.                                     (apply-env env (eval-simple-value left-value env))
  328.                                     (eval-comp-value left-value env))))      
  329.         (if (empty? args)
  330.           (if (symbol? left-value-evaluated)
  331.               (apply-env env left-value-evaluated)
  332.               left-value-evaluated)
  333.           (if (procval? left-value-evaluated)
  334.               (apply-procedure left-value-evaluated (car args) env)
  335.               ;(encontrar left-value-evaluated args))))))
  336.               (display args))))))
  337.  
  338. (define (is-comp-calls-empty cls env)
  339.   (cases calls cls
  340.     (some-calls (cls) (empty? cls))                            
  341.     (else "")))
  342.  
  343. (define (apply-complement s-val compl env)
  344.   (cases complement compl
  345.     (assign (comp-value calls)
  346.             (let ((id (apply-env-ref env (eval-simple-value s-val env))) (val (eval-calls calls comp-value env)))
  347.               (begin                
  348.                 (setref! id val)
  349.                 val)))                    
  350.  
  351.     (assign-and (assign-op comp-value calls)
  352.                 (let ((left-val-ref (apply-env-ref env (eval-simple-value s-val env)))
  353.                       (right-val (eval-calls calls comp-value env)))
  354.                   (let ((result (apply-assign assign-op (deref left-val-ref) right-val)))
  355.                     (begin
  356.                       (setref! left-val-ref result)
  357.                       result))))  
  358.     (comp-calls (calls) (eval-calls calls s-val env))))                                        
  359.  
  360. (define (eval-comp-value c-value env)
  361.   (cases comp-value c-value
  362.     (a-value (value) (eval-value value env))
  363.     (unop-value (un-op comp-value) (eval-un-op (eval-comp-value comp-value env)))))
  364.  
  365. (define eval-un-op
  366.   (lambda (val)
  367.     (cond
  368.       ((eqv? val "true") "false")
  369.       ((eqv? val "false") "true")
  370.       (else (eopl:error 'eval-un-op "Not a bool")))))      
  371.  
  372. (define (eval-value a-value env)
  373.   (cases value a-value
  374.     (a-s-val (simple-value)(if (symbol? (eval-simple-value simple-value env))
  375.                                (apply-env env (eval-simple-value simple-value env))
  376.                                (eval-simple-value simple-value env)))
  377.     (compl-val (comp-value val-compl) (eval-val-compl comp-value val-compl env))))
  378.  
  379. (define (eval-val-compl comp-value v-compl env)
  380.   (cases val-compl v-compl
  381.     (val-call (calls) (eval-calls calls comp-value env))
  382.     (binop-val (bin-op comp-v) (apply-op bin-op (list (eval-comp-value  comp-value env) (eval-comp-value comp-v env))))))
  383.  
  384. (define (eval-call cl s-val env)
  385.   (cases call cl
  386.     (arguments-call (arguments) (eval-args arguments s-val env))
  387.     (else "")))
  388.  
  389. (define (eval-args args s-val env)
  390.   (cases arguments args
  391.     (some-arguments (comp-values) (if (simple-value? s-val)                                    
  392.                                       (let ((proc (apply-env env (eval-simple-value s-val env))))                                        
  393.                                         (if (procval? proc)
  394.                                             (map (lambda (x) (eval-comp-value x env)) comp-values)
  395.                                             (eopl:error 'Error "Can't apply args to ~s" proc)))                                      
  396.                                       (let ((proc (eval-comp-value s-val env)))
  397.                                         (if (procval? proc)
  398.                                             (map (lambda (x) (eval-comp-value x env)) comp-values)
  399.                                             (eopl:error 'Error "Can't apply args to ~s" proc)))))
  400.                          
  401.     (arr-arguments (comp-value comp-values) (map (lambda (x) (eval-comp-value x env)) (cons comp-value comp-values)))))
  402.  
  403. (define (eval-simple-value s-val env)
  404.   (cases simple-value s-val
  405.     (id-val  (identifier)  identifier)
  406.     (int-val (number) number)
  407.     (str-val (text) (string-trim text "\""))
  408.     (true-val  () "true")
  409.     (false-val () "false")
  410.     (nil-val   () "nil")
  411.     (arr-val   (comp-value) (map (lambda (x) (eval-comp-value x env)) comp-value))))
  412.  
  413. (define (apply-op op args)
  414.   (cases bin-op op
  415.      (add ()  (operacion args 'suma))
  416.      (diff () (- (car args) (cadr args)))
  417.      (mult () (operacion args 'mult))
  418.      (div () (/ (car args) (cadr args)))
  419.      (mod () (modulo (car args) (cadr args)))
  420.      (pow ()(expt (car args) (cadr args)))
  421.      (great () (if (> (car args) (cadr args)) "true" "false"))
  422.      (great-eq () (if (>= (car args) (cadr args)) "true" "false"))
  423.      (less () (if (< (car args) (cadr args)) "true" "false"))
  424.      (less-eq () (if (<= (car args) (cadr args)) "true" "false"))
  425.      (equal () (if (equal? (car args) (cadr args)) "true" "false"))
  426.      (not-equal () (if (not(equal? (car args) (cadr args))) "true" "false"))
  427.      (and-op () (if (and (eval-bool (car args)) (eval-bool (cadr args))) "true" "false"))
  428.      (or-op () (if (or (eval-bool (car args)) (eval-bool (cadr args))) "true" "false"))
  429.      (in-range () (rango (car args) (cadr args) 'in))
  430.      (ex-range () (rango (car args) (cadr args) 'ex))
  431.      (st-range () (steps (car args) (cadr args)))))
  432.  
  433. (define eval-bool
  434.   (lambda (val)
  435.     (if (eqv? val "true") #t #f)))
  436.  
  437. (define (apply-assign op arg1 arg2)
  438.   (cases assign-op op
  439.     (add-eq () (+ arg1 arg2))
  440.     (diff-eq () (- arg1 arg2))
  441.     (mult-eq () (* arg1 arg2))
  442.     (div-eq () (/ arg1 arg2))
  443.     (pow-eq () (expt arg1 arg2))))
  444.    
  445. #|Función que opera seguún el tipo de dato que contenga la lista|#
  446. (define (operacion lista sys)
  447.   (cond
  448.     [(equal? lista '()) "Error"]
  449.     #|Si mi lista de args son puras cadenas entonces sé que su suma equivale a concatenar ambos|#
  450.     [(and (string? (car lista)) (string? (cadr lista)) (eq? sys 'suma))
  451.  
  452.      ;---AQUÍ LO QUE HAGO ES LIMPIAR MI CADENA DE ESTO: #\"
  453.      (list->string(eliminar(string->list
  454.      (string-append (car lista) (cadr lista)))))]
  455.     ;---------------------------------------------------
  456. #|Si el simbolo es 'mult tengo que verificar que almenos uno de los elemenos sea un número para saber
  457. cuantas veces repetir mi cadena|#
  458.     [(or
  459.       (and (string? (car lista)) (number? (cadr lista)) (eq? sys 'mult))
  460.       (and (number? (car lista)) (string? (cadr lista)) (eq? sys 'mult)))
  461.  
  462.      ;---AQUÍ LO QUE HAGO ES LIMPIAR MI CADENA DE ESTO: #\"
  463.       (list->string(eliminar(string->list(mul (car lista) (cadr lista)))))]
  464.     ;---------------------------------------------------
  465.    
  466.     #|Si no se cumple que almenos uno sea cadena entonces hay que verificar si ambos son números. Así,
  467. ya se trate de una suma o una multiplicación, los puedo operar de manera común y corriente|#
  468.     [(and (number? (car lista)) (number? (cadr lista)))
  469.              (if (eq? sys 'suma) (+ (car lista) (cadr lista))
  470.                                  (* (car lista) (cadr lista)))]
  471.     #|Si no cumple ninguna, entonces se trata de un arreglo y debo usar funciones auxiliares|#
  472.     [else (if (eq? sys 'suma)(operar (car lista) (cadr lista))
  473.              (duplicar (car lista) (cadr lista)))
  474.      ]))
  475.  
  476. #|Duplica el contenido de una lista n veces|#
  477. (define (duplicar lista n)
  478.   (cond
  479.     [(eq? '() lista) '()]
  480.     [(= n 0)'()]
  481.     [else (append lista (duplicar lista (- n 1)))]))
  482.  
  483. #|Suma dos arreglos teniendo en cuenta la manera en que son recibidos|#
  484. (define (operar lista1 lista2)
  485.   (cond
  486.     [(and (equal? lista1 '()) (equal? lista2 '())) '()]
  487.     [(append (list (+ (car lista1)
  488.                       (car lista2)))
  489.              (operar (cdr lista1)
  490.                      (cdr lista2)))]))
  491.  
  492. #|MULTIPLICAR CADENAS|#
  493. #|Esta función crea una sola cadena que realmente es una cadena repetida n veces|#
  494. (define (mul cadena n)
  495.   (cond
  496.     [(and (number? cadena) (string? n)) (mul n cadena)]
  497.     [(= n 0) ""]
  498.     [(string-append cadena (mul cadena (- n 1)))]))
  499.  
  500. #|ELIMINAR DIAGONALES DEL TEXTO|#
  501. #|dado a que las cadenas son acompañadas por un #\" entonces hago esta función para eliminarlas y devolver una
  502. cadena más limpia|#
  503. (define (eliminar lista)
  504.   (cond
  505.     [(eq? '() lista)'()]
  506.     [(eq? (car lista) #\")(append (eliminar (cdr lista)))]
  507.    [else (append (list(car lista)) (eliminar (cdr lista)))]))
  508.  
  509. #|Encontrar:
  510.  Debo partir de la siguiente premisa para entender lo que debo hacer:
  511.  Hay dos posibilidades cuando tratamos de obtener un valor de un arreglo.
  512. a)El rango siempre será una lista de longitud 2. Dado a que su naturaleza es tener un inicio y un final.
  513. ;-------------------POSIBILIDADES 1-----------------
  514. (define lista1 (list (list (list 1 2) 3) 4));<----arreglo(longitud 2)=[[[1,2],3],4]
  515. (define lista4 (list (list 0) (list 0) (list 0)))  ;<----lista de rangos de longitud 1)= arreglo[0][0]
  516. ;-------------------POSIBILIDADES 2-----------------
  517. (define lista2 (list(list 1 2 3 4)));<----arreglo (longitud 1)=[1,2,3,4]
  518. (define lista3 (list (list 0 3)));<-------rango   (longitud 2)= arreglo[0,3]
  519. |#
  520. #|Función encontrar, encuentra un dato dentro de un arreglo.|#
  521. (define (encontrar lis-vals lis-pos)
  522.  (cond
  523. #|Si alguna no es de longitud uno, lo que equivale a un arreglo de posibles arreglos y una posición compuesta
  524. (arreglo[in][end]), entonces usamos la función general con ambas listas|#
  525.    [(not (or (= 1 (length lis-vals)) (= 1(length lis-pos)))) (comp-range-array lis-vals lis-pos)]
  526.    
  527.    #|Si la condición anterior no se cumple, estaremos hablando de que ambas son listas simples o sencillas
  528. (un arreglo de sólo números un llamado a posición que va de in a end sin más). Por esto, llamaremos a
  529. simple-range-array que recibe un inicio, un final, una lista y un ac (ac será sólo con propósitos comparativos).
  530. Por lo tanto, invocaremos tal función de la siguiente manera:
  531. inicio = primer valor de la lista lis-pos (array[0,2]->'('(0 2)))->0)
  532. final  = segundo valor de la lista lis-pos(array[0,2]->'('(0 2)))->2)(Si estoy haciendo array[0] entonces end=in)
  533. lista  = (car lis-vals)-->(car(list lis-vals))
  534. ac     = (car lis-vals)-->(car(list lis-vals))|#
  535.    [else (simple-range-array (caar lis-pos) (if (= 1 (length(car lis-pos)))
  536.                                          (caar lis-pos) (cadar lis-pos)) lis-vals lis-vals)]))
  537.  
  538. #|Arreglo simple, posición simple|#
  539. (define (simple-range-array in end lis ac)
  540.  (cond
  541.    #|Tenemos que verificar que in no sea negativo porque tal posición no existe y además debemos verificar que
  542. end no sea mayor que la máxima posición de la lista (dado a que la lista la estaremos modificando por motivos de
  543. recursión, usaremos ac)|#
  544.    [(or (< in 0)  (> end (- (length ac) 1))) "span class="kw1"> Error"]
  545.    #|Si la lista está vacía devolvemos vación ya que el propósito de esta función es retornar una lista|#
  546.    [(empty? lis) '()]
  547.    #|Nuestro punto de parada es cuando nuestro inicio llegue a su final, entonces devolveremos lo que contenga
  548.      el dato en esa posición de la lista ingresada. Si lo que devuelve es una lista, la entregamos tal como está
  549.      si lo que devuelve es un dato diferente a lista, devolvemos el dato dentro de una lista.|#
  550.    [(= in end)  (if (list? (list-ref lis in)) (list-ref lis in) (list (list-ref lis in)))]
  551.    #|Mientras que el punto de parada no se cumpla, concatenaremos el dato que se encuentra en la posición in
  552.      con la recurisón de simple-range-array pero ahora in se aumentará en uno y su end,lis y ac serán los mismos.|#
  553.    [else (append (list (list-ref lis in)) (simple-range-array (+ in 1) end lis ac))]))
  554.  
  555.  
  556. #|Cuando no se trate de un arreglo simple y por lo tanto de una llamado a posicionamiento simple, acudiremos a
  557. la función encon que recibe dos listas|#
  558. (define (encon lista1 lista2)
  559.  (cond
  560. #|Punto de parada: cuando la lista a la cual le estamos buscando un número, termine siendo el mismo entonces
  561. devolverlo.|#
  562.    [(number? lista1) lista1]
  563. #|Mientras ningun punto de parada se cumpla seguiremos haciendo llamado a encontrar (para que se encargue de decidir
  564. si hemos llegado a un punto donde las lista1 es simple (arreglo sencillo) o seguimos teniendo un arreglo compuesto).
  565. pero la lista donde buscaremos el dato será el producto de hacer list-ref con la lista1 intacta y como posición tendremos
  566. el primer dato, del primer dato de lista2 -arreglo[0][1]-->'('(0)'(1))--> 0-. Como lista2 pasaremos el resto de esta.|#
  567.    [else (encontrar (list-ref lista1 (caar lista2)) (cdr lista2))]))
  568.  
  569. #|Función bool me regresa una lista de dos booleanos las cuales me servirán de indicador para saber si mi llamado
  570. es compuesto o no.|#
  571. (define (bool lista)
  572.  (map (lambda (x) (= 1 (length x)))lista))
  573.  
  574.  
  575. #|----------------------Funcion evalua arreglos compuestos-------------------------------------------------|#
  576. (define (comp-range-array lista1 lista2)
  577.  (cond
  578. #|Si bool devuelve una lista con dos datos de tipo #true entonces estaremos hablando de una lista de posiciones compuesta
  579. con llamado a dato en una sola posición (Ej: array[0][0]). Entonces,haremos llamado a encon con ambas listas|#
  580.    [(and (equal? #t (car (bool lista2)))
  581.          (equal? #t (cadr (bool lista2)))) (encon lista1 lista2)]
  582.    
  583. #|Si no devuelve una lista de sólo true's quiere decir que tenemos un arreglo compuesto y llamado de posición compuesto
  584. que desea sacar una fragmento de un arreglo contenido sobre otro.
  585. Ej: array = [[1,2,3],4,5]; puts(array[0][0,2]);
  586. Por lo tanto llamaremos a la función principal encontrar para que se encargue de evaluar de nuevo todo y sacar
  587. lo necesario a través de las diferentes funciones auxiliares|#
  588.    
  589.    [else (encontrar (encon lista1 lista2) (cdr lista2))]))
  590.  
  591. ; eval-simple-value s-val env (cases simple-value s-val (id-val ...) (num-val ...) (true-val ...))
  592. ;   evalúa un valor simple, comprende los casos desde id-val hasta arr-val
  593. ;   para el caso de id-val se debe hacer apply-env
  594.  
  595. #|Función que dependiendo de el simbolo, realiza una lista excluyente o incluyente en un rango origen-destino|#
  596. (define (rango origen destino sym)
  597.  (cond
  598.    #|Me aseguro que origen y destino sean números para no cometer errores de operación|#
  599.    [(not(or(number? origen) (number? destino))) "span class="kw1"> Error"]
  600.    [(equal? sym 'in) (inclu origen destino)]
  601.    [(equal? sym 'ex) (exclu origen destino)]
  602.    #|Si no se digita el sym permitido, debo mostrar error|#
  603.    [else "span class="kw1"> Error"]))
  604.  
  605. #|La función inclu realiza una lista que va desde origen hasta destino siendo el punto de parada cuando origen
  606. sea igual a destino|#
  607. (define (inclu origen destino)
  608.  (cond
  609.    [(or (list? origen) (list? destino))"span class="kw1"> Error"]
  610.    [(= origen destino) (list origen)]
  611.    [(< origen destino) (append (list origen) (inclu (+ origen 1) destino))]
  612.    [(> origen destino) (reverse(inclu destino origen))]))
  613.  
  614. #|La función exclu realiza una lista que va desde origen hasta destino siendo el punto de parada cuando origen
  615. sea igual a destino pero con la diferencia que el punto de para devuelve vacio.|#
  616. (define (exclu origen destino)
  617.  (cond
  618.    [(or (list? origen) (list? destino))"span class="kw1"> Error"]
  619.    [(= origen destino) empty]
  620.    [(< origen destino) (append (list origen) (exclu(+ origen 1) destino))]
  621.    [(> origen destino) (append (list origen) (exclu(- origen 1) destino))]))
  622.  
  623. #|Para explicar pasos, tendremos de ejemplo lo siguiente:
  624. lista       = '(1 2 3 4 5)
  625. paso        = 2
  626. lis-compare = lista|#
  627. (define (pasos lista paso lis-compare)
  628.  (cond
  629.    [(empty? lista) '()];<----Si la lista está vacía, devolver vacío (Dado a que la función retorna una lista).
  630.    
  631.    [(or(and (< (car lis-compare) (last lis-compare))                   ;|  Verificar que sea posible hacer paso con la
  632.             (> 0 paso))(and (> (car lis-compare) (last lis-compare))   ;|->lista dada. Dado a que la lista se verá
  633.                             (< 0 paso)))(eopl:error 'Step "bad step")] ;|  afectada por recursión usamos lis-compare
  634.    
  635.    [else (append (list(car lista)) ;->Concatenar el primero de la lista (1)...
  636.                  (pasos (if (positive? paso)                                              ;|...con el llamado recursivo
  637.                             (if(> paso (length lista)) '() (list-tail lista paso))        ;|->pero ahora lista será
  638.                      (if(> (* -1 paso) (length lista)) '() (list-tail lista (* -1 paso))));|'(3 4 5) gracias a list-tail
  639.                         paso                                                              ;| paso será el mismo
  640.                         lis-compare))]))                                                  ;|y lis-compare será la misma.
  641.  
  642. (define (steps lista paso)
  643.  (pasos lista paso lista))
  644.  
  645. ;*******************************************************************************************
  646. ;Referencias
  647. (define-datatype reference reference?
  648.  (a-ref (position integer?)
  649.         (vec vector?)))
  650.  
  651. (define deref
  652.  (lambda (ref)
  653.    (primitive-deref ref)))
  654.  
  655. (define primitive-deref
  656.  (lambda (ref)
  657.    (cases reference ref
  658.      (a-ref (pos vec)
  659.             (vector-ref vec pos)))))
  660.  
  661. (define setref!
  662.  (lambda (ref val)
  663.    (primitive-setref! ref val)))
  664.  
  665. (define primitive-setref!
  666.  (lambda (ref val)
  667.    (cases reference ref
  668.      (a-ref (pos vec)
  669.             (vector-set! vec pos val)))))
  670.  
  671. ;*******************************************************************************************
  672. ;*******************************************************************************************
  673. ;Ambientes
  674.  
  675. ;definición del tipo de dato ambiente
  676. (define-datatype environment environment?
  677.  (empty-env-record)
  678.  (extended-env-record
  679.   (syms (list-of symbol?))
  680.   (vec  vector?)
  681.   (env environment?)))
  682.  
  683. (define scheme-value? (lambda (v) #t))
  684.  
  685. ;empty-env:      -> enviroment
  686. ;función que crea un ambiente vacío
  687. (define empty-env  
  688.  (lambda ()
  689.    (empty-env-record)))       ;llamado al constructor de ambiente vacío
  690.  
  691.  
  692. ;extend-env: <list-of symbols> <list-of numbers> enviroment -> enviroment
  693. ;función que crea un ambiente extendido
  694. (define extend-env
  695.  (lambda (syms vals env)
  696.    (extended-env-record syms (list->vector vals) env)))
  697.  
  698. ;extend-env-recursively: <list-of symbols> <list-of <list-of symbols>> <list-of expressions> environment -> environment
  699. ;función que crea un ambiente extendido para procedimientos recursivos
  700. (define extend-env-recursively
  701.  (lambda (proc-names idss bodies old-env)
  702.    (let ((len (length proc-names)))
  703.      (let ((vec (make-vector len)))
  704.        (let ((env (extended-env-record proc-names vec old-env)))
  705.          (for-each
  706.            (lambda (pos ids body)
  707.              (vector-set! vec pos (closure ids body env)))
  708.            (iota len) idss bodies)
  709.          env)))))
  710.  
  711. ; |Ambiente recursivo para un solo procedimiento
  712.  
  713. (define (a-recursive-env a-proc-name ids body env)
  714.  (let ((vec (make-vector 1)))
  715.    (let ((env (extended-env-record (list a-proc-name) vec env)))
  716.          (vector-set! vec 0 (closure ids body env))
  717.          env)
  718.    )
  719.  )
  720.  
  721. ;iota: number -> list
  722. ;función que retorna una lista de los números desde 0 hasta end
  723. (define iota
  724.  (lambda (end)
  725.    (let loop ((next 0))
  726.      (if (>= next end) '()
  727.        (cons next (loop (+ 1 next)))))))
  728.  
  729. ;función que busca un símbolo en un ambiente
  730. (define apply-env
  731.  (lambda (env sym)  
  732.    (deref (apply-env-ref env sym))))
  733.  
  734. (define apply-env-ref
  735.  (lambda (env sym)
  736.    (cases environment env
  737.      (empty-env-record () (eopl:error 'Error "undefined local variable or method ~s" sym))
  738.      (extended-env-record (syms vals env)
  739.                           (let ((pos (rib-find-position sym syms)))
  740.                             (if (number? pos)
  741.                                 (a-ref pos vals)
  742.                                 (apply-env-ref env sym)))))))
  743.  
  744. ;valida un simbolo en el ambiente
  745. ;función que busca un símbolo en un ambiente
  746. (define check-apply-env
  747.  (lambda (env sym)
  748.    (check-apply-env-ref env sym)))
  749.  
  750. (define check-apply-env-ref
  751.  (lambda (env sym)
  752.    (cases environment env
  753.      (empty-env-record ()
  754.                        #f)
  755.      (extended-env-record (syms vals env)
  756.                           (let ((pos (rib-find-position sym syms)))
  757.                             (if (number? pos)
  758.                                 #t
  759.                                 (check-apply-env-ref env sym)))))))
  760.  
  761. ;*******************************************************************************************
  762. ;*******************************************************************************************
  763. ;Ambiente inicial
  764.  
  765. (define (init-env) (empty-env))
  766. ;*******************************************************************************************
  767. ;*******************************************************************************************
  768. ;Funciones Auxiliares
  769.  
  770. ; funciones auxiliares para encontrar la posición de un símbolo
  771. ; en la lista de símbolos de un ambiente
  772.  
  773. (define rib-find-position
  774.  (lambda (sym los)
  775.    (list-find-position sym los)))
  776.  
  777. (define list-find-position
  778.  (lambda (sym los)
  779.    (list-index (lambda (sym1) (eqv? sym1 sym)) los)))
  780.  
  781. (define list-index
  782.  (lambda (pred ls)
  783.    (cond
  784.      ((null? ls) #f)
  785.      ((pred (car ls)) 0)
  786.      (else (let ((list-index-r (list-index pred (cdr ls))))
  787.              (if (number? list-index-r)
  788.                (+ list-index-r 1)
  789.                #f))))))
  790.  
  791. ;*******************************************************************************************
  792. ;*******************************************************************************************
  793.  
  794. ;;Función que retorna una lista dado un inicio, un final, y un incremento
  795. (define iota-range
  796.  (lambda (start end step)
  797.    (cond [(or
  798.            (and (< start end) (> 0 step))
  799.            (and (> start end) (< 0 step)))
  800.           (eopl:error 'Step "bad step")]
  801.          [else
  802.           (let loop ((next start))
  803.             (if (= 0 (abs (- next end)))
  804.                 (list next)
  805.                 (cons next (loop (+ next step)))))]
  806.          )
  807.    ))
  808.  
  809. ; #Ejemplos:
  810. ; > (eval-range (inclusive 1 10 1))
  811. ; (1 2 3 4 5 6 7 8 9 10)
  812. ; > (eval-range (exclusive 1 10 1))
  813. ; (1 2 3 4 5 6 7 8 9)
  814. ; > (eval-range (inclusive 1 -10 1))
  815. ; . . Step: bad step
  816. ; > (eval-range (inclusive -1 10 -1))
  817. ; . . Step: bad step
  818.  
  819. ;ruby def fact(n) if (n == 0) then return 1; else puts "el valor de n es ",n; return (n * (fact ((n - 1)))); end end puts "el factorial de 5 es", (fact(5)); end
  820. ;*******************************************************************************************
  821. ;*******************************************************************************************
  822. ; ruby def print(v) puts v; end print(2); end
  823. (interpretador)
  824.  
  825. ;ruby def fact(n) if (n == 0) then return 1; else return (n*(fact((n - 1)))); end end fact(5); end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement