0
votes

version of racket/drSCHEME i use does not allow me to use internal definitions using (R5RS) language

like these two for examples below give me error messages

define: not allowed in an expression context in: (define inp (read-command))

(define repl 
 (lambda() 
 (display "\nUofL>") 
 (define inp (read-command)) 
 (define lengtha (length com)) 
      (cond 
        ((equal? inp "CLEAR")(set! lista '())(repl)) 
        ((equal? inp "REV")(set! lista (cdr lista))(set! lista (rev lista))(repl)) 
        ((equal? inp "STACK")(set! lista (cdr lista))(display lista)(repl)) 
        ((equal? inp "SWAP")(set! lista (cdr lista))(set! lista (append (list (cadr lista)) (list (car lista)) (cddr lista)))(repl)) 
        ((equal? (car lista) "EXIT") (display "Bye.")(set! lista (cdr lista))) 
        ((equal? inp "DROP")(set! lista (cddr lista))(repl)) 
        ((equal? (car lista) "POP") 
         (set! lista (cdr lista)) 
         (cond 
           ((null? lista)(display "Empty Stack")(repl)) 
           ((string->number (car lista))(set! pop (car lista))(set! lista (cdr lista))(repl) ) 
           ((search (car lista) sym symval) 
            (cond 
              ((null? (cdr lista)) (set! lista (cdr lista)) 
              (display "Empty Stack") (repl)) 
              (else 
               (addsym (car lista) (cadr lista)) 
               (set! pop (cadr lista)) 
               (set! lista (cddr lista)) 
               (repl)))) 

           (else 
            (set! lista (cdr lista)) 
            (display "Var not declared")(repl)))) 

        ((equal? inp "SAVE") 
         (set! lista (cdr lista)) 
         (cond 
           ((equal? pop "")(display "Can't SAVE null")) 
           (else  (set! lista (append (list pop) lista))(set! pop ""))) 
         (repl)) 
        ((equal? inp "DUP")(set! lista (cdr lista))(set! lista (append (list (car lista)) lista))(repl)) 
        ((equal? (op? (car lista)) ".")(set! lista (cdr lista)) 
        (cond 
          ((equal? lengtha 1)(if (null? lista) (display "Empty Stack") (display (car lista)))(repl)) 
          (else (displayn (- lengtha 1))(repl)))) 
        ((string->number (car lista)) 
         (cond 
           ((null? (cdr lista))(repl)) 
           ((op? (cadr lista))(repl)) 
           (else (set! lista (cleanup-eval lista))(repl)))) 
        ((equal? (car lista) "define") 
         (set! lista (cdr lista)) 
         (set! sym (append (list (car lista)) sym)) 
         (set! lista (cdr lista)) 
         (cond 
           ((string->number (car lista)) 
            (set! symval (append (list (string->number (car lista))) symval))) 
           (else 
            (set! symval (append (list (car lista)) symval)))) 


         (set! lista (cdr lista)) 
         (repl) ) 
        (else 
         (cond 
           ((search (car lista) sym symval)(set! lista (append (list (cadr res)) (cdr lista))) 
           (if (number? (car lista)) (set! lista (append (list(number->string (car lista))))))) 
           (else 
            (display (car lista))(set! lista (cdr lista)))))) 
            (repl)))) 

edit: for the above definition, i tried doing this as an alternative, but it just results in my stack,rev and the other command just printing out their own names...

(define repl
             (lambda()
              (display "\nUofL>")
              (let ((inp (read-command))
                    (lengtha (length com))
2

2 Answers

1
votes

Internal definitions can only be at the beginning of a procedure (or implicit-procedure contexts, like let bodies). In any case, they're syntactic sugar for letrec* forms, and you can always rewrite in terms of that.

1
votes

If you have read your R5RS bible you know it's not allowed to have local define after any other expressions. Thus:

(define (read-command) 
  (set! com '( '() ))             ;; illegal needs to go after ret1 define
  (set! wl (read-as-list))        ;; illegal needs to go after ret1 define
  (define ret1 (list->string wl))
  (commRead) 
  ret1) 

I'm not sure what the global variables com or w1 are for, but you can set them later. In fact you don't need define at all:

(define (read-command) 
  (let* ((tmp-w1 (read-as-list))
         (ret1 (list->string tmp-wl)))
    (set! com '( '() ))
    (set! wl tmp-w1)
    (commRead) 
    ret1))

EDIT

Here is a rewrite for repl as well:

(define (repl) 
  (display "\nUofL>") 
  (let* ((inp (read-command)) 
         (lengtha (length com))) 
    (cond 
      ((equal? inp "CLEAR")(set! lista '())(repl)) 
      ((equal? inp "REV")(set! lista (cdr lista))(set! lista (rev lista))(repl)) 
      ((equal? inp "STACK")(set! lista (cdr lista))(display lista)(repl)) 
      ((equal? inp "SWAP")(set! lista (cdr lista))(set! lista (append (list (cadr lista)) (list (car lista)) (cddr lista)))(repl)) 
      ((equal? (car lista) "EXIT") (display "Bye.")(set! lista (cdr lista))) 
      ((equal? inp "DROP")(set! lista (cddr lista))(repl)) 
      ((equal? (car lista) "POP") 
       (set! lista (cdr lista)) 
       (cond 
         ((null? lista)(display "Empty Stack")(repl)) 
         ((string->number (car lista))(set! pop (car lista))(set! lista (cdr lista))(repl) ) 
         ((search (car lista) sym symval) 
          (cond 
            ((null? (cdr lista)) (set! lista (cdr lista)) 
                                 (display "Empty Stack") (repl)) 
            (else 
             (addsym (car lista) (cadr lista)) 
             (set! pop (cadr lista)) 
             (set! lista (cddr lista)) 
             (repl)))) 

         (else 
          (set! lista (cdr lista)) 
          (display "Var not declared")(repl)))) 

      ((equal? inp "SAVE") 
       (set! lista (cdr lista)) 
       (cond 
         ((equal? pop "")(display "Can't SAVE null")) 
         (else  (set! lista (append (list pop) lista))(set! pop ""))) 
       (repl)) 
      ((equal? inp "DUP")(set! lista (cdr lista))(set! lista (append (list (car lista)) lista))(repl)) 
      ((equal? (op? (car lista)) ".")(set! lista (cdr lista)) 
                                     (cond 
                                       ((equal? lengtha 1)(if (null? lista) (display "Empty Stack") (display (car lista)))(repl)) 
                                       (else (displayn (- lengtha 1))(repl)))) 
      ((string->number (car lista)) 
       (cond 
         ((null? (cdr lista))(repl)) 
         ((op? (cadr lista))(repl)) 
         (else (set! lista (cleanup-eval lista))(repl)))) 
      ((equal? (car lista) "define") 
       (set! lista (cdr lista)) 
       (set! sym (append (list (car lista)) sym)) 
       (set! lista (cdr lista)) 
       (cond 
         ((string->number (car lista)) 
          (set! symval (append (list (string->number (car lista))) symval))) 
         (else 
          (set! symval (append (list (car lista)) symval)))) 

Since you are using R5RS I used let* here too in case there are side effects. A let won't necessarily evaluate it's argument left to right though I expect PLTs implementation to do that.

I'm sure you could do without a lot of side effects here. Instead of relying on global variables you could just pass them along. It would make your program easier to test and debug.