femtolisp icon indicating copy to clipboard operation
femtolisp copied to clipboard

Compiler leaking globals when (define var) not direct member of a lambda

Open jniewerth opened this issue 8 years ago • 1 comments

The following code leaks a as a global:

(define (func)
   (if #t 
             (define a 5)
   ))

I could fix this by duplicating get-defined-vars from compiler.lsp (was used by expander + compiler) and changing get-defined-vars for the compiler like this:

(define (get-defined-vars expr)
  (letrec ((get-defined-vars-
            (lambda (expr)
              (cond
               ((atom? expr) ())
               ((and
                 (eq? (car expr) 'define)
                 (pair? (cdr expr))
                 )
                (or
                 (and
                  (symbol? (cadr expr))
                  (list* (cadr expr) (get-defined-vars- (caddr expr )))
                  )
                 (and (pair? (cadr expr))
                      (symbol? (caadr expr))
                      (list (caadr expr)))
                 ()
                 )
                )
               ((not (member (car expr) (list 'lambda 'trycatch )))
                (apply nconc (map get-defined-vars- (cdr expr))))
               (else ())))))
    (delete-duplicates (get-defined-vars- expr))))

Before that change the scanner did only descent into "begin" blocks but not deeper.

jniewerth avatar Feb 15 '17 13:02 jniewerth

Thanks for finding this. Is there a reason not to use the corrected code in both the expander and compiler?

JeffBezanson avatar Jun 06 '19 23:06 JeffBezanson