mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
refactor: better args handling
This commit is contained in:
parent
09e8a97d34
commit
598ef08b5d
|
@ -1 +1 @@
|
|||
(print "Hello, World")
|
||||
(print "Hello, hello world!")
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{compiler::instr::*, parser::Sexpr::{self, *}};
|
||||
use crate::{vm::instr::*, compiler::parser::Sexpr::{self, *}};
|
||||
pub struct Compiler {
|
||||
pub instructions: Vec<Instr>,
|
||||
pub register_pointer: usize,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Definition of assembler's instructions.
|
||||
pub mod instr;
|
||||
/// Definition of the compiler.
|
||||
pub mod compile;
|
||||
pub mod compile;
|
||||
/// Definition of the parser.
|
||||
pub mod parser;
|
|
@ -1,5 +1,5 @@
|
|||
use regex::Regex;
|
||||
use crate::parser::Sexpr::*;
|
||||
use crate::compiler::parser::Sexpr::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Sexpr {
|
|
@ -1,4 +1,4 @@
|
|||
use std::{fs::{read_to_string, File}, path::Path, io::{Write, Seek}, time::Instant};
|
||||
use std::{fs::{read_to_string, File}, path::{Path, PathBuf}, io::{Write, Seek}, time::Instant};
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
|
@ -8,55 +8,87 @@ use args::Args;
|
|||
mod util;
|
||||
use util::cover_paren;
|
||||
|
||||
mod parser;
|
||||
use parser::{tokenize, Parser, Sexpr};
|
||||
|
||||
mod compiler;
|
||||
use compiler::{compile::Compiler, instr::Instr};
|
||||
use compiler::{compile::Compiler, parser::{tokenize, Parser}};
|
||||
|
||||
mod vm;
|
||||
use vm::parser::parse_instr;
|
||||
|
||||
fn main() {
|
||||
let start = Instant::now();
|
||||
let args = Args::from_args();
|
||||
|
||||
let src = cover_paren(read_to_string(&args.file).unwrap());
|
||||
let file_name = match args.output {
|
||||
match (args.compile, args.run) {
|
||||
(true, true) => {
|
||||
eprintln!("TODO: Compile and run at the same time.");
|
||||
std::process::exit(1);
|
||||
},
|
||||
// Compile
|
||||
(true, false) => {
|
||||
let src = read_to_string(&args.file).unwrap();
|
||||
compile_src(src, args.output, args.file, start);
|
||||
},
|
||||
// Run
|
||||
(false, true) => {
|
||||
let src = read_to_string(&args.file).unwrap();
|
||||
run_src(src, start);
|
||||
},
|
||||
(false, false) => {
|
||||
if args.file.extension() == Some("blsp".as_ref()) {
|
||||
let src = read_to_string(&args.file).unwrap();
|
||||
compile_src(src, args.output, args.file, start);
|
||||
} else if args.file.extension() == Some("bsm".as_ref()) {
|
||||
let src = read_to_string(&args.file).unwrap();
|
||||
run_src(src, start);
|
||||
} else {
|
||||
panic!("No mode specified");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn compile_src(src: String, path: Option<PathBuf>, file: PathBuf, start: Instant) {
|
||||
let file_name = match path {
|
||||
Some(path) => path,
|
||||
None => Path::new(&args.file).to_path_buf(),
|
||||
None => Path::new(&file).to_path_buf(),
|
||||
}.file_stem().unwrap().to_str().unwrap().to_string();
|
||||
|
||||
let tokens = tokenize(&src);
|
||||
let tokens = tokenize(&cover_paren(src));
|
||||
let mut parser = Parser::new(tokens.clone());
|
||||
let result = parser.parse();
|
||||
|
||||
match result {
|
||||
Ok(ast) => {
|
||||
compile(ast, file_name, start);
|
||||
let mut compiler = Compiler::new();
|
||||
let code = compiler.compile(ast, 0);
|
||||
match code {
|
||||
Ok(code) => {
|
||||
let mut file = File::create(format!("{}.bsm", file_name)).unwrap();
|
||||
for line in code {
|
||||
write!(file, "{}\n", line).unwrap();
|
||||
}
|
||||
file.seek(std::io::SeekFrom::End(-1)).unwrap(); // Trim last newline
|
||||
|
||||
let elapsed = start.elapsed();
|
||||
println!("Compiled in {}.{}s", elapsed.as_secs(), elapsed.subsec_millis());
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn compile(ast: Sexpr, file_name: String, start: Instant) {
|
||||
let mut compiler = Compiler::new();
|
||||
let code = compiler.compile(ast, 0);
|
||||
match code {
|
||||
Ok(code) => {
|
||||
let mut file = File::create(format!("{}.bsm", file_name)).unwrap();
|
||||
for line in code {
|
||||
write!(file, "{}\n", line).unwrap();
|
||||
}
|
||||
file.seek(std::io::SeekFrom::End(-1)).unwrap(); // Trim last newline
|
||||
|
||||
let elapsed = start.elapsed();
|
||||
println!("Compiled in {}.{}s", elapsed.as_secs(), elapsed.subsec_millis());
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
fn run_src(src: String, start: Instant) {
|
||||
let instrs = parse_instr(&src);
|
||||
for i in instrs {
|
||||
println!("{}", i);
|
||||
}
|
||||
let elapsed = start.elapsed();
|
||||
println!("Executed in {}.{}s", elapsed.as_secs(), elapsed.subsec_millis());
|
||||
}
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
pub mod parse;
|
||||
/// Definition of the VM instructions.
|
||||
pub mod instr;
|
||||
/// Definition of the instruction parser.
|
||||
pub mod parser;
|
|
@ -1,6 +1,6 @@
|
|||
use crate::compiler::instr::*;
|
||||
use crate::vm::instr::*;
|
||||
|
||||
pub fn parse(src: &str) -> Vec<Instr> {
|
||||
pub fn parse_instr(src: &str) -> Vec<Instr> {
|
||||
let mut result = Vec::new();
|
||||
|
||||
for line in src.lines() {
|
||||
|
@ -17,7 +17,7 @@ pub fn parse(src: &str) -> Vec<Instr> {
|
|||
while let Some(part) = parts.next() { match in_quote {
|
||||
true => {
|
||||
if part.ends_with("\"") {
|
||||
str.push_str(&format!(" {}", part));
|
||||
str.push_str(&format!(" {}", part.trim_end_matches("\"")));
|
||||
args.push(str);
|
||||
str = String::new();
|
||||
in_quote = false;
|
||||
|
@ -25,7 +25,7 @@ pub fn parse(src: &str) -> Vec<Instr> {
|
|||
},
|
||||
false => {
|
||||
if part.starts_with("$\"") {
|
||||
str.push_str(&part);
|
||||
str.push_str(&part.trim_start_matches("$\""));
|
||||
in_quote = true;
|
||||
} else { args.push(part.to_string()); }
|
||||
}
|
Loading…
Reference in a new issue