Skip to main content

falsec_cli/
lib.rs

1use clap::builder::Styles;
2use clap::{Parser, Subcommand, ValueEnum, ValueHint};
3use std::path::PathBuf;
4
5#[derive(Debug, Parser)]
6#[command(name = "falsec", version, about, long_about = None, styles=styles())]
7pub struct Cli {
8    pub name: Option<String>,
9
10    /// The path to the configuration file
11    #[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath)]
12    pub config: Option<PathBuf>,
13
14    /// Enable debug output
15    #[arg(short, long, action = clap::ArgAction::Count)]
16    pub debug: u8,
17
18    #[command(subcommand)]
19    pub command: Commands,
20}
21
22#[derive(Debug, Subcommand)]
23pub enum Commands {
24    Run(Run),
25    Compile(Compile),
26}
27
28#[derive(ValueEnum, Copy, Clone, PartialEq, Eq, Debug)]
29pub enum TypeSafety {
30    /// No type safety checks are performed.
31    None,
32    /// When trying to execute a lambda, make sure that the popped value is a lambda.
33    Lambda,
34    /// Include all checks from [TypeSafety::Lambda], and make sure that when storing or loading
35    /// a variable, the popped value is a variable name.
36    LambdaAndVar,
37    /// Include all checks from [TypeSafety::LambdaAndVar], and ensure that only integers can be
38    /// used for arithmetic operations.
39    Full,
40}
41
42mod run {
43    use crate::TypeSafety;
44    use clap::{Args, ValueHint};
45    use std::ffi::OsString;
46
47    /// Execute a FALSE program
48    #[derive(Debug, Args)]
49    #[command(version, about, long_about = None)]
50    pub struct Run {
51        #[arg(long, require_equals = true, value_name = "TYPE", value_enum)]
52        pub type_safety: Option<TypeSafety>,
53
54        /// The path to the FALSE program to execute
55        #[arg(value_name = "FILE", value_hint = ValueHint::FilePath)]
56        pub program: OsString,
57    }
58}
59
60pub use run::Run;
61
62mod compile {
63    use crate::TypeSafety;
64    use clap::{Args, ValueHint};
65    use std::ffi::OsString;
66
67    /// Compile a FALSE program
68    #[derive(Debug, Args)]
69    #[command(version, about, long_about = None)]
70    pub struct Compile {
71        #[arg(long, require_equals = true, value_name = "TYPE", value_enum)]
72        pub type_safety: Option<TypeSafety>,
73
74        /// The path to the intermediary assembly
75        #[arg(long, value_name = "FILE", value_hint = ValueHint::FilePath)]
76        pub dump_asm: Option<OsString>,
77
78        /// The path to the compiled FALSE program
79        #[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath)]
80        pub out: Option<OsString>,
81
82        /// The path to the FALSE program to execute
83        #[arg(value_name = "FILE", value_hint = ValueHint::FilePath)]
84        pub program: OsString,
85    }
86}
87
88pub use compile::Compile;
89
90fn styles() -> Styles {
91    Styles::styled()
92        .usage(
93            anstyle::Style::new()
94                .bold()
95                .underline()
96                .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Yellow))),
97        )
98        .header(
99            anstyle::Style::new()
100                .bold()
101                .underline()
102                .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Yellow))),
103        )
104        .literal(
105            anstyle::Style::new().fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Green))),
106        )
107        .invalid(
108            anstyle::Style::new()
109                .bold()
110                .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Red))),
111        )
112        .error(
113            anstyle::Style::new()
114                .bold()
115                .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Red))),
116        )
117        .valid(
118            anstyle::Style::new()
119                .bold()
120                .underline()
121                .fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Green))),
122        )
123        .placeholder(
124            anstyle::Style::new().fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::White))),
125        )
126}