Created
March 2, 2017 15:37
-
-
Save yrashk/3ea4b3d8a392d0d8eb8ac04996a9af84 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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