compiler, runtime: Initial Support For Calling Controls
Support calling (invoking) a Control. There is still plenty more to do here, but we are off to a good start. Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -0,0 +1,322 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
import Common
|
||||
import Foundation
|
||||
import Macros
|
||||
import Runtime
|
||||
import SwiftTreeSitter
|
||||
import Testing
|
||||
import TreeSitter
|
||||
import TreeSitterP4
|
||||
import P4Lang
|
||||
|
||||
@testable import P4Compiler
|
||||
|
||||
@Test func test_simple_control_declaration() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple() {
|
||||
action a() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
true: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
let x = { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
#expect(program.InstancesWithTypes(x).count == 1)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration2() async throws {
|
||||
let simple_parser_declaration = """
|
||||
struct Testing {
|
||||
};
|
||||
control simple() {
|
||||
action a() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
true: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
control complex() {
|
||||
action b() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
true: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let filter = { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple" || c.name == "complex"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
#expect(program.InstancesWithTypes(filter).count == 2)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_actions() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple() {
|
||||
action a() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
true: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
let x = { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
#expect(program.InstancesWithTypes(x).count == 1)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_misnamed_actions() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple() {
|
||||
action a() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
true: exact;
|
||||
}
|
||||
actions = {
|
||||
b;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(
|
||||
#RequireErrorResult(
|
||||
Error(
|
||||
withMessage: "{54, 63}: Error(s) parsing property list: {91, 26}: Error(s) parsing table actions: Cannot find b in lexical scope."
|
||||
),
|
||||
Program.Compile(simple_parser_declaration))
|
||||
)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_misnamed_actions2() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple() {
|
||||
action a() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
true: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
b;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(
|
||||
#RequireErrorResult(
|
||||
Error(
|
||||
withMessage: "{54, 72}: Error(s) parsing property list: {91, 35}: Error(s) parsing table actions: Cannot find b in lexical scope."
|
||||
),
|
||||
Program.Compile(simple_parser_declaration))
|
||||
)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_mistyped_actions() async throws {
|
||||
let simple_parser_declaration = """
|
||||
bool a() {
|
||||
return true;
|
||||
};
|
||||
control simple() {
|
||||
table t {
|
||||
key = {
|
||||
true: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(
|
||||
#RequireErrorResult(
|
||||
Error(
|
||||
withMessage: "{64, 63}: Error(s) parsing property list: {101, 26}: Error(s) parsing table actions: {101, 26}: a does not name an action"
|
||||
),
|
||||
Program.Compile(simple_parser_declaration))
|
||||
)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_parameters() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(bool x, bool y) {
|
||||
action a() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
y: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(#RequireOkResult(Program.Compile(simple_parser_declaration)))
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_multiple_tables() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(bool x, bool y, bool a, bool b) {
|
||||
action a() {
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
y: exact;
|
||||
}
|
||||
}
|
||||
table u {
|
||||
key = {
|
||||
a: exact;
|
||||
b: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(
|
||||
#RequireErrorResult(
|
||||
Error(
|
||||
withMessage: "{0, 215}: More than one table in control declaration"
|
||||
),
|
||||
Program.Compile(simple_parser_declaration))
|
||||
)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_action_using_parameter() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(bool x, bool y) {
|
||||
action a(int z) {
|
||||
z = 5;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
y: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(#RequireOkResult(Program.Compile(simple_parser_declaration)))
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_action_using_parameter_wrong_type() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(bool x, bool y) {
|
||||
action a(int z) {
|
||||
z = false;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
y: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(
|
||||
#RequireErrorResult(
|
||||
Error(
|
||||
withMessage:
|
||||
"{57, 10}: Failed to parse a statement element: {57, 1}: Cannot assign value with type Boolean to identifier z with type Int"
|
||||
),
|
||||
Program.Compile(simple_parser_declaration))
|
||||
)
|
||||
}
|
||||
|
||||
@Test func test_simple_control_declaration_with_element_after_apply() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(bool x, bool y) {
|
||||
action a(int z) {
|
||||
z = false;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
y: exact;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
table x {
|
||||
key = {
|
||||
x: exact;
|
||||
y: exact;
|
||||
}
|
||||
}
|
||||
};
|
||||
"""
|
||||
#expect(
|
||||
#RequireErrorResult(
|
||||
Error(
|
||||
withMessage:
|
||||
"Could not compile the P4 program"
|
||||
),
|
||||
Program.Compile(simple_parser_declaration))
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
import Common
|
||||
import Foundation
|
||||
import Macros
|
||||
import P4Lang
|
||||
import P4Runtime
|
||||
import SwiftTreeSitter
|
||||
import Testing
|
||||
import TreeSitter
|
||||
import TreeSitterP4
|
||||
|
||||
@testable import P4Compiler
|
||||
|
||||
@Test func test_control_single_key() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(inout int result, bool x) {
|
||||
action a() {
|
||||
result = 5;
|
||||
}
|
||||
action b() {
|
||||
result = 7;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
b;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
|
||||
// Pull the control out of the compiled program.
|
||||
let controls = program.InstancesWithTypes() { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
var control = ((controls[0].dataType() as P4DataType) as! Control)
|
||||
|
||||
// Add entries to the table.
|
||||
control = control.updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4BooleanValue(withValue: true)),
|
||||
TypedIdentifier(name: "a", withType: P4Type(Action()))
|
||||
)
|
||||
).updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4BooleanValue(withValue: false)),
|
||||
TypedIdentifier(name: "b", withType: P4Type(Action()))
|
||||
))
|
||||
|
||||
// Set a variable in the global scope for the inout first parameter.
|
||||
var global_values = VarValueScopes().enter()
|
||||
global_values = global_values.declare(
|
||||
identifier: Identifier(name: "result_arg"),
|
||||
withValue: P4Value(
|
||||
P4IntValue(withValue: 0),
|
||||
P4Type(P4Int())))
|
||||
|
||||
let runtime = try #UseOkResult(
|
||||
P4Runtime.Runtime<P4TableHitMissValue, Control>.create(control: control, withGlobalValues: global_values))
|
||||
|
||||
let (hit_miss, updated_execution) = try #UseOkResult(runtime.run(
|
||||
withArguments: ArgumentList([
|
||||
Argument(TypedIdentifier(name: "result_arg", withType: P4Type(P4Int())), atIndex: 0),
|
||||
Argument(P4Value(P4BooleanValue(withValue: true)), atIndex: 1),
|
||||
])))
|
||||
|
||||
// We expect there to be a hit.
|
||||
#expect(hit_miss == P4TableHitMissValue.Hit)
|
||||
|
||||
// And that the proper action was invoked.
|
||||
let result_arg = try #UseOkResult(updated_execution.scopes.lookup(identifier: Identifier(name: "result_arg")))
|
||||
#expect(result_arg.eq(P4Value(P4IntValue(withValue: 5))))
|
||||
}
|
||||
|
||||
@Test func test_control_single_key_false() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(inout int result, bool x) {
|
||||
action a() {
|
||||
result = 5;
|
||||
}
|
||||
action b() {
|
||||
result = 7;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
b;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
|
||||
// Pull the control out of the compiled program.
|
||||
let controls = program.InstancesWithTypes() { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
var control = ((controls[0].dataType() as P4DataType) as! Control)
|
||||
|
||||
// Add entries to the table.
|
||||
control = control.updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4BooleanValue(withValue: true)),
|
||||
TypedIdentifier(name: "a", withType: P4Type(Action()))
|
||||
)
|
||||
).updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4BooleanValue(withValue: false)),
|
||||
TypedIdentifier(name: "b", withType: P4Type(Action()))
|
||||
))
|
||||
|
||||
// Set a variable in the global scope for the inout first parameter.
|
||||
var global_values = VarValueScopes().enter()
|
||||
global_values = global_values.declare(
|
||||
identifier: Identifier(name: "result_arg"),
|
||||
withValue: P4Value(
|
||||
P4IntValue(withValue: 0),
|
||||
P4Type(P4Int())))
|
||||
|
||||
let runtime = try #UseOkResult(
|
||||
P4Runtime.Runtime<P4TableHitMissValue, Control>.create(control: control, withGlobalValues: global_values))
|
||||
|
||||
let (hit_miss, updated_execution) = try #UseOkResult(runtime.run(
|
||||
withArguments: ArgumentList([
|
||||
Argument(TypedIdentifier(name: "result_arg", withType: P4Type(P4Int())), atIndex: 0),
|
||||
Argument(P4Value(P4BooleanValue(withValue: false)), atIndex: 1),
|
||||
])))
|
||||
|
||||
// We expect there to be a hit.
|
||||
#expect(hit_miss == P4TableHitMissValue.Hit)
|
||||
|
||||
// And that the proper action was invoked.
|
||||
let result_arg = try #UseOkResult(updated_execution.scopes.lookup(identifier: Identifier(name: "result_arg")))
|
||||
#expect(result_arg.eq(P4Value(P4IntValue(withValue: 7))))
|
||||
}
|
||||
|
||||
@Test func test_control_single_integer_key_hit() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(inout int result, int x) {
|
||||
action a() {
|
||||
result = 5;
|
||||
}
|
||||
action b() {
|
||||
result = 7;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
b;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
|
||||
// Pull the control out of the compiled program.
|
||||
let controls = program.InstancesWithTypes() { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
var control = ((controls[0].dataType() as P4DataType) as! Control)
|
||||
|
||||
// Add entries to the table.
|
||||
control = control.updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4IntValue(withValue: 5)),
|
||||
TypedIdentifier(name: "a", withType: P4Type(Action()))
|
||||
)
|
||||
).updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4IntValue(withValue: 2)),
|
||||
TypedIdentifier(name: "b", withType: P4Type(Action()))
|
||||
))
|
||||
|
||||
// Set a variable in the global scope for the inout first parameter.
|
||||
var global_values = VarValueScopes().enter()
|
||||
global_values = global_values.declare(
|
||||
identifier: Identifier(name: "result_arg"),
|
||||
withValue: P4Value(
|
||||
P4IntValue(withValue: 0),
|
||||
P4Type(P4Int())))
|
||||
|
||||
let runtime = try #UseOkResult(
|
||||
P4Runtime.Runtime<P4TableHitMissValue, Control>.create(control: control, withGlobalValues: global_values))
|
||||
|
||||
let (hit_miss, updated_execution) = try #UseOkResult(runtime.run(
|
||||
withArguments: ArgumentList([
|
||||
Argument(TypedIdentifier(name: "result_arg", withType: P4Type(P4Int())), atIndex: 0),
|
||||
Argument(P4Value(P4IntValue(withValue: 5)), atIndex: 1),
|
||||
])))
|
||||
|
||||
// We expect there to be a hit.
|
||||
#expect(hit_miss == P4TableHitMissValue.Hit)
|
||||
|
||||
let result_arg = try #UseOkResult(updated_execution.scopes.lookup(identifier: Identifier(name: "result_arg")))
|
||||
#expect(result_arg.eq(P4Value(P4IntValue(withValue: 5))))
|
||||
}
|
||||
|
||||
@Test func test_control_single_integer_key_miss() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(inout int result, int x) {
|
||||
action a() {
|
||||
result = 5;
|
||||
}
|
||||
action b() {
|
||||
result = 7;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
b;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
|
||||
// Pull the control out of the compiled program.
|
||||
let controls = program.InstancesWithTypes() { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
var control = ((controls[0].dataType() as P4DataType) as! Control)
|
||||
|
||||
// Add entries to the table.
|
||||
control = control.updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4IntValue(withValue: 1)),
|
||||
TypedIdentifier(name: "a", withType: P4Type(Action()))
|
||||
)
|
||||
).updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4IntValue(withValue: 2)),
|
||||
TypedIdentifier(name: "b", withType: P4Type(Action()))
|
||||
))
|
||||
|
||||
// Set a variable in the global scope for the inout first parameter.
|
||||
var global_values = VarValueScopes().enter()
|
||||
global_values = global_values.declare(
|
||||
identifier: Identifier(name: "result_arg"),
|
||||
withValue: P4Value(
|
||||
P4IntValue(withValue: 0),
|
||||
P4Type(P4Int())))
|
||||
|
||||
let runtime = try #UseOkResult(
|
||||
P4Runtime.Runtime<P4TableHitMissValue, Control>.create(control: control, withGlobalValues: global_values))
|
||||
|
||||
let (hit_miss, updated_execution) = try #UseOkResult(runtime.run(
|
||||
withArguments: ArgumentList([
|
||||
Argument(TypedIdentifier(name: "result_arg", withType: P4Type(P4Int())), atIndex: 0),
|
||||
Argument(P4Value(P4IntValue(withValue: 3)), atIndex: 1),
|
||||
])))
|
||||
|
||||
// We expect there to be a hit.
|
||||
#expect(hit_miss == P4TableHitMissValue.Miss)
|
||||
|
||||
let result_arg = try #UseOkResult(updated_execution.scopes.lookup(identifier: Identifier(name: "result_arg")))
|
||||
#expect(result_arg.eq(P4Value(P4IntValue(withValue: 0))))
|
||||
}
|
||||
|
||||
@Test func test_control_multiple_keys() async throws {
|
||||
let simple_parser_declaration = """
|
||||
control simple(inout int result, bool x, int f) {
|
||||
action a() {
|
||||
result = 5;
|
||||
}
|
||||
action b() {
|
||||
result = 7;
|
||||
}
|
||||
table t {
|
||||
key = {
|
||||
x: exact;
|
||||
f: exact;
|
||||
}
|
||||
actions = {
|
||||
a;
|
||||
b;
|
||||
}
|
||||
}
|
||||
apply {
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let program = try! #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
|
||||
// Pull the control out of the compiled program.
|
||||
let controls = program.InstancesWithTypes() { (tipe: P4Type) -> Bool in
|
||||
switch tipe.dataType() {
|
||||
case let c as Control: c.name == "simple"
|
||||
default: false
|
||||
}
|
||||
}
|
||||
var control = ((controls[0].dataType() as P4DataType) as! Control)
|
||||
|
||||
// Add entries to the table.
|
||||
control = control.updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4BooleanValue(withValue: true)),
|
||||
TypedIdentifier(name: "a", withType: P4Type(Action()))
|
||||
)
|
||||
).updateTable(
|
||||
addEntry: (
|
||||
P4Value(P4IntValue(withValue: 5)),
|
||||
TypedIdentifier(name: "b", withType: P4Type(Action()))
|
||||
))
|
||||
|
||||
// Set a variable in the global scope for the inout first parameter.
|
||||
var global_values = VarValueScopes().enter()
|
||||
global_values = global_values.declare(
|
||||
identifier: Identifier(name: "result_arg"),
|
||||
withValue: P4Value(
|
||||
P4IntValue(withValue: 0),
|
||||
P4Type(P4Int())))
|
||||
|
||||
let runtime = try #UseOkResult(
|
||||
P4Runtime.Runtime<P4TableHitMissValue, Control>.create(control: control, withGlobalValues: global_values))
|
||||
|
||||
let (hit_miss, updated_execution) = try #UseOkResult(runtime.run(
|
||||
withArguments: ArgumentList([
|
||||
Argument(TypedIdentifier(name: "result_arg", withType: P4Type(P4Int())), atIndex: 0),
|
||||
Argument(P4Value(P4BooleanValue(withValue: false)), atIndex: 1),
|
||||
Argument(P4Value(P4IntValue(withValue: 5)), atIndex: 2),
|
||||
])))
|
||||
|
||||
// We expect there to be a hit.
|
||||
#expect(hit_miss == P4TableHitMissValue.Hit)
|
||||
|
||||
// And that the proper action was invoked.
|
||||
let result_arg = try #UseOkResult(updated_execution.scopes.lookup(identifier: Identifier(name: "result_arg")))
|
||||
#expect(result_arg.eq(P4Value(P4IntValue(withValue: 7))))
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user