diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-10-23 12:54:14 +0200 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-12-12 07:49:33 +0100 |
| commit | d492aa8271f9fb02351b1144733508194df67746 (patch) | |
| tree | a035d7c495ebc6a12b01e0018b345760de24ba22 /lib/xixanta/src/context.rs | |
| parent | 4f24eb5e5754c4e1e2c6069bdaf1b0f34c856c1b (diff) | |
| download | tools.nes-d492aa8271f9fb02351b1144733508194df67746.tar.gz tools.nes-d492aa8271f9fb02351b1144733508194df67746.zip | |
Re-work the support on labels, variables and jumps
As a way to firstly adapt on the latest changes from the parser since
184c39579227 ("Re-work the parser from scratch"), the assembler had to
leave out some features on 16114b2ca358 ("Adapt the assembler to the
changes on the parser"). This commit reintroduces support for settings
labels, variables and referencing them, while also providing a more
robust implementation at that.
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib/xixanta/src/context.rs')
| -rw-r--r-- | lib/xixanta/src/context.rs | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/lib/xixanta/src/context.rs b/lib/xixanta/src/context.rs index 3fceab9..bccac12 100644 --- a/lib/xixanta/src/context.rs +++ b/lib/xixanta/src/context.rs @@ -59,28 +59,35 @@ impl Context { } } - /// Sets a value for a new variable defined in the assignment `node`. - pub fn set_variable(&mut self, id: &PString, bundle: &Bundle) -> Result<(), ContextError> { + /// Sets a value for a variable defined in the assignment `node`. If + /// `overwrite` is set to true, then this value will be set even if the + /// variable already existed, otherwise it will return a ContextError + pub fn set_variable( + &mut self, + id: &PString, + bundle: &Bundle, + overwrite: bool, + ) -> Result<(), ContextError> { let scope_name = self.name().to_string(); let scope = self.map.get_mut(&scope_name).unwrap(); match scope.get_mut(&id.value) { - Some(_) => { - return Err(ContextError { - message: format!( - "'{}' already defined in {}: you cannot re-assign variables", - id.value, - self.to_human() - ), - line: id.line, - reason: ContextErrorReason::Redefinition, - }) + Some(sc) => { + if !overwrite { + return Err(ContextError { + message: format!( + "'{}' already defined in {}: you cannot re-assign variables", + id.value, + self.to_human() + ), + line: id.line, + reason: ContextErrorReason::Redefinition, + }); + } + *sc = bundle.clone(); } None => { - self.map.insert( - scope_name, - HashMap::from([(id.value.clone(), bundle.to_owned())]), - ); + scope.insert(id.value.clone(), bundle.to_owned()); } } @@ -121,6 +128,16 @@ impl Context { } } + pub fn force_context_switch(&mut self, name: &String) { + self.stack.push(name.to_owned()); + } + + pub fn force_context_pop(&mut self) { + if !self.stack.is_empty() { + self.stack.truncate(self.stack.len() - 1); + } + } + // Pushes a new context given a `node`, which holds the identifier of the // new scope. fn context_push(&mut self, id: &PNode) { @@ -150,7 +167,7 @@ impl Context { } // Returns the name of the current context. - fn name(&self) -> &str { + pub fn name(&self) -> &str { match self.stack.last() { Some(name) => name, None => GLOBAL_CONTEXT, |
