Skip to content

Instantly share code, notes, and snippets.

@yrashk
Created March 2, 2017 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yrashk/3ea4b3d8a392d0d8eb8ac04996a9af84 to your computer and use it in GitHub Desktop.
Save yrashk/3ea4b3d8a392d0d8eb8ac04996a9af84 to your computer and use it in GitHub Desktop.
diff --git a/Cargo.toml b/Cargo.toml
index 0f50257..a72d1c1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -44,6 +44,7 @@ log = "0.3.6"
log4rs = { version = "0.6.1", features = ["toml_format"] }
serde_json = "0.9.8"
clap = "2.20.5"
+ordermap = "0.2.8"
[dev-dependencies]
quickcheck = "0.4.1"
diff --git a/src/crates.rs b/src/crates.rs
index 21b04f8..c8b0bb2 100644
--- a/src/crates.rs
+++ b/src/crates.rs
@@ -43,4 +43,6 @@ extern crate lazy_static;
extern crate crypto;
-extern crate serde_json;
\ No newline at end of file
+extern crate serde_json;
+
+extern crate ordermap;
\ No newline at end of file
diff --git a/src/script/mod_core.rs b/src/script/mod_core.rs
index 00d0c99..0f5e3b5 100644
--- a/src/script/mod_core.rs
+++ b/src/script/mod_core.rs
@@ -64,36 +64,67 @@ lazy_static! {
};
}
+macro_rules! init_words {
+ ($($word: ident),*) => {{
+ let mut map = ::std::collections::BTreeMap::new();
+ let mut ctr = 0u8;
+ $(
+ map.insert($word, ctr);
+ ctr += 1;
+ )*
+ map
+ }};
+}
+
+macro_rules! match_word {
+ ($current_word: expr, $words : expr,
+ $otherwise: expr, $($word: expr => $call: expr),*) => {
+ match $words.get(&$current_word) {
+ $(
+ Some(&$word) => $call,
+ )*
+ Some(_) => Err(Error::UnknownWord),
+ None => $otherwise
+ }
+ };
+}
+
pub struct Handler<'a> {
publisher: pubsub::PublisherAccessor<Vec<u8>>,
+ words: ::std::collections::BTreeMap<&'static [u8], u8>,
phantom: PhantomData<&'a ()>
}
impl<'a> Module<'a> for Handler<'a> {
fn handle(&mut self, env: &mut Env<'a>, word: &'a [u8], pid: EnvId) -> PassResult<'a> {
- try_word!(env, self.handle_builtins(env, word, pid));
- try_word!(env, self.handle_dowhile(env, word, pid));
- try_word!(env, self.handle_times(env, word, pid));
- try_word!(env, self.handle_scope_end(env, word, pid));
- try_word!(env, self.handle_eval(env, word, pid));
- try_word!(env, self.handle_eval_validp(env, word, pid));
- try_word!(env, self.handle_eval_scoped(env, word, pid));
- try_word!(env, self.handle_set(env, word, pid));
- try_word!(env, self.handle_def(env, word, pid));
- try_word!(env, self.handle_not(env, word, pid));
- try_word!(env, self.handle_and(env, word, pid));
- try_word!(env, self.handle_or(env, word, pid));
- try_word!(env, self.handle_ifelse(env, word, pid));
- try_word!(env, self.handle_send(env, word, pid));
- try_word!(env, self.handle_featurep(env, word, pid));
- Err(Error::UnknownWord)
+ match_word!(word, self.words,
+ {
+ try_word!(env, self.handle_builtins(env, word, pid));
+ Err(Error::UnknownWord)
+ },
+ 0 => self.handle_dowhile(env, word, pid),
+ 1 => self.handle_times(env, word, pid),
+ 2 => self.handle_scope_end(env, word, pid),
+ 3 => self.handle_eval(env, word, pid),
+ 4 => self.handle_eval_validp(env, word, pid),
+ 5 => self.handle_eval_scoped(env, word, pid),
+ 6 => self.handle_set(env, word, pid),
+ 7 => self.handle_def(env, word, pid),
+ 8 => self.handle_not(env, word, pid),
+ 9 => self.handle_and(env, word, pid),
+ 10 => self.handle_or(env, word, pid),
+ 11 => self.handle_ifelse(env, word, pid),
+ 12 => self.handle_send(env, word, pid),
+ 13 => self.handle_featurep(env, word, pid))
}
}
impl<'a> Handler<'a> {
pub fn new(publisher: pubsub::PublisherAccessor<Vec<u8>>) -> Self {
- Handler { publisher: publisher, phantom: PhantomData }
+ let words = init_words!(DOWHILE, TIMES, SCOPE_END, EVAL, EVAL_VALIDP, EVAL_SCOPED, SET, DEF,
+ NOT, AND, OR, IFELSE, SEND, FEATUREQ);
+ Handler { publisher: publisher, phantom: PhantomData, words: words }
}
#[inline]
@@ -109,7 +140,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_not(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, NOT);
+// word_is!(env, word, NOT);
let a = stack_pop!(env);
if a == STACK_TRUE {
@@ -125,7 +156,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_and(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, AND);
+// word_is!(env, word, AND);
let a = stack_pop!(env);
let b = stack_pop!(env);
@@ -147,7 +178,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_or(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, OR);
+// word_is!(env, word, OR);
let a = stack_pop!(env);
let b = stack_pop!(env);
@@ -169,7 +200,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_ifelse(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, IFELSE);
+// word_is!(env, word, IFELSE);
let else_ = stack_pop!(env);
let then = stack_pop!(env);
let cond = stack_pop!(env);
@@ -188,7 +219,7 @@ impl<'a> Handler<'a> {
#[inline]
#[cfg(feature = "scoped_dictionary")]
fn handle_eval_scoped(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, EVAL_SCOPED);
+// word_is!(env, word, EVAL_SCOPED);
env.push_dictionary();
let a = stack_pop!(env);
env.program.push(SCOPE_END);
@@ -206,7 +237,7 @@ impl<'a> Handler<'a> {
#[inline]
#[cfg(feature = "scoped_dictionary")]
fn handle_scope_end(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, SCOPE_END);
+// word_is!(env, word, SCOPE_END);
env.pop_dictionary();
Ok(())
}
@@ -220,7 +251,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_eval(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, EVAL);
+// word_is!(env, word, EVAL);
let a = stack_pop!(env);
env.program.push(a);
Ok(())
@@ -228,7 +259,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_eval_validp(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, EVAL_VALIDP);
+// word_is!(env, word, EVAL_VALIDP);
let a = stack_pop!(env);
if parse_bin(a).is_ok() {
env.push(STACK_TRUE);
@@ -240,7 +271,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_dowhile(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, DOWHILE);
+// word_is!(env, word, DOWHILE);
let v = stack_pop!(env);
let mut vec = Vec::new();
@@ -270,7 +301,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_times(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, TIMES);
+// word_is!(env, word, TIMES);
let count = stack_pop!(env);
let v = stack_pop!(env);
@@ -305,7 +336,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_set(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, SET);
+// word_is!(env, word, SET);
let word = stack_pop!(env);
let value = stack_pop!(env);
match binparser::word(word) {
@@ -330,7 +361,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_def(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, DEF);
+// word_is!(env, word, DEF);
let word = stack_pop!(env);
let value = stack_pop!(env);
match binparser::word(word) {
@@ -352,7 +383,7 @@ impl<'a> Handler<'a> {
#[inline]
fn handle_send(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, SEND);
+// word_is!(env, word, SEND);
let topic = stack_pop!(env);
let data = stack_pop!(env);
@@ -366,7 +397,7 @@ impl<'a> Handler<'a> {
#[inline]
#[allow(unused_variables)]
fn handle_featurep(&mut self, env: &mut Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
- word_is!(env, word, FEATUREQ);
+// word_is!(env, word, FEATUREQ);
let name = stack_pop!(env);
#[cfg(feature = "scoped_dictionary")]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment