Support Binary Math Operators
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -246,8 +246,9 @@ extension SelectExpression: CompilableExpression {
|
|||||||
let maybe_selector = Expression.Compile(node: selector_node, withContext: context)
|
let maybe_selector = Expression.Compile(node: selector_node, withContext: context)
|
||||||
guard case .Ok(let selector) = maybe_selector else {
|
guard case .Ok(let selector) = maybe_selector else {
|
||||||
return .Error(
|
return .Error(
|
||||||
Error(
|
ErrorOnNode(
|
||||||
withMessage:
|
node: selector_node,
|
||||||
|
withError:
|
||||||
"Could not parse transition select expression selector expression: \(maybe_selector.error()!)"
|
"Could not parse transition select expression selector expression: \(maybe_selector.error()!)"
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -343,8 +344,8 @@ extension BinaryOperatorExpression: CompilableExpression {
|
|||||||
// swift-format-ignore
|
// swift-format-ignore
|
||||||
#RequireNodesType<Node, EvaluatableExpression?>(
|
#RequireNodesType<Node, EvaluatableExpression?>(
|
||||||
nodes: binary_operator_expression_node,
|
nodes: binary_operator_expression_node,
|
||||||
type: ["binaryEqualOperatorExpression", "binaryLessThanOperatorExpression", "binaryLessThanEqualOperatorExpression", "binaryGreaterThanOperatorExpression", "binaryGreaterThanEqualOperatorExpression", "binaryAndOperatorExpression", "binaryOrOperatorExpression"],
|
type: ["binaryEqualOperatorExpression", "binaryLessThanOperatorExpression", "binaryLessThanEqualOperatorExpression", "binaryGreaterThanOperatorExpression", "binaryGreaterThanEqualOperatorExpression", "binaryAndOperatorExpression", "binaryOrOperatorExpression", "binaryAddOperatorExpression", "binarySubtractOperatorExpression", "binaryMultiplyOperatorExpression", "binaryDivideOperatorExpression"],
|
||||||
nice_type_names: [ "binary equal operator", "binary less than operator", "binary less than or equal to operator", "binary greater than operator", "binary greater than or equal to operator", "binary and operator", "binary or operator"])
|
nice_type_names: [ "binary equal operator", "binary less than operator", "binary less than or equal to operator", "binary greater than operator", "binary greater than or equal to operator", "binary and operator", "binary or operator", "binary add operator", "binary subtract operator", "binary multiply operator", "binary divide operator"])
|
||||||
|
|
||||||
if binary_operator_expression_node.childCount < currentChildIdxSafe {
|
if binary_operator_expression_node.childCount < currentChildIdxSafe {
|
||||||
return Result.Error(
|
return Result.Error(
|
||||||
@@ -382,7 +383,7 @@ extension BinaryOperatorExpression: CompilableExpression {
|
|||||||
return Result.Error(maybe_right_hand_side.error()!)
|
return Result.Error(maybe_right_hand_side.error()!)
|
||||||
}
|
}
|
||||||
|
|
||||||
let evaluators = [
|
let evaluators: [String: (String, P4Type, BinaryOperatorChecker?, BinaryOperatorEvaluator)] = [
|
||||||
"binaryEqualOperatorExpression": (
|
"binaryEqualOperatorExpression": (
|
||||||
"Binary Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
"Binary Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||||
binary_equal_operator_evaluator
|
binary_equal_operator_evaluator
|
||||||
@@ -409,6 +410,20 @@ extension BinaryOperatorExpression: CompilableExpression {
|
|||||||
"binaryOrOperatorExpression": (
|
"binaryOrOperatorExpression": (
|
||||||
"Binary And", P4Boolean(), binary_and_or_operator_checker, binary_or_operator_evaluator
|
"Binary And", P4Boolean(), binary_and_or_operator_checker, binary_or_operator_evaluator
|
||||||
),
|
),
|
||||||
|
"binaryAddOperatorExpression": (
|
||||||
|
"Binary Add", P4Int(), binary_int_math_operator_checker, binary_add_operator_evaluator
|
||||||
|
),
|
||||||
|
"binarySubtractOperatorExpression": (
|
||||||
|
"Binary Subtract", P4Int(), binary_int_math_operator_checker,
|
||||||
|
binary_subtract_operator_evaluator
|
||||||
|
),
|
||||||
|
"binaryMultiplyOperatorExpression": (
|
||||||
|
"Binary Multiply", P4Int(), binary_int_math_operator_checker,
|
||||||
|
binary_multiply_operator_evaluator
|
||||||
|
),
|
||||||
|
"binaryDivideOperatorExpression": (
|
||||||
|
"Binary Divide", P4Int(), binary_int_math_operator_checker, binary_divide_operator_evaluator
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
guard let selected_evaluator = evaluators[binary_operator_expression_node.nodeType!] else {
|
guard let selected_evaluator = evaluators[binary_operator_expression_node.nodeType!] else {
|
||||||
@@ -600,7 +615,6 @@ extension FieldAccessExpression: CompilableLValueExpression {
|
|||||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||||
) -> Result<EvaluatableLValueExpression?> {
|
) -> Result<EvaluatableLValueExpression?> {
|
||||||
let expression = node.child(at: 0)!
|
let expression = node.child(at: 0)!
|
||||||
print("expression: \(expression)")
|
|
||||||
#SkipUnlessNodeType<Node, EvaluatableExpression?>(
|
#SkipUnlessNodeType<Node, EvaluatableExpression?>(
|
||||||
node: expression, type: "fieldAccessExpression")
|
node: expression, type: "fieldAccessExpression")
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public struct SelectExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public typealias NamedBinaryOperatorEvaluator = (String, P4Type, (P4Value, P4Value) -> P4Value)
|
public typealias NamedBinaryOperatorEvaluator = (String, P4Type, (P4Value, P4Value) -> P4Value)
|
||||||
|
public typealias BinaryOperatorEvaluator = (P4Value, P4Value) -> P4Value
|
||||||
public struct BinaryOperatorExpression {
|
public struct BinaryOperatorExpression {
|
||||||
public let evaluator: NamedBinaryOperatorEvaluator
|
public let evaluator: NamedBinaryOperatorEvaluator
|
||||||
public let left: EvaluatableExpression
|
public let left: EvaluatableExpression
|
||||||
|
|||||||
@@ -123,20 +123,6 @@ public func binary_gte_operator_evaluator(left: P4Value, right: P4Value) -> P4Va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public typealias BinaryOperatorChecker = (EvaluatableExpression, EvaluatableExpression) -> Result<
|
|
||||||
()
|
|
||||||
>
|
|
||||||
|
|
||||||
public func binary_and_or_operator_checker(
|
|
||||||
left: EvaluatableExpression, right: EvaluatableExpression
|
|
||||||
) -> Result<()> {
|
|
||||||
// Check that both are Boolean-typed things!
|
|
||||||
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 .Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
public func binary_and_operator_evaluator(left: P4Value, right: P4Value) -> P4Value {
|
public func binary_and_operator_evaluator(left: P4Value, right: P4Value) -> P4Value {
|
||||||
let bleft = left as! P4BooleanValue
|
let bleft = left as! P4BooleanValue
|
||||||
let bright = right as! P4BooleanValue
|
let bright = right as! P4BooleanValue
|
||||||
@@ -153,6 +139,62 @@ public func binary_or_operator_evaluator(left: P4Value, right: P4Value) -> P4Val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func binary_add_operator_evaluator(left: P4Value, right: P4Value) -> P4Value {
|
||||||
|
let ileft = left as! P4IntValue
|
||||||
|
let iright = right as! P4IntValue
|
||||||
|
return Map(input: ileft.access() + iright.access()) { input in
|
||||||
|
P4IntValue(withValue: input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func binary_subtract_operator_evaluator(left: P4Value, right: P4Value) -> P4Value {
|
||||||
|
let ileft = left as! P4IntValue
|
||||||
|
let iright = right as! P4IntValue
|
||||||
|
return Map(input: ileft.access() - iright.access()) { input in
|
||||||
|
P4IntValue(withValue: input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func binary_multiply_operator_evaluator(left: P4Value, right: P4Value) -> P4Value {
|
||||||
|
let ileft = left as! P4IntValue
|
||||||
|
let iright = right as! P4IntValue
|
||||||
|
return Map(input: ileft.access() * iright.access()) { input in
|
||||||
|
P4IntValue(withValue: input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func binary_divide_operator_evaluator(left: P4Value, right: P4Value) -> P4Value {
|
||||||
|
let ileft = left as! P4IntValue
|
||||||
|
let iright = right as! P4IntValue
|
||||||
|
return Map(input: ileft.access() / iright.access()) { input in
|
||||||
|
P4IntValue(withValue: input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// swift-format-ignore
|
||||||
|
public typealias BinaryOperatorChecker = (EvaluatableExpression, EvaluatableExpression) -> Result<()>
|
||||||
|
|
||||||
|
public func binary_and_or_operator_checker(
|
||||||
|
left: EvaluatableExpression, right: EvaluatableExpression
|
||||||
|
) -> Result<()> {
|
||||||
|
// Check that both are Boolean-typed things!
|
||||||
|
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 .Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
public func binary_int_math_operator_checker(
|
||||||
|
left: EvaluatableExpression, right: EvaluatableExpression
|
||||||
|
) -> Result<()> {
|
||||||
|
// Check that both are int-typed things!
|
||||||
|
if !(left.type().eq(rhs: P4Int()) && right.type().eq(rhs: P4Int())) {
|
||||||
|
return .Error(
|
||||||
|
Error(withMessage: "Mathematical operation on operands with non-int type is not allowed"))
|
||||||
|
}
|
||||||
|
return .Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
extension BinaryOperatorExpression: EvaluatableExpression {
|
extension BinaryOperatorExpression: EvaluatableExpression {
|
||||||
public func evaluate(execution: Common.ProgramExecution) -> Common.Result<any Common.P4Value> {
|
public func evaluate(execution: Common.ProgramExecution) -> Common.Result<any Common.P4Value> {
|
||||||
let maybe_evaluated_left = self.left.evaluate(execution: execution)
|
let maybe_evaluated_left = self.left.evaluate(execution: execution)
|
||||||
|
|||||||
@@ -294,3 +294,342 @@ import TreeSitterP4
|
|||||||
|
|
||||||
#expect(state_result == P4Lang.reject)
|
#expect(state_result == P4Lang.reject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add Integers
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_add_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (5 + 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
let program = try #UseOkResult(Program.Compile(simple))
|
||||||
|
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
|
||||||
|
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||||
|
|
||||||
|
#expect(state_result == P4Lang.accept)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_add_non_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (true + 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 16}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_add_non_integer2() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (5 + false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 17}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_add_non_integer3() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (false + false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 21}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtract Integers
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_subtract_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (0 == (5 - 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
let program = try #UseOkResult(Program.Compile(simple))
|
||||||
|
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
|
||||||
|
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||||
|
|
||||||
|
#expect(state_result == P4Lang.accept)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_subtract_non_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (true - 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 16}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_subtract_non_integer2() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (5 - false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 17}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_subtract_non_integer3() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (false - false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 21}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Multiply Integers
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_multiply_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (25 == (5 * 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
let program = try #UseOkResult(Program.Compile(simple))
|
||||||
|
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
|
||||||
|
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||||
|
|
||||||
|
#expect(state_result == P4Lang.accept)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_multiply_non_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (true * 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 16}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_multiply_non_integer2() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (5 * false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 17}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_multiply_non_integer3() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (false * false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 21}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Divide Integers
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_divide_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (1 == (5 / 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
let program = try #UseOkResult(Program.Compile(simple))
|
||||||
|
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
|
||||||
|
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||||
|
|
||||||
|
#expect(state_result == P4Lang.accept)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_divide_non_integer() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (true / 5)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 16}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_divide_non_integer2() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (5 / false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 17}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func test_simple_parser_binary_operator_divide_non_integer3() async throws {
|
||||||
|
let simple = """
|
||||||
|
parser main_parser() {
|
||||||
|
state start {
|
||||||
|
transition select (10 == (false / false)) {
|
||||||
|
true: accept;
|
||||||
|
false: reject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
#RequireErrorResult(
|
||||||
|
Error(
|
||||||
|
withMessage:
|
||||||
|
"{72, 21}: Could not parse transition select expression selector expression: Mathematical operation on operands with non-int type is not allowed"
|
||||||
|
),
|
||||||
|
Program.Compile(simple)))
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ export default grammar({
|
|||||||
$.binaryGreaterThanEqualOperatorExpression,
|
$.binaryGreaterThanEqualOperatorExpression,
|
||||||
$.binaryAndOperatorExpression,
|
$.binaryAndOperatorExpression,
|
||||||
$.binaryOrOperatorExpression,
|
$.binaryOrOperatorExpression,
|
||||||
|
$.binaryAddOperatorExpression,
|
||||||
|
$.binarySubtractOperatorExpression,
|
||||||
|
$.binaryMultiplyOperatorExpression,
|
||||||
|
$.binaryDivideOperatorExpression,
|
||||||
),
|
),
|
||||||
arrayAccessExpression: $ => seq($.expression, $.open_bracket, $.expression, $.close_bracket),
|
arrayAccessExpression: $ => seq($.expression, $.open_bracket, $.expression, $.close_bracket),
|
||||||
fieldAccessExpression: $=> prec.left(2, seq($.expression, $.field_access, $.identifier)),
|
fieldAccessExpression: $=> prec.left(2, seq($.expression, $.field_access, $.identifier)),
|
||||||
@@ -115,6 +119,11 @@ export default grammar({
|
|||||||
binaryAndOperatorExpression: $ => prec.left(2, seq($.expression, $.and, $.expression)),
|
binaryAndOperatorExpression: $ => prec.left(2, seq($.expression, $.and, $.expression)),
|
||||||
binaryOrOperatorExpression: $ => prec.left(2, seq($.expression, $.or, $.expression)),
|
binaryOrOperatorExpression: $ => prec.left(2, seq($.expression, $.or, $.expression)),
|
||||||
|
|
||||||
|
binaryAddOperatorExpression: $ => prec.left(2, seq($.expression, $.add, $.expression)),
|
||||||
|
binarySubtractOperatorExpression: $ => prec.left(2, seq($.expression, $.subtract, $.expression)),
|
||||||
|
binaryMultiplyOperatorExpression: $ => prec.left(2, seq($.expression, $.multiply, $.expression)),
|
||||||
|
binaryDivideOperatorExpression: $ => prec.left(2, seq($.expression, $.divide, $.expression)),
|
||||||
|
|
||||||
// Tokens
|
// Tokens
|
||||||
_semicolon: $ => ";",
|
_semicolon: $ => ";",
|
||||||
colon: $ => ":",
|
colon: $ => ":",
|
||||||
@@ -178,6 +187,11 @@ export default grammar({
|
|||||||
and: $=> "&&",
|
and: $=> "&&",
|
||||||
or: $=> "||",
|
or: $=> "||",
|
||||||
|
|
||||||
|
add: $=> '+',
|
||||||
|
subtract: $=> '-',
|
||||||
|
multiply: $=> '*',
|
||||||
|
divide: $=> '/',
|
||||||
|
|
||||||
open_bracket: $=> '[',
|
open_bracket: $=> '[',
|
||||||
close_bracket: $=> ']',
|
close_bracket: $=> ']',
|
||||||
field_access: $=> '.',
|
field_access: $=> '.',
|
||||||
|
|||||||
Reference in New Issue
Block a user