use std;
use std::fmt::{Display, Formatter, Result};
use moore_common::name::*;
pub use self::Token::*;
pub use self::DelimToken::*;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum Token {
Ident(Name),
Lit(Literal),
OpenDelim(DelimToken),
CloseDelim(DelimToken),
Keyword(Kw),
Period,
Comma,
Colon,
Semicolon,
Apostrophe,
Ampersand,
Arrow,
Condition,
LtGt,
VarAssign,
Lshift,
Rshift,
Eq,
Neq,
Lt,
Leq,
Gt,
Geq,
MatchEq,
MatchNeq,
MatchLt,
MatchLeq,
MatchGt,
MatchGeq,
Add,
Sub,
Mul,
Div,
Pow,
Pipe,
Qmark,
Eof
}
impl Token {
pub fn as_str(self) -> &'static str {
match self {
Ident(_) => "identifier",
Lit(l) => l.as_str(),
OpenDelim(Paren) => "(",
CloseDelim(Paren) => ")",
OpenDelim(Brack) => "[",
CloseDelim(Brack) => "]",
Keyword(kw) => kw.as_str(),
Period => ".",
Comma => ",",
Colon => ":",
Semicolon => ";",
Apostrophe => "'",
Ampersand => "&",
Arrow => "=>",
Condition => "??",
LtGt => "<>",
VarAssign => ":=",
Lshift => "<<",
Rshift => ">>",
Eq => "=",
Neq => "/=",
Lt => "<",
Leq => "<=",
Gt => ">",
Geq => ">=",
MatchEq => "?=",
MatchNeq => "?/=",
MatchLt => "?<",
MatchLeq => "?<=",
MatchGt => "?>",
MatchGeq => "?>=",
Add => "+",
Sub => "-",
Mul => "*",
Div => "/",
Pow => "**",
Pipe => "|",
Qmark => "?",
Eof => "end of file",
}
}
pub fn is_ident(self) -> bool {
match self {
Ident(_) => true,
_ => false
}
}
}
impl Display for Token {
fn fmt(&self, f: &mut Formatter) -> Result {
match *self {
Ident(n) => write!(f, "identifier `{}`", n),
Lit(l) => write!(f, "{}", l.as_str()),
Keyword(kw) => write!(f, "keyword `{}`", kw.as_str()),
tkn => write!(f, "`{}`", tkn.as_str()),
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum Literal {
Abstract(
Option<Name>,
Name,
Option<Name>,
Option<Exponent>,
),
BitString(
Option<Name>,
BitStringBase,
Name,
),
Char(char),
String(Name),
}
impl Literal {
pub fn as_str(self) -> &'static str {
match self {
Literal::Abstract(..) => "abstract literal",
Literal::BitString(..) => "bit string literal",
Literal::Char(..) => "character literal",
Literal::String(..) => "string literal",
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum DelimToken {
Paren,
Brack,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct Exponent(
pub ExponentSign,
pub Name,
);
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum ExponentSign {
Positive,
Negative,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum BitStringBase {
B, O, X, D,
UB, UO, UX,
SB, SO, SX,
}
macro_rules! declare_keywords {(
$( ($konst: ident, $string: expr) )*
) => {
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)]
pub enum Kw {
$($konst,)*
}
impl Kw {
pub fn as_str(self) -> &'static str {
match self {
$(Kw::$konst => $string,)*
}
}
}
impl std::fmt::Display for Kw {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
pub fn find_keyword<S: AsRef<str>>(name: S) -> Option<Kw> {
use std::collections::HashMap;
thread_local!(static TBL: HashMap<String,Kw> = {
let mut tbl = HashMap::new();
$(tbl.insert($string.to_lowercase(), Kw::$konst);)*
tbl
});
TBL.with(|tbl| tbl.get(&name.as_ref().to_lowercase()).map(|kw| *kw))
}
}}
declare_keywords! {
(Abs, "abs")
(Access, "access")
(After, "after")
(Alias, "alias")
(All, "all")
(And, "and")
(Architecture, "architecture")
(Array, "array")
(Assert, "assert")
(Assume, "assume")
(AssumeGuarantee, "assume_guarantee")
(Attribute, "attribute")
(Begin, "begin")
(Block, "block")
(Body, "body")
(Buffer, "buffer")
(Bus, "bus")
(Case, "case")
(Component, "component")
(Configuration, "configuration")
(Constant, "constant")
(Context, "context")
(Cover, "cover")
(Default, "default")
(Disconnect, "disconnect")
(Downto, "downto")
(Else, "else")
(Elsif, "elsif")
(End, "end")
(Entity, "entity")
(Exit, "exit")
(Fairness, "fairness")
(File, "file")
(For, "for")
(Force, "force")
(Function, "function")
(Generate, "generate")
(Generic, "generic")
(Group, "group")
(Guarded, "guarded")
(If, "if")
(Impure, "impure")
(In, "in")
(Inertial, "inertial")
(Inout, "inout")
(Is, "is")
(Label, "label")
(Library, "library")
(Linkage, "linkage")
(Literal, "literal")
(Loop, "loop")
(Map, "map")
(Mod, "mod")
(Nand, "nand")
(New, "new")
(Next, "next")
(Nor, "nor")
(Not, "not")
(Null, "null")
(Of, "of")
(On, "on")
(Open, "open")
(Or, "or")
(Others, "others")
(Out, "out")
(Package, "package")
(Parameter, "parameter")
(Port, "port")
(Postponed, "postponed")
(Procedure, "procedure")
(Process, "process")
(Property, "property")
(Protected, "protected")
(Pure, "pure")
(Range, "range")
(Record, "record")
(Register, "register")
(Reject, "reject")
(Release, "release")
(Rem, "rem")
(Report, "report")
(Restrict, "restrict")
(RestrictGuarantee, "restrict_guarantee")
(Return, "return")
(Rol, "rol")
(Ror, "ror")
(Select, "select")
(Sequence, "sequence")
(Severity, "severity")
(Shared, "shared")
(Signal, "signal")
(Sla, "sla")
(Sll, "sll")
(Sra, "sra")
(Srl, "srl")
(Strong, "strong")
(Subtype, "subtype")
(Then, "then")
(To, "to")
(Transport, "transport")
(Type, "type")
(Unaffected, "unaffected")
(Units, "units")
(Until, "until")
(Use, "use")
(Variable, "variable")
(Vmode, "vmode")
(Vprop, "vprop")
(Vunit, "vunit")
(Wait, "wait")
(When, "when")
(While, "while")
(With, "with")
(Xnor, "xnor")
(Xor, "xor")
}