56 lines
1.9 KiB
Rust
56 lines
1.9 KiB
Rust
use crate::{
|
|
errors::ParseError,
|
|
stack::{Instruction, Stack},
|
|
};
|
|
|
|
pub fn parse(stack: &mut Stack, file_content: &str) {
|
|
for (i, line) in file_content.lines().enumerate() {
|
|
if line.trim().starts_with(';') || line.is_empty() {
|
|
continue;
|
|
}
|
|
|
|
let inst_line: String;
|
|
if let Some(comment_index) = line.trim().find(';') {
|
|
inst_line = line.trim().chars().take(comment_index).collect();
|
|
} else {
|
|
inst_line = line.trim().chars().collect();
|
|
}
|
|
|
|
let command: [String; 2] = inst_line.split_once(char::is_whitespace).map_or_else(
|
|
|| [inst_line.trim().to_string(), "".to_string()],
|
|
|(first, second)| [first.trim().to_string(), second.trim().to_string()],
|
|
);
|
|
|
|
let name: String = command[0].clone();
|
|
let mut arg: String = String::new();
|
|
let mut data: u16 = 0;
|
|
|
|
if !command[1].is_empty() {
|
|
if name.chars().nth(0) == Some('#') || name.chars().nth(1) == Some('#') {
|
|
let splited_data: Vec<String> =
|
|
command[1].split_whitespace().map(String::from).collect();
|
|
arg = splited_data.get(0).unwrap().clone();
|
|
} else if name.chars().nth(0) == Some('$') || name.chars().nth(1) == Some('$') {
|
|
arg = command[1].clone();
|
|
} else if let Ok(number) = command[1].parse::<i32>() {
|
|
data = number as u16;
|
|
} else {
|
|
eprintln!(
|
|
"{}",
|
|
ParseError::ArgumentNotRequired(
|
|
command[0].to_string(),
|
|
i + 1,
|
|
line.to_string()
|
|
)
|
|
);
|
|
std::process::exit(2);
|
|
}
|
|
}
|
|
|
|
if name != "" {
|
|
let inst = Instruction { name, arg, data };
|
|
stack.program.push(inst);
|
|
}
|
|
}
|
|
}
|