From ca14802a2130b9e522fc4df2da9fe4d87eaa7339 Mon Sep 17 00:00:00 2001 From: MCorange99 Date: Sat, 23 Mar 2024 03:58:42 +0200 Subject: [PATCH] v2 --- .github/workflows/rust.yml | 26 - .gitignore | 15 +- .vscode/extensions.json | 11 + .vscode/launch.json | 45 + .vscode/settings.json | 5 + Cargo.lock | 490 ++--- Cargo.toml | 15 +- README.md | 23 - REF.md | 53 + editor/vscode/.gitignore | 2 - editor/vscode/.vscode/launch.json | 17 - editor/vscode/.vscodeignore | 4 - editor/vscode/CHANGELOG.md | 9 - editor/vscode/LICENSE | 0 editor/vscode/README.md | 17 - editor/vscode/language-configuration.json | 30 - editor/vscode/mclang-0.0.3.vsix | Bin 4807 -> 0 bytes editor/vscode/package.json | 42 - editor/vscode/syntaxes/mclang.tmLanguage.json | 147 -- editor/vscode/vsc-extension-quickstart.md | 29 - editor/vscode/yarn.lock | 1784 ----------------- examples/hello_world.mcl | 4 - examples/rule110.mcl | 39 - examples/seq_100.mcl | 5 - include/compat.mcl | 1 - include/fs.mcl | 18 - include/int.mcl | 15 - include/io.mcl | 50 - include/linux.mcl | 322 --- include/linux/io.mcl | 14 + include/linux/linux.mcl | 2 + include/linux/syscalls.mcl | 322 +++ include/mem.mcl | 0 include/std.mcl | 8 +- include/types.mcl | 4 + include/util.mcl | 15 - src/bin/mcl_test_dev.rs | 172 -- src/cli.rs | 129 ++ src/compile/commands.rs | 88 - src/compile/linux_x86_64.rs | 661 ------ src/compile/mod.rs | 28 - src/compiler/mod.rs | 104 + src/compiler/utils.rs | 36 + src/compiler/x86_64_linux_nasm/mod.rs | 521 +++++ src/compiler/x86_64_linux_nasm/utils.rs | 37 + src/config.rs | 26 - src/constants.rs | 277 --- src/errors/mod.rs | 18 - src/interpret/linux_x86_64/mod.rs | 425 ---- src/interpret/linux_x86_64/syscalls.rs | 22 - src/interpret/mod.rs | 27 - src/lexer.rs | 126 -- src/lexer/mod.rs | 389 ++++ src/logger/colors.rs | 32 + src/logger/macros.rs | 106 + src/logger/mod.rs | 83 + src/logger/types.rs | 40 + src/main.rs | 174 +- src/parser.rs | 222 -- src/parser/builtin.rs | 46 + src/parser/mod.rs | 787 ++++++++ src/parser/precompiler.rs | 213 ++ src/parser/utils.rs | 103 + src/precompiler.rs | 147 -- src/preprocessor.rs | 617 ------ src/typechecker.rs | 403 ---- src/types/ast/mod.rs | 215 ++ src/types/common.rs | 37 + src/types/mod.rs | 3 + src/types/token/mod.rs | 162 ++ src/util.rs | 117 -- test.mcl | 49 +- tests/fail_unknown_word.mcl | 1 - tests/math.mcl | 7 - 74 files changed, 3745 insertions(+), 6488 deletions(-) delete mode 100644 .github/workflows/rust.yml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json delete mode 100644 README.md create mode 100644 REF.md delete mode 100644 editor/vscode/.gitignore delete mode 100644 editor/vscode/.vscode/launch.json delete mode 100644 editor/vscode/.vscodeignore delete mode 100644 editor/vscode/CHANGELOG.md delete mode 100644 editor/vscode/LICENSE delete mode 100644 editor/vscode/README.md delete mode 100644 editor/vscode/language-configuration.json delete mode 100644 editor/vscode/mclang-0.0.3.vsix delete mode 100644 editor/vscode/package.json delete mode 100644 editor/vscode/syntaxes/mclang.tmLanguage.json delete mode 100644 editor/vscode/vsc-extension-quickstart.md delete mode 100644 editor/vscode/yarn.lock delete mode 100644 examples/hello_world.mcl delete mode 100755 examples/rule110.mcl delete mode 100644 examples/seq_100.mcl delete mode 100644 include/compat.mcl delete mode 100644 include/fs.mcl delete mode 100644 include/int.mcl delete mode 100644 include/io.mcl delete mode 100644 include/linux.mcl create mode 100644 include/linux/io.mcl create mode 100644 include/linux/linux.mcl create mode 100644 include/linux/syscalls.mcl delete mode 100644 include/mem.mcl create mode 100644 include/types.mcl delete mode 100644 include/util.mcl delete mode 100644 src/bin/mcl_test_dev.rs create mode 100644 src/cli.rs delete mode 100644 src/compile/commands.rs delete mode 100644 src/compile/linux_x86_64.rs delete mode 100644 src/compile/mod.rs create mode 100644 src/compiler/mod.rs create mode 100644 src/compiler/utils.rs create mode 100644 src/compiler/x86_64_linux_nasm/mod.rs create mode 100644 src/compiler/x86_64_linux_nasm/utils.rs delete mode 100644 src/config.rs delete mode 100644 src/constants.rs delete mode 100644 src/errors/mod.rs delete mode 100644 src/interpret/linux_x86_64/mod.rs delete mode 100644 src/interpret/linux_x86_64/syscalls.rs delete mode 100644 src/interpret/mod.rs delete mode 100644 src/lexer.rs create mode 100644 src/lexer/mod.rs create mode 100644 src/logger/colors.rs create mode 100644 src/logger/macros.rs create mode 100644 src/logger/mod.rs create mode 100644 src/logger/types.rs delete mode 100644 src/parser.rs create mode 100644 src/parser/builtin.rs create mode 100644 src/parser/mod.rs create mode 100644 src/parser/precompiler.rs create mode 100644 src/parser/utils.rs delete mode 100644 src/precompiler.rs delete mode 100644 src/preprocessor.rs delete mode 100644 src/typechecker.rs create mode 100644 src/types/ast/mod.rs create mode 100644 src/types/common.rs create mode 100644 src/types/mod.rs create mode 100644 src/types/token/mod.rs delete mode 100644 src/util.rs delete mode 100644 tests/fail_unknown_word.mcl delete mode 100644 tests/math.mcl diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 782d450..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Rust - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Build - run: cargo build --release --verbose - - name: Run cargo tests - run: cargo test --release --verbose - - name: Run lang tests - run: ./target/release/mcl_test_dev -m test - - name: Check formatting with clippy - run: cargo clippy -- -W clippy::pedantic -A clippy::struct-excessive-bools -A clippy::too_many_lines -A clippy::similar_names diff --git a/.gitignore b/.gitignore index 281acbf..bc90cfa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ -/target -/a - -test -test.nasm -test.o \ No newline at end of file +/* +!/.vscode +!/.gitignore +!/.gitkeep +!/src +!/include +!/Cargo* +!/REF.md +!/*.mcl \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c2c934d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,11 @@ +{ + "recommendations": [ + "aaron-bond.better-comments", + "usernamehw.errorlens", + "tamasfe.even-better-toml", + "platformio.platformio-ide", + "1YiB.rust-bundle", + "tamasfe.even-better-toml", + "ms-vscode.cpptools" + ] +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2c194bb --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'mclangc-v2'", + "cargo": { + "args": [ + "build", + "--bin=mclangc-v2", + "--package=mclangc-v2" + ], + "filter": { + "name": "mclangc-v2", + "kind": "bin" + } + }, + "args": ["-o", "test", "test.mcl", "-r"], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'mclangc-v2'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=mclangc-v2", + "--package=mclangc-v2" + ], + "filter": { + "name": "mclangc-v2", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c46eec0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "*.s": "platformio-debug.asm" + } +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 54e6f9f..b530893 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,76 +3,106 @@ version = 3 [[package]] -name = "addr2line" -version = "0.19.0" +name = "anstream" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ - "gimli", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", ] [[package]] -name = "adler" +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] [[package]] -name = "backtrace" -version = "0.3.67" +name = "anstyle-wincon" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", + "anstyle", + "windows-sys", ] +[[package]] +name = "anyhow" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" -version = "1.3.2" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] -name = "cc" -version = "1.0.79" +name = "camino" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" [[package]] name = "clap" -version = "4.1.8" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "is-terminal", - "once_cell", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.1.8" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", "syn", @@ -80,76 +110,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" -dependencies = [ - "os_str_bytes", -] +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] -name = "color-eyre" -version = "0.6.2" +name = "colorchoice" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" -dependencies = [ - "backtrace", - "color-spantrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", - "tracing-error", -] - -[[package]] -name = "color-spantrace" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" -dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", -] - -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "eyre" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "gimli" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "heck" @@ -157,40 +126,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "io-lifetimes" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "is-terminal" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" -dependencies = [ - "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -198,156 +133,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "libc" -version = "0.2.140" +name = "map-macro" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "fb950a42259642e5a3483115aca87eebed2a64886993463af9c9739c205b8d3a" [[package]] -name = "linux-raw-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" - -[[package]] -name = "mclang" +name = "mclangc" version = "0.1.0" dependencies = [ + "anyhow", + "bitflags", + "camino", "clap", - "color-eyre", - "eyre", + "clap_derive", + "lazy_static", + "map-macro", + "parse_int", + "snailquote", ] [[package]] -name = "memchr" -version = "2.5.0" +name = "num-traits" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ - "adler", + "autocfg", ] [[package]] -name = "object" -version = "0.30.3" +name = "parse_int" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +checksum = "2d695b79916a2c08bcff7be7647ab60d1402885265005a6658ffe6d763553c5a" dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" - -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - -[[package]] -name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "num-traits", ] [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] [[package]] -name = "rustc-demangle" -version = "0.1.21" +name = "snailquote" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustix" -version = "0.36.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" +checksum = "ec62a949bda7f15800481a711909f946e1204f2460f89210eaf7f57730f88f86" dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", + "thiserror", + "unicode_categories", ] [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -355,129 +217,57 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.2.0" +name = "thiserror" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ - "winapi-util", + "thiserror-impl", ] [[package]] -name = "thread_local" -version = "1.1.7" +name = "thiserror-impl" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-error" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" -dependencies = [ - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "sharded-slab", - "thread_local", - "tracing-core", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "valuable" -version = "0.1.0" +name = "unicode_categories" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] -name = "version_check" -version = "0.9.4" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[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-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" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -490,42 +280,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/Cargo.toml b/Cargo.toml index 89dcf10..b6bf4d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,9 +2,18 @@ name = "mclangc" version = "0.1.0" edition = "2021" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version = "4.1.8", features = ["derive"] } -color-eyre = "0.6.2" -eyre = "0.6.8" +anyhow = "1.0.80" +bitflags = "2.4.2" +camino = "1.1.6" +clap = { version = "4.5.2", features = ["derive"] } +clap_derive = "4.5.0" +lazy_static = "1.4.0" +map-macro = "0.3.0" +parse_int = "0.6.0" +# serde = { version = "1.0.197", features = ["derive"] } +# regex = "1.10.3" +snailquote = "0.3.1" diff --git a/README.md b/README.md deleted file mode 100644 index e1eb630..0000000 --- a/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# mclang rev2 - -This is the second revision of [MCLang](https://github.com/mc-lang/mclang) now written in rust! - -## Goals - -✅ - relatevely usable by normal programmers -✅ - speed comparable to unoptimised C (sometimes) -✅ - static typing -❌ - self hosted (maybe better if not? Since rust is fast asf) -❌ - multiplatform (~~windows~~, linux and mac) -✅ - interop with other languages -❌ - package manager -❌ - installer - -## Documentation - -The docs are currently are just made in MarkDown. -You can find the docs [here](/docs/index.md) - -## Credits - -[MCotange](https://github.com/MCorange99) - The one and only me, the creator and current maintainer or mclang rev1 and rev2 diff --git a/REF.md b/REF.md new file mode 100644 index 0000000..7d7a011 --- /dev/null +++ b/REF.md @@ -0,0 +1,53 @@ +# Reference + +```mclang +typedef str do int ptr end // [int, ptr] + +include "std.mcl" + +const sizeof(u8) 1 end +const sizeof(u16) 2 end +const sizeof(u32) 4 end +const sizeof(u64) 8 end + +structdef Foo do + buz do sizeof(u64) end + baz do sizeof(u64) end +done + +memory s_foo Foo end + +//? Comments :3 + +extern fn a with void returns void then done +inline fn b with void returns void then done +export fn c with void returns void then done + +fn puts with str returns void then drop drop done +// fn putd with int returns void then drop done + +fn main with int ptr returns int then + // 1 2 add + 69 _dbg_print + "Hewo" puts + + if 3 4 eq do + "omg what impossible!\n" + else if 1 1 eq do + "whaaaaaaaaa\n" + else + "finally, some good soup\n" + done + puts + + 10 + while dup 0 gt do + "uwu" puts + dup _dbg_print + 1 + done + +done + + +``` diff --git a/editor/vscode/.gitignore b/editor/vscode/.gitignore deleted file mode 100644 index b632597..0000000 --- a/editor/vscode/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -**/*.log -**/node_modules/ diff --git a/editor/vscode/.vscode/launch.json b/editor/vscode/.vscode/launch.json deleted file mode 100644 index 0e191b5..0000000 --- a/editor/vscode/.vscode/launch.json +++ /dev/null @@ -1,17 +0,0 @@ -// A launch configuration that launches the extension inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Extension", - "type": "extensionHost", - "request": "launch", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ] - } - ] -} \ No newline at end of file diff --git a/editor/vscode/.vscodeignore b/editor/vscode/.vscodeignore deleted file mode 100644 index f369b5e..0000000 --- a/editor/vscode/.vscodeignore +++ /dev/null @@ -1,4 +0,0 @@ -.vscode/** -.vscode-test/** -.gitignore -vsc-extension-quickstart.md diff --git a/editor/vscode/CHANGELOG.md b/editor/vscode/CHANGELOG.md deleted file mode 100644 index de57969..0000000 --- a/editor/vscode/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# Change Log - -All notable changes to the "mclang" extension will be documented in this file. - -Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. - -## [Unreleased] - -- Initial release \ No newline at end of file diff --git a/editor/vscode/LICENSE b/editor/vscode/LICENSE deleted file mode 100644 index e69de29..0000000 diff --git a/editor/vscode/README.md b/editor/vscode/README.md deleted file mode 100644 index 82cb65a..0000000 --- a/editor/vscode/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# mclang README - -Code highlghting for mclang 1 and 2 - -## Known Issues - -None - -## Release Notes - -Users appreciate release notes as you update your extension. - -### 1.0.0 - -Initial release of mclang - -**Enjoy!** diff --git a/editor/vscode/language-configuration.json b/editor/vscode/language-configuration.json deleted file mode 100644 index 8f162a0..0000000 --- a/editor/vscode/language-configuration.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "comments": { - // symbol used for single line comment. Remove this entry if your language does not support line comments - "lineComment": "//", - // symbols used for start and end a block comment. Remove this entry if your language does not support block comments - "blockComment": [ "/*", "*/" ] - }, - // symbols used as brackets - "brackets": [ - ["{", "}"], - ["[", "]"], - ["(", ")"] - ], - // symbols that are auto closed when typing - "autoClosingPairs": [ - ["{", "}"], - ["[", "]"], - ["(", ")"], - ["\"", "\""], - ["'", "'"] - ], - // symbols that can be used to surround a selection - "surroundingPairs": [ - ["{", "}"], - ["[", "]"], - ["(", ")"], - ["\"", "\""], - ["'", "'"] - ] -} \ No newline at end of file diff --git a/editor/vscode/mclang-0.0.3.vsix b/editor/vscode/mclang-0.0.3.vsix deleted file mode 100644 index fc2c7ced7e0ba832eca22dcc8ab74a3e324dddf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4807 zcmai22T)U6w+=P*-UI}sBfWQ(E+9y+(xmqmAP_*KfD|c;L6DB2gR~&sgf3k=3er)U zfFdP;@WQ=6Ub*xB_tu#+`{-k5wboEfxKh zim2P{unY=q-?s^Elimr0D) zaaDN~XnZF7y#;H8D_6A&834>Ayn&vTN!PNo7h%BdwBx4nnd9JcFr6~09v9TkF~-)b z=I4i@qSWDJ`u^KOp1sP;x};_z#5ZAadUJLXFff-Z_5KynG1aCNh5tR}R$ME_ID4F3rK(n5cXQjn|c{;(V=TZyXc! zaoOR^F(Rh?MwFB_3sMCzTVvcHBd%@hsi!?Lef1xdw!j|@DZ6NJh8&{o(BlN}LI*dZ znMo18jl_JmB}UPO#XdGTsV`5`0b$g!rnl0H6y3yydvl}A<*~p;D%_o{^Tt%OEZiVCI4o+R>k}(fv&+ zqi0?fDQ969)L`qO${R~)t!&K%V5Q7vNq^p=srDo~PXJMprWy5EcRO%|cxFVu8r_@) zda)@)E2n2xYEbu%mzu2@N{w!;}`y*T>{{DfJB?d0C8)4%3~D{}rCb`R2MVOtmy%~G9=sWSVX z$R@|RIfL*%Zdo`uwe)|(zm()#7@kGW&t)uD#hra>SbK`Ccc~^amy56(F|}|H3jmmR}zxjx9~+q2DN z=}8%>ADnB7s#`}I{dup7UfV_sJ zcC*7<8L+`bGOk2>a;yPT$fE#rFBF*WzIiW?iuCw1xn}Y_UA_urOQ&SW#QIJ^c&}Uh zHIj)O2b?=%{jU>Ul2zVbRYS*6Xknuf4~pEs0-h|D?+qa%pF2U?9tPgG4Kb+!<6L%C zE(7kLk8yDgb6+ZdVU^oTx*BSC?rI2mIv6KZVZ5bKIS7qZqi4vGXS%OkDRwPNLQ+Td zl}eBC$}S-R{@c--l_1jn*#f9ck8Qt@I;Z}$T3Z+xN;F0tH{3}?H*c7xl@uX67NYTU zvEZ5JM-I3J8D1SlgQ(N?+EzVt4{&pm#<5vC$Xk=@c6vypaIsR#sU(2 zA>7Wxq?;DG(P!37&uJKowWC5Rm%nZvuw)MLcc|qf1evy1X}>;$!yJ9WETh$Z?k%v< zy%DW-TI~`M^0wX?EDsessq&3R?Yoeza+$d}uIIR^b8Xsov`4<7-k>Mkns`Pvt0PgO zmomI>-8~T69BbEWROO2osjM9w((gejYRH66oWAkN(}nnxLquq^)SWj-MVN}6aqyxx zqt#u$l@w&5zZMhk+~CxWs?eS+Do8=GbNJ*at8qrOW6?Zbe#-JrfCJ84(D!5RCq^@! z7P#IeRf&!LAAwv92Y6OI^{3N~M)-Jl4db?i%=qn2OuJuc&qb$gR=^%q+mO!bX#)wc zXJX6gG4&vg0|5LJX@#82k*2*A={uS#YPyDMLLe{*2lEq<;5;Lkz2-0b2gC`p4gKfi zU&G~f=woN^j>**!&NVcA)i{WRFMo)Bnjrge_p=V#p@^O(bonxgjyc{jCJk;cD zBEg{dAg(7T!f1Z0%DKDhJ;iP{QinOlgCr6zu&M=3qR+@#n&!_sg)prT5K4+*0>n$Xnaq1&lrR-qKEyJ9xG0th1K>@)dRyZlXuTR@*5Fwu?B6UGsP-~F+_lCv3f1jnTKA9* z=)(uLFK|Tt*uLX1n&sdJY1XNtA;n7G$-&~uqK6(l-8fP!YkvG#gCmp);S7a#Ps4Fq zB5Vq7bzfz{dfLk07guFqbsNjg?&uS#&hm@Ol+=?Z13l0#bJ3m8mzB{IwM->#HKW^6K27I7|& zY%#KP4%}C*gs`{@w8toLs|>*vCz7-Q-({)=5I5A7`1V4Si_f@=}HZWE!J$DHagN_YS2Q^^-M7hzEMI-cw{_^!7fDb@OJCh;uOb-=FAC%?=VQS2LOtW3pk^{V*sxg;K$qcRD! zpNY%7QYlb-caHEt=~vwy^Moro)#<6;A)t01<&k;)73-+zk4Xw50p1=1Gu5{yAM-g` zJY*efAT(=q^;ab0I4L$ILQgg$XB*b?C9lAP%GRa_xWbMfSm_7LZx40yY=3Q$Co(jz z$oTPtWLKcZ!sD4wU?`A+icmDiKK zVM-G}#Q2oNO46@{N~@a>+cGuu-v!cx{cLxr*chPcxO?N}Ztm-}zz;4U0+#1Mv%#uc zW~9 zW$i{KVQsl-A(HGy8rQvTUeDLVI<-gDA;4^R8|#ppBEoJVg_8skZm>i5X0tJ-1okUp z4G5D`6IoEKPO&7B>udF0%7W8w(U@DbfzLSDdL8uS)`Dzvf`S9_O`Mt8)t#MCPs`b9 z++-smR(iPcj11r9O~D|OnmTXw*8!({rBsQAFTh95oTxNyh1>*O73Ak{`qRjt#Tz8} zKFU)HJ(j>>>bCh9ob`9qo5^0;@MGOiKf4RRO&BvBEh#n4$sgmzlqxBad@{w^w0NvL z+C9s9Z{K3-;HV|h`PW3Ej~q+j$*B0|&4zcQCu6GF7I5b514tNhZsRR#J1Yo(=}Y%D zN}t(g1{;#bo6^5BycR*oj052(KBB9~_K5Mp;!-90CnQbT;f>ZLa2vWZX1b+yJI&uac{hVeMD8Q7}J&V=awNx1Q{*% z=wNXux~uB;aZc67uj`IA@&rrREi7wk8U(ds7vDO1o8m>Tn-FUUh0tN&SmLUo7-p*@ zr|5{?nhC<5drX*e`tXE7n;RA*Yx9HJi?D-&PZ7t#K$R4^)SA&QNWD)ws4Gd5ck2^_ z(_unh`!X$aD-t@$rVx9J;#%~gs;2zaCKaxN*Fb)2f~t|9s=>!yP3FtE^TY&}a2q5$ zqa_^4^8*rOlq-gsHh!9jyN>pLvs?C~@-go~8P=rFq;`Wr4|r{T*8JZfy+Q}gU-fBvVifVWX*DF<1dnH{PnX{8wXgyvM^3hP;dD{{H zzDx{EsjYZ4$tai+LT)&)Y$>{OI4dQv$YK>Mt?D4^yxZ3#ZyTW)i_lUCB0o+ztE9<` zLywbu9;X!Kp!vkb8O4`V2YFN{D-n;*ieTvuTUj^~KSFm6tzX|Kd4N16Jl7Mo?LAb& zKmb4-bKIb(jfH&^=f9sjV7B7F3;{hKe(Q@%rx5?f_;;W7Hv#~FfYM+T%>UB0{Ttxl z-OoP&XBdFrlep9iU0_@^8h;Ao^G4&s;Ls`DKQaD~w&PF83q^e)lg}0Pg~6f9_sEO1X1AePM9ulS>ePs_P4k|0en_Fc45~jFSH+I=?001;B;Y`ZNFMTI<5# d(49*F|Bv$0)5gQh8FONVx#Tf%38XlG`yXmNIT-)| diff --git a/editor/vscode/package.json b/editor/vscode/package.json deleted file mode 100644 index 25be400..0000000 --- a/editor/vscode/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "mclang", - "displayName": "mclang", - "description": "Code highlighting for mclang", - "version": "0.0.3", - "repository": { - "type": "git", - "url": "git@github.com:mc-lang/mclang2.git" - }, - "engines": { - "vscode": "^1.54.0" - }, - "categories": [ - "Programming Languages" - ], - "contributes": { - "languages": [ - { - "id": "mclang", - "aliases": [ - "MCLang", - "mclang" - ], - "extensions": [ - ".mcl" - ], - "configuration": "./language-configuration.json" - } - ], - "grammars": [ - { - "language": "mclang", - "scopeName": "source.mcl", - "path": "./syntaxes/mclang.tmLanguage.json" - } - ] - }, - "dependencies": { - "generator-code": "^1.7.4", - "@vscode/vsce": "^2.15.0" - } -} diff --git a/editor/vscode/syntaxes/mclang.tmLanguage.json b/editor/vscode/syntaxes/mclang.tmLanguage.json deleted file mode 100644 index a70f660..0000000 --- a/editor/vscode/syntaxes/mclang.tmLanguage.json +++ /dev/null @@ -1,147 +0,0 @@ -{ - "name": "MCLang", - "fileTypes": [ - "mcl" - ], - "scopeName": "source.mcl", - - "patterns": [ - { - "include": "#errors" - }, - { - "include": "#keywords" - }, - { - "include": "#definitions" - }, - { - "include": "#placeholders" - }, - { - "include": "#strings" - }, - { - "include": "#comments" - }, - { - "include": "#intrinsics" - }, - { - "include": "#constants-and-special-vars" - } - ], - "repository": { - "errors": { - "patterns": [ - { - "name": "invalid.illegal", - "match": "(?<=^|\\s)(?:const|memory)\\s+(end)(?:$|\\s)" - }, - { - "name": "invalid.illegal", - "match": "(?<=^|\\s)(?:fn)\\s+(done)(?:$|\\s)" - }, - { - "name": "invalid.illegal", - "match": "(?<=^|\\s)(memory|const)\\s+\\S*(\\s+|$)end(?:\n|\\s)" - }, - { - "name": "invalid.illegal", - "match": "(?<=^|\\s)(inline)\\s+(?!fn(\\s|$))" - } - ] - }, - "keywords": { - "patterns": [ - - { - "name": "keyword.declaration.mclang", - "match": "(?<=\\s|^)(macro|memory|fn|const|in|inline|include|assert|offset|addr-of|call-like|reset|let|peek|with|returns)(?:\\s|$)" - }, - { - "name": "keyword.control.mclang", - "match": "(?<=\\s|^)(if|else|elif|end|done|then|while|do|if\\*)(?:\\s|$)" - } - ] - }, - "definitions": { - "patterns": [ - { - "name": "support.class.mclang", - "match": "(?<=(macro|memory|fn|const)\\s+)(\\S*)" - }, - { - "name": "support.class.mclang", - "match": "(?<=(let|peek)\\s+)\\S+.*(?=\\s+(in))" - } - ] - }, - "placeholders": { - "patterns": [ - { - "name": "markup.italic.mclang", - "match": "(?<=(\\s|^))_[\\S]*_(?:(\\s|$))" - } - ] - }, - "strings": { - "patterns": [ - { - "name": "string.quoted.double.mclang", - "begin": "\"", - "end": "\"", - "patterns": [ - { - "name": "constant.character.escape.mclang", - "match": "\\\\." - } - ] - }, - { - "name": "string.quoted.single.mclang", - "begin": "'", - "end": "'", - "patterns": [ - { - "name": "constant.character.escape.mclang", - "match": "\\\\." - } - ] - } - ] - }, - "comments": { - "patterns": [ - { - "name": "constant.other.character-class.regexp", - "match": "(?://\\s*)(TODO(O*)|FIXME).*" - }, - { - "name": "comment.line.double-slash.mclang", - "match": "(//(?!\\s?(TODO(O*)|FIXME)(\\s|:|$)).*|//\\s*)" - } - ] - }, - "intrinsics": { - "patterns": [ - { - "name": "variable.name.source.mclang", - "match": "(?<=^|\\s)(\\+|-|\\*|int|ptr|bool|addr|any|void|max|divmod|_dbg_print|=|>|<|>=|<=|!=|>>|<<|\\||&|not|dup|swap|drop|over|rot|argc|argv|here|syscall0|syscall1|syscall2|syscall3|syscall4|syscall5|syscall6|\\?\\?\\?)(?=>$|\\s)" - } - ] - }, - "constants-and-special-vars": { - "patterns": [ - { - "name": "constant.numeric.mclang", - "match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)\\b(?!\\$)" - }, - { - "name": "entity.name.function.mclang", - "match": "(?<=^|\\s)(NULL|true|false|cast(ptr)|cast(int)|cast(bool)|sizeof\\(u64\\)|sizeof\\(u32\\)|sizeof\\(ptr\\)|sizeof\\(bool\\)|sizeof\\(int\\)|sizeof\\(addr\\)|STDIN|STDOUT|STDERR|@ptr|@@ptr|@bool|@int|@addr|!bool|!ptr|!int|!addr|AT_FDCWD|O_RDONLY|O_WRONLY|O_RDWR|O_CREAT|O_TRUNC|O_NONBLOCK|F_SETFL|F_GETFL|EAGAIN|CLOCK_MONOTONIC|TIMER_ABSTIME|MAP_PRIVATE|MAP_ANONYMOUS|PROT_READ|PROT_WRITE|SIGQUIT|timespec\\.tv_sec|timespec\\.tv_nsec|sizeof\\(timespec\\)|ptr\\+|ptr-|ptr!=|ptr=|ptr<|\\+ptr|ptr-diff|sizeof\\(stat\\)|stat\\.st_dev|stat\\.st_ino|stat\\.st_mode|stat\\.st_nlink|stat\\.st_uid|stat\\.st_gid|stat\\.st_rdev|stat\\.st_size|@stat\\.st_size|stat\\.st_blksize|stat\\.st_blocks|stat\\.st_atim|stat\\.st_mtim|stat\\.st_ctim|sizeof\\(stat\\.st_dev\\)|sizeof\\(stat\\.st_ino\\)|sizeof\\(stat\\.st_mode\\)|sizeof\\(stat\\.st_nlink\\)|sizeof\\(stat\\.st_uid\\)|sizeof\\(stat\\.st_gid\\)|sizeof\\(stat\\.st_rdev\\)|sizeof\\(stat\\.st_size\\)|sizeof\\(stat\\.st_blksize\\)|sizeof\\(stat\\.st_blocks\\)|sizeof\\(stat\\.st_atim\\)|sizeof\\(stat\\.st_mtim\\)|sizeof\\(stat\\.st_ctim\\)|write|read|openat|fstat|stat|close|exit|mmap|clock_nanosleep|clock_gettime|fork|getpid|execve|wait4|rename|fcntl|kill|dup2|/|%|mod|div|imod|idiv|emod|nth_argv|lnot|land|lor|inc64-by|inc64|dec64|inc32|dec32|inc8|dec8|swap64|cstrlen|cstreq|cstr-to-str|fputs|puts|eputs|WIFSTOPPED|WIFCONTINUED|WIFSIGNALED|WTERMSIG|WIFEXITED|WEXITSTATUS|offsetof\\(Str\\.count\\)|offsetof\\(Str\\.data\\)|sizeof\\(Str\\)|Str\\.count|Str\\.data|@Str\\.count|@Str\\.data|!Str\\.count|!Str\\.data|@Str|!Str|str-chop-one-left|str-chop-one-right|\\?space|str-trim-left|str-chop-by-predicate|str-chop-by-delim|str-starts-with|\\?str-empty|streq|\\?digit|isdigit|\\?alpha|isalpha|\\?alnum|isalnum|try-parse-int|PUTU_BUFFER_CAP|fputu|fput0u|putu|put0u|eputu|memcpy|memset|srand|RAND_A|RAND_C|rand|getenv|TMP_CAP|tmp-clean|tmp-end|tmp-rewind|tmp-alloc|tmp-str-to-cstr|tmp-append|tmp-append-ptr|execvp|append-item|tmp-utos|map-file|\\?file-exist|\\?shell-safe-char|\\?shell-safe-str|shell-escape|timeit/from-here|1e9|timeit/to-here|str-rfind|dirname|putch|remove-ext|cmd-echoed)(?:\\s|$)" - } - ] - } - } -} \ No newline at end of file diff --git a/editor/vscode/vsc-extension-quickstart.md b/editor/vscode/vsc-extension-quickstart.md deleted file mode 100644 index f4e4c46..0000000 --- a/editor/vscode/vsc-extension-quickstart.md +++ /dev/null @@ -1,29 +0,0 @@ -# Welcome to your VS Code Extension - -## What's in the folder - -* This folder contains all of the files necessary for your extension. -* `package.json` - this is the manifest file in which you declare your language support and define the location of the grammar file that has been copied into your extension. -* `syntaxes/mclang.tmLanguage.json` - this is the Text mate grammar file that is used for tokenization. -* `language-configuration.json` - this is the language configuration, defining the tokens that are used for comments and brackets. - -## Get up and running straight away - -* Make sure the language configuration settings in `language-configuration.json` are accurate. -* Press `F5` to open a new window with your extension loaded. -* Create a new file with a file name suffix matching your language. -* Verify that syntax highlighting works and that the language configuration settings are working. - -## Make changes - -* You can relaunch the extension from the debug toolbar after making changes to the files listed above. -* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. - -## Add more language features - -* To add features such as IntelliSense, hovers and validators check out the VS Code extenders documentation at https://code.visualstudio.com/docs - -## Install your extension - -* To start using your extension with Visual Studio Code copy it into the `/.vscode/extensions` folder and restart Code. -* To share your extension with the world, read on https://code.visualstudio.com/docs about publishing an extension. diff --git a/editor/vscode/yarn.lock b/editor/vscode/yarn.lock deleted file mode 100644 index 5c5fe8a..0000000 --- a/editor/vscode/yarn.lock +++ /dev/null @@ -1,1784 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/helper-validator-identifier@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@octokit/auth-token@^2.4.4": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36" - integrity sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g== - dependencies: - "@octokit/types" "^6.0.3" - -"@octokit/core@^3.5.1": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.6.0.tgz#3376cb9f3008d9b3d110370d90e0a1fcd5fe6085" - integrity sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q== - dependencies: - "@octokit/auth-token" "^2.4.4" - "@octokit/graphql" "^4.5.8" - "@octokit/request" "^5.6.3" - "@octokit/request-error" "^2.0.5" - "@octokit/types" "^6.0.3" - before-after-hook "^2.2.0" - universal-user-agent "^6.0.0" - -"@octokit/endpoint@^6.0.1": - version "6.0.12" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.12.tgz#3b4d47a4b0e79b1027fb8d75d4221928b2d05658" - integrity sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA== - dependencies: - "@octokit/types" "^6.0.3" - is-plain-object "^5.0.0" - universal-user-agent "^6.0.0" - -"@octokit/graphql@^4.5.8": - version "4.8.0" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3" - integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg== - dependencies: - "@octokit/request" "^5.6.0" - "@octokit/types" "^6.0.3" - universal-user-agent "^6.0.0" - -"@octokit/openapi-types@^12.11.0": - version "12.11.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-12.11.0.tgz#da5638d64f2b919bca89ce6602d059f1b52d3ef0" - integrity sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ== - -"@octokit/plugin-paginate-rest@^2.16.8": - version "2.21.3" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz#7f12532797775640dbb8224da577da7dc210c87e" - integrity sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw== - dependencies: - "@octokit/types" "^6.40.0" - -"@octokit/plugin-request-log@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" - integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== - -"@octokit/plugin-rest-endpoint-methods@^5.12.0": - version "5.16.2" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz#7ee8bf586df97dd6868cf68f641354e908c25342" - integrity sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw== - dependencies: - "@octokit/types" "^6.39.0" - deprecation "^2.3.1" - -"@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677" - integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg== - dependencies: - "@octokit/types" "^6.0.3" - deprecation "^2.0.0" - once "^1.4.0" - -"@octokit/request@^5.6.0", "@octokit/request@^5.6.3": - version "5.6.3" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.6.3.tgz#19a022515a5bba965ac06c9d1334514eb50c48b0" - integrity sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A== - dependencies: - "@octokit/endpoint" "^6.0.1" - "@octokit/request-error" "^2.1.0" - "@octokit/types" "^6.16.1" - is-plain-object "^5.0.0" - node-fetch "^2.6.7" - universal-user-agent "^6.0.0" - -"@octokit/rest@^18.0.6": - version "18.12.0" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.12.0.tgz#f06bc4952fc87130308d810ca9d00e79f6988881" - integrity sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q== - dependencies: - "@octokit/core" "^3.5.1" - "@octokit/plugin-paginate-rest" "^2.16.8" - "@octokit/plugin-request-log" "^1.0.4" - "@octokit/plugin-rest-endpoint-methods" "^5.12.0" - -"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.39.0", "@octokit/types@^6.40.0": - version "6.41.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.41.0.tgz#e58ef78d78596d2fb7df9c6259802464b5f84a04" - integrity sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg== - dependencies: - "@octokit/openapi-types" "^12.11.0" - -"@types/minimatch@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== - -ansi-styles@^3.0.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-differ@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" - integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - -async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - -azure-devops-node-api@^11.0.1: - version "11.2.0" - resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz#bf04edbef60313117a0507415eed4790a420ad6b" - integrity sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA== - dependencies: - tunnel "0.0.6" - typed-rest-client "^1.8.4" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -before-after-hook@^2.2.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" - integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== - -binaryextensions@^4.16.0: - version "4.18.0" - resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-4.18.0.tgz#22aeada2d14de062c60e8ca59a504a5636a76ceb" - integrity sha512-PQu3Kyv9dM4FnwB7XGj1+HucW+ShvJzJqjuw1JkKVs1mWdwOKVcRjOi+pV9X52A0tNvrPCsPkbFFQb+wE1EAXw== - -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -chalk@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -cheerio-select@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" - integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== - dependencies: - boolbase "^1.0.0" - css-select "^5.1.0" - css-what "^6.1.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - -cheerio@^1.0.0-rc.9: - version "1.0.0-rc.12" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" - integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== - dependencies: - cheerio-select "^2.1.0" - dom-serializer "^2.0.0" - domhandler "^5.0.3" - domutils "^3.0.1" - htmlparser2 "^8.0.1" - parse5 "^7.0.0" - parse5-htmlparser2-tree-adapter "^7.0.0" - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg== - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -commander@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-select@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" - integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== - dependencies: - boolbase "^1.0.0" - css-what "^6.1.0" - domhandler "^5.0.2" - domutils "^3.0.1" - nth-check "^2.0.1" - -css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -dargs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" - integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== - -debug@^4.1.1: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deprecation@^2.0.0, deprecation@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" - integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== - -detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dom-serializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" - integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - entities "^4.2.0" - -domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -domutils@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" - integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.1" - -ejs@^3.1.8: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== - dependencies: - jake "^10.8.5" - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -entities@^4.2.0, entities@^4.3.0, entities@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" - integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== - -entities@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" - integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -execa@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-plist@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/fast-plist/-/fast-plist-0.1.3.tgz#328cd9335e93a2479ac90814a1302437574ea925" - integrity sha512-d9cEfo/WcOezgPLAC/8t8wGb6YOD6JTCPMw2QcG2nAdFmyY+9rTUizCTaGjIZAloWENTEUMAPpkUAIJJJ0i96A== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -fd-slicer@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" - integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== - dependencies: - pend "~1.2.0" - -filelist@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -generator-code@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/generator-code/-/generator-code-1.7.4.tgz#9b3c9320e6f3f5f6b1a16075453409126c765bd4" - integrity sha512-HKO4Y5QTk75XTcCZeOTipIrifN4yo91Phe5gva6FSEeZcBIUhL0DtAvXBNkar4rRXjkp6OxmJW5q0c94xJcb5A== - dependencies: - chalk "^4.1.2" - fast-plist "^0.1.3" - request-light "^0.7.0" - sanitize-filename "^1.6.3" - which "^3.0.0" - yeoman-generator "^5.8.0" - yosay "^2.0.2" - -get-intrinsic@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== - -github-username@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/github-username/-/github-username-6.0.0.tgz#d543eced7295102996cd8e4e19050ebdcbe60658" - integrity sha512-7TTrRjxblSI5l6adk9zd+cV5d6i1OrJSo3Vr9xdGqFLBQo0mz5P9eIfKCDJ7eekVGGFLbce0qbPSnktXV2BjDQ== - dependencies: - "@octokit/rest" "^18.0.6" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.0.0, glob@^7.0.6, glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hosted-git-info@^4.0.2: - version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== - dependencies: - lru-cache "^6.0.0" - -htmlparser2@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" - integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - domutils "^3.0.1" - entities "^4.3.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== - -is-glob@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -isbinaryfile@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.0.tgz#034b7e54989dab8986598cbcea41f66663c65234" - integrity sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -keytar@^7.7.0: - version "7.9.0" - resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb" - integrity sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ== - dependencies: - node-addon-api "^4.3.0" - prebuild-install "^7.0.1" - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -linkify-it@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" - integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== - dependencies: - uc.micro "^1.0.1" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash@^4.17.11: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -markdown-it@^12.3.2: - version "12.3.2" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" - integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== - dependencies: - argparse "^2.0.1" - entities "~2.1.0" - linkify-it "^3.0.1" - mdurl "^1.0.1" - uc.micro "^1.0.5" - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== - -mem-fs-editor@^9.0.0: - version "9.7.0" - resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-9.7.0.tgz#dbb458b8acb885c84013645e93f71aa267a7fdf6" - integrity sha512-ReB3YD24GNykmu4WeUL/FDIQtkoyGB6zfJv60yfCo3QjKeimNcTqv2FT83bP0ccs6uu+sm5zyoBlspAzigmsdg== - dependencies: - binaryextensions "^4.16.0" - commondir "^1.0.1" - deep-extend "^0.6.0" - ejs "^3.1.8" - globby "^11.1.0" - isbinaryfile "^5.0.0" - minimatch "^7.2.0" - multimatch "^5.0.0" - normalize-path "^3.0.0" - textextensions "^5.13.0" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime@^1.3.4: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^7.2.0: - version "7.4.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.2.tgz#157e847d79ca671054253b840656720cb733f10f" - integrity sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -multimatch@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" - integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== - dependencies: - "@types/minimatch" "^3.0.3" - array-differ "^3.0.0" - array-union "^2.1.0" - arrify "^2.0.1" - minimatch "^3.0.4" - -mute-stream@~0.0.4: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - -node-abi@^3.3.0: - version "3.33.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f" - integrity sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog== - dependencies: - semver "^7.3.5" - -node-addon-api@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== - -node-fetch@^2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== - dependencies: - whatwg-url "^5.0.0" - -normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== - -object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -pad-component@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pad-component/-/pad-component-0.0.1.tgz#ad1f22ce1bf0fdc0d6ddd908af17f351a404b8ac" - integrity sha512-8EKVBxCRSvLnsX1p2LlSFSH3c2/wuhY9/BXXWu8boL78FbVKqn2L5SpURt1x5iw6Gq8PTqJ7MdPoe5nCtX3I+g== - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-semver@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/parse-semver/-/parse-semver-1.1.1.tgz#9a4afd6df063dc4826f93fba4a99cf223f666cb8" - integrity sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ== - dependencies: - semver "^5.1.0" - -parse5-htmlparser2-tree-adapter@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" - integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== - dependencies: - domhandler "^5.0.2" - parse5 "^7.0.0" - -parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" - integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== - dependencies: - entities "^4.4.0" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" - integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -prebuild-install@^7.0.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" - integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== - dependencies: - detect-libc "^2.0.0" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^3.3.0" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^4.0.0" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -qs@^6.9.1: - version "6.11.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f" - integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ== - dependencies: - side-channel "^1.0.4" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -read@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== - dependencies: - mute-stream "~0.0.4" - -readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - -request-light@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a" - integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q== - -resolve@^1.1.6, resolve@^1.10.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-async@^2.0.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@^5.0.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -sanitize-filename@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" - integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== - dependencies: - truncate-utf8-bytes "^1.0.0" - -sax@>=0.6.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -"semver@2 || 3 || 4 || 5", semver@^5.1.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^7.2.1, semver@^7.3.5: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shelljs@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" - integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== - dependencies: - decompress-response "^6.0.0" - once "^1.3.1" - simple-concat "^1.0.0" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -sort-keys@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.2.0.tgz#6b7638cee42c506fff8c1cecde7376d21315be18" - integrity sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg== - dependencies: - is-plain-obj "^2.0.0" - -spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== - dependencies: - ansi-regex "^3.0.0" - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -taketalk@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/taketalk/-/taketalk-1.0.0.tgz#b4d4f0deed206ae7df775b129ea2ca6de52f26dd" - integrity sha512-kS7E53It6HA8S1FVFBWP7HDwgTiJtkmYk7TsowGlizzVrivR1Mf9mgjXHY1k7rOfozRVMZSfwjB3bevO4QEqpg== - dependencies: - get-stdin "^4.0.1" - minimist "^1.1.0" - -tar-fs@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -textextensions@^5.13.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-5.15.0.tgz#4bb3296ad6fc111cf4b39c589dd028d8aaaf7060" - integrity sha512-MeqZRHLuaGamUXGuVn2ivtU3LA3mLCCIO5kUGoohTCoGmCBg/+8yPhWVX9WSl9telvVd8erftjFk9Fwb2dD6rw== - -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -truncate-utf8-bytes@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" - integrity sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ== - dependencies: - utf8-byte-length "^1.0.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - -tunnel@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" - integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -typed-rest-client@^1.8.4: - version "1.8.9" - resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.8.9.tgz#e560226bcadfe71b0fb5c416b587f8da3b8f92d8" - integrity sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g== - dependencies: - qs "^6.9.1" - tunnel "0.0.6" - underscore "^1.12.1" - -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - -underscore@^1.12.1: - version "1.13.6" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" - integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== - -universal-user-agent@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" - integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== - -url-join@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" - integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== - -utf8-byte-length@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" - integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vsce@^2.15.0: - version "2.15.0" - resolved "https://registry.yarnpkg.com/vsce/-/vsce-2.15.0.tgz#4a992e78532092a34a755143c6b6c2cabcb7d729" - integrity sha512-P8E9LAZvBCQnoGoizw65JfGvyMqNGlHdlUXD1VAuxtvYAaHBKLBdKPnpy60XKVDAkQCfmMu53g+gq9FM+ydepw== - dependencies: - azure-devops-node-api "^11.0.1" - chalk "^2.4.2" - cheerio "^1.0.0-rc.9" - commander "^6.1.0" - glob "^7.0.6" - hosted-git-info "^4.0.2" - keytar "^7.7.0" - leven "^3.1.0" - markdown-it "^12.3.2" - mime "^1.3.4" - minimatch "^3.0.3" - parse-semver "^1.1.1" - read "^1.0.7" - semver "^5.1.0" - tmp "^0.2.1" - typed-rest-client "^1.8.4" - url-join "^4.0.1" - xml2js "^0.4.23" - yauzl "^2.3.1" - yazl "^2.2.2" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/which/-/which-3.0.0.tgz#a9efd016db59728758a390d23f1687b6e8f59f8e" - integrity sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ== - dependencies: - isexe "^2.0.0" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -xml2js@^0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yauzl@^2.3.1: - version "2.10.0" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" - integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.1.0" - -yazl@^2.2.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" - integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== - dependencies: - buffer-crc32 "~0.2.3" - -yeoman-generator@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-5.8.0.tgz#a1951ce0d95555f94adc5975a517d4741b5ce24d" - integrity sha512-dsrwFn9/c2/MOe80sa2nKfbZd/GaPTgmmehdgkFifs1VN/I7qPsW2xcBfvSkHNGK+PZly7uHyH8kaVYSFNUDhQ== - dependencies: - chalk "^4.1.0" - dargs "^7.0.0" - debug "^4.1.1" - execa "^5.1.1" - github-username "^6.0.0" - lodash "^4.17.11" - mem-fs-editor "^9.0.0" - minimist "^1.2.5" - read-pkg-up "^7.0.1" - run-async "^2.0.0" - semver "^7.2.1" - shelljs "^0.8.5" - sort-keys "^4.2.0" - text-table "^0.2.0" - -yosay@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/yosay/-/yosay-2.0.2.tgz#a7017e764cd88d64a1ae64812201de5b157adf6d" - integrity sha512-avX6nz2esp7IMXGag4gu6OyQBsMh/SEn+ZybGu3yKPlOTE6z9qJrzG/0X5vCq/e0rPFy0CUYCze0G5hL310ibA== - dependencies: - ansi-regex "^2.0.0" - ansi-styles "^3.0.0" - chalk "^1.0.0" - cli-boxes "^1.0.0" - pad-component "0.0.1" - string-width "^2.0.0" - strip-ansi "^3.0.0" - taketalk "^1.0.0" - wrap-ansi "^2.0.0" diff --git a/examples/hello_world.mcl b/examples/hello_world.mcl deleted file mode 100644 index a7fef71..0000000 --- a/examples/hello_world.mcl +++ /dev/null @@ -1,4 +0,0 @@ -include "std.mcl" - -"Henlo World! :3\n" puts - diff --git a/examples/rule110.mcl b/examples/rule110.mcl deleted file mode 100755 index 916e49d..0000000 --- a/examples/rule110.mcl +++ /dev/null @@ -1,39 +0,0 @@ -include "std.mcl" - -macro BOARD_SIZE 100 end - -mem BOARD_SIZE 2 - + 1 @8 - -0 while dup BOARD_SIZE 2 - < do - 0 while dup BOARD_SIZE < do - dup mem + !8 if - dup mem + BOARD_SIZE + '*' @8 - else - dup mem + BOARD_SIZE + ' ' @8 - end - 1 + - end - - mem + BOARD_SIZE + '\n' @8 - - BOARD_SIZE 1 + mem BOARD_SIZE + puts - - // pattern - mem !8 1 shl - mem 1 + !8 - bor - - 1 while dup BOARD_SIZE 2 - < do - swap 1 shl 7 band - over mem + 1 + !8 bor - 2dup 110 swap shr 1 band - swap mem + swap @8 - swap - - 1 + - end - drop drop - - 1 + -end -drop \ No newline at end of file diff --git a/examples/seq_100.mcl b/examples/seq_100.mcl deleted file mode 100644 index a9a3bbb..0000000 --- a/examples/seq_100.mcl +++ /dev/null @@ -1,5 +0,0 @@ - -0 while dup 100 < do - dup print - 1 + -end diff --git a/include/compat.mcl b/include/compat.mcl deleted file mode 100644 index 1d19a26..0000000 --- a/include/compat.mcl +++ /dev/null @@ -1 +0,0 @@ -// todo: add some sort of macrow \ No newline at end of file diff --git a/include/fs.mcl b/include/fs.mcl deleted file mode 100644 index 3268996..0000000 --- a/include/fs.mcl +++ /dev/null @@ -1,18 +0,0 @@ -const FS_O_APPEND 1024 end // append to existing file -const FS_O_ASYNC 8192 end // use signal-driven IO -const FS_O_CLOEXEC 524288 end // use close-on-exec (avoid race conditions and lock contentions) -const FS_O_CREAT 64 end // create file if it doesn’t exist -const FS_O_DIRECT 16384 end // bypass cache (slower) -const FS_O_DIRECTORY 65536 end // fail if pathname isn’t a directory -const FS_O_DSYNC 4096 end // ensure output is sent to hardware and metadata written before return -const FS_O_EXCL 128 end // ensure creation of file -const FS_O_LARGEFILE 0 end // allows use of file sizes represented by off64_t -const FS_O_NOATIME 262144 end // do not increment access time upon open -const FS_O_NOCTTY 256 end // if pathname is a terminal device, don’t become controlling terminal -const FS_O_NOFOLLOW 131072 end // fail if pathname is symbolic link -const FS_O_NONBLOCK 2048 end // if possible, open file with non-blocking IO -const FS_O_NDELAY 2048 end // same as O_NONBLOCK -const FS_O_PATH 2097152 end // open descriptor for obtaining permissions and status of a file but does not allow read/write operations -const FS_O_SYNC 1052672 end // wait for IO to complete before returning -const FS_O_TMPFILE 4259840 end // create an unnamed, unreachable (via any other open call) temporary file -const FS_O_TRUNC 512 end // if file exists, ovewrite it (careful!) diff --git a/include/int.mcl b/include/int.mcl deleted file mode 100644 index 4d9366f..0000000 --- a/include/int.mcl +++ /dev/null @@ -1,15 +0,0 @@ -const NULL 0 end -const false 0 end -const true 1 end - -inline fn div with int int returns int then divmod drop done -inline fn mod with int int returns int then divmod swap drop done - - -inline fn dup2 with any any returns any any any any then over over done -inline fn drop2 with any any returns void then drop drop done - -const sizeof(u64) 8 end -const sizeof(u32) 4 end -const sizeof(u16) 2 end -const sizeof(u8) 1 end \ No newline at end of file diff --git a/include/io.mcl b/include/io.mcl deleted file mode 100644 index 22f0b43..0000000 --- a/include/io.mcl +++ /dev/null @@ -1,50 +0,0 @@ - -// Write to a file descriptor using the SYS_write syscall -// args: [buff_size, buff_ptr, fd] -// @arg buff_size: Int - number of bytes to write -// @arg buff_ptr: Ptr - pointer to the buffer to write -// @arg fd: Int - file descriptor -// @ret Int -inline fn write with int ptr int returns int then - SYS_write syscall3 -done - -// Write to a file descriptor using the SYS_write syscall -// args: [buff_size, buff_ptr, fd] -// @arg buff_size: Int - number of bytes to write -// @arg buff_ptr: Ptr - pointer to the buffer to write -// @arg fd: Int - file descriptor -// @ret Int -inline fn read with int ptr int returns int then - SYS_read syscall3 -done - - -// Print a string to STDOUT -// args: [str_size, str_ptr] -// @arg buff_size: Int - number of bytes to write -// @arg buff_ptr: Ptr - pointer to the buffer to write -// @ret NULL -inline fn puts with int ptr returns void then - STDOUT write drop -done - -// Print a string to STDERR -// args: [str_size, str_ptr] -// @arg buff_size: Int - number of bytes to write -// @arg buff_ptr: Ptr - pointer to the buffer to write -// @ret NULL -inline fn eputs with int ptr returns void then - STDOUT write drop -done - -// TODO: make putc and eputc after we make local mem - -// Exit the program with exit_code -// args: [exit_code] -// @arg exit_code: Int -// @ret NULL/NEVER -inline fn exit with int returns void then - SYS_exit syscall1 drop -done - diff --git a/include/linux.mcl b/include/linux.mcl deleted file mode 100644 index 6b459b9..0000000 --- a/include/linux.mcl +++ /dev/null @@ -1,322 +0,0 @@ - -// file descriptors -const STDIN 0 end -const STDOUT 1 end -const STDERR 2 end - - -// syscalls -const SYS_read 0 end -const SYS_write 1 end -const SYS_open 2 end -const SYS_close 3 end -const SYS_stat 4 end -const SYS_fstat 5 end -const SYS_lstat 6 end -const SYS_poll 7 end -const SYS_lseek 8 end -const SYS_mmap 9 end -const SYS_mprotect 10 end -const SYS_munmap 11 end -const SYS_brk 12 end -const SYS_rt_sigaction 13 end -const SYS_rt_sigprocmask 14 end -const SYS_rt_sigreturn 15 end -const SYS_ioctl 16 end -const SYS_pread64 17 end -const SYS_pwrite64 18 end -const SYS_readv 19 end -const SYS_writev 20 end -const SYS_access 21 end -const SYS_pipe 22 end -const SYS_select 23 end -const SYS_sched_yield 24 end -const SYS_mremap 25 end -const SYS_msync 26 end -const SYS_mincore 27 end -const SYS_madvise 28 end -const SYS_shmget 29 end -const SYS_shmat 30 end -const SYS_shmctl 31 end -const SYS_dup 32 end -const SYS_dup2 33 end -const SYS_pause 34 end -const SYS_nanosleep 35 end -const SYS_getitimer 36 end -const SYS_alarm 37 end -const SYS_setitimer 38 end -const SYS_getpid 39 end -const SYS_sendfile 40 end -const SYS_socket 41 end -const SYS_connect 42 end -const SYS_accept 43 end -const SYS_sendto 44 end -const SYS_recvfrom 45 end -const SYS_sendmsg 46 end -const SYS_recvmsg 47 end -const SYS_shutdown 48 end -const SYS_bind 49 end -const SYS_listen 50 end -const SYS_getsockname 51 end -const SYS_getpeername 52 end -const SYS_socketpair 53 end -const SYS_setsockopt 54 end -const SYS_getsockopt 55 end -const SYS_clone 56 end -const SYS_fork 57 end -const SYS_vfork 58 end -const SYS_execve 59 end -const SYS_exit 60 end -const SYS_wait4 61 end -const SYS_kill 62 end -const SYS_uname 63 end -const SYS_semget 64 end -const SYS_semop 65 end -const SYS_semctl 66 end -const SYS_shmdt 67 end -const SYS_msgget 68 end -const SYS_msgsnd 69 end -const SYS_msgrcv 70 end -const SYS_msgctl 71 end -const SYS_fcntl 72 end -const SYS_flock 73 end -const SYS_fsync 74 end -const SYS_fdatasync 75 end -const SYS_truncate 76 end -const SYS_ftruncate 77 end -const SYS_getdents 78 end -const SYS_getcwd 79 end -const SYS_chdir 80 end -const SYS_fchdir 81 end -const SYS_rename 82 end -const SYS_mkdir 83 end -const SYS_rmdir 84 end -const SYS_creat 85 end -const SYS_link 86 end -const SYS_unlink 87 end -const SYS_symlink 88 end -const SYS_readlink 89 end -const SYS_chmod 90 end -const SYS_fchmod 91 end -const SYS_chown 92 end -const SYS_fchown 93 end -const SYS_lchown 94 end -const SYS_umask 95 end -const SYS_gettimeofday 96 end -const SYS_getrlimit 97 end -const SYS_getrusage 98 end -const SYS_sysinfo 99 end -const SYS_times 100 end -const SYS_ptrace 101 end -const SYS_getuid 102 end -const SYS_syslog 103 end -const SYS_getgid 104 end -const SYS_setuid 105 end -const SYS_setgid 106 end -const SYS_geteuid 107 end -const SYS_getegid 108 end -const SYS_setpgid 109 end -const SYS_getppid 110 end -const SYS_getpgrp 111 end -const SYS_setsid 112 end -const SYS_setreuid 113 end -const SYS_setregid 114 end -const SYS_getgroups 115 end -const SYS_setgroups 116 end -const SYS_setresuid 117 end -const SYS_getresuid 118 end -const SYS_setresgid 119 end -const SYS_getresgid 120 end -const SYS_getpgid 121 end -const SYS_setfsuid 122 end -const SYS_setfsgid 123 end -const SYS_getsid 124 end -const SYS_capget 125 end -const SYS_capset 126 end -const SYS_rt_sigpending 127 end -const SYS_rt_sigtimedwait 128 end -const SYS_rt_sigqueueinfo 129 end -const SYS_rt_sigsuspend 130 end -const SYS_sigaltstack 131 end -const SYS_utime 132 end -const SYS_mknod 133 end -const SYS_uselib 134 end -const SYS_personality 135 end -const SYS_ustat 136 end -const SYS_statfs 137 end -const SYS_fstatfs 138 end -const SYS_sysfs 139 end -const SYS_getpriority 140 end -const SYS_setpriority 141 end -const SYS_sched_setparam 142 end -const SYS_sched_getparam 143 end -const SYS_sched_setscheduler 144 end -const SYS_sched_getscheduler 145 end -const SYS_sched_get_priority_max 146 end -const SYS_sched_get_priority_min 147 end -const SYS_sched_rr_get_interval 148 end -const SYS_mlock 149 end -const SYS_munlock 150 end -const SYS_mlockall 151 end -const SYS_munlockall 152 end -const SYS_vhangup 153 end -const SYS_modify_ldt 154 end -const SYS_pivot_root 155 end -const SYS__sysctl 156 end -const SYS_prctl 157 end -const SYS_arch_prctl 158 end -const SYS_adjtimex 159 end -const SYS_setrlimit 160 end -const SYS_chroot 161 end -const SYS_sync 162 end -const SYS_acct 163 end -const SYS_settimeofday 164 end -const SYS_mount 165 end -const SYS_umount2 166 end -const SYS_swapon 167 end -const SYS_swapoff 168 end -const SYS_reboot 169 end -const SYS_sethostname 170 end -const SYS_setdomainname 171 end -const SYS_iopl 172 end -const SYS_ioperm 173 end -const SYS_create_module 174 end -const SYS_init_module 175 end -const SYS_delete_module 176 end -const SYS_get_kernel_syms 177 end -const SYS_query_module 178 end -const SYS_quotactl 179 end -const SYS_nfsservctl 180 end -const SYS_getpmsg 181 end -const SYS_putpmsg 182 end -const SYS_afs_syscall 183 end -const SYS_tuxcall 184 end -const SYS_security 185 end -const SYS_gettid 186 end -const SYS_readahead 187 end -const SYS_setxattr 188 end -const SYS_lsetxattr 189 end -const SYS_fsetxattr 190 end -const SYS_getxattr 191 end -const SYS_lgetxattr 192 end -const SYS_fgetxattr 193 end -const SYS_listxattr 194 end -const SYS_llistxattr 195 end -const SYS_flistxattr 196 end -const SYS_removexattr 197 end -const SYS_lremovexattr 198 end -const SYS_fremovexattr 199 end -const SYS_tkill 200 end -const SYS_time 201 end -const SYS_futex 202 end -const SYS_sched_setaffinity 203 end -const SYS_sched_getaffinity 204 end -const SYS_set_thread_area 205 end -const SYS_io_setup 206 end -const SYS_io_destroy 207 end -const SYS_io_getevents 208 end -const SYS_io_submit 209 end -const SYS_io_cancel 210 end -const SYS_get_thread_area 211 end -const SYS_lookup_dcookie 212 end -const SYS_epoll_create 213 end -const SYS_epoll_ctl_old 214 end -const SYS_epoll_wait_old 215 end -const SYS_remap_file_pages 216 end -const SYS_getdents64 217 end -const SYS_set_tid_address 218 end -const SYS_restart_syscall 219 end -const SYS_semtimedop 220 end -const SYS_fadvise64 221 end -const SYS_timer_create 222 end -const SYS_timer_settime 223 end -const SYS_timer_gettime 224 end -const SYS_timer_getoverrun 225 end -const SYS_timer_delete 226 end -const SYS_clock_settime 227 end -const SYS_clock_gettime 228 end -const SYS_clock_getres 229 end -const SYS_clock_nanosleep 230 end -const SYS_exit_group 231 end -const SYS_epoll_wait 232 end -const SYS_epoll_ctl 233 end -const SYS_tgkill 234 end -const SYS_utimes 235 end -const SYS_vserver 236 end -const SYS_mbind 237 end -const SYS_set_mempolicy 238 end -const SYS_get_mempolicy 239 end -const SYS_mq_open 240 end -const SYS_mq_unlink 241 end -const SYS_mq_timedsend 242 end -const SYS_mq_timedreceive 243 end -const SYS_mq_notify 244 end -const SYS_mq_getsetattr 245 end -const SYS_kexec_load 246 end -const SYS_waitid 247 end -const SYS_add_key 248 end -const SYS_request_key 249 end -const SYS_keyctl 250 end -const SYS_ioprio_set 251 end -const SYS_ioprio_get 252 end -const SYS_inotify_init 253 end -const SYS_inotify_add_watch 254 end -const SYS_inotify_rm_watch 255 end -const SYS_migrate_pages 256 end -const SYS_openat 257 end -const SYS_mkdirat 258 end -const SYS_mknodat 259 end -const SYS_fchownat 260 end -const SYS_futimesat 261 end -const SYS_newfstatat 262 end -const SYS_unlinkat 263 end -const SYS_renameat 264 end -const SYS_linkat 265 end -const SYS_symlinkat 266 end -const SYS_readlinkat 267 end -const SYS_fchmodat 268 end -const SYS_faccessat 269 end -const SYS_pselect6 270 end -const SYS_ppoll 271 end -const SYS_unshare 272 end -const SYS_set_robust_list 273 end -const SYS_get_robust_list 274 end -const SYS_splice 275 end -const SYS_tee 276 end -const SYS_sync_file_range 277 end -const SYS_vmsplice 278 end -const SYS_move_pages 279 end -const SYS_utimensat 280 end -const SYS_epoll_pwait 281 end -const SYS_signalfd 282 end -const SYS_timerfd_create 283 end -const SYS_eventfd 284 end -const SYS_fallocate 285 end -const SYS_timerfd_settime 286 end -const SYS_timerfd_gettime 287 end -const SYS_accept4 288 end -const SYS_signalfd4 289 end -const SYS_eventfd2 290 end -const SYS_epoll_create1 291 end -const SYS_dup3 292 end -const SYS_pipe2 293 end -const SYS_inotify_init1 294 end -const SYS_preadv 295 end -const SYS_pwritev 296 end -const SYS_rt_tgsigqueueinfo 297 end -const SYS_perf_event_open 298 end -const SYS_recvmmsg 299 end -const SYS_fanotify_init 300 end -const SYS_fanotify_mark 301 end -const SYS_prlimit64 302 end -const SYS_name_to_handle_at 303 end -const SYS_open_by_handle_at 304 end -const SYS_clock_adjtime 305 end -const SYS_syncfs 306 end -const SYS_sendmmsg 307 end -const SYS_setns 308 end -const SYS_getcpu 309 end -const SYS_process_vm_readv 310 end -const SYS_process_vm_writev 311 end -const SYS_kcmp 312 end -const SYS_finit_module 313 end \ No newline at end of file diff --git a/include/linux/io.mcl b/include/linux/io.mcl new file mode 100644 index 0000000..8dddb95 --- /dev/null +++ b/include/linux/io.mcl @@ -0,0 +1,14 @@ + +fn fwrite with u64 ptr u64 returns u64 then + SYS_write syscall3 +done + + + +fn puts with u64 ptr u64 returns u64 then + STDOUT fwrite drop +done + +fn eputs with u64 ptr u64 returns u64 then + STDERR fwrite drop +done \ No newline at end of file diff --git a/include/linux/linux.mcl b/include/linux/linux.mcl new file mode 100644 index 0000000..dca656f --- /dev/null +++ b/include/linux/linux.mcl @@ -0,0 +1,2 @@ +include "linux/syscalls.mcl" +include "linux/io.mcl" \ No newline at end of file diff --git a/include/linux/syscalls.mcl b/include/linux/syscalls.mcl new file mode 100644 index 0000000..6773721 --- /dev/null +++ b/include/linux/syscalls.mcl @@ -0,0 +1,322 @@ + +// file descriptors +const STDIN 0 end +const STDOUT 1 end +const STDERR 2 end + + +// syscalls +// const SYS_read 0 end +const SYS_write 1 end +// const SYS_open 2 end +// const SYS_close 3 end +// const SYS_stat 4 end +// const SYS_fstat 5 end +// const SYS_lstat 6 end +// const SYS_poll 7 end +// const SYS_lseek 8 end +// const SYS_mmap 9 end +// const SYS_mprotect 10 end +// const SYS_munmap 11 end +// const SYS_brk 12 end +// const SYS_rt_sigaction 13 end +// const SYS_rt_sigprocmask 14 end +// const SYS_rt_sigreturn 15 end +// const SYS_ioctl 16 end +// const SYS_pread64 17 end +// const SYS_pwrite64 18 end +// const SYS_readv 19 end +// const SYS_writev 20 end +// const SYS_access 21 end +// const SYS_pipe 22 end +// const SYS_select 23 end +// const SYS_sched_yield 24 end +// const SYS_mremap 25 end +// const SYS_msync 26 end +// const SYS_mincore 27 end +// const SYS_madvise 28 end +// const SYS_shmget 29 end +// const SYS_shmat 30 end +// const SYS_shmctl 31 end +// const SYS_dup 32 end +// const SYS_dup2 33 end +// const SYS_pause 34 end +// const SYS_nanosleep 35 end +// const SYS_getitimer 36 end +// const SYS_alarm 37 end +// const SYS_setitimer 38 end +// const SYS_getpid 39 end +// const SYS_sendfile 40 end +// const SYS_socket 41 end +// const SYS_connect 42 end +// const SYS_accept 43 end +// const SYS_sendto 44 end +// const SYS_recvfrom 45 end +// const SYS_sendmsg 46 end +// const SYS_recvmsg 47 end +// const SYS_shutdown 48 end +// const SYS_bind 49 end +// const SYS_listen 50 end +// const SYS_getsockname 51 end +// const SYS_getpeername 52 end +// const SYS_socketpair 53 end +// const SYS_setsockopt 54 end +// const SYS_getsockopt 55 end +// const SYS_clone 56 end +// const SYS_fork 57 end +// const SYS_vfork 58 end +// const SYS_execve 59 end +const SYS_exit 60 end +// const SYS_wait4 61 end +// const SYS_kill 62 end +// const SYS_uname 63 end +// const SYS_semget 64 end +// const SYS_semop 65 end +// const SYS_semctl 66 end +// const SYS_shmdt 67 end +// const SYS_msgget 68 end +// const SYS_msgsnd 69 end +// const SYS_msgrcv 70 end +// const SYS_msgctl 71 end +// const SYS_fcntl 72 end +// const SYS_flock 73 end +// const SYS_fsync 74 end +// const SYS_fdatasync 75 end +// const SYS_truncate 76 end +// const SYS_ftruncate 77 end +// const SYS_getdents 78 end +// const SYS_getcwd 79 end +// const SYS_chdir 80 end +// const SYS_fchdir 81 end +// const SYS_rename 82 end +// const SYS_mkdir 83 end +// const SYS_rmdir 84 end +// const SYS_creat 85 end +// const SYS_link 86 end +// const SYS_unlink 87 end +// const SYS_symlink 88 end +// const SYS_readlink 89 end +// const SYS_chmod 90 end +// const SYS_fchmod 91 end +// const SYS_chown 92 end +// const SYS_fchown 93 end +// const SYS_lchown 94 end +// const SYS_umask 95 end +// const SYS_gettimeofday 96 end +// const SYS_getrlimit 97 end +// const SYS_getrusage 98 end +// const SYS_sysinfo 99 end +// const SYS_times 100 end +// const SYS_ptrace 101 end +// const SYS_getuid 102 end +// const SYS_syslog 103 end +// const SYS_getgid 104 end +// const SYS_setuid 105 end +// const SYS_setgid 106 end +// const SYS_geteuid 107 end +// const SYS_getegid 108 end +// const SYS_setpgid 109 end +// const SYS_getppid 110 end +// const SYS_getpgrp 111 end +// const SYS_setsid 112 end +// const SYS_setreuid 113 end +// const SYS_setregid 114 end +// const SYS_getgroups 115 end +// const SYS_setgroups 116 end +// const SYS_setresuid 117 end +// const SYS_getresuid 118 end +// const SYS_setresgid 119 end +// const SYS_getresgid 120 end +// const SYS_getpgid 121 end +// const SYS_setfsuid 122 end +// const SYS_setfsgid 123 end +// const SYS_getsid 124 end +// const SYS_capget 125 end +// const SYS_capset 126 end +// const SYS_rt_sigpending 127 end +// const SYS_rt_sigtimedwait 128 end +// const SYS_rt_sigqueueinfo 129 end +// const SYS_rt_sigsuspend 130 end +// const SYS_sigaltstack 131 end +// const SYS_utime 132 end +// const SYS_mknod 133 end +// const SYS_uselib 134 end +// const SYS_personality 135 end +// const SYS_ustat 136 end +// const SYS_statfs 137 end +// const SYS_fstatfs 138 end +// const SYS_sysfs 139 end +// const SYS_getpriority 140 end +// const SYS_setpriority 141 end +// const SYS_sched_setparam 142 end +// const SYS_sched_getparam 143 end +// const SYS_sched_setscheduler 144 end +// const SYS_sched_getscheduler 145 end +// const SYS_sched_get_priority_max 146 end +// const SYS_sched_get_priority_min 147 end +// const SYS_sched_rr_get_interval 148 end +// const SYS_mlock 149 end +// const SYS_munlock 150 end +// const SYS_mlockall 151 end +// const SYS_munlockall 152 end +// const SYS_vhangup 153 end +// const SYS_modify_ldt 154 end +// const SYS_pivot_root 155 end +// const SYS__sysctl 156 end +// const SYS_prctl 157 end +// const SYS_arch_prctl 158 end +// const SYS_adjtimex 159 end +// const SYS_setrlimit 160 end +// const SYS_chroot 161 end +// const SYS_sync 162 end +// const SYS_acct 163 end +// const SYS_settimeofday 164 end +// const SYS_mount 165 end +// const SYS_umount2 166 end +// const SYS_swapon 167 end +// const SYS_swapoff 168 end +// const SYS_reboot 169 end +// const SYS_sethostname 170 end +// const SYS_setdomainname 171 end +// const SYS_iopl 172 end +// const SYS_ioperm 173 end +// const SYS_create_module 174 end +// const SYS_init_module 175 end +// const SYS_delete_module 176 end +// const SYS_get_kernel_syms 177 end +// const SYS_query_module 178 end +// const SYS_quotactl 179 end +// const SYS_nfsservctl 180 end +// const SYS_getpmsg 181 end +// const SYS_putpmsg 182 end +// const SYS_afs_syscall 183 end +// const SYS_tuxcall 184 end +// const SYS_security 185 end +// const SYS_gettid 186 end +// const SYS_readahead 187 end +// const SYS_setxattr 188 end +// const SYS_lsetxattr 189 end +// const SYS_fsetxattr 190 end +// const SYS_getxattr 191 end +// const SYS_lgetxattr 192 end +// const SYS_fgetxattr 193 end +// const SYS_listxattr 194 end +// const SYS_llistxattr 195 end +// const SYS_flistxattr 196 end +// const SYS_removexattr 197 end +// const SYS_lremovexattr 198 end +// const SYS_fremovexattr 199 end +// const SYS_tkill 200 end +// const SYS_time 201 end +// const SYS_futex 202 end +// const SYS_sched_setaffinity 203 end +// const SYS_sched_getaffinity 204 end +// const SYS_set_thread_area 205 end +// const SYS_io_setup 206 end +// const SYS_io_destroy 207 end +// const SYS_io_getevents 208 end +// const SYS_io_submit 209 end +// const SYS_io_cancel 210 end +// const SYS_get_thread_area 211 end +// const SYS_lookup_dcookie 212 end +// const SYS_epoll_create 213 end +// const SYS_epoll_ctl_old 214 end +// const SYS_epoll_wait_old 215 end +// const SYS_remap_file_pages 216 end +// const SYS_getdents64 217 end +// const SYS_set_tid_address 218 end +// const SYS_restart_syscall 219 end +// const SYS_semtimedop 220 end +// const SYS_fadvise64 221 end +// const SYS_timer_create 222 end +// const SYS_timer_settime 223 end +// const SYS_timer_gettime 224 end +// const SYS_timer_getoverrun 225 end +// const SYS_timer_delete 226 end +// const SYS_clock_settime 227 end +// const SYS_clock_gettime 228 end +// const SYS_clock_getres 229 end +// const SYS_clock_nanosleep 230 end +// const SYS_exit_group 231 end +// const SYS_epoll_wait 232 end +// const SYS_epoll_ctl 233 end +// const SYS_tgkill 234 end +// const SYS_utimes 235 end +// const SYS_vserver 236 end +// const SYS_mbind 237 end +// const SYS_set_mempolicy 238 end +// const SYS_get_mempolicy 239 end +// const SYS_mq_open 240 end +// const SYS_mq_unlink 241 end +// const SYS_mq_timedsend 242 end +// const SYS_mq_timedreceive 243 end +// const SYS_mq_notify 244 end +// const SYS_mq_getsetattr 245 end +// const SYS_kexec_load 246 end +// const SYS_waitid 247 end +// const SYS_add_key 248 end +// const SYS_request_key 249 end +// const SYS_keyctl 250 end +// const SYS_ioprio_set 251 end +// const SYS_ioprio_get 252 end +// const SYS_inotify_init 253 end +// const SYS_inotify_add_watch 254 end +// const SYS_inotify_rm_watch 255 end +// const SYS_migrate_pages 256 end +// const SYS_openat 257 end +// const SYS_mkdirat 258 end +// const SYS_mknodat 259 end +// const SYS_fchownat 260 end +// const SYS_futimesat 261 end +// const SYS_newfstatat 262 end +// const SYS_unlinkat 263 end +// const SYS_renameat 264 end +// const SYS_linkat 265 end +// const SYS_symlinkat 266 end +// const SYS_readlinkat 267 end +// const SYS_fchmodat 268 end +// const SYS_faccessat 269 end +// const SYS_pselect6 270 end +// const SYS_ppoll 271 end +// const SYS_unshare 272 end +// const SYS_set_robust_list 273 end +// const SYS_get_robust_list 274 end +// const SYS_splice 275 end +// const SYS_tee 276 end +// const SYS_sync_file_range 277 end +// const SYS_vmsplice 278 end +// const SYS_move_pages 279 end +// const SYS_utimensat 280 end +// const SYS_epoll_pwait 281 end +// const SYS_signalfd 282 end +// const SYS_timerfd_create 283 end +// const SYS_eventfd 284 end +// const SYS_fallocate 285 end +// const SYS_timerfd_settime 286 end +// const SYS_timerfd_gettime 287 end +// const SYS_accept4 288 end +// const SYS_signalfd4 289 end +// const SYS_eventfd2 290 end +// const SYS_epoll_create1 291 end +// const SYS_dup3 292 end +// const SYS_pipe2 293 end +// const SYS_inotify_init1 294 end +// const SYS_preadv 295 end +// const SYS_pwritev 296 end +// const SYS_rt_tgsigqueueinfo 297 end +// const SYS_perf_event_open 298 end +// const SYS_recvmmsg 299 end +// const SYS_fanotify_init 300 end +// const SYS_fanotify_mark 301 end +// const SYS_prlimit64 302 end +// const SYS_name_to_handle_at 303 end +// const SYS_open_by_handle_at 304 end +// const SYS_clock_adjtime 305 end +// const SYS_syncfs 306 end +// const SYS_sendmmsg 307 end +// const SYS_setns 308 end +// const SYS_getcpu 309 end +// const SYS_process_vm_readv 310 end +// const SYS_process_vm_writev 311 end +// const SYS_kcmp 312 end +// const SYS_finit_module 313 end \ No newline at end of file diff --git a/include/mem.mcl b/include/mem.mcl deleted file mode 100644 index e69de29..0000000 diff --git a/include/std.mcl b/include/std.mcl index e4e2146..7f30f81 100644 --- a/include/std.mcl +++ b/include/std.mcl @@ -1,6 +1,2 @@ -include "linux.mcl" -include "io.mcl" -include "util.mcl" -include "int.mcl" -include "fs.mcl" -include "compat.mcl" \ No newline at end of file +include "linux/linux.mcl" +include "types.mcl" \ No newline at end of file diff --git a/include/types.mcl b/include/types.mcl new file mode 100644 index 0000000..8989182 --- /dev/null +++ b/include/types.mcl @@ -0,0 +1,4 @@ +const sizeof(u8) 1 end +const sizeof(u16) 2 end +const sizeof(u32) 4 end +const sizeof(u64) 8 end \ No newline at end of file diff --git a/include/util.mcl b/include/util.mcl deleted file mode 100644 index 0044e8a..0000000 --- a/include/util.mcl +++ /dev/null @@ -1,15 +0,0 @@ - -// Assert implementation -// args: [condition, str_len, str_ptr] -// @arg condition: Bool -// @arg str_len: Int -// @arg str_ptr: Ptr -// @ret NULL/NEVER -fn assert with bool int ptr returns void then - rot - if else - "Assert failed: \"" eputs eputs - "\". Exiting!\n" eputs - 1 exit - end -done \ No newline at end of file diff --git a/src/bin/mcl_test_dev.rs b/src/bin/mcl_test_dev.rs deleted file mode 100644 index b3164ba..0000000 --- a/src/bin/mcl_test_dev.rs +++ /dev/null @@ -1,172 +0,0 @@ - -use std::path::{PathBuf, Path}; -use std::process::Stdio; -use std::{process, fs}; -use clap::Parser; -use color_eyre::Result; -use eyre::eyre; - -pub mod color { - #![allow(dead_code)] - pub const NONE: &str = "\x1b[0m"; - pub const RESET: &str = "\x1b[0m"; - pub const BRIGHT: &str = "\x1b[1m"; - pub const DIM: &str = "\x1b[2m"; - pub const UNDERSCORE: &str = "\x1b[4m"; - pub const BLINK: &str = "\x1b[5m"; - pub const REVERSE: &str = "\x1b[7m"; - pub const HIDDEN: &str = "\x1b[8m"; - pub const FG_BLACK: &str = "\x1b[30m"; - pub const FG_RED: &str = "\x1b[31m"; - pub const FG_GREEN: &str = "\x1b[32m"; - pub const FG_YELLOW: &str = "\x1b[33m"; - pub const FG_BLUE: &str = "\x1b[34m"; - pub const FG_MAGENTA: &str = "\x1b[35m"; - pub const FG_CYAN: &str = "\x1b[36m"; - pub const FG_WHITE: &str = "\x1b[37m"; - pub const BG_BLACK: &str = "\x1b[40m"; - pub const BG_RED: &str = "\x1b[41m"; - pub const BG_GREEN: &str = "\x1b[42m"; - pub const BG_YELLOW: &str = "\x1b[43m"; - pub const BG_BLUE: &str = "\x1b[44m"; - pub const BG_MAGENTA: &str = "\x1b[45m"; - pub const BG_CYAN: &str = "\x1b[46m"; - pub const BG_WHITE: &str = "\x1b[47m"; -} - -#[allow(dead_code)] -#[derive(Debug)] -struct TestOutput { - stdout: String, - stderr: String, - stdin: String, - status: i32 -} - -fn run_test + std::convert::AsRef>(f_in: PathBuf, f_out: &PathBuf, compiler: P, compile_mode: bool, stdin: String) -> Result { - let mut command = process::Command::new(compiler); - command.stdout(Stdio::piped()); - command.stderr(Stdio::piped()); - if compile_mode { - command.arg("-cqr"); - } else { - command.arg("-sq"); - } - - command.arg("-i"); - command.arg(f_in); - command.arg("-o"); - command.arg(f_out); - - let child = command.spawn()?; - - let out = child.wait_with_output()?; - - let stdout = out.stdout.iter().map(|c| { - char::from_u32(u32::from(*c)).expect("Failed to parse stdout char").to_string() - }).collect::(); - - let stderr = out.stderr.iter().map(|c| { - char::from_u32(u32::from(*c)).expect("Failed to parse stderr char").to_string() - }).collect::(); - - - Ok(TestOutput { - stdout, - stderr, - stdin, - status: out.status.code().unwrap() - }) -} - -fn run_tests(args: Args) -> Result<()>{ - - let files = fs::read_dir(args.input)?; - - for file in files { - let file = file?; - let f_name = file.file_name().to_string_lossy().to_string(); - let f_out = PathBuf::from(&args.output).join(f_name); - - - let intp = run_test(file.path(), &f_out, &args.compiler_path, false, String::new())?; - let comp = run_test(file.path(), &f_out, &args.compiler_path, true, String::new())?; - compare_results(&intp, &comp, &file.path())?; - } - - Ok(()) -} - - -fn compare_results(intp: &TestOutput, comp: &TestOutput, f_in: &Path) -> Result<()> { - - if intp.stdout != comp.stdout { - println!("{b}[ {r}ERR{rs}{b} ]{rs} {f} compiled and interpreted stdout versions differ", r=color::FG_RED, rs=color::RESET, b=color::BRIGHT, f=f_in.display()); - println!("compiled:\n{}", comp.stdout); - println!("interpreted:\n{}", intp.stdout); - return Err(eyre!("Testing failed")); - } - - if intp.stderr != comp.stderr { - println!("{b}[ {r}ERR{rs}{b} ]{rs} {f} compiled and interpreted stderr versions differ", r=color::FG_RED, rs=color::RESET, b=color::BRIGHT, f=f_in.display()); - println!("compiled:\n{}", comp.stderr); - println!("interpreted:\n{}", intp.stderr); - return Err(eyre!("Testing failed")); - } - - if intp.status != comp.status { - println!("{b}[ {r}ERR{rs}{b} ]{rs} {f} compiled and interpreted status codes differ", r=color::FG_RED, rs=color::RESET, b=color::BRIGHT, f=f_in.display()); - println!("compiled:\n{}", comp.status); - println!("interpreted:\n{}", intp.status); - return Err(eyre!("Testing failed")); - } - - println!("{b}[ {g}OK{rs}{b} ]{rs} {f} ", g=color::FG_GREEN, rs=color::RESET, b=color::BRIGHT, f=f_in.display()); - Ok(()) -} - -#[derive(Parser, Debug, Clone)] -#[command(author, version, about, long_about = None)] -struct Args { - - /// Mode, allowed modes: test, record - #[arg(long, short)] - mode: String, - - /// Use compile mode - #[arg(long, short)] - compile: bool, - - /// Use interpret mode - #[arg(long, short='s')] - interpret: bool, - - /// Output folder - #[arg(long, short, default_value_t=String::from("./target/mcl_test_dev"))] - output: String, - - /// Input folder - #[arg(long, short, default_value_t=String::from("./tests"))] - input: String, - - /// Compiler path - #[arg(long, short, default_value_t=String::from("./target/release/mclangc"))] - compiler_path: String - - -} - -fn main() -> Result<()> { - let args = Args::parse(); - fs::create_dir_all(&args.output)?; - match args.mode.as_str() { - "test" => run_tests(args), - "record" => todo!("Implement test result recording"), - s => { - eprintln!("Unknown mode '{s}'"); - return Err(eyre!("Bad subcommand")); - } - }?; - - Ok(()) -} diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..d0b8f6a --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,129 @@ +use clap::{builder::PossibleValue, Parser, ValueEnum}; +use camino::Utf8PathBuf; + +lazy_static::lazy_static! { + static ref DEFAULT_INCLUDE_PATHS: Vec = vec![ + Utf8PathBuf::from("./"), + Utf8PathBuf::from("./include"), + Utf8PathBuf::from("~/.mclang/include"), + ]; +} + +#[derive(Debug, Parser)] +pub struct CliArgs { + /// Only compile, dont link + #[arg(long, short)] + pub compile: bool, + + /// Verosity + /// -1 - Nothing + /// 0 - Only errors + /// 1 - Normal + /// 2 - Verbose + /// 3 - Tracing + #[arg(long, short, default_value_t=1)] + pub verbose: i8, + + /// Runt the program after compilation + #[arg(long, short)] + pub run: bool, + + /// Output execuable file path + #[arg(long, short, default_value="./a.out")] + pub output: Utf8PathBuf, + + /// Paths to search for libraries + #[arg(long="include", short='I', default_values_t=DEFAULT_INCLUDE_PATHS.clone().into_iter())] + pub include_path: Vec, + + /// Target to compile to + #[arg(long, short='T', default_value_t=CompilationTarget::X86_64_linux_nasm)] + pub target: CompilationTarget, + + /// Input code files + #[arg(required=true, num_args=1..)] + pub input: Vec, + + #[clap(skip)] + pub passthrough: Vec +} + + + +impl CliArgs { + pub fn parse_with_passthrough() -> Self { + let mut clap_args = Vec::new(); + let mut pt_args = Vec::new(); + let mut switch = false; + for arg in std::env::args() { + if arg == String::from("--") { + switch = true; + continue; + } + + if !switch { + //clap args + clap_args.push(arg); + } else { + // passwthrough + pt_args.push(arg); + } + } + + let mut cargs = Self::parse_from(clap_args); + cargs.passthrough = pt_args; + + cargs + } +} + + + +#[allow(non_camel_case_types)] +#[derive(Debug, Clone)] +pub enum CompilationTarget { + X86_64_linux_nasm +} + +impl ValueEnum for CompilationTarget { + fn value_variants<'a>() -> &'a [Self] { + &[ + Self::X86_64_linux_nasm + ] + } + + fn to_possible_value(&self) -> Option { + match self { + CompilationTarget::X86_64_linux_nasm => Some(PossibleValue::new("x86_64-linux-nasm")), + } + } +} + +impl std::fmt::Display for CompilationTarget { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let r = match self { + CompilationTarget::X86_64_linux_nasm => "x86_64-linux-nasm", + }; + write!(f, "{}", r) + } +} + +// impl From for clap::builder::OsStr { +// fn from(value: CompilationTarget) -> Self { +// match value { +// CompilationTarget::X86_64_linux_nasm => "X86_64_linux_nasm".into() +// } +// } +// } + +// impl TryFrom<&str> for CompilationTarget { +// type Error = anyhow::Error; +// fn try_from(value: &str) -> Result { +// match value { +// "X86_64_linux_nasm" => Ok(CompilationTarget::X86_64_linux_nasm) +// _ => bail!("Unknown compilation target {value}") +// } +// } + +// } + diff --git a/src/compile/commands.rs b/src/compile/commands.rs deleted file mode 100644 index 98426e6..0000000 --- a/src/compile/commands.rs +++ /dev/null @@ -1,88 +0,0 @@ -use std::path::{PathBuf, Path}; -use std::process::{Command, Stdio}; -use color_eyre::Result; -use crate::info; - -pub fn linux_x86_64_compile_and_link(of_a: &Path, of_o: &Path, of_c: &Path, quiet: bool) -> Result<()> { - - let nasm_args = [ - "-felf64", - of_a.to_str().unwrap(), - "-o", - of_o.to_str().unwrap() - ]; - - let ld_args = [ - of_o.to_str().unwrap(), - "-o", - of_c.to_str().unwrap() - ]; - - - let mut proc = if cfg!(target_os = "windows") { - return Ok(()); - } else { - Command::new("nasm") - .args(nasm_args) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn()? - }; - if !quiet { - info!("running 'nasm {}'", nasm_args.join(" ")); - } - let exit = proc.wait()?; - - if !quiet { - info!("nasm process exited with code {}", exit); - } - - - let mut proc2 = if cfg!(target_os = "windows") { - return Ok(()); - } else { - Command::new("ld") - .args(ld_args) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn()? - }; - if !quiet { - info!("running 'ld {}'", ld_args.join(" ")); - } - let exit2 = proc2.wait()?; - if !quiet { - info!("ld process exited with code {}", exit2); - } - - - - Ok(()) -} - -pub fn linux_x86_64_run(bin: &Path, args: &[String], quiet: bool) -> Result { - - let bin = PathBuf::from( - format!("./{}", bin.to_string_lossy()) - ); - - let mut proc = if cfg!(target_os = "windows") { - return Ok(0); - } else { - Command::new(bin.clone()) - .args(args) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn()? - }; - // println!("{}", quiet); - if !quiet { - info!("running {} {}", bin.to_string_lossy(), args.join(" ")); - } - let exit = proc.wait()?; - if !quiet { - info!("{} process exited with code {}", bin.to_string_lossy(), exit); - } - - Ok(exit.code().unwrap_or(0)) -} \ No newline at end of file diff --git a/src/compile/linux_x86_64.rs b/src/compile/linux_x86_64.rs deleted file mode 100644 index 572caf7..0000000 --- a/src/compile/linux_x86_64.rs +++ /dev/null @@ -1,661 +0,0 @@ -use std::{fs, path::PathBuf, io::{Write, BufWriter}, collections::HashMap}; -use crate::{constants::{Operator, OpType, KeywordType}, Args, warn, lerror}; -use color_eyre::Result; -use crate::compile::commands::linux_x86_64_compile_and_link; -use crate::constants::InstructionType; -use super::{commands::linux_x86_64_run, Constant, Memory, Function}; -use eyre::eyre; - - -pub fn compile(tokens: &[Operator], args: &Args) -> Result{ - let debug = args.get_opt_level()? < 1; - - let mut of_c = PathBuf::from(&args.out_file); - let (mut of_o, mut of_a) = if args.out_file == *crate::DEFAULT_OUT_FILE { - let of_o = PathBuf::from("/tmp/mclang_comp.o"); - let of_a = PathBuf::from("/tmp/mclang_comp.nasm"); - (of_o, of_a) - } else { - let of_o = PathBuf::from(&args.out_file); - let of_a = PathBuf::from(&args.out_file); - (of_o, of_a) - }; - - of_c.set_extension(""); - of_o.set_extension("o"); - of_a.set_extension("nasm"); - - let mut should_push_ret = false; - - let file = fs::File::create(&of_a)?; - let mut writer = BufWriter::new(&file); - let mut memories: Vec = Vec::new(); - let mut constants: HashMap = HashMap::new(); - let mut functions: Vec = Vec::new(); - // println!("{}", tokens.len()); - let mut strings: Vec = Vec::new(); - - writeln!(writer, "BITS 64")?; - writeln!(writer, "segment .text")?; - - writeln!(writer, "_dbg_print:")?; - writeln!(writer, " mov r9, -3689348814741910323")?; - writeln!(writer, " sub rsp, 40")?; - writeln!(writer, " mov BYTE [rsp+31], 10")?; - writeln!(writer, " lea rcx, [rsp+30]")?; - writeln!(writer, ".L2:")?; - writeln!(writer, " mov rax, rdi")?; - writeln!(writer, " lea r8, [rsp+32]")?; - writeln!(writer, " mul r9")?; - writeln!(writer, " mov rax, rdi")?; - writeln!(writer, " sub r8, rcx")?; - writeln!(writer, " shr rdx, 3")?; - writeln!(writer, " lea rsi, [rdx+rdx*4]")?; - writeln!(writer, " add rsi, rsi")?; - writeln!(writer, " sub rax, rsi")?; - writeln!(writer, " add eax, 48")?; - writeln!(writer, " mov BYTE [rcx], al")?; - writeln!(writer, " mov rax, rdi")?; - writeln!(writer, " mov rdi, rdx")?; - writeln!(writer, " mov rdx, rcx")?; - writeln!(writer, " sub rcx, 1")?; - writeln!(writer, " cmp rax, 9")?; - writeln!(writer, " ja .L2")?; - writeln!(writer, " lea rax, [rsp+32]")?; - writeln!(writer, " mov edi, 1")?; - writeln!(writer, " sub rdx, rax")?; - writeln!(writer, " xor eax, eax")?; - writeln!(writer, " lea rsi, [rsp+32+rdx]")?; - writeln!(writer, " mov rdx, r8")?; - writeln!(writer, " mov rax, 1")?; - writeln!(writer, " syscall")?; - writeln!(writer, " add rsp, 40")?; - writeln!(writer, " ret")?; - - if crate::config::ENABLE_EXPORTED_FUNCTIONS && !args.lib_mode { - writeln!(writer, "global _start")?; - writeln!(writer, "_start:")?; - writeln!(writer, " lea rbp, [rel ret_stack]")?; - writeln!(writer, " call main")?; - writeln!(writer, " jmp end")?; - - } - - - let mut ti = 0; - while ti < tokens.len() { - let token = &tokens[ti]; - // println!("{:?}", token); - if debug { - writeln!(writer, "addr_{ti}:")?; - if token.typ == OpType::Instruction(InstructionType::PushInt) { - writeln!(writer, " ;; -- {:?} {}", token.typ, token.value)?; - } else if token.typ == OpType::Instruction(InstructionType::PushStr) { - writeln!(writer, " ;; -- {:?} {}", token.typ, token.text.escape_debug())?; - } else { - writeln!(writer, " ;; -- {:?}", token.typ)?; - } - } else { - if ti > 0 { - if tokens[ti-1].typ == OpType::Keyword(KeywordType::Else) || - tokens[ti-1].typ == OpType::Keyword(KeywordType::End){ - writeln!(writer, "addr_{ti}:")?; - } - } - - if ti + 1 < tokens.len() && tokens[ti+1].typ == OpType::Keyword(KeywordType::End) { - writeln!(writer, "addr_{ti}:")?; - } - - if let OpType::Keyword(keyword) = &token.typ { - match keyword { - &KeywordType::End | - &KeywordType::While => { - writeln!(writer, "addr_{ti}:")?; - } - _ => () - } - } - - } - match token.typ.clone() { - // stack - - OpType::Instruction(instruction) => { - match instruction { - InstructionType::PushInt => { - writeln!(writer, " mov rax, {}", token.value)?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::PushStr => { - writeln!(writer, " mov rax, {}", token.text.len())?; - writeln!(writer, " push rax")?; - writeln!(writer, " mov rax, str_{}", strings.len())?; - writeln!(writer, " push rax")?; - strings.push(token.text.clone()); - ti += 1; - } - InstructionType::Drop => { - writeln!(writer, " pop rax")?; - ti += 1; - }, - InstructionType::Print => { - writeln!(writer, " pop rdi")?; - writeln!(writer, " call _dbg_print")?; - ti += 1; - }, - - InstructionType::Dup => { - writeln!(writer, " pop rax")?; - writeln!(writer, " push rax")?; - writeln!(writer, " push rax")?; - - ti += 1; - }, - - InstructionType::Rot => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rcx")?; - writeln!(writer, " push rbx")?; - writeln!(writer, " push rax")?; - writeln!(writer, " push rcx")?; - - ti += 1; - }, - InstructionType::Swap => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " push rax")?; - writeln!(writer, " push rbx")?; - - ti += 1; - }, - InstructionType::Over => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " push rbx")?; - writeln!(writer, " push rax")?; - writeln!(writer, " push rbx")?; - - ti += 1; - }, - InstructionType::Load8 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " xor rbx, rbx")?; - writeln!(writer, " mov bl, byte [rax]")?; - writeln!(writer, " push rbx")?; - ti += 1; - } - - InstructionType::Store8 => { - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " mov byte [rax], bl")?; - ti += 1; - } - InstructionType::Load32 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " xor rbx, rbx")?; - writeln!(writer, " mov bl, dword [rax]")?; - writeln!(writer, " push rbx")?; - ti += 1; - } - - InstructionType::Store32 => { - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " mov dword[rax], bl")?; - ti += 1; - } - InstructionType::Load64 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " xor rbx, rbx")?; - writeln!(writer, " mov bl, qword [rax]")?; - writeln!(writer, " push rbx")?; - ti += 1; - } - - InstructionType::Store64 => { - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " mov qword [rax], bl")?; - ti += 1; - } - - // math - InstructionType::Plus => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " add rax, rbx")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::Minus => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " sub rbx, rax")?; - writeln!(writer, " push rbx")?; - ti += 1; - }, - InstructionType::Equals => { - writeln!(writer, " mov rcx, 0")?; - writeln!(writer, " mov rdx, 1")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " cmp rax, rbx")?; - writeln!(writer, " cmove rcx, rdx")?; - writeln!(writer, " push rcx")?; - ti += 1; - }, - InstructionType::Lt => { - writeln!(writer, " mov rcx, 0")?; - writeln!(writer, " mov rdx, 1")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " cmp rax, rbx")?; - writeln!(writer, " cmovl rcx, rdx")?; - writeln!(writer, " push rcx")?; - ti += 1; - }, - InstructionType::Gt => { - writeln!(writer, " mov rcx, 0")?; - writeln!(writer, " mov rdx, 1")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " cmp rax, rbx")?; - writeln!(writer, " cmovg rcx, rdx")?; - writeln!(writer, " push rcx")?; - ti += 1; - }, - InstructionType::NotEquals => { - writeln!(writer, " mov rcx, 1")?; - writeln!(writer, " mov rdx, 0")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " cmp rax, rbx")?; - writeln!(writer, " cmove rcx, rdx")?; - writeln!(writer, " push rcx")?; - ti += 1; - }, - InstructionType::Le => { - writeln!(writer, " mov rcx, 0")?; - writeln!(writer, " mov rdx, 1")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " cmp rax, rbx")?; - writeln!(writer, " cmovle rcx, rdx")?; - writeln!(writer, " push rcx")?; - ti += 1; - }, - InstructionType::Ge => { - writeln!(writer, " mov rcx, 0")?; - writeln!(writer, " mov rdx, 1")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " cmp rax, rbx")?; - writeln!(writer, " cmovge rcx, rdx")?; - writeln!(writer, " push rcx")?; - ti += 1; - }, - InstructionType::Band => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " and rbx, rax")?; - writeln!(writer, " push rbx")?; - ti += 1; - }, - InstructionType::Bor => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " or rbx, rax")?; - writeln!(writer, " push rbx")?; - ti += 1; - }, - InstructionType::Shr => { - writeln!(writer, " pop rcx")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " shr rbx, cl")?; - writeln!(writer, " push rbx")?; - ti += 1; - }, - InstructionType::Shl => { - writeln!(writer, " pop rcx")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " shl rbx, cl")?; - writeln!(writer, " push rbx")?; - ti += 1; - }, - InstructionType::DivMod => { - writeln!(writer, " xor rdx, rdx")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " div rbx")?; - writeln!(writer, " push rax")?; - writeln!(writer, " push rdx")?; - ti += 1; - }, - InstructionType::Mul => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " mul rbx")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::Syscall0 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " syscall")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::Syscall1 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rdi")?; - writeln!(writer, " syscall")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::Syscall2 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rdi")?; - writeln!(writer, " pop rsi")?; - writeln!(writer, " syscall")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::Syscall3 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rdi")?; - writeln!(writer, " pop rsi")?; - writeln!(writer, " pop rdx")?; - writeln!(writer, " syscall")?; - writeln!(writer, " push rax")?; - - ti += 1; - }, - InstructionType::Syscall4 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rdi")?; - writeln!(writer, " pop rsi")?; - writeln!(writer, " pop rdx")?; - writeln!(writer, " pop r10")?; - writeln!(writer, " syscall")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::Syscall5 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rdi")?; - writeln!(writer, " pop rsi")?; - writeln!(writer, " pop rdx")?; - writeln!(writer, " pop r10")?; - writeln!(writer, " pop r8")?; - writeln!(writer, " syscall")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::Syscall6 => { - writeln!(writer, " pop rax")?; - writeln!(writer, " pop rdi")?; - writeln!(writer, " pop rsi")?; - writeln!(writer, " pop rdx")?; - writeln!(writer, " pop r10")?; - writeln!(writer, " pop r8")?; - writeln!(writer, " pop r9")?; - writeln!(writer, " syscall")?; - writeln!(writer, " push rax")?; - ti += 1; - }, - InstructionType::MemUse => { - writeln!(writer, " push mem_{}", token.addr.unwrap())?; - ti += 1; - }, - InstructionType::None => { - println!("{token:?}"); - unreachable!() - }, - InstructionType::FnCall => { - writeln!(writer, " call {}", token.text)?; - ti += 1; - }, - InstructionType::Return => { - - if crate::config::ENABLE_EXPORTED_FUNCTIONS && should_push_ret { - writeln!(writer, " pop rdx")?; - should_push_ret = false; - } - - writeln!(writer, " sub rbp, 8")?; - writeln!(writer, " mov rbx, qword [rbp]")?; - writeln!(writer, " push rbx")?; - writeln!(writer, " ret")?; - ti += 1; - }, - InstructionType::CastBool | - InstructionType::CastPtr | - InstructionType::CastInt | - InstructionType::CastVoid | - InstructionType::TypeBool | - InstructionType::TypePtr | - InstructionType::TypeInt | - InstructionType::TypeVoid | - InstructionType::TypeAny | - InstructionType::Returns | - InstructionType::With => { - ti += 1; - } - InstructionType::ConstUse => { - writeln!(writer, " mov rax, qword [const_{}]", token.text)?; - writeln!(writer, " push rax")?; - - let mut c = constants.get(&token.text).unwrap().clone(); - c.used = true; - constants.remove(&token.text); - constants.insert(token.text.clone(), c); - ti += 1; - }, - } - } - - - OpType::Keyword(keyword) => { - match keyword { - - // block - KeywordType::If | - KeywordType::Do => { - writeln!(writer, " pop rax")?; - writeln!(writer, " test rax, rax")?; - writeln!(writer, " jz addr_{}", token.jmp)?; - ti += 1; - } - KeywordType::Else => { - writeln!(writer, " jmp addr_{}", token.jmp)?; - ti += 1; - }, - KeywordType::While => { - ti += 1; - } - KeywordType::End => { - if ti + 1 != token.jmp { - // writeln!(writer, " jmp addr_{}", token.jmp)?; - } - ti += 1; - }, - KeywordType::Memory => { - memories.push(Memory { size: token.value, loc: token.loc.clone(), id: token.addr.unwrap() }); - ti += 1; - } - KeywordType::ConstantDef => { - // TODO: after we add c style strings add supoort for them in constants - let a = args.get_opt_level()? < 1; - let c = Constant{ - loc: token.loc.clone(), - name: token.text.clone(), - value_i: Some(token.value), - value_s: None, - used: a, - }; - - constants.insert(token.text.clone(), c); - ti += 1; - }, - KeywordType::FunctionDef => { - writeln!(writer, "{}:", token.text)?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " mov qword [rbp], rbx")?; - writeln!(writer, " add rbp, 8")?; - functions.push(Function { loc: token.loc.clone(), name: token.text.clone(), exter: false}); - ti += 1; - }, - KeywordType::FunctionDone => { - - if crate::config::ENABLE_EXPORTED_FUNCTIONS && should_push_ret { - writeln!(writer, " pop rdx")?; - should_push_ret = false; - } - - writeln!(writer, " sub rbp, 8")?; - writeln!(writer, " mov rbx, qword [rbp]")?; - writeln!(writer, " push rbx")?; - writeln!(writer, " ret")?; - ti += 1; - } - KeywordType::FunctionThen => ti += 1, - KeywordType::Function | - KeywordType::Include | - KeywordType::Inline | - KeywordType::Export | - KeywordType::Constant => unreachable!(), - KeywordType::FunctionDefExported => { - - if !crate::config::ENABLE_EXPORTED_FUNCTIONS { - lerror!(&token.loc, "Experimental feature 'exported functions' is not enabled"); - return Err(eyre!("")); - } - - writeln!(writer, "global {}", token.text)?; - writeln!(writer, "{}:", token.text)?; - - writeln!(writer, " pop rbx")?; - writeln!(writer, " mov qword [rbp], rbx")?; - writeln!(writer, " add rbp, 8")?; - warn!("External functions are highly experimental and should be treated as such"); - if token.types.0 == 0 { - writeln!(writer, " ; no arguments")?; - } else { - if token.types.0 >= 1 { - writeln!(writer, " push rdi")?; - } - if token.types.0 >= 2 { - writeln!(writer, " push rsi")?; - } - if token.types.0 >= 3 { - writeln!(writer, " push rdx")?; - } - if token.types.0 >= 4 { - writeln!(writer, " push rcx")?; - } - if token.types.0 >= 5 { - writeln!(writer, " push r8")?; - } - if token.types.0 >= 6 { - writeln!(writer, " push r9")?; - } - if token.types.0 >= 7 { - lerror!(&token.loc, "More than 6 arguments in an external function is not supported"); - return Err(eyre!("")); - } - } - - if token.types.1 == 1 { - should_push_ret = true; - } else if token.types.1 > 1 { - lerror!(&token.loc, "More than 1 return arguments in an external function is not supported"); - return Err(eyre!("")); - } - - functions.push(Function { loc: token.loc.clone(), name: token.text.clone(), exter: false}); - ti += 1; - }, - } - } - } - } - writeln!(writer, "addr_{ti}:")?; - if crate::config::ENABLE_EXPORTED_FUNCTIONS && !args.lib_mode { - writeln!(writer, "end:")?; - writeln!(writer, " mov rax, 60")?; - writeln!(writer, " mov rdi, 0")?; - writeln!(writer, " syscall")?; - } - writeln!(writer, "segment .data")?; - for (i, s) in strings.iter().enumerate() { - let s_chars = s.chars().map(|c| (c as u32).to_string()).collect::>(); - let s_list = s_chars.join(","); - writeln!(writer, " str_{}: db {} ; {}", i, s_list, s.escape_default())?; - } - - for (_, c) in constants { - if !c.used { - continue; - } - - if let Some(v) = &c.value_i { - writeln!(writer, " const_{}: dq {}", c.name, v)?; - } else if let Some(_v) = &c.value_s { - todo!(); - } else { - unreachable!(); - } - - } - - - writeln!(writer, "segment .bss")?; - for s in memories { - writeln!(writer, " mem_{}: resb {}", s.id, s.size)?; - } - writeln!(writer, " ret_stack: resq 256")?; - - // for t in tokens { - // println!("{t:?}"); - // } - - writer.flush()?; - - - pre_compile_steps( - String::from_utf8_lossy(writer.buffer()).to_string().as_str(), - functions - )?; - - linux_x86_64_compile_and_link(&of_a, &of_o, &of_c, args.quiet)?; - if args.run { - let c = linux_x86_64_run(&of_c, &[], args.quiet)?; - return Ok(c); - } - - - Ok(0) -} - - -fn pre_compile_steps(_code: &str, functions: Vec) -> Result<()> { - let mut has_main = false; - - for func in functions { - if func.name == "main" { - has_main = true; - } - } - - - if !has_main { - crate::errors::missing_main_fn(); - return Err(eyre!("")); - } - - Ok(()) -} \ No newline at end of file diff --git a/src/compile/mod.rs b/src/compile/mod.rs deleted file mode 100644 index 542e6ed..0000000 --- a/src/compile/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::constants::Loc; - -pub mod linux_x86_64; -pub mod commands; - -#[derive(Debug, Clone)] -pub struct Constant { - pub loc: Loc, - pub name: String, - pub value_i: Option, - pub value_s: Option, - pub used: bool - // extern: bool -} - -#[derive(Debug, Clone)] -pub struct Memory { - pub size: usize, - pub loc: Loc, - pub id: usize -} - -#[derive(Debug, Clone)] -pub struct Function { - pub loc: Loc, - pub name: String, - pub exter: bool, -} \ No newline at end of file diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs new file mode 100644 index 0000000..1fc074e --- /dev/null +++ b/src/compiler/mod.rs @@ -0,0 +1,104 @@ +mod x86_64_linux_nasm; +mod utils; + +use anyhow::bail; + +use crate::{cli::{CliArgs, CompilationTarget}, types::ast::Program}; +use std::{collections::HashMap, fs::File, io::{BufWriter, Write}, path::{Path, PathBuf}, process::Command}; + + + +pub trait Compiler { + fn new() -> Self; + fn generate_asm(&mut self, prog: &Program, fd: &mut BufWriter) -> anyhow::Result<()>; + fn compile(&mut self, asm_fp: &Path, obj: &Path) -> anyhow::Result<()>; + fn link(&mut self, obj_files: Vec, bin_fp: &Path) -> anyhow::Result<()>; + /// Return programs that are needed + fn needed_dependencies(&mut self) -> Vec<&str>; +} + +//NOTE: No bsd cause im not about to create 3 or 4 diffrent compilation targets + +pub fn compile_program(cli_args: &CliArgs, prog_map: HashMap<&Path, Program>) -> anyhow::Result<()> { + let mut compiler = match cli_args.target { + CompilationTarget::X86_64_linux_nasm => x86_64_linux_nasm::X86_64LinuxNasmCompiler::new(), + }; + let bin_p = cli_args.output.as_std_path(); + let mut objs = Vec::new(); + for (k, v) in prog_map { + let mut asm_p = k.to_path_buf(); + let mut obj_p = k.to_path_buf(); + + asm_p.set_extension("s"); + obj_p.set_extension("o"); + + + if let Err(_) = compile_file(&mut compiler, cli_args, asm_p.as_path(), obj_p.as_path(), &v) { + error!("Failed to compile file {k:?}"); + bail!("") + } + objs.push(obj_p.clone()); + } + + if let Err(e) = compiler.link(objs, bin_p) { + error!("Failed to link program: {e}"); + bail!("") + } + + info!("Finished building program"); + + if cli_args.run { + // run_cmd(format!("./{}", bin_p.to_string_lossy()), cli_args.passthrough.clone())?; + let bin = bin_p.to_string_lossy().to_string(); + let mut cmd = Command::new(format!("./{}", bin.clone())); + let cmd = cmd.args(cli_args.passthrough.clone()); + + let child = match cmd.spawn() { + Ok(c) => c, + Err(e) => { + error!("Unable to run {cmd:?}: {e}"); + bail!(""); + } + }; + let ret = child.wait_with_output().expect("fuck i know"); + + + if !ret.status.success() { + error!("Process running {bin:?} exited abnormaly, run with -v 2 for more output"); + bail!("") + } else { + info!("Process exited successfully") + } + + } + + + Ok(()) +} + +pub fn compile_file(compiler: &mut C, _: &CliArgs, asm_file: &Path, obj_file: &Path, prog: &Program) -> anyhow::Result<()> { + + let asm_fd = std::fs::File::options() + .write(true) + .write(true) + .create(true) + .truncate(true) + .append(false) + .open(asm_file); + + let asm_fd = match asm_fd { + Ok(fd) => fd, + Err(e) => { + error!("Failed to open file {asm_file:?}: {e}"); + bail!(""); + } + }; + + let mut buf_asm_fd = BufWriter::new(asm_fd); + + compiler.generate_asm(prog, &mut buf_asm_fd)?; + buf_asm_fd.flush()?; + + compiler.compile(asm_file, obj_file)?; + Ok(()) +} \ No newline at end of file diff --git a/src/compiler/utils.rs b/src/compiler/utils.rs new file mode 100644 index 0000000..ede944c --- /dev/null +++ b/src/compiler/utils.rs @@ -0,0 +1,36 @@ +use std::{fmt::Debug, process::{Command, Stdio}}; + +use anyhow::bail; + + + +pub fn run_cmd<'a, S: Into + Debug + Clone>(bin: S, args: Vec) -> anyhow::Result<()> { + let debug = unsafe { + crate::logger::LOGGER.enabled(crate::logger::Level::Debug) + }; + let mut cmd = Command::new(bin.clone().into()); + let cmd = cmd.args(args); + let cmd = if debug { + cmd.stdout(Stdio::inherit()) + } else { + cmd.stdout(Stdio::null()) + }; + let cmd = cmd.stderr(Stdio::inherit()); + + let child = match cmd.spawn() { + Ok(c) => c, + Err(e) => { + error!("Unable to run {cmd:?}: {e}"); + bail!(""); + } + }; + let ret = child.wait_with_output().expect("fuck i know"); + + + if !ret.status.success() { + error!("Process running {bin:?} exited abnormaly, run with -v 2 for more output"); + bail!("") + } + + Ok(()) +} \ No newline at end of file diff --git a/src/compiler/x86_64_linux_nasm/mod.rs b/src/compiler/x86_64_linux_nasm/mod.rs new file mode 100644 index 0000000..4932d7f --- /dev/null +++ b/src/compiler/x86_64_linux_nasm/mod.rs @@ -0,0 +1,521 @@ +mod utils; + +use std::path::PathBuf; +use std::{fs::File, io::BufWriter, path::Path}; +use std::io::Write; +use crate::types::ast::{AstNode, EscIdent, Function, MemSize, Module, Program}; +use crate::types::token::{InstructionType, Token, TokenType}; + +use super::utils::run_cmd; +use super::Compiler; + + + + +pub struct X86_64LinuxNasmCompiler { + strings: Vec, + // func_mem_i: Vec, + // func_mem_list: HashMap, + if_i: usize, + while_i: usize, + used_consts: Vec +} + +impl X86_64LinuxNasmCompiler { + fn handle_token(&mut self, fd: &mut BufWriter, _: &Program, token: &Token) -> anyhow::Result<()> { + match &token.typ { + TokenType::Instruction(it) => { + match it { + InstructionType::PushInt(i) => { + writeln!(fd, " mov rax, {i} ; PUSHINT({i})")?; + writeln!(fd, " push rax")?; + }, + InstructionType::PushStr(s) => { + writeln!(fd, " push {}", s.len())?; + writeln!(fd, " push str_{}; PUSHSTR({})", self.strings.len(), s.escape_debug())?; + self.strings.push(s.clone()); + }, + InstructionType::PushCStr(s) => { + writeln!(fd, " push str_{}; PUSHCSTR({})", self.strings.len(), s.escape_debug())?; + self.strings.push(s.clone()); + }, + InstructionType::PushChar(c) => { + writeln!(fd, " push {}; PUSHCHAR({})", *c as u8, c.escape_debug())?; + }, + InstructionType::Drop => { + writeln!(fd, " pop rax ; DROP")?; + }, + InstructionType::Print => { + writeln!(fd, " pop rdi")?; + writeln!(fd, " call _dbg_print ; _DBG_PRINT")?; + }, + InstructionType::Dup => { + writeln!(fd, " pop rax ; DUP")?; + writeln!(fd, " push rax")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Rot => { + writeln!(fd, " pop rax ; ROT")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " pop rcx")?; + writeln!(fd, " push rbx")?; + writeln!(fd, " push rax")?; + writeln!(fd, " push rcx")?; + }, + InstructionType::Over => { + writeln!(fd, " pop rax ; OVER")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " push rbx")?; + writeln!(fd, " push rax")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::Swap => { + writeln!(fd, " pop rax ; SWAP")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " push rax")?; + writeln!(fd, " push rbx")?; + } + InstructionType::Minus => { + writeln!(fd, " pop rax ; SUB")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " sub rbx, rax")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::Plus => { + writeln!(fd, " pop rax ; ADD")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " add rax, rbx")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Equals => { + writeln!(fd, " mov rcx, 0 ; EQ")?; + writeln!(fd, " mov rdx, 1")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " cmp rax, rbx")?; + writeln!(fd, " cmove rcx, rdx")?; + writeln!(fd, " push rcx")?; + }, + InstructionType::Gt => { + writeln!(fd, " mov rcx, 0 ; GT")?; + writeln!(fd, " mov rdx, 1")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " cmp rax, rbx")?; + writeln!(fd, " cmovg rcx, rdx")?; + writeln!(fd, " push rcx")?; + }, + InstructionType::Lt => { + writeln!(fd, " mov rcx, 0 ; LT")?; + writeln!(fd, " mov rdx, 1")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " cmp rax, rbx")?; + writeln!(fd, " cmovl rcx, rdx")?; + writeln!(fd, " push rcx")?; + }, + InstructionType::Ge => { + writeln!(fd, " mov rcx, 0 ; GE")?; + writeln!(fd, " mov rdx, 1")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " cmp rax, rbx")?; + writeln!(fd, " cmovge rcx, rdx")?; + writeln!(fd, " push rcx")?; + }, + InstructionType::Le => { + writeln!(fd, " mov rcx, 0 ; LE")?; + writeln!(fd, " mov rdx, 1")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " cmp rax, rbx")?; + writeln!(fd, " cmovle rcx, rdx")?; + writeln!(fd, " push rcx")?; + }, + InstructionType::NotEquals => { + writeln!(fd, " mov rdx, 1 ; NEQ")?; + writeln!(fd, " mov rcx, 0")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " cmp rax, rbx")?; + writeln!(fd, " cmove rcx, rdx")?; + writeln!(fd, " push rcx")?; + }, + InstructionType::Band => { + writeln!(fd, " pop rax ; BAND")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " and rbx, rax")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::Bor => { + writeln!(fd, " pop rax ; BOR")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " or rbx, rax")?; + writeln!(fd, " push rbx")?; + } + InstructionType::Shr => { + writeln!(fd, " pop rcx")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " shr rbx, cl")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::Shl => { + writeln!(fd, " pop rcx")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " shl rbx, cl")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::DivMod => { + writeln!(fd, " xor rdx, rdx")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " div rbx")?; + writeln!(fd, " push rax")?; + writeln!(fd, " push rdx")?; + }, + InstructionType::Mul => { + writeln!(fd, " pop rax ; MUL")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " mul rbx")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Read8 => { + writeln!(fd, " pop rax ; READ8")?; + writeln!(fd, " xor rbx, rbx")?; + writeln!(fd, " mov bl, byte [rax]")?; + writeln!(fd, " push rbx")?; + } + InstructionType::Write8 => { + writeln!(fd, " pop rax ; WRITE 8")?; + writeln!(fd, " xor rbx, rbx")?; + writeln!(fd, " mov ebx, dword [rax]")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::Read32 => { + writeln!(fd, " pop rax ; READ 32")?; + writeln!(fd, " xor rbx, rbx")?; + writeln!(fd, " mov ebx, dword [rax]")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::Write32 => { + writeln!(fd, " pop rbx ; WRITE 32")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " mov dword[rax], ebx")?; + }, + InstructionType::Read64 => { + writeln!(fd, " pop rax ; READ 32")?; + writeln!(fd, " xor rbx, rbx")?; + writeln!(fd, " mov rbx, qword [rax]")?; + writeln!(fd, " push rbx")?; + }, + InstructionType::Write64 => { + writeln!(fd, " pop rbx ; WRITE 64")?; + writeln!(fd, " pop rax")?; + writeln!(fd, " mov qword[rax], rbx")?; + }, + InstructionType::Syscall0 => { + writeln!(fd, " pop rax")?; + writeln!(fd, " syscall")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Syscall1 => { + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rdi")?; + writeln!(fd, " syscall")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Syscall2 => { + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rdi")?; + writeln!(fd, " pop rsi")?; + writeln!(fd, " syscall")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Syscall3 => { + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rdi")?; + writeln!(fd, " pop rsi")?; + writeln!(fd, " pop rdx")?; + writeln!(fd, " syscall")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Syscall4 => { + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rdi")?; + writeln!(fd, " pop rsi")?; + writeln!(fd, " pop rdx")?; + writeln!(fd, " pop r10")?; + writeln!(fd, " syscall")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Syscall5 => { + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rdi")?; + writeln!(fd, " pop rsi")?; + writeln!(fd, " pop rdx")?; + writeln!(fd, " pop r10")?; + writeln!(fd, " pop r8")?; + writeln!(fd, " syscall")?; + writeln!(fd, " push rax")?; + }, + InstructionType::Syscall6 => { + writeln!(fd, " pop rax")?; + writeln!(fd, " pop rdi")?; + writeln!(fd, " pop rsi")?; + writeln!(fd, " pop rdx")?; + writeln!(fd, " pop r10")?; + writeln!(fd, " pop r8")?; + writeln!(fd, " pop r9")?; + writeln!(fd, " syscall")?; + writeln!(fd, " push rax")?; + }, + InstructionType::CastBool | + InstructionType::CastPtr | + InstructionType::CastInt | + InstructionType::CastVoid => (), //? Possibly have a use for this + InstructionType::FnCall | + InstructionType::MemUse | + InstructionType::StructPath(_) | + InstructionType::StructItem(_) | + InstructionType::ConstUse => unreachable!(), + InstructionType::Return => { + writeln!(fd, " sub rbp, 8")?; + writeln!(fd, " mov rbx, qword [rbp]")?; + writeln!(fd, " push rbx")?; + writeln!(fd, " ret")?; + }, + } + }, + TokenType::Keyword(_) | + TokenType::Type(_) | + TokenType::Unknown(_) => unreachable!(), + } + Ok(()) + } + + fn handle_module(&mut self, fd: &mut BufWriter, prog: &Program, module: &Module) -> anyhow::Result<()> { + writeln!(fd, "; {} Module START", module.path.join("::"))?; + self.handle_ast_list(fd, prog, module.body.clone())?; + writeln!(fd, "; {} Module END", module.path.join("::"))?; + Ok(()) + } + + fn handle_function(&mut self, fd: &mut BufWriter, prog: &Program, func: &Function) -> anyhow::Result<()> { + writeln!(fd, "{f}: ; fn {f}", f=func.get_ident_escaped())?; + writeln!(fd, " fn_setup")?; + + self.handle_ast_list(fd, prog, func.body.clone())?; + + writeln!(fd, " fn_cleanup")?; + writeln!(fd, " ret")?; + Ok(()) + } + + fn handle_ast_list(&mut self, fd: &mut BufWriter, prog: &Program, ast: Vec) -> anyhow::Result<()> { + for node in ast { + match &node { + AstNode::Function(f) => self.handle_function(fd, prog, f)?, + AstNode::Constant(_) => (), + AstNode::If(i) => { + let id = self.if_i; + self.if_i += 1; + + writeln!(fd, "; IF({id}) START")?; + self.handle_ast_list(fd, prog, i.test.clone())?; + writeln!(fd, " pop rax")?; + writeln!(fd, " test rax, rax")?; + writeln!(fd, " jz if_{id}_else")?; + writeln!(fd, "if_{id}_start:")?; + self.handle_ast_list(fd, prog, i.body.clone())?; + writeln!(fd, " jmp if_{id}_end")?; + writeln!(fd, "if_{id}_else:")?; + self.handle_ast_list(fd, prog, vec![Box::leak(i.els.clone()).clone()])?; + writeln!(fd, "if_{id}_end:")?; + writeln!(fd, "; IF({id}) END")?; + }, + AstNode::While(w) => { + let id = self.while_i; + self.while_i += 1; + writeln!(fd, "; WHILE({id}) START")?; + writeln!(fd, "while_{id}_test:")?; + self.handle_ast_list(fd, prog, w.test.clone())?; + writeln!(fd, " pop rax")?; + writeln!(fd, " test rax, rax")?; + writeln!(fd, " jz while_{id}_exit")?; + writeln!(fd, "while_{id}_start:")?; + self.handle_ast_list(fd, prog, w.body.clone())?; + writeln!(fd, "while_{id}_end:")?; + writeln!(fd, " jmp while_{id}_test")?; + writeln!(fd, "while_{id}_exit:")?; + writeln!(fd, "; WHILE({id}) END")?; + }, + AstNode::Module(m) => self.handle_module(fd, prog, m)?, + AstNode::Memory(_) => { + //? Possibly allow stack based allocation somehow + // if !m.statc { + // todo!() + // } + }, + AstNode::MemUse(m) => { + let tmp = if let Some(disp) = m.disp { + format!("+{disp}") + } else { + String::new() + }; + writeln!(fd, " push m_{}{}", m.get_ident_escaped(), tmp)?; + }, + AstNode::ConstUse(c) => { + self.used_consts.push(c.get_ident_escaped()); + writeln!(fd, " mov rax, qword [c_{}]", c.get_ident_escaped())?; + writeln!(fd, " push rax")?; + }, + AstNode::FnCall(f)=> { + writeln!(fd, " call {f} ; FUNCTIONCALL({f:?})", f=f.get_ident_escaped())?; + }, + AstNode::Block(b)=> { + writeln!(fd, "; BLOCK({}) START", b.comment)?; + self.handle_ast_list(fd, prog, b.body.clone())?; + writeln!(fd, "; BLOCK({}) END", b.comment)?; + }, + AstNode::Token(t) => self.handle_token(fd, prog, t)?, + AstNode::Int(_, _) | + AstNode::Str(_, _) | + AstNode::CStr(_, _) | + AstNode::Char(_, _) => unreachable!(), + AstNode::StructDef(_) => (), + AstNode::StructDispPush { disp, ident, .. } => { + writeln!(fd, " mov rax, {} ; STRUCTDISPPUSH({})", disp, ident)?; + writeln!(fd, " push rax")?; + }, + } + } + Ok(()) + } +} + + +impl Compiler for X86_64LinuxNasmCompiler { + fn new() -> Self { + Self { + strings: Vec::new(), + used_consts: Vec::new(), + if_i: 0, + while_i: 0, + // func_mem_i: Vec::new(), + // func_mem_list: HashMap::new(), + } + } + + fn generate_asm(&mut self, prog: &Program, fd: &mut BufWriter) -> anyhow::Result<()> { + + writeln!(fd, "BITS 64")?; + writeln!(fd, "segment .text")?; + + writeln!(fd, "%macro fn_setup 0")?; + writeln!(fd, " pop rbx")?; + writeln!(fd, " mov qword [rbp], rbx")?; + writeln!(fd, " add rbp, 8")?; + writeln!(fd, "%endmacro")?; + writeln!(fd, "%macro fn_cleanup 0")?; + writeln!(fd, " sub rbp, 8")?; + writeln!(fd, " mov rbx, qword [rbp]")?; + writeln!(fd, " push rbx")?; + writeln!(fd, "%endmacro")?; + + writeln!(fd, "{}", utils::DBG_PRINT)?; + writeln!(fd, "global _start")?; + writeln!(fd, "_start:")?; + writeln!(fd, " lea rbp, [rel ret_stack]")?; + writeln!(fd, " call main")?; + writeln!(fd, " jmp __MCL_END__")?; + + match &prog.ast { + AstNode::Module(m) => { + self.handle_module(fd, prog, m)?; + }, + _ => panic!() + } + + + writeln!(fd, "__MCL_END__:")?; + writeln!(fd, " mov rax, 60")?; + writeln!(fd, " mov rdi, 0")?; + writeln!(fd, " syscall")?; + + writeln!(fd, "segment .data")?; + for (_, v) in prog.constants.iter() { + + if !self.used_consts.contains(&v.get_ident_escaped()) { + continue; + } + + match Box::leak(v.value.clone()) { + AstNode::Int(_, val) => { + writeln!(fd, " c_{}: dq {}", v.get_ident_escaped(), val)?; + } + AstNode::Str(_, val) | + AstNode::CStr(_, val) => { + let s_chars = val.chars().map(|c| (c as u32).to_string()).collect::>(); + let s_list = s_chars.join(","); + writeln!(fd, " c_{}: db {} ; {}", v.get_ident_escaped(), s_list, val.escape_debug())?; + } + AstNode::Char(_, val) => { + writeln!(fd, " c_{}: db {} ; '{}'", v.get_ident_escaped(), *val as u8, val)?; + } + c => panic!("{c:?}") + }; + } + + for (i, s) in self.strings.iter().enumerate() { + let s_chars = s.chars().map(|c| (c as u32).to_string()).collect::>(); + let s_list = s_chars.join(","); + writeln!(fd, " str_{i}: db {} ; STRDEF({})", s_list, s.escape_debug())?; + } + writeln!(fd, "segment .bss")?; + writeln!(fd, " ret_stack: resq 256")?; + + for (_, v) in &prog.memories { + match &v.size { + MemSize::Size(s) => { + writeln!(fd, " m_{}: resb {}", v.get_ident_escaped(), s)?; + }, + MemSize::Type(tt) => { + writeln!(fd, " m_{}: resb {} ; {:?}", v.get_ident_escaped(), tt.get_size(), tt)?; + }, + } + } + + + Ok(()) + } + + + fn compile(&mut self, asm_fp: &Path, obj_fp: &Path) -> anyhow::Result<()> { + run_cmd("nasm", vec![ + String::from("-felf64"), + String::from("-o"), + obj_fp.to_string_lossy().to_string(), + asm_fp.to_string_lossy().to_string() + ]) + } + + fn link(&mut self, obj_files: Vec, bin_fp: &Path) -> anyhow::Result<()> { + let mut args = vec![ + String::from("-o"), + bin_fp.to_string_lossy().to_string(), + ]; + + for f in obj_files { + args.push(f.to_string_lossy().to_string()) + } + + run_cmd("ld", args) + } + + fn needed_dependencies(&mut self) -> Vec<&str> { + vec![ + "nasm", + "ld" + ] + } +} \ No newline at end of file diff --git a/src/compiler/x86_64_linux_nasm/utils.rs b/src/compiler/x86_64_linux_nasm/utils.rs new file mode 100644 index 0000000..82a0895 --- /dev/null +++ b/src/compiler/x86_64_linux_nasm/utils.rs @@ -0,0 +1,37 @@ + + +pub const DBG_PRINT: &'static str = " +_dbg_print: + mov r9, -3689348814741910323 + sub rsp, 40 + mov BYTE [rsp+31], 10 + lea rcx, [rsp+30] +.L2: + mov rax, rdi + lea r8, [rsp+32] + mul r9 + mov rax, rdi + sub r8, rcx + shr rdx, 3 + lea rsi, [rdx+rdx*4] + add rsi, rsi + sub rax, rsi + add eax, 48 + mov BYTE [rcx], al + mov rax, rdi + mov rdi, rdx + mov rdx, rcx + sub rcx, 1 + cmp rax, 9 + ja .L2 + lea rax, [rsp+32] + mov edi, 1 + sub rdx, rax + xor eax, eax + lea rsi, [rsp+32+rdx] + mov rdx, r8 + mov rax, 1 + syscall + add rsp, 40 + ret +"; \ No newline at end of file diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index 214c4be..0000000 --- a/src/config.rs +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Prints out extra information - */ -pub const DEV_MODE: bool = false; - -pub const DEFAULT_OUT_FILE: &str = "a.out"; -pub const DEFAULT_INCLUDES: [&str;1] = [ - "./include", - // "~/.mclang/include", -]; - - -/** - * Interpreting configs - * `MEM_SZ` is the buffer size for memory - * `STRING_SZ` is the buffer size for strings - * if you have buffer overflow consider increasing these - */ -pub const MEM_SZ: usize = 640 * 1000; // 4kb -pub const STRING_SZ: usize = 640 * 1000; // 4kb - - -/** - * Experimental options - */ -pub const ENABLE_EXPORTED_FUNCTIONS: bool = false; \ No newline at end of file diff --git a/src/constants.rs b/src/constants.rs deleted file mode 100644 index 9027aa6..0000000 --- a/src/constants.rs +++ /dev/null @@ -1,277 +0,0 @@ - - - -#[derive(Debug, Clone, PartialEq)] -pub enum InstructionType { - - // stack - PushInt, - PushStr, - Drop, - Print, - Dup, - Rot, // a b c => b c a - Over, // a b => a b a - Swap, // a b => b a - - // math - Minus, - Plus, - Equals, - Gt, - Lt, - Ge, - Le, - NotEquals, - Band, // & - Bor, // | - Shr, // >> - Shl, // << - DivMod, // / - Mul, - - - // mem - Load8, - Store8, - Load32, - Store32, - Load64, - Store64, - - // syscalls - Syscall0, - Syscall1, - Syscall2, - Syscall3, - Syscall4, - Syscall5, - Syscall6, - - CastBool, - CastPtr, - CastInt, - CastVoid, - - // typing - TypeBool, - TypePtr, - TypeInt, - TypeVoid, - // TypeStr, - TypeAny, - Returns, - With, - - FnCall, - MemUse, - ConstUse, - - Return, - None // Used for macros and any other non built in word definitions - -} -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum KeywordType { - If, - Else, - End, - While, - Do, - Include, - Memory, - Constant, - ConstantDef, - Function, - FunctionDef, - FunctionDefExported, - FunctionThen, - FunctionDone, - Inline, - Export -} - -#[derive(Debug, Clone, PartialEq)] -pub enum OpType { - Keyword(KeywordType), - Instruction(InstructionType) -} - -#[derive(Debug, Clone)] -pub struct Operator{ - pub typ: OpType, - pub tok_typ: TokenType, - pub value: usize, - pub text: String, //? only used for OpType::PushStr - pub addr: Option, //? only used for OpType::PushStr - pub jmp: usize, - pub loc: Loc, - pub types: (usize, usize) -} - -impl Operator { - pub fn new(typ: OpType, tok_typ: TokenType, value: usize, text: String, file: String, row: usize, col: usize) -> Self { - Self { - typ, - value, - jmp: 0, - addr: None, - text, - loc: (file, row, col), - tok_typ, - types: (0, 0) - } - } - pub fn set_addr(&mut self, addr: usize) -> Self { - self.addr = Some(addr); - (*self).clone() - } - - // pub fn set_types(&mut self, args: usize, rets: usize) -> Self { - // self.types = (args, rets); - // (*self).clone() - // } - -} - -impl OpType { - pub fn human(&self) -> String { - match (*self).clone() { - OpType::Instruction(instruction) => { - match instruction { - - InstructionType::PushInt => "Number", - InstructionType::PushStr => "String", - InstructionType::Print => "_dbg_print", - InstructionType::Dup => "dup", - InstructionType::Drop => "drop", - InstructionType::Rot => "rot", - InstructionType::Over => "over", - InstructionType::Swap => "swap", - InstructionType::Plus => "+", - InstructionType::Minus => "-", - InstructionType::Equals => "=", - InstructionType::Gt => ">", - InstructionType::Lt => "<", - InstructionType::NotEquals => "!=", - InstructionType::Le => "<=", - InstructionType::Ge => ">=", - InstructionType::Band => "band", - InstructionType::Bor => "bor", - InstructionType::Shr => "shr", - InstructionType::Shl => "shl", - InstructionType::DivMod => "divmod", - InstructionType::Mul => "*", - InstructionType::Load8 => "load8", - InstructionType::Store8 => "store8", - InstructionType::Load32 => "load32", - InstructionType::Store32 => "store32", - InstructionType::Load64 => "load64", - InstructionType::Store64 => "store64", - InstructionType::Syscall0 => "syscall0", - InstructionType::Syscall1 => "syscall1", - InstructionType::Syscall2 => "syscall2", - InstructionType::Syscall3 => "syscall3", - InstructionType::Syscall4 => "syscall4", - InstructionType::Syscall5 => "syscall5", - InstructionType::Syscall6 => "syscall6", - InstructionType::CastBool => "cast(bool", - InstructionType::CastPtr => "cast(ptr)", - InstructionType::CastInt => "cast(int)", - InstructionType::CastVoid => "cast(void)", - InstructionType::None => "None", - InstructionType::MemUse => "Memory use (internal)", - InstructionType::FnCall => "Function Call (Internal)", - InstructionType::ConstUse => "Constant Use (Internal)", - InstructionType::Return => "return", - InstructionType::TypeBool => "bool", - InstructionType::TypePtr => "ptr", - InstructionType::TypeInt => "int", - InstructionType::TypeVoid => "void", - InstructionType::Returns => "returns", - InstructionType::With => "with", - InstructionType::TypeAny => "any", - } - } - OpType::Keyword(keyword) => { - match keyword { - KeywordType::If => "if", - KeywordType::Else => "else", - KeywordType::End => "end", - KeywordType::While => "while", - KeywordType::Do => "do", - KeywordType::Include => "include", - KeywordType::Memory => "memory", - KeywordType::Function => "fn", - KeywordType::Constant => "const", - KeywordType::FunctionThen => "then", - KeywordType::FunctionDone => "done", - KeywordType::ConstantDef => "constant Definition (internal)", - KeywordType::FunctionDef => "function definition (internal)", - KeywordType::FunctionDefExported => "extern function definition (internal)", - KeywordType::Inline => "inline", - KeywordType::Export => "export", - } - } - - }.to_string() - } -} - -#[derive(Debug, Clone)] -pub struct Token { - pub file: String, - pub line: usize, - pub col: usize, - pub text: String, - pub typ: TokenType, - pub value: Option, //* only used for Memories - pub addr: Option, //* only used for Memories - pub op_typ: OpType //* only used for Memories -} - -#[derive(Debug, Clone, PartialEq, Copy)] -pub enum TokenType { - Word, - Int, - String, - Char -} - -impl Token { - pub fn loc(&self) -> Loc { - ( - self.file.clone(), - self.line, - self.col - ) - } -} - -impl TokenType { - pub fn human(self) -> String { - match self { - TokenType::Word => "Word", - TokenType::Int => "Int", - TokenType::String => "String", - TokenType::Char => "Char" - }.to_string() - } -} - -pub type Loc = (String, usize, usize); - -#[derive(Debug, PartialEq, Clone)] -pub enum Types { - Bool, - Ptr, - Int, - Void, - Any - // U8, - // U16, - // U32, - // U64, - // todo: add signed numbers since we dont have them yet lol -} - diff --git a/src/errors/mod.rs b/src/errors/mod.rs deleted file mode 100644 index d6e14c3..0000000 --- a/src/errors/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::{error, help, code_block}; - - - -pub fn missing_main_fn() { - error!("Main function not found, please create one lol"); - help!("Heres a basic main function with code that prints hello world:\n{}", - code_block!( - concat!( - "include \"std.mcl\"\n", - "\n", - "fn main with void retuns void then\n", - " \"Hello world!\\n\" puts\n", - "done\n" - ) - ) - ); -} \ No newline at end of file diff --git a/src/interpret/linux_x86_64/mod.rs b/src/interpret/linux_x86_64/mod.rs deleted file mode 100644 index 62c686e..0000000 --- a/src/interpret/linux_x86_64/mod.rs +++ /dev/null @@ -1,425 +0,0 @@ -use std::collections::HashMap; - -use crate::{constants::{OpType, Loc, InstructionType, KeywordType, Operator}, lerror, error}; -// use crate::util::logger; -use color_eyre::Result; -use eyre::eyre; - -use super::{Memory, Function, Constant}; -mod syscalls; - -fn stack_pop(stack: &mut Vec, pos: &Loc) -> Result { - if let Some(i) = stack.pop() { Ok(i) } else { - lerror!(&pos.clone(), "Stack underflow"); - Err(eyre!("Stack underflow")) - } -} - -pub fn run(ops: &[crate::constants::Operator]) -> Result{ - let mut stack: Vec = Vec::new(); - let mut mem: Vec = vec![0; crate::MEM_SZ + crate::STRING_SZ]; - let mut string_idx = 0; - - let prerunned = pre_run(ops); - let functions = prerunned.functions; - let constants = prerunned.constants; - let memories = prerunned.memories; - - let mut ret_stack: Vec = Vec::new(); - - // for token in &tokens { - // println!("{{typ: \"{:?}\", val: {}, jmp: {}}}", token.typ, token.value, token.jmp); - // } - - // jump to main func - let mut ip = if let Some(i) = functions.get("main") {i.id} else { - crate::errors::missing_main_fn(); - return Err(eyre!("")); - }; - - while ip < ops.len() { - let op = &ops[ip]; - let pos = op.loc.clone(); - match op.typ.clone() { - OpType::Instruction(instruction) => { - match instruction { - InstructionType::PushInt => { - stack.push(op.value); - ip += 1; - }, - InstructionType::PushStr => { - if op.addr.is_none() { - stack.push(op.text.len()); // string len - stack.push(string_idx + crate::MEM_SZ); - - for c in op.text.bytes() { - mem[crate::MEM_SZ + string_idx] = u64::from(c); - string_idx += 1; - } - } else { - stack.push(op.text.len()); - if let Some(addr) = op.addr { - stack.push(addr); - } - } - - - ip += 1; - }, - InstructionType::Drop => { - stack.pop(); - ip += 1; - }, - InstructionType::Dup => { - let a = stack_pop(&mut stack, &pos)?; - stack.push(a); - stack.push(a); - ip += 1; - }, - - InstructionType::Rot => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - let c = stack_pop(&mut stack, &pos)?; - stack.push(b); - stack.push(a); - stack.push(c); - ip += 1; - } - InstructionType::Swap => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(a); - stack.push(b); - ip += 1; - } - InstructionType::Over => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b); - stack.push(a); - stack.push(b); - ip += 1; - } - - InstructionType::Print => { - let a = stack_pop(&mut stack, &pos)?; - println!("{a}"); - // let _ = io::stdout().flush(); - ip += 1; - }, - #[allow(clippy::cast_possible_truncation)] - InstructionType::Load8 | - InstructionType::Load32 | - InstructionType::Load64 => { - let a = stack_pop(&mut stack, &pos)?; - if a > crate::MEM_SZ { - lerror!(&op.loc, "Invalid memory address {a}"); - return Ok(1); - } - let byte = mem[a]; - stack.push(byte as usize); - ip += 1; - } - #[allow(clippy::cast_possible_truncation)] - InstructionType::Store8 => { - let val = stack_pop(&mut stack, &pos)?; - let addr = stack_pop(&mut stack, &pos)?; - - if addr > crate::MEM_SZ { - lerror!(&op.loc, "Invalid memory address {addr}"); - return Ok(1); - } - - mem[addr] = u64::from(val as u8); - ip += 1; - } - #[allow(clippy::cast_possible_truncation)] - InstructionType::Store32 => { - let val = stack_pop(&mut stack, &pos)?; - let addr = stack_pop(&mut stack, &pos)?; - - if addr > crate::MEM_SZ { - lerror!(&op.loc, "Invalid memory address {addr}"); - return Ok(1); - } - - mem[addr] = u64::from(val as u32); - ip += 1; - } - - #[allow(clippy::cast_possible_truncation)] - InstructionType::Store64 => { - let val = stack_pop(&mut stack, &pos)?; - let addr = stack_pop(&mut stack, &pos)?; - - if addr > crate::MEM_SZ { - lerror!(&op.loc, "Invalid memory address {addr}"); - return Ok(1); - } - - mem[addr] = val as u64; - ip += 1; - } - - // math - InstructionType::Plus => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b + a); - ip += 1; - }, - InstructionType::Minus => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b - a); - ip += 1; - }, - InstructionType::Equals => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(usize::from(b == a)); - ip += 1; - }, - InstructionType::Gt => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(usize::from(b > a)); - ip += 1; - }, - InstructionType::Lt => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(usize::from(b < a)); - ip += 1; - }, - InstructionType::NotEquals => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(usize::from(b != a)); - ip += 1; - }, - InstructionType::Ge => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(usize::from(b >= a)); - ip += 1; - }, - InstructionType::Le => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(usize::from(b <= a)); - ip += 1; - }, - - InstructionType::Band => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(a & b); - ip += 1; - } - - InstructionType::Bor => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(a | b); - ip += 1; - } - - InstructionType::Shr => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b >> a); - ip += 1; - } - - InstructionType::Shl => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b << a); - ip += 1; - } - - InstructionType::DivMod => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b / a); - stack.push(b % a); - ip += 1; - } - InstructionType::Mul => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b * a); - ip += 1; - } - InstructionType::Syscall0 => { - todo!(); - // ti += 1; - }, - InstructionType::Syscall1 => { - todo!(); - // ti += 1; - }, - InstructionType::Syscall2 => { - todo!(); - // ti += 1; - }, - InstructionType::Syscall3 => { - let rax = stack_pop(&mut stack, &pos)?; - let rdi = stack_pop(&mut stack, &pos)?; - let rsi = stack_pop(&mut stack, &pos)?; - let rdx = stack_pop(&mut stack, &pos)?; - // println!("yes"); - let ret = match rax { - 1 => syscalls::sys_write(rax, rdi, rsi, rdx, &mem), - 0 => 0, //? temp, so clippy doesnt complain - _ => { - error!("Syscall(3) #{} is not implemented", rax); - return Err(eyre!("Syscall not implemented")); - } - }; - stack.push(ret); - // println!("{}", stack.len()); - ip += 1; - }, - InstructionType::Syscall4 => { - todo!(); - // ti += 1; - }, - InstructionType::Syscall5 => { - todo!(); - // ti += 1; - }, - InstructionType::Syscall6 => { - todo!(); - // ti += 1; - }, - InstructionType::MemUse => { - - let m = memories.get(&op.addr.unwrap()).unwrap(); - stack.push(m.id); - ip += 1; - }, - InstructionType::FnCall => { - ret_stack.push(ip); - let f = functions.get(&op.text).unwrap(); - ip = f.id; - } - InstructionType::Return => { - ip = ret_stack.pop().unwrap(); - ip += 1; - } - InstructionType::ConstUse => { - let a = constants.get(&op.text).unwrap(); - - if let Some(i) = a.value_i { - stack.push(i); - } else if let Some(_s) = a.value_s.clone() { - unimplemented!(); - } - ip += 1; - }, - InstructionType::CastBool | - InstructionType::CastPtr | - InstructionType::CastInt | - InstructionType::CastVoid | - InstructionType::TypeBool | - InstructionType::TypePtr | - InstructionType::TypeInt | - InstructionType::TypeVoid | - InstructionType::TypeAny | - InstructionType::Returns | - InstructionType::With => ip += 1, - InstructionType::None => unreachable!(), - } - - } - OpType::Keyword(k) => { - match k { - // blocks - KeywordType::If => { - let a = stack_pop(&mut stack, &pos)?; - if a == 0 { - // println!("If({ti}) => t: {:?} j: {}", tokens[token.jmp as usize].typ, token.jmp); - ip = op.jmp; - } else { - ip += 1; - } - }, - KeywordType::Else | KeywordType::End => { - ip = op.jmp; - } - KeywordType::Do => { - let a = stack.pop().unwrap(); - if a == 0 { - ip = op.jmp; - } else { - ip += 1; - } - } - KeywordType::While | //* exept this one, this one should just skip over - KeywordType::Memory | - KeywordType::FunctionDef | - KeywordType::FunctionDefExported | - KeywordType::ConstantDef => { - //? Disabled since we now pre run the whole program - // constants.insert(op.text.clone(), Constant { loc: op.loc.clone(), name: op.text.clone(), value_i: Some(op.value), value_s: None, used: false }); - ip += 1; - }, - KeywordType::FunctionDone => { - if let Some(i) = ret_stack.pop() { - ip = i + 1; - } else { - break; - } - }, - - KeywordType::FunctionThen => ip += 1, - KeywordType::Constant | - KeywordType::Function | - KeywordType::Inline | - KeywordType::Export | - KeywordType::Include => unreachable!(), - } - } - - } - } - - - Ok(0) -} - -pub struct Defineds { - pub memories: HashMap, - pub functions: HashMap, - pub constants: HashMap -} - -pub fn pre_run(ops: &[Operator]) -> Defineds { - let mut defineds = Defineds{ - memories: HashMap::new(), - functions: HashMap::new(), - constants: HashMap::new(), - }; - for (ip, op) in ops.iter().enumerate() { - - match op.typ { - OpType::Keyword(KeywordType::Memory) => { - defineds.memories.insert(op.addr.unwrap(), Memory { size: op.value, loc: op.loc.clone(), id: op.addr.unwrap() }); - }, - OpType::Keyword(KeywordType::FunctionDefExported) => { - - } - OpType::Keyword(KeywordType::FunctionDef) => { - defineds.functions.insert(op.text.clone(), Function { loc: op.loc.clone(), name: op.text.clone(), id: ip }); - }, - OpType::Keyword(KeywordType::ConstantDef) => { - defineds.constants.insert(op.text.clone(), Constant { loc: op.loc.clone(), name: op.text.clone(), value_i: Some(op.value), value_s: None, used: false }); - }, - _ => () - } - } - defineds -} \ No newline at end of file diff --git a/src/interpret/linux_x86_64/syscalls.rs b/src/interpret/linux_x86_64/syscalls.rs deleted file mode 100644 index 0b9e1b2..0000000 --- a/src/interpret/linux_x86_64/syscalls.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[allow(clippy::cast_possible_truncation)] -pub fn sys_write(sys_n: usize, fd: usize, buff: usize, count: usize, mem: &Vec ) -> usize { - let mem = (*mem).clone(); - // println!("{:?}", &mem[buff..(buff + count)]); - // return 0 ; - let s = &mem[buff..(buff + count)].iter().map(|i| { - char::from_u32(u32::from(*i as u8)).unwrap_or('_').to_string() - }).collect::(); - - match fd { - 1 => { - print!("{s}"); - }, - 2 => { - eprint!("{s}"); - }, - _ => panic!("Unknown file {fd}") - }; - let _ = std::io::Write::flush(&mut std::io::stdout()); - let _ = std::io::Write::flush(&mut std::io::stderr()); - sys_n -} \ No newline at end of file diff --git a/src/interpret/mod.rs b/src/interpret/mod.rs deleted file mode 100644 index 1385744..0000000 --- a/src/interpret/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::constants::Loc; - -pub mod linux_x86_64; - -#[derive(Debug, Clone)] -pub struct Constant { - pub loc: Loc, - pub name: String, - pub value_i: Option, - pub value_s: Option, - pub used: bool - // extern: bool -} - -#[derive(Debug, Clone)] -pub struct Memory { - pub size: usize, - pub loc: Loc, - pub id: usize -} - -#[derive(Debug, Clone)] -pub struct Function { - pub loc: Loc, - pub name: String, - pub id: usize -} \ No newline at end of file diff --git a/src/lexer.rs b/src/lexer.rs deleted file mode 100644 index 4943395..0000000 --- a/src/lexer.rs +++ /dev/null @@ -1,126 +0,0 @@ - -use crate::{constants::{Token, TokenType}, Args}; - -fn lex_word(s: String, tok_type: TokenType) -> (TokenType, String) { - match s { - s if s.parse::().is_ok() && tok_type == TokenType::Word => { // negative numbers not yet implemented - (TokenType::Int, s) - }, - s if tok_type == TokenType::Word => { - (TokenType::Word, s) - }, - s if tok_type == TokenType::String => { - (TokenType::String, s) - } - s if tok_type == TokenType::Char => { - (TokenType::Char, s) - } - _ => unreachable!() - } -} - -pub fn find_col(text: &str, mut col: usize, predicate: F) -> usize where F: Fn(char, char) -> bool { - let mut last = '\0'; - while col < text.len() && !predicate(text.chars().nth(col).unwrap(), last) { - last = text.chars().nth(col).unwrap(); - col += 1; - } - - col -} - - -// TODO: Implement multiline strings -fn lex_line(text: &str) -> Vec<(usize, String, TokenType)> { - let mut tokens: Vec<(usize, String, TokenType)> = Vec::new(); - - let mut col = find_col(text, 0, |x, _| !x.is_whitespace()); - let mut col_end: usize = 0; - while col_end < text.to_string().len() { - if (text.len() - col) < 1 { - return tokens; - } - if &text[col..=col] == "\"" { - col_end = find_col(text, col + 1, |x, x2| x == '"' && x2 != '\\'); - let t = &text[(col + 1)..col_end]; - let t = t.replace("\\n", "\n") - .replace("\\t", "\t") - .replace("\\r", "\r") - .replace("\\\'", "\'") - .replace("\\\"", "\"") - .replace("\\0", "\0"); - if !t.is_empty() { - tokens.push((col, t.to_string(), TokenType::String)); - } - col = find_col(text, col_end + 1, |x, _| !x.is_whitespace()); - - } else if &text[col..=col] == "'"{ - col_end = find_col(text, col + 1, |x, x2| x == '\'' && x2 != '\\'); - let t = &text[(col + 1)..col_end]; - let t = t.replace("\\n", "\n") - .replace("\\t", "\t") - .replace("\\r", "\r") - .replace("\\\'", "\'") - .replace("\\\"", "\"") - .replace("\\0", "\0"); - - - if !t.is_empty() { - tokens.push((col, t.to_string(), TokenType::Char)); - } - col = find_col(text, col_end + 1, |x, _| !x.is_whitespace()); - - } else { - - col_end = find_col(text, col, |x, _| x.is_whitespace()); - let t = &text[col..col_end]; - - if t == "//" { - return tokens; - } - - if !t.is_empty() { - tokens.push((col, t.to_string(), TokenType::Word)); - } - col = find_col(text, col_end, |x, _| !x.is_whitespace()); - } - } - tokens -} - -pub fn lex(code: &str, file: &str, _args: &Args) -> Vec { - let lines: Vec<(usize, &str)> = code - .split(['\n', '\r']) - .enumerate() - .collect(); - - let lines: Vec<(usize, String)> = lines.iter().map(|i| (i.0, i.1.to_string())).collect(); - - let mut tokens: Vec = Vec::new(); - - for (row, line) in lines { - let lt = lex_line(&line); - for (col, tok, tok_type) in lt { - let (tok_type, tok) = lex_word(tok, tok_type); - let t = Token{ - file: file.to_string(), - line: row + 1, - col, - text: tok, - typ: tok_type, - value: None, - addr: None, - op_typ: crate::constants::OpType::Instruction(crate::constants::InstructionType::None) - }; - tokens.push(t); - } - } - // println!("{}", tokens.len()); - - // for token in tokens.clone() { - // println!("tok: {:?}", token.text); - // } - - - tokens -} \ No newline at end of file diff --git a/src/lexer/mod.rs b/src/lexer/mod.rs new file mode 100644 index 0000000..3124647 --- /dev/null +++ b/src/lexer/mod.rs @@ -0,0 +1,389 @@ +use std::path::Path; +use anyhow::bail; + +use crate::{error, types::{common::Loc, token::{InstructionType, KeywordType, Token, TokenType, TypeType}}}; + + + +pub struct Lexer { + pub loc: Loc, + pub tokens: Vec +} + +impl Lexer { + pub fn new() -> Self { + Self { + loc: Default::default(), + tokens: Default::default(), + } + } + + + pub fn lex(&mut self, file: &Path) -> anyhow::Result<&mut Self> { + self.reset(file); + + let chars = match std::fs::read_to_string(file) { + Ok(c) => c, + Err(e) => { + error!("Failed to open file {file:?} : {e}"); + bail!(""); + } + }.chars().collect::>(); + + + let mut idx = 0; + let mut buf = String::new(); + let mut is_searching = false; + + if let Err(_) = self.go_to_first_char(&chars, &mut idx) { + return Ok(self); + } + + let mut start_loc = self.loc.clone(); + while idx < chars.len() { + + match chars[idx] { + + 'c' if chars.get(idx + 1) == Some(&'"') => { + start_loc = self.loc.clone(); + is_searching = true; + idx += 2; // skip c and " + self.loc.col += 2; + + if !buf.is_empty() { + debug!({loc => self.loc() }, "buffer was not empty, intresting"); + } + + loop { + if chars[idx] == '"' && chars[idx-1] != '\\' { + break; + } + buf.push(chars[idx]); + if chars[idx] == '\n' { + self.loc.inc_line() + } + self.loc.inc_col(); + idx += 1; + } + + buf.push('\0'); + let str = self.unescape(&&buf); + self.loc.inc_col(); + self.tokens.push(Token::new(TokenType::Instruction(InstructionType::PushCStr(str)), self.loc(), buf.clone())); + buf.clear(); + } + + '"' => { + start_loc = self.loc.clone(); + is_searching = true; + idx += 1; // skip " + self.loc.col += 1; + + if !buf.is_empty() { + debug!({loc => self.loc() }, "buffer was not empty, intresting ({buf:?})"); + } + + // while chars.get(idx+1) != Some(&'"') && chars[idx] != '\\' && chars.get(idx+1).is_some() { + loop { + if chars[idx] == '"' && chars[idx-1] != '\\' { + break; + } + buf.push(chars[idx]); + if chars[idx] == '\n' { + self.loc.inc_line() + } + self.loc.inc_col(); + idx += 1; + } + + + let str = self.unescape(&buf); + self.loc.inc_col(); + self.tokens.push(Token::new(TokenType::Instruction(InstructionType::PushStr(str)), start_loc.clone(), buf.clone())); + buf.clear(); + } + + '\'' => { + start_loc = self.loc.clone(); + is_searching = true; + idx += 1; // skip ' + self.loc.col += 1; + + if !buf.is_empty() { + debug!({loc => self.loc() }, "buffer was not empty, intresting ({buf})"); + } + + loop { + if chars[idx] == '"' && chars[idx-1] != '\\' { + break; + } + buf.push(chars[idx]); + if chars[idx] == '\n' { + self.loc.inc_line() + } + self.loc.inc_col(); + idx += 1; + } + + let str = self.unescape(&&&buf); + if str.len() > 1 { + error!({loc => self.loc()}, "Chars can only have 1 char"); + bail!("") + } + + self.loc.inc_col(); + self.tokens.push(Token::new(TokenType::Instruction(InstructionType::PushStr(str)), self.loc(), buf.clone())); + buf.clear(); + } + ':' if chars.get(idx + 1) == Some(&':') => { + let mut p_buf = vec![buf.clone()]; + buf.clear(); + idx += 2; // skip :: + self.loc.col += 2; + + while idx < chars.len() { + match chars[idx] { + ' ' | '\n' | '\r' => { + if !p_buf.is_empty() { + p_buf.push(buf.clone()); + } + + self.tokens.push(Token::new(TokenType::Instruction(InstructionType::StructPath(p_buf.clone())), start_loc.clone(), p_buf.clone().join("::"))); + buf.clear(); + break; + } + c @ ('\'' | '"') => { + error!({loc => self.loc()}, "Invalid char in struct path token, expected /a-z|A-Z|0-9|_|-/ got {c}"); + bail!("") + } + + ':' if chars.get(idx + 1) == Some(&':') => { + if buf.is_empty() { + error!({loc => self.loc()}, "Invalid char in struct path token, expected /a-z|A-Z|0-9|_|-/ got '.'"); + bail!("") + } + idx += 2; // skip :: + self.loc.col += 2; + p_buf.push(buf.clone()); + buf.clear(); + } + + c => { + buf.push(c); + idx += 1; + self.loc.inc_col(); + } + } + } + } + + '.' if !buf.is_empty() => { + let mut p_buf = vec![buf.clone()]; + buf.clear(); + idx += 1; // skip . + self.loc.inc_col(); + + while idx < chars.len() { + match chars[idx] { + ' ' | '\n' | '\r' => { + if !p_buf.is_empty() { + p_buf.push(buf.clone()); + } + self.tokens.push(Token::new(TokenType::Instruction(InstructionType::StructItem(p_buf.clone())), start_loc.clone(), p_buf.clone().join("."))); + buf.clear(); + break; + } + c @ ('\'' | '"') => { + error!({loc => self.loc()}, "Invalid char in struct access token, expected /a-z|A-Z|0-9|_|-/ got {c}"); + bail!("") + } + + '.' => { + if buf.is_empty() { + error!({loc => self.loc()}, "Invalid char in struct access token, expected /a-z|A-Z|0-9|_|-/ got '.'"); + bail!("") + } + idx += 1; // skip . + self.loc.col += 1; + p_buf.push(buf.clone()); + buf.clear(); + } + + c => { + buf.push(c); + idx += 1; + self.loc.inc_col(); + } + } + } + } + + ch @ (' ' | '\n' | '\r') => { + if ch == '\n' { + self.loc.inc_line(); + } else { + self.loc.inc_col(); + } + if !buf.is_empty() { + //TODO: Implement signed ints + if let Ok(int) = parse_int::parse::(&buf) { + self.tokens.push(Token::new(TokenType::Instruction(InstructionType::PushInt(int)), start_loc.clone(), buf.clone())); + } else { + let token_type = self.match_token_type(&buf); + self.tokens.push(Token::new(token_type, start_loc.clone(), buf.clone())); + } + + buf.clear(); + is_searching = true; + } + } + + '/' if chars.get(idx + 1) == Some(&'/') => { + let mut c = chars.get(idx); + while c.is_some() && c != Some(&'\n') { + self.loc.inc_col(); + idx += 1; + c = chars.get(idx); + } + self.loc.inc_line(); + } + + + ch => { + if is_searching { + is_searching = false; + start_loc = self.loc.clone(); + } + + buf.push(ch); + self.loc.inc_col(); + } + + } + idx += 1; + } + //? Add last token + //TODO: Implement signed ints + if !buf.is_empty() { + if let Ok(int) = parse_int::parse::(&buf) { + self.tokens.push(Token::new(TokenType::Instruction(InstructionType::PushInt(int)), start_loc.clone(), buf.clone())); + } else { + let token_type = self.match_token_type(&buf); + self.tokens.push(Token::new(token_type, start_loc.clone(), buf.clone())); + } + } + + // for t in &self.tokens { + // debug!({loc => t.loc.clone()}, "token: {:?}", t.typ); + // } + + Ok(self) + } + + fn go_to_first_char(&mut self, chars: &Vec, idx: &mut usize) -> anyhow::Result<()> { + loop { + if let Some(c) = chars.get(*idx) { + match c { + ' ' | '\r' => self.loc.inc_col(), + '\n' => self.loc.inc_line(), + _ => break, + } + *idx += 1; + } else { + warn!("Empty program"); + bail!("") + } + } + + + Ok(()) + } + + fn match_token_type(&self, s: &str) -> TokenType { + match s { + "if" => TokenType::Keyword(KeywordType::If), + "else" => TokenType::Keyword(KeywordType::Else), + "end" => TokenType::Keyword(KeywordType::End), + "while" => TokenType::Keyword(KeywordType::While), + "do" => TokenType::Keyword(KeywordType::Do), + "include" => TokenType::Keyword(KeywordType::Include), + "memory" => TokenType::Keyword(KeywordType::Memory), + "const" => TokenType::Keyword(KeywordType::Constant), + "fn" => TokenType::Keyword(KeywordType::Function), + "then" => TokenType::Keyword(KeywordType::Then), + "done" => TokenType::Keyword(KeywordType::Done), + "typedef" => TokenType::Keyword(KeywordType::TypeDef), + "structdef" => TokenType::Keyword(KeywordType::StructDef), + "inline" => TokenType::Keyword(KeywordType::Inline), + "export" => TokenType::Keyword(KeywordType::Export), + "extern" => TokenType::Keyword(KeywordType::Extern), + "returns" => TokenType::Keyword(KeywordType::Returns), + "with" => TokenType::Keyword(KeywordType::With), + "drop" => TokenType::Instruction(InstructionType::Drop), + "_dbg_print" => TokenType::Instruction(InstructionType::Print), + "dup" => TokenType::Instruction(InstructionType::Dup), + "rot" => TokenType::Instruction(InstructionType::Rot), + "over" => TokenType::Instruction(InstructionType::Over), + "swap" => TokenType::Instruction(InstructionType::Swap), + "sub" => TokenType::Instruction(InstructionType::Minus), + "add" => TokenType::Instruction(InstructionType::Plus), + "eq" => TokenType::Instruction(InstructionType::Equals), + "gt" => TokenType::Instruction(InstructionType::Gt), + "lt" => TokenType::Instruction(InstructionType::Lt), + "ge" => TokenType::Instruction(InstructionType::Ge), + "le" => TokenType::Instruction(InstructionType::Le), + "neq" => TokenType::Instruction(InstructionType::NotEquals), + "band" => TokenType::Instruction(InstructionType::Band), + "bor" => TokenType::Instruction(InstructionType::Bor), + "shr" => TokenType::Instruction(InstructionType::Shr), + "shl" => TokenType::Instruction(InstructionType::Shl), + "divmod" => TokenType::Instruction(InstructionType::DivMod), + "mul" => TokenType::Instruction(InstructionType::Mul), + "read8" => TokenType::Instruction(InstructionType::Read8), + "write8" => TokenType::Instruction(InstructionType::Write8), + "read32" => TokenType::Instruction(InstructionType::Read32), + "write32" => TokenType::Instruction(InstructionType::Write32), + "read64" => TokenType::Instruction(InstructionType::Read64), + "write64" => TokenType::Instruction(InstructionType::Write64), + "syscall0" => TokenType::Instruction(InstructionType::Syscall0), + "syscall1" => TokenType::Instruction(InstructionType::Syscall1), + "syscall2" => TokenType::Instruction(InstructionType::Syscall2), + "syscall3" => TokenType::Instruction(InstructionType::Syscall3), + "syscall4" => TokenType::Instruction(InstructionType::Syscall4), + "syscall5" => TokenType::Instruction(InstructionType::Syscall5), + "syscall6" => TokenType::Instruction(InstructionType::Syscall6), + "(bool)" => TokenType::Instruction(InstructionType::CastBool), + "(ptr)" => TokenType::Instruction(InstructionType::CastPtr), + "(int)" => TokenType::Instruction(InstructionType::CastInt), + "(void)" => TokenType::Instruction(InstructionType::CastVoid), + "return" => TokenType::Instruction(InstructionType::Return), + "ptr" => TokenType::Type(TypeType::Ptr), + "u8" => TokenType::Type(TypeType::U8), + "u16" => TokenType::Type(TypeType::U16), + "u32" => TokenType::Type(TypeType::U32), + "u64" => TokenType::Type(TypeType::U64), + "void" => TokenType::Type(TypeType::Void), + "any" => TokenType::Type(TypeType::Any), + t => TokenType::Unknown(t.to_string()) + } + } + + pub fn reset(&mut self, file: &Path) -> &mut Self { + self.loc.file = file.to_string_lossy().to_string(); + self.loc.line = 1; + self.loc.col = 0; + self.tokens = Vec::new(); + self + } + + fn loc(&self) -> Loc { + self.loc.clone() + } + fn unescape(&self, s: &String) -> String { + //TODO: add more escapes + s + .replace("\\n", "\n") + .replace("\\0", "\0") + } + +} \ No newline at end of file diff --git a/src/logger/colors.rs b/src/logger/colors.rs new file mode 100644 index 0000000..5950972 --- /dev/null +++ b/src/logger/colors.rs @@ -0,0 +1,32 @@ +#![allow(dead_code)] +pub const RESET: &str = "\x1b[0m"; +pub const BOLD: &str = "\x1b[1m"; +pub const ITALIC: &str = "\x1b[3m"; +pub const UNDERLINE: &str = "\x1b[4m"; +pub const BLINK: &str = "\x1b[5m"; +pub const BLINK2: &str = "\x1b[6m"; +pub const SELECTED: &str = "\x1b[7m"; +pub const BLACK: &str = "\x1b[30m"; +pub const RED: &str = "\x1b[31m"; +pub const GREEN: &str = "\x1b[32m"; +pub const YELLOW: &str = "\x1b[33m"; +pub const BLUE: &str = "\x1b[34m"; +pub const MAGENTA: &str = "\x1b[35m"; +pub const BEIGE: &str = "\x1b[36m"; +pub const WHITE: &str = "\x1b[37m"; +pub const BLACKBG: &str = "\x1b[40m"; +pub const REDBG: &str = "\x1b[41m"; +pub const GREENBG: &str = "\x1b[42m"; +pub const YELLOWBG: &str = "\x1b[43m"; +pub const BLUEBG: &str = "\x1b[44m"; +pub const MAGENTABG: &str = "\x1b[45m"; +pub const BEIGEBG: &str = "\x1b[46m"; +pub const WHITEBG: &str = "\x1b[47m"; +pub const GREY: &str = "\x1b[90m"; +pub const RED2: &str = "\x1b[91m"; +pub const GREEN2: &str = "\x1b[92m"; +pub const YELLOW2: &str = "\x1b[93m"; +pub const BLUE2: &str = "\x1b[94m"; +pub const MAGENTA2: &str = "\x1b[95m"; +pub const BEIGE2: &str = "\x1b[96m"; +pub const WHITE2: &str = "\x1b[97m"; diff --git a/src/logger/macros.rs b/src/logger/macros.rs new file mode 100644 index 0000000..5b1056a --- /dev/null +++ b/src/logger/macros.rs @@ -0,0 +1,106 @@ + + +#[macro_export] +macro_rules! log { + ({$($k: expr => $v: expr),* $(,)? }, $lvl:expr, $($arg:tt),+) => { + crate::log_tagged!({$($k => $v,)*}, crate::logger::Level::Info, $($arg)+) + }; + (module: $module:expr, $lvl:expr, $($arg:tt)+) => { + unsafe { + crate::logger::LOGGER.log( + crate::logger::LogEvent { + level: $lvl, + module_path: $module.to_string(), + message: format!($($arg)+), + tags: std::collections::HashMap::new() + } + ) + } + }; + + + ($lvl:expr, $($arg:tt)+) => { + crate::log!(module: module_path!(), $lvl, $($arg)+) + }; +} + +#[macro_export] +macro_rules! log_tagged { + ({$($k: expr => $v: expr),* $(,)? }, $module:expr, $lvl:expr, $($arg:tt)+) => { + unsafe { + crate::logger::LOGGER.log( + crate::logger::LogEvent { + level: $lvl, + module_path: $module.to_string(), + message: format!($($arg)+), + tags: map_macro::hash_map!{$(stringify!($k).to_string() => Box::new($v) as Box,)*} + } + ) + } + }; +} + + +#[macro_export] +macro_rules! debug { + (module: $module:expr, $($arg:tt)+) => { + crate::log!(module: $module, crate::logger::Level::Debug, $($arg:tt)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, module_path!(), crate::logger::Level::Debug, $($arg)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, module: $module:expr, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, $module, crate::logger::Level::Debug, $($arg)+) + }; + ($($arg:tt)+) => { + crate::log!(crate::logger::Level::Debug, $($arg)+) + }; +} + +#[macro_export] +macro_rules! info { + (module: $module:expr, $($arg:tt)+) => { + crate::log!(module: $module, crate::logger::Level::Info, $($arg:tt)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, module_path!(), crate::logger::Level::Info, $($arg)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, module: $module:expr, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, $module, crate::logger::Level::Info, $($arg)+) + }; + ($($arg:tt)+) => { + crate::log!(crate::logger::Level::Info, $($arg)+) + }; +} + +#[macro_export] +macro_rules! warn { + (module: $module:expr, $($arg:tt)+) => { + crate::log!(module: $module, crate::logger::Level::Warn, $($arg:tt)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, module_path!(), crate::logger::Level::Warn, $($arg)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, module: $module:expr, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, $module, crate::logger::Level::Warn, $($arg)+) + }; + ($($arg:tt)+) => { + crate::log!(crate::logger::Level::Warn, $($arg)+) + }; +} + +#[macro_export] +macro_rules! error { + (module: $module:expr, $($arg:tt)+) => { + crate::log!(module: $module, crate::logger::Level::Error, $($arg:tt)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, module_path!(), crate::logger::Level::Error, $($arg)+) + }; + ({$($k: expr => $v: expr),* $(,)? }, module: $module:expr, $($arg:tt)+) => { + crate::log_tagged!({$($k => $v,)*}, $module, crate::logger::Level::Error, $($arg)+) + }; + ($($arg:tt)+) => { + crate::log!(crate::logger::Level::Error, $($arg)+) + }; +} diff --git a/src/logger/mod.rs b/src/logger/mod.rs new file mode 100644 index 0000000..4e96324 --- /dev/null +++ b/src/logger/mod.rs @@ -0,0 +1,83 @@ + +// use log::{Level, LevelFilter, Metadata, Record, SetLoggerError}; + +use std::ops::Deref; + +use crate::{cli::CliArgs, types::common::Loc}; + +mod types; +mod colors; +#[macro_use] +pub mod macros; +pub use types::{Level, LogEvent, LOGGER}; +use types::*; + + +pub struct Logger{ + pub level: i8 +} + + +impl Logger { + pub fn new(args: &CliArgs) -> Box { + Box::new(Self { + level: args.verbose + }) + } + + pub fn init(args: &CliArgs) -> anyhow::Result<()>{ + unsafe { + types::LOGGER = Box::leak( + Self::new(args) + ); + } + Ok(()) + } + + fn get_prefix(&self, level: Level) -> String { + use colors::{BOLD, RESET, RED, YELLOW, BLUE, GREEN, MAGENTA}; + match level { + Level::Error => format!("{BOLD}{RED}error{RESET}", ), + Level::Warn => format!("{BOLD}{YELLOW}warn{RESET}", ), + Level::Info => format!("{BOLD}{GREEN}info{RESET}", ), + Level::Debug => format!("{BOLD}{BLUE}debug{RESET}", ), + Level::Trace => format!("{BOLD}{MAGENTA}trace{RESET}", ), + } + } +} + +impl Log for Logger { + fn enabled(&self, level: Level) -> bool { + match level { + Level::Error if self.level >= 0 => true, + Level::Warn | + Level::Info if self.level >= 1 => true, + Level::Debug if self.level >= 2 => true, + Level::Trace if self.level >= 3 => true, + _ => false + } + } + + fn log(&self, event: LogEvent) { + + if self.enabled(event.level) { + let modpath = if event.level > Level::Info { + format!(" [{}]", event.module_path) + } else { + String::new() + }; + + if let Some(loc) = event.tags.get("loc") { + let loc: String = (*loc.deref()).downcast_ref::() + .map_or(String::from("INVALID"), |l| l.to_string()); + println!("{} {}{modpath}: {}", loc, self.get_prefix(event.level), event.message); + } else { + println!("{}{modpath}: {}", self.get_prefix(event.level), event.message); + } + } + } + + fn level(&self) -> i8 { + self.level + } +} \ No newline at end of file diff --git a/src/logger/types.rs b/src/logger/types.rs new file mode 100644 index 0000000..36c59c2 --- /dev/null +++ b/src/logger/types.rs @@ -0,0 +1,40 @@ +use std::{any::Any, collections::HashMap, fmt::Debug }; + + +pub static mut LOGGER: &dyn Log = &NopLogger; + +struct NopLogger; + +#[allow(dead_code)] +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub enum Level { + Error = 1, + Warn, + Info, + Debug, + Trace, +} + +// pub trait Tag: Display + Debug + Any {} + + +pub struct LogEvent { + pub level: Level, + pub module_path: String, + pub message: String, + pub tags: HashMap> +} + + +impl Log for NopLogger { + fn enabled(&self, _: Level) -> bool {false} + fn level(&self) -> i8 {0} + fn log(&self, _: LogEvent) {} +} + + +pub trait Log { + fn enabled(&self, level: Level) -> bool; + fn log(&self, event: LogEvent); + fn level(&self) -> i8; +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9de7469..0761d80 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,141 +1,47 @@ -#![allow(clippy::wildcard_imports)] -#![allow(clippy::too_many_lines)] -mod constants; -mod interpret; -mod util; -mod compile; -mod parser; + +use std::collections::HashMap; + +#[macro_use] +mod logger; +mod cli; +mod types; mod lexer; -mod preprocessor; -mod typechecker; -mod precompiler; -mod config; -mod errors; -use config::*; -use std::{fs, collections::HashMap}; +pub mod parser; +mod compiler; -use clap::Parser; -use color_eyre::Result; -use eyre::eyre; +fn main() { + let cli_args = cli::CliArgs::parse_with_passthrough(); + logger::Logger::init(&cli_args).expect("Failed to init logger"); -#[derive(Parser, Debug, Clone)] -#[command(author, version, about, long_about = None)] -pub struct Args { - /// Input source file - #[arg(long, short)] - in_file: String, + let mut prog_map = HashMap::new(); + for file in &cli_args.input { + let mut lexer = lexer::Lexer::new(); - /// Output compiled file - #[arg(long, short, default_value_t=String::from(DEFAULT_OUT_FILE))] - out_file: String, - - /// Compile - #[arg(long, short)] - compile: bool, - - /// Interpert - #[arg(long, short='s')] - interpret: bool, - - /// Run the compiled executable - #[arg(long, short)] - run: bool, - - /// Dont print any output exept the actual running codes output - #[arg(long, short)] - quiet: bool, - - /// Add an include directory [default: ["./include", "~/.mclang/include"]] - #[arg(long, short='I')] - include: Vec, - - /// Unsafe mode, disables typechecking - #[arg(long="unsafe", default_value_t = false)] - unsaf: bool, - - /// Optimisation level, available levels: 'D': debug, '0': No optimisations - #[arg(long, short='O', default_value_t=String::from("0"))] - optimisation: String, - - // disables the main function - #[arg(long="lib")] - lib_mode: bool - //#[arg(long, short='F')] - //features: Vec, - -} - -impl Args { - /// Get optimisation level - /// 0 => no optimisations - /// 1 => slight optimisations, mostly size ones - /// # Errors - /// - /// Throws when the opt level is not known - pub fn get_opt_level(&self) -> Result{ - match self.optimisation.as_str() { - "D" | "d" => Ok(0), - "0" | "" => Ok(1), - o => { - error!("Unknown optimisation level {o}"); - Err(eyre!("")) - } + info!("Lexing file {file:?}"); + if let Err(_) = lexer.lex(file.as_std_path()) { + error!("Lexing failed, exiting"); + return; } + + // for t in &lexer.tokens { + // info!({loc => t.loc.clone()}, "{:?}", t.typ); + // } + // dbg!(&lexer.tokens); + + info!("Parsing file {file:?}"); + let prog = match parser::parse(&cli_args, &mut lexer.tokens) { + Ok(r) => r, + Err(_) => { + error!("Parsing failed, exiting"); + return; + } + }; + + prog_map.insert(file.as_std_path(), prog); + } -} - -fn main() -> Result<()>{ - - - let args = Args::parse(); - - let Ok(code) = fs::read_to_string(&args.in_file) else { - error!("Failed to read file {}, exiting!", &args.in_file); - return Ok(()); - }; - - let tokens = lexer::lex(&code, args.in_file.as_str(), &args); - - - let mut parser = parser::Parser::new(tokens, &args, None); - let tokens = match parser.parse(){ - Ok(t) => t, - Err(e) => { - error!("Parsing failed, exiting!"); - if crate::DEV_MODE { - return Err(e) - } - return Ok(()); - } - }; - - match typechecker::typecheck(tokens.clone(), &args, None, HashMap::new(), HashMap::new()) { - Ok(_) => (), - Err(e) => { - error!("Typechecking failed, exiting!"); - if crate::DEV_MODE { - return Err(e); - } - return Ok(()); - } - }; - - let c = if args.compile && args.interpret { - error!("Cannot compile and interpret at the same time"); - 0 - } else if args.interpret { - if let Ok(c) = interpret::linux_x86_64::run(&tokens) { c } else { - error!("Interpretation failed, exiting!"); - 1 - } - } else if args.compile { - if let Ok(c) = compile::linux_x86_64::compile(&tokens, &args) { c } else { - error!("Compilation failed, exiting!"); - 1 - } - } else { - error!("Did not choose to compile or to interpret, exiting"); - 0 - }; - std::process::exit(c); + if let Err(_) = compiler::compile_program(&cli_args, prog_map) { + error!("Failed to compile program, exiting"); + } + } diff --git a/src/parser.rs b/src/parser.rs deleted file mode 100644 index 61ffe43..0000000 --- a/src/parser.rs +++ /dev/null @@ -1,222 +0,0 @@ -use std::ops::Deref; - -use crate::{constants::{Operator, OpType, Token, TokenType, Loc, KeywordType, InstructionType}, lerror, preprocessor::Preprocessor, Args}; -use color_eyre::Result; -use eyre::eyre; - -pub fn cross_ref(mut program: Vec) -> Result> { - let mut stack: Vec = Vec::new(); - - for ip in 0..program.len() { - let op = &program.clone()[ip]; - // println!("{op:?}"); - match op.typ { - // OpType::Keyword(KeywordType::FunctionDef) | - OpType::Keyword(KeywordType::If | KeywordType::While) => { - stack.push(ip); - } - OpType::Keyword(KeywordType::Else) => { - let Some(if_ip) = stack.pop() else { - lerror!(&op.loc, "Unclosed-if else block"); - return Err(eyre!("Cross referencing")); - }; - if program[if_ip].typ != OpType::Keyword(KeywordType::If) { - lerror!(&op.clone().loc,"'else' can only close 'if' blocks"); - return Err(eyre!("Bad block")); - } - - program[if_ip].jmp = ip + 1; - stack.push(ip); - }, - OpType::Keyword(KeywordType::End) => { - let Some(block_ip) = stack.pop() else { - lerror!(&op.loc, "Unclosed if, if-else, while-do, function, memory, or constant"); - return Err(eyre!("Cross referencing")); - }; - - match &program[block_ip].typ { - OpType::Keyword(KeywordType::If | KeywordType::Else) => { - program[block_ip].jmp = ip; - program[ip].jmp = ip + 1; - } - - OpType::Keyword(KeywordType::Do) => { - program[ip].jmp = program[block_ip].jmp; - program[block_ip].jmp = ip + 1; - } - - OpType::Keyword(KeywordType::Memory | KeywordType::Constant) => (), - - a => { - println!("{a:?}"); - lerror!(&op.clone().loc,"'end' can only close if, if-else, while-do, function, memory, or constant blocks"); - return Err(eyre!("")); - } - } - - } - OpType::Keyword(KeywordType::Do) => { - let Some(block_ip) = stack.pop() else { - lerror!(&op.loc, "Unclosed while-do block"); - return Err(eyre!("Cross referencing")); - }; - - program[ip].jmp = block_ip; - stack.push(ip); - } - _ => () - } - - } - if !stack.is_empty() { - // println!("{:?}", stack); - lerror!(&program[stack.pop().expect("Empy stack")].clone().loc,"Unclosed block, {:?}", program[stack.pop().expect("Empy stack")].clone()); - return Err(eyre!("Unclosed block")); - } - - Ok(program.clone()) -} - -pub struct Parser<'a> { - tokens: Vec, - pub preprocessor: Preprocessor<'a>, - #[allow(dead_code)] - args: &'a Args -} - -impl<'a> Parser<'a> { - pub fn new(file: Vec, args: &'a Args, p: Option>) -> Self { - let pre = if let Some(p) = p {p} else { - Preprocessor::new(Vec::new(), args) - }; - - Self{ - tokens: file, - preprocessor: pre, - args - } - } - - pub fn parse(&mut self) -> Result> { - let mut tokens = Vec::new(); - - for token in &self.tokens { - if token.text.is_empty() { - continue; - } - let pos = (token.file.clone(), token.line, token.col); - match token.typ { - TokenType::Word => { - let word_type = if token.op_typ == OpType::Instruction(InstructionType::MemUse) { - OpType::Instruction(InstructionType::MemUse) - } else { - lookup_word(&token.text, &pos) - }; - - tokens.push(Operator::new(word_type, token.typ, token.value.unwrap_or(0), token.text.clone(), token.file.clone(), token.line, token.col).set_addr(token.addr.unwrap_or(0))); - }, - TokenType::Int => {// negative numbers not yet implemented - tokens.push(Operator::new(OpType::Instruction(InstructionType::PushInt), token.typ, token.text.parse::()?, String::new(), token.file.clone(), token.line, token.col)); - }, - TokenType::String => { - tokens.push(Operator::new(OpType::Instruction(InstructionType::PushStr), token.typ, 0, token.text.clone(), token.file.clone(), token.line, token.col)); - } - TokenType::Char => { - let c = token.text.clone(); - if c.len() != 1 { - lerror!(&token.loc(), "Chars can only be of lenght 1, got {}", c.len()); - return Err(eyre!("")); - } - - tokens.push(Operator::new(OpType::Instruction(InstructionType::PushInt), token.typ, token.text.chars().next().unwrap() as usize, String::new(), token.file.clone(), token.line, token.col)); - } - }; - - - } - self.preprocessor.program = tokens; - let t = self.preprocessor.preprocess()?.get_ops(); - let t = cross_ref(t)?; - - Ok(t) - } -} - - -pub fn lookup_word>(s: &str, _pos: P) -> OpType { - let n = s.parse::(); - if n.is_ok() { - return OpType::Instruction(InstructionType::PushInt); - } - match s { - //stack - "_dbg_print" => OpType::Instruction(InstructionType::Print), - "dup" => OpType::Instruction(InstructionType::Dup), - "drop" => OpType::Instruction(InstructionType::Drop), - "rot" => OpType::Instruction(InstructionType::Rot), - "over" => OpType::Instruction(InstructionType::Over), - "swap" => OpType::Instruction(InstructionType::Swap), - - // comp and math - "+" => OpType::Instruction(InstructionType::Plus), - "-" => OpType::Instruction(InstructionType::Minus), - "=" => OpType::Instruction(InstructionType::Equals), - "!=" => OpType::Instruction(InstructionType::NotEquals), - ">" => OpType::Instruction(InstructionType::Gt), - "<" => OpType::Instruction(InstructionType::Lt), - ">=" => OpType::Instruction(InstructionType::Ge), - "<=" => OpType::Instruction(InstructionType::Le), - - "band" => OpType::Instruction(InstructionType::Band), - "bor" => OpType::Instruction(InstructionType::Bor), - "shr" => OpType::Instruction(InstructionType::Shr), - "shl" => OpType::Instruction(InstructionType::Shl), - "divmod" => OpType::Instruction(InstructionType::DivMod), - "*" => OpType::Instruction(InstructionType::Mul), - - - // mem - "load8" => OpType::Instruction(InstructionType::Load8), - "store8" => OpType::Instruction(InstructionType::Store8), - "load32" => OpType::Instruction(InstructionType::Load32), - "store32" => OpType::Instruction(InstructionType::Store32), - "load64" => OpType::Instruction(InstructionType::Load64), - "store64" => OpType::Instruction(InstructionType::Store64), - - "syscall0" => OpType::Instruction(InstructionType::Syscall0), - "syscall1" => OpType::Instruction(InstructionType::Syscall1), - "syscall2" => OpType::Instruction(InstructionType::Syscall2), - "syscall3" => OpType::Instruction(InstructionType::Syscall3), - "syscall4" => OpType::Instruction(InstructionType::Syscall4), - "syscall5" => OpType::Instruction(InstructionType::Syscall5), - "syscall6" => OpType::Instruction(InstructionType::Syscall6), - "cast(bool)" => OpType::Instruction(InstructionType::CastBool), - "cast(ptr)" => OpType::Instruction(InstructionType::CastPtr), - "cast(int)" => OpType::Instruction(InstructionType::CastInt), - "cast(void)" => OpType::Instruction(InstructionType::CastVoid), - // block - "if" => OpType::Keyword(KeywordType::If), - "else" => OpType::Keyword(KeywordType::Else), - "end" => OpType::Keyword(KeywordType::End), - "while" => OpType::Keyword(KeywordType::While), - "do" => OpType::Keyword(KeywordType::Do), - "include" => OpType::Keyword(KeywordType::Include), - "memory" => OpType::Keyword(KeywordType::Memory), - "const" => OpType::Keyword(KeywordType::Constant), - "fn" => OpType::Keyword(KeywordType::Function), - "then" => OpType::Keyword(KeywordType::FunctionThen), - "done" => OpType::Keyword(KeywordType::FunctionDone), - "inline" => OpType::Keyword(KeywordType::Inline), - "export" => OpType::Keyword(KeywordType::Export), - "return" => OpType::Instruction(InstructionType::Return), - "returns" => OpType::Instruction(InstructionType::Returns), - "bool" => OpType::Instruction(InstructionType::TypeBool), - "int" => OpType::Instruction(InstructionType::TypeInt), - "ptr" => OpType::Instruction(InstructionType::TypePtr), - "void" => OpType::Instruction(InstructionType::TypeVoid), - "any" => OpType::Instruction(InstructionType::TypeAny), - "with" => OpType::Instruction(InstructionType::With), - _ => OpType::Instruction(InstructionType::None) - } - -} \ No newline at end of file diff --git a/src/parser/builtin.rs b/src/parser/builtin.rs new file mode 100644 index 0000000..4bb61e5 --- /dev/null +++ b/src/parser/builtin.rs @@ -0,0 +1,46 @@ +use std::collections::HashMap; + +use lazy_static::lazy_static; + +use crate::types::{ast::{AstNode, Constant, Module, Program}, common::Loc}; + + +lazy_static!( + static ref DEFAULT_CONSTANTS: HashMap<&'static str, AstNode> = { + let mut h = HashMap::new(); + // No bsd cause im not about to create 3 or 4 diffrent compilation targets + h.insert("__WINDOWS", AstNode::Int(Loc::default(), cfg!(target_os = "windows") as usize)); + h.insert("__LINUX", AstNode::Int(Loc::default(), cfg!(target_os = "linux") as usize)); + h.insert("__ENDIAN_LITTLE", AstNode::Int(Loc::default(), cfg!(target_endian="little") as usize)); + h.insert("__ENDIAN_BIG", AstNode::Int(Loc::default(), cfg!(target_endian="big") as usize)); + + + h + }; +); + + + +pub fn get_builtin_symbols(prog: &mut Program) -> AstNode { + let mut md = Module { + loc: Loc::new(String::from("BUILTIN"), 0, 0), + path: vec![String::from("builtin")], + ident: String::from("BUILTIN"), + body: Vec::new(), + }; + + + + for (k, v) in DEFAULT_CONSTANTS.iter() { + let c = Constant { + loc: Loc::default(), + ident: k.to_string(), + value: Box::from(v.clone()), + }; + prog.constants.insert(k.to_string(), c.clone()); + md.body.push(AstNode::Constant(c)); + } + + + AstNode::Module(md) +} \ No newline at end of file diff --git a/src/parser/mod.rs b/src/parser/mod.rs new file mode 100644 index 0000000..e726310 --- /dev/null +++ b/src/parser/mod.rs @@ -0,0 +1,787 @@ +mod utils; +mod precompiler; +mod builtin; + +use std::{collections::HashMap, path::Path}; + +use anyhow::{bail, Result}; + +use crate::{cli::CliArgs, lexer::Lexer, types::{ast::{AstNode, Block, ConstUse, Constant, FnCall, Function, If, MemSize, MemUse, Memory, Module, Program, StructDef, While}, common::Loc, token::{InstructionType, KeywordType, Token, TokenType, TypeType}}}; + +use self::{builtin::get_builtin_symbols, precompiler::{precompile_const, precompile_mem}, utils::{expect, peek_check, peek_check_multiple, PeekResult}}; + + +bitflags::bitflags! { + struct Flags: u8 { + const EXTERN = 1 << 0; + const EXPORT = 1 << 1; + const INLINE = 1 << 2; + const ALLOW_TYPES = 1 << 3; + } +} + +//TODO: Implement Module paths +pub fn parse(cli_args: &CliArgs, tokens: &mut Vec) -> Result { + tokens.reverse(); + let module = Module { + loc: Loc::new(&tokens[0].loc.file, 0, 0), + ident: Path::new(&tokens[0].loc.file).file_stem().expect("Something went horribly wrong").to_string_lossy().to_string(), + body: Vec::new(), + path: vec![], + }; + + + let mut prog = Program { + ast: AstNode::Module(module.clone()), + functions: HashMap::new(), + constants: HashMap::new(), + memories: HashMap::new(), + struct_defs: HashMap::new() + }; + + let syms = get_builtin_symbols(&mut prog); + match &mut prog.ast { + AstNode::Module(module) => { + module.body.push(syms) + } + _ => unreachable!() + } + + while !tokens.is_empty() { + let node = parse_next(cli_args, &mut prog, tokens, Flags::empty(), true)?; + match &mut prog.ast { + AstNode::Module(module) => { + module.body.push(node); + } + _ => unreachable!() + } + } + + // prog.ast = module; + + Ok(prog) +} + +fn parse_next(cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec, flags: Flags, is_module_root: bool) -> Result { + let token = tokens.pop().expect("We broke reality!"); + // debug!({loc => token.loc.clone()}, "t: {:?}", token.typ); + let ret = match &token.typ { + TokenType::Keyword(kw) => { + match kw { + KeywordType::If => parse_if(&token, cli_args, prog, tokens)?, + KeywordType::While => parse_while(&token, cli_args, prog, tokens)?, + KeywordType::Include => parse_include(&token, cli_args, prog, tokens)?, + KeywordType::Memory => parse_memory(&token, cli_args, prog, tokens, is_module_root)?, + KeywordType::Constant => parse_const(&token, cli_args, prog, tokens)?, + KeywordType::Function => parse_function(&token, cli_args, prog, tokens, flags)?, + KeywordType::StructDef => parse_struct(&token, cli_args, prog, tokens)?, + KeywordType::TypeDef => todo!(), + KeywordType::Inline => parse_inline(&token, cli_args, prog, tokens, flags)?, + KeywordType::Export => parse_export(&token, cli_args, prog, tokens, flags)?, + KeywordType::Extern => parse_extern(&token, cli_args, prog, tokens, flags)?, + kw => { + dbg!(&prog.constants); + error!({loc => token.loc}, "Unexpected token {kw:?}"); + bail!("") + } + } + }, + TokenType::Instruction(it) => { + if is_module_root { + error!({loc => token.loc}, "Unexpected token {it:?}, please create a main function, this is not a scripting language"); + bail!("") + } else { + match it { + InstructionType::StructPath(p) => parse_struct_path(&token, prog, p)?, + InstructionType::StructItem(p) => parse_struct_item(&token, prog, p)?, + _ => AstNode::Token(token) + } + } + }, + TokenType::Unknown(ut) => { + if is_module_root { + error!({loc => token.loc}, "Unexpected token {ut:?}, please create a main function, this is not a scripting language"); + bail!("") + } else { + // AstNode::Token(token) + parse_unknown(&token, cli_args, prog, tokens, flags)? + } + }, + TokenType::Type(t) => { + if flags.contains(Flags::ALLOW_TYPES) { + AstNode::Token(token) + } else { + error!({loc => token.loc}, "Unexpected type {t:?}"); + bail!("") + } + }, + }; + Ok(ret) +} + +fn parse_struct_item(org: &Token, prog: &mut Program, p: &Vec) -> Result { + fn find_disp(strct: &StructDef, disp: &mut usize, path: &[String]) { + let Some(p) = path.get(0) else { + return + }; + + for item in &strct.body { + if p == &item.0 { + match &item.2 { + TypeType::Struct(strct) => { + *disp += item.1; + find_disp(strct, disp, &path[1..]) + }, + _ => { + *disp += item.1; + } + } + } + } + + } + if let Some(mem) = prog.memories.get(&p[0].to_string()) { + match &mem.size { + MemSize::Size(_) => { + error!({loc => org.loc()}, "You can only access items in structs"); + bail!("") + }, + MemSize::Type(t) => { + match t { + TypeType::Struct(s) => { + + let mut disp = 0; + find_disp(&s, &mut disp, &p[1..]); + return Ok(AstNode::MemUse(MemUse{ + ident: p[0].clone(), + loc: org.loc(), + disp: Some(disp) + })); + }, + _ => { + error!({loc => org.loc()}, "You can only access items in structs"); + bail!("") + } + } + }, + } + } + + error!("Failed to find memory {}", p[0]); + bail!("") +} + +fn parse_struct_path(org: &Token, prog: &mut Program, p: &Vec) -> Result { + + fn find_disp(strct: &StructDef, disp: &mut usize, path: &[String]) { + let Some(p) = path.get(0) else { + return + }; + + for item in &strct.body { + if p == &item.0 { + match &item.2 { + TypeType::Struct(strct) => { + *disp += item.1; + find_disp(strct, disp, &path[1..]) + }, + _ => { + *disp += item.1; + } + } + } + } + + } + let mut disp = 0; + if let Some(strct) = prog.struct_defs.get(&p[0].to_string()) { + find_disp(strct, &mut disp, &p[1..]); + return Ok(AstNode::StructDispPush{ + ident: org.lexem.clone(), + loc: org.loc(), + disp + }); + } + + error!("Failed to find struct {}", p[0]); + bail!("") +} + +fn parse_struct(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec) -> Result { + let ident = expect(tokens, TokenType::Unknown(String::new()))?; + expect(tokens, TokenType::Keyword(KeywordType::Do))?; + + + let mut body: Vec<(String, usize, TypeType)> = Vec::new(); + let mut size = 0; + + loop { + let ident = expect(tokens, TokenType::Unknown(String::new()))?; + expect(tokens, TokenType::Keyword(KeywordType::Do))?; + let typ = parse_next(cli_args, prog, tokens, Flags::ALLOW_TYPES, false)?; + let (typ, disp) = match &typ { + AstNode::Token(t) => { + match &t.typ { + TokenType::Type(t) => { + let disp = size; + size += t.get_size(); + (t, disp) + } + _ => { + error!({loc => t.loc()}, "Expected type, got {t:?}"); + bail!("") + } + } + }, + t => { + error!({loc => typ.loc()}, "Expected type, got {t:?}"); + bail!("") + } + }; + expect(tokens, TokenType::Keyword(KeywordType::End))?; + + body.push((ident.lexem, disp, typ.clone())); + + if peek_check(tokens, TokenType::Keyword(KeywordType::Done)).correct(){ + tokens.pop(); + break; + } + // if peek_check(tokens, TokenType::Keyword(KeywordType::End)).correct() + }; + + + + let def = StructDef{ + loc: org.loc(), + ident: ident.lexem.clone(), + body, + size, + }; + + prog.struct_defs.insert(ident.lexem, def.clone()); + + Ok(AstNode::StructDef(def)) +} + +fn parse_memory(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec, is_module_root: bool) -> Result { + let name = expect(tokens, TokenType::Unknown(String::new()))?; + + + let mut body = Vec::new(); + loop { + + let t = peek_check(tokens, TokenType::Keyword(KeywordType::End)); + match t { + PeekResult::Correct(_) => break, + PeekResult::Wrong(_) => (), + PeekResult::None => panic!("idk what to do herre"), + } + body.push(parse_next(cli_args, prog, tokens, Flags::ALLOW_TYPES, false)?); + } + expect(tokens, TokenType::Keyword(KeywordType::End))?; + + let val = precompile_mem(prog, body)?; + + let name = name.lexem.clone() + .replace("(", "_OPRN_") + .replace(")", "_CPRN_"); + + let def = Memory{ + loc: org.loc(), + ident: name.clone(), + size: val, + statc: is_module_root, + }; + + + prog.memories.insert(name, def.clone()); + + Ok(AstNode::Memory(def)) + +} + +// TODO: Extern functions +fn parse_function(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec, flags: Flags ) -> Result { + + + let name = expect(tokens, TokenType::Unknown(String::new()))?; + expect(tokens, TokenType::Keyword(KeywordType::With))?; + let mut args = Vec::new(); + + loop { + if let PeekResult::Correct(t) = peek_check_multiple(tokens, vec![ + TokenType::Type(TypeType::Any), + TokenType::Type(TypeType::U8), + TokenType::Type(TypeType::U16), + TokenType::Type(TypeType::U32), + TokenType::Type(TypeType::U64), + TokenType::Type(TypeType::Ptr), + TokenType::Type(TypeType::Void), + TokenType::Type(TypeType::Custom(Vec::new())), + ]) { + match &t.typ { + TokenType::Type(tt) => { + args.push(tt.clone()); + } + _ => unreachable!() + } + } else { + break; + } + tokens.pop(); + } + + expect(tokens, TokenType::Keyword(KeywordType::Returns))?; + + let mut ret_args = Vec::new(); + + loop { + if let PeekResult::Correct(t) = peek_check_multiple(tokens, vec![ + TokenType::Type(TypeType::Any), + TokenType::Type(TypeType::U8), + TokenType::Type(TypeType::U16), + TokenType::Type(TypeType::U32), + TokenType::Type(TypeType::U64), + TokenType::Type(TypeType::Ptr), + TokenType::Type(TypeType::Void), + TokenType::Type(TypeType::Custom(Vec::new())), + ]) { + match &t.typ { + TokenType::Type(tt) => { + ret_args.push(tt.clone()); + } + _ => unreachable!() + } + } else { + break; + } + tokens.pop(); + } + + + expect(tokens, TokenType::Keyword(KeywordType::Then))?; + let mut body = Vec::new(); + loop { + + let fn_got = peek_check(tokens, TokenType::Keyword(KeywordType::Done)); + match fn_got { + PeekResult::Correct(_) => break, + PeekResult::Wrong(_) => (), + PeekResult::None => panic!("idk what to do herre"), + } + body.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?); + } + expect(tokens, TokenType::Keyword(KeywordType::Done))?; + + let fn_def = Function { + loc: org.loc(), + inline: flags.contains(Flags::INLINE), + extrn: flags.contains(Flags::EXTERN), + export: flags.contains(Flags::EXPORT), + ident: name.lexem.clone(), + arg_types: args, + ret_types: ret_args, + body, + }; + //TODO: Support module paths without double definitions + // let mut mp = match &prog.ast { + // AstNode::Module(m) => { + // m.path.clone() + // } + // _ => panic!("") + // }; + // mp.push(name.lexem.clone()); + // let mp = mp.join("::"); + + // prog.function_aliases.insert(mp, name.lexem.clone()); + prog.functions.insert(name.lexem.clone(), fn_def.clone()); + Ok(AstNode::Function(fn_def)) +} + +fn parse_if(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec) -> Result { + let mut test: Vec = Vec::new(); + let mut body: Vec = Vec::new(); + let mut els: Vec = Vec::new(); + loop { + test.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?); + match peek_check(tokens, TokenType::Keyword(KeywordType::Do)) { + PeekResult::Correct(_) => break, + PeekResult::Wrong(w) => { + match w.typ { + TokenType::Keyword(KeywordType::Then) => { + warn!({loc => w.loc()}, "If is defined as `if ... do ... done`"); + } + _ => () + } + }, + PeekResult::None => panic!("idk what to do herre"), + } + } + + expect(tokens, TokenType::Keyword(KeywordType::Do))?; + + + + loop { + body.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?); + match peek_check_multiple(tokens, vec![ + TokenType::Keyword(KeywordType::Else), + TokenType::Keyword(KeywordType::Done), + ]) { + PeekResult::Correct(_) => break, + PeekResult::Wrong(_) => (), + PeekResult::None => panic!("idk what to do herre"), + } + } + + + let els_t = tokens.last().expect("IMPOSSIBLEEE!!!!!!111").clone(); + let els = match els_t.typ.clone() { + TokenType::Keyword(kw) => { + match kw { + KeywordType::Done => { + expect(tokens, TokenType::Keyword(KeywordType::Done))?; + AstNode::Block(Block{ + comment: String::new(), + loc: els_t.loc, + body: Vec::new(), + }) + }, + KeywordType::Else => { + expect(tokens, TokenType::Keyword(KeywordType::Else))?; + if peek_check(tokens, TokenType::Keyword(KeywordType::If)).correct() { + let if_org =expect(tokens, TokenType::Keyword(KeywordType::If))?; + parse_if(&if_org, cli_args, prog, tokens)? + } else { + loop { + els.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?); + match peek_check(tokens, TokenType::Keyword(KeywordType::Done)) { + PeekResult::Correct(_) => break, + PeekResult::Wrong(w) => { + match w.typ { + TokenType::Keyword(KeywordType::Then) => { + warn!("If is defined as `if ... do ... done`"); + } + _ => () + } + }, + PeekResult::None => panic!("idk what to do herre"), + } + } + expect(tokens, TokenType::Keyword(KeywordType::Done))?; + + AstNode::Block(Block{ + comment: String::new(), + loc: els_t.loc, + body: els, + }) + } + }, + e => { + error!({loc => els_t.loc.clone()}, "Expected {:?} or {:?} but got {:?}", KeywordType::Done, KeywordType::Else, e); + bail!(""); + } + } + }, + e => { + error!({loc => els_t.loc.clone()}, "Expected {:?} or {:?} but got {:?}", KeywordType::Done, KeywordType::Else, e); + bail!(""); + } + }; + Ok(AstNode::If(If{ + test, + body, + els: Box::new(els), + loc: org.loc(), + })) +} + + +fn parse_while(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec) -> Result { + let mut test: Vec = Vec::new(); + let mut body: Vec = Vec::new(); + loop { + test.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?); + match peek_check(tokens, TokenType::Keyword(KeywordType::Do)) { + PeekResult::Correct(_) => break, + PeekResult::Wrong(w) => { + match w.typ { + TokenType::Keyword(KeywordType::Then) => { + warn!("while is defined as `while ... do ... done`"); + } + _ => () + } + }, + PeekResult::None => panic!("idk what to do herre"), + } + } + + expect(tokens, TokenType::Keyword(KeywordType::Do))?; + + + + loop { + body.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?); + match peek_check_multiple(tokens, vec![ + TokenType::Keyword(KeywordType::Else), + TokenType::Keyword(KeywordType::Done), + ]) { + PeekResult::Correct(_) => break, + PeekResult::Wrong(_) => (), + PeekResult::None => panic!("idk what to do herre"), + } + } + + + expect(tokens, TokenType::Keyword(KeywordType::Done))?; + + Ok(AstNode::While(While{ + test, + body, + loc: org.loc(), + })) +} + +fn parse_inline(_: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec, flags: Flags) -> Result { + let allowed_tokens = vec!{ + TokenType::Keyword(KeywordType::Function) + }; + + + let Some(t) = tokens.last() else { + error!("Expected one of {:?} after {:?} but found nothing", allowed_tokens, TokenType::Keyword(KeywordType::Inline)); + bail!("") + }; + + + let mut found = false; + + for at in &allowed_tokens { + if utils::cmp(at, &t.typ) { + found = true; + } + } + + if !found { + error!({loc => t.loc.clone()}, "Expected one of {:?} after {:?} but found {:?}", allowed_tokens, TokenType::Keyword(KeywordType::Inline), t.typ); + bail!(""); + } + + + parse_next(cli_args, prog, tokens, flags | Flags::INLINE, false) +} + +fn parse_extern(_: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec, flags: Flags) -> Result { + let allowed_tokens = vec!{ + TokenType::Keyword(KeywordType::Function), + TokenType::Keyword(KeywordType::Constant), + TokenType::Keyword(KeywordType::Memory), + }; + + + let Some(t) = tokens.last() else { + error!("Expected one of {:?} after {:?} but found nothing", allowed_tokens, TokenType::Keyword(KeywordType::Extern)); + bail!("") + }; + + + let mut found = false; + + for at in &allowed_tokens { + if utils::cmp(at, &t.typ) { + found = true; + } + } + + if !found { + error!({loc => t.loc.clone()}, "Expected one of {:?} after {:?} but found {:?}", allowed_tokens, TokenType::Keyword(KeywordType::Extern), t.typ); + bail!(""); + } + + + parse_next(cli_args, prog, tokens, flags | Flags::EXTERN, false) +} + +fn parse_export(_: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec, flags: Flags) -> Result { + let allowed_tokens = vec!{ + TokenType::Keyword(KeywordType::Function), + TokenType::Keyword(KeywordType::Constant), + TokenType::Keyword(KeywordType::Memory), + }; + + + let Some(t) = tokens.last() else { + error!("Expected one of {:?} after {:?} but found nothing", allowed_tokens, TokenType::Keyword(KeywordType::Export)); + bail!("") + }; + + + let mut found = false; + + for at in &allowed_tokens { + if utils::cmp(at, &t.typ) { + found = true; + } + } + + if !found { + error!({loc => t.loc.clone()}, "Expected one of {:?} after {:?} but found {:?}", allowed_tokens, TokenType::Keyword(KeywordType::Export), t.typ); + bail!(""); + } + + + parse_next(cli_args, prog, tokens, flags | Flags::EXPORT, false) +} + + +fn parse_include(_: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec) -> Result { + let path = expect(tokens, + TokenType::Instruction( + InstructionType::PushStr( + String::new() + ) + ) + )?; + + for ip in &cli_args.include_path { + let p = ip.join(&path.lexem).to_path_buf(); + if p.exists() { + info!({loc => path.loc.clone()}, "Lexing file {}", path.lexem.clone()); + let mut lexer = Lexer::new(); + lexer.lex(p.as_std_path())?; + + let mut mod_tokens = lexer.tokens; + + mod_tokens.reverse(); + + let mut mp = match &prog.ast { + AstNode::Module(m) => { + m.path.clone() + } + _ => panic!("") + }; + + mp.push(p.file_stem().unwrap().to_string()); + + let module = Module { + loc: Loc::new(path.loc.file.clone(), 0, 0), + ident: Path::new(&path.loc.file).file_stem().expect("Something went horribly wrong").to_string_lossy().to_string(), + body: Vec::new(), + path: mp, + }; + + + let mut mod_prog = Program { + ast: AstNode::Module(module), + functions: prog.functions.clone(), + constants: prog.constants.clone(), + memories: prog.memories.clone(), + struct_defs: prog.struct_defs.clone(), + + }; + + info!({loc => path.loc.clone()}, "Parsing file {}", path.lexem.clone()); + while !mod_tokens.is_empty() { + let node = parse_next(cli_args, &mut mod_prog, &mut mod_tokens, Flags::empty(), true)?; + match &mut mod_prog.ast { + AstNode::Module(module) => { + module.body.push(node); + } + _ => unreachable!() + } + } + + prog.constants = mod_prog.constants; + prog.functions = mod_prog.functions; + prog.memories = mod_prog.memories; + return Ok(mod_prog.ast) + } + + }; + + error!("Could not find file {:?} in these locations: {:?}", path.lexem, cli_args.include_path); + bail!("") + +} + +fn parse_const(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec) -> Result { + let name = expect(tokens, TokenType::Unknown(String::new()))?; + + + let mut body = Vec::new(); + loop { + + let t = peek_check(tokens, TokenType::Keyword(KeywordType::End)); + match t { + PeekResult::Correct(_) => break, + PeekResult::Wrong(_) => (), + PeekResult::None => panic!("idk what to do herre"), + } + body.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?); + } + expect(tokens, TokenType::Keyword(KeywordType::End))?; + + let val = precompile_const(prog, body, &mut Vec::new())?; + + + let def = Constant{ + loc: org.loc(), + ident: name.lexem.clone(), + value: Box::new(val), + }; + + + prog.constants.insert(name.lexem, def.clone()); + + Ok(AstNode::Constant(def)) +} + +fn parse_unknown(org: &Token, _: &CliArgs, prog: &mut Program, _: &mut Vec, _: Flags ) -> Result { + //TODO: Typing? + if let Some(func) = prog.functions.get(&org.lexem.clone()) { + if func.inline { + return Ok(AstNode::Block(Block{ loc: org.loc.clone(), body: func.body.clone(), comment: format!("inline fn {}", func.ident) })) + } else { + return Ok(AstNode::FnCall(FnCall{ loc: org.loc.clone(), ident: org.lexem.clone() })); + } + } + + if let Some(_) = prog.constants.get(&org.lexem.clone()) { + return Ok(AstNode::ConstUse(ConstUse{ loc: org.loc.clone(), ident: org.lexem.clone() })); + } + + if let Some(_) = prog.memories.get(&org.lexem.clone()) { + return Ok(AstNode::MemUse(MemUse{ loc: org.loc.clone(), ident: org.lexem.clone(), disp: None })); + } + + if let Some(t) = prog.struct_defs.get(&org.lexem.clone()) { + return Ok(AstNode::Token(Token { + typ: TokenType::Type(TypeType::Struct(t.clone())), + loc: org.loc(), + lexem: org.lexem.clone(), + })); + } + + + // if org.lexem.clone().contains("::") { + // let pth = org.lexem.clone(); + // let pth = pth.split("::").collect::>(); + // dbg!(prog.struct_defs.clone()); + // if let Some(t) = prog.struct_defs.get(&pth[0].to_string()) { + // if let Some(i) = t.body.iter().find(|i| i.0 == pth[1].to_string()) { + // return Ok(AstNode::StructDispPush{ + // ident: org.lexem.clone(), + // loc: org.loc(), + // disp: i.1 + // }); + + // } + // } + // } + + + // dbg!(&prog.constants); + debug!({loc => org.loc.clone()}, "Unknown token"); + error!({loc => org.loc.clone()}, "Unknown token {:?}", org); + bail!("") +} \ No newline at end of file diff --git a/src/parser/precompiler.rs b/src/parser/precompiler.rs new file mode 100644 index 0000000..c8fd8e4 --- /dev/null +++ b/src/parser/precompiler.rs @@ -0,0 +1,213 @@ +use anyhow::bail; + +use crate::types::{ast::{AstNode, MemSize, Program}, common::Loc, token::{InstructionType, TokenType, TypeType}}; + + +pub fn precompile_mem(prog: &Program, ast: Vec ) -> anyhow::Result { + match &ast[0] { + AstNode::Token(t) => { + match &t.typ { + TokenType::Type(_) => { + let mut buf = vec![]; + let mut i = 0; + while ast.len() > i { + match &ast[i] { + AstNode::Token(t) => { + match &t.typ { + TokenType::Type(t) => { + match t { + TypeType::Struct(s) => { + return Ok(MemSize::Type(TypeType::Struct(s.clone()))); + }, + _ => () + } + buf.push(t.clone()); + i += 1; + } + _ => { + error!({loc => t.loc()}, "Cannot use a type and a number as a memory size at the same time"); + bail!("") + } + } + }, + _ => { + error!({loc => t.loc()}, "Cannot use a type and a number as a memory size at the same time"); + bail!("") + } + } + } + return Ok(MemSize::Type(TypeType::Custom(buf))); + } + _ => () + } + }, + _ => (), + } + match precompile_const(prog, ast, &mut Vec::new()) { + Ok(v) => { + match v { + AstNode::Int(_, i) => { + return Ok(MemSize::Size(i)) + } + _ => { + error!({loc => v.loc()}, "Can only have a type or a number as a memory size"); + bail!("") + } + } + }, + Err(e) => bail!(e), + } +} +pub fn precompile_const(prog: &Program, ast: Vec, stack: &mut Vec ) -> anyhow::Result { + for node in ast.clone() { + match &node { + AstNode::ConstUse(c) => { + let Some(val) = prog.constants.get(&c.ident) else { + error!({loc => c.loc.clone()}, "Unknown constant {:?}", c.ident) ; + bail!("") + }; + match Box::leak(val.value.clone()) { + t @ AstNode::Int(..) => { + return Ok(t.clone()); + } + + t @ AstNode::Str(..) => { + return Ok(t.clone()); + } + + t @ AstNode::CStr(..) => { + return Ok(t.clone()); + } + + t @ AstNode::Char(..) => { + return Ok(t.clone()); + } + + + // AstNode::Token(t) => { + // match t.typ.clone() { + // TokenType::Instruction(it) => { + // match it { + // InstructionType::PushInt(i) => stack.push(i), + // InstructionType::PushCStr(_) => { + // //TODO: Handle this better + // return Ok(AstNode::Token(t.clone())); + // }, + // InstructionType::PushChar(_) => { + // //TODO: Handle this better + // return Ok(AstNode::Token(t.clone())); + // }, + // _ => panic!() + // } + // }, + // _ => panic!() + // } + // }, + _ => panic!() + } + + }, + AstNode::Token(t) => { + match t.typ.clone() { + TokenType::Keyword(_) => { + error!({loc => t.loc.clone()}, "Unsupported token {t:?}, we dont support precompilation of this") ; + bail!("") + }, + TokenType::Instruction(it) => { + match it { + InstructionType::PushInt(i) => { + stack.push(i); + }, + InstructionType::PushCStr(s) => { + //TODO: Handle this better + return Ok(AstNode::CStr(t.loc.clone(), s)); + }, + InstructionType::PushStr(s) => { + //TODO: Handle this better + return Ok(AstNode::Str(t.loc.clone(), s)); + }, + InstructionType::PushChar(c) => { + //TODO: Handle this better + return Ok(AstNode::Char(t.loc.clone(), c)); + }, + InstructionType::Minus => { + let a = stack_pop(stack, &t.loc)?; + let b = stack_pop(stack, &t.loc)?; + stack.push(b - a); + }, + InstructionType::Plus => { + let a = stack_pop(stack, &t.loc)?; + let b = stack_pop(stack, &t.loc)?; + stack.push(b + a); + }, + InstructionType::DivMod => { + let a = stack_pop(stack, &t.loc)?; + let b = stack_pop(stack, &t.loc)?; + stack.push(b / a); + stack.push(b % a); + }, + InstructionType::Mul => { + let a = stack_pop(stack, &t.loc)?; + let b = stack_pop(stack, &t.loc)?; + stack.push(b * a); + }, + InstructionType::Drop => { + stack_pop(stack, &t.loc)?; + }, + //TODO: Support these later + // InstructionType::Dup => todo!(), + // InstructionType::Rot => todo!(), + // InstructionType::Over => todo!(), + // InstructionType::Swap => todo!(), + // InstructionType::Equals => todo!(), + // InstructionType::Gt => todo!(), + // InstructionType::Lt => todo!(), + // InstructionType::Ge => todo!(), + // InstructionType::Le => todo!(), + // InstructionType::NotEquals => todo!(), + // InstructionType::Band => todo!(), + // InstructionType::Bor => todo!(), + // InstructionType::Shr => todo!(), + // InstructionType::Shl => todo!(), + //TODO: Support this when we have types + // InstructionType::CastBool => todo!(), + // InstructionType::CastPtr => todo!(), + // InstructionType::CastInt => todo!(), + // InstructionType::CastVoid => todo!(), + InstructionType::ConstUse => unreachable!(), + _ => { + error!({loc => t.loc.clone()}, "Unsupported token {t:?}, we dont support precompilation of this") ; + bail!("") + } + } + }, + TokenType::Unknown(_) => unreachable!(), + TokenType::Type(_) => { + error!({loc => t.loc()}, "Cannot use a type and a number as a memory size at the same time"); + bail!("") + }, + } + }, + //TODO: Implement these + t @ AstNode::If { .. } | + t @ AstNode::While { .. } | + t => { + error!({loc => t.loc()}, "Unsupported token {t:?}, we dont support precompilation of this") ; + bail!("") + } + } + + } + + Ok(AstNode::Int(ast[0].loc(), stack[0])) +} + +fn stack_pop(stack: &mut Vec, loc: &Loc) -> anyhow::Result { + match stack.pop() { + Some(i) => Ok(i), + None => { + error!({loc => loc.clone()}, "Failed to precompile tokens, failed to pop from stack"); + bail!("") + }, + } +} \ No newline at end of file diff --git a/src/parser/utils.rs b/src/parser/utils.rs new file mode 100644 index 0000000..484cac2 --- /dev/null +++ b/src/parser/utils.rs @@ -0,0 +1,103 @@ +use anyhow::{bail, Result}; + +use crate::types::token::{Token, TokenType}; + +#[derive(Debug, Clone, PartialEq, PartialOrd)] +pub enum PeekResult { + Correct(T), + Wrong(T), + None +} + +impl PeekResult { + pub fn correct(&self) -> bool{ + match self { + PeekResult::Correct(_) => true, + _ => false + } + } + #[allow(dead_code)] + pub fn wrong(&self) -> bool{ + match self { + PeekResult::Wrong(_) => true, + _ => false + } + } + + #[allow(dead_code)] + pub fn none(&self) -> bool{ + match self { + PeekResult::None => true, + _ => false + } + } +} + +pub fn cmp(lhs: &TokenType, rhs: &TokenType) -> bool { + match (lhs, rhs) { + (TokenType::Keyword(lhs), TokenType::Keyword(rhs)) => { + std::mem::discriminant(lhs) == std::mem::discriminant(rhs) + }, + (TokenType::Instruction(lhs), TokenType::Instruction(rhs)) => { + std::mem::discriminant(lhs) == std::mem::discriminant(rhs) + }, + (TokenType::Type(lhs), TokenType::Type(rhs)) => { + std::mem::discriminant(lhs) == std::mem::discriminant(rhs) + }, + (TokenType::Unknown(_), TokenType::Unknown(_)) => true, + _ => false + } +} + +pub fn peek_check_multiple(tokens: &Vec, typs: Vec) -> PeekResult<&Token>{ + let t = tokens.last(); + + if let Some(t) = t { + for tt in typs.clone() { + if cmp(&t.typ, &tt) { + return PeekResult::Correct(t); + } + } + PeekResult::Wrong(t) + } else { + PeekResult::None + } +} + +pub fn peek_check(tokens: &Vec, typ: TokenType) -> PeekResult<&Token> { + let t = tokens.last(); + + match t { + Some(t) => { + //? Source: https://doc.rust-lang.org/std/mem/fn.discriminant.html + if cmp(&t.typ, &typ) { + PeekResult::Correct(t) + } else { + PeekResult::Wrong(t) + } + }, + None => { + PeekResult::None + } + } +} + +pub fn expect(tokens: &mut Vec, typ: TokenType) -> Result { + let t = tokens.pop(); + + match t { + Some(t) => { + //? Source: https://doc.rust-lang.org/std/mem/fn.discriminant.html + if std::mem::discriminant(&t.typ) != std::mem::discriminant(&typ) { + error!({loc => t.loc()}, "Expected {:?}, but got {:?}", typ, t.typ); + bail!("") + } + Ok(t) + }, + None => { + error!("Expected {:?}, but found nothing", typ); + bail!("") + } + } + +} \ No newline at end of file diff --git a/src/precompiler.rs b/src/precompiler.rs deleted file mode 100644 index 9c4bc3e..0000000 --- a/src/precompiler.rs +++ /dev/null @@ -1,147 +0,0 @@ - -use color_eyre::Result; -use eyre::eyre; - -use crate::{constants::{ OpType, InstructionType, Loc, Operator}, lerror}; - -fn stack_pop(stack: &mut Vec, loc: &Loc) -> Result { - if let Some(i) = stack.pop() { Ok(i) } else { - lerror!(&loc.clone(), "Stack underflow"); - Err(eyre!("Stack underflow")) - } -} - -pub fn precompile(tokens: &Vec) -> Result>{ - - let mut stack: Vec = Vec::new(); - for token in tokens.iter() { - match token.typ.clone() { - OpType::Instruction(i) => { - let loc = token.loc.clone(); - match i { - InstructionType::PushInt => { - stack.push(token.value); - }, - InstructionType::Plus => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(b + a); - }, - InstructionType::Minus => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(b - a); - }, - InstructionType::Equals => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(usize::from(b == a)); - }, - InstructionType::Gt => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(usize::from(b > a)); - }, - InstructionType::Lt => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(usize::from(b < a)); - }, - InstructionType::NotEquals => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(usize::from(b != a)); - }, - InstructionType::Ge => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(usize::from(b >= a)); - }, - InstructionType::Le => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(usize::from(b <= a)); - }, - - InstructionType::Band => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(a & b); - } - - InstructionType::Bor => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(a | b); - } - - InstructionType::Shr => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(b >> a); - } - - InstructionType::Shl => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(b << a); - } - - InstructionType::DivMod => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(b / a); - stack.push(b % a); - } - InstructionType::Mul => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(b * a); - } - InstructionType::Drop => { - stack.pop(); - }, - InstructionType::Dup => { - let a = stack_pop(&mut stack, &loc)?; - stack.push(a); - stack.push(a); - }, - - InstructionType::Rot => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - let c = stack_pop(&mut stack, &loc)?; - stack.push(b); - stack.push(a); - stack.push(c); - } - InstructionType::Swap => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(a); - stack.push(b); - } - InstructionType::Over => { - let a = stack_pop(&mut stack, &loc)?; - let b = stack_pop(&mut stack, &loc)?; - stack.push(b); - stack.push(a); - stack.push(b); - } - _ => { - lerror!(&token.loc, "Unsupported precompiler instruction {:?}", i); - dbg!(tokens); - return Err(eyre!("")); - } - } - } - OpType::Keyword(_) => { - lerror!(&token.loc, "Unsupported precompiler keyword {:?}", token.typ); - dbg!(tokens); - return Err(eyre!("")); - } - } - } - - Ok(stack) -} \ No newline at end of file diff --git a/src/preprocessor.rs b/src/preprocessor.rs deleted file mode 100644 index 360e47b..0000000 --- a/src/preprocessor.rs +++ /dev/null @@ -1,617 +0,0 @@ -use std::collections::HashMap; -use std::ops::Deref; -use std::path::{PathBuf, Path}; - - -use color_eyre::Result; -use eyre::eyre; - -use crate::constants::{Loc, OpType, TokenType, KeywordType, InstructionType, Operator}; -use crate::lexer::lex; -use crate::precompiler::precompile; -use crate::{lerror, Args, warn, linfo, parser}; -use crate::parser::lookup_word; - - - -#[derive(Debug, Clone)] -pub struct Function { - pub loc: Loc, - pub name: String, - pub inline: bool, - pub tokens: Option> -} - -#[derive(Debug, Clone)] -pub struct Constant { - pub loc: Loc, - pub name: String -} - -#[derive(Debug, Clone)] -pub struct Memory { - pub loc: Loc, - pub id: usize - -} - -type Functions = HashMap; -type Memories = HashMap; -type Constants = HashMap; - -#[derive(Debug, Clone)] -pub struct Preprocessor<'a> { - pub program: Vec, - pub functions: Functions, - pub memories: Memories, - pub constants: Constants, - args: &'a Args -} - - -impl<'a> Preprocessor<'a> { - pub fn new(prog: Vec, args: &'a Args) -> Self { - Self { - program: prog, - args, - functions: HashMap::new(), - memories: HashMap::new(), - constants: HashMap::new(), - } - } - - - pub fn preprocess(&mut self) -> Result<&mut Preprocessor<'a>>{ - // println!("pre: has do tokens: {:?}", self.program.iter().map(|t| if t.typ == OpType::Keyword(KeywordType::Do) {Some(t)} else {None} ).collect::>>()); - - let mut f_inline = false; - let mut f_extern = false; - - let mut program: Vec = Vec::new(); - - let mut rtokens = self.program.clone(); - rtokens.reverse(); - while !rtokens.is_empty() { - let mut op = rtokens.pop().unwrap(); - // println!("{token:?}"); - let op_type = op.typ.clone(); - match op_type { - OpType::Keyword(KeywordType::Include) => { - if rtokens.is_empty() { - lerror!(&op.loc, "Include path not found, expected {} but found nothing", TokenType::String.human()); - return Err(eyre!("")); - } - - let include_path = rtokens.pop().unwrap(); - - if include_path.tok_typ != TokenType::String { - lerror!(&include_path.loc, "Bad include path, expected {} but found {}", TokenType::String.human(), include_path.typ.human()); - return Err(eyre!("")); - } - - let mut in_paths = self.args.include.clone(); - in_paths.append(&mut crate::DEFAULT_INCLUDES.to_vec().clone().iter().map(|f| (*f).to_string()).collect::>()); - - let mut include_code = String::new(); - let mut pth = PathBuf::new(); - if include_path.text.chars().collect::>()[0] == '.' { - let p = Path::new(include_path.loc.0.as_str()); - let p = p.parent().unwrap(); - let p = p.join(&include_path.text); - pth = p.clone(); - include_code = std::fs::read_to_string(p)?; - } else { - for path in in_paths { - let p = PathBuf::from(path); - let p = p.join(&include_path.text); - pth = p.clone(); - - if p.exists() { - include_code = std::fs::read_to_string(p)?; - } - - } - } - - if include_code.is_empty() { - lerror!(&include_path.loc, "Include file in path '{}' was not found or is empty", include_path.text); - return Err(eyre!("")); - } - let a = pth.to_str().unwrap().to_string(); - let code = lex(&include_code, a.as_str(), self.args); - let mut p = parser::Parser::new(code, self.args, Some(self.clone())); - let mut code = p.parse()?; - - self.set_constants(p.preprocessor.get_constants()); - self.set_functions(p.preprocessor.get_functions()); - self.set_memories(p.preprocessor.get_memories()); - code.reverse(); - rtokens.append(&mut code); - - - } - - OpType::Keyword(KeywordType::Memory) => { - if rtokens.is_empty() { - lerror!(&op.loc, "Memory name not found, expected {} but found nothing", TokenType::String.human()); - return Err(eyre!("")); - } - - let name = rtokens.pop().unwrap(); - - self.is_word_available(&name, KeywordType::Memory)?; - - let mut code: Vec = Vec::new(); - - let mut depth = 0; - while !rtokens.is_empty() { - let t = rtokens.pop().unwrap(); - let typ = t.typ.clone(); - if typ == OpType::Keyword(KeywordType::End) && depth == 0 { - break; - } else if typ == OpType::Keyword(KeywordType::End) && depth != 0 { - depth -= 1; - code.push(t); - } else if typ == OpType::Keyword(KeywordType::If) || typ == OpType::Keyword(KeywordType::Do) { - code.push(t); - depth += 1; - } else { - code.push(t); - } - } - let res = precompile(&code)?; - - - if res.len() != 1 { - lerror!(&op.loc, "Expected 1 number, got {:?}", res); - return Err(eyre!("")); - } - op.value = res[0]; - op.addr = Some(self.memories.len()); - program.push(op.clone()); - - self.memories.insert(name.text, Memory { loc: op.loc, id: self.memories.len() }); - - } - - OpType::Keyword(KeywordType::Function) => { - if rtokens.is_empty() { - lerror!(&op.loc, "Function name not found, expected {} but found nothing", TokenType::Word.human()); - return Err(eyre!("")); - } - - let mut name = rtokens.pop().unwrap(); - - if let '0'..='9' = name.text.chars().next().unwrap() { - lerror!(&name.loc, "Function name starts with a number which is not allowed"); - return Err(eyre!("")); - } - - // let mut should_warn = false; - for c in name.text.clone().chars() { - match c { - 'a'..='z' | - 'A'..='Z' | - '0'..='9' | - '-' | '_' => (), - '(' | ')' => { - name.text = name.text.clone().replace('(', "__OP_PAREN__").replace(')', "__CL_PAREN__"); - } - _ => { - lerror!(&name.loc, "Function name contains '{c}', which is unsupported"); - return Err(eyre!("")); - } - } - } - // if should_warn { - //TODO: add -W option in cli args to enable more warnings - //lwarn!(&function_name.loc, "Function name contains '(' or ')', this character is not supported but will be replaced with '__OP_PAREN__' or '__CL_PAREN__' respectively "); - // } - - self.is_word_available(&name, KeywordType::Function)?; - - - if f_inline { - f_inline = false; - let mut prog: Vec = Vec::new(); - let mut depth = -1; - while !rtokens.is_empty() { - let op = rtokens.pop().unwrap(); - - match op.typ.clone() { - OpType::Instruction(i) => { - match i { - InstructionType::TypeAny | - InstructionType::TypeBool | - InstructionType::TypeInt | - InstructionType::TypePtr | - InstructionType::With | - InstructionType::Returns | - InstructionType::TypeVoid => { - if depth >= 0 { - prog.push(op); - } - }, - _ => prog.push(op) - } - } - OpType::Keyword(k) => { - match k { - KeywordType::Inline | - KeywordType::Include => { - todo!("make error") - }, - KeywordType::FunctionThen => { - if depth >= 0 { - prog.push(op); - } - depth += 1; - }, - KeywordType::FunctionDone => { - if depth == 0 { - break; - } - - depth -= 1; - }, - _ => prog.push(op) - } - } - } - } - let mut pre = self.clone(); - pre.program = prog; - pre.preprocess()?; - prog = pre.get_ops(); - - self.functions.insert(name.text.clone(), Function{ - loc: name.loc.clone(), - name: name.text.clone(), - inline: true, - tokens: Some(prog) - }); - - } else if f_extern { - f_extern = false; - self.functions.insert(name.text.clone(), Function{ - loc: name.loc.clone(), - name: name.text.clone(), - inline: false, - tokens: None - }); - let mut a: Vec = Vec::new(); - let mut fn_def = op.clone(); - a.push(rtokens.pop().unwrap()); - let mut ret = false; - while !rtokens.is_empty() { - let op = rtokens.pop().unwrap(); - // println!("{:?}",op); - a.push(op.clone()); - if op.typ == OpType::Instruction(InstructionType::Returns) { - ret = true; - } - - if op.typ == OpType::Keyword(KeywordType::FunctionThen) { - break; - } - - if op.typ == OpType::Instruction(InstructionType::TypeBool) || - op.typ == OpType::Instruction(InstructionType::TypeInt) || - op.typ == OpType::Instruction(InstructionType::TypePtr) { - - if ret { - fn_def.types.1 += 1; - } else { - fn_def.types.0 += 1; - } - } - } - - fn_def.typ = OpType::Keyword(KeywordType::FunctionDefExported); - fn_def.text = name.text; - // fn_def.set_types(args, rets); - // println!("{:?}", fn_def.types); - program.push(fn_def); - program.append(&mut a); - - - } else { - - self.functions.insert(name.text.clone(), Function{ - loc: name.loc.clone(), - name: name.text.clone(), - inline: false, - tokens: None - }); - - let mut fn_def = op.clone(); - fn_def.typ = OpType::Keyword(KeywordType::FunctionDef); - fn_def.text = name.text; - // println!("{:?}", token); - program.push(fn_def); - } - } - - OpType::Keyword(KeywordType::Constant) => { - if rtokens.is_empty() { - lerror!(&op.loc, "Constant name not found, expected {} but found nothing", TokenType::Word.human()); - return Err(eyre!("")); - } - // println!("{token:?}"); - - let mut name = rtokens.pop().unwrap(); - // let mut should_warn = false; - - if let '0'..='9' = name.text.chars().next().unwrap() { - lerror!(&name.loc, "Constant name starts with a number which is not allowed"); - return Err(eyre!("")); - } - - for c in name.text.clone().chars() { - match c { - 'a'..='z' | - 'A'..='Z' | - '0'..='9' | - '-' | '_' => (), - '(' | ')' => { - // should_warn = true; - name.text = name.text.clone().replace('(', "__OP_PAREN__").replace(')', "__CL_PAREN__"); - } - _ => { - lerror!(&name.loc, "Constant name contains '{c}', which is unsupported"); - return Err(eyre!("")); - } - } - } - // if should_warn { - //TODO: add -W option in cli args to enable more warnings - //lwarn!(&name.loc, "Constant name contains '(' or ')', this character is not supported but will be replaced with '__OP_PAREN__' or '__CL_PAREN__' respectively "); - // } - - self.is_word_available(&name, KeywordType::Constant)?; - - - self.constants.insert(name.text.clone(), Constant{ - loc: name.loc.clone(), - name: name.text.clone(), - }); - - // println!("{:?}", self.constants); - - let mut const_def = op.clone(); - const_def.typ = OpType::Keyword(KeywordType::ConstantDef); - const_def.text = name.text; - - let item = rtokens.pop().unwrap(); - if item.tok_typ == TokenType::Int { - const_def.value = item.value; - } else { - lerror!(&op.loc, "For now only {:?} is allowed in constants", TokenType::Int); - return Err(eyre!("")); - } - - let posibly_end = rtokens.pop(); - // println!("end: {posibly_end:?}"); - if posibly_end.is_none() || posibly_end.unwrap().typ != OpType::Keyword(KeywordType::End) { - lerror!(&op.loc, "Constant was not closed with an 'end' instruction, expected 'end' but found nothing"); - return Err(eyre!("")); - } - // token.value = - - program.push(const_def); - } - - OpType::Keyword(KeywordType::Inline) => { - if f_extern { - lerror!(&op.loc, "Function is already marked as extern, function cannot be inline and extern at the same time"); - return Err(eyre!("")); - } else if f_inline { - lerror!(&op.loc, "Function is already marked as inline, remove this inline Keyword"); - return Err(eyre!("")); - } else { - f_inline = true; - } - } - - OpType::Keyword(KeywordType::Export) => { - if f_inline { - lerror!(&op.loc, "Function is already marked as inline, function cannot be inline and extern at the same time"); - return Err(eyre!("")); - } else if f_extern { - lerror!(&op.loc, "Function is already marked as extern, remove this extern Keyword"); - return Err(eyre!("")); - } else { - f_extern = true; - } - } - - _ => { - program.push(op); - } - } - } - self.program = program; - // println!("has do tokens: {:?}", self.program.iter().map(|t| if t.typ == OpType::Keyword(KeywordType::Do) {Some(t)} else {None} ).collect::>>()); - //* Feel free to fix this horrifying shit - //* i wanna kms - let mut times = 0; - // dbg!(program.clone()); - while self.program.iter().map(|f| { - if f.tok_typ == TokenType::Word && - f.typ != OpType::Instruction(InstructionType::FnCall) && - f.typ != OpType::Instruction(InstructionType::MemUse) && - f.typ != OpType::Keyword(KeywordType::FunctionDef) && - f.typ != OpType::Keyword(KeywordType::FunctionDefExported) && - f.typ != OpType::Keyword(KeywordType::ConstantDef) && - f.typ != OpType::Instruction(InstructionType::ConstUse) { - lookup_word(&f.text, &f.loc) - } else { - OpType::Instruction(InstructionType::PushInt) // i hate myself, this is a randomly picked optype so its happy and works - } - - }).collect::>().contains(&OpType::Instruction(InstructionType::None)){ - - if times >= 50 { - warn!("File import depth maxed out, if the program crashes try reducing the import depth, good luck youll need it"); - break - } - self.expand()?; - times += 1; - } - Ok(self) - } - - pub fn expand(&mut self) -> Result<()> { - let mut program: Vec = Vec::new(); - // println!("{:?}", self.functions); - let mut rtokens = self.program.clone(); - rtokens.reverse(); - - while !rtokens.is_empty() { - let op = rtokens.pop().unwrap(); - let op_type = op.typ.clone(); - if op.tok_typ == TokenType::Word { - match op_type { - OpType::Instruction(InstructionType::None) => { - let m = self.functions.get(&op.text.clone().replace('(', "__OP_PAREN__").replace(')', "__CL_PAREN__")); - let mem = self.memories.get(&op.text); - let cons = self.constants.get(&op.text.clone().replace('(', "__OP_PAREN__").replace(')', "__CL_PAREN__")); - if let Some(m) = m { - if m.inline { - program.append(&mut m.tokens.clone().unwrap()); - } else { - let mut t = op.clone(); - t.typ = OpType::Instruction(InstructionType::FnCall); - t.text = m.name.clone(); - program.push(t.clone()); - } - - // println!("##### {:?}", t); - } else if let Some(mem) = mem { - let mut t = op.clone(); - t.addr = Some(mem.deref().id); - t.typ = OpType::Instruction(InstructionType::MemUse); - program.push(t); - } else if let Some(cons) = cons { - let mut t = op.clone(); - t.text = cons.deref().name.clone(); - t.typ = OpType::Instruction(InstructionType::ConstUse); - program.push(t); - - } else { - lerror!(&op.loc, "Preprocess: Unknown word '{}'", op.text.clone()); - return Err(eyre!("")); - } - } - _ => { - program.push(op.clone()); - } - } - } else { - program.push(op.clone()); - } - - // if op.typ == OpType::Keyword(KeywordType::Do) { - // println!("expand: {:?}", op); - // program.push(op.clone()); - // } - - } - // println!("expand: has do tokens: {:?}", program.iter().map(|t| if t.typ == OpType::Keyword(KeywordType::Do) {Some(t)} else {None} ).collect::>>()); - - self.program = program; - // println!("{:#?}", self.program); - // println!("{:?}", self.program.last().unwrap()); - Ok(()) - } - - - - pub fn get_ops(&mut self) -> Vec { - self.program.clone() - } - pub fn is_word_available(&self, word: &Operator, typ: KeywordType) -> Result { - - match typ { - KeywordType::Memory | - KeywordType::Constant | - KeywordType::Function => (), - _ => panic!() - } - - if word.tok_typ != TokenType::Word { - lerror!(&word.loc, "Bad {typ:?}, expected {} but found {}", TokenType::Word.human(), word.typ.human()); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - - let w = lookup_word(&word.text, &word.loc); - if w != OpType::Instruction(InstructionType::None) { - lerror!(&word.loc, "Bad {typ:?}, {typ:?} definition cannot be builtin word, got {:?}", word.text); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - - let m = self.memories.get(&word.text); - if let Some(m) = m { - if typ == KeywordType::Memory { - lerror!(&word.loc, "Memories cannot be redefined, got {}", word.text); - linfo!(&m.loc, "first definition here"); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - lerror!(&word.loc, "{typ:?} cannot replace memory, got {}", word.text); - linfo!(&m.loc, "first definition here"); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - let f = self.functions.get(&word.text); - if let Some(f) = f { - if typ == KeywordType::Function { - lerror!(&word.loc, "Functions cannot be redefined, got {}", word.text); - linfo!(&f.loc, "first definition here"); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - lerror!(&word.loc, "{typ:?} cannot replace function, got {}", word.text); - linfo!(&f.loc, "first definition here"); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - let c = self.constants.get(&word.text); - if let Some(c) = c { - if typ == KeywordType::Constant { - lerror!(&word.loc, "Constants cannot be redefined, got {}", word.text); - linfo!(&c.loc, "first definition here"); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - lerror!(&word.loc, "{typ:?} cannot replace constant, got {}", word.text); - linfo!(&c.loc, "first definition here"); - if crate::DEV_MODE {println!("{word:?}")} - return Err(eyre!("")); - } - - Ok(true) - } - - pub fn set_functions(&mut self, f: Functions) { - self.functions = f; - } - pub fn set_constants(&mut self, f: Constants) { - self.constants = f; - } - pub fn set_memories(&mut self, f: Memories) { - self.memories = f; - } - - pub fn get_functions(&mut self) -> Functions { - self.functions.clone() - } - pub fn get_constants(&mut self) -> Constants { - self.constants.clone() - } - pub fn get_memories(&mut self) -> Memories{ - self.memories.clone() - } -} \ No newline at end of file diff --git a/src/typechecker.rs b/src/typechecker.rs deleted file mode 100644 index 1d256b0..0000000 --- a/src/typechecker.rs +++ /dev/null @@ -1,403 +0,0 @@ -use std::collections::HashMap; - -use crate::{constants::{Operator, Types, OpType, KeywordType, InstructionType, Loc}, Args, lerror, warn}; -use color_eyre::Result; -use eyre::eyre; - -#[allow(dead_code)] -#[derive(Debug, Clone)] -pub struct Function { - loc: Loc, - args: Vec, - returns: Vec, -} - -#[derive(Debug, Clone)] -pub struct Constant { - #[allow(dead_code)] - loc: Loc, - types: Vec, -} - -impl Function { - #[allow(dead_code)] - pub fn default() -> Self { - Self { - args: Vec::new(), - returns: Vec::new(), - loc: (String::new(), 0, 0) - } - } -} - -type Functions = HashMap; -type Constants = HashMap; - -pub fn typecheck(ops: Vec, args: &Args, init_types: Option>, funcs: HashMap, consts: HashMap) -> Result<(Vec, Functions, Constants)>{ - if args.unsaf { - if !args.quiet { - warn!("Unsafe mode enabled, disabling typechecker, goodluck"); - } - return Ok((Vec::new(), HashMap::new(), HashMap::new())); - } - - let mut functions: HashMap = funcs; - let mut constants: HashMap = consts; - // let mut in_function: (String, Function, Loc) = (String::new(), Function::default(), (String::new(), 0, 0)); - let mut stack: Vec = if let Some(i) = init_types {i} else {Vec::new()}; - let mut stack_snapshots: Vec> = Vec::new(); - let mut rtokens = ops; - rtokens.reverse(); - // println!("{:#?}", ops); - while !rtokens.is_empty() { - let op = rtokens.pop().unwrap(); - // println!("{:?}", stack.clone()); - // println!("{:?}", op); - // println!("{}", ops.len()); - match op.typ.clone() { - OpType::Keyword(keyword) => { - match keyword { - KeywordType::If | - KeywordType::Do => { - stack_pop(&mut stack, &op, &[Types::Bool])?; - }, - - KeywordType::FunctionDefExported | - KeywordType::FunctionDef => { - let name = op.text.clone(); - // println!("{:?}", name); - if let Some(p) = rtokens.pop() { - if p.typ != OpType::Instruction(InstructionType::With){ - lerror!(&op.loc, "Expected {:?}, got {:?}", OpType::Instruction(InstructionType::With), p.typ); - return Err(eyre!("")); - } - - } else { - lerror!(&op.loc, "Expected {:?}, got nothing", OpType::Instruction(InstructionType::With)); - return Err(eyre!("")); - } - - let mut p = rtokens.pop(); - let mut func = Function { - args: Vec::new(), - returns: Vec::new(), - loc: op.loc - }; - let mut return_args = false; - while p.as_ref().is_some() { - let op = p.as_ref().unwrap(); - if op.typ == OpType::Instruction(InstructionType::TypeBool) || - op.typ == OpType::Instruction(InstructionType::TypeInt) || - op.typ == OpType::Instruction(InstructionType::TypePtr) || - op.typ == OpType::Instruction(InstructionType::TypeAny) || - op.typ == OpType::Instruction(InstructionType::TypeVoid) { - let t = if op.typ == OpType::Instruction(InstructionType::TypeInt) { - Types::Int - } else if op.typ == OpType::Instruction(InstructionType::TypeBool) { - Types::Bool - } else if op.typ == OpType::Instruction(InstructionType::TypePtr) { - Types::Ptr - } else if op.typ == OpType::Instruction(InstructionType::TypeVoid) { - if return_args { - func.returns = vec![Types::Void]; - } else { - func.args = vec![Types::Void]; - return_args = true; - continue; - } - Types::Void - } else if op.typ == OpType::Instruction(InstructionType::TypeAny) { - Types::Any - } else { - panic!() - }; - - if return_args { - func.returns.push(t); - } else { - func.args.push(t); - } - } - - if op.typ == OpType::Instruction(InstructionType::Returns) { - return_args = true; - } - - if op.typ == OpType::Keyword(KeywordType::FunctionThen) { - break; - } - p = rtokens.pop(); - }; - - - let mut code: Vec = Vec::new(); - - while !rtokens.is_empty() { - let op = rtokens.pop().unwrap(); - - if op.typ == OpType::Keyword(KeywordType::FunctionDone) { - break; - } - code.push(op); - } - let ts = if func.args.clone() == vec![Types::Void] { - Vec::new() - } else { - func.args.clone() - }; - - if ts.contains(&Types::Void) { - continue; - } - functions.insert(name.clone(), func.clone()); - let (ret_typs, _, _) = typecheck(code, args, Some(ts.clone()), functions.clone(), constants.clone())?; - if ret_typs != func.returns && !func.returns.contains(&Types::Void){ - lerror!(&func.loc, "Expected {:?}, but got {:?}", func.returns, ret_typs); - return Err(eyre!("")) - } - - if !func.args.contains(&Types::Void) { - stack.append(&mut func.args); - } - stack_snapshots.push(stack.clone()); - } - - KeywordType::Else | - KeywordType::End | - KeywordType::While | - KeywordType::Include | - KeywordType::Constant | - KeywordType::Memory => (), - KeywordType::ConstantDef => { - // println!("defined constant"); - constants.insert(op.text, Constant { loc: op.loc.clone(), types: vec![Types::Int] }); - - }, - KeywordType::FunctionThen | - KeywordType::FunctionDone | - KeywordType::Inline | - KeywordType::Export | - KeywordType::Function => { - println!("{:?}", op); - unreachable!() - }, - } - }, - OpType::Instruction(instruction) => { - match instruction { - InstructionType::PushInt => { - stack.push(Types::Int); - }, - InstructionType::PushStr => { - stack.push(Types::Int); - stack.push(Types::Ptr); - - }, - InstructionType::Drop => { - stack_pop(&mut stack, &op, &[Types::Any])?; - }, - InstructionType::Print => { - stack_pop(&mut stack, &op, &[Types::Int])?; - }, - InstructionType::Dup => { - let a = stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(a); - }, - InstructionType::Rot => { - let a = stack_pop(&mut stack, &op, &[Types::Any])?; - let b = stack_pop(&mut stack, &op, &[Types::Any])?; - let c = stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(b); - stack.push(a); - stack.push(c); - }, - InstructionType::Over => { - let a = stack_pop(&mut stack, &op, &[Types::Any])?; - let b = stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(b.clone()); - stack.push(a); - stack.push(b); - }, - InstructionType::Swap => { - let a = stack_pop(&mut stack, &op, &[Types::Any])?; - let b = stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(a); - stack.push(b); - }, - InstructionType::Minus | - InstructionType::Plus | - InstructionType::Band | - InstructionType::Bor | - InstructionType::Shr | - InstructionType::Shl | - InstructionType::Mul => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Int])?; - stack.push(Types::Int); - }, - InstructionType::Equals | - InstructionType::Gt | - InstructionType::Lt | - InstructionType::Ge | - InstructionType::Le | - InstructionType::NotEquals => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Int])?; - stack.push(Types::Bool); - }, - InstructionType::DivMod => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Int])?; - stack.push(Types::Int); - stack.push(Types::Int); - }, - InstructionType::Load8 | - InstructionType::Load32 | - InstructionType::Load64 => { - stack_pop(&mut stack, &op, &[Types::Ptr])?; - stack.push(Types::Int); - }, - InstructionType::Store8 | - InstructionType::Store32 | - InstructionType::Store64 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Ptr])?; - }, - InstructionType::Syscall0 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack.push(Types::Int); - }, - InstructionType::Syscall1 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Int); - }, - InstructionType::Syscall2 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Int); - }, - InstructionType::Syscall3 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Int); - }, - InstructionType::Syscall4 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Int); - }, - InstructionType::Syscall5 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Int); - }, - InstructionType::Syscall6 => { - stack_pop(&mut stack, &op, &[Types::Int])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Int); - }, - InstructionType::CastBool => { - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Bool); - }, - InstructionType::CastPtr => { - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Ptr); - }, - InstructionType::CastInt => { - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Int); - }, - InstructionType::CastVoid => { - stack_pop(&mut stack, &op, &[Types::Any])?; - stack.push(Types::Any); - }, - InstructionType::MemUse => { - stack.push(Types::Ptr); - }, - InstructionType::FnCall => { - stack_snapshots.push(stack.clone()); - - let f = if let Some(f) = functions.get(&op.text) {f} else { - lerror!(&op.loc, "Could not find function {}", op.text); - return Err(eyre!("")); - }; - - // in_function = (op.text.clone(), f.clone(), op.loc.clone()); - - let mut s = stack.clone(); - let mut a = f.args.clone(); - // s.reverse(); - a.reverse(); - - for t in a{ - if let Some(s2) = s.pop(){ - if t != s2 { - lerror!(&op.loc, "Expected {:?}, but got {:?}", t, s2); - return Err(eyre!("")); - } - } else { - lerror!(&op.loc, "Expected {:?}, but got nothing", t); - return Err(eyre!("")); - } - } - - - } - InstructionType::Return | - InstructionType::None | - InstructionType::TypeBool | - InstructionType::TypePtr | - InstructionType::TypeInt | - InstructionType::TypeVoid | - InstructionType::TypeAny | - InstructionType::Returns | - InstructionType::With => (), - InstructionType::ConstUse => { - // println!("{constants:?}"); - let mut c = constants.get(&op.text).unwrap().clone(); - stack.append(&mut c.types); - }, - } - }, - - } - - - } - - Ok((stack, functions, constants)) -} - - - -fn stack_pop(v: &mut Vec, op: &Operator, t: &[Types]) -> Result { - if v.is_empty() { - lerror!(&op.loc, "Expected {:?}, but got nothing", t); - return Err(eyre!("")); - } - let r = v.pop().unwrap(); - - if !t.contains(&r) && t[0] != Types::Any { - lerror!(&op.loc, "Expected {:?}, but got {:?}", t, r); - return Err(eyre!("")); - } - - Ok(r) -} diff --git a/src/types/ast/mod.rs b/src/types/ast/mod.rs new file mode 100644 index 0000000..204c120 --- /dev/null +++ b/src/types/ast/mod.rs @@ -0,0 +1,215 @@ +use std::collections::HashMap; + +use super::{common::Loc, token::{Token, TypeType}}; + + +//TODO: Implement missing stuff +#[derive(Debug, Clone)] +pub enum AstNode { + Int(Loc, usize), + Str(Loc, String), + CStr(Loc, String), + Char(Loc, char), + // ExternFnDef { + // loc: Loc, + // ident: String, + // arg_types: Vec, + // ret_type: TokenType, + // }, + Function(Function), + Constant(Constant), + // ExternConstantDef{ + // loc: Loc, + // ident: String, + // value: InstructionType + // }, + // StructDef{ + // loc: Loc, + // extrn: bool, + // ident: String, + // body: Vec<(String, usize)> // (field ident, size in bytes) + // }, + StructDef(StructDef), + StructDispPush{ + loc: Loc, + disp: usize, + ident: String, + }, + // StructItemPush{ + // loc: Loc, + // disp: usize, + // ident: String, + // }, + If(If), + While(While), + Module(Module), + Memory(Memory), + MemUse(MemUse), + ConstUse(ConstUse), + FnCall(FnCall), + Block(Block), + Token(Token), +} + +impl AstNode { + pub fn loc(&self) -> Loc { + match self { + AstNode::Function(f) => f.loc.clone(), + AstNode::Constant(c) => c.loc.clone(), + AstNode::If(t)=> t.loc.clone(), + AstNode::While(t)=> t.loc.clone(), + AstNode::Module(m) => m.loc.clone(), + AstNode::Memory(m) => m.loc.clone(), + AstNode::MemUse(t)=> t.loc.clone(), + AstNode::ConstUse(t)=> t.loc.clone(), + AstNode::FnCall(t)=> t.loc.clone(), + AstNode::Block(t)=> t.loc.clone(), + AstNode::Token(tok) => tok.loc.clone(), + AstNode::Int(loc, _) => loc.clone(), + AstNode::Str(loc, _) => loc.clone(), + AstNode::CStr(loc, _) => loc.clone(), + AstNode::Char(loc, _) => loc.clone(), + AstNode::StructDef(s) => s.loc.clone(), + AstNode::StructDispPush { loc, ..} => loc.clone(), + // AstNode::StructItemPush { loc, .. } => loc.clone(), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct StructDef { + pub loc: Loc, + pub ident: String, + pub body: Vec<(String, usize, TypeType)>, // (field ident, size in bytes) + pub size: usize +} +#[derive(Debug, Clone)] +pub struct MemUse { + pub loc: Loc, + pub ident: String, + pub disp: Option +} +#[derive(Debug, Clone)] +pub struct ConstUse { + pub loc: Loc, + pub ident: String, +} +#[derive(Debug, Clone)] +pub struct FnCall { + pub loc: Loc, + pub ident: String, +} +#[derive(Debug, Clone)] +pub struct Block { + pub comment: String, + pub loc: Loc, + pub body: Vec +} + +#[derive(Debug, Clone)] +pub struct While { + pub loc: Loc, + pub test: Vec, + pub body: Vec, +} + +#[derive(Debug, Clone)] +pub struct If { + pub loc: Loc, + pub test: Vec, + pub body: Vec, + pub els: Box, +} + +#[derive(Debug, Clone)] +pub struct Module { + pub loc: Loc, + pub path: Vec, + pub ident: String, + pub body: Vec +} + +#[derive(Debug, Clone)] +pub struct Function { + pub loc: Loc, + pub ident: String, + pub inline: bool, + pub extrn: bool, + pub export: bool, + pub arg_types: Vec, + pub ret_types: Vec, + pub body: Vec +} + +#[derive(Debug, Clone)] +pub struct Constant { + pub loc: Loc, + pub ident: String, + pub value: Box +} + +#[derive(Debug, Clone)] +pub struct Memory { + pub loc: Loc, + pub ident: String, + pub statc: bool, + pub size: MemSize // bytes +} + + +#[derive(Debug, Clone)] +pub struct Program { + pub ast: AstNode, + pub functions: HashMap, + pub constants: HashMap, + pub memories: HashMap, + pub struct_defs: HashMap, +} + +#[derive(Debug, Clone)] +pub enum MemSize { + Size(usize), + Type(TypeType) +} + +impl EscIdent for FnCall { + fn ident(&self) -> String { + self.ident.clone() + } +} + +impl EscIdent for ConstUse { + fn ident(&self) -> String { + self.ident.clone() + } +} + +impl EscIdent for MemUse { + fn ident(&self) -> String { + self.ident.clone() + } +} + +impl EscIdent for Constant { + fn ident(&self) -> String { + self.ident.clone() + } +} +impl EscIdent for Memory { + fn ident(&self) -> String { + self.ident.clone() + } +} +impl EscIdent for Function { + fn ident(&self) -> String { + self.ident.clone() + } +} + +pub trait EscIdent { + fn ident(&self) -> String; + fn get_ident_escaped(&self) -> String { + self.ident().replace("(", "_OPRN_") + .replace(")", "_CPRN_") + } +} \ No newline at end of file diff --git a/src/types/common.rs b/src/types/common.rs new file mode 100644 index 0000000..1ac7443 --- /dev/null +++ b/src/types/common.rs @@ -0,0 +1,37 @@ +use std::fmt::Display; + + +#[derive(Debug, Clone, Default, PartialEq)] +pub struct Loc { + pub file: String, + pub line: usize, + pub col: usize +} + + +impl Loc { + pub fn new>(f: T, line: usize, col: usize) -> Self { + Self { + file: f.into(), + line, + col, + } + } + pub fn inc_line(&mut self) { + self.line += 1; + self.col = 0; + } + + pub fn inc_col(&mut self) { + self.col += 1; + } +} + +impl Display for Loc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}:{}:{}", self.file, self.line, self.col)?; + Ok(()) + } +} + + diff --git a/src/types/mod.rs b/src/types/mod.rs new file mode 100644 index 0000000..286aa7f --- /dev/null +++ b/src/types/mod.rs @@ -0,0 +1,3 @@ +pub mod common; +pub mod token; +pub mod ast; diff --git a/src/types/token/mod.rs b/src/types/token/mod.rs new file mode 100644 index 0000000..8b33b3a --- /dev/null +++ b/src/types/token/mod.rs @@ -0,0 +1,162 @@ +#![allow(dead_code)] + +use super::{ast::StructDef, common::Loc}; + +#[derive(Debug, Clone, PartialEq)] +pub enum InstructionType { + + // stack + PushInt(usize), + PushStr(String), + PushCStr(String), + PushChar(char), + StructPath(Vec), // foo::bar + StructItem(Vec), // foo.bar + Drop, + Print, + Dup, + Rot, // a b c => b c a + Over, // a b => a b a + Swap, // a b => b a + + // math + Minus, + Plus, + Equals, + Gt, + Lt, + Ge, + Le, + NotEquals, + Band, // & + Bor, // | + Shr, // >> + Shl, // << + DivMod, // / + Mul, + + + // mem + Read8, + Write8, + Read32, + Write32, + Read64, + Write64, + + // syscalls + Syscall0, + Syscall1, + Syscall2, + Syscall3, + Syscall4, + Syscall5, + Syscall6, + + CastBool, + CastPtr, + CastInt, + CastVoid, + + FnCall, + MemUse, + ConstUse, + + Return, +} +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum KeywordType { + If, + Else, + End, + While, + Do, + Include, + Memory, + Constant, + Function, + Then, + Done, + StructDef, + TypeDef, + Inline, + Export, + Extern, + Returns, + With, +} + +#[derive(Clone, PartialEq)] +pub enum TypeType { + Ptr, + U8, + U16, + U32, + U64, + Void, + Any, + Custom(Vec), + Struct(StructDef) +} + +impl TypeType { + pub fn get_size(&self) -> usize { + match self { + TypeType::Ptr => std::mem::size_of::<*const ()>(), + TypeType::U8 => 1, + TypeType::U16 => 2, + TypeType::U32 => 4, + TypeType::U64 => 8, + TypeType::Void => 0, + TypeType::Any => 0, + TypeType::Custom(ts) => ts.iter().map(|f| f.get_size()).sum(), + TypeType::Struct(s) => s.size, + } + } +} + +impl std::fmt::Debug for TypeType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Ptr => write!(f, "Ptr"), + Self::U8 => write!(f, "U8"), + Self::U16 => write!(f, "U16"), + Self::U32 => write!(f, "U32"), + Self::U64 => write!(f, "U64"), + Self::Void => write!(f, "Void"), + Self::Any => write!(f, "Any"), + Self::Custom(arg0) => f.debug_tuple("Custom").field(arg0).finish(), + Self::Struct(arg0) => write!(f, "{} {}{:?}", arg0.size, arg0.ident, arg0.body), + } + } +} + + +#[derive(Debug, Clone, PartialEq)] +pub enum TokenType { + Keyword(KeywordType), + Type(TypeType), + Instruction(InstructionType), + Unknown(String) +} + + +#[derive(Debug, Clone, PartialEq)] +pub struct Token { + pub typ: TokenType, + pub loc: Loc, + pub lexem: String, +} + +impl Token { + pub fn new(typ: TokenType, loc: Loc, lexem: String) -> Self { + Self { + typ, + loc, + lexem, + } + } + pub fn loc(&self) -> Loc { + self.loc.clone() + } +} \ No newline at end of file diff --git a/src/util.rs b/src/util.rs deleted file mode 100644 index 15b41ac..0000000 --- a/src/util.rs +++ /dev/null @@ -1,117 +0,0 @@ -// use color_eyre::Result; - -pub mod color { - #![allow(dead_code)] - pub const NONE: &str = "\x1b[0m"; - pub const RESET: &str = "\x1b[0m"; - pub const BRIGHT: &str = "\x1b[1m"; - pub const DIM: &str = "\x1b[2m"; - pub const UNDERSCORE: &str = "\x1b[4m"; - pub const BLINK: &str = "\x1b[5m"; - pub const REVERSE: &str = "\x1b[7m"; - pub const HIDDEN: &str = "\x1b[8m"; - pub const FG_BLACK: &str = "\x1b[30m"; - pub const FG_RED: &str = "\x1b[31m"; - pub const FG_GREEN: &str = "\x1b[32m"; - pub const FG_YELLOW: &str = "\x1b[33m"; - pub const FG_BLUE: &str = "\x1b[34m"; - pub const FG_MAGENTA: &str = "\x1b[35m"; - pub const FG_CYAN: &str = "\x1b[36m"; - pub const FG_WHITE: &str = "\x1b[37m"; - pub const BG_BLACK: &str = "\x1b[40m"; - pub const BG_RED: &str = "\x1b[41m"; - pub const BG_GREEN: &str = "\x1b[42m"; - pub const BG_YELLOW: &str = "\x1b[43m"; - pub const BG_BLUE: &str = "\x1b[44m"; - pub const BG_MAGENTA: &str = "\x1b[45m"; - pub const BG_CYAN: &str = "\x1b[46m"; - pub const BG_WHITE: &str = "\x1b[47m"; -} - -pub mod logger { - #![allow(dead_code)] - use std::ops::Deref; - - use crate::{util::color, constants::Loc}; - - pub fn error(msg: &str) { - println!("{red}error{r}: {msg}", red=color::FG_RED, r=color::RESET); - } - - pub fn warn(msg: &str) { - println!("{yellow}warn{r}: {msg}", yellow=color::FG_YELLOW, r=color::RESET); - } - - pub fn info(msg: &str) { - println!("{green}info{r}: {msg}", green=color::FG_GREEN, r=color::RESET); - } - - pub fn note(msg: &str) { - println!("{blue}note{r}: {msg}", blue=color::FG_BLUE, r=color::RESET); - } - - - pub fn lerror>(loc: P, msg: &str) { - println!("{f}:{r}:{c} {red}error{rs}: {msg}", red=color::FG_RED, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2); - } - - pub fn lwarn>(loc: P, msg: &str) { - println!("{f}:{r}:{c} {yellow}warn{rs}: {msg}", yellow=color::FG_YELLOW, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2); - } - - pub fn linfo>(loc: P, msg: &str) { - println!("{f}:{r}:{c} {green}info{rs}: {msg}", green=color::FG_GREEN, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2); - } - - pub fn lnote>(loc: P, msg: &str) { - println!("{f}:{r}:{c} {blue}note{rs}: {msg}", blue=color::FG_BLUE, rs=color::RESET, f=loc.0, r=loc.1, c=loc.2); - } - - pub fn help(msg: &str) { - println!("{blue}help{r}: {msg}", blue=color::FG_CYAN, r=color::RESET); - } - - pub fn code_block(code: &str) -> String { - let mut ret = String::new(); - let lines = code.lines(); - - for (i, line) in lines.enumerate() { - use std::fmt::Write; - writeln!(ret, "{}{} | {}{}",color::FG_BLUE, i + 1, line, color::RESET).unwrap(); - } - ret - } - pub mod macros { - #[macro_export] macro_rules! error { ($($arg:tt)*) => { $crate::util::logger::error(std::format_args!($($arg)*).to_string().as_str()) }; } - #[macro_export] macro_rules! warn { ($($arg:tt)*) => { $crate::util::logger::warn( std::format_args!($($arg)*).to_string().as_str()) }; } - #[macro_export] macro_rules! info { ($($arg:tt)*) => { $crate::util::logger::info( std::format_args!($($arg)*).to_string().as_str()) }; } - #[macro_export] macro_rules! note { ($($arg:tt)*) => { $crate::util::logger::note( std::format_args!($($arg)*).to_string().as_str()) }; } - - #[macro_export] macro_rules! lerror { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::lerror($dst, std::format_args!($($arg)*).to_string().as_str()) }; } - #[macro_export] macro_rules! lwarn { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::lwarn($dst, std::format_args!($($arg)*).to_string().as_str()) }; } - #[macro_export] macro_rules! linfo { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::linfo($dst, std::format_args!($($arg)*).to_string().as_str()) }; } - #[macro_export] macro_rules! lnote { ($dst:expr, $($arg:tt)*) => { $crate::util::logger::lnote($dst, std::format_args!($($arg)*).to_string().as_str()) }; } - - #[macro_export] macro_rules! help { ($($arg:tt)*) => { $crate::util::logger::help( std::format_args!($($arg)*).to_string().as_str()) }; } - #[macro_export] macro_rules! code_block { ($($arg:tt)*) => { $crate::util::logger::code_block( std::format_args!($($arg)*).to_string().as_str()) }; } - } - -} - -// pub trait StringExtra{ -// fn find_idx(&self, pat: char, start: u32) -> Result; -// } -// impl StringExtra for String { -// fn find_idx(&self, pat: char, start: u32) -> Result { -// let mut col = start; - -// for c in (*self).chars() { -// if c == pat { -// return Ok(col); -// } -// col += 1; -// } -// Err(()) - -// } -// } \ No newline at end of file diff --git a/test.mcl b/test.mcl index 4e424cf..a7131f2 100644 --- a/test.mcl +++ b/test.mcl @@ -1,12 +1,49 @@ -// include "std.mcl" -fn mcl_print with int ptr returns void then - 1 1 syscall3 drop +include "std.mcl" + +structdef Uwu do + owo do u64 end + twt do u64 end done -fn mcl_dump with int returns void then - _dbg_print +structdef Foo do + buz do u64 end + uwu do Uwu end done + +memory s_foo Foo end + +//? Comments :3 + +// extern fn a with void returns void then done +// inline fn b with void returns void then done +// export fn c with void returns void then done + +// fn putd with int returns void then drop done + fn main with void returns void then - "hi\n" mcl_print + + s_foo.uwu.twt 69 write64 + + s_foo.uwu.twt read64 _dbg_print + // 1 2 add + // 69 _dbg_print + // "Hewo\n" puts + + // if 3 4 eq do + // "omg what impossible!\n" + // else if 1 1 eq do + // "whaaaaaaaaa\n" + // else + // "finally, some good soup\n" + // done + // puts + + // 10 + // while dup 0 gt do + // "uwu " puts + // dup _dbg_print + // 1 sub + // done + done diff --git a/tests/fail_unknown_word.mcl b/tests/fail_unknown_word.mcl deleted file mode 100644 index 13724a0..0000000 --- a/tests/fail_unknown_word.mcl +++ /dev/null @@ -1 +0,0 @@ -gftdesd5ryutfgyhibugtf6r4 \ No newline at end of file diff --git a/tests/math.mcl b/tests/math.mcl deleted file mode 100644 index 89d4cd5..0000000 --- a/tests/math.mcl +++ /dev/null @@ -1,7 +0,0 @@ -34 35 + print - -800 380 - print - -10 5 * print - -40 5 / print \ No newline at end of file