interp.rs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. use crate::ast::*;
  2. use rand::Rng;
  3. use std::collections::HashMap;
  4. use std::fmt;
  5. macro_rules! bail {
  6. ($fmt:expr) => { return Err(Error { message: format!($fmt), }) };
  7. ($fmt:expr, $($e:expr),*) => { return Err(Error { message: format!($fmt, $($e),*), }) }
  8. }
  9. #[derive(Debug)]
  10. pub enum Value {
  11. Lit(Literal),
  12. Tup(Vec<Value>),
  13. Builtin(&'static BuiltinFunc),
  14. }
  15. impl Value {
  16. fn as_num(&self) -> Result<i64, Error> {
  17. match self {
  18. Value::Lit(Literal::Num(n)) => Ok(*n),
  19. _ => self.with_str(|s| bail!("Expected number, got {}", s)),
  20. }
  21. }
  22. fn as_str(&self) -> Result<&str, Error> {
  23. match self {
  24. Value::Lit(Literal::Str(s)) => Ok(s),
  25. _ => self.with_str(|s| bail!("Expected string, got {}", s)),
  26. }
  27. }
  28. fn with_str<U>(&self, f: impl FnOnce(&str) -> U) -> U {
  29. match self {
  30. Value::Lit(Literal::Str(s)) => f(s),
  31. Value::Lit(Literal::Atom(s)) => f(s),
  32. Value::Lit(Literal::Num(n)) => f(&format!("{}", n)),
  33. Value::Tup(values) => {
  34. let mut buf = String::new();
  35. buf.push('<');
  36. for (i, val) in values.iter().enumerate() {
  37. if i > 0 {
  38. buf.push_str(", ");
  39. }
  40. buf.push_str(&val.to_string());
  41. }
  42. buf.push('>');
  43. f(&buf)
  44. }
  45. Value::Builtin(func) => f(&format!("#<builtin {}>", func.name)),
  46. }
  47. }
  48. }
  49. impl fmt::Display for Value {
  50. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  51. self.with_str(|s| write!(f, "{}", s))
  52. }
  53. }
  54. pub struct BuiltinFunc {
  55. name: &'static str,
  56. callback: &'static dyn Fn(&mut State, &Expr) -> Result<Value, Error>,
  57. }
  58. #[derive(Debug)]
  59. pub struct Error {
  60. message: String,
  61. }
  62. impl fmt::Display for Error {
  63. fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
  64. write!(fmt, "{}", self.message)
  65. }
  66. }
  67. impl std::error::Error for Error {}
  68. const BUILTINS: &[BuiltinFunc] = &[
  69. BuiltinFunc {
  70. name: "rep",
  71. callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
  72. let args = match expr {
  73. Expr::Tup(tup) => tup,
  74. _ => bail!("`rep`: expected tuple"),
  75. };
  76. if args.len() != 2 {
  77. bail!("`rep`: expected two arguments, got {}", args.len())
  78. }
  79. let num = state.eval(&args[0])?.as_num()?;
  80. let rep = (0..num).map(|_| args[1].clone()).collect();
  81. state.eval(&Expr::Cat(rep))
  82. },
  83. },
  84. BuiltinFunc {
  85. name: "length",
  86. callback: &|_state: &mut State, expr: &Expr| -> Result<Value, Error> {
  87. let args = match expr {
  88. Expr::Tup(tup) => tup,
  89. _ => bail!("`length`: expected tuple"),
  90. };
  91. Ok(Value::Lit(Literal::Num(args.len() as i64)))
  92. },
  93. },
  94. BuiltinFunc {
  95. name: "to-upper",
  96. callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
  97. let s = state.eval(expr)?;
  98. Ok(Value::Lit(Literal::Str(s.as_str()?.to_uppercase())))
  99. },
  100. },
  101. BuiltinFunc {
  102. name: "to-lower",
  103. callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
  104. let s = state.eval(expr)?;
  105. Ok(Value::Lit(Literal::Str(s.as_str()?.to_lowercase())))
  106. },
  107. },
  108. ];
  109. impl fmt::Debug for BuiltinFunc {
  110. fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
  111. writeln!(fmt, "BuiltinFunc {{ name: {:?}, ... }}", self.name)
  112. }
  113. }
  114. enum NamedItem {
  115. Expr(Expr),
  116. Builtin(&'static BuiltinFunc),
  117. }
  118. pub struct State {
  119. scope: HashMap<String, NamedItem>,
  120. rand: rand::rngs::ThreadRng,
  121. }
  122. impl Default for State {
  123. fn default() -> State {
  124. Self::new()
  125. }
  126. }
  127. impl State {
  128. pub fn new() -> State {
  129. let mut s = State {
  130. scope: HashMap::new(),
  131. rand: rand::thread_rng(),
  132. };
  133. for builtin in BUILTINS {
  134. s.scope
  135. .insert(builtin.name.to_string(), NamedItem::Builtin(builtin));
  136. }
  137. s
  138. }
  139. pub fn autocomplete(&self, fragment: &str, at_beginning: bool) -> Vec<String> {
  140. let mut possibilities = Vec::new();
  141. for name in self.scope.keys() {
  142. if name.starts_with(fragment) {
  143. possibilities.push(name.clone());
  144. }
  145. }
  146. if at_beginning && "puts".starts_with(fragment) {
  147. possibilities.push("puts ".to_owned());
  148. }
  149. possibilities
  150. }
  151. pub fn execute(&mut self, stmt: &Stmt) -> Result<(), Error> {
  152. match stmt {
  153. Stmt::Puts(expr) => {
  154. let val = self.eval(expr)?;
  155. println!("{}", val.to_string());
  156. }
  157. Stmt::Assn(name, expr) => {
  158. self.scope
  159. .insert(name.to_string(), NamedItem::Expr(expr.clone()));
  160. }
  161. Stmt::LitAssn(name, strs) => {
  162. let choices = strs
  163. .iter()
  164. .map(|s| Choice {
  165. weight: None,
  166. value: Expr::Lit(Literal::Str(s.clone())),
  167. })
  168. .collect();
  169. self.scope
  170. .insert(name.to_string(), NamedItem::Expr(Expr::Chc(choices)));
  171. }
  172. _ => bail!("unimplemented"),
  173. }
  174. Ok(())
  175. }
  176. fn eval(&mut self, expr: &Expr) -> Result<Value, Error> {
  177. match expr {
  178. Expr::Lit(l) => Ok(Value::Lit(l.clone())),
  179. Expr::Var(v) => {
  180. let e = match self.scope.get(v) {
  181. Some(NamedItem::Expr(e)) => e.clone(),
  182. Some(NamedItem::Builtin(b)) => return Ok(Value::Builtin(b)),
  183. None => bail!("no such thing: {}", v),
  184. };
  185. self.eval(&e)
  186. }
  187. Expr::Cat(cat) => {
  188. if cat.len() == 1 {
  189. self.eval(&cat[0])
  190. } else {
  191. let mut buf = String::new();
  192. for expr in cat {
  193. let val = self.eval(expr)?;
  194. buf.push_str(&val.to_string());
  195. }
  196. Ok(Value::Lit(Literal::Str(buf)))
  197. }
  198. }
  199. Expr::Chc(choices) => {
  200. if choices.len() == 1 {
  201. self.eval(&choices[0].value)
  202. } else {
  203. self.choose(choices)
  204. }
  205. }
  206. Expr::Tup(values) => Ok(Value::Tup(
  207. values
  208. .iter()
  209. .map(|v| self.eval(v))
  210. .collect::<Result<Vec<Value>, Error>>()?,
  211. )),
  212. Expr::Ap(fun, arg) => match self.eval(fun)? {
  213. Value::Builtin(builtin) => (builtin.callback)(self, arg),
  214. _ => bail!("bad function: {:?}", fun),
  215. },
  216. Expr::Range(from, to) => {
  217. let from = self.eval(from)?.as_num()?;
  218. let to = self.eval(to)?.as_num()?;
  219. Ok(Value::Lit(Literal::Num(self.rand.gen_range(from..=to))))
  220. }
  221. _ => bail!("unimplemented: {:?}", expr),
  222. }
  223. }
  224. fn choose(&mut self, choices: &[Choice]) -> Result<Value, Error> {
  225. let max = choices.iter().map(Choice::weight).sum();
  226. let mut choice = self.rand.gen_range(0..max);
  227. for ch in choices {
  228. if choice < ch.weight() {
  229. return self.eval(&ch.value);
  230. }
  231. choice -= ch.weight();
  232. }
  233. bail!("unreachable")
  234. }
  235. }