Skip to content

Commit

Permalink
use proper alias pattern instead of [...]::id
Browse files Browse the repository at this point in the history
  • Loading branch information
leissa committed Nov 2, 2024
1 parent 8c5b3f3 commit 8df09f8
Show file tree
Hide file tree
Showing 17 changed files with 193 additions and 143 deletions.
8 changes: 5 additions & 3 deletions docs/langref.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,12 @@ Tuple patterns allow for _groups_:
- `(a b c: Nat, d e: Bool)` means `(a: Nat, b: Nat, c: Nat, d: Bool, e: Bool)`.
- `[a b c: Nat, d e: Bool]` means `[a: Nat, b: Nat, c: Nat, d: Bool, e: Bool]`.

You can introduce an optional name for the whole tuple pattern:
#### Alias Pattern

You can wrap a pattern into an *alias pattern*:

```rust
let abc::(a, b, c) = (1, 2, 3);
let (a, b, c) as abc = (1, 2, 3);
```

This will bind
Expand All @@ -236,7 +238,7 @@ This will bind
Here is another example:

```rust
{T: *, as: Nat}::Tas [%mem.M, %mem.Ptr Tas] → [%mem.M, T]
{T: *, a: Nat} as Ts [%mem.M, %mem.Ptr Ts] → [%mem.M, T]
```

#### Rebind
Expand Down
77 changes: 58 additions & 19 deletions include/mim/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ class Expr : public Node {
: Node(loc) {}

public:
/// @name Precedence
///@{
enum class Prec {
Err,
Bot,
Where,
Arrow,
Pi,
App,
Extract,
Lit,
};

static constexpr bool is_rassoc(Prec p) { return p == Prec::Arrow; }
///@}

Ref emit(Emitter&) const;
virtual void bind(Scopes&) const = 0;
virtual Ref emit_decl(Emitter&, Ref /*type*/) const { fe::unreachable(); }
Expand Down Expand Up @@ -170,32 +186,26 @@ class ValDecl : public Decl {

class Ptrn : public Decl {
public:
Ptrn(Loc loc, Dbg dbg)
: Decl(loc)
, dbg_(dbg) {}
Ptrn(Loc loc)
: Decl(loc) {}

Dbg dbg() const { return dbg_; }
virtual bool implicit() const { return false; }

virtual void bind(Scopes&, bool rebind, bool quiet) const = 0;
Ref emit_value(Emitter&, Ref) const;
virtual Ref emit_type(Emitter&) const = 0;
virtual Ref emit_value(Emitter&, Ref) const = 0;
virtual Ref emit_type(Emitter&) const = 0;

[[nodiscard]] static Ptr<Expr> to_expr(AST&, Ptr<Ptrn>&&);
[[nodiscard]] static Ptr<Ptrn> to_ptrn(Ptr<Expr>&&);

private:
virtual void emit_value_(Emitter&, Ref) const {}

Dbg dbg_;
};

class ErrorPtrn : public Ptrn {
public:
ErrorPtrn(Loc loc)
: Ptrn(loc, Dbg()) {}
: Ptrn(loc) {}

void bind(Scopes&, bool rebind, bool quiet) const override;
Ref emit_value(Emitter&, Ref) const override;
Ref emit_type(Emitter&) const override;
std::ostream& stream(Tab&, std::ostream&) const override;
};
Expand All @@ -204,9 +214,11 @@ class ErrorPtrn : public Ptrn {
class IdPtrn : public Ptrn {
public:
IdPtrn(Loc loc, Dbg dbg, Ptr<Expr>&& type)
: Ptrn(loc, dbg)
: Ptrn(loc)
, dbg_(dbg)
, type_(std::move(type)) {}

Dbg dbg() const { return dbg_; }
const Expr* type() const { return type_.get(); }

static Ptr<IdPtrn> mk_type(AST& ast, Ptr<Expr>&& type) {
Expand All @@ -219,35 +231,63 @@ class IdPtrn : public Ptrn {
}

void bind(Scopes&, bool rebind, bool quiet) const override;
Ref emit_value(Emitter&, Ref) const override;
Ref emit_type(Emitter&) const override;
std::ostream& stream(Tab&, std::ostream&) const override;

private:
Dbg dbg_;
Ptr<Expr> type_;
};

/// `dbg_0 ... dbg_n-2 id` where `id` = `dbg_n-1: type`
class GrpPtrn : public Ptrn {
public:
GrpPtrn(Dbg dbg, const IdPtrn* id)
: Ptrn(dbg.loc(), dbg)
: Ptrn(dbg.loc())
, dbg_(dbg)
, id_(id) {}

Dbg dbg() const { return dbg_; }
const IdPtrn* id() const { return id_; }

void bind(Scopes&, bool rebind, bool quiet) const override;
Ref emit_value(Emitter&, Ref) const override;
Ref emit_type(Emitter&) const override;
std::ostream& stream(Tab&, std::ostream&) const override;

private:
Dbg dbg_;
const IdPtrn* id_;
};

/// `dbg::(ptrn_0, ..., ptrn_n-1)` or `dbg::[ptrn_0, ..., ptrn_n-1]`
/// `ptrn as id`
class AliasPtrn : public Ptrn {
public:
AliasPtrn(Loc loc, Ptr<Ptrn>&& ptrn, Dbg dbg)
: Ptrn(loc)
, ptrn_(std::move(ptrn))
, dbg_(dbg) {}

const Ptrn* ptrn() const { return ptrn_.get(); }
Dbg dbg() const { return dbg_; }
bool implicit() const override { return ptrn()->implicit(); }

void bind(Scopes&, bool rebind, bool quiet) const override;
Ref emit_value(Emitter&, Ref) const override;
Ref emit_type(Emitter&) const override;
std::ostream& stream(Tab&, std::ostream&) const override;

private:
Ptr<Ptrn> ptrn_;
Dbg dbg_;
};

/// `(ptrn_0, ..., ptrn_n-1)`, `[ptrn_0, ..., ptrn_n-1]`, or `{ptrn_0, ..., ptrn_n-1}`
class TuplePtrn : public Ptrn {
public:
TuplePtrn(Loc loc, Tok::Tag delim_l, Ptrs<Ptrn>&& ptrns, Dbg dbg)
: Ptrn(loc, dbg)
TuplePtrn(Loc loc, Tok::Tag delim_l, Ptrs<Ptrn>&& ptrns)
: Ptrn(loc)
, delim_l_(delim_l)
, ptrns_(std::move(ptrns)) {}

Expand All @@ -262,14 +302,13 @@ class TuplePtrn : public Ptrn {
size_t num_ptrns() const { return ptrns().size(); }

void bind(Scopes&, bool rebind, bool quiet) const override;
Ref emit_value(Emitter&, Ref) const override;
Ref emit_type(Emitter&) const override;
Ref emit_decl(Emitter&, Ref type) const;
Ref emit_body(Emitter&, Ref decl) const;
std::ostream& stream(Tab&, std::ostream&) const override;

private:
void emit_value_(Emitter&, Ref) const override;

Tok::Tag delim_l_;
Ptrs<Ptrn> ptrns_;
};
Expand Down
19 changes: 14 additions & 5 deletions include/mim/ast/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ class Parser : public fe::Parser<Tok, Tok::Tag, Look_Ahead, Parser> {

/// @name parse exprs
///@{
Ptr<Expr> parse_expr(std::string_view ctxt, Prec = Prec::Bot);
Ptr<Expr> parse_expr(std::string_view ctxt, Expr::Prec = Expr::Prec::Bot);
Ptr<Expr> parse_primary_expr(std::string_view ctxt);
Ptr<Expr> parse_infix_expr(Tracker, Ptr<Expr>&& lhs, Prec = Prec::Bot);
Ptr<Expr> parse_infix_expr(Tracker, Ptr<Expr>&& lhs, Expr::Prec = Expr::Prec::Bot);
///@}

/// @name parse primary exprs
Expand All @@ -94,11 +94,20 @@ class Parser : public fe::Parser<Tok, Tok::Tag, Look_Ahead, Parser> {
Ptr<Expr> parse_insert_expr();
///@}

enum PtrnStyle {
Style_Bit = 0b001,
Brckt_Style = 0b001,
Paren_Style = 0b000,
Implicit = 0b010,
Annex_Allowed = 0b100,
};

/// @name parse ptrns
///@{
/// Depending on @p tag, this parses a `()`-style (Tok::Tag::D_paren_l) or `[]`-style (Tok::Tag::D_brckt_l) Ptrn.
Ptr<Ptrn> parse_ptrn(Tok::Tag tag, std::string_view ctxt, Prec = Prec::Bot, bool allow_annex = false);
Ptr<TuplePtrn> parse_tuple_ptrn();
/// Depending on @p style, this parses a `()`-style (Tok::Tag::D_paren_l) or `[]`-style (Tok::Tag::D_brckt_l) Ptrn.
Ptr<Ptrn> parse_ptrn(int style, std::string_view ctxt, Expr::Prec = Expr::Prec::Bot);
Ptr<Ptrn> parse_ptrn_(int style, std::string_view ctxt, Expr::Prec = Expr::Prec::Bot);
Ptr<TuplePtrn> parse_tuple_ptrn(int style);
///@}

/// @name parse decls
Expand Down
22 changes: 3 additions & 19 deletions include/mim/ast/tok.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ class Lit;
namespace ast {

// clang-format off
#define MIM_KEY(m) \
#define MIM_KEY(m) \
m(K_module, "module") \
m(K_import, "import") \
m(K_plugin, "plugin") \
m(K_and, "and" ) \
m(K_ax, "axm" ) \
m(K_as, "as" ) \
m(K_axm, "axm" ) \
m(K_let, "let" ) \
m(K_rec, "rec" ) \
m(K_ret, "ret" ) \
Expand Down Expand Up @@ -85,7 +86,6 @@ constexpr auto Num_Keys = size_t(0) MIM_KEY(CODE);
m(T_top, "") \
m(T_box, "") \
m(T_colon, ":") \
m(T_colon_colon,"::") \
m(T_comma, ",") \
m(T_dollar, "$") \
m(T_dot, ".") \
Expand All @@ -100,22 +100,6 @@ constexpr auto Num_Keys = size_t(0) MIM_KEY(CODE);
m("top", T_top ) \
m("insert", K_ins ) \

/// @name Precedence
///@{
enum class Prec {
Err,
Bot,
Where,
Arrow,
Pi,
App,
Extract,
Lit,
};

inline constexpr bool is_rassoc(Prec p) { return p == Prec::Arrow; }
///@}

class Tok {
public:
/// @name Tag
Expand Down
4 changes: 2 additions & 2 deletions lit/affine/for_over_mem.mim
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ con extern main [mem: %mem.M, argc: I32, argv: %mem.Ptr (%mem.Ptr (I32, 0), 0),
let mem = %mem.store (mem, lea, a);
continue (mem, a, b);

con for_exit [mem: %mem.M, I32, I32]::acc =
con for_exit [mem: %mem.M, I32, I32] =
let lea = %mem.lea (arr_size, <arr_size; I32>, 0) (ptr, %core.conv.u arr_size (%core.wrap.sub 0 (argc, 4I32)));
let (mem, val)::ld = %mem.load (mem, lea);
let ld = %mem.load (mem, lea);
return ld;
end;

Expand Down
2 changes: 1 addition & 1 deletion lit/group.mim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %mim %s -o -
lam f(a b: Nat, x: «a; Nat»): Bool = ff;
axm %foo.F: [p e: Nat] → *;
axm %foo.bar: {p e: Nat}::pe [Nat] [a b: %foo.F pe] → %foo.F (p, e);
axm %foo.bar: {p e: Nat} as pe [Nat] [a b: %foo.F pe] → %foo.F (p, e);
2 changes: 1 addition & 1 deletion lit/mem/mem_rm.mim
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
// RUN: clang %t.ll -S -emit-llvm -Wno-override-module -o -
plugin core;

fun extern f (a b: I32)::ab : I32 =
fun extern f (a b: I32) as ab : I32 =
return (%mem.rm (2, ‹2; I32›, I32) (%core.div.sdiv @ i32) ab);
6 changes: 3 additions & 3 deletions lit/mem/mslot_load_store.mim
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
plugin core;

con extern main(mem: %mem.M, argc: I32, argv: %mem.Ptr («⊤:Nat; %mem.Ptr («⊤:Nat; I8», 0)», 0), return: Cn [%mem.M, I32]) =
let (mem, ptr) = %mem.mslot (I32, 0) (mem, 4, 0);
let mem = %mem.store (mem, ptr, argc);
let (mem, val)::ld = %mem.load (mem, ptr);
let (mem, ptr) = %mem.mslot (I32, 0) (mem, 4, 0);
let mem = %mem.store (mem, ptr, argc);
let (mem, val) as ld = %mem.load (mem, ptr);
return ld;

// CHECK-DAG: con extern main _{{[0-9_]+}}::[mem_[[mainMemId:[_0-9]*]]: %mem.M, argc_[[argcId:[0-9_]+]]: I32, %mem.Ptr («⊤:Nat; %mem.Ptr («⊤:Nat; I8», 0)», 0), return_[[returnId:[_0-9]*]]: Cn [%mem.M, I32]]{{(@.*)?}}= {
Expand Down
6 changes: 3 additions & 3 deletions lit/mem/slot_load_store.mim
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
plugin core;

con extern main(mem: %mem.M, argc: I32, argv: %mem.Ptr («⊤:Nat; %mem.Ptr («⊤:Nat; I8», 0)», 0), return: Cn [%mem.M, I32]) =
let (mem, ptr) = %mem.slot (I32, 0) (mem, 0);
let mem = %mem.store (mem, ptr, argc);
let (mem, val)::ld = %mem.load (mem, ptr);
let (mem, ptr) = %mem.slot (I32, 0) (mem, 0);
let mem = %mem.store (mem, ptr, argc);
let ld = %mem.load (mem, ptr);
return ld;

// CHECK-DAG: con extern main _{{[0-9_]+}}::[mem_[[mainMemId:[_0-9]*]]: %mem.M, argc_[[argcId:[0-9_]+]]: I32, %mem.Ptr («⊤:Nat; %mem.Ptr («⊤:Nat; I8», 0)», 0), return_[[returnId:[_0-9]*]]: Cn [%mem.M, I32]]{{(@.*)?}}= {
Expand Down
9 changes: 6 additions & 3 deletions src/mim/ast/bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,21 @@ void Import::bind(Scopes& s) const { module()->bind(s); }
*/

void ErrorPtrn::bind(Scopes&, bool, bool) const {}
void GrpPtrn::bind(Scopes& s, bool rebind, bool quiet) const { s.bind(dbg(), this, rebind, quiet); }

void IdPtrn::bind(Scopes& s, bool rebind, bool quiet) const {
if (!quiet && type()) type()->bind(s);
s.bind(dbg(), this, rebind, quiet);
}

void TuplePtrn::bind(Scopes& s, bool rebind, bool quiet) const {
for (const auto& ptrn : ptrns()) ptrn->bind(s, rebind, quiet);
void AliasPtrn::bind(Scopes& s, bool rebind, bool quiet) const {
ptrn()->bind(s, rebind, quiet);
s.bind(dbg(), this, rebind, quiet);
}

void GrpPtrn::bind(Scopes& s, bool rebind, bool quiet) const { s.bind(dbg(), this, rebind, quiet); }
void TuplePtrn::bind(Scopes& s, bool rebind, bool quiet) const {
for (const auto& ptrn : ptrns()) ptrn->bind(s, rebind, quiet);
}

/*
* Expr
Expand Down
Loading

0 comments on commit 8df09f8

Please sign in to comment.