interp.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. use crate::ast::*;
  2. use rand::Rng;
  3. use std::collections::HashMap;
  4. #[derive(Debug)]
  5. pub enum Value {
  6. Lit(Literal),
  7. Tup(Vec<Value>),
  8. }
  9. impl Value {
  10. fn to_string(&self) -> String {
  11. match self {
  12. Value::Lit(Literal::Str(s)) => s.clone(),
  13. Value::Lit(Literal::Atom(s)) => s.clone(),
  14. Value::Lit(Literal::Num(n)) => format!("{}", n),
  15. Value::Tup(values) => {
  16. let mut buf = String::new();
  17. buf.push_str("<");
  18. for (i, val) in values.iter().enumerate() {
  19. if i > 0 {
  20. buf.push_str(", ");
  21. }
  22. buf.push_str(&val.to_string());
  23. }
  24. buf.push_str(">");
  25. buf
  26. }
  27. }
  28. }
  29. }
  30. pub struct State {
  31. scope: HashMap<String, Expr>,
  32. rand: rand::rngs::ThreadRng,
  33. }
  34. impl State {
  35. pub fn new() -> State {
  36. State {
  37. scope: HashMap::new(),
  38. rand: rand::thread_rng(),
  39. }
  40. }
  41. pub fn execute(&mut self, stmt: &Stmt) {
  42. match stmt {
  43. Stmt::Puts(expr) => {
  44. let val = self.eval(expr);
  45. println!("{}", val.to_string());
  46. }
  47. Stmt::Assn(name, expr) => {
  48. self.scope.insert(name.to_string(), expr.clone());
  49. }
  50. Stmt::LitAssn(name, strs) => {
  51. let choices = strs.iter().map(|s| Choice {
  52. weight: None,
  53. value: Expr::Lit(Literal::Str(s.clone())),
  54. }).collect();
  55. self.scope.insert(name.to_string(), Expr::Chc(choices));
  56. }
  57. _ => panic!("unimplemented"),
  58. }
  59. }
  60. fn eval(&mut self, expr: &Expr) -> Value {
  61. match expr {
  62. Expr::Lit(l) => Value::Lit(l.clone()),
  63. Expr::Var(v) => {
  64. let e = if let Some(x) = self.scope.get(v) {
  65. x.clone()
  66. } else {
  67. panic!("no such thing: {}", v);
  68. };
  69. self.eval(&e)
  70. }
  71. Expr::Cat(cat) => {
  72. if cat.len() == 1 {
  73. self.eval(&cat[0])
  74. } else {
  75. let mut buf = String::new();
  76. for expr in cat {
  77. let val = self.eval(expr);
  78. buf.push_str(&val.to_string());
  79. }
  80. Value::Lit(Literal::Str(buf))
  81. }
  82. }
  83. Expr::Chc(choices) => {
  84. if choices.len() == 1 {
  85. self.eval(&choices[0].value)
  86. } else {
  87. self.choose(choices)
  88. }
  89. }
  90. Expr::Tup(values) =>
  91. Value::Tup(values.iter().map(|v| self.eval(v)).collect()),
  92. _ => panic!("unimplemented: {:?}", expr),
  93. }
  94. }
  95. fn choose(&mut self, choices: &[Choice]) -> Value {
  96. let max = choices.iter().map(Choice::weight).sum();
  97. let mut choice = self.rand.gen_range(0..max);
  98. for ch in choices {
  99. if choice < ch.weight() {
  100. return self.eval(&ch.value);
  101. }
  102. choice -= ch.weight();
  103. }
  104. panic!("unreachable")
  105. }
  106. }