Commit b1465dc8 authored by Kai Rese's avatar Kai Rese
Browse files

reduce parameter count for encoding functions

parent 40113dc8
......@@ -37,7 +37,7 @@ pub fn assemble(statements: &[Statement]) -> Result<Vec<u8>, ErrorVec> {
Err(_) => label_symbols.push((name, curr_position)),
}
} else if let Statement::Instruction(instruction) = statement {
if let InstructionStatement::Data(_, Some(name)) = instruction {
if let InstructionStatement::Data((_, Some(name))) = instruction {
match label_symbols.binary_search_by(|entry| entry.0.cmp(name)) {
Ok(_) => errors.push(Error {
line_number,
......@@ -59,93 +59,78 @@ pub fn assemble(statements: &[Statement]) -> Result<Vec<u8>, ErrorVec> {
let line_number = index + 1;
curr_position += 2;
let code = match instruction {
InstructionStatement::AddReg(first, second, third) => {
encode_3_reg(line_number, &register_symbols, 0x0, first, second, third)
InstructionStatement::AddReg(identifier) => {
encode_3_reg(line_number, &register_symbols, 0x0, *identifier)
}
InstructionStatement::AddImm(first, second) => {
encode_reg_imm(line_number, &register_symbols, 0x1, first, *second, true)
InstructionStatement::AddImm(arguments) => {
encode_reg_imm(line_number, &register_symbols, 0x1, *arguments, true)
}
InstructionStatement::Sub(first, second, third) => {
encode_3_reg(line_number, &register_symbols, 0x2, first, second, third)
InstructionStatement::Sub(identifier) => {
encode_3_reg(line_number, &register_symbols, 0x2, *identifier)
}
InstructionStatement::SetTarget(first, second, third) => encode_reg_target(
InstructionStatement::SetTarget(arguments) => encode_reg_target(
line_number,
&register_symbols,
&label_symbols,
curr_position,
0x3,
first,
*second,
*third,
*arguments,
),
InstructionStatement::LoadReg(first, second, third) => {
encode_3_reg(line_number, &register_symbols, 0x4, first, second, third)
InstructionStatement::LoadReg(identifier) => {
encode_3_reg(line_number, &register_symbols, 0x4, *identifier)
}
InstructionStatement::LoadImm(first, second, third) => encode_reg_target(
InstructionStatement::LoadImm(arguments) => encode_reg_target(
line_number,
&register_symbols,
&label_symbols,
curr_position,
0x5,
first,
*second,
*third,
*arguments,
),
InstructionStatement::StoreReg(first, second, third) => {
encode_3_reg(line_number, &register_symbols, 0x6, first, second, third)
InstructionStatement::StoreReg(identifier) => {
encode_3_reg(line_number, &register_symbols, 0x6, *identifier)
}
InstructionStatement::StoreImm(first, second, third) => encode_reg_target(
InstructionStatement::StoreImm(arguments) => encode_reg_target(
line_number,
&register_symbols,
&label_symbols,
curr_position,
0x7,
first,
*second,
*third,
*arguments,
),
InstructionStatement::JumpImm(first, second) => encode_target(
line_number,
&label_symbols,
curr_position,
0x8,
*first,
*second,
),
InstructionStatement::JumpReg(first, second) => {
encode_reg_imm(line_number, &register_symbols, 0x9, first, *second, true)
InstructionStatement::JumpImm(arguments) => {
encode_target(line_number, &label_symbols, curr_position, 0x8, *arguments)
}
InstructionStatement::JumpReg(arguments) => {
encode_reg_imm(line_number, &register_symbols, 0x9, *arguments, true)
}
InstructionStatement::BranchEqualZero(first, second, third) => encode_reg_target(
InstructionStatement::BranchEqualZero(arguments) => encode_reg_target(
line_number,
&register_symbols,
&label_symbols,
curr_position,
0xa,
first,
*second,
*third,
*arguments,
),
InstructionStatement::BranchGreaterZero(first, second, third) => encode_reg_target(
InstructionStatement::BranchGreaterZero(arguments) => encode_reg_target(
line_number,
&register_symbols,
&label_symbols,
curr_position,
0xb,
first,
*second,
*third,
*arguments,
),
InstructionStatement::ShiftLeft(first, second, third) => {
encode_2_reg_imm(line_number, &register_symbols, 0xc, first, second, *third)
InstructionStatement::ShiftLeft(arguments) => {
encode_2_reg_imm(line_number, &register_symbols, 0xc, *arguments)
}
InstructionStatement::ShiftRight(first, second, third) => {
encode_2_reg_imm(line_number, &register_symbols, 0xd, first, second, *third)
InstructionStatement::ShiftRight(arguments) => {
encode_2_reg_imm(line_number, &register_symbols, 0xd, *arguments)
}
InstructionStatement::BoolTable(first, second, third) => {
encode_2_reg_imm(line_number, &register_symbols, 0xd, first, second, *third)
InstructionStatement::BoolTable(arguments) => {
encode_2_reg_imm(line_number, &register_symbols, 0xd, *arguments)
}
InstructionStatement::Stop => Ok((0x0f, 0x00)),
InstructionStatement::Data(first, _) => Ok((
InstructionStatement::Data((first, _)) => Ok((
((*first as usize >> 8) & 0xff) as u8,
(*first as usize & 0xff) as u8,
)),
......@@ -172,13 +157,11 @@ fn encode_3_reg<'a>(
line_number: usize,
register_symbols: &'a [(&str, u8)],
code: u8,
first: &'a str,
second: &'a str,
third: &'a str,
identifier: (&'a str, &'a str, &'a str),
) -> Result<(u8, u8), Error> {
let low_byte: u8 = code | (get_identifier(line_number, register_symbols, first)? << 4);
let high_byte: u8 = get_identifier(line_number, register_symbols, second)?
| (get_identifier(line_number, register_symbols, third)? << 4);
let low_byte: u8 = code | (get_identifier(line_number, register_symbols, identifier.0)? << 4);
let high_byte: u8 = get_identifier(line_number, register_symbols, identifier.1)?
| (get_identifier(line_number, register_symbols, identifier.2)? << 4);
Ok((low_byte, high_byte))
}
......@@ -186,13 +169,12 @@ fn encode_reg_imm<'a>(
line_number: usize,
register_symbols: &'a [(&str, u8)],
code: u8,
first: &'a str,
second: isize,
arguments: (&'a str, isize),
signed: bool,
) -> Result<(u8, u8), Error> {
let low_byte: u8 = code | (get_identifier(line_number, register_symbols, first)? << 4);
assert_range(line_number, second, 8, signed)?;
let high_byte: u8 = second as u8;
let low_byte: u8 = code | (get_identifier(line_number, register_symbols, arguments.0)? << 4);
assert_range(line_number, arguments.1, 8, signed)?;
let high_byte: u8 = arguments.1 as u8;
Ok((low_byte, high_byte))
}
......@@ -202,13 +184,12 @@ fn encode_reg_target<'a>(
label_symbols: &'a [(&str, usize)],
ip: usize,
code: u8,
first: &'a str,
second: Option<&'a str>,
third: isize,
arguments: (&'a str, Option<&'a str>, isize),
) -> Result<(u8, u8), Error> {
let target = get_target_address(line_number, label_symbols, second, ip)? as isize + third;
let target =
get_target_address(line_number, label_symbols, arguments.1, ip)? as isize + arguments.2;
assert_range(line_number, target, 8, true)?;
let low_byte: u8 = code | (get_identifier(line_number, &register_symbols, first)? << 4);
let low_byte: u8 = code | (get_identifier(line_number, &register_symbols, arguments.0)? << 4);
let high_byte: u8 = target as u8;
Ok((low_byte, high_byte))
}
......@@ -218,10 +199,10 @@ fn encode_target<'a>(
label_symbols: &[(&str, usize)],
ip: usize,
code: u8,
first: Option<&'a str>,
second: isize,
arguments: (Option<&'a str>, isize),
) -> Result<(u8, u8), Error> {
let target = get_target_address(line_number, label_symbols, first, ip)? as isize + second;
let target =
get_target_address(line_number, label_symbols, arguments.0, ip)? as isize + arguments.1;
assert_range(line_number, target, 12, true)?;
let low_byte: u8 = code | ((target & 0xf) << 4) as u8;
let high_byte: u8 = (target >> 4) as u8;
......@@ -232,13 +213,12 @@ fn encode_2_reg_imm<'a>(
line_number: usize,
register_symbols: &[(&str, u8)],
code: u8,
first: &'a str,
second: &'a str,
third: isize,
arguments: (&'a str, &'a str, isize),
) -> Result<(u8, u8), Error> {
let low_byte: u8 = code | (get_identifier(line_number, register_symbols, first)? << 4);
assert_range(line_number, third, 4, false)?;
let high_byte: u8 = get_identifier(line_number, register_symbols, second)? | (third << 4) as u8;
let low_byte: u8 = code | (get_identifier(line_number, register_symbols, arguments.0)? << 4);
assert_range(line_number, arguments.2, 4, false)?;
let high_byte: u8 =
get_identifier(line_number, register_symbols, arguments.1)? | (arguments.2 << 4) as u8;
Ok((low_byte, high_byte))
}
......
......@@ -29,23 +29,23 @@ pub enum InstructionToken {
#[derive(Debug, PartialEq)]
pub enum InstructionStatement<'a> {
AddReg(&'a str, &'a str, &'a str),
AddImm(&'a str, isize),
Sub(&'a str, &'a str, &'a str),
SetTarget(&'a str, Option<&'a str>, isize),
LoadReg(&'a str, &'a str, &'a str),
LoadImm(&'a str, Option<&'a str>, isize),
StoreReg(&'a str, &'a str, &'a str),
StoreImm(&'a str, Option<&'a str>, isize),
JumpImm(Option<&'a str>, isize),
JumpReg(&'a str, isize),
BranchEqualZero(&'a str, Option<&'a str>, isize),
BranchGreaterZero(&'a str, Option<&'a str>, isize),
ShiftLeft(&'a str, &'a str, isize),
ShiftRight(&'a str, &'a str, isize),
BoolTable(&'a str, &'a str, isize),
AddReg((&'a str, &'a str, &'a str)),
AddImm((&'a str, isize)),
Sub((&'a str, &'a str, &'a str)),
SetTarget((&'a str, Option<&'a str>, isize)),
LoadReg((&'a str, &'a str, &'a str)),
LoadImm((&'a str, Option<&'a str>, isize)),
StoreReg((&'a str, &'a str, &'a str)),
StoreImm((&'a str, Option<&'a str>, isize)),
JumpImm((Option<&'a str>, isize)),
JumpReg((&'a str, isize)),
BranchEqualZero((&'a str, Option<&'a str>, isize)),
BranchGreaterZero((&'a str, Option<&'a str>, isize)),
ShiftLeft((&'a str, &'a str, isize)),
ShiftRight((&'a str, &'a str, isize)),
BoolTable((&'a str, &'a str, isize)),
Stop,
Data(isize, Option<&'a str>),
Data((isize, Option<&'a str>)),
}
impl Display for InstructionToken {
......
......@@ -82,15 +82,15 @@ fn create_add_statement<'a>(
if let Token::Identifier(second) = tokens[2] {
assert_len(line_number, tokens.len() - 1, 3, None)?;
let third = extract_identifier(line_number, 3, tokens)?;
Ok(Statement::Instruction(InstructionStatement::AddReg(
Ok(Statement::Instruction(InstructionStatement::AddReg((
first, second, third,
)))
))))
} else if let Token::Number(second) = tokens[2] {
assert_len(line_number, tokens.len() - 1, 2, None)?;
assert_range(line_number, second, 8, true)?;
Ok(Statement::Instruction(InstructionStatement::AddImm(
Ok(Statement::Instruction(InstructionStatement::AddImm((
first, second,
)))
))))
} else {
Err(Error {
line_number,
......@@ -112,9 +112,9 @@ fn create_sub_statement<'a>(
let first = extract_identifier(line_number, 1, tokens)?;
let second = extract_identifier(line_number, 2, tokens)?;
let third = extract_identifier(line_number, 3, tokens)?;
Ok(Statement::Instruction(InstructionStatement::Sub(
Ok(Statement::Instruction(InstructionStatement::Sub((
first, second, third,
)))
))))
}
fn create_set_target_statement<'a>(
......@@ -124,9 +124,9 @@ fn create_set_target_statement<'a>(
assert_len(line_number, tokens.len() - 1, 2, Some(3))?;
let first = extract_identifier(line_number, 1, tokens)?;
let (second, third) = extract_target(line_number, 2, tokens)?;
Ok(Statement::Instruction(InstructionStatement::SetTarget(
Ok(Statement::Instruction(InstructionStatement::SetTarget((
first, second, third,
)))
))))
}
fn create_load_statement<'a>(
......@@ -138,14 +138,14 @@ fn create_load_statement<'a>(
if let Token::Identifier(second) = tokens[2] {
assert_len(line_number, tokens.len() - 1, 3, None)?;
let third = extract_identifier(line_number, 3, tokens)?;
Ok(Statement::Instruction(InstructionStatement::LoadReg(
Ok(Statement::Instruction(InstructionStatement::LoadReg((
first, second, third,
)))
))))
} else {
let (second, third) = extract_target(line_number, 2, tokens)?;
Ok(Statement::Instruction(InstructionStatement::LoadImm(
Ok(Statement::Instruction(InstructionStatement::LoadImm((
first, second, third,
)))
))))
}
}
......@@ -158,14 +158,14 @@ fn create_store_statement<'a>(
if let Token::Identifier(second) = tokens[2] {
assert_len(line_number, tokens.len() - 1, 3, None)?;
let third = extract_identifier(line_number, 3, tokens)?;
Ok(Statement::Instruction(InstructionStatement::StoreReg(
Ok(Statement::Instruction(InstructionStatement::StoreReg((
first, second, third,
)))
))))
} else {
let (second, third) = extract_target(line_number, 2, tokens)?;
Ok(Statement::Instruction(InstructionStatement::StoreImm(
Ok(Statement::Instruction(InstructionStatement::StoreImm((
first, second, third,
)))
))))
}
}
......@@ -177,9 +177,9 @@ fn create_jump_statement<'a>(
if let Token::Identifier(first) = tokens[1] {
if tokens.len() - 1 == 2 {
if let Token::Number(second) = tokens[2] {
Ok(Statement::Instruction(InstructionStatement::JumpReg(
Ok(Statement::Instruction(InstructionStatement::JumpReg((
first, second,
)))
))))
} else {
Err(Error {
line_number,
......@@ -192,15 +192,15 @@ fn create_jump_statement<'a>(
})
}
} else {
Ok(Statement::Instruction(InstructionStatement::JumpReg(
Ok(Statement::Instruction(InstructionStatement::JumpReg((
first, 0,
)))
))))
}
} else {
let (first, second) = extract_target(line_number, 1, tokens)?;
Ok(Statement::Instruction(InstructionStatement::JumpImm(
Ok(Statement::Instruction(InstructionStatement::JumpImm((
first, second,
)))
))))
}
}
......@@ -212,7 +212,7 @@ fn create_branch_equal_zero_statement<'a>(
let first = extract_identifier(line_number, 1, tokens)?;
let (second, third) = extract_target(line_number, 2, tokens)?;
Ok(Statement::Instruction(
InstructionStatement::BranchEqualZero(first, second, third),
InstructionStatement::BranchEqualZero((first, second, third)),
))
}
......@@ -224,7 +224,7 @@ fn create_branch_greater_zero_statement<'a>(
let first = extract_identifier(line_number, 1, tokens)?;
let (second, third) = extract_target(line_number, 2, tokens)?;
Ok(Statement::Instruction(
InstructionStatement::BranchGreaterZero(first, second, third),
InstructionStatement::BranchGreaterZero((first, second, third)),
))
}
......@@ -237,9 +237,9 @@ fn create_shift_left_statement<'a>(
let second = extract_identifier(line_number, 2, tokens)?;
let third = extract_number(line_number, 3, tokens)?;
assert_range(line_number, third, 4, false)?;
Ok(Statement::Instruction(InstructionStatement::ShiftLeft(
Ok(Statement::Instruction(InstructionStatement::ShiftLeft((
first, second, third,
)))
))))
}
fn create_shift_right_statement<'a>(
......@@ -251,9 +251,9 @@ fn create_shift_right_statement<'a>(
let second = extract_identifier(line_number, 2, tokens)?;
let third = extract_number(line_number, 3, tokens)?;
assert_range(line_number, third, 4, false)?;
Ok(Statement::Instruction(InstructionStatement::ShiftRight(
Ok(Statement::Instruction(InstructionStatement::ShiftRight((
first, second, third,
)))
))))
}
fn create_bool_table_statement<'a>(
......@@ -265,9 +265,9 @@ fn create_bool_table_statement<'a>(
let second = extract_identifier(line_number, 2, tokens)?;
let third = extract_number(line_number, 3, tokens)?;
assert_range(line_number, third, 4, false)?;
Ok(Statement::Instruction(InstructionStatement::BoolTable(
Ok(Statement::Instruction(InstructionStatement::BoolTable((
first, second, third,
)))
))))
}
fn create_stop_statement<'a>(
......@@ -290,9 +290,9 @@ fn create_data_statement<'a>(
None
};
Ok(Statement::Instruction(InstructionStatement::Data(
Ok(Statement::Instruction(InstructionStatement::Data((
first, second,
)))
))))
}
fn assert_len(
......@@ -374,11 +374,7 @@ fn extract_identifier<'a>(
}
}
fn extract_number(
line_number: usize,
position: usize,
tokens: &[Token],
) -> Result<isize, Error> {
fn extract_number(line_number: usize, position: usize, tokens: &[Token]) -> Result<isize, Error> {
if let Token::Number(value) = tokens[position] {
Ok(value)
} else {
......@@ -483,9 +479,9 @@ mod tests {
];
assert_eq!(
Ok(Statement::Instruction(InstructionStatement::AddReg(
Ok(Statement::Instruction(InstructionStatement::AddReg((
"example1", "example2", "example3"
))),
)))),
parse_line(0, &test_line)
);
}
......@@ -499,9 +495,9 @@ mod tests {
];
assert_eq!(
Ok(Statement::Instruction(InstructionStatement::AddImm(
Ok(Statement::Instruction(InstructionStatement::AddImm((
"example1", -42
))),
)))),
parse_line(0, &test_line)
);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment