interp.rs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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 Fn(&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_str("<");
  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_str(">");
  43. f(&buf)
  44. }
  45. Value::Builtin(func) =>
  46. f(&format!("#<builtin {}>", func.name)),
  47. }
  48. }
  49. fn to_string(&self) -> String {
  50. self.with_str(|s| s.to_string())
  51. }
  52. }
  53. pub struct BuiltinFunc {
  54. name: &'static str,
  55. callback: &'static dyn Fn(&mut State, &Expr) -> Result<Value, Error>,
  56. }
  57. #[derive(Debug)]
  58. pub struct Error {
  59. message: String,
  60. }
  61. impl fmt::Display for Error {
  62. fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
  63. write!(fmt, "{}", self.message)
  64. }
  65. }
  66. impl std::error::Error for Error {}
  67. const BUILTINS: &[BuiltinFunc] = &[
  68. BuiltinFunc {
  69. name: "rep",
  70. callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
  71. let args = match expr {
  72. Expr::Tup(tup) => tup,
  73. _ => bail!("`rep`: expected tuple"),
  74. };
  75. if args.len() != 2 {
  76. bail!("`rep`: expected two arguments, got {}", args.len())
  77. }
  78. let num = state.eval(&args[0])?.as_num()?;
  79. let rep = (0..num).map(|_| args[1].clone()).collect();
  80. state.eval(&Expr::Cat(rep))
  81. }
  82. },
  83. BuiltinFunc {
  84. name: "length",
  85. callback: &|_state: &mut State, expr: &Expr| -> Result<Value, Error> {
  86. let args = match expr {
  87. Expr::Tup(tup) => tup,
  88. _ => bail!("`length`: expected tuple"),
  89. };
  90. Ok(Value::Lit(Literal::Num(args.len() as i64)))
  91. }
  92. },
  93. BuiltinFunc {
  94. name: "to-upper",
  95. callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
  96. let s = state.eval(expr)?;
  97. Ok(Value::Lit(Literal::Str(s.as_str()?.to_uppercase())))
  98. }
  99. },
  100. BuiltinFunc {
  101. name: "to-lower",
  102. callback: &|state: &mut State, expr: &Expr| -> Result<Value, Error> {
  103. let s = state.eval(expr)?;
  104. Ok(Value::Lit(Literal::Str(s.as_str()?.to_lowercase())))
  105. }
  106. },
  107. ];
  108. impl fmt::Debug for BuiltinFunc {
  109. fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
  110. writeln!(fmt, "BuiltinFunc {{ name: {:?}, ... }}", self.name)
  111. }
  112. }
  113. enum NamedItem {
  114. Expr(Expr),
  115. Builtin(&'static BuiltinFunc),
  116. }
  117. pub struct State {
  118. scope: HashMap<String, NamedItem>,
  119. rand: rand::rngs::ThreadRng,
  120. }
  121. impl State {
  122. pub fn new() -> State {
  123. let mut s = State {
  124. scope: HashMap::new(),
  125. rand: rand::thread_rng(),
  126. };
  127. for builtin in BUILTINS {
  128. s.scope.insert(
  129. builtin.name.to_string(),
  130. NamedItem::Builtin(builtin),
  131. );
  132. }
  133. s
  134. }
  135. pub fn execute(&mut self, stmt: &Stmt) -> Result<(), Error> {
  136. Ok(match stmt {
  137. Stmt::Puts(expr) => {
  138. let val = self.eval(expr)?;
  139. println!("{}", val.to_string());
  140. }
  141. Stmt::Assn(name, expr) => {
  142. self.scope.insert(name.to_string(), NamedItem::Expr(expr.clone()));
  143. }
  144. Stmt::LitAssn(name, strs) => {
  145. let choices = strs.iter().map(|s| Choice {
  146. weight: None,
  147. value: Expr::Lit(Literal::Str(s.clone())),
  148. }).collect();
  149. self.scope.insert(name.to_string(), NamedItem::Expr(Expr::Chc(choices)));
  150. }
  151. _ => bail!("unimplemented"),
  152. })
  153. }
  154. fn eval(&mut self, expr: &Expr) -> Result<Value, Error> {
  155. match expr {
  156. Expr::Lit(l) => Ok(Value::Lit(l.clone())),
  157. Expr::Var(v) => {
  158. let e = match self.scope.get(v) {
  159. Some(NamedItem::Expr(e)) =>
  160. e.clone(),
  161. Some(NamedItem::Builtin(b)) =>
  162. return Ok(Value::Builtin(b)),
  163. None =>
  164. bail!("no such thing: {}", v),
  165. };
  166. self.eval(&e)
  167. }
  168. Expr::Cat(cat) => {
  169. if cat.len() == 1 {
  170. self.eval(&cat[0])
  171. } else {
  172. let mut buf = String::new();
  173. for expr in cat {
  174. let val = self.eval(expr)?;
  175. buf.push_str(&val.to_string());
  176. }
  177. Ok(Value::Lit(Literal::Str(buf)))
  178. }
  179. }
  180. Expr::Chc(choices) => {
  181. if choices.len() == 1 {
  182. self.eval(&choices[0].value)
  183. } else {
  184. self.choose(choices)
  185. }
  186. }
  187. Expr::Tup(values) =>
  188. Ok(Value::Tup(values.iter().map(|v| self.eval(v)).collect::<Result<Vec<Value>, Error>>()?)),
  189. Expr::Ap(fun, arg) => {
  190. match self.eval(fun)? {
  191. Value::Builtin(builtin) => (builtin.callback)(self, arg),
  192. _ => bail!("bad function: {:?}", fun),
  193. }
  194. }
  195. Expr::Range(from, to) => {
  196. let from = self.eval(from)?.as_num()?;
  197. let to = self.eval(to)?.as_num()?;
  198. Ok(Value::Lit(Literal::Num(self.rand.gen_range(from..=to))))
  199. }
  200. _ => bail!("unimplemented: {:?}", expr),
  201. }
  202. }
  203. fn choose(&mut self, choices: &[Choice]) -> Result<Value, Error> {
  204. let max = choices.iter().map(Choice::weight).sum();
  205. let mut choice = self.rand.gen_range(0..max);
  206. for ch in choices {
  207. if choice < ch.weight() {
  208. return self.eval(&ch.value);
  209. }
  210. choice -= ch.weight();
  211. }
  212. bail!("unreachable")
  213. }
  214. }