Support `<>` for non-equality
5712ca7cfdd7408e9f522a23e30e12fccfcdd12d0b85ed3fe1eacc8a75518bd2
The `!` is already used for too many things.
1 parent
41b8d492
lib/std/lang/parser/tests.rad
+6 -1
| 2205 | 2205 | let case ast::NodeValue::BinOp(op5) = modOp.value |
|
| 2206 | 2206 | else throw testing::TestError::Failed; |
|
| 2207 | 2207 | try testing::expect(op5.op == ast::BinaryOp::Mod); |
|
| 2208 | 2208 | } |
|
| 2209 | 2209 | ||
| 2210 | - | /// Test parsing comparison binary operators (==, !=). |
|
| 2210 | + | /// Test parsing comparison binary operators (==, !=, <>). |
|
| 2211 | 2211 | @test fn testParseBinOpEq() throws (testing::TestError) { |
|
| 2212 | 2212 | let eq = try! parseExprStr("a == b"); |
|
| 2213 | 2213 | let case ast::NodeValue::BinOp(op1) = eq.value |
|
| 2214 | 2214 | else throw testing::TestError::Failed; |
|
| 2215 | 2215 | try testing::expect(op1.op == ast::BinaryOp::Eq); |
|
| 2216 | 2216 | ||
| 2217 | 2217 | let ne = try! parseExprStr("x != y"); |
|
| 2218 | 2218 | let case ast::NodeValue::BinOp(op2) = ne.value |
|
| 2219 | 2219 | else throw testing::TestError::Failed; |
|
| 2220 | 2220 | try testing::expect(op2.op == ast::BinaryOp::Ne); |
|
| 2221 | + | ||
| 2222 | + | let altNe = try! parseExprStr("x <> y"); |
|
| 2223 | + | let case ast::NodeValue::BinOp(op3) = altNe.value |
|
| 2224 | + | else throw testing::TestError::Failed; |
|
| 2225 | + | try testing::expect(op3.op == ast::BinaryOp::Ne); |
|
| 2221 | 2226 | } |
|
| 2222 | 2227 | ||
| 2223 | 2228 | /// Test parsing comparison binary operators. |
|
| 2224 | 2229 | @test fn testParseBinOpGtLt() throws (testing::TestError) { |
|
| 2225 | 2230 | let lt = try! parseExprStr("a < b"); |
lib/std/lang/scanner.rad
+4 -1
| 39 | 39 | Caret, // ^ |
|
| 40 | 40 | Tilde, // ~ |
|
| 41 | 41 | Underscore, // _ |
|
| 42 | 42 | Question, // ? |
|
| 43 | 43 | Bang, // ! |
|
| 44 | - | BangEqual, // != |
|
| 44 | + | BangEqual, // != or <> |
|
| 45 | 45 | Equal, // = |
|
| 46 | 46 | EqualEqual, // == |
|
| 47 | 47 | Gt, // > |
|
| 48 | 48 | GtEqual, // >= |
|
| 49 | 49 | Lt, // < |
| 555 | 555 | return tok(s, TokenKind::EqualEqual); |
|
| 556 | 556 | } |
|
| 557 | 557 | return tok(s, TokenKind::Equal); |
|
| 558 | 558 | } |
|
| 559 | 559 | case '<' => { |
|
| 560 | + | if consume(s, '>') { |
|
| 561 | + | return tok(s, TokenKind::BangEqual); |
|
| 562 | + | } |
|
| 560 | 563 | if consume(s, '<') { |
|
| 561 | 564 | if consume(s, '=') { |
|
| 562 | 565 | return tok(s, TokenKind::LtLtEqual); |
|
| 563 | 566 | } |
|
| 564 | 567 | return tok(s, TokenKind::LtLt); |
lib/std/lang/scanner/tests.rad
+2 -1
| 164 | 164 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof); |
|
| 165 | 165 | } |
|
| 166 | 166 | ||
| 167 | 167 | @test fn testScanDoubleCharTokens() throws (testing::TestError) { |
|
| 168 | 168 | let mut s = testScanner( |
|
| 169 | - | "== != <= >= < > >> << -> =>" |
|
| 169 | + | "== != <> <= >= < > >> << -> =>" |
|
| 170 | 170 | ); |
|
| 171 | 171 | try testing::expect(super::next(&mut s).kind == super::TokenKind::EqualEqual); |
|
| 172 | 172 | try testing::expect(super::next(&mut s).kind == super::TokenKind::BangEqual); |
|
| 173 | + | try testing::expect(super::next(&mut s).kind == super::TokenKind::BangEqual); |
|
| 173 | 174 | try testing::expect(super::next(&mut s).kind == super::TokenKind::LtEqual); |
|
| 174 | 175 | try testing::expect(super::next(&mut s).kind == super::TokenKind::GtEqual); |
|
| 175 | 176 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Lt); |
|
| 176 | 177 | try testing::expect(super::next(&mut s).kind == super::TokenKind::Gt); |
|
| 177 | 178 | try testing::expect(super::next(&mut s).kind == super::TokenKind::GtGt); |