Parse binary operators
This commit is contained in:
parent
4d307d0eb9
commit
78816dff10
41
src/ast.cpp
41
src/ast.cpp
@ -3,6 +3,37 @@
|
||||
#include <sstream>
|
||||
|
||||
namespace AST {
|
||||
int operator_precedence(BinOp& op) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string format_operator(BinOp& op) {
|
||||
switch (op) {
|
||||
case BinOp::Assignment:
|
||||
return "=";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
}
|
||||
|
||||
std::string IntLiteralExpression::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
out << this->m_value;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string ValueReferenceExpression::formatted() {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
std::string BinaryOperationExpression::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
out << this->m_lhs->formatted();
|
||||
out << " " << format_operator(this->m_binop) << " ";
|
||||
out << this->m_rhs->formatted();
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string ExpressionStatement::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
out << this->m_expr->formatted();
|
||||
@ -28,16 +59,6 @@ namespace AST {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string IntLiteralExpression::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
out << this->m_value;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string ValueReferenceExpression::formatted() {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
std::string Function::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
out << this->m_name;
|
||||
|
||||
21
src/ast.h
21
src/ast.h
@ -8,6 +8,13 @@
|
||||
#include <memory>
|
||||
|
||||
namespace AST {
|
||||
enum class BinOp {
|
||||
Assignment,
|
||||
};
|
||||
|
||||
int operator_precedence(BinOp& op);
|
||||
std::string format_operator(BinOp& op);
|
||||
|
||||
class Node {
|
||||
public:
|
||||
virtual std::string formatted() = 0;
|
||||
@ -51,6 +58,20 @@ namespace AST {
|
||||
virtual llvm::Value* codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
||||
};
|
||||
|
||||
class BinaryOperationExpression : public Expression {
|
||||
private:
|
||||
std::unique_ptr<Expression> m_lhs;
|
||||
BinOp m_binop;
|
||||
std::unique_ptr<Expression> m_rhs;
|
||||
public:
|
||||
BinaryOperationExpression(std::unique_ptr<Expression> lhs, BinOp op, std::unique_ptr<Expression> rhs)
|
||||
: m_lhs{ std::move(lhs) }, m_binop{ op }, m_rhs{ std::move(rhs) } {
|
||||
}
|
||||
virtual ~BinaryOperationExpression() override = default;
|
||||
virtual std::string formatted() override;
|
||||
virtual llvm::Value* codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
||||
};
|
||||
|
||||
|
||||
class ReturnStatement : public Statement {
|
||||
private:
|
||||
|
||||
@ -22,6 +22,11 @@ namespace AST {
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value* BinaryOperationExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||
auto ty = builder.builder->getInt32Ty();
|
||||
return llvm::ConstantInt::get(ty, 0);
|
||||
}
|
||||
|
||||
void ReturnStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||
if (!builder.block)
|
||||
return;
|
||||
|
||||
@ -18,7 +18,7 @@ namespace parsing {
|
||||
}
|
||||
}
|
||||
|
||||
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream) {
|
||||
Result<std::unique_ptr<AST::Expression>, std::string> parse_primary_expression(token::TokenStream& stream) {
|
||||
token::TokenStream inner{ stream };
|
||||
try {
|
||||
auto token = inner.next();
|
||||
@ -43,6 +43,58 @@ namespace parsing {
|
||||
}
|
||||
}
|
||||
|
||||
Result<AST::BinOp, std::string> parse_binop(token::TokenStream& stream) {
|
||||
token::TokenStream inner{ stream };
|
||||
try {
|
||||
auto token = inner.next();
|
||||
if (token.type != token::Type::Symbol) {
|
||||
throw std::runtime_error("Expected binop");
|
||||
}
|
||||
if (token.content == "=") {
|
||||
stream.m_position = inner.m_position;
|
||||
return new AST::BinOp{ AST::BinOp::Assignment };
|
||||
}
|
||||
|
||||
throw std::runtime_error("Expected binop");
|
||||
}
|
||||
catch (std::runtime_error error) {
|
||||
return new std::string{ error.what() };
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<AST::Expression> parse_rhs(
|
||||
token::TokenStream& stream, std::unique_ptr<AST::Expression> lhs, int prev_precedence) {
|
||||
|
||||
auto binop_res = parse_binop(stream);
|
||||
while (binop_res.ok()) {
|
||||
auto binop = binop_res.unwrap();
|
||||
auto rhs = parse_primary_expression(stream).unwrap();
|
||||
|
||||
if (AST::operator_precedence(binop) > prev_precedence) {
|
||||
rhs = parse_rhs(stream, std::move(rhs), AST::operator_precedence(binop));
|
||||
}
|
||||
|
||||
auto binop_expr = new AST::BinaryOperationExpression{ std::move(lhs), binop, std::move(rhs) };
|
||||
lhs = std::unique_ptr<AST::Expression>{ binop_expr };
|
||||
|
||||
binop_res = parse_binop(stream);
|
||||
}
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream) {
|
||||
try {
|
||||
auto lhs = parse_primary_expression(stream).unwrap();
|
||||
return new std::unique_ptr{ parse_rhs(stream, std::move(lhs), 0) };
|
||||
}
|
||||
catch (std::runtime_error error) {
|
||||
return new std::string{ error.what() };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Result<std::unique_ptr<AST::InitializationStatement>, std::string> parse_init_statement(token::TokenStream& stream) {
|
||||
token::TokenStream inner{ stream };
|
||||
try {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user