VM Bytecode char to string instructions
All checks were successful
per-push tests / build (push) Successful in 3m17s
per-push tests / test-frontend (push) Successful in 1m11s
per-push tests / test-utility (push) Successful in 2m10s
per-push tests / test-backend (push) Successful in 1m52s
per-push tests / timed-decomposer-parse (push) Successful in 1m39s

New instrucions: CTOS and MKSTR. CTOS creates a string containing
a single (input) character. MKSTR creates a new blank string. Unit
tests included.

fixes: #42

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2025-08-09 05:23:45 +00:00
parent e310b901c3
commit f48867db42
2 changed files with 45 additions and 13 deletions

View file

@ -1,3 +1,13 @@
# TODO: add the following info
# - introductory VM info (description, list of components)
# - info on the different data types
# - info on garbage collection
# - info on program execution
# - info on error handling
# - info on traps
# - info on numbers
# - info on symtable (and its uses)
[[addressing_modes]] [[addressing_modes]]
name = "expr" name = "expr"
mutable = true mutable = true
@ -275,6 +285,12 @@ args = ["src"]
output = "" output = ""
description = "decrements number at source" description = "decrements number at source"
[[instructions]]
name = "ctos"
args = ["src"]
output = ""
description = "mutates a char datum into a string datum"
[[instructions]] [[instructions]]
name = "cton" name = "cton"
args = ["src"] args = ["src"]
@ -317,6 +333,12 @@ args = []
output = "a blank bytevector" output = "a blank bytevector"
description = "creates a blank bytevector" description = "creates a blank bytevector"
[[instructions]]
name = "mkstr"
args = []
output = "an empty string"
description = "creates a new empty string"
[[instructions]] [[instructions]]
name = "index" name = "index"
args = ["collection", "index"] args = ["collection", "index"]

View file

@ -369,6 +369,16 @@ impl VM {
}), }),
// byte/char to and from number conversions // byte/char to and from number conversions
i::CTOS => access!(&instr.1[0], {
if let Datum::Char(schr) = **access!(&instr.1[0]) {
let mut v = vec![];
v.push(schr);
Datum::String(v).into()
} else {
e!("illegal argument to CTOS instruction");
}
}),
i::CTON => access!(&instr.1[0], { i::CTON => access!(&instr.1[0], {
if let Datum::Char(schr) = **access!(&instr.1[0]) { if let Datum::Char(schr) = **access!(&instr.1[0]) {
Datum::Number(Number::Fra(Fraction(schr as isize, 1))).into() Datum::Number(Number::Fra(Fraction(schr as isize, 1))).into()
@ -421,6 +431,8 @@ impl VM {
i::MKBVEC => self.expr = Datum::ByteVector(vec![]).into(), i::MKBVEC => self.expr = Datum::ByteVector(vec![]).into(),
i::MKSTR => self.expr = Datum::String(vec![]).into(),
i::INDEX => { i::INDEX => {
let Datum::Number(ref idx) = **access!(&instr.1[1]) else { let Datum::Number(ref idx) = **access!(&instr.1[1]) else {
e!("illegal argument to INDEX instruction"); e!("illegal argument to INDEX instruction");
@ -1067,23 +1079,20 @@ mod tests {
#[test] #[test]
fn isa_conversions() { fn isa_conversions() {
/* program:
* dupl %0, $ex
* cton $ex
* push $ex
* ntoc $ex
* push $ex
* ntoi $ex
* push $ex
* ntoe $ex
* push $ex
*/
let mut vm = VM::from(Program(vec![ let mut vm = VM::from(Program(vec![
// load from stack into expr // load from stack into expr
Instruction(i::DUPL, vec![Operand(Address::Stack, 0), Instruction(i::DUPL, vec![Operand(Address::Stack, 0),
Operand(Address::Expr, 0)]), Operand(Address::Expr, 0)]),
// create a strunct 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)]),
// create a number and push to stack // create a number and push to stack
Instruction(i::CTON, vec![Operand(Address::Expr, 0)]), Instruction(i::CTON, vec![Operand(Address::Expr, 0)]),
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]), Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
@ -1112,7 +1121,8 @@ mod tests {
(1, Datum::Number(Number::Fra(Fraction(97, 1))).into()), (1, Datum::Number(Number::Fra(Fraction(97, 1))).into()),
(2, Datum::Number(Number::Flt(Float(97.0))).into()), (2, Datum::Number(Number::Flt(Float(97.0))).into()),
(3, Datum::Number(Number::Fra(Fraction(97, 1))).into()), (3, Datum::Number(Number::Fra(Fraction(97, 1))).into()),
(4, Datum::Char(b'a').into()), (4, Datum::String(vec![b'a']).into()),
(5, Datum::Char(b'a').into()),
], ],
syms: vec![], syms: vec![],
errr: None, errr: None,