Skip to content

Commit

Permalink
Merge pull request #400 from yamacir-kit/configurator
Browse files Browse the repository at this point in the history
Configurator
  • Loading branch information
yamacir-kit authored Jun 11, 2022
2 parents dfbcf40 + 62ab16c commit cde20d2
Show file tree
Hide file tree
Showing 14 changed files with 229 additions and 172 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ sudo rm -rf /usr/local/share/meevax

| Target Name | Description
|:-------------------|:--
| `all` (default) | Build shared-library `libmeevax.0.4.50.so` and executable `meevax`.
| `all` (default) | Build shared-library `libmeevax.0.4.58.so` and executable `meevax`.
| `test` | Test executable `meevax`.
| `package` | Generate debian package `meevax_0.4.50_amd64.deb`.
| `package` | Generate debian package `meevax_0.4.58_amd64.deb`.
| `install` | Copy files into `/usr/local` __(1)__.
| `install.deb` | `all` + `package` + `sudo apt install <meevax>.deb`
| `safe-install.deb` | `all` + `test` + `package` + `sudo apt install <meevax>.deb`
Expand All @@ -120,7 +120,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's
## Usage

```
Meevax Lisp System, version 0.4.50
Meevax Lisp System, version 0.4.58
Usage: meevax [OPTION...] [FILE...]
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.50
0.4.58
266 changes: 135 additions & 131 deletions include/meevax/kernel/configurator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <meevax/kernel/error.hpp>
#include <meevax/kernel/ghost.hpp>
#include <meevax/kernel/interaction_environment.hpp>
#include <meevax/kernel/procedure.hpp>
#include <meevax/kernel/version.hpp>

Expand All @@ -33,133 +34,161 @@ inline namespace kernel
{
friend environment;

explicit configurator()
{}

IMPORT(environment, evaluate, NIL);
IMPORT(environment, load, NIL);
IMPORT(environment, print, const);
IMPORT(environment, read, NIL);

USING_STATIC(environment, print);

template <typename Key>
using dispatcher = std::unordered_map<Key, procedure::function_type>;

const dispatcher<char> short_options, short_options_with_arguments;
public:
static inline auto batch = false;
static inline auto debug = false;
static inline auto interactive = true;
static inline auto trace = false;
static inline auto verbose = false;

const dispatcher<std::string> long_options, long_options_with_arguments;
static auto display_version() -> void
{
print("Meevax Lisp ", version());
}

public:
bool batch = false;
bool debug = false;
bool interactive = false;
bool trace = false;
bool verbose = false;
static auto display_help() -> void
{
display_version();
print();
print("Usage: meevax [OPTION...] [FILE...]");
print();
print("Options:");
print(" -b, --batch Suppress any system output.");
print(" -d, --debug Display detailed informations for developers.");
print(" -e, --evaluate=STRING Read and evaluate given STRING at configuration step.");
print(" -h, --help Display this help text and exit.");
print(" -i, --interactive Take over control of root environment.");
print(" -l, --load=FILENAME Same as -e '(load FILENAME)'");
print(" -t, --trace Display stacks of virtual machine for each steps.");
print(" -v, --version Display version information and exit.");
print(" --verbose Display detailed informations.");
print(" -w, --write=OBJECT Same as -e '(write OBJECT)'");
}

explicit configurator()
: short_options
{
std::make_pair('b', [this](auto&&...)
{
return make<bool>(batch = true);
}),
private:
static inline const dispatcher<char> short_options
{
std::make_pair('b', [](auto&&...)
{
return make<bool>(batch = true);
}),

std::make_pair('d', [this](auto&&...)
{
return make<bool>(debug = true);
}),
std::make_pair('d', [](auto&&...)
{
return make<bool>(debug = true);
}),

std::make_pair('h', [this](auto&&...) -> lvalue
{
display_help();
throw exit_status::success;
}),
std::make_pair('h', [](auto&&...) -> lvalue
{
configurator::display_help();
throw exit_status::success;
}),

std::make_pair('i', [this](auto&&...)
{
return make<bool>(interactive = true);
}),
std::make_pair('i', [](auto&&...)
{
return make<bool>(interactive = true);
}),

std::make_pair('v', [this](auto&&...) -> lvalue
{
display_version();
throw exit_status::success;
}),
}
std::make_pair('v', [](auto&&...) -> lvalue
{
configurator::display_version();
throw exit_status::success;
}),
};

, short_options_with_arguments
{
std::make_pair('e', [this](const_reference x, auto&&...)
{
return print(evaluate(x)), unspecified_object;
}),
static inline const dispatcher<char> short_options_with_arguments
{
std::make_pair('e', [](const_reference x, auto&&...)
{
print(interaction_environment().as<environment>().evaluate(x));
return unspecified_object;
}),

std::make_pair('l', [this](const_reference x, auto&&...)
{
return load(x.as_const<string>());
}),
std::make_pair('l', [](const_reference x, auto&&...)
{
return interaction_environment().as<environment>().load(x.as_const<symbol>());
}),

std::make_pair('w', [this](const_reference x, auto&&...)
{
return print(x), unspecified_object;
}),
}
std::make_pair('w', [](const_reference x, auto&&...)
{
print(x);
return unspecified_object;
}),
};

, long_options
{
std::make_pair("batch", [this](auto&&...)
{
return make<bool>(batch = true);
}),
static inline const dispatcher<std::string> long_options
{
std::make_pair("batch", [](auto&&...)
{
return make<bool>(batch = true);
}),

std::make_pair("debug", [this](auto&&...)
{
return make<bool>(debug = true);
}),
std::make_pair("debug", [](auto&&...)
{
return make<bool>(debug = true);
}),

std::make_pair("help", [this](auto&&...) -> lvalue
{
display_help();
throw exit_status::success;
}),
std::make_pair("help", [](auto&&...) -> lvalue
{
display_help();
throw exit_status::success;
}),

std::make_pair("interactive", [this](auto&&...)
{
return make<bool>(interactive = true);
}),
std::make_pair("interactive", [](auto&&...)
{
return make<bool>(interactive = true);
}),

std::make_pair("trace", [this](auto&&...)
{
return make<bool>(trace = true);
}),
std::make_pair("trace", [](auto&&...)
{
return make<bool>(trace = true);
}),

std::make_pair("verbose", [this](auto&&...)
{
return make<bool>(verbose = true);
}),
std::make_pair("verbose", [](auto&&...)
{
return make<bool>(verbose = true);
}),

std::make_pair("version", [this](auto&&...) -> lvalue
{
display_version();
throw exit_status::success;
}),
}
std::make_pair("version", [](auto&&...) -> lvalue
{
display_version();
throw exit_status::success;
}),
};

, long_options_with_arguments
{
std::make_pair("evaluate", [this](const_reference x, auto&&...)
{
return print(evaluate(x)), unspecified_object;
}),
static inline const dispatcher<std::string> long_options_with_arguments
{
std::make_pair("evaluate", [](const_reference x, auto&&...)
{
print(interaction_environment().as<environment>().evaluate(x));
return unspecified_object;
}),

std::make_pair("load", [this](const_reference x, auto&&...)
{
return load(x.as_const<string>());
}),
std::make_pair("load", [](const_reference x, auto&&...)
{
return interaction_environment().as<environment>().load(x.as_const<string>());
}),

std::make_pair("write", [this](const_reference x, auto&&...)
{
return print(x), unspecified_object;
}),
}
{}
std::make_pair("write", [](const_reference x, auto&&...)
{
print(x);
return unspecified_object;
}),
};

public:
auto configure(const int argc, char const* const* const argv)
{
return configure({ argv + 1, argv + argc });
Expand All @@ -169,11 +198,7 @@ inline namespace kernel
{
static std::regex const pattern { R"(--(\w[-\w]+)(=(.*))?|-([\w]+))" };

if (std::empty(args))
{
interactive = true;
}
else for (auto current_option = std::begin(args); current_option != std::end(args); ++current_option) [&]()
for (auto current_option = std::begin(args); current_option != std::end(args); ++current_option) [&]()
{
std::smatch analysis {};

Expand All @@ -185,7 +210,7 @@ inline namespace kernel
// std::cout << header("") << "analysis[3] = " << analysis[3] << std::endl;
// std::cout << header("") << "analysis[4] = " << analysis[4] << std::endl;

if (auto const current_short_options = analysis.str(4); not current_short_options.empty())
if (auto const& current_short_options = analysis.str(4); not current_short_options.empty())
{
for (auto current_short_option = std::cbegin(current_short_options); current_short_option != std::cend(current_short_options); ++current_short_option)
{
Expand All @@ -210,7 +235,8 @@ inline namespace kernel
}
else
{
throw error(make<string>(cat, "unknown short-option -", *current_short_option));
throw error(make<string>("unknown short-option"),
make<symbol>(*current_short_option));
}
}
}
Expand All @@ -237,41 +263,19 @@ inline namespace kernel
}
else
{
throw error(make<string>(cat, "unknown long-option: ", *current_option));
throw error(make<string>("unknown long-option"),
make<symbol>(*current_option));
}
}
else
{
interactive = false;
return load(*current_option);
}

return unspecified_object;
}();
}

auto display_version() const -> void
{
print("Meevax Lisp ", version());
}

auto display_help() const -> void
{
display_version();
print();
print("Usage: meevax [OPTION...] [FILE...]");
print();
print("Options:");
print(" -b, --batch Suppress any system output.");
print(" -d, --debug Display detailed informations for developers.");
print(" -e, --evaluate=STRING Read and evaluate given STRING at configuration step.");
print(" -h, --help Display this help text and exit.");
print(" -i, --interactive Take over control of root environment.");
print(" -l, --load=FILENAME Same as -e '(load FILENAME)'");
print(" -t, --trace Display stacks of virtual machine for each steps.");
print(" -v, --version Display version information and exit.");
print(" --verbose Display detailed informations.");
print(" -w, --write=OBJECT Same as -e '(write OBJECT)'");
}
};
} // namespace kernel
} // namespace meevax
Expand Down
10 changes: 5 additions & 5 deletions include/meevax/kernel/environment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ inline namespace kernel
{
(import(xs), ...);

define<procedure>("set-batch!", [this](let const& xs, auto&&...) { return batch = select(car(xs)); });
define<procedure>("set-debug!", [this](let const& xs, auto&&...) { return debug = select(car(xs)); });
define<procedure>("set-interactive!", [this](let const& xs, auto&&...) { return interactive = select(car(xs)); });
define<procedure>("set-trace!", [this](let const& xs, auto&&...) { return trace = select(car(xs)); });
define<procedure>("set-verbose!", [this](let const& xs, auto&&...) { return verbose = select(car(xs)); });
// define<procedure>("set-batch!", [this](let const& xs, auto&&...) { return batch = select(car(xs)); });
// define<procedure>("set-debug!", [this](let const& xs, auto&&...) { return debug = select(car(xs)); });
// define<procedure>("set-interactive!", [this](let const& xs, auto&&...) { return interactive = select(car(xs)); });
// define<procedure>("set-trace!", [this](let const& xs, auto&&...) { return trace = select(car(xs)); });
// define<procedure>("set-verbose!", [this](let const& xs, auto&&...) { return verbose = select(car(xs)); });
}

auto operator [](const_reference) -> const_reference;
Expand Down
Loading

0 comments on commit cde20d2

Please sign in to comment.