aboutsummaryrefslogtreecommitdiff
path: root/lib/xixanta/src/object.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xixanta/src/object.rs')
-rw-r--r--lib/xixanta/src/object.rs32
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/xixanta/src/object.rs b/lib/xixanta/src/object.rs
index cd1db1f..a05c315 100644
--- a/lib/xixanta/src/object.rs
+++ b/lib/xixanta/src/object.rs
@@ -118,10 +118,22 @@ impl Bundle {
#[derive(Debug, Clone)]
pub enum ObjectType {
Address,
+ Proc,
Value,
Argument,
}
+impl std::fmt::Display for ObjectType {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self {
+ ObjectType::Address => write!(f, "raw address"),
+ ObjectType::Proc => write!(f, "proc"),
+ ObjectType::Value => write!(f, "variable"),
+ ObjectType::Argument => write!(f, "macro argument"),
+ }
+ }
+}
+
/// Bundle and metadata which is stored on the context table for a given
/// variable or label.
#[derive(Debug, Clone)]
@@ -214,7 +226,7 @@ impl Context {
/// Returns the value of the object represented by the given `id`. Note that
/// this `id` can be scoped or not, and this function will try to pick the
/// variable from the right scope. The value itself will be resolved if the
- /// type is ObjectType::Address.
+ /// type is ObjectType::Address or ObjectType::Proc.
pub fn get_variable(&mut self, id: &PString, mappings: &[Mapping]) -> Result<Object, String> {
// First of all, figure out the name of the scope and the real name of
// the variable. If this was not scoped at all (None case when trying to
@@ -242,14 +254,24 @@ impl Context {
match self.map.get_mut(scope_name) {
Some(scope) => match scope.get_mut(var_name) {
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 => {
var.accessed += 1;
Ok(var.clone())
}
+ // If it's a raw address, then we return the resolved value.
ObjectType::Address => {
let var_to_resolve = var.clone();
Ok(self.resolve_label(mappings, &var_to_resolve)?)
}
+ // If it's a .proc, then we account for the number of times
+ // it was accessed, and we return the resolved value.
+ ObjectType::Proc => {
+ var.accessed += 1;
+ let var_to_resolve = var.clone();
+ Ok(self.resolve_label(mappings, &var_to_resolve)?)
+ }
},
None => {
// If it cannot be found, then we have to move up through
@@ -290,9 +312,13 @@ impl Context {
/// address.
///
/// NOTE: this function asserts that the given `object` is of type
- /// ObjectType::Address, otherwise it doesn't make sense to call it.
+ /// ObjectType::Address or ObjectType::Proc, otherwise it doesn't make sense
+ /// to call it.
pub fn resolve_label(&self, mappings: &[Mapping], object: &Object) -> Result<Object, String> {
- assert!(matches!(object.object_type, ObjectType::Address));
+ assert!(matches!(
+ object.object_type,
+ ObjectType::Address | ObjectType::Proc
+ ));
let mut ret = object.clone();