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:
parent
e93a2fc48f
commit
090c96eae9
2 changed files with 49 additions and 0 deletions
|
@ -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 {
|
||||
|
|
25
users/tazjin/rlox/src/interpreter/builtins.rs
Normal file
25
users/tazjin/rlox/src/interpreter/builtins.rs
Normal 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)))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue