mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-08-15 14:50:42 +03:00
Merge pull request #550 from HigherOrderCO/451-add-le-and-ge-operators
#451 Add <= and >= operators
This commit is contained in:
commit
94678b61fe
@ -1,5 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## 0.2.34
|
||||
- Added `<=` and `>=` operators. (#451)
|
||||
|
||||
## 0.2.33
|
||||
- Added `expand_main`, a compilation pass that expands references in the entry point function. (#424)
|
||||
- Changed the `float_combinators` pass to not extract in the entry point function. (#424)
|
||||
@ -11,4 +14,4 @@
|
||||
- Created the changelog.
|
||||
|
||||
## 0.2.0
|
||||
- Initial public release of Bend.
|
||||
- Initial public release of Bend.
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -62,7 +62,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bend-lang"
|
||||
version = "0.2.33"
|
||||
version = "0.2.34"
|
||||
dependencies = [
|
||||
"TSPL",
|
||||
"clap",
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "bend-lang"
|
||||
description = "A high-level, massively parallel programming language"
|
||||
license = "Apache-2.0"
|
||||
version = "0.2.33"
|
||||
version = "0.2.34"
|
||||
edition = "2021"
|
||||
rust-version = "1.74"
|
||||
exclude = ["tests/"]
|
||||
|
@ -68,6 +68,7 @@
|
||||
"nums",
|
||||
"OOM's",
|
||||
"oper",
|
||||
"opers",
|
||||
"parallelizable",
|
||||
"peekable",
|
||||
"postcondition",
|
||||
|
@ -384,6 +384,7 @@ Therefore, all `bind` functions must call the builtin function `undefer` before
|
||||
This is necessary to ensure that the continuation in recursive monadic functions stays lazy and doesn't expand infinitely.
|
||||
|
||||
This is an example of a recursive function that would loop if passing the variable `a` to the recursive call `Result/foo(a, b)` was not deferred:
|
||||
|
||||
```python
|
||||
def Result/foo(x, y):
|
||||
with Result:
|
||||
@ -546,21 +547,23 @@ u24 = 42
|
||||
|
||||
Currently, the 3 number types cannot be mixed.
|
||||
|
||||
| Operation | Syntax | Supported Types |
|
||||
| -------------- | -------- | ---------------- |
|
||||
| Addition | x + y | int, float, uint |
|
||||
| Subtraction | x - y | int, float, uint |
|
||||
| Multiplication | x \* y | int, float, uint |
|
||||
| Division | x / y | int, float, uint |
|
||||
| Remainder | x % y | int, float, uint |
|
||||
| Exponentiation | x \*\* y | float |
|
||||
| Equal | x == y | int, float, uint |
|
||||
| Not Equal | x != y | int, float, uint |
|
||||
| Less Than | x < y | int, float, uint |
|
||||
| Greater Than | x > y | int, float, uint |
|
||||
| Bitwise And | x & y | int, uint |
|
||||
| Bitwise Or | x \| y | int, uint |
|
||||
| Bitwise Xor | x ^ y | int, uint |
|
||||
| Operation | Syntax | Supported Types |
|
||||
| --------------------- | -------- | ---------------- |
|
||||
| Addition | x + y | int, float, uint |
|
||||
| Subtraction | x - y | int, float, uint |
|
||||
| Multiplication | x \* y | int, float, uint |
|
||||
| Division | x / y | int, float, uint |
|
||||
| Remainder | x % y | int, float, uint |
|
||||
| Exponentiation | x \*\* y | float |
|
||||
| Equal | x == y | int, float, uint |
|
||||
| Not Equal | x != y | int, float, uint |
|
||||
| Less Than | x < y | int, float, uint |
|
||||
| Greater Than | x > y | int, float, uint |
|
||||
| Less Than or Equal | x <= y | int, float, uint |
|
||||
| Greater Than or Equal | x >= y | int, float, uint |
|
||||
| Bitwise And | x & y | int, uint |
|
||||
| Bitwise Or | x \| y | int, uint |
|
||||
| Bitwise Xor | x ^ y | int, uint |
|
||||
|
||||
### Constructor Literals
|
||||
|
||||
@ -1026,6 +1029,7 @@ Therefore, all `bind` functions must call the builtin function `undefer` before
|
||||
This is necessary to ensure that the continuation in recursive monadic functions stays lazy and doesn't expand infinitely.
|
||||
|
||||
This is an example of a recursive function that would loop if passing the variable `a` to the recursive call `Result/foo(a, b)` was not deferred:
|
||||
|
||||
```python
|
||||
Result/foo x y = with Result {
|
||||
ask a = (Result/Ok 1)
|
||||
@ -1078,21 +1082,23 @@ u24 = 42
|
||||
|
||||
Currently, the 3 number types cannot be mixed.
|
||||
|
||||
| Operation | Syntax | Supported Types |
|
||||
| -------------- | ---------- | ---------------- |
|
||||
| Addition | (+ x y) | int, float, uint |
|
||||
| Subtraction | (- x y) | int, float, uint |
|
||||
| Multiplication | (\* x y) | int, float, uint |
|
||||
| Division | (/ x y) | int, float, uint |
|
||||
| Remainder | (% x y) | int, float, uint |
|
||||
| Exponentiation | (\*\* x y) | float |
|
||||
| Equal | (== x y) | int, float, uint |
|
||||
| Not Equal | (!= x y) | int, float, uint |
|
||||
| Less Than | (< x y) | int, float, uint |
|
||||
| Greater Than | (> x y) | int, float, uint |
|
||||
| Bitwise And | (& x y) | int, uint |
|
||||
| Bitwise Or | (\| x y) | int, uint |
|
||||
| Bitwise Xor | (^ x y) | int, uint |
|
||||
| Operation | Syntax | Supported Types |
|
||||
| --------------------- | ---------- | ---------------- |
|
||||
| Addition | (+ x y) | int, float, uint |
|
||||
| Subtraction | (- x y) | int, float, uint |
|
||||
| Multiplication | (\* x y) | int, float, uint |
|
||||
| Division | (/ x y) | int, float, uint |
|
||||
| Remainder | (% x y) | int, float, uint |
|
||||
| Exponentiation | (\*\* x y) | float |
|
||||
| Equal | (== x y) | int, float, uint |
|
||||
| Not Equal | (!= x y) | int, float, uint |
|
||||
| Less Than | (< x y) | int, float, uint |
|
||||
| Greater Than | (> x y) | int, float, uint |
|
||||
| Less Than or Equal | (<= x y) | int, float, uint |
|
||||
| Greater Than or Equal | (>= x y) | int, float, uint |
|
||||
| Bitwise And | (& x y) | int, uint |
|
||||
| Bitwise Or | (\| x y) | int, uint |
|
||||
| Bitwise Xor | (^ x y) | int, uint |
|
||||
|
||||
### Character Literal
|
||||
|
||||
|
@ -248,6 +248,8 @@ impl fmt::Display for Op {
|
||||
Op::SHL => write!(f, "<<"),
|
||||
Op::LOG => todo!(),
|
||||
Op::ATN => todo!(),
|
||||
Op::LE => write!(f, "<="),
|
||||
Op::GE => write!(f, ">="),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,6 +202,10 @@ pub enum Op {
|
||||
LOG,
|
||||
// a^b
|
||||
POW,
|
||||
/// Less than or equal
|
||||
LE,
|
||||
/// Greater than or equal
|
||||
GE,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -1057,6 +1057,10 @@ pub trait ParserCommons<'a>: Parser<'a> {
|
||||
Op::SHL
|
||||
} else if self.try_consume_exactly(">>") {
|
||||
Op::SHR
|
||||
} else if self.try_consume_exactly("<=") {
|
||||
Op::LE
|
||||
} else if self.try_consume_exactly(">=") {
|
||||
Op::GE
|
||||
} else if self.try_consume_exactly("<") {
|
||||
Op::LT
|
||||
} else if self.try_consume_exactly(">") {
|
||||
@ -1094,6 +1098,10 @@ pub trait ParserCommons<'a>: Parser<'a> {
|
||||
Op::SHL
|
||||
} else if self.starts_with(">>") {
|
||||
Op::SHR
|
||||
} else if self.starts_with("<=") {
|
||||
Op::LE
|
||||
} else if self.starts_with(">=") {
|
||||
Op::GE
|
||||
} else if self.starts_with("<") {
|
||||
Op::LT
|
||||
} else if self.starts_with(">") {
|
||||
|
@ -180,7 +180,7 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
let node = self.new_opr();
|
||||
self.link(fst, node.0);
|
||||
self.encode_term(snd, node.1);
|
||||
self.link(up, node.2);
|
||||
self.encode_le_ge_opers(opr, up, node.2);
|
||||
}
|
||||
// Partially apply with snd, flip
|
||||
(fst, Term::Num { val }) => {
|
||||
@ -194,7 +194,7 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
let node2 = self.new_opr();
|
||||
self.link(node1.2, node2.0);
|
||||
self.encode_term(snd, node2.1);
|
||||
self.link(up, node2.2);
|
||||
self.encode_le_ge_opers(opr, up, node2.2);
|
||||
} else {
|
||||
// flip
|
||||
let val = val.to_bits();
|
||||
@ -203,7 +203,7 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
let node = self.new_opr();
|
||||
self.encode_term(fst, node.0);
|
||||
self.link(snd, node.1);
|
||||
self.link(up, node.2);
|
||||
self.encode_le_ge_opers(opr, up, node.2);
|
||||
}
|
||||
}
|
||||
// Don't partially apply
|
||||
@ -216,7 +216,7 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
let node2 = self.new_opr();
|
||||
self.link(node1.2, node2.0);
|
||||
self.encode_term(snd, node2.1);
|
||||
self.link(up, node2.2);
|
||||
self.encode_le_ge_opers(opr, up, node2.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -240,6 +240,20 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
})
|
||||
}
|
||||
|
||||
fn encode_le_ge_opers(&mut self, opr: &Op, up: Place<'t>, node: Place<'t>) {
|
||||
match opr {
|
||||
Op::LE | Op::GE => {
|
||||
let node_eq = self.new_opr();
|
||||
let eq_val =
|
||||
Place::Tree(LoanedMut::new(Tree::Num { val: hvm::ast::Numb(Op::EQ.to_native_tag() as u32) }));
|
||||
self.link(eq_val, node_eq.0);
|
||||
self.link(node_eq.1, node);
|
||||
self.link(up, node_eq.2);
|
||||
}
|
||||
_ => self.link(up, node),
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_pat(&mut self, pat: &Pattern, up: Place<'t>) {
|
||||
maybe_grow(|| match pat {
|
||||
Pattern::Var(None) => self.link(up, Place::Tree(LoanedMut::new(Tree::Era))),
|
||||
@ -452,6 +466,9 @@ impl Op {
|
||||
Op::ATN => hvm::hvm::OP_AND,
|
||||
Op::LOG => hvm::hvm::OP_OR,
|
||||
Op::POW => hvm::hvm::OP_XOR,
|
||||
|
||||
Op::LE => hvm::hvm::OP_GT,
|
||||
Op::GE => hvm::hvm::OP_LT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1176,6 +1176,8 @@ impl Op {
|
||||
Op::NEQ => 3,
|
||||
Op::LT => 4,
|
||||
Op::GT => 4,
|
||||
Op::LE => 4,
|
||||
Op::GE => 4,
|
||||
Op::SHL => 5,
|
||||
Op::SHR => 5,
|
||||
Op::ADD => 6,
|
||||
|
@ -5,4 +5,7 @@ def main:
|
||||
-5 + -1 == -6,
|
||||
-3 * -9 == +27,
|
||||
0.250 + 0.125 == 0.375,
|
||||
1 >= 1 == 1,
|
||||
1 <= 0 == 0,
|
||||
42 >= 43 == 0,
|
||||
]
|
||||
|
@ -3,7 +3,7 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/ops.bend
|
||||
---
|
||||
NumScott:
|
||||
[1, 1, 1, 1, 1]
|
||||
[1, 1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
Scott:
|
||||
[1, 1, 1, 1, 1]
|
||||
[1, 1, 1, 1, 1, 1, 1, 1]
|
||||
|
Loading…
Reference in New Issue
Block a user