Skip to content

Commit

Permalink
make .where truly upside down
Browse files Browse the repository at this point in the history
* better error messages
  • Loading branch information
leissa committed Apr 25, 2024
1 parent 2ce91c0 commit c9de8cf
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 22 deletions.
8 changes: 4 additions & 4 deletions include/thorin/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,14 +344,14 @@ class BlockExpr : public Expr {
/// `decls e` or `e .where decls` if @p where is `true`.
class DeclExpr : public Expr {
public:
DeclExpr(Loc loc, Ptrs<ValDecl>&& decls, Ptr<Expr>&& expr, bool where)
DeclExpr(Loc loc, Ptrs<ValDecl>&& decls, Ptr<Expr>&& expr, bool is_where)
: Expr(loc)
, decls_(std::move(decls))
, expr_(std::move(expr))
, where_(where) {}
, is_where_(is_where) {}

const auto& decls() const { return decls_; }
bool where() const { return where_; }
bool is_where() const { return is_where_; }
const Expr* expr() const { return expr_.get(); }

void bind(Scopes&) const override;
Expand All @@ -362,7 +362,7 @@ class DeclExpr : public Expr {

Ptrs<ValDecl> decls_;
Ptr<Expr> expr_;
bool where_;
bool is_where_;
};

/// `.Type level`
Expand Down
29 changes: 14 additions & 15 deletions lit/regex/match_manual.thorin
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@
.con .extern main[mem: %mem.M, argc: .I32, argv: %mem.Ptr («⊤:.Nat; %mem.Ptr («⊤:.Nat; .I8», 0)», 0), exit : .Cn [%mem.M, .I32]] =
(exit, match_argument) # (%core.icmp.ug (argc, 1I32)) (mem, 0I32)
.where
.con error(mem: %mem.M, i : .I32) =
reject (mem, 0I32)
.where
.con reject[mem: %mem.M, .Idx Top] = exit (mem, 0I32);
.end
.con match_argument[mem: %mem.M, .I32] =
.let arg1 = %mem.lea (Top, ‹Top; %mem.Ptr («⊤:.Nat; .I8», 0)›, 0) (argv, 1I32);
.let (`mem, to_match) = %mem.load (mem, arg1);
Expand All @@ -45,10 +40,6 @@
.let is_end = %core.icmp.e (c, '\0');
(not_end, error)#is_end (mem, new_i)
.where
.con not_a(mem: %mem.M, i: .I32) =
.let is_match_b = %core.icmp.e (c, 'b');
(error, state1)#is_match_b (mem, i);

.con not_end(mem: %mem.M, i: .I32) =
.let is_match_a = %core.icmp.e (c, 'a');
(not_a, state2)#is_match_a (mem, i)
Expand All @@ -60,22 +51,30 @@
.let is_end = %core.icmp.e (c, '\0');
(not_end, accept)#is_end (mem, new_i)
.where
.con not_a(mem: %mem.M, i: .I32) =
.let is_match_b = %core.icmp.e (c, 'b');
(error, state1)#is_match_b (mem, i);

.con not_end(mem: %mem.M, i: .I32) =
.let is_match_a = %core.icmp.e (c, 'a');
(not_a, state2)#is_match_a (mem, i);

.con accept[mem: %mem.M, .I32] =
exit (mem, 1I32);

.con not_a(mem: %mem.M, i: .I32) =
.let is_match_b = %core.icmp.e (c, 'b');
(error, state1)#is_match_b (mem, i);
.end
.end
.end;
.con not_a(mem: %mem.M, i: .I32) =
.let is_match_b = %core.icmp.e (c, 'b');
(error, state1)#is_match_b (mem, i);
.end
.end
.end
.end
.end;
.con error(mem: %mem.M, i : .I32) =
reject (mem, 0I32)
.where
.con reject[mem: %mem.M, .Idx Top] = exit (mem, 0I32);
.end;
.end

// CHECK-NOT: %regex.
5 changes: 4 additions & 1 deletion src/thorin/ast/bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ void LitExpr::bind(Scopes& s) const {
}

void DeclExpr::bind(Scopes& s) const {
for (const auto& decl : decls()) decl->bind(s);
if (is_where())
for (const auto& decl : decls() | std::ranges::views::reverse) decl->bind(s);
else
for (const auto& decl : decls()) decl->bind(s);
expr()->bind(s);
}

Expand Down
5 changes: 4 additions & 1 deletion src/thorin/ast/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ Ref LitExpr::emit_(Emitter& e) const {
}

Ref DeclExpr::emit_(Emitter& e) const {
for (const auto& decl : decls()) decl->emit(e);
if (is_where())
for (const auto& decl : decls() | std::ranges::views::reverse) decl->emit(e);
else
for (const auto& decl : decls()) decl->emit(e);
return expr()->emit(e);
}

Expand Down
5 changes: 5 additions & 0 deletions src/thorin/ast/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,12 @@ Ptr<Expr> Parser::parse_infix_expr(Tracker track, Ptr<Expr>&& lhs, Prec curr_pre
lex();
auto decls = parse_decls();
lhs = ptr<DeclExpr>(track, std::move(decls), std::move(lhs), true);

bool where = ahead().tag() == Tag::K_where;
expect(Tag::K_end, "end of a .where declaration block");
if (where)
ast().note(lhs->loc().anew_finis(),
"did you accidentally end your declaration expression with a ';'?");
return lhs;
}
default: return lhs;
Expand Down
2 changes: 1 addition & 1 deletion src/thorin/ast/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ std::ostream& LitExpr::stream(Tab& tab, std::ostream& os) const {
}

std::ostream& DeclExpr::stream(Tab& tab, std::ostream& os) const {
if (where()) {
if (is_where()) {
tab.println(os, "{} .where", S(tab, expr()));
++tab;
for (const auto& decl : decls()) tab.println(os, "{}", S(tab, decl.get()));
Expand Down

0 comments on commit c9de8cf

Please sign in to comment.