ADD: import module from wongola-std.
parent
2fe55d2c20
commit
335189c31c
|
@ -11,7 +11,7 @@ PARAMS ::= (ident type? (comma ident type?)*)
|
||||||
RET ::= type?
|
RET ::= type?
|
||||||
BLOCK ::= obrace INSTR* cbrace
|
BLOCK ::= obrace INSTR* cbrace
|
||||||
|
|
||||||
DIR ::= hash ident EXPR
|
DIR ::= hash ident EXPR (as ident)?
|
||||||
|
|
||||||
EXPR ::=
|
EXPR ::=
|
||||||
| ADDSUB
|
| ADDSUB
|
||||||
|
@ -29,4 +29,4 @@ LITERAL ::=
|
||||||
CALL ::= ident opar ARGS cpar
|
CALL ::= ident opar ARGS cpar
|
||||||
ARGS ::= (EXPR (comma EXPR)*)?
|
ARGS ::= (EXPR (comma EXPR)*)?
|
||||||
|
|
||||||
NS ::= ident (dot ident)+
|
NS ::= ident (dot (ident|CALL))+
|
||||||
|
|
169
lib/Compiler.cpp
169
lib/Compiler.cpp
|
@ -3,6 +3,8 @@
|
||||||
#include <llvm/IR/BasicBlock.h>
|
#include <llvm/IR/BasicBlock.h>
|
||||||
#include <llvm/IR/Verifier.h>
|
#include <llvm/IR/Verifier.h>
|
||||||
#include <llvm/IR/Type.h>
|
#include <llvm/IR/Type.h>
|
||||||
|
#include <llvm/IR/Function.h>
|
||||||
|
#include <llvm/IR/Value.h>
|
||||||
#include <llvm/TargetParser/Host.h>
|
#include <llvm/TargetParser/Host.h>
|
||||||
#include <llvm/Target/TargetOptions.h>
|
#include <llvm/Target/TargetOptions.h>
|
||||||
#include <llvm/Target/TargetMachine.h>
|
#include <llvm/Target/TargetMachine.h>
|
||||||
|
@ -13,7 +15,8 @@
|
||||||
|
|
||||||
namespace wg
|
namespace wg
|
||||||
{
|
{
|
||||||
/*explicit*/ Compiler::Compiler()
|
/*explicit*/ Compiler::Compiler(Mod& mod)
|
||||||
|
: m_mod { mod }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,8 +54,8 @@ namespace wg
|
||||||
opt,
|
opt,
|
||||||
rm);
|
rm);
|
||||||
|
|
||||||
m_module->setDataLayout(target_machine->createDataLayout());
|
m_mod.mod().setDataLayout(target_machine->createDataLayout());
|
||||||
m_module->setTargetTriple(target_triple);
|
m_mod.mod().setTargetTriple(target_triple);
|
||||||
|
|
||||||
auto filename = obj.string();
|
auto filename = obj.string();
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
@ -68,16 +71,125 @@ namespace wg
|
||||||
llvm::errs() << "Target machine cannot emit a file of this type";
|
llvm::errs() << "Target machine cannot emit a file of this type";
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::verifyModule(*m_module);
|
llvm::verifyModule(m_mod.mod());
|
||||||
|
|
||||||
pass.run(*m_module);
|
pass.run(m_mod.mod());
|
||||||
|
|
||||||
dest.flush();
|
dest.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::init_package(std::shared_ptr<Node> node)
|
|
||||||
|
void Compiler::execute(std::shared_ptr<Node> node)
|
||||||
{
|
{
|
||||||
m_pkg->scan(node, *m_sym);
|
imports(node);
|
||||||
|
scan(node);
|
||||||
|
compile(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::imports(std::shared_ptr<Node> node)
|
||||||
|
{
|
||||||
|
switch (node->type())
|
||||||
|
{
|
||||||
|
case NODE_DIR: {
|
||||||
|
if (node->child(0)->repr() == "import")
|
||||||
|
{
|
||||||
|
auto mod_name = node->child(1)->repr();
|
||||||
|
auto lib_path = "/usr/lib/libwongola-std.so";
|
||||||
|
auto lib = llvm::sys::DynamicLibrary::getLibrary(lib_path);
|
||||||
|
|
||||||
|
if (lib.isValid())
|
||||||
|
{
|
||||||
|
std::string entry_name = "lib_" + mod_name;
|
||||||
|
typedef std::unique_ptr<Mod>(*func)();
|
||||||
|
|
||||||
|
func entry = (func) lib.getAddressOfSymbol
|
||||||
|
(entry_name.c_str());
|
||||||
|
|
||||||
|
if (entry == nullptr)
|
||||||
|
{
|
||||||
|
node->loc().error<compile_error>
|
||||||
|
("cannot import module '"
|
||||||
|
+ mod_name
|
||||||
|
+ "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->size() == 3)
|
||||||
|
{
|
||||||
|
mod_name = node->child(2)->repr();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_imports.insert({mod_name, entry()});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->loc().error<compile_error>("cannot stdlib");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
for (size_t i=0; i<node->size(); i++)
|
||||||
|
{
|
||||||
|
imports(node->child(i));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compiler::scan(std::shared_ptr<Node> node)
|
||||||
|
{
|
||||||
|
switch (node->type())
|
||||||
|
{
|
||||||
|
case NODE_FUNDECL: {
|
||||||
|
std::string name = node->child(0)->repr();
|
||||||
|
std::vector<llvm::Type*> params;
|
||||||
|
std::vector<std::shared_ptr<Node>> buffer;
|
||||||
|
|
||||||
|
for (size_t i=0; i<node->child(1)->size(); i++)
|
||||||
|
{
|
||||||
|
auto param = node->child(1)->child(i);
|
||||||
|
|
||||||
|
if (param->type() == NODE_IDENT)
|
||||||
|
{
|
||||||
|
buffer.push_back(param);
|
||||||
|
}
|
||||||
|
else if (param->type() == NODE_TYPE)
|
||||||
|
{
|
||||||
|
for (auto p: buffer)
|
||||||
|
{
|
||||||
|
params.push_back((llvm::Type*)
|
||||||
|
llvm::Type::getInt32Ty(m_mod.context()));
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* ret = llvm::Type::getVoidTy(m_mod.context());
|
||||||
|
|
||||||
|
if (node->child(2)->size() > 0)
|
||||||
|
{
|
||||||
|
ret = (llvm::Type*) llvm::Type::getInt32Ty(m_mod.context());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* fun_ty = llvm::FunctionType::get(ret, params, false);
|
||||||
|
|
||||||
|
m_mod.sym().declare_prototype(name, fun_ty, node->loc());
|
||||||
|
|
||||||
|
llvm::Function::Create(fun_ty,
|
||||||
|
llvm::Function::ExternalLinkage,
|
||||||
|
name,
|
||||||
|
m_mod.mod());
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
for (size_t i=0; i<node->size(); i++)
|
||||||
|
{
|
||||||
|
scan(node->child(i));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* Compiler::compile(std::shared_ptr<Node> node)
|
llvm::Value* Compiler::compile(std::shared_ptr<Node> node)
|
||||||
|
@ -102,13 +214,39 @@ namespace wg
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_DIR: {
|
case NODE_DIR: {
|
||||||
if (node->child(0)->repr() == "import")
|
return nullptr;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NODE_NS: {
|
||||||
|
auto mod_name = node->child(0)->repr();
|
||||||
|
auto ident = node->child(1)->child(0)->repr();
|
||||||
|
|
||||||
|
if (auto itr=m_imports.find(mod_name);
|
||||||
|
itr != std::end(m_imports))
|
||||||
{
|
{
|
||||||
std::string pkg_name = node->child(1)->repr();
|
auto fun = itr->second->mod().getFunction(ident);
|
||||||
std::cout << "import pkg " << pkg_name << std::endl;
|
WG_ASSERT(fun, "cannot call unknown function '" + ident + "'");
|
||||||
|
|
||||||
|
std::vector<llvm::Value*> values;
|
||||||
|
|
||||||
|
auto arg_node = node->child(1)->child(1);
|
||||||
|
for (size_t i=0; i<arg_node->size(); i++)
|
||||||
|
{
|
||||||
|
auto arg = arg_node->child(i);
|
||||||
|
auto val = compile(arg);
|
||||||
|
values.push_back(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_builder->CreateCall(fun, values);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->loc().error<compile_error>("cannot find module '"
|
||||||
|
+ mod_name
|
||||||
|
+ "'");
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_RETURN: {
|
case NODE_RETURN: {
|
||||||
|
@ -165,12 +303,12 @@ namespace wg
|
||||||
case NODE_FUNDECL: {
|
case NODE_FUNDECL: {
|
||||||
auto ident = node->child(0)->repr();
|
auto ident = node->child(0)->repr();
|
||||||
auto body = node->child(3);
|
auto body = node->child(3);
|
||||||
auto fun = m_module-> getFunction(ident);
|
auto fun = m_mod.mod(). getFunction(ident);
|
||||||
|
|
||||||
|
|
||||||
llvm::BasicBlock* old_bb = m_builder->GetInsertBlock();
|
llvm::BasicBlock* old_bb = m_builder->GetInsertBlock();
|
||||||
|
|
||||||
auto* bb = llvm::BasicBlock::Create(*m_context,
|
auto* bb = llvm::BasicBlock::Create(m_mod.context(),
|
||||||
"entry",
|
"entry",
|
||||||
fun);
|
fun);
|
||||||
m_builder->SetInsertPoint(bb);
|
m_builder->SetInsertPoint(bb);
|
||||||
|
@ -187,7 +325,7 @@ namespace wg
|
||||||
case NODE_CALL: {
|
case NODE_CALL: {
|
||||||
std::string ident = node->child(0)->repr();
|
std::string ident = node->child(0)->repr();
|
||||||
|
|
||||||
auto fun = m_module->getFunction(ident);
|
auto fun = m_mod.mod().getFunction(ident);
|
||||||
WG_ASSERT(fun, "cannot call unknown function '" + ident + "'");
|
WG_ASSERT(fun, "cannot call unknown function '" + ident + "'");
|
||||||
|
|
||||||
std::vector<llvm::Value*> values;
|
std::vector<llvm::Value*> values;
|
||||||
|
@ -233,8 +371,7 @@ namespace wg
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_INT: {
|
case NODE_INT: {
|
||||||
|
return llvm::ConstantInt::get(m_mod.context(),
|
||||||
return llvm::ConstantInt::get(*m_context,
|
|
||||||
llvm::APInt(32,
|
llvm::APInt(32,
|
||||||
std::stoi(node->repr()),
|
std::stoi(node->repr()),
|
||||||
true));
|
true));
|
||||||
|
|
|
@ -8,32 +8,30 @@
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "SymTable.hpp"
|
#include "SymTable.hpp"
|
||||||
#include "Package.hpp"
|
#include "Mod.hpp"
|
||||||
|
|
||||||
namespace wg
|
namespace wg
|
||||||
{
|
{
|
||||||
|
WG_ERROR(compile_error);
|
||||||
|
|
||||||
class Compiler
|
class Compiler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Compiler();
|
explicit Compiler(Mod& mod);
|
||||||
virtual ~Compiler();
|
virtual ~Compiler();
|
||||||
|
|
||||||
void gen(std::filesystem::path obj);
|
void gen(std::filesystem::path obj);
|
||||||
void init_package(std::shared_ptr<Node> node);
|
|
||||||
|
void execute(std::shared_ptr<Node> node);
|
||||||
|
void imports(std::shared_ptr<Node> node);
|
||||||
|
void scan(std::shared_ptr<Node> node);
|
||||||
llvm::Value* compile(std::shared_ptr<Node> node);
|
llvm::Value* compile(std::shared_ptr<Node> node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<llvm::LLVMContext> m_context =
|
Mod& m_mod;
|
||||||
std::make_unique<llvm::LLVMContext>();
|
std::unordered_map<std::string, std::unique_ptr<Mod>> m_imports;
|
||||||
|
|
||||||
std::unique_ptr<llvm::IRBuilder<>> m_builder =
|
std::unique_ptr<llvm::IRBuilder<>> m_builder =
|
||||||
std::make_unique<llvm::IRBuilder<>>(*m_context);
|
std::make_unique<llvm::IRBuilder<>>(m_mod.context());
|
||||||
|
|
||||||
std::unique_ptr<llvm::Module> m_module =
|
|
||||||
std::make_unique<llvm::Module>("my module", *m_context);
|
|
||||||
|
|
||||||
std::unique_ptr<SymTable> m_sym = std::make_unique<SymTable>();
|
|
||||||
std::unique_ptr<Package> m_pkg = std::make_unique<Package>(*m_context,
|
|
||||||
*m_module);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace wg
|
||||||
{
|
{
|
||||||
/*explicit*/ Lexer::Lexer()
|
/*explicit*/ Lexer::Lexer()
|
||||||
{
|
{
|
||||||
|
add_keyword("as", NODE_AS);
|
||||||
add_keyword("int", NODE_TYPE, true);
|
add_keyword("int", NODE_TYPE, true);
|
||||||
add_keyword("fun", NODE_FUN);
|
add_keyword("fun", NODE_FUN);
|
||||||
add_keyword("return", NODE_RETURN);
|
add_keyword("return", NODE_RETURN);
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "Mod.hpp"
|
||||||
|
|
||||||
|
namespace wg
|
||||||
|
{
|
||||||
|
/*explicit*/ Mod::Mod(std::string const& name)
|
||||||
|
: m_name { name }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Mod::~Mod()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef wg_MOD_HPP
|
||||||
|
#define wg_MOD_HPP
|
||||||
|
|
||||||
|
#include <llvm/IR/LLVMContext.h>
|
||||||
|
#include <llvm/IR/Module.h>
|
||||||
|
|
||||||
|
#include "SymTable.hpp"
|
||||||
|
#include "commons.hpp"
|
||||||
|
|
||||||
|
namespace wg
|
||||||
|
{
|
||||||
|
class Mod
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Mod(std::string const& name);
|
||||||
|
virtual ~Mod();
|
||||||
|
|
||||||
|
llvm::LLVMContext& context() { return *m_context; }
|
||||||
|
llvm::Module& mod() { return *m_module; }
|
||||||
|
SymTable& sym() { return *m_sym; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_name;
|
||||||
|
std::unique_ptr<llvm::LLVMContext> m_context =
|
||||||
|
std::make_unique<llvm::LLVMContext>();
|
||||||
|
|
||||||
|
std::unique_ptr<llvm::Module> m_module =
|
||||||
|
std::make_unique<llvm::Module>(m_name, *m_context);
|
||||||
|
|
||||||
|
std::unique_ptr<SymTable> m_sym = std::make_unique<SymTable>();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,7 +17,8 @@
|
||||||
G(NODE_ARGS), G(NODE_TYPE), G(NODE_RETURN), \
|
G(NODE_ARGS), G(NODE_TYPE), G(NODE_RETURN), \
|
||||||
G(NODE_FUN), G(NODE_PARAMS), G(NODE_BLOCK), \
|
G(NODE_FUN), G(NODE_PARAMS), G(NODE_BLOCK), \
|
||||||
G(NODE_OBRACE), G(NODE_CBRACE), G(NODE_FUNDECL), \
|
G(NODE_OBRACE), G(NODE_CBRACE), G(NODE_FUNDECL), \
|
||||||
G(NODE_EXTERN), G(NODE_RET), G(NODE_DOT), G(NODE_NS)
|
G(NODE_EXTERN), G(NODE_RET), G(NODE_DOT), G(NODE_NS), \
|
||||||
|
G(NODE_AS)
|
||||||
|
|
||||||
namespace wg
|
namespace wg
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
#include <llvm/IR/Value.h>
|
|
||||||
#include <llvm/IR/Function.h>
|
|
||||||
|
|
||||||
#include "Package.hpp"
|
|
||||||
|
|
||||||
namespace wg
|
|
||||||
{
|
|
||||||
/*explicit*/ Package::Package(llvm::LLVMContext& context,
|
|
||||||
llvm::Module& mod)
|
|
||||||
: m_context { context }
|
|
||||||
, m_module { mod }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*virtual*/ Package::~Package()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Package::scan(std::shared_ptr<Node> node, SymTable& sym)
|
|
||||||
{
|
|
||||||
switch (node->type())
|
|
||||||
{
|
|
||||||
case NODE_DIR: {
|
|
||||||
if (node->child(0)->repr() == "package")
|
|
||||||
{
|
|
||||||
m_name = node->child(1)->repr();
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case NODE_FUNDECL: {
|
|
||||||
std::string name = node->child(0)->repr();
|
|
||||||
std::vector<llvm::Type*> params;
|
|
||||||
std::vector<std::shared_ptr<Node>> buffer;
|
|
||||||
|
|
||||||
for (size_t i=0; i<node->child(1)->size(); i++)
|
|
||||||
{
|
|
||||||
auto param = node->child(1)->child(i);
|
|
||||||
|
|
||||||
if (param->type() == NODE_IDENT)
|
|
||||||
{
|
|
||||||
buffer.push_back(param);
|
|
||||||
}
|
|
||||||
else if (param->type() == NODE_TYPE)
|
|
||||||
{
|
|
||||||
for (auto p: buffer)
|
|
||||||
{
|
|
||||||
params.push_back((llvm::Type*)
|
|
||||||
llvm::Type::getInt32Ty(m_context));
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* ret = llvm::Type::getVoidTy(m_context);
|
|
||||||
|
|
||||||
if (node->child(2)->size() > 0)
|
|
||||||
{
|
|
||||||
ret = (llvm::Type*) llvm::Type::getInt32Ty(m_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* fun_ty = llvm::FunctionType::get(ret, params, false);
|
|
||||||
|
|
||||||
sym.declare_prototype(name, fun_ty, node->loc());
|
|
||||||
|
|
||||||
llvm::Function::Create(fun_ty,
|
|
||||||
llvm::Function::ExternalLinkage,
|
|
||||||
name,
|
|
||||||
m_module);
|
|
||||||
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
for (size_t i=0; i<node->size(); i++)
|
|
||||||
{
|
|
||||||
scan(node->child(i), sym);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef wg_PACKAGE_HPP
|
|
||||||
#define wg_PACKAGE_HPP
|
|
||||||
|
|
||||||
#include "commons.hpp"
|
|
||||||
|
|
||||||
#include "SymTable.hpp"
|
|
||||||
#include "Node.hpp"
|
|
||||||
#include <llvm/IR/LLVMContext.h>
|
|
||||||
|
|
||||||
namespace wg
|
|
||||||
{
|
|
||||||
class Package
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit Package(llvm::LLVMContext& context,
|
|
||||||
llvm::Module& mod);
|
|
||||||
virtual ~Package();
|
|
||||||
|
|
||||||
void scan(std::shared_ptr<Node> node, SymTable& sym);
|
|
||||||
|
|
||||||
private:
|
|
||||||
llvm::LLVMContext& m_context;
|
|
||||||
llvm::Module& m_module;
|
|
||||||
std::string m_name;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -231,6 +231,13 @@ namespace wg
|
||||||
consume(NODE_HASH);
|
consume(NODE_HASH);
|
||||||
node->add_child(consume(NODE_IDENT));
|
node->add_child(consume(NODE_IDENT));
|
||||||
node->add_child(parse_expr());
|
node->add_child(parse_expr());
|
||||||
|
|
||||||
|
if (type_is(NODE_AS))
|
||||||
|
{
|
||||||
|
consume();
|
||||||
|
node->add_child(consume(NODE_IDENT));
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +359,16 @@ namespace wg
|
||||||
while (type_is(NODE_DOT))
|
while (type_is(NODE_DOT))
|
||||||
{
|
{
|
||||||
consume();
|
consume();
|
||||||
node->add_child(consume(NODE_IDENT));
|
|
||||||
|
if (type_is(NODE_IDENT)
|
||||||
|
&& type_is(NODE_OPAR, 1))
|
||||||
|
{
|
||||||
|
node->add_child(parse_call());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->add_child(consume(NODE_IDENT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|
20
meson.build
20
meson.build
|
@ -7,13 +7,6 @@ project('wongola',
|
||||||
'cpp_std=c++17'
|
'cpp_std=c++17'
|
||||||
])
|
])
|
||||||
|
|
||||||
shared_library(
|
|
||||||
'wongola-std',
|
|
||||||
sources: [
|
|
||||||
'std/io.cpp'
|
|
||||||
],
|
|
||||||
install: true
|
|
||||||
)
|
|
||||||
|
|
||||||
wongola_lib = static_library(
|
wongola_lib = static_library(
|
||||||
'wongola',
|
'wongola',
|
||||||
|
@ -24,7 +17,7 @@ wongola_lib = static_library(
|
||||||
'lib/Compiler.cpp',
|
'lib/Compiler.cpp',
|
||||||
'lib/Loc.cpp',
|
'lib/Loc.cpp',
|
||||||
'lib/SymTable.cpp',
|
'lib/SymTable.cpp',
|
||||||
'lib/Package.cpp',
|
'lib/Mod.cpp',
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('LLVM')
|
dependency('LLVM')
|
||||||
|
@ -36,6 +29,17 @@ wongola_dep = declare_dependency(
|
||||||
include_directories: ['lib']
|
include_directories: ['lib']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
shared_library(
|
||||||
|
'wongola-std',
|
||||||
|
sources: [
|
||||||
|
'std/io.cpp'
|
||||||
|
],
|
||||||
|
dependencies: [
|
||||||
|
wongola_dep
|
||||||
|
],
|
||||||
|
install: true
|
||||||
|
)
|
||||||
|
|
||||||
executable('wongoc',
|
executable('wongoc',
|
||||||
sources: [
|
sources: [
|
||||||
'src/main.cpp',
|
'src/main.cpp',
|
||||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -5,6 +5,7 @@
|
||||||
#include <Parser.hpp>
|
#include <Parser.hpp>
|
||||||
#include <Compiler.hpp>
|
#include <Compiler.hpp>
|
||||||
#include <llvm/Support/DynamicLibrary.h>
|
#include <llvm/Support/DynamicLibrary.h>
|
||||||
|
#include "Mod.hpp"
|
||||||
|
|
||||||
std::filesystem::path name_to_obj(std::string const& path)
|
std::filesystem::path name_to_obj(std::string const& path)
|
||||||
{
|
{
|
||||||
|
@ -41,9 +42,10 @@ void load(std::string const& path)
|
||||||
wg::Parser parser;
|
wg::Parser parser;
|
||||||
auto ast = parser.parse(tokens);
|
auto ast = parser.parse(tokens);
|
||||||
|
|
||||||
wg::Compiler compiler;
|
wg::Mod mod {"main"};
|
||||||
compiler.init_package(ast);
|
wg::Compiler compiler {mod};
|
||||||
compiler.compile(ast);
|
|
||||||
|
compiler.execute(ast);
|
||||||
compiler.gen(name_to_obj(path));
|
compiler.gen(name_to_obj(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +103,7 @@ int main(int argc, char** argv)
|
||||||
ss << "clang++" << " -o " << output_path << " ";
|
ss << "clang++" << " -o " << output_path << " ";
|
||||||
|
|
||||||
ss << objname;
|
ss << objname;
|
||||||
//ss << " -lwongola-std ";
|
ss << " -lwongola-std ";
|
||||||
system(ss.str().c_str());
|
system(ss.str().c_str());
|
||||||
|
|
||||||
std::filesystem::remove(objname);
|
std::filesystem::remove(objname);
|
||||||
|
|
24
std/io.cpp
24
std/io.cpp
|
@ -1,10 +1,24 @@
|
||||||
#include "io.hpp"
|
#include "io.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
extern "C" void hello(int x)
|
extern "C" std::unique_ptr<wg::Mod> lib_io()
|
||||||
{
|
{
|
||||||
for (int i=0; i<x; i++)
|
auto mod = std::make_unique<wg::Mod>("io");
|
||||||
{
|
|
||||||
std::cout << "hello ! " << std::endl;
|
std::vector<llvm::Type*> params;
|
||||||
}
|
auto* ret = llvm::Type::getInt32Ty(mod->context());
|
||||||
|
|
||||||
|
auto* ftype = llvm::FunctionType::get(ret, params, false);
|
||||||
|
|
||||||
|
llvm::Function::Create(ftype,
|
||||||
|
llvm::Function::ExternalLinkage,
|
||||||
|
"hello",
|
||||||
|
mod->mod());
|
||||||
|
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int hello(int x)
|
||||||
|
{
|
||||||
|
return 2 * x + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#ifndef IO_HPP
|
#ifndef IO_HPP
|
||||||
#define IO_HPP
|
#define IO_HPP
|
||||||
|
#include "../lib/Mod.hpp"
|
||||||
|
|
||||||
|
extern "C" std::unique_ptr<wg::Mod> lib_io();
|
||||||
extern "C" void hello(int x);
|
extern "C" int hello(int x);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,3 +76,11 @@ TEST_CASE_METHOD(LexerTest, "Lexer_pkg_namespace")
|
||||||
test_next(lex, "DOT");
|
test_next(lex, "DOT");
|
||||||
test_end(lex);
|
test_end(lex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(LexerTest, "Lexer_as")
|
||||||
|
{
|
||||||
|
wg::Lexer lex;
|
||||||
|
lex.scan(" as ");
|
||||||
|
test_next(lex, "AS");
|
||||||
|
test_end(lex);
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ TEST_CASE_METHOD(ParserTest, "Parser_dir")
|
||||||
{
|
{
|
||||||
test_parse("PROG(DIR(IDENT[hello],IDENT[world]))",
|
test_parse("PROG(DIR(IDENT[hello],IDENT[world]))",
|
||||||
"#hello world");
|
"#hello world");
|
||||||
|
|
||||||
|
test_parse("PROG(DIR(IDENT[hello],IDENT[world],IDENT[boom]))",
|
||||||
|
"#hello world as boom");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,4 +98,8 @@ TEST_CASE_METHOD(ParserTest, "Parser_namespace")
|
||||||
{
|
{
|
||||||
test_parse("PROG(NS(IDENT[a],IDENT[b],IDENT[c],IDENT[d]))",
|
test_parse("PROG(NS(IDENT[a],IDENT[b],IDENT[c],IDENT[d]))",
|
||||||
" a.b.c.d; ");
|
" a.b.c.d; ");
|
||||||
|
|
||||||
|
test_parse("PROG(NS(IDENT[a],IDENT[b],IDENT[c],"
|
||||||
|
"CALL(IDENT[d],ARGS)))",
|
||||||
|
" a.b.c.d(); ");
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue