Skip to content

Commit b4b8dc4

Browse files
Pointer pattern (#280)
* Pointer pattern * elab new Pattern.pointer constructor * pointer match test --------- Co-authored-by: Arthur Paulino <arthurleonardo.ap@gmail.com>
1 parent c165d21 commit b4b8dc4

5 files changed

Lines changed: 28 additions & 1 deletion

File tree

Ix/Aiur/Check.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ where
392392
let bind ← aux pat typ
393393
let bind' ← aux pat' typ
394394
if bind != bind' then throw $ .differentBindings bind bind' else pure bind
395+
| (.pointer pat, .pointer typ) => aux pat typ
395396
| _ => throw $ .incompatiblePattern pat typ
396397

397398
partial def inferTuple (term : Term) : CheckM (Array Typ × TypedTermInner) := do

Ix/Aiur/Match.lean

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ inductive SPattern
1111
| ref : Global → Array Local → SPattern
1212
| tuple : Array Local → SPattern
1313
| array : Array Local → SPattern
14+
| pointer : Local → SPattern
1415
deriving BEq, Hashable, Inhabited
1516

1617
structure Clause where
@@ -76,6 +77,12 @@ def dnfProd (branches: List $ Pattern × UniqTerm) (body : ExtTerm) : CompilerM
7677
let (vars, guards) ← flattenArgs args.toArray
7778
let clause := ⟨.ref global vars, guards, term⟩
7879
aux renames (clauses.push clause) rest body
80+
| (.pointer arg, term) :: rest => do
81+
let id ← newId
82+
let var := .idx id
83+
let guards := #[(arg, (id, .var var))]
84+
let clause := ⟨.pointer var, guards, term⟩
85+
aux renames (clauses.push clause) rest body
7986
aux Array.empty Array.empty branches body
8087
where
8188
flattenArgs args := do
@@ -98,6 +105,7 @@ def patTypeLength (decls : Decls) : SPattern → Nat
98105
| .tuple _ => 1
99106
| .array _ => 1
100107
| .ref global _ => typeLookup global |>.constructors.length
108+
| .pointer _ => 1
101109
where
102110
typeLookup (global : Global) :=
103111
match global.popNamespace with
@@ -200,6 +208,8 @@ def spatternToPattern : SPattern → Pattern
200208
| .ref global vars => .ref global (vars.map .var).toList
201209
| .tuple vars => .tuple (vars.map .var)
202210
| .array vars => .array (vars.map .var)
211+
-- pointer patterns are unique and will be converted into a load operation before this function is called
212+
| .pointer _ => unreachable!
203213

204214
mutual
205215

@@ -214,6 +224,9 @@ partial def branchesToTerm (branches : List (SPattern × Decision)) (dec : Decis
214224
partial def decisionToTerm : Decision → Option Term
215225
| .success ⟨renames, value⟩ =>
216226
some $ renames.foldr (init := value) fun (x, y) acc => .let (.var x) y acc
227+
| .switch ptr [(.pointer val, body)] _ => do
228+
let body' ← decisionToTerm body
229+
some $ .let (.var val) (.load (.var ptr)) body'
217230
| .switch var branches dec => some $ .match (.var var) (branchesToTerm branches dec)
218231
| .let var term body => do
219232
let body' ← decisionToTerm body

Ix/Aiur/Meta.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ syntax num : pattern
1515
syntax "(" pattern (", " pattern)* ")" : pattern
1616
syntax "[" pattern (", " pattern)* "]" : pattern
1717
syntax pattern "|" pattern : pattern
18+
syntax "&" pattern : pattern
1819

1920
def elabListCore (head : α) (tail : Array α) (elabFn : α → TermElabM Expr)
2021
(listEltType : Expr) (isArray := false) : TermElabM Expr := do
@@ -58,6 +59,8 @@ partial def elabPattern : ElabStxCat `pattern
5859
mkAppM ``Pattern.array #[← elabList p ps elabPattern ``Pattern true]
5960
| `(pattern| $p₁:pattern | $p₂:pattern) => do
6061
mkAppM ``Pattern.or #[← elabPattern p₁, ← elabPattern p₂]
62+
| `(pattern| &$p:pattern) => do
63+
mkAppM ``Pattern.pointer #[← elabPattern p]
6164
| stx => throw $ .error stx "Invalid syntax for pattern"
6265

6366
declare_syntax_cat typ

Ix/Aiur/Term.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Aiur
77
inductive Local
88
| str : String → Local
99
| idx : Nat → Local
10-
deriving Repr, BEq, Hashable
10+
deriving Repr, BEq, Inhabited, Hashable
1111

1212
structure Global where
1313
toName : Lean.Name
@@ -46,6 +46,7 @@ inductive Pattern
4646
| tuple : Array Pattern → Pattern
4747
| array : Array Pattern → Pattern
4848
| or : Pattern → Pattern → Pattern
49+
| pointer : Pattern → Pattern
4950
deriving Repr, BEq, Hashable, Inhabited
5051

5152
inductive Typ where

Tests/Aiur.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ def toplevel := ⟦
5050
-- cast(Nat.Zero, (G, G))
5151
-- }
5252

53+
fn pointer_match() -> G {
54+
let two = Nat.Succ(store(Nat.Succ(store(Nat.Zero))));
55+
match two {
56+
Nat.Succ(&Nat.Succ(&Nat.Zero)) => 1,
57+
_ => 0,
58+
}
59+
}
60+
5361
fn even(m: Nat) -> G {
5462
match m {
5563
Nat.Zero => 1,
@@ -210,6 +218,7 @@ def aiurTestCases : List AiurTestCase := [
210218
.noIO `eq_zero_dummy #[0, 37] #[1, 0, 1, 0],
211219
.noIO `store_and_load #[42] #[42],
212220
-- .noIO `cast_zero #[] #[0, 0],
221+
.noIO `pointer_match #[] #[1],
213222
.noIO `is_0_even #[] #[1],
214223
.noIO `is_1_even #[] #[0],
215224
.noIO `is_2_even #[] #[1],

0 commit comments

Comments
 (0)