diff options
author | Freya Murphy <freya@freyacat.org> | 2024-02-29 17:04:28 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-02-29 17:04:28 -0500 |
commit | 5d2747e26f51cc2344a6bd95f93457248fdfebd8 (patch) | |
tree | 8755b4068166c3854d26817683ce438a771ab319 /matrix-bin | |
parent | more mat, sys, and os stdlib functions, better matrix printing, other fixes (diff) | |
download | matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.gz matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.bz2 matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.zip |
fin prob
Diffstat (limited to 'matrix-bin')
-rw-r--r-- | matrix-bin/Cargo.lock | 385 | ||||
-rw-r--r-- | matrix-bin/Cargo.toml | 4 | ||||
-rw-r--r-- | matrix-bin/src/helper.rs | 8 | ||||
-rw-r--r-- | matrix-bin/src/main.rs | 119 | ||||
-rw-r--r-- | matrix-bin/src/repl.rs | 53 |
5 files changed, 132 insertions, 437 deletions
diff --git a/matrix-bin/Cargo.lock b/matrix-bin/Cargo.lock deleted file mode 100644 index f61fea6..0000000 --- a/matrix-bin/Cargo.lock +++ /dev/null @@ -1,385 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clipboard-win" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec832972fefb8cf9313b45a0d1945e29c9c251f1d4c6eafc5fe2124c02d2e81" -dependencies = [ - "error-code", -] - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "error-code" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc" - -[[package]] -name = "fd-lock" -version = "4.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" -dependencies = [ - "cfg-if", - "rustix", - "windows-sys", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "matrix" -version = "0.1.0" -dependencies = [ - "anyhow", - "num-complex", - "num-rational", - "regex", -] - -[[package]] -name = "matrix-repl" -version = "0.1.0" -dependencies = [ - "matrix", - "rustyline", -] - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec", -] - -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - -[[package]] -name = "num-bigint" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[package]] -name = "regex" -version = "1.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rustix" -version = "0.38.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "rustyline" -version = "13.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86" -dependencies = [ - "bitflags", - "cfg-if", - "clipboard-win", - "fd-lock", - "home", - "libc", - "log", - "memchr", - "nix", - "radix_trie", - "unicode-segmentation", - "unicode-width", - "utf8parse", - "winapi", -] - -[[package]] -name = "smallvec" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" - -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/matrix-bin/Cargo.toml b/matrix-bin/Cargo.toml index bdb8fb8..10c537e 100644 --- a/matrix-bin/Cargo.toml +++ b/matrix-bin/Cargo.toml @@ -10,6 +10,6 @@ path = "src/main.rs" [dependencies] clap = { version = "4", features = [ "derive" ] } ctrlc = "3" -matrix = { path = "../matrix" } -matrix-stdlib = { path = "../matrix-stdlib" } +matrix-lang = { path = "../matrix-lang" } +matrix-std = { path = "../matrix-std" } rustyline = { version = "13", features = [ "derive" ] } diff --git a/matrix-bin/src/helper.rs b/matrix-bin/src/helper.rs index 95e0848..df40946 100644 --- a/matrix-bin/src/helper.rs +++ b/matrix-bin/src/helper.rs @@ -1,7 +1,6 @@ use std::{borrow::Cow, rc::Rc, cell::RefCell}; - -use matrix::{lex::{Lexer, TokenData, Token}, vm::Vm}; use rustyline::{validate::{Validator, ValidationResult, ValidationContext}, highlight::Highlighter, Helper, Hinter, completion::Completer}; +use matrix_lang::prelude::*; #[derive(Helper, Hinter)] pub struct MatrixHelper { @@ -205,6 +204,7 @@ impl Highlighter for MatrixHelper { T::Else | T::While | T::Let | + T::Const | T::Function | T::Continue | T::Break | @@ -290,12 +290,12 @@ impl Completer for MatrixHelper { } let _ = (line, pos, ctx); - let globals = self.vm.borrow().global_names(); + let globals = self.vm.borrow().globals(); let names: Vec<Rc<str>> = globals .borrow() .clone() .into_iter() - .filter(|n| n.starts_with(&buf)) + .filter_map(|n| if n.name.starts_with(&buf) { Some(n.name.clone()) } else { None }) .collect(); if buf.is_empty() { diff --git a/matrix-bin/src/main.rs b/matrix-bin/src/main.rs index 225b353..64d1b3f 100644 --- a/matrix-bin/src/main.rs +++ b/matrix-bin/src/main.rs @@ -1,6 +1,6 @@ use std::{path::PathBuf, io::{self, Read, IsTerminal}, fs, cell::RefCell, rc::Rc}; use clap::{Parser as ArgParser, ColorChoice}; -use matrix::{compiler::{Compiler, CompilerBuilder}, vm::Vm, parse::{Parser, ParserBuilder}, value::Value}; +use matrix_lang::prelude::*; use repl::Repl; mod repl; @@ -12,16 +12,20 @@ pub struct Args { /// A path to a input program. Uses stdin if not specified. file: Option<PathBuf>, - /// Runs a repl, loading the provided program first + /// Compiles the given program #[arg(short, long)] - repl: bool, + compile: bool, + + /// Optional output for compiled output + #[arg(short, long)] + output: Option<PathBuf>, /// Print out debug information #[arg(short, long)] debug: bool, /// Choses color - #[arg(short, long)] + #[arg(long)] color: Option<ColorChoice>, /// Disables optimizations @@ -29,18 +33,21 @@ pub struct Args { disable_optimizations: bool, } +pub enum Mode { + Repl, + Execute(String), + Compile(String, PathBuf), +} + pub struct State<'a> { parser: Parser, compiler: Compiler<'a>, vm: Rc<RefCell<Vm>>, - repl: bool, color: bool, - #[allow(unused)] - debug: bool, } impl<'a> State<'a> { - pub fn new (args: Args) -> (Self, Option<String>) { + pub fn new (args: Args) -> (Self, Mode) { let stdin = read_stdin(); @@ -53,20 +60,43 @@ impl<'a> State<'a> { file = None; } - let repl = args.repl || file.is_none(); + let mode; + let repl; + if args.compile { + let path = match (args.output, args.file) { + (Some(path), _) => path, + (None, Some(path)) => { + let mut path = path.clone(); + path.set_extension("matc"); + path + }, + (None, None) => { + PathBuf::from("matc.out") + } + }; + let file = file.unwrap_or(String::new()); + mode = Mode::Compile(file, path); + repl = false; + } else if let Some(file) = file { + mode = Mode::Execute(file); + repl = false; + } else { + mode = Mode::Repl; + repl = true; + } + let mut vm = Vm::new(); let parser = ParserBuilder::new() .optimize(!args.disable_optimizations) .build(); - let mut vm = Vm::new(); let compiler = CompilerBuilder::new() .repl(repl) .debug(args.debug) .names(vm.names()) - .globals(vm.global_names()) + .globals(vm.globals()) .build(); - matrix_stdlib::load(&mut vm); + matrix_std::load(&mut vm); let color = match args.color { Some(ColorChoice::Auto) | None => { @@ -76,21 +106,40 @@ impl<'a> State<'a> { Some(ColorChoice::Never) => false, }; - (Self { parser, vm: Rc::new(RefCell::new(vm)), compiler, repl, debug: args.debug, color }, file) + (Self { + parser, + vm: Rc::new(RefCell::new(vm)), + compiler, + color, + }, mode) } - pub fn execute(&mut self, code: String) -> matrix::Result<Value> { - let ast = self.parser.parse(code)?; - let fun = self.compiler.compile(&ast)?; + pub fn execute(&mut self, fun: Rc<Function>) -> Result<Value> { let val = self.vm.try_borrow_mut().unwrap().run(fun)?; Ok(val) } + pub fn compile(&mut self, code: String) -> Result<Rc<Function>> { + let ast = self.parser.parse(code)?; + let fun = self.compiler.compile(&ast)?; + Ok(fun) + } + + pub fn load_program(&mut self, body: String) -> Result<Rc<Function>> { + match Program::load(&body)? { + Some(fun) => { + Ok(fun) + }, + None => { + self.compile(body) + }, + } + } } -pub fn error(err: matrix::Error, state: &State) { +pub fn error(err: Exception, state: &State) { if state.color { - println!("\x1b[31m\x1b[1mError:\x1b[0m {err}"); + println!("\x1b[31mError:\x1b[0m {err}"); } else { println!("Error: {err}"); } @@ -106,19 +155,33 @@ fn read_stdin() -> String { buffer } +fn handle_mode(state: &mut State, mode: Mode) -> Result<()> { + match mode { + Mode::Repl => { + let mut repl = Repl::new(state); + repl.run(); + }, + Mode::Execute(body) => { + let fun = state.load_program(body)?; + state.execute(fun)?; + }, + Mode::Compile(body, path) => { + let fun = state.compile(body)?; + let mut file = File::create(path).map_err(|e| + exception!(IO_EXCEPTION, "{e}") + )?; + Program::save(fun, &mut file)?; + } + }; + Ok(()) +} + fn main() { let args = Args::parse(); - let (mut state, file) = State::new(args); + let (mut state, mode) = State::new(args); - if let Some(file) = file { - if let Err(err) = state.execute(file) { - error(err, &state); - } + if let Err(e) = handle_mode(&mut state, mode) { + error(e, &state); } - - if state.repl { - Repl::new(state).run(); - } - } diff --git a/matrix-bin/src/repl.rs b/matrix-bin/src/repl.rs index f2964d4..fe9975f 100644 --- a/matrix-bin/src/repl.rs +++ b/matrix-bin/src/repl.rs @@ -1,21 +1,26 @@ use std::{io::Write, sync::atomic::Ordering}; - -use matrix::{value::Value, vm::Interupt}; -use rustyline::{Config, EditMode, ColorMode, Editor, CompletionType}; +use rustyline::{Config, EditMode, ColorMode, Editor, CompletionType, error::ReadlineError}; +use matrix_lang::prelude::*; use crate::{State, helper::MatrixHelper}; -pub struct Repl<'a> { - state: State<'a> +pub struct Repl<'s, 'a> { + state: &'s mut State<'a> } -impl<'a> Repl<'a> { +impl<'s, 'a> Repl<'s, 'a> { - pub fn new(state: State<'a>) -> Self { + pub fn new(state: &'s mut State<'a>) -> Self { Self { state } } - pub fn run(&mut self) { + fn execute(&mut self, line: String) -> Result<Value> { + let fun = self.state.compile(line)?; + let val = self.state.execute(fun)?; + Ok(val) + } + + pub fn run(&mut self) { let interupt = self.state.vm.borrow().interupt(); ctrlc::set_handler(move || { @@ -23,26 +28,33 @@ impl<'a> Repl<'a> { }).unwrap(); let config = Config::builder() + .indent_size(4) + .edit_mode(EditMode::Emacs) .check_cursor_position(true) .completion_type(CompletionType::List) - .edit_mode(EditMode::Emacs) .color_mode(if self.state.color { ColorMode::Enabled } else { ColorMode::Disabled }) .build(); let helper = MatrixHelper::new(self.state.vm.clone()); + let histfile = std::env::var("MATRIX_HISTORY").ok(); + let mut rl = Editor::with_config(config).unwrap(); rl.set_helper(Some(helper)); + if let Some(hf) = &histfile { + rl.load_history(hf).ok(); + } loop { - let Ok(line) = rl.readline(">> ") else { - break; - }; - if let Err(_) = rl.add_history_entry(&line) { - break; + let line = match rl.readline(">> ") { + Ok(line) => line, + Err(ReadlineError::Eof) => break, + Err(_) => continue, }; - match self.state.execute(line) { - Err(err) => crate::error(err, &self.state), + + rl.add_history_entry(&line).ok(); + + match self.execute(line) { Ok(val) => { if val != Value::Nil { if self.state.color { @@ -52,8 +64,13 @@ impl<'a> Repl<'a> { } } } - } - let _ = std::io::stdout().flush(); + Err(err) => crate::error(err, &self.state), + }; + std::io::stdout().flush().ok(); + } + + if let Some(hf) = &histfile { + rl.save_history(hf).ok(); } } |