Adding support for declaration of external modules as .mm files.
This commit is contained in:
parent
ef0e1be751
commit
4df447f23e
|
@ -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
|
||||
|
|
55
ModuleLoader.cpp
Normal file
55
ModuleLoader.cpp
Normal 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
10
ModuleLoader.hpp
Normal 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
|
26
main.cpp
26
main.cpp
|
@ -21,6 +21,7 @@
|
|||
#include "Parser.hpp"
|
||||
#include "CppEmitter.hpp"
|
||||
#include "ModuleRegistry.hpp"
|
||||
#include "ModuleLoader.hpp"
|
||||
#include "BitcodeEmitter.hpp"
|
||||
|
||||
#include <llvm/Bitcode/ReaderWriter.h>
|
||||
|
@ -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<std::string> sources;
|
||||
std::vector<std::string> 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");
|
||||
|
|
Reference in New Issue
Block a user