compiler, runtime, common, testing: Support Directions on Parameters and Attributed Types

Add support for directions on parameters and attributed types. The
latter is necessary to support the former, but is not limited to
the direction use case. An attributed type is a P4 type with attributes
(like its direction, whether it is read only, etc.) Other attributes
will be added in the future.

Changes necessary to support attributed types include:
1. Global instances tracked during compilation are not attributed
types and not simply types.
2. (future) Type checking will have to make sure that a types
attributes do not affect type compatibility.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-04-13 06:25:08 -04:00
parent 9669a99dfc
commit 35b2537754
17 changed files with 209 additions and 64 deletions
@@ -39,8 +39,8 @@ let p4_program_with_control_decl = """
// snippet.include // snippet.include
let flter = { (tipe: P4Type) -> Bool in let flter = { (tipe: P4TypeAttributed) -> Bool in
switch tipe { switch tipe.type {
case let c as Control: c.name == "simple" case let c as Control: c.name == "simple"
default: false default: false
} }
+2 -2
View File
@@ -16,10 +16,10 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
/// A scope that resolves variable identifiers to their types. /// A scope that resolves variable identifiers to their types.
public typealias VarTypeScope = Scope<P4Type> public typealias VarTypeScope = Scope<P4TypeAttributed>
/// Scopes that resolve variable identifiers to their types. /// Scopes that resolve variable identifiers to their types.
public typealias VarTypeScopes = Scopes<P4Type> public typealias VarTypeScopes = Scopes<P4TypeAttributed>
/// A scope that resolves type identifiers to their types. /// A scope that resolves type identifiers to their types.
public typealias TypeTypeScope = Scope<P4Type> public typealias TypeTypeScope = Scope<P4Type>
+73
View File
@@ -782,3 +782,76 @@ public class P4SetDefaultValue: P4Value {
"Default of P4Set of \(self.type()) type" "Default of P4Set of \(self.type()) type"
} }
} }
public enum Direction: Equatable, CustomStringConvertible {
case In
case Out
case InOut
public var description: String {
return switch self {
case Direction.In: "In"
case Direction.Out: "Out"
case Direction.InOut: "InOut"
}
}
/// Compare two optional ``Direction``s
static public func eqopt(_ lhs: Direction?, _ rhs: Direction?) -> Bool {
// If both are empty, they are the same.
if lhs == .none && rhs == .none {
return true
}
// If one is empty, they are different
if lhs == .none || rhs == .none {
return false
}
// Both have values -- compare them natively.
return lhs! == rhs!
}
}
public enum P4TypeAttribute {
case Direction(Direction)
case Readonly // Not yet used -- here to keep Swift warnings at bay
}
public struct P4TypeAttributed {
let attributes: [P4TypeAttribute]
public let type: P4Type
public init(_ type: P4Type, _ attributes: [P4TypeAttribute]) {
self.attributes = attributes
self.type = type
}
public func direction() -> Direction? {
let result = attributes.firstIndex { attribute in
return switch attribute {
case .Direction(_): true
default: false
}
}
return result.flatMap { index in
return switch attributes[index] {
case .Direction(let d): d
default: Optional<Direction>.none
}
}
}
public func readOnly() -> Bool {
return attributes.contains { attribute in
return switch attribute {
case .Readonly: true
default: false
}
}
}
public static func Attributeless(_ type: P4Type) -> P4TypeAttributed {
return P4TypeAttributed(type, [])
}
}
+37 -6
View File
@@ -120,6 +120,30 @@ extension ParameterList: Compilable {
} }
} }
extension Direction: Compilable {
public typealias T = Direction
public static func Compile(
node: Node, withContext context: CompilerContext
) -> Result<(Direction, CompilerContext)> {
let direction_node = node
#RequireNodeType<Node, (Direction, CompilerContext)>(
node: direction_node, type: "direction", nice_type_name: "direction")
let directions = [
"in": Direction.In,
"out": Direction.Out,
"inout": Direction.InOut,
]
guard let parsed_direction = directions[direction_node.text!] else {
return .Error(
ErrorOnNode(
node: direction_node, withError: "\(direction_node.text!) is not a valid direction"))
}
return .Ok((parsed_direction, context))
}
}
extension Parameter: Compilable { extension Parameter: Compilable {
public typealias T = Parameter public typealias T = Parameter
public static func Compile( public static func Compile(
@@ -148,15 +172,22 @@ extension Parameter: Compilable {
withError: "Annotations in parameter declarations are not yet handled")) withError: "Annotations in parameter declarations are not yet handled"))
// Will increment indexes here. // Will increment indexes here.
} }
currentChild = node.child(at: currentChildIdx)
var direction: Direction? = .none
// Direction? // Direction?
if currentChild!.nodeType == "direction" { if currentChild!.nodeType == "direction" {
return .Error(
ErrorOnNode( let maybe_parsed_direction = Direction.Compile(node: currentChild!, withContext: context)
node: currentChild!, withError: "Direction in parameter declarations are not yet handled" guard case .Ok((let parsed_direction, _)) = maybe_parsed_direction else {
)) return .Error(maybe_parsed_direction.error()!)
// Will increment indexes here.
} }
direction = parsed_direction
currentChildIdx += 1
currentChildIdxSafe += 1
}
currentChild = node.child(at: currentChildIdx)
if currentChild!.nodeType != "typeRef" { if currentChild!.nodeType != "typeRef" {
return Result.Error( return Result.Error(
@@ -195,7 +226,7 @@ extension Parameter: Compilable {
return Result.Ok( return Result.Ok(
( (
Parameter( Parameter(
identifier: parameter_name, withType: parameter_type), identifier: parameter_name, withType: parameter_type, withDirection: direction),
context context
)) ))
} }
+9 -6
View File
@@ -108,7 +108,8 @@ extension FunctionDeclaration: CompilableDeclaration {
// Add the parameters into scope. // Add the parameters into scope.
var function_scope = context.instances.enter() var function_scope = context.instances.enter()
for parameter in function_parameters.parameters { for parameter in function_parameters.parameters {
function_scope = function_scope.declare(identifier: parameter.name, withValue: parameter.type) function_scope = function_scope.declare(
identifier: parameter.name, withValue: parameter.attributedType())
} }
let maybe_function_body = Parser.Statement.Compile( let maybe_function_body = Parser.Statement.Compile(
@@ -331,7 +332,7 @@ extension P4Lang.Parser: CompilableDeclaration {
for parameter in parameter_list.parameters { for parameter in parameter_list.parameters {
current_context = current_context.update( current_context = current_context.update(
newInstances: current_context.instances.declare( newInstances: current_context.instances.declare(
identifier: parameter.name, withValue: parameter.type)) identifier: parameter.name, withValue: parameter.attributedType()))
} }
currentChildIdx += 1 currentChildIdx += 1
@@ -374,7 +375,7 @@ extension P4Lang.Parser: CompilableDeclaration {
parser, parser,
context.update( context.update(
newInstances: updated_context.instances.declare( newInstances: updated_context.instances.declare(
identifier: parser.name, withValue: parser)) identifier: parser.name, withValue: P4TypeAttributed(parser, [])))
)) ))
case Result.Error(let error): return .Error(error) case Result.Error(let error): return .Error(error)
} }
@@ -436,7 +437,8 @@ extension Control: CompilableDeclaration {
// Before continuing, make sure to put the parameters into context. // Before continuing, make sure to put the parameters into context.
var control_scope = local_context.instances.enter() var control_scope = local_context.instances.enter()
for parameter in control_parameters.parameters { for parameter in control_parameters.parameters {
control_scope = control_scope.declare(identifier: parameter.name, withValue: parameter.type) control_scope = control_scope.declare(
identifier: parameter.name, withValue: parameter.attributedType())
} }
local_context = local_context.update(newInstances: control_scope) local_context = local_context.update(newInstances: control_scope)
@@ -505,7 +507,7 @@ extension Control: CompilableDeclaration {
declared_control, declared_control,
context.update( context.update(
newInstances: context.instances.declare( newInstances: context.instances.declare(
identifier: control_name, withValue: declared_control)) identifier: control_name, withValue: P4TypeAttributed(declared_control, [])))
)) ))
} }
} }
@@ -566,7 +568,8 @@ extension Action: Compilable {
// Add the parameters into scope. // Add the parameters into scope.
var function_scope = context.instances.enter() var function_scope = context.instances.enter()
for parameter in action_parameters.parameters { for parameter in action_parameters.parameters {
function_scope = function_scope.declare(identifier: parameter.name, withValue: parameter.type) function_scope = function_scope.declare(
identifier: parameter.name, withValue: parameter.attributedType())
} }
let maybe_action_body = Parser.Statement.Compile( let maybe_action_body = Parser.Statement.Compile(
+2 -2
View File
@@ -43,13 +43,13 @@ extension TypedIdentifier: CompilableExpression {
node: node, type: "identifier") node: node, type: "identifier")
guard guard
case Result.Ok(let type) = context.instances.lookup( case Result.Ok(let attributed_type) = context.instances.lookup(
identifier: Common.Identifier(name: node.text!)) identifier: Common.Identifier(name: node.text!))
else { else {
return .Error(ErrorOnNode(node: node, withError: "Cannot find \(node.text!) in scope")) return .Error(ErrorOnNode(node: node, withError: "Cannot find \(node.text!) in scope"))
} }
return .Ok(TypedIdentifier(name: node.text!, withType: type)) return .Ok(TypedIdentifier(name: node.text!, withType: attributed_type.type))
} }
} }
+1 -1
View File
@@ -231,7 +231,7 @@ extension VariableDeclarationStatement: CompilableStatement {
// Context with updated names to include the newly declared name. // Context with updated names to include the newly declared name.
context.update( context.update(
newInstances: context.instances.declare( newInstances: context.instances.declare(
identifier: parsed_variablename, withValue: declaration_p4_type)) identifier: parsed_variablename, withValue: P4TypeAttributed(declaration_p4_type, [])))
)) ))
} }
} }
+18 -4
View File
@@ -19,21 +19,35 @@ import Common
public struct Parameter: CustomStringConvertible, Equatable { public struct Parameter: CustomStringConvertible, Equatable {
public static func == (lhs: Parameter, rhs: Parameter) -> Bool { public static func == (lhs: Parameter, rhs: Parameter) -> Bool {
return lhs.name == rhs.name && lhs.type.eq(rhs: rhs.type) return lhs.name == rhs.name && lhs.type.eq(rhs: rhs.type) && lhs.direction == rhs.direction
} }
public var name: Identifier public var name: Identifier
public var type: P4Type public var type: P4Type
public var direction: Direction?
public init( public init(
identifier: Identifier, withType type: P4Type identifier: Identifier, withType type: P4Type, withDirection direction: Direction? = .none
) { ) {
self.name = identifier self.name = identifier
self.type = type self.type = type
self.direction = direction
} }
public var description: String { public var description: String {
return "Parameter: \(self.name) with type \(self.type)" let direction = self.direction != .none ? self.direction!.description : "no"
return "Parameter: \(self.name) with type \(self.type) with \(direction) direction"
}
/// Calculate whether the `argument` is compatible with this parameter.
public func compatible(_ argument: Argument) -> Bool {
let arg_type = argument.argument.type()
return arg_type.eq(rhs: self.type)
}
public func attributedType() -> P4TypeAttributed {
return P4TypeAttributed(
self.type, self.direction == .none ? [] : [P4TypeAttribute.Direction(self.direction!)])
} }
} }
@@ -89,7 +103,7 @@ public struct ArgumentList {
for (arg, param) in zip(self.arguments, parameters.parameters) { for (arg, param) in zip(self.arguments, parameters.parameters) {
let arg_index = arg.index let arg_index = arg.index
let arg_type = arg.argument.type() let arg_type = arg.argument.type()
if !arg_type.eq(rhs: param.type) { if !param.compatible(arg) {
return .Error( return .Error(
Error( Error(
withMessage: withMessage:
+8 -6
View File
@@ -23,13 +23,15 @@ public struct ExpressionStatement {
public struct Program { public struct Program {
public var types: [P4Type] = Array() public var types: [P4Type] = Array()
public var instances: [P4Type] = Array() public var instances: [P4TypeAttributed] = Array()
/// Type of closure for filtering results from ``Program/InstancesWithTypes(_:)`` and ``Program/TypesWithTypes(_:)`` /// Type of closure for filtering results from ``Program/InstancesWithTypes(_:)``
public typealias AttributedTypeFilter = (P4TypeAttributed) -> Bool
/// Type of closure for filtering results from ``Program/TypesWithTypes(_:)``
public typealias TypeFilter = (P4Type) -> Bool public typealias TypeFilter = (P4Type) -> Bool
/// Retrieve global instances in the compiled P4 program. /// Retrieve global instances in the compiled P4 program.
public func InstancesWithTypes() -> [P4Type] { public func InstancesWithTypes() -> [P4TypeAttributed] {
return self.instances return self.instances
} }
@@ -45,7 +47,7 @@ public struct Program {
/// ///
/// @Snippet(path: "use-program-instanceswithtypes", slice: "include") /// @Snippet(path: "use-program-instanceswithtypes", slice: "include")
/// ///
public func InstancesWithTypes(_ filter: TypeFilter) -> [P4Type] { public func InstancesWithTypes(_ filter: AttributedTypeFilter) -> [P4TypeAttributed] {
return self.instances.filter { instance in return self.instances.filter { instance in
filter(instance) filter(instance)
} }
@@ -82,8 +84,8 @@ public struct Program {
} }
public func find_parser(withName name: Identifier) -> Result<Parser> { public func find_parser(withName name: Identifier) -> Result<Parser> {
for instances in self.instances { for instance in self.instances {
guard let parser = instances as? Parser else { guard let parser = instance.type as? Parser else {
continue continue
} }
if parser.name == name { if parser.name == name {
+12
View File
@@ -14,3 +14,15 @@
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import Common
public struct AttributedP4Type {
public let type: P4Type
public let attributes: P4TypeAttributed
public init(_ type: P4Type, _ attributes: P4TypeAttributed) {
self.type = type
self.attributes = attributes
}
}
+3 -2
View File
@@ -81,11 +81,12 @@ extension TypedIdentifier: EvaluatableLValueExpression {
return .Error(Error(withMessage: "Cannot assign to identifier not in scope")) return .Error(Error(withMessage: "Cannot assign to identifier not in scope"))
} }
if !type.eq(rhs: to.type()) { if !type.type.eq(rhs: to.type()) {
return .Error( return .Error(
Error( Error(
withMessage: withMessage:
"Cannot assign value with type \(to.type()) to identifier \(self) with type \(type)")) "Cannot assign value with type \(to.type()) to identifier \(self) with type \(type.type)"
))
} }
return .Ok(()) return .Ok(())
} }
+8 -8
View File
@@ -40,7 +40,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int())) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Int())))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
identifier: Identifier(name: "ta"), identifier: Identifier(name: "ta"),
@@ -68,7 +68,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Int()) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Int()))
#expect( #expect(
#RequireErrorResult( #RequireErrorResult(
Error( Error(
@@ -91,7 +91,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int())) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Int())))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
identifier: Identifier(name: "ta"), identifier: Identifier(name: "ta"),
@@ -118,7 +118,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int())) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Int())))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
identifier: Identifier(name: "ta"), identifier: Identifier(name: "ta"),
@@ -145,7 +145,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int())) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Int())))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
identifier: Identifier(name: "ta"), identifier: Identifier(name: "ta"),
@@ -173,7 +173,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Array(withValueType: P4Int()))) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Array(withValueType: P4Int()))))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
let nested = P4ArrayValue( let nested = P4ArrayValue(
@@ -206,7 +206,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int())) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Int())))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
identifier: Identifier(name: "ta"), identifier: Identifier(name: "ta"),
@@ -235,7 +235,7 @@ import TreeSitterP4
}; };
""" """
var test_declarations = VarTypeScopes().enter() var test_declarations = VarTypeScopes().enter()
test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Array(withValueType: P4Int()))) test_declarations = test_declarations.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Array(withValueType: P4Int()))))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
let nested = P4ArrayValue( let nested = P4ArrayValue(
+4 -4
View File
@@ -39,8 +39,8 @@ import P4Lang
} }
}; };
""" """
let x = { (tipe: P4Type) -> Bool in let x = { (tipe: P4TypeAttributed) -> Bool in
switch tipe { switch tipe.type {
case let c as Control: c.name == "simple" case let c as Control: c.name == "simple"
default: false default: false
} }
@@ -73,8 +73,8 @@ import P4Lang
}; };
""" """
let filter = { (tipe: P4Type) -> Bool in let filter = { (tipe: P4TypeAttributed) -> Bool in
switch tipe { switch tipe.type {
case let c as Control: c.name == "simple" || c.name == "complex" case let c as Control: c.name == "simple" || c.name == "complex"
default: false default: false
} }
+9
View File
@@ -166,3 +166,12 @@ import TreeSitterP4
#expect(#RequireOkResult(Program.Compile(simple_parser_declaration))) #expect(#RequireOkResult(Program.Compile(simple_parser_declaration)))
} }
@Test func test_function_declaration_with_parameters_and_direction() async throws {
let simple_parser_declaration = """
bool functionb(in bool x, out string y, inout int z) {
x = true;
};
"""
#expect(#RequireOkResult(Program.Compile(simple_parser_declaration)))
}
+10 -10
View File
@@ -28,39 +28,39 @@ import TreeSitterP4
@Test func test_scope() async throws { @Test func test_scope() async throws {
let s = VarTypeScope() let s = VarTypeScope()
let s2 = s.declare(identifier: Identifier(name: "first"), withValue: P4Int()) let s2 = s.declare(identifier: Identifier(name: "first"), withValue: P4TypeAttributed.Attributeless(P4Int()))
let found_first = try! #require(s2.lookup(identifier: Identifier(name: "first"))) let found_first = try! #require(s2.lookup(identifier: Identifier(name: "first")))
#expect(found_first.eq(rhs: P4Int())) #expect(found_first.type.eq(rhs: P4Int()))
#expect(s2.count == 1) #expect(s2.count == 1)
} }
@Test func test_scope_no_set() async throws { @Test func test_scope_no_set() async throws {
var ss = VarTypeScopes().enter() var ss = VarTypeScopes().enter()
ss = ss.declare(identifier: Identifier(name: "first"), withValue: P4Int()) ss = ss.declare(identifier: Identifier(name: "first"), withValue: P4TypeAttributed.Attributeless(P4Int()))
ss = ss.enter() ss = ss.enter()
ss = ss.declare(identifier: Identifier(name: "second"), withValue: P4Boolean()) ss = ss.declare(identifier: Identifier(name: "second"), withValue: P4TypeAttributed.Attributeless(P4Boolean()))
let found_first = try! #UseOkResult(ss.lookup(identifier: Identifier(name: "first"))) let found_first = try! #UseOkResult(ss.lookup(identifier: Identifier(name: "first")))
let found_second = try! #UseOkResult(ss.lookup(identifier: Identifier(name: "second"))) let found_second = try! #UseOkResult(ss.lookup(identifier: Identifier(name: "second")))
#expect(found_first.eq(rhs: P4Int())) #expect(found_first.type.eq(rhs: P4Int()))
#expect(found_second.eq(rhs: P4Boolean())) #expect(found_second.type.eq(rhs: P4Boolean()))
} }
@Test func test_scope_set() async throws { @Test func test_scope_set() async throws {
var ss = VarTypeScopes().enter() var ss = VarTypeScopes().enter()
let id = Identifier(name: "first") let id = Identifier(name: "first")
let id_type = P4Int() let id_type = P4TypeAttributed.Attributeless(P4Int())
ss = ss.declare(identifier: id, withValue: id_type) ss = ss.declare(identifier: id, withValue: id_type)
ss = ss.enter() ss = ss.enter()
ss = ss.declare(identifier: Identifier(name: "second"), withValue: P4Boolean()) ss = ss.declare(identifier: Identifier(name: "second"), withValue: P4TypeAttributed.Attributeless(P4Boolean()))
// Change the value of `first`. // Change the value of `first`.
ss = ss.set(identifier: id, withValue: P4String()) ss = ss.set(identifier: id, withValue: P4TypeAttributed.Attributeless(P4String()))
// Verify the change! // Verify the change!
let found = try! #UseOkResult(ss.lookup(identifier: id)) let found = try! #UseOkResult(ss.lookup(identifier: id))
#expect(found.eq(rhs: P4String())) #expect(found.type.eq(rhs: P4String()))
} }
+10 -10
View File
@@ -45,7 +45,7 @@ import TreeSitterP4
P4StructFieldIdentifier(name: "count", withType: P4Int()), P4StructFieldIdentifier(name: "count", withType: P4Int()),
]) ])
let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields) let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
@@ -139,7 +139,7 @@ import TreeSitterP4
P4StructFieldIdentifier(name: "count", withType: P4Int()), P4StructFieldIdentifier(name: "count", withType: P4Int()),
]) ])
let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields) let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
@@ -174,7 +174,7 @@ import TreeSitterP4
P4StructFieldIdentifier(name: "count", withType: P4Int()), P4StructFieldIdentifier(name: "count", withType: P4Int()),
]) ])
let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields) let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
@@ -208,7 +208,7 @@ import TreeSitterP4
P4StructFieldIdentifier(name: "count", withType: P4Int()), P4StructFieldIdentifier(name: "count", withType: P4Int()),
]) ])
let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields) let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
@@ -248,7 +248,7 @@ import TreeSitterP4
let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)]) let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields) let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(ts_struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
@@ -290,7 +290,7 @@ import TreeSitterP4
P4StructFieldIdentifier(name: "count", withType: P4Int()), P4StructFieldIdentifier(name: "count", withType: P4Int()),
]) ])
let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields) let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
test_values = test_values.declare( test_values = test_values.declare(
@@ -322,7 +322,7 @@ import TreeSitterP4
P4StructFieldIdentifier(name: "count", withType: P4Int()), P4StructFieldIdentifier(name: "count", withType: P4Int()),
]) ])
let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields) let struct_type = P4Struct(withName: Identifier(name: "Testing"), andFields: fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(struct_type))
#expect( #expect(
#RequireErrorResult( #RequireErrorResult(
@@ -357,7 +357,7 @@ import TreeSitterP4
let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)]) let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields) let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(ts_struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
@@ -405,7 +405,7 @@ import TreeSitterP4
let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)]) let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields) let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(ts_struct_type))
var test_values = VarValueScopes().enter() var test_values = VarValueScopes().enter()
@@ -452,7 +452,7 @@ import TreeSitterP4
let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)]) let ts_fields = P4StructFields([P4StructFieldIdentifier(name: "ty", withType: ty_struct_type)])
let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields) let ts_struct_type = P4Struct(withName: Identifier(name: "outer"), andFields: ts_fields)
test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: ts_struct_type) test_declarations = test_declarations.declare(identifier: Identifier(name: "ts"), withValue: P4TypeAttributed.Attributeless(ts_struct_type))
#expect( #expect(
#RequireErrorResult( #RequireErrorResult(
+1 -1
View File
@@ -253,7 +253,7 @@ import TreeSitterP4
}; };
""" """
var test_types = VarTypeScopes().enter() var test_types = VarTypeScopes().enter()
test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4Array(withValueType: P4Int())) test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4TypeAttributed.Attributeless(P4Array(withValueType: P4Int())))
#expect( #expect(
#RequireErrorResult( #RequireErrorResult(
Error( Error(