Adding support for declaration of external modules as .mm files.

This commit is contained in:
Stefano Sanfilippo 2015-03-10 00:52:51 +01:00
parent ef0e1be751
commit 4df447f23e
4 changed files with 95 additions and 5 deletions

View File

@ -67,9 +67,13 @@ elseif(BISON_VERSION VERSION_LESS 3.0)
endif() endif()
## 3. External components ## 3. External components
find_package(Boost 1.48 REQUIRED regex system filesystem) find_package(Boost 1.48 REQUIRED regex system filesystem)
find_package(LLVM REQUIRED CONFIG) find_package(LLVM REQUIRED CONFIG)
find_library(YAML_LIBRARIES yaml-cpp)
find_path(YAML_INCLUDE_DIRS yaml.h /usr/include/yaml-cpp/)
add_definitions( add_definitions(
${Boost_DEFINITIONS} ${Boost_DEFINITIONS}
${LLVM_DEFINITIONS} ${LLVM_DEFINITIONS}
@ -78,6 +82,7 @@ add_definitions(
include_directories( include_directories(
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${LLVM_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS}
${YAML_INCLUDE_DIRS}
) )
## 4. Build ## 4. Build
@ -92,7 +97,8 @@ flex_target(Scanner Monicelli.lpp ${CMAKE_CURRENT_BINARY_DIR}/Lexer.cpp)
add_flex_bison_dependency(Scanner Parser) add_flex_bison_dependency(Scanner Parser)
add_executable(mcc add_executable(mcc
main.cpp Nodes.cpp ModuleRegistry.cpp main.cpp Nodes.cpp
ModuleRegistry.cpp ModuleLoader.cpp
${BISON_Parser_OUTPUTS} ${FLEX_Scanner_OUTPUTS} ${BISON_Parser_OUTPUTS} ${FLEX_Scanner_OUTPUTS}
CppEmitter.cpp BitcodeEmitter.cpp CppEmitter.cpp BitcodeEmitter.cpp
) )
@ -110,6 +116,7 @@ llvm_map_components_to_libnames(LLVM_LIBRARIES
target_link_libraries(mcc target_link_libraries(mcc
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${LLVM_LIBRARIES} ${LLVM_LIBRARIES}
${YAML_LIBRARIES}
) )
## 6. Build the runtime library too ## 6. Build the runtime library too

55
ModuleLoader.cpp Normal file
View File

@ -0,0 +1,55 @@
#include "Nodes.hpp"
#include "ModuleRegistry.hpp"
#include "ModuleLoader.hpp"
#include <yaml-cpp/yaml.h>
#include <string>
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<FunArg> *args = new PointerList<FunArg>();
for (auto const& arg: proto.second["args"]) {
args->push_back(new FunArg(
new Id(arg.first.as<std::string>()),
toType(arg.second.as<std::string>()),
false
));
}
Type type;
if (proto.second["type"]) {
type = toType(proto.second["type"].as<std::string>());
} else {
type = Type::VOID;
}
to.registerFunction(new FunctionPrototype(
new Id(proto.first.as<std::string>()), type, args
));
}
}

10
ModuleLoader.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef MODULE_LOADER_HPP
#define MODULE_LOADER_HPP
namespace monicelli {
void loadModule(std::string const& from, monicelli::ModuleRegistry &to);
}
#endif

View File

@ -21,6 +21,7 @@
#include "Parser.hpp" #include "Parser.hpp"
#include "CppEmitter.hpp" #include "CppEmitter.hpp"
#include "ModuleRegistry.hpp" #include "ModuleRegistry.hpp"
#include "ModuleLoader.hpp"
#include "BitcodeEmitter.hpp" #include "BitcodeEmitter.hpp"
#include <llvm/Bitcode/ReaderWriter.h> #include <llvm/Bitcode/ReaderWriter.h>
@ -41,9 +42,27 @@ using namespace monicelli;
int main(int argc, char **argv) { int main(int argc, char **argv) {
registerStdLib(getModuleRegistry()); registerStdLib(getModuleRegistry());
boost::regex namere("^(.+)\\.mc$");
boost::regex modulere("^(.+)\\.mm$");
std::vector<std::string> sources;
std::vector<std::string> modules;
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
std::string inputname(argv[i]); std::string arg(argv[i]);
std::ifstream instream(inputname); 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; Program program;
Scanner scanner(&instream); Scanner scanner(&instream);
@ -56,8 +75,7 @@ int main(int argc, char **argv) {
parser.parse(); parser.parse();
boost::regex namere("^(.+)\\.mc$"); std::string outputname = boost::filesystem::path(name).filename().native();
std::string outputname = boost::filesystem::path(inputname).filename().native();
if (boost::regex_match(outputname, namere)) { if (boost::regex_match(outputname, namere)) {
outputname = boost::regex_replace(outputname, namere, "$1.bc"); outputname = boost::regex_replace(outputname, namere, "$1.bc");