diff --git a/src/Rust/Cargo.lock b/src/Rust/Cargo.lock index 79912599051150568032984aec0e5c18cda8bf13..9f75e1e998856296c98bf40ef8ef5b9bf9073b9c 100644 --- a/src/Rust/Cargo.lock +++ b/src/Rust/Cargo.lock @@ -106,6 +106,15 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -143,18 +152,39 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "by_address" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" + [[package]] name = "bytecount" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + [[package]] name = "cast" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "castaway" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" +dependencies = [ + "rustversion", +] + [[package]] name = "cbindgen" version = "0.27.0" @@ -307,6 +337,20 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "compact_str" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + [[package]] name = "console" version = "0.15.8" @@ -340,7 +384,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -361,7 +405,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -389,6 +433,31 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -445,6 +514,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "fast-srgb8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" + [[package]] name = "fastrand" version = "2.1.1" @@ -496,6 +571,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hermit-abi" version = "0.4.0" @@ -527,13 +608,23 @@ dependencies = [ "walkdir", ] +[[package]] +name = "instability" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" +dependencies = [ + "quote", + "syn 2.0.77", +] + [[package]] name = "is-terminal" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi", + "hermit-abi 0.4.0", "libc", "windows-sys 0.52.0", ] @@ -553,6 +644,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -606,18 +706,50 @@ dependencies = [ "semver", ] +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lru" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" +dependencies = [ + "hashbrown", +] + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "log", + "wasi", + "windows-sys 0.52.0", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -648,12 +780,101 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "palette" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" +dependencies = [ + "approx", + "fast-srgb8", + "palette_derive", + "phf", +] + +[[package]] +name = "palette_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" +dependencies = [ + "by_address", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + [[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "plotters" version = "0.3.6" @@ -700,6 +921,43 @@ dependencies = [ "proc-macro2", ] +[[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 = "ratatui" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" +dependencies = [ + "bitflags", + "cassowary", + "compact_str", + "crossterm", + "instability", + "itertools 0.13.0", + "lru", + "palette", + "paste", + "strum", + "strum_macros", + "unicode-segmentation", + "unicode-truncate", + "unicode-width", +] + [[package]] name = "rayon" version = "1.10.0" @@ -720,6 +978,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.10.6" @@ -774,6 +1041,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + [[package]] name = "ryu" version = "1.0.18" @@ -789,6 +1062,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "semver" version = "1.0.23" @@ -843,12 +1122,54 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "similar" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "smol_str" version = "0.3.1" @@ -859,12 +1180,40 @@ dependencies = [ "serde", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.77", +] + [[package]] name = "syn" version = "1.0.109" @@ -1001,6 +1350,17 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unicode-truncate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +dependencies = [ + "itertools 0.13.0", + "unicode-segmentation", + "unicode-width", +] + [[package]] name = "unicode-width" version = "0.1.13" @@ -1048,6 +1408,7 @@ dependencies = [ "clap_complete", "clap_mangen", "log", + "ratatui", "serde", "thiserror", "toml", @@ -1173,6 +1534,7 @@ version = "0.5.0" dependencies = [ "anyhow", "log", + "ratatui", "serde", "serde_json", "vvs_ass", @@ -1235,6 +1597,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.93" @@ -1300,6 +1668,22 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -1309,6 +1693,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/src/Rust/Cargo.toml b/src/Rust/Cargo.toml index 1bada05b996e61090396cba4abb4be1e24e14722..f5a301a45cedd3a19df9bd09efa7419d5e54168f 100644 --- a/src/Rust/Cargo.toml +++ b/src/Rust/Cargo.toml @@ -91,7 +91,8 @@ ttf-parser = { version = "*" } ab_glyph = { version = "*" } # CLI -clap_mangen = "*" # Could be replace by something crafter by hand… +ratatui = { version = "*", features = [ "macros", "palette" ] } +clap_mangen = "*" # TODO: Could be replace by something crafter by hand… clap_complete = "*" clap = { version = "*", default-features = false, features = [ "usage", diff --git a/src/Rust/vvs_cli/Cargo.toml b/src/Rust/vvs_cli/Cargo.toml index a83fa5d4aacfeb0bc285ee01864b7d76b5da9c6d..dc91c6da19dc49ef438ef78ab61bf081c117e906 100644 --- a/src/Rust/vvs_cli/Cargo.toml +++ b/src/Rust/vvs_cli/Cargo.toml @@ -27,6 +27,7 @@ log.workspace = true clap_mangen.workspace = true clap_complete.workspace = true clap.workspace = true +ratatui.workspace = true [build-dependencies] anyhow.workspace = true diff --git a/src/Rust/vvs_cli/src/args.rs b/src/Rust/vvs_cli/src/args.rs index 5f74ba2f279764c02b3187e096660c12d14d3839..3b1bd4d71fdcc191100487fde2efa4ff09b560e3 100644 --- a/src/Rust/vvs_cli/src/args.rs +++ b/src/Rust/vvs_cli/src/args.rs @@ -1,9 +1,8 @@ use crate::parser::FileTypeValueParser; -use clap::Parser; use clap_complete::Shell; use std::path::PathBuf; -#[derive(Parser, Debug)] +#[derive(clap::Parser, Debug)] #[command( author , version , about @@ -11,7 +10,6 @@ use std::path::PathBuf; , groups = [ clap::ArgGroup::new("action").args(["manpage", "shell", "font-file", "script.vvs"]) , clap::ArgGroup::new("ass") .args(["subtitle.ass"]).conflicts_with_all(["manpage", "font-file"]) , clap::ArgGroup::new("opts") .args(["options.ini"]) .conflicts_with_all(["shell", "manpage", "font-file"]) - , clap::ArgGroup::new("infos") .args(["info"]) .conflicts_with_all(["shell", "manpage", "font-file"]) ])] pub struct Args { /// The script to run. @@ -58,19 +56,6 @@ pub struct Args { )] pub includes: Vec<PathBuf>, - /// Shows informations about a script. - /// - /// The informations consists of the loaded modules, all the options, their possible values, - /// the order of the jobs, etc. - /// - /// When printing informations about a script you won't be able to run it. You can however - /// print the informations about a script then enter in iteractive mode. - #[arg( short = 'P' - , long = "info" - , action = clap::ArgAction::SetTrue - )] - pub info: bool, - /// Display infos about embeded fonts or external fonts. #[arg( long = "font-info" , action = clap::ArgAction::Set diff --git a/src/Rust/vvs_cli/src/compiler.rs b/src/Rust/vvs_cli/src/compiler.rs new file mode 100644 index 0000000000000000000000000000000000000000..9fafdcc60a5912a417007b9dc4ce30ccf704ab12 --- /dev/null +++ b/src/Rust/vvs_cli/src/compiler.rs @@ -0,0 +1,48 @@ +use crate::args::Args; +use anyhow::Context as _; +use clap::CommandFactory as _; +use std::path::PathBuf; +use vvs_lang::{FrontendPipeline, SearchPath, SourceCode}; +use vvs_runtime::Runtime; +use vvs_xdg::file::TempFile; + +pub struct Settings { + pub script: Option<PathBuf>, + pub ass_file: Option<PathBuf>, + pub options: Option<PathBuf>, + pub includes: Vec<PathBuf>, + pub terminal: ratatui::DefaultTerminal, +} + +pub fn run(settings: Settings) -> anyhow::Result<()> { + let script = match settings.script { + Some(script) => SourceCode::from_path(&script)?, + None => return Ok(Args::command().print_help()?), + }; + let _ = script.module().context("expected a valid module name")?; + + let Settings { ass_file, options, includes, .. } = settings; + let output = FrontendPipeline::new(&script) + .passes(&[]) + .search( + &SearchPath::from_iter(includes) + .with_script_folder(script.folder().context("expected the script to have a parent folder")?), + ) + .options(options.as_ref())? + .run()?; + + let mut file = TempFile::new("vvcc")?; + Runtime::new(move |ctx| { + Ok(vvs_codegen::lowerer::Lowerer::new(&ctx, &output.main.name)? + .declare_globals(output.declared_functions())? + .lower_module(&output.main.name, output.ast)? + .lower_modules(output.imports)? + .generate_main(output.main)? + .finished()) + })? + .with_output_file(&mut file) + .with_terminal(settings.terminal) + .run_on_file(ass_file.context("no subtitle file to run the script on")?)?; + file.leak(); + Ok(()) +} diff --git a/src/Rust/vvs_cli/src/config.rs b/src/Rust/vvs_cli/src/config.rs index 25772ae6c976df7ded339d3161dccaa2ded71c4c..026ea26ff9770134993d857cc44b97727a989004 100644 --- a/src/Rust/vvs_cli/src/config.rs +++ b/src/Rust/vvs_cli/src/config.rs @@ -29,7 +29,6 @@ pub struct Config { pub script: Option<PathBuf>, pub ass_file: Option<PathBuf>, pub options: Option<PathBuf>, - pub info: bool, pub manpage: bool, pub shell: Option<Shell>, pub font_info: Option<Option<PathBuf>>, @@ -114,7 +113,7 @@ impl Config { append args => self, { includes }; set_if_not args => self, { script, ass_file, options, shell, font_info }; max args => self, { verbose }; - override args => self, { info, manpage }; + override args => self, { manpage }; } self } diff --git a/src/Rust/vvs_cli/src/lib.rs b/src/Rust/vvs_cli/src/lib.rs index 2c31f840f0a5cd4c6123589fe9f2dbfc68920392..784888b9061a17bd12603b6f5fff89f5d349ef23 100644 --- a/src/Rust/vvs_cli/src/lib.rs +++ b/src/Rust/vvs_cli/src/lib.rs @@ -1,6 +1,7 @@ #![forbid(unsafe_code)] pub mod args; +pub mod compiler; pub mod config; pub mod logger; diff --git a/src/Rust/vvs_cli/src/main.rs b/src/Rust/vvs_cli/src/main.rs index c8030eca5a55488bcfd5c52fc8d87096ac55f166..ddf5ca0dbcf9870a04a60f1da517bc7bdf417529 100644 --- a/src/Rust/vvs_cli/src/main.rs +++ b/src/Rust/vvs_cli/src/main.rs @@ -7,11 +7,10 @@ use clap::{CommandFactory as _, Parser as _}; use std::{fs, io, path::Path}; use vvs_cli::{ args::Args, + compiler, config::{Config, ConfigFile}, }; -use vvs_lang::{FrontendPipeline, SearchPath, SourceCode}; -use vvs_runtime::Runtime; -use vvs_xdg::{file::TempFile, XDGConfig, XDGConfigMergedSilent}; +use vvs_xdg::{XDGConfig, XDGConfigMergedSilent}; fn print_font(n: impl AsRef<Path>, f: &[u8]) -> Result<()> { let f = vvs_font::Font::try_from(f).with_context(|| format!("failed to parse font {}", n.as_ref().display()))?; @@ -27,7 +26,7 @@ fn print_font(n: impl AsRef<Path>, f: &[u8]) -> Result<()> { fn main() -> Result<()> { vvs_cli::logger::init(None).context("failed to init logger")?; - let Config { script, ass_file, options, info, manpage, shell, font_info, includes, .. } = Config::default() + let Config { script, ass_file, options, manpage, shell, font_info, includes, .. } = Config::default() .with_config_file( XDGConfig::<ConfigFile, XDGConfigMergedSilent>::new("vvcc") .file("vvcc.toml") @@ -36,60 +35,21 @@ fn main() -> Result<()> { .with_args(Args::parse()) .apply_logger(); - // Handle auxiliary stuff if manpage { - return clap_mangen::Man::new(Args::command()) + clap_mangen::Man::new(Args::command()) .render(&mut io::stdout()) - .context("failed to render manpage for vvcc"); + .context("failed to render manpage for vvcc") } else if let Some(shell) = shell { clap_complete::generate(shell, &mut Args::command(), Args::command().get_name().to_string(), &mut io::stdout()); - return Ok(()); + Ok(()) } else if let Some(font_info) = font_info { - return match font_info { + match font_info { Some(p) => print_font(&p, &fs::read(&p).with_context(|| format!("failed to read font: {}", p.display()))?), None => vvs_font::embeded_fonts().try_for_each(|(n, f)| print_font(n, f)), - }; - } - - // Parse, build, execute the script. - let script = match script { - Some(script) => SourceCode::from_path(&script)?, - None => return Ok(Args::command().print_help()?), - }; - println!("main module ........ {}", script.module().context("expected a valid module name")?); - let output = FrontendPipeline::new(&script) - .passes(&[]) - .search( - &SearchPath::from_iter(includes) - .with_script_folder(script.folder().context("expected the script to have a parent folder")?), - ) - .options(options.as_ref())? - .run()?; - - if info { - match ass_file { - Some(ref path) => println!("ass file ........... {}", path.display()), - None => println!("ass file ........... ø"), } - match options { - Some(path) => println!("options file ....... {}", path.display()), - None => println!("options file ....... ø"), - } - print!("{output}"); + } else { + compiler::run(compiler::Settings { script, ass_file, options, includes, terminal: ratatui::init() })?; + ratatui::restore(); + Ok(()) } - - let mut file = TempFile::new("vvcc")?; - Runtime::new(move |ctx| { - Ok(vvs_codegen::lowerer::Lowerer::new(&ctx, &output.main.name)? - .declare_globals(output.declared_functions())? - .lower_module(&output.main.name, output.ast)? - .lower_modules(output.imports)? - .generate_main(output.main)? - .finished()) - })? - .run_on_file(ass_file.context("no subtitle file to run the script on")?)? - .write_ass_to_file(&mut file)?; - - println!("output file ........ {}", file.leak().path().display()); - Ok(()) } diff --git a/src/Rust/vvs_runtime/Cargo.toml b/src/Rust/vvs_runtime/Cargo.toml index 25ee18213b4bcfc88847c914a5f978fed636b285..40e2e94761c08ff7c9f26de1c653fb389a772d8b 100644 --- a/src/Rust/vvs_runtime/Cargo.toml +++ b/src/Rust/vvs_runtime/Cargo.toml @@ -11,6 +11,7 @@ log.workspace = true anyhow.workspace = true serde.workspace = true serde_json.workspace = true +ratatui.workspace = true vvs_runtime_types.workspace = true vvs_ass.workspace = true vvs_utils.workspace = true diff --git a/src/Rust/vvs_runtime/src/runtime.rs b/src/Rust/vvs_runtime/src/runtime.rs index 3eb25e53ab62ef56d3b6baa27a710b8aacbbf49b..a1b65e9c996c69ff9f466c38d0b8276527d19f7a 100644 --- a/src/Rust/vvs_runtime/src/runtime.rs +++ b/src/Rust/vvs_runtime/src/runtime.rs @@ -1,28 +1,30 @@ use crate::workers::Workers; use anyhow::{bail, Context as _}; -use std::{ - path::Path, - sync::{ - atomic::{AtomicU64, Ordering}, - Arc, - }, - thread, -}; +use std::{fs, path::Path, sync::atomic::Ordering, thread}; use vvs_ass::{ass_container_from_file, ASSContainer}; use vvs_llvm::prelude::*; use vvs_runtime_types::types::VVRTTable; +use ratatui::{ + crossterm::event::{self, Event, KeyCode, KeyEventKind}, + widgets::{Block, Paragraph}, +}; + #[allow(dead_code)] -pub struct Runtime { +pub struct Runtime<'a> { jit: JIT, workers: Workers, + output: Option<&'a mut fs::File>, + terminal: Option<ratatui::DefaultTerminal>, } -impl Runtime { - pub fn new<'a>(init: impl FnOnce(Context<'a>) -> anyhow::Result<Module<'a>>) -> anyhow::Result<Self> { +impl<'a> Runtime<'a> { + pub fn new<'ctx>(init: impl FnOnce(Context<'ctx>) -> anyhow::Result<Module<'ctx>>) -> anyhow::Result<Self> { Ok(Self { jit: JIT::init(init)?, - workers: Workers::new(|flag: Arc<AtomicU64>| loop { + output: None, + terminal: None, + workers: Workers::new(|flag| loop { match flag.load(Ordering::SeqCst) { 0 => thread::yield_now(), u64::MAX => return Ok(()), @@ -32,13 +34,45 @@ impl Runtime { }) } - pub fn run_on_container(self, ass: ASSContainer<VVRTTable>) -> anyhow::Result<ASSContainer<VVRTTable>> { - todo!("run on {ass:?}") + pub fn with_output_file(self, output: &'a mut fs::File) -> Self { + Self { output: Some(output), ..self } } - pub fn run_on_file(self, file: impl AsRef<Path>) -> anyhow::Result<ASSContainer<VVRTTable>> { + pub fn with_terminal(self, terminal: ratatui::DefaultTerminal) -> Self { + Self { terminal: Some(terminal), ..self } + } + + pub fn run_on_file(self, file: impl AsRef<Path>) -> anyhow::Result<()> { self.run_on_container( ass_container_from_file::<VVRTTable>(file.as_ref()).context("failed to parse the subtitle file")?, ) } + + pub fn run_on_container(self, ass: ASSContainer<VVRTTable>) -> anyhow::Result<()> { + let Self { output, terminal, .. } = self; + log::error!("run on {ass:?}"); + + match terminal { + None => todo!("handle the case where we don't have a terminal"), + Some(mut terminal) => loop { + terminal.draw(|frame| { + frame.render_widget( + Paragraph::new("Hello World!").block(Block::bordered().title("Greeting")), + frame.area(), + ); + })?; + if let Event::Key(key) = event::read()? { + if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { + break; + } + } + }, + } + + if let Some(output) = output { + ass.write_ass_to_file(output)?; + } + + Ok(()) + } } diff --git a/src/Rust/vvs_xdg/src/file/temp.rs b/src/Rust/vvs_xdg/src/file/temp.rs index 3481602447d8604596b53e199482b4f165a3884d..38360a1e70e2d77a2d02c3fb60c1c1ab530bae32 100644 --- a/src/Rust/vvs_xdg/src/file/temp.rs +++ b/src/Rust/vvs_xdg/src/file/temp.rs @@ -49,6 +49,18 @@ impl DerefMut for TempFile { } } +impl AsRef<File> for TempFile { + fn as_ref(&self) -> &File { + self.deref() + } +} + +impl AsMut<File> for TempFile { + fn as_mut(&mut self) -> &mut File { + self.deref_mut() + } +} + impl Drop for TempFile { fn drop(&mut self) { if !self.leak {