DRY arithmetic parsing

This commit is contained in:
2020-10-17 22:52:07 +02:00
parent 3999c51eb7
commit e560fc5657
2 changed files with 82 additions and 441 deletions
+29 -6
View File
@@ -189,7 +189,7 @@ impl<'a> TokenParser<'a> {
Ok(Some((wr, rd1, rd2, mask)))
} else {
Err(CrsnError::Parse("Instruction needs 2 (RW Rd) or 3 (Wr Rd Rd) arguments!".into(), self.start_pos.clone()))
Err(CrsnError::Parse("Instruction needs 2 (RW,Rd) or 3 (Wr,Rd,Rd) arguments!".into(), self.start_pos.clone()))
}
} else {
Ok(None)
@@ -232,7 +232,7 @@ impl<'a> TokenParser<'a> {
Ok(Some((wr, rd, mask)))
} else {
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr Rd) arguments!".into(), self.start_pos.clone()))
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr,Rd) arguments!".into(), self.start_pos.clone()))
}
} else {
Ok(None)
@@ -262,7 +262,7 @@ impl<'a> TokenParser<'a> {
Ok(Some((wr1, wr2, mask)))
} else {
Err(CrsnError::Parse("Instruction needs 2 (RW RW) arguments!".into(), self.start_pos.clone()))
Err(CrsnError::Parse("Instruction needs 2 (RW,RW) arguments!".into(), self.start_pos.clone()))
}
} else {
Ok(None)
@@ -270,6 +270,7 @@ impl<'a> TokenParser<'a> {
}
/// Parse combining binary instruction operands (i.e. add) without masks
/// Accepts (Wr, Rd, Rd) and (RdWr, Rd)
pub fn parse_wr_rd_rd(&mut self) -> Result<(Wr, Rd, Rd), CrsnError> {
if self.len() == 2 {
let rw = self.next_rdwr()?;
@@ -281,11 +282,32 @@ impl<'a> TokenParser<'a> {
let rd2 = self.next_rd()?;
Ok((wr, rd1, rd2))
} else {
Err(CrsnError::Parse("Instruction needs 2 (RW Rd) or 3 (Wr Rd Rd) arguments!".into(), self.start_pos.clone()))
Err(CrsnError::Parse("Instruction needs 2 (RW,Rd) or 3 (Wr,Rd,Rd) arguments!".into(), self.start_pos.clone()))
}
}
/// Parse combining binary instruction operands (i.e. add) without masks
/// Accepts (Wr, Rd, Rd) and (RdWr, Rd)
pub fn parse_wr_rd_rd_or_n(&mut self, n : Value) -> Result<(Wr, Rd, Rd), CrsnError> {
if self.len() == 1 {
let rw = self.next_rdwr()?;
Ok((rw.wr(), rw.rd(), Rd::immediate(n)))
} else if self.len() == 2 {
let rw = self.next_rdwr()?;
let rd = self.next_rd()?;
Ok((rw.wr(), rw.rd(), rd))
} else if self.len() == 3 {
let wr = self.next_wr()?;
let rd1 = self.next_rd()?;
let rd2 = self.next_rd()?;
Ok((wr, rd1, rd2))
} else {
Err(CrsnError::Parse("Instruction needs 1 (RW,1), 2 (RW,Rd) or 3 (Wr,Rd,Rd) arguments!".into(), self.start_pos.clone()))
}
}
/// Parse unary instruction operands (i.e. complement) without masks
/// Accepts (Wr, Rd) and (RdWr)
pub fn parse_wr_rd(&mut self) -> Result<(Wr, Rd), CrsnError> {
if self.len() == 1 {
let rw = self.next_rdwr()?;
@@ -295,18 +317,19 @@ impl<'a> TokenParser<'a> {
let rd = self.next_rd()?;
Ok((wr, rd))
} else {
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr Rd) arguments!".into(), self.start_pos.clone()))
Err(CrsnError::Parse("Instruction needs 1 (RW) or 2 (Wr,Rd) arguments!".into(), self.start_pos.clone()))
}
}
/// Parse a swap-type binary instruction operands (i.e. exchange) without masks
/// Accepts (RdWr, RdWr)
pub fn parse_rdwr_rdwr(&mut self, _keyword: &str, _prefix: &str, _pos: &SourcePosition) -> Result<(RdWr, RdWr), CrsnError> {
if self.len() == 2 {
let rw1 = self.next_rdwr()?;
let rw2 = self.next_rdwr()?;
Ok((rw1, rw2))
} else {
Err(CrsnError::Parse("Instruction needs 2 (RW RW) arguments!".into(), self.start_pos.clone()))
Err(CrsnError::Parse("Instruction needs 2 (RW,RW) arguments!".into(), self.start_pos.clone()))
}
}
}