expr.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use crate::{
  19. error::{Error, Result},
  20. //prop::{Property, PropertySubType, PropertyType, PropertySExprValue},
  21. };
  22. use darkfi_serial::{Decodable, Encodable, ReadExt, SerialDecodable, SerialEncodable};
  23. use std::io::{Read, Write};
  24. #[derive(Clone, Debug, PartialEq, SerialEncodable, SerialDecodable)]
  25. pub enum SExprVal {
  26. Null,
  27. Bool(bool),
  28. Uint32(u32),
  29. Float32(f32),
  30. Str(String),
  31. }
  32. impl SExprVal {
  33. fn is_null(&self) -> bool {
  34. match self {
  35. Self::Null => true,
  36. _ => false,
  37. }
  38. }
  39. fn is_bool(&self) -> bool {
  40. match self {
  41. Self::Bool(_) => true,
  42. _ => false,
  43. }
  44. }
  45. fn is_u32(&self) -> bool {
  46. match self {
  47. Self::Uint32(_) => true,
  48. _ => false,
  49. }
  50. }
  51. fn is_f32(&self) -> bool {
  52. match self {
  53. Self::Float32(_) => true,
  54. _ => false,
  55. }
  56. }
  57. fn is_str(&self) -> bool {
  58. match self {
  59. Self::Str(_) => true,
  60. _ => false,
  61. }
  62. }
  63. fn as_bool(&self) -> Result<bool> {
  64. match self {
  65. Self::Bool(v) => Ok(*v),
  66. _ => Err(Error::PropertyWrongType),
  67. }
  68. }
  69. pub fn as_u32(&self) -> Result<u32> {
  70. match self {
  71. Self::Uint32(v) => Ok(*v),
  72. _ => Err(Error::PropertyWrongType),
  73. }
  74. }
  75. pub fn as_f32(&self) -> Result<f32> {
  76. match self {
  77. Self::Float32(v) => Ok(*v),
  78. _ => Err(Error::PropertyWrongType),
  79. }
  80. }
  81. fn as_str(&self) -> Result<String> {
  82. match self {
  83. Self::Str(v) => Ok(v.clone()),
  84. _ => Err(Error::PropertyWrongType),
  85. }
  86. }
  87. pub fn coerce_f32(&self) -> Result<f32> {
  88. match self {
  89. Self::Uint32(v) => Ok(*v as f32),
  90. Self::Float32(v) => Ok(*v),
  91. _ => Err(Error::PropertyWrongType),
  92. }
  93. }
  94. }
  95. #[derive(Debug, PartialEq)]
  96. pub struct SExprMachine<'a> {
  97. pub globals: Vec<(String, SExprVal)>,
  98. pub stmts: &'a SExprCode,
  99. }
  100. // Each item is a statement
  101. pub type SExprCode = Vec<Op>;
  102. #[derive(Debug, PartialEq)]
  103. pub enum Op {
  104. Null,
  105. Add((Box<Op>, Box<Op>)),
  106. Sub((Box<Op>, Box<Op>)),
  107. Mul((Box<Op>, Box<Op>)),
  108. Div((Box<Op>, Box<Op>)),
  109. ConstBool(bool),
  110. ConstUint32(u32),
  111. ConstFloat32(f32),
  112. ConstStr(String),
  113. LoadVar(String),
  114. //StoreVar((String, Box<Op>)),
  115. Min((Box<Op>, Box<Op>)),
  116. Max((Box<Op>, Box<Op>)),
  117. IsEqual((Box<Op>, Box<Op>)),
  118. LessThan((Box<Op>, Box<Op>)),
  119. Float32ToUint32(Box<Op>),
  120. }
  121. impl<'a> SExprMachine<'a> {
  122. pub fn call(&self) -> Result<SExprVal> {
  123. if self.stmts.is_empty() {
  124. return Ok(SExprVal::Null)
  125. }
  126. for i in 0..(self.stmts.len() - 1) {
  127. self.eval(&self.stmts[i])?;
  128. }
  129. self.eval(self.stmts.last().unwrap())
  130. }
  131. fn eval(&self, op: &Op) -> Result<SExprVal> {
  132. match op {
  133. Op::Null => Ok(SExprVal::Null),
  134. Op::Add((lhs, rhs)) => self.add(lhs, rhs),
  135. Op::Sub((lhs, rhs)) => self.sub(lhs, rhs),
  136. Op::Mul((lhs, rhs)) => self.mul(lhs, rhs),
  137. Op::Div((lhs, rhs)) => self.div(lhs, rhs),
  138. Op::ConstBool(val) => Ok(SExprVal::Bool(*val)),
  139. Op::ConstUint32(val) => Ok(SExprVal::Uint32(*val)),
  140. Op::ConstFloat32(val) => Ok(SExprVal::Float32(*val)),
  141. Op::ConstStr(val) => Ok(SExprVal::Str(val.clone())),
  142. Op::LoadVar(var) => self.load_var(var),
  143. //Op::StoreVar((var, val)) => self.store_var(var, val),
  144. Op::Min((lhs, rhs)) => self.min(lhs, rhs),
  145. Op::Max((lhs, rhs)) => self.max(lhs, rhs),
  146. Op::IsEqual((lhs, rhs)) => self.is_equal(lhs, rhs),
  147. Op::LessThan((lhs, rhs)) => self.less_than(lhs, rhs),
  148. Op::Float32ToUint32(val) => self.float32_to_uint32(val),
  149. }
  150. }
  151. fn add(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  152. let lhs = self.eval(lhs)?;
  153. let rhs = self.eval(rhs)?;
  154. if lhs.is_u32() && rhs.is_u32() {
  155. return Ok(SExprVal::Uint32(lhs.as_u32().unwrap() + rhs.as_u32().unwrap()))
  156. }
  157. let lhs = lhs.coerce_f32()?;
  158. let rhs = rhs.coerce_f32()?;
  159. Ok(SExprVal::Float32(lhs + rhs))
  160. }
  161. fn sub(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  162. let lhs = self.eval(lhs)?;
  163. let rhs = self.eval(rhs)?;
  164. if lhs.is_u32() && rhs.is_u32() {
  165. return Ok(SExprVal::Uint32(lhs.as_u32().unwrap() - rhs.as_u32().unwrap()))
  166. }
  167. let lhs = lhs.coerce_f32()?;
  168. let rhs = rhs.coerce_f32()?;
  169. Ok(SExprVal::Float32(lhs - rhs))
  170. }
  171. fn mul(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  172. let lhs = self.eval(lhs)?;
  173. let rhs = self.eval(rhs)?;
  174. if lhs.is_u32() && rhs.is_u32() {
  175. return Ok(SExprVal::Uint32(lhs.as_u32().unwrap() * rhs.as_u32().unwrap()))
  176. }
  177. let lhs = lhs.coerce_f32()?;
  178. let rhs = rhs.coerce_f32()?;
  179. Ok(SExprVal::Float32(lhs * rhs))
  180. }
  181. fn div(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  182. let lhs = self.eval(lhs)?;
  183. let rhs = self.eval(rhs)?;
  184. // Always coerce
  185. let lhs = lhs.coerce_f32()?;
  186. let rhs = rhs.coerce_f32()?;
  187. Ok(SExprVal::Float32(lhs / rhs))
  188. }
  189. fn load_var(&self, var: &str) -> Result<SExprVal> {
  190. for (name, val) in &self.globals {
  191. if name == var {
  192. return Ok(val.clone())
  193. }
  194. }
  195. Err(Error::SExprGlobalNotFound)
  196. }
  197. //fn store_var(&mut self, var, val) {
  198. //}
  199. fn min(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  200. let lhs = self.eval(lhs)?;
  201. let rhs = self.eval(rhs)?;
  202. if lhs.is_u32() && rhs.is_u32() {
  203. let lhs = lhs.as_u32().unwrap();
  204. let rhs = rhs.as_u32().unwrap();
  205. let min = if lhs < rhs { lhs } else { rhs };
  206. return Ok(SExprVal::Uint32(min))
  207. }
  208. let lhs = lhs.coerce_f32()?;
  209. let rhs = rhs.coerce_f32()?;
  210. let min = if lhs < rhs { lhs } else { rhs };
  211. Ok(SExprVal::Float32(min))
  212. }
  213. fn max(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  214. let lhs = self.eval(lhs)?;
  215. let rhs = self.eval(rhs)?;
  216. if lhs.is_u32() && rhs.is_u32() {
  217. let lhs = lhs.as_u32().unwrap();
  218. let rhs = rhs.as_u32().unwrap();
  219. let max = if lhs > rhs { lhs } else { rhs };
  220. return Ok(SExprVal::Uint32(max))
  221. }
  222. let lhs = lhs.coerce_f32()?;
  223. let rhs = rhs.coerce_f32()?;
  224. let max = if lhs > rhs { lhs } else { rhs };
  225. Ok(SExprVal::Float32(max))
  226. }
  227. fn is_equal(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  228. let lhs = self.eval(lhs)?;
  229. let rhs = self.eval(rhs)?;
  230. if lhs.is_u32() && rhs.is_u32() {
  231. return Ok(SExprVal::Bool(lhs.as_u32().unwrap() == rhs.as_u32().unwrap()))
  232. }
  233. let lhs = lhs.coerce_f32()?;
  234. let rhs = rhs.coerce_f32()?;
  235. let is_equal = (lhs - rhs).abs() < f32::EPSILON;
  236. Ok(SExprVal::Bool(is_equal))
  237. }
  238. fn less_than(&self, lhs: &Op, rhs: &Op) -> Result<SExprVal> {
  239. let lhs = self.eval(lhs)?;
  240. let rhs = self.eval(rhs)?;
  241. if lhs.is_u32() && rhs.is_u32() {
  242. return Ok(SExprVal::Bool(lhs.as_u32().unwrap() < rhs.as_u32().unwrap()))
  243. }
  244. let lhs = lhs.coerce_f32()?;
  245. let rhs = rhs.coerce_f32()?;
  246. Ok(SExprVal::Bool(lhs < rhs))
  247. }
  248. fn float32_to_uint32(&self, val: &Op) -> Result<SExprVal> {
  249. let val = self.eval(val)?;
  250. if val.is_u32() {
  251. return Ok(SExprVal::Uint32(val.as_u32()?))
  252. }
  253. Ok(SExprVal::Uint32(val.as_f32()? as u32))
  254. }
  255. }
  256. impl Encodable for Op {
  257. fn encode<S: Write>(&self, s: &mut S) -> std::result::Result<usize, std::io::Error> {
  258. let mut len = 0;
  259. match self {
  260. Self::Null => {
  261. len += 0u8.encode(s)?;
  262. }
  263. Self::Add((lhs, rhs)) => {
  264. len += 1u8.encode(s)?;
  265. len += lhs.encode(s)?;
  266. len += rhs.encode(s)?;
  267. }
  268. Self::Sub((lhs, rhs)) => {
  269. len += 2u8.encode(s)?;
  270. len += lhs.encode(s)?;
  271. len += rhs.encode(s)?;
  272. }
  273. Self::Mul((lhs, rhs)) => {
  274. len += 3u8.encode(s)?;
  275. len += lhs.encode(s)?;
  276. len += rhs.encode(s)?;
  277. }
  278. Self::Div((lhs, rhs)) => {
  279. len += 4u8.encode(s)?;
  280. len += lhs.encode(s)?;
  281. len += rhs.encode(s)?;
  282. }
  283. Self::ConstBool(val) => {
  284. len += 5u8.encode(s)?;
  285. len += val.encode(s)?;
  286. }
  287. Self::ConstUint32(val) => {
  288. len += 6u8.encode(s)?;
  289. len += val.encode(s)?;
  290. }
  291. Self::ConstFloat32(val) => {
  292. len += 7u8.encode(s)?;
  293. len += val.encode(s)?;
  294. }
  295. Self::ConstStr(val) => {
  296. len += 8u8.encode(s)?;
  297. len += val.encode(s)?;
  298. }
  299. Self::LoadVar(var) => {
  300. len += 9u8.encode(s)?;
  301. len += var.encode(s)?;
  302. }
  303. // StoreVar
  304. Self::Min((lhs, rhs)) => {
  305. len += 11u8.encode(s)?;
  306. len += lhs.encode(s)?;
  307. len += rhs.encode(s)?;
  308. }
  309. Self::Max((lhs, rhs)) => {
  310. len += 12u8.encode(s)?;
  311. len += lhs.encode(s)?;
  312. len += rhs.encode(s)?;
  313. }
  314. Self::IsEqual((lhs, rhs)) => {
  315. len += 13u8.encode(s)?;
  316. len += lhs.encode(s)?;
  317. len += rhs.encode(s)?;
  318. }
  319. Self::LessThan((lhs, rhs)) => {
  320. len += 14u8.encode(s)?;
  321. len += lhs.encode(s)?;
  322. len += rhs.encode(s)?;
  323. }
  324. Self::Float32ToUint32(val) => {
  325. len += 15u8.encode(s)?;
  326. len += val.encode(s)?;
  327. }
  328. }
  329. Ok(len)
  330. }
  331. }
  332. impl Decodable for Op {
  333. fn decode<D: Read>(d: &mut D) -> std::result::Result<Self, std::io::Error> {
  334. let op_type = d.read_u8()?;
  335. let self_ = match op_type {
  336. 0 => Self::Null,
  337. 1 => Self::Add((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  338. 2 => Self::Sub((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  339. 3 => Self::Mul((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  340. 4 => Self::Div((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  341. 5 => Self::ConstBool(d.read_bool()?),
  342. 6 => Self::ConstUint32(d.read_u32()?),
  343. 7 => Self::ConstFloat32(d.read_f32()?),
  344. 8 => Self::ConstStr(String::decode(d)?),
  345. 9 => Self::LoadVar(String::decode(d)?),
  346. // StoreVar
  347. 11 => Self::Min((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  348. 12 => Self::Max((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  349. 13 => Self::IsEqual((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  350. 14 => Self::LessThan((Box::new(Self::decode(d)?), Box::new(Self::decode(d)?))),
  351. 15 => Self::Float32ToUint32(Box::new(Self::decode(d)?)),
  352. _ => return Err(std::io::Error::new(std::io::ErrorKind::Other, "Invalid Op type")),
  353. };
  354. Ok(self_)
  355. }
  356. }
  357. #[cfg(test)]
  358. mod tests {
  359. use super::*;
  360. use darkfi_serial::{deserialize, serialize};
  361. #[test]
  362. fn seval() {
  363. let machine = SExprMachine {
  364. globals: vec![
  365. ("sw".to_string(), SExprVal::Uint32(110u32)),
  366. ("sh".to_string(), SExprVal::Uint32(4u32)),
  367. ],
  368. stmts: &vec![Op::Add((
  369. Box::new(Op::ConstUint32(5)),
  370. Box::new(Op::Div((
  371. Box::new(Op::LoadVar("sw".to_string())),
  372. Box::new(Op::ConstUint32(2)),
  373. ))),
  374. ))],
  375. };
  376. assert_eq!(machine.call().unwrap(), SExprVal::Float32(60.));
  377. }
  378. #[test]
  379. fn encdec_code() {
  380. let code = Op::Add((
  381. Box::new(Op::ConstUint32(5)),
  382. Box::new(Op::Div((
  383. Box::new(Op::LoadVar("sw".to_string())),
  384. Box::new(Op::ConstUint32(2)),
  385. ))),
  386. ));
  387. let code_s = serialize(&code);
  388. let code2 = deserialize::<Op>(&code_s).unwrap();
  389. assert_eq!(code, code2);
  390. }
  391. }