From 5fca76b56034554d965b77d1485f92685d79bc84 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Tue, 7 Jul 2026 23:51:17 +0200 Subject: Let arguments be able to reference their macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The enum type for macro arguments has been adjusted so it accepts a String. This is then used to store the name of the macro for this argument. This is a bit of a circlejerk, but in the end it stems from the fact that macro arguments were sort of a hack defined ad-hoc each time they were needed. That being said, if we want to report macro arguments being unused, we need to reference the actual macro definition, not the macro call. Signed-off-by: Miquel Sabaté Solà --- lib/xixanta/src/assembler.rs | 87 ++++++++++++++++++++++++++++++-------------- lib/xixanta/src/object.rs | 8 ++-- 2 files changed, 63 insertions(+), 32 deletions(-) (limited to 'lib') diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index bc74d9e..dac298a 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -1221,30 +1221,60 @@ impl<'a> Assembler<'a> { // If this was a .proc definition then we are certain that // this is dead code, which is a really crappy situation. - if matches!(bundle.object_type, ObjectType::Proc) { - errors.push(Error { - line: 0, - message: format!("proc '{full_name}' is unused"), - source, - expanded_from: self.macro_context.clone(), - global: true, - }); - } else { - let (line, global) = match &bundle.node { - Some(n) => (n.value.line, false), - None => (0, true), - }; + // Otherwise, we cannot exactly pin down whether this is + // harmless or not. Hence, just issue a warning and let the + // programmer decide on this. + match &bundle.object_type { + ObjectType::Proc => { + errors.push(Error { + line: 0, + message: format!("proc '{full_name}' is unused"), + source, + expanded_from: self.macro_context.clone(), + global: true, + }); + } + ObjectType::Argument(macro_name) => match self.macros.get(macro_name) { + Some(mcr) => { + let macro_definition = &mcr.left.as_ref().unwrap().value; + self.warnings.push(Error { + line: macro_definition.line, + message: format!( + "argument '{name}' of the macro '{}' is unused", + macro_definition.value + ), + source, + expanded_from: self.macro_context.clone(), + global: false, + }); + } + None => { + self.warnings.push(Error { + line: 0, + message: format!( + "{} '{full_name}' is unused", + bundle.object_type + ), + source, + expanded_from: self.macro_context.clone(), + global: true, + }); + } + }, + _ => { + let (line, global) = match &bundle.node { + Some(n) => (n.value.line, false), + None => (0, true), + }; - // Otherwise, we cannot exactly pin down whether this is - // harmless or not. Hence, just issue a warning and let - // the programmer decide on this. - self.warnings.push(Error { - line, - message: format!("{} '{full_name}' is unused", bundle.object_type), - source, - expanded_from: self.macro_context.clone(), - global, - }); + self.warnings.push(Error { + line, + message: format!("{} '{full_name}' is unused", bundle.object_type), + source, + expanded_from: self.macro_context.clone(), + global, + }); + } } continue; } @@ -1463,7 +1493,8 @@ impl<'a> Assembler<'a> { // Consume a node which contains a macro call by pushing its bundles now. fn bundle_call(&mut self, node: &PNode) -> Result<(), Vec> { // Get the macro we are trying to reproduce. - let mcr = *self.macros.get(&node.value.value).ok_or(Error { + let macro_name = &node.value.value; + let mcr = *self.macros.get(macro_name).ok_or(Error { line: node.value.line, message: format!( "could not find a macro with the name '{}'", @@ -1517,7 +1548,7 @@ impl<'a> Assembler<'a> { node: Some(arg.clone()), mapping: self.current_mapping, segment: self.current_segment, - object_type: ObjectType::Argument, + object_type: ObjectType::Argument(macro_name.clone()), asan_ignore: false, asan_reserve: 1, accessed: 0, @@ -3240,7 +3271,7 @@ impl<'a> Assembler<'a> { if let Ok(var) = self.context.get_variable(&node.value, &self.mappings) { if matches!( var.object_type, - ObjectType::Address | ObjectType::Argument | ObjectType::Proc + ObjectType::Address | ObjectType::Argument(_) | ObjectType::Proc ) { return Ok(()); } @@ -3274,7 +3305,7 @@ impl<'a> Assembler<'a> { if let Ok(var) = self.context.get_variable(left_name, &self.mappings) { if matches!( var.object_type, - ObjectType::Address | ObjectType::Argument | ObjectType::Proc + ObjectType::Address | ObjectType::Argument(_) | ObjectType::Proc ) { return Ok(()); } @@ -3282,7 +3313,7 @@ impl<'a> Assembler<'a> { if let Ok(var) = self.context.get_variable(right_name, &self.mappings) { if matches!( var.object_type, - ObjectType::Address | ObjectType::Argument | ObjectType::Proc + ObjectType::Address | ObjectType::Argument(_) | ObjectType::Proc ) { return Ok(()); } diff --git a/lib/xixanta/src/object.rs b/lib/xixanta/src/object.rs index 08f94fd..64d4298 100644 --- a/lib/xixanta/src/object.rs +++ b/lib/xixanta/src/object.rs @@ -120,7 +120,7 @@ pub enum ObjectType { Address, Proc, Value, - Argument, + Argument(String), } impl std::fmt::Display for ObjectType { @@ -129,7 +129,7 @@ impl std::fmt::Display for ObjectType { ObjectType::Address => write!(f, "label"), ObjectType::Proc => write!(f, "proc"), ObjectType::Value => write!(f, "variable"), - ObjectType::Argument => write!(f, "macro argument"), + ObjectType::Argument(_) => write!(f, "macro argument"), } } } @@ -242,7 +242,7 @@ impl Context { Some(var) => match var.object_type { // If it's a value or an argument, then we just account for // the number of times it was accessed and return it as is. - ObjectType::Value | ObjectType::Argument => { + ObjectType::Value | ObjectType::Argument(_) => { var.accessed += 1; Ok(var.clone()) } @@ -348,7 +348,7 @@ impl Context { // For macro arguments, we still want to preserve the // 'accessed' member, as arguments are re-created on each // use and this information might get lost in the process. - ObjectType::Argument => { + ObjectType::Argument(_) => { let before = sc.accessed; *sc = object.clone(); sc.accessed = before; -- cgit v1.2.3