Skip to content

Commit

Permalink
Println (#28)
Browse files Browse the repository at this point in the history
* factor printf out of runtime

* completely remove runtime

* fix tester

* add println

* update readme
  • Loading branch information
jackparsonss committed Jun 24, 2024
1 parent c603d0a commit 7e57934
Show file tree
Hide file tree
Showing 21 changed files with 206 additions and 66 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ set(ANTLR_NAMESPACE "fusion")
include("${CMAKE_SOURCE_DIR}/cmake/antlr_generate.cmake")
include_directories("${CMAKE_SOURCE_DIR}/include")
add_subdirectory("${CMAKE_SOURCE_DIR}/src")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/runtime")
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,19 @@ fn main(): i32 {
```

##### print
Prints the argument passed into stdout
Prints the argument passed to stdout
```
print(5);
```

##### println
Prints the argument passed to stdout with a newline at the end
```
println(100);
```
```
```

#### Arithmetic
- addition: `+`
- subtraction: `-`
Expand Down
3 changes: 2 additions & 1 deletion include/backend/builtin/print.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@

namespace builtin {
void define_all();
void define_print(std::shared_ptr<Type> type);
void define_print(TypePtr type);
void define_println(TypePtr type);
} // namespace builtin
3 changes: 2 additions & 1 deletion include/backend/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
#include "shared/type.h"

namespace io {
void print(mlir::Value, std::shared_ptr<Type>);
void printf(mlir::Value value, TypePtr type);
void println(mlir::Value value, TypePtr type);
} // namespace io
2 changes: 2 additions & 0 deletions include/shared/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ class Type {
public:
explicit Type(std::string name);
std::string get_name() const;
std::string get_specifier() const;
mlir::Type get_mlir() const;
mlir::Type get_pointer();

bool operator==(const Type rhs) const;

Expand Down
8 changes: 0 additions & 8 deletions runtime/CMakeLists.txt

This file was deleted.

12 changes: 0 additions & 12 deletions runtime/src/CMakeLists.txt

This file was deleted.

9 changes: 0 additions & 9 deletions runtime/src/io.c

This file was deleted.

2 changes: 1 addition & 1 deletion src/ast/passes/def_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void DefRef::visit_call(shared_ptr<ast::Call> node) {
}

bool DefRef::is_builtin(std::string name) {
if (name == "print") {
if (name == "print" || name == "println") {
return true;
}

Expand Down
47 changes: 35 additions & 12 deletions src/ast/symbol/symbol_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,24 @@
#include "ast/symbol/symbol_table.h"
#include "shared/context.h"

SymbolTable::SymbolTable() {
ScopePtr global_scope = make_shared<Scope>(nullptr);
this->scopes.push_back(global_scope);
current_scope = global_scope;
namespace {
shared_ptr<ast::Function> make_print(TypePtr type) {
Token* token = new antlr4::CommonToken(1);
auto body = make_shared<ast::Block>(token);

init_types();
init_builtins();
}
std::vector<shared_ptr<ast::Parameter>> params = {
make_shared<ast::Parameter>(
make_shared<ast::Variable>(ast::Qualifier::Let, type, "arg", token),
token),
};

void SymbolTable::init_types() {
define(make_shared<BuiltinTypeSymbol>(ctx::i32->get_name()));
define(make_shared<BuiltinTypeSymbol>(ctx::ch->get_name()));
std::string name = "print_" + type->get_name();
auto print =
make_shared<ast::Function>(name, name, body, type, params, token);
return print;
}

shared_ptr<ast::Function> make_print(TypePtr type) {
shared_ptr<ast::Function> make_println(TypePtr type) {
Token* token = new antlr4::CommonToken(1);
auto body = make_shared<ast::Block>(token);

Expand All @@ -30,18 +33,38 @@ shared_ptr<ast::Function> make_print(TypePtr type) {
token),
};

std::string name = "print_" + type->get_name();
std::string name = "println_" + type->get_name();
auto print =
make_shared<ast::Function>(name, name, body, type, params, token);
return print;
}
} // namespace

SymbolTable::SymbolTable() {
ScopePtr global_scope = make_shared<Scope>(nullptr);
this->scopes.push_back(global_scope);
current_scope = global_scope;

init_types();
init_builtins();
}

void SymbolTable::init_types() {
define(make_shared<BuiltinTypeSymbol>(ctx::i32->get_name()));
define(make_shared<BuiltinTypeSymbol>(ctx::ch->get_name()));
}

void SymbolTable::init_builtins() {
auto print_i32 = make_print(ctx::i32);
auto print_ch = make_print(ctx::ch);

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));
}

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

void builtin::define_all() {}
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/Block.h"

namespace {
void create_type_str(TypePtr type) {
std::string ty = type->get_specifier();
auto gvalue = mlir::StringRef(ty.c_str(), 3);

auto gtype =
mlir::LLVM::LLVMArrayType::get(ctx::ch->get_mlir(), gvalue.size());

ctx::builder->create<mlir::LLVM::GlobalOp>(
*ctx::loc, gtype, true, mlir::LLVM::Linkage::Internal, type->get_name(),
ctx::builder->getStringAttr(gvalue), 0);
}

void setupPrintf() {
auto func_type = mlir::LLVM::LLVMFunctionType::get(
ctx::i32->get_mlir(), ctx::ch->get_pointer(), true);

ctx::builder->create<mlir::LLVM::LLVMFuncOp>(*ctx::loc, "printf",
func_type);
}

void newline_type_str(TypePtr type) {
std::string ty = type->get_specifier() + "\n";
auto gvalue = mlir::StringRef(ty.c_str(), 4);

auto gtype =
mlir::LLVM::LLVMArrayType::get(ctx::ch->get_mlir(), gvalue.size());

ctx::builder->create<mlir::LLVM::GlobalOp>(
*ctx::loc, gtype, true, mlir::LLVM::Linkage::Internal,
"newline_" + type->get_name(), ctx::builder->getStringAttr(gvalue), 0);
}
} // namespace

void builtin::define_all() {
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);
}

void builtin::define_print(TypePtr type) {
auto func_type = mlir::LLVM::LLVMFunctionType::get(
ctx::none->get_mlir(), {type->get_mlir()}, false);

mlir::LLVM::LLVMFuncOp func = ctx::builder->create<mlir::LLVM::LLVMFuncOp>(
*ctx::loc, "print_" + type->get_name(), func_type);

mlir::Block* body = func.addEntryBlock();
ctx::builder->setInsertionPointToStart(body);

mlir::Value arg = func.getArgument(0);
io::printf(arg, type);

ctx::builder->create<mlir::LLVM::ReturnOp>(*ctx::loc, mlir::Value{});
ctx::builder->setInsertionPointToEnd(ctx::module->getBody());
}

void builtin::define_println(TypePtr type) {
auto func_type = mlir::LLVM::LLVMFunctionType::get(
ctx::none->get_mlir(), {type->get_mlir()}, false);

mlir::LLVM::LLVMFuncOp func = ctx::builder->create<mlir::LLVM::LLVMFuncOp>(
*ctx::loc, "println_" + type->get_name(), func_type);

mlir::Block* body = func.addEntryBlock();
ctx::builder->setInsertionPointToStart(body);

mlir::Value arg = func.getArgument(0);
io::println(arg, type);

ctx::builder->create<mlir::LLVM::ReturnOp>(*ctx::loc, mlir::Value{});
ctx::builder->setInsertionPointToEnd(ctx::module->getBody());
}
38 changes: 31 additions & 7 deletions src/backend/io.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
#include "backend/io.h"
#include <string>
#include "backend/types/integer.h"
#include "backend/utils.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "shared/context.h"

#include "mlir/Dialect/LLVMIR/FunctionCallUtils.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "shared/context.h"

void io::print(mlir::Value value, TypePtr type) {
std::string name = "print_" + type->get_name();
mlir::LLVM::LLVMFuncOp func = mlir::LLVM::lookupOrCreateFn(
*ctx::module, name, type->get_mlir(), ctx::none->get_mlir());
namespace {
void print(mlir::Value value, TypePtr type, std::string name) {
mlir::LLVM::GlobalOp global;
if (!(global = ctx::module->lookupSymbol<mlir::LLVM::GlobalOp>(name))) {
llvm::errs() << "missing format string!\n";
return;
}

mlir::Value global_ptr =
ctx::builder->create<mlir::LLVM::AddressOfOp>(*ctx::loc, global);

mlir::Value cst0 = integer::create_i32(0);
mlir::Value arg = ctx::builder->create<mlir::LLVM::GEPOp>(
*ctx::loc, ctx::ch->get_pointer(), global_ptr,
mlir::ArrayRef<mlir::Value>({cst0, cst0}));

mlir::LLVM::LLVMFuncOp func =
ctx::module->lookupSymbol<mlir::LLVM::LLVMFuncOp>("printf");
utils::call(func, {arg, value});
}
} // namespace

void io::printf(mlir::Value value, TypePtr type) {
print(value, type, type->get_name());
}

ctx::builder->create<mlir::LLVM::CallOp>(*ctx::loc, func, value);
void io::println(mlir::Value value, TypePtr type) {
print(value, type, "newline_" + type->get_name());
}
3 changes: 1 addition & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ int main(int argc, char** argv) {
std::string filename = std::string(argv[i + 1]);
backend.to_object(filename + ".o");

std::string command = "clang " + filename + ".o -o " + filename +
" -L./ -lfusert -Wl,-rpath,./";
std::string command = "clang " + filename + ".o -o " + filename;
system(command.c_str());

command = "rm " + filename + ".o";
Expand Down
20 changes: 20 additions & 0 deletions src/shared/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ std::string Type::get_name() const {
return this->name;
}

std::string Type::get_specifier() const {
if (*this == Type::ch) {
return "%c";
}

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

if (*this == Type::f32) {
return "%g";
}

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

mlir::Type Type::get_mlir() const {
if (*this == Type::ch) {
return ctx::builder->getI8Type();
Expand All @@ -40,3 +56,7 @@ mlir::Type Type::get_mlir() const {

throw std::runtime_error("invalid mlir type found");
}

mlir::Type Type::get_pointer() {
return mlir::LLVM::LLVMPointerType::get(get_mlir());
}
5 changes: 1 addition & 4 deletions tests/ci_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
"testedExecutablePaths": {
"fusion": "/__w/fusion/fusion/bin/fuse"
},
"runtimes": {
"fusion": "/__w/fusion/fusion/bin/libfusert.so"
},
"toolchains": {
"fusion": [
{
Expand All @@ -27,7 +24,7 @@
"$INPUT"
],
"output": "-",
"usesRuntime": true,
"usesRuntime": false,
"usesInStr": false,
"allowError": true
}
Expand Down
2 changes: 2 additions & 0 deletions tests/input/builtin/character.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ fn main(): i32 {
print(x);
print('\n');

println('z');

return 0;
}
2 changes: 2 additions & 0 deletions tests/input/builtin/integer.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
fn main(): i32 {
let x: i32 = 100;
print(5);
println(x);

return 0;
}
7 changes: 6 additions & 1 deletion tests/lli-temp.out
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
90
8
5
1
6
2
0
1 change: 1 addition & 0 deletions tests/output/builtin/character.out
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
a
z
2 changes: 1 addition & 1 deletion tests/output/builtin/integer.out
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5
5100
Loading

0 comments on commit 7e57934

Please sign in to comment.