cargo fmt
This commit is contained in:
17
src/asm.rs
17
src/asm.rs
@@ -1,19 +1,19 @@
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum Argument {
|
pub enum Argument {
|
||||||
MemoryLocation(u8),
|
MemoryLocation(u8),
|
||||||
Constant(u8)
|
Constant(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Label<'a>{
|
pub struct Label<'a> {
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
pub location: u8
|
pub location: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum JumpArgument<'a> {
|
pub enum JumpArgument<'a> {
|
||||||
Location(u8),
|
Location(u8),
|
||||||
Label(&'a str)
|
Label(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
@@ -22,25 +22,24 @@ pub enum Instruction<'a> {
|
|||||||
MemoryLocationInstruction(MemoryLocationInstruction, Option<Label<'a>>),
|
MemoryLocationInstruction(MemoryLocationInstruction, Option<Label<'a>>),
|
||||||
ConstantArgumentInstruction(ConstantArgumentInstruction, Option<Label<'a>>),
|
ConstantArgumentInstruction(ConstantArgumentInstruction, Option<Label<'a>>),
|
||||||
ArgumentInstruction(ArgumentInstruction, Option<Label<'a>>),
|
ArgumentInstruction(ArgumentInstruction, Option<Label<'a>>),
|
||||||
Jump(JumpArgument<'a>, Option<Label<'a>>)
|
Jump(JumpArgument<'a>, Option<Label<'a>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum NoArgumentInstruction {
|
pub enum NoArgumentInstruction {
|
||||||
NOP
|
NOP,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum MemoryLocationInstruction {
|
pub enum MemoryLocationInstruction {
|
||||||
STA(u8)
|
STA(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum ConstantArgumentInstruction {
|
pub enum ConstantArgumentInstruction {
|
||||||
BRZ(u8),
|
BRZ(u8),
|
||||||
BRC(u8),
|
BRC(u8),
|
||||||
BRN(u8)
|
BRN(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -1,16 +1,14 @@
|
|||||||
use std::fs;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate pest_derive;
|
extern crate pest_derive;
|
||||||
|
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
|
||||||
|
|
||||||
mod asm;
|
mod asm;
|
||||||
mod parse;
|
|
||||||
mod generate;
|
mod generate;
|
||||||
|
mod parse;
|
||||||
|
|
||||||
use parse::{parse_asm, AsmParser};
|
use parse::{parse_asm, AsmParser};
|
||||||
|
|
||||||
@@ -27,6 +25,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let instructions = parse_asm(AsmParser::parse(parse::Rule::program, &file_content).unwrap_or_else(|e| panic!("{}", e)));
|
let instructions = parse_asm(
|
||||||
|
AsmParser::parse(parse::Rule::program, &file_content).unwrap_or_else(|e| panic!("{}", e)),
|
||||||
|
);
|
||||||
println!("{:#?}", instructions);
|
println!("{:#?}", instructions);
|
||||||
}
|
}
|
||||||
|
|||||||
116
src/parse.rs
116
src/parse.rs
@@ -17,7 +17,11 @@ pub fn parse_asm<'a>(pairs: Pairs<'a, Rule>) -> Vec<Instruction<'a>> {
|
|||||||
// Second can only be Some if we have a label, thus second must be the
|
// Second can only be Some if we have a label, thus second must be the
|
||||||
// instruction if that is the case.
|
// instruction if that is the case.
|
||||||
if second.is_some() {
|
if second.is_some() {
|
||||||
instruction.push(parse_instruction(second.unwrap(), first, instruction_counter));
|
instruction.push(parse_instruction(
|
||||||
|
second.unwrap(),
|
||||||
|
first,
|
||||||
|
instruction_counter,
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
instruction.push(parse_instruction(first.unwrap(), None, instruction_counter));
|
instruction.push(parse_instruction(first.unwrap(), None, instruction_counter));
|
||||||
}
|
}
|
||||||
@@ -32,7 +36,11 @@ pub fn parse_asm<'a>(pairs: Pairs<'a, Rule>) -> Vec<Instruction<'a>> {
|
|||||||
instruction
|
instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_instruction<'a>(instruction: Pair<'a, Rule>, label: Option<Pair<'a, Rule>>, instruction_counter: u8) -> Instruction<'a>{
|
fn parse_instruction<'a>(
|
||||||
|
instruction: Pair<'a, Rule>,
|
||||||
|
label: Option<Pair<'a, Rule>>,
|
||||||
|
instruction_counter: u8,
|
||||||
|
) -> Instruction<'a> {
|
||||||
let label = label.map(|l| parse_label(l, instruction_counter));
|
let label = label.map(|l| parse_label(l, instruction_counter));
|
||||||
let mut instruction = instruction.into_inner();
|
let mut instruction = instruction.into_inner();
|
||||||
let mnemonic = instruction.next().unwrap();
|
let mnemonic = instruction.next().unwrap();
|
||||||
@@ -41,61 +49,91 @@ fn parse_instruction<'a>(instruction: Pair<'a, Rule>, label: Option<Pair<'a, Rul
|
|||||||
Rule::no_arg_instruction => parse_no_arg_instruction(mnemonic, label),
|
Rule::no_arg_instruction => parse_no_arg_instruction(mnemonic, label),
|
||||||
Rule::arg_instruction => {
|
Rule::arg_instruction => {
|
||||||
parse_arg_instruction(mnemonic, instruction.next().unwrap(), label)
|
parse_arg_instruction(mnemonic, instruction.next().unwrap(), label)
|
||||||
},
|
}
|
||||||
Rule::jump_instruction => {
|
Rule::jump_instruction => {
|
||||||
parse_jump_instruction(mnemonic, instruction.next().unwrap(), label)
|
parse_jump_instruction(mnemonic, instruction.next().unwrap(), label)
|
||||||
},
|
}
|
||||||
Rule::memory_location_instruction => {
|
Rule::memory_location_instruction => {
|
||||||
parse_memory_location_instruction(mnemonic, instruction.next().unwrap(), label)
|
parse_memory_location_instruction(mnemonic, instruction.next().unwrap(), label)
|
||||||
},
|
}
|
||||||
Rule::constant_arg_instruction => {
|
Rule::constant_arg_instruction => {
|
||||||
parse_constant_arg_instruction(mnemonic, instruction.next().unwrap(), label)
|
parse_constant_arg_instruction(mnemonic, instruction.next().unwrap(), label)
|
||||||
},
|
}
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_no_arg_instruction<'a>(instruction: Pair<'a, Rule>, label: Option<Label<'a>>) -> Instruction<'a> {
|
fn parse_no_arg_instruction<'a>(
|
||||||
|
instruction: Pair<'a, Rule>,
|
||||||
|
label: Option<Label<'a>>,
|
||||||
|
) -> Instruction<'a> {
|
||||||
match instruction.as_str() {
|
match instruction.as_str() {
|
||||||
"NOP" => Instruction::NoArgumentInstruction(NoArgumentInstruction::NOP, label),
|
"NOP" => Instruction::NoArgumentInstruction(NoArgumentInstruction::NOP, label),
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_arg_instruction<'a>(instruction: Pair<'a, Rule>, arg: Pair<'a, Rule>, label: Option<Label<'a>>) -> Instruction<'a> {
|
fn parse_arg_instruction<'a>(
|
||||||
|
instruction: Pair<'a, Rule>,
|
||||||
|
arg: Pair<'a, Rule>,
|
||||||
|
label: Option<Label<'a>>,
|
||||||
|
) -> Instruction<'a> {
|
||||||
let arg = parse_argument(arg);
|
let arg = parse_argument(arg);
|
||||||
match instruction.as_str() {
|
match instruction.as_str() {
|
||||||
"LDA" => Instruction::ArgumentInstruction(ArgumentInstruction::LDA(arg), label),
|
"LDA" => Instruction::ArgumentInstruction(ArgumentInstruction::LDA(arg), label),
|
||||||
"ADD" => Instruction::ArgumentInstruction(ArgumentInstruction::ADD(arg), label),
|
"ADD" => Instruction::ArgumentInstruction(ArgumentInstruction::ADD(arg), label),
|
||||||
"SUB" => Instruction::ArgumentInstruction(ArgumentInstruction::SUB(arg), label),
|
"SUB" => Instruction::ArgumentInstruction(ArgumentInstruction::SUB(arg), label),
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_jump_instruction<'a>(instruction: Pair<'a, Rule>, arg: Pair<'a, Rule>, label: Option<Label<'a>>) -> Instruction<'a> {
|
fn parse_jump_instruction<'a>(
|
||||||
|
instruction: Pair<'a, Rule>,
|
||||||
|
arg: Pair<'a, Rule>,
|
||||||
|
label: Option<Label<'a>>,
|
||||||
|
) -> Instruction<'a> {
|
||||||
let arg = parse_jump_argument(arg);
|
let arg = parse_jump_argument(arg);
|
||||||
match instruction.as_str() {
|
match instruction.as_str() {
|
||||||
"JMP" => Instruction::Jump(arg, label),
|
"JMP" => Instruction::Jump(arg, label),
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_memory_location_instruction<'a>(instruction: Pair<'a, Rule>, arg: Pair<'a, Rule>,label: Option<Label<'a>>) -> Instruction<'a> {
|
|
||||||
let arg_string = arg.as_str();
|
|
||||||
let arg_value = u8::from_str_radix(&arg_string[1..arg_string.len()-1], 16).unwrap();
|
|
||||||
match instruction.as_str() {
|
|
||||||
"STA" => Instruction::MemoryLocationInstruction(MemoryLocationInstruction::STA(arg_value), label),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_constant_arg_instruction<'a>(instruction: Pair<'a, Rule>, arg: Pair<'a, Rule>, label: Option<Label<'a>>) -> Instruction<'a> {
|
fn parse_memory_location_instruction<'a>(
|
||||||
|
instruction: Pair<'a, Rule>,
|
||||||
|
arg: Pair<'a, Rule>,
|
||||||
|
label: Option<Label<'a>>,
|
||||||
|
) -> Instruction<'a> {
|
||||||
|
let arg_string = arg.as_str();
|
||||||
|
let arg_value = u8::from_str_radix(&arg_string[1..arg_string.len() - 1], 16).unwrap();
|
||||||
|
match instruction.as_str() {
|
||||||
|
"STA" => {
|
||||||
|
Instruction::MemoryLocationInstruction(MemoryLocationInstruction::STA(arg_value), label)
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_constant_arg_instruction<'a>(
|
||||||
|
instruction: Pair<'a, Rule>,
|
||||||
|
arg: Pair<'a, Rule>,
|
||||||
|
label: Option<Label<'a>>,
|
||||||
|
) -> Instruction<'a> {
|
||||||
let arg_value = u8::from_str_radix(&arg.as_str()[1..], 16).unwrap();
|
let arg_value = u8::from_str_radix(&arg.as_str()[1..], 16).unwrap();
|
||||||
match instruction.as_str() {
|
match instruction.as_str() {
|
||||||
"BRZ" => Instruction::ConstantArgumentInstruction(ConstantArgumentInstruction::BRZ(arg_value), label),
|
"BRZ" => Instruction::ConstantArgumentInstruction(
|
||||||
"BRC" => Instruction::ConstantArgumentInstruction(ConstantArgumentInstruction::BRC(arg_value), label),
|
ConstantArgumentInstruction::BRZ(arg_value),
|
||||||
"BRN" => Instruction::ConstantArgumentInstruction(ConstantArgumentInstruction::BRN(arg_value), label),
|
label,
|
||||||
_ => unreachable!()
|
),
|
||||||
|
"BRC" => Instruction::ConstantArgumentInstruction(
|
||||||
|
ConstantArgumentInstruction::BRC(arg_value),
|
||||||
|
label,
|
||||||
|
),
|
||||||
|
"BRN" => Instruction::ConstantArgumentInstruction(
|
||||||
|
ConstantArgumentInstruction::BRN(arg_value),
|
||||||
|
label,
|
||||||
|
),
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,26 +142,24 @@ fn parse_argument<'a>(argument: Pair<'a, Rule>) -> Argument {
|
|||||||
match argument.as_rule() {
|
match argument.as_rule() {
|
||||||
Rule::memory_location => {
|
Rule::memory_location => {
|
||||||
let arg_string = argument.as_str();
|
let arg_string = argument.as_str();
|
||||||
let arg_value = u8::from_str_radix(&arg_string[1..arg_string.len()-1], 16).unwrap();
|
let arg_value = u8::from_str_radix(&arg_string[1..arg_string.len() - 1], 16).unwrap();
|
||||||
Argument::MemoryLocation(arg_value)
|
Argument::MemoryLocation(arg_value)
|
||||||
},
|
}
|
||||||
Rule::digit_literal => {
|
Rule::digit_literal => {
|
||||||
let arg_value = u8::from_str_radix(&argument.as_str()[1..], 16).unwrap();
|
let arg_value = u8::from_str_radix(&argument.as_str()[1..], 16).unwrap();
|
||||||
Argument::Constant(arg_value)
|
Argument::Constant(arg_value)
|
||||||
},
|
}
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_label<'a>(label: Pair<'a, Rule>, instruction_counter: u8) -> Label<'a> {
|
fn parse_label<'a>(label: Pair<'a, Rule>, instruction_counter: u8) -> Label<'a> {
|
||||||
match label.as_rule() {
|
match label.as_rule() {
|
||||||
Rule::label => {
|
Rule::label => Label {
|
||||||
Label {
|
name: label.as_str(),
|
||||||
name: label.as_str(),
|
location: instruction_counter,
|
||||||
location: instruction_counter
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +167,9 @@ fn parse_jump_argument<'a>(arg: Pair<'a, Rule>) -> JumpArgument<'a> {
|
|||||||
let arg = arg.into_inner().next().unwrap();
|
let arg = arg.into_inner().next().unwrap();
|
||||||
match arg.as_rule() {
|
match arg.as_rule() {
|
||||||
Rule::label => JumpArgument::Label(arg.as_str()),
|
Rule::label => JumpArgument::Label(arg.as_str()),
|
||||||
Rule::jump_location => JumpArgument::Location(u8::from_str_radix(arg.as_str(), 16).unwrap()),
|
Rule::jump_location => {
|
||||||
_ => unreachable!()
|
JumpArgument::Location(u8::from_str_radix(arg.as_str(), 16).unwrap())
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user