From c37408c7a2e4ff5c6be395b9d49f9698e9af0edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 29 Sep 2020 13:27:54 +0200 Subject: [PATCH] read program from file; fmt, cleanup --- Cargo.lock | 340 +++++++++++++++++++++++++++++++ crsn.json5 | 10 + crsn/src/asm/parse/parse_data.rs | 2 +- crsn/src/builtin/exec.rs | 3 +- crsn/src/module/mod.rs | 2 +- crsn/src/runtime/fault.rs | 3 +- crsn/src/runtime/run_thread.rs | 5 +- crsn/src/utils/mod.rs | 3 +- crsn_arith/src/lib.rs | 4 +- crsn_arith/src/parse.rs | 2 +- crsn_screen/src/defs.rs | 2 +- crsn_screen/src/exec.rs | 39 ++-- crsn_screen/src/lib.rs | 6 +- crsn_stacks/src/exec.rs | 2 +- crsn_stacks/src/lib.rs | 12 +- crsn_stacks/src/parse.rs | 5 +- examples/factorial.csn | 15 ++ examples/screen_bounce.csn | 28 +++ launcher/Cargo.toml | 3 + launcher/src/main.rs | 186 ++++++++--------- launcher/src/read_file.rs | 14 ++ 21 files changed, 536 insertions(+), 150 deletions(-) create mode 100644 crsn.json5 create mode 100644 examples/factorial.csn create mode 100644 examples/screen_bounce.csn create mode 100644 launcher/src/read_file.rs diff --git a/Cargo.lock b/Cargo.lock index 707c7e2..58833dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,23 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.32" @@ -35,6 +53,39 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + [[package]] name = "cc" version = "1.0.60" @@ -58,6 +109,36 @@ dependencies = [ "time", ] +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clappconfig" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3bdf54005ba6e218706edda1659879b0bc2c28d01e8f15a45b33ff52c89848" +dependencies = [ + "anyhow", + "clap", + "env_logger", + "json5", + "log", + "serde", + "serde_json", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -124,6 +205,15 @@ dependencies = [ "crsn", ] +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + [[package]] name = "downcast-rs" version = "1.2.0" @@ -157,12 +247,40 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c53dc3a653e0f64081026e4bf048d48fec9fce90c66e8326ca7292df0ff2d82" +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + [[package]] name = "getrandom" version = "0.1.15" @@ -183,6 +301,15 @@ dependencies = [ "libc", ] +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + [[package]] name = "instant" version = "0.1.7" @@ -192,16 +319,35 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "json5" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb2522ff59fbfefb955e9bd44d04d5e5c2d0e8865bfc2c3d1ab3916183ef5ee" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + [[package]] name = "launcher" version = "0.1.0" dependencies = [ "anyhow", + "clappconfig", "crsn", "crsn_arith", "crsn_screen", "crsn_stacks", "log", + "serde", "simple_logger", "thiserror", ] @@ -236,6 +382,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -337,6 +489,12 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "orbclient" version = "0.3.27" @@ -373,6 +531,49 @@ dependencies = [ "winapi", ] +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1", +] + [[package]] name = "pkg-config" version = "0.3.18" @@ -394,6 +595,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.7" @@ -574,6 +781,24 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "regex" +version = "1.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -583,6 +808,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + [[package]] name = "scopeguard" version = "1.1.0" @@ -613,12 +844,55 @@ dependencies = [ "libc", ] +[[package]] +name = "serde" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "sexp" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8fa7ac9df84000b0238cf497cb2d3056bac2ff2a7d8cf179d2803b4b58571f" +[[package]] +name = "sha-1" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + [[package]] name = "simple_logger" version = "1.9.0" @@ -638,6 +912,12 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "syn" version = "1.0.41" @@ -663,6 +943,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.20" @@ -683,6 +981,15 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + [[package]] name = "time" version = "0.1.44" @@ -694,12 +1001,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.2" @@ -810,6 +1141,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/crsn.json5 b/crsn.json5 new file mode 100644 index 0000000..27c7e2b --- /dev/null +++ b/crsn.json5 @@ -0,0 +1,10 @@ +/* Croissant runtime config */ +{ + "log": { + /* Log level: "off", "error", "warn", "info", "debug", "trace" */ + "level": "trace", + /* Selective debug for modules: + * Mapping (Rust module path) -> (log level) */ + "modules": {} + } +} diff --git a/crsn/src/asm/parse/parse_data.rs b/crsn/src/asm/parse/parse_data.rs index 8d796d9..815ddf1 100644 --- a/crsn/src/asm/parse/parse_data.rs +++ b/crsn/src/asm/parse/parse_data.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::convert::TryFrom; use sexp::{Atom, Sexp}; @@ -6,7 +7,6 @@ use crate::asm::data::{DataDisp, Rd, RdData, reg, Wr, WrData}; use crate::asm::data::literal::Label; use crate::asm::error::CrsnError; use crate::asm::parse::sexp_expect::expect_string_atom; -use std::borrow::Cow; /// Parse a label pub fn parse_label(name: Option) -> Result { diff --git a/crsn/src/builtin/exec.rs b/crsn/src/builtin/exec.rs index ad5f08d..19870b7 100644 --- a/crsn/src/builtin/exec.rs +++ b/crsn/src/builtin/exec.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use crate::asm::data::{Rd, RdData}; use crate::asm::data::literal::Addr; use crate::asm::instr::Cond; @@ -6,7 +8,6 @@ use crate::module::{EvalRes, OpTrait}; use crate::runtime::fault::Fault; use crate::runtime::frame::StackFrame; use crate::runtime::run_thread::{state::RunState, ThreadInfo}; -use std::time::Duration; impl OpTrait for BuiltinOp { fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result { diff --git a/crsn/src/module/mod.rs b/crsn/src/module/mod.rs index 7dca685..cb5f51a 100644 --- a/crsn/src/module/mod.rs +++ b/crsn/src/module/mod.rs @@ -23,7 +23,7 @@ pub enum ParseOpRes { impl ParseOpRes { /// Helper to construct an extension op - pub fn ext(op : impl OpTrait) -> Self { + pub fn ext(op: impl OpTrait) -> Self { Self::Parsed(Op::Ext(Box::new(op))) } } diff --git a/crsn/src/runtime/fault.rs b/crsn/src/runtime/fault.rs index ed9097f..97918a2 100644 --- a/crsn/src/runtime/fault.rs +++ b/crsn/src/runtime/fault.rs @@ -1,8 +1,9 @@ +use std::borrow::Cow; + use thiserror::Error; use crate::asm::data::literal::{DebugMsg, Label, RoutineName, Value}; use crate::asm::data::Register; -use std::borrow::Cow; #[derive(Error, Debug)] pub enum Fault { diff --git a/crsn/src/runtime/run_thread.rs b/crsn/src/runtime/run_thread.rs index 8e2212f..3c9be78 100644 --- a/crsn/src/runtime/run_thread.rs +++ b/crsn/src/runtime/run_thread.rs @@ -11,7 +11,6 @@ use crate::module::EvalRes; use crate::runtime::fault::Fault; use crate::runtime::frame::StackFrame; use crate::runtime::program::Program; -use std::pin::Pin; #[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] pub struct ThreadToken(pub u32); @@ -67,7 +66,7 @@ impl RunThread { } } Err(Fault::Halt) => { - info!("Program ended."); + // TODO implement coordinated shutdown when more threads are running! break 'run; } Err(e) => { @@ -76,5 +75,7 @@ impl RunThread { } } } + + debug!("Thread ended."); } } diff --git a/crsn/src/utils/mod.rs b/crsn/src/utils/mod.rs index b5e5989..7f10c80 100644 --- a/crsn/src/utils/mod.rs +++ b/crsn/src/utils/mod.rs @@ -1,3 +1,4 @@ +pub use option_ext::UncheckedOptionExt; + mod option_ext; -pub use option_ext::UncheckedOptionExt; diff --git a/crsn_arith/src/lib.rs b/crsn_arith/src/lib.rs index 427a488..e3b2824 100644 --- a/crsn_arith/src/lib.rs +++ b/crsn_arith/src/lib.rs @@ -1,7 +1,7 @@ -use crsn::module::{CrsnExtension, ParseOpRes}; -use crsn::asm::parse::arg_parser::ArgParser; use crsn::asm::error::CrsnError; use crsn::asm::instr::Op; +use crsn::asm::parse::arg_parser::ArgParser; +use crsn::module::{CrsnExtension, ParseOpRes}; mod defs; mod parse; diff --git a/crsn_arith/src/parse.rs b/crsn_arith/src/parse.rs index c5f1284..4912393 100644 --- a/crsn_arith/src/parse.rs +++ b/crsn_arith/src/parse.rs @@ -2,7 +2,7 @@ use crsn::asm::data::{Rd, Wr}; use crsn::asm::error::CrsnError; use crsn::asm::instr::Op; use crsn::asm::parse::arg_parser::ArgParser; -use crsn::module::{ParseOpRes}; +use crsn::module::ParseOpRes; use crate::defs::ArithOp; diff --git a/crsn_screen/src/defs.rs b/crsn_screen/src/defs.rs index 66969a0..cb61d58 100644 --- a/crsn_screen/src/defs.rs +++ b/crsn_screen/src/defs.rs @@ -1,4 +1,4 @@ -use crsn::asm::data::{Rd, RdObj, Wr}; +use crsn::asm::data::Rd; #[derive(Clone, Debug, Eq, PartialEq)] pub enum ScreenOp { diff --git a/crsn_screen/src/exec.rs b/crsn_screen/src/exec.rs index 5299af9..b8c3f86 100644 --- a/crsn_screen/src/exec.rs +++ b/crsn_screen/src/exec.rs @@ -1,18 +1,15 @@ -use std::collections::{HashMap, VecDeque}; +use std::ops::Sub; +use std::time::{Duration, Instant}; + +use minifb::{ScaleMode, Window, WindowOptions}; use crsn::asm::data::literal::Value; use crsn::asm::instr::Cond; -use crsn::module::{CrsnExtension, EvalRes, OpTrait}; +use crsn::module::{EvalRes, OpTrait}; use crsn::runtime::fault::Fault; use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; use crate::defs::ScreenOp; -use minifb::{Window, WindowOptions, ScaleMode}; -use parking_lot::Mutex; -use std::sync::Arc; -use std::time::{Instant, Duration}; -use std::ops::Sub; -use crsn::utils::UncheckedOptionExt; #[derive(Debug)] struct Opts { @@ -27,7 +24,7 @@ struct Backend { buffer: Vec, window: Option, last_render: Instant, - opts: Opts + opts: Opts, } impl Default for Backend { @@ -41,19 +38,19 @@ impl Default for Backend { opts: Opts { auto_blit: true, frame_rate: Duration::from_micros(16600), - } + }, } } } -const OPT_AUTO_BLIT : u64 = 1; -const OPT_FRAME_RATE : u64 = 2; +const OPT_AUTO_BLIT: u64 = 1; +const OPT_FRAME_RATE: u64 = 2; // Hack for Window -unsafe impl std::marker::Send for Backend { } +unsafe impl std::marker::Send for Backend {} impl OpTrait for ScreenOp { - fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result { + fn execute(&self, _info: &ThreadInfo, state: &mut RunState) -> Result { let eres = EvalRes::default(); match self { ScreenOp::ScreenInit { width, height } => { @@ -64,11 +61,11 @@ impl OpTrait for ScreenOp { ScreenOp::SetOpt { opt, val } => { let opt = state.read(*opt)?; let val = state.read(*val)?; - let backend : &mut Backend = state.ext_mut(); + let backend: &mut Backend = state.ext_mut(); match opt { OPT_AUTO_BLIT => { - backend.opts.auto_blit = (val != 0); + backend.opts.auto_blit = val != 0; debug!("Set auto blit to {:?}", backend.opts.auto_blit); } OPT_FRAME_RATE => { @@ -83,7 +80,7 @@ impl OpTrait for ScreenOp { } ScreenOp::Blit { force } => { let force = state.read(*force)?; - let backend : &mut Backend = state.ext_mut(); + let backend: &mut Backend = state.ext_mut(); if force != 0 { blit(backend) @@ -96,7 +93,7 @@ impl OpTrait for ScreenOp { let y = state.read(*y)?; let color = state.read(*color)?; - let backend : &mut Backend = state.ext_mut(); + let backend: &mut Backend = state.ext_mut(); if x >= backend.width as u64 || y >= backend.height as u64 { state.set_flag(Cond::Overflow, true); @@ -104,7 +101,7 @@ impl OpTrait for ScreenOp { } match &mut backend.window { - Some(w) => { + Some(_w) => { let index = y * backend.width as u64 + x; if index as usize > backend.buffer.len() { warn!("Screen set pixel out of bounds"); @@ -130,7 +127,7 @@ impl OpTrait for ScreenOp { } fn init(state: &mut RunState, width: Value, height: Value) -> Result<(), Fault> { - let mut window = Window::new( + let window = Window::new( "Croissant", width as usize, height as usize, @@ -142,7 +139,7 @@ fn init(state: &mut RunState, width: Value, height: Value) -> Result<(), Fault> ).expect("Unable to create window"); // TODO fault - let backend : &mut Backend = state.ext_mut(); + let backend: &mut Backend = state.ext_mut(); if backend.window.is_some() { return Err(Fault::NotAllowed("Screen already initialized".into())); diff --git a/crsn_screen/src/lib.rs b/crsn_screen/src/lib.rs index 75c5360..39d07fc 100644 --- a/crsn_screen/src/lib.rs +++ b/crsn_screen/src/lib.rs @@ -1,10 +1,10 @@ #[macro_use] extern crate log; -use crsn::module::{CrsnExtension, ParseOpRes}; -use crsn::asm::parse::arg_parser::ArgParser; -use crsn::asm::instr::Op; use crsn::asm::error::CrsnError; +use crsn::asm::instr::Op; +use crsn::asm::parse::arg_parser::ArgParser; +use crsn::module::{CrsnExtension, ParseOpRes}; mod defs; mod parse; diff --git a/crsn_stacks/src/exec.rs b/crsn_stacks/src/exec.rs index 6cb71a4..b96ee1f 100644 --- a/crsn_stacks/src/exec.rs +++ b/crsn_stacks/src/exec.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, VecDeque}; use crsn::asm::data::literal::Value; use crsn::asm::instr::Cond; -use crsn::module::{CrsnExtension, EvalRes, OpTrait}; +use crsn::module::{EvalRes, OpTrait}; use crsn::runtime::fault::Fault; use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; diff --git a/crsn_stacks/src/lib.rs b/crsn_stacks/src/lib.rs index 914575a..828739f 100644 --- a/crsn_stacks/src/lib.rs +++ b/crsn_stacks/src/lib.rs @@ -1,10 +1,10 @@ -use crsn::module::{CrsnExtension, ParseOpRes}; -use crsn::asm::parse::arg_parser::ArgParser; -use crsn::asm::instr::Op; -use crsn::asm::error::CrsnError; -use crsn::runtime::run_thread::{ThreadInfo, RunState}; use crsn::asm::data::literal::Value; +use crsn::asm::error::CrsnError; +use crsn::asm::instr::Op; +use crsn::asm::parse::arg_parser::ArgParser; +use crsn::module::{CrsnExtension, ParseOpRes}; use crsn::runtime::fault::Fault; +use crsn::runtime::run_thread::{RunState, ThreadInfo}; mod defs; mod parse; @@ -28,7 +28,7 @@ impl CrsnExtension for StackOps { parse::parse(keyword, args) } - fn drop_obj(&self, ti: &ThreadInfo, state: &mut RunState, handle: Value) -> Result, Fault> { + fn drop_obj(&self, _ti: &ThreadInfo, state: &mut RunState, handle: Value) -> Result, Fault> { exec::drop_obj(state, handle) } } diff --git a/crsn_stacks/src/parse.rs b/crsn_stacks/src/parse.rs index a149859..b5368fc 100644 --- a/crsn_stacks/src/parse.rs +++ b/crsn_stacks/src/parse.rs @@ -1,10 +1,7 @@ - use crsn::asm::error::CrsnError; use crsn::asm::instr::Op; use crsn::asm::parse::arg_parser::ArgParser; -use crsn::module::{ParseOpRes}; - - +use crsn::module::ParseOpRes; use crate::defs::StackOp; diff --git a/examples/factorial.csn b/examples/factorial.csn new file mode 100644 index 0000000..11e17bc --- /dev/null +++ b/examples/factorial.csn @@ -0,0 +1,15 @@ +( + (main + (call fac 5) + (ld r0 res0) + (halt) + ) + (fac + (cmp arg0 2 + (eq? (ret 2))) + (sub r0 arg0 1) + (call fac r0) + (mul r0 arg0 res0) + (ret r0) + ) +) diff --git a/examples/screen_bounce.csn b/examples/screen_bounce.csn new file mode 100644 index 0000000..33f6e67 --- /dev/null +++ b/examples/screen_bounce.csn @@ -0,0 +1,28 @@ +( + (main + (sc-init 800 600) + (sc-opt 1 0) ; auto blit + (sc-opt 2 60) ; frame rate + + (ld r0 5) ; x + (ld r1 0) ; y + + (ld r2 1) ; dx + (ld r3 1) ; dy + + (ld r5 0x3300ff) + + (:loop) + (add r5 0x000001) + (and r5 0xffffff) + (sc-px r0 r1 r5) + (add r0 r2) + (add r1 r3) + (cmp r0 799 (eq? (ld r2 -1))) + (cmp r0 0 (eq? (ld r2 1))) + (cmp r1 599 (eq? (ld r3 -1))) + (cmp r1 0 (eq? (ld r3 1))) + (sc-blit 0) + (j :loop) + ) +) \ No newline at end of file diff --git a/launcher/Cargo.toml b/launcher/Cargo.toml index 5db0e67..e9487a1 100644 --- a/launcher/Cargo.toml +++ b/launcher/Cargo.toml @@ -16,3 +16,6 @@ simple_logger = "1.9.0" log = "0.4.11" thiserror = "1.0.20" anyhow = "1.0.32" +clappconfig = "0.4.0" + +serde = { version = "1.0.116", features = ["derive"] } diff --git a/launcher/src/main.rs b/launcher/src/main.rs index 29124b0..c3a1be9 100644 --- a/launcher/src/main.rs +++ b/launcher/src/main.rs @@ -1,109 +1,82 @@ #[macro_use] extern crate log; - +use std::collections::HashMap; use std::sync::Arc; -use simple_logger::SimpleLogger; +use clappconfig::{AppConfig, clap}; +use clappconfig::clap::ArgMatches; +use serde::{Deserialize, Serialize}; use crsn::asm::data::literal::Addr; use crsn::runtime::run_thread::{RunThread, ThreadToken}; -use crsn::runtime::run_thread; use crsn_arith::ArithOps; -use crsn_stacks::StackOps; use crsn_screen::ScreenOps; -use std::time::Duration; -use log::LevelFilter; - -fn main() { - SimpleLogger::new() - .with_level(LevelFilter::Warn) - .init().unwrap(); - - // ;(dec r0 (z? (ret))) - /*let program = " - ( - (main - (ld r0 2) - (:again) - (dec r0) - (jif nz :again) - (fault \"that's it\") - ) - ) - ";*/ - /* - let program = " - ( - (main - (ld r0 2) - (call add2x r0 15) - (ld r0 res0) - (fault \"that's it\") - ) - (add2x - (ld r0 arg0) - (ld r1 arg1) - (add r0 r1) - (add r0 r1) - (ret r0) - ) - ) - ";*/ - - /* let program = " - ( - (main - (j :lbl) - (ld _ arg0) - (fault) - (:lbl) - (call fac 5) - (ld r0 res0) - ) - (fac - (cmp arg0 2 - (eq? (ret 2))) - (ld r0 arg0) - (dec r0) - (call fac r0) - (ld r0 arg0) - (mul r0 res0) - (ret r0) - ) - ) - ";*/ - - let program = " - ( - (main - (sc-init 800 600) - (sc-opt 1 0) ; auto blit - (sc-opt 2 60) ; frame rate - - (ld r0 5) ; x - (ld r1 0) ; y - - (ld r2 1) ; dx - (ld r3 1) ; dy - - (ld r5 0x3300ff) - - (:loop) - (add r5 0x000001) - (and r5 0xffffff) - (sc-px r0 r1 r5) - (add r0 r2) - (add r1 r3) - (cmp r0 799 (eq? (ld r2 -1))) - (cmp r0 0 (eq? (ld r2 1))) - (cmp r1 599 (eq? (ld r3 -1))) - (cmp r1 0 (eq? (ld r3 1))) - (sc-blit 0) - (j :loop) +use crsn_stacks::StackOps; + +mod read_file; + +#[derive(Debug, Clone, Serialize, Deserialize)] +struct LogConfig { + level: String, + modules: HashMap, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +struct Config { + log: LogConfig, + #[serde(skip)] + program_file: String, +} + +impl Default for Config { + fn default() -> Self { + Self { + log: LogConfig { + level: "info".to_string(), + modules: Default::default(), + }, + program_file: "".to_string(), + } + } +} + +impl AppConfig for Config { + type Init = Self; + + fn logging(&self) -> &str { + &self.log.level + } + + fn logging_mod_levels(&self) -> Option<&HashMap> { + Some(&self.log.modules) + } + + /// Add args to later use in the `configure` method. + fn add_args<'a: 'b, 'b>(clap: clap::App<'a, 'b>) -> clap::App<'a, 'b> { + // Default impl + clap.arg( + clap::Arg::with_name("input") + .value_name("FILE") + .help("Program to run") + .required_unless("default-config") + .takes_value(true), ) - ) - "; + } + + fn configure(mut self, clap: &ArgMatches) -> anyhow::Result { + self.program_file = clap.value_of("input").unwrap().to_string(); + Ok(self) + } +} + + +fn main() -> anyhow::Result<()> { + let config = Config::init("crsn", "crsn.json5", env!("CARGO_PKG_VERSION"))?; + + info!("Loading {}", config.program_file); + + let source = read_file::read_file(&config.program_file)?; let parsers = Arc::new(vec![ ArithOps::new(), @@ -111,18 +84,23 @@ fn main() { ScreenOps::new(), ]); - let parsed = crsn::asm::assemble(program, parsers).unwrap(); + let parsed = crsn::asm::assemble(&source, parsers)?; - let uniq = run_thread::new_uniq(); + info!("Start runtime"); - let mut thread1 = RunThread::new(ThreadToken(0), Some(uniq.clone()), parsed.clone(), Addr(0), &[]); - //thread1.set_speed(Duration::from_millis(250)); + let thread = RunThread::new( + ThreadToken(0), + None, + parsed.clone(), + Addr(0), // TODO find "main"? + &[], // TODO from CLI? + ); - let _thread2 = RunThread::new(ThreadToken(1), Some(uniq), parsed.clone(), Addr(0), &[]); + let a = thread.start(); + // ... + let _ = a.join(); - let a = thread1.start(); - //let b = thread2.start(); + info!("Runtime shut down."); - a.join().unwrap(); - //b.join().unwrap(); + Ok(()) } diff --git a/launcher/src/read_file.rs b/launcher/src/read_file.rs new file mode 100644 index 0000000..5ac24b8 --- /dev/null +++ b/launcher/src/read_file.rs @@ -0,0 +1,14 @@ +use std::fs::File; +use std::io; +use std::io::Read; +use std::path::Path; + +/// Read a file to string +pub fn read_file>(path: P) -> io::Result { + let path = path.as_ref(); + let mut file = File::open(path)?; + + let mut buf = String::new(); + file.read_to_string(&mut buf)?; + Ok(buf) +}