#![cfg_attr(feature = "no_std", no_std)]
#![allow(warnings)]
#![allow(dead_code)]
//extern crate core as rust_core;
extern crate seahash;
#[cfg(feature="no_std")] #[macro_use]
extern crate alloc;
#[cfg(not(feature = "no_std"))]
extern crate core;
#[cfg(feature="no_std")]
use hashbrown::HashMap;
#[cfg(not(feature = "no_std"))]
use std::collections::HashMap;
#[cfg(feature="no_std")]
use alloc::fmt::{self, Debug, Display};
#[cfg(not(feature = "no_std"))]
use std::fmt::{self, Debug, Display};
#[cfg(feature="no_std")]
use alloc::vec::Vec;
#[cfg(feature="no_std")]
use fxhash::FxHasher;
#[cfg(feature = "no_std")]
use embedded_io::{self, Read, Write};
#[cfg(not(feature = "no_std"))]
use std::io::{self, Error as ioError, Cursor, Read, Write};
#[cfg(feature = "no_std")]
use alloc::string::{String, ToString};
#[cfg(feature = "no_std")]
use core::hash::{Hash, Hasher};
#[cfg(not(feature = "no_std"))]
use std::hash::{Hash, Hasher};
#[cfg(feature = "no_std")]
use alloc::boxed::Box;
#[cfg(feature = "matrix")]
extern crate nalgebra as na;
#[cfg(feature = "pretty_print")]
extern crate tabled;
#[cfg(feature = "serde")] #[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(any(feature = "math_pow", feature = "f64", feature = "f32", feature = "complex", feature = "rational"))]
extern crate num_traits;
use paste::paste;
#[cfg(any(feature = "math_pow", feature = "f64"))]
use num_traits::*;
#[cfg(feature = "rational")]
use num_rational::Rational64;
#[cfg(feature = "vector3")]
use nalgebra::Vector3;
#[cfg(feature = "vectord")]
use nalgebra::DVector;
#[cfg(feature = "vector2")]
use nalgebra::Vector2;
#[cfg(feature = "vector4")]
use nalgebra::Vector4;
#[cfg(feature = "row_vectord")]
use nalgebra::RowDVector;
#[cfg(feature = "matrix1")]
use nalgebra::Matrix1;
#[cfg(feature = "matrix3")]
use nalgebra::Matrix3;
#[cfg(feature = "matrix4")]
use nalgebra::Matrix4;
#[cfg(feature = "row_vector3")]
use nalgebra::RowVector3;
#[cfg(feature = "row_vector4")]
use nalgebra::RowVector4;
#[cfg(feature = "row_vector2")]
use nalgebra::RowVector2;
#[cfg(feature = "matrixd")]
use nalgebra::DMatrix;
#[cfg(feature = "matrix2x3")]
use nalgebra::Matrix2x3;
#[cfg(feature = "matrix3x2")]
use nalgebra::Matrix3x2;
#[cfg(feature = "matrix2")]
use nalgebra::Matrix2;
#[cfg(feature = "pretty_print")]
use tabled::{
builder::Builder,
settings::{object::Rows,Panel, Span, Alignment, Modify, Style},
Tabled,
};
pub mod error;
pub mod kind;
pub mod nodes;
pub mod structures;
pub mod value;
#[cfg(feature = "functions")]
pub mod functions;
#[cfg(feature = "mika")]
pub mod mika;
pub mod program;
pub mod stdlib;
pub mod types;
pub use self::error::*;
pub use self::kind::*;
pub use self::nodes::*;
pub use self::structures::*;
pub use self::value::*;
#[cfg(feature = "functions")]
pub use self::functions::*;
#[cfg(feature = "mika")]
pub use self::mika::*;
pub use self::program::*;
pub use self::stdlib::*;
pub use self::types::*;
// Mech Source Code
// ---------------------------------------------------------------------------
#[cfg(feature = "functions")]
inventory::collect!(FunctionDescriptor);
#[cfg(feature = "functions")]
inventory::collect!(FunctionCompilerDescriptor);
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MechSourceCode {
String(String),
Tree(Program),
Html(String),
ByteCode(Vec<u8>),
Program(Vec<MechSourceCode>),
Image(String,Vec<u8>),
}
impl MechSourceCode {
pub fn to_string(&self) -> String {
match self {
MechSourceCode::ByteCode(bc) => {
#[cfg(feature = "program")]
match ParsedProgram::from_bytes(bc) {
Ok(program) => {
format!("{:#?}",program)
},
Err(e) => return format!("Error parsing bytecode: {:?}", e),
}
#[cfg(not(feature = "program"))]
format!("{:#?}", bc)
}
MechSourceCode::Image(extension,img) => {
format!("Image (.{}) with {} bytes", extension, img.len())
}
MechSourceCode::String(s) => s.clone(),
MechSourceCode::Tree(p) => todo!("Print the tree!"),
MechSourceCode::Html(h) => h.clone(),
MechSourceCode::Program(v) => v.iter().map(|c| c.to_string()).collect::<Vec<String>>().join("\n"),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct IndexedString {
pub data: Vec<char>,
pub index_map: Vec<Vec<usize>>,
pub rows: usize,
pub cols: usize,
}
impl IndexedString {
fn new(input: &str) -> Self {
let mut data = Vec::new();
let mut index_map = Vec::new();
let mut current_row = 0;
let mut current_col = 0;
index_map.push(Vec::new());
for c in input.chars() {
data.push(c);
if c == '\n' {
index_map.push(Vec::new());
current_row += 1;
current_col = 0;
} else {
index_map[current_row].push(data.len() - 1);
current_col += 1;
}
}
let rows = index_map.len();
let cols = if rows > 0 { index_map[0].len() } else { 0 };
IndexedString {
data,
index_map,
rows,
cols,
}
}
fn to_string(&self) -> String {
self.data.iter().collect()
}
fn get(&self, row: usize, col: usize) -> Option<char> {
if row < self.rows {
let rowz = &self.index_map[row];
if col < rowz.len() {
let index = self.index_map[row][col];
Some(self.data[index])
} else {
None
}
} else {
None
}
}
fn set(&mut self, row: usize, col: usize, new_char: char) -> Result<(), String> {
if row < self.rows {
let row_indices = &mut self.index_map[row];
if col < row_indices.len() {
let index = row_indices[col];
self.data[index] = new_char;
Ok(())
} else {
Err("Column index out of bounds".to_string())
}
} else {
Err("Row index out of bounds".to_string())
}
}
}
// Humanize
// ---------------------------------------------------------------------------
// Turn bytes into something more readable by humans
// Useful for visualizing register dumps, hashes, etc.
pub fn hash_chars(input: &Vec<char>) -> u64 {
seahash::hash(input.iter().map(|s| String::from(*s)).collect::<String>().as_bytes()) & 0x00FFFFFFFFFFFFFF
}
pub fn hash_bytes(input: &Vec<u8>) -> u64 {
seahash::hash(input) & 0x00FFFFFFFFFFFFFF
}
pub fn hash_str(input: &str) -> u64 {
seahash::hash(input.as_bytes()) & 0x00FFFFFFFFFFFFFF
}
pub fn emojify_bytes(bytes: &[u8]) -> String {
let start = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len() - 1);
let mut out = String::new();
for &b in &bytes[start..] {
out.push_str(EMOJILIST[b as usize]);
}
out
}
pub fn humanize_bytes(bytes: &[u8]) -> String {
let parts: Vec<&str> = bytes
.iter()
.enumerate()
.filter_map(|(ix, &b)| if ix % 2 == 1 { Some(WORDLIST[b as usize]) } else { None })
.collect();
parts.join("-")
}
pub fn emojify<T>(num: &T) -> String
where
T: Display + Copy + TryInto<u128>,
<T as TryInto<u128>>::Error: std::fmt::Debug,
{
match (*num).try_into() {
Ok(v) => {
let bytes = v.to_be_bytes();
emojify_bytes(&bytes)
}
Err(_) => format!("{}", num),
}
}
pub fn humanize<T>(num: &T) -> String
where
T: Display + Copy + TryInto<u128>,
<T as TryInto<u128>>::Error: Debug,
{
match (*num).try_into() {
Ok(v) => {
let bytes = v.to_be_bytes();
let first_non_zero = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len() - 1);
let trimmed = &bytes[first_non_zero..];
humanize_bytes(trimmed)
}
Err(_) => format!("{}", num),
}
}
pub const WORDLIST: &[&str;256] = &[
"nil", "ama", "ine", "ska", "pha", "gel", "art",
"ona", "sas", "ist", "aus", "pen", "ust", "umn",
"ado", "con", "loo", "man", "eer", "lin", "ium",
"ack", "som", "lue", "ird", "avo", "dog", "ger",
"ter", "nia", "bon", "nal", "ina", "pet", "cat",
"ing", "lie", "ken", "fee", "ola", "old", "rad",
"met", "cut", "azy", "cup", "ota", "dec", "del",
"elt", "iet", "don", "ble", "ear", "rth", "eas",
"war", "eig", "tee", "ele", "emm", "ene", "qua",
"tst", "fan", "fif", "fil", "fin", "fis", "fiv",
"flo", "for", "foo", "fou", "fot", "fox", "fre",
"fri", "fru", "gee", "gia", "glu", "fol", "gre",
"ham", "hap", "har", "haw", "hel", "hig", "hot",
"hyd", "ida", "ill", "ind", "ini", "ink", "iwa",
"and", "ite", "jer", "jig", "joh", "jul", "uly",
"kan", "ket", "kil", "kin", "kit", "lac", "lak",
"lem", "ard", "lim", "lio", "lit", "lon", "lou",
"low", "mag", "nes", "mai", "gam", "arc", "mar",
"mao", "mas", "may", "mex", "mic", "mik", "ril",
"min", "mir", "mis", "mio", "mob", "moc", "ech",
"moe", "tan", "oon", "ain", "mup", "sic", "neb",
"une", "net", "nev", "nin", "een", "nit", "nor",
"nov", "nut", "oct", "ohi", "okl", "one", "ora",
"ges", "ore", "osc", "ove", "oxy", "pap", "par",
"pey", "pip", "piz", "plu", "pot", "pri", "pur",
"que", "uqi", "qui", "red", "riv", "rob", "roi",
"rug", "sad", "sal", "sat", "sep", "sev", "eve",
"sha", "sie", "sin", "sik", "six", "sit", "sky",
"soc", "sod", "sol", "sot", "tir", "ker", "spr",
"sta", "ste", "mam", "mer", "swe", "tab", "tag",
"see", "nis", "tex", "thi", "the", "tim", "tri",
"twe", "ent", "two", "unc", "ess", "uni", "ura",
"veg", "ven", "ver", "vic", "vid", "vio", "vir",
"was", "est", "whi", "hit", "iam", "win", "his",
"wis", "olf", "wyo", "ray", "ank", "yel", "zeb",
"ulu", "fix", "gry", "hol", "jup", "lam", "pas",
"rom", "sne", "ten", "uta"];
// Emoji list is for quicker visual scanning/recognition when comparing registers
pub const EMOJILIST: &[&str; 256] = &[
"๐ต","๐ถ","๐บ","๐ฆ","๐ฆ","๐ฑ","๐","๐","๐ฆ","๐ท","๐ฎ","๐ฆฌ","๐ฏ","๐ด","๐ซ","๐ฆ","๐ฆ","๐ฆ","๐ฆ","๐","๐ฆฃ","๐ฆ","๐ฆ","๐ซ","๐","๐ญ","๐ฐ","๐ฟ๏ธ","๐ฆซ","๐ฆ","๐ฆ","๐ป","๐จ","๐ผ","๐ฆฅ","๐ฆฆ","๐ฆจ","๐ฆ","๐ฆก","๐ฆ","๐","๐ฆ","๐ง","๐๏ธ","๐ฆ
","๐ฆ","๐ฆโ๐ฅ","๐ฆ","๐ฆค","๐ฆฉ","๐ฆ","๐ฆ","๐ธ","๐","๐ข","๐ฆ","๐","๐ฒ","๐ฆ","๐ณ","๐ฌ","๐ฆญ","๐ ","๐ฆ","๐","๐ชผ","๐ฆ","๐ฆ","๐ฆ","๐ฆ","๐","๐ฆ","๐","๐","๐ชฒ","๐","๐ฆ","๐ธ๏ธ","๐ชฐ","๐ชฑ","๐ฆ ","๐ป","๐ฝ","๐ถ","๐ฎ","๐","๐ชธ","๐ชถ","๐ฆง","๐ชฟ","๐ฆข","๐ค",
"๐น","๐ณ","๐ด","๐ต","๐","๐","๐","๐","๐","๐ช","โญ","โ
","๐ง๏ธ","๐จ๏ธ","๐","โ๏ธ","โ๏ธ","โ๏ธ","๐ฅ","๐ป",
"๐","๐","๐","๐","๐โ๐ฉ","๐","๐","๐ฅญ","๐","๐","๐","๐ฅ","๐
","๐ซ","๐ฅฅ","๐ฅ","๐ฅ","๐ฝ","๐ถ๏ธ","๐ซ","๐ฅ","๐ฅฆ","๐ง","๐ง
","๐ซ","๐ฆ","๐ง","๐ฉ","๐ช","๐ฐ","๐ง","๐ฅง","๐ซ","๐ญ","๐","๐ฅจ","๐ฅฏ","๐ง","๐","๐ฟ","๐ง",
"๐ค","๐ง","๐ป","๐ท","๐ช","๐ธ","๐น","๐บ","๐ป","๐ช","๐ฅ","โ๏ธ","๐ท","๐งณ","๐ก๏ธ","๐งธ","๐งถ","๐","๐ฏ๏ธ","๐ก","๐ฆ","๐","๐๏ธ","๐ช","๐ง","๐ช","๐ฉ","โ๏ธ","โ๏ธ","๐งฐ","๐งฒ","๐ช","๐ฌ","๐ก","๐งท","๐งน","๐งบ","๐ชฃ","๐งผ","๐งฝ","๐งฏ","๐",
"โฐ","๐","๐ฉ๏ธ","๐","๐ฐ๏ธ","๐","๐ธ","โ","๐","๐","๐","๐","๐","๐","๐","๐๏ธ","๐๏ธ","๐ต","๐ฆผ","๐ฒ","๐น","๐ผ","๐","๐ฐ","๐ฆ","๐ซ","โ๏ธ","๐๏ธ","๐๏ธ","๐๏ธ","๐","๐","โ๏ธ","๐๏ธ","๐","โพ","๐","๐พ","๐ณ","โณ","โธ๏ธ","๐คฟ","๐ท","๐ฏ","๐ช","๐งฉ","๐ช
","๐จ","๐งญ","๐๏ธ","๐๏ธ","โฒ","โบ","๐ ","๐","๐งต","๐","๐ช","๐๏ธ","๐","โต"
];