diff --git a/Snippets/use-program-instanceswithtypes.swift b/Snippets/use-program-instanceswithtypes.swift new file mode 100644 index 0000000..ba88ba7 --- /dev/null +++ b/Snippets/use-program-instanceswithtypes.swift @@ -0,0 +1,50 @@ +// 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 Runtime +import SwiftTreeSitter +import Testing +import TreeSitter +import TreeSitterP4 +import P4Lang +import P4Compiler + +let p4_program_with_control_decl = """ + control simple() { + action a() { + } + table t { + key = { + true: exact; + } + } + }; + """ + + +// snippet.include +let flter = { (tipe: P4Type) -> Bool in + switch tipe { + case let c as Control: c.name == "simple" + default: false + } +} +if case .Ok(let program) = Program.Compile(p4_program_with_control_decl) { + print(program.InstancesWithTypes(flter)) +} diff --git a/Snippets/use-program-typeswithtypes.swift b/Snippets/use-program-typeswithtypes.swift new file mode 100644 index 0000000..45e8192 --- /dev/null +++ b/Snippets/use-program-typeswithtypes.swift @@ -0,0 +1,44 @@ +// 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 Runtime +import SwiftTreeSitter +import Testing +import TreeSitter +import TreeSitterP4 +import P4Lang +import P4Compiler + +let p4_program_with_struct_decl = """ + struct agg { + int x; + }; + """ + +// snippet.include +let flter = { (tipe: P4Type) -> Bool in + switch tipe { + case let c as P4Struct: c.name == "agg" + default: false + } +} +if case .Ok(let program) = Program.Compile(p4_program_with_struct_decl) { + print(program.TypesWithTypes(flter)) +} + diff --git a/Sources/P4Lang/Program.swift b/Sources/P4Lang/Program.swift index a2450ae..42ea3aa 100644 --- a/Sources/P4Lang/Program.swift +++ b/Sources/P4Lang/Program.swift @@ -25,6 +25,55 @@ public struct Program { public var types: [P4Type] = Array() public var instances: [P4Type] = Array() + /// Type of closure for filtering results from ``Program/InstancesWithTypes(_:)`` and ``Program/TypesWithTypes(_:)`` + public typealias TypeFilter = (P4Type) -> Bool + + /// Retrieve global instances in the compiled P4 program. + public func InstancesWithTypes() -> [P4Type] { + return self.instances + } + + /// Retrieve global instances in the compiled P4 program. + /// + /// Use the given filter to select which of the global instances + /// from the compiled P4 program to retrieve. + /// + /// If the compiled P4 program (from the source in the + /// string `p4_program_with_control_decl`) has two Control + /// instances and you only want to select the one named simple, + /// you could use a filter like + /// + /// @Snippet(path: "use-program-instanceswithtypes", slice: "include") + /// + public func InstancesWithTypes(_ filter: TypeFilter) -> [P4Type] { + return self.instances.filter() { instance in + filter(instance) + } + } + + /// Retrieve global types in the compiled P4 program. + public func TypesWithTypes() -> [P4Type] { + return self.types + } + + /// Retrieve global types declared in the compiled P4 program. + /// + /// Use the given filter to select which of the global types + /// declared in the compiled P4 program to retrieve. + /// + /// If the compiled P4 program (from the source in the + /// string `p4_program_with_struct_decl`) has two structs declared and + /// you only want to select the one named `agg`, you could + /// use a filter like + /// + /// @Snippet(path: "use-program-typeswithtypes", slice: "include") + /// + public func TypesWithTypes(_ filter: TypeFilter) -> [P4Type] { + return self.types.filter() { instance in + filter(instance) + } + } + /// Find the program's main parser /// /// Note: For now, the main parser is expected to be named main_parser.