diff --git a/Tests/p4rseTests/ArrayTests.swift b/Tests/p4rseTests/ArrayTests.swift
new file mode 100644
index 0000000..2d2d6bc
--- /dev/null
+++ b/Tests/p4rseTests/ArrayTests.swift
@@ -0,0 +1,255 @@
+// p4rse, Copyright 2026, Will Hawkins
+//
+// This file is part of p4rse.
+//
+// This file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import Common
+import Foundation
+import Macros
+import P4Runtime
+import P4Lang
+import SwiftTreeSitter
+import Testing
+import TreeSitter
+import TreeSitterP4
+
+@testable import P4Compiler
+
+@Test func test_array_access() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ bool where_to = ta[1] == 2;
+ transition select (where_to) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ta"),
+ withValue: P4ArrayValue(withType: P4Int(), withValue: [
+ P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_array_access_invalid_type() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ bool where_to = ta[1];
+ transition select (where_to) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Int())
+ #expect(
+ #RequireErrorResult(
+ Error(
+ withMessage: "{49, 22}: Failed to parse a statement element: {65, 2}: ta does not name an array type"
+ ),
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ )
+}
+
+@Test func test_array_access2() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ bool where_to = ta[0] == 2;
+ transition select (where_to) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ta"),
+ withValue: P4ArrayValue(withType: P4Int(), withValue: [
+ P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.reject)
+}
+
+@Test func test_array_access3() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ transition select (ta[0] == 1) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ta"),
+ withValue: P4ArrayValue(withType: P4Int(), withValue: [
+ P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_array_access4() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ transition select (ta[1] == 2) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ta"),
+ withValue: P4ArrayValue(withType: P4Int(), withValue: [
+ P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_array_access_nested() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ int where_to = ta[0][0];
+ transition select (where_to == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Array(withValueType: P4Int())))
+ var test_values = ValueScopes().enter()
+
+ let nested = P4ArrayValue(
+ withType: P4Int(),
+ withValue: [P4IntValue(withValue: 5), P4IntValue(withValue: 2), P4IntValue(withValue: 3)])
+
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ta"),
+ withValue: P4ArrayValue(withType: P4Array(withValueType: P4Int()), withValue: [nested]))
+
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_array_set() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ ta[1] = 3;
+ bool where_to = ta[1] == 3;
+ transition select (where_to) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ta"),
+ withValue: P4ArrayValue(withType: P4Int(), withValue: [
+ P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_array_set_nested() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ ta[0][0] = 5;
+ int where_to = ta[0][0];
+ transition select (where_to == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Array(withValueType: P4Int())))
+ var test_values = ValueScopes().enter()
+
+ let nested = P4ArrayValue(
+ withType: P4Int(),
+ withValue: [P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3)])
+
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ta"),
+ withValue: P4ArrayValue(withType: P4Array(withValueType: P4Int()), withValue: [nested]))
+
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
diff --git a/Tests/p4rseTests/BinaryOperators.swift b/Tests/p4rseTests/BinaryOperators.swift
new file mode 100644
index 0000000..53836ff
--- /dev/null
+++ b/Tests/p4rseTests/BinaryOperators.swift
@@ -0,0 +1,126 @@
+// p4rse, Copyright 2026, Will Hawkins
+//
+// This file is part of p4rse.
+//
+// This file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import Common
+import Foundation
+import Macros
+import P4Lang
+import P4Runtime
+import SwiftTreeSitter
+import Testing
+import TreeSitter
+import TreeSitterP4
+
+@testable import P4Compiler
+
+@Test func test_simple_parser_binary_operator_equal() async throws {
+ let simple = """
+ parser main_parser() {
+ state start {
+ transition select (true == true) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_simple_parser_binary_operator_equal_not_equal() async throws {
+ let simple = """
+ parser main_parser() {
+ state start {
+ transition select (true == false) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.reject)
+}
+
+@Test func test_simple_parser_binary_operator_equal_integer() async throws {
+ let simple = """
+ parser main_parser() {
+ state start {
+ transition select (5 == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_simple_parser_binary_operator_equal_not_equal_integer() async throws {
+ let simple = """
+ parser main_parser() {
+ state start {
+ transition select (5 == 6) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.reject)
+}
+
+@Test func test_simple_parser_binary_operator_equal_invalid_types() async throws {
+ let simple = """
+ parser main_parser() {
+ state start {
+ transition select (5 == true) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+
+ // TODO: This test should throw an error.
+
+ #expect(state_result == P4Lang.reject)
+}
\ No newline at end of file
diff --git a/Tests/p4rseTests/ConditionalTests.swift b/Tests/p4rseTests/ConditionalTests.swift
new file mode 100644
index 0000000..8101a9c
--- /dev/null
+++ b/Tests/p4rseTests/ConditionalTests.swift
@@ -0,0 +1,82 @@
+// p4rse, Copyright 2026, Will Hawkins
+//
+// This file is part of p4rse.
+//
+// This file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import Common
+import Foundation
+import Macros
+import P4Lang
+import P4Runtime
+import SwiftTreeSitter
+import Testing
+import TreeSitter
+import TreeSitterP4
+
+@testable import P4Compiler
+
+@Test func test_simple_parser_with_conditional_statement() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ bool x = true;
+ string check = "Invalid";
+ if (x) {
+ x = false;
+ check = "valid";
+ }
+ transition select (x) {
+ false: reject;
+ true: accept;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.reject)
+}
+
+@Test func test_simple_parser_with_conditional_statement_and_else() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ bool x = false;
+ string check = "Invalid";
+ if (x) {
+ x = false;
+ check = "a";
+ } else {
+ x = true;
+ check = "b";
+ }
+ transition select (x) {
+ false: reject;
+ true: accept;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(state_result == P4Lang.accept)
+
+}
diff --git a/Tests/p4rseTests/ParserTests.swift b/Tests/p4rseTests/ParserCompilerTests.swift
similarity index 91%
rename from Tests/p4rseTests/ParserTests.swift
rename to Tests/p4rseTests/ParserCompilerTests.swift
index bf13c9d..4e8c2b8 100644
--- a/Tests/p4rseTests/ParserTests.swift
+++ b/Tests/p4rseTests/ParserCompilerTests.swift
@@ -41,7 +41,7 @@ import P4Lang
Program.Compile(simple_parser_declaration)))
}
-@Test func test_simple_parser_with_statement() async throws {
+@Test func test_simple_compilation_with_statement() async throws {
let simple_parser_declaration = """
parser main_parser() {
state start {
@@ -61,7 +61,7 @@ import P4Lang
#expect(state.statements.count == 1)
}
-@Test func test_simple_parser_with_instantiation() async throws {
+@Test func test_simple_compilation_with_instantiation() async throws {
let simple_parser_declaration = """
parser main_parser() {
state start {
@@ -95,7 +95,7 @@ import P4Lang
#expect(compilation_error.msg.contains("asdf"))
}
-@Test func test_simple_parser_macro_nodetype_test() async throws {
+@Test func test_simple_compiler_macro_nodetype_test() async throws {
let simple = """
parser main_parser() {
state start {
@@ -113,6 +113,6 @@ import P4Lang
#expect(
#RequireErrorResult<(EvaluatableStatement, CompilerContext)>(
Error(withMessage: "{2, 154}: Did not find assignment statement"),
- ParserAssignmentStatement.Compile(
+ ParserAssignmentStatement.Compile( // Note: Calling ParserAssignmentStatement compilation directly.
node: result.rootNode!, withContext: CompilerContext(withNames: LexicalScopes()))))
}
diff --git a/Tests/p4rseTests/RuntimeTests.swift b/Tests/p4rseTests/RuntimeTests.swift
index 26c61b4..8e37aa0 100644
--- a/Tests/p4rseTests/RuntimeTests.swift
+++ b/Tests/p4rseTests/RuntimeTests.swift
@@ -80,218 +80,3 @@ import TreeSitterP4
Error(withMessage: "Could not find the start state"),
runtime.run()))
}
-
-@Test func test_simple_parser_with_transition_select_expression() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- transition select (true) {
- false: reject;
- true: accept;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
- let parser = try #UseOkResult(program.find_parser(withName: Identifier(name: "main_parser")))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(parser.states.count() == 1)
-
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_simple_parser_with_transition_select_expression_to_reject() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- transition select (false) {
- false: reject;
- true: accept;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
- let parser = try #UseOkResult(program.find_parser(withName: Identifier(name: "main_parser")))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(parser.states.count() == 1)
- #expect(state_result == P4Lang.reject)
-}
-
-@Test func test_simple_parser_with_conditional_statement() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- bool x = true;
- string check = "Invalid";
- if (x) {
- x = false;
- check = "valid";
- }
- transition select (x) {
- false: reject;
- true: accept;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.reject)
-}
-
-@Test func test_simple_parser_with_conditional_statement_and_else() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- bool x = false;
- string check = "Invalid";
- if (x) {
- x = false;
- check = "a";
- } else {
- x = true;
- check = "b";
- }
- transition select (x) {
- false: reject;
- true: accept;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.accept)
-
-}
-
-@Test func test_no_matching_key_transition() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- transition select (false) {
- true: accept;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
-
- #expect(
- #RequireErrorResult<(ParserState, ProgramExecution)>(
- Error(withMessage: "No key matched the selector"),
- runtime.run()))
-}
-
-@Test func test_simple_parser_binary_operator_equal() async throws {
- let simple = """
- parser main_parser() {
- state start {
- transition select (true == true) {
- true: accept;
- false: reject;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_simple_parser_binary_operator_equal_not_equal() async throws {
- let simple = """
- parser main_parser() {
- state start {
- transition select (true == false) {
- true: accept;
- false: reject;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.reject)
-}
-
-@Test func test_simple_parser_binary_operator_equal_integer() async throws {
- let simple = """
- parser main_parser() {
- state start {
- transition select (5 == 5) {
- true: accept;
- false: reject;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_simple_parser_binary_operator_equal_not_equal_integer() async throws {
- let simple = """
- parser main_parser() {
- state start {
- transition select (5 == 6) {
- true: accept;
- false: reject;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.reject)
-}
-
-@Test func test_simple_parser_binary_operator_equal_invalid_types() async throws {
- let simple = """
- parser main_parser() {
- state start {
- transition select (5 == true) {
- true: accept;
- false: reject;
- };
- }
- };
- """
-
- let program = try #UseOkResult(Program.Compile(simple))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
-
- // TODO: This test should throw an error.
-
- #expect(state_result == P4Lang.reject)
-}
\ No newline at end of file
diff --git a/Tests/p4rseTests/StructTests.swift b/Tests/p4rseTests/StructTests.swift
new file mode 100644
index 0000000..039673e
--- /dev/null
+++ b/Tests/p4rseTests/StructTests.swift
@@ -0,0 +1,406 @@
+// p4rse, Copyright 2026, Will Hawkins
+//
+// This file is part of p4rse.
+//
+// This file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import Common
+import Foundation
+import Macros
+import P4Runtime
+import P4Lang
+import SwiftTreeSitter
+import Testing
+import TreeSitter
+import TreeSitterP4
+
+@testable import P4Compiler
+
+@Test func test_field_access() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ bool where_to = ts.yesno;
+ transition select (where_to) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ let fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
+
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(withType: struct_type, andInitializers: [
+ P4BooleanValue(withValue: true),
+ P4IntValue(withValue: 5),
+ ]))
+
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_field_access_opp() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ bool where_to = ts.yesno;
+ transition select (where_to) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ let fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
+
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(withType: struct_type, andInitializers: [
+ P4BooleanValue(withValue: false),
+ P4IntValue(withValue: 5),
+ ]))
+
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.reject)
+}
+
+
+@Test func test_field_access2() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ transition select (ts.count == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ let fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
+
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(withType: struct_type, andInitializers: [
+ P4BooleanValue(withValue: true),
+ P4IntValue(withValue: 5),
+ ]))
+
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_field_access2_opp() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ transition select (ts.count == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ let fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
+
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(withType: struct_type, andInitializers: [
+ P4BooleanValue(withValue: true),
+ P4IntValue(withValue: 8),
+ ]))
+
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.reject)
+}
+
+@Test func test_field_access_nested() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ int where_to = ts.ty.count;
+ transition select (where_to == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+
+ let ty_fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let ty_struct_type = P4Struct(withName: Identifier(name: "nested"), andFields: ty_fields)
+
+ let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
+ let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
+
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type)
+
+ var test_values = ValueScopes().enter()
+
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(
+ withType: ts_struct_type,
+ andInitializers: [
+ P4StructValue(
+ withType: ty_struct_type,
+ andInitializers: [
+ P4BooleanValue(withValue: true),
+ P4IntValue(withValue: 5),
+ ])
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_field_write() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ ts.yesno = true;
+ bool where_to = ts.yesno;
+ transition select (where_to) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ let fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
+
+ var test_values = ValueScopes().enter()
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(withType: struct_type, andInitializers: [
+ P4BooleanValue(withValue: false),
+ P4IntValue(withValue: 5),
+ ]))
+
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_field_write_invalid_type() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ ts.yesno = 5;
+ transition accept;
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+ let fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
+
+ #expect(
+ #RequireErrorResult(
+ Error(
+ withMessage: "{49, 13}: Failed to parse a statement element: {49, 8}: Cannot assign value of type Int to field with type Boolean"
+ ),
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ )
+}
+
+@Test func test_field_write_nested() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ ts.ty.count = 5;
+ int where_to = ts.ty.count;
+ transition select (where_to == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+
+ let ty_fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let ty_struct_type = P4Struct(withName: Identifier(name: "nested"), andFields: ty_fields)
+
+ let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
+ let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
+
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type)
+
+ var test_values = ValueScopes().enter()
+
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(
+ withType: ts_struct_type,
+ andInitializers: [
+ P4StructValue(
+ withType: ty_struct_type,
+ andInitializers: [
+ P4BooleanValue(withValue: true),
+ P4IntValue(withValue: 7),
+ ])
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_field_write_nested2() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ ts.ty.count = 3;
+ ts.ty.count = 5;
+ int where_to = ts.ty.count;
+ transition select (where_to == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+
+ let ty_fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let ty_struct_type = P4Struct(withName: Identifier(name: "nested"), andFields: ty_fields)
+
+ let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
+ let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
+
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type)
+
+ var test_values = ValueScopes().enter()
+
+ test_values = test_values.declare(
+ identifier: Identifier(name: "ts"),
+ withValue: P4StructValue(
+ withType: ts_struct_type,
+ andInitializers: [
+ P4StructValue(
+ withType: ty_struct_type,
+ andInitializers: [
+ P4BooleanValue(withValue: true),
+ P4IntValue(withValue: 7),
+ ])
+ ]))
+ let program = try #UseOkResult(
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_field_write_nested_invalid_type() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ ts.ty.count = false;
+ int where_to = ts.ty.count;
+ transition select (where_to == 5) {
+ true: accept;
+ false: reject;
+ };
+ }
+ };
+ """
+ var test_types = LexicalScopes().enter()
+
+ let ty_fields = P4StructFields([
+ P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
+ P4StructFieldIdentifier(name: "count", withType: P4Int()),
+ ])
+ let ty_struct_type = P4Struct(withName: Identifier(name: "nested"), andFields: ty_fields)
+
+ let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
+ let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
+
+ test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type)
+
+ #expect(
+ #RequireErrorResult(
+ Error(
+ withMessage: "{49, 20}: Failed to parse a statement element: {49, 11}: Cannot assign value of type Boolean to field with type Int"
+ ),
+ Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
+ )
+
+}
diff --git a/Tests/p4rseTests/TransitionTests.swift b/Tests/p4rseTests/TransitionTests.swift
new file mode 100644
index 0000000..591a944
--- /dev/null
+++ b/Tests/p4rseTests/TransitionTests.swift
@@ -0,0 +1,91 @@
+// p4rse, Copyright 2026, Will Hawkins
+//
+// This file is part of p4rse.
+//
+// This file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+import Common
+import Foundation
+import Macros
+import P4Lang
+import P4Runtime
+import SwiftTreeSitter
+import Testing
+import TreeSitter
+import TreeSitterP4
+
+@testable import P4Compiler
+
+@Test func test_simple_parser_with_transition_select_expression() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ transition select (true) {
+ false: reject;
+ true: accept;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
+ let parser = try #UseOkResult(program.find_parser(withName: Identifier(name: "main_parser")))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(parser.states.count() == 1)
+
+ #expect(state_result == P4Lang.accept)
+}
+
+@Test func test_simple_parser_with_transition_select_expression_to_reject() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ transition select (false) {
+ false: reject;
+ true: accept;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
+ let parser = try #UseOkResult(program.find_parser(withName: Identifier(name: "main_parser")))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+ let (state_result, _) = try! #UseOkResult(runtime.run())
+
+ #expect(parser.states.count() == 1)
+ #expect(state_result == P4Lang.reject)
+}
+
+@Test func test_no_matching_key_transition() async throws {
+ let simple_parser_declaration = """
+ parser main_parser() {
+ state start {
+ transition select (false) {
+ true: accept;
+ };
+ }
+ };
+ """
+
+ let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
+ let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
+
+ #expect(
+ #RequireErrorResult<(ParserState, ProgramExecution)>(
+ Error(withMessage: "No key matched the selector"),
+ runtime.run()))
+}
\ No newline at end of file
diff --git a/Tests/p4rseTests/TypeTests.swift b/Tests/p4rseTests/TypeTests.swift
index 780e80b..5d18f90 100644
--- a/Tests/p4rseTests/TypeTests.swift
+++ b/Tests/p4rseTests/TypeTests.swift
@@ -16,14 +16,13 @@
// along with this program. If not, see .
import Foundation
-import Common
import Macros
import SwiftTreeSitter
import Testing
import TreeSitter
import TreeSitterP4
-@testable import P4Compiler
+@testable import Common
@Test func test_simple_struct() async throws {
let fields = P4StructFields([
diff --git a/Tests/p4rseTests/ValueTypeParserTests.swift b/Tests/p4rseTests/ValueTypeParserTests.swift
index 4af3ffd..bc5d49b 100644
--- a/Tests/p4rseTests/ValueTypeParserTests.swift
+++ b/Tests/p4rseTests/ValueTypeParserTests.swift
@@ -52,7 +52,7 @@ import TreeSitterP4
#RequireErrorResult(
Error(
withMessage:
- "{112, 16}: Failed to parse a statement element: {112, 16}: Cannot assign value of type Boolean to where_to (with type String)"
+ "{112, 16}: Failed to parse a statement element: {112, 8}: Cannot assign value with type Boolean to identifier where_to with type String"
),
Program.Compile(simple_parser_declaration)))
}
@@ -73,7 +73,7 @@ import TreeSitterP4
#RequireErrorResult(
Error(
withMessage:
- "{114, 22}: Failed to parse a statement element: {114, 22}: Cannot assign value of type String to where_to (with type Boolean)"
+ "{114, 22}: Failed to parse a statement element: {114, 8}: Cannot assign value with type String to identifier where_to with type Boolean"
),
Program.Compile(simple_parser_declaration)))
}
@@ -252,354 +252,3 @@ import TreeSitterP4
),
Program.Compile(simple_parser_declaration, withGlobalTypes: test_types)))
}
-
-
-@Test func test_array_access() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- bool where_to = ta[1] == 2;
- transition select (where_to) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ta"),
- withValue: P4ArrayValue(withType: P4Int(), withValue: [
- P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
- ]))
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_array_access_invalid_type() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- bool where_to = ta[1];
- transition select (where_to) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Int())
- #expect(
- #RequireErrorResult(
- Error(
- withMessage: "{49, 22}: Failed to parse a statement element: {65, 2}: ta does not name an array type"
- ),
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- )
-}
-
-@Test func test_array_access2() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- bool where_to = ta[0] == 2;
- transition select (where_to) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ta"),
- withValue: P4ArrayValue(withType: P4Int(), withValue: [
- P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
- ]))
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.reject)
-}
-
-@Test func test_array_access3() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- transition select (ta[0] == 1) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ta"),
- withValue: P4ArrayValue(withType: P4Int(), withValue: [
- P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
- ]))
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_array_access4() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- transition select (ta[1] == 2) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int()))
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ta"),
- withValue: P4ArrayValue(withType: P4Int(), withValue: [
- P4IntValue(withValue: 1), P4IntValue(withValue: 2), P4IntValue(withValue: 3),
- ]))
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_array_access_nested() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- int where_to = ta[0][0];
- transition select (where_to == 5) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Array(withValueType: P4Int())))
- var test_values = ValueScopes().enter()
-
- let nested = P4ArrayValue(
- withType: P4Int(),
- withValue: [P4IntValue(withValue: 5), P4IntValue(withValue: 2), P4IntValue(withValue: 3)])
-
- test_values = test_values.declare(
- identifier: Identifier(name: "ta"),
- withValue: P4ArrayValue(withType: P4Array(withValueType: P4Int()), withValue: [nested]))
-
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
-
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_field_access() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- bool where_to = ts.yesno;
- transition select (where_to) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- let fields = P4StructFields([
- P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
- P4StructFieldIdentifier(name: "count", withType: P4Int()),
- ])
- let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
- test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
-
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ts"),
- withValue: P4StructValue(withType: struct_type, andInitializers: [
- P4BooleanValue(withValue: true),
- P4IntValue(withValue: 5),
- ]))
-
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_field_access_opp() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- bool where_to = ts.yesno;
- transition select (where_to) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- let fields = P4StructFields([
- P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
- P4StructFieldIdentifier(name: "count", withType: P4Int()),
- ])
- let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
- test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
-
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ts"),
- withValue: P4StructValue(withType: struct_type, andInitializers: [
- P4BooleanValue(withValue: false),
- P4IntValue(withValue: 5),
- ]))
-
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
- #expect(state_result == P4Lang.reject)
-}
-
-
-@Test func test_field_access2() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- transition select (ts.count == 5) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- let fields = P4StructFields([
- P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
- P4StructFieldIdentifier(name: "count", withType: P4Int()),
- ])
- let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
- test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
-
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ts"),
- withValue: P4StructValue(withType: struct_type, andInitializers: [
- P4BooleanValue(withValue: true),
- P4IntValue(withValue: 5),
- ]))
-
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
- #expect(state_result == P4Lang.accept)
-}
-
-@Test func test_field_access2_opp() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- transition select (ts.count == 5) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
- let fields = P4StructFields([
- P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
- P4StructFieldIdentifier(name: "count", withType: P4Int()),
- ])
- let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
- test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: struct_type)
-
- var test_values = ValueScopes().enter()
- test_values = test_values.declare(
- identifier: Identifier(name: "ts"),
- withValue: P4StructValue(withType: struct_type, andInitializers: [
- P4BooleanValue(withValue: true),
- P4IntValue(withValue: 8),
- ]))
-
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
- #expect(state_result == P4Lang.reject)
-}
-
-@Test func test_field_access_nested() async throws {
- let simple_parser_declaration = """
- parser main_parser() {
- state start {
- int where_to = ts.ty.count;
- transition select (where_to == 5) {
- true: accept;
- false: reject;
- };
- }
- };
- """
- var test_types = LexicalScopes().enter()
-
- let ty_fields = P4StructFields([
- P4StructFieldIdentifier(name: "yesno", withType: P4Boolean()),
- P4StructFieldIdentifier(name: "count", withType: P4Int()),
- ])
- let ty_struct_type = P4Struct(withName: Identifier(name: "nested"), andFields: ty_fields)
-
- let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
- let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
-
- test_types = test_types.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type)
-
- var test_values = ValueScopes().enter()
-
- test_values = test_values.declare(
- identifier: Identifier(name: "ts"),
- withValue: P4StructValue(
- withType: ts_struct_type,
- andInitializers: [
- P4StructValue(
- withType: ty_struct_type,
- andInitializers: [
- P4BooleanValue(withValue: true),
- P4IntValue(withValue: 5),
- ])
- ]))
- let program = try #UseOkResult(
- Program.Compile(simple_parser_declaration, withGlobalTypes: test_types))
- let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
- let (state_result, _) = try! #UseOkResult(runtime.run())
- #expect(state_result == P4Lang.accept)
-}
\ No newline at end of file