Skip to content

Commit

Permalink
Add some error checking and move some of the returned items into a ho…
Browse files Browse the repository at this point in the history
…lding struct instead, to keep things cleaner.
  • Loading branch information
sciguyryan committed Jul 16, 2024
1 parent 58a2954 commit ca23d53
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 30 deletions.
61 changes: 32 additions & 29 deletions redox-core/src/parsing/asm_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ use std::{num::ParseIntError, str::FromStr};

use crate::{
ins::{
expression::{
Expression,
{ExpressionArgs::*, ExpressionOperator::*},
},
expression::{Expression, ExpressionArgs::*, ExpressionOperator::*},
instruction::Instruction,
op_codes::OpCode,
},
parsing::type_hints::{ArgTypeHint, InstructionLookup},
parsing::{
data_declaration::DataDeclarationType,
type_hints::{ArgTypeHint, InstructionLookup},
},
reg::registers::RegisterId,
};

use super::type_hints::InstructionHints;
use super::{data_declaration::DataDeclaration, type_hints::InstructionHints};

const F32_REGISTERS: [RegisterId; 2] = [RegisterId::FR1, RegisterId::FR2];

Expand Down Expand Up @@ -56,26 +56,6 @@ enum Argument {
Expression(Expression),
}

/// The supported data declaration command types.
#[derive(Debug, Clone)]
enum DataDeclarationType {
/// Declare a byte storage block.
DB,
}

impl TryFrom<&str> for DataDeclarationType {
type Error = ();

fn try_from(string: &str) -> Result<Self, Self::Error> {
match string.to_lowercase().as_str() {
"db" => Ok(DataDeclarationType::DB),
_ => {
panic!("invalid syntax - an unrecognized data declaration {string}");
}
}
}
}

/// The sections that can be found in an valid file.
enum FileSection {
/// The text (code) section of an assembly file.
Expand Down Expand Up @@ -138,13 +118,17 @@ pub struct AsmParser<'a> {

/// A vector of the parsed instructions.
pub parsed_instructions: Vec<Instruction>,

/// A vector of the parsed data declarations.
pub parsed_data_declarations: Vec<DataDeclaration>,
}

impl<'a> AsmParser<'a> {
pub fn new() -> Self {
Self {
hints: InstructionHints::new(),
parsed_instructions: vec![],
parsed_data_declarations: vec![],
}
}

Expand All @@ -155,6 +139,8 @@ impl<'a> AsmParser<'a> {
/// * `string` - The string to be parsed.
pub fn parse(&mut self, string: &str) {
let mut instructions = Vec::with_capacity(100);
let mut data_declarations = Vec::<DataDeclaration>::with_capacity(100);
let mut read_only_data_declarations = Vec::<DataDeclaration>::with_capacity(100);

// Convert newlines into a single type and automatically
// allow lines ending with a \ to be treated as a singular line.
Expand All @@ -177,12 +163,27 @@ impl<'a> AsmParser<'a> {
FileSection::Text => {
instructions.push(self.parse_code_line(line));
}
FileSection::Data => self.parse_data_line(line),
FileSection::ReadOnlyData => todo!(),
FileSection::Data => {
let (label, decl_type, bytes) = self.parse_data_line(line);

if data_declarations.iter().any(|d| d.label == label)
|| read_only_data_declarations.iter().any(|d| d.label == label)
{
panic!("invalid syntax - a duplicate label with the name of {label}.");
}

data_declarations.push(DataDeclaration::new(decl_type, label, bytes));
}
FileSection::ReadOnlyData => {
todo!();
}
}
}

self.parsed_instructions = instructions;
self.parsed_data_declarations = data_declarations;

println!("{:#?}", self.parsed_data_declarations);
}

/// Parse a code line of an assembly file.
Expand Down Expand Up @@ -394,7 +395,7 @@ impl<'a> AsmParser<'a> {
/// # Arguments
///
/// * `line` - A code line to be parsed.
fn parse_data_line(&mut self, line: &str) {
fn parse_data_line(&mut self, line: &str) -> (String, DataDeclarationType, Vec<u8>) {
use unicode_segmentation::UnicodeSegmentation;

let graphemes: Vec<&str> = line.graphemes(true).collect();
Expand Down Expand Up @@ -467,6 +468,8 @@ impl<'a> AsmParser<'a> {

println!("label = {label}, declaration_type = {declaration_type:?}, storage = {storage:?}");
//println!("{:?}", String::from_utf8(storage));

(label.clone(), declaration_type, storage)
}

/// Parse a section line of an ASM file.
Expand Down
39 changes: 39 additions & 0 deletions redox-core/src/parsing/data_declaration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#[derive(Debug, Clone)]
pub struct DataDeclaration {
/// The [`DataDeclarationType`].
pub declaration_type: DataDeclarationType,
/// The label associated with the statement.
pub label: String,
/// The stored bytes.
pub bytes: Vec<u8>,
}

impl DataDeclaration {
pub fn new(declaration_type: DataDeclarationType, label: String, bytes: Vec<u8>) -> Self {
Self {
declaration_type,
label,
bytes,
}
}
}

/// The supported data declaration statement types.
#[derive(Debug, Clone)]
pub enum DataDeclarationType {
/// Declare a byte storage block.
DB,
}

impl TryFrom<&str> for DataDeclarationType {
type Error = ();

fn try_from(string: &str) -> Result<Self, Self::Error> {
match string.to_lowercase().as_str() {
"db" => Ok(DataDeclarationType::DB),
_ => {
panic!("invalid syntax - an unrecognized data declaration {string}");
}
}
}
}
1 change: 1 addition & 0 deletions redox-core/src/parsing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod asm_parser;
mod data_declaration;
mod type_hints;
3 changes: 2 additions & 1 deletion redox-terminal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ fn main() {
}

let code = "section .data
banana db \"apples\",0xff
banana db \"apples\"
waffles db \"waffles\"
section .text
push 0
call :LABEL_1
Expand Down

0 comments on commit ca23d53

Please sign in to comment.