about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/interpreter
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-01-14T14·44+0300
committertazjin <mail@tazj.in>2021-01-14T15·19+0000
commitfe97398fd9d1e20ad4a953e27d080721b949865a (patch)
tree9212b05097922a9e63ef16fea9be8ebaa18c952b /users/tazjin/rlox/src/interpreter
parent1ed34443d832fcfd7b683ecdcb58b0c445443def (diff)
refactor(tazjin/rlox): Thread lifetimes through interpreter r/2104
In order to store a function in the interpreter's representation of a
callable, the lifetimes used throughout rlox need to be threaded
through properly.

This is currently not optimal, for two reasons:

* following the design of the book's scanner, the source code slice
  needs to still be available at runtime. Rust makes this explicit,
  but it seems unnecessary.

* the interpreter's lifetime is now bounded to be smaller than the
  source's, which means that the REPL no longer persists state between
  evaluations

Both of these can be fixed eventually by diverging the scanner from
the book slightly, but right now that's not my priority.

Change-Id: Id0bf694541ff59795cfdea3c64a965384a49bfe2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2391
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin/rlox/src/interpreter')
-rw-r--r--users/tazjin/rlox/src/interpreter/tests.rs25
1 files changed, 17 insertions, 8 deletions
diff --git a/users/tazjin/rlox/src/interpreter/tests.rs b/users/tazjin/rlox/src/interpreter/tests.rs
index 3aaea707d64b..93a025c5e832 100644
--- a/users/tazjin/rlox/src/interpreter/tests.rs
+++ b/users/tazjin/rlox/src/interpreter/tests.rs
@@ -1,8 +1,11 @@
 use super::*;
 
+fn code(code: &str) -> Vec<char> {
+    code.chars().collect()
+}
+
 /// Evaluate a code snippet, returning a value.
-fn parse_eval(code: &str) -> Value {
-    let chars: Vec<char> = code.chars().collect();
+fn parse_eval<'a>(chars: &'a [char]) -> Value<'a> {
     let tokens = scanner::scan(&chars).expect("could not scan code");
     let program = parser::parse(tokens).expect("could not parse code");
     Interpreter::create()
@@ -12,7 +15,7 @@ fn parse_eval(code: &str) -> Value {
 
 #[test]
 fn test_if() {
-    let result = parse_eval(
+    let code = code(
         r#"
 if (42 > 23)
   "pass";
@@ -21,12 +24,15 @@ else
 "#,
     );
 
-    assert_eq!(Value::Literal(Literal::String("pass".into())), result);
+    assert_eq!(
+        Value::Literal(Literal::String("pass".into())),
+        parse_eval(&code)
+    );
 }
 
 #[test]
 fn test_scope() {
-    let result = parse_eval(
+    let code = code(
         r#"
 var result = "";
 
@@ -48,16 +54,19 @@ var c = "global c";
 
     assert_eq!(
         Value::Literal(Literal::String("inner a, outer b, global c".into())),
-        result
+        parse_eval(&code),
     );
 }
 
 #[test]
 fn test_binary_operators() {
-    assert_eq!(Value::Literal(Literal::Number(42.0)), parse_eval("40 + 2;"));
+    assert_eq!(
+        Value::Literal(Literal::Number(42.0)),
+        parse_eval(&code("40 + 2;"))
+    );
 
     assert_eq!(
         Value::Literal(Literal::String("foobar".into())),
-        parse_eval("\"foo\" + \"bar\";")
+        parse_eval(&code("\"foo\" + \"bar\";"))
     );
 }