Skip to content

Commit

Permalink
add(backend): codegen for Expression
Browse files Browse the repository at this point in the history
  • Loading branch information
nullptr0x committed Nov 14, 2023
1 parent 195d837 commit 298bdd4
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
7 changes: 4 additions & 3 deletions Swirl/include/parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ struct Node {

std::string value;

const virtual std::vector<std::unique_ptr<Node>>& getExprValue() { throw std::runtime_error("getExprValue called on Node instance"); }
virtual const std::vector<std::unique_ptr<Node>>& getExprValue() { throw std::runtime_error("getExprValue called on Node instance"); }
virtual Param getParamInstance() { return Param{}; }
virtual std::string getValue() const { throw std::runtime_error("getValue called on base node"); };
virtual NodeType getType() const { throw std::runtime_error("getType called on base node"); };
virtual std::vector<Param> getParams() const { throw std::runtime_error("getParams called on base getParams"); };
virtual llvm::Value* codegen() { throw std::runtime_error("unimplemented Node::codegen"); }
virtual int8_t getArity() { throw std::runtime_error("getArity called on base Node instance "); }
};


struct Op: Node {
std::string value;

// the value will be 3 bytes at max so no need of a reference
int8_t arity = 2; // the no. of operands the operator requires, binary by default

Op() = default;
explicit Op(std::string val): value(std::move(val)) {}
Expand All @@ -56,6 +56,7 @@ struct Op: Node {
return value;
}

int8_t getArity() override { return arity; }
[[nodiscard]] NodeType getType() const override {
return ND_OP;
}
Expand Down
34 changes: 32 additions & 2 deletions Swirl/src/transpiler/transpiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


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

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

Expand All @@ -34,8 +34,38 @@ llvm::Value* StrLit::codegen() {
}

llvm::Value* Expression::codegen() {
// TODO: support for unary operators
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) {
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);
}
}
}
};

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

eval.push(op_table[nd->getValue()](op1, op2));
}
}
}
}

llvm::Value* FuncCall::codegen() {
Expand Down

0 comments on commit 298bdd4

Please sign in to comment.