From 09e8a97d3448c108240493b56d3396324cd5a5d5 Mon Sep 17 00:00:00 2001 From: Natapat Samutpong Date: Wed, 26 Jan 2022 15:07:53 +0700 Subject: [PATCH] refactor: merge all repos --- Cargo.lock | 13 - Cargo.toml | 2 - Makefile | 15 +- blspc/Cargo.toml | 1 - blspc/src/args.rs | 12 + blspc/src/compiler/compile.rs | 5 +- .../src/lib.rs => blspc/src/compiler/instr.rs | 40 +++- blspc/src/compiler/mod.rs | 3 + blspc/src/main.rs | 72 +++--- blspc/src/vm/mod.rs | 1 + blspc/src/vm/parse.rs | 58 +++++ blvm/.gitignore | 1 - blvm/Cargo.lock | 225 ------------------ blvm/Cargo.toml | 10 - blvm/src/args.rs | 11 - blvm/src/main.rs | 17 -- blvm/src/parser.rs | 17 -- middle/Cargo.toml | 8 - 18 files changed, 152 insertions(+), 359 deletions(-) rename middle/src/lib.rs => blspc/src/compiler/instr.rs (72%) create mode 100644 blspc/src/vm/mod.rs create mode 100644 blspc/src/vm/parse.rs delete mode 100644 blvm/.gitignore delete mode 100644 blvm/Cargo.lock delete mode 100644 blvm/Cargo.toml delete mode 100644 blvm/src/args.rs delete mode 100644 blvm/src/main.rs delete mode 100644 blvm/src/parser.rs delete mode 100644 middle/Cargo.toml diff --git a/Cargo.lock b/Cargo.lock index ae84401..87c1f9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,19 +41,10 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" name = "blspc" version = "0.1.0" dependencies = [ - "middle", "regex", "structopt", ] -[[package]] -name = "blvm" -version = "0.1.0" -dependencies = [ - "middle", - "structopt", -] - [[package]] name = "clap" version = "2.34.0" @@ -105,10 +96,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" -[[package]] -name = "middle" -version = "0.1.0" - [[package]] name = "proc-macro-error" version = "1.0.4" diff --git a/Cargo.toml b/Cargo.toml index 917f927..dd98273 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,4 @@ [workspace] members = [ "blspc", - "blvm", - "middle", ] diff --git a/Makefile b/Makefile index 18aba22..047f001 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,12 @@ -all: build-blspc build-blvm +all: build +debug: build-debug -build-blspc: +build: + cd ./blspc; cargo build --release + rm ~/bin/blspc -f + mv ./target/release/blspc ~/bin/blspc + +build-debug: cd ./blspc; cargo build rm ~/bin/blspc -f mv ./target/debug/blspc ~/bin/blspc - -build-blvm: - cd ./blvm; cargo build - rm ~/bin/blvm -f - mv ./target/debug/blvm ~/bin/blvm diff --git a/blspc/Cargo.toml b/blspc/Cargo.toml index dee8eb1..ec85500 100644 --- a/blspc/Cargo.toml +++ b/blspc/Cargo.toml @@ -12,6 +12,5 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -middle = { path = "../middle" } regex = "1.5.4" structopt = "0.3.26" diff --git a/blspc/src/args.rs b/blspc/src/args.rs index f3c0fbe..0fee70d 100644 --- a/blspc/src/args.rs +++ b/blspc/src/args.rs @@ -9,7 +9,19 @@ pub struct Args { #[structopt(short, long, parse(from_occurrences))] pub verbose: u8, + /// Compliation mode (-c). + #[structopt(short, long)] + pub compile: bool, + + /// Run mode (-r). + #[structopt(short, long)] + pub run: bool, + /// Files to process. #[structopt(name = "FILE", parse(from_os_str))] pub file: PathBuf, + + /// Output file. + #[structopt(short, long, parse(from_os_str))] + pub output: Option, } \ No newline at end of file diff --git a/blspc/src/compiler/compile.rs b/blspc/src/compiler/compile.rs index 1d1fef0..1c3104a 100644 --- a/blspc/src/compiler/compile.rs +++ b/blspc/src/compiler/compile.rs @@ -1,7 +1,4 @@ -use crate::parser::Sexpr::{self, *}; - -use middle::*; - +use crate::{compiler::instr::*, parser::Sexpr::{self, *}}; pub struct Compiler { pub instructions: Vec, pub register_pointer: usize, diff --git a/middle/src/lib.rs b/blspc/src/compiler/instr.rs similarity index 72% rename from middle/src/lib.rs rename to blspc/src/compiler/instr.rs index 2c02f4f..162244b 100644 --- a/middle/src/lib.rs +++ b/blspc/src/compiler/instr.rs @@ -1,4 +1,4 @@ -use std::fmt::Display; +use std::{fmt::Display, str::FromStr}; /// Literal types for the assembler. #[derive(Clone, Debug)] @@ -20,6 +20,35 @@ impl Display for Type { } } +impl FromStr for Type { + type Err = String; + + fn from_str(s: &str) -> Result { + if !s.starts_with("$") { + return Err(format!("Invalid literal: {}", s)); + } + + let s = &s[1..]; + match s { + "true" => Ok(Type::Boolean(true)), + "false" => Ok(Type::Boolean(false)), + _ => { + let fl = s.parse::(); + if fl.is_ok() { + Ok(Type::Float(fl.unwrap())) + } else { + let i = s.parse::(); + if i.is_ok() { + Ok(Type::Int(i.unwrap())) + } else { + Ok(Type::String(s.to_string())) + } + } + } + } + } +} + #[derive(Clone, Copy, Debug)] pub struct Register { pub value: usize } @@ -29,6 +58,15 @@ impl Display for Register { } } +impl FromStr for Register { + type Err = (); + + fn from_str(s: &str) -> Result { + let value = s[1..].parse::().map_err(|_| ())?; + Ok(Register { value }) + } +} + /// Instructions for the assembler. #[derive(Clone, Debug)] pub enum Instr { diff --git a/blspc/src/compiler/mod.rs b/blspc/src/compiler/mod.rs index b10d1ef..a882a57 100644 --- a/blspc/src/compiler/mod.rs +++ b/blspc/src/compiler/mod.rs @@ -1 +1,4 @@ +/// Definition of assembler's instructions. +pub mod instr; +/// Definition of the compiler. pub mod compile; \ No newline at end of file diff --git a/blspc/src/main.rs b/blspc/src/main.rs index aa521c0..287a630 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, time::Instant}; +use std::{fs::{read_to_string, File}, path::Path, io::{Write, Seek}, time::Instant}; use structopt::StructOpt; @@ -9,66 +9,54 @@ mod util; use util::cover_paren; mod parser; -use parser::{tokenize, Parser}; +use parser::{tokenize, Parser, Sexpr}; mod compiler; -use compiler::compile::Compiler; +use compiler::{compile::Compiler, instr::Instr}; + +mod vm; fn main() { let start = Instant::now(); let args = Args::from_args(); let src = cover_paren(read_to_string(&args.file).unwrap()); - let file_name = Path::new(&args.file).file_stem().unwrap().to_str().unwrap(); + let file_name = match args.output { + Some(path) => path, + None => Path::new(&args.file).to_path_buf(), + }.file_stem().unwrap().to_str().unwrap().to_string(); let tokens = tokenize(&src); let mut parser = Parser::new(tokens.clone()); let result = parser.parse(); - match args.verbose { - 0 => { - let mut file = File::create(format!("{}.bbb", file_name)).unwrap(); - - let mut compiler = Compiler::new(); - let before = Instant::now(); - for instr in compiler.compile(result.unwrap(), 0).unwrap() { - write!(file, "{}\n", instr).unwrap(); - } - let spent = before.elapsed(); - let total = start.elapsed(); - - println!("Compiled in {}.{}s, Total of {}.{}s", spent.as_secs(), spent.subsec_millis(), total.as_secs(), total.subsec_millis()); + match result { + Ok(ast) => { + compile(ast, file_name, start); }, - 1 => { - println!("Parsed AST: {:#?}", result); + Err(e) => { + eprintln!("{}", e); + } + } - let mut file = File::create(format!("{}.bbb", file_name)).unwrap(); +} - let mut compiler = Compiler::new(); - let before = Instant::now(); - for instr in compiler.compile(result.unwrap(), 0).unwrap() { - write!(file, "{}\n", instr).unwrap(); +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(); } - let spent = before.elapsed(); - let total = start.elapsed(); + file.seek(std::io::SeekFrom::End(-1)).unwrap(); // Trim last newline - println!("Compiled in {}.{}s, Total of {}.{}s", spent.as_secs(), spent.subsec_millis(), total.as_secs(), total.subsec_millis()); + let elapsed = start.elapsed(); + println!("Compiled in {}.{}s", elapsed.as_secs(), elapsed.subsec_millis()); }, - 2 | _ => { - println!("Tokens: {:?}", tokens); - println!("Parsed AST: {:#?}", result); - - let mut file = File::create(format!("{}.bbb", file_name)).unwrap(); - - let mut compiler = Compiler::new(); - let before = Instant::now(); - for instr in compiler.compile(result.unwrap(), 0).unwrap() { - write!(file, "{}\n", instr).unwrap(); - } - let spent = before.elapsed(); - let total = start.elapsed(); - - println!("Compiled in {}.{}s, Total of {}.{}s", spent.as_secs(), spent.subsec_millis(), total.as_secs(), total.subsec_millis()); + Err(err) => { + eprintln!("{}", err); } } } diff --git a/blspc/src/vm/mod.rs b/blspc/src/vm/mod.rs new file mode 100644 index 0000000..329584d --- /dev/null +++ b/blspc/src/vm/mod.rs @@ -0,0 +1 @@ +pub mod parse; \ No newline at end of file diff --git a/blspc/src/vm/parse.rs b/blspc/src/vm/parse.rs new file mode 100644 index 0000000..dfd7306 --- /dev/null +++ b/blspc/src/vm/parse.rs @@ -0,0 +1,58 @@ +use crate::compiler::instr::*; + +pub fn parse(src: &str) -> Vec { + let mut result = Vec::new(); + + for line in src.lines() { + //