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
Add basic sequence support
  • Loading branch information
dosisod committed Oct 23, 2022
commit c59c46521c260056fddac4c555c21cb9ea5eb819
18 changes: 17 additions & 1 deletion mypyc/irbuild/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
MappingPattern,
SingletonPattern,
SequencePattern,
StarredPattern,
ValuePattern,
)
from mypy.traverser import TraverserVisitor
Expand All @@ -22,7 +23,7 @@
dict_del_item,
slow_isinstance_op,
)
from mypyc.primitives.list_ops import check_list
from mypyc.primitives.list_ops import check_list, list_get_item_op
from mypyc.irbuild.builder import IRBuilder

class MatchVisitor(TraverserVisitor):
Expand Down Expand Up @@ -234,6 +235,8 @@ def visit_mapping_pattern(self, pattern: MappingPattern) -> None:
self.builder.goto(self.code_block)

def visit_sequence_pattern(self, pattern: SequencePattern) -> None:
assert not any(isinstance(p, StarredPattern) for p in pattern.patterns)

is_list = self.builder.call_c(
check_list,
[self.subject],
Expand All @@ -242,6 +245,19 @@ def visit_sequence_pattern(self, pattern: SequencePattern) -> None:

self.builder.add_bool_branch(is_list, self.code_block, self.next_block)

for i, p in enumerate(pattern.patterns):
self.builder.activate_block(self.code_block)
self.code_block = BasicBlock()

item = self.builder.call_c(
list_get_item_op,
[self.subject, self.builder.load_int(i)],
p.line,
)

with self.enter_subpattern(item):
p.accept(self)

def bind_as_pattern(self, value: Value, new_block: bool = False) -> None:
if self.as_pattern and self.as_pattern.name:
if new_block:
Expand Down
63 changes: 63 additions & 0 deletions mypyc/test-data/irbuild-match.test
Original file line number Diff line number Diff line change
Expand Up @@ -1233,3 +1233,66 @@ L2:
L3:
r9 = box(None, 1)
return r9
[case testMatchFixedLengthSequencePattern_python3_10]
def f(x):
match x:
case [1, 2]:
print("matched")
[out]
def f(x):
x :: object
r0 :: int32
r1 :: bit
r2 :: list
r3, r4, r5 :: object
r6 :: int32
r7 :: bit
r8 :: bool
r9 :: list
r10, r11, r12 :: object
r13 :: int32
r14 :: bit
r15 :: bool
r16 :: str
r17 :: object
r18 :: str
r19 :: object
r20 :: object[1]
r21 :: object_ptr
r22, r23 :: object
L0:
r0 = PyList_Check(x)
r1 = r0 != 0
if r1 goto L1 else goto L4 :: bool
L1:
r2 = cast(list, x)
r3 = CPyList_GetItem(r2, 0)
r4 = object 1
r5 = PyObject_RichCompare(r3, r4, 2)
r6 = PyObject_IsTrue(r5)
r7 = r6 >= 0 :: signed
r8 = truncate r6: int32 to builtins.bool
if r8 goto L2 else goto L4 :: bool
L2:
r9 = cast(list, x)
r10 = CPyList_GetItem(r9, 2)
r11 = object 2
r12 = PyObject_RichCompare(r10, r11, 2)
r13 = PyObject_IsTrue(r12)
r14 = r13 >= 0 :: signed
r15 = truncate r13: int32 to builtins.bool
if r15 goto L3 else goto L4 :: bool
L3:
r16 = 'matched'
r17 = builtins :: module
r18 = 'print'
r19 = CPyObject_GetAttr(r17, r18)
r20 = [r16]
r21 = load_address r20
r22 = _PyObject_Vectorcall(r19, r21, 1, 0)
keep_alive r16
goto L5
L4:
L5:
r23 = box(None, 1)
return r23
7 changes: 7 additions & 0 deletions mypyc/test-data/run-match.test
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def f(x):
case {}:
print("test map final")

case ["test", 13]:
print("test 13")

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

Expand Down Expand Up @@ -109,6 +112,9 @@ f({"test": 12, "key": "value", "abc": "123"})
# test map final
f({})

# test 13
f(["test", 13])

# test sequence final
f([])

Expand Down Expand Up @@ -137,5 +143,6 @@ test 12 (rest={})
test 12 (rest={'key': 'value'})
test 12 (rest={'key': 'value', 'abc': '123'})
test map final
test 13
test sequence final
test final