interp.rs 5.6 KB

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