aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2024-10-29 14:49:44 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2024-12-12 07:54:51 +0100
commitd2d6d90acf2e9a8ccb4cbcec619d2a0d49cd462a (patch)
treee3c7c11f4ca78d9202a6f85b6fff30a5552baa18
parente9f149a590b019a0c2f55d1fb407461df1119ff2 (diff)
downloadtools.nes-d2d6d90acf2e9a8ccb4cbcec619d2a0d49cd462a.tar.gz
tools.nes-d2d6d90acf2e9a8ccb4cbcec619d2a0d49cd462a.zip
Don't rely on the identifier for control identity
Instead, use a new enum type to identify the control statements that we actually support. This way the assembler is more easily aware on the control that it's dealing with, and can be more sure on certain aspects of the implementation on control support. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
-rw-r--r--Cargo.lock40
-rw-r--r--Cargo.toml4
-rw-r--r--crates/nasm/Cargo.toml4
-rw-r--r--lib/xixanta/src/assembler.rs94
-rw-r--r--lib/xixanta/src/context.rs13
-rw-r--r--lib/xixanta/src/node.rs30
-rw-r--r--lib/xixanta/src/opcodes.rs30
-rw-r--r--lib/xixanta/src/parser.rs70
8 files changed, 182 insertions, 103 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 72365c6..e86a0da 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "anstream"
-version = "0.6.15"
+version = "0.6.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
+checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -19,33 +19,33 @@ dependencies = [
[[package]]
name = "anstyle"
-version = "1.0.8"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56"
[[package]]
name = "anstyle-parse"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.1.1"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.4"
+version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
+checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys",
@@ -53,9 +53,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.89"
+version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
+checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8"
[[package]]
name = "clap"
@@ -99,9 +99,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colorchoice"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "heck"
@@ -146,9 +146,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.87"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
+checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
@@ -170,9 +170,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
-version = "2.0.79"
+version = "2.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
dependencies = [
"proc-macro2",
"quote",
@@ -193,9 +193,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "windows-sys"
-version = "0.52.0"
+version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
diff --git a/Cargo.toml b/Cargo.toml
index 1ea211b..552c48f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,3 +10,7 @@ authors = ["Miquel Sabaté Solà"]
[workspace.dependencies]
xixanta = { path = "./lib/xixanta", version = "0.1.0" }
+
+[profile.release]
+codegen-units = 1
+lto = true
diff --git a/crates/nasm/Cargo.toml b/crates/nasm/Cargo.toml
index b89b48c..110e5ad 100644
--- a/crates/nasm/Cargo.toml
+++ b/crates/nasm/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2021"
authors = ["Miquel Sabaté Solà <mikisabate@gmail.com>"]
[dependencies]
-anyhow = "1.0.82"
-clap = { version = "4.5.4", features = ["derive"] }
+anyhow = "^1"
+clap = { version = "^4", features = ["derive"] }
xixanta.workspace = true
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index e614b42..0f164d7 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -1,7 +1,7 @@
use crate::context::Context;
use crate::errors::{Error, EvalError};
use crate::mapping::Segment;
-use crate::node::{NodeType, PNode, PString};
+use crate::node::{ControlType, NodeType, PNode, PString};
use crate::opcodes::{AddressingMode, INSTRUCTIONS};
use crate::parser::Parser;
use std::cmp::Ordering;
@@ -145,7 +145,7 @@ impl Assembler {
let mut current_macro = None;
for (idx, node) in nodes.iter().enumerate() {
- match node.node_type {
+ match &node.node_type {
NodeType::Label => {
if let Err(err) =
self.context
@@ -174,43 +174,46 @@ impl Assembler {
Err(e) => errors.push(Error::Eval(e)),
}
}
- NodeType::Control => {
+ NodeType::Control(control_type) => {
// TODO: prevent nesting of control statements depending on
// a definition (e.g. .macro's cannot be nested inside of
// another control statement, but .if yes).
- let id = node.value.value.as_str();
-
- if id == ".macro" {
- // TODO: macros are only on the global scope.
- //
- // TODO: boy this is ugly. In fact, this stupid shit if
- // current_macro might not be relevant anymore.
- current_macro = Some(&node.left.as_ref().unwrap().value);
- // TODO: watch out for weird shit on the name of arguments.
- self.macros
- .entry(node.left.as_ref().unwrap().value.value.clone())
- .or_insert(Macro {
- nodes: Range {
- start: idx + 1,
- end: idx + 1,
- },
- args: node
- .args
- .clone()
- .unwrap_or_default()
- .into_iter()
- .map(|a| a.value)
- .collect::<Vec<_>>(),
- });
- } else if id == ".endmacro" {
- // TODO: if m.nodes.start < idx - 1 => empty macro
- if let Some(name) = current_macro {
+ match control_type {
+ ControlType::StartMacro => {
+ // TODO: macros are only on the global scope.
+ //
+ // TODO: boy this is ugly. In fact, this stupid shit if
+ // current_macro might not be relevant anymore.
+ current_macro = Some(&node.left.as_ref().unwrap().value);
+ // TODO: watch out for weird shit on the name of arguments.
self.macros
- .entry(name.value.clone())
- .and_modify(|m| m.nodes.end = idx - 1);
+ .entry(node.left.as_ref().unwrap().value.value.clone())
+ .or_insert(Macro {
+ nodes: Range {
+ start: idx + 1,
+ end: idx + 1,
+ },
+ args: node
+ .args
+ .clone()
+ .unwrap_or_default()
+ .into_iter()
+ .map(|a| a.value)
+ .collect::<Vec<_>>(),
+ });
+ }
+ ControlType::EndMacro => {
+ // TODO: if m.nodes.start < idx - 1 => empty macro
+
+ if let Some(name) = current_macro {
+ self.macros
+ .entry(name.value.clone())
+ .and_modify(|m| m.nodes.end = idx - 1);
+ }
+ current_macro = None;
}
- current_macro = None;
+ _ => {}
}
if let Err(err) = self.context.change_context(node) {
// TODO: forbid if inside_macro
@@ -271,7 +274,7 @@ impl Assembler {
}
}
}
- NodeType::Control => {
+ NodeType::Control(_) => {
if let Err(e) = self.evaluate_control_statement(node) {
errors.push(Error::Eval(e));
}
@@ -422,7 +425,7 @@ impl Assembler {
match node.node_type {
NodeType::Instruction => Ok(self.evaluate_instruction(node)?),
NodeType::Literal => Ok(self.evaluate_literal(node)?),
- NodeType::Control => Ok(self.evaluate_control_expression(node)?),
+ NodeType::Control(_) => Ok(self.evaluate_control_expression(node)?),
NodeType::Value => match self.literal_mode {
Some(LiteralMode::Hexadecimal) => Ok(self.evaluate_hexadecimal(node)?),
Some(LiteralMode::Binary) => Ok(self.evaluate_binary(node)?),
@@ -722,31 +725,30 @@ impl Assembler {
// Otherwise, check the function that could act as a statement that
// produces bundles.
- let function = node.value.value.as_str();
- match function {
- ".byte" | ".db" => self.push_evaluated_arguments(node, 1),
- ".addr" | ".word" | ".dw" => self.push_evaluated_arguments(node, 2),
+ match node.node_type {
+ NodeType::Control(ControlType::Byte) => self.push_evaluated_arguments(node, 1),
+ NodeType::Control(ControlType::Addr) | NodeType::Control(ControlType::Word) => {
+ self.push_evaluated_arguments(node, 2)
+ }
_ => Err(EvalError {
line: node.value.line,
message: format!(
"cannot handle control statement '{}' in this context",
- function
+ node.value.value
),
}),
}
}
fn evaluate_control_expression(&mut self, node: &PNode) -> Result<Bundle, EvalError> {
- let function = node.value.value.to_lowercase();
-
- match function.as_str() {
- ".hibyte" => self.evaluate_byte(node, true),
- ".lobyte" => self.evaluate_byte(node, false),
+ match node.node_type {
+ NodeType::Control(ControlType::Hibyte) => self.evaluate_byte(node, true),
+ NodeType::Control(ControlType::Lobyte) => self.evaluate_byte(node, false),
_ => Err(EvalError {
line: node.value.line,
message: format!(
"cannot handle control statement '{}' as an expression in this context",
- function
+ node.value.value
),
}),
}
diff --git a/lib/xixanta/src/context.rs b/lib/xixanta/src/context.rs
index bccac12..6933085 100644
--- a/lib/xixanta/src/context.rs
+++ b/lib/xixanta/src/context.rs
@@ -1,6 +1,6 @@
use crate::assembler::Bundle;
use crate::errors::{ContextError, ContextErrorReason};
-use crate::node::{PNode, PString};
+use crate::node::{ControlType, NodeType, PNode, PString};
use crate::opcodes::CONTROL_FUNCTIONS;
use std::collections::HashMap;
@@ -111,16 +111,19 @@ impl Context {
}
// And push/pop the context depending on the control being used.
- match node.value.value.as_str() {
- ".macro" => {
+ match node.node_type {
+ NodeType::Control(ControlType::StartMacro) => {
self.context_push(&node.left.clone().unwrap());
Ok((true, false))
}
- ".proc" | ".scope" => {
+ NodeType::Control(ControlType::StartProc)
+ | NodeType::Control(ControlType::StartScope) => {
self.context_push(&node.left.clone().unwrap());
Ok((true, true))
}
- ".endmacro" | ".endproc" | ".endscope" => {
+ NodeType::Control(ControlType::EndMacro)
+ | NodeType::Control(ControlType::EndProc)
+ | NodeType::Control(ControlType::EndScope) => {
self.context_pop(&node.value)?;
Ok((true, true))
}
diff --git a/lib/xixanta/src/node.rs b/lib/xixanta/src/node.rs
index a28d625..c787394 100644
--- a/lib/xixanta/src/node.rs
+++ b/lib/xixanta/src/node.rs
@@ -82,6 +82,24 @@ impl PString {
}
}
+/// The type of control function being used. Use this enum in order to detect
+/// which control function was detected instead of the node value.
+#[derive(Debug, Clone, PartialEq)]
+pub enum ControlType {
+ Hibyte,
+ Lobyte,
+ StartMacro,
+ EndMacro,
+ StartProc,
+ EndProc,
+ StartScope,
+ EndScope,
+ Segment,
+ Byte,
+ Word,
+ Addr,
+}
+
/// The PNode type.
#[derive(Debug, Clone, PartialEq)]
pub enum NodeType {
@@ -106,10 +124,12 @@ pub enum NodeType {
Assignment,
/// A control statement (e.g. ".proc foo"). The `value` string contains the
- /// name of the function, the `left` an optional identifier (e.g. the "foo"
- /// on ".proc foo"), and the `args` contain any possible arguments that have
- /// been passed to this control statement.
- Control,
+ /// name of the function as it was provided (use the `ControlType` value of
+ /// the enum to detect which function was exactly provided), the `left` an
+ /// optional identifier (e.g. the "foo" on ".proc foo"), and the `args`
+ /// contain any possible arguments that have been passed to this control
+ /// statement.
+ Control(ControlType),
/// A literal expression, that is, something that starts with '#', '%' or
/// '$'. The `left` node contains the inner expression.
@@ -130,7 +150,7 @@ impl fmt::Display for NodeType {
NodeType::Instruction => write!(f, "instruction"),
NodeType::Indirection => write!(f, "indirection"),
NodeType::Assignment => write!(f, "assignment"),
- NodeType::Control => write!(f, "control function"),
+ NodeType::Control(_) => write!(f, "control function"),
NodeType::Literal => write!(f, "literal"),
NodeType::Label => write!(f, "label"),
NodeType::Call => write!(f, "call"),
diff --git a/lib/xixanta/src/opcodes.rs b/lib/xixanta/src/opcodes.rs
index 0e7f379..4e336ba 100644
--- a/lib/xixanta/src/opcodes.rs
+++ b/lib/xixanta/src/opcodes.rs
@@ -1,3 +1,4 @@
+use crate::node::ControlType;
use std::collections::HashMap;
use std::fmt;
@@ -55,6 +56,7 @@ pub struct ShortEntry {
#[derive(Debug)]
pub struct Control {
+ pub control_type: ControlType,
pub has_identifier: bool,
pub required_args: Option<usize>,
pub touches_context: bool,
@@ -714,20 +716,20 @@ lazy_static! {
pub static ref CONTROL_FUNCTIONS: HashMap<String, Control> = {
let mut functions = HashMap::new();
- functions.insert(String::from(".hibyte"), Control { has_identifier: false, required_args: Some(1), touches_context: false });
- functions.insert(String::from(".lobyte"), Control { has_identifier: false, required_args: Some(1), touches_context: false });
- functions.insert(String::from(".macro"), Control { has_identifier: true, required_args: None, touches_context: true });
- functions.insert(String::from(".proc"), Control { has_identifier: true, required_args: Some(0), touches_context: true });
- functions.insert(String::from(".scope"), Control { has_identifier: true, required_args: Some(0), touches_context: true });
- functions.insert(String::from(".endscope"), Control { has_identifier: false, required_args: Some(0), touches_context: true });
- functions.insert(String::from(".endproc"), Control { has_identifier: false, required_args: Some(0), touches_context: true });
- functions.insert(String::from(".endmacro"), Control { has_identifier: false, required_args: Some(0), touches_context: true });
- functions.insert(String::from(".segment"), Control { has_identifier: false, required_args: Some(1), touches_context: true });
- functions.insert(String::from(".byte"), Control { has_identifier: false, required_args: None, touches_context: false });
- functions.insert(String::from(".db"), Control { has_identifier: false, required_args: None, touches_context: false });
- functions.insert(String::from(".word"), Control { has_identifier: false, required_args: None, touches_context: false });
- functions.insert(String::from(".dw"), Control { has_identifier: false, required_args: None, touches_context: false });
- functions.insert(String::from(".addr"), Control { has_identifier: false, required_args: None, touches_context: false });
+ functions.insert(String::from(".hibyte"), Control { control_type: ControlType::Hibyte, has_identifier: false, required_args: Some(1), touches_context: false });
+ functions.insert(String::from(".lobyte"), Control { control_type: ControlType::Lobyte, has_identifier: false, required_args: Some(1), touches_context: false });
+ functions.insert(String::from(".macro"), Control { control_type: ControlType::StartMacro, has_identifier: true, required_args: None, touches_context: true });
+ functions.insert(String::from(".proc"), Control { control_type: ControlType::StartProc, has_identifier: true, required_args: Some(0), touches_context: true });
+ functions.insert(String::from(".scope"), Control { control_type: ControlType::StartScope, has_identifier: true, required_args: Some(0), touches_context: true });
+ functions.insert(String::from(".endscope"), Control { control_type: ControlType::EndScope, has_identifier: false, required_args: Some(0), touches_context: true });
+ functions.insert(String::from(".endproc"), Control { control_type: ControlType::EndProc, has_identifier: false, required_args: Some(0), touches_context: true });
+ functions.insert(String::from(".endmacro"), Control { control_type: ControlType::EndMacro, has_identifier: false, required_args: Some(0), touches_context: true });
+ functions.insert(String::from(".segment"), Control { control_type: ControlType::Segment, has_identifier: false, required_args: Some(1), touches_context: true });
+ functions.insert(String::from(".byte"), Control { control_type: ControlType::Byte, has_identifier: false, required_args: None, touches_context: false });
+ functions.insert(String::from(".db"), Control { control_type: ControlType::Byte, has_identifier: false, required_args: None, touches_context: false });
+ functions.insert(String::from(".word"), Control { control_type: ControlType::Word, has_identifier: false, required_args: None, touches_context: false });
+ functions.insert(String::from(".dw"), Control { control_type: ControlType::Word, has_identifier: false, required_args: None, touches_context: false });
+ functions.insert(String::from(".addr"), Control { control_type: ControlType::Addr, has_identifier: false, required_args: None, touches_context: false });
functions
};
diff --git a/lib/xixanta/src/parser.rs b/lib/xixanta/src/parser.rs
index 2c20369..9e7b7d5 100644
--- a/lib/xixanta/src/parser.rs
+++ b/lib/xixanta/src/parser.rs
@@ -703,11 +703,13 @@ impl Parser {
fn parse_control(&mut self, id: PString, line: &str) -> Result<PNode, ParseError> {
let mut left = None;
let required;
+ let node_type;
// Ensure that this is a function that we know of. In the past this was
// not done and it brought too many problems that made the more
// "abstract" way of handling this just too complicated.
if let Some(control) = CONTROL_FUNCTIONS.get(&id.value.to_lowercase()) {
+ node_type = control.control_type.clone();
required = control.required_args;
// If this control function has an identifier (e.g. `.macro
@@ -740,7 +742,7 @@ impl Parser {
}
Ok(PNode {
- node_type: NodeType::Control,
+ node_type: NodeType::Control(node_type),
value: id,
left,
right: None,
@@ -815,6 +817,7 @@ impl Parser {
#[cfg(test)]
mod tests {
use super::*;
+ use crate::node::ControlType;
fn assert_one_valid(parser: &mut Parser, line: &str) {
assert!(parser.parse(line.as_bytes()).is_ok());
@@ -1356,7 +1359,12 @@ mod tests {
assert!(parser.parse(line.as_bytes()).is_ok());
let node = parser.nodes.last().unwrap();
- assert_node(node, NodeType::Control, line, ".endmacro");
+ assert_node(
+ node,
+ NodeType::Control(ControlType::EndMacro),
+ line,
+ ".endmacro",
+ );
assert!(node.left.is_none());
assert!(node.right.is_none());
assert!(node.args.is_none());
@@ -1378,7 +1386,12 @@ mod tests {
assert!(parser.parse(line.as_bytes()).is_ok());
let node = parser.nodes.last().unwrap();
- assert_node(node, NodeType::Control, line, ".hibyte");
+ assert_node(
+ node,
+ NodeType::Control(ControlType::Hibyte),
+ line,
+ ".hibyte",
+ );
assert!(node.left.is_none());
assert!(node.right.is_none());
@@ -1403,7 +1416,7 @@ mod tests {
assert!(parser.parse(line.as_bytes()).is_ok());
let node = parser.nodes.last().unwrap();
- assert_node(node, NodeType::Control, line, ".byte");
+ assert_node(node, NodeType::Control(ControlType::Byte), line, ".byte");
assert!(node.left.is_none());
assert!(node.right.is_none());
@@ -1428,7 +1441,12 @@ mod tests {
assert!(parser.parse(line.as_bytes()).is_ok());
let node = parser.nodes.last().unwrap();
- assert_node(node, NodeType::Control, line, ".scope");
+ assert_node(
+ node,
+ NodeType::Control(ControlType::StartScope),
+ line,
+ ".scope",
+ );
assert!(node.right.is_none());
assert!(node.args.is_none());
@@ -1452,7 +1470,12 @@ mod tests {
assert!(parser.parse(line.as_bytes()).is_ok());
let node = parser.nodes.last().unwrap();
- assert_node(node, NodeType::Control, line, ".macro");
+ assert_node(
+ node,
+ NodeType::Control(ControlType::StartMacro),
+ line,
+ ".macro",
+ );
assert!(node.right.is_none());
let left = node.left.clone().unwrap();
@@ -1479,7 +1502,12 @@ mod tests {
assert!(parser.parse(line.as_bytes()).is_ok());
let node = parser.nodes.last().unwrap();
- assert_node(node, NodeType::Control, line, ".macro");
+ assert_node(
+ node,
+ NodeType::Control(ControlType::StartMacro),
+ line,
+ ".macro",
+ );
assert!(node.right.is_none());
let left = node.left.clone().unwrap();
@@ -1522,7 +1550,12 @@ mod tests {
assert!(left.args.is_none());
let control = left.left.clone().unwrap();
- assert_node(&control, NodeType::Control, line, ".hibyte");
+ assert_node(
+ &control,
+ NodeType::Control(ControlType::Hibyte),
+ line,
+ ".hibyte",
+ );
assert!(control.left.is_none());
assert!(control.right.is_none());
@@ -1558,7 +1591,12 @@ mod tests {
assert!(left.args.is_none());
let control = left.left.clone().unwrap();
- assert_node(&control, NodeType::Control, line, ".hibyte");
+ assert_node(
+ &control,
+ NodeType::Control(ControlType::Hibyte),
+ line,
+ ".hibyte",
+ );
assert!(control.left.is_none());
assert!(control.right.is_none());
@@ -1597,7 +1635,12 @@ mod tests {
assert!(left.args.is_none());
let control = left.left.clone().unwrap();
- assert_node(&control, NodeType::Control, line, ".hibyte");
+ assert_node(
+ &control,
+ NodeType::Control(ControlType::Hibyte),
+ line,
+ ".hibyte",
+ );
assert!(control.left.is_none());
assert!(control.right.is_none());
@@ -1633,7 +1676,12 @@ mod tests {
assert!(left.args.is_none());
let control = left.left.clone().unwrap();
- assert_node(&control, NodeType::Control, line, ".hibyte");
+ assert_node(
+ &control,
+ NodeType::Control(ControlType::Hibyte),
+ line,
+ ".hibyte",
+ );
assert!(control.left.is_none());
assert!(control.right.is_none());