KCL: Comparison operators (#4025)
Add `==, !=, >, >=, <, <=` to the language parser, executor and tests. Closes https://github.com/KittyCAD/modeling-app/issues/4020 Currently these comparison operators are associative, allowing users to chain them, e.g. (x <= y <= z). This should not be allowed, will do in a follow-up. See https://github.com/KittyCAD/modeling-app/issues/4155
This commit is contained in:
@ -83520,6 +83520,48 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"^"
|
"^"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers not equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<="
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -87076,6 +87118,48 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"^"
|
"^"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers not equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<="
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -90636,6 +90720,48 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"^"
|
"^"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers not equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<="
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -115048,6 +115174,48 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"^"
|
"^"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers not equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<="
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -118997,6 +119165,48 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"^"
|
"^"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers not equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<="
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -122553,6 +122763,48 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"^"
|
"^"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers not equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<="
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -126107,6 +126359,48 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"^"
|
"^"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Are two numbers not equal?",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"!="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left greater than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
">="
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Is left less than or equal to right",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"<="
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -82,6 +82,78 @@ Raise a number to a power.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
Are two numbers equal?
|
||||||
|
|
||||||
|
**enum:** `==`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
Are two numbers not equal?
|
||||||
|
|
||||||
|
**enum:** `!=`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
Is left greater than right
|
||||||
|
|
||||||
|
**enum:** `>`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
Is left greater than or equal to right
|
||||||
|
|
||||||
|
**enum:** `>=`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
Is left less than right
|
||||||
|
|
||||||
|
**enum:** `<`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
Is left less than or equal to right
|
||||||
|
|
||||||
|
**enum:** `<=`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2778,6 +2778,12 @@ impl BinaryExpression {
|
|||||||
BinaryOperator::Div => (left / right).into(),
|
BinaryOperator::Div => (left / right).into(),
|
||||||
BinaryOperator::Mod => (left % right).into(),
|
BinaryOperator::Mod => (left % right).into(),
|
||||||
BinaryOperator::Pow => (left.powf(right)).into(),
|
BinaryOperator::Pow => (left.powf(right)).into(),
|
||||||
|
BinaryOperator::Eq => (left == right).into(),
|
||||||
|
BinaryOperator::Neq => (left != right).into(),
|
||||||
|
BinaryOperator::Gt => (left > right).into(),
|
||||||
|
BinaryOperator::Gte => (left >= right).into(),
|
||||||
|
BinaryOperator::Lt => (left < right).into(),
|
||||||
|
BinaryOperator::Lte => (left <= right).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(KclValue::UserVal(UserVal {
|
Ok(KclValue::UserVal(UserVal {
|
||||||
@ -2861,6 +2867,30 @@ pub enum BinaryOperator {
|
|||||||
#[serde(rename = "^")]
|
#[serde(rename = "^")]
|
||||||
#[display("^")]
|
#[display("^")]
|
||||||
Pow,
|
Pow,
|
||||||
|
/// Are two numbers equal?
|
||||||
|
#[serde(rename = "==")]
|
||||||
|
#[display("==")]
|
||||||
|
Eq,
|
||||||
|
/// Are two numbers not equal?
|
||||||
|
#[serde(rename = "!=")]
|
||||||
|
#[display("!=")]
|
||||||
|
Neq,
|
||||||
|
/// Is left greater than right
|
||||||
|
#[serde(rename = ">")]
|
||||||
|
#[display(">")]
|
||||||
|
Gt,
|
||||||
|
/// Is left greater than or equal to right
|
||||||
|
#[serde(rename = ">=")]
|
||||||
|
#[display(">=")]
|
||||||
|
Gte,
|
||||||
|
/// Is left less than right
|
||||||
|
#[serde(rename = "<")]
|
||||||
|
#[display("<")]
|
||||||
|
Lt,
|
||||||
|
/// Is left less than or equal to right
|
||||||
|
#[serde(rename = "<=")]
|
||||||
|
#[display("<=")]
|
||||||
|
Lte,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mathematical associativity.
|
/// Mathematical associativity.
|
||||||
@ -2889,6 +2919,12 @@ impl BinaryOperator {
|
|||||||
BinaryOperator::Div => *b"div",
|
BinaryOperator::Div => *b"div",
|
||||||
BinaryOperator::Mod => *b"mod",
|
BinaryOperator::Mod => *b"mod",
|
||||||
BinaryOperator::Pow => *b"pow",
|
BinaryOperator::Pow => *b"pow",
|
||||||
|
BinaryOperator::Eq => *b"eqq",
|
||||||
|
BinaryOperator::Neq => *b"neq",
|
||||||
|
BinaryOperator::Gt => *b"gtr",
|
||||||
|
BinaryOperator::Gte => *b"gte",
|
||||||
|
BinaryOperator::Lt => *b"ltr",
|
||||||
|
BinaryOperator::Lte => *b"lte",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2899,6 +2935,8 @@ impl BinaryOperator {
|
|||||||
BinaryOperator::Add | BinaryOperator::Sub => 11,
|
BinaryOperator::Add | BinaryOperator::Sub => 11,
|
||||||
BinaryOperator::Mul | BinaryOperator::Div | BinaryOperator::Mod => 12,
|
BinaryOperator::Mul | BinaryOperator::Div | BinaryOperator::Mod => 12,
|
||||||
BinaryOperator::Pow => 13,
|
BinaryOperator::Pow => 13,
|
||||||
|
Self::Gt | Self::Gte | Self::Lt | Self::Lte => 9,
|
||||||
|
Self::Eq | Self::Neq => 8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2908,6 +2946,7 @@ impl BinaryOperator {
|
|||||||
match self {
|
match self {
|
||||||
Self::Add | Self::Sub | Self::Mul | Self::Div | Self::Mod => Associativity::Left,
|
Self::Add | Self::Sub | Self::Mul | Self::Div | Self::Mod => Associativity::Left,
|
||||||
Self::Pow => Associativity::Right,
|
Self::Pow => Associativity::Right,
|
||||||
|
Self::Gt | Self::Gte | Self::Lt | Self::Lte | Self::Eq | Self::Neq => Associativity::Left, // I don't know if this is correct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -303,6 +303,12 @@ fn binary_operator(i: TokenSlice) -> PResult<BinaryOperator> {
|
|||||||
"*" => BinaryOperator::Mul,
|
"*" => BinaryOperator::Mul,
|
||||||
"%" => BinaryOperator::Mod,
|
"%" => BinaryOperator::Mod,
|
||||||
"^" => BinaryOperator::Pow,
|
"^" => BinaryOperator::Pow,
|
||||||
|
"==" => BinaryOperator::Eq,
|
||||||
|
"!=" => BinaryOperator::Neq,
|
||||||
|
">" => BinaryOperator::Gt,
|
||||||
|
">=" => BinaryOperator::Gte,
|
||||||
|
"<" => BinaryOperator::Lt,
|
||||||
|
"<=" => BinaryOperator::Lte,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(KclError::Syntax(KclErrorDetails {
|
return Err(KclError::Syntax(KclErrorDetails {
|
||||||
source_ranges: token.as_source_ranges(),
|
source_ranges: token.as_source_ranges(),
|
||||||
@ -3705,6 +3711,8 @@ const my14 = 4 ^ 2 - 3 ^ 2 * 2
|
|||||||
5
|
5
|
||||||
}"#
|
}"#
|
||||||
);
|
);
|
||||||
|
snapshot_test!(be, "let x = 3 == 3");
|
||||||
|
snapshot_test!(bf, "let x = 3 != 3");
|
||||||
snapshot_test!(bg, r#"x = 4"#);
|
snapshot_test!(bg, r#"x = 4"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
source: kcl/src/parser/parser_impl.rs
|
||||||
|
expression: actual
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"end": 14,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"start": 0,
|
||||||
|
"end": 14,
|
||||||
|
"declarations": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclarator",
|
||||||
|
"start": 4,
|
||||||
|
"end": 14,
|
||||||
|
"id": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 4,
|
||||||
|
"end": 5,
|
||||||
|
"name": "x",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"type": "BinaryExpression",
|
||||||
|
"type": "BinaryExpression",
|
||||||
|
"start": 8,
|
||||||
|
"end": 14,
|
||||||
|
"operator": "==",
|
||||||
|
"left": {
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 8,
|
||||||
|
"end": 9,
|
||||||
|
"value": 3,
|
||||||
|
"raw": "3",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 13,
|
||||||
|
"end": 14,
|
||||||
|
"value": 3,
|
||||||
|
"raw": "3",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"digest": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "const",
|
||||||
|
"digest": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nonCodeMeta": {
|
||||||
|
"nonCodeNodes": {},
|
||||||
|
"start": [],
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"digest": null
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
source: kcl/src/parser/parser_impl.rs
|
||||||
|
expression: actual
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"end": 14,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"start": 0,
|
||||||
|
"end": 14,
|
||||||
|
"declarations": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclarator",
|
||||||
|
"start": 4,
|
||||||
|
"end": 14,
|
||||||
|
"id": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 4,
|
||||||
|
"end": 5,
|
||||||
|
"name": "x",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"type": "BinaryExpression",
|
||||||
|
"type": "BinaryExpression",
|
||||||
|
"start": 8,
|
||||||
|
"end": 14,
|
||||||
|
"operator": "!=",
|
||||||
|
"left": {
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 8,
|
||||||
|
"end": 9,
|
||||||
|
"value": 3,
|
||||||
|
"raw": "3",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 13,
|
||||||
|
"end": 14,
|
||||||
|
"value": 3,
|
||||||
|
"raw": "3",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"digest": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "const",
|
||||||
|
"digest": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nonCodeMeta": {
|
||||||
|
"nonCodeNodes": {},
|
||||||
|
"start": [],
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"digest": null
|
||||||
|
}
|
||||||
@ -27,7 +27,7 @@ pub fn token(i: &mut Located<&str>) -> PResult<Token> {
|
|||||||
'.' => alt((number, double_period, period)),
|
'.' => alt((number, double_period, period)),
|
||||||
'#' => hash,
|
'#' => hash,
|
||||||
'$' => dollar,
|
'$' => dollar,
|
||||||
'!' => bang,
|
'!' => alt((operator, bang)),
|
||||||
' ' | '\t' | '\n' => whitespace,
|
' ' | '\t' | '\n' => whitespace,
|
||||||
_ => alt((operator, keyword,type_, word))
|
_ => alt((operator, keyword,type_, word))
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ fn word(i: &mut Located<&str>) -> PResult<Token> {
|
|||||||
|
|
||||||
fn operator(i: &mut Located<&str>) -> PResult<Token> {
|
fn operator(i: &mut Located<&str>) -> PResult<Token> {
|
||||||
let (value, range) = alt((
|
let (value, range) = alt((
|
||||||
">=", "<=", "==", "=>", "!= ", "|>", "*", "+", "-", "/", "%", "=", "<", ">", r"\", "|", "^",
|
">=", "<=", "==", "=>", "!=", "|>", "*", "+", "-", "/", "%", "=", "<", ">", r"\", "|", "^",
|
||||||
))
|
))
|
||||||
.with_span()
|
.with_span()
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
@ -1522,6 +1522,18 @@ const things = "things"
|
|||||||
assert_tokens(expected, actual);
|
assert_tokens(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn not_eq() {
|
||||||
|
let actual = lexer("!=").unwrap();
|
||||||
|
let expected = vec![Token {
|
||||||
|
token_type: TokenType::Operator,
|
||||||
|
value: "!=".to_owned(),
|
||||||
|
start: 0,
|
||||||
|
end: 2,
|
||||||
|
}];
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unrecognized_token() {
|
fn test_unrecognized_token() {
|
||||||
let actual = lexer("12 ; 8").unwrap();
|
let actual = lexer("12 ; 8").unwrap();
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
assert(3 == 3, "equality")
|
||||||
|
assert(3.0 == 3.0, "equality of floats")
|
||||||
|
assert(3 != 4, "non-equality")
|
||||||
|
assert(3.0 != 4.0, "non-equality of floats")
|
||||||
|
assert(3 < 4, "lt")
|
||||||
|
assert(3 <= 4, "lte but actually lt")
|
||||||
|
assert(4 <= 4, "lte but actually eq")
|
||||||
|
assert(4 > 3, "gt")
|
||||||
|
assert(4 >= 3, "gte but actually gt")
|
||||||
|
assert(3 >= 3, "gte but actually eq")
|
||||||
|
|
||||||
|
assert(0.0 == 0.0, "equality of zero")
|
||||||
|
assert(0.0 == -0.0, "equality of zero and neg zero")
|
||||||
@ -0,0 +1 @@
|
|||||||
|
assert(3 == 3 == 3, "this should not compile")
|
||||||
@ -57,6 +57,7 @@ async fn run_fail(code: &str) -> KclError {
|
|||||||
|
|
||||||
gen_test!(property_of_object);
|
gen_test!(property_of_object);
|
||||||
gen_test!(index_of_array);
|
gen_test!(index_of_array);
|
||||||
|
gen_test!(comparisons);
|
||||||
gen_test_fail!(
|
gen_test_fail!(
|
||||||
invalid_index_str,
|
invalid_index_str,
|
||||||
"semantic: Only integers >= 0 can be used as the index of an array, but you're using a string"
|
"semantic: Only integers >= 0 can be used as the index of an array, but you're using a string"
|
||||||
@ -99,4 +100,5 @@ gen_test!(if_else);
|
|||||||
// if_else_no_expr,
|
// if_else_no_expr,
|
||||||
// "syntax: blocks inside an if/else expression must end in an expression"
|
// "syntax: blocks inside an if/else expression must end in an expression"
|
||||||
// );
|
// );
|
||||||
|
gen_test_fail!(comparisons_multiple, "syntax: Invalid number: true");
|
||||||
gen_test!(add_lots);
|
gen_test!(add_lots);
|
||||||
|
|||||||
Reference in New Issue
Block a user