Website Summary Files Commits Branches @commit @diff @stats
path: root / assembler / src / parser / instruction.rs
diff options
context:
space:
mode:
Commit9517d3d05e86621b6c4ed58edd7f5821632e0872 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-02-14 08:23:08 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-02-14 08:24:27 +0200
Files2d633e6452e8167bada5db90d061cbdbd8ffcf89 /assembler/src/parser/instruction.rs
tonkobali-9517d3d05e86621b6c4ed58edd7f5821632e0872.tar
tonkobali-9517d3d05e86621b6c4ed58edd7f5821632e0872.tar.gz
tonkobali-9517d3d05e86621b6c4ed58edd7f5821632e0872.zip
Parent2cf1097e124c5a0c5836987416b080b6aa4cdd0f (diff)
feat(assembler): Implemented semantic analysis
1 files changed, 46 insertions, 0 deletions
-rw-r--r--assembler/src/parser/instruction.rs46
diff --git a/assembler/src/parser/instruction.rs b/assembler/src/parser/instruction.rs
index c44c1de..18d67b7 100644
--- a/assembler/src/parser/instruction.rs
+++ b/assembler/src/parser/instruction.rs
@@ -1,5 +1,15 @@
use super::{ Instruction, Address };
+#[derive(Debug)]
+pub(crate) enum ArgumentError {
+ UnknownInstruction,
+ TooMany,
+ TooFew,
+ NotLocation,
+ NotNumber,
+ NotString,
+}
+
impl Instruction {
fn new_subleq(a: &Address, b: &Address, c: &Address) -> Instruction {
if let Address::Constants(_) = c {
@@ -11,6 +21,42 @@ impl Instruction {
}
}
+ fn check_args_len(&self, expected: usize) -> Result<(), ArgumentError> {
+ if self.args.len() < expected {
+ return Err(ArgumentError::TooFew);
+ }
+ else if self.args.len() > 3 {
+ return Err(ArgumentError::TooMany);
+ }
+ Ok(())
+ }
+
+ pub(crate) fn check_args(&self) -> Result<(), ArgumentError> {
+ match &*self.name {
+ "subleq" => {
+ self.check_args_len(3)?;
+
+ for arg in &self.args {
+ if ! arg.is_location() {
+ return Err(ArgumentError::NotLocation);
+ }
+ }
+ },
+ "jmp" => {
+ self.check_args_len(1)?;
+
+ if ! self.args[0].is_location() {
+ return Err(ArgumentError::NotLocation);
+ }
+ },
+ "add" => {
+ self.check_args_len(2)?;
+ },
+ _ => return Err(ArgumentError::UnknownInstruction),
+ }
+ Ok(())
+ }
+
pub(crate) fn collapse(&mut self, next: usize) -> Vec<Instruction> {
self.name = self.name.to_lowercase();
static Z: Address = Address::Memory(0);