Skip to content

Commit a47c6da

Browse files
committed
Emit error if parenthesis absent from declaration
1 parent c3588b9 commit a47c6da

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

src/parsing/parser.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub enum ParsingError {
3939
InvalidForma(usize),
4040
InvalidGenus(usize),
4141
InvalidSignature(usize),
42+
InvalidParameters(usize),
4243
InvalidDeclaration(usize),
4344
InvalidSection(usize),
4445
InvalidInvocation(usize),
@@ -76,6 +77,7 @@ impl ParsingError {
7677
ParsingError::InvalidGenus(offset) => *offset,
7778
ParsingError::InvalidSignature(offset) => *offset,
7879
ParsingError::InvalidDeclaration(offset) => *offset,
80+
ParsingError::InvalidParameters(offset) => *offset,
7981
ParsingError::InvalidSection(offset) => *offset,
8082
ParsingError::InvalidInvocation(offset) => *offset,
8183
ParsingError::InvalidFunction(offset) => *offset,
@@ -856,6 +858,23 @@ impl<'i> Parser<'i> {
856858

857859
(name, parameters)
858860
} else {
861+
// Check if the text contains multiple space-separated identifiers
862+
// which would indicate parameters without parentheses
863+
let words: Vec<&str> = text
864+
.trim()
865+
.split_whitespace()
866+
.collect();
867+
if words.len() > 1 {
868+
// Check if all words look like valid identifiers
869+
let all_valid_identifiers = words
870+
.iter()
871+
.all(|word| validate_identifier(word).is_some());
872+
873+
if all_valid_identifiers {
874+
return Err(ParsingError::InvalidParameters(self.offset));
875+
}
876+
}
877+
859878
let name = validate_identifier(text).ok_or(ParsingError::InvalidIdentifier(
860879
self.offset,
861880
text.to_string(),

src/problem/messages.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,65 @@ Finally, variables can be assigned for the names of the input parameters:
350350
.to_string(),
351351
)
352352
}
353+
ParsingError::InvalidParameters(_) => {
354+
let examples = vec![
355+
Procedure {
356+
name: Identifier("create_bypass"),
357+
parameters: Some(vec![Identifier("a"), Identifier("b")]),
358+
signature: None,
359+
elements: Vec::new(),
360+
},
361+
Procedure {
362+
name: Identifier("bulldoze"),
363+
parameters: Some(vec![Identifier("c")]),
364+
signature: None,
365+
elements: Vec::new(),
366+
},
367+
Procedure {
368+
name: Identifier("lawsuit"),
369+
parameters: None,
370+
signature: Some(Signature {
371+
domain: Genus::Single(Forma("Council")),
372+
range: Genus::List(Forma("Penny")),
373+
}),
374+
elements: Vec::new(),
375+
},
376+
Procedure {
377+
name: Identifier("lawsuit"),
378+
parameters: Some(vec![Identifier("c")]),
379+
signature: Some(Signature {
380+
domain: Genus::Single(Forma("Council")),
381+
range: Genus::List(Forma("Penny")),
382+
}),
383+
elements: Vec::new(),
384+
},
385+
];
386+
387+
(
388+
"Parameters must be enclosed in parentheses".to_string(),
389+
format!(
390+
r#"
391+
Parameters to a procedure must be variables, and enclosed in parentheses. For
392+
example:
393+
394+
{}
395+
{}
396+
397+
Naming the input genus is optional, however; these are both valid procedure
398+
declarations (and in fact the same):
399+
400+
{}
401+
{}
402+
"#,
403+
examples[0].present(renderer),
404+
examples[1].present(renderer),
405+
examples[2].present(renderer),
406+
examples[3].present(renderer)
407+
)
408+
.trim_ascii()
409+
.to_string(),
410+
)
411+
}
353412
ParsingError::InvalidSection(_) => {
354413
// Roman numeral sections don't have AST representation
355414
(
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
% technique v1
2+
3+
make_coffee beans water : Beans Water -> Coffee
4+
5+
# Coffee making procedure
6+
This procedure demonstrates incorrect parameter syntax.
7+
8+
1. Grind the beans.
9+
2. Heat the water.
10+
3. Brew the coffee.

tests/parsing/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ make-coffee : Ingredients -> Coffee
6969
make coffee : Ingredients -> Coffee
7070
"#
7171
.trim_ascii(),
72-
ParsingError::InvalidIdentifier(0, "".to_string()),
72+
ParsingError::InvalidParameters(0),
7373
);
7474
}
7575

0 commit comments

Comments
 (0)