diff --git a/blspc/example/hello.blsp b/blspc/example/hello.blsp index 3eaf6d1..89d01f8 100644 --- a/blspc/example/hello.blsp +++ b/blspc/example/hello.blsp @@ -1 +1 @@ -(print "Hello, World") \ No newline at end of file +(print "Hello, hello world!") \ No newline at end of file diff --git a/blspc/src/compiler/compile.rs b/blspc/src/compiler/compile.rs index 1c3104a..3433abd 100644 --- a/blspc/src/compiler/compile.rs +++ b/blspc/src/compiler/compile.rs @@ -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, pub register_pointer: usize, diff --git a/blspc/src/compiler/mod.rs b/blspc/src/compiler/mod.rs index a882a57..9ab42a6 100644 --- a/blspc/src/compiler/mod.rs +++ b/blspc/src/compiler/mod.rs @@ -1,4 +1,4 @@ -/// Definition of assembler's instructions. -pub mod instr; /// Definition of the compiler. -pub mod compile; \ No newline at end of file +pub mod compile; +/// Definition of the parser. +pub mod parser; \ No newline at end of file diff --git a/blspc/src/parser.rs b/blspc/src/compiler/parser.rs similarity index 98% rename from blspc/src/parser.rs rename to blspc/src/compiler/parser.rs index 37cc1d3..95b70e7 100644 --- a/blspc/src/parser.rs +++ b/blspc/src/compiler/parser.rs @@ -1,5 +1,5 @@ use regex::Regex; -use crate::parser::Sexpr::*; +use crate::compiler::parser::Sexpr::*; #[derive(Debug, Clone)] pub enum Sexpr { diff --git a/blspc/src/main.rs b/blspc/src/main.rs index 287a630..c4fd3c1 100644 --- a/blspc/src/main.rs +++ b/blspc/src/main.rs @@ -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, 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()); } diff --git a/blspc/src/compiler/instr.rs b/blspc/src/vm/instr.rs similarity index 100% rename from blspc/src/compiler/instr.rs rename to blspc/src/vm/instr.rs diff --git a/blspc/src/vm/mod.rs b/blspc/src/vm/mod.rs index 329584d..3699eaf 100644 --- a/blspc/src/vm/mod.rs +++ b/blspc/src/vm/mod.rs @@ -1 +1,4 @@ -pub mod parse; \ No newline at end of file +/// Definition of the VM instructions. +pub mod instr; +/// Definition of the instruction parser. +pub mod parser; \ No newline at end of file diff --git a/blspc/src/vm/parse.rs b/blspc/src/vm/parser.rs similarity index 89% rename from blspc/src/vm/parse.rs rename to blspc/src/vm/parser.rs index dfd7306..c81fd0b 100644 --- a/blspc/src/vm/parse.rs +++ b/blspc/src/vm/parser.rs @@ -1,6 +1,6 @@ -use crate::compiler::instr::*; +use crate::vm::instr::*; -pub fn parse(src: &str) -> Vec { +pub fn parse_instr(src: &str) -> Vec { let mut result = Vec::new(); for line in src.lines() { @@ -17,7 +17,7 @@ pub fn parse(src: &str) -> Vec { 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 { }, 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()); } }