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 actions: [Action] = Array()
var tables: [Table] = Array() var tables: [Table] = Array()
var apply: ApplyStatement? = .none
// Because the final child // Because the final child
// is the '}'. // is the '}'.
@@ -478,6 +479,20 @@ extension Control: CompilableDeclaration {
} }
tables.append(table_declaration) tables.append(table_declaration)
local_context = updated_context 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 { } else {
return .Error( return .Error(
ErrorOnNode(node: currentChild, withError: "Uknown node type in control declaration")) 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")) 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 = let declared_control =
(Control( (Control(
named: control_name, withParameters: control_parameters, withTable: tables[0], named: control_name, withParameters: control_parameters, withTable: tables[0],
withActions: Actions(withActions: actions)) withActions: Actions(withActions: actions), withApply: apply)
as P4DataType) as P4DataType)
// Don't forget to add the newly declared Control to the instance that we were given // 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) 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)) node: currentChild!, withContext: context.update(newInstances: function_scope))
guard case .Ok((let action_body, _)) = maybe_action_body else { guard case .Ok((let action_body, _)) = maybe_action_body else {
return .Error(maybe_action_body.error()!) return .Error(maybe_action_body.error()!)
} }
// TODO: Actions cannot contain switches!
return .Ok( 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 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 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)
}
}
+13 -1
View File
@@ -37,6 +37,8 @@ import P4Lang
true: exact; true: exact;
} }
} }
apply {
}
}; };
""" """
let x = { (tipe: P4Type) -> Bool in let x = { (tipe: P4Type) -> Bool in
@@ -61,6 +63,8 @@ import P4Lang
true: exact; true: exact;
} }
} }
apply {
}
}; };
control complex() { control complex() {
action b() { action b() {
@@ -70,6 +74,8 @@ import P4Lang
true: exact; true: exact;
} }
} }
apply {
}
}; };
""" """
@@ -94,6 +100,8 @@ import P4Lang
y: exact; y: exact;
} }
} }
apply {
}
}; };
""" """
#expect(#RequireOkResult(Program.Compile(simple_parser_declaration))) #expect(#RequireOkResult(Program.Compile(simple_parser_declaration)))
@@ -111,6 +119,8 @@ import P4Lang
y: exact; y: exact;
} }
} }
apply {
}
}; };
""" """
#expect(#RequireOkResult(Program.Compile(simple_parser_declaration))) #expect(#RequireOkResult(Program.Compile(simple_parser_declaration)))
@@ -128,13 +138,15 @@ import P4Lang
y: exact; y: exact;
} }
} }
apply {
}
}; };
""" """
#expect( #expect(
#RequireErrorResult( #RequireErrorResult(
Error( Error(
withMessage: withMessage:
"{51, 20}: Failed to parse a statement element: {57, 10}: Failed to parse a statement element: {57, 1}: Cannot assign value with type Boolean to identifier z with type Int" "{57, 10}: Failed to parse a statement element: {57, 1}: Cannot assign value with type Boolean to identifier z with type Int"
), ),
Program.Compile(simple_parser_declaration)) Program.Compile(simple_parser_declaration))
) )