@@ -16,7 +16,8 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
public typealias StatementInterloper = (EvaluatableStatement, ControlFlow, ProgramExecution) -> Void
|
public typealias StatementInterloper = (EvaluatableStatement, ControlFlow, ProgramExecution) -> Void
|
||||||
public typealias ExpressionInterloper = (EvaluatableExpression, Result<P4Value>, ProgramExecution) -> Void
|
public typealias ExpressionInterloper = (EvaluatableExpression, Result<P4Value>, ProgramExecution)
|
||||||
|
-> Void
|
||||||
|
|
||||||
open class ProgramExecution: CustomStringConvertible {
|
open class ProgramExecution: CustomStringConvertible {
|
||||||
public var scopes: VarValueScopes = VarValueScopes()
|
public var scopes: VarValueScopes = VarValueScopes()
|
||||||
@@ -75,7 +76,9 @@ open class ProgramExecution: CustomStringConvertible {
|
|||||||
return self.statement_interloper
|
return self.statement_interloper
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setStatementInterloper(_ interloper: @escaping StatementInterloper) -> ProgramExecution {
|
public func setStatementInterloper(
|
||||||
|
_ interloper: @escaping StatementInterloper
|
||||||
|
) -> ProgramExecution {
|
||||||
let pe = ProgramExecution(copy: self)
|
let pe = ProgramExecution(copy: self)
|
||||||
pe.statement_interloper = interloper
|
pe.statement_interloper = interloper
|
||||||
return pe
|
return pe
|
||||||
@@ -85,7 +88,9 @@ open class ProgramExecution: CustomStringConvertible {
|
|||||||
return self.expression_interloper
|
return self.expression_interloper
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setExpressionInterloper(_ interloper: @escaping ExpressionInterloper) -> ProgramExecution {
|
public func setExpressionInterloper(
|
||||||
|
_ interloper: @escaping ExpressionInterloper
|
||||||
|
) -> ProgramExecution {
|
||||||
let pe = ProgramExecution(copy: self)
|
let pe = ProgramExecution(copy: self)
|
||||||
pe.expression_interloper = interloper
|
pe.expression_interloper = interloper
|
||||||
return pe
|
return pe
|
||||||
@@ -138,7 +143,6 @@ open class ProgramExecution: CustomStringConvertible {
|
|||||||
return new_pe
|
return new_pe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A scope that resolves variable identifiers to their values.
|
/// A scope that resolves variable identifiers to their values.
|
||||||
|
|||||||
@@ -363,8 +363,9 @@ func ContainsInvalidStatements(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func ContainsInvalidStatements(block: BlockStatement, invalids: [EvaluatableStatement.Type]) -> Bool {
|
func ContainsInvalidStatements(block: BlockStatement, invalids: [EvaluatableStatement.Type]) -> Bool
|
||||||
return block.statements.contains() { statement in
|
{
|
||||||
|
return block.statements.contains { statement in
|
||||||
for es in invalids {
|
for es in invalids {
|
||||||
if type(of: statement) == es {
|
if type(of: statement) == es {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -492,7 +492,7 @@ extension Control: CompilableDeclaration {
|
|||||||
apply = (apply_statement as! ApplyStatement)
|
apply = (apply_statement as! ApplyStatement)
|
||||||
|
|
||||||
// The apply is the last thing in a control declaration.
|
// The apply is the last thing in a control declaration.
|
||||||
break;
|
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"))
|
||||||
@@ -603,7 +603,9 @@ extension Action: Compilable {
|
|||||||
|
|
||||||
return .Ok(
|
return .Ok(
|
||||||
(
|
(
|
||||||
Action(named: action_name, withParameters: action_parameters, withBody: (action_body as! BlockStatement)),
|
Action(
|
||||||
|
named: action_name, withParameters: action_parameters,
|
||||||
|
withBody: (action_body as! BlockStatement)),
|
||||||
current_context
|
current_context
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,8 +247,8 @@ extension ExpressionStatement: CompilableStatement {
|
|||||||
let expression_node = node.child(at: 0)!
|
let expression_node = node.child(at: 0)!
|
||||||
|
|
||||||
return switch Expression.Compile(node: expression_node, withContext: context) {
|
return switch Expression.Compile(node: expression_node, withContext: context) {
|
||||||
case .Ok(let expression): .Ok((ExpressionStatement(expression), context))
|
case .Ok(let expression): .Ok((ExpressionStatement(expression), context))
|
||||||
case .Error(let e): .Error(e)
|
case .Error(let e): .Error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,7 +340,8 @@ extension ApplyStatement: CompilableStatement {
|
|||||||
let expression_node = node.child(at: 1)!
|
let expression_node = node.child(at: 1)!
|
||||||
|
|
||||||
return switch BlockStatement.Compile(node: expression_node, withContext: context) {
|
return switch BlockStatement.Compile(node: expression_node, withContext: context) {
|
||||||
case .Ok((let statement, let updated_context)): .Ok((ApplyStatement(statement as! BlockStatement), updated_context))
|
case .Ok((let statement, let updated_context)):
|
||||||
|
.Ok((ApplyStatement(statement as! BlockStatement), updated_context))
|
||||||
case .Error(let e): .Error(e)
|
case .Error(let e): .Error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ public func Call<T>(
|
|||||||
return (.Ok(call_result), updated_execution.replaceScopes(inout_scopes))
|
return (.Ok(call_result), updated_execution.replaceScopes(inout_scopes))
|
||||||
}
|
}
|
||||||
|
|
||||||
public typealias ExecuteStatementResultHandler = (ControlFlow, ProgramExecution) -> (ControlFlow, ProgramExecution)
|
public typealias ExecuteStatementResultHandler = (ControlFlow, ProgramExecution) -> (
|
||||||
|
ControlFlow, ProgramExecution
|
||||||
|
)
|
||||||
|
|
||||||
public func ExecuteStatement(
|
public func ExecuteStatement(
|
||||||
_ statements: [EvaluatableStatement], handleResult handler: ExecuteStatementResultHandler,
|
_ statements: [EvaluatableStatement], handleResult handler: ExecuteStatementResultHandler,
|
||||||
@@ -119,7 +121,8 @@ public func ExecuteStatement(
|
|||||||
|
|
||||||
public func ExecuteStatement(
|
public func ExecuteStatement(
|
||||||
_ statement: EvaluatableStatement, handleResult handler: ExecuteStatementResultHandler,
|
_ statement: EvaluatableStatement, handleResult handler: ExecuteStatementResultHandler,
|
||||||
inExecution execution: ProgramExecution) -> (ControlFlow, ProgramExecution) {
|
inExecution execution: ProgramExecution
|
||||||
|
) -> (ControlFlow, ProgramExecution) {
|
||||||
return ExecuteStatement([statement], handleResult: handler, inExecution: execution)
|
return ExecuteStatement([statement], handleResult: handler, inExecution: execution)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ extension SelectExpression: EvaluatableExpression {
|
|||||||
switch EvaluateExpression(self.selector, inExecution: execution) {
|
switch EvaluateExpression(self.selector, inExecution: execution) {
|
||||||
case (.Ok(let selector_value), let updated_execution):
|
case (.Ok(let selector_value), let updated_execution):
|
||||||
for sce in self.case_expressions {
|
for sce in self.case_expressions {
|
||||||
if case (.Ok(let kse), let updated_execution) = EvaluateExpression(sce.key, inExecution: updated_execution),
|
if case (.Ok(let kse), let updated_execution) = EvaluateExpression(
|
||||||
|
sce.key, inExecution: updated_execution),
|
||||||
kse.eq(selector_value)
|
kse.eq(selector_value)
|
||||||
{
|
{
|
||||||
//let result = sce.evaluate(execution: updated_execution)
|
//let result = sce.evaluate(execution: updated_execution)
|
||||||
|
|||||||
@@ -44,12 +44,12 @@ extension ParserStateDirectTransition: EvaluatableParserState {
|
|||||||
) -> (any EvaluatableParserState, Common.ProgramExecution) {
|
) -> (any EvaluatableParserState, Common.ProgramExecution) {
|
||||||
var program = program.enter_scope()
|
var program = program.enter_scope()
|
||||||
|
|
||||||
|
let (control_flow, next_execution) = ExecuteStatement(
|
||||||
let (control_flow, next_execution) = ExecuteStatement(statements, handleResult: { (control_flow, execution) in
|
statements,
|
||||||
return (control_flow, execution)
|
handleResult: { (control_flow, execution) in
|
||||||
|
return (control_flow, execution)
|
||||||
}, inExecution: program)
|
}, inExecution: program)
|
||||||
|
|
||||||
|
|
||||||
switch control_flow {
|
switch control_flow {
|
||||||
case .Next: program = next_execution
|
case .Next: program = next_execution
|
||||||
case .Error: return (reject, next_execution.exit_scope())
|
case .Error: return (reject, next_execution.exit_scope())
|
||||||
@@ -105,11 +105,12 @@ extension ParserStateSelectTransition: EvaluatableParserState {
|
|||||||
) -> (any EvaluatableParserState, Common.ProgramExecution) {
|
) -> (any EvaluatableParserState, Common.ProgramExecution) {
|
||||||
var program = program.enter_scope()
|
var program = program.enter_scope()
|
||||||
|
|
||||||
let (control_flow, next_execution) = ExecuteStatement(statements, handleResult: { (control_flow, execution) in
|
let (control_flow, next_execution) = ExecuteStatement(
|
||||||
return (control_flow, execution)
|
statements,
|
||||||
|
handleResult: { (control_flow, execution) in
|
||||||
|
return (control_flow, execution)
|
||||||
}, inExecution: program)
|
}, inExecution: program)
|
||||||
|
|
||||||
|
|
||||||
switch control_flow {
|
switch control_flow {
|
||||||
case .Next: program = next_execution
|
case .Next: program = next_execution
|
||||||
case .Error: return (reject, next_execution.exit_scope())
|
case .Error: return (reject, next_execution.exit_scope())
|
||||||
@@ -121,7 +122,6 @@ extension ParserStateSelectTransition: EvaluatableParserState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//switch self.selectExpression.evaluate(execution: program) {
|
//switch self.selectExpression.evaluate(execution: program) {
|
||||||
switch EvaluateExpression(self.selectExpression, inExecution: program) {
|
switch EvaluateExpression(self.selectExpression, inExecution: program) {
|
||||||
case (.Ok(let value), let program):
|
case (.Ok(let value), let program):
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ public struct ParserRuntime: CustomStringConvertible {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func run(withArguments arguments: ArgumentList) -> Result<(ParserState, ProgramExecution)> {
|
public func run(withArguments arguments: ArgumentList) -> Result<(ParserState, ProgramExecution)>
|
||||||
|
{
|
||||||
let pe =
|
let pe =
|
||||||
if let initial = initialValues {
|
if let initial = initialValues {
|
||||||
ProgramExecution(withGlobalValues: initial)
|
ProgramExecution(withGlobalValues: initial)
|
||||||
@@ -67,14 +68,16 @@ public struct ParserRuntime: CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run the P4 parser on a given packet
|
/// Run the P4 parser on a given packet
|
||||||
public func run(withArguments arguments: ArgumentList, inExecution pe: ProgramExecution) -> Result<(ParserState, ProgramExecution)>
|
public func run(
|
||||||
{
|
withArguments arguments: ArgumentList, inExecution pe: ProgramExecution
|
||||||
|
) -> Result<(ParserState, ProgramExecution)> {
|
||||||
|
|
||||||
let pe = if let globals = initialValues {
|
let pe =
|
||||||
pe.setGlobalValues(globals)
|
if let globals = initialValues {
|
||||||
} else {
|
pe.setGlobalValues(globals)
|
||||||
pe
|
} else {
|
||||||
}
|
pe
|
||||||
|
}
|
||||||
|
|
||||||
let (end_state, execution) = parser.call(execution: pe, arguments: arguments)
|
let (end_state, execution) = parser.call(execution: pe, arguments: arguments)
|
||||||
if let error = execution.getError() {
|
if let error = execution.getError() {
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ extension VariableDeclarationStatement: EvaluatableStatement {
|
|||||||
public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) {
|
public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) {
|
||||||
guard
|
guard
|
||||||
//case (.Ok(let initial_value), let execution) = self.initializer.evaluate(execution: execution)
|
//case (.Ok(let initial_value), let execution) = self.initializer.evaluate(execution: execution)
|
||||||
case (.Ok(let initial_value), let execution) = EvaluateExpression(self.initializer, inExecution: execution)
|
case (.Ok(let initial_value), let execution) = EvaluateExpression(
|
||||||
|
self.initializer, inExecution: execution)
|
||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
ControlFlow.Error,
|
ControlFlow.Error,
|
||||||
@@ -61,7 +62,8 @@ extension ConditionalStatement: EvaluatableStatement {
|
|||||||
public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) {
|
public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) {
|
||||||
guard
|
guard
|
||||||
//case (.Ok(let evaluated_condition), let execution) = self.condition.evaluate(execution: execution)
|
//case (.Ok(let evaluated_condition), let execution) = self.condition.evaluate(execution: execution)
|
||||||
case (.Ok(let evaluated_condition), let execution) = EvaluateExpression(self.condition, inExecution: execution)
|
case (.Ok(let evaluated_condition), let execution) = EvaluateExpression(
|
||||||
|
self.condition, inExecution: execution)
|
||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
ControlFlow.Error,
|
ControlFlow.Error,
|
||||||
|
|||||||
Reference in New Issue
Block a user