Phase 1.2-1.6: replace variables HashMap<String,String> with HashMap<String,Value>, rewrite str_to_dyn/dyn_to_str -> value_to_dynamic/dynamic_to_value, update resolve_string/evaluate_condition/is_truthy for Value

This commit is contained in:
Glint Dev
2026-07-21 20:32:29 +03:00
parent 5597f07787
commit 30cf2e5e26
7 changed files with 542 additions and 53 deletions

View File

@@ -1,5 +1,6 @@
use super::opcodes::*;
use super::types::InterpError;
use super::types::{InterpError, Value};
use compact_str::CompactString;
pub struct Reader<'a> {
pub data: &'a [u8],
@@ -138,6 +139,77 @@ impl<'a> Reader<'a> {
Ok(s)
}
pub fn read_value(&mut self, type_op: u8) -> Result<Option<Value>, InterpError> {
let val = match type_op {
OP_PROP_STR | OP_PROP_COLOR | OP_PROP_FSPATH | OP_PROP_IDENT => {
Some(Value::Str(CompactString::new(self.read_string()?)))
}
OP_PROP_RHEI => {
let raw = self.read_string()?;
let mut s = String::with_capacity(super::rhei::RHEI_PREFIX.len() + raw.len());
s.push_str(super::rhei::RHEI_PREFIX);
s.push_str(&raw);
Some(Value::Str(CompactString::new(s)))
}
OP_PROP_VAR => {
let name = self.read_str_ref()?;
let mut s = String::with_capacity(name.len() + 1);
s.push('$');
s.push_str(name);
Some(Value::Str(CompactString::new(s)))
}
OP_PROP_INT => Some(Value::Int(self.read_i64()?)),
OP_PROP_FLOAT => Some(Value::Float(self.read_f64()?)),
OP_PROP_BOOL => Some(Value::Bool(self.read_byte()? != 0)),
OP_PROP_NULL => None,
OP_PROP_ARRAY => {
let items = self.read_array_as_values()?;
Some(Value::Array(items))
}
OP_PROP_UNIT => {
let num = self.read_f64()?;
let unit = self.read_str_ref()?;
let s = if num.fract() == 0.0 {
format!("{}{}", num as i64, unit)
} else {
format!("{}{}", num, unit)
};
Some(Value::Str(CompactString::new(s)))
}
OP_PROP_CALL => {
let name = self.read_string()?;
let arg_count = self.read_u32()? as usize;
let mut args = Vec::with_capacity(arg_count);
for _ in 0..arg_count {
let op = self.read_byte()?;
let val = self.read_value(op)?.unwrap_or(Value::None);
args.push(match val {
Value::Str(s) => s.to_string(),
Value::Int(i) => i.to_string(),
Value::Float(f) => f.to_string(),
Value::Bool(b) => b.to_string(),
_ => String::new(),
});
}
Some(Value::Str(CompactString::new(format!("{}({})", name, args.join(",")))))
}
_ => None,
};
Ok(val)
}
pub fn read_array_as_values(&mut self) -> Result<Vec<Value>, InterpError> {
let count = self.read_u32()? as usize;
let mut items = Vec::with_capacity(count);
for _ in 0..count {
let elem_op = self.read_byte()?;
if let Some(v) = self.read_value(elem_op)? {
items.push(v);
}
}
Ok(items)
}
pub fn read_array_as_strings(&mut self) -> Result<Vec<String>, InterpError> {
let count = self.read_u32()? as usize;
let mut items = Vec::with_capacity(count);