Browse Source

thread AST so we can print atoms

Getty Ritter 2 years ago
parent
commit
86808855cc
1 changed files with 35 additions and 30 deletions
  1. 35 30
      src/interp.rs

+ 35 - 30
src/interp.rs

@@ -24,42 +24,47 @@ pub enum Value {
     Nil,
 }
 
-impl fmt::Display for Value {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.with_str(|s| write!(f, "{}", s))
+impl Value {
+    fn to_string(&self, ast: &ASTArena) -> String {
+        self.with_str(ast, |s| s.to_string())
     }
 }
+// impl fmt::Display for Value {
+//     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+//         self.with_str(|s| write!(f, "{}", s))
+//     }
+// }
 
 impl Value {
     /// Convert this value to a Rust integer, failing otherwise
-    fn as_num(&self) -> Result<i64, Error> {
+    fn as_num(&self, ast: &ASTArena) -> Result<i64, Error> {
         match self {
             Value::Lit(Literal::Num(n)) => Ok(*n),
-            _ => self.with_str(|s| bail!("Expected number, got {}", s)),
+            _ => self.with_str(ast, |s| bail!("Expected number, got {}", s)),
         }
     }
 
     /// Convert this value to a Rust string, failing otherwise
-    fn as_str(&self) -> Result<&str, Error> {
+    fn as_str(&self, ast: &ASTArena) -> Result<&str, Error> {
         match self {
             Value::Lit(Literal::Str(s)) => Ok(s),
-            _ => self.with_str(|s| bail!("Expected string, got {}", s)),
+            _ => self.with_str(ast, |s| bail!("Expected string, got {}", s)),
         }
     }
 
     /// Convert this value to a Rust slice, failing otherwise
-    fn as_tup(&self) -> Result<&[Thunk], Error> {
+    fn as_tup(&self, ast: &ASTArena) -> Result<&[Thunk], Error> {
         match self {
             Value::Tup(vals) => Ok(vals),
-            _ => self.with_str(|s| bail!("Expected tuple, got {}", s)),
+            _ => self.with_str(ast, |s| bail!("Expected tuple, got {}", s)),
         }
     }
 
     /// Convert this value to a closure, failing otherwise
-    fn as_closure(&self) -> Result<&Closure, Error> {
+    fn as_closure(&self, ast: &ASTArena) -> Result<&Closure, Error> {
         match self {
             Value::Closure(closure) => Ok(closure),
-            _ => self.with_str(|s| bail!("Expected tuple, got {}", s)),
+            _ => self.with_str(ast, |s| bail!("Expected tuple, got {}", s)),
         }
     }
 
@@ -68,11 +73,11 @@ impl Value {
     /// not completely forced already: indeed, this can't, since it
     /// doesn't have access to the `State`. Unevaluated fragments of
     /// the value will be printed as `#<unevaluated>`.
-    fn with_str<U>(&self, f: impl FnOnce(&str) -> U) -> U {
+    fn with_str<U>(&self, ast: &ASTArena, f: impl FnOnce(&str) -> U) -> U {
         match self {
             Value::Nil => f(""),
             Value::Lit(Literal::Str(s)) => f(s),
-            Value::Lit(Literal::Atom(s)) => f(&format!("{:?}", s)),
+            Value::Lit(Literal::Atom(s)) => f(&format!("{}", &ast[s.item])),
             Value::Lit(Literal::Num(n)) => f(&format!("{}", n)),
             Value::Tup(values) => {
                 let mut buf = String::new();
@@ -82,7 +87,7 @@ impl Value {
                         buf.push_str(", ");
                     }
                     match val {
-                        Thunk::Value(v) => buf.push_str(&v.to_string()),
+                        Thunk::Value(v) => buf.push_str(&v.to_string(ast)),
                         Thunk::Expr(..) => buf.push_str("#<unevaluated>"),
                         Thunk::Builtin(func) => buf.push_str(&format!("#<builtin {}>", func.name)),
                     }
@@ -138,9 +143,9 @@ const BUILTINS: &[BuiltinFunc] = &[
                 (args[0], args[1])
             };
             let mut buf = String::new();
-            let num = state.eval(rep, env)?.as_num()?;
+            let num = state.eval(rep, env)?.as_num(&state.ast.borrow())?;
             for _ in 0..num {
-                buf.push_str(&state.eval(expr, env)?.as_str()?.to_string());
+                buf.push_str(&state.eval(expr, env)?.as_str(&state.ast.borrow())?.to_string());
             }
             Ok(Value::Lit(Literal::Str(buf)))
         },
@@ -159,14 +164,14 @@ const BUILTINS: &[BuiltinFunc] = &[
         name: "to-upper",
         callback: &|state: &State, expr: ExprRef, env: &Env| -> Result<Value, Error> {
             let s = state.eval(expr, env)?;
-            Ok(Value::Lit(Literal::Str(s.as_str()?.to_uppercase())))
+            Ok(Value::Lit(Literal::Str(s.as_str(&state.ast.borrow())?.to_uppercase())))
         },
     },
     BuiltinFunc {
         name: "capitalize",
         callback: &|state: &State, expr: ExprRef, env: &Env| -> Result<Value, Error> {
             let s = state.eval(expr, env)?;
-            Ok(Value::Lit(Literal::Str(titlecase::titlecase(s.as_str()?))))
+            Ok(Value::Lit(Literal::Str(titlecase::titlecase(s.as_str(&state.ast.borrow())?))))
 
         },
     },
@@ -174,17 +179,17 @@ const BUILTINS: &[BuiltinFunc] = &[
         name: "to-lower",
         callback: &|state: &State, expr: ExprRef, env: &Env| -> Result<Value, Error> {
             let s = state.eval(expr, env)?;
-            Ok(Value::Lit(Literal::Str(s.as_str()?.to_lowercase())))
+            Ok(Value::Lit(Literal::Str(s.as_str(&state.ast.borrow())?.to_lowercase())))
         },
     },
     BuiltinFunc {
         name: "concat",
         callback: &|state: &State, expr: ExprRef, env: &Env| -> Result<Value, Error> {
             let val = state.eval(expr, env)?;
-            let tup = val.as_tup()?;
+            let tup = val.as_tup(&state.ast.borrow())?;
             let mut contents = Vec::new();
             for elem in tup {
-                for th in state.hnf(elem)?.as_tup()? {
+                for th in state.hnf(elem)?.as_tup(&state.ast.borrow())? {
                     contents.push(th.clone());
                 }
             }
@@ -195,15 +200,15 @@ const BUILTINS: &[BuiltinFunc] = &[
         name: "tuple-fold",
         callback: &|state: &State, expr: ExprRef, env: &Env| -> Result<Value, Error> {
             let val = state.eval(expr, env)?;
-            let args = val.as_tup()?;
+            let args = val.as_tup(&state.ast.borrow())?;
             if let [func, init, tup] = args {
                 let func = state.hnf(func)?;
                 let tup = state.hnf(tup)?;
 
                 let mut result = init.clone();
-                for t in tup.as_tup()? {
-                    let partial = state.eval_closure(func.as_closure()?, result)?;
-                    result = Thunk::Value(state.eval_closure(partial.as_closure()?, t.clone())?);
+                for t in tup.as_tup(&state.ast.borrow())? {
+                    let partial = state.eval_closure(func.as_closure(&state.ast.borrow())?, result)?;
+                    result = Thunk::Value(state.eval_closure(partial.as_closure(&state.ast.borrow())?, t.clone())?);
                 }
 
                 state.hnf(&result)
@@ -405,7 +410,7 @@ impl State {
                 if let Ok(expr) = expr {
                     let val = self.eval(expr, &None)?;
                     let val = self.force(val)?;
-                    writeln!(io::stdout(), "{}", val.to_string())?;
+                    writeln!(io::stdout(), "{}", val.to_string(&self.ast.borrow()))?;
                 } else {
                     bail!("{:?}", err);
                 }
@@ -442,7 +447,7 @@ impl State {
             Stmt::Puts(expr) => {
                 let val = self.eval(*expr, &None)?;
                 let val = self.force(val)?;
-                writeln!(output, "{}", val.to_string()).unwrap();
+                writeln!(output, "{}", val.to_string(&self.ast.borrow())).unwrap();
             }
 
             // Look up the provided name, and if it's not already
@@ -577,7 +582,7 @@ impl State {
                     for expr in cat {
                         let val = self.eval(*expr, env)?;
                         let val = self.force(val)?;
-                        buf.push_str(&val.to_string());
+                        buf.push_str(&val.to_string(&self.ast.borrow()));
                     }
                     Ok(Value::Lit(Literal::Str(buf)))
                 }
@@ -607,8 +612,8 @@ impl State {
             // for a range, choose randomly between the start and end
             // expressions
             Expr::Range(from, to) => {
-                let from = self.eval(*from, env)?.as_num()?;
-                let to = self.eval(*to, env)?.as_num()?;
+                let from = self.eval(*from, env)?.as_num(&self.ast.borrow())?;
+                let to = self.eval(*to, env)?.as_num(&self.ast.borrow())?;
                 Ok(Value::Lit(Literal::Num(
                     self.rand.borrow_mut().gen_range_i64(from, to+1),
                 )))