Support Setting Arrays/Fields
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
public typealias TypeScope = Scope<P4Type>
|
||||
public typealias TypeScopes = Scopes<P4Type>
|
||||
@@ -117,6 +117,18 @@ public struct P4StructFields: Sequence, CustomStringConvertible, Equatable {
|
||||
public func count() -> Int {
|
||||
return self.fields.count
|
||||
}
|
||||
|
||||
public func describe_with_values(values: [P4Value?]) -> String {
|
||||
assert(values.count == self.count())
|
||||
return zip(self.fields, values).map() { (field, value) in
|
||||
let actual_value = if let v = value {
|
||||
v.description
|
||||
} else {
|
||||
"Unset"
|
||||
}
|
||||
return String("\(field): \(actual_value)")
|
||||
}.joined(separator: "; ")
|
||||
}
|
||||
}
|
||||
|
||||
/// The type for a P4 struct
|
||||
@@ -159,7 +171,7 @@ public class P4StructValue: P4Value {
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
return "Struct"
|
||||
return "Struct: \(self.stype.fields.describe_with_values(values: self.values))"
|
||||
}
|
||||
|
||||
public let stype: P4Struct
|
||||
@@ -169,7 +181,7 @@ public class P4StructValue: P4Value {
|
||||
self.init(withType: type, andInitializers: [])
|
||||
}
|
||||
|
||||
public init(withType type: P4Struct, andInitializers initializers: [P4Value]) {
|
||||
public init(withType type: P4Struct, andInitializers initializers: [P4Value?]) {
|
||||
var values: [P4Value?] = Array(repeating: .none, count: type.fields.count())
|
||||
|
||||
for i in 0..<initializers.count {
|
||||
@@ -188,6 +200,23 @@ public class P4StructValue: P4Value {
|
||||
}
|
||||
return .none
|
||||
}
|
||||
|
||||
public func set(field: P4StructFieldIdentifier, to: P4Value) -> Result<P4StructValue> {
|
||||
var updated_values = self.values
|
||||
|
||||
for field_idx in 0..<stype.fields.count() {
|
||||
if stype.fields.fields[field_idx] == field {
|
||||
if !stype.fields.fields[field_idx].type.eq(rhs: to.type()) {
|
||||
return .Error(Error(withMessage: "Cannot assign value with type \(to.type()) to field with type \(stype.fields.fields[field_idx].type))"))
|
||||
}
|
||||
updated_values[field_idx] = to
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return .Ok(P4StructValue(withType: self.stype, andInitializers: updated_values))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// A P4 boolean type
|
||||
@@ -337,18 +366,25 @@ public class P4ArrayValue: P4Value {
|
||||
return P4Array(withValueType: self.vtype)
|
||||
}
|
||||
|
||||
let value: [EvaluatableExpression]
|
||||
let value: [P4Value]
|
||||
let vtype: P4Type
|
||||
|
||||
public init(withType type: P4Type, withValue value: [EvaluatableExpression]) {
|
||||
public init(withType type: P4Type, withValue value: [P4Value]) {
|
||||
self.vtype = type
|
||||
self.value = value
|
||||
}
|
||||
|
||||
public func access(_ index: Int) -> EvaluatableExpression {
|
||||
public func access(_ index: Int) -> P4Value {
|
||||
return self.value[index]
|
||||
}
|
||||
|
||||
public func set(index: Int, to: P4Value) -> Result<P4ArrayValue> {
|
||||
// TODO: Check for OOB
|
||||
var updated_values = self.value
|
||||
updated_values[index] = to
|
||||
return Result.Ok(P4ArrayValue(withType: self.vtype, withValue: updated_values))
|
||||
}
|
||||
|
||||
public func eq(rhs: P4Value) -> Bool {
|
||||
guard rhs as? P4ArrayValue != nil else {
|
||||
return false
|
||||
|
||||
@@ -40,3 +40,8 @@ public protocol P4Value: CustomStringConvertible {
|
||||
func type() -> any P4Type
|
||||
func eq(rhs: P4Value) -> Bool
|
||||
}
|
||||
|
||||
public protocol EvaluatableLValueExpression: EvaluatableExpression {
|
||||
func set(to: P4Value, inScopes scopes: ValueScopes, duringExecution execution: ProgramExecution) -> Result<(ValueScopes, P4Value)>
|
||||
func check(to: EvaluatableExpression, inScopes scopes: TypeScopes) -> Result<()>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user