Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mypyc] Add match statement support #13953

Merged
merged 102 commits into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
3e6744e
Add `match` statement entrypoint:
dosisod Oct 9, 2022
39f366d
Cleanup
dosisod Oct 9, 2022
8bee07a
Add value pattern check
dosisod Oct 10, 2022
0883015
Cleanup
dosisod Oct 10, 2022
e646c44
Reset
dosisod Oct 11, 2022
b27b380
Add value pattern
dosisod Oct 11, 2022
f1e6a30
Explicitly type out len 2 or pattern
dosisod Oct 11, 2022
31e3ace
Add multiple Or Pattern support
dosisod Oct 11, 2022
538d488
Add one
dosisod Oct 11, 2022
b653335
Generalize
dosisod Oct 11, 2022
2870c8e
Minimize
dosisod Oct 11, 2022
988769d
Rearange codeblock
dosisod Oct 11, 2022
6cae5f8
Cleanup
dosisod Oct 11, 2022
856dc85
Make it more readable
dosisod Oct 11, 2022
65c9aae
Add class pattern support
dosisod Oct 11, 2022
2955d9f
Add wildcard
dosisod Oct 12, 2022
96fb472
Add multibody support
dosisod Oct 12, 2022
f961fd0
Fix failing tests
dosisod Oct 12, 2022
899c954
Add final block gotos
dosisod Oct 12, 2022
dcf84e0
Add complex sanity test
dosisod Oct 12, 2022
eb2dc2d
Add run test
dosisod Oct 12, 2022
522461d
Add pattern guard for value pattern
dosisod Oct 12, 2022
8ce67d9
Add pattern guard support to all existing patterns
dosisod Oct 12, 2022
c364489
Add singleton pattern
dosisod Oct 12, 2022
d43e8ca
Greatly reduce number of opcodes
dosisod Oct 12, 2022
acdeb33
Move code_block out
dosisod Oct 14, 2022
beb1476
Move out next_block
dosisod Oct 14, 2022
4d8cbc3
Cleanup
dosisod Oct 14, 2022
a332551
Add elifs
dosisod Oct 14, 2022
8fd6546
Move pattern building to its own function
dosisod Oct 14, 2022
42b8d58
Move body builder out of each if stmt
dosisod Oct 14, 2022
130647e
Add recursive matching
dosisod Oct 14, 2022
cc9f375
Add basic AsPattern support
dosisod Oct 15, 2022
331531b
Add groundwork for captured patterns
dosisod Oct 16, 2022
92b05b8
Convert to visitor
dosisod Oct 16, 2022
2e1a2ad
Rewrite using visitor
dosisod Oct 16, 2022
c55236e
Add basic AsPattern support for ValuePattern:
dosisod Oct 16, 2022
0af9b24
Add Or pattern support for AsPattern
dosisod Oct 16, 2022
aedd1a6
Add AsPattern support for class pattern
dosisod Oct 16, 2022
5b95596
Cleanup
dosisod Oct 16, 2022
25d0edc
Add basic positional arg parsing
dosisod Oct 19, 2022
b85f178
Add support for variable number of positional args
dosisod Oct 19, 2022
9293549
Use self.code_block
dosisod Oct 19, 2022
2132f78
Add support for keyword class patterns
dosisod Oct 19, 2022
c5dd161
Add better scoping entering
dosisod Oct 19, 2022
c64c343
Split context managers
dosisod Oct 19, 2022
49d60c8
Support nested patterns in class pattern
dosisod Oct 19, 2022
1deecb4
Fix as pattern binding to subpatterns
dosisod Oct 20, 2022
df4a146
Add positional captures
dosisod Oct 20, 2022
0376526
Add basic mapping support
dosisod Oct 20, 2022
5e479b0
Add key value patterns
dosisod Oct 21, 2022
820b9bd
Add basic mapping rest
dosisod Oct 21, 2022
29eadd5
Make sure to pop keys from rest dict
dosisod Oct 21, 2022
d538d69
Cleanup
dosisod Oct 21, 2022
553e41c
Split match stuff into its own file
dosisod Oct 21, 2022
5c8b4c5
Merge remote-tracking branch 'upstream/master' into mypyc-match
dosisod Oct 21, 2022
ec128ad
Add a bunch of tests
dosisod Oct 21, 2022
1b0523b
Fix next_block not being setup for or pattern
dosisod Oct 23, 2022
626d8f1
Fix as pattern variable being assigned if condition is false
dosisod Oct 23, 2022
3bb2e55
Sorta fix mapping issue:
dosisod Oct 23, 2022
59f140e
Switch to using PyDict_Check
dosisod Oct 23, 2022
67efc08
Fix dict item being accessed via get attr instead of get item
dosisod Oct 23, 2022
e57f0a1
Check that key is contained in dict before grabbing it
dosisod Oct 23, 2022
214dcea
Finish map runtime tests
dosisod Oct 23, 2022
ad82d9f
Add empty sequence pattern matching
dosisod Oct 23, 2022
c59c465
Add basic sequence support
dosisod Oct 23, 2022
fc74fa2
Get unbound sequence capture working at end of list (almost):
dosisod Oct 23, 2022
739962f
Fix last commit
dosisod Oct 23, 2022
0115381
Updates
dosisod Oct 24, 2022
38a5cc5
Require exact size for fixed length sequences
dosisod Oct 24, 2022
04f0cbc
Very hacky support for star pattern in middle of list
dosisod Oct 24, 2022
360f686
Hackily add leading star pattern
dosisod Oct 24, 2022
9714a2c
Cleanups
dosisod Oct 24, 2022
5b70d51
Renaming
dosisod Oct 24, 2022
25564c8
Cleanup
dosisod Oct 25, 2022
9601a23
Cleanups
dosisod Oct 25, 2022
16e8d12
Renames
dosisod Oct 25, 2022
b241029
Cleanup
dosisod Oct 25, 2022
4b2cfc3
Cleanups
dosisod Oct 25, 2022
ede2e14
More cleanups
dosisod Oct 25, 2022
0b30e8b
Add class pattern support for builtins
dosisod Oct 25, 2022
8f0a3bf
Cleanup
dosisod Oct 27, 2022
96cd6b1
Add more tests
dosisod Oct 27, 2022
47f9682
Black
dosisod Oct 27, 2022
532ff8a
Uncomment old tests, add python_version flag
dosisod Oct 27, 2022
f73b60a
Reorganize ops
dosisod Oct 27, 2022
b525188
Isort
dosisod Oct 27, 2022
e01090c
Merge upstream
dosisod Oct 27, 2022
a117794
Switch to using older typing syntax
dosisod Oct 28, 2022
22c1327
Fix build errors:
dosisod Oct 28, 2022
3836f00
Only run match code for Python 3.10+
dosisod Oct 28, 2022
4f18437
Fix length of empty sequence patterns not being checked
dosisod Oct 28, 2022
4f218b9
Fix `[*rest]` patterns not binding to `rest`
dosisod Oct 28, 2022
6c5de33
Allow for pattern matching Mapping and Sequence protocols
dosisod Oct 31, 2022
c8f8c84
Remove previously added command-line arguments:
dosisod Oct 31, 2022
dff0c71
Fix flags not being defined in Python 3.9 and below:
dosisod Oct 31, 2022
03fab7e
Merge branch 'master' into mypyc-match
dosisod Nov 4, 2022
07486a0
Attempt to fix last commit:
dosisod Nov 5, 2022
85ec2d7
Merge branch 'master' into mypyc-match
dosisod Nov 15, 2022
9728bc6
Trigger CI
dosisod Nov 15, 2022
5bb3e28
Merge branch 'master' into mypyc-match
dosisod Dec 1, 2022
af5bca8
Add review suggestions:
dosisod Dec 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Hackily add leading star pattern
  • Loading branch information
dosisod committed Oct 24, 2022
commit 360f686c9e3b192371d38b78eb5a314984166fd7
10 changes: 9 additions & 1 deletion mypyc/irbuild/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,20 @@ def visit_sequence_pattern(self, pattern: SequencePattern) -> None:
with self.enter_subpattern(item):
p.accept(self)

if capture and index:
if capture and index is not None:
self.builder.activate_block(self.code_block)
self.code_block = BasicBlock()

target = self.builder.get_assignment_target(capture)

if index == 0:
capture_end = self.builder.binary_op(
capture_end,
self.builder.load_int(1),
"-",
pattern.patterns[0].line,
)

rest = self.builder.call_c(
list_slice_op,
[
Expand Down
127 changes: 127 additions & 0 deletions mypyc/test-data/irbuild-match.test
Original file line number Diff line number Diff line change
Expand Up @@ -1576,3 +1576,130 @@ L14:
L15:
r39 = box(None, 1)
return r39
[case testMatchSequenceWithStarPatternAtTheStart_python3_10]
def f(x):
match x:
case [*rest, 1, 2]:
print("matched")
[out]
def f(x):
x :: object
r0 :: int32
r1 :: bit
r2 :: native_int
r3, r4 :: bit
r5 :: native_int
r6 :: list
r7, r8 :: bit
r9, r10, r11 :: int
r12, r13, r14 :: object
r15 :: int32
r16 :: bit
r17 :: bool
r18 :: native_int
r19 :: list
r20, r21 :: bit
r22, r23, r24 :: int
r25, r26, r27 :: object
r28 :: int32
r29 :: bit
r30 :: bool
r31 :: native_int
r32 :: list
r33, r34 :: bit
r35, r36, r37 :: int
r38, rest :: object
r39 :: str
r40 :: object
r41 :: str
r42 :: object
r43 :: object[1]
r44 :: object_ptr
r45, r46 :: object
L0:
r0 = PyList_Check(x)
r1 = r0 != 0
if r1 goto L1 else goto L18 :: bool
L1:
r2 = PyObject_Size(x)
r3 = r2 >= 0 :: signed
r4 = 2 <= r2 :: signed
if r4 goto L2 else goto L18 :: bool
L2:
r5 = r2 - 2
r6 = cast(list, x)
r7 = r5 <= 4611686018427387903 :: signed
if r7 goto L3 else goto L4 :: bool
L3:
r8 = r5 >= -4611686018427387904 :: signed
if r8 goto L5 else goto L4 :: bool
L4:
r9 = CPyTagged_FromInt64(r5)
r10 = r9
goto L6
L5:
r11 = r5 << 1
r10 = r11
L6:
r12 = CPyList_GetItem(r6, r10)
r13 = object 1
r14 = PyObject_RichCompare(r12, r13, 2)
r15 = PyObject_IsTrue(r14)
r16 = r15 >= 0 :: signed
r17 = truncate r15: int32 to builtins.bool
if r17 goto L7 else goto L18 :: bool
L7:
r18 = r2 - 1
r19 = cast(list, x)
r20 = r18 <= 4611686018427387903 :: signed
if r20 goto L8 else goto L9 :: bool
L8:
r21 = r18 >= -4611686018427387904 :: signed
if r21 goto L10 else goto L9 :: bool
L9:
r22 = CPyTagged_FromInt64(r18)
r23 = r22
goto L11
L10:
r24 = r18 << 1
r23 = r24
L11:
r25 = CPyList_GetItem(r19, r23)
r26 = object 2
r27 = PyObject_RichCompare(r25, r26, 2)
r28 = PyObject_IsTrue(r27)
r29 = r28 >= 0 :: signed
r30 = truncate r28: int32 to builtins.bool
if r30 goto L12 else goto L18 :: bool
L12:
r31 = r18 - 1
r32 = cast(list, x)
r33 = r31 <= 4611686018427387903 :: signed
if r33 goto L13 else goto L14 :: bool
L13:
r34 = r31 >= -4611686018427387904 :: signed
if r34 goto L15 else goto L14 :: bool
L14:
r35 = CPyTagged_FromInt64(r31)
r36 = r35
goto L16
L15:
r37 = r31 << 1
r36 = r37
L16:
r38 = CPyList_GetSlice(r32, 0, r36)
rest = r38
L17:
r39 = 'matched'
r40 = builtins :: module
r41 = 'print'
r42 = CPyObject_GetAttr(r40, r41)
r43 = [r39]
r44 = load_address r43
r45 = _PyObject_Vectorcall(r42, r44, 1, 0)
keep_alive r39
goto L19
L18:
L19:
r46 = box(None, 1)
return r46
11 changes: 11 additions & 0 deletions mypyc/test-data/run-match.test
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ def f(x):
case ["test", *rest3, 16]:
print(f"test 16 ({rest3})")

case [*rest4, "test", 17]:
print(f"test 17 ({rest4})")

case []:
print("test sequence final")

Expand Down Expand Up @@ -144,6 +147,11 @@ f(["test", 16])
f(["test", "filler", 16])
f(["test", "more", "filler", 16])

# test 17
f(["test", 17])
f(["stuff", "test", 17])
f(["more", "stuff", "test", 17])

# test sequence final
f([])

Expand Down Expand Up @@ -181,5 +189,8 @@ test 15 (['something'])
test 16 ([])
test 16 (['filler'])
test 16 (['more', 'filler'])
test 17 ([])
test 17 (['stuff'])
test 17 (['more', 'stuff'])
test sequence final
test final