switching language to tswq
This commit is contained in:
130
.gitignore
vendored
130
.gitignore
vendored
@@ -1,112 +1,36 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
.direnv/
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
# dependencies (bun install)
|
||||
node_modules
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
# output
|
||||
out
|
||||
dist
|
||||
*.tgz
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
# code coverage
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
# logs
|
||||
logs
|
||||
_.log
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Unit test / coverage reports
|
||||
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
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
# caches
|
||||
.eslintcache
|
||||
.cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
|
||||
#Added by cargo
|
||||
#
|
||||
#already existing elements are commented out
|
||||
|
||||
/target
|
||||
**/*.rs.bk
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
@@ -1 +0,0 @@
|
||||
max_width=140 # Not ideal
|
||||
501
Cargo.lock
generated
501
Cargo.lock
generated
@@ -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"
|
||||
18
Cargo.toml
18
Cargo.toml
@@ -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"
|
||||
@@ -1,5 +0,0 @@
|
||||
FROM rust:1.89
|
||||
|
||||
# RUN apt update && apt-get install -y llvm clang
|
||||
RUN rustup component add rustfmt
|
||||
WORKDIR /code
|
||||
5
build.rs
5
build.rs
@@ -1,5 +0,0 @@
|
||||
extern crate lalrpop;
|
||||
|
||||
fn main() {
|
||||
lalrpop::process_root().unwrap();
|
||||
}
|
||||
412
bun.lock
Normal file
412
bun.lock
Normal 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=="],
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
version: "3"
|
||||
services:
|
||||
boring:
|
||||
build: .
|
||||
volumes:
|
||||
- .:/code/
|
||||
18
eslint.config.ts
Normal file
18
eslint.config.ts
Normal 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
31
package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
26
packages/boringlang/package.json
Normal file
26
packages/boringlang/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
11
packages/boringlang/src/index.ts
Normal file
11
packages/boringlang/src/index.ts
Normal 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();
|
||||
19
packages/boringlang/tsconfig.json
Normal file
19
packages/boringlang/tsconfig.json
Normal 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
10
prettier.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { type Config } from "prettier";
|
||||
|
||||
const config: Config = {
|
||||
trailingComma: "all",
|
||||
singleQuote: false,
|
||||
printWidth: 80,
|
||||
semi: true,
|
||||
};
|
||||
|
||||
export default config;
|
||||
410
src/ast.rs
410
src/ast.rs
@@ -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>,
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::ast;
|
||||
124
src/compiler.rs
124
src/compiler.rs
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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> },
|
||||
}
|
||||
@@ -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}
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
119
src/main.rs
119
src/main.rs
@@ -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());
|
||||
}
|
||||
@@ -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(());
|
||||
}
|
||||
}
|
||||
@@ -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_)?,
|
||||
});
|
||||
}
|
||||
}
|
||||
1638
src/type_checking.rs
1638
src/type_checking.rs
File diff suppressed because it is too large
Load Diff
58
src/types.rs
58
src/types.rs
@@ -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
19
tsconfig.json
Normal 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/**/*"]
|
||||
}
|
||||
Reference in New Issue
Block a user