Skip to content

Commit

Permalink
Added syntax for user-written continuations
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugobros3 committed Jun 20, 2024
1 parent 7598431 commit ad84ee2
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 12 deletions.
11 changes: 11 additions & 0 deletions include/artic/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,17 @@ struct TypeApp : public Type {
void print(Printer&) const override;
};

/// The codomain of functions that don't return anything.
struct NoCodomType : public Type {
NoCodomType(const Loc& loc)
: Type(loc)
{}

const artic::Type* infer(TypeChecker&) override;
void bind(NameBinder&) override;
void print(Printer&) const override;
};

/// Type resulting from a parsing error.
struct ErrorType : public Type {
ErrorType(const Loc& loc)
Expand Down
2 changes: 2 additions & 0 deletions src/bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ void TypeApp::bind(NameBinder& binder) {
binder.bind(path);
}

void NoCodomType::bind(NameBinder&) {}

void ErrorType::bind(NameBinder&) {}

// Statements ----------------------------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions src/check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,8 @@ const artic::Type* UnsizedArrayType::infer(TypeChecker& checker) {
}

const artic::Type* FnType::infer(TypeChecker& checker) {
if (to->isa<ast::NoCodomType>())
return checker.type_table.cn_type(checker.infer(*from));
return checker.type_table.fn_type(checker.infer(*from), checker.infer(*to));
}

Expand All @@ -869,6 +871,10 @@ const artic::Type* TypeApp::infer(TypeChecker& checker) {
return path.type = path.infer(checker, false);
}

const artic::Type* NoCodomType::infer(TypeChecker& checker) {
return checker.type_table.no_ret_type();
}

// Statements ----------------------------------------------------------------------

const artic::Type* DeclStmt::infer(TypeChecker& checker) {
Expand Down
10 changes: 5 additions & 5 deletions src/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1658,7 +1658,7 @@ const thorin::Def* StaticDecl::emit(Emitter& emitter) const {

const thorin::Def* FnDecl::emit(Emitter& emitter) const {
auto _ = emitter.save_state();
const thorin::FnType* cont_type = nullptr;
const artic::FnType* fn_type = nullptr;
Emitter::MonoFn mono_fn { this, {} };
if (type_params) {
for (auto& param : type_params->params)
Expand All @@ -1667,12 +1667,12 @@ const thorin::Def* FnDecl::emit(Emitter& emitter) const {
if (auto it = emitter.mono_fns.find(mono_fn); it != emitter.mono_fns.end())
return it->second;
emitter.poly_defs.emplace_back();
cont_type = type->as<artic::ForallType>()->body->convert(emitter)->as<thorin::FnType>();
fn_type = type->as<artic::ForallType>()->body->as<artic::FnType>();
} else {
cont_type = type->convert(emitter)->as<thorin::FnType>();
fn_type = type->as<artic::FnType>();
}

auto cont = emitter.world.continuation(cont_type, emitter.debug_info(*this));
auto cont = emitter.world.continuation(fn_type->convert(emitter)->as<thorin::FnType>(), emitter.debug_info(*this));
if (type_params)
emitter.mono_fns.emplace(std::move(mono_fn), cont);

Expand Down Expand Up @@ -1715,7 +1715,7 @@ const thorin::Def* FnDecl::emit(Emitter& emitter) const {
fn->def = def = cont;

emitter.enter(cont);
emitter.emit(*fn->param, emitter.tuple_from_params(cont, true));
emitter.emit(*fn->param, emitter.tuple_from_params(cont, !fn_type->codom->isa<artic::NoRetType>()));
if (fn->filter)
cont->set_filter(emitter.world.filter(thorin::Array<const thorin::Def*>(cont->num_params(), emitter.emit(*fn->filter))));
auto value = emitter.emit(*fn->body);
Expand Down
14 changes: 11 additions & 3 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ Ptr<ast::FnDecl> Parser::parse_fn_decl() {
error(ahead().loc(), "parameter list expected in function definition");

Ptr<ast::Type> ret_type;
if (accept(Token::Arrow))
ret_type = parse_type();
if (accept(Token::Arrow)) {
if (accept(Token::Not))
ret_type = make_ptr<ast::NoCodomType>(prev_);
else
ret_type = parse_type();
}

Ptr<ast::Expr> body;
if (ahead().tag() == Token::LBrace)
Expand Down Expand Up @@ -1085,7 +1089,11 @@ Ptr<ast::FnType> Parser::parse_fn_type() {
else
from = parse_error_type();
expect(Token::Arrow);
auto to = parse_type();
Ptr<ast::Type> to;
if (accept(Token::Not))
to = make_ptr<ast::NoCodomType>(prev_);
else
to = parse_type();
return make_ptr<ast::FnType>(tracker(), std::move(from), std::move(to));
}

Expand Down
10 changes: 6 additions & 4 deletions src/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,10 +659,8 @@ void UnsizedArrayType::print(Printer& p) const {
void FnType::print(Printer& p) const {
p << log::keyword_style("fn") << ' ';
print_parens(p, from);
if (to) {
p << " -> ";
to->print(p);
}
p << " -> ";
to->print(p);
}

void PtrType::print(Printer& p) const {
Expand All @@ -682,6 +680,10 @@ void TypeApp::print(Printer& p) const {
path.print(p);
}

void NoCodomType::print(artic::Printer& p) const {
p << "!";
}

void ErrorType::print(Printer& p) const {
p << log::error_style("<invalid type>");
}
Expand Down

0 comments on commit ad84ee2

Please sign in to comment.