// Copyright (c) 2022 Marceline Cramer // SPDX-License-Identifier: GPL-3.0-or-later use console::Style; pub mod parse; pub mod lexer; use lexer::Token; pub struct ColorTheme { normal: Style, keyword: Style, literal: Style, comment: Style, error: Style, } impl ColorTheme { pub fn new() -> Self { Self { normal: Style::default(), keyword: Style::new().blue(), literal: Style::new().cyan(), comment: Style::new().white(), error: Style::new().black().on_red().bold(), } } pub fn token_style(&self, token: &Token) -> &Style { use Token::*; match token { Struct | Function | For | If | Else | In | Let | Mut => &self.keyword, BinaryInteger | OctalInteger | DecimalInteger => &self.literal, SingleLineComment => &self.comment, Error => &self.error, _ => &self.normal, } } } #[cfg(test)] mod tests { use super::*; #[test] fn lex_file() { let source = include_str!("test/clock.fae"); let theme = ColorTheme::new(); let mut lex = lexer::Lexer::new(source); while let Some(token) = lex.next() { let style = theme.token_style(&token); let styled = style.apply_to(format!("{:?}: {}", token, lex.slice())); println!("{}", styled); } } // TODO use spans to color-code instead of raw tokens, to show original whitespace /*#[test] fn color_file() { let source = include_str!("test/example.fae"); let theme = ColorTheme::new(); let mut lex = Token::lexer(source); while let Some(token) = lex.next() { let style = theme.token_style(&token); print!("{}", style.apply_to(lex.slice())); } }*/ }