1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-09-28 09:27:35 +00:00

refactor: better args handling

This commit is contained in:
Natapat Samutpong 2022-01-26 15:35:40 +07:00
parent 09e8a97d34
commit 598ef08b5d
8 changed files with 74 additions and 39 deletions

View file

@ -1 +1 @@
(print "Hello, World") (print "Hello, hello world!")

View file

@ -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,

View file

@ -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;

View file

@ -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 {

View file

@ -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,40 +8,58 @@ 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);
},
Err(e) => {
eprintln!("{}", e);
}
}
}
fn compile(ast: Sexpr, file_name: String, start: Instant) {
let mut compiler = Compiler::new(); let mut compiler = Compiler::new();
let code = compiler.compile(ast, 0); let code = compiler.compile(ast, 0);
match code { match code {
@ -59,4 +77,18 @@ fn compile(ast: Sexpr, file_name: String, start: Instant) {
eprintln!("{}", err); eprintln!("{}", err);
} }
} }
},
Err(e) => {
eprintln!("{}", e);
}
}
}
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());
} }

View file

@ -1 +1,4 @@
pub mod parse; /// Definition of the VM instructions.
pub mod instr;
/// Definition of the instruction parser.
pub mod parser;

View file

@ -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()); }
} }