Skip to content

Commit

Permalink
Initial work on the data section parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
sciguyryan committed Jul 9, 2024
1 parent cc6eab4 commit c321524
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ rand_xoshiro = "0.6.0"
strum = "0.26.3"
strum_macros = "0.26.4"
thiserror = "1.0.61"
unescape = "0.1.0"
unicode-segmentation = "1.11.0"
winres = "0.1.12"

[profile.dev]
Expand Down
2 changes: 2 additions & 0 deletions redox-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ rand.workspace = true
rand_xoshiro.workspace = true
strum.workspace = true
strum_macros.workspace = true
unescape.workspace = true
unicode-segmentation.workspace = true
thiserror.workspace = true

[dev-dependencies]
Expand Down
80 changes: 79 additions & 1 deletion redox-core/src/parsing/asm_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl<'a> AsmParser<'a> {
FileSection::Text => {
instructions.push(self.parse_code_line(line));
}
FileSection::Data => todo!(),
FileSection::Data => self.parse_data_line(line),
FileSection::ReadOnlyData => todo!(),
}
}
Expand Down Expand Up @@ -369,6 +369,68 @@ impl<'a> AsmParser<'a> {
AsmParser::try_build_instruction(final_option.opcode, &arguments, label)
}

/// Parse a data line of an assembly file.
///
/// # Arguments
///
/// * `line` - A code line to be parsed.
fn parse_data_line(&mut self, line: &str) {
use unicode_segmentation::UnicodeSegmentation;

let graphemes: Vec<&str> = line.graphemes(true).collect();

let mut in_quoted_string = false;

let mut escaped_args = vec![];
let mut buffer = String::new();
for (i, g) in graphemes.iter().enumerate() {
let is_escaped = i > 0 && graphemes[i - 1] == "\\";

if !is_escaped && (*g == "\"" || *g == "'") {
// We have reached the end of a quoted segment.
if in_quoted_string {
AsmParser::push_buffer_if_not_empty(&mut buffer, &mut escaped_args);
}

in_quoted_string = !in_quoted_string;
continue;
}

if !in_quoted_string && (*g == " " || *g == "\t" || *g == ",") {
// We have reached the end of a segment.
if !buffer.is_empty() {
AsmParser::push_buffer_if_not_empty(&mut buffer, &mut escaped_args);
}

continue;
}

buffer.push_str(g);
}

assert!(
!in_quoted_string,
"invalid syntax - closing quotation mark not present for line: {line}."
);

// Push the final argument to the list.
AsmParser::push_buffer_if_not_empty(&mut buffer, &mut escaped_args);

assert!(
escaped_args.len() >= 3,
"invalid syntax - insufficient arguments for line: {line}."
);

// Now we want to ensure we correctly handle any escape sequences.
let mut arguments = vec![];
for argument in escaped_args {
let un = unescape::unescape(&argument).unwrap_or(argument);
arguments.push(un);
}

println!("{arguments:?}");
}

/// Parse a section line of an ASM file.
///
/// # Arguments
Expand All @@ -389,6 +451,22 @@ impl<'a> AsmParser<'a> {
}
}

/// Push a string buffer onto an string argument vector.
///
/// # Arguments
///
/// * `arg` - The argument string.
/// * `vec` - The vector that the argument should be pushed too, if it isn't empty.
#[inline]
fn push_buffer_if_not_empty(arg: &mut String, vec: &mut Vec<String>) {
if arg.is_empty() {
return;
}

vec.push(arg.clone());
arg.clear();
}

/// Try to build an [`Instruction`] from an [`OpCode`] and a set of arguments.
///
/// # Arguments
Expand Down
10 changes: 9 additions & 1 deletion redox-terminal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,15 @@ fn main() {
panic!("currently unsupported");
}

let code = "section .text\r\npush 0\r\ncall :LABEL_1\r\nhlt\r\n:LABEL_1\r\nmov 0xdeadbeef, EAX\r\niret";
let code = "section .data
banana db \"apples\"
section .text
push 0
call :LABEL_1
hlt
:LABEL_1
mov 0xdeadbeef, EAX
iret";
let mut compiler = Compiler::new();
let data = compiler.compile_assembly(code, true);

Expand Down

0 comments on commit c321524

Please sign in to comment.