summaryrefslogtreecommitdiffstats
path: root/combi.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-08-28 06:59:46 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-08-28 06:59:46 -0700
commit5dfae394410270cb884f32d4f8591a60e1e4a76c (patch)
tree7582ca1f78e676e5781330121f4000c5c75eea98 /combi.h
parentb4360fddf3f7368d618b3a706397c2b437ba074f (diff)
downloadtxr-5dfae394410270cb884f32d4f8591a60e1e4a76c.tar.gz
txr-5dfae394410270cb884f32d4f8591a60e1e4a76c.tar.bz2
txr-5dfae394410270cb884f32d4f8591a60e1e4a76c.zip
compiler: bugfix: incorrect scoping in macro param binding.
The destructuring binder binds all of the variables in the template to nil values and then assigns to them as it walks the object that is being destructured. Unfortunately, this results in incorrect treatment of init-forms, which are evaluated in the wrong scope. They are actually evaluated in completely the wrong scope due to the use of up:env, but the problem can't be fixed by removing up:env. The approach here is to generate a big let* construct that binds the variables in sequence, rather than assigning to them. * share/txr/stdlib/compiler.tl (expand-bind-mac-params): The basic structure of the code remains the same, but the details are rewritten. Instead of emitting a body of forms, we emit let* bindings. Because some of the logic requires imperative statements, like stepping pointers through the destructured object, these are mixed into the variable initializations via progn. The local functions emit-stmt and emit-var provide the interface for doing this. There is a bit of trickery in the situation that an optional parameter also has the presence-indicator variable. We must bind the parameter in an environment in which that presence-indicator variable is not yet visible. This is achieved by binding the variable to a nil value, and then binding the presence indicator to an expression which sets the variable's value as a side effect, and yields a Boolean value that initializes the indicator.
Diffstat (limited to 'combi.h')
0 files changed, 0 insertions, 0 deletions