From ad276fffb31c77135d802db6f460e1e78aeef974 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Fri, 4 Jul 2025 21:39:00 +1200 Subject: Raise error if an instruction name is redefined --- src/stages/semantic.rs | 15 ++++++++++++++- src/stages/semantic_tokens.rs | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/stages/semantic.rs b/src/stages/semantic.rs index 909659d..dc9709e 100644 --- a/src/stages/semantic.rs +++ b/src/stages/semantic.rs @@ -1,15 +1,24 @@ use crate::*; +use std::str::FromStr; + use indexmap::{IndexMap, IndexSet}; pub fn parse_semantic(syntactic: Vec>) -> Result>> { + let mut errors = Vec::new(); + // Record all label definitions and macro names up front. let mut definitions = IndexMap::new(); let mut macro_names = IndexSet::new(); for token in &syntactic { match &token.value { SyntacticToken::LabelDefinition(name) => { + // Check if identifier is reserved. + if Instruction::from_str(&name).is_ok() { + let error = SemanticError::ReservedIdentifier(name.to_string()); + errors.push(Tracked::from(error, token.source.clone())); + } // Use a fake index for now. let definition = Definition::new(0, DefinitionVariant::LabelDefinition); let tracked = Tracked::from(definition, token.source.clone()); @@ -19,6 +28,11 @@ pub fn parse_semantic(syntactic: Vec>) -> Result { let name = &definition.name; + // Check if identifier is reserved. + if Instruction::from_str(&name).is_ok() { + let error = SemanticError::ReservedIdentifier(name.to_string()); + errors.push(Tracked::from(error, name.source.clone())); + } if !macro_names.insert(name.clone()) { unreachable!("Uncaught duplicate macro definition '{name}'") } @@ -29,7 +43,6 @@ pub fn parse_semantic(syntactic: Vec>) -> Result> = Vec::new(); - let mut errors = Vec::new(); let mut stack = Vec::new(); for syn_token in syntactic { diff --git a/src/stages/semantic_tokens.rs b/src/stages/semantic_tokens.rs index fc454be..c735828 100644 --- a/src/stages/semantic_tokens.rs +++ b/src/stages/semantic_tokens.rs @@ -49,6 +49,7 @@ pub enum SemanticToken { pub enum SemanticError { InvocationBeforeDefinition, + ReservedIdentifier(String), } @@ -64,6 +65,8 @@ fn report_semantic_error(error: &Tracked, source_code: &str) { let message = match &error.value { SemanticError::InvocationBeforeDefinition => "Macro cannot be invoked before it has been defined", + SemanticError::ReservedIdentifier(name) => + &format!("Identifier '{name}' is reserved for a built-in instruction"), }; report_source_issue(LogLevel::Error, &context, message); } -- cgit v1.2.3-70-g09d2