// 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 public struct LocalElements {} public struct LocalElement {} public struct ParserAssignmentStatement { public let lvalue: EvaluatableLValueExpression public let value: EvaluatableExpression public init( withLValue lvalue: EvaluatableLValueExpression, withValue value: EvaluatableExpression ) { self.lvalue = lvalue self.value = value } } /// A P4 Parser State /// /// Note: A P4 Parser State is both a type and a value. /// This "bare" parser state represents the state more as a type than a value. public class ParserState: P4Type, Equatable, CustomStringConvertible { let name: Identifier public let statements: [EvaluatableStatement] public static func == (lhs: ParserState, rhs: ParserState) -> Bool { return lhs.eq(rhs: rhs) } public func eq(rhs: any Common.P4Type) -> Bool { return switch rhs { case let rrhs as ParserState: self.name == rrhs.name default: false } } public var description: String { return "Parser State named \(self.name)" } public func getName() -> Identifier { return self.name } public func getStatements() -> [EvaluatableStatement] { return self.statements } /// Construct a ParserState public init(_ name: Identifier, _ statements: [EvaluatableStatement] = Array()) { self.name = name self.statements = statements } public func def() -> P4DataValue? { return .none } public func instantiate(_ name: Identifier) -> InstantiatedParserState? { return .none } } public class _AnyParserState: ParserState { public override func eq(rhs: any Common.P4Type) -> Bool { return switch rhs { case is ParserState: true default: false } } } nonisolated(unsafe) public let AnyParserState = _AnyParserState(Identifier(name: "AnyParserState")) public struct TransitionStatement {} public class ParserStateDirectTransition: ParserState { public let next_state: InstantiatedParserState? public let next_state_identifier: Identifier? /// Construct a ParserState public init( name: Identifier, withNextState next_state: InstantiatedParserState, withStatements stmts: [EvaluatableStatement] = Array(), ) { self.next_state = next_state self.next_state_identifier = .none super.init(name, stmts) } public init( name: Identifier, withNextStateIdentifier next_state_id: Identifier, withStatements stmts: [EvaluatableStatement] = Array(), ) { self.next_state = .none self.next_state_identifier = next_state_id super.init(name, stmts) } public override func instantiate(_ name: Identifier) -> InstantiatedParserState? { return if let next_state = self.next_state { ParserStateDirectTransitionValue(name: name, withState: self, withNextState: next_state) } else { ParserStateDirectTransitionValue( name: name, withState: self, withNextStateIdentifier: self.next_state_identifier!) } } } public class ParserStateNoTransition: ParserState { /// Construct a ParserState public init( name: Identifier, withStatements stmts: [EvaluatableStatement] = Array(), ) { super.init(name, stmts) } public override func instantiate(_ name: Identifier) -> InstantiatedParserState? { return ParserStateNoTransitionValue(name: name, withState: self) } } public class ParserStateSelectTransition: ParserState { public let te: SelectExpression public init( name: Identifier, withTransitionExpression te: SelectExpression, withStatements stmts: [EvaluatableStatement] = Array() ) { self.te = te super.init(name, stmts) } public override func instantiate(_ name: Identifier) -> InstantiatedParserState? { return ParserStateSelectTransitionValue(name: name, withState: self, withSelectExpression: te) } } /// Instantiated Parser State /// public class InstantiatedParserState: P4DataValue { public static func == (lhs: InstantiatedParserState, rhs: InstantiatedParserState) -> Bool { return lhs.state == rhs.state } public func type() -> any Common.P4Type { return self.state } public func eq(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let other as InstantiatedParserState: self.state == other.state default: false } } public func lt(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let other as InstantiatedParserState: self.state.getName() < other.state.getName() default: false } } public func lte(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let other as InstantiatedParserState: self.state.getName() <= other.state.getName() default: false } } public func gt(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let other as InstantiatedParserState: self.state.getName() > other.state.getName() default: false } } public func gte(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let other as InstantiatedParserState: self.state.getName() >= other.state.getName() default: false } } public private(set) var state: ParserState public private(set) var name: Identifier public var description: String { return "Instance of state of type \(state) named \(name)" } public init(_ name: Identifier, _ state: ParserState) { self.name = name self.state = state } } public class ParserStateDirectTransitionValue: InstantiatedParserState { public let next_state: InstantiatedParserState? public let next_state_identifier: Identifier? public init( name: Identifier, withState state: ParserStateDirectTransition, withNextState next_state: InstantiatedParserState ) { self.next_state = next_state self.next_state_identifier = .none super.init(name, state) } public init( name: Identifier, withState state: ParserStateDirectTransition, withNextStateIdentifier next_state_id: Identifier ) { self.next_state = .none self.next_state_identifier = next_state_id super.init(name, state) } } public class ParserStateNoTransitionValue: InstantiatedParserState { public init(name: Identifier, withState state: ParserStateNoTransition) { super.init(name, state) } } public class ParserStateSelectTransitionValue: InstantiatedParserState { public let te: SelectExpression public init( name: Identifier, withState state: ParserStateSelectTransition, withSelectExpression te: SelectExpression ) { self.te = te super.init(name, state) } } nonisolated(unsafe) private let accept_type = ParserStateNoTransition( name: Identifier(name: "accept"), withStatements: []) nonisolated(unsafe) private let reject_type = ParserStateNoTransition( name: Identifier(name: "reject"), withStatements: []) nonisolated(unsafe) public let accept = ParserStateNoTransitionValue( name: Identifier(name: "accept"), withState: accept_type) nonisolated(unsafe) public let reject = ParserStateNoTransitionValue( name: Identifier(name: "reject"), withState: reject_type) public struct ParserStates { public var states: [ParserState] = Array() public func count() -> Int { return states.count } public func find(withIdentifier id: Identifier) -> ParserState? { for state in states { if state.getName() == id { return .some(state) } } return .none } public init(_ states: [ParserState] = Array()) { self.states = states } public func append(state: ParserState) -> ParserStates { var new_states = self.states new_states.append(state) return ParserStates(new_states) } } /// A P4 Parser /// /// Note: A Parser is a type public struct Parser: P4Type { public var states: ParserStates public var name: Identifier public var parameters: ParameterList public init(withName name: Identifier) { self.states = ParserStates() self.parameters = ParameterList() self.name = name } public init(withName name: Identifier, withParameters parameters: ParameterList) { self.states = ParserStates() self.parameters = parameters self.name = name } public func findStartState() -> ParserState? { return self.states.find(withIdentifier: Identifier(name: "start")) } public var description: String { return "Parser \(self.name) with parameters: \(parameters) and states: \(self.states)" } public func def() -> P4DataValue? { return .none } public func eq(rhs: any Common.P4Type) -> Bool { return switch rhs { case let parser_rhs as Parser: self.name == parser_rhs.name default: false } } public func instantiate(_ name: Identifier) -> ParserValue { return ParserValue(self, name) } } /// A instance of a P4 Parser /// public struct ParserValue: P4DataValue { public func type() -> P4Type { return self.tipe } public func eq(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let rrhs as ParserValue: rrhs.type().eq(rhs: self.type()) && self.name == rrhs.name default: false } } public func lt(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let rrhs as ParserValue: rrhs.type().eq(rhs: self.type()) && self.name < rrhs.name default: false } } public func lte(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let rrhs as ParserValue: rrhs.type().eq(rhs: self.type()) && self.name <= rrhs.name default: false } } public func gt(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let rrhs as ParserValue: rrhs.type().eq(rhs: self.type()) && self.name > rrhs.name default: false } } public func gte(rhs: any Common.P4DataValue) -> Bool { return switch rhs { case let rrhs as ParserValue: rrhs.type().eq(rhs: self.type()) && self.name >= rrhs.name default: false } } public var tipe: Parser public var name: Identifier public init(_ tipe: Parser, _ name: Identifier) { self.tipe = tipe self.name = name } public var description: String { return "Parser \(self.name) of type \(self.tipe)" } public func def() -> P4DataValue? { return self.tipe.def() } }