dev/prometeuc-base (#4)
Co-authored-by: Nilton Constantino <nilton.constantino@visma.com> Reviewed-on: #4
This commit is contained in:
parent
d9f6c30c38
commit
4cc0170c74
399
Cargo.lock
generated
399
Cargo.lock
generated
@ -154,6 +154,12 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.9"
|
||||
@ -181,6 +187,12 @@ dependencies = [
|
||||
"libloading 0.7.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert-unchecked"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7330592adf847ee2e3513587b4db2db410a0d751378654e7e993d9adcbe5c795"
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
@ -258,6 +270,9 @@ name = "bumpalo"
|
||||
version = "3.19.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
@ -297,6 +312,15 @@ dependencies = [
|
||||
"wayland-client",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "castaway"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.52"
|
||||
@ -400,7 +424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
"unicode-width 0.1.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -450,6 +474,20 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compact_str"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"cfg-if",
|
||||
"itoa",
|
||||
"rustversion",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
@ -519,6 +557,12 @@ dependencies = [
|
||||
"bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cow-utils"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79"
|
||||
|
||||
[[package]]
|
||||
name = "cpal"
|
||||
version = "0.15.3"
|
||||
@ -775,6 +819,15 @@ dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
@ -1105,6 +1158,22 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonmax"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51"
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.2"
|
||||
@ -1116,6 +1185,15 @@ dependencies = [
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@ -1423,6 +1501,187 @@ dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "4.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52"
|
||||
|
||||
[[package]]
|
||||
name = "oxc-miette"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e03e63fd113c068b82d07c9c614b0b146c08a3ac0a4dface3ea1d1a9d14d549e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"owo-colors",
|
||||
"oxc-miette-derive",
|
||||
"textwrap",
|
||||
"thiserror",
|
||||
"unicode-width 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc-miette-derive"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e21f680e8c5f1900297d394627d495351b9e37761f7bbf90116bd5eeb6e80967"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_allocator"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17374a91329f2e362bc8be31cb3e171ef226777d0ea668e17a39620443693027"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"bumpalo",
|
||||
"hashbrown 0.15.5",
|
||||
"rustc-hash 2.1.1",
|
||||
"simdutf8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_ast"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b38cfe954ee987354af015020f5cb2723df6fed6cd688eff24388437c7eb7e"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"cow-utils",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"oxc_allocator",
|
||||
"oxc_ast_macros",
|
||||
"oxc_estree",
|
||||
"oxc_regular_expression",
|
||||
"oxc_span",
|
||||
"oxc_syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_ast_macros"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85f9e03eff90b041078edcc8aff09457eb4126fa5d62a383fdb082d3ae286274"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_diagnostics"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a24c41929c1910d83fb6f4c508190a8b2d1bad02e81c8cb3a9d3f474ca0ad2c1"
|
||||
dependencies = [
|
||||
"cow-utils",
|
||||
"oxc-miette",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_ecmascript"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30fba86c97b571671f941b818e6831ba821aac398b9f6f3b4e3367ca264b8324"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"oxc_ast",
|
||||
"oxc_span",
|
||||
"oxc_syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_estree"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e587034bb5f108dd987e5419a4ad35a173550bd9439fc2b610d34e4ce41e8b23"
|
||||
|
||||
[[package]]
|
||||
name = "oxc_index"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eca5d9726cd0a6e433debe003b7bc88b2ecad0bb6109f0cef7c55e692139a34"
|
||||
|
||||
[[package]]
|
||||
name = "oxc_parser"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8dc385aca3586877f8c918aed1141b885dedcfc1019d6ea5be4105f8e2a7965e"
|
||||
dependencies = [
|
||||
"assert-unchecked",
|
||||
"bitflags 2.10.0",
|
||||
"cow-utils",
|
||||
"memchr",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"oxc_allocator",
|
||||
"oxc_ast",
|
||||
"oxc_diagnostics",
|
||||
"oxc_ecmascript",
|
||||
"oxc_regular_expression",
|
||||
"oxc_span",
|
||||
"oxc_syntax",
|
||||
"rustc-hash 2.1.1",
|
||||
"seq-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_regular_expression"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8d172402f6d542ab2837d35126cc42ad6989b9c2289b06bc5c8c89dceb60c48"
|
||||
dependencies = [
|
||||
"oxc_allocator",
|
||||
"oxc_ast_macros",
|
||||
"oxc_diagnostics",
|
||||
"oxc_estree",
|
||||
"oxc_span",
|
||||
"phf",
|
||||
"rustc-hash 2.1.1",
|
||||
"unicode-id-start",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_span"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75881376dfdbb6a23f12a66794904f0d215629f208edcf7e156c0770e89e2101"
|
||||
dependencies = [
|
||||
"compact_str",
|
||||
"oxc-miette",
|
||||
"oxc_allocator",
|
||||
"oxc_ast_macros",
|
||||
"oxc_estree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxc_syntax"
|
||||
version = "0.48.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6d88037a5de07f66299ab523a65545cc48d550658cea8cadcea09b60596dd49"
|
||||
dependencies = [
|
||||
"assert-unchecked",
|
||||
"bitflags 2.10.0",
|
||||
"cow-utils",
|
||||
"nonmax",
|
||||
"oxc_allocator",
|
||||
"oxc_ast_macros",
|
||||
"oxc_estree",
|
||||
"oxc_index",
|
||||
"oxc_span",
|
||||
"phf",
|
||||
"rustc-hash 2.1.1",
|
||||
"ryu-js",
|
||||
"unicode-id-start",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.5"
|
||||
@ -1458,6 +1717,48 @@ version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.10"
|
||||
@ -1607,6 +1908,22 @@ dependencies = [
|
||||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prometeuc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"oxc_allocator",
|
||||
"oxc_ast",
|
||||
"oxc_parser",
|
||||
"oxc_span",
|
||||
"prometeu-bytecode",
|
||||
"prometeu-core",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.38.4"
|
||||
@ -1631,6 +1948,21 @@ version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "range-alloc"
|
||||
version = "0.1.4"
|
||||
@ -1760,6 +2092,18 @@ version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
|
||||
|
||||
[[package]]
|
||||
name = "ryu-js"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd29631678d6fb0903b69223673e122c32e9ae559d0960a38d574695ebc0ea15"
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
version = "0.7.4"
|
||||
@ -1803,6 +2147,12 @@ dependencies = [
|
||||
"tiny-skia",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "seq-macro"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
@ -1852,6 +2202,18 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.11"
|
||||
@ -1873,6 +2235,12 @@ version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "smawk"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
||||
|
||||
[[package]]
|
||||
name = "smithay-client-toolkit"
|
||||
version = "0.19.2"
|
||||
@ -1965,6 +2333,17 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
|
||||
dependencies = [
|
||||
"smawk",
|
||||
"unicode-linebreak",
|
||||
"unicode-width 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
@ -2071,12 +2450,24 @@ dependencies = [
|
||||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-id-start"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81b79ad29b5e19de4260020f8919b443b2ef0277d242ce532ec7b7a2cc8b6007"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-linebreak"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
@ -2089,6 +2480,12 @@ version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
|
||||
@ -3,6 +3,8 @@ members = [
|
||||
"crates/prometeu-core",
|
||||
"crates/prometeu-runtime-desktop",
|
||||
"crates/prometeu",
|
||||
"crates/prometeu-bytecode",
|
||||
"crates/prometeuc",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ pub mod firmware;
|
||||
pub mod fs;
|
||||
pub mod telemetry;
|
||||
pub mod debugger_protocol;
|
||||
mod prometeu_os;
|
||||
pub mod prometeu_os;
|
||||
mod prometeu_hub;
|
||||
|
||||
pub use hardware::hardware::Hardware;
|
||||
|
||||
@ -1,3 +1,20 @@
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub enum ButtonId {
|
||||
Up = 0,
|
||||
Down = 1,
|
||||
Left = 2,
|
||||
Right = 3,
|
||||
A = 4,
|
||||
B = 5,
|
||||
X = 6,
|
||||
Y = 7,
|
||||
L = 8,
|
||||
R = 9,
|
||||
Start = 10,
|
||||
Select = 11,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy, Debug)]
|
||||
pub struct Button {
|
||||
pub pressed: bool,
|
||||
|
||||
@ -9,7 +9,7 @@ mod cartridge;
|
||||
mod cartridge_loader;
|
||||
mod window;
|
||||
|
||||
pub use button::Button;
|
||||
pub use button::{Button, ButtonId};
|
||||
pub use cartridge::{AppMode, Cartridge, CartridgeDTO, CartridgeError};
|
||||
pub use cartridge_loader::{CartridgeLoader, DirectoryCartridgeLoader, PackedCartridgeLoader};
|
||||
pub use color::Color;
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
mod prometeu_os;
|
||||
pub mod syscalls;
|
||||
|
||||
pub use prometeu_os::PrometeuOS;
|
||||
pub use syscalls::Syscall;
|
||||
pub use crate::virtual_machine::native_interface::NativeInterface;
|
||||
@ -2,7 +2,7 @@ use crate::fs::{FsBackend, FsState, VirtualFS};
|
||||
use crate::hardware::{HardwareBridge, InputSignals};
|
||||
use crate::log::{LogLevel, LogService, LogSource};
|
||||
use crate::model::{Cartridge, Color, Sample};
|
||||
use crate::prometeu_os::NativeInterface;
|
||||
use crate::prometeu_os::{NativeInterface, Syscall};
|
||||
use crate::telemetry::{CertificationConfig, Certifier, TelemetryFrame};
|
||||
use crate::virtual_machine::{Value, VirtualMachine};
|
||||
use std::collections::HashMap;
|
||||
@ -554,17 +554,18 @@ impl NativeInterface for PrometeuOS {
|
||||
/// Each syscall returns the number of virtual cycles it consumed.
|
||||
fn syscall(&mut self, id: u32, vm: &mut VirtualMachine, hw: &mut dyn HardwareBridge) -> Result<u64, String> {
|
||||
self.telemetry_current.syscalls += 1;
|
||||
match id {
|
||||
let syscall = Syscall::from_u32(id).ok_or_else(|| format!("Unknown syscall: 0x{:08X}", id))?;
|
||||
match syscall {
|
||||
// --- System Syscalls ---
|
||||
|
||||
// system.has_cart() -> bool
|
||||
0x0001 => {
|
||||
Syscall::SystemHasCart => {
|
||||
// Returns true if a cartridge is available.
|
||||
vm.push(Value::Boolean(true)); // For now, assume true or check state
|
||||
Ok(10)
|
||||
}
|
||||
// system.run_cart() -> null
|
||||
0x0002 => {
|
||||
Syscall::SystemRunCart => {
|
||||
// Triggers loading and execution of the current cartridge.
|
||||
vm.push(Value::Null);
|
||||
Ok(100)
|
||||
@ -573,7 +574,7 @@ impl NativeInterface for PrometeuOS {
|
||||
// --- GFX Syscalls ---
|
||||
|
||||
// gfx.clear(color_index) -> null
|
||||
0x1001 => {
|
||||
Syscall::GfxClear => {
|
||||
let color_idx = vm.pop_integer()? as usize;
|
||||
let color = self.get_color(color_idx, hw);
|
||||
hw.gfx_mut().clear(color);
|
||||
@ -581,7 +582,7 @@ impl NativeInterface for PrometeuOS {
|
||||
Ok(100)
|
||||
}
|
||||
// gfx.draw_rect(x, y, w, h, color_index) -> null
|
||||
0x1002 => {
|
||||
Syscall::GfxFillRect => {
|
||||
let color_idx = vm.pop_integer()? as usize;
|
||||
let h = vm.pop_integer()? as i32;
|
||||
let w = vm.pop_integer()? as i32;
|
||||
@ -593,7 +594,7 @@ impl NativeInterface for PrometeuOS {
|
||||
Ok(200)
|
||||
}
|
||||
// gfx.draw_line(x1, y1, x2, y2, color_index) -> null
|
||||
0x1003 => {
|
||||
Syscall::GfxDrawLine => {
|
||||
let color_idx = vm.pop_integer()? as usize;
|
||||
let y2 = vm.pop_integer()? as i32;
|
||||
let x2 = vm.pop_integer()? as i32;
|
||||
@ -605,7 +606,7 @@ impl NativeInterface for PrometeuOS {
|
||||
Ok(200)
|
||||
}
|
||||
// gfx.draw_circle(x, y, r, color_index) -> null
|
||||
0x1004 => {
|
||||
Syscall::GfxDrawCircle => {
|
||||
let color_idx = vm.pop_integer()? as usize;
|
||||
let r = vm.pop_integer()? as i32;
|
||||
let y = vm.pop_integer()? as i32;
|
||||
@ -616,7 +617,7 @@ impl NativeInterface for PrometeuOS {
|
||||
Ok(200)
|
||||
}
|
||||
// gfx.draw_disc(x, y, r, border_color_idx, fill_color_idx) -> null
|
||||
0x1005 => {
|
||||
Syscall::GfxDrawDisc => {
|
||||
let fill_color_idx = vm.pop_integer()? as usize;
|
||||
let border_color_idx = vm.pop_integer()? as usize;
|
||||
let r = vm.pop_integer()? as i32;
|
||||
@ -629,7 +630,7 @@ impl NativeInterface for PrometeuOS {
|
||||
Ok(300)
|
||||
}
|
||||
// gfx.draw_square(x, y, w, h, border_color_idx, fill_color_idx) -> null
|
||||
0x1006 => {
|
||||
Syscall::GfxDrawSquare => {
|
||||
let fill_color_idx = vm.pop_integer()? as usize;
|
||||
let border_color_idx = vm.pop_integer()? as usize;
|
||||
let h = vm.pop_integer()? as i32;
|
||||
@ -646,7 +647,7 @@ impl NativeInterface for PrometeuOS {
|
||||
// --- Input Syscalls ---
|
||||
|
||||
// input.get_pad(button_id) -> bool
|
||||
0x2001 => {
|
||||
Syscall::InputGetPad => {
|
||||
let button_id = vm.pop_integer()? as u32;
|
||||
let is_down = self.is_button_down(button_id, hw);
|
||||
vm.push(Value::Boolean(is_down));
|
||||
@ -656,7 +657,7 @@ impl NativeInterface for PrometeuOS {
|
||||
// --- Audio Syscalls ---
|
||||
|
||||
// audio.play_sample(sample_id, voice_id, volume, pan, pitch)
|
||||
0x3001 => {
|
||||
Syscall::AudioPlaySample => {
|
||||
let pitch = vm.pop_number()?;
|
||||
let pan = vm.pop_integer()? as u8;
|
||||
let volume = vm.pop_integer()? as u8;
|
||||
@ -681,7 +682,7 @@ impl NativeInterface for PrometeuOS {
|
||||
|
||||
// FS_OPEN(path) -> handle
|
||||
// Opens a file in the virtual sandbox and returns a numeric handle.
|
||||
0x4001 => {
|
||||
Syscall::FsOpen => {
|
||||
let path = match vm.pop()? {
|
||||
Value::String(s) => s,
|
||||
_ => return Err("Expected string path".into()),
|
||||
@ -697,7 +698,7 @@ impl NativeInterface for PrometeuOS {
|
||||
Ok(200)
|
||||
}
|
||||
// FS_READ(handle) -> content
|
||||
0x4002 => {
|
||||
Syscall::FsRead => {
|
||||
let handle = vm.pop_integer()? as u32;
|
||||
let path = self.open_files.get(&handle).ok_or("Invalid handle")?;
|
||||
match self.fs.read_file(path) {
|
||||
@ -713,7 +714,7 @@ impl NativeInterface for PrometeuOS {
|
||||
}
|
||||
}
|
||||
// FS_WRITE(handle, content)
|
||||
0x4003 => {
|
||||
Syscall::FsWrite => {
|
||||
let content = match vm.pop()? {
|
||||
Value::String(s) => s,
|
||||
_ => return Err("Expected string content".into()),
|
||||
@ -732,14 +733,14 @@ impl NativeInterface for PrometeuOS {
|
||||
}
|
||||
}
|
||||
// FS_CLOSE(handle)
|
||||
0x4004 => {
|
||||
Syscall::FsClose => {
|
||||
let handle = vm.pop_integer()? as u32;
|
||||
self.open_files.remove(&handle);
|
||||
vm.push(Value::Null);
|
||||
Ok(100)
|
||||
}
|
||||
// FS_LISTDIR(path)
|
||||
0x4005 => {
|
||||
Syscall::FsListDir => {
|
||||
let path = match vm.pop()? {
|
||||
Value::String(s) => s,
|
||||
_ => return Err("Expected string path".into()),
|
||||
@ -758,7 +759,7 @@ impl NativeInterface for PrometeuOS {
|
||||
}
|
||||
}
|
||||
// FS_EXISTS(path) -> bool
|
||||
0x4006 => {
|
||||
Syscall::FsExists => {
|
||||
let path = match vm.pop()? {
|
||||
Value::String(s) => s,
|
||||
_ => return Err("Expected string path".into()),
|
||||
@ -767,7 +768,7 @@ impl NativeInterface for PrometeuOS {
|
||||
Ok(100)
|
||||
}
|
||||
// FS_DELETE(path)
|
||||
0x4007 => {
|
||||
Syscall::FsDelete => {
|
||||
let path = match vm.pop()? {
|
||||
Value::String(s) => s,
|
||||
_ => return Err("Expected string path".into()),
|
||||
@ -782,7 +783,7 @@ impl NativeInterface for PrometeuOS {
|
||||
// --- Log Syscalls (0x5000) ---
|
||||
|
||||
// LOG_WRITE(level, msg)
|
||||
0x5001 => {
|
||||
Syscall::LogWrite => {
|
||||
let msg = match vm.pop()? {
|
||||
Value::String(s) => s,
|
||||
_ => return Err("Expected string message".into()),
|
||||
@ -791,7 +792,7 @@ impl NativeInterface for PrometeuOS {
|
||||
self.syscall_log_write(vm, level, 0, msg)
|
||||
}
|
||||
// LOG_WRITE_TAG(level, tag, msg)
|
||||
0x5002 => {
|
||||
Syscall::LogWriteTag => {
|
||||
let msg = match vm.pop()? {
|
||||
Value::String(s) => s,
|
||||
_ => return Err("Expected string message".into()),
|
||||
@ -800,8 +801,6 @@ impl NativeInterface for PrometeuOS {
|
||||
let level = vm.pop_integer()?;
|
||||
self.syscall_log_write(vm, level, tag, msg)
|
||||
}
|
||||
|
||||
_ => Err(format!("Unknown syscall: 0x{:08X}", id)),
|
||||
}
|
||||
}
|
||||
}
|
||||
110
crates/prometeu-core/src/prometeu_os/syscalls.rs
Normal file
110
crates/prometeu-core/src/prometeu_os/syscalls.rs
Normal file
@ -0,0 +1,110 @@
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub enum Syscall {
|
||||
// System
|
||||
SystemHasCart = 0x0001,
|
||||
SystemRunCart = 0x0002,
|
||||
|
||||
// GFX
|
||||
GfxClear = 0x1001,
|
||||
GfxFillRect = 0x1002,
|
||||
GfxDrawLine = 0x1003,
|
||||
GfxDrawCircle = 0x1004,
|
||||
GfxDrawDisc = 0x1005,
|
||||
GfxDrawSquare = 0x1006,
|
||||
|
||||
// Input
|
||||
InputGetPad = 0x2001,
|
||||
|
||||
// Audio
|
||||
AudioPlaySample = 0x3001,
|
||||
|
||||
// FS
|
||||
FsOpen = 0x4001,
|
||||
FsRead = 0x4002,
|
||||
FsWrite = 0x4003,
|
||||
FsClose = 0x4004,
|
||||
FsListDir = 0x4005,
|
||||
FsExists = 0x4006,
|
||||
FsDelete = 0x4007,
|
||||
|
||||
// Log
|
||||
LogWrite = 0x5001,
|
||||
LogWriteTag = 0x5002,
|
||||
}
|
||||
|
||||
impl Syscall {
|
||||
pub fn from_u32(id: u32) -> Option<Self> {
|
||||
match id {
|
||||
0x0001 => Some(Self::SystemHasCart),
|
||||
0x0002 => Some(Self::SystemRunCart),
|
||||
0x1001 => Some(Self::GfxClear),
|
||||
0x1002 => Some(Self::GfxFillRect),
|
||||
0x1003 => Some(Self::GfxDrawLine),
|
||||
0x1004 => Some(Self::GfxDrawCircle),
|
||||
0x1005 => Some(Self::GfxDrawDisc),
|
||||
0x1006 => Some(Self::GfxDrawSquare),
|
||||
0x2001 => Some(Self::InputGetPad),
|
||||
0x3001 => Some(Self::AudioPlaySample),
|
||||
0x4001 => Some(Self::FsOpen),
|
||||
0x4002 => Some(Self::FsRead),
|
||||
0x4003 => Some(Self::FsWrite),
|
||||
0x4004 => Some(Self::FsClose),
|
||||
0x4005 => Some(Self::FsListDir),
|
||||
0x4006 => Some(Self::FsExists),
|
||||
0x4007 => Some(Self::FsDelete),
|
||||
0x5001 => Some(Self::LogWrite),
|
||||
0x5002 => Some(Self::LogWriteTag),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::SystemHasCart => "system.has_cart",
|
||||
Self::SystemRunCart => "system.run_cart",
|
||||
Self::GfxClear => "gfx.clear",
|
||||
Self::GfxFillRect => "gfx.fillRect",
|
||||
Self::GfxDrawLine => "gfx.drawLine",
|
||||
Self::GfxDrawCircle => "gfx.drawCircle",
|
||||
Self::GfxDrawDisc => "gfx.drawDisc",
|
||||
Self::GfxDrawSquare => "gfx.drawSquare",
|
||||
Self::InputGetPad => "input.get_pad",
|
||||
Self::AudioPlaySample => "audio.playSample",
|
||||
Self::FsOpen => "fs.open",
|
||||
Self::FsRead => "fs.read",
|
||||
Self::FsWrite => "fs.write",
|
||||
Self::FsClose => "fs.close",
|
||||
Self::FsListDir => "fs.listDir",
|
||||
Self::FsExists => "fs.exists",
|
||||
Self::FsDelete => "fs.delete",
|
||||
Self::LogWrite => "log.write",
|
||||
Self::LogWriteTag => "log.writeTag",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_name(name: &str) -> Option<Self> {
|
||||
match name {
|
||||
"system.has_cart" => Some(Self::SystemHasCart),
|
||||
"system.run_cart" => Some(Self::SystemRunCart),
|
||||
"gfx.clear" => Some(Self::GfxClear),
|
||||
"gfx.fillRect" | "gfx.draw_rect" => Some(Self::GfxFillRect),
|
||||
"gfx.drawLine" | "gfx.draw_line" => Some(Self::GfxDrawLine),
|
||||
"gfx.drawCircle" | "gfx.draw_circle" => Some(Self::GfxDrawCircle),
|
||||
"gfx.drawDisc" | "gfx.draw_disc" => Some(Self::GfxDrawDisc),
|
||||
"gfx.drawSquare" | "gfx.draw_square" => Some(Self::GfxDrawSquare),
|
||||
"input.get_pad" => Some(Self::InputGetPad),
|
||||
"audio.playSample" | "audio.play_sample" => Some(Self::AudioPlaySample),
|
||||
"fs.open" => Some(Self::FsOpen),
|
||||
"fs.read" => Some(Self::FsRead),
|
||||
"fs.write" => Some(Self::FsWrite),
|
||||
"fs.close" => Some(Self::FsClose),
|
||||
"fs.listDir" => Some(Self::FsListDir),
|
||||
"fs.exists" => Some(Self::FsExists),
|
||||
"fs.delete" => Some(Self::FsDelete),
|
||||
"log.write" => Some(Self::LogWrite),
|
||||
"log.writeTag" => Some(Self::LogWriteTag),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,3 +5,12 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
prometeu-bytecode = { path = "../prometeu-bytecode" }
|
||||
prometeu-core = { path = "../prometeu-core" }
|
||||
oxc_parser = "0.48.0"
|
||||
oxc_allocator = "0.48.0"
|
||||
oxc_ast = "0.48.0"
|
||||
oxc_span = "0.48.0"
|
||||
clap = { version = "4.4", features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
anyhow = "1.0"
|
||||
|
||||
35
crates/prometeuc/src/cli.rs
Normal file
35
crates/prometeuc/src/cli.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "prometeuc")]
|
||||
#[command(about = "Prometeu Compiler", long_about = None)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
/// Builds a Prometeu project
|
||||
Build {
|
||||
/// Project directory
|
||||
project_dir: PathBuf,
|
||||
|
||||
/// Entry file
|
||||
#[arg(short, long)]
|
||||
entry: Option<PathBuf>,
|
||||
|
||||
/// Output PBC file
|
||||
#[arg(short, long)]
|
||||
out: Option<PathBuf>,
|
||||
|
||||
/// Emit disassembly file
|
||||
#[arg(long, default_value_t = true)]
|
||||
emit_disasm: bool,
|
||||
|
||||
/// Emit symbols file
|
||||
#[arg(long, default_value_t = true)]
|
||||
emit_symbols: bool,
|
||||
},
|
||||
}
|
||||
324
crates/prometeuc/src/codegen/codegen.rs
Normal file
324
crates/prometeuc/src/codegen/codegen.rs
Normal file
@ -0,0 +1,324 @@
|
||||
use anyhow::{Result, anyhow};
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_span::{Span, GetSpan};
|
||||
use prometeu_bytecode::opcode::OpCode;
|
||||
use prometeu_bytecode::asm::{Asm, Operand, assemble};
|
||||
use crate::compiler::Symbol;
|
||||
use crate::syscall_map;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct Codegen {
|
||||
file_name: String,
|
||||
source_text: String,
|
||||
pub symbols: Vec<Symbol>,
|
||||
instructions: Vec<(Asm, bool)>, // (Asm, has_symbol)
|
||||
locals: HashMap<String, u32>,
|
||||
next_local: u32,
|
||||
label_count: u32,
|
||||
}
|
||||
|
||||
impl Codegen {
|
||||
pub fn new(file_name: String, source_text: String) -> Self {
|
||||
Self {
|
||||
file_name,
|
||||
source_text,
|
||||
symbols: Vec::new(),
|
||||
instructions: Vec::new(),
|
||||
locals: HashMap::new(),
|
||||
next_local: 0,
|
||||
label_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile_program(&mut self, program: &Program) -> Result<Vec<u8>> {
|
||||
// Find tick function
|
||||
let mut tick_fn = None;
|
||||
for item in &program.body {
|
||||
if let Statement::ExportNamedDeclaration(decl) = item {
|
||||
if let Some(Declaration::FunctionDeclaration(f)) = &decl.declaration {
|
||||
if let Some(ident) = &f.id {
|
||||
if ident.name == "tick" {
|
||||
tick_fn = Some(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tick_fn = tick_fn.ok_or_else(|| anyhow!("export function tick() not found"))?;
|
||||
|
||||
// Entry point: loop calling tick
|
||||
self.emit_label("entry".to_string());
|
||||
self.emit_op(OpCode::Call, vec![Operand::Label("tick".to_string()), Operand::U32(0)], Span::default());
|
||||
self.emit_op(OpCode::FrameSync, vec![], Span::default());
|
||||
self.emit_op(OpCode::Jmp, vec![Operand::Label("entry".to_string())], Span::default());
|
||||
|
||||
// Function tick
|
||||
self.emit_label("tick".to_string());
|
||||
self.compile_function(tick_fn)?;
|
||||
self.emit_op(OpCode::Ret, vec![], Span::default());
|
||||
|
||||
let asm_vec: Vec<Asm> = self.instructions.iter().map(|(a, _)| a.clone()).collect();
|
||||
let rom = assemble(&asm_vec).map_err(|e| anyhow!("Assemble error: {}", e))?;
|
||||
|
||||
// Finalize symbols (associate PC)
|
||||
self.finalize_symbols();
|
||||
|
||||
Ok(rom)
|
||||
}
|
||||
|
||||
fn compile_function(&mut self, f: &Function) -> Result<()> {
|
||||
self.locals.clear();
|
||||
self.next_local = 0;
|
||||
|
||||
if let Some(body) = &f.body {
|
||||
for stmt in &body.statements {
|
||||
self.compile_stmt(stmt)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_stmt(&mut self, stmt: &Statement) -> Result<()> {
|
||||
match stmt {
|
||||
Statement::VariableDeclaration(var) => {
|
||||
for decl in &var.declarations {
|
||||
if let BindingPatternKind::BindingIdentifier(ident) = &decl.id.kind {
|
||||
let name = ident.name.to_string();
|
||||
if let Some(init) = &decl.init {
|
||||
self.compile_expr(init)?;
|
||||
} else {
|
||||
self.emit_op(OpCode::PushI32, vec![Operand::I32(0)], decl.span);
|
||||
}
|
||||
let id = self.next_local;
|
||||
self.locals.insert(name, id);
|
||||
self.emit_op(OpCode::SetLocal, vec![Operand::U32(id)], decl.span);
|
||||
self.next_local += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Statement::ExpressionStatement(expr_stmt) => {
|
||||
self.compile_expr(&expr_stmt.expression)?;
|
||||
self.emit_op(OpCode::Pop, vec![], expr_stmt.span);
|
||||
}
|
||||
Statement::IfStatement(if_stmt) => {
|
||||
let else_label = self.new_label("else");
|
||||
let end_label = self.new_label("end_if");
|
||||
|
||||
self.compile_expr(&if_stmt.test)?;
|
||||
self.emit_op(OpCode::JmpIfFalse, vec![Operand::Label(else_label.clone())], if_stmt.span);
|
||||
|
||||
self.compile_stmt(&if_stmt.consequent)?;
|
||||
self.emit_op(OpCode::Jmp, vec![Operand::Label(end_label.clone())], Span::default());
|
||||
|
||||
self.emit_label(else_label);
|
||||
if let Some(alt) = &if_stmt.alternate {
|
||||
self.compile_stmt(alt)?;
|
||||
}
|
||||
|
||||
self.emit_label(end_label);
|
||||
}
|
||||
Statement::BlockStatement(block) => {
|
||||
for stmt in &block.body {
|
||||
self.compile_stmt(stmt)?;
|
||||
}
|
||||
}
|
||||
_ => return Err(anyhow!("Unsupported statement type at {:?}", stmt.span())),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_expr(&mut self, expr: &Expression) -> Result<()> {
|
||||
match expr {
|
||||
Expression::NumericLiteral(n) => {
|
||||
let val = n.value;
|
||||
if val.fract() == 0.0 && val >= i32::MIN as f64 && val <= i32::MAX as f64 {
|
||||
self.emit_op(OpCode::PushI32, vec![Operand::I32(val as i32)], n.span);
|
||||
} else {
|
||||
self.emit_op(OpCode::PushI64, vec![Operand::I64(val as i64)], n.span);
|
||||
}
|
||||
}
|
||||
Expression::BooleanLiteral(b) => {
|
||||
self.emit_op(OpCode::PushBool, vec![Operand::Bool(b.value)], b.span);
|
||||
}
|
||||
Expression::Identifier(ident) => {
|
||||
let name = ident.name.to_string();
|
||||
if let Some(&id) = self.locals.get(&name) {
|
||||
self.emit_op(OpCode::GetLocal, vec![Operand::U32(id)], ident.span);
|
||||
} else {
|
||||
return Err(anyhow!("Undefined variable: {} at {:?}", name, ident.span));
|
||||
}
|
||||
}
|
||||
Expression::AssignmentExpression(assign) => {
|
||||
if let AssignmentTarget::AssignmentTargetIdentifier(ident) = &assign.left {
|
||||
let name = ident.name.to_string();
|
||||
self.compile_expr(&assign.right)?;
|
||||
if let Some(&id) = self.locals.get(&name) {
|
||||
self.emit_op(OpCode::Dup, vec![], assign.span);
|
||||
self.emit_op(OpCode::SetLocal, vec![Operand::U32(id)], assign.span);
|
||||
} else {
|
||||
return Err(anyhow!("Undefined variable: {} at {:?}", name, ident.span));
|
||||
}
|
||||
} else {
|
||||
return Err(anyhow!("Unsupported assignment target at {:?}", assign.span));
|
||||
}
|
||||
}
|
||||
Expression::BinaryExpression(bin) => {
|
||||
self.compile_expr(&bin.left)?;
|
||||
self.compile_expr(&bin.right)?;
|
||||
let op = match bin.operator {
|
||||
BinaryOperator::Addition => OpCode::Add,
|
||||
BinaryOperator::Subtraction => OpCode::Sub,
|
||||
BinaryOperator::Multiplication => OpCode::Mul,
|
||||
BinaryOperator::Division => OpCode::Div,
|
||||
BinaryOperator::Equality => OpCode::Eq,
|
||||
BinaryOperator::Inequality => OpCode::Neq,
|
||||
BinaryOperator::LessThan => OpCode::Lt,
|
||||
BinaryOperator::GreaterThan => OpCode::Gt,
|
||||
BinaryOperator::LessEqualThan => OpCode::Lte,
|
||||
BinaryOperator::GreaterEqualThan => OpCode::Gte,
|
||||
_ => return Err(anyhow!("Unsupported binary operator {:?} at {:?}", bin.operator, bin.span)),
|
||||
};
|
||||
self.emit_op(op, vec![], bin.span);
|
||||
}
|
||||
Expression::LogicalExpression(log) => {
|
||||
self.compile_expr(&log.left)?;
|
||||
self.compile_expr(&log.right)?;
|
||||
let op = match log.operator {
|
||||
LogicalOperator::And => OpCode::And,
|
||||
LogicalOperator::Or => OpCode::Or,
|
||||
_ => return Err(anyhow!("Unsupported logical operator {:?} at {:?}", log.operator, log.span)),
|
||||
};
|
||||
self.emit_op(op, vec![], log.span);
|
||||
}
|
||||
Expression::UnaryExpression(unary) => {
|
||||
self.compile_expr(&unary.argument)?;
|
||||
let op = match unary.operator {
|
||||
UnaryOperator::UnaryNegation => OpCode::Neg,
|
||||
UnaryOperator::UnaryPlus => return Ok(()),
|
||||
UnaryOperator::LogicalNot => OpCode::Not,
|
||||
_ => return Err(anyhow!("Unsupported unary operator {:?} at {:?}", unary.operator, unary.span)),
|
||||
};
|
||||
self.emit_op(op, vec![], unary.span);
|
||||
}
|
||||
Expression::CallExpression(call) => {
|
||||
let name = self.get_callee_name(&call.callee)?;
|
||||
if let Some(syscall_id) = syscall_map::map_syscall(&name) {
|
||||
if name == "input.btnA" {
|
||||
self.emit_op(OpCode::PushI32, vec![Operand::I32(syscall_map::BTN_A as i32)], call.span);
|
||||
} else if name == "input.btnB" {
|
||||
self.emit_op(OpCode::PushI32, vec![Operand::I32(syscall_map::BTN_B as i32)], call.span);
|
||||
} else {
|
||||
for arg in &call.arguments {
|
||||
if let Some(expr) = arg.as_expression() {
|
||||
self.compile_expr(expr)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.emit_op(OpCode::Syscall, vec![Operand::U32(syscall_id)], call.span);
|
||||
} else {
|
||||
return Err(anyhow!("Unsupported function call: {} at {:?}", name, call.span));
|
||||
}
|
||||
}
|
||||
Expression::StaticMemberExpression(member) => {
|
||||
let obj = self.get_callee_name_from_member_obj(&member.object)?;
|
||||
let prop = member.property.name.to_string();
|
||||
let full_name = format!("{}.{}", obj, prop);
|
||||
// If it's used as a value (GetGlobal/GetLocal?), but for now we only support it in calls
|
||||
return Err(anyhow!("Member expression outside call not supported: {} at {:?}", full_name, member.span));
|
||||
}
|
||||
_ => return Err(anyhow!("Unsupported expression type at {:?}", expr.span())),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_callee_name(&self, expr: &Expression) -> Result<String> {
|
||||
match expr {
|
||||
Expression::Identifier(ident) => Ok(ident.name.to_string()),
|
||||
Expression::StaticMemberExpression(member) => {
|
||||
let obj = self.get_callee_name_from_member_obj(&member.object)?;
|
||||
let prop = member.property.name.to_string();
|
||||
Ok(format!("{}.{}", obj, prop))
|
||||
}
|
||||
_ => Err(anyhow!("Unsupported callee expression at {:?}", expr.span())),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_callee_name_from_member_obj(&self, expr: &Expression) -> Result<String> {
|
||||
if let Expression::Identifier(ident) = expr {
|
||||
Ok(ident.name.to_string())
|
||||
} else {
|
||||
Err(anyhow!("Unsupported member object expression"))
|
||||
}
|
||||
}
|
||||
|
||||
fn new_label(&mut self, prefix: &str) -> String {
|
||||
let label = format!("{}_{}", prefix, self.label_count);
|
||||
self.label_count += 1;
|
||||
label
|
||||
}
|
||||
|
||||
fn emit_label(&mut self, name: String) {
|
||||
self.instructions.push((Asm::Label(name), false));
|
||||
}
|
||||
|
||||
fn emit_op(&mut self, opcode: OpCode, operands: Vec<Operand>, span: Span) {
|
||||
let has_symbol = if !span.is_unspanned() {
|
||||
let (line, col) = self.lookup_pos(span.start);
|
||||
self.symbols.push(Symbol {
|
||||
pc: 0,
|
||||
file: self.file_name.clone(),
|
||||
line,
|
||||
col,
|
||||
});
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
self.instructions.push((Asm::Op(opcode, operands), has_symbol));
|
||||
}
|
||||
|
||||
fn lookup_pos(&self, pos: u32) -> (usize, usize) {
|
||||
let mut line = 1;
|
||||
let mut col = 1;
|
||||
for (i, c) in self.source_text.char_indices() {
|
||||
if i as u32 == pos {
|
||||
break;
|
||||
}
|
||||
if c == '\n' {
|
||||
line += 1;
|
||||
col = 1;
|
||||
} else {
|
||||
col += 1;
|
||||
}
|
||||
}
|
||||
(line, col)
|
||||
}
|
||||
|
||||
fn finalize_symbols(&mut self) {
|
||||
let mut current_pc = 0u32;
|
||||
let mut symbol_ptr = 0;
|
||||
|
||||
for (instr, has_symbol) in &self.instructions {
|
||||
match instr {
|
||||
Asm::Label(_) => {}
|
||||
Asm::Op(_opcode, operands) => {
|
||||
if *has_symbol && symbol_ptr < self.symbols.len() {
|
||||
self.symbols[symbol_ptr].pc = current_pc;
|
||||
symbol_ptr += 1;
|
||||
}
|
||||
|
||||
current_pc += 2;
|
||||
for operand in operands {
|
||||
match operand {
|
||||
Operand::U32(_) | Operand::I32(_) | Operand::Label(_) => current_pc += 4,
|
||||
Operand::I64(_) | Operand::F64(_) => current_pc += 8,
|
||||
Operand::Bool(_) => current_pc += 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,3 @@
|
||||
pub use prometeu_bytecode::opcode::OpCode;
|
||||
pub use prometeu_bytecode::asm::{Asm, Operand, assemble};
|
||||
pub mod codegen;
|
||||
|
||||
pub use codegen::Codegen;
|
||||
72
crates/prometeuc/src/compiler.rs
Normal file
72
crates/prometeuc/src/compiler.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use std::path::Path;
|
||||
use anyhow::{Result, Context};
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_parser::Parser;
|
||||
use oxc_span::SourceType;
|
||||
use crate::codegen::Codegen;
|
||||
use std::fs;
|
||||
use prometeu_bytecode::disasm::disasm;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Symbol {
|
||||
pub pc: u32,
|
||||
pub file: String,
|
||||
pub line: usize,
|
||||
pub col: usize,
|
||||
}
|
||||
|
||||
pub fn compile(entry: &Path, out: &Path, emit_disasm: bool, emit_symbols: bool) -> Result<()> {
|
||||
let source_text = fs::read_to_string(entry)
|
||||
.with_context(|| format!("Failed to read entry file: {:?}", entry))?;
|
||||
|
||||
let allocator = Allocator::default();
|
||||
let source_type = SourceType::from_path(entry).unwrap_or_default();
|
||||
|
||||
let mut codegen = Codegen::new(entry.to_string_lossy().to_string(), source_text.clone());
|
||||
let rom = {
|
||||
let ret = Parser::new(&allocator, &source_text, source_type).parse();
|
||||
|
||||
if !ret.errors.is_empty() {
|
||||
for error in ret.errors {
|
||||
eprintln!("{:?}", error);
|
||||
}
|
||||
return Err(anyhow::anyhow!("Failed to parse module"));
|
||||
}
|
||||
|
||||
codegen.compile_program(&ret.program)?
|
||||
};
|
||||
|
||||
fs::write(out, &rom).with_context(|| format!("Failed to write PBC to {:?}", out))?;
|
||||
|
||||
if emit_symbols {
|
||||
let symbols_path = out.with_file_name("symbols.json");
|
||||
let symbols_json = serde_json::to_string_pretty(&codegen.symbols)?;
|
||||
fs::write(&symbols_path, symbols_json)?;
|
||||
}
|
||||
|
||||
if emit_disasm {
|
||||
let disasm_path = out.with_extension("disasm.txt");
|
||||
let instructions = disasm(&rom).map_err(|e| anyhow::anyhow!("Disassembly failed: {}", e))?;
|
||||
|
||||
let mut disasm_text = String::new();
|
||||
for instr in instructions {
|
||||
let symbol = codegen.symbols.iter().find(|s| s.pc == instr.pc);
|
||||
let comment = if let Some(s) = symbol {
|
||||
format!(" ; {}:{}", s.file, s.line)
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
let operands_str = instr.operands.iter()
|
||||
.map(|o| format!("{:?}", o))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
|
||||
disasm_text.push_str(&format!("{:08X} {:?} {}{}\n", instr.pc, instr.opcode, operands_str, comment));
|
||||
}
|
||||
fs::write(disasm_path, disasm_text)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1,5 +1,37 @@
|
||||
pub mod codegen;
|
||||
use clap::Parser;
|
||||
use anyhow::Result;
|
||||
|
||||
fn main() {
|
||||
println!("Prometeu Compiler (stub)");
|
||||
pub mod cli;
|
||||
pub mod codegen;
|
||||
pub mod compiler;
|
||||
pub mod syscall_map;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli = cli::Cli::parse();
|
||||
|
||||
match cli.command {
|
||||
cli::Commands::Build {
|
||||
project_dir,
|
||||
entry,
|
||||
out,
|
||||
emit_disasm,
|
||||
emit_symbols,
|
||||
} => {
|
||||
let entry = entry.unwrap_or_else(|| project_dir.join("src/main.ts"));
|
||||
let build_dir = project_dir.join("build");
|
||||
let out = out.unwrap_or_else(|| build_dir.join("program.pbc"));
|
||||
|
||||
if !build_dir.exists() {
|
||||
std::fs::create_dir_all(&build_dir)?;
|
||||
}
|
||||
|
||||
println!("Building project at {:?}", project_dir);
|
||||
println!("Entry: {:?}", entry);
|
||||
println!("Output: {:?}", out);
|
||||
|
||||
compiler::compile(&entry, &out, emit_disasm, emit_symbols)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
27
crates/prometeuc/src/syscall_map.rs
Normal file
27
crates/prometeuc/src/syscall_map.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use prometeu_core::prometeu_os::Syscall;
|
||||
use prometeu_core::model::ButtonId;
|
||||
|
||||
pub const BTN_UP: u32 = ButtonId::Up as u32;
|
||||
pub const BTN_DOWN: u32 = ButtonId::Down as u32;
|
||||
pub const BTN_LEFT: u32 = ButtonId::Left as u32;
|
||||
pub const BTN_RIGHT: u32 = ButtonId::Right as u32;
|
||||
pub const BTN_A: u32 = ButtonId::A as u32;
|
||||
pub const BTN_B: u32 = ButtonId::B as u32;
|
||||
pub const BTN_X: u32 = ButtonId::X as u32;
|
||||
pub const BTN_Y: u32 = ButtonId::Y as u32;
|
||||
pub const BTN_L: u32 = ButtonId::L as u32;
|
||||
pub const BTN_R: u32 = ButtonId::R as u32;
|
||||
pub const BTN_START: u32 = ButtonId::Start as u32;
|
||||
pub const BTN_SELECT: u32 = ButtonId::Select as u32;
|
||||
|
||||
pub fn map_syscall(name: &str) -> Option<u32> {
|
||||
if let Some(syscall) = Syscall::from_name(name) {
|
||||
return Some(syscall as u32);
|
||||
}
|
||||
|
||||
// Fallback para nomes especiais do compilador
|
||||
match name {
|
||||
"input.btnA" | "input.btnB" => Some(Syscall::InputGetPad as u32),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
29
examples/colorsquare/build/program.disasm.txt
Normal file
29
examples/colorsquare/build/program.disasm.txt
Normal file
@ -0,0 +1,29 @@
|
||||
00000000 Call U32(18) U32(0)
|
||||
0000000A FrameSync
|
||||
0000000C Jmp U32(0)
|
||||
00000012 PushI32 U32(2016) ; examples/colorsquare/src/main.ts:2
|
||||
00000018 SetLocal U32(0) ; examples/colorsquare/src/main.ts:2
|
||||
0000001E PushI32 U32(4) ; examples/colorsquare/src/main.ts:4
|
||||
00000024 Syscall U32(8193) ; examples/colorsquare/src/main.ts:4
|
||||
0000002A JmpIfFalse U32(70) ; examples/colorsquare/src/main.ts:4
|
||||
00000030 PushI32 U32(63488) ; examples/colorsquare/src/main.ts:4
|
||||
00000036 Dup ; examples/colorsquare/src/main.ts:4
|
||||
00000038 SetLocal U32(0) ; examples/colorsquare/src/main.ts:4
|
||||
0000003E Pop ; examples/colorsquare/src/main.ts:4
|
||||
00000040 Jmp U32(70)
|
||||
00000046 PushI32 U32(5) ; examples/colorsquare/src/main.ts:5
|
||||
0000004C Syscall U32(8193) ; examples/colorsquare/src/main.ts:5
|
||||
00000052 JmpIfFalse U32(110) ; examples/colorsquare/src/main.ts:5
|
||||
00000058 PushI32 U32(31) ; examples/colorsquare/src/main.ts:5
|
||||
0000005E Dup ; examples/colorsquare/src/main.ts:5
|
||||
00000060 SetLocal U32(0) ; examples/colorsquare/src/main.ts:5
|
||||
00000066 Pop ; examples/colorsquare/src/main.ts:5
|
||||
00000068 Jmp U32(110)
|
||||
0000006E PushI32 U32(60) ; examples/colorsquare/src/main.ts:7
|
||||
00000074 PushI32 U32(60) ; examples/colorsquare/src/main.ts:7
|
||||
0000007A PushI32 U32(40) ; examples/colorsquare/src/main.ts:7
|
||||
00000080 PushI32 U32(40) ; examples/colorsquare/src/main.ts:7
|
||||
00000086 GetLocal U32(0) ; examples/colorsquare/src/main.ts:7
|
||||
0000008C Syscall U32(4098) ; examples/colorsquare/src/main.ts:7
|
||||
00000092 Pop ; examples/colorsquare/src/main.ts:7
|
||||
00000094 Ret
|
||||
BIN
examples/colorsquare/build/program.pbc
Normal file
BIN
examples/colorsquare/build/program.pbc
Normal file
Binary file not shown.
140
examples/colorsquare/build/symbols.json
Normal file
140
examples/colorsquare/build/symbols.json
Normal file
@ -0,0 +1,140 @@
|
||||
[
|
||||
{
|
||||
"pc": 18,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 2,
|
||||
"col": 15
|
||||
},
|
||||
{
|
||||
"pc": 24,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 2,
|
||||
"col": 7
|
||||
},
|
||||
{
|
||||
"pc": 30,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 4,
|
||||
"col": 7
|
||||
},
|
||||
{
|
||||
"pc": 36,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 4,
|
||||
"col": 7
|
||||
},
|
||||
{
|
||||
"pc": 42,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 4,
|
||||
"col": 3
|
||||
},
|
||||
{
|
||||
"pc": 48,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 4,
|
||||
"col": 29
|
||||
},
|
||||
{
|
||||
"pc": 54,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 4,
|
||||
"col": 21
|
||||
},
|
||||
{
|
||||
"pc": 56,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 4,
|
||||
"col": 21
|
||||
},
|
||||
{
|
||||
"pc": 62,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 4,
|
||||
"col": 21
|
||||
},
|
||||
{
|
||||
"pc": 70,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 5,
|
||||
"col": 7
|
||||
},
|
||||
{
|
||||
"pc": 76,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 5,
|
||||
"col": 7
|
||||
},
|
||||
{
|
||||
"pc": 82,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 5,
|
||||
"col": 3
|
||||
},
|
||||
{
|
||||
"pc": 88,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 5,
|
||||
"col": 29
|
||||
},
|
||||
{
|
||||
"pc": 94,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 5,
|
||||
"col": 21
|
||||
},
|
||||
{
|
||||
"pc": 96,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 5,
|
||||
"col": 21
|
||||
},
|
||||
{
|
||||
"pc": 102,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 5,
|
||||
"col": 21
|
||||
},
|
||||
{
|
||||
"pc": 110,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 7,
|
||||
"col": 16
|
||||
},
|
||||
{
|
||||
"pc": 116,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 7,
|
||||
"col": 20
|
||||
},
|
||||
{
|
||||
"pc": 122,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 7,
|
||||
"col": 24
|
||||
},
|
||||
{
|
||||
"pc": 128,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 7,
|
||||
"col": 28
|
||||
},
|
||||
{
|
||||
"pc": 134,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 7,
|
||||
"col": 32
|
||||
},
|
||||
{
|
||||
"pc": 140,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 7,
|
||||
"col": 3
|
||||
},
|
||||
{
|
||||
"pc": 146,
|
||||
"file": "examples/colorsquare/src/main.ts",
|
||||
"line": 7,
|
||||
"col": 3
|
||||
}
|
||||
]
|
||||
8
examples/colorsquare/src/main.ts
Normal file
8
examples/colorsquare/src/main.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export function tick(): void {
|
||||
let color = 0x07E0; // green
|
||||
|
||||
if (input.btnA()) color = 0xF800; // red
|
||||
if (input.btnB()) color = 0x001F; // blue
|
||||
|
||||
gfx.fillRect(60, 60, 40, 40, color);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user