Work On Derived Types

1. Add support for field access
2. Add support for proper type checking of array access
3. Add tests for nested field and array access

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-03-16 08:31:16 -04:00
parent 8ee20fcf9f
commit 2fd5ecf8d6
10 changed files with 629 additions and 72 deletions
+32 -2
View File
@@ -76,10 +76,16 @@ extension P4IntValue: EvaluatableExpression {
}
}
extension P4ArrayValue: EvaluatableExpression {
public func evaluate(execution: Common.ProgramExecution) -> Common.Result<any Common.P4Value> {
return .Ok(self)
}
}
// Variables are evaluatable because they can be looked up by identifiers.
extension TypedIdentifier: EvaluatableExpression {
public func type() -> any Common.P4Type {
return self.parsed_type
return self.type
}
public func evaluate(execution: Common.ProgramExecution) -> Result<P4Value> {
@@ -139,6 +145,30 @@ extension ArrayAccessExpression: EvaluatableExpression {
}
public func type() -> any Common.P4Type {
return P4Int.create()
return self.type.value_type()
}
}
extension FieldAccessExpression: EvaluatableExpression {
public func evaluate(execution: Common.ProgramExecution) -> Common.Result<any Common.P4Value> {
let maybe_struct = self.strct.evaluate(execution: execution)
guard case Result.Ok(let strct) = maybe_struct else {
return maybe_struct
}
guard let struct_strct = strct as? P4StructValue else {
return Result.Error(Error(withMessage: "\(strct) does not identify a struct"))
}
// TODO: Create a default value?
guard let value = struct_strct.get(field: self.field) else {
return .Error(Error(withMessage: "Missing value"))
}
return .Ok(value)
}
public func type() -> any Common.P4Type {
return self.field.type
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ extension ConditionalStatement: EvaluatableStatement {
guard case .Ok(let evaluated_condition) = self.condition.evaluate(execution: execution) else {
return execution.setError(error: Error(withMessage: "Could not evaluate \(self.condition)"))
}
if !evaluated_condition.type().eq(rhs: P4Boolean.create()) {
if !evaluated_condition.type().eq(rhs: P4Boolean()) {
return execution.setError(error: Error(withMessage: "Condition expression is not a Boolean"))
}
if evaluated_condition.eq(rhs: P4BooleanValue.init(withValue: true)) {