5ff7353e5f4508d427c30baee6233140b5c71a7a — Alex Karle 1 year, 5 months ago e98c287
assignment: Fix assignment vs definition bug

I had intermingled assignment and definition such that

var x = 5;


x = 5;

did the same thing, when really the first should create a new binding
in the current environment and the second should update the value in
*whichever environment has x defined (the closest one)*.

This was found while implementing 'while' since the following was an
infinite loop:

var x = 10;
while (x > 0) {
    print x;
    x = x - 1;

With the splitting of var -> env-def! and = -> env-set! in this patch,
it works as expected!
1 files changed, 13 insertions(+), 2 deletions(-)

M interpreter.scm
M interpreter.scm => interpreter.scm +13 -2
@@ 15,9 15,17 @@
		   (if parent
		       (env-get parent el)
		       (runtime-err! (format "Unbound variable ~A" el))))))
	    ((eq? action 'set)
	    ((eq? action 'def)
	     ;; var block, sets in current env
	     (lambda (el val)
	       (hash-table-set! ht el val)))
	    ((eq? action 'set)
	     (lambda (el val)
	       (if (hash-table-exists? ht el)
		   (hash-table-set! ht el val)
		   (if parent
		       (env-set! parent el val)
		       (runtime-err! (format "Unable to set unbound variable ~A" el))))))
	    ((eq? action 'exists)
	     (lambda (el)
	       (if (hash-table-exists? ht el)

@@ 31,6 39,9 @@
(define (env-set! env key val)
  ((env 'set) key val))

(define (env-def! env key val)
  ((env 'def) key val))

(define (env-exists? env key)
  ((env 'exists) key))

@@ 145,7 156,7 @@
            (if (null? (var-stmt-init stmt))
              (evaluate (var-stmt-init stmt) env))))
      (env-set! env (token-lexeme (var-stmt-name stmt)) value))
      (env-def! env (token-lexeme (var-stmt-name stmt)) value))
   ((expr-stmt? stmt)
    (let ((res (evaluate (expr-stmt-value stmt) env)))