Number-to-ByteVector-conversion (#44)
Some checks failed
per-push tests / build (push) Failing after 33s
per-push tests / test-frontend (push) Has been skipped
per-push tests / timed-decomposer-parse (push) Has been skipped
per-push tests / test-utility (push) Has been skipped
per-push tests / test-backend (push) Has been skipped

# Number and ByteVector conversions

Adds the following to isa conversions between data types, as well as tests for each:

- `NTOBV` Number To ByteVector - takes a mutable memory address with a Number and replaces this value with a ByteVector of the same numerical value
- `BVTON` ByteVector To Number - takes a mutable memory address with a ByteVector and replaces this value with a Number of the same numerical value as the ByteVector's value

Reviewed-on: #44
Co-authored-by: Kolby Heacock <codeshiftster@gmail.com>
Co-committed-by: Kolby Heacock <codeshiftster@gmail.com>
This commit is contained in:
Kolby Heacock 2025-12-04 12:09:44 -08:00 committed by Ava Apples Affine
parent 5582da5b41
commit cc60e45fab
2 changed files with 70 additions and 9 deletions

View file

@ -16,7 +16,7 @@
*/
use organelle::{Fraction, Number, Numeric};
use organelle::{Float, Fraction, Number, Numeric};
use crate::hmap::QuickMap;
use crate::stackstack::StackStack;
@ -399,6 +399,28 @@ impl VM {
}
}),
i::NTOBV => access!(&instr.1[0], {
if let Datum::Number(snum) = **access!(&instr.1[0]) {
let n = snum.make_inexact();
if !snum.is_exact() || n.0.fract() != 0.0 ||
n.0 > u8::MAX.into() || n.0 < 0.0 {
e!("input to NTOBV cannot cleanly convert");
}
Datum::ByteVector(n.0.to_ne_bytes().to_vec()).into()
} else {
e!("illegal argument to NTOBV instruction");
}
}),
i::BVTON => access!(&instr.1[0], {
if let Datum::ByteVector(sbv) = &**access!(&instr.1[0]) {
let sf64 = f64::from_ne_bytes(sbv.clone().try_into().unwrap());
Datum::Number(Number::Flt(Float(sf64))).into()
} else {
e!("illegal argument to BVTON instruction");
}
}),
i::NTOC => access!(&instr.1[0], {
if let Datum::Number(snum) = **access!(&instr.1[0]) {
let n = snum.make_inexact();
@ -1098,16 +1120,16 @@ mod tests {
#[test]
fn isa_conversions() {
let mut vm = VM::from(Program(vec![], vec![
// load from stack into expr
Instruction(i::DUPL, vec![Operand(Address::Stack, 0),
Operand(Address::Expr, 0)]),
// create a strunct and push to stack
// create a struct and push to stack
Instruction(i::CTOS, vec![Operand(Address::Expr, 0)]),
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
// reset expr to original char
Instruction(i::DUPL, vec![Operand(Address::Stack, 1),
Operand(Address::Expr, 0)]),
@ -1123,9 +1145,18 @@ mod tests {
Instruction(i::NTOE, vec![Operand(Address::Expr, 0)]),
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
// convert to ByteVector and push to stack
Instruction(i::NTOBV, vec![Operand(Address::Expr, 0)]),
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
// convert back to inexact and push to stack
Instruction(i::BVTON, vec![Operand(Address::Expr, 0)]),
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
// create a char and push to stack
Instruction(i::NTOC, vec![Operand(Address::Expr, 0)]),
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
])).with_stack({
let mut i = StackStack::new();
i.push_current_stack(Datum::Char(b'a').into());
@ -1135,12 +1166,14 @@ mod tests {
let case = TestResult{
expr: None,
stack: vec![
(0, Datum::Char(b'a').into()),
(1, Datum::Number(Number::Fra(Fraction(97, 1))).into()),
(2, Datum::Number(Number::Flt(Float(97.0))).into()),
(3, Datum::Number(Number::Fra(Fraction(97, 1))).into()),
(4, Datum::String(vec![b'a']).into()),
(5, Datum::Char(b'a').into()),
(0, Datum::Char(b'a').into()), // NTOC
(1, Datum::Number(Number::Flt(Float(97.0))).into()), // BVTON
(2, Datum::ByteVector(vec![0, 0, 0, 0, 0, 64, 88, 64]).into()), // NTOBV
(3, Datum::Number(Number::Fra(Fraction(97, 1))).into()), // NTOE
(4, Datum::Number(Number::Flt(Float(97.0))).into()), // NTOI
(5, Datum::Number(Number::Fra(Fraction(97, 1))).into()), // CTON
(6, Datum::String(vec![b'a']).into()), // CTOS
(7, Datum::Char(b'a').into()), // DUPL
],
syms: vec![],
errr: None,