From d95f62157bc17ee8aad12aa8887315766207c326 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Mon, 13 Oct 2025 19:22:36 +1300 Subject: Track more information with SymbolParser To be able to re-use the symbol parser code in the intermediate stage in order to quickly find all symbol definitions and invocations in the program (in particular now that macro definitions are indistinguishable from label definitions, since they can both follow references), the symbol parser now tracks additional information about each symbol (argument count, torque-specific role, and parent macro definition). --- src/stages/compiler.rs | 77 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/src/stages/compiler.rs b/src/stages/compiler.rs index 7dfebd0..1476ec8 100644 --- a/src/stages/compiler.rs +++ b/src/stages/compiler.rs @@ -1,8 +1,6 @@ use crate::*; use assembler::{Symbol, SymbolRole, DefinitionType}; -use SymbolRole::*; -use DefinitionType::*; use std::path::Path; @@ -22,7 +20,27 @@ pub fn parse_symbols(source_code: &str, path: Option<&Path>) -> Option semantic, Err(_errors) => return None, }; - Some(SymbolParser::new().parse(&semantic)) + // Convert symbols to the format required by the assembler library. + let parsed = SymbolParser::new().parse(&semantic); + let mut symbols = Vec::new(); + for symbol in parsed { + let name = format!("{}::{}", symbol.name, symbol.arg_count); + let namespace = match symbol.macro_name { + Some(macro_name) => vec![macro_name], + None => vec![], + }; + let source = symbol.source; + let role = match symbol.role { + SymbolRoleDetailed::MacroDefinition => + SymbolRole::Definition(DefinitionType::CanFollowReference), + SymbolRoleDetailed::LabelDefinition => + SymbolRole::Definition(DefinitionType::CanFollowReference), + SymbolRoleDetailed::Invocation => + SymbolRole::Reference, + }; + symbols.push(Symbol { name, namespace, source, role }); + } + Some(symbols) } /// Push source code to a source compilation string. @@ -43,10 +61,27 @@ pub fn push_code(compilation: &mut String, source_file: &SourceFile) { } -// Extract symbol definitions from a list of semantic tokens. +// Track additional information for each symbol. +pub struct SymbolDetailed { + pub name: String, + pub macro_name: Option, + pub arg_count: usize, + pub role: SymbolRoleDetailed, + pub source: SourceSpan, +} + +pub enum SymbolRoleDetailed { + MacroDefinition, + LabelDefinition, + Invocation, +} + + +// Extract symbol definitions and invocations from a list of semantic tokens. pub struct SymbolParser { + /// Current macro definition name. pub macro_name: Option, - pub symbols: Vec, + pub symbols: Vec, } impl SymbolParser { @@ -57,18 +92,19 @@ impl SymbolParser { } } - fn record_symbol(&mut self, name: &str, arg_count: usize, source: &SourceSpan, role: SymbolRole) { - let name = format!("{name}:{arg_count}"); - let namespace = match &self.macro_name { - Some(macro_name) => vec![macro_name.to_owned()], - None => vec![], - }; - let source = source.to_owned(); - self.symbols.push(Symbol { name, namespace, source, role }); - + fn record_symbol(&mut self, name: &str, arg_count: usize, source: &SourceSpan, role: SymbolRoleDetailed) { + self.symbols.push( + SymbolDetailed { + name: name.to_string(), + macro_name: self.macro_name.clone(), + arg_count, + role, + source: source.clone(), + } + ); } - pub fn parse(mut self, semantic: &[Tracked]) -> Vec { + pub fn parse(mut self, semantic: &[Tracked]) -> Vec { for token in semantic { let source = &token.source; match &token.value { @@ -78,8 +114,9 @@ impl SymbolParser { &definition.name, definition.arguments.len(), &definition.name.source, - Definition(CanFollowReference), + SymbolRoleDetailed::MacroDefinition, ); + // Track that we're currently inside a macro definition. self.macro_name = Some(definition.name.to_string()); for argument in &definition.arguments { @@ -87,7 +124,7 @@ impl SymbolParser { &argument.name, 0, &argument.source, - Definition(MustPrecedeReference), + SymbolRoleDetailed::MacroDefinition, ); } match &definition.body { @@ -139,7 +176,7 @@ impl SymbolParser { &invocation.name, invocation.arguments.len(), &source, - Reference, + SymbolRoleDetailed::Invocation, ); for argument in &invocation.arguments { @@ -168,7 +205,7 @@ impl SymbolParser { &name, 0, &source, - Definition(CanFollowReference), + SymbolRoleDetailed::LabelDefinition, ); } BlockToken::PinnedAddress(integer) => { @@ -184,7 +221,7 @@ impl SymbolParser { &field.name.to_string(), 0, &field.source, - Reference, + SymbolRoleDetailed::Invocation, ); } } -- cgit v1.2.3-70-g09d2