diff --git a/Sources/P4Runtime/Common.swift b/Sources/P4Runtime/Common.swift index d486da3..87d0fe5 100644 --- a/Sources/P4Runtime/Common.swift +++ b/Sources/P4Runtime/Common.swift @@ -22,7 +22,7 @@ public func Call( body: (ProgramExecution) -> (Result, ProgramExecution), withArguments args: ArgumentList, withParameters params: ParameterList, inExecution execution: ProgramExecution ) -> (Result, ProgramExecution) { - + if case .Error(let e) = args.compatible(params) { return (.Error(e), execution) } @@ -53,21 +53,32 @@ public func Call( for (parameter, argument) in zip(params.parameters, args.arguments) { if let param_direction = parameter.type.direction(), - param_direction == Direction.InOut || param_direction == Direction.Out { + param_direction == Direction.InOut || param_direction == Direction.Out + { // Let's make sure that it is an evaluatable l value! guard let arg_lvalue = argument.argument as? EvaluatableLValueExpression else { - return (.Error(Error(withMessage: "(in)out parameter argument is not lvalue")), updated_execution.exit_scope()) + return ( + .Error(Error(withMessage: "(in)out parameter argument is not lvalue")), + updated_execution.exit_scope() + ) } - guard case .Ok(let arg_new_value) = updated_execution.scopes.lookup(identifier: parameter.name) else { - return (.Error(Error(withMessage: "Could not get (in)out parameter value from scope")), updated_execution.exit_scope()) + guard + case .Ok(let arg_new_value) = updated_execution.scopes.lookup(identifier: parameter.name) + else { + return ( + .Error(Error(withMessage: "Could not get (in)out parameter value from scope")), + updated_execution.exit_scope() + ) } - switch arg_lvalue.set(to: arg_new_value, inScopes: inout_scopes, duringExecution: updated_execution) { - case .Ok((let updated_scopes, _)): inout_scopes = updated_scopes - case .Error(let e): return (.Error(e), updated_execution.exit_scope()) + switch arg_lvalue.set( + to: arg_new_value, inScopes: inout_scopes, duringExecution: updated_execution) + { + case .Ok((let updated_scopes, _)): inout_scopes = updated_scopes + case .Error(let e): return (.Error(e), updated_execution.exit_scope()) } - } + } } return (.Ok(call_result), updated_execution.replaceScopes(inout_scopes)) -} \ No newline at end of file +} diff --git a/Sources/P4Runtime/Expressions.swift b/Sources/P4Runtime/Expressions.swift index 9565eb3..c374a9c 100644 --- a/Sources/P4Runtime/Expressions.swift +++ b/Sources/P4Runtime/Expressions.swift @@ -33,7 +33,8 @@ extension SelectExpression: EvaluatableExpression { switch self.selector.evaluate(execution: execution) { case (.Ok(let selector_value), let updated_execution): for sce in self.case_expressions { - if case (.Ok(let kse), let updated_execution) = sce.key.evaluate(execution: updated_execution), + if case (.Ok(let kse), let updated_execution) = sce.key.evaluate( + execution: updated_execution), kse.eq(selector_value) { let result = sce.evaluate(execution: updated_execution) @@ -82,10 +83,23 @@ extension TypedIdentifier: EvaluatableLValueExpression { } return switch type.assignableFromType(to.type()) { - case TypeCheckResults.IncompatibleTypes: .Error( Error( withMessage: "Cannot assign value with type \(to.type()) to identifier \(self) with type \(type)")) - case TypeCheckResults.ReadOnly: .Error( Error( withMessage: "Cannot assign value with type \(to.type()) to identifier \(self) that is read only")) - case TypeCheckResults.WrongDirection: .Error( Error( withMessage: "Cannot assign value with type \(to.type()) to identifier \(self) that is in parameter")) - case TypeCheckResults.Ok: .Ok(()) + case TypeCheckResults.IncompatibleTypes: + .Error( + Error( + withMessage: + "Cannot assign value with type \(to.type()) to identifier \(self) with type \(type)")) + case TypeCheckResults.ReadOnly: + .Error( + Error( + withMessage: + "Cannot assign value with type \(to.type()) to identifier \(self) that is read only")) + case TypeCheckResults.WrongDirection: + .Error( + Error( + withMessage: + "Cannot assign value with type \(to.type()) to identifier \(self) that is in parameter") + ) + case TypeCheckResults.Ok: .Ok(()) } } } @@ -253,7 +267,8 @@ extension ArrayAccessExpression: EvaluatableLValueExpression { let updated_execution = execution let maybe_value = self.name.evaluate(execution: updated_execution) guard case (.Ok(let value), let updated_execution) = maybe_value else { - return .Error(Error(withMessage: "\(self.name) cannot be evaluated: \(maybe_value.0.error()!)")) + return .Error( + Error(withMessage: "\(self.name) cannot be evaluated: \(maybe_value.0.error()!)")) } guard let array_value = value.dataValue() as? P4ArrayValue else { return Result.Error(Error(withMessage: "\(self.name) does not identify an array")) @@ -263,7 +278,8 @@ extension ArrayAccessExpression: EvaluatableLValueExpression { let maybe_indexor_value = self.indexor.evaluate(execution: updated_execution) guard case (.Ok(let indexor_value), let updated_execution) = maybe_indexor_value else { return Result.Error( - Error(withMessage: "\(self.indexor) cannot be evaluated: \(maybe_indexor_value.0.error()!)")) + Error(withMessage: "\(self.indexor) cannot be evaluated: \(maybe_indexor_value.0.error()!)") + ) } guard let indexor_int = indexor_value.dataValue() as? P4IntValue else { return Result.Error(Error(withMessage: "\(self.indexor) cannot be used to index an array")) @@ -282,7 +298,8 @@ extension ArrayAccessExpression: EvaluatableLValueExpression { } let array_lvalue = self.name as! EvaluatableLValueExpression - return array_lvalue.set(to: updated_array_value, inScopes: scopes, duringExecution: updated_execution) + return array_lvalue.set( + to: updated_array_value, inScopes: scopes, duringExecution: updated_execution) } public func check( @@ -385,7 +402,8 @@ extension FieldAccessExpression: EvaluatableLValueExpression { // We use recursion here -- ultimately finding our way to a TypedIdentifier that // will update the scope. Pretty cool! let struct_lvalue = self.strct as! EvaluatableLValueExpression - return struct_lvalue.set(to: new_struct_value, inScopes: scopes, duringExecution: updated_execution) + return struct_lvalue.set( + to: new_struct_value, inScopes: scopes, duringExecution: updated_execution) } public func check( @@ -435,24 +453,33 @@ extension KeysetExpression: EvaluatableExpression { } extension FunctionCall: EvaluatableExpression { - public func evaluate(execution: Common.ProgramExecution) -> (Common.Result, ProgramExecution) { + public func evaluate( + execution: Common.ProgramExecution + ) -> (Common.Result, ProgramExecution) { guard let body = self.callee.body else { - return (.Error(Error(withMessage: "No body for called function (\(self.callee.name))")), execution) + return ( + .Error(Error(withMessage: "No body for called function (\(self.callee.name))")), execution + ) } - let call_body: (ProgramExecution) -> (Result, ProgramExecution) = { (execution: ProgramExecution) in + let call_body: (ProgramExecution) -> (Result, ProgramExecution) = { + (execution: ProgramExecution) in let (control_flow, updated_execution) = body.evaluate(execution: execution) return switch control_flow { case ControlFlow.Return(.some(let value)): (.Ok(value), updated_execution) default: - (.Error(Error(withMessage: "No value returned from called function (\(self.callee.name))")), execution) + ( + .Error( + Error(withMessage: "No value returned from called function (\(self.callee.name))")), + execution + ) } } return Call( - body: call_body, withArguments: self.arguments, withParameters: self.callee.params, - inExecution: execution) + body: call_body, withArguments: self.arguments, withParameters: self.callee.params, + inExecution: execution) } public func type() -> P4Type { diff --git a/Sources/P4Runtime/Parser.swift b/Sources/P4Runtime/Parser.swift index f705c1e..1fe6812 100644 --- a/Sources/P4Runtime/Parser.swift +++ b/Sources/P4Runtime/Parser.swift @@ -188,7 +188,8 @@ extension Parser: LibraryCallable { return switch Call( - body: call_body, withArguments: arguments, withParameters: parameters, inExecution: execution) + body: call_body, withArguments: arguments, withParameters: parameters, + inExecution: execution) { case (.Ok(let value), let updated_execution): (value.dataValue() as! InstantiatedParserState, updated_execution) diff --git a/Sources/P4Runtime/Statements.swift b/Sources/P4Runtime/Statements.swift index 977ba53..70cf241 100644 --- a/Sources/P4Runtime/Statements.swift +++ b/Sources/P4Runtime/Statements.swift @@ -41,7 +41,9 @@ extension BlockStatement: EvaluatableStatement { extension VariableDeclarationStatement: EvaluatableStatement { public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) { - guard case (.Ok(let initial_value), let execution) = self.initializer.evaluate(execution: execution) else { + guard + case (.Ok(let initial_value), let execution) = self.initializer.evaluate(execution: execution) + else { return ( ControlFlow.Error, execution.setError(error: Error(withMessage: "Could not evaluate \(self.initializer)")) @@ -55,7 +57,10 @@ extension VariableDeclarationStatement: EvaluatableStatement { extension ConditionalStatement: EvaluatableStatement { public func evaluate(execution: ProgramExecution) -> (ControlFlow, ProgramExecution) { - guard case (.Ok(let evaluated_condition), let execution) = self.condition.evaluate(execution: execution) else { + guard + case (.Ok(let evaluated_condition), let execution) = self.condition.evaluate( + execution: execution) + else { return ( ControlFlow.Error, execution.setError(error: Error(withMessage: "Could not evaluate \(self.condition)"))