@@ -175,7 +175,8 @@ public class P4StructValue: P4Value {
|
|||||||
return self.stype
|
return self.stype
|
||||||
}
|
}
|
||||||
|
|
||||||
func bin_op_impl(lhs: P4StructValue, rhs: P4StructValue, op: (P4Value?, P4Value?) -> Bool) -> Bool {
|
func bin_op_impl(lhs: P4StructValue, rhs: P4StructValue, op: (P4Value?, P4Value?) -> Bool) -> Bool
|
||||||
|
{
|
||||||
if lhs.stype.fields.count() != rhs.stype.fields.count() {
|
if lhs.stype.fields.count() != rhs.stype.fields.count() {
|
||||||
// If there are a different number of fields, then we cannot
|
// If there are a different number of fields, then we cannot
|
||||||
// possibly be equal.
|
// possibly be equal.
|
||||||
@@ -212,7 +213,7 @@ public class P4StructValue: P4Value {
|
|||||||
guard let rrhs = rhs as? P4StructValue else {
|
guard let rrhs = rhs as? P4StructValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
||||||
if ilhs == nil && irhs == nil {
|
if ilhs == nil && irhs == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -228,7 +229,7 @@ public class P4StructValue: P4Value {
|
|||||||
guard let rrhs = rhs as? P4StructValue else {
|
guard let rrhs = rhs as? P4StructValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
||||||
if ilhs == nil && irhs == nil {
|
if ilhs == nil && irhs == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -244,7 +245,7 @@ public class P4StructValue: P4Value {
|
|||||||
guard let rrhs = rhs as? P4StructValue else {
|
guard let rrhs = rhs as? P4StructValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
||||||
if ilhs == nil && irhs == nil {
|
if ilhs == nil && irhs == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -260,7 +261,7 @@ public class P4StructValue: P4Value {
|
|||||||
guard let rrhs = rhs as? P4StructValue else {
|
guard let rrhs = rhs as? P4StructValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
||||||
if ilhs == nil && irhs == nil {
|
if ilhs == nil && irhs == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -277,7 +278,7 @@ public class P4StructValue: P4Value {
|
|||||||
guard let rrhs = rhs as? P4StructValue else {
|
guard let rrhs = rhs as? P4StructValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
return bin_op_impl(lhs: self, rhs: rrhs) { ilhs, irhs in
|
||||||
if ilhs == nil && irhs == nil {
|
if ilhs == nil && irhs == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -386,28 +387,28 @@ public class P4BooleanValue: P4Value {
|
|||||||
guard let bool_rhs = rhs as? P4BooleanValue else {
|
guard let bool_rhs = rhs as? P4BooleanValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return (self.value ? 1 : 0 ) < (bool_rhs.value ? 1 : 0)
|
return (self.value ? 1 : 0) < (bool_rhs.value ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func lte(rhs: P4Value) -> Bool {
|
public func lte(rhs: P4Value) -> Bool {
|
||||||
guard let bool_rhs = rhs as? P4BooleanValue else {
|
guard let bool_rhs = rhs as? P4BooleanValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return (self.value ? 1 : 0 ) <= (bool_rhs.value ? 1 : 0)
|
return (self.value ? 1 : 0) <= (bool_rhs.value ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func gt(rhs: P4Value) -> Bool {
|
public func gt(rhs: P4Value) -> Bool {
|
||||||
guard let bool_rhs = rhs as? P4BooleanValue else {
|
guard let bool_rhs = rhs as? P4BooleanValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return (self.value ? 1 : 0 ) > (bool_rhs.value ? 1 : 0)
|
return (self.value ? 1 : 0) > (bool_rhs.value ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func gte(rhs: P4Value) -> Bool {
|
public func gte(rhs: P4Value) -> Bool {
|
||||||
guard let bool_rhs = rhs as? P4BooleanValue else {
|
guard let bool_rhs = rhs as? P4BooleanValue else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return (self.value ? 1 : 0 ) >= (bool_rhs.value ? 1 : 0)
|
return (self.value ? 1 : 0) >= (bool_rhs.value ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var description: String {
|
public var description: String {
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ struct Expression {
|
|||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
#RequireNodeType<Node, EvaluatableExpression>(node: expression_node, type: "expression", nice_type_name: "expression")
|
#RequireNodeType<Node, EvaluatableExpression>(
|
||||||
|
node: expression_node, type: "expression", nice_type_name: "expression")
|
||||||
|
|
||||||
expression_node = expression_node.child(at: 0)!
|
expression_node = expression_node.child(at: 0)!
|
||||||
#RequireNodesType<Node, EvaluatableExpression>(
|
#RequireNodesType<Node, EvaluatableExpression>(
|
||||||
@@ -180,7 +181,8 @@ struct LValue {
|
|||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
#RequireNodeType<Node, EvaluatableExpression>(node: expression_node, type: "expression", nice_type_name: "expression")
|
#RequireNodeType<Node, EvaluatableExpression>(
|
||||||
|
node: expression_node, type: "expression", nice_type_name: "expression")
|
||||||
|
|
||||||
expression_node = expression_node.child(at: 0)!
|
expression_node = expression_node.child(at: 0)!
|
||||||
#RequireNodesType<Node, EvaluatableExpression>(
|
#RequireNodesType<Node, EvaluatableExpression>(
|
||||||
@@ -381,21 +383,43 @@ extension BinaryOperatorExpression: CompilableExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let evaluators = [
|
let evaluators = [
|
||||||
"binaryEqualOperatorExpression": ("Binary Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none, binary_equal_operator_evaluator),
|
"binaryEqualOperatorExpression": (
|
||||||
"binaryLessThanOperatorExpression": ("Binary Less Than", P4Boolean(), Optional<BinaryOperatorChecker>.none, binary_lt_operator_evaluator),
|
"Binary Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||||
"binaryLessThanEqualOperatorExpression": ("Binary Less Than Or Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none, binary_lte_operator_evaluator),
|
binary_equal_operator_evaluator
|
||||||
"binaryGreaterThanOperatorExpression": ("Binary Greater Than", P4Boolean(), Optional<BinaryOperatorChecker>.none, binary_gt_operator_evaluator),
|
),
|
||||||
"binaryGreaterThanEqualOperatorExpression": ("Binary Greater Than Or Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none, binary_gte_operator_evaluator),
|
"binaryLessThanOperatorExpression": (
|
||||||
"binaryAndOperatorExpression": ("Binary Or", P4Boolean(), binary_and_or_operator_checker, binary_and_operator_evaluator),
|
"Binary Less Than", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||||
"binaryOrOperatorExpression": ("Binary And", P4Boolean(), binary_and_or_operator_checker, binary_or_operator_evaluator),
|
binary_lt_operator_evaluator
|
||||||
|
),
|
||||||
|
"binaryLessThanEqualOperatorExpression": (
|
||||||
|
"Binary Less Than Or Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||||
|
binary_lte_operator_evaluator
|
||||||
|
),
|
||||||
|
"binaryGreaterThanOperatorExpression": (
|
||||||
|
"Binary Greater Than", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||||
|
binary_gt_operator_evaluator
|
||||||
|
),
|
||||||
|
"binaryGreaterThanEqualOperatorExpression": (
|
||||||
|
"Binary Greater Than Or Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||||
|
binary_gte_operator_evaluator
|
||||||
|
),
|
||||||
|
"binaryAndOperatorExpression": (
|
||||||
|
"Binary Or", P4Boolean(), binary_and_or_operator_checker, binary_and_operator_evaluator
|
||||||
|
),
|
||||||
|
"binaryOrOperatorExpression": (
|
||||||
|
"Binary And", P4Boolean(), binary_and_or_operator_checker, binary_or_operator_evaluator
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
guard let selected_evaluator = evaluators[binary_operator_expression_node.nodeType!] else {
|
guard let selected_evaluator = evaluators[binary_operator_expression_node.nodeType!] else {
|
||||||
return Result.Error(Error(withMessage: "No evaluator for \(binary_operator_expression_node.nodeType!)"))
|
return Result.Error(
|
||||||
|
Error(withMessage: "No evaluator for \(binary_operator_expression_node.nodeType!)"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let checker = selected_evaluator.2, case .Error(let e) = checker(left_hand_side, right_hand_side) {
|
if let checker = selected_evaluator.2,
|
||||||
return Result.Error(e)
|
case .Error(let e) = checker(left_hand_side, right_hand_side)
|
||||||
|
{
|
||||||
|
return Result.Error(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .Ok(
|
return .Ok(
|
||||||
|
|||||||
@@ -123,9 +123,13 @@ public func binary_gte_operator_evaluator(left: P4Value, right: P4Value) -> P4Va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public typealias BinaryOperatorChecker = (EvaluatableExpression, EvaluatableExpression) -> Result<()>
|
public typealias BinaryOperatorChecker = (EvaluatableExpression, EvaluatableExpression) -> Result<
|
||||||
|
()
|
||||||
|
>
|
||||||
|
|
||||||
public func binary_and_or_operator_checker(left: EvaluatableExpression, right: EvaluatableExpression) -> Result<()> {
|
public func binary_and_or_operator_checker(
|
||||||
|
left: EvaluatableExpression, right: EvaluatableExpression
|
||||||
|
) -> Result<()> {
|
||||||
// Check that both are Boolean-typed things!
|
// Check that both are Boolean-typed things!
|
||||||
if !(left.type().eq(rhs: P4Boolean()) && right.type().eq(rhs: P4Boolean())) {
|
if !(left.type().eq(rhs: P4Boolean()) && right.type().eq(rhs: P4Boolean())) {
|
||||||
return .Error(Error(withMessage: "And/Or on operands with non-bool type is not allowed"))
|
return .Error(Error(withMessage: "And/Or on operands with non-bool type is not allowed"))
|
||||||
|
|||||||
Reference in New Issue
Block a user