106 lines
3.0 KiB
Rust
106 lines
3.0 KiB
Rust
use std::{collections::VecDeque};
|
|
|
|
use crate::{token::{Token}, builtin::modules::Module};
|
|
|
|
#[derive(Default)]
|
|
pub struct LangSpecs {
|
|
/// builtin modules for extra builtin functions
|
|
builtin_features: Vec<crate::builtin::modules::Module>,
|
|
lang_version: u32,
|
|
authors: Vec<String>,
|
|
embedded_files: Vec<String>,
|
|
}
|
|
|
|
impl LangSpecs {
|
|
|
|
pub fn features(&self) -> &[crate::builtin::modules::Module] {
|
|
&self.builtin_features
|
|
}
|
|
}
|
|
|
|
pub fn resolve_directives(tokens: &mut VecDeque<Token>) -> LangSpecs {
|
|
let mut specs = LangSpecs::default();
|
|
|
|
for token in tokens.iter() {
|
|
match token {
|
|
Token::CompilerDirective(text, _) => parse_directive(text, &mut specs),
|
|
_ => ()
|
|
}
|
|
}
|
|
|
|
// remove compiler directives from source
|
|
tokens.retain(|token| match token {
|
|
Token::CompilerDirective(_, _) => false,
|
|
_ => true
|
|
});
|
|
|
|
specs
|
|
}
|
|
|
|
static DIRECTIVE_REGEX_SRC: &'static str = concat!(
|
|
r"@feature\(((?:\s*[\w]+\s*,?)*)\)",
|
|
r"|@version\(\s*([0-9]{3})\s*\)",
|
|
r"|@author\((.*)\)",
|
|
r"|@embed\((.*)\)"
|
|
);
|
|
|
|
lazy_static::lazy_static! {
|
|
static ref DIRECTIVE_REGEX: regex::Regex = regex::Regex::new(DIRECTIVE_REGEX_SRC).unwrap();
|
|
}
|
|
|
|
pub fn from_list(text: &str) -> Vec<String> {
|
|
let mut vec = vec![];
|
|
|
|
for word in text.split(',') {
|
|
vec.push(String::from(word.trim()))
|
|
}
|
|
|
|
vec
|
|
}
|
|
|
|
fn parse_directive(text: &str, specs: &mut LangSpecs) {
|
|
|
|
for cap in DIRECTIVE_REGEX.captures_iter(text) {
|
|
let mut enumerator = cap.iter().enumerate();
|
|
loop {
|
|
let next = enumerator.next();
|
|
if next.is_none() {
|
|
break;
|
|
}
|
|
|
|
let (i, group) = next.unwrap();
|
|
|
|
// ignore first group as its the entire match,
|
|
// as well as the 1st group (= comments)
|
|
if i < 1 {
|
|
continue;
|
|
}
|
|
|
|
if let Some(mat) = group {
|
|
match i {
|
|
1 => {
|
|
specs.builtin_features.append(&mut Module::from_list(mat.as_str()));
|
|
return;
|
|
},
|
|
2 => {
|
|
specs.lang_version = mat.as_str().parse().unwrap();
|
|
return;
|
|
},
|
|
3 => {
|
|
specs.authors.push(String::from(mat.as_str()));
|
|
return;
|
|
},
|
|
4 => {
|
|
specs.embedded_files.append(&mut from_list(mat.as_str()));
|
|
crate::message(crate::token::MessageType::Warning, "Embed directive not working at current state");
|
|
return;
|
|
},
|
|
_ => crate::message(crate::token::MessageType::Warning, format!("unknown directive: `{}`", text)),
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
crate::message(crate::token::MessageType::Warning, format!("unknown directive: `{}`", text));
|
|
} |