switching language to tswq

This commit is contained in:
2025-08-17 16:10:13 -06:00
parent f554b09efc
commit 03662d980f
26 changed files with 573 additions and 4596 deletions

130
.gitignore vendored
View File

@@ -1,112 +1,36 @@
# Byte-compiled / optimized / DLL files .direnv/
__pycache__/
*.py[cod]
*$py.class
# C extensions # dependencies (bun install)
*.so node_modules
# Distribution / packaging # output
.Python out
build/ dist
develop-eggs/ *.tgz
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller # code coverage
# Usually these files are written by a python script from a template coverage
# before PyInstaller builds the exe, so as to inject date/other infos into it. *.lcov
*.manifest
*.spec
# Installer logs # logs
pip-log.txt logs
pip-delete-this-directory.txt _.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# Unit test / coverage reports # dotenv environment variable files
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env .env
.venv .env.development.local
env/ .env.test.local
venv/ .env.production.local
ENV/ .env.local
env.bak/
venv.bak/
# Spyder project settings # caches
.spyderproject .eslintcache
.spyproject .cache
*.tsbuildinfo
# Rope project settings # IntelliJ based IDEs
.ropeproject .idea
# mkdocs documentation # Finder (MacOS) folder config
/site .DS_Store
# mypy
.mypy_cache/
#Added by cargo
#
#already existing elements are commented out
/target
**/*.rs.bk

View File

@@ -1 +0,0 @@
max_width=140 # Not ideal

501
Cargo.lock generated
View File

@@ -1,501 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "ascii-canvas"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6"
dependencies = [
"term",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bit-set"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "boring-lang"
version = "0.0.1"
dependencies = [
"clap",
"lalrpop",
"lalrpop-util",
"regex",
"thiserror",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "diff"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "ena"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
dependencies = [
"log",
]
[[package]]
name = "fixedbitset"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "indexmap"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]
[[package]]
name = "lalrpop"
version = "0.19.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15174f1c529af5bf1283c3bc0058266b483a67156f79589fab2a25e23cf8988"
dependencies = [
"ascii-canvas",
"atty",
"bit-set",
"diff",
"ena",
"itertools",
"lalrpop-util",
"petgraph",
"pico-args",
"regex",
"regex-syntax",
"string_cache",
"term",
"tiny-keccak",
"unicode-xid",
]
[[package]]
name = "lalrpop-util"
version = "0.19.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3e58cce361efcc90ba8a0a5f982c741ff86b603495bb15a998412e957dcd278"
dependencies = [
"regex",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "once_cell"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "petgraph"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom",
"redox_syscall",
]
[[package]]
name = "regex"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]]
name = "rustversion"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
[[package]]
name = "siphasher"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1"
[[package]]
name = "string_cache"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a"
dependencies = [
"lazy_static",
"new_debug_unreachable",
"phf_shared",
"precomputed-hash",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123a78a3596b24fee53a6464ce52d8ecbf62241e6294c7e7fe12086cd161f512"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
"once_cell",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@@ -1,18 +0,0 @@
[package]
name = "boring-lang"
version = "0.0.1"
authors = ["asegavac"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies.lalrpop] # <-- We added this and everything after!
version = "0.19.6"
features = ["lexer"]
[dependencies]
lalrpop-util = "0.19.6"
regex = "1"
# inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "llvm7-0" }
clap = "2.33.0"
thiserror = "1"

View File

@@ -1,5 +0,0 @@
FROM rust:1.89
# RUN apt update && apt-get install -y llvm clang
RUN rustup component add rustfmt
WORKDIR /code

View File

@@ -1,5 +0,0 @@
extern crate lalrpop;
fn main() {
lalrpop::process_root().unwrap();
}

412
bun.lock Normal file
View File

@@ -0,0 +1,412 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "boringlang",
"dependencies": {
"ohm-js": "^17.2.1",
},
"devDependencies": {
"@types/bun": "latest",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
"jiti": "^2.5.1",
"prettier": "^3.6.2",
"typescript": "^5.9.2",
"typescript-language-server": "^4.4.0",
"vscode-langservers-extracted": "^4.10.0",
},
},
"packages/boringlang": {
"name": "boringlang",
"version": "0.1.0",
"dependencies": {
"@bunli/core": "latest",
},
"devDependencies": {
"@bunli/test": "latest",
"@types/bun": "latest",
"bunli": "latest",
},
},
},
"packages": {
"@bunli/core": ["@bunli/core@0.1.0", "", { "dependencies": { "@bunli/utils": "0.1.0", "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0" } }, "sha512-+1hZ3cLgFLbpXndHhxZDkGNYj8zLvxmTSW4y+Kna6sJXI/L1lKaQGZBzu8+LmUckG+25BMydgocP59yaRURRag=="],
"@bunli/test": ["@bunli/test@0.1.0", "", { "dependencies": { "@bunli/core": "0.1.0" }, "peerDependencies": { "bun": ">=1.0.0" } }, "sha512-kSvZ/CxoJ6xZLTCEF53bJnOqAGsMI2qd5oq9PwW9n4wPvnJhHO624+cS+1LHUhmCc68LzI0QyxoWTZJ1SnUqAg=="],
"@bunli/utils": ["@bunli/utils@0.1.0", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "bun": ">=1.0.0" } }, "sha512-2KR4ZWhkFzRR4PYc9FB0Y738Xle98Heyr8se6YK+vetDXxhlBiM4W2WZ7IBHmZn12PcXedc5DBvDjrvOdXXv/Q=="],
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
"@eslint/config-array": ["@eslint/config-array@0.21.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ=="],
"@eslint/config-helpers": ["@eslint/config-helpers@0.3.1", "", {}, "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="],
"@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="],
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
"@eslint/js": ["@eslint/js@9.33.0", "", {}, "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A=="],
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
"@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
"@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.2.20", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zygk+yeaww9kBw2JBWwA13KyOKySxbnetms/WyRFaUYhxiuJHkzv1c6/Ou7sIHa9Gbq4fYQEhx88Ywy1wu2oTQ=="],
"@oven/bun-darwin-x64": ["@oven/bun-darwin-x64@1.2.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-k2akVmSvJHuzpwgwIU8ltary7EQbqlbvxgtYlVqYvnqUpRdRbkuJXAZhN5zuDNTftaG4l22Q/bX04tBB8Txmjg=="],
"@oven/bun-darwin-x64-baseline": ["@oven/bun-darwin-x64-baseline@1.2.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-bxXZlLD6DJ8rc/Ht0Cgm0BH1AJVO/axOElXJP42LUUKQ/U4t3OKkFDbFiTPGphcy5teMLkoYl+a2Cz8P9q2gVQ=="],
"@oven/bun-linux-aarch64": ["@oven/bun-linux-aarch64@1.2.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-g+CzF02RzKgSmuEHNLoDTtiiQR33cEZWcd/tWR+24h92xe5wXuqQsV7vQJLR6e44BWkDOACpTIrfW4UAaHw4Cw=="],
"@oven/bun-linux-aarch64-musl": ["@oven/bun-linux-aarch64-musl@1.2.20", "", { "os": "linux", "cpu": "none" }, "sha512-zB3aKckyUdKENLP+lm/PoXQPBTthJsY7dhYih+qVT95N29acLO2eWeSHgRkS7Pl2FV+mLJo9LvjRhC8oaSSoOw=="],
"@oven/bun-linux-x64": ["@oven/bun-linux-x64@1.2.20", "", { "os": "linux", "cpu": "x64" }, "sha512-KJZ0zJKadKCD6EI/mBv/0PUysMpd1r4o3WhQ73PjCZx2w95Ka2fSBAIsy9e/rxc07D4LHr26nGyMmC1K8IcS6Q=="],
"@oven/bun-linux-x64-baseline": ["@oven/bun-linux-x64-baseline@1.2.20", "", { "os": "linux", "cpu": "x64" }, "sha512-xtYPn84ur9U7YaS0+rwjs6YMgSv5Z4gMnqPQ1QTLw92nt1v9Cw17YypVab4zUk222o5Y6kS3DRkDdSHBh8uQfA=="],
"@oven/bun-linux-x64-musl": ["@oven/bun-linux-x64-musl@1.2.20", "", { "os": "linux", "cpu": "x64" }, "sha512-XPtQITGbJXgUrMXOJo3IShwQd3awB93ZIh5+4S3DF9Ek/lwXVSuueIIAfnveR/r9JRgEA5+g/1ZHVf1/3qaElg=="],
"@oven/bun-linux-x64-musl-baseline": ["@oven/bun-linux-x64-musl-baseline@1.2.20", "", { "os": "linux", "cpu": "x64" }, "sha512-rANapFZRrgOTeotaf556iIxguyjQbensL6gT3cXZDnXG+aVhv65hSnjqzM7vfHxlzoXbAmoUkJOpce0qEg/HlA=="],
"@oven/bun-windows-x64": ["@oven/bun-windows-x64@1.2.20", "", { "os": "win32", "cpu": "x64" }, "sha512-Jt4bAf30qG4SvnL6tO4QzZNbMjg5sLZHif22rZLwX7W6rWPAvgqyYdwDSGHN8Kkbe6KqV4DceyKQgRr83sU66Q=="],
"@oven/bun-windows-x64-baseline": ["@oven/bun-windows-x64-baseline@1.2.20", "", { "os": "win32", "cpu": "x64" }, "sha512-2291+pyVQ771zd8jgCNJ/jpPBaLJg/X7BWX06M9GpBNmC1tu3Rfr3LaWP8C/XTi80PZJnzNZGeMlcDhRY57y/A=="],
"@pkgr/core": ["@pkgr/core@0.2.9", "", {}, "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA=="],
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
"@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
"@types/bun": ["@types/bun@1.2.20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/node": ["@types/node@24.3.0", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow=="],
"@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="],
"@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="],
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
"ansi-regex": ["ansi-regex@6.2.0", "", {}, "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg=="],
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
"boringlang": ["boringlang@workspace:packages/boringlang"],
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"bun": ["bun@1.2.20", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "1.2.20", "@oven/bun-darwin-x64": "1.2.20", "@oven/bun-darwin-x64-baseline": "1.2.20", "@oven/bun-linux-aarch64": "1.2.20", "@oven/bun-linux-aarch64-musl": "1.2.20", "@oven/bun-linux-x64": "1.2.20", "@oven/bun-linux-x64-baseline": "1.2.20", "@oven/bun-linux-x64-musl": "1.2.20", "@oven/bun-linux-x64-musl-baseline": "1.2.20", "@oven/bun-windows-x64": "1.2.20", "@oven/bun-windows-x64-baseline": "1.2.20" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "bun": "bin/bun.exe", "bunx": "bin/bunx.exe" } }, "sha512-1ZGQynT+jPOHLY4IfzSubjbWcXsY2Z+irhW5D8RKC0wQ6KG4MvtgniAYQbSFYINGg8Wb2ydx+WgAG2BdhngAfw=="],
"bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="],
"bunli": ["bunli@0.1.1", "", { "dependencies": { "@bunli/core": "0.1.0", "@bunli/utils": "0.1.0", "glob": "^11.0.0", "zod": "^3.24.1" }, "bin": { "bunli": "dist/cli.js" } }, "sha512-hRNwQZGtXaKSnwGW1cCVPlBG14QMKAcQIg01Vf8eVmyJzIu2LE/wF5uFkdKXAXF/SDGVs9LZcXK9I8oQn5igRg=="],
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
"core-js": ["core-js@3.45.0", "", {}, "sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
"eslint": ["eslint@9.33.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.33.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA=="],
"eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="],
"eslint-plugin-prettier": ["eslint-plugin-prettier@5.5.4", "", { "dependencies": { "prettier-linter-helpers": "^1.0.0", "synckit": "^0.11.7" }, "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", "prettier": ">=3.0.0" }, "optionalPeers": ["@types/eslint", "eslint-config-prettier"] }, "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg=="],
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-diff": ["fast-diff@1.3.0", "", {}, "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="],
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
"glob": ["glob@11.0.3", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.0.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
"globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"jackspeak": ["jackspeak@4.1.1", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" } }, "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ=="],
"jiti": ["jiti@2.5.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="],
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
"jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="],
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
"lru-cache": ["lru-cache@11.1.0", "", {}, "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A=="],
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
"node-html-parser": ["node-html-parser@6.1.13", "", { "dependencies": { "css-select": "^5.1.0", "he": "1.2.0" } }, "sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg=="],
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
"ohm-js": ["ohm-js@17.2.1", "", {}, "sha512-4cXF0G09fAYU9z61kTfkNbKK1Kz/sGEZ5NbVWHoe9Qi7VB7y+Spwk051CpUTfUENdlIr+vt8tMV4/LosTE2cDQ=="],
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
"path-scurry": ["path-scurry@2.0.0", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg=="],
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
"prettier-linter-helpers": ["prettier-linter-helpers@1.0.0", "", { "dependencies": { "fast-diff": "^1.1.2" } }, "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="],
"request-light": ["request-light@0.7.0", "", {}, "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q=="],
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"synckit": ["synckit@0.11.11", "", { "dependencies": { "@pkgr/core": "^0.2.9" } }, "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw=="],
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
"typescript-language-server": ["typescript-language-server@4.4.0", "", { "bin": { "typescript-language-server": "lib/cli.mjs" } }, "sha512-enWhplhHX7PA0q+IcKHBMpTQh9I2Bmb3L45rwnkATHMsZ7YLduyyCdOmVUWJSYZfkWaBMiKwi/e2FQo4xsKeWw=="],
"undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
"vscode-css-languageservice": ["vscode-css-languageservice@6.3.7", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-5TmXHKllPzfkPhW4UE9sODV3E0bIOJPOk+EERKllf2SmAczjfTmYeq5txco+N3jpF8KIZ6loj/JptpHBQuVQRA=="],
"vscode-html-languageservice": ["vscode-html-languageservice@5.5.1", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "^3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-/ZdEtsZ3OiFSyL00kmmu7crFV9KwWR+MgpzjsxO60DQH7sIfHZM892C/E4iDd11EKocr+NYuvOA4Y7uc3QzLEA=="],
"vscode-json-languageservice": ["vscode-json-languageservice@5.6.1", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "jsonc-parser": "^3.3.1", "vscode-languageserver-textdocument": "^1.0.12", "vscode-languageserver-types": "^3.17.5", "vscode-uri": "^3.1.0" } }, "sha512-IQIURBF2VMKBdWcMunbHSI3G2WmJ9H7613E1hRxIXX7YsAPSdBxnEiIUrTnsSW/3fk+QW1kfsvSigqgAFYIYtg=="],
"vscode-jsonrpc": ["vscode-jsonrpc@9.0.0-next.9", "", {}, "sha512-IM/RHL7ZklEUh1N2Rh4OjRL6D9MyIXq3v+zIkPLXq74hM1eW7WRLP0/cjzNu/baRFC00sFxJm95RBKsT8dXzRQ=="],
"vscode-langservers-extracted": ["vscode-langservers-extracted@4.10.0", "", { "dependencies": { "@vscode/l10n": "^0.0.18", "core-js": "^3.20.1", "jsonc-parser": "^3.2.1", "regenerator-runtime": "^0.13.9", "request-light": "^0.7.0", "semver": "^7.6.1", "typescript": "^4.0.5", "vscode-css-languageservice": "^6.2.14", "vscode-html-languageservice": "^5.2.0", "vscode-json-languageservice": "^5.3.11", "vscode-languageserver": "^10.0.0-next.3", "vscode-languageserver-textdocument": "^1.0.11", "vscode-languageserver-types": "^3.17.5", "vscode-markdown-languageservice": "^0.5.0-alpha.6", "vscode-nls": "^5.2.0", "vscode-uri": "^3.0.8" }, "bin": { "vscode-css-language-server": "bin/vscode-css-language-server", "vscode-eslint-language-server": "bin/vscode-eslint-language-server", "vscode-html-language-server": "bin/vscode-html-language-server", "vscode-json-language-server": "bin/vscode-json-language-server", "vscode-markdown-language-server": "bin/vscode-markdown-language-server" } }, "sha512-EFf9uQI4dAKbzMQFjDvVm1xJq1DXAQvBEuEfPGrK/xzfsL5xWTfIuRr90NgfmqwO+IEt6vLZm9EOj6R66xIifg=="],
"vscode-languageserver": ["vscode-languageserver@10.0.0-next.14", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.6-next.14" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-1TqBDfRLlAIPs6MR5ISI8z7sWlvGL3oHGm9GAHLNOmBZ2+9pmw0yR9vB44/SYuU4bSizxU24tXDFW+rw9jek4A=="],
"vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.6-next.14", "", { "dependencies": { "vscode-jsonrpc": "9.0.0-next.9", "vscode-languageserver-types": "3.17.6-next.6" } }, "sha512-0VD83wxN5kI9vgeaIDQnAxgrbZfKiFNIxdFY5LKe3SZdZd+LAJLMrklSrwfefS7hEzaHw6Z++VFdVJJU+gh1Zg=="],
"vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="],
"vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="],
"vscode-markdown-languageservice": ["vscode-markdown-languageservice@0.5.0-alpha.11", "", { "dependencies": { "@vscode/l10n": "^0.0.10", "node-html-parser": "^6.1.5", "picomatch": "^2.3.1", "vscode-languageserver-protocol": "^3.17.1", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.7" } }, "sha512-P1uBMAD5iylgpcweWCU1kQwk8SZngktnljXsZk1vFPorXv1mrEI7BkBpOUU0fhVssKgvFlCNLkI7KmwZLC7pdA=="],
"vscode-nls": ["vscode-nls@5.2.0", "", {}, "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="],
"vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="],
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
"wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
"wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
"glob/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="],
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"vscode-langservers-extracted/typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="],
"vscode-languageserver-protocol/vscode-languageserver-types": ["vscode-languageserver-types@3.17.6-next.6", "", {}, "sha512-aiJY5/yW+xzw7KPNlwi3gQtddq/3EIn5z8X8nCgJfaiAij2R1APKePngv+MUdLdYJBVTLu+Qa0ODsT+pHgYguQ=="],
"vscode-markdown-languageservice/@vscode/l10n": ["@vscode/l10n@0.0.10", "", {}, "sha512-E1OCmDcDWa0Ya7vtSjp/XfHFGqYJfh+YPC1RkATU71fTac+j1JjCcB3qwSzmlKAighx2WxhLlfhS0RwAN++PFQ=="],
"vscode-markdown-languageservice/vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="],
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"vscode-markdown-languageservice/vscode-languageserver-protocol/vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="],
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
}
}

View File

@@ -1,6 +0,0 @@
version: "3"
services:
boring:
build: .
volumes:
- .:/code/

18
eslint.config.ts Normal file
View File

@@ -0,0 +1,18 @@
import { defineConfig } from "eslint/config";
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
export default defineConfig([
{
files: ["**/*.ts"],
rules: {
"prettier/prettier": [
"error",
{},
{
usePrettierrc: true,
},
],
},
},
eslintPluginPrettierRecommended,
]);

31
package.json Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "boringlang",
"description": "The Boring programming language",
"private": true,
"author": "Andrew Segavac",
"homepage": "https://code.buildbetter.boats/asegavac/boringlang",
"repository": {
"type": "git",
"url": "ssh://gitea@code.buildbetter.boats:2282/asegavac/boringlang.git"
},
"scripts": {
"build": "bun run --filter 'boringlang' build",
"format": "bun run prettier **/*.ts",
"type-check": "bun run tsc --noEmit",
"check": "bun run format -- --check && bun run type-check"
},
"devDependencies": {
"@types/bun": "latest",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
"jiti": "^2.5.1",
"prettier": "^3.6.2",
"typescript": "^5.9.2",
"typescript-language-server": "^4.4.0",
"vscode-langservers-extracted": "^4.10.0"
},
"workspaces": ["packages/*"],
"dependencies": {
"ohm-js": "^17.2.1"
}
}

View File

@@ -0,0 +1,26 @@
{
"name": "boringlang",
"version": "0.1.0",
"type": "module",
"description": "The Boring programming language CLI",
"author": "Andrew Segavac",
"homepage": "https://code.buildbetter.boats/asegavac/boringlang",
"repository": {
"type": "git",
"url": "ssh://gitea@code.buildbetter.boats:2282/asegavac/boringlang.git"
},
"scripts": {
"dev": "bun run src/index.ts",
"build": "bun build ./src/index.ts --outfile dist/boringlang --compile",
"test": "bun test",
"type-check": "tsc --noEmit",
},
"dependencies": {
"@bunli/core": "latest",
},
"devDependencies": {
"@bunli/test": "latest",
"@types/bun": "latest",
"bunli": "latest"
}
}

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bun
import { createCLI } from "@bunli/core";
const cli = createCLI({
name: "boringlang",
version: "0.1.0",
description: "Boring programming language CLI",
});
await cli.run();

View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": "./src",
"types": ["bun-types"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test/**/*"]
}

10
prettier.config.ts Normal file
View File

@@ -0,0 +1,10 @@
import { type Config } from "prettier";
const config: Config = {
trailingComma: "all",
singleQuote: false,
printWidth: 80,
semi: true,
};
export default config;

View File

@@ -1,410 +0,0 @@
use std::cell::RefCell;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IdGenerator {
id_key: String,
counter: RefCell<i64>,
}
impl IdGenerator {
pub fn new(key: &str) -> Self {
IdGenerator {
id_key: key.to_string(),
counter: RefCell::new(0),
}
}
pub fn next(&self) -> String {
*self.counter.borrow_mut() += 1;
(self.id_key.to_owned() + &self.counter.borrow().to_string()).to_string()
}
}
pub fn new_unit() -> TypeUsage {
TypeUsage::Named(NamedTypeUsage {
type_parameters: GenericUsage::Known(GenericInstantiation { parameters: vec![] }),
name: Identifier {
name: Spanned {
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "unit".to_string(),
},
},
})
}
pub fn new_never() -> TypeUsage {
TypeUsage::Named(NamedTypeUsage {
type_parameters: GenericUsage::Known(GenericInstantiation { parameters: vec![] }),
name: Identifier {
name: Spanned {
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "!".to_string(),
},
},
})
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Span {
pub left: usize,
pub right: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Spanned<T> {
pub span: Span,
pub value: T,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionTypeUsage {
pub arguments: Vec<TypeUsage>,
pub return_type: Box<TypeUsage>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NamedTypeUsage {
pub type_parameters: GenericUsage,
pub name: Identifier,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UnknownTypeUsage {
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum NamespaceTypeUsage {
Type(NamedTypeUsage), // Module
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TypeUsage {
Function(FunctionTypeUsage),
Named(NamedTypeUsage),
Unknown(UnknownTypeUsage),
Namespace(NamespaceTypeUsage),
}
impl TypeUsage {
pub fn new_unknown(id_gen: &IdGenerator) -> TypeUsage {
return TypeUsage::Unknown(UnknownTypeUsage { name: id_gen.next() });
}
pub fn new_named(identifier: &Identifier, generic_usage: &GenericUsage) -> TypeUsage {
return TypeUsage::Named(NamedTypeUsage {
type_parameters: generic_usage.clone(),
name: identifier.clone(),
});
}
pub fn new_builtin(name: String) -> TypeUsage {
TypeUsage::Named(NamedTypeUsage {
type_parameters: GenericUsage::Known(GenericInstantiation { parameters: vec![] }),
name: Identifier {
name: Spanned {
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: name,
},
},
})
}
pub fn new_function(arg_count: usize, id_gen: &IdGenerator) -> TypeUsage {
return TypeUsage::Function(FunctionTypeUsage {
arguments: (0..arg_count).map(|_| TypeUsage::new_unknown(&id_gen)).collect(),
return_type: Box::new(TypeUsage::new_unknown(&id_gen)),
});
}
pub fn replace_type(&self, old: &str, new: &Identifier) -> TypeUsage {
match &self {
TypeUsage::Function(function) => {
return TypeUsage::Function(FunctionTypeUsage {
arguments: function.arguments.iter().map(|arg| arg.replace_type(old, new)).collect(),
return_type: Box::new(function.return_type.replace_type(old, new)),
});
}
TypeUsage::Named(named) => {
let name = if named.name.name.value == old {
new.clone()
} else {
named.name.clone()
};
return TypeUsage::Named(NamedTypeUsage {
type_parameters: named.type_parameters.clone(),
name: name,
});
}
TypeUsage::Namespace(namespace) => return TypeUsage::Namespace(namespace.clone()),
TypeUsage::Unknown(unkown) => return TypeUsage::Unknown(unkown.clone()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericParameter {
pub name: Identifier,
pub bounds: Vec<Identifier>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Generic {
pub parameters: Vec<GenericParameter>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericInstantiation {
pub parameters: Vec<TypeUsage>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum GenericUsage {
Known(GenericInstantiation),
Unknown,
}
impl GenericUsage {
pub fn new(type_parameters: &[TypeUsage]) -> Self {
GenericUsage::Known(GenericInstantiation {
parameters: type_parameters.iter().map(|tp| tp.clone()).collect(),
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Operator {
Mul,
Div,
Plus,
Minus,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LiteralInt {
pub value: Spanned<String>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LiteralFloat {
pub value: Spanned<String>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LiteralBool {
pub value: Spanned<String>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LiteralString {
pub value: Spanned<String>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LiteralStruct {
pub type_parameters: GenericUsage,
pub name: Identifier,
pub fields: Vec<(Identifier, Expression)>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Identifier {
pub name: Spanned<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionCall {
pub source: Expression,
pub arguments: Vec<Expression>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StructGetter {
pub type_parameters: GenericUsage,
pub source: Expression,
pub attribute: Identifier,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Operation {
pub left: Expression,
pub op: Operator,
pub right: Expression,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct VariableUsage {
pub name: Identifier,
pub type_parameters: GenericUsage,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct IfExpression {
pub condition: Expression,
pub block: Block,
pub else_: Option<Block>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Subexpression {
LiteralInt(LiteralInt),
LiteralFloat(LiteralFloat),
LiteralBool(LiteralBool),
LiteralString(LiteralString),
LiteralStruct(LiteralStruct),
FunctionCall(FunctionCall),
VariableUsage(VariableUsage),
If(IfExpression),
StructGetter(StructGetter),
Block(Block),
Op(Operation),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Expression {
pub subexpression: Box<Subexpression>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ReturnStatement {
pub source: Expression,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LetStatement {
pub variable_name: Identifier,
pub expression: Expression,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum AssignmentTarget {
Variable(VariableUsage),
StructAttr(StructGetter),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct AssignmentStatement {
pub source: AssignmentTarget,
pub expression: Expression,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Statement {
Return(ReturnStatement),
Let(LetStatement),
Assignment(AssignmentStatement),
Expression(Expression),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Block {
pub statements: Vec<Statement>,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct VariableDeclaration {
pub name: Identifier,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionDeclaration {
pub generic: Generic,
pub name: Identifier,
pub arguments: Vec<VariableDeclaration>,
pub return_type: TypeUsage,
}
impl FunctionDeclaration {
pub fn to_type(&self) -> TypeUsage {
TypeUsage::Function(FunctionTypeUsage {
arguments: self.arguments.iter().map(|arg| arg.type_.clone()).collect(),
return_type: Box::new(self.return_type.clone()),
})
}
pub fn to_method_type(&self) -> TypeUsage {
TypeUsage::Function(FunctionTypeUsage {
arguments: self.arguments[1..self.arguments.len()]
.iter()
.map(|arg| arg.type_.clone())
.collect(),
return_type: Box::new(self.return_type.clone()),
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Function {
pub declaration: FunctionDeclaration,
pub block: Block,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PrimitiveTypeDeclaration {
pub name: String, // cannot be identifier as it's not declared anywhere specific, it's builtins
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StructField {
pub name: Identifier,
pub type_: TypeUsage,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StructTypeDeclaration {
pub generic: Generic,
pub name: Identifier,
pub fields: Vec<StructField>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TraitItem {
FunctionDeclaration(FunctionDeclaration),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TraitTypeDeclaration {
pub generic: Generic,
pub name: Identifier,
pub functions: Vec<TraitItem>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TypeDeclaration {
Struct(StructTypeDeclaration),
Primitive(PrimitiveTypeDeclaration),
Trait(TraitTypeDeclaration),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Impl {
pub generic: Generic,
pub struct_: NamedTypeUsage,
pub trait_: Option<NamedTypeUsage>,
pub functions: Vec<Function>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ModuleItem {
Function(Function),
TypeDeclaration(TypeDeclaration),
Impl(Impl),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Module {
pub items: Vec<ModuleItem>,
}

View File

@@ -1,3 +0,0 @@
use std::collections::HashMap;
use crate::ast;

View File

@@ -1,124 +0,0 @@
use inkwell::builder::Builder;
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue};
use std::collections::HashMap;
use std::convert::TryInto;
use std::mem;
use crate::ast;
type Scope<'ctx> = HashMap<String, BasicValueEnum<'ctx>>;
pub struct ModuleCodeGen<'ctx> {
context: &'ctx Context,
module: Module<'ctx>,
builder: Builder<'ctx>,
scope: Scope<'ctx>,
}
impl<'ctx> ModuleCodeGen<'ctx> {
pub fn new(context: &'ctx Context, name: String) -> Self {
return ModuleCodeGen {
context: context,
module: context.create_module(&name),
builder: context.create_builder(),
scope: Scope::new(),
};
}
pub fn gen_literal_int(&mut self, literal_int: &ast::LiteralInt) -> IntValue<'ctx> {
self.context
.i64_type()
.const_int(unsafe { mem::transmute::<i64, u64>(literal_int.value) }, true)
}
pub fn gen_op_expression(&mut self, scope: &Scope<'ctx>, operation: &ast::Operation) -> IntValue<'ctx> {
let lhs_result = self.gen_expression(scope, &operation.left);
let rhs_result = self.gen_expression(scope, &operation.right);
self.gen_op_int(&lhs_result, &rhs_result, &operation.op)
}
pub fn gen_op_int(&mut self, lhs: &IntValue<'ctx>, rhs: &IntValue<'ctx>, op: &ast::Operator) -> IntValue<'ctx> {
match *op {
ast::Operator::Plus => self.builder.build_int_add(*lhs, *rhs, "add"),
ast::Operator::Minus => self.builder.build_int_sub(*lhs, *rhs, "sub"),
ast::Operator::Mul => self.builder.build_int_mul(*lhs, *rhs, "mul"),
ast::Operator::Div => self.builder.build_int_signed_div(*lhs, *rhs, "div"),
}
}
pub fn gen_expression(&mut self, scope: &Scope<'ctx>, expression: &Box<ast::Expression>) -> IntValue<'ctx> {
match &**expression {
ast::Expression::LiteralInt(literal_int) => self.gen_literal_int(&literal_int),
ast::Expression::Identifier(identifier) => match scope[&identifier.name] {
BasicValueEnum::IntValue(value) => value,
_ => panic!("function returned type other than int, no types yet"),
},
ast::Expression::FunctionCall(function_call) => self.gen_function_call(scope, &function_call),
ast::Expression::Op(operation) => self.gen_op_expression(scope, &operation),
}
}
pub fn gen_function_call(&mut self, scope: &Scope<'ctx>, function_call: &ast::FunctionCall) -> IntValue<'ctx> {
let fn_value = self.module.get_function(&function_call.name.name).unwrap();
let mut arguments = Vec::new();
for expression in (&function_call.arguments).into_iter() {
arguments.push(BasicValueEnum::IntValue(self.gen_expression(scope, &expression)));
}
let result = self
.builder
.build_call(fn_value, &arguments, &function_call.name.name)
.try_as_basic_value()
.left()
.unwrap();
match result {
BasicValueEnum::IntValue(value) => value,
_ => panic!("function returned type other than int, no types yet"),
}
}
// Generates a FunctionValue for an `ast::Function`. This does not genereate a body,
// that task is left to the `gen_function` function. The reason this is split
// between two functions is that first all signatures are generated and then all bodies. This
// allows bodies to reference `FunctionValue` wherever they are declared in the file.
pub fn gen_signature(&mut self, function: &ast::Function) -> FunctionValue {
let mut args = Vec::new();
for _ in &function.arguments {
args.push(self.context.i64_type().into());
}
let fn_type = self.context.i64_type().fn_type(&args, false);
let fn_value = self.module.add_function(&function.name.name, fn_type, None);
fn_value
}
pub fn gen_function(&mut self, function: &ast::Function) {
let fn_value = self.module.get_function(&function.name.name).unwrap();
let basic_block = self.context.append_basic_block(fn_value, "entry");
self.builder.position_at_end(basic_block);
let mut scope = self.scope.clone();
for (i, param) in (&function.arguments).into_iter().enumerate() {
scope.insert(param.name.name.to_string(), fn_value.get_nth_param(i.try_into().unwrap()).unwrap());
}
let body = &function.block;
let return_value = self.gen_expression(&scope, &body.expression);
self.builder.build_return(Some(&return_value));
}
pub fn gen_module(&mut self, module: ast::Module) {
// generate all signatures before the fuction bodies
for function in &module.functions {
self.gen_signature(&function);
}
for function in module.functions {
self.gen_function(&function);
}
}
pub fn dump(&self) -> String {
self.module.print_to_string().to_string()
}
}

View File

@@ -1,64 +0,0 @@
use crate::ast;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum TypingError {
#[error("unknown named type")]
TypeDoesNotExist { identifier: ast::Identifier },
#[error("identifier is not type")]
IdentifierIsNotType { identifier: ast::Identifier },
#[error("argument length mismatch")]
ArgumentLengthMismatch {
// TODO: add position
},
#[error("type mismatch")]
TypeMismatch {
type_one: ast::TypeUsage,
type_two: ast::TypeUsage,
},
#[error("unknown field name")]
UnknownFieldName { identifier: ast::Identifier },
#[error("cannot assign to method")]
CannotAssignToMethod { identifier: ast::Identifier },
#[error("multiple field name matches")]
MultipleFieldName { identifier: ast::Identifier },
#[error("attribute gotten of non-struct")]
AttributeOfNonstruct { identifier: ast::Identifier },
#[error("name is not a struct, cannot instaniate")]
NotAStructLiteral { identifier: ast::Identifier },
#[error("struct literal fields mismatch")]
StructLiteralFieldsMismatch { struct_name: ast::Identifier },
#[error("missing trait function")]
MissingTraitFunction {
struct_name: ast::Identifier,
function_name: ast::Identifier,
},
#[error("function not in trait")]
FunctionNotInTrait { function_name: ast::Identifier },
#[error("impl trait must be trait")]
ImplTraitMustBeTrait { trait_name: ast::Identifier },
#[error("function call used with non-function")]
FunctionCallNotAFunction {
// TODO: add position
},
#[error("`if` condition must be bool")]
IfConditionMustBeBool {
// TODO: add position
},
#[error("cannot use type as an expression")]
TypeIsNotAnExpression { type_name: ast::Identifier },
#[error("wrong number of type parameters")]
WrongNumberOfTypeParameters {
// TODO: add position
},
#[error("invalid use of alias")]
InvalidUseofAlias,
#[error("alias cannot have type parameters")]
InvalidTypeParameterOnAlias {
alias: ast::Identifier,
},
#[error("type cannot be used for generic")]
InvalidTypeForGeneric,
#[error("multiple errors")]
MultipleErrors { errors: Vec<TypingError> },
}

View File

@@ -1,352 +0,0 @@
use crate::ast;
grammar(id_generator: &ast::IdGenerator);
match {
r"[0-9]+",
r"[0-9]+\.[0-9]+",
r"[A-Za-z_][A-Za-z0-9_]*",
":",
";",
"{",
"}",
"(",
")",
"[",
"]",
"",
".",
"+",
"-",
"*",
"/",
"fn",
"return",
"let",
"true",
"false",
"if",
"else",
"=",
"for",
"type",
"trait",
"struct",
"impl",
",",
r"'(\\'|[^'])*'",
r#""(\\"|[^"])*""#,
r"\s*" => { },
r"//[^\n\r]*[\n\r]*" => { }, // `// comment`
}
pub LiteralInt: String = {
<literal:r"[0-9]+"> => literal.to_string()
};
pub SpannedLiteralInt: ast::LiteralInt = {
<literal_int:Spanned<LiteralInt>> => ast::LiteralInt{value: literal_int, type_: ast::TypeUsage::new_builtin("i64".to_string())}
};
pub LiteralFloat: String = {
<literal:r"[0-9]+\.[0-9]+"> => literal.to_string()
};
pub SpannedLiteralFloat: ast::LiteralFloat = {
<literal_float:Spanned<LiteralFloat>> => ast::LiteralFloat{value: literal_float, type_: ast::TypeUsage::new_builtin("f64".to_string())}
};
pub LiteralBool: String = {
"true" => "true".to_string(),
"false" => "false".to_string(),
};
pub SpannedLiteralBool: ast::LiteralBool = {
<literal_bool:Spanned<LiteralBool>> => ast::LiteralBool{value: literal_bool, type_: ast::TypeUsage::new_builtin("bool".to_string())}
};
pub LiteralString: String = {
<s:r"'(\\'|[^'])*'"> => String::from(&s[1..s.len()-1]),
<s:r#""(\\"|[^"])*""#> => String::from(&s[1..s.len()-1]),
};
pub SpannedLiteralString: ast::LiteralString = {
<literal_string:Spanned<LiteralString>> => ast::LiteralString{value: literal_string, type_: ast::TypeUsage::new_builtin("String".to_string())}
};
pub Identifier: String = {
<i:r"[A-Za-z_][A-Za-z0-9_]*"> => i.to_string()
};
pub GenericUsage: ast::GenericUsage = {
"[" <tp:Comma<TypeUsage>> "]" => ast::GenericUsage::new(&tp),
};
pub LiteralStructField: (ast::Identifier, ast::Expression) = {
<field:SpannedIdentifier> ":" <expr:Expression> => (field, expr)
};
pub LiteralStruct: ast::LiteralStruct = {
<i:SpannedIdentifier> <gu:GenericUsage?> "{" <field_list:Comma<LiteralStructField>> "}" => {
match gu {
Some(tp) => {
ast::LiteralStruct{
type_parameters: tp.clone(),
name: i.clone(),
fields: field_list,
type_: ast::TypeUsage::new_named(&i, &tp),
}
},
None => {
ast::LiteralStruct{
type_parameters: ast::GenericUsage::new(&[]),
name: i.clone(),
fields: field_list,
type_: ast::TypeUsage::new_named(&i, &ast::GenericUsage::new(&[])),
}
}
}
}
};
pub SpannedIdentifier: ast::Identifier = {
<i:Spanned<Identifier>> => ast::Identifier{name: i}
};
pub FunctionCall: ast::FunctionCall = {
<source:Term> "(" <args:Comma<Expression>> ")" => ast::FunctionCall{source: source, arguments: args, type_: ast::TypeUsage::new_unknown(&id_generator)}
};
pub StructGetter: ast::StructGetter = {
<source:Term> "." <field:SpannedIdentifier> <gu:GenericUsage?> => match gu {
Some(tp) => ast::StructGetter{type_parameters: tp, source: source, attribute: field, type_: ast::TypeUsage::new_unknown(&id_generator)},
None => ast::StructGetter{type_parameters: ast::GenericUsage::Unknown, source: source, attribute: field, type_: ast::TypeUsage::new_unknown(&id_generator)},
}
};
pub VariableUsage: ast::VariableUsage = {
<identifier:SpannedIdentifier> <gu:GenericUsage?> => match gu {
Some(tp) => ast::VariableUsage{name: identifier, type_parameters: tp.clone(), type_: ast::TypeUsage::new_unknown(&id_generator)},
None => ast::VariableUsage{name: identifier, type_parameters: ast::GenericUsage::Unknown, type_: ast::TypeUsage::new_unknown(&id_generator)},
}
};
pub IfExpression: ast::IfExpression = {
"if" "("<c:Expression>")" <b:Block> => ast::IfExpression{condition: c, block: b, else_: None, type_: ast::TypeUsage::new_unknown(&id_generator)},
"if" "("<c:Expression>")" <b:Block> "else" <e:Block> => ast::IfExpression{condition: c, block: b, else_: Some(e), type_: ast::TypeUsage::new_unknown(&id_generator)},
};
pub Expression: ast::Expression = {
<l:Expression> "+" <r:Factor> => {
ast::Expression{
subexpression: Box::new(ast::Subexpression::Op(ast::Operation{left: l, op: ast::Operator::Plus, right: r})),
type_: ast::TypeUsage::new_unknown(&id_generator),
}
},
<l:Expression> "-" <r:Factor> => {
ast::Expression{
subexpression: Box::new(ast::Subexpression::Op(ast::Operation{left: l, op: ast::Operator::Minus, right: r})),
type_: ast::TypeUsage::new_unknown(&id_generator),
}
},
Factor,
};
pub Factor: ast::Expression = {
<l:Factor> "*" <r:Term> => {
ast::Expression{
subexpression: Box::new(ast::Subexpression::Op(ast::Operation{left: l, op: ast::Operator::Mul, right: r})),
type_: ast::TypeUsage::new_unknown(&id_generator),
}
},
<l:Factor> "/" <r:Term> => {
ast::Expression{
subexpression: Box::new(ast::Subexpression::Op(ast::Operation{left: l, op: ast::Operator::Div, right: r})),
type_: ast::TypeUsage::new_unknown(&id_generator),
}
},
Term,
};
pub Term: ast::Expression = {
SpannedLiteralInt => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralInt(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
SpannedLiteralFloat => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralFloat(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
SpannedLiteralBool => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralBool(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
SpannedLiteralString => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralString(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
LiteralStruct => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralStruct(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
FunctionCall => ast::Expression{subexpression: Box::new(ast::Subexpression::FunctionCall(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
StructGetter => ast::Expression{subexpression: Box::new(ast::Subexpression::StructGetter(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
VariableUsage => ast::Expression{subexpression: Box::new(ast::Subexpression::VariableUsage(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
IfExpression => ast::Expression{subexpression: Box::new(ast::Subexpression::If(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
Block => ast::Expression{subexpression: Box::new(ast::Subexpression::Block(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
"(" <e:Expression> ")" => e,
};
pub ReturnStatement: ast::ReturnStatement = {
"return" <e:Expression> => ast::ReturnStatement{source: e}
};
pub LetStatement: ast::LetStatement = {
//TODO: support destructuring with tuples, when they exist.
//TODO: add mut, weak
"let" <n:SpannedIdentifier> "=" <e:Expression> => ast::LetStatement{variable_name: n, type_: ast::TypeUsage::new_unknown(&id_generator), expression: e},
"let" <n:SpannedIdentifier> ":" <t:TypeUsage> "=" <e:Expression> => ast::LetStatement{variable_name: n, type_: t, expression: e},
};
pub AssignmentStatement: ast::AssignmentStatement = {
<v:VariableUsage> "=" <e:Expression> => ast::AssignmentStatement{source: ast::AssignmentTarget::Variable(v), expression: e},
<sg:StructGetter> "=" <e:Expression> => ast::AssignmentStatement{source: ast::AssignmentTarget::StructAttr(sg), expression: e},
};
pub Statement: ast::Statement = {
<r:ReturnStatement> ";" => ast::Statement::Return(r),
<l:LetStatement> ";" => ast::Statement::Let(l),
<a:AssignmentStatement> ";" => ast::Statement::Assignment(a),
<e:Expression> ";" => ast::Statement::Expression(e),
};
pub Block: ast::Block = {
"{" <v:(<Statement>)*> <e:Expression?> "}" => match e {
None => ast::Block{statements: v, type_: ast::TypeUsage::new_unknown(&id_generator)},
Some(e) => {
let mut v = v;
v.push(ast::Statement::Expression(e));
ast::Block{statements: v, type_: ast::TypeUsage::new_unknown(&id_generator)}
}
}
};
pub PartialNamedTypeUsage: ast::NamedTypeUsage = {
<n:SpannedIdentifier> <gu:GenericUsage?> => match gu {
Some(tp) => ast::NamedTypeUsage{type_parameters: tp, name: n},
None => ast::NamedTypeUsage{type_parameters: ast::GenericUsage::Unknown, name: n},
},
};
pub NamedTypeUsage: ast::NamedTypeUsage = {
<n:SpannedIdentifier> <gu:GenericUsage?> => match gu {
Some(tp) => ast::NamedTypeUsage{type_parameters: tp, name: n},
None => ast::NamedTypeUsage{type_parameters: ast::GenericUsage::new(&[]), name: n},
},
};
pub PartialTypeUsage: ast::TypeUsage = {
<n:PartialNamedTypeUsage> => ast::TypeUsage::Named(n),
"fn" "(" <args:Comma<PartialTypeUsage>> ")" => ast::TypeUsage::Function(ast::FunctionTypeUsage{arguments: args, return_type: Box::new(ast::new_unit())}),
"fn" "(" <args:Comma<PartialTypeUsage>> ")" ":" <rt:PartialTypeUsage> => ast::TypeUsage::Function(ast::FunctionTypeUsage{arguments: args, return_type: Box::new(rt)}),
};
pub TypeUsage: ast::TypeUsage = {
<n:NamedTypeUsage> => ast::TypeUsage::Named(n),
"fn" "(" <args:Comma<TypeUsage>> ")" => ast::TypeUsage::Function(ast::FunctionTypeUsage{arguments: args, return_type: Box::new(ast::new_unit())}),
"fn" "(" <args:Comma<TypeUsage>> ")" ":" <rt:TypeUsage> => ast::TypeUsage::Function(ast::FunctionTypeUsage{arguments: args, return_type: Box::new(rt)}),
};
pub VariableDeclaration: ast::VariableDeclaration = {
<i:SpannedIdentifier> ":" <t:TypeUsage> => ast::VariableDeclaration{name: i, type_: t},
};
pub GenericParameter: ast::GenericParameter = {
<i:SpannedIdentifier> => ast::GenericParameter{name: i, bounds: vec!()},
<i:SpannedIdentifier> ":" <bounds:PlusSeparated<SpannedIdentifier>> => ast::GenericParameter{name: i, bounds: bounds},
};
pub Generic: ast::Generic = {
"[" <p:Comma<GenericParameter>> "]" => ast::Generic{parameters: p},
};
pub FunctionDeclaration: ast::FunctionDeclaration = {
"fn" <n:SpannedIdentifier> <g:Generic> "(" <args:Comma<VariableDeclaration>> ")" => ast::FunctionDeclaration{name: n, generic: g, arguments: args, return_type: ast::new_unit()},
"fn" <n:SpannedIdentifier> <g:Generic> "(" <args:Comma<VariableDeclaration>> ")" ":" <rt:TypeUsage> => ast::FunctionDeclaration{name: n, generic: g, arguments: args, return_type: rt},
"fn" <n:SpannedIdentifier> "(" <args:Comma<VariableDeclaration>> ")" => ast::FunctionDeclaration{name: n, generic: ast::Generic{parameters: vec!()}, arguments: args, return_type: ast::new_unit()},
"fn" <n:SpannedIdentifier> "(" <args:Comma<VariableDeclaration>> ")" ":" <rt:TypeUsage> => ast::FunctionDeclaration{name: n, generic: ast::Generic{parameters: vec!()}, arguments: args, return_type: rt},
};
pub Function: ast::Function = {
<d:FunctionDeclaration> <b:Block> => ast::Function{declaration: d, block: b}
};
pub StructField: ast::StructField = {
<i:SpannedIdentifier> ":" <t:TypeUsage> => ast::StructField{name: i, type_: t},
};
pub StructTypeDeclaration: ast::StructTypeDeclaration = {
"type" <i:SpannedIdentifier> <g:Generic?> "struct" "{" <f:Comma<StructField>> "}" => match g {
Some(generic) => ast::StructTypeDeclaration{name: i, generic: generic, fields: f},
None => ast::StructTypeDeclaration{name: i, generic: ast::Generic{parameters: vec!()}, fields: f},
}
};
pub TraitItem: ast::TraitItem = {
<fd:FunctionDeclaration> ";" => ast::TraitItem::FunctionDeclaration(fd),
};
pub TraitTypeDeclaration: ast::TraitTypeDeclaration = {
"type" <i:SpannedIdentifier> <g:Generic> "trait" "{" <ti:TraitItem*> "}" => ast::TraitTypeDeclaration{name: i, generic: g, functions: ti},
"type" <i:SpannedIdentifier> "trait" "{" <ti:TraitItem*> "}" => ast::TraitTypeDeclaration{name: i, generic: ast::Generic{parameters: vec!()}, functions: ti},
};
pub TypeDeclaration: ast::TypeDeclaration = {
<s:StructTypeDeclaration> => ast::TypeDeclaration::Struct(s),
<t:TraitTypeDeclaration> => ast::TypeDeclaration::Trait(t),
};
pub Impl: ast::Impl = {
"impl" <g:Generic?> <s:NamedTypeUsage> "{" <f:Function*> "}" => {
let generic = match g {
Some(g) => g,
None => ast::Generic{parameters: vec!()},
};
ast::Impl{generic: generic, trait_: None, struct_: s, functions: f}
},
"impl" <g:Generic?> <t:NamedTypeUsage> "for" <s:NamedTypeUsage> "{" <f:Function*> "}" => {
let generic = match g {
Some(g) => g,
None => ast::Generic{parameters: vec!()},
};
ast::Impl{generic: generic, trait_: Some(t), struct_: s, functions: f}
}
};
pub ModuleItem: ast::ModuleItem = {
<f:Function> => ast::ModuleItem::Function(f),
<td:TypeDeclaration> => ast::ModuleItem::TypeDeclaration(td),
<i:Impl> => ast::ModuleItem::Impl(i),
};
pub Module: ast::Module = {
<i:ModuleItem*> => ast::Module{items: i}
};
// From https://lalrpop.github.io/lalrpop/tutorial/006_macros.html
// Comma separated list of T with optional trailing comma
Comma<T>: Vec<T> = {
<v:(<T> ",")*> <e:T?> => match e {
None => v,
Some(e) => {
let mut v = v;
v.push(e);
v
}
}
};
// PlusSeparated separated list of T with optional trailing comma
PlusSeparated<T>: Vec<T> = {
<v:(<T> "+")*> <e:T?> => match e {
None => v,
Some(e) => {
let mut v = v;
v.push(e);
v
}
}
};
Spanned<Rule>: ast::Spanned<Rule> = {
<l: @L> <rule: Rule> <r: @R> => ast::Spanned{span: ast::Span{left: l, right: r}, value: rule}
};

View File

@@ -1,654 +0,0 @@
use crate::ast;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Debug, Clone)]
pub enum NumericValue {
I8(i8),
I16(i16),
I32(i32),
I64(i64),
ISize(isize),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
USize(usize),
F32(f32),
F64(f64),
}
#[derive(Debug, Clone)]
pub struct StructValue {
source: ast::StructTypeDeclaration,
fields: HashMap<String, Value>,
}
type BuiltinFunction = fn(Vec<Value>) -> Value;
#[derive(Debug, Clone)]
pub enum FunctionRef {
User(ast::Function),
Builtin(BuiltinFunction),
}
#[derive(Debug, Clone)]
pub struct Function {
pub partial: Vec<Value>,
pub ref_: FunctionRef,
}
#[derive(Debug, Clone)]
pub enum Value {
Numeric(NumericValue),
Bool(bool),
String(String),
Function(Function),
Struct(Arc<Mutex<StructValue>>),
Unit,
}
#[derive(Debug, Clone)]
pub enum NamedEntity {
TypeDeclaration(ast::TypeDeclaration),
Variable(Value),
}
#[derive(Debug, Clone)]
struct Context {
pub environment: HashMap<String, NamedEntity>,
pub impls: HashMap<String, ast::Impl>,
pub current_module: ast::Module,
}
impl Context {
fn set_variable(&mut self, name: String, value: &Value) {
self.environment.insert(name.to_string(), NamedEntity::Variable(value.clone()));
}
fn new_env(&self) -> Context {
return Context::from_module(&self.current_module);
}
fn from_module(module: &ast::Module) -> Context {
let mut ctx = Context {
environment: create_builtins(),
impls: HashMap::new(),
current_module: module.clone(),
};
for item in ctx.current_module.items.iter() {
match item {
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Struct(struct_)) => {
ctx.environment.insert(
struct_.name.name.value.to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(struct_.clone())),
);
}
ast::ModuleItem::Function(function) => {
ctx.environment.insert(
function.declaration.name.name.value.to_string(),
NamedEntity::Variable(Value::Function(Function {
partial: vec![],
ref_: FunctionRef::User(function.clone()),
})),
);
}
ast::ModuleItem::Impl(impl_) => {
ctx.impls.insert(impl_.struct_.name.name.value.to_string(), impl_.clone());
}
_ => {}
}
}
return ctx;
}
}
fn create_builtins() -> HashMap<String, NamedEntity> {
let mut result = HashMap::new();
result.insert(
"i8".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i8".to_string(),
})),
);
result.insert(
"i16".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i16".to_string(),
})),
);
result.insert(
"i32".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i32".to_string(),
})),
);
result.insert(
"i64".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i64".to_string(),
})),
);
result.insert(
"isize".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "isize".to_string(),
})),
);
result.insert(
"u8".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u8".to_string(),
})),
);
result.insert(
"u16".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u16".to_string(),
})),
);
result.insert(
"u32".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u32".to_string(),
})),
);
result.insert(
"u64".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u64".to_string(),
})),
);
result.insert(
"usize".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "usize".to_string(),
})),
);
result.insert(
"f32".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "f32".to_string(),
})),
);
result.insert(
"f64".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "f64".to_string(),
})),
);
result.insert(
"bool".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "bool".to_string(),
})),
);
result.insert(
"!".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "!".to_string(),
})),
);
result.insert(
"unit".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "!".to_string(),
})),
);
result.insert(
"String".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "String".to_string(),
})),
);
return result;
}
pub enum ExpressionResult {
Value(Value),
Return(Value),
}
pub struct TreeWalkInterpreter {}
impl TreeWalkInterpreter {
pub fn with_module(self: &Self, module: &ast::Module) -> Value {
let mut ctx = Context::from_module(module);
let main = match &ctx.environment["main"] {
NamedEntity::Variable(Value::Function(func)) => match &func.ref_ {
FunctionRef::User(ref_) => ref_.clone(),
_ => panic!("main should be a user defined function"),
},
_ => panic!("main should be a user defined function"),
};
return self.with_function(&mut ctx, &main);
}
fn with_function(self: &Self, ctx: &mut Context, function: &ast::Function) -> Value {
let result = self.with_block(ctx, &function.block);
return match result {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => r,
};
}
fn with_block(self: &Self, ctx: &mut Context, block: &ast::Block) -> ExpressionResult {
let mut last = ExpressionResult::Value(Value::Unit);
for statement in block.statements.iter() {
let result = self.with_statement(ctx, statement);
match result {
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
ExpressionResult::Value(r) => {
last = ExpressionResult::Value(r);
}
}
}
return last;
}
fn with_statement(self: &Self, ctx: &mut Context, statement: &ast::Statement) -> ExpressionResult {
match statement {
ast::Statement::Return(return_statement) => {
let result = match self.with_expression(ctx, &return_statement.source) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
return ExpressionResult::Return(result);
}
ast::Statement::Let(let_statement) => {
let result = match self.with_expression(ctx, &let_statement.expression) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
ctx.set_variable(let_statement.variable_name.name.value.to_string(), &result);
return ExpressionResult::Value(Value::Unit);
}
ast::Statement::Assignment(assignment_statement) => {
return self.with_assignment_statement(ctx, assignment_statement);
}
ast::Statement::Expression(expression) => {
return self.with_expression(ctx, expression);
}
}
}
fn with_assignment_statement(self: &Self, ctx: &mut Context, statement: &ast::AssignmentStatement) -> ExpressionResult {
let result = match self.with_expression(ctx, &statement.expression) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
match &statement.source {
ast::AssignmentTarget::Variable(variable) => {
ctx.set_variable(variable.name.name.value.to_string(), &result);
}
ast::AssignmentTarget::StructAttr(struct_attr) => {
let mut source = match self.with_expression(ctx, &struct_attr.source) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
match &mut source {
Value::Struct(s) => {
let mut struct_ = s.lock().unwrap();
struct_.fields.insert(struct_attr.attribute.name.value.clone(), result);
}
_ => panic!("set attr on nonstruct, should never happen due to type system"),
}
}
}
return ExpressionResult::Value(Value::Unit);
}
fn with_expression(self: &Self, ctx: &mut Context, expression: &ast::Expression) -> ExpressionResult {
match &*expression.subexpression {
ast::Subexpression::LiteralInt(literal_int) => {
let value: i64 = literal_int.value.value.parse().unwrap();
return ExpressionResult::Value(Value::Numeric(NumericValue::I64(value)));
}
ast::Subexpression::LiteralFloat(literal_float) => {
let value: f64 = literal_float.value.value.parse().unwrap();
return ExpressionResult::Value(Value::Numeric(NumericValue::F64(value)));
}
ast::Subexpression::LiteralBool(literal_bool) => {
let value: bool = if &literal_bool.value.value == "true" { true } else { false };
return ExpressionResult::Value(Value::Bool(value));
}
ast::Subexpression::LiteralString(literal_string) => {
let value: String = literal_string.value.value.to_string();
return ExpressionResult::Value(Value::String(value));
}
ast::Subexpression::LiteralStruct(literal_struct) => {
let declaration = match &ctx.environment[&literal_struct.name.name.value] {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => declaration.clone(),
_ => panic!("not a struct"),
};
let mut fields = HashMap::new();
for field in declaration.fields.iter() {
for (field_name, field_expression) in literal_struct.fields.iter() {
if field.name.name.value == field_name.name.value {
let field_result = match self.with_expression(ctx, field_expression) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
fields.insert(field.name.name.value.to_string(), field_result);
}
}
}
return ExpressionResult::Value(Value::Struct(Arc::new(Mutex::new(StructValue {
source: declaration.clone(),
fields: fields,
}))));
}
ast::Subexpression::FunctionCall(function_call) => {
let source = match self.with_expression(ctx, &function_call.source) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
let mut argument_values = vec![];
for arg in function_call.arguments.iter() {
let argument_value = match self.with_expression(ctx, arg) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
argument_values.push(argument_value);
}
match &source {
Value::Function(function) => match &function.ref_ {
FunctionRef::User(user_function) => {
let mut fn_ctx = ctx.new_env();
let mut i = 0;
for partial_arg in &function.partial {
fn_ctx.set_variable(
user_function.declaration.arguments[i].name.name.value.to_string(),
&partial_arg.clone(),
);
i = i + 1;
}
for argument_value in &argument_values {
fn_ctx.set_variable(
user_function.declaration.arguments[i].name.name.value.to_string(),
&argument_value.clone(),
);
}
return ExpressionResult::Value(self.with_function(&mut fn_ctx, user_function));
}
FunctionRef::Builtin(builtin_function) => {
let all_values = function
.partial
.iter()
.map(|val| val.clone())
.chain(argument_values.into_iter())
.collect();
return ExpressionResult::Value(builtin_function(all_values));
}
},
_ => panic!("type error: function call source must be a function"),
}
}
ast::Subexpression::VariableUsage(variable_usage) => {
if !ctx.environment.contains_key(&variable_usage.name.name.value) {
panic!("{}", variable_usage.name.name.value.clone());
}
let variable_value = match &ctx.environment[&variable_usage.name.name.value] {
NamedEntity::Variable(v) => v.clone(),
_ => panic!("variable lookup of type"),
};
return ExpressionResult::Value(variable_value);
}
ast::Subexpression::If(if_expression) => {
let condition = match self.with_expression(ctx, &if_expression.condition) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
match &condition {
Value::Bool(cond) => {
if cond.clone() {
return self.with_block(ctx, &if_expression.block);
} else {
return match &if_expression.else_ {
Some(else_) => self.with_block(ctx, else_),
None => ExpressionResult::Value(Value::Unit),
};
}
}
_ => panic!("TypeError: condition must be bool"),
}
}
ast::Subexpression::StructGetter(struct_getter) => {
let source = match self.with_expression(ctx, &struct_getter.source) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
match &source {
Value::Struct(struct_) => {
let s = struct_.lock().unwrap();
if s.fields.contains_key(&struct_getter.attribute.name.value) {
return ExpressionResult::Value(s.fields[&struct_getter.attribute.name.value].clone());
}
for module_item in &ctx.current_module.items {
match module_item {
ast::ModuleItem::Impl(impl_) => {
if impl_.struct_.name.name.value == s.source.name.name.value {
for method in &impl_.functions {
if method.declaration.name.name.value == struct_getter.attribute.name.value {
// if first type matches, partial apply self
if method.declaration.arguments.len() > 0 {
match &method.declaration.arguments[0].type_ {
ast::TypeUsage::Named(arg_named) => {
if arg_named.name.name.value == "Self" {
return ExpressionResult::Value(Value::Function(Function {
partial: vec![source.clone()],
ref_: FunctionRef::User(method.clone()),
}));
}
}
_ => {}
}
}
return ExpressionResult::Value(Value::Function(Function {
partial: vec![],
ref_: FunctionRef::User(method.clone()),
}));
}
}
}
}
_ => {}
}
}
panic!("TypeError: Method not found");
}
_ => {
panic!("TypeError: struct getter used with non-struct");
}
}
}
ast::Subexpression::Block(block) => {
return self.with_block(ctx, block);
}
ast::Subexpression::Op(op) => {
let left = match self.with_expression(ctx, &op.left) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
let right = match self.with_expression(ctx, &op.right) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
return ExpressionResult::Return(r);
}
};
let result = match (&left, &op.op, &right) {
//I
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I8(r))) => {
Value::Numeric(NumericValue::I8(l + r))
}
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I8(r))) => {
Value::Numeric(NumericValue::I8(l - r))
}
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I8(r))) => {
Value::Numeric(NumericValue::I8(l * r))
}
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Div, Value::Numeric(NumericValue::I8(r))) => {
Value::Numeric(NumericValue::I8(l / r))
}
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I16(r))) => {
Value::Numeric(NumericValue::I16(l + r))
}
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I16(r))) => {
Value::Numeric(NumericValue::I16(l - r))
}
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I16(r))) => {
Value::Numeric(NumericValue::I16(l * r))
}
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Div, Value::Numeric(NumericValue::I16(r))) => {
Value::Numeric(NumericValue::I16(l / r))
}
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I32(r))) => {
Value::Numeric(NumericValue::I32(l + r))
}
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I32(r))) => {
Value::Numeric(NumericValue::I32(l - r))
}
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I32(r))) => {
Value::Numeric(NumericValue::I32(l * r))
}
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Div, Value::Numeric(NumericValue::I32(r))) => {
Value::Numeric(NumericValue::I32(l / r))
}
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I64(r))) => {
Value::Numeric(NumericValue::I64(l + r))
}
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I64(r))) => {
Value::Numeric(NumericValue::I64(l - r))
}
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I64(r))) => {
Value::Numeric(NumericValue::I64(l * r))
}
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Div, Value::Numeric(NumericValue::I64(r))) => {
Value::Numeric(NumericValue::I64(l / r))
}
//U
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U8(r))) => {
Value::Numeric(NumericValue::U8(l + r))
}
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U8(r))) => {
Value::Numeric(NumericValue::U8(l - r))
}
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U8(r))) => {
Value::Numeric(NumericValue::U8(l * r))
}
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Div, Value::Numeric(NumericValue::U8(r))) => {
Value::Numeric(NumericValue::U8(l / r))
}
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U16(r))) => {
Value::Numeric(NumericValue::U16(l + r))
}
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U16(r))) => {
Value::Numeric(NumericValue::U16(l - r))
}
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U16(r))) => {
Value::Numeric(NumericValue::U16(l * r))
}
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Div, Value::Numeric(NumericValue::U16(r))) => {
Value::Numeric(NumericValue::U16(l / r))
}
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U32(r))) => {
Value::Numeric(NumericValue::U32(l + r))
}
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U32(r))) => {
Value::Numeric(NumericValue::U32(l - r))
}
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U32(r))) => {
Value::Numeric(NumericValue::U32(l * r))
}
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Div, Value::Numeric(NumericValue::U32(r))) => {
Value::Numeric(NumericValue::U32(l / r))
}
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U64(r))) => {
Value::Numeric(NumericValue::U64(l + r))
}
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U64(r))) => {
Value::Numeric(NumericValue::U64(l - r))
}
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U64(r))) => {
Value::Numeric(NumericValue::U64(l * r))
}
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Div, Value::Numeric(NumericValue::U64(r))) => {
Value::Numeric(NumericValue::U64(l / r))
}
//F
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::F32(r))) => {
Value::Numeric(NumericValue::F32(l + r))
}
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Minus, Value::Numeric(NumericValue::F32(r))) => {
Value::Numeric(NumericValue::F32(l - r))
}
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Mul, Value::Numeric(NumericValue::F32(r))) => {
Value::Numeric(NumericValue::F32(l * r))
}
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Div, Value::Numeric(NumericValue::F32(r))) => {
Value::Numeric(NumericValue::F32(l / r))
}
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::F64(r))) => {
Value::Numeric(NumericValue::F64(l + r))
}
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Minus, Value::Numeric(NumericValue::F64(r))) => {
Value::Numeric(NumericValue::F64(l - r))
}
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Mul, Value::Numeric(NumericValue::F64(r))) => {
Value::Numeric(NumericValue::F64(l * r))
}
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Div, Value::Numeric(NumericValue::F64(r))) => {
Value::Numeric(NumericValue::F64(l / r))
}
//fail
_ => panic!(""),
};
return ExpressionResult::Value(result);
}
}
}
}

View File

@@ -1,119 +0,0 @@
// mod types;
mod ast;
mod errors;
mod interpreter;
mod trait_checking;
mod type_checking;
#[macro_use]
extern crate lalrpop_util;
lalrpop_mod!(pub grammar); // synthesized by LALRPOP
use std::fs;
extern crate clap;
use clap::{App, Arg};
fn main() {
let matches = App::new("Boring Language Compiler")
.version("0.0.1")
.author("Andrew Segavac")
.about("Compiles boringlang files")
.arg(
Arg::with_name("OUTPUT")
.short("o")
.long("out")
.value_name("OUTOUT")
.help("Sets an output file")
.takes_value(true),
)
.arg(Arg::with_name("INPUT").help("Sets the input file").required(true).index(1))
.arg(Arg::with_name("v").short("v").multiple(true).help("Sets the level of verbosity"))
.get_matches();
let input = matches.value_of("INPUT").unwrap();
let contents = fs::read_to_string(input).expect("input file not found");
let unknown_id_gen = ast::IdGenerator::new("S");
let module_ast = grammar::ModuleParser::new().parse(&unknown_id_gen, &contents).unwrap(); //TODO: convert to error
// println!("ast: {:#?}", &module_ast);
// println!("resolved ast: {:#?}", &resolved_ast);
let trait_checker = trait_checking::TraitChecker {};
match trait_checker.with_module(&module_ast) {
Ok(_) => {}
Err(err) => {
println!("trait checking error: {:#?}", &err);
return;
}
}
let type_checker = type_checking::TypeChecker {};
let type_checking_result = type_checker.with_module(&module_ast);
match &type_checking_result {
Ok((checked_ast, subst)) => {
println!("checked ast: {:#?}", &checked_ast);
println!("substitutions: {:#?}", &subst);
let interpreter = interpreter::TreeWalkInterpreter {};
let result = interpreter.with_module(&checked_ast);
println!("final result: {:#?}", &result);
}
Err(err) => {
println!("type checking error: {:#?}", &err);
}
}
// let context = Context::create();
// let mut code_gen = compiler::ModuleCodeGen::new(&context, "main".to_string());
// code_gen.gen_module(module_ast);
//
// let mut f = fs::File::create(output).expect("Unable to create out file");
// f.write_all(code_gen.dump().as_bytes()).expect("Unable to write data");
}
#[test]
fn grammar() {
let id_gen = ast::IdGenerator::new("S");
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "22").is_ok());
assert!(grammar::IdentifierParser::new().parse(&id_gen, "foo").is_ok());
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "2a").is_err());
assert!(grammar::TermParser::new().parse(&id_gen, "22").is_ok());
assert!(grammar::TermParser::new().parse(&id_gen, "foo").is_ok());
assert!(grammar::ExpressionParser::new().parse(&id_gen, "22 * foo").is_ok());
assert!(grammar::ExpressionParser::new().parse(&id_gen, "22 * 33").is_ok());
assert!(grammar::ExpressionParser::new().parse(&id_gen, "(22 * 33) + 24").is_ok());
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24 }").is_ok());
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24; 25 }").is_ok());
// assert!(grammar::BlockParser::new().parse("{ (22 * 33) + 24\n 24 }").is_ok());
assert!(grammar::BlockParser::new().parse(&id_gen, "{ }").is_ok());
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo: i32").is_ok());
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo").is_err());
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "1234").is_err());
assert!(grammar::FunctionParser::new()
.parse(&id_gen, "fn add(a: i32, b: i32): i32 { a + b }")
.is_ok());
assert!(grammar::FunctionParser::new()
.parse(&id_gen, "fn random_dice_roll(): i32 { 4 }")
.is_ok());
assert!(grammar::FunctionParser::new()
.parse(&id_gen, "fn add(a: i32, b: i32): i32 { a + }")
.is_err());
assert!(grammar::FunctionParser::new()
.parse(&id_gen, "fn add(a: i32, b: i32): i32")
.is_err());
assert!(grammar::FunctionCallParser::new().parse(&id_gen, "foo(1, 2)").is_ok());
assert!(grammar::ModuleParser::new()
.parse(&id_gen, "fn add(a: i32, b: i32): i32 { a + b }")
.is_ok());
assert!(grammar::ModuleParser::new()
.parse(
&id_gen,
"fn add(a: i32, b: i32): i32 { a + b } fn subtract(a: i32, b: i32): i32 { a - b }"
)
.is_ok());
}

View File

@@ -1,156 +0,0 @@
use crate::ast;
use crate::errors;
use std::collections::HashMap;
pub type Result<T, E = errors::TypingError> = std::result::Result<T, E>;
#[derive(Debug, Clone, PartialEq, Eq)]
struct Context {
pub environment_traits: HashMap<String, ast::TraitTypeDeclaration>,
}
fn create_builtins() -> HashMap<String, ast::TraitTypeDeclaration> {
let result = HashMap::<String, ast::TraitTypeDeclaration>::new();
return result;
}
fn compare_struct_trait(
struct_: &ast::TypeUsage,
trait_: &ast::TypeUsage,
struct_name: &ast::Identifier,
trait_name: &ast::Identifier,
) -> Result<()> {
match struct_ {
ast::TypeUsage::Named(named) => match trait_ {
ast::TypeUsage::Named(trait_named) => {
if named.name.name.value == trait_named.name.name.value {
return Ok(());
}
return Err(errors::TypingError::TypeMismatch {
type_one: struct_.clone(),
type_two: trait_.clone(),
});
}
ast::TypeUsage::Function(_) => {
return Err(errors::TypingError::TypeMismatch {
type_one: struct_.clone(),
type_two: trait_.clone(),
});
}
_ => panic!("Unknown in function definition"),
},
ast::TypeUsage::Function(function) => match trait_ {
ast::TypeUsage::Named(_) => {
return Err(errors::TypingError::TypeMismatch {
type_one: struct_.clone(),
type_two: trait_.clone(),
});
}
ast::TypeUsage::Function(trait_function) => {
if function.arguments.len() != trait_function.arguments.len() {
return Err(errors::TypingError::TypeMismatch {
type_one: struct_.clone(),
type_two: trait_.clone(),
});
}
for (i, _) in function.arguments.iter().enumerate() {
compare_struct_trait(&function.arguments[i], &trait_function.arguments[i], struct_name, trait_name)?;
}
compare_struct_trait(&function.return_type, &trait_function.return_type, struct_name, trait_name)?;
return Ok(());
}
_ => panic!("Unknown in function definition"),
},
_ => panic!("Unknown in function definition"),
}
}
pub struct TraitChecker {}
impl TraitChecker {
pub fn with_module(self: &Self, module: &ast::Module) -> Result<()> {
let mut ctx = Context {
environment_traits: create_builtins(),
};
for item in module.items.iter() {
match item {
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Trait(trait_)) => {
ctx.environment_traits.insert(trait_.name.name.value.to_string(), trait_.clone());
}
_ => {}
}
}
for item in module.items.iter() {
match item {
ast::ModuleItem::Impl(impl_) => {
self.with_impl(&ctx, impl_)?;
}
_ => {}
}
}
return Ok(());
}
fn with_impl(self: &Self, ctx: &Context, impl_: &ast::Impl) -> Result<()> {
// See if trait actually matches
match &impl_.trait_ {
Some(trait_) => {
// assert trait functions satisfied
if !ctx.environment_traits.contains_key(&trait_.name.name.value) {
return Err(errors::TypingError::TypeDoesNotExist {
identifier: trait_.name.clone(),
});
}
let trait_declaration = &ctx.environment_traits[&trait_.name.name.value];
for trait_item in trait_declaration.functions.iter() {
match trait_item {
ast::TraitItem::FunctionDeclaration(declaration) => {
let mut found = false;
for impl_function in impl_.functions.iter() {
if impl_function.declaration.name.name.value == declaration.name.name.value {
found = true;
compare_struct_trait(
&impl_function.declaration.to_type(),
&declaration.to_type(),
&impl_.struct_.name,
&trait_.name,
)?;
}
}
if found == false {
return Err(errors::TypingError::MissingTraitFunction {
struct_name: impl_.struct_.name.clone(),
function_name: declaration.name.clone(),
});
}
}
}
}
// assert all functions are in trait
for impl_function in impl_.functions.iter() {
let mut found = false;
for trait_item in trait_declaration.functions.iter() {
match trait_item {
ast::TraitItem::FunctionDeclaration(declaration) => {
if impl_function.declaration.name.name.value == declaration.name.name.value {
found = true;
break;
}
}
};
}
if found == false {
return Err(errors::TypingError::FunctionNotInTrait {
function_name: impl_function.declaration.name.clone(),
});
}
}
}
None => {}
}
// TODO: check for duplicate functions
return Ok(());
}
}

View File

@@ -1,379 +0,0 @@
use crate::ast;
use crate::errors;
pub type Result<T, E = errors::TypingError> = std::result::Result<T, E>;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Context {
pub type_aliases: Vec<ast::AliasTypeDeclaration>,
}
fn resolve_type(ctx: &Context, type_: &ast::NamedTypeUsage) -> Result<ast::TypeUsage> {
let mut changed = true;
let mut result = ast::TypeUsage::Named(type_.clone());
while changed {
changed = false;
let current = &result.clone();
match current {
ast::TypeUsage::Named(named) => {
for alias in ctx.type_aliases.iter() {
if named.name.name.value == alias.name.name.value { // is alias, replace
changed = true;
result = alias.replaces.clone();
}
}
}
_ => break,
}
}
match &result {
ast::TypeUsage::Named(named) => {
match &named.type_parameters {
ast::GenericUsage::Known(known) => {
let mut result_params = vec!();
for param in known.parameters.iter() {
result_params.push(process_type(ctx, param)?);
}
let mut new_named = named.clone();
new_named.type_parameters = ast::GenericUsage::new(&result_params);
result = ast::TypeUsage::Named(new_named);
},
_ => {}
}
},
ast::TypeUsage::Function(func) => {
match &type_.type_parameters {
ast::GenericUsage::Known(known) => {
if known.parameters.len() > 0 {
return Err(errors::TypingError::InvalidTypeParameterOnAlias{alias: type_.name.clone()});
}
},
_ => {} //skip
}
},
_ => {
panic!("alias of a non-type, not possible");
}
}
return Ok(result);
}
fn process_type(ctx: &Context, type_: &ast::TypeUsage) -> Result<ast::TypeUsage> {
match type_ {
ast::TypeUsage::Named(named) => {
return Ok(resolve_type(ctx, named)?);
}
ast::TypeUsage::Function(function) => {
let mut arguments = vec!();
for a in function.arguments.iter() {
arguments.push(process_type(ctx, &a.clone())?);
}
return Ok(ast::TypeUsage::Function(ast::FunctionTypeUsage {
arguments: arguments,
return_type: Box::new(process_type(ctx, &function.return_type.clone())?),
}));
}
ast::TypeUsage::Unknown(unknown) => {
return Ok(ast::TypeUsage::Unknown(unknown.clone()));
},
ast::TypeUsage::Namespace(namespace) => {
match namespace {
ast::NamespaceTypeUsage::Type(named_type)=> {
let result = resolve_type(ctx, named_type)?;
match result {
ast::TypeUsage::Named(named) => {
return Ok(ast::TypeUsage::Namespace(ast::NamespaceTypeUsage::Type(named)));
},
_ => {
return Err(errors::TypingError::InvalidUseofAlias);
}
}
}
}
}
}
}
pub struct TypeAliasResolver {}
impl TypeAliasResolver {
pub fn with_module(self: &Self, module: &ast::Module) -> Result<ast::Module> {
let mut ctx = Context { type_aliases: vec![] };
for item in module.items.iter() {
match item {
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Alias(alias)) => {
ctx.type_aliases.push(alias.clone());
}
_ => {}
}
}
let mut items = vec!();
for item in module.items.iter() {
items.push(match item {
ast::ModuleItem::Function(function) => ast::ModuleItem::Function(self.with_function(&ctx, function)?),
ast::ModuleItem::TypeDeclaration(type_declaration) => {
ast::ModuleItem::TypeDeclaration(self.with_type_declaration(&ctx, type_declaration)?)
}
ast::ModuleItem::Impl(impl_) => ast::ModuleItem::Impl(self.with_impl(&ctx, impl_)?),
});
}
return Ok(ast::Module {
items: items,
});
}
fn with_function(self: &Self, ctx: &Context, function: &ast::Function) -> Result<ast::Function> {
return Ok(ast::Function {
declaration: self.with_function_declaration(ctx, &function.declaration)?,
block: self.with_block(ctx, &function.block)?,
});
}
fn with_function_declaration(self: &Self, ctx: &Context, declaration: &ast::FunctionDeclaration) -> Result<ast::FunctionDeclaration> {
let mut arguments = vec!();
for arg in declaration.arguments.iter() {
arguments.push(ast::VariableDeclaration {
name: arg.name.clone(),
type_: process_type(ctx, &arg.type_)?,
});
}
return Ok(ast::FunctionDeclaration {
name: declaration.name.clone(),
generic: declaration.generic.clone(),
arguments: arguments,
return_type: process_type(ctx, &declaration.return_type)?,
});
}
fn with_type_declaration(self: &Self, ctx: &Context, type_declaration: &ast::TypeDeclaration) -> Result<ast::TypeDeclaration> {
match type_declaration {
ast::TypeDeclaration::Struct(struct_) => {
return Ok(ast::TypeDeclaration::Struct(self.with_struct_declaration(ctx, struct_)?));
}
ast::TypeDeclaration::Primitive(primitive) => {
return Ok(ast::TypeDeclaration::Primitive(primitive.clone()));
}
ast::TypeDeclaration::Alias(alias) => {
return Ok(ast::TypeDeclaration::Alias(alias.clone()));
}
ast::TypeDeclaration::Trait(trait_) => {
return Ok(ast::TypeDeclaration::Trait(self.with_trait(ctx, trait_)?));
}
}
}
fn with_struct_declaration(self: &Self, ctx: &Context, struct_: &ast::StructTypeDeclaration) -> Result<ast::StructTypeDeclaration> {
let mut fields = vec!();
for field in struct_.fields.iter() {
fields.push(ast::StructField {
name: field.name.clone(),
type_: process_type(ctx, &field.type_)?,
});
}
return Ok(ast::StructTypeDeclaration {
generic: struct_.generic.clone(),
name: struct_.name.clone(),
fields: fields,
});
}
fn with_trait(self: &Self, ctx: &Context, trait_: &ast::TraitTypeDeclaration) -> Result<ast::TraitTypeDeclaration> {
let mut trait_ctx = ctx.clone();
trait_ctx.type_aliases.push(ast::AliasTypeDeclaration {
name: ast::Identifier {
name: ast::Spanned {
span: ast::Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "Self".to_string(),
},
},
replaces: ast::TypeUsage::Named(ast::NamedTypeUsage {
type_parameters: ast::GenericUsage::Unknown,
name: trait_.name.clone(),
}),
});
let mut functions = vec!();
for f in trait_.functions.iter() {
functions.push(match f {
ast::TraitItem::Function(function) => ast::TraitItem::Function(self.with_function(&trait_ctx, function)?),
ast::TraitItem::FunctionDeclaration(function_declaration) => {
ast::TraitItem::FunctionDeclaration(self.with_function_declaration(&trait_ctx, function_declaration)?)
}
});
}
return Ok(ast::TraitTypeDeclaration {
generic: trait_.generic.clone(),
name: trait_.name.clone(),
functions: functions,
});
}
fn with_impl(self: &Self, ctx: &Context, impl_: &ast::Impl) -> Result<ast::Impl> {
let mut impl_ctx = ctx.clone();
impl_ctx.type_aliases.push(ast::AliasTypeDeclaration {
name: ast::Identifier {
name: ast::Spanned {
span: ast::Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "Self".to_string(),
},
},
replaces: ast::TypeUsage::Named(impl_.struct_.clone()),
});
let mut functions = vec!();
for f in impl_.functions.iter() {
functions.push(self.with_function(&impl_ctx, f)?);
}
return Ok(ast::Impl {
generic: impl_.generic.clone(),
trait_: impl_.trait_.clone(),
struct_: impl_.struct_.clone(),
functions: functions,
});
}
fn with_block(self: &Self, ctx: &Context, block: &ast::Block) -> Result<ast::Block> {
let mut statements = vec!();
for s in block.statements.iter() {
statements.push(self.with_statement(ctx, s)?);
}
return Ok(ast::Block {
statements: statements,
type_: process_type(ctx, &block.type_)?,
});
}
fn with_statement(self: &Self, ctx: &Context, statement: &ast::Statement) -> Result<ast::Statement> {
match statement {
ast::Statement::Return(return_statement) => {
return Ok(ast::Statement::Return(self.with_return_statement(ctx, return_statement)?));
}
ast::Statement::Let(let_statement) => {
return Ok(ast::Statement::Let(self.with_let_statement(ctx, let_statement)?));
}
ast::Statement::Assignment(assignment_statement) => {
return Ok(ast::Statement::Assignment(self.with_assignment_statement(ctx, assignment_statement)?));
}
ast::Statement::Expression(expression) => {
return Ok(ast::Statement::Expression(self.with_expression(ctx, expression)?));
}
}
}
fn with_return_statement(self: &Self, ctx: &Context, statement: &ast::ReturnStatement) -> Result<ast::ReturnStatement> {
return Ok(ast::ReturnStatement {
source: self.with_expression(ctx, &statement.source)?,
});
}
fn with_let_statement(self: &Self, ctx: &Context, statement: &ast::LetStatement) -> Result<ast::LetStatement> {
return Ok(ast::LetStatement {
variable_name: statement.variable_name.clone(),
expression: self.with_expression(ctx, &statement.expression)?,
type_: process_type(ctx, &statement.type_)?,
});
}
fn with_assignment_statement(self: &Self, ctx: &Context, statement: &ast::AssignmentStatement) -> Result<ast::AssignmentStatement> {
return Ok(ast::AssignmentStatement {
source: match &statement.source {
ast::AssignmentTarget::Variable(variable) => ast::AssignmentTarget::Variable(ast::VariableUsage {
type_parameters: variable.type_parameters.clone(),
name: variable.name.clone(),
type_: process_type(ctx, &variable.type_)?,
}),
ast::AssignmentTarget::StructAttr(struct_attr) => ast::AssignmentTarget::StructAttr(ast::StructGetter {
type_parameters: struct_attr.type_parameters.clone(),
source: self.with_expression(ctx, &struct_attr.source)?,
attribute: struct_attr.attribute.clone(),
type_: process_type(ctx, &struct_attr.type_)?,
}),
},
expression: self.with_expression(ctx, &statement.expression)?,
});
}
fn with_expression(self: &Self, ctx: &Context, expression: &ast::Expression) -> Result<ast::Expression> {
return Ok(ast::Expression {
subexpression: Box::new(match &*expression.subexpression {
ast::Subexpression::LiteralInt(literal_int) => ast::Subexpression::LiteralInt(ast::LiteralInt {
value: literal_int.value.clone(),
type_: process_type(ctx, &literal_int.type_)?,
}),
ast::Subexpression::LiteralFloat(literal_float) => ast::Subexpression::LiteralFloat(ast::LiteralFloat {
value: literal_float.value.clone(),
type_: process_type(ctx, &literal_float.type_)?,
}),
ast::Subexpression::LiteralBool(literal_bool) => ast::Subexpression::LiteralBool(ast::LiteralBool {
value: literal_bool.value.clone(),
type_: process_type(ctx, &literal_bool.type_)?,
}),
ast::Subexpression::LiteralString(literal_string) => ast::Subexpression::LiteralString(ast::LiteralString {
value: literal_string.value.clone(),
type_: process_type(ctx, &literal_string.type_)?,
}),
ast::Subexpression::LiteralStruct(literal_struct) => {
let result = resolve_type(
ctx,
&ast::NamedTypeUsage {
type_parameters: literal_struct.type_parameters.clone(),
name: literal_struct.name.clone(),
},
)?;
let new_name = match &result {
ast::TypeUsage::Named(named) => named.name.clone(),
_ => panic!("LiteralStruct resolved to non-named-type"),
};
let mut fields = vec!();
for field in literal_struct.fields.iter() {
fields.push((field.0.clone(), self.with_expression(ctx, &field.1)?));
}
ast::Subexpression::LiteralStruct(ast::LiteralStruct {
type_parameters: literal_struct.type_parameters.clone(),
name: new_name.clone(),
fields: fields,
type_: process_type(ctx, &literal_struct.type_)?,
})
}
ast::Subexpression::FunctionCall(function_call) => {
let mut arguments = vec!();
for arg in function_call.arguments.iter() {
arguments.push(self.with_expression(ctx, arg)?);
}
ast::Subexpression::FunctionCall(ast::FunctionCall {
source: self.with_expression(ctx, &function_call.source)?,
arguments: arguments,
type_: process_type(ctx, &function_call.type_)?,
})
},
ast::Subexpression::VariableUsage(variable_usage) => ast::Subexpression::VariableUsage(ast::VariableUsage {
name: variable_usage.name.clone(),
type_parameters: variable_usage.type_parameters.clone(),
type_: process_type(ctx, &variable_usage.type_)?,
}),
ast::Subexpression::If(if_expression) => ast::Subexpression::If(ast::IfExpression {
condition: self.with_expression(ctx, &if_expression.condition)?,
block: self.with_block(ctx, &if_expression.block)?,
else_: match &if_expression.else_ {
Some(else_) => Some(self.with_block(ctx, else_)?),
None => None,
},
type_: process_type(ctx, &if_expression.type_)?,
}),
ast::Subexpression::StructGetter(struct_getter) => ast::Subexpression::StructGetter(ast::StructGetter {
type_parameters: struct_getter.type_parameters.clone(),
source: self.with_expression(ctx, &struct_getter.source)?,
attribute: struct_getter.attribute.clone(),
type_: process_type(ctx, &struct_getter.type_)?,
}),
ast::Subexpression::Block(block) => ast::Subexpression::Block(self.with_block(ctx, &block)?),
ast::Subexpression::Op(op) => ast::Subexpression::Op(ast::Operation {
left: self.with_expression(ctx, &op.left)?,
op: op.op.clone(),
right: self.with_expression(ctx, &op.right)?,
}),
}),
type_: process_type(ctx, &expression.type_)?,
});
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,58 +0,0 @@
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Signedness {
Signed,
Unsigned,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum IntBitness {
X8,
X16,
X32,
X64,
X128,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum FloatBitness {
X32,
X64,
X128,
}
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct IntTypeDef {
pub signedness: Signedness,
pub bitness: IntBitness,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct FloatTypeDef {
pub bitness: FloatBitness,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct FunctionTypeDef {
pub arguments: Vec<Type>,
pub return_type: Box<Type>,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum Type {
Bool,
Int(IntTypeDef),
Float(FloatTypeDef),
Function(FunctionTypeDef),
// String(StringTypeDef),
// Struct(StructTypeDef),
// Trait(TraitTypeDef),
// Void,
// Never,
}
/// Used for places where type info may or may not be solved.
#[derive(Clone, Eq, PartialEq, Hash)]
pub enum SpecifiedType {
Unknown,
Type(Type),
}

19
tsconfig.json Normal file
View File

@@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": ".",
"types": ["bun-types"]
},
"include": ["./**/*"],
"exclude": ["node_modules", "dist", "test/**/*"]
}