Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6ed3128
commit 0ee230e
Showing
12 changed files
with
240 additions
and
87 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use clap::{Parser, Subcommand}; | ||
use clap_verbosity_flag::Verbosity; | ||
|
||
use crate::{run::RunOpts, transpile::TranspileOpts}; | ||
|
||
#[derive(Parser, Debug)] | ||
#[clap(name = "Brainease")] | ||
#[clap(about = "A brainf*ck-style programming language, but readable")] | ||
pub struct Cli { | ||
#[clap(subcommand)] | ||
pub command: Commands, | ||
|
||
#[clap(flatten)] | ||
pub verbose: Verbosity, | ||
} | ||
|
||
#[derive(Subcommand, Debug)] | ||
pub enum Commands { | ||
Transpile(TranspileOpts), | ||
Run(RunOpts), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,22 @@ | ||
use brainease_lexer::parser; | ||
use brainease_runtime::{io_handler::DefaultIoHandler, runtime::Runtime}; | ||
mod cli; | ||
mod run; | ||
mod transpile; | ||
mod util; | ||
|
||
use clap::Parser; | ||
use std::{ | ||
io::{stdout, Result, Write}, | ||
path::Path, | ||
process, | ||
}; | ||
use cli::{Cli, Commands}; | ||
|
||
pub mod args; | ||
pub mod reader; | ||
pub mod util; | ||
fn main() { | ||
let args = Cli::parse(); | ||
|
||
fn main() -> Result<()> { | ||
let args = args::Args::parse(); | ||
util::fallback_rust_log(&args.log_level); | ||
util::setup_logger(&args.verbose); | ||
|
||
log::trace!("Cli args: {:?}", args); | ||
let result = match &args.command { | ||
Commands::Transpile(opts) => transpile::run(opts), | ||
Commands::Run(opts) => run::run(opts), | ||
}; | ||
|
||
if !args.main.ends_with(".brain") { | ||
log::error!("{} does not end with .brain", args.main); | ||
process::exit(1); | ||
if let Err(err) = result { | ||
log::trace!("{:#?}", err) | ||
} | ||
|
||
let path = Path::new(&args.main); | ||
|
||
let main_file = reader::read_file(path); | ||
let instructions = parser::parse_file(&main_file); | ||
|
||
log::trace!("Instructions: {:?}", instructions); | ||
|
||
let mut runtime = Runtime::new(instructions, args.memory, DefaultIoHandler {}); | ||
|
||
log::debug!("Starting runtime"); | ||
|
||
// A little space between stdout | ||
let elapsed_time = runtime.run()?; | ||
|
||
stdout().write_all(b"\n").unwrap(); | ||
|
||
log::debug!("Elapsed time: {}s.", elapsed_time.as_secs_f64()); | ||
|
||
Ok(()) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use std::{ | ||
io::{self, stdout, Write}, | ||
path::Path, | ||
}; | ||
|
||
use brainease_lexer::parser; | ||
use brainease_runtime::{ | ||
io_handler::{DefaultIoHandler, IoHandler}, | ||
runtime::Runtime, | ||
}; | ||
use clap::Parser; | ||
|
||
use crate::util; | ||
|
||
#[derive(Parser, Debug)] | ||
#[clap(name = "run", about = "Run Brainease source code")] | ||
pub struct RunOpts { | ||
/// The main brainease file to run | ||
#[clap(short = 'f', long = "file")] | ||
main: String, | ||
|
||
/// The length to initialize the memory array | ||
#[clap(short = 'm', long = "memory", default_value = "3000")] | ||
memory_length: usize, | ||
} | ||
|
||
pub fn run(opts: &RunOpts) -> io::Result<()> { | ||
let main = Path::new(&opts.main); | ||
|
||
// Checks for .main file format | ||
if !opts.main.ends_with(".brain") { | ||
log::error!( | ||
"{:?} has an unknown file format of {:?}", | ||
main.file_name().unwrap(), | ||
main.extension().unwrap() | ||
); | ||
|
||
return Ok(()); | ||
} | ||
|
||
let main_content = util::read_file(main)?; | ||
|
||
log::trace!("Parsing {}", main.display()); | ||
|
||
let instructions = parser::parse_file(&main_content); | ||
|
||
log::trace!("{:#?}", instructions); | ||
|
||
let mut runtime = Runtime::new(instructions, opts.memory_length, DefaultIoHandler {}); | ||
|
||
start_runtime(&mut runtime)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn start_runtime<I>(runtime: &mut Runtime<I>) -> Result<(), I::Err> | ||
where | ||
I: IoHandler, | ||
{ | ||
log::debug!("Starting runtime"); | ||
|
||
let elapsed_time = runtime.run()?; | ||
|
||
// Prints suffix | ||
stdout().write_all(b"\n").unwrap(); | ||
|
||
log::debug!("Elapsed time: {}s.", elapsed_time.as_secs_f64()); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use std::{io, path::Path}; | ||
|
||
use brainease_runtime::io_handler::DefaultIoHandler; | ||
use brainease_runtime::runtime::Runtime; | ||
use brainease_transpiler::as_string::AsString; | ||
use brainease_transpiler::parser; | ||
use clap::Parser; | ||
|
||
use crate::run::start_runtime; | ||
use crate::util; | ||
|
||
#[derive(Parser, Debug)] | ||
#[clap( | ||
name = "transpile", | ||
about = "Transpile Brainease source code to Brainfuck" | ||
)] | ||
pub struct TranspileOpts { | ||
/// The bf source file to transpile | ||
#[clap(short = 'f', long = "file")] | ||
main: String, | ||
|
||
/// The output file to write | ||
#[clap(short = 'o', long = "output")] | ||
output: Option<String>, | ||
|
||
#[clap(short = 'r', long = "run", help = "Run the transpiled code")] | ||
run_after: bool, | ||
|
||
#[clap( | ||
long = "memory", | ||
help = "The memory length when -r is used", | ||
default_value = "3000" | ||
)] | ||
memory_length: usize, | ||
} | ||
|
||
pub fn run(opts: &TranspileOpts) -> io::Result<()> { | ||
let main = Path::new(&opts.main); | ||
let main_content = util::read_file(main)?; | ||
|
||
log::trace!("Transpiling {}", main.display()); | ||
|
||
let transpiled = parser::parse_bf(&main_content); | ||
|
||
log::trace!("{:#?}", transpiled); | ||
|
||
let output_name = &opts.output.clone().unwrap_or_else(|| { | ||
if opts.main.ends_with(".bf") { | ||
opts.main.replace(".bf", ".brain") | ||
} else { | ||
format!("{}.brain", opts.main) | ||
} | ||
}); | ||
|
||
let string_lines = AsString::all(&transpiled, 0); | ||
|
||
util::write_file(Path::new(output_name), string_lines)?; | ||
|
||
if opts.run_after { | ||
let mut runtime = Runtime::new(transpiled, opts.memory_length, DefaultIoHandler {}); | ||
|
||
start_runtime(&mut runtime)?; | ||
} | ||
|
||
Ok(()) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use clap_verbosity_flag::Verbosity; | ||
|
||
pub fn setup_logger(verbose: &Verbosity) { | ||
env_logger::builder() | ||
.filter_level(verbose.log_level_filter()) | ||
.format_indent(None) | ||
.format_module_path(false) | ||
.format_target(false) | ||
.format_timestamp(None) | ||
.init(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
mod logger; | ||
mod reader; | ||
|
||
pub use logger::*; | ||
pub use reader::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use std::{fs, io, path::Path}; | ||
|
||
pub fn read_file(path: &Path) -> io::Result<String> { | ||
log::trace!("Reading {}", path.display()); | ||
|
||
let content = fs::read_to_string(path); | ||
|
||
if let Err(err) = &content { | ||
log::error!("Could not find {}", path.display()); | ||
log::trace!("{:#?}", err); | ||
} | ||
|
||
content | ||
} | ||
|
||
pub fn write_file(path: &Path, contents: Vec<String>) -> io::Result<()> { | ||
log::trace!("Writing {}", path.display()); | ||
|
||
let result = fs::write(path, contents.join("\n")); | ||
|
||
if let Err(err) = &result { | ||
log::error!("Could not write to {}", path.display()); | ||
log::trace!("{:#?}", err); | ||
} | ||
|
||
result | ||
} |