interp.rs 6.2 KB

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