From 6919c02ada2b57184228d73671639f2d8a8869bd Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Wed, 17 May 2023 23:12:03 +0100 Subject: [PATCH] Add the skeleton of th subcommand system --- serene/include/serene/commands.h | 27 +++++++++++++ serene/src/CMakeLists.txt | 6 ++- serene/src/commands/commands.cpp | 30 ++++++++++++++ serene/src/serene.cpp | 67 +++++++++++++++++++++----------- 4 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 serene/include/serene/commands.h create mode 100644 serene/src/commands/commands.cpp diff --git a/serene/include/serene/commands.h b/serene/include/serene/commands.h new file mode 100644 index 0000000..57cacf0 --- /dev/null +++ b/serene/include/serene/commands.h @@ -0,0 +1,27 @@ +/* -*- C++ -*- + * Serene Programming Language + * + * Copyright (c) 2019-2023 Sameer Rahmani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SERENE_COMMANDS_H +#define SERENE_COMMANDS_H + +namespace serene::commands { +int cc(int argc, char **argv); +int run(); +} // namespace serene::commands + +#endif diff --git a/serene/src/CMakeLists.txt b/serene/src/CMakeLists.txt index a763059..532bb28 100644 --- a/serene/src/CMakeLists.txt +++ b/serene/src/CMakeLists.txt @@ -14,4 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -target_sources(serene PRIVATE serene.cpp) +target_sources(serene PRIVATE + serene.cpp + + commands/commands.cpp +) diff --git a/serene/src/commands/commands.cpp b/serene/src/commands/commands.cpp new file mode 100644 index 0000000..714eb98 --- /dev/null +++ b/serene/src/commands/commands.cpp @@ -0,0 +1,30 @@ +/* -*- C++ -*- + * Serene Programming Language + * + * Copyright (c) 2019-2023 Sameer Rahmani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "serene/commands.h" + +#include + +namespace serene::commands { +int cc(int argc, char **argv) { + printf(">> %d, %s\n", argc, argv[0]); + return 0; +} + +int run() { return 0; } +} // namespace serene::commands diff --git a/serene/src/serene.cpp b/serene/src/serene.cpp index dcd1332..1fa50fb 100644 --- a/serene/src/serene.cpp +++ b/serene/src/serene.cpp @@ -16,32 +16,55 @@ * along with this program. If not, see . */ -#include -#include -#include +#include "serene/commands.h" +#include "serene/config.h" -struct Vec3 { - int x, y, z; +#include +#include - // following constructor is no longer needed since C++20 - Vec3(int x = 0, int y = 0, int z = 0) noexcept : x(x), y(y), z(z) {} +#include +#include - friend std::ostream &operator<<(std::ostream &os, const Vec3 &v) { - return os << "{ x=" << v.x << ", y=" << v.y << ", z=" << v.z << " }"; +namespace cl = llvm::cl; + +static std::string banner = + llvm::formatv("\n\nSerene Compiler Version {0}" + "\nCopyright (C) 2019-2023 " + "Sameer Rahmani \n" + "Serene comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome\n" + "to redistribute it under certain conditions; \n" + "for details take a look at the LICENSE file.\n", + SERENE_VERSION); + +namespace serene::opts { +// Global options =========================================================== +static cl::opt verbose("v", cl::desc("Use verbose output"), + cl::cat(cl::getGeneralCategory()), + cl::sub(cl::SubCommand::getAll())); + +// Subcommands ============================================================== +// We don't use this subcommand directly but we need it for the CLI interface +static cl::SubCommand CC("cc", "Serene's C compiler interface"); + +static cl::SubCommand Run("run", "Run a Serene file"); +} // namespace serene::opts + +int main(int argc, char **argv) { + + // We don't use llvm::cl here cause we want to let + // the clang take care of the argument parsing. + if ((argc >= 2) && (strcmp(argv[1], "cc") == 0)) { + return serene::commands::cc(--argc, ++argv); } -}; -int main() { - // Use the default constructor. - std::unique_ptr v1 = std::make_unique(); - // Use the constructor that matches these arguments - std::unique_ptr v2 = std::make_unique(0, 1, 2); - // Create a unique_ptr to an array of 5 elements - std::unique_ptr v3 = std::make_unique(5); + // We start using llvm::cl from here onward which + // enforces our rules even for the subcommands. + cl::ParseCommandLineOptions(argc, argv, banner); - std::cout << "make_unique(): " << *v1 << '\n' - << "make_unique(0,1,2): " << *v2 << '\n' - << "make_unique(5): "; - for (int i = 0; i < 5; i++) - std::cout << std::setw(i ? 30 : 0) << v3[static_cast(i)] << '\n'; + if (serene::opts::Run) { + serene::commands::run(); + } + + return 0; }