Support Calling Parsers With Parameters

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-04-02 01:28:43 -04:00
parent 7cdbee1999
commit d971aab1fe
12 changed files with 345 additions and 82 deletions
@@ -160,3 +160,45 @@ import TreeSitterP4
#expect(AsInstantiatedParserState(state_result) == P4Lang.reject)
}
@Test func test_select_expression_from_parser_parameters() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
transition select (pmtr) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
let args = ArgumentList([
P4BooleanValue(withValue: false), P4StringValue(withValue: "Testing"), P4IntValue(withValue: 5),
])
let (state_result, _) = try! #UseOkResult(runtime.run(withArguments: args))
#expect(AsInstantiatedParserState(state_result) == P4Lang.reject)
}
@Test func test_select_expression_from_parser_parameters2() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
transition select (imtr == 5) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
let args = ArgumentList([
P4BooleanValue(withValue: false), P4StringValue(withValue: "Testing"), P4IntValue(withValue: 5),
])
let (state_result, _) = try! #UseOkResult(runtime.run(withArguments: args))
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
}
@@ -169,3 +169,16 @@ import P4Lang
#expect(parameters.parameters[2].name == Identifier(name: "imtr"))
#expect(parameters.parameters[2].type.eq(rhs: P4Int()))
}
@Test func test_simple_compiler_parser_use_parameters() async throws {
let simple = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
pmtr = true;
transition accept;
}
};
"""
#expect(#RequireOkResult(Program.Compile(simple)))
}
+91
View File
@@ -80,3 +80,94 @@ import TreeSitterP4
Error(withMessage: "Could not find the start state"),
runtime.run()))
}
@Test func test_simple_runtime_parser_with_parameters() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
transition select (pmtr) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
let args = ArgumentList([
P4BooleanValue(withValue: true), P4StringValue(withValue: "Testing"), P4IntValue(withValue: 5),
])
let (state_result, _) = try! #UseOkResult(runtime.run(withArguments: args))
// We should be in the accept state.
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
}
@Test func test_simple_runtime_parser_with_mismatched_parameter_types() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
transition select (pmtr) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
let args = ArgumentList([
P4BooleanValue(withValue: true), P4BooleanValue(withValue: false), P4IntValue(withValue: 5),
])
#expect(
#RequireErrorResult<(ParserState, ProgramExecution)>(
Error(withMessage: "Cannot call parser: Argument 2's type (Boolean) is incompatible with the parameter type (String)"),
runtime.run(withArguments: args)))
}
@Test func test_simple_runtime_parser_with_mismatched_parameter_types2() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
transition select (pmtr) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
let args = ArgumentList([
P4IntValue(withValue: 5), P4StringValue(withValue: "Testing"), P4IntValue(withValue: 5),
])
#expect(
#RequireErrorResult<(ParserState, ProgramExecution)>(
Error(withMessage: "Cannot call parser: Argument 1's type (Int) is incompatible with the parameter type (Boolean)"),
runtime.run(withArguments: args)))
}
@Test func test_simple_runtime_parser_with_mismatched_parameter_counts() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
transition select (pmtr) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
let args = ArgumentList([P4BooleanValue(withValue: true)])
#expect(
#RequireErrorResult<(ParserState, ProgramExecution)>(
Error(withMessage: "Cannot call parser: 1 arguments found but 3 required"),
runtime.run(withArguments: args)))
}
@@ -262,3 +262,20 @@ import TreeSitterP4
),
Program.Compile(simple_parser_declaration, withGlobalInstances: test_types)))
}
@Test func test_simple_compiler_parser_parameters_invalid_types() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
pmtr = 1;
transition accept;
}
};
"""
#expect(
#RequireErrorResult(
Error(
withMessage: "{85, 9}: Failed to parse a statement element: {85, 4}: Cannot assign value with type Int to identifier pmtr with type Boolean"
),
Program.Compile(simple_parser_declaration)))
}