Skip to content

Commit

Permalink
refactor(core)
Browse files Browse the repository at this point in the history
  • Loading branch information
nullptr0x committed Apr 12, 2024
1 parent 578aa70 commit 07b0578
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 29 deletions.
1 change: 1 addition & 0 deletions Swirl/include/parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ struct Function: Node {
struct FuncCall: Node {
std::vector<Expression> args;
std::string ident;
std::string type = "void";
std::string getValue() const override { return ident; }
Node* parent = nullptr;

Expand Down
13 changes: 13 additions & 0 deletions Swirl/include/tokenizer/InputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@


class InputStream {
std::tuple<size_t, size_t, size_t> cache;

public:
std::size_t Pos = 0, Line = 1, Col = 0;

explicit InputStream(std::string& _source);

/** @brief Returns the next value without discarding it */
Expand All @@ -16,11 +19,21 @@ class InputStream {
/** @brief returns the next value and discards it */
char next();

/** @brief back off by one char **/
void backoff();

/** @brief returns true if no more chars are left in the stream */
bool eof();

/** @brief saves the current state */
void setReturnPoint();

/** @brief restores cache */
void restoreCache();

/** @brief resets the state of the stream */
void reset();

private:
std::string m_Source{};
};
Expand Down
2 changes: 1 addition & 1 deletion Swirl/include/tokens/Tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ enum TokenType {
MACRO,

NONE,
_NONE, // to be used in the parser, "" will be replaced with this
_NONE // to be used in the parser, "" will be replaced with this
};

struct Token {
Expand Down
3 changes: 2 additions & 1 deletion Swirl/src/swirl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ std::unordered_map<std::string, uint8_t> operators = {
{"++", 30},
{"--", 31},
{"~", 32},
{"//", 33}
};


Expand Down Expand Up @@ -184,7 +185,7 @@ int main(int argc, const char** const argv) {

std::string file_name = SW_FED_FILE_PATH.substr(SW_FED_FILE_PATH.find_last_of("/\\") + 1);
std::string out_dir = SW_FED_FILE_PATH.replace(SW_FED_FILE_PATH.find(file_name),file_name.length(),"");
file_name = file_name.substr(0, file_name.find_last_of("."));
file_name = file_name.substr(0, file_name.find_last_of('.'));

SW_OUTPUT = file_name;

Expand Down
22 changes: 21 additions & 1 deletion Swirl/src/tokenizer/InputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <string>
#include <tokenizer/InputStream.h>

std::size_t prev_col_state = 0;

InputStream::InputStream(std::string& _source): m_Source(_source) {}

char InputStream::peek() {
Expand All @@ -15,14 +17,32 @@ char InputStream::next() {
// }

char chr = m_Source.at(Pos++);
if (chr == '\n') { Line++; Col = 0;}

if (chr == '\n') {prev_col_state = Col; Line++; Col = 0;}
else {
Col++;
}

return chr;
}

void InputStream::backoff() {
char chr = m_Source.at(--Pos);
if (chr == '\n') {
Line--; Col = prev_col_state;
} else {
Col--;
}
}

void InputStream::setReturnPoint() {
cache = {Pos, Line, Col};
}

void InputStream::restoreCache() {
std::tie(Pos, Line, Col) = cache;
}

void InputStream::reset() {
Col = Pos = 0; Line = 1;
}
Expand Down
125 changes: 99 additions & 26 deletions Swirl/src/transpiler/transpiler.cpp
Original file line number Diff line number Diff line change
@@ -1,98 +1,171 @@
#include <iostream>
#include <parser/parser.h>

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/PassManager.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/GlobalValue.h>
#include <llvm/IR/CallingConv.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/Value.h>
#include <llvm/AsmParser/Parser.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/SourceMgr.h>


extern std::string SW_OUTPUT;
extern std::vector<std::unique_ptr<Node>> ParsedModule;

llvm::LLVMContext Context;
llvm::IRBuilder<> Builder(Context);

auto LModule = std::make_unique<llvm::Module>("test", Context);
auto LModule = std::make_unique<llvm::Module>(SW_OUTPUT, Context);


std::unordered_map<std::string, llvm::Type*> type_registry = {
{"i64", llvm::Type::getInt64Ty(Context)},
{"i32", llvm::Type::getInt32Ty(Context)},
{"i128", llvm::Type::getInt128Ty(Context)},
{"float", llvm::Type::getFloatTy(Context)},
{"bool", llvm::Type::getInt1Ty(Context)},
{"void", llvm::Type::getVoidTy(Context)}
};


llvm::Value* IntLit::codegen() {
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), value, 10);
}


llvm::Value* FloatLit::codegen() {
return llvm::ConstantFP::get(llvm::Type::getFloatTy(Context), value);
}


llvm::Value* StrLit::codegen() {
return llvm::ConstantDataArray::getString(Context, value, true);
}


void printIR() {
LModule->print(llvm::outs(), nullptr);
llvm::outs().flush();
}


llvm::Value* Function::codegen() {
std::vector<llvm::Type*> param_types;
for (const auto& param : params)
param_types.push_back(type_registry[param.var_type]);

llvm::FunctionType* f_type = llvm::FunctionType::get(llvm::Type::getVoidTy(Context), param_types, false);
llvm::Function* func = llvm::Function::Create(f_type, llvm::GlobalValue::ExternalLinkage, ident, LModule.get());

llvm::BasicBlock* BB = llvm::BasicBlock::Create(Context, value, func);
Builder.SetInsertPoint(BB);

if (ident == "main") { printIR(); }
return func;
}


llvm::Value* Expression::codegen() {
std::stack<llvm::Value*> eval{};
static std::unordered_map<std::string, std::function<llvm::Value*(llvm::Value*, llvm::Value*)>> op_table = {
{"+", [](llvm::Value* a, llvm::Value* b) { return Builder.CreateAdd(a, b); }},
{"-", [](llvm::Value* a, llvm::Value* b) { return Builder.CreateSub(a, b); }},
{"*", [](llvm::Value* a, llvm::Value* b) { return Builder.CreateMul(a, b); }},
{"/",
[](llvm::Value* a, llvm::Value* b) {
static std::unordered_map<std::string, std::function<llvm::Value*(llvm::Value*, llvm::Value*)>> op_table
= {
{"+", [](llvm::Value* a, llvm::Value* b) { return Builder.CreateAdd(a, b); }},
{"-", [](llvm::Value* a, llvm::Value* b) { return Builder.CreateSub(a, b); }},
{"*", [](llvm::Value* a, llvm::Value* b) { return Builder.CreateMul(a, b); }},
{"/",
[](llvm::Value *a, llvm::Value *b) {
if (a->getType()->isIntegerTy())
a = Builder.CreateSIToFP(a, llvm::Type::getFloatTy(Context));
if (b->getType()->isIntegerTy()) {
b = Builder.CreateSIToFP(b, llvm::Type::getFloatTy(Context));
}
return Builder.CreateFDiv(a, b);
}
return Builder.CreateFDiv(a, b);
}
}
};

for (const std::unique_ptr<Node>& nd : expr) {
if (nd->getType() != ND_OP) {
std::cout << nd->getValue() << std::endl;
eval.push(nd->codegen());
continue;
}
else {
if (nd->getArity() == 2) {
std::cout << nd->getValue() << std::endl;
if (eval.size() < 2) { throw std::runtime_error("Not enough operands on eval stack"); }
llvm::Value* op2 = eval.top();
eval.pop();
llvm::Value* op1 = eval.top();
eval.pop();
eval.push(op_table[nd->getValue()](op1, op2));
}
continue;
}
}

std::cout << "expr::codegen called" << ": " << std::endl;
std::cout << "size of eval stack: " << eval.size() << std::endl;
eval.top()->print(llvm::outs());
return eval.top();
}


llvm::Value* FuncCall::codegen() {
llvm::Type* returnType = llvm::Type::getVoidTy(Context);
std::vector<llvm::Type*> paramTypes; // Empty parameter list for this example
llvm::Type* returnType = type_registry[type];
std::vector<llvm::Type*> paramTypes;
llvm::FunctionType* functionType = llvm::FunctionType::get(returnType, paramTypes, false);
llvm::Function* myFunction = llvm::Function::Create(functionType, llvm::GlobalValue::ExternalLinkage, "print", LModule.get());
llvm::Function* myFunction = llvm::Function::Create(functionType, llvm::GlobalValue::ExternalLinkage, "c", LModule.get());


llvm::Function* func = LModule->getFunction(ident);
if (!func)
throw std::runtime_error("No such function defined");

std::vector<llvm::Value*> arguments{};
for ( auto& item : args)
for ( auto& item : args) {
arguments.push_back(item.codegen());
}

llvm::Value* ret = Builder.CreateCall(func, arguments, ident);
return ret;
}


llvm::Value* Var::codegen() {
auto type_iter = type_registry.find(var_type);
if (type_iter == type_registry.end()) throw std::runtime_error("undefined type");

llvm::Value* ret;
llvm::Value* init = nullptr;

if (initialized)
init = value.codegen();

if (!parent) {
auto* var = new llvm::GlobalVariable(
*LModule, type_iter->second, is_const, llvm::GlobalVariable::InternalLinkage,
nullptr, var_ident
);

if (init) {
auto* val = llvm::dyn_cast<llvm::Constant>(init);
var->setInitializer(val);
}

ret = var;
} else {
llvm::AllocaInst* var_alloca = Builder.CreateAlloca(type_iter->second, nullptr, var_ident);
// * is_volatile is false
if (init) Builder.CreateStore(init, var_alloca);
ret = var_alloca;
}

return ret;
}

0 comments on commit 07b0578

Please sign in to comment.