summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-07-17 20:13:15 -0700
committerKaz Kylheku <kaz@kylheku.com>2023-07-17 20:13:15 -0700
commitef239fb96066c558fd8965dce8ab923162f5519e (patch)
tree790aac016a611cbd87d699797e7c9fe21666d681
parentb1b84927153006f4f444908d21f9f37d387b552d (diff)
downloadtxr-ef239fb96066c558fd8965dce8ab923162f5519e.tar.gz
txr-ef239fb96066c558fd8965dce8ab923162f5519e.tar.bz2
txr-ef239fb96066c558fd8965dce8ab923162f5519e.zip
Bug exposed due to to environment changes.
There was a bug in rt_defun in that it was not calling vm_invalidate_binding. This mean that compiled functions were not picking up redefinitions. This bug is fixed now because rt_defun now calls sethash on the top_fb directly, which modifies the existing binding cell; it is not allocating a new cell. We put in new test cases to confirm the proper redefinition behaviors. The proper redefinition behavior exposes an issue in pattern matching. * tests/019/redef.tl: New file. * stdlib/match.tl (transform-quote): This function's compiled image, when deposited into a .tlo file, becomes incorrect because (sys:hash-lit) turns into #H() syntax, which reads back as something else. In other words (sys:hash-lit) deosn't have print-read consistency and so doesn't externalize. To fix this right we would need a print mode which ensures machine readability rather than human readability, like in Common Lisp. For now, we just break up the pattern so that it's not a literal match. This bug was hidden due to theredefinition issue. When match.tl is being compiled, it defines non-triv-pat-p twice. Due to redefinitions not kicking in properly, the first definition of non-triv-pat-p remains in effect for some functions. When transform-qquote is being expanded, the (sys:hash-lit) pattern is treated as non-trivial, even though it is is trivial, and so it is turned into pattern matching code. The code doesn't contain a (sys:hash-lit) literal and so the issue doesn't occur.
-rw-r--r--stdlib/match.tl2
-rw-r--r--tests/019/redef.tl19
2 files changed, 20 insertions, 1 deletions
diff --git a/stdlib/match.tl b/stdlib/match.tl
index fb11aa4f..149ea71f 100644
--- a/stdlib/match.tl
+++ b/stdlib/match.tl
@@ -1088,7 +1088,7 @@
((sys:hash-lit nil . @(all (@key @val)))
^@(hash ,*(zip [mapcar transform-qquote key]
[mapcar transform-qquote val])))
- ((sys:hash-lit)
+ ((sys:hash-lit . @(eq nil))
'@(hash))
((sys:struct-lit @type . @args)
^@(struct ,(transform-qquote type)
diff --git a/tests/019/redef.tl b/tests/019/redef.tl
new file mode 100644
index 00000000..036fb8c9
--- /dev/null
+++ b/tests/019/redef.tl
@@ -0,0 +1,19 @@
+(load "../common")
+
+(defun foo () :foo)
+
+(defvar foov :foov)
+
+(defun bar () (list (foo) foov))
+
+(compile 'bar)
+
+(test (bar) (:foo :foov))
+
+(defun foo () :bar)
+
+(makunbound 'foov)
+
+(defparml foov :barv)
+
+(test (bar) (:bar :barv))