use crate::*; use assembler::SymbolRole::*; use assembler::DefinitionType::*; pub fn new_compiler() -> Compiler { Compiler::new(parse_symbols, push_code) } /// Parse all symbols from a source code string. pub fn parse_symbols(source_code: &str, path: Option<&Path>) -> Option> { let syntactic = match parse_syntactic(source_code, path) { Ok(syntactic) => syntactic, Err(_errors) => return None, }; Some(SymbolParser::new().parse(&syntactic)) } /// Push source code to a source compilation string. pub fn push_code(compilation: &mut String, source_file: &SourceFile) { // Skip blank files. let source_code = &source_file.source_code; if source_code.chars().all(|c| c.is_whitespace()) { return; } // Ensure that the previous section is followed by two newline characters. if !compilation.is_empty() { if !compilation.ends_with('\n') { compilation.push('\n'); } if !compilation.ends_with("\n\n") { compilation.push('\n'); } } // Push a path comment and the source code. let path_str = source_file.path.as_os_str().to_string_lossy(); let path_comment = format!("(: {path_str} )\n"); compilation.push_str(&path_comment); compilation.push_str(&source_code); } // Extract symbol definitions from a list of semantic tokens. pub struct SymbolParser { pub symbols: Vec, } impl SymbolParser { pub fn new() -> Self { Self { symbols: Vec::new(), } } fn record_symbol(&mut self, name: &str, source: &SourceSpan, role: SymbolRole) { let name = name.to_string(); let namespace = Vec::new(); let source = source.to_owned(); self.symbols.push(Symbol { name, namespace, source, role }); } pub fn parse(mut self, semantic: &[Tracked]) -> Vec { for token in semantic { match &token.value { SyntacticToken::MacroDefinition(definition) => { self.record_symbol( &definition.name, &definition.name.source, Definition(MustPrecedeReference), ); for token in &definition.body { if let SyntacticToken::Invocation(name) = &token.value { self.record_symbol(&name, &token.source, Reference); } } } SyntacticToken::LabelDefinition(name) => { self.record_symbol(&name, &token.source, Definition(CanFollowReference)); } _ => (), } } return self.symbols; } }