From 5f9ca90fd54987d4b342e863fa893b4b7f0c35b4 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 23 Apr 2022 17:03:17 +0200 Subject: [PATCH] test out better debugging --- Cargo.lock | 374 +++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 5 +- src/ast.rs | 26 +++- src/bytecode.rs | 25 ++-- src/compile.rs | 2 +- src/errors.rs | 2 +- src/gc.rs | 28 ++-- src/lib.rs | 15 +- src/parse.rs | 12 +- src/util.rs | 13 +- src/vm.rs | 59 ++++---- test.dil | 4 - tests/common.rs | 2 +- 13 files changed, 422 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04ad0da..70bebe3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,10 +3,46 @@ version = 3 [[package]] -name = "autocfg" -version = "1.0.1" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" @@ -14,6 +50,18 @@ version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "console" version = "0.15.0" @@ -28,24 +76,41 @@ dependencies = [ ] [[package]] -name = "debug2" -version = "0.1.0" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e70062ea3df6318129246273f4b1748900752293d47e7610b5e8a84bc14c44c" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "debug2-derive", + "cfg-if", ] [[package]] -name = "debug2-derive" -version = "0.1.0" +name = "dbg-pls" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b37e8941dd632993cf5b4ea33a630faa132fdc42481a8c2621dede631e871a" +checksum = "e845b944ea4a6b446aec7c221c48fd6e73f2ab38e1af720cac0f47895dcc4580" +dependencies = [ + "dbg-pls-derive", + "itoa", + "once_cell", + "prettyplease", + "proc-macro2", + "quote", + "ryu", + "syn", + "syntect", + "textwrap", +] + +[[package]] +name = "dbg-pls-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46318b37603779055a193fbb0454bb762e284f72a4d3c231f4a6ab8d3eede31" dependencies = [ "proc-macro2", "quote", "syn", - "synstructure", ] [[package]] @@ -53,7 +118,7 @@ name = "dilaria" version = "0.1.0" dependencies = [ "bumpalo", - "debug2", + "dbg-pls", "insta", "rustc-hash", ] @@ -64,6 +129,24 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "flate2" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "hashbrown" version = "0.11.2" @@ -72,9 +155,9 @@ checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", @@ -82,17 +165,16 @@ dependencies = [ [[package]] name = "insta" -version = "1.10.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3cb858fc306825b542b1311d5fd536e4483680528f303a17a1d6803b0f6ce17" +checksum = "689960f187c43c01650c805fb6bc6f55ab944499d86d4ffe9474ad78991d8e94" dependencies = [ "console", - "lazy_static", + "once_cell", "serde", "serde_json", "serde_yaml", "similar", - "uuid", ] [[package]] @@ -108,10 +190,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "libc" -version = "0.2.112" +name = "lazycell" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.124" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" + +[[package]] +name = "line-wrap" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" +dependencies = [ + "safemem", +] [[package]] name = "linked-hash-map" @@ -120,29 +217,122 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] -name = "once_cell" -version = "1.9.0" +name = "memchr" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "miniz_oxide" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +dependencies = [ + "adler", +] + +[[package]] +name = "num_threads" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" + +[[package]] +name = "onig" +version = "6.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ddfe2c93bb389eea6e6d713306880c7f6dcc99a75b659ce145d962c861b225" +dependencies = [ + "bitflags", + "lazy_static", + "libc", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd3eee045c84695b53b20255bb7317063df090b68e18bfac0abb6c39cf7f33e" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "plist" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225" +dependencies = [ + "base64", + "indexmap", + "line-wrap", + "serde", + "time", + "xml-rs", +] + +[[package]] +name = "prettyplease" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b83ec2d0af5c5c556257ff52c9f98934e243b9fd39604bfb2a9b75ec2e97f18" +dependencies = [ + "proc-macro2", + "syn", +] [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -156,19 +346,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] -name = "serde" -version = "1.0.133" +name = "safemem" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.133" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -177,9 +382,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", @@ -205,10 +410,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" [[package]] -name = "syn" -version = "1.0.85" +name = "smawk" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" +checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" + +[[package]] +name = "syn" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ "proc-macro2", "quote", @@ -216,15 +427,25 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "syntect" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031" dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", + "bincode", + "bitflags", + "flate2", + "fnv", + "lazy_static", + "lazycell", + "onig", + "plist", + "regex-syntax", + "serde", + "serde_derive", + "serde_json", + "walkdir", + "yaml-rust", ] [[package]] @@ -237,6 +458,43 @@ dependencies = [ "winapi", ] +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "time" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +dependencies = [ + "itoa", + "libc", + "num_threads", +] + +[[package]] +name = "unicode-linebreak" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f" +dependencies = [ + "regex", +] + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -244,10 +502,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] -name = "uuid" -version = "0.8.2" +name = "walkdir" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] [[package]] name = "winapi" @@ -265,12 +528,27 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 109993f..a945a96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,14 +7,13 @@ edition = "2021" [dependencies] bumpalo = { version = "3.8.0", features = ["collections"] } +dbg-pls = { version = "0.2.2", features = ["colors", "derive"], optional = true } rustc-hash = { version = "1.1.0", optional = true } -debug2 = { version = "0.1.0", optional = true } - [features] fxhash = ["rustc-hash"] -_debug = ["debug2"] +_debug = ["dbg-pls"] # todo: we don't actually want this as a default feature default = ["_debug", "fxhash"] diff --git a/src/ast.rs b/src/ast.rs index ed90b74..c2a75c4 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -5,9 +5,9 @@ use crate::errors::Span; use crate::gc::Symbol; -use bumpalo::collections::Vec; #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Ident { pub sym: Symbol, pub span: Span, @@ -16,12 +16,14 @@ pub struct Ident { pub type Program<'ast> = Block<'ast>; #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Block<'ast> { - pub stmts: Vec<'ast, Stmt<'ast>>, + pub stmts: &'ast [Stmt<'ast>], pub span: Span, } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Stmt<'ast> { Declaration(Declaration<'ast>), Assignment(Assignment<'ast>), @@ -37,6 +39,7 @@ pub enum Stmt<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Declaration<'ast> { pub span: Span, pub name: Ident, @@ -44,6 +47,7 @@ pub struct Declaration<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Assignment<'ast> { pub span: Span, pub lhs: Expr<'ast>, @@ -51,14 +55,16 @@ pub struct Assignment<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct FnDecl<'ast> { pub span: Span, pub name: Ident, - pub params: Vec<'ast, Ident>, + pub params: &'ast [Ident], pub body: Block<'ast>, } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct IfStmt<'ast> { pub span: Span, pub cond: Expr<'ast>, @@ -67,6 +73,7 @@ pub struct IfStmt<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum ElsePart<'ast> { Else(Block<'ast>, Span), ElseIf(IfStmt<'ast>, Span), @@ -81,6 +88,7 @@ impl ElsePart<'_> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct WhileStmt<'ast> { pub span: Span, pub cond: Expr<'ast>, @@ -88,6 +96,7 @@ pub struct WhileStmt<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Expr<'ast> { Ident(Ident), Literal(Literal<'ast>), @@ -109,10 +118,11 @@ impl Expr<'_> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Literal<'ast> { String(Symbol, Span), Number(f64, Span), - Array(Vec<'ast, Expr<'ast>>, Span), + Array(&'ast [Expr<'ast>], Span), Object(Span), Boolean(bool, Span), Null(Span), @@ -132,6 +142,7 @@ impl Literal<'_> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct UnaryOp<'ast> { pub span: Span, pub expr: Expr<'ast>, @@ -139,12 +150,14 @@ pub struct UnaryOp<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum UnaryOpKind { Not, Neg, } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct BinaryOp<'ast> { pub span: Span, pub lhs: Expr<'ast>, @@ -153,6 +166,7 @@ pub struct BinaryOp<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum BinaryOpKind { And, Or, @@ -170,6 +184,7 @@ pub enum BinaryOpKind { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Call<'ast> { pub callee: Expr<'ast>, pub span: Span, @@ -177,7 +192,8 @@ pub struct Call<'ast> { } #[derive(Debug, PartialEq)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum CallKind<'ast> { Field(Ident), - Fn(Vec<'ast, Expr<'ast>>), + Fn(&'ast [Expr<'ast>]), } diff --git a/src/bytecode.rs b/src/bytecode.rs index 1824591..1df3cf5 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -61,14 +61,15 @@ use crate::errors::Span; use crate::vm::Value; use bumpalo::collections::Vec; +use std::fmt::{Debug, Formatter}; /// This struct contains all data for a function. -#[derive(Debug)] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct FnBlock<'bc> { /// The bytecode of the function pub code: Vec<'bc, Instr>, - /// The sizes of the stack required by the function after the instruction at the same index. This is only used - /// during compilation to calculate local variable offsets. + /// The sizes of the stack required by the function after the instruction at the same index. + /// This is only used during compilation to calculate local variable offsets. pub stack_sizes: Vec<'bc, usize>, /// The corresponding source code location of each instruction. This is debuginfo and only /// used if there are errors. @@ -78,23 +79,19 @@ pub struct FnBlock<'bc> { pub arity: u32, } -#[cfg(feature = "_debug")] -impl debug2::Debug for FnBlock<'_> { - fn fmt(&self, f: &mut debug2::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("FnBlock") - .field("code", &self.code.as_slice()) - .field("stack_sizes", &self.stack_sizes.as_slice()) - .field("spans", &self.spans.as_slice()) - .field("arity", &self.arity) - .finish() +impl Debug for FnBlock<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + self.code.fmt(f) } } +/// Index into the block list pub type Function = usize; -/// A bytecode instruction. For more details on the structure of the bytecode, read the module level docs [`bytecode`](`self`) +/// A bytecode instruction. For more details on the structure of the bytecode, +/// read the module level docs [`bytecode`](`self`) #[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "_debug", derive(debug2::Debug))] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Instr { /// An operation that does nothing. Nop, diff --git a/src/compile.rs b/src/compile.rs index 7ffe4c4..c62755e 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -471,7 +471,7 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> { let offset = self.env.borrow().lookup_local(name)?; - for param in params { + for param in params.iter() { self.compile_expr(param)?; } diff --git a/src/errors.rs b/src/errors.rs index a357f5a..89da85a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -13,7 +13,7 @@ pub use span::Span; mod span { #[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)] - #[cfg_attr(feature = "_debug", derive(debug2::Debug))] + #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Span { pub start: usize, pub end: usize, diff --git a/src/gc.rs b/src/gc.rs index 589ae55..ebde3c0 100644 --- a/src/gc.rs +++ b/src/gc.rs @@ -18,6 +18,13 @@ pub struct Gc { ptr: NonNull, } +#[cfg(feature = "_debug")] +impl dbg_pls::DebugPls for Gc { + fn fmt(&self, f: dbg_pls::Formatter<'_>) { + todo!() + } +} + impl Deref for Gc { type Target = T; @@ -30,21 +37,6 @@ impl Deref for Gc { } } -#[cfg(feature = "_debug")] -impl debug2::Debug for Gc { - fn fmt(&self, f: &mut debug2::Formatter<'_>) -> std::fmt::Result { - T::fmt(&*self, f) - } -} - -#[cfg(feature = "_debug")] -impl debug2::Debug for Gc { - fn fmt(&self, f: &mut debug2::Formatter<'_>) -> std::fmt::Result { - let str = self.deref(); - debug2::Debug::fmt(&str, f) - } -} - impl Debug for Gc { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { T::fmt(self, f) @@ -61,7 +53,7 @@ impl Copy for Gc {} /// An reference to an interned String. Hashing and Equality are O(1) and just look at the pointer address #[derive(Clone, Copy)] -#[cfg_attr(feature = "_debug", derive(debug2::Debug))] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Symbol { gc: Gc, } @@ -74,20 +66,18 @@ type ObjectMap = HashMap; /// ``` /// This is inside the local x now. #[derive(Clone, Copy)] -#[cfg_attr(feature = "_debug", derive(debug2::Debug))] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Object { gc: Gc, } #[derive(Debug)] #[repr(C)] -#[cfg_attr(feature = "_debug", derive(debug2::Debug))] struct HeapObject { kind: HeapObjectKind, } #[derive(Debug)] -#[cfg_attr(feature = "_debug", derive(debug2::Debug))] enum HeapObjectKind { String(Gc), Object(ObjectMap), diff --git a/src/lib.rs b/src/lib.rs index ce5287d..52af954 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,14 +19,14 @@ pub use lex::*; pub use parse::*; #[cfg(not(feature = "fxhash"))] -#[allow(clippy::disallowed_type)] +#[allow(clippy::disallowed_types)] type HashMap = std::collections::HashMap; #[cfg(feature = "fxhash")] type HashMap = rustc_hash::FxHashMap; #[cfg(not(feature = "fxhash"))] -#[allow(clippy::disallowed_type)] +#[allow(clippy::disallowed_types)] type HashSet = std::collections::HashSet; #[cfg(feature = "fxhash")] @@ -59,7 +59,7 @@ pub fn run_program(program: &str, cfg: &mut Config) { fn process_ast(program: &str, ast: &Program, mut runtime: RtAlloc, cfg: &mut Config<'_>) { if cfg.debug { - println!("AST:\n{:?}\n", ast); + util::dbg("AST:\n", ast); } let bytecode_alloc = Bump::new(); @@ -69,14 +69,7 @@ fn process_ast(program: &str, ast: &Program, mut runtime: RtAlloc, cfg: &mut Con match bytecode { Ok(code) => { if cfg.debug { - #[cfg(feature = "_debug")] - { - println!("Bytecode:\n{}\n", debug2::pprint(code)); - } - #[cfg(not(feature = "_debug"))] - { - println!("Bytecode:\n{:#?}\n", code); - } + println!("Bytecode:\n{:#?}\n", code); } let result = vm::execute(code, runtime, cfg); diff --git a/src/parse.rs b/src/parse.rs index 2204b54..49d46da 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -97,12 +97,12 @@ where } } - fn statement_list(&mut self) -> ParseResult>> { + fn statement_list(&mut self) -> ParseResult<&'ast [Stmt<'ast>]> { enter_parse!(self); let mut stmts = Vec::new_in(self.bump); let return_stmts = loop { if let Some(TokenKind::BraceC) | None = self.peek_kind() { - break Ok(stmts); + break Ok(stmts.into_bump_slice()); } let stmt = self.statement()?; stmts.push(stmt); @@ -190,7 +190,7 @@ where })) } - fn fn_args(&mut self) -> ParseResult> { + fn fn_args(&mut self) -> ParseResult<&'ast [Ident]> { enter_parse!(self); self.expect(TokenKind::ParenO)?; @@ -597,7 +597,7 @@ where return_expr } - fn parse_list(&mut self, close: TokenKind, mut parser: F) -> ParseResult> + fn parse_list(&mut self, close: TokenKind, mut parser: F) -> ParseResult<&'ast [T]> where F: FnMut(&mut Self) -> ParseResult, { @@ -606,7 +606,7 @@ where let mut elements = Vec::new_in(self.bump); if self.peek_kind() == Some(&close) { - return Ok(elements); + return Ok(elements.into_bump_slice()); } let expr = parser(self)?; @@ -632,7 +632,7 @@ where } exit_parse!(self); - Ok(elements) + Ok(elements.into_bump_slice()) } // token helpers diff --git a/src/util.rs b/src/util.rs index d94af05..9b2e0d4 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,9 +1,20 @@ /// Statically asserts that the size of the type is x bytes big (on 64-bit) macro_rules! assert_size { - ($name:ident == $size:expr) => { + ($name:ident <= $size:expr) => { #[cfg(target_pointer_width = "64")] const _: [(); $size] = [(); ::std::mem::size_of::<$name>()]; }; } pub(crate) use assert_size; +use std::fmt::Display; + +#[cfg(feature = "_debug")] +pub fn dbg(prefix: impl Display, x: impl dbg_pls::DebugPls) { + eprintln!("{prefix}{}", dbg_pls::pretty(&x)) +} + +#[cfg(not(feature = "_debug"))] +pub fn dbg(prefix: impl Display, x: impl std::fmt::Debug) { + eprintln!("{prefix}{x:#?}"); +} diff --git a/src/vm.rs b/src/vm.rs index 25d0ab8..046a210 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -8,7 +8,8 @@ use std::io::{Read, Write}; type VmError = Box<&'static str>; type VmResult = Result<(), VmError>; -util::assert_size!(VmResult == 8); +// never get bigger than a machine word. +util::assert_size!(VmResult <= std::mem::size_of::()); pub fn execute<'bc>( bytecode: &'bc [FnBlock<'bc>], @@ -31,7 +32,7 @@ pub fn execute<'bc>( } #[derive(Debug, Clone, Copy)] -#[cfg_attr(feature = "_debug", derive(debug2::Debug))] +#[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Value { /// `null` Null, @@ -51,7 +52,7 @@ pub enum Value { NativeU(usize), } -util::assert_size!(Value == 24); +util::assert_size!(Value <= 24); const TRUE: Value = Value::Bool(true); const FALSE: Value = Value::Bool(false); @@ -70,22 +71,23 @@ struct Vm<'bc, 'io> { current_block_index: usize, /// The offset of the first parameter of the current function stack_offset: usize, - /// Index of the instruction currently being executed + /// Index of the next instruction being executed. is out of bounds if the current + /// instruction is the last one pc: usize, } impl<'bc> Vm<'bc, '_> { fn execute_function(&mut self) -> VmResult { - let code = &self.current.code; - loop { - let instr = code.get(self.pc); + let instr = self.current.code.get(self.pc); + self.pc += 1; match instr { Some(&instr) => self.dispatch_instr(instr)?, None => return Ok(()), } - // debug_assert_eq!(self.current.stack_sizes[self.pc], self.stack.len()); - self.pc += 1; + if self.pc > 0 { + debug_assert_eq!(self.current.stack_sizes[self.pc - 1], self.stack.len()); + } } } @@ -188,8 +190,7 @@ impl<'bc> Vm<'bc, '_> { } Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize, Instr::Call => self.call()?, - // todo implement - Instr::Return => self.ret()?, + Instr::Return => return Ok(()), Instr::ShrinkStack(size) => { assert!(self.stack.len() >= size); let new_len = self.stack.len() - size; @@ -217,26 +218,22 @@ impl<'bc> Vm<'bc, '_> { let old_offset = self.stack_offset; let old_idx = self.current_block_index; let function = self.stack.pop().unwrap(); - if let Value::Function(func) = function { - let fn_block = &self.blocks[func]; + let function = function.unwrap_function(); + let fn_block = &self.blocks[function]; - let new_stack_frame_start = self.stack.len(); - self.stack_offset = new_stack_frame_start; + let new_stack_frame_start = self.stack.len(); + self.stack_offset = new_stack_frame_start; - self.stack.push(Value::NativeU(old_offset)); - self.stack.push(Value::NativeU(self.pc)); - self.stack.push(Value::Function(old_idx)); + self.stack.push(Value::NativeU(old_offset)); + self.stack.push(Value::NativeU(self.pc)); + self.stack.push(Value::Function(old_idx)); - self.current_block_index = func; - self.current = fn_block; + self.current_block_index = function; + self.current = fn_block; - self.pc = 0; + self.pc = 0; - // TODO don't be recursive like this - self.execute_function()?; - } else { - return Err("not a function".into()); - } + // we are now set up correctly, let the next instruction run Ok(()) } @@ -246,9 +243,9 @@ impl<'bc> Vm<'bc, '_> { let bookkeeping_offset = self.stack_offset + current_arity; - let old_stack_offset = self.stack[bookkeeping_offset].as_native_int(); - let old_pc = self.stack[bookkeeping_offset + 1].as_native_int(); - let old_function = self.stack[bookkeeping_offset + 2].as_function(); + let old_stack_offset = self.stack[bookkeeping_offset].unwrap_native_int(); + let old_pc = self.stack[bookkeeping_offset + 1].unwrap_native_int(); + let old_function = self.stack[bookkeeping_offset + 2].unwrap_function(); self.stack_offset = old_stack_offset; self.pc = old_pc; @@ -281,7 +278,7 @@ Expected Stack size after instruction: {}", impl Value { /// Unwrap the Value into a `usize` expecting the `NativeU` variant - fn as_native_int(&self) -> usize { + fn unwrap_native_int(&self) -> usize { if let Value::NativeU(n) = self { *n } else { @@ -290,7 +287,7 @@ impl Value { } /// Unwrap the Value into a `Function` expecting the `Function` variant - fn as_function(&self) -> Function { + fn unwrap_function(&self) -> Function { if let Value::Function(fun) = self { *fun } else { diff --git a/test.dil b/test.dil index f587f20..d40ef00 100644 --- a/test.dil +++ b/test.dil @@ -4,7 +4,3 @@ fn test() { test(); test(); - -fn uwu() {} - -uwu(); diff --git a/tests/common.rs b/tests/common.rs index 94cada5..2ab7e16 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -4,7 +4,7 @@ macro_rules! run_test { #[test] fn $name() { let code = $code; - let output = crate::common::_run_test(code); + let output = $crate::common::_run_test(code); insta::assert_debug_snapshot!(output); } };