Better Support For Keysets

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-03-27 01:36:38 -04:00
parent fafc80553e
commit 99804e3053
7 changed files with 476 additions and 51 deletions
+113 -11
View File
@@ -17,43 +17,145 @@
import Common
public struct KeysetExpression {
public class KeysetExpression {
public func update_type(to: P4Type) -> Result<KeysetExpression> {
return .Ok(self)
}
public func kse_evaluate(execution: Common.ProgramExecution) -> Result<P4Value> {
return .Error(Error(withMessage: "Missing key in keyset expression"))
}
public func kse_type() -> P4Type {
return P4Boolean()
}
}
public class NonDefaultKeysetExpression: KeysetExpression {
public let key: EvaluatableExpression
public init(_ key: EvaluatableExpression) {
self.key = key
}
// Some keyset expressions need additional
// context about their types -- e.g., default.
// Override to update and return true if the
// update is safe.
public override func update_type(to: P4Type) -> Result<KeysetExpression> {
// In the default case, if the current key type
// does not match the updated type, that's an
// error.
return Map(input: key.type().eq(rhs: to)) { input in
input
? .Ok(self)
: .Error(
Error(withMessage: "Keyset expression type does not match selector expression type"))
}
}
public override func kse_evaluate(execution: Common.ProgramExecution) -> Result<P4Value> {
return self.key.evaluate(execution: execution)
}
public override func kse_type() -> P4Type {
return self.key.type()
}
}
public class DefaultKeysetExpression: KeysetExpression {
let type: P4Type
public init(withType type: P4Type) {
self.type = type
}
public override func update_type(to: P4Type) -> Result<KeysetExpression> {
return Map(input: type.eq(rhs: to)) { input in
input
? .Ok(DefaultKeysetExpression(withType: to))
: .Error(
Error(withMessage: "Keyset expression type does not match selector expression type"))
}
}
public override func kse_evaluate(execution: Common.ProgramExecution) -> Result<P4Value> {
return .Ok(P4SetDefaultValue(withType: self.type))
}
public override func kse_type() -> P4Type {
return P4Set(withSetType: self.type)
}
}
public class PlaceholderDefaultKeysetExpression: KeysetExpression {
public override init() {}
public override func update_type(to: P4Type) -> Result<KeysetExpression> {
.Ok(DefaultKeysetExpression(withType: to))
}
public override func kse_evaluate(execution: Common.ProgramExecution) -> Result<P4Value> {
return .Error(Error(withMessage: "Cannot evaluate a placeholder default keyset expression"))
}
public override func kse_type() -> P4Type {
return P4Set(withSetType: P4Boolean())
}
}
public struct SelectCaseExpression {
public let key: KeysetExpression
public let next_state_identifier: Identifier
public let next_state: ParserState?
public init(withKey key: EvaluatableExpression, withNextState next_state_id: Identifier) {
public init(withKey key: KeysetExpression, withNextState next_state_id: Identifier) {
self.key = key
self.next_state_identifier = next_state_id
self.next_state = .none
}
public init(
withKey key: EvaluatableExpression, withNextState next_state_id: Identifier,
withNextState next_state: ParserState
withKey key: KeysetExpression, withNextState next_state_id: Identifier,
withNextState next_state: ParserState?
) {
self.key = key
self.next_state_identifier = next_state_id
self.next_state = next_state
}
// Some keyset expressions need additional
// context about their types -- e.g., default.
// Override to update and return true if the
public func update_type(to: P4Type) -> Result<SelectCaseExpression> {
switch key.update_type(to: to) {
case .Ok(let new_kse):
.Ok(
SelectCaseExpression(
withKey: new_kse, withNextState: self.next_state_identifier,
withNextState: self.next_state))
case .Error(let e): .Error(e)
}
}
}
public struct SelectExpression {
public let selector: EvaluatableExpression
public let keyset_expressions: [KeysetExpression]
public let select_expressions: [SelectCaseExpression]
public init(
withSelector selector: EvaluatableExpression, withKeysetExpressions kses: [KeysetExpression]
withSelector selector: EvaluatableExpression,
withSelectCaseExpressions kses: [SelectCaseExpression]
) {
self.selector = selector
self.keyset_expressions = kses
self.select_expressions = kses
}
public func append_checked_kse(kse: KeysetExpression) -> SelectExpression {
var new_kse = self.keyset_expressions
new_kse.append(kse)
public func append_checked_sce(sce: SelectCaseExpression) -> SelectExpression {
var new_cses = self.select_expressions
new_cses.append(sce)
return SelectExpression(
withSelector: self.selector, withKeysetExpressions: new_kse)
withSelector: self.selector, withSelectCaseExpressions: new_cses)
}
}