Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 33.40 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 (eval-exp-batch batch env)
  215.   (cases exp-batch batch
  216.     (a-batch (exp exps) (let ((result (eval-expressions (cons exp exps) env)))
  217.                           (if (or (environment? result) (void? result))
  218.                               (begin (display "=> ") 'nil)
  219.                               result)))))
  220.  
  221. (define (eval-proc-batch batch env)
  222.   (cases exp-batch batch
  223.     (a-batch (exp exps)
  224.            ;  (begin
  225.             ;   (pretty-display "-------------------------------------------------------------------")
  226.              ;  (pretty-display exp)
  227.               ; (pretty-display "-------------------------------------------------------------------")
  228.                ;(pretty-display exps)
  229.               (eval-expressions (cons exp exps) env))))
  230.  
  231. (define (is-return-exp? exp)
  232.   (cases expression exp
  233.     (return-exp (comp-value) #t)
  234.     (else #f)))
  235.  
  236. (define (eval-expressions exps env)
  237.  (if (or (empty? (cdr exps)) (is-return-exp? (car exps)))                
  238.      (eval-expression (car exps) env)    
  239.      (let ((next-env (eval-expression (car exps) env)))
  240.        (if (environment? next-env) (eval-expressions (cdr exps) next-env)
  241.            (eval-expressions (cdr exps) env)))))
  242.  
  243. (define (eval-expression exp env)
  244.   (cases expression exp
  245.     (a-simple-exp (simple-exp) (begin
  246.                                  (pretty-display "SIMPL EXP")
  247.                                  (eval-simple-exp simple-exp env)))
  248.  
  249.     (declare-exp (id ids) (extend-env (cons id ids) (map (lambda (x) 'nil) (cons id ids)) env))
  250.    
  251.     (puts-exp (vals)
  252.               (for-each (lambda (arg)
  253.                           (if (check-apply-env env arg) (pretty-display (apply-env env arg))
  254.                           (pretty-display arg)))
  255.                         (map (lambda(x) (eval-comp-value x env)) vals)))
  256.  
  257.     (if-exp (if-comp if-batch elsif-comps elsif-batchs else-batch) (begin
  258.                                                                      (pretty-display "IF EXPRESSION")
  259.                                                                      (if (eqv? "true" (eval-comp-value if-comp env))
  260.                                                                        (eval-exp-batch if-batch env)
  261.                                                                        (if (or (empty? elsif-comps) (empty? elsif-batchs))
  262.                                                                            (if (empty? else-batch)
  263.                                                                                (void)
  264.                                                                                (eval-exp-batch (car else-batch) env))
  265.                                                                            (eval-expression (if-exp (car elsif-comps) (car elsif-batchs) (cdr elsif-comps) (cdr elsif-batchs) else-batch) env)))))
  266.  
  267.     (unless-exp (comp-bool batch else-batch) (if (eqv? "false" (eval-comp-value comp-bool env))
  268.                                                  (eval-exp-batch batch env)
  269.                                                  (if (empty? else-batch)
  270.                                                      (void)
  271.                                                      (eval-exp-batch (car else-batch) env))))
  272.  
  273.     (function-exp (name ids batch) (begin
  274.                                      (pretty-print "FUNCTION EXP")
  275.                                      (a-recursive-env name ids batch env)))
  276.      
  277.     (while-exp (comp-bool batch) (if (eqv? "true" (eval-comp-value comp-bool env))
  278.                                      (let ((new-env(eval-exp-batch batch env)))
  279.                                        (if (environment? new-env)
  280.                                            (eval-expression (while-exp comp-bool batch) new-env)
  281.                                            (eval-expression (while-exp comp-bool batch) env)))
  282.                                      (void)))
  283.  
  284.     (until-exp (comp-bool batch) (if (eqv? "false" (eval-comp-value comp-bool env))
  285.                                      (let ((new-env(eval-exp-batch batch env)))
  286.                                        (if (environment? new-env)
  287.                                            (eval-expression (until-exp comp-bool batch) new-env)
  288.                                            (eval-expression (until-exp comp-bool batch) env)))
  289.                                      (void)))  
  290.  
  291.     (return-exp (comp-value) (begin
  292.                                (pretty-display "RETURN EXP")
  293.                                (eval-comp-value comp-value env)))
  294.  
  295.     ;for-exp        
  296.     (else "TO DO")))
  297.  
  298. (define (eval-simple-exp s-exp env)
  299.   (cases simple-exp s-exp
  300.     (val-exp (simple-value complement) (apply-complement simple-value complement env))))
  301.    
  302.      
  303.       ;(else (let ((proc (apply-env env (eval-comp-value comp-value env))))
  304.        ;       (if (procval? proc)
  305.         ;          (apply-procedure proc (eval-calls calls  env))
  306.          ;         (eopl:error 'eval-expression
  307.           ;                       "Attempt to apply non-procedure ~s" proc)))))))
  308.  
  309. (define (eval-calls-args cls left-value env)
  310.   (cases calls cls
  311.     (some-calls (calls) (if (empty? calls)
  312.                             '()
  313.                             (cons (eval-call (car calls) left-value env)
  314.                                   (eval-calls-args (some-calls (cdr calls)) left-value env))))))
  315.  
  316. (define eval-calls
  317.   (lambda (cls left-value env)
  318.     (let ((args (eval-calls-args cls left-value env))
  319.           (left-value-evaluated (if (simple-value? left-value)
  320.                                     (eval-simple-value left-value env)
  321.                                     (eval-comp-value left-value env))))
  322.       (if (empty? args)
  323.           (if (symbol? left-value-evaluated)
  324.               (apply-env env left-value-evaluated)
  325.               left-value-evaluated)
  326.           (let ((id-value (apply-env env left-value-evaluated)))
  327.             (if (procval? id-value)
  328.                 (apply-1 id-value (car args) env)
  329.                 ;(display )
  330.                 (display "handle arr-vals")))))))      
  331.  
  332. (define apply-1
  333.   (lambda (proc args env)
  334.     (cases procval proc
  335.       (closure (ids body env)
  336.               ; (begin
  337.                ;  (pretty-display ids)                
  338.                 ; (pretty-display (apply-env (extend-env ids args env) 'n))
  339.                  ;(pretty-display args)
  340.                  (eval-proc-batch body (extend-env ids args env))))))
  341.  
  342. (define (is-comp-calls-empty cls env)
  343.   (cases calls cls
  344.     (some-calls (cls) (empty? cls))                            
  345.     (else "")))
  346.  
  347. (define (apply-complement s-val compl env)
  348.   (cases complement compl
  349.     (assign (comp-value calls)
  350.             (let ((id (apply-env-ref env (eval-simple-value s-val env))) (val (eval-calls calls comp-value env)))
  351.               (begin                
  352.                 (setref! id val)
  353.                 val)))                    
  354.  
  355.     (assign-and (assign-op comp-value calls)
  356.                 (let ((left-val-ref (apply-env-ref env (eval-simple-value s-val env)))
  357.                       (right-val (eval-calls calls comp-value env)))
  358.                   (let ((result (apply-assign assign-op (deref left-val-ref) right-val)))
  359.                     (begin
  360.                       (setref! left-val-ref result)
  361.                       result))))  
  362.     (comp-calls (calls) (eval-calls calls s-val env))))                                        
  363.  
  364. (define (eval-comp-value c-value env)
  365.   (cases comp-value c-value
  366.     (a-value (value) (eval-value value env))
  367.     (unop-value (un-op comp-value) (eval-un-op (eval-comp-value comp-value env)))))
  368.  
  369. (define eval-un-op
  370.   (lambda (val)
  371.     (cond
  372.       ((eqv? val "true") "false")
  373.       ((eqv? val "false") "true")
  374.       (else (eopl:error 'eval-un-op "Not a bool")))))      
  375.  
  376. (define (eval-value a-value env)
  377.   (cases value a-value
  378.     (a-s-val (simple-value)(if (symbol? (eval-simple-value simple-value env))
  379.                                (apply-env env (eval-simple-value simple-value env))
  380.                                (eval-simple-value simple-value env)))
  381.     (compl-val (comp-value val-compl)
  382.                (begin
  383.                  (pretty-display "COMPL-VAL")
  384.                  (pretty-display comp-value)
  385.                  (pretty-display val-compl)
  386.                  (pretty-display (environment? env))
  387.                  (eval-val-compl comp-value val-compl env)))))
  388.  
  389. (define (eval-val-compl comp-value v-compl env)
  390.   (cases val-compl v-compl
  391.     (val-call (calls) (eval-calls calls comp-value env))
  392.     (binop-val (bin-op comp-v) (apply-op bin-op (list (eval-comp-value  comp-value env) (eval-comp-value comp-v env))))))
  393.  
  394. ;(define (eval-val-compl a-val a-val-compl env)
  395.  ; (cases val-compl a-val-compl
  396.   ;  (val-call (calls) (encontrar ;<--- encuentra un dato de un arreglo con otra lista que suponemos es de posiciones
  397.    ;                    a-val ;<--- lista del arreglo
  398.     ;                   (map (lambda (x) (eval-call x a-val env))(is-comp-calls-empty calls env));<---lista de posiciones
  399.      ;                  ))              
  400.        
  401.  
  402. (define (eval-call cl s-val env)
  403.   (cases call cl
  404.     (arguments-call (arguments) (eval-args arguments s-val env))
  405.     (else "")))
  406.  
  407. #|Eval-args evalua un argumento en un ambiente|#
  408. (define (eval-args args s-val env)
  409.   (cases arguments args
  410.     (some-arguments (comp-values) (if (simple-value? s-val)                                    
  411.                                       (let ((proc (apply-env env (eval-simple-value s-val env))))                                        
  412.                                         (if (procval? proc)
  413.                                             (map (lambda (x) (eval-comp-value x env)) comp-values)
  414.                                             (eopl:error 'Error "Can't apply args to ~s" proc)))
  415.                                       (let ((proc (apply-env env (eval-comp-value s-val env))))
  416.                                         (if (procval? proc)
  417.                                             (map (lambda (x) (eval-comp-value x env)) comp-values)
  418.                                             (eopl:error 'Error "Can't apply args to ~s" proc)))))                                          
  419.  
  420.                                      
  421.                                 ;      (let ((proc (apply-env env (eval-simple-value s-val env))))
  422.                                  ;       (if (procval? proc)
  423.                                   ;          (apply-procedure proc (map (lambda (x)(eval-comp-value x env)) comp-values) env)
  424.                                    ;         (eopl:error 'Error "Can't apply args to ~s" proc)))
  425.                                     ;  (let ((proc (apply-env env (eval-comp-value s-val env))))
  426.                                      ;   (if (procval? proc)
  427.                                       ;      (apply-procedure proc (map (lambda (x)(eval-comp-value x env)) comp-values) env)
  428.                                        ;     (eopl:error 'Error "Can't apply args to ~s" proc)))))
  429.                    
  430.     #|Si es de tipo arreglo el argumento, uso eval-comp-value para evaluar el comp-value (no sé que hacer con
  431. el comp-values porque ni siquiera sé que debería contener)|#
  432.     (arr-arguments (comp-value comp-values) (append(list(eval-comp-value comp-value env))
  433.                                                   (map (lambda (x)(eval-comp-value x env))
  434.                                                        comp-values)
  435.                                                   ))))
  436.  
  437. (define (encontrar lis-vals lis-pos)
  438.   (cond
  439.     [(and (andmap number? lis-vals) (andmap list? lis-pos)) "Error"]
  440.     [(not (and (= 1 (length lis-vals)) (= 1(length lis-pos)))) (general lis-vals lis-pos)]
  441.    
  442.     #|Arreglo simple, posición simple|#
  443.     [else (simple-range-array (caar lis-pos) (if (= 1 (length(car lis-pos)))
  444.                                           (caar lis-pos) (cadar lis-pos)) (car lis-vals) (car lis-vals))]))
  445.  
  446. #|Arreglo simple, posición simple|#
  447. (define (simple-range-array in end lis ac)
  448.   (cond
  449.     [(or (< in 0)  (> end (- (length ac) 1))) "Error"]
  450.     [(empty? lis) '()]
  451.     [(= in end) (list (list-ref lis in))]
  452.     [else (append (list (list-ref lis in)) (simple-range-array (+ in 1) end lis ac))]))
  453.  
  454.  
  455.  
  456.  
  457.  
  458. (define (encon lista1 lista2)
  459.   (cond
  460.     [(number? lista1) lista1]
  461.     [(andmap number? lista1) lista1]
  462.     [else (encon (list-ref lista1 (caar lista2)) (cdr lista2))]))
  463.  
  464. (define (bo lista)
  465.   (map (lambda (x) (= 1 (length x)))lista))
  466.  
  467. (define (general lista1 lista2)
  468.   (cond
  469.     [(and (equal? #t (car (bo lista2)))
  470.           (equal? #t (cadr (bo lista2)))) (encon lista1 lista2)]
  471.    
  472.     [(or(and (equal? #f (car (bo lista2)))
  473.              (equal? #f (cadr (bo lista2))))
  474.         (and (equal?  #f (car (bo lista2)))
  475.              (equal? #t (cadr (bo lista2))))) "Error de ingreso"]
  476.    
  477.     [else (encontrar (list(encon lista1 lista2)) (cdr lista2))]))
  478.  
  479. ; eval-simple-value s-val env (cases simple-value s-val (id-val ...) (num-val ...) (true-val ...))
  480. ;   evalúa un valor simple, comprende los casos desde id-val hasta arr-val
  481. ;   para el caso de id-val se debe hacer apply-env
  482.  
  483. (define (eval-simple-value s-val env)
  484.   (cases simple-value s-val
  485.     (id-val  (identifier)  identifier)
  486.     (int-val (number) number)
  487.     (str-val (text) (string-trim text "\""))
  488.     (true-val  () "true")
  489.     (false-val () "false")
  490.     (nil-val   () "nil")
  491.     (arr-val   (comp-value) (map (lambda (x) (eval-comp-value x env)) comp-value))))
  492.  
  493. (define (apply-op op args)
  494.   (cases bin-op op
  495.      (add ()  (operacion args 'suma))
  496.      (diff () (- (car args) (cadr args)))
  497.      (mult () (operacion args 'mult))
  498.      (div () (/ (car args) (cadr args)))
  499.      (mod () (modulo (car args) (cadr args)))
  500.      (pow ()(expt (car args) (cadr args)))
  501.      (great () (if (> (car args) (cadr args)) "true" "false"))
  502.      (great-eq () (if (>= (car args) (cadr args)) "true" "false"))
  503.      (less () (if (< (car args) (cadr args)) "true" "false"))
  504.      (less-eq () (if (<= (car args) (cadr args)) "true" "false"))
  505.      (equal () (if (equal? (car args) (cadr args)) "true" "false"))
  506.      (not-equal () (if (not(equal? (car args) (cadr args))) "true" "false"))
  507.      (and-op () (if (and (eval-bool (car args)) (eval-bool (cadr args))) "true" "false"))
  508.      (or-op () (if (or (eval-bool (car args)) (eval-bool (cadr args))) "true" "false"))
  509.      (in-range () (rango (car args) (cadr args) 'in))
  510.      (ex-range () (rango (car args) (cadr args) 'ex))
  511.      (st-range () (steps (car args) (cadr args)))))
  512.  
  513. (define eval-bool
  514.   (lambda (val)
  515.     (if (eqv? val "true") #t #f)))
  516.  
  517. (define (apply-assign op arg1 arg2)
  518.   (cases assign-op op
  519.     (add-eq () (+ arg1 arg2))
  520.     (diff-eq () (- arg1 arg2))
  521.     (mult-eq () (* arg1 arg2))
  522.     (div-eq () (/ arg1 arg2))
  523.     (pow-eq () (expt arg1 arg2))))
  524.    
  525. #|Función que dependiendo de el simbolo, realiza una lista excluyente o incluyente en un rango origen-destino|#
  526. (define (rango origen destino sym)
  527.   (cond
  528.     #|Me aseguro que origen y destino sean números para no cometer errores de operación|#
  529.     [(not(or(number? origen) (number? destino))) "Error"]
  530.     [(equal? sym 'in) (inclu origen destino)]
  531.     [(equal? sym 'ex) (exclu origen destino)]
  532.     #|Si no se digita el sym permitido, debo mostrar error|#
  533.     [else "Error"]))
  534.  
  535. #|La función inclu realiza una lista que va desde origen hasta destino siendo el punto de parada cuando origen
  536. sea igual a destino|#
  537. (define (inclu origen destino)
  538.   (cond
  539.     [(= origen destino) (list origen)]
  540.     [(< origen destino) (append (list origen) (inclu (+ origen 1) destino))]
  541.     [(> origen destino) (reverse(inclu destino origen))]))
  542.  
  543. #|La función exclu realiza una lista que va desde origen hasta destino siendo el punto de parada cuando origen
  544. sea igual a destino pero con la diferencia que el punto de para devuelve vacio.|#
  545. (define (exclu origen destino)
  546.   (cond
  547.     [(= origen destino) empty]
  548.     [(< origen destino) (append (list origen) (exclu(+ origen 1) destino))]
  549.     [(> origen destino) (append (list origen) (exclu(- origen 1) destino))]))
  550.  
  551. #|Pasos recibe una lista, un comparador y un paso, la idea es que se genere una nueva lista que contenga los datos
  552. de la lista que fue pasada pero filtrada por paso, o sea, que la misma vaya de paso a paso.
  553.  
  554. El ac es realmente la misma lista, sólo que esta no se verá afectada por la recursión, la idea es que paso en algún
  555. momento será igual a un dato de la lista y por tanto si deseo hacer el paso a paso correcto debo verificar que la manera
  556. en que deseo ir, debe estar contenido dentro de la lista que deseo filtrar.|#
  557. (define (pasos lista ac paso)
  558.   (cond
  559.     [(equal? '() lista)'()]
  560.     [(not(list? (member paso ac))) "Error"]
  561.     [(= (+ paso (car lista)) (last lista)) (list (+ paso (car lista)))]
  562.     [else (append (list (car lista)) (list (+ paso (car lista)))
  563.                    (pasos (cddr lista) ac paso))]))
  564.  
  565. (define(steps lista paso)
  566.   (pasos lista lista paso))
  567.  
  568. #|Función que opera seguún el tipo de dato que contenga la lista|#
  569. (define (operacion lista sys)
  570.   (cond
  571.     [(equal? lista '()) "Error"]
  572.     #|Si mi lista de args son puras cadenas entonces sé que su suma equivale a concatenar ambos|#
  573.     [(and (string? (car lista)) (string? (cadr lista)) (eq? sys 'suma))
  574.  
  575.      ;---AQUÍ LO QUE HAGO ES LIMPIAR MI CADENA DE ESTO: #\"
  576.      (list->string(eliminar(string->list
  577.      (string-append (car lista) (cadr lista)))))]
  578.     ;---------------------------------------------------
  579. #|Si el simbolo es 'mult tengo que verificar que almenos uno de los elemenos sea un número para saber
  580. cuantas veces repetir mi cadena|#
  581.     [(or
  582.       (and (string? (car lista)) (number? (cadr lista)) (eq? sys 'mult))
  583.       (and (number? (car lista)) (string? (cadr lista)) (eq? sys 'mult)))
  584.  
  585.      ;---AQUÍ LO QUE HAGO ES LIMPIAR MI CADENA DE ESTO: #\"
  586.       (list->string(eliminar(string->list(mul (car lista) (cadr lista)))))]
  587.     ;---------------------------------------------------
  588.    
  589.     #|Si no se cumple que almenos uno sea cadena entonces hay que verificar si ambos son números. Así,
  590. ya se trate de una suma o una multiplicación, los puedo operar de manera común y corriente|#
  591.     [(and (number? (car lista)) (number? (cadr lista)))
  592.              (if (eq? sys 'suma) (+ (car lista) (cadr lista))
  593.                                  (* (car lista) (cadr lista)))]
  594.     #|Si no cumple ninguna, entonces se trata de un arreglo y debo usar funciones auxiliares|#
  595.     [else (if (eq? sys 'suma)(operar (car lista) (cadr lista))
  596.              (duplicar (car lista) (cadr lista)))
  597.      ]))
  598.  
  599. #|Duplica el contenido de una lista n veces|#
  600. (define (duplicar lista n)
  601.   (cond
  602.     [(eq? '() lista) '()]
  603.     [(= n 0)'()]
  604.     [else (append lista (duplicar lista (- n 1)))]))
  605.  
  606. #|Suma dos arreglos teniendo en cuenta la manera en que son recibidos|#
  607. (define (operar lista1 lista2)
  608.   (cond
  609.     [(and (equal? lista1 '()) (equal? lista2 '())) '()]
  610.     [(append (list (+ (car lista1)
  611.                       (car lista2)))
  612.              (operar (cdr lista1)
  613.                      (cdr lista2)))]))
  614.  
  615. #|MULTIPLICAR CADENAS|#
  616. #|Esta función crea una sola cadena que realmente es una cadena repetida n veces|#
  617. (define (mul cadena n)
  618.   (cond
  619.     [(and (number? cadena) (string? n)) (mul n cadena)]
  620.     [(= n 0) ""]
  621.     [(string-append cadena (mul cadena (- n 1)))]))
  622.  
  623. #|ELIMINAR DIAGONALES DEL TEXTO|#
  624. #|dado a que las cadenas son acompañadas por un #\" entonces hago esta función para eliminarlas y devolver una
  625. cadena más limpia|#
  626. (define (eliminar lista)
  627.   (cond
  628.     [(eq? '() lista)'()]
  629.     [(eq? (car lista) #\")(append (eliminar (cdr lista)))]
  630.    [else (append (list(car lista)) (eliminar (cdr lista)))]))
  631. ;*******************************************************************************************
  632. ;Referencias
  633. (define-datatype reference reference?
  634.  (a-ref (position integer?)
  635.         (vec vector?)))
  636.  
  637. (define deref
  638.  (lambda (ref)
  639.    (primitive-deref ref)))
  640.  
  641. (define primitive-deref
  642.  (lambda (ref)
  643.    (cases reference ref
  644.      (a-ref (pos vec)
  645.             (vector-ref vec pos)))))
  646.  
  647. (define setref!
  648.  (lambda (ref val)
  649.    (primitive-setref! ref val)))
  650.  
  651. (define primitive-setref!
  652.  (lambda (ref val)
  653.    (cases reference ref
  654.      (a-ref (pos vec)
  655.             (vector-set! vec pos val)))))
  656.  
  657. ;*******************************************************************************************
  658. ;*******************************************************************************************
  659. ;Ambientes
  660.  
  661. ;definición del tipo de dato ambiente
  662. (define-datatype environment environment?
  663.  (empty-env-record)
  664.  (extended-env-record
  665.   (syms (list-of symbol?))
  666.   (vec  vector?)
  667.   (env environment?)))
  668.  
  669. (define scheme-value? (lambda (v) #t))
  670.  
  671. ;empty-env:      -> enviroment
  672. ;función que crea un ambiente vacío
  673. (define empty-env  
  674.  (lambda ()
  675.    (empty-env-record)))       ;llamado al constructor de ambiente vacío
  676.  
  677.  
  678. ;extend-env: <list-of symbols> <list-of numbers> enviroment -> enviroment
  679. ;función que crea un ambiente extendido
  680. (define extend-env
  681.  (lambda (syms vals env)
  682.    (extended-env-record syms (list->vector vals) env)))
  683.  
  684. ;extend-env-recursively: <list-of symbols> <list-of <list-of symbols>> <list-of expressions> environment -> environment
  685. ;función que crea un ambiente extendido para procedimientos recursivos
  686. (define extend-env-recursively
  687.  (lambda (proc-names idss bodies old-env)
  688.    (let ((len (length proc-names)))
  689.      (let ((vec (make-vector len)))
  690.        (let ((env (extended-env-record proc-names vec old-env)))
  691.          (for-each
  692.            (lambda (pos ids body)
  693.              (vector-set! vec pos (closure ids body env)))
  694.            (iota len) idss bodies)
  695.          env)))))
  696.  
  697. ; |Ambiente recursivo para un solo procedimiento
  698.  
  699. (define (a-recursive-env a-proc-name ids body env)
  700.  (let ((vec (make-vector 1)))
  701.    (let ((env (extended-env-record (list a-proc-name) vec env)))
  702.          (vector-set! vec 0 (closure ids body env))
  703.          env)
  704.    )
  705.  )
  706.  
  707. ;iota: number -> list
  708. ;función que retorna una lista de los números desde 0 hasta end
  709. (define iota
  710.  (lambda (end)
  711.    (let loop ((next 0))
  712.      (if (>= next end) '()
  713.        (cons next (loop (+ 1 next)))))))
  714.  
  715. ;función que busca un símbolo en un ambiente
  716. (define apply-env
  717.  (lambda (env sym)
  718.    (deref (apply-env-ref env sym))))
  719.  
  720. (define apply-env-ref
  721.  (lambda (env sym)
  722.    (cases environment env
  723.      (empty-env-record ()
  724.                        (eopl:error 'Error "undefined local variable or method ~s" sym))
  725.      (extended-env-record (syms vals env)
  726.                           (let ((pos (rib-find-position sym syms)))
  727.                             (if (number? pos)
  728.                                 (a-ref pos vals)
  729.                                 (apply-env-ref env sym)))))))
  730.  
  731. ;valida un simbolo en el ambiente
  732. ;función que busca un símbolo en un ambiente
  733. (define check-apply-env
  734.  (lambda (env sym)
  735.    (check-apply-env-ref env sym)))
  736.  
  737. (define check-apply-env-ref
  738.  (lambda (env sym)
  739.    (cases environment env
  740.      (empty-env-record ()
  741.                        #f)
  742.      (extended-env-record (syms vals env)
  743.                           (let ((pos (rib-find-position sym syms)))
  744.                             (if (number? pos)
  745.                                 #t
  746.                                 (check-apply-env-ref env sym)))))))
  747.  
  748. ;*******************************************************************************************
  749. ;*******************************************************************************************
  750. ;Ambiente inicial
  751.  
  752. (define (init-env) (empty-env))
  753. ;*******************************************************************************************
  754. ;*******************************************************************************************
  755. ;Funciones Auxiliares
  756.  
  757. ; funciones auxiliares para encontrar la posición de un símbolo
  758. ; en la lista de símbolos de un ambiente
  759.  
  760. (define rib-find-position
  761.  (lambda (sym los)
  762.    (list-find-position sym los)))
  763.  
  764. (define list-find-position
  765.  (lambda (sym los)
  766.    (list-index (lambda (sym1) (eqv? sym1 sym)) los)))
  767.  
  768. (define list-index
  769.  (lambda (pred ls)
  770.    (cond
  771.      ((null? ls) #f)
  772.      ((pred (car ls)) 0)
  773.      (else (let ((list-index-r (list-index pred (cdr ls))))
  774.              (if (number? list-index-r)
  775.                (+ list-index-r 1)
  776.                #f))))))
  777.  
  778. ;*******************************************************************************************
  779. ;*******************************************************************************************
  780. ;;;Rangos
  781. (define-datatype range range?
  782.  (inclusive (start number?) (end number?) (step number?))
  783.  (exclusive (start number?) (end number?) (step number?))
  784.  )
  785.  
  786. (define (eval-range a-range)
  787.  (cases range a-range
  788.    (inclusive (start end step) (iota-range start end step))
  789.    (exclusive (start end step) (iota-range start (- end 1) step))
  790.    )
  791.  )
  792.  
  793. ;;Función que retorna una lista dado un inicio, un final, y un incremento
  794. (define iota-range
  795.  (lambda (start end step)
  796.    (cond [(or
  797.            (and (< start end) (> 0 step))
  798.            (and (> start end) (< 0 step)))
  799.           (eopl:error 'Step "bad step")]
  800.          [else
  801.           (let loop ((next start))
  802.             (if (= 0 (abs (- next end)))
  803.                 (list next)
  804.                 (cons next (loop (+ next step)))))]
  805.          )
  806.    ))
  807.  
  808. ; #Ejemplos:
  809. ; > (eval-range (inclusive 1 10 1))
  810. ; (1 2 3 4 5 6 7 8 9 10)
  811. ; > (eval-range (exclusive 1 10 1))
  812. ; (1 2 3 4 5 6 7 8 9)
  813. ; > (eval-range (inclusive 1 -10 1))
  814. ; . . Step: bad step
  815. ; > (eval-range (inclusive -1 10 -1))
  816. ; . . Step: bad step
  817.  
  818. ;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
  819. ;*******************************************************************************************
  820. ;*******************************************************************************************
  821. ; ruby def print(v) puts v; end print(2); end
  822. (interpretador)
  823. ;ruby def fact(n) if (n == 0) then return 1; else return (fact((n - 1))); end end fact(5); end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement