Skip to content

Commit

Permalink
feat(cli): 🎸 Add check command
Browse files Browse the repository at this point in the history
  • Loading branch information
kamack38 committed Feb 7, 2024
1 parent 42ee2d5 commit 972a220
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
42 changes: 39 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use ram_machine::error::ParserErrorChain;
use ram_machine::parser::Parser;
use ram_machine::ram_code::RamCode;
use std::ops::Add;
use std::path::PathBuf;
use std::{fs, io};
use thiserror::Error;
Expand All @@ -7,9 +11,9 @@ use ram_machine::{
parser::ParserError,
};

use clap::{Parser, Subcommand};
use clap::{Parser as ClapParser, Subcommand};

#[derive(Parser, Debug)]
#[derive(ClapParser, Debug)]
#[command(author, version, about, long_about = None)]
struct Cli {
/// Specifies the path to the input file from which data will be read (input passed from the command line takes precedence)
Expand All @@ -32,7 +36,9 @@ struct Cli {
pub enum Commands {
/// Run ram machine code from file
Run { file: PathBuf, input: Vec<i64> },
// Check { file: PathBuf },

/// Validates ram code syntax of a given file
Check { file: PathBuf },
// Repl,
// Debug,
}
Expand All @@ -56,6 +62,9 @@ pub enum RuntimeError {

#[error("Could not write output to file: '{0}'")]
WriteOutputFileError(io::Error),

#[error("{0}")]
CheckFileError(ParserErrorChain),
}

pub fn app() -> Result<(), RuntimeError> {
Expand Down Expand Up @@ -96,6 +105,33 @@ pub fn app() -> Result<(), RuntimeError> {
.map_err(|e| RuntimeError::WriteOutputFileError(e))?;
}
}
Commands::Check { file } => {
let unparsed_file =
fs::read_to_string(file).map_err(|e| RuntimeError::ReadCodeError(e))?;
let parser = Parser::new();
let mut errors = ParserErrorChain::new();

let mut code = RamCode::new();
let lines = unparsed_file.lines().into_iter().enumerate();
for (index, line) in lines {
if line.is_empty() {
continue;
};
parser.parse_line(line, &mut code).unwrap_or_else(|err| {
errors.add((
index
.add(1)
.try_into()
.expect("Could not convert the line number to u32"),
err,
))
});
}

if !errors.is_empty() {
return Err(RuntimeError::CheckFileError(errors));
}
}
};
Ok(())
}
45 changes: 45 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::parser::ParserError;

pub struct ParserErrorChain(Vec<(u32, ParserError)>);

impl ParserErrorChain {
pub fn new() -> Self {
Self(Vec::new())
}

pub fn add(&mut self, (line, err): (u32, ParserError)) {
self.0.push((line, err))
}

pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}

impl std::fmt::Debug for ParserErrorChain {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut output: String = "".to_string();
for (line, err) in &self.0 {
output.push_str(&format!(
"At line {} found error: {}\n",
line.to_string(),
err
));
}
write!(f, "{}", output)
}
}

impl std::fmt::Display for ParserErrorChain {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut output: String = "".to_string();
for (line, err) in &self.0 {
output.push_str(&format!(
"At line {} found error: {}\n",
line.to_string(),
err
));
}
write!(f, "{}", output)
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod error;
pub mod interpreter;
pub mod parser;

Expand Down

0 comments on commit 972a220

Please sign in to comment.