Skip to content

Commit

Permalink
Booleans (#30)
Browse files Browse the repository at this point in the history
* grammar, node, builder

* refactor to make primitive types easier

* implement backend
  • Loading branch information
jackparsonss committed Jun 25, 2024
1 parent 7e57934 commit 40d6c63
Show file tree
Hide file tree
Showing 23 changed files with 141 additions and 34 deletions.
9 changes: 8 additions & 1 deletion grammar/Fusion.g4
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ expr
| expr (op=PLUS | op=MINUS) expr #addSub
| expr (op=GT | op=LT | op=GE | op=LE) expr #gtLtCond
| expr (op=EQ | op=NE) expr #eqNeCond
| BOOLEAN #literalBool
| CHARACTER #literalChar
| INT #literalInt
| ID #identifier
;

qualifier: CONST | LET;

type: I32 | CHAR;
type
: I32
| CHAR
| BOOL
;

// keywords
RETURN: 'return';
Expand Down Expand Up @@ -76,8 +81,10 @@ COMMENT: '/*' .*? '*/' -> skip;
// types
I32: 'i32';
CHAR: 'ch';
BOOL: 'bool';

// literals
BOOLEAN: ('true' | 'false');
INT: [0-9]+;
ID: [a-zA-Z_][a-zA-Z0-9_]*;
CHARACTER: '\'' ( '\\\\' | '\\0' | '\\a' | '\\b' | '\\t' | '\\n' | '\\r' | '\\"' | '\\\'' | ~[\\'] ) '\'';
Expand Down
11 changes: 11 additions & 0 deletions include/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ class CharacterLiteral : public Expression {
void xml(int level) override;
};

class BooleanLiteral : public Expression {
private:
bool value;

public:
explicit BooleanLiteral(bool value, Token* token);
bool get_value() const;

void xml(int level) override;
};

class Variable : public Expression {
private:
std::string name;
Expand Down
1 change: 1 addition & 0 deletions include/ast/builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Builder : public FusionBaseVisitor {
std::any visitStatement(FusionParser::StatementContext* ctx) override;
std::any visitLiteralInt(FusionParser::LiteralIntContext* ctx) override;
std::any visitLiteralChar(FusionParser::LiteralCharContext* ctx) override;
std::any visitLiteralBool(FusionParser::LiteralBoolContext* ctx) override;
std::any visitDeclaration(FusionParser::DeclarationContext* ctx) override;
std::any visitType(FusionParser::TypeContext* ctx) override;
std::any visitQualifier(FusionParser::QualifierContext* ctx) override;
Expand Down
6 changes: 3 additions & 3 deletions include/ast/symbol/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ using std::shared_ptr;
class Symbol {
private:
std::string name;
shared_ptr<Type> type;
TypePtr type;

public:
virtual std::string get_name();
virtual shared_ptr<Type> get_type();
virtual TypePtr get_type();

Symbol(std::string name);
Symbol(std::string name, shared_ptr<Type> type);
Symbol(std::string name, TypePtr type);
};

typedef shared_ptr<Symbol> SymbolPtr;
Expand Down
3 changes: 2 additions & 1 deletion include/backend/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ class Backend {
shared_ptr<ast::Block> traverse();
mlir::Value visit_block(shared_ptr<ast::Block>);
mlir::Value visit_integer_literal(shared_ptr<ast::IntegerLiteral>);
mlir::Value visit_character_literal(shared_ptr<ast::CharacterLiteral>);
mlir::Value visit_boolean_literal(shared_ptr<ast::BooleanLiteral>);
mlir::Value visit_variable(shared_ptr<ast::Variable>);
mlir::Value visit_declaration(shared_ptr<ast::Declaration>);
mlir::Value visit_function(shared_ptr<ast::Function>);
mlir::Value visit_call(shared_ptr<ast::Call>);
mlir::Value visit_parameter(shared_ptr<ast::Parameter>);
mlir::Value visit_return(shared_ptr<ast::Return>);
mlir::Value visit_character_literal(shared_ptr<ast::CharacterLiteral>);
mlir::Value visit_binary_operator(shared_ptr<ast::BinaryOperator>);
};
5 changes: 5 additions & 0 deletions include/backend/builtin/builtin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

namespace builtin {
void define_all();
}
2 changes: 1 addition & 1 deletion include/backend/builtin/print.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "shared/type.h"

namespace builtin {
void define_all();
void define_all_print();
void define_print(TypePtr type);
void define_println(TypePtr type);
} // namespace builtin
7 changes: 7 additions & 0 deletions include/backend/types/boolean.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include "mlir/IR/Value.h"

namespace boolean {
mlir::Value create_bool(bool value);
} // namespace boolean
11 changes: 7 additions & 4 deletions include/shared/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ extern unique_ptr<mlir::ModuleOp> module;
extern shared_ptr<mlir::OpBuilder> builder;
extern mlir::MLIRContext context;

extern shared_ptr<Type> ch;
extern shared_ptr<Type> i32;
extern shared_ptr<Type> f32;
extern shared_ptr<Type> none;
extern TypePtr ch;
extern TypePtr i32;
extern TypePtr f32;
extern TypePtr none;
extern TypePtr t_bool;

extern std::vector<TypePtr> primitives;

extern void initialize_context();
} // namespace ctx
1 change: 1 addition & 0 deletions include/shared/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Type {
static const Type f32;
static const Type none;
static const Type unset;
static const Type t_bool;
};

typedef std::shared_ptr<Type> TypePtr;
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ set(
"${CMAKE_CURRENT_SOURCE_DIR}/backend/utils.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/backend/types/integer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/backend/types/character.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/backend/types/boolean.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/backend/builtin/builtin.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/backend/builtin/print.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/backend/expressions/arithmetic.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ast/builder.cpp"
Expand Down
15 changes: 15 additions & 0 deletions src/ast/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ TypePtr ast::Expression::get_type() const {
return this->type;
}

ast::BooleanLiteral::BooleanLiteral(bool value, Token* token)
: Expression(ctx::t_bool, token) {
this->value = value;
}

bool ast::BooleanLiteral::get_value() const {
return this->value;
}

void ast::BooleanLiteral::xml(int level) {
std::string s = value ? "true" : "false";
std::cout << std::string(level * 4, ' ') << "<bool value=\"" << s
<< "\"/>\n";
}

ast::CharacterLiteral::CharacterLiteral(char value, Token* token)
: Expression(ctx::ch, token) {
this->value = value;
Expand Down
11 changes: 11 additions & 0 deletions src/ast/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ std::any Builder::visitLiteralInt(FusionParser::LiteralIntContext* ctx) {
return to_node(node);
}

std::any Builder::visitLiteralBool(FusionParser::LiteralBoolContext* ctx) {
Token* token = ctx->BOOLEAN()->getSymbol();
bool value = true;
if (ctx->BOOLEAN()->getText() == "false") {
value = false;
}

auto node = make_shared<ast::BooleanLiteral>(value, token);
return to_node(node);
}

std::any Builder::visitLiteralChar(FusionParser::LiteralCharContext* ctx) {
std::unordered_map<std::string, char> special_characters = {
{"\\0", '\0'}, {"\\a", '\a'}, {"\\b", '\b'},
Expand Down
20 changes: 9 additions & 11 deletions src/ast/symbol/symbol_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,19 @@ SymbolTable::SymbolTable() {
}

void SymbolTable::init_types() {
define(make_shared<BuiltinTypeSymbol>(ctx::i32->get_name()));
define(make_shared<BuiltinTypeSymbol>(ctx::ch->get_name()));
for (const auto& ty : ctx::primitives) {
define(make_shared<BuiltinTypeSymbol>(ty->get_name()));
}
}

void SymbolTable::init_builtins() {
auto print_i32 = make_print(ctx::i32);
auto print_ch = make_print(ctx::ch);
for (const auto& ty : ctx::primitives) {
auto print = make_print(ty);
auto println = make_println(ty);

auto println_i32 = make_println(ctx::i32);
auto println_ch = make_println(ctx::ch);

define(make_shared<FunctionSymbol>(print_i32, this->current_scope));
define(make_shared<FunctionSymbol>(print_ch, this->current_scope));
define(make_shared<FunctionSymbol>(println_i32, this->current_scope));
define(make_shared<FunctionSymbol>(println_ch, this->current_scope));
define(make_shared<FunctionSymbol>(print, this->current_scope));
define(make_shared<FunctionSymbol>(println, this->current_scope));
}
}

void SymbolTable::push() {
Expand Down
2 changes: 1 addition & 1 deletion src/backend/backend.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "backend/backend.h"
#include "backend/builtin/print.h"
#include "backend/builtin/builtin.h"
#include "shared/context.h"

#include "llvm/IR/LegacyPassManager.h"
Expand Down
6 changes: 6 additions & 0 deletions src/backend/builtin/builtin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "backend/builtin/builtin.h"
#include "backend/builtin/print.h"

void builtin::define_all() {
define_all_print();
}
19 changes: 7 additions & 12 deletions src/backend/builtin/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,15 @@ void newline_type_str(TypePtr type) {
}
} // namespace

void builtin::define_all() {
void builtin::define_all_print() {
setupPrintf();

create_type_str(ctx::i32);
create_type_str(ctx::ch);

newline_type_str(ctx::i32);
newline_type_str(ctx::ch);

define_print(ctx::i32);
define_print(ctx::ch);

define_println(ctx::i32);
define_println(ctx::ch);
for (const auto& ty : ctx::primitives) {
create_type_str(ty);
newline_type_str(ty);
define_print(ty);
define_println(ty);
}
}

void builtin::define_print(TypePtr type) {
Expand Down
9 changes: 9 additions & 0 deletions src/backend/types/boolean.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "backend/types/boolean.h"
#include "shared/context.h"

mlir::Value boolean::create_bool(bool value) {
mlir::Value val = ctx::builder->create<mlir::LLVM::ConstantOp>(
*ctx::loc, ctx::t_bool->get_mlir(), value);

return val;
}
7 changes: 7 additions & 0 deletions src/backend/visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "ast/ast.h"
#include "backend/backend.h"
#include "backend/expressions/arithmetic.h"
#include "backend/types/boolean.h"
#include "backend/types/character.h"
#include "backend/types/integer.h"
#include "backend/utils.h"
Expand All @@ -21,6 +22,7 @@ mlir::Value Backend::visit(shared_ptr<ast::Node> node) {
try_visit(node, ast::Block, this->visit_block);
try_visit(node, ast::IntegerLiteral, this->visit_integer_literal);
try_visit(node, ast::CharacterLiteral, this->visit_character_literal);
try_visit(node, ast::BooleanLiteral, this->visit_boolean_literal);
try_visit(node, ast::Variable, this->visit_variable);
try_visit(node, ast::Declaration, this->visit_declaration);
try_visit(node, ast::Function, this->visit_function);
Expand Down Expand Up @@ -50,6 +52,11 @@ mlir::Value Backend::visit_character_literal(
return character::create_ch(node->get_value());
}

mlir::Value Backend::visit_boolean_literal(
shared_ptr<ast::BooleanLiteral> node) {
return boolean::create_bool(node->get_value());
}

mlir::Value Backend::visit_variable(shared_ptr<ast::Variable> node) {
auto pair = variables.find(node->get_ref_name());
if (pair == variables.end()) {
Expand Down
12 changes: 12 additions & 0 deletions src/shared/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ TypePtr ctx::ch;
TypePtr ctx::i32;
TypePtr ctx::f32;
TypePtr ctx::none;
TypePtr ctx::t_bool;

std::vector<TypePtr> ctx::primitives;

void ctx::initialize_context() {
context.loadDialect<mlir::LLVM::LLVMDialect>();
Expand All @@ -19,6 +22,15 @@ void ctx::initialize_context() {
ctx::i32 = std::make_shared<Type>(Type::i32);
ctx::f32 = std::make_shared<Type>(Type::f32);
ctx::none = std::make_shared<Type>(Type::none);
ctx::t_bool = std::make_shared<Type>(Type::t_bool);

ctx::primitives = {
ctx::ch,
ctx::i32,
ctx::f32,
ctx::t_bool,
};

module = std::make_unique<mlir::ModuleOp>(
mlir::ModuleOp::create(builder->getUnknownLoc()));
}
9 changes: 9 additions & 0 deletions src/shared/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const Type Type::i32 = Type("i32");
const Type Type::f32 = Type("f32");
const Type Type::none = Type("none");
const Type Type::unset = Type("unset");
const Type Type::t_bool = Type("bool");

Type::Type(std::string name) {
this->name = name;
Expand All @@ -34,6 +35,10 @@ std::string Type::get_specifier() const {
return "%g";
}

if (*this == Type::t_bool) {
return "%d";
}

throw std::runtime_error("type is not printable");
}

Expand All @@ -50,6 +55,10 @@ mlir::Type Type::get_mlir() const {
return ctx::builder->getF32Type();
}

if (*this == Type::t_bool) {
return ctx::builder->getI1Type();
}

if (*this == Type::none) {
return mlir::LLVM::LLVMVoidType::get(&ctx::context);
}
Expand Down
5 changes: 5 additions & 0 deletions tests/input/declaration/basic.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@ fn main(): i32 {
print(z);
print(w);

let t: bool = true;
let f: bool = false;
println(t);
println(f);

return 0;
}
2 changes: 2 additions & 0 deletions tests/output/declaration/basic.out
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
55a
1
0

0 comments on commit 40d6c63

Please sign in to comment.