mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-10-26 14:05:36 +03:00
Merge pull request #590 from HigherOrderCO/582-add-native-casting-operations
#582 Add native casting operations
This commit is contained in:
commit
f26d5e85d4
@ -18,8 +18,9 @@ and this project does not currently adhere to a particular versioning scheme.
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `log` and `atan2` builtin functions. ([#583][gh-583])
|
|
||||||
- Create new type of top-level definition for writing native HVM definitions. ([#586][gh-586])
|
- Create new type of top-level definition for writing native HVM definitions. ([#586][gh-586])
|
||||||
|
- Add `log` and `atan2` builtin functions. ([#583][gh-583])
|
||||||
|
- Add `to_f24`, `to_u24` and `to_i24` number casting builtin functions. ([#582][gh-582])
|
||||||
|
|
||||||
## [0.2.35] - 2024-06-06
|
## [0.2.35] - 2024-06-06
|
||||||
|
|
||||||
@ -340,6 +341,7 @@ and this project does not currently adhere to a particular versioning scheme.
|
|||||||
[gh-516]: https://github.com/HigherOrderCO/Bend/issues/516
|
[gh-516]: https://github.com/HigherOrderCO/Bend/issues/516
|
||||||
[gh-526]: https://github.com/HigherOrderCO/Bend/issues/526
|
[gh-526]: https://github.com/HigherOrderCO/Bend/issues/526
|
||||||
[gh-528]: https://github.com/HigherOrderCO/Bend/issues/528
|
[gh-528]: https://github.com/HigherOrderCO/Bend/issues/528
|
||||||
|
[gh-582]: https://github.com/HigherOrderCO/Bend/issues/582
|
||||||
[gh-583]: https://github.com/HigherOrderCO/Bend/issues/583
|
[gh-583]: https://github.com/HigherOrderCO/Bend/issues/583
|
||||||
[gh-586]: https://github.com/HigherOrderCO/Bend/issues/586
|
[gh-586]: https://github.com/HigherOrderCO/Bend/issues/586
|
||||||
[Unreleased]: https://github.com/HigherOrderCO/Bend/compare/0.2.35...HEAD
|
[Unreleased]: https://github.com/HigherOrderCO/Bend/compare/0.2.35...HEAD
|
||||||
|
@ -226,3 +226,37 @@ A Natural Number can be written with literals with a `#` before the literal numb
|
|||||||
|
|
||||||
## IO
|
## IO
|
||||||
IO Functions are in the **next milestone**!
|
IO Functions are in the **next milestone**!
|
||||||
|
|
||||||
|
## Numeric operations
|
||||||
|
|
||||||
|
### log
|
||||||
|
```py
|
||||||
|
def log(x: f24, base: f24) -> f24
|
||||||
|
```
|
||||||
|
Computes the logarithm of `x` with the specified `base`.
|
||||||
|
|
||||||
|
### atan2
|
||||||
|
```py
|
||||||
|
def atan2(x: f24, y: f24) -> f24
|
||||||
|
```
|
||||||
|
Computes the arctangent of `y / x`.
|
||||||
|
|
||||||
|
Has the same behaviour as `atan2f` in the C math lib.
|
||||||
|
|
||||||
|
### to_f24
|
||||||
|
```py
|
||||||
|
def to_f24(x: any number) -> f24
|
||||||
|
```
|
||||||
|
Casts any native number to an f24.
|
||||||
|
|
||||||
|
### to_u24
|
||||||
|
```py
|
||||||
|
def to_u24(x: any number) -> u24
|
||||||
|
```
|
||||||
|
Casts any native number to a u24.
|
||||||
|
|
||||||
|
### to_i24
|
||||||
|
```py
|
||||||
|
def to_i24(x: any number) -> i24
|
||||||
|
```
|
||||||
|
Casts any native number to an i24.
|
||||||
|
@ -95,7 +95,10 @@ print text = (IO/Call IO/MAGIC "PUT_TEXT" text @x (IO/Done IO/MAGIC x))
|
|||||||
#read_file path = (IO/Call IO/MAGIC "GET_FILE" path @x (IO/Done IO/MAGIC x))
|
#read_file path = (IO/Call IO/MAGIC "GET_FILE" path @x (IO/Done IO/MAGIC x))
|
||||||
#write_file path text = (IO/Call IO/MAGIC "PUT_FILE" (path, text) @x (IO/Done IO/MAGIC x))
|
#write_file path text = (IO/Call IO/MAGIC "PUT_FILE" (path, text) @x (IO/Done IO/MAGIC x))
|
||||||
|
|
||||||
|
# Returns a monotonically increasing nanosecond timestamp as an u48 encoded as a pair of u24s.
|
||||||
get_time = (IO/Call IO/MAGIC "GET_TIME" * @x (IO/Done IO/MAGIC x))
|
get_time = (IO/Call IO/MAGIC "GET_TIME" * @x (IO/Done IO/MAGIC x))
|
||||||
|
|
||||||
|
# Sleeps for the given number of nanoseconds, given by an u48 encoded as a pair of u24s.
|
||||||
sleep hi_lo = (IO/Call IO/MAGIC "PUT_TIME" hi_lo @x (IO/Done IO/MAGIC x))
|
sleep hi_lo = (IO/Call IO/MAGIC "PUT_TIME" hi_lo @x (IO/Done IO/MAGIC x))
|
||||||
|
|
||||||
|
|
||||||
@ -110,10 +113,31 @@ defer val = @x (x val)
|
|||||||
defer_arg defered arg = @x (defered x arg)
|
defer_arg defered arg = @x (defered x arg)
|
||||||
undefer defered = (defered @x x)
|
undefer defered = (defered @x x)
|
||||||
|
|
||||||
# log :: f24 -> f24 -> f24
|
|
||||||
|
# Native numeric operations
|
||||||
|
|
||||||
|
# log(x: f24, base: f24) -> f24
|
||||||
# Computes the logarithm of `x` with the specified `base`.
|
# Computes the logarithm of `x` with the specified `base`.
|
||||||
log x base = (| base x)
|
hvm log:
|
||||||
# atan2 :: f24 -> f24 -> f24
|
(x ($([|] $(x ret)) ret))
|
||||||
|
|
||||||
|
# atan2(x: f24, y: f24) -> f24
|
||||||
# Has the same behaviour as `atan2f` in the C math lib.
|
# Has the same behaviour as `atan2f` in the C math lib.
|
||||||
# Computes the arctangent of the quotient of its two arguments.
|
# Computes the arctangent of the quotient of its two arguments.
|
||||||
atan2 x y = (& x y)
|
hvm atan2:
|
||||||
|
($([&] $(y ret)) (y ret))
|
||||||
|
|
||||||
|
# to_f24(x: native number) -> f24
|
||||||
|
# Casts any native number to an f24.
|
||||||
|
hvm to_f24:
|
||||||
|
($([f24] ret) ret)
|
||||||
|
|
||||||
|
# to_u24(x: native number) -> u24
|
||||||
|
# Casts any native number to a u24.
|
||||||
|
hvm to_u24:
|
||||||
|
($([u24] ret) ret)
|
||||||
|
|
||||||
|
# to_i24(x: native number) -> i24
|
||||||
|
# Casts any native number to an i24.
|
||||||
|
hvm to_i24:
|
||||||
|
($([i24] ret) ret)
|
||||||
|
@ -49,8 +49,19 @@ impl Ctx<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rm_def(book: &mut Book, def_name: &Name) {
|
||||||
|
if book.defs.contains_key(def_name) {
|
||||||
|
book.defs.shift_remove(def_name);
|
||||||
|
} else if book.hvm_defs.contains_key(def_name) {
|
||||||
|
book.hvm_defs.shift_remove(def_name);
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove unused definitions.
|
// Remove unused definitions.
|
||||||
for def in self.book.defs.keys().cloned().collect::<Vec<_>>() {
|
let names = self.book.defs.keys().cloned().chain(self.book.hvm_defs.keys().cloned()).collect::<Vec<_>>();
|
||||||
|
for def in names {
|
||||||
if let Some(use_) = used.get(&def) {
|
if let Some(use_) = used.get(&def) {
|
||||||
match use_ {
|
match use_ {
|
||||||
Used::Main => {
|
Used::Main => {
|
||||||
@ -60,7 +71,7 @@ impl Ctx<'_> {
|
|||||||
// Used by a non-builtin definition.
|
// Used by a non-builtin definition.
|
||||||
// Prune if `prune_all`, otherwise show a warning.
|
// Prune if `prune_all`, otherwise show a warning.
|
||||||
if prune_all {
|
if prune_all {
|
||||||
self.book.defs.shift_remove(&def);
|
rm_def(self.book, &def);
|
||||||
} else {
|
} else {
|
||||||
self.info.add_rule_warning("Definition is unused.", WarningType::UnusedDefinition, def);
|
self.info.add_rule_warning("Definition is unused.", WarningType::UnusedDefinition, def);
|
||||||
}
|
}
|
||||||
@ -69,7 +80,7 @@ impl Ctx<'_> {
|
|||||||
// Unused, but a user-defined constructor.
|
// Unused, but a user-defined constructor.
|
||||||
// Prune if `prune_all`, otherwise nothing.
|
// Prune if `prune_all`, otherwise nothing.
|
||||||
if prune_all {
|
if prune_all {
|
||||||
self.book.defs.shift_remove(&def);
|
rm_def(self.book, &def);
|
||||||
} else {
|
} else {
|
||||||
// Don't show warning if it's a user-defined constructor.
|
// Don't show warning if it's a user-defined constructor.
|
||||||
}
|
}
|
||||||
@ -77,7 +88,7 @@ impl Ctx<'_> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Unused builtin, can always be pruned.
|
// Unused builtin, can always be pruned.
|
||||||
self.book.defs.shift_remove(&def);
|
rm_def(self.book, &def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,21 +129,21 @@ pub fn desugar_book(
|
|||||||
|
|
||||||
ctx.book.make_var_names_unique();
|
ctx.book.make_var_names_unique();
|
||||||
ctx.book.desugar_use();
|
ctx.book.desugar_use();
|
||||||
|
|
||||||
ctx.book.make_var_names_unique();
|
ctx.book.make_var_names_unique();
|
||||||
ctx.book.linearize_vars();
|
ctx.book.linearize_vars();
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
ctx.check_unbound_vars()?;
|
ctx.check_unbound_vars()?;
|
||||||
|
|
||||||
// Optimizing passes
|
|
||||||
if opts.float_combinators {
|
if opts.float_combinators {
|
||||||
ctx.book.float_combinators(MAX_NET_SIZE);
|
ctx.book.float_combinators(MAX_NET_SIZE);
|
||||||
}
|
}
|
||||||
|
// sanity check
|
||||||
ctx.check_unbound_refs()?;
|
ctx.check_unbound_refs()?;
|
||||||
|
|
||||||
|
// Optimizing passes
|
||||||
ctx.prune(opts.prune);
|
ctx.prune(opts.prune);
|
||||||
|
|
||||||
if opts.merge {
|
if opts.merge {
|
||||||
ctx.book.merge_definitions();
|
ctx.book.merge_definitions();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Expected +42.0
|
# Expected +42.0
|
||||||
hvm to_f24:
|
hvm to_f24_:
|
||||||
($([f24] a) a)
|
($([f24] a) a)
|
||||||
|
|
||||||
main = (to_f24 42)
|
main = (to_f24_ 42)
|
48
tests/golden_tests/run_file/num_cast.bend
Normal file
48
tests/golden_tests/run_file/num_cast.bend
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
main =
|
||||||
|
use inf = (** 9.0 (** 9.0 9.0))
|
||||||
|
(
|
||||||
|
(to_u24 0),
|
||||||
|
(to_u24 1),
|
||||||
|
(to_u24 123456),
|
||||||
|
(to_u24 -1),
|
||||||
|
(to_u24 +1),
|
||||||
|
(to_u24 +0),
|
||||||
|
(to_u24 +400),
|
||||||
|
(to_u24 1.0),
|
||||||
|
(to_u24 1.5),
|
||||||
|
(to_u24 -3.0),
|
||||||
|
(to_u24 -3.5),
|
||||||
|
(to_u24 inf), # inf
|
||||||
|
(to_u24 (* -1.0 inf)), # -inf
|
||||||
|
(to_u24 (/ inf inf)), # nan (inf/inf)
|
||||||
|
99999,
|
||||||
|
(to_i24 0),
|
||||||
|
(to_i24 1),
|
||||||
|
(to_i24 123456),
|
||||||
|
(to_i24 -1),
|
||||||
|
(to_i24 +1),
|
||||||
|
(to_i24 +0),
|
||||||
|
(to_i24 +400),
|
||||||
|
(to_i24 1.0),
|
||||||
|
(to_i24 1.5),
|
||||||
|
(to_i24 -3.0),
|
||||||
|
(to_i24 -3.5),
|
||||||
|
(to_i24 inf), # inf
|
||||||
|
(to_i24 (* -1.0 inf)), # -inf
|
||||||
|
(to_i24 (/ inf inf)), # nan (inf/inf)
|
||||||
|
99999,
|
||||||
|
(to_f24 0),
|
||||||
|
(to_f24 1),
|
||||||
|
(to_f24 123456),
|
||||||
|
(to_f24 -1),
|
||||||
|
(to_f24 +1),
|
||||||
|
(to_f24 +0),
|
||||||
|
(to_f24 +400),
|
||||||
|
(to_f24 1.0),
|
||||||
|
(to_f24 1.5),
|
||||||
|
(to_f24 -3.0),
|
||||||
|
(to_f24 -3.5),
|
||||||
|
(to_f24 inf), # inf
|
||||||
|
(to_f24 (* -1.0 inf)), # -inf
|
||||||
|
(to_f24 (/ inf inf)) # nan (inf/inf)
|
||||||
|
)
|
9
tests/snapshots/run_file__num_cast.bend.snap
Normal file
9
tests/snapshots/run_file__num_cast.bend.snap
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
source: tests/golden_tests.rs
|
||||||
|
input_file: tests/golden_tests/run_file/num_cast.bend
|
||||||
|
---
|
||||||
|
NumScott:
|
||||||
|
(0, (1, (123456, (16777215, (1, (0, (400, (1, (1, (0, (0, (16777215, (0, (0, (99999, (+0, (+1, (+123456, (-1, (+1, (+0, (+400, (+1, (+1, (-3, (-3, (+8388607, (-8388608, (+0, (99999, (0.000, (1.000, (123456.000, (-1.000, (1.000, (0.000, (400.000, (1.000, (1.500, (-3.000, (-3.500, (inf, (-inf, NaN)))))))))))))))))))))))))))))))))))))))))))
|
||||||
|
|
||||||
|
Scott:
|
||||||
|
(0, (1, (123456, (16777215, (1, (0, (400, (1, (1, (0, (0, (16777215, (0, (0, (99999, (+0, (+1, (+123456, (-1, (+1, (+0, (+400, (+1, (+1, (-3, (-3, (+8388607, (-8388608, (+0, (99999, (0.000, (1.000, (123456.000, (-1.000, (1.000, (0.000, (400.000, (1.000, (1.500, (-3.000, (-3.500, (inf, (-inf, NaN)))))))))))))))))))))))))))))))))))))))))))
|
Loading…
Reference in New Issue
Block a user