diff options
author | Case Duckworth | 2024-04-16 22:28:51 -0500 |
---|---|---|
committer | Case Duckworth | 2024-04-16 22:28:51 -0500 |
commit | d8bc4b0236cc09ac45323bffcd740388aab57e1d (patch) | |
tree | 9f96cfeaaabf708ef61f30934196cccc8bce65c8 | |
parent | Don't error on empty input (diff) | |
download | lam-d8bc4b0236cc09ac45323bffcd740388aab57e1d.tar.gz lam-d8bc4b0236cc09ac45323bffcd740388aab57e1d.zip |
Fix a subtle bug in adding parameters to local procedure envs
I couldn't use e[p[1]] = r[1] because that invokes environment's __newindex metamethod, which is equivalent to `set!' -- that is, it mutates the existing binding from the closest enclosing environment
-rw-r--r-- | type.lua | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/type.lua b/type.lua index e4fccc9..e2370b6 100644 --- a/type.lua +++ b/type.lua | |||
@@ -299,8 +299,7 @@ function m.procedure (params, body, env, eval) | |||
299 | end | 299 | end |
300 | -- (lambda x ..) or (lambda (x . y) ..) | 300 | -- (lambda x ..) or (lambda (x . y) ..) |
301 | if type.isp(p, "symbol") then | 301 | if type.isp(p, "symbol") then |
302 | e[p] = r | 302 | return rawset(e, p, r) |
303 | return e | ||
304 | end | 303 | end |
305 | if p[1] == nil then | 304 | if p[1] == nil then |
306 | error("too many arguments", | 305 | error("too many arguments", |
@@ -311,7 +310,7 @@ function m.procedure (params, body, env, eval) | |||
311 | rlen, #self.params) | 310 | rlen, #self.params) |
312 | end | 311 | end |
313 | -- bind car(p) to car(r) | 312 | -- bind car(p) to car(r) |
314 | e[p[1]] = r[1] | 313 | rawset(e, p[1], r[1]) |
315 | -- recurse | 314 | -- recurse |
316 | return doargs(p[2], r[2], e) | 315 | return doargs(p[2], r[2], e) |
317 | end | 316 | end |