compiler, runtime: Control Declarations Have Apply Statements

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-04-20 03:35:55 -04:00
parent 1847df7fab
commit c6f086f67f
5 changed files with 70 additions and 4 deletions
+26 -3
View File
@@ -452,6 +452,7 @@ extension Control: CompilableDeclaration {
var actions: [Action] = Array()
var tables: [Table] = Array()
var apply: ApplyStatement? = .none
// Because the final child
// is the '}'.
@@ -478,6 +479,20 @@ extension Control: CompilableDeclaration {
}
tables.append(table_declaration)
local_context = updated_context
} else if currentChild.nodeType == "apply_statement" {
// When we see an apply, that is it for the actions and the tables.
let maybe_apply_statement = ApplyStatement.Compile(
node: currentChild, withContext: local_context)
guard
case .Ok((let apply_statement, let updated_context)) = maybe_apply_statement
else {
return .Error(maybe_apply_statement.error()!)
}
local_context = updated_context
apply = (apply_statement as! ApplyStatement)
// The apply is the last thing in a control declaration.
break;
} else {
return .Error(
ErrorOnNode(node: currentChild, withError: "Uknown node type in control declaration"))
@@ -494,10 +509,16 @@ extension Control: CompilableDeclaration {
ErrorOnNode(node: node, withError: "More than one table in control declaration"))
}
// Check to make sure that there is an apply.
guard let apply = apply else {
return .Error(
ErrorOnNode(node: node, withError: "Missing apply in control declaration"))
}
let declared_control =
(Control(
named: control_name, withParameters: control_parameters, withTable: tables[0],
withActions: Actions(withActions: actions))
withActions: Actions(withActions: actions), withApply: apply)
as P4DataType)
// Don't forget to add the newly declared Control to the instance that we were given
@@ -572,15 +593,17 @@ extension Action: Compilable {
identifier: parameter.name, withValue: parameter.type)
}
let maybe_action_body = Parser.Statement.Compile(
let maybe_action_body = BlockStatement.Compile(
node: currentChild!, withContext: context.update(newInstances: function_scope))
guard case .Ok((let action_body, _)) = maybe_action_body else {
return .Error(maybe_action_body.error()!)
}
// TODO: Actions cannot contain switches!
return .Ok(
(
Action(named: action_name, withParameters: action_parameters, withBody: action_body),
Action(named: action_name, withParameters: action_parameters, withBody: (action_body as! BlockStatement)),
current_context
))
}
+16
View File
@@ -329,3 +329,19 @@ extension ReturnStatement: CompilableStatement {
}
}
}
extension ApplyStatement: CompilableStatement {
public static func Compile(
node: SwiftTreeSitter.Node, withContext context: CompilerContext
) -> Common.Result<(any Common.EvaluatableStatement, CompilerContext)> {
#RequireNodeType<Node, (EvaluatableStatement, CompilerContext)>(
node: node, type: "apply_statement", nice_type_name: "apply statement")
let expression_node = node.child(at: 1)!
return switch BlockStatement.Compile(node: expression_node, withContext: context) {
case .Ok((let statement, let updated_context)): .Ok((ApplyStatement(statement as! BlockStatement), updated_context))
case .Error(let e): .Error(e)
}
}
}
+9
View File
@@ -63,3 +63,12 @@ public struct ReturnStatement {
self.value = value
}
}
public struct ApplyStatement {
public let body: BlockStatement?
public init() { self.body = .none }
public init(_ body: BlockStatement) {
self.body = body
}
}
+6
View File
@@ -123,3 +123,9 @@ extension ReturnStatement: EvaluatableStatement {
}
}
}
extension ApplyStatement: EvaluatableStatement {
public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) {
return (ControlFlow.Next, execution)
}
}