interpreter: concatenation; proper type display

This commit is contained in:
Guillem L. Jara
2026-05-25 14:37:18 +02:00
parent fa77cb8f44
commit 58f63c35a1
3 changed files with 49 additions and 3 deletions
+1
View File
@@ -224,6 +224,7 @@ impl OpCode {
| Self::Divide
| Self::Raise
| Self::Modulo
| Self::Concat
)
}
+36
View File
@@ -1,6 +1,8 @@
use std::{
borrow::Cow,
fmt::Display,
hash::Hash,
io::Write,
mem::discriminant,
ops::{Add, Div, Mul, Sub},
};
@@ -62,6 +64,26 @@ impl Value<'_> {
_ => 0.,
}
}
pub fn write_string(&self, f: &mut Vec<u8>) {
match self {
Self::String(s) | Self::Regex(s) => f.extend_from_slice(s),
Self::Float(n) => write!(f, "{n}").unwrap(),
&Self::Bool(false) => f.push(b'0'),
&Self::Bool(true) => f.push(b'1'),
Self::Array(_) => panic!("Attempted to use array in scalar context!"),
_ => {}
}
}
pub fn string_size_hint(&self) -> usize {
match self {
Self::String(s) | Self::Regex(s) => s.len(),
Self::Float(_) => 2,
Self::Bool(_) => 1,
_ => 0,
}
}
}
impl<'a> Add for &'_ Value<'a> {
@@ -109,3 +131,17 @@ impl Hash for Value<'_> {
}
}
}
impl Display for Value<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Value::Float(n) => <_ as Display>::fmt(n, f),
Value::String(s) => write!(f, "{:?}", String::from_utf8_lossy(s)),
Value::Regex(s) => write!(f, "/{}/", String::from_utf8_lossy(s)),
&Value::Bool(b) => write!(f, "{}", b as usize),
Value::Array(_) => write!(f, "array"),
Value::Untyped => write!(f, "untyped"),
Value::Unassigned => write!(f, "unassigned"),
}
}
}
+12 -3
View File
@@ -1,6 +1,7 @@
use std::{
fmt::{self, Display},
mem::replace,
vec::Vec as StdVec,
};
use ahash::RandomState;
@@ -117,6 +118,14 @@ impl Interpreter<'_> {
OpCode::Subtract => lhs - rhs,
OpCode::Multiply => lhs * rhs,
OpCode::Divide => lhs / rhs,
OpCode::Concat => {
let mut buf = StdVec::with_capacity(
lhs.string_size_hint() + rhs.string_size_hint(),
);
lhs.write_string(&mut buf);
rhs.write_string(&mut buf);
Value::String(buf.into())
}
_ => todo!(),
}
};
@@ -203,7 +212,7 @@ impl Display for Registers<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Registers:")?;
let n = self.0.len().checked_ilog10().unwrap_or(0) as usize + 1;
fmt_list(f, self.0.iter(), |f, i, e| write!(f, "r{i:0n$} = {e:?}"))
fmt_list(f, self.0.iter(), |f, i, e| write!(f, "r{i:0n$} = {e}"))
}
}
@@ -211,7 +220,7 @@ impl Display for SymbolTable<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Symbols:")?;
fmt_list(f, self.user.iter(), |f, i, (k, v)| {
write!(f, "user[{i}] @ {k} = {v:?}")
write!(f, "user[{i}] @ {k} = {v}")
})
}
}
@@ -219,7 +228,7 @@ impl Display for SymbolTable<'_> {
impl Display for Consts<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Consts:")?;
fmt_list(f, self.0.iter(), |f, i, e| write!(f, "mem[{i}] = {e:?}"))
fmt_list(f, self.0.iter(), |f, i, e| write!(f, "mem[{i}] = {e}"))
}
}