1#![cfg_attr(feature = "no_std", no_std)]
2#![allow(warnings)]
3#![allow(dead_code)]
4
5extern crate seahash;
7
8#[cfg(feature="no_std")] #[macro_use]
9extern crate alloc;
10#[cfg(not(feature = "no_std"))]
11extern crate core;
12
13#[cfg(feature="no_std")]
14use hashbrown::HashMap;
15#[cfg(not(feature = "no_std"))]
16use std::collections::HashMap;
17
18#[cfg(feature="no_std")]
19use alloc::fmt::{self, Debug, Display};
20#[cfg(not(feature = "no_std"))]
21use std::fmt::{self, Debug, Display};
22
23#[cfg(feature="no_std")]
24use alloc::vec::Vec;
25
26#[cfg(feature="no_std")]
27use fxhash::FxHasher;
28
29#[cfg(feature = "no_std")]
30use embedded_io::{self, Read, Write};
31#[cfg(not(feature = "no_std"))]
32use std::io::{self, Error as ioError, Cursor, Read, Write};
33
34#[cfg(feature = "no_std")]
35use alloc::string::{String, ToString};
36
37#[cfg(feature = "no_std")]
38use core::hash::{Hash, Hasher};
39#[cfg(not(feature = "no_std"))]
40use std::hash::{Hash, Hasher};
41
42#[cfg(feature = "no_std")]
43use alloc::boxed::Box;
44
45#[cfg(feature = "matrix")]
46extern crate nalgebra as na;
47#[cfg(feature = "pretty_print")]
48extern crate tabled;
49#[cfg(feature = "serde")] #[macro_use]
50extern crate serde_derive;
51#[cfg(feature = "serde")]
52extern crate serde;
53#[cfg(any(feature = "math_pow", feature = "f64", feature = "f32", feature = "complex", feature = "rational"))]
54extern crate num_traits;
55
56use paste::paste;
57
58#[cfg(any(feature = "math_pow", feature = "f64"))]
59use num_traits::*;
60#[cfg(feature = "rational")]
61use num_rational::Rational64;
62#[cfg(feature = "vector3")]
63use nalgebra::Vector3;
64#[cfg(feature = "vectord")]
65use nalgebra::DVector;
66#[cfg(feature = "vector2")]
67use nalgebra::Vector2;
68#[cfg(feature = "vector4")]
69use nalgebra::Vector4;
70#[cfg(feature = "row_vectord")]
71use nalgebra::RowDVector;
72#[cfg(feature = "matrix1")]
73use nalgebra::Matrix1;
74#[cfg(feature = "matrix3")]
75use nalgebra::Matrix3;
76#[cfg(feature = "matrix4")]
77use nalgebra::Matrix4;
78#[cfg(feature = "row_vector3")]
79use nalgebra::RowVector3;
80#[cfg(feature = "row_vector4")]
81use nalgebra::RowVector4;
82#[cfg(feature = "row_vector2")]
83use nalgebra::RowVector2;
84#[cfg(feature = "matrixd")]
85use nalgebra::DMatrix;
86#[cfg(feature = "matrix2x3")]
87use nalgebra::Matrix2x3;
88#[cfg(feature = "matrix3x2")]
89use nalgebra::Matrix3x2;
90#[cfg(feature = "matrix2")]
91use nalgebra::Matrix2;
92
93#[cfg(feature = "pretty_print")]
94use tabled::{
95 builder::Builder,
96 settings::{object::Rows,Panel, Span, Alignment, Modify, Style},
97 Tabled,
98};
99
100pub mod error;
101pub mod kind;
102pub mod nodes;
103pub mod structures;
104pub mod value;
105#[cfg(feature = "functions")]
106pub mod functions;
107#[cfg(feature = "mika")]
108pub mod mika;
109pub mod program;
110pub mod stdlib;
111pub mod types;
112
113pub use self::error::*;
114pub use self::kind::*;
115pub use self::nodes::*;
116pub use self::structures::*;
117pub use self::value::*;
118#[cfg(feature = "functions")]
119pub use self::functions::*;
120#[cfg(feature = "mika")]
121pub use self::mika::*;
122pub use self::program::*;
123pub use self::stdlib::*;
124pub use self::types::*;
125
126#[cfg(feature = "functions")]
130inventory::collect!(FunctionDescriptor);
131
132#[cfg(feature = "functions")]
133inventory::collect!(FunctionCompilerDescriptor);
134
135#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
136#[derive(Clone, Debug, PartialEq, Eq)]
137pub enum MechSourceCode {
138 String(String),
139 Tree(Program),
140 Html(String),
141 ByteCode(Vec<u8>),
142 Program(Vec<MechSourceCode>),
143 Image(String,Vec<u8>),
144}
145
146impl MechSourceCode {
147
148 pub fn to_string(&self) -> String {
149 match self {
150 MechSourceCode::ByteCode(bc) => {
151 #[cfg(feature = "program")]
152 match ParsedProgram::from_bytes(bc) {
153 Ok(program) => {
154 format!("{:#?}",program)
155 },
156 Err(e) => return format!("Error parsing bytecode: {:?}", e),
157 }
158 #[cfg(not(feature = "program"))]
159 format!("{:#?}", bc)
160 }
161 MechSourceCode::Image(extension,img) => {
162 format!("Image (.{}) with {} bytes", extension, img.len())
163 }
164 MechSourceCode::String(s) => s.clone(),
165 MechSourceCode::Tree(p) => todo!("Print the tree!"),
166 MechSourceCode::Html(h) => h.clone(),
167 MechSourceCode::Program(v) => v.iter().map(|c| c.to_string()).collect::<Vec<String>>().join("\n"),
168 }
169 }
170}
171
172#[derive(Clone, Debug, PartialEq, Eq)]
173pub struct IndexedString {
174 pub data: Vec<char>,
175 pub index_map: Vec<Vec<usize>>,
176 pub rows: usize,
177 pub cols: usize,
178}
179
180impl IndexedString {
181
182 fn new(input: &str) -> Self {
183 let mut data = Vec::new();
184 let mut index_map = Vec::new();
185 let mut current_row = 0;
186 let mut current_col = 0;
187 index_map.push(Vec::new());
188 for c in input.chars() {
189 data.push(c);
190 if c == '\n' {
191 index_map.push(Vec::new());
192 current_row += 1;
193 current_col = 0;
194 } else {
195 index_map[current_row].push(data.len() - 1);
196 current_col += 1;
197 }
198 }
199 let rows = index_map.len();
200 let cols = if rows > 0 { index_map[0].len() } else { 0 };
201 IndexedString {
202 data,
203 index_map,
204 rows,
205 cols,
206 }
207 }
208
209 fn to_string(&self) -> String {
210 self.data.iter().collect()
211 }
212
213 fn get(&self, row: usize, col: usize) -> Option<char> {
214 if row < self.rows {
215 let rowz = &self.index_map[row];
216 if col < rowz.len() {
217 let index = self.index_map[row][col];
218 Some(self.data[index])
219 } else {
220 None
221 }
222 } else {
223 None
224 }
225 }
226
227 fn set(&mut self, row: usize, col: usize, new_char: char) -> Result<(), String> {
228 if row < self.rows {
229 let row_indices = &mut self.index_map[row];
230 if col < row_indices.len() {
231 let index = row_indices[col];
232 self.data[index] = new_char;
233 Ok(())
234 } else {
235 Err("Column index out of bounds".to_string())
236 }
237 } else {
238 Err("Row index out of bounds".to_string())
239 }
240 }
241}
242
243pub fn hash_chars(input: &Vec<char>) -> u64 {
250 seahash::hash(input.iter().map(|s| String::from(*s)).collect::<String>().as_bytes()) & 0x00FFFFFFFFFFFFFF
251}
252
253pub fn hash_bytes(input: &Vec<u8>) -> u64 {
254 seahash::hash(input) & 0x00FFFFFFFFFFFFFF
255}
256
257pub fn hash_str(input: &str) -> u64 {
258 seahash::hash(input.as_bytes()) & 0x00FFFFFFFFFFFFFF
259}
260
261pub fn emojify_bytes(bytes: &[u8]) -> String {
262 let start = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len() - 1);
263 let mut out = String::new();
264 for &b in &bytes[start..] {
265 out.push_str(EMOJILIST[b as usize]);
266 }
267 out
268}
269
270pub fn humanize_bytes(bytes: &[u8]) -> String {
271 let parts: Vec<&str> = bytes
272 .iter()
273 .enumerate()
274 .filter_map(|(ix, &b)| if ix % 2 == 1 { Some(WORDLIST[b as usize]) } else { None })
275 .collect();
276 parts.join("-")
277}
278
279pub fn emojify<T>(num: &T) -> String
280where
281 T: Display + Copy + TryInto<u128>,
282 <T as TryInto<u128>>::Error: std::fmt::Debug,
283{
284 match (*num).try_into() {
285 Ok(v) => {
286 let bytes = v.to_be_bytes();
287 emojify_bytes(&bytes)
288 }
289 Err(_) => format!("{}", num),
290 }
291}
292
293pub fn humanize<T>(num: &T) -> String
294where
295 T: Display + Copy + TryInto<u128>,
296 <T as TryInto<u128>>::Error: Debug,
297{
298 match (*num).try_into() {
299 Ok(v) => {
300 let bytes = v.to_be_bytes();
301 let first_non_zero = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len() - 1);
302 let trimmed = &bytes[first_non_zero..];
303 humanize_bytes(trimmed)
304 }
305 Err(_) => format!("{}", num),
306}
307}
308
309pub const WORDLIST: &[&str;256] = &[
310 "nil", "ama", "ine", "ska", "pha", "gel", "art",
311 "ona", "sas", "ist", "aus", "pen", "ust", "umn",
312 "ado", "con", "loo", "man", "eer", "lin", "ium",
313 "ack", "som", "lue", "ird", "avo", "dog", "ger",
314 "ter", "nia", "bon", "nal", "ina", "pet", "cat",
315 "ing", "lie", "ken", "fee", "ola", "old", "rad",
316 "met", "cut", "azy", "cup", "ota", "dec", "del",
317 "elt", "iet", "don", "ble", "ear", "rth", "eas",
318 "war", "eig", "tee", "ele", "emm", "ene", "qua",
319 "tst", "fan", "fif", "fil", "fin", "fis", "fiv",
320 "flo", "for", "foo", "fou", "fot", "fox", "fre",
321 "fri", "fru", "gee", "gia", "glu", "fol", "gre",
322 "ham", "hap", "har", "haw", "hel", "hig", "hot",
323 "hyd", "ida", "ill", "ind", "ini", "ink", "iwa",
324 "and", "ite", "jer", "jig", "joh", "jul", "uly",
325 "kan", "ket", "kil", "kin", "kit", "lac", "lak",
326 "lem", "ard", "lim", "lio", "lit", "lon", "lou",
327 "low", "mag", "nes", "mai", "gam", "arc", "mar",
328 "mao", "mas", "may", "mex", "mic", "mik", "ril",
329 "min", "mir", "mis", "mio", "mob", "moc", "ech",
330 "moe", "tan", "oon", "ain", "mup", "sic", "neb",
331 "une", "net", "nev", "nin", "een", "nit", "nor",
332 "nov", "nut", "oct", "ohi", "okl", "one", "ora",
333 "ges", "ore", "osc", "ove", "oxy", "pap", "par",
334 "pey", "pip", "piz", "plu", "pot", "pri", "pur",
335 "que", "uqi", "qui", "red", "riv", "rob", "roi",
336 "rug", "sad", "sal", "sat", "sep", "sev", "eve",
337 "sha", "sie", "sin", "sik", "six", "sit", "sky",
338 "soc", "sod", "sol", "sot", "tir", "ker", "spr",
339 "sta", "ste", "mam", "mer", "swe", "tab", "tag",
340 "see", "nis", "tex", "thi", "the", "tim", "tri",
341 "twe", "ent", "two", "unc", "ess", "uni", "ura",
342 "veg", "ven", "ver", "vic", "vid", "vio", "vir",
343 "was", "est", "whi", "hit", "iam", "win", "his",
344 "wis", "olf", "wyo", "ray", "ank", "yel", "zeb",
345 "ulu", "fix", "gry", "hol", "jup", "lam", "pas",
346 "rom", "sne", "ten", "uta"];
347
348pub const EMOJILIST: &[&str; 256] = &[
351 "๐ต","๐ถ","๐บ","๐ฆ","๐ฆ","๐ฑ","๐","๐","๐ฆ","๐ท","๐ฎ","๐ฆฌ","๐ฏ","๐ด","๐ซ","๐ฆ","๐ฆ","๐ฆ","๐ฆ","๐","๐ฆฃ","๐ฆ","๐ฆ","๐ซ","๐","๐ญ","๐ฐ","๐ฟ๏ธ","๐ฆซ","๐ฆ","๐ฆ","๐ป","๐จ","๐ผ","๐ฆฅ","๐ฆฆ","๐ฆจ","๐ฆ","๐ฆก","๐ฆ","๐","๐ฆ","๐ง","๐๏ธ","๐ฆ
","๐ฆ","๐ฆโ๐ฅ","๐ฆ","๐ฆค","๐ฆฉ","๐ฆ","๐ฆ","๐ธ","๐","๐ข","๐ฆ","๐","๐ฒ","๐ฆ","๐ณ","๐ฌ","๐ฆญ","๐ ","๐ฆ","๐","๐ชผ","๐ฆ","๐ฆ","๐ฆ","๐ฆ","๐","๐ฆ","๐","๐","๐ชฒ","๐","๐ฆ","๐ธ๏ธ","๐ชฐ","๐ชฑ","๐ฆ ","๐ป","๐ฝ","๐ถ","๐ฎ","๐","๐ชธ","๐ชถ","๐ฆง","๐ชฟ","๐ฆข","๐ค",
352 "๐น","๐ณ","๐ด","๐ต","๐","๐","๐","๐","๐","๐ช","โญ","โ
","๐ง๏ธ","๐จ๏ธ","๐","โ๏ธ","โ๏ธ","โ๏ธ","๐ฅ","๐ป",
353 "๐","๐","๐","๐","๐โ๐ฉ","๐","๐","๐ฅญ","๐","๐","๐","๐ฅ","๐
","๐ซ","๐ฅฅ","๐ฅ","๐ฅ","๐ฝ","๐ถ๏ธ","๐ซ","๐ฅ","๐ฅฆ","๐ง","๐ง
","๐ซ","๐ฆ","๐ง","๐ฉ","๐ช","๐ฐ","๐ง","๐ฅง","๐ซ","๐ญ","๐","๐ฅจ","๐ฅฏ","๐ง","๐","๐ฟ","๐ง",
354 "๐ค","๐ง","๐ป","๐ท","๐ช","๐ธ","๐น","๐บ","๐ป","๐ช","๐ฅ","โ๏ธ","๐ท","๐งณ","๐ก๏ธ","๐งธ","๐งถ","๐","๐ฏ๏ธ","๐ก","๐ฆ","๐","๐๏ธ","๐ช","๐ง","๐ช","๐ฉ","โ๏ธ","โ๏ธ","๐งฐ","๐งฒ","๐ช","๐ฌ","๐ก","๐งท","๐งน","๐งบ","๐ชฃ","๐งผ","๐งฝ","๐งฏ","๐",
355 "โฐ","๐","๐ฉ๏ธ","๐","๐ฐ๏ธ","๐","๐ธ","โ","๐","๐","๐","๐","๐","๐","๐","๐๏ธ","๐๏ธ","๐ต","๐ฆผ","๐ฒ","๐น","๐ผ","๐","๐ฐ","๐ฆ","๐ซ","โ๏ธ","๐๏ธ","๐๏ธ","๐๏ธ","๐","๐","โ๏ธ","๐๏ธ","๐","โพ","๐","๐พ","๐ณ","โณ","โธ๏ธ","๐คฟ","๐ท","๐ฏ","๐ช","๐งฉ","๐ช
","๐จ","๐งญ","๐๏ธ","๐๏ธ","โฒ","โบ","๐ ","๐","๐งต","๐","๐ช","๐๏ธ","๐","โต"
356];