compiler, runtime: Control Declarations Have Apply Statements
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -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
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -123,3 +123,9 @@ extension ReturnStatement: EvaluatableStatement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension ApplyStatement: EvaluatableStatement {
|
||||||
|
public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) {
|
||||||
|
return (ControlFlow.Next, execution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user