Skip to content

Commit

Permalink
Fix setting the variable
Browse files Browse the repository at this point in the history
Signed-off-by: Miquel Sabaté Solà <[email protected]>
  • Loading branch information
mssola committed Oct 23, 2024
1 parent 124dc01 commit 2a908ba
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
18 changes: 13 additions & 5 deletions lib/xixanta/src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ impl Assembler {

for (idx, node) in nodes.iter().enumerate() {
match node.node_type {
NodeType::Label => {
if let Err(err) =
self.context
.set_variable(&node.value, &Bundle::default(), false)
{
errors.push(Error::Context(err));
}
}
NodeType::Assignment => {
// TODO: in fact, we cannot have assignments in many places.
if current_macro.is_some() {
Expand All @@ -127,7 +135,8 @@ impl Assembler {
}
match self.evaluate_node(node.left.as_ref().unwrap()) {
Ok(value) => {
if let Err(err) = self.context.set_variable(&node.value, &value) {
if let Err(err) = self.context.set_variable(&node.value, &value, false)
{
errors.push(Error::Context(err));
}
}
Expand Down Expand Up @@ -195,8 +204,6 @@ impl Assembler {
for node in nodes {
match node.node_type {
NodeType::Label => {
// And now make up a fake bundle object which contains the
// value of the address that has been processed.
let segment = &self.segments[self.current_segment];
let value = (segment.start as usize + segment.offset).to_le_bytes();
let bundle = Bundle {
Expand All @@ -207,12 +214,13 @@ impl Assembler {
affected_on_page: false,
};

if let Err(err) = self.context.set_variable(&node.value, &bundle) {
if let Err(err) = self.context.set_variable(&node.value, &bundle, true) {
errors.push(Error::Context(err));
}
}
NodeType::Instruction => {
if self.can_bundle {
self.literal_mode = None;
match self.evaluate_node(node) {
Ok(bundle) => {
if let Err(e) = self.push_bundle(&mut bundles, bundle) {
Expand Down Expand Up @@ -290,7 +298,7 @@ impl Assembler {
for (idx, arg) in args.unwrap().iter().enumerate() {
let bundle = self.evaluate_node(arg)?;
self.context
.set_variable(margs.nth(idx).unwrap(), &bundle)?;
.set_variable(margs.nth(idx).unwrap(), &bundle, false)?;
}
}

Expand Down
39 changes: 23 additions & 16 deletions lib/xixanta/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand Down

0 comments on commit 2a908ba

Please sign in to comment.