compiler, runtime, common, documentation: Refactor Type System
The type system (and the value system) now include attributes for each type (things like direction, const-ness). Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -19,36 +19,29 @@ import Common
|
||||
|
||||
public struct Parameter: CustomStringConvertible, Equatable {
|
||||
public static func == (lhs: Parameter, rhs: Parameter) -> Bool {
|
||||
return lhs.name == rhs.name && lhs.type.eq(rhs: rhs.type) && lhs.direction == rhs.direction
|
||||
return lhs.name == rhs.name && lhs.type.eq(rhs.type)
|
||||
}
|
||||
|
||||
public var name: Identifier
|
||||
public var type: P4Type
|
||||
public var direction: Direction?
|
||||
|
||||
public init(
|
||||
identifier: Identifier, withType type: P4Type, withDirection direction: Direction? = .none
|
||||
identifier: Identifier, withType type: P4Type
|
||||
) {
|
||||
self.name = identifier
|
||||
self.type = type
|
||||
self.direction = direction
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
let direction = self.direction != .none ? self.direction!.description : "no"
|
||||
return "Parameter: \(self.name) with type \(self.type) with \(direction) direction"
|
||||
return "Parameter: \(self.name) with type \(self.type)"
|
||||
}
|
||||
|
||||
/// 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)
|
||||
return arg_type.eq(self.type)
|
||||
}
|
||||
|
||||
public func attributedType() -> P4TypeAttributed {
|
||||
return P4TypeAttributed(
|
||||
self.type, self.direction == .none ? [] : [P4TypeAttribute.Direction(self.direction!)])
|
||||
}
|
||||
}
|
||||
|
||||
public struct ParameterList: CustomStringConvertible, Equatable {
|
||||
|
||||
@@ -120,53 +120,53 @@ public struct Table: CustomStringConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
public struct Control: P4Type, P4Value, Equatable, CustomStringConvertible {
|
||||
public struct Control: P4DataType, P4DataValue, Equatable, CustomStringConvertible {
|
||||
public static func == (lhs: Control, rhs: Control) -> Bool {
|
||||
// Two "bare" controls are always equal.
|
||||
return true
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Type) -> Bool {
|
||||
public func eq(rhs: any Common.P4DataType) -> Bool {
|
||||
return switch rhs {
|
||||
case is Control: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func type() -> any Common.P4Type {
|
||||
public func type() -> any Common.P4DataType {
|
||||
return self
|
||||
}
|
||||
|
||||
// Any operation between two "bare" parser states is always true.
|
||||
public func eq(rhs: any Common.P4Value) -> Bool {
|
||||
public func eq(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is Control: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func lt(rhs: any Common.P4Value) -> Bool {
|
||||
public func lt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is Control: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func lte(rhs: any Common.P4Value) -> Bool {
|
||||
public func lte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is Control: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func gt(rhs: any Common.P4Value) -> Bool {
|
||||
public func gt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is Control: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func gte(rhs: any Common.P4Value) -> Bool {
|
||||
public func gte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is Control: true
|
||||
default: false
|
||||
@@ -200,7 +200,7 @@ public struct Control: P4Type, P4Value, Equatable, CustomStringConvertible {
|
||||
self.table = table
|
||||
}
|
||||
|
||||
public func def() -> any P4Value {
|
||||
public func def() -> any P4DataValue {
|
||||
return Control(
|
||||
named: Identifier(name: ""),
|
||||
withParameters: ParameterList(),
|
||||
|
||||
@@ -19,34 +19,34 @@ import Common
|
||||
|
||||
public struct Declaration {}
|
||||
|
||||
public struct FunctionDeclaration: P4Type, P4Value {
|
||||
public func type() -> any Common.P4Type {
|
||||
public struct FunctionDeclaration: P4DataType, P4DataValue {
|
||||
public func type() -> any Common.P4DataType {
|
||||
return self
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Type) -> Bool {
|
||||
public func eq(rhs: any Common.P4DataType) -> Bool {
|
||||
switch rhs {
|
||||
case let frhs as FunctionDeclaration:
|
||||
return frhs.tipe.eq(rhs: self.tipe) && frhs.params == self.params
|
||||
return frhs.tipe.eq(self.tipe) && frhs.params == self.params
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Value) -> Bool {
|
||||
public func eq(rhs: any Common.P4DataValue) -> Bool {
|
||||
switch rhs {
|
||||
case let frhs as FunctionDeclaration: return self.eq(rhs: frhs as P4Type)
|
||||
case let frhs as FunctionDeclaration: return self.eq(rhs: frhs as P4DataType)
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
public func lt(rhs: any Common.P4Value) -> Bool {
|
||||
public func lt(rhs: any Common.P4DataValue) -> Bool {
|
||||
switch rhs {
|
||||
case let frhs as FunctionDeclaration: return self.name < frhs.name
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
public func lte(rhs: any Common.P4Value) -> Bool {
|
||||
public func lte(rhs: any Common.P4DataValue) -> Bool {
|
||||
switch rhs {
|
||||
case let frhs as FunctionDeclaration: return self.name <= frhs.name
|
||||
default: return false
|
||||
@@ -54,23 +54,24 @@ public struct FunctionDeclaration: P4Type, P4Value {
|
||||
|
||||
}
|
||||
|
||||
public func gt(rhs: any Common.P4Value) -> Bool {
|
||||
public func gt(rhs: any Common.P4DataValue) -> Bool {
|
||||
switch rhs {
|
||||
case let frhs as FunctionDeclaration: return self.name > frhs.name
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
public func gte(rhs: any Common.P4Value) -> Bool {
|
||||
public func gte(rhs: any Common.P4DataValue) -> Bool {
|
||||
switch rhs {
|
||||
case let frhs as FunctionDeclaration: return self.name >= frhs.name
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
public func def() -> any Common.P4Value {
|
||||
public func def() -> any Common.P4DataValue {
|
||||
return FunctionDeclaration(
|
||||
named: Identifier(name: ""), ofType: P4Boolean(), withParameters: ParameterList([]),
|
||||
named: Identifier(name: ""), ofType: P4Type(P4Boolean()),
|
||||
withParameters: ParameterList([]),
|
||||
withBody: .none)
|
||||
}
|
||||
|
||||
|
||||
@@ -25,15 +25,15 @@ public struct KeysetExpression {
|
||||
}
|
||||
|
||||
public func compatible(type: P4Type) -> Result<()> {
|
||||
if let key_type = self.key.type() as? P4Set {
|
||||
if !key_type.set_type().eq(rhs: type) {
|
||||
if let key_type = self.key.type().dataType() as? P4Set {
|
||||
if !key_type.set_type().eq(type) {
|
||||
return .Error(
|
||||
Error(
|
||||
withMessage:
|
||||
"Key expression of type set of type \(key_type.set_type()) is not compatible with selector type \(type)"
|
||||
))
|
||||
}
|
||||
} else if !self.key.type().eq(rhs: type) {
|
||||
} else if !self.key.type().eq(type) {
|
||||
return .Error(
|
||||
Error(
|
||||
withMessage:
|
||||
@@ -66,26 +66,27 @@ public struct SelectCaseExpression {
|
||||
|
||||
public struct SelectExpression {
|
||||
public let selector: EvaluatableExpression
|
||||
public let select_expressions: [SelectCaseExpression]
|
||||
public let case_expressions: [SelectCaseExpression]
|
||||
|
||||
public init(
|
||||
withSelector selector: EvaluatableExpression,
|
||||
withSelectCaseExpressions sces: [SelectCaseExpression]
|
||||
) {
|
||||
self.selector = selector
|
||||
self.select_expressions = sces
|
||||
self.case_expressions = sces
|
||||
}
|
||||
|
||||
public func append_checked_sce(sce: SelectCaseExpression) -> SelectExpression {
|
||||
var new_cses = self.select_expressions
|
||||
var new_cses = self.case_expressions
|
||||
new_cses.append(sce)
|
||||
return SelectExpression(
|
||||
withSelector: self.selector, withSelectCaseExpressions: new_cses)
|
||||
}
|
||||
}
|
||||
|
||||
public typealias NamedBinaryOperatorEvaluator = (String, P4Type, (P4Value, P4Value) -> P4Value)
|
||||
public typealias BinaryOperatorEvaluator = (P4Value, P4Value) -> P4Value
|
||||
public typealias NamedBinaryOperatorEvaluator = (String, P4Type, (P4Value, P4Value) -> P4DataValue)
|
||||
public typealias BinaryOperatorEvaluator = (P4Value, P4Value) -> P4DataValue
|
||||
|
||||
public struct BinaryOperatorExpression {
|
||||
public let evaluator: NamedBinaryOperatorEvaluator
|
||||
public let left: EvaluatableExpression
|
||||
|
||||
+26
-26
@@ -41,53 +41,53 @@ public struct ParserAssignmentStatement {
|
||||
///
|
||||
/// 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, P4Value, Equatable, CustomStringConvertible {
|
||||
public class ParserState: P4DataType, P4DataValue, Equatable, CustomStringConvertible {
|
||||
public static func == (lhs: ParserState, rhs: ParserState) -> Bool {
|
||||
// Two "bare" parser states are always equal.
|
||||
return true
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Type) -> Bool {
|
||||
public func eq(rhs: any Common.P4DataType) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func type() -> any Common.P4Type {
|
||||
public func type() -> any Common.P4DataType {
|
||||
return self
|
||||
}
|
||||
|
||||
// Any operation between two "bare" parser states is always true.
|
||||
public func eq(rhs: any Common.P4Value) -> Bool {
|
||||
public func eq(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func lt(rhs: any Common.P4Value) -> Bool {
|
||||
public func lt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func lte(rhs: any Common.P4Value) -> Bool {
|
||||
public func lte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func gt(rhs: any Common.P4Value) -> Bool {
|
||||
public func gt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func gte(rhs: any Common.P4Value) -> Bool {
|
||||
public func gte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
@@ -101,7 +101,7 @@ public class ParserState: P4Type, P4Value, Equatable, CustomStringConvertible {
|
||||
/// Construct a ParserState
|
||||
public init() {}
|
||||
|
||||
public func def() -> any P4Value {
|
||||
public func def() -> any P4DataValue {
|
||||
return ParserState()
|
||||
}
|
||||
}
|
||||
@@ -116,46 +116,46 @@ public class InstantiatedParserState: ParserState {
|
||||
return lhs.state == rhs.state
|
||||
}
|
||||
|
||||
public override func eq(rhs: any Common.P4Type) -> Bool {
|
||||
public override func eq(rhs: any Common.P4DataType) -> Bool {
|
||||
return switch rhs {
|
||||
case is ParserState: true
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public override func type() -> any Common.P4Type {
|
||||
public override func type() -> any Common.P4DataType {
|
||||
return self
|
||||
}
|
||||
|
||||
public override func eq(rhs: any Common.P4Value) -> Bool {
|
||||
public override func eq(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as InstantiatedParserState: self.state == other.state
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public override func lt(rhs: any Common.P4Value) -> Bool {
|
||||
public override func lt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as InstantiatedParserState: self.state < other.state
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public override func lte(rhs: any Common.P4Value) -> Bool {
|
||||
public override func lte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as InstantiatedParserState: self.state <= other.state
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public override func gt(rhs: any Common.P4Value) -> Bool {
|
||||
public override func gt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as InstantiatedParserState: self.state > other.state
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public override func gte(rhs: any Common.P4Value) -> Bool {
|
||||
public override func gte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as InstantiatedParserState: self.state >= other.state
|
||||
default: false
|
||||
@@ -185,7 +185,7 @@ public class InstantiatedParserState: ParserState {
|
||||
statements = Array()
|
||||
}
|
||||
|
||||
public override func def() -> any P4Value {
|
||||
public override func def() -> any P4DataValue {
|
||||
return InstantiatedParserState(name: Identifier(name: ""))
|
||||
}
|
||||
}
|
||||
@@ -276,40 +276,40 @@ public struct ParserStates {
|
||||
/// A P4 Parser
|
||||
///
|
||||
/// Note: A Parser is both a type _and_ a value.
|
||||
public struct Parser: P4Type, P4Value {
|
||||
public func type() -> any Common.P4Type {
|
||||
public struct Parser: P4DataType, P4DataValue {
|
||||
public func type() -> any Common.P4DataType {
|
||||
return self
|
||||
}
|
||||
|
||||
public func eq(rhs: any Common.P4Type) -> Bool {
|
||||
public func eq(rhs: any Common.P4DataType) -> Bool {
|
||||
return switch rhs {
|
||||
case let parser_rhs as Parser: self.name == parser_rhs.name
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func lt(rhs: any Common.P4Value) -> Bool {
|
||||
public func lt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let parser_rhs as Parser: self.name < parser_rhs.name
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func lte(rhs: any Common.P4Value) -> Bool {
|
||||
public func lte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let parser_rhs as Parser: self.name <= parser_rhs.name
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func gt(rhs: any Common.P4Value) -> Bool {
|
||||
public func gt(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let parser_rhs as Parser: self.name > parser_rhs.name
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
public func gte(rhs: any Common.P4Value) -> Bool {
|
||||
public func gte(rhs: any Common.P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let parser_rhs as Parser: self.name >= parser_rhs.name
|
||||
default: false
|
||||
@@ -342,7 +342,7 @@ public struct Parser: P4Type, P4Value {
|
||||
return .none
|
||||
}
|
||||
|
||||
public func eq(rhs: any P4Value) -> Bool {
|
||||
public func eq(rhs: any P4DataValue) -> Bool {
|
||||
return switch rhs {
|
||||
case let other as Parser: self.name == other.name
|
||||
default: false
|
||||
@@ -353,7 +353,7 @@ public struct Parser: P4Type, P4Value {
|
||||
return "Parser \(self.name) with parameters: \(parameters) and states: \(self.states)"
|
||||
}
|
||||
|
||||
public func def() -> any P4Value {
|
||||
public func def() -> any P4DataValue {
|
||||
return Parser(withName: Identifier(name: ""))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,16 +22,16 @@ public struct ExpressionStatement {
|
||||
}
|
||||
|
||||
public struct Program {
|
||||
public var types: [P4Type] = Array()
|
||||
public var instances: [P4TypeAttributed] = Array()
|
||||
public var types: [P4DataType] = Array()
|
||||
public var instances: [P4Type] = Array()
|
||||
|
||||
/// Type of closure for filtering results from ``Program/InstancesWithTypes(_:)``
|
||||
public typealias AttributedTypeFilter = (P4TypeAttributed) -> Bool
|
||||
public typealias AttributedTypeFilter = (P4Type) -> Bool
|
||||
/// Type of closure for filtering results from ``Program/TypesWithTypes(_:)``
|
||||
public typealias TypeFilter = (P4Type) -> Bool
|
||||
public typealias TypeFilter = (P4DataType) -> Bool
|
||||
|
||||
/// Retrieve global instances in the compiled P4 program.
|
||||
public func InstancesWithTypes() -> [P4TypeAttributed] {
|
||||
public func InstancesWithTypes() -> [P4Type] {
|
||||
return self.instances
|
||||
}
|
||||
|
||||
@@ -47,14 +47,14 @@ public struct Program {
|
||||
///
|
||||
/// @Snippet(path: "use-program-instanceswithtypes", slice: "include")
|
||||
///
|
||||
public func InstancesWithTypes(_ filter: AttributedTypeFilter) -> [P4TypeAttributed] {
|
||||
public func InstancesWithTypes(_ filter: AttributedTypeFilter) -> [P4Type] {
|
||||
return self.instances.filter { instance in
|
||||
filter(instance)
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve global types in the compiled P4 program.
|
||||
public func TypesWithTypes() -> [P4Type] {
|
||||
public func TypesWithTypes() -> [P4DataType] {
|
||||
return self.types
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public struct Program {
|
||||
///
|
||||
/// @Snippet(path: "use-program-typeswithtypes", slice: "include")
|
||||
///
|
||||
public func TypesWithTypes(_ filter: TypeFilter) -> [P4Type] {
|
||||
public func TypesWithTypes(_ filter: TypeFilter) -> [P4DataType] {
|
||||
return self.types.filter { instance in
|
||||
filter(instance)
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public struct Program {
|
||||
|
||||
public func find_parser(withName name: Identifier) -> Result<Parser> {
|
||||
for instance in self.instances {
|
||||
guard let parser = instance.type as? Parser else {
|
||||
guard let parser = instance.dataType() as? Parser else {
|
||||
continue
|
||||
}
|
||||
if parser.name == name {
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
import Common
|
||||
|
||||
public struct AttributedP4Type {
|
||||
public let type: P4Type
|
||||
public let attributes: P4TypeAttributed
|
||||
public let type: P4DataType
|
||||
public let attributes: P4Type
|
||||
|
||||
public init(_ type: P4Type, _ attributes: P4TypeAttributed) {
|
||||
public init(_ type: P4DataType, _ attributes: P4Type) {
|
||||
self.type = type
|
||||
self.attributes = attributes
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user