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 struct Compiler {
|
||||||
pub instructions: Vec<Instr>,
|
pub instructions: Vec<Instr>,
|
||||||
pub register_pointer: usize,
|
pub register_pointer: usize,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/// Definition of assembler's instructions.
|
|
||||||
pub mod instr;
|
|
||||||
/// Definition of the compiler.
|
/// 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 regex::Regex;
|
||||||
use crate::parser::Sexpr::*;
|
use crate::compiler::parser::Sexpr::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Sexpr {
|
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;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
@ -8,55 +8,87 @@ use args::Args;
|
||||||
mod util;
|
mod util;
|
||||||
use util::cover_paren;
|
use util::cover_paren;
|
||||||
|
|
||||||
mod parser;
|
|
||||||
use parser::{tokenize, Parser, Sexpr};
|
|
||||||
|
|
||||||
mod compiler;
|
mod compiler;
|
||||||
use compiler::{compile::Compiler, instr::Instr};
|
use compiler::{compile::Compiler, parser::{tokenize, Parser}};
|
||||||
|
|
||||||
mod vm;
|
mod vm;
|
||||||
|
use vm::parser::parse_instr;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let args = Args::from_args();
|
let args = Args::from_args();
|
||||||
|
|
||||||
let src = cover_paren(read_to_string(&args.file).unwrap());
|
match (args.compile, args.run) {
|
||||||
let file_name = match args.output {
|
(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,
|
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();
|
}.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 mut parser = Parser::new(tokens.clone());
|
||||||
let result = parser.parse();
|
let result = parser.parse();
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(ast) => {
|
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) => {
|
Err(e) => {
|
||||||
eprintln!("{}", e);
|
eprintln!("{}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile(ast: Sexpr, file_name: String, start: Instant) {
|
fn run_src(src: String, start: Instant) {
|
||||||
let mut compiler = Compiler::new();
|
let instrs = parse_instr(&src);
|
||||||
let code = compiler.compile(ast, 0);
|
for i in instrs {
|
||||||
match code {
|
println!("{}", i);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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();
|
let mut result = Vec::new();
|
||||||
|
|
||||||
for line in src.lines() {
|
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 {
|
while let Some(part) = parts.next() { match in_quote {
|
||||||
true => {
|
true => {
|
||||||
if part.ends_with("\"") {
|
if part.ends_with("\"") {
|
||||||
str.push_str(&format!(" {}", part));
|
str.push_str(&format!(" {}", part.trim_end_matches("\"")));
|
||||||
args.push(str);
|
args.push(str);
|
||||||
str = String::new();
|
str = String::new();
|
||||||
in_quote = false;
|
in_quote = false;
|
||||||
|
@ -25,7 +25,7 @@ pub fn parse(src: &str) -> Vec<Instr> {
|
||||||
},
|
},
|
||||||
false => {
|
false => {
|
||||||
if part.starts_with("$\"") {
|
if part.starts_with("$\"") {
|
||||||
str.push_str(&part);
|
str.push_str(&part.trim_start_matches("$\""));
|
||||||
in_quote = true;
|
in_quote = true;
|
||||||
} else { args.push(part.to_string()); }
|
} else { args.push(part.to_string()); }
|
||||||
}
|
}
|
Loading…
Reference in a new issue