use std::fmt::Display;
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum EqualityOperator {
Lte,
Lt,
Gte,
Gt,
Eq,
Ne,
}
impl Display for EqualityOperator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EqualityOperator::Lte => f.write_str("<="),
EqualityOperator::Lt => f.write_str("<"),
EqualityOperator::Gte => f.write_str(">="),
EqualityOperator::Gt => f.write_str(">"),
EqualityOperator::Eq => f.write_str("=="),
EqualityOperator::Ne => f.write_str("!="),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Keyword {
Source,
Mainmenu,
Config,
Menuconfig,
Choice,
Endchoice,
Menu,
Endmenu,
If,
Endif,
Bool,
DefBool,
Tristate,
DefTristate,
String,
Hex,
Int,
Default,
Depends,
On,
Select,
Imply,
Visible,
Range,
Prompt,
Comment,
}
impl Display for Keyword {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Keyword::Source => f.write_str("source"),
Keyword::Mainmenu => f.write_str("mainmenu"),
Keyword::Config => f.write_str("config"),
Keyword::Menuconfig => f.write_str("menuconfic"),
Keyword::Choice => f.write_str("choice"),
Keyword::Endchoice => f.write_str("endchoice"),
Keyword::Menu => f.write_str("menu"),
Keyword::Endmenu => f.write_str("endmenu"),
Keyword::If => f.write_str("if"),
Keyword::Endif => f.write_str("endif"),
Keyword::Bool => f.write_str("bool"),
Keyword::DefBool => f.write_str("def_bool"),
Keyword::Tristate => f.write_str("tristate"),
Keyword::DefTristate => f.write_str("def_tristate"),
Keyword::String => f.write_str("string"),
Keyword::Hex => f.write_str("hex"),
Keyword::Int => f.write_str("int"),
Keyword::Default => f.write_str("default"),
Keyword::Depends => f.write_str("depends"),
Keyword::On => f.write_str("on"),
Keyword::Select => f.write_str("select"),
Keyword::Imply => f.write_str("imply"),
Keyword::Visible => f.write_str("visible"),
Keyword::Range => f.write_str("range"),
Keyword::Prompt => f.write_str("prompt"),
Keyword::Comment => f.write_str("comment"),
}
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum Lexicon {
Keyword(Keyword),
Identifier(String),
String(String),
Help(String),
EqualityOperator(EqualityOperator),
ImmediateAssignment,
Assignment,
AppendAssignment,
Not,
MacroOpen,
Open,
Close,
Comma,
EOT,
Error(String),
And,
Or,
}
impl Display for Lexicon {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Lexicon::Keyword(k) => f.write_str(&format!("{}", k)),
Lexicon::Identifier(s) => f.write_str(s),
Lexicon::String(s) => f.write_str(s),
Lexicon::Help(s) => f.write_str(s),
Lexicon::EqualityOperator(o) => f.write_str(&format!("{}", o)),
Lexicon::ImmediateAssignment => f.write_str(":="),
Lexicon::Assignment => f.write_str("="),
Lexicon::AppendAssignment => f.write_str("+="),
Lexicon::Not => f.write_str("+="),
Lexicon::MacroOpen => f.write_str("$("),
Lexicon::Open => f.write_str("("),
Lexicon::Close => f.write_str(")"),
Lexicon::Comma => f.write_str(","),
Lexicon::EOT => f.write_str("[End Of Transmission/File]"),
Lexicon::Error(s) => f.write_str(&format!("Error: {}", s)),
Lexicon::And => f.write_str("&"),
Lexicon::Or => f.write_str("|"),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Token {
term: Lexicon,
column: usize,
line: usize,
raw: String,
}
impl Display for Token {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!("{}", self.term))
}
}
impl Token {
pub(super) fn create(term: Lexicon, column: usize, line: usize, raw: &str) -> Self {
Self {
term,
column,
line,
raw: raw.to_string(),
}
}
pub(crate) fn create_error(column: usize, line: usize, s: &str) -> Self {
Self {
term: Lexicon::Error(s.to_string()),
column,
line,
raw: s.to_string(),
}
}
pub(super) fn create_eot(column: usize, line: usize) -> Self {
Self {
term: Lexicon::EOT,
column,
line,
raw: "".to_owned(),
}
}
pub fn term(&self) -> Lexicon {
self.term.clone()
}
pub fn column(&self) -> usize {
self.column
}
pub fn line(&self) -> usize {
self.line
}
pub fn raw(&self) -> String {
self.raw.clone()
}
pub fn eot(&self) -> bool {
match self.term {
Lexicon::EOT => return true,
_ => return false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_token_creation() {
let expected = Token {
term: Lexicon::EOT,
column: 0,
line: 0,
raw: "".to_owned(),
};
let got = Token::create(Lexicon::EOT, 0, 0, &"");
assert_eq!(expected, got);
}
}