about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-01-14T00·13+0300
committertazjin <mail@tazj.in>2021-01-14T00·31+0000
commit090c96eae998fd399975e85321189a136a7dbddd (patch)
tree67ae4090eb8992f8c00eb34adb6cc0bcbfa2f435
parente93a2fc48f229f7b577dad6080e3258b677e7131 (diff)
feat(tazjin/rlox): Scaffolding for builtin functions r/2095
... and adds an example builtin which returns the current epoch.

The types introduced by this, especially in the interpreter module,
are going to be used for user-defined functions, too.

Change-Id: I0364a67241e94642cde08489ac711a340e30ebe8
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2381
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
-rw-r--r--users/tazjin/rlox/src/interpreter.rs24
-rw-r--r--users/tazjin/rlox/src/interpreter/builtins.rs25
2 files changed, 49 insertions, 0 deletions
diff --git a/users/tazjin/rlox/src/interpreter.rs b/users/tazjin/rlox/src/interpreter.rs
index b59034ea97..5e2eba02d4 100644
--- a/users/tazjin/rlox/src/interpreter.rs
+++ b/users/tazjin/rlox/src/interpreter.rs
@@ -5,8 +5,32 @@ use std::collections::HashMap;
 use std::rc::Rc;
 use std::sync::RwLock;
 
+// Implementation of built-in functions.
+mod builtins;
+
 // Tree-walk interpreter
 
+// Representation of all callables, including builtins & user-defined
+// functions.
+#[derive(Clone, Debug)]
+pub enum Callable {
+    Builtin(&'static dyn builtins::Builtin),
+}
+
+impl Callable {
+    fn arity(&self) -> usize {
+        match self {
+            Callable::Builtin(builtin) => builtin.arity(),
+        }
+    }
+
+    fn call(&self, args: Vec<Value>) -> Result<Value, Error> {
+        match self {
+            Callable::Builtin(builtin) => builtin.call(args),
+        }
+    }
+}
+
 // Representation of an in-language value.
 #[derive(Clone, Debug)]
 enum Value {
diff --git a/users/tazjin/rlox/src/interpreter/builtins.rs b/users/tazjin/rlox/src/interpreter/builtins.rs
new file mode 100644
index 0000000000..6ed9f07c3f
--- /dev/null
+++ b/users/tazjin/rlox/src/interpreter/builtins.rs
@@ -0,0 +1,25 @@
+use std::fmt;
+use std::time::{SystemTime, UNIX_EPOCH};
+
+use crate::errors::Error;
+use crate::interpreter::Value;
+use crate::parser::Literal;
+
+pub trait Builtin: fmt::Debug {
+    fn arity(&self) -> usize;
+    fn call(&self, args: Vec<Value>) -> Result<Value, Error>;
+}
+
+// Builtin to return the current timestamp.
+#[derive(Debug)]
+pub struct Clock {}
+impl Builtin for Clock {
+    fn arity(&self) -> usize {
+        0
+    }
+
+    fn call(&self, _args: Vec<Value>) -> Result<Value, Error> {
+        let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
+        Ok(Value::Literal(Literal::Number(now.as_secs() as f64)))
+    }
+}