From e5b63d5e2deb5bcecc4f5adb4ff7363fbf20d173 Mon Sep 17 00:00:00 2001 From: lionarius Date: Mon, 2 Dec 2024 13:57:32 +0300 Subject: [PATCH] separate interpreter and compiler --- Cargo.lock | 43 ++++++++----- Cargo.toml | 10 ++- crates/compiler/Cargo.toml | 12 ++++ {src => crates/compiler/src}/ast/mod.rs | 0 .../compiler/src}/ast/optimization.rs | 0 {src => crates/compiler/src}/ast/typed.rs | 0 {src => crates/compiler/src}/ast/untyped.rs | 0 {src => crates/compiler/src}/cli.rs | 17 +----- {src => crates/compiler/src}/error.rs | 0 {src => crates/compiler/src}/lib.rs | 2 - {src => crates/compiler/src}/main.rs | 56 +++-------------- {src => crates/compiler/src}/parse/lexer.rs | 0 {src => crates/compiler/src}/parse/mod.rs | 0 {src => crates/compiler/src}/parse/parser.rs | 0 {src => crates/compiler/src}/parse/token.rs | 0 .../src}/representation/intermediate.rs | 0 .../compiler/src}/representation/mod.rs | 0 .../compiler/src}/representation/util.rs | 0 {src => crates/compiler/src}/symbols/mod.rs | 0 {src => crates/compiler/src}/util.rs | 0 crates/interpreter/Cargo.toml | 14 +++++ crates/interpreter/src/cli.rs | 46 ++++++++++++++ .../interpreter/src}/interpreter/mod.rs | 9 ++- .../interpreter/src}/interpreter/value.rs | 0 crates/interpreter/src/lib.rs | 1 + crates/interpreter/src/main.rs | 61 +++++++++++++++++++ run_all.sh | 35 +++++++++++ 27 files changed, 214 insertions(+), 92 deletions(-) create mode 100644 crates/compiler/Cargo.toml rename {src => crates/compiler/src}/ast/mod.rs (100%) rename {src => crates/compiler/src}/ast/optimization.rs (100%) rename {src => crates/compiler/src}/ast/typed.rs (100%) rename {src => crates/compiler/src}/ast/untyped.rs (100%) rename {src => crates/compiler/src}/cli.rs (92%) rename {src => crates/compiler/src}/error.rs (100%) rename {src => crates/compiler/src}/lib.rs (70%) rename {src => crates/compiler/src}/main.rs (78%) rename {src => crates/compiler/src}/parse/lexer.rs (100%) rename {src => crates/compiler/src}/parse/mod.rs (100%) rename {src => crates/compiler/src}/parse/parser.rs (100%) rename {src => crates/compiler/src}/parse/token.rs (100%) rename {src => crates/compiler/src}/representation/intermediate.rs (100%) rename {src => crates/compiler/src}/representation/mod.rs (100%) rename {src => crates/compiler/src}/representation/util.rs (100%) rename {src => crates/compiler/src}/symbols/mod.rs (100%) rename {src => crates/compiler/src}/util.rs (100%) create mode 100644 crates/interpreter/Cargo.toml create mode 100644 crates/interpreter/src/cli.rs rename {src => crates/interpreter/src}/interpreter/mod.rs (95%) rename {src => crates/interpreter/src}/interpreter/value.rs (100%) create mode 100644 crates/interpreter/src/lib.rs create mode 100644 crates/interpreter/src/main.rs create mode 100755 run_all.sh diff --git a/Cargo.lock b/Cargo.lock index a1d2821..82b17f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,6 +133,18 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "compiler" +version = "0.1.0" +dependencies = [ + "anyhow", + "byteorder", + "clap", + "integer-encoding", + "itertools", + "thiserror", +] + [[package]] name = "crossterm" version = "0.25.0" @@ -158,19 +170,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "developing-compilers" -version = "0.1.0" -dependencies = [ - "anyhow", - "byteorder", - "clap", - "inquire", - "integer-encoding", - "itertools", - "thiserror", -] - [[package]] name = "dyn-clone" version = "1.0.17" @@ -230,6 +229,20 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d762194228a2f1c11063e46e32e5acb96e66e906382b9eb5441f2e0504bbd5a" +[[package]] +name = "interpreter" +version = "0.1.0" +dependencies = [ + "anyhow", + "byteorder", + "clap", + "compiler", + "inquire", + "integer-encoding", + "itertools", + "thiserror", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -247,9 +260,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.162" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "lock_api" diff --git a/Cargo.toml b/Cargo.toml index 5d46741..a6892dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,11 @@ -[package] -edition = "2021" -name = "developing-compilers" -version = "0.1.0" +[workspace] +members = ["crates/compiler", "crates/interpreter"] +resolver = "2" -[dependencies] +[workspace.dependencies] anyhow = "1.0.89" byteorder = "1.5.0" clap = { version = "4.5.19", features = ["derive"] } -inquire = "0.7.5" integer-encoding = "4.0.2" itertools = "0.13.0" thiserror = "2.0.3" diff --git a/crates/compiler/Cargo.toml b/crates/compiler/Cargo.toml new file mode 100644 index 0000000..9ff3ad9 --- /dev/null +++ b/crates/compiler/Cargo.toml @@ -0,0 +1,12 @@ +[package] +edition = "2021" +name = "compiler" +version = "0.1.0" + +[dependencies] +anyhow = { workspace = true } +byteorder = { workspace = true } +clap = { workspace = true } +integer-encoding = { workspace = true } +itertools = { workspace = true } +thiserror = { workspace = true } diff --git a/src/ast/mod.rs b/crates/compiler/src/ast/mod.rs similarity index 100% rename from src/ast/mod.rs rename to crates/compiler/src/ast/mod.rs diff --git a/src/ast/optimization.rs b/crates/compiler/src/ast/optimization.rs similarity index 100% rename from src/ast/optimization.rs rename to crates/compiler/src/ast/optimization.rs diff --git a/src/ast/typed.rs b/crates/compiler/src/ast/typed.rs similarity index 100% rename from src/ast/typed.rs rename to crates/compiler/src/ast/typed.rs diff --git a/src/ast/untyped.rs b/crates/compiler/src/ast/untyped.rs similarity index 100% rename from src/ast/untyped.rs rename to crates/compiler/src/ast/untyped.rs diff --git a/src/cli.rs b/crates/compiler/src/cli.rs similarity index 92% rename from src/cli.rs rename to crates/compiler/src/cli.rs index 75f4ce5..03b48bc 100644 --- a/src/cli.rs +++ b/crates/compiler/src/cli.rs @@ -2,7 +2,7 @@ use std::ops::Deref; use std::path::PathBuf; use clap::{CommandFactory, Parser, Subcommand}; -use developing_compilers::ast::optimization::OLevel; +use compiler::ast::optimization::OLevel; pub struct Args { inner: ArgsInner, @@ -45,9 +45,6 @@ pub enum Command { input: PathBuf, output: PathBuf, }, - Int { - input: PathBuf, - }, } #[derive(Copy, Clone, PartialEq, Eq, clap::ValueEnum)] @@ -101,7 +98,6 @@ fn validate_inner(args: ArgsInner) -> Result { .. } => validate_gen(input, output, output_symbols)?, Command::Com { input, output, .. } => validate_com(input, output)?, - Command::Int { input } => validate_int(input)?, }; Ok(args) @@ -218,14 +214,3 @@ fn validate_com(input: &PathBuf, output: &PathBuf) -> Result<(), clap::Error> { Ok(()) } - -fn validate_int(input: &PathBuf) -> Result<(), clap::Error> { - if !input.is_file() { - return Err(clap::Error::raw( - clap::error::ErrorKind::InvalidValue, - format!("Input file '{}' does not exist", input.display()), - )); - } - - Ok(()) -} diff --git a/src/error.rs b/crates/compiler/src/error.rs similarity index 100% rename from src/error.rs rename to crates/compiler/src/error.rs diff --git a/src/lib.rs b/crates/compiler/src/lib.rs similarity index 70% rename from src/lib.rs rename to crates/compiler/src/lib.rs index d3c9de5..3a5ccd2 100644 --- a/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -1,7 +1,5 @@ pub mod ast; pub mod error; -pub mod interpreter; pub mod parse; pub mod representation; pub mod symbols; -pub mod util; diff --git a/src/main.rs b/crates/compiler/src/main.rs similarity index 78% rename from src/main.rs rename to crates/compiler/src/main.rs index 3af34cd..4e613bb 100644 --- a/src/main.rs +++ b/crates/compiler/src/main.rs @@ -1,19 +1,18 @@ mod cli; +mod util; use std::fs; use std::io::{self, Write}; use std::path::Path; use cli::GenMode; -use developing_compilers::ast::optimization::OLevel; -use developing_compilers::ast::typed::{Type, TypedExpr}; -use developing_compilers::interpreter::{Interpreter, Value}; -use developing_compilers::representation::intermediate::IntermediateExpr; -use developing_compilers::*; -use inquire::CustomType; -use integer_encoding::{VarIntReader, VarIntWriter}; -use parse::parser::Parser; -use symbols::SymbolsTable; +use compiler::ast::optimization::OLevel; +use compiler::ast::typed::TypedExpr; +use compiler::parse::parser::Parser; +use compiler::representation::intermediate::IntermediateExpr; +use compiler::symbols::SymbolsTable; +use compiler::*; +use integer_encoding::VarIntWriter; fn main() -> anyhow::Result<()> { let args = cli::Args::parse(); @@ -42,7 +41,6 @@ fn main() -> anyhow::Result<()> { input, output, } => com_command(*optimization_level, input, output), - cli::Command::Int { input } => int_command(input), }; if let Err(e) = result { @@ -52,44 +50,6 @@ fn main() -> anyhow::Result<()> { Ok(()) } -fn int_command(input: &Path) -> Result<(), anyhow::Error> { - let (symbols, ir) = { - let mut reader = io::BufReader::new(fs::File::open(input)?); - let symbols = SymbolsTable::read(&mut reader)?; - let n = reader.read_varint::()?; - let mut ir = Vec::with_capacity(n as usize); - for _ in 0..n { - ir.push(IntermediateExpr::read(&mut reader)?); - } - (symbols, ir) - }; - - let mut interpreter = Interpreter::new(ir, symbols, |ty, name| match ty { - Type::Int => Value::Int( - CustomType::new(&format!("Input int {}", name)) - .with_default(0) - .prompt() - .unwrap_or_default(), - ), - Type::Float => Value::Float( - CustomType::new(&format!("Input float {}", name)) - .with_default(0.0) - .prompt() - .unwrap_or_default(), - ), - }); - - let result = interpreter.run()?; - - if let Some(result) = result { - println!("Result: {}", result); - } else { - println!("No result"); - } - - Ok(()) -} - fn com_command(o_level: OLevel, input: &Path, output: &Path) -> Result<(), anyhow::Error> { let input = fs::read_to_string(input)?; let mut symbols = SymbolsTable::default(); diff --git a/src/parse/lexer.rs b/crates/compiler/src/parse/lexer.rs similarity index 100% rename from src/parse/lexer.rs rename to crates/compiler/src/parse/lexer.rs diff --git a/src/parse/mod.rs b/crates/compiler/src/parse/mod.rs similarity index 100% rename from src/parse/mod.rs rename to crates/compiler/src/parse/mod.rs diff --git a/src/parse/parser.rs b/crates/compiler/src/parse/parser.rs similarity index 100% rename from src/parse/parser.rs rename to crates/compiler/src/parse/parser.rs diff --git a/src/parse/token.rs b/crates/compiler/src/parse/token.rs similarity index 100% rename from src/parse/token.rs rename to crates/compiler/src/parse/token.rs diff --git a/src/representation/intermediate.rs b/crates/compiler/src/representation/intermediate.rs similarity index 100% rename from src/representation/intermediate.rs rename to crates/compiler/src/representation/intermediate.rs diff --git a/src/representation/mod.rs b/crates/compiler/src/representation/mod.rs similarity index 100% rename from src/representation/mod.rs rename to crates/compiler/src/representation/mod.rs diff --git a/src/representation/util.rs b/crates/compiler/src/representation/util.rs similarity index 100% rename from src/representation/util.rs rename to crates/compiler/src/representation/util.rs diff --git a/src/symbols/mod.rs b/crates/compiler/src/symbols/mod.rs similarity index 100% rename from src/symbols/mod.rs rename to crates/compiler/src/symbols/mod.rs diff --git a/src/util.rs b/crates/compiler/src/util.rs similarity index 100% rename from src/util.rs rename to crates/compiler/src/util.rs diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml new file mode 100644 index 0000000..a417d54 --- /dev/null +++ b/crates/interpreter/Cargo.toml @@ -0,0 +1,14 @@ +[package] +edition = "2021" +name = "interpreter" +version = "0.1.0" + +[dependencies] +compiler = { path = "../compiler" } +anyhow = { workspace = true } +byteorder = { workspace = true } +clap = { workspace = true } +inquire = "0.7.5" +integer-encoding = { workspace = true } +itertools = { workspace = true } +thiserror = { workspace = true } diff --git a/crates/interpreter/src/cli.rs b/crates/interpreter/src/cli.rs new file mode 100644 index 0000000..36117e2 --- /dev/null +++ b/crates/interpreter/src/cli.rs @@ -0,0 +1,46 @@ +use std::ops::Deref; +use std::path::PathBuf; + +use clap::{CommandFactory, Parser}; + +pub struct Args { + inner: ArgsInner, +} + +#[derive(Parser)] +pub struct ArgsInner { + pub input: PathBuf, +} + +impl Args { + pub fn parse() -> Self { + let inner = match validate_inner(ArgsInner::parse()) { + Ok(args) => args, + Err(err) => { + let mut command = ArgsInner::command(); + err.format(&mut command).exit(); + }, + }; + + Self { inner } + } +} + +impl Deref for Args { + type Target = ArgsInner; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +fn validate_inner(args: ArgsInner) -> Result { + if args.input.is_file() { + Ok(args) + } else { + Err(clap::Error::raw( + clap::error::ErrorKind::InvalidValue, + format!("Input file '{}' does not exist", args.input.display()), + )) + } +} diff --git a/src/interpreter/mod.rs b/crates/interpreter/src/interpreter/mod.rs similarity index 95% rename from src/interpreter/mod.rs rename to crates/interpreter/src/interpreter/mod.rs index 3a6f334..7e18cea 100644 --- a/src/interpreter/mod.rs +++ b/crates/interpreter/src/interpreter/mod.rs @@ -3,13 +3,12 @@ mod value; use std::collections::HashMap; use anyhow::Context; +use compiler::ast::BinOp; +use compiler::ast::typed::Type; +use compiler::representation::intermediate::{IntermediateExpr, IntermediateValue}; +use compiler::symbols::{Symbol, SymbolsTable}; pub use value::Value; -use crate::ast::BinOp; -use crate::ast::typed::Type; -use crate::representation::intermediate::{IntermediateExpr, IntermediateValue}; -use crate::symbols::{Symbol, SymbolsTable}; - pub struct Interpreter { exprs: Vec, symbols: SymbolsTable, diff --git a/src/interpreter/value.rs b/crates/interpreter/src/interpreter/value.rs similarity index 100% rename from src/interpreter/value.rs rename to crates/interpreter/src/interpreter/value.rs diff --git a/crates/interpreter/src/lib.rs b/crates/interpreter/src/lib.rs new file mode 100644 index 0000000..144a532 --- /dev/null +++ b/crates/interpreter/src/lib.rs @@ -0,0 +1 @@ +pub mod interpreter; diff --git a/crates/interpreter/src/main.rs b/crates/interpreter/src/main.rs new file mode 100644 index 0000000..f29acc1 --- /dev/null +++ b/crates/interpreter/src/main.rs @@ -0,0 +1,61 @@ +use std::path::Path; +use std::{fs, io}; + +use compiler::ast::typed::Type; +use compiler::representation::intermediate::IntermediateExpr; +use compiler::symbols::SymbolsTable; +use inquire::CustomType; +use integer_encoding::VarIntReader; +use interpreter::interpreter::{Interpreter, Value}; + +mod cli; + +fn main() -> anyhow::Result<()> { + let args = cli::Args::parse(); + + let result = int_command(&args.input); + + if let Err(e) = result { + eprintln!("error: {}", e); + } + + Ok(()) +} + +fn int_command(input: &Path) -> Result<(), anyhow::Error> { + let (symbols, ir) = { + let mut reader = io::BufReader::new(fs::File::open(input)?); + let symbols = SymbolsTable::read(&mut reader)?; + let n = reader.read_varint::()?; + let mut ir = Vec::with_capacity(n as usize); + for _ in 0..n { + ir.push(IntermediateExpr::read(&mut reader)?); + } + (symbols, ir) + }; + + let mut interpreter = Interpreter::new(ir, symbols, |ty, name| match ty { + Type::Int => Value::Int( + CustomType::new(&format!("Input int {}", name)) + .with_default(0) + .prompt() + .unwrap_or_default(), + ), + Type::Float => Value::Float( + CustomType::new(&format!("Input float {}", name)) + .with_default(0.0) + .prompt() + .unwrap_or_default(), + ), + }); + + let result = interpreter.run()?; + + if let Some(result) = result { + println!("Result: {}", result); + } else { + println!("No result"); + } + + Ok(()) +} diff --git a/run_all.sh b/run_all.sh new file mode 100755 index 0000000..8d6ce5f --- /dev/null +++ b/run_all.sh @@ -0,0 +1,35 @@ +mkdir -p ./test/lex +cargo run -r -- lex ./test/in.txt ./test/lex/tokens.txt ./test/lex/symbols.txt + +mkdir -p ./test/syn +cargo run -r -- syn ./test/in.txt ./test/syn/tree.txt + +mkdir -p ./test/sem/none +cargo run -r -- sem ./test/in.txt ./test/sem/none/tree.txt + +mkdir -p ./test/sem/o1 +cargo run -r -- sem -o o1 ./test/in.txt ./test/sem/o1/tree.txt + +mkdir -p ./test/sem/o2 +cargo run -r -- sem -o o2 ./test/in.txt ./test/sem/o2/tree.txt + +mkdir -p ./test/sem/o3 +cargo run -r -- sem -o o3 ./test/in.txt ./test/sem/o3/tree.txt + +mkdir -p ./test/gen/ir +cargo run -r -- gen i ./test/in.txt ./test/gen/ir/result.txt ./test/gen/ir/symbols.txt + +mkdir -p ./test/gen/p +cargo run -r -- gen p ./test/in.txt ./test/gen/p/result.txt ./test/gen/p/symbols.txt + +mkdir -p ./test/gen/ir-o +cargo run -r -- gen i -o o2 ./test/in.txt ./test/gen/ir-o/result.txt ./test/gen/ir-o/symbols.txt + +mkdir -p ./test/gen/p-o +cargo run -r -- gen p -o o2 ./test/in.txt ./test/gen/p-o/result.txt ./test/gen/p-o/symbols.txt + +mkdir -p ./test/com +cargo run -r -- com ./test/in.txt ./test/com/result.bin + +mkdir -p ./test/com-o +cargo run -r -- com -o o2 ./test/in.txt ./test/com-o/result.bin