feat(tazjin/rlox): Scaffolding for builtin functions

... 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
This commit is contained in:
Vincent Ambo 2021-01-14 03:13:51 +03:00 committed by tazjin
parent e93a2fc48f
commit 090c96eae9
2 changed files with 49 additions and 0 deletions

View file

@ -5,8 +5,32 @@ use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use std::sync::RwLock; use std::sync::RwLock;
// Implementation of built-in functions.
mod builtins;
// Tree-walk interpreter // 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. // Representation of an in-language value.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
enum Value { enum Value {

View file

@ -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)))
}
}