Skip to content

Commit 4fe235e

Browse files
authored
Merge pull request #645 from OpenVADL/bugfix/fix-crash-in-higher-order-macros-too-many-arguments
parser: Fix crash in higher order macros with too many arguments
2 parents e495391 + 67a63f9 commit 4fe235e

File tree

4 files changed

+66
-9
lines changed

4 files changed

+66
-9
lines changed

vadl/main/vadl/ast/ParserUtils.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -528,16 +528,30 @@ static Diagnostic unknownSyntaxTypeError(String name, SymbolTable macroTable,
528528
.build();
529529
}
530530

531-
static Diagnostic tooManyMacroArgumentsError(Macro macro, SourceLocation location) {
531+
static Diagnostic tooManyMacroArgumentsError(@Nullable Macro macro, SyntaxType type,
532+
SourceLocation location) {
532533
// Unfortunately, we need the types of the macro parameters to parse the invocation to
533534
// completion. But if more arguments are provided than parameter are defined we cannot parse
534535
// them and therefore only know that too many exist but not how many were provided.
535-
return error("Invalid Model Invocation", location)
536-
.locationDescription(location,
537-
"Model `%s` only expected %d arguments but, you provided at least %d.",
538-
macro.name().name,
539-
macro.params().size(), macro.params().size() + 1)
540-
.build();
536+
// The macro may not exist if we are calling a macro that is passed to the current macro, in
537+
// which case we need to rely on the type.
538+
var builder = error("Invalid Model Invocation", location);
539+
if (macro != null) {
540+
builder.locationDescription(location,
541+
"Model `%s` only expected %d arguments but, you provided at least %d.",
542+
macro.name().name,
543+
macro.params().size(), macro.params().size() + 1);
544+
} else {
545+
var argCount = switch (type) {
546+
case ProjectionType pt -> pt.arguments.size();
547+
default -> 1;
548+
};
549+
550+
builder.locationDescription(location,
551+
"The model only expected %d arguments but, you provided at least %d.",
552+
argCount, argCount + 1);
553+
}
554+
return builder.build();
541555
}
542556

543557
private static boolean isPlaceholder(Node n) {

vadl/main/vadl/ast/vadl.ATG

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,15 +2062,15 @@ PRODUCTIONS
20622062
// If too many arguments exist we cannot parse them because we
20632063
// need the information from the model signature to know how to
20642064
// parse them so instead we must abort parsing and throw an error.
2065-
if (!params.hasNext()) throw ParserUtils.tooManyMacroArgumentsError(macro, nextTokenLoc());
2065+
if (!params.hasNext()) throw ParserUtils.tooManyMacroArgumentsError(macro, paramType, nextTokenLoc());
20662066
.)
20672067
macroBody<out Node arg1, params.next()> (. args.add(arg1); .)
20682068
{
20692069
SYM_SEMICOLON (.
20702070
// If too many arguments exist we cannot parse them because we
20712071
// need the information from the model signature to know how to
20722072
// parse them so instead we must abort parsing and throw an error.
2073-
if (!params.hasNext()) throw ParserUtils.tooManyMacroArgumentsError(macro, nextTokenLoc());
2073+
if (!params.hasNext()) throw ParserUtils.tooManyMacroArgumentsError(macro, paramType,nextTokenLoc());
20742074
.)
20752075
macroBody<out Node arg2, params.next()> (. args.add(arg2); .)
20762076
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// In a previous version this example lead to a crash
2+
// This was only because the error code assumed that the invalidly called macro always exists but since we support
3+
// higher order macros like this, the assumption isn't correct.
4+
// https://github.com/OpenVADL/openvadl/issues/644
5+
6+
record InstrWithFunct (id: Id, mnemo: Str, opcode: Ex, funct: Id)
7+
8+
model-type InstrWithFunctElemSize = (InstrWithFunct, Id, Id) -> IsaDefs
9+
10+
model InstrBHSD (modelid: InstrWithFunctElemSize, i: InstrWithFunct): IsaDefs = {
11+
$modelid ($i; ElementsB; SizeB; ".B")
12+
}
13+
14+
15+
// Reported Diagnostics:
16+
//
17+
// error: Invalid Model Invocation
18+
// ╭──[test/resources/diagnostics/parser/invalidHigherOrderMacroWithTooManyArguments.vadl:11:35]
19+
// │
20+
// 11 │ $modelid ($i; ElementsB; SizeB; ".B")
21+
// │ ^^^^ The model only expected 3 arguments but, you provided at least 4.
22+
// │
23+
//
24+
//
25+
// Part of the class vadl.ast.DiagnosticsTest
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
model flo (id: Id): Ex = {
2+
1 + 2
3+
}
4+
5+
constant x = $flo(y; z)
6+
7+
8+
// Reported Diagnostics:
9+
//
10+
// error: Invalid Model Invocation
11+
// ╭──[test/resources/diagnostics/parser/invalidModelWithTooManyArguments.vadl:5:22]
12+
// │
13+
// 5 │ constant x = $flo(y; z)
14+
// │ ^ Model `flo` only expected 1 arguments but, you provided at least 2.
15+
// │
16+
//
17+
//
18+
// Part of the class vadl.ast.DiagnosticsTest

0 commit comments

Comments
 (0)