pub mod error;
pub mod numeric;
pub mod opcodes;
pub mod postfix;
pub mod token;
pub mod checksum;
pub mod string;
pub mod value;
pub mod array;
pub mod array_value;
use error::CalcError;
use opcodes::Opcode;
pub type CalcResult<T> = Result<T, CalcError>;
#[derive(Debug, Clone, PartialEq)]
pub enum ExprKind {
Numeric,
String,
Array,
}
#[derive(Debug, Clone)]
pub struct CompiledExpr {
pub code: Vec<Opcode>,
pub kind: ExprKind,
pub loop_pairs: Vec<(usize, usize)>,
}
impl CompiledExpr {
pub fn arg_usage(&self) -> (u32, u32) {
use opcodes::CoreOp;
let mut inputs: u32 = 0;
let mut stores: u32 = 0;
for op in &self.code {
match op {
Opcode::Core(CoreOp::End) => break,
Opcode::Core(CoreOp::PushVar(idx)) | Opcode::Core(CoreOp::PushDoubleVar(idx)) => {
if (*idx as usize) < CALC_NARGS {
inputs |= (1u32 << *idx) & !stores;
}
}
Opcode::Core(CoreOp::StoreVar(idx)) | Opcode::Core(CoreOp::StoreDoubleVar(idx)) => {
if (*idx as usize) < CALC_NARGS {
stores |= 1u32 << *idx;
}
}
_ => {}
}
}
(inputs, stores)
}
pub fn disassemble(&self) -> String {
let mut out = String::new();
for (i, op) in self.code.iter().enumerate() {
out.push_str(&format!("{:4}: {:?}\n", i, op));
}
out
}
}
pub const CALC_NARGS: usize = 21;
#[derive(Debug, Clone)]
pub struct NumericInputs {
pub vars: [f64; CALC_NARGS],
pub prev_val: f64,
}
impl NumericInputs {
pub fn new() -> Self {
NumericInputs {
vars: [0.0; CALC_NARGS],
prev_val: 0.0,
}
}
pub fn with_vars(vars: [f64; CALC_NARGS]) -> Self {
NumericInputs {
vars,
prev_val: 0.0,
}
}
}
impl Default for NumericInputs {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct StringInputs {
pub num_vars: [f64; CALC_NARGS], pub str_vars: [String; CALC_NARGS], pub prev_val: f64,
}
impl StringInputs {
pub fn new() -> Self {
StringInputs {
num_vars: [0.0; CALC_NARGS],
str_vars: std::array::from_fn(|_| String::new()),
prev_val: 0.0,
}
}
}
impl Default for StringInputs {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct ArrayInputs {
pub num_vars: [f64; CALC_NARGS],
pub arrays: Vec<Vec<f64>>, pub array_size: usize,
pub prev_val: f64,
}
impl ArrayInputs {
pub fn new(array_size: usize) -> Self {
ArrayInputs {
num_vars: [0.0; CALC_NARGS],
arrays: vec![Vec::new(); CALC_NARGS],
array_size,
prev_val: 0.0,
}
}
}
impl Default for ArrayInputs {
fn default() -> Self {
Self::new(1)
}
}