diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e033eb..6d6c2b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,9 +67,13 @@ elseif(BISON_VERSION VERSION_LESS 3.0) endif() ## 3. External components + find_package(Boost 1.48 REQUIRED regex system filesystem) find_package(LLVM REQUIRED CONFIG) +find_library(YAML_LIBRARIES yaml-cpp) +find_path(YAML_INCLUDE_DIRS yaml.h /usr/include/yaml-cpp/) + add_definitions( ${Boost_DEFINITIONS} ${LLVM_DEFINITIONS} @@ -78,6 +82,7 @@ add_definitions( include_directories( ${Boost_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} + ${YAML_INCLUDE_DIRS} ) ## 4. Build @@ -92,7 +97,8 @@ flex_target(Scanner Monicelli.lpp ${CMAKE_CURRENT_BINARY_DIR}/Lexer.cpp) add_flex_bison_dependency(Scanner Parser) add_executable(mcc - main.cpp Nodes.cpp ModuleRegistry.cpp + main.cpp Nodes.cpp + ModuleRegistry.cpp ModuleLoader.cpp ${BISON_Parser_OUTPUTS} ${FLEX_Scanner_OUTPUTS} CppEmitter.cpp BitcodeEmitter.cpp ) @@ -110,6 +116,7 @@ llvm_map_components_to_libnames(LLVM_LIBRARIES target_link_libraries(mcc ${Boost_LIBRARIES} ${LLVM_LIBRARIES} + ${YAML_LIBRARIES} ) ## 6. Build the runtime library too diff --git a/ModuleLoader.cpp b/ModuleLoader.cpp new file mode 100644 index 0000000..75d157d --- /dev/null +++ b/ModuleLoader.cpp @@ -0,0 +1,55 @@ +#include "Nodes.hpp" +#include "ModuleRegistry.hpp" +#include "ModuleLoader.hpp" + +#include +#include + +using namespace monicelli; + + +static +Type toType(std::string const& value) { + if (value == "int") { + return Type::INT; + } else if (value == "float") { + return Type::FLOAT; + } else if (value == "double") { + return Type::DOUBLE; + } else if (value == "char") { + return Type::CHAR; + } else if (value == "bool") { + return Type::BOOL; + } else { + return Type::VOID; + } +} + +void monicelli::loadModule(std::string const& from, ModuleRegistry &to) { + YAML::Node module = YAML::LoadFile(from); + + if (!module["functions"]) return; + + for (auto const& proto: module["functions"]) { + PointerList *args = new PointerList(); + for (auto const& arg: proto.second["args"]) { + args->push_back(new FunArg( + new Id(arg.first.as()), + toType(arg.second.as()), + false + )); + } + + Type type; + if (proto.second["type"]) { + type = toType(proto.second["type"].as()); + } else { + type = Type::VOID; + } + + to.registerFunction(new FunctionPrototype( + new Id(proto.first.as()), type, args + )); + } +} + diff --git a/ModuleLoader.hpp b/ModuleLoader.hpp new file mode 100644 index 0000000..74f21da --- /dev/null +++ b/ModuleLoader.hpp @@ -0,0 +1,10 @@ +#ifndef MODULE_LOADER_HPP +#define MODULE_LOADER_HPP + +namespace monicelli { + +void loadModule(std::string const& from, monicelli::ModuleRegistry &to); + +} + +#endif diff --git a/main.cpp b/main.cpp index 293a9c3..d5e5e0d 100644 --- a/main.cpp +++ b/main.cpp @@ -21,6 +21,7 @@ #include "Parser.hpp" #include "CppEmitter.hpp" #include "ModuleRegistry.hpp" +#include "ModuleLoader.hpp" #include "BitcodeEmitter.hpp" #include @@ -41,9 +42,27 @@ using namespace monicelli; int main(int argc, char **argv) { registerStdLib(getModuleRegistry()); + boost::regex namere("^(.+)\\.mc$"); + boost::regex modulere("^(.+)\\.mm$"); + + std::vector sources; + std::vector modules; + for (int i = 1; i < argc; ++i) { - std::string inputname(argv[i]); - std::ifstream instream(inputname); + std::string arg(argv[i]); + if (boost::regex_match(arg, namere)) { + sources.push_back(arg); + } else if (boost::regex_match(arg, modulere)) { + modules.push_back(arg); + } + } + + for (std::string const& name: modules) { + loadModule(name, getModuleRegistry()); + } + + for (std::string const& name: sources) { + std::ifstream instream(name); Program program; Scanner scanner(&instream); @@ -56,8 +75,7 @@ int main(int argc, char **argv) { parser.parse(); - boost::regex namere("^(.+)\\.mc$"); - std::string outputname = boost::filesystem::path(inputname).filename().native(); + std::string outputname = boost::filesystem::path(name).filename().native(); if (boost::regex_match(outputname, namere)) { outputname = boost::regex_replace(outputname, namere, "$1.bc");