[lexer,types] Move named_char to types as types/char/names.rs
Move char.rs to be char/mod.rs
This commit is contained in:
parent
5cb66d932f
commit
fd5df91e27
4 changed files with 116 additions and 92 deletions
|
@ -1,60 +0,0 @@
|
|||
/* lexer/src/named_char.rs
|
||||
* Eryn Wells <eryn@erynwells.me>
|
||||
*/
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
|
||||
const ALARM: &'static str = "alarm";
|
||||
const BACKSPACE: &'static str = "backspace";
|
||||
const DELETE: &'static str = "delete";
|
||||
const ESCAPE: &'static str = "escape";
|
||||
const NEWLINE: &'static str = "newline";
|
||||
const NULL: &'static str = "null";
|
||||
const RETURN: &'static str = "return";
|
||||
const SPACE: &'static str = "space";
|
||||
const TAB: &'static str = "tab";
|
||||
|
||||
/// Mapping of names to `char` values. Returns the name of the given character, if a name exists.
|
||||
/// Otherwise, returns `None`.
|
||||
fn char_for(named: &str) -> Option<char> {
|
||||
static ONCE = ONCE_INIT;
|
||||
static mut names_to_chars: HashMap<&'static str, char>;
|
||||
unsafe {
|
||||
ONCE.call_once(|| {
|
||||
names_to_chars = HashMap::new();
|
||||
names_to_chars.insert(ALARM, '\x07');
|
||||
names_to_chars.insert(BACKSPACE, '\x08');
|
||||
names_to_chars.insert(DELETE, '\x7F');
|
||||
names_to_chars.insert(ESCAPE, '\x1B');
|
||||
names_to_chars.insert(NEWLINE, '\n');
|
||||
names_to_chars.insert(NULL, '\0');
|
||||
names_to_chars.insert(RETURN, '\r');
|
||||
names_to_chars.insert(SPACE, ' ');
|
||||
names_to_chars.insert(TAB, '\t');
|
||||
});
|
||||
names_to_chars.get(named)
|
||||
}
|
||||
}
|
||||
|
||||
/// Mapping of `char` values to names. Returns the name of the given character, if a name exists.
|
||||
/// Otherwise, returns `None`.
|
||||
fn name_of(c: char) -> Option<&'static str> {
|
||||
static ONCE = ONCE_INIT;
|
||||
static mut chars_to_names: HashMap<char, &'static str>;
|
||||
unsafe {
|
||||
ONCE.call_once(|| {
|
||||
chars_to_names = HashMap::new();
|
||||
chars_to_names.insert('\x07', ALARM);
|
||||
chars_to_names.insert('\x08', BACKSPACE);
|
||||
chars_to_names.insert('\x7F', DELETE);
|
||||
chars_to_names.insert('\x1B', ESCAPE);
|
||||
chars_to_names.insert('\n', NEWLINE);
|
||||
chars_to_names.insert('\0', NULL);
|
||||
chars_to_names.insert('\r', RETURN);
|
||||
chars_to_names.insert(' ', SPACE);
|
||||
chars_to_names.insert('\t', TAB);
|
||||
});
|
||||
chars_to_names.get(c)
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* types/char.rs
|
||||
* Eryn Wells <eryn@erynwells.me>
|
||||
*/
|
||||
|
||||
use object::Object;
|
||||
use predicates::IsChar;
|
||||
|
||||
impl IsChar for Object {
|
||||
fn is_char(&self) -> bool {
|
||||
match *self {
|
||||
Object::Char(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use object::Object;
|
||||
use predicates::{IsBool, IsChar};
|
||||
|
||||
#[test]
|
||||
fn chars_are_chars() {
|
||||
assert_eq!(Object::Char('a').is_char(), true);
|
||||
assert_eq!(Object::Char('a').is_bool(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn equal_chars_are_equal() {
|
||||
assert_eq!(Object::Char('a'), Object::Char('a'));
|
||||
}
|
||||
}
|
51
types/src/char/mod.rs
Normal file
51
types/src/char/mod.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* types/char.rs
|
||||
* Eryn Wells <eryn@erynwells.me>
|
||||
*/
|
||||
|
||||
mod names;
|
||||
|
||||
use object::Object;
|
||||
use predicates::IsChar;
|
||||
|
||||
|
||||
impl IsChar for Object {
|
||||
fn is_char(&self) -> bool {
|
||||
match *self {
|
||||
Object::Char(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Object {
|
||||
pub fn from_char(c: char) -> Object {
|
||||
Object::Char(c)
|
||||
}
|
||||
|
||||
pub fn from_char_name(name: &str) -> Option<Object> {
|
||||
names::char_for(name).map(|c| Object::from_char(c))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use object::Object;
|
||||
use predicates::{IsBool, IsChar};
|
||||
|
||||
#[test]
|
||||
fn chars_are_chars() {
|
||||
assert_eq!(Object::from_char('a').is_char(), true);
|
||||
assert_eq!(Object::from_char('a').is_bool(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn equal_chars_are_equal() {
|
||||
assert_eq!(Object::from_char('a'), Object::from_char('a'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn named_chars_are_created() {
|
||||
assert_eq!(Object::from_char_name("newline"), Some(Object::from_char('\n')));
|
||||
assert_eq!(Object::from_char_name("asdf"), None);
|
||||
}
|
||||
}
|
65
types/src/char/names.rs
Normal file
65
types/src/char/names.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* types/src/char/names.rs
|
||||
* Eryn Wells <eryn@erynwells.me>
|
||||
*/
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
|
||||
const ALARM: &'static str = "alarm";
|
||||
const BACKSPACE: &'static str = "backspace";
|
||||
const DELETE: &'static str = "delete";
|
||||
const ESCAPE: &'static str = "escape";
|
||||
const NEWLINE: &'static str = "newline";
|
||||
const NULL: &'static str = "null";
|
||||
const RETURN: &'static str = "return";
|
||||
const SPACE: &'static str = "space";
|
||||
const TAB: &'static str = "tab";
|
||||
|
||||
/// Mapping of names to `char` values. Returns the name of the given character, if a name exists.
|
||||
/// Otherwise, returns `None`.
|
||||
pub fn char_for(name: &str) -> Option<char> {
|
||||
type NameMap = HashMap<&'static str, char>;
|
||||
static ONCE: Once = ONCE_INIT;
|
||||
static mut NAMES_TO_CHARS: *const NameMap = 0 as *const NameMap;
|
||||
unsafe {
|
||||
ONCE.call_once(|| {
|
||||
let mut map = NameMap::new();
|
||||
map.insert(ALARM, '\x07');
|
||||
map.insert(BACKSPACE, '\x08');
|
||||
map.insert(DELETE, '\x7F');
|
||||
map.insert(ESCAPE, '\x1B');
|
||||
map.insert(NEWLINE, '\n');
|
||||
map.insert(NULL, '\0');
|
||||
map.insert(RETURN, '\r');
|
||||
map.insert(SPACE, ' ');
|
||||
map.insert(TAB, '\t');
|
||||
NAMES_TO_CHARS = mem::transmute(Box::new(map));
|
||||
});
|
||||
(*NAMES_TO_CHARS).get(name).map(|c| *c)
|
||||
}
|
||||
}
|
||||
|
||||
/// Mapping of `char` values to names. Returns the name of the given character, if a name exists.
|
||||
/// Otherwise, returns `None`.
|
||||
pub fn name_of(c: char) -> Option<&'static str> {
|
||||
type CharMap = HashMap<char, &'static str>;
|
||||
static ONCE: Once = ONCE_INIT;
|
||||
static mut CHARS_TO_NAMES: *const CharMap = 0 as *const CharMap;
|
||||
unsafe {
|
||||
ONCE.call_once(|| {
|
||||
let mut map = CharMap::new();
|
||||
map.insert('\x07', ALARM);
|
||||
map.insert('\x08', BACKSPACE);
|
||||
map.insert('\x7F', DELETE);
|
||||
map.insert('\x1B', ESCAPE);
|
||||
map.insert('\n', NEWLINE);
|
||||
map.insert('\0', NULL);
|
||||
map.insert('\r', RETURN);
|
||||
map.insert(' ', SPACE);
|
||||
map.insert('\t', TAB);
|
||||
CHARS_TO_NAMES = mem::transmute(Box::new(map));
|
||||
});
|
||||
(*CHARS_TO_NAMES).get(&c).map(|s| *s)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue