Skip to content

Commit a831592

Browse files
committed
fix another bug in macro scoping
1 parent 1f1e7b9 commit a831592

File tree

4 files changed

+42
-24
lines changed

4 files changed

+42
-24
lines changed

src/compile/mod.rs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ use crate::{
3232
function::DynamicFunction,
3333
lsp::{CodeMeta, Completion, ImportSrc, SetInverses, SigDecl},
3434
media::{LayoutParam, VoxelsParam},
35-
parse::ident_modifier_args,
3635
parse::{
37-
flip_unsplit_items, flip_unsplit_lines, max_placeholder, parse, split_items, split_words,
36+
flip_unsplit_items, flip_unsplit_lines, ident_modifier_args, max_placeholder, parse,
37+
split_items, split_words,
3838
},
3939
Array, ArrayValue, Assembly, BindingKind, BindingMeta, Boxed, CodeSpan, CustomInverse,
40-
Diagnostic, DiagnosticKind, DocComment, DocCommentSig, Function, FunctionId, GitTarget, Ident,
41-
ImplPrimitive, InputSrc, IntoInputSrc, IntoSysBackend, Node, NumericSubscript, PrimClass,
42-
Primitive, Purity, RunMode, SemanticComment, SigNode, Signature, Sp, Span, SubSide, Subscript,
43-
SysBackend, Uiua, UiuaError, UiuaErrorKind, UiuaResult, Value, CONSTANTS, EXAMPLE_UA,
44-
SUBSCRIPT_DIGITS, VERSION,
40+
Diagnostic, DiagnosticKind, DocComment, DocCommentSig, ExactDoubleIterator, Function,
41+
FunctionId, GitTarget, Ident, ImplPrimitive, InputSrc, IntoInputSrc, IntoSysBackend, Node,
42+
NumericSubscript, PrimClass, Primitive, Purity, RunMode, SemanticComment, SigNode, Signature,
43+
Sp, Span, SubSide, Subscript, SysBackend, Uiua, UiuaError, UiuaErrorKind, UiuaResult, Value,
44+
CONSTANTS, EXAMPLE_UA, SUBSCRIPT_DIGITS, VERSION,
4545
};
4646
pub(crate) use data::*;
4747
pub use pre_eval::PreEvalMode;
@@ -231,7 +231,7 @@ enum ScopeKind {
231231
/// A scope that includes all bindings in a module
232232
AllInModule,
233233
/// A temporary scope, probably for a macro
234-
Temp(Option<MacroLocal>),
234+
Macro(Option<MacroLocal>),
235235
/// A binding scope
236236
Binding,
237237
/// A function scope between some delimiters
@@ -389,8 +389,11 @@ impl Compiler {
389389
let src = self.asm.inputs.add_src(src, input);
390390
self.load_impl(input, src)
391391
}
392-
fn scopes(&self) -> impl Iterator<Item = &Scope> {
393-
once(&self.scope).chain(self.higher_scopes.iter().rev())
392+
fn scopes(&self) -> impl ExactDoubleIterator<Item = &Scope> {
393+
once(&self.scope)
394+
.chain(self.higher_scopes.iter().rev())
395+
.collect::<Vec<_>>()
396+
.into_iter()
394397
}
395398
#[allow(dead_code)]
396399
fn scopes_mut(&mut self) -> impl Iterator<Item = &mut Scope> {
@@ -1686,23 +1689,23 @@ impl Compiler {
16861689
// for scope in self.scopes() {
16871690
// println!(" {:?} {:?}", scope.kind, scope.names);
16881691
// }
1692+
let skip = if skip_temp {
1693+
self.scopes()
1694+
.rposition(|sc| matches!(sc.kind, ScopeKind::Macro(_)))
1695+
.map(|s| s + 1)
1696+
.unwrap_or(0)
1697+
} else {
1698+
0
1699+
};
16891700
let mut hit_file = false;
1690-
let mut hit_temp = false;
1691-
for scope in self.scopes() {
1701+
for scope in self.scopes().skip(skip) {
16921702
if matches!(scope.kind, ScopeKind::File(_))
16931703
|| stop_at_binding && matches!(scope.kind, ScopeKind::Binding)
16941704
{
16951705
if hit_file {
16961706
break;
16971707
}
16981708
hit_file = true;
1699-
} else if matches!(scope.kind, ScopeKind::Temp(_)) {
1700-
if skip_temp && !hit_temp {
1701-
hit_temp = true;
1702-
continue;
1703-
}
1704-
} else if skip_temp && !hit_temp {
1705-
continue;
17061709
}
17071710
if let Some(local) = scope.names.get(name).copied() {
17081711
return Some(local);
@@ -2814,7 +2817,7 @@ impl Compiler {
28142817
}
28152818
SetterStashKind::Scope(ScopeKind::Binding) => "binding",
28162819
SetterStashKind::Scope(ScopeKind::File(_)) => "file",
2817-
SetterStashKind::Scope(ScopeKind::Temp(_)) => "macro",
2820+
SetterStashKind::Scope(ScopeKind::Macro(_)) => "macro",
28182821
SetterStashKind::Scope(ScopeKind::Module(_)) => "module",
28192822
SetterStashKind::Scope(ScopeKind::Test) => "test scope",
28202823
};

src/compile/modifier.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,7 @@ impl Compiler {
15801580
) -> UiuaResult<Node> {
15811581
let span = self.add_span(ref_span.clone());
15821582
Ok(match self.scope.kind {
1583-
ScopeKind::Temp(Some(mac_local)) if mac_local.macro_index == local.index => {
1583+
ScopeKind::Macro(Some(mac_local)) if mac_local.macro_index == local.index => {
15841584
// Recursive
15851585
if let Some(sig) = mac.sig {
15861586
Node::CallMacro {
@@ -1968,7 +1968,7 @@ impl Compiler {
19681968
let orig_names = names.clone();
19691969
// Create temp scope
19701970
let temp_scope = Scope {
1971-
kind: ScopeKind::Temp(macro_local),
1971+
kind: ScopeKind::Macro(macro_local),
19721972
names,
19731973
experimental: self.scope.experimental,
19741974
experimental_error: self.scope.experimental_error,

tests/macros.ua

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# Index macros
1+
################
2+
# Index macros #
3+
################
24
F! ← ^0 5
35
G! ← F!^0
46
⍤⤙≍ ¯5 G!¯
@@ -28,6 +30,7 @@ F! ← ⨬(
2830
F! ← -^0 i
2931
⍤⤙≍ i F!0
3032

33+
# Scoping shenanigans
3134
┌─╴M
3235
X ← "Inner"
3336
A! ← ^0
@@ -37,7 +40,18 @@ X ← "Outer"
3740
⍤⤙≍ "Outer" M~A!X
3841
⍤⤙≍ "Outer" M~B!X
3942

40-
# Code macros
43+
┌─╴Mod
44+
X ← "Inner"
45+
Mac₁! ← ^0
46+
Mac₂! ← Mac₁!^0
47+
└─╴
48+
X ← "Outer"
49+
⍤⤙≍ "Outer" Mod~Mac₁!X
50+
⍤⤙≍ "Outer" Mod~Mac₂!X
51+
52+
###############
53+
# Code macros #
54+
###############
4155
F! ←^
4256
G! ←^ ⇌
4357
H‼ ←^ ⊂⊢.

todo.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# 0.17
44
- `Variants` field for module
55
- Fix caching with labels
6+
- Fix performance of deep `dip` nesting
67
- Don't serialize sortedness flags
78
- Sided `fork`
89
- Sided `join`

0 commit comments

Comments
 (0)