From c7c4290b6bfbfc9f6268ceca9f1db67a5765a32a Mon Sep 17 00:00:00 2001 From: karroffel Date: Mon, 16 Jan 2017 19:01:06 +0100 Subject: [PATCH] added documentation for pattern matching --- extensions/gdscript.py | 2 +- reference/gdscript.rst | 129 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/extensions/gdscript.py b/extensions/gdscript.py index 7f08d551..875285d8 100644 --- a/extensions/gdscript.py +++ b/extensions/gdscript.py @@ -90,7 +90,7 @@ class GDScriptLexer(RegexLexer): 'do', 'var', 'const', 'extends', 'export', 'onready', 'tool', 'static', 'setget', 'signal', 'breakpoint', 'switch', 'case', 'assert', 'break', 'continue', 'elif', 'else', 'for', 'if', - 'pass', 'return', 'while'), suffix=r'\b'), + 'pass', 'return', 'while', 'match'), suffix=r'\b'), Keyword), ], 'builtins': [ diff --git a/reference/gdscript.rst b/reference/gdscript.rst index ddcbf4c7..743ddd28 100644 --- a/reference/gdscript.rst +++ b/reference/gdscript.rst @@ -159,6 +159,8 @@ keywords are reserved words (tokens), they can't be used as identifiers. +------------+---------------------------------------------------------------------------------------------------------------+ | while | See while_. | +------------+---------------------------------------------------------------------------------------------------------------+ +| match | See match_. | ++------------+---------------------------------------------------------------------------------------------------------------+ | switch | Reserved for future implementation. | +------------+---------------------------------------------------------------------------------------------------------------+ | case | Reserved for future implementation. | @@ -694,6 +696,133 @@ in the loop variable. for i in range(2,8,2): statement # similar to [2, 4, 6] but does not allocate an array +match +^^^^^ + +A ``match`` statement is used to branch execution of a program. +It's the equivalent of the ``switch`` statement found in many other languages but offers some additional features. + +Basic syntax: +:: + + match [expression]: + [pattern](s): [block] + [pattern](s): [block] + [pattern](s): [block] + + +**Crash-course for people who are familiar to switch statements**: + +1) replace ``switch`` by ``match`` +2) remove ``case`` +3) remove any ``break`` s. If you don't want to ``break`` by default you can use ``continue`` to get a fallthrough. +4) change ``default`` to a single underscore. + + +**Control flow**: + +The patterns get matched from top to bottom. +If a pattern matches the corresponding block gets executed. After that the execution will continue after the ``match`` statement. +If you want to have a fallthrough you can use ``continue`` to stop execution in the current block and check the next one. + + + + +There are 6 pattern types: + +- constant pattern + constant primitives like numbers and strings :: + + match x: + 1: print("I'm number one!") + 2: print("Two are better than one!") + "test": print("Oh snap! It's a string!") + +- variable pattern + matching on the contents of a variable/enum :: + + match typeof(x): + TYPE_FLOAT: print("float") + TYPE_STRING: print("text") + TYPE_ARRAY: print("array") + + +- wilcard pattern + This pattern matches everything. It's written as a single underscore. + + It can be used as the equivalent of the ``default`` in a ``switch`` statement in other languages. :: + + match x: + 1: print("it's one!") + 2: print("it's one times two!") + _: print("it's not 1 or 2. I don't care tbh") + + +- binding pattern + A binding pattern introduces a new variable. It's like the wildcard pattern: it matches everything - but it also gives that value a name. + Especially useful in array and dictionary patterns. :: + + match x: + 1: print("it's one!") + 2: print("it's one times two!") + var new_var: print("it's not 1 or 2, it's ", new_var) + + +- array pattern + matches an array. Every single element of the array pattern is a pattern itself so you can nest them. + + First the length of the array is tested. It has to be the same like the pattern, otherwise the pattern doesn't match. + + **Open-ended array**: An array can be bigger than the pattern by making the last subpattern ``..`` + + Every subpattern has to be comma seperated. :: + + match x: + []: + print("emtpy array") + [1, 3, "test", null]: + print("very specific array") + [var start, _, "test"]: + print("first element is ", start, " ande the last is \"test\"") + [42, ..]: + print("open ended array") + +- dictionary pattern + works similar to the array pattern. Every key has to be a constant pattern. + + First the size of the dictionary is tested. It has to be the same like the pattern, otherwise the pattern doesn't match. + + **Open-ended dictionary**: A dictionary can be bigger than the pattern by making the last subpattern ``..`` + + Every subpattern has to be comma seperated. + + If you don't specify a value then only the existance of the key is checked (treating the dictionary like a set). + + A value pattern is seperated from the key pattern with a ``:`` :: + + match x: + {}: + print("empty dict") + {"name": "dennis"}: + print("the name is dennis") + {"name": "dennis", "age": var age}: + print("dennis is ", age, " years old.") + {"name", "age"}: + print("has a name and an age, but it's not dennis :(") + {"key": "godotisawesome", ..}: + print("I only checked for one entry and ignored the rest") + +Multipatterns: + You can also specify multiple patterns which are seperated by a comma. Those patterns aren't allowed to have any bindings in them. :: + + match x: + 1, 2, 3: + print("it's 1 - 3") + "sword", "splashpotion", "fist": + print("yep, you've taken damage") + + + Classes ~~~~~~~