Skip to content

Commit

Permalink
Add time provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Jul 31, 2023
1 parent ce358df commit 6adfb1c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/core/dictionary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ impl Dictionary {
}
define_word_impl(&mut self.words, name.into(), word, allow_redefine)
}

pub fn undefine_word(&mut self, name: &str) -> bool {
self.words.remove(name).is_some()
}
}

type WordsMap = HashMap<String, DictionaryEntry>;
27 changes: 27 additions & 0 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct Context<'a> {
pub dictionary: Dictionary,

pub input: Lexer<'a>,
pub clock: &'a dyn Clock,

pub stdout: &'a mut dyn Write,
}

Expand All @@ -38,6 +40,7 @@ impl<'a> Context<'a> {
next: None,
dictionary: Default::default(),
input: Lexer::new(input),
clock: &SystemClock,
stdout,
}
}
Expand All @@ -51,6 +54,15 @@ impl<'a> Context<'a> {
module.init(&mut self.dictionary)
}

pub fn with_clock(mut self, clock: &'a dyn Clock) -> Self {
self.set_clock(clock);
self
}

pub fn set_clock(&mut self, clock: &'a dyn Clock) {
self.clock = clock;
}

pub fn run(&mut self) -> Result<u8> {
let mut current = Some(Rc::new(InterpreterCont) as Cont);
while let Some(cont) = current.take() {
Expand Down Expand Up @@ -166,6 +178,21 @@ impl<T: Module> Module for &T {
}
}

pub trait Clock {
fn now_ms(&self) -> u64;
}

struct SystemClock;

impl Clock for SystemClock {
fn now_ms(&self) -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis() as u64
}
}

struct InterpreterCont;

impl ContImpl for InterpreterCont {
Expand Down
4 changes: 2 additions & 2 deletions src/core/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ impl Stack {
}

pub fn push_bool(&mut self, value: bool) -> Result<()> {
self.push(BigInt::from(if value {
self.push(if value {
-BigInt::one()
} else {
BigInt::zero()
}))
})
}

pub fn push_int<T: Into<BigInt>>(&mut self, value: T) -> Result<()> {
Expand Down
21 changes: 21 additions & 0 deletions src/modules/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,27 @@ impl Control {
ctx.stack.push_argcount(0, ctx.dictionary.make_nop())
}

#[cmd(name = "forget", args(word_from_stack = false))]
#[cmd(name = "(forget)", args(word_from_stack = true))]
fn interpret_forget(ctx: &mut Context, word_from_stack: bool) -> Result<()> {
let mut word = if word_from_stack {
*ctx.stack.pop_string()?
} else {
let word = ctx.input.scan_word()?.ok_or(Error::UnexpectedEof)?;
word.data.to_owned()
};

if ctx.dictionary.lookup(&word).is_none() {
word.push(' ');
if ctx.dictionary.lookup(&word).is_none() {
return Err(Error::UndefinedWord);
}
}

ctx.dictionary.undefine_word(&word);
Ok(())
}

// === Input parse ===

#[cmd(name = "word")]
Expand Down
10 changes: 10 additions & 0 deletions src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,14 @@ impl FiftModule for BaseModule {

Ok(())
}

#[cmd(name = "now")]
fn interpret_now(ctx: &mut Context) -> Result<()> {
ctx.stack.push_int(ctx.clock.now_ms() / 1000)
}

#[cmd(name = "now_ms")]
fn interpret_now_ms(ctx: &mut Context) -> Result<()> {
ctx.stack.push_int(ctx.clock.now_ms())
}
}

0 comments on commit 6adfb1c

Please sign in to comment.