Skip to content

Commit 87e451d

Browse files
committed
only allow placeholder shorthand in monadic index macros
1 parent 3c90c70 commit 87e451d

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

parser/src/parse.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,18 +1998,26 @@ pub fn ident_modifier_args(ident: &str) -> usize {
19981998
count
19991999
}
20002000

2001-
/// Get the maximum placeholder index in a list of words
2002-
pub fn max_placeholder(words: &[Sp<Word>]) -> Option<usize> {
2001+
/// Get the maximum placeholder index in a list of words,
2002+
/// as well as the span of a placeholder shorthand
2003+
pub fn max_placeholder(words: &[Sp<Word>]) -> Option<(usize, Option<CodeSpan>)> {
20032004
let mut max: Option<usize> = None;
2004-
let mut set = |i: Option<usize>| {
2005-
if let Some(i) = i {
2005+
let mut shorthand_span = None;
2006+
let mut set = |is: Option<(usize, Option<CodeSpan>)>| {
2007+
if let Some((i, s)) = is {
20062008
let max = max.get_or_insert(0);
20072009
*max = (*max).max(i);
2010+
if shorthand_span.is_none() && s.is_some() {
2011+
shorthand_span = s;
2012+
}
20082013
}
20092014
};
20102015
for word in words {
20112016
match &word.value {
2012-
Word::Placeholder(i) => set(Some(i.unwrap_or(0))),
2017+
Word::Placeholder(i) => set(Some((
2018+
i.unwrap_or(0),
2019+
i.is_none().then(|| word.span.clone()),
2020+
))),
20132021
Word::Strand(items) => set(max_placeholder(items)),
20142022
Word::Array(arr) => {
20152023
for line in arr.word_lines() {
@@ -2033,7 +2041,7 @@ pub fn max_placeholder(words: &[Sp<Word>]) -> Option<usize> {
20332041
_ => {}
20342042
}
20352043
}
2036-
max
2044+
max.map(|i| (i, shorthand_span))
20372045
}
20382046

20392047
/// Trim space words

src/compile/binding.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ impl Compiler {
183183
return Ok(());
184184
}
185185
// Index macro
186-
match (ident_margs, max_placeholder) {
186+
match (ident_margs, &max_placeholder) {
187187
(0, None) => {}
188188
(_, None) => {
189189
self.add_error(
@@ -204,7 +204,7 @@ impl Compiler {
204204
);
205205
return Ok(());
206206
}
207-
(n, Some(max)) => {
207+
(n, Some((max, shorthand_span))) => {
208208
if max + 1 > n {
209209
self.emit_diagnostic(
210210
format!(
@@ -216,6 +216,17 @@ impl Compiler {
216216
span.clone(),
217217
);
218218
}
219+
if let Some(span) = shorthand_span {
220+
if *max > 0 {
221+
self.add_error(
222+
span.clone(),
223+
format!(
224+
"`{name}` cannot use the placeholder shorthand \
225+
because it contains a ^{max}. Use explicit ^0 instead."
226+
),
227+
)
228+
}
229+
}
219230
}
220231
}
221232
if max_placeholder.is_some() || ident_margs > 0 {

tests_special/error.ua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,6 @@ F ← |0.1000 ⍢(F F F|1)
186186

187187
|
188188

189-
+⊸¤⇡1e5
189+
+⊸¤⇡1e5
190+
191+
F‼ ← ^^1

0 commit comments

Comments
 (0)