scratchattach 3.0.0b0__py3-none-any.whl → 3.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cli/__about__.py +1 -0
- cli/__init__.py +26 -0
- cli/cmd/__init__.py +4 -0
- cli/cmd/group.py +127 -0
- cli/cmd/login.py +60 -0
- cli/cmd/profile.py +7 -0
- cli/cmd/sessions.py +5 -0
- cli/context.py +142 -0
- cli/db.py +66 -0
- cli/namespace.py +14 -0
- cloud/__init__.py +2 -0
- cloud/_base.py +483 -0
- cloud/cloud.py +183 -0
- editor/__init__.py +22 -0
- editor/asset.py +265 -0
- editor/backpack_json.py +115 -0
- editor/base.py +191 -0
- editor/block.py +584 -0
- editor/blockshape.py +357 -0
- editor/build_defaulting.py +51 -0
- editor/code_translation/__init__.py +0 -0
- editor/code_translation/parse.py +177 -0
- editor/comment.py +80 -0
- editor/commons.py +145 -0
- editor/extension.py +50 -0
- editor/field.py +99 -0
- editor/inputs.py +138 -0
- editor/meta.py +117 -0
- editor/monitor.py +185 -0
- editor/mutation.py +381 -0
- editor/pallete.py +88 -0
- editor/prim.py +174 -0
- editor/project.py +381 -0
- editor/sprite.py +609 -0
- editor/twconfig.py +114 -0
- editor/vlb.py +134 -0
- eventhandlers/__init__.py +0 -0
- eventhandlers/_base.py +101 -0
- eventhandlers/cloud_events.py +130 -0
- eventhandlers/cloud_recorder.py +26 -0
- eventhandlers/cloud_requests.py +544 -0
- eventhandlers/cloud_server.py +249 -0
- eventhandlers/cloud_storage.py +135 -0
- eventhandlers/combine.py +30 -0
- eventhandlers/filterbot.py +163 -0
- eventhandlers/message_events.py +42 -0
- other/__init__.py +0 -0
- other/other_apis.py +598 -0
- other/project_json_capabilities.py +475 -0
- {scratchattach-3.0.0b0.dist-info → scratchattach-3.0.0b1.dist-info}/METADATA +1 -1
- scratchattach-3.0.0b1.dist-info/RECORD +79 -0
- scratchattach-3.0.0b1.dist-info/top_level.txt +7 -0
- site/__init__.py +0 -0
- site/_base.py +93 -0
- site/activity.py +426 -0
- site/alert.py +226 -0
- site/backpack_asset.py +119 -0
- site/browser_cookie3_stub.py +17 -0
- site/browser_cookies.py +61 -0
- site/classroom.py +454 -0
- site/cloud_activity.py +121 -0
- site/comment.py +228 -0
- site/forum.py +436 -0
- site/placeholder.py +132 -0
- site/project.py +932 -0
- site/session.py +1323 -0
- site/studio.py +704 -0
- site/typed_dicts.py +151 -0
- site/user.py +1252 -0
- utils/__init__.py +0 -0
- utils/commons.py +263 -0
- utils/encoder.py +161 -0
- utils/enums.py +237 -0
- utils/exceptions.py +277 -0
- utils/optional_async.py +154 -0
- utils/requests.py +306 -0
- scratchattach/__init__.py +0 -37
- scratchattach/__main__.py +0 -93
- scratchattach-3.0.0b0.dist-info/RECORD +0 -8
- scratchattach-3.0.0b0.dist-info/top_level.txt +0 -1
- {scratchattach-3.0.0b0.dist-info → scratchattach-3.0.0b1.dist-info}/WHEEL +0 -0
- {scratchattach-3.0.0b0.dist-info → scratchattach-3.0.0b1.dist-info}/entry_points.txt +0 -0
- {scratchattach-3.0.0b0.dist-info → scratchattach-3.0.0b1.dist-info}/licenses/LICENSE +0 -0
editor/blockshape.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enums stating the shape of a block from its opcode (i.e: stack, c-mouth, cap, hat etc)
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
# Perhaps this should be merged with pallete.py
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Final, Literal
|
|
9
|
+
|
|
10
|
+
from . import commons
|
|
11
|
+
from scratchattach.utils.enums import _EnumWrapper
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class _MutationDependent(commons.Singleton):
|
|
15
|
+
"""
|
|
16
|
+
Singleton value that represents the uncertainty of a vablue because it depends on block mutation data.
|
|
17
|
+
"""
|
|
18
|
+
INSTANCE = 0
|
|
19
|
+
def __bool__(self):
|
|
20
|
+
raise TypeError("Need mutation data to work out attribute value.")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
MUTATION_DEPENDENT: Final[Literal[_MutationDependent.INSTANCE]] = _MutationDependent.INSTANCE
|
|
24
|
+
"""Value used when mutation data is required to work out the attribute value"""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(init=True, repr=True)
|
|
28
|
+
class BlockShape:
|
|
29
|
+
"""
|
|
30
|
+
The shape of a block; e.g. is it a stack, c-mouth, cap, hat reporter, boolean or menu block?
|
|
31
|
+
"""
|
|
32
|
+
is_stack: bool | _MutationDependent = False # Most blocks - e.g. move [10] steps
|
|
33
|
+
is_c_mouth: bool | _MutationDependent = False # Has substack - e.g. repeat
|
|
34
|
+
is_cap: bool | _MutationDependent = False # No next - e.g. forever
|
|
35
|
+
is_hat: bool | _MutationDependent = False # No parent - e.g. when gf clicked
|
|
36
|
+
is_reporter: bool | _MutationDependent = False # (reporter)
|
|
37
|
+
is_boolean: bool | _MutationDependent = False # <reporter>
|
|
38
|
+
is_menu: bool | _MutationDependent = False # Shadow reporters, e.g. costume menu
|
|
39
|
+
opcode: str = None
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def is_attachable(self):
|
|
43
|
+
if self.is_cap is MUTATION_DEPENDENT:
|
|
44
|
+
raise TypeError(
|
|
45
|
+
"Can't tell if the block is attachable because we can't be sure if it is a cap block or not (stop block)")
|
|
46
|
+
return not self.is_cap and not self.is_reporter
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class BlockShapes(_EnumWrapper):
|
|
50
|
+
MOTION_MOVESTEPS = BlockShape(is_stack=True, opcode="motion_movesteps")
|
|
51
|
+
MOTION_TURNRIGHT = BlockShape(is_stack=True, opcode="motion_turnright")
|
|
52
|
+
MOTION_TURNLEFT = BlockShape(is_stack=True, opcode="motion_turnleft")
|
|
53
|
+
MOTION_GOTO = BlockShape(is_stack=True, opcode="motion_goto")
|
|
54
|
+
MOTION_GOTOXY = BlockShape(is_stack=True, opcode="motion_gotoxy")
|
|
55
|
+
MOTION_GLIDETO = BlockShape(is_stack=True, opcode="motion_glideto")
|
|
56
|
+
MOTION_GLIDESECSTOXY = BlockShape(is_stack=True, opcode="motion_glidesecstoxy")
|
|
57
|
+
MOTION_POINTINDIRECTION = BlockShape(is_stack=True, opcode="motion_pointindirection")
|
|
58
|
+
MOTION_POINTTOWARDS = BlockShape(is_stack=True, opcode="motion_pointtowards")
|
|
59
|
+
MOTION_CHANGEXBY = BlockShape(is_stack=True, opcode="motion_changexby")
|
|
60
|
+
MOTION_SETX = BlockShape(is_stack=True, opcode="motion_setx")
|
|
61
|
+
MOTION_CHANGEYBY = BlockShape(is_stack=True, opcode="motion_changeyby")
|
|
62
|
+
MOTION_SETY = BlockShape(is_stack=True, opcode="motion_sety")
|
|
63
|
+
MOTION_IFONEDGEBOUNCE = BlockShape(is_stack=True, opcode="motion_ifonedgebounce")
|
|
64
|
+
MOTION_SETROTATIONSTYLE = BlockShape(is_stack=True, opcode="motion_setrotationstyle")
|
|
65
|
+
MOTION_XPOSITION = BlockShape(is_reporter=True, opcode="motion_xposition")
|
|
66
|
+
MOTION_YPOSITION = BlockShape(is_reporter=True, opcode="motion_yposition")
|
|
67
|
+
MOTION_DIRECTION = BlockShape(is_reporter=True, opcode="motion_direction")
|
|
68
|
+
MOTION_SCROLL_RIGHT = BlockShape(is_stack=True, opcode="motion_scroll_right")
|
|
69
|
+
MOTION_SCROLL_UP = BlockShape(is_stack=True, opcode="motion_scroll_up")
|
|
70
|
+
MOTION_ALIGN_SCENE = BlockShape(is_stack=True, opcode="motion_align_scene")
|
|
71
|
+
MOTION_XSCROLL = BlockShape(is_reporter=True, opcode="motion_xscroll")
|
|
72
|
+
MOTION_YSCROLL = BlockShape(is_reporter=True, opcode="motion_yscroll")
|
|
73
|
+
MOTION_GOTO_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="motion_goto_menu")
|
|
74
|
+
MOTION_GLIDETO_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="motion_glideto_menu")
|
|
75
|
+
MOTION_POINTTOWARDS_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="motion_pointtowards_menu")
|
|
76
|
+
|
|
77
|
+
LOOKS_SAYFORSECS = BlockShape(is_stack=True, opcode="looks_sayforsecs")
|
|
78
|
+
LOOKS_SAY = BlockShape(is_stack=True, opcode="looks_say")
|
|
79
|
+
LOOKS_THINKFORSECS = BlockShape(is_stack=True, opcode="looks_thinkforsecs")
|
|
80
|
+
LOOKS_THINK = BlockShape(is_stack=True, opcode="looks_think")
|
|
81
|
+
LOOKS_SWITCHCOSTUMETO = BlockShape(is_stack=True, opcode="looks_switchcostumeto")
|
|
82
|
+
LOOKS_NEXTCOSTUME = BlockShape(is_stack=True, opcode="looks_nextcostume")
|
|
83
|
+
LOOKS_SWITCHBACKDROPTO = BlockShape(is_stack=True, opcode="looks_switchbackdropto")
|
|
84
|
+
LOOKS_SWITCHBACKDROPTOANDWAIT = BlockShape(is_stack=True, opcode="looks_switchbackdroptoandwait")
|
|
85
|
+
LOOKS_NEXTBACKDROP = BlockShape(is_stack=True, opcode="looks_nextbackdrop")
|
|
86
|
+
LOOKS_CHANGESIZEBY = BlockShape(is_stack=True, opcode="looks_changesizeby")
|
|
87
|
+
LOOKS_SETSIZETO = BlockShape(is_stack=True, opcode="looks_setsizeto")
|
|
88
|
+
LOOKS_CHANGEEFFECTBY = BlockShape(is_stack=True, opcode="looks_changeeffectby")
|
|
89
|
+
LOOKS_SETEFFECTTO = BlockShape(is_stack=True, opcode="looks_seteffectto")
|
|
90
|
+
LOOKS_CLEARGRAPHICEFFECTS = BlockShape(is_stack=True, opcode="looks_cleargraphiceffects")
|
|
91
|
+
LOOKS_SHOW = BlockShape(is_stack=True, opcode="looks_show")
|
|
92
|
+
LOOKS_HIDE = BlockShape(is_stack=True, opcode="looks_hide")
|
|
93
|
+
LOOKS_GOTOFRONTBACK = BlockShape(is_stack=True, opcode="looks_gotofrontback")
|
|
94
|
+
LOOKS_GOFORWARDBACKWARDLAYERS = BlockShape(is_stack=True, opcode="looks_goforwardbackwardlayers")
|
|
95
|
+
LOOKS_COSTUMENUMBERNAME = BlockShape(is_reporter=True, opcode="looks_costumenumbername")
|
|
96
|
+
LOOKS_BACKDROPNUMBERNAME = BlockShape(is_reporter=True, opcode="looks_backdropnumbername")
|
|
97
|
+
LOOKS_SIZE = BlockShape(is_reporter=True, opcode="looks_size")
|
|
98
|
+
LOOKS_HIDEALLSPRITES = BlockShape(is_stack=True, opcode="looks_hideallsprites")
|
|
99
|
+
LOOKS_SETSTRETCHTO = BlockShape(is_stack=True, opcode="looks_setstretchto")
|
|
100
|
+
LOOKS_CHANGESTRETCHBY = BlockShape(is_stack=True, opcode="looks_changestretchby")
|
|
101
|
+
LOOKS_COSTUME = BlockShape(is_reporter=True, is_menu=True, opcode="looks_costume")
|
|
102
|
+
LOOKS_BACKDROPS = BlockShape(is_reporter=True, is_menu=True, opcode="looks_backdrops")
|
|
103
|
+
|
|
104
|
+
SOUND_PLAYUNTILDONE = BlockShape(is_stack=True, opcode="sound_playuntildone")
|
|
105
|
+
SOUND_PLAY = BlockShape(is_stack=True, opcode="sound_play")
|
|
106
|
+
SOUND_STOPALLSOUNDS = BlockShape(is_stack=True, opcode="sound_stopallsounds")
|
|
107
|
+
SOUND_CHANGEEFFECTBY = BlockShape(is_stack=True, opcode="sound_changeeffectby")
|
|
108
|
+
SOUND_SETEFFECTTO = BlockShape(is_stack=True, opcode="sound_seteffectto")
|
|
109
|
+
SOUND_CLEAREFFECTS = BlockShape(is_stack=True, opcode="sound_cleareffects")
|
|
110
|
+
SOUND_CHANGEVOLUMEBY = BlockShape(is_stack=True, opcode="sound_changevolumeby")
|
|
111
|
+
SOUND_SETVOLUMETO = BlockShape(is_stack=True, opcode="sound_setvolumeto")
|
|
112
|
+
SOUND_VOLUME = BlockShape(is_reporter=True, opcode="sound_volume")
|
|
113
|
+
SOUND_SOUNDS_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="sound_sounds_menu")
|
|
114
|
+
|
|
115
|
+
EVENT_WHENFLAGCLICKED = BlockShape(is_hat=True, opcode="event_whenflagclicked")
|
|
116
|
+
EVENT_WHENKEYPRESSED = BlockShape(is_hat=True, opcode="event_whenkeypressed")
|
|
117
|
+
EVENT_WHENTHISSPRITECLICKED = BlockShape(is_hat=True, opcode="event_whenthisspriteclicked")
|
|
118
|
+
EVENT_WHENSTAGECLICKED = BlockShape(is_hat=True, opcode="event_whenstageclicked")
|
|
119
|
+
EVENT_WHENBACKDROPSWITCHESTO = BlockShape(is_hat=True, opcode="event_whenbackdropswitchesto")
|
|
120
|
+
EVENT_WHENGREATERTHAN = BlockShape(is_hat=True, opcode="event_whengreaterthan")
|
|
121
|
+
EVENT_WHENBROADCASTRECEIVED = BlockShape(is_hat=True, opcode="event_whenbroadcastreceived")
|
|
122
|
+
EVENT_BROADCAST = BlockShape(is_stack=True, opcode="event_broadcast")
|
|
123
|
+
EVENT_BROADCASTANDWAIT = BlockShape(is_stack=True, opcode="event_broadcastandwait")
|
|
124
|
+
EVENT_WHENTOUCHINGOBJECT = BlockShape(is_hat=True, opcode="event_whentouchingobject")
|
|
125
|
+
EVENT_BROADCAST_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="event_broadcast_menu")
|
|
126
|
+
EVENT_TOUCHINGOBJECTMENU = BlockShape(is_reporter=True, is_menu=True, opcode="event_touchingobjectmenu")
|
|
127
|
+
|
|
128
|
+
CONTROL_WAIT = BlockShape(is_stack=True, opcode="control_wait")
|
|
129
|
+
CONTROL_FOREVER = BlockShape(is_c_mouth=True, is_stack=True, is_cap=True, opcode="control_forever")
|
|
130
|
+
CONTROL_IF = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_if")
|
|
131
|
+
CONTROL_IF_ELSE = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_if_else")
|
|
132
|
+
CONTROL_WAIT_UNTIL = BlockShape(is_stack=True, opcode="control_wait_until")
|
|
133
|
+
CONTROL_REPEAT_UNTIL = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_repeat_until")
|
|
134
|
+
CONTROL_STOP = BlockShape(is_stack=True, is_cap=MUTATION_DEPENDENT, opcode="control_stop")
|
|
135
|
+
CONTROL_START_AS_CLONE = BlockShape(is_hat=True, opcode="control_start_as_clone")
|
|
136
|
+
CONTROL_CREATE_CLONE_OF = BlockShape(is_stack=True, opcode="control_create_clone_of")
|
|
137
|
+
CONTROL_DELETE_THIS_CLONE = BlockShape(is_stack=True, is_cap=True, opcode="control_delete_this_clone")
|
|
138
|
+
CONTROL_FOR_EACH = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_for_each")
|
|
139
|
+
CONTROL_WHILE = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_while")
|
|
140
|
+
CONTROL_GET_COUNTER = BlockShape(is_reporter=True, opcode="control_get_counter")
|
|
141
|
+
CONTROL_INCR_COUNTER = BlockShape(is_stack=True, opcode="control_incr_counter")
|
|
142
|
+
CONTROL_CLEAR_COUNTER = BlockShape(is_stack=True, opcode="control_clear_counter")
|
|
143
|
+
CONTROL_ALL_AT_ONCE = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_all_at_once")
|
|
144
|
+
CONTROL_CREATE_CLONE_OF_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="control_create_clone_of_menu")
|
|
145
|
+
|
|
146
|
+
SENSING_TOUCHINGOBJECT = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_touchingobject")
|
|
147
|
+
SENSING_TOUCHINGCOLOR = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_touchingcolor")
|
|
148
|
+
SENSING_COLORISTOUCHINGCOLOR = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_coloristouchingcolor")
|
|
149
|
+
SENSING_DISTANCETO = BlockShape(is_reporter=True, opcode="sensing_distanceto")
|
|
150
|
+
SENSING_ASKANDWAIT = BlockShape(is_stack=True, opcode="sensing_askandwait")
|
|
151
|
+
SENSING_ANSWER = BlockShape(is_reporter=True, opcode="sensing_answer")
|
|
152
|
+
SENSING_KEYPRESSED = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_keypressed")
|
|
153
|
+
SENSING_MOUSEDOWN = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_mousedown")
|
|
154
|
+
SENSING_MOUSEX = BlockShape(is_reporter=True, opcode="sensing_mousex")
|
|
155
|
+
SENSING_MOUSEY = BlockShape(is_reporter=True, opcode="sensing_mousey")
|
|
156
|
+
SENSING_SETDRAGMODE = BlockShape(is_stack=True, opcode="sensing_setdragmode")
|
|
157
|
+
SENSING_LOUDNESS = BlockShape(is_reporter=True, opcode="sensing_loudness")
|
|
158
|
+
SENSING_TIMER = BlockShape(is_reporter=True, opcode="sensing_timer")
|
|
159
|
+
SENSING_RESETTIMER = BlockShape(is_stack=True, opcode="sensing_resettimer")
|
|
160
|
+
SENSING_OF = BlockShape(is_reporter=True, opcode="sensing_of")
|
|
161
|
+
SENSING_CURRENT = BlockShape(is_reporter=True, opcode="sensing_current")
|
|
162
|
+
SENSING_DAYSSINCE2000 = BlockShape(is_reporter=True, opcode="sensing_dayssince2000")
|
|
163
|
+
SENSING_USERNAME = BlockShape(is_reporter=True, opcode="sensing_username")
|
|
164
|
+
SENSING_LOUD = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_loud")
|
|
165
|
+
SENSING_USERID = BlockShape(is_reporter=True, opcode="sensing_userid")
|
|
166
|
+
SENSING_TOUCHINGOBJECTMENU = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_touchingobjectmenu")
|
|
167
|
+
SENSING_DISTANCETOMENU = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_distancetomenu")
|
|
168
|
+
SENSING_KEYOPTIONS = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_keyoptions")
|
|
169
|
+
SENSING_OF_OBJECT_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_of_object_menu")
|
|
170
|
+
|
|
171
|
+
OPERATOR_ADD = BlockShape(is_reporter=True, opcode="operator_add")
|
|
172
|
+
OPERATOR_SUBTRACT = BlockShape(is_reporter=True, opcode="operator_subtract")
|
|
173
|
+
OPERATOR_MULTIPLY = BlockShape(is_reporter=True, opcode="operator_multiply")
|
|
174
|
+
OPERATOR_DIVIDE = BlockShape(is_reporter=True, opcode="operator_divide")
|
|
175
|
+
OPERATOR_RANDOM = BlockShape(is_reporter=True, opcode="operator_random")
|
|
176
|
+
OPERATOR_GT = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_gt")
|
|
177
|
+
OPERATOR_LT = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_lt")
|
|
178
|
+
OPERATOR_EQUALS = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_equals")
|
|
179
|
+
OPERATOR_AND = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_and")
|
|
180
|
+
OPERATOR_OR = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_or")
|
|
181
|
+
OPERATOR_NOT = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_not")
|
|
182
|
+
OPERATOR_JOIN = BlockShape(is_reporter=True, opcode="operator_join")
|
|
183
|
+
OPERATOR_LETTER_OF = BlockShape(is_reporter=True, opcode="operator_letter_of")
|
|
184
|
+
OPERATOR_LENGTH = BlockShape(is_reporter=True, opcode="operator_length")
|
|
185
|
+
OPERATOR_CONTAINS = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_contains")
|
|
186
|
+
OPERATOR_MOD = BlockShape(is_reporter=True, opcode="operator_mod")
|
|
187
|
+
OPERATOR_ROUND = BlockShape(is_reporter=True, opcode="operator_round")
|
|
188
|
+
OPERATOR_MATHOP = BlockShape(is_reporter=True, opcode="operator_mathop")
|
|
189
|
+
|
|
190
|
+
DATA_VARIABLE = BlockShape(is_reporter=True, opcode="data_variable")
|
|
191
|
+
DATA_SETVARIABLETO = BlockShape(is_stack=True, opcode="data_setvariableto")
|
|
192
|
+
DATA_CHANGEVARIABLEBY = BlockShape(is_stack=True, opcode="data_changevariableby")
|
|
193
|
+
DATA_SHOWVARIABLE = BlockShape(is_stack=True, opcode="data_showvariable")
|
|
194
|
+
DATA_HIDEVARIABLE = BlockShape(is_stack=True, opcode="data_hidevariable")
|
|
195
|
+
DATA_LISTCONTENTS = BlockShape(is_reporter=True, opcode="data_listcontents")
|
|
196
|
+
DATA_ADDTOLIST = BlockShape(is_stack=True, opcode="data_addtolist")
|
|
197
|
+
DATA_DELETEOFLIST = BlockShape(is_stack=True, opcode="data_deleteoflist")
|
|
198
|
+
DATA_DELETEALLOFLIST = BlockShape(is_stack=True, opcode="data_deletealloflist")
|
|
199
|
+
DATA_INSERTATLIST = BlockShape(is_stack=True, opcode="data_insertatlist")
|
|
200
|
+
DATA_REPLACEITEMOFLIST = BlockShape(is_stack=True, opcode="data_replaceitemoflist")
|
|
201
|
+
DATA_ITEMOFLIST = BlockShape(is_reporter=True, is_boolean=True, opcode="data_itemoflist")
|
|
202
|
+
DATA_ITEMNUMOFLIST = BlockShape(is_reporter=True, opcode="data_itemnumoflist")
|
|
203
|
+
DATA_LENGTHOFLIST = BlockShape(is_reporter=True, opcode="data_lengthoflist")
|
|
204
|
+
DATA_LISTCONTAINSITEM = BlockShape(is_reporter=True, is_boolean=True, opcode="data_listcontainsitem")
|
|
205
|
+
DATA_SHOWLIST = BlockShape(is_stack=True, opcode="data_showlist")
|
|
206
|
+
DATA_HIDELIST = BlockShape(is_stack=True, opcode="data_hidelist")
|
|
207
|
+
DATA_LISTINDEXALL = BlockShape(is_reporter=True, is_menu=True, opcode="data_listindexall")
|
|
208
|
+
DATA_LISTINDEXRANDOM = BlockShape(is_reporter=True, is_menu=True, opcode="data_listindexrandom")
|
|
209
|
+
|
|
210
|
+
PROCEDURES_DEFINITION = BlockShape(is_hat=True, opcode="procedures_definition")
|
|
211
|
+
PROCEDURES_CALL = BlockShape(is_stack=True, opcode="procedures_call")
|
|
212
|
+
PROCEDURES_DECLARATION = BlockShape(is_stack=True, opcode="procedures_declaration")
|
|
213
|
+
PROCEDURES_PROTOTYPE = BlockShape(is_stack=True, opcode="procedures_prototype")
|
|
214
|
+
|
|
215
|
+
ARGUMENT_REPORTER_STRING_NUMBER = BlockShape(is_reporter=True, opcode="argument_reporter_string_number")
|
|
216
|
+
ARGUMENT_REPORTER_BOOLEAN = BlockShape(is_reporter=True, is_boolean=True, opcode="argument_reporter_boolean")
|
|
217
|
+
ARGUMENT_EDITOR_REPORTER = BlockShape(is_reporter=True, is_boolean=True, opcode="argument_editor_reporter")
|
|
218
|
+
ARGUMENT_EDITOR_STRING_NUMBER = BlockShape(is_reporter=True, opcode="argument_editor_string_number")
|
|
219
|
+
|
|
220
|
+
MUSIC_PLAYDRUMFORBEATS = BlockShape(is_stack=True, opcode="music_playDrumForBeats")
|
|
221
|
+
MUSIC_RESTFORBEATS = BlockShape(is_stack=True, opcode="music_restForBeats")
|
|
222
|
+
MUSIC_PLAYNOTEFORBEATS = BlockShape(is_stack=True, opcode="music_playNoteForBeats")
|
|
223
|
+
MUSIC_SETINSTRUMENT = BlockShape(is_stack=True, opcode="music_setInstrument")
|
|
224
|
+
MUSIC_SETTEMPO = BlockShape(is_stack=True, opcode="music_setTempo")
|
|
225
|
+
MUSIC_CHANGETEMPO = BlockShape(is_stack=True, opcode="music_changeTempo")
|
|
226
|
+
MUSIC_GETTEMPO = BlockShape(is_reporter=True, opcode="music_getTempo")
|
|
227
|
+
MUSIC_MIDIPLAYDRUMFORBEATS = BlockShape(is_stack=True, opcode="music_midiPlayDrumForBeats")
|
|
228
|
+
MUSIC_MIDISETINSTRUMENT = BlockShape(is_stack=True, opcode="music_midiSetInstrument")
|
|
229
|
+
MUSIC_MENU_DRUM = BlockShape(is_reporter=True, is_menu=True, opcode="music_menu_DRUM")
|
|
230
|
+
MUSIC_MENU_INSTRUMENT = BlockShape(is_reporter=True, is_menu=True, opcode="music_menu_INSTRUMENT")
|
|
231
|
+
|
|
232
|
+
PEN_CLEAR = BlockShape(is_stack=True, opcode="pen_clear")
|
|
233
|
+
PEN_STAMP = BlockShape(is_stack=True, opcode="pen_stamp")
|
|
234
|
+
PEN_PENDOWN = BlockShape(is_stack=True, opcode="pen_penDown")
|
|
235
|
+
PEN_PENUP = BlockShape(is_stack=True, opcode="pen_penUp")
|
|
236
|
+
PEN_SETPENCOLORTOCOLOR = BlockShape(is_stack=True, opcode="pen_setPenColorToColor")
|
|
237
|
+
PEN_CHANGEPENCOLORPARAMBY = BlockShape(is_stack=True, opcode="pen_changePenColorParamBy")
|
|
238
|
+
PEN_SETPENCOLORPARAMTO = BlockShape(is_stack=True, opcode="pen_setPenColorParamTo")
|
|
239
|
+
PEN_CHANGEPENSIZEBY = BlockShape(is_stack=True, opcode="pen_changePenSizeBy")
|
|
240
|
+
PEN_SETPENSIZETO = BlockShape(is_stack=True, opcode="pen_setPenSizeTo")
|
|
241
|
+
PEN_SETPENHUETONUMBER = BlockShape(is_stack=True, opcode="pen_setPenHueToNumber")
|
|
242
|
+
PEN_CHANGEPENHUEBY = BlockShape(is_stack=True, opcode="pen_changePenHueBy")
|
|
243
|
+
PEN_SETPENSHADETONUMBER = BlockShape(is_stack=True, opcode="pen_setPenShadeToNumber")
|
|
244
|
+
PEN_CHANGEPENSHADEBY = BlockShape(is_stack=True, opcode="pen_changePenShadeBy")
|
|
245
|
+
PEN_MENU_COLORPARAM = BlockShape(is_reporter=True, is_menu=True, opcode="pen_menu_colorParam")
|
|
246
|
+
|
|
247
|
+
VIDEOSENSING_WHENMOTIONGREATERTHAN = BlockShape(is_hat=True, opcode="videoSensing_whenMotionGreaterThan")
|
|
248
|
+
VIDEOSENSING_VIDEOON = BlockShape(is_reporter=True, opcode="videoSensing_videoOn")
|
|
249
|
+
VIDEOSENSING_VIDEOTOGGLE = BlockShape(is_stack=True, opcode="videoSensing_videoToggle")
|
|
250
|
+
VIDEOSENSING_SETVIDEOTRANSPARENCY = BlockShape(is_stack=True, opcode="videoSensing_setVideoTransparency")
|
|
251
|
+
VIDEOSENSING_MENU_ATTRIBUTE = BlockShape(is_reporter=True, is_menu=True, opcode="videoSensing_menu_ATTRIBUTE")
|
|
252
|
+
VIDEOSENSING_MENU_SUBJECT = BlockShape(is_reporter=True, is_menu=True, opcode="videoSensing_menu_SUBJECT")
|
|
253
|
+
VIDEOSENSING_MENU_VIDEO_STATE = BlockShape(is_reporter=True, is_menu=True, opcode="videoSensing_menu_VIDEO_STATE")
|
|
254
|
+
|
|
255
|
+
TEXT2SPEECH_SPEAKANDWAIT = BlockShape(is_stack=True, opcode="text2speech_speakAndWait")
|
|
256
|
+
TEXT2SPEECH_SETVOICE = BlockShape(is_stack=True, opcode="text2speech_setVoice")
|
|
257
|
+
TEXT2SPEECH_SETLANGUAGE = BlockShape(is_stack=True, opcode="text2speech_setLanguage")
|
|
258
|
+
TEXT2SPEECH_MENU_VOICES = BlockShape(is_reporter=True, is_menu=True, opcode="text2speech_menu_voices")
|
|
259
|
+
TEXT2SPEECH_MENU_LANGUAGES = BlockShape(is_reporter=True, is_menu=True, opcode="text2speech_menu_languages")
|
|
260
|
+
TRANSLATE_GETTRANSLATE = BlockShape(is_reporter=True, opcode="translate_getTranslate")
|
|
261
|
+
TRANSLATE_GETVIEWERLANGUAGE = BlockShape(is_reporter=True, opcode="translate_getViewerLanguage")
|
|
262
|
+
TRANSLATE_MENU_LANGUAGES = BlockShape(is_reporter=True, is_menu=True, opcode="translate_menu_languages")
|
|
263
|
+
|
|
264
|
+
MAKEYMAKEY_WHENMAKEYKEYPRESSED = BlockShape(is_hat=True, opcode="makeymakey_whenMakeyKeyPressed")
|
|
265
|
+
MAKEYMAKEY_WHENCODEPRESSED = BlockShape(is_hat=True, opcode="makeymakey_whenCodePressed")
|
|
266
|
+
MAKEYMAKEY_MENU_KEY = BlockShape(is_reporter=True, is_menu=True, opcode="makeymakey_menu_KEY")
|
|
267
|
+
MAKEYMAKEY_MENU_SEQUENCE = BlockShape(is_reporter=True, is_menu=True, opcode="makeymakey_menu_SEQUENCE")
|
|
268
|
+
|
|
269
|
+
MICROBIT_WHENBUTTONPRESSED = BlockShape(opcode="microbit_whenButtonPressed") # todo: finish this
|
|
270
|
+
MICROBIT_ISBUTTONPRESSED = BlockShape(opcode="microbit_isButtonPressed")
|
|
271
|
+
MICROBIT_WHENGESTURE = BlockShape(opcode="microbit_whenGesture")
|
|
272
|
+
MICROBIT_DISPLAYSYMBOL = BlockShape(opcode="microbit_displaySymbol")
|
|
273
|
+
MICROBIT_DISPLAYTEXT = BlockShape(opcode="microbit_displayText")
|
|
274
|
+
MICROBIT_DISPLAYCLEAR = BlockShape(opcode="microbit_displayClear")
|
|
275
|
+
MICROBIT_WHENTILTED = BlockShape(opcode="microbit_whenTilted")
|
|
276
|
+
MICROBIT_ISTILTED = BlockShape(opcode="microbit_isTilted")
|
|
277
|
+
MICROBIT_GETTILTANGLE = BlockShape(opcode="microbit_getTiltAngle")
|
|
278
|
+
MICROBIT_WHENPINCONNECTED = BlockShape(opcode="microbit_whenPinConnected")
|
|
279
|
+
MICROBIT_MENU_BUTTONS = BlockShape(opcode="microbit_menu_buttons")
|
|
280
|
+
MICROBIT_MENU_GESTURES = BlockShape(opcode="microbit_menu_gestures")
|
|
281
|
+
MICROBIT_MENU_TILTDIRECTIONANY = BlockShape(opcode="microbit_menu_tiltDirectionAny")
|
|
282
|
+
MICROBIT_MENU_TILTDIRECTION = BlockShape(opcode="microbit_menu_tiltDirection")
|
|
283
|
+
MICROBIT_MENU_TOUCHPINS = BlockShape(opcode="microbit_menu_touchPins")
|
|
284
|
+
MICROBIT_MENU_PINSTATE = BlockShape(opcode="microbit_menu_pinState")
|
|
285
|
+
|
|
286
|
+
EV3_MOTORTURNCLOCKWISE = BlockShape(opcode="ev3_motorTurnClockwise")
|
|
287
|
+
EV3_MOTORTURNCOUNTERCLOCKWISE = BlockShape(opcode="ev3_motorTurnCounterClockwise")
|
|
288
|
+
EV3_MOTORSETPOWER = BlockShape(opcode="ev3_motorSetPower")
|
|
289
|
+
EV3_GETMOTORPOSITION = BlockShape(opcode="ev3_getMotorPosition")
|
|
290
|
+
EV3_WHENBUTTONPRESSED = BlockShape(opcode="ev3_whenButtonPressed")
|
|
291
|
+
EV3_WHENDISTANCELESSTHAN = BlockShape(opcode="ev3_whenDistanceLessThan")
|
|
292
|
+
EV3_WHENBRIGHTNESSLESSTHAN = BlockShape(opcode="ev3_whenBrightnessLessThan")
|
|
293
|
+
EV3_BUTTONPRESSED = BlockShape(opcode="ev3_buttonPressed")
|
|
294
|
+
EV3_GETDISTANCE = BlockShape(opcode="ev3_getDistance")
|
|
295
|
+
EV3_GETBRIGHTNESS = BlockShape(opcode="ev3_getBrightness")
|
|
296
|
+
EV3_BEEP = BlockShape(opcode="ev3_beep")
|
|
297
|
+
EV3_MENU_MOTORPORTS = BlockShape(opcode="ev3_menu_motorPorts")
|
|
298
|
+
EV3_MENU_SENSORPORTS = BlockShape(opcode="ev3_menu_sensorPorts")
|
|
299
|
+
|
|
300
|
+
BOOST_MOTORONFOR = BlockShape(opcode="boost_motorOnFor")
|
|
301
|
+
BOOST_MOTORONFORROTATION = BlockShape(opcode="boost_motorOnForRotation")
|
|
302
|
+
BOOST_MOTORON = BlockShape(opcode="boost_motorOn")
|
|
303
|
+
BOOST_MOTOROFF = BlockShape(opcode="boost_motorOff")
|
|
304
|
+
BOOST_SETMOTORPOWER = BlockShape(opcode="boost_setMotorPower")
|
|
305
|
+
BOOST_SETMOTORDIRECTION = BlockShape(opcode="boost_setMotorDirection")
|
|
306
|
+
BOOST_GETMOTORPOSITION = BlockShape(opcode="boost_getMotorPosition")
|
|
307
|
+
BOOST_WHENCOLOR = BlockShape(opcode="boost_whenColor")
|
|
308
|
+
BOOST_SEEINGCOLOR = BlockShape(opcode="boost_seeingColor")
|
|
309
|
+
BOOST_WHENTILTED = BlockShape(opcode="boost_whenTilted")
|
|
310
|
+
BOOST_GETTILTANGLE = BlockShape(opcode="boost_getTiltAngle")
|
|
311
|
+
BOOST_SETLIGHTHUE = BlockShape(opcode="boost_setLightHue")
|
|
312
|
+
BOOST_MENU_MOTOR_ID = BlockShape(opcode="boost_menu_MOTOR_ID")
|
|
313
|
+
BOOST_MENU_MOTOR_DIRECTION = BlockShape(opcode="boost_menu_MOTOR_DIRECTION")
|
|
314
|
+
BOOST_MENU_MOTOR_REPORTER_ID = BlockShape(opcode="boost_menu_MOTOR_REPORTER_ID")
|
|
315
|
+
BOOST_MENU_COLOR = BlockShape(opcode="boost_menu_COLOR")
|
|
316
|
+
BOOST_MENU_TILT_DIRECTION_ANY = BlockShape(opcode="boost_menu_TILT_DIRECTION_ANY")
|
|
317
|
+
BOOST_MENU_TILT_DIRECTION = BlockShape(opcode="boost_menu_TILT_DIRECTION")
|
|
318
|
+
|
|
319
|
+
WEDO2_MOTORONFOR = BlockShape(opcode="wedo2_motorOnFor")
|
|
320
|
+
WEDO2_MOTORON = BlockShape(opcode="wedo2_motorOn")
|
|
321
|
+
WEDO2_MOTOROFF = BlockShape(opcode="wedo2_motorOff")
|
|
322
|
+
WEDO2_STARTMOTORPOWER = BlockShape(opcode="wedo2_startMotorPower")
|
|
323
|
+
WEDO2_SETMOTORDIRECTION = BlockShape(opcode="wedo2_setMotorDirection")
|
|
324
|
+
WEDO2_SETLIGHTHUE = BlockShape(opcode="wedo2_setLightHue")
|
|
325
|
+
WEDO2_WHENDISTANCE = BlockShape(opcode="wedo2_whenDistance")
|
|
326
|
+
WEDO2_WHENTILTED = BlockShape(opcode="wedo2_whenTilted")
|
|
327
|
+
WEDO2_GETDISTANCE = BlockShape(opcode="wedo2_getDistance")
|
|
328
|
+
WEDO2_ISTILTED = BlockShape(opcode="wedo2_isTilted")
|
|
329
|
+
WEDO2_GETTILTANGLE = BlockShape(opcode="wedo2_getTiltAngle")
|
|
330
|
+
WEDO2_PLAYNOTEFOR = BlockShape(opcode="wedo2_playNoteFor")
|
|
331
|
+
WEDO2_MENU_MOTOR_ID = BlockShape(opcode="wedo2_menu_MOTOR_ID")
|
|
332
|
+
WEDO2_MENU_MOTOR_DIRECTION = BlockShape(opcode="wedo2_menu_MOTOR_DIRECTION")
|
|
333
|
+
WEDO2_MENU_OP = BlockShape(opcode="wedo2_menu_OP")
|
|
334
|
+
WEDO2_MENU_TILT_DIRECTION_ANY = BlockShape(opcode="wedo2_menu_TILT_DIRECTION_ANY")
|
|
335
|
+
WEDO2_MENU_TILT_DIRECTION = BlockShape(opcode="wedo2_menu_TILT_DIRECTION")
|
|
336
|
+
|
|
337
|
+
GDXFOR_WHENGESTURE = BlockShape(opcode="gdxfor_whenGesture")
|
|
338
|
+
GDXFOR_WHENFORCEPUSHEDORPULLED = BlockShape(opcode="gdxfor_whenForcePushedOrPulled")
|
|
339
|
+
GDXFOR_GETFORCE = BlockShape(opcode="gdxfor_getForce")
|
|
340
|
+
GDXFOR_WHENTILTED = BlockShape(opcode="gdxfor_whenTilted")
|
|
341
|
+
GDXFOR_ISTILTED = BlockShape(opcode="gdxfor_isTilted")
|
|
342
|
+
GDXFOR_GETTILT = BlockShape(opcode="gdxfor_getTilt")
|
|
343
|
+
GDXFOR_ISFREEFALLING = BlockShape(opcode="gdxfor_isFreeFalling")
|
|
344
|
+
GDXFOR_GETSPINSPEED = BlockShape(opcode="gdxfor_getSpinSpeed")
|
|
345
|
+
GDXFOR_GETACCELERATION = BlockShape(opcode="gdxfor_getAcceleration")
|
|
346
|
+
GDXFOR_MENU_GESTUREOPTIONS = BlockShape(opcode="gdxfor_menu_gestureOptions")
|
|
347
|
+
GDXFOR_MENU_PUSHPULLOPTIONS = BlockShape(opcode="gdxfor_menu_pushPullOptions")
|
|
348
|
+
GDXFOR_MENU_TILTANYOPTIONS = BlockShape(opcode="gdxfor_menu_tiltAnyOptions")
|
|
349
|
+
GDXFOR_MENU_TILTOPTIONS = BlockShape(opcode="gdxfor_menu_tiltOptions")
|
|
350
|
+
GDXFOR_MENU_AXISOPTIONS = BlockShape(opcode="gdxfor_menu_axisOptions")
|
|
351
|
+
|
|
352
|
+
COREEXAMPLE_EXAMPLEOPCODE = BlockShape(is_reporter=True, opcode="coreExample_exampleOpcode")
|
|
353
|
+
COREEXAMPLE_EXAMPLEWITHINLINEIMAGE = BlockShape(is_stack=True, opcode="coreExample_exampleWithInlineImage")
|
|
354
|
+
|
|
355
|
+
NOTE = BlockShape(is_reporter=True, is_menu=True, opcode="note")
|
|
356
|
+
MATRIX = BlockShape(is_reporter=True, is_menu=True, opcode="matrix")
|
|
357
|
+
UNDEFINED = BlockShape(is_hat=True, is_cap=True, opcode="red_hat_block")
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module which stores the 'default' or 'current' selected Sprite/project (stored as a stack) which makes it easier to write scratch code directly in Python
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from typing import Iterable, TYPE_CHECKING, Final, Literal
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from . import sprite, block, prim, comment
|
|
10
|
+
from . import commons
|
|
11
|
+
|
|
12
|
+
# TODO: should deque be used here?
|
|
13
|
+
class _SetSprite(commons.Singleton):
|
|
14
|
+
INSTANCE = 0
|
|
15
|
+
def __repr__(self):
|
|
16
|
+
return f'<Reminder to default your sprite to {current_sprite()}>'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
SPRITE_DEFAULT: Final[Literal[_SetSprite.INSTANCE]] = _SetSprite.INSTANCE
|
|
20
|
+
|
|
21
|
+
_sprite_stack: list[sprite.Sprite] = []
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def stack_add_sprite(_sprite: sprite.Sprite):
|
|
25
|
+
_sprite_stack.append(_sprite)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def current_sprite() -> sprite.Sprite | None:
|
|
29
|
+
"""
|
|
30
|
+
Retrieve the default sprite from the top of the sprite stack
|
|
31
|
+
"""
|
|
32
|
+
if len(_sprite_stack) == 0:
|
|
33
|
+
return None
|
|
34
|
+
return _sprite_stack[-1]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def pop_sprite(_sprite: sprite.Sprite) -> sprite.Sprite | None:
|
|
38
|
+
assert _sprite_stack.pop() == _sprite
|
|
39
|
+
return _sprite
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def add_block(_block: block.Block | prim.Prim) -> block.Block | prim.Prim:
|
|
43
|
+
return current_sprite().add_block(_block)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def add_chain(*chain: Iterable[block.Block | prim.Prim]) -> block.Block | prim.Prim:
|
|
47
|
+
return current_sprite().add_chain(*chain)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def add_comment(_comment: comment.Comment):
|
|
51
|
+
return current_sprite().add_comment(_comment)
|
|
File without changes
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Union, Generic, TypeVar
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from collections.abc import Sequence
|
|
6
|
+
|
|
7
|
+
from lark import Lark, Transformer, Tree, Token, v_args
|
|
8
|
+
from lark.reconstruct import Reconstructor
|
|
9
|
+
|
|
10
|
+
R = TypeVar("R")
|
|
11
|
+
class SupportsRead(ABC, Generic[R]):
|
|
12
|
+
@abstractmethod
|
|
13
|
+
def read(self, size: int | None = -1) -> R:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
LANG_PATH = Path(__file__).parent / "language.lark"
|
|
17
|
+
|
|
18
|
+
lang = Lark(LANG_PATH.read_text(), maybe_placeholders=False)
|
|
19
|
+
reconstructor = Reconstructor(lang)
|
|
20
|
+
|
|
21
|
+
def parse(script: Union[str, bytes, SupportsRead[str], Path]) -> Tree:
|
|
22
|
+
if isinstance(script, Path):
|
|
23
|
+
script = script.read_text()
|
|
24
|
+
if isinstance(script, SupportsRead):
|
|
25
|
+
read_data = script.read()
|
|
26
|
+
assert isinstance(read_data, str)
|
|
27
|
+
script = read_data
|
|
28
|
+
if isinstance(script, bytes):
|
|
29
|
+
script = script.decode("utf-8")
|
|
30
|
+
return lang.parse(script)
|
|
31
|
+
|
|
32
|
+
def unparse(tree: Tree) -> str:
|
|
33
|
+
return reconstructor.reconstruct(tree)
|
|
34
|
+
|
|
35
|
+
class PrettyUnparser(Transformer):
|
|
36
|
+
INDENT_STRING = " "
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def _indent(cls, text):
|
|
40
|
+
if not text:
|
|
41
|
+
return ""
|
|
42
|
+
return "\n".join(cls.INDENT_STRING + line for line in text.splitlines())
|
|
43
|
+
|
|
44
|
+
def PARAM_NAME(self, token):
|
|
45
|
+
return token.value
|
|
46
|
+
|
|
47
|
+
def BLOCK_NAME(self, token):
|
|
48
|
+
return token.value
|
|
49
|
+
|
|
50
|
+
def EVENT(self, token):
|
|
51
|
+
return token.value
|
|
52
|
+
|
|
53
|
+
def CONTROL_BLOCK_NAME(self, token):
|
|
54
|
+
return token.value
|
|
55
|
+
|
|
56
|
+
def _PREPROC_INSTR_CONTENT(self, token):
|
|
57
|
+
return token.value
|
|
58
|
+
|
|
59
|
+
def _COMMMENT_CONTENT(self, token):
|
|
60
|
+
return token.value
|
|
61
|
+
|
|
62
|
+
@v_args(inline=True)
|
|
63
|
+
def hat(self, child):
|
|
64
|
+
return child
|
|
65
|
+
|
|
66
|
+
@v_args(inline=True)
|
|
67
|
+
def param(self, child):
|
|
68
|
+
return child
|
|
69
|
+
|
|
70
|
+
@v_args(inline=True)
|
|
71
|
+
def value_param(self, name):
|
|
72
|
+
return name
|
|
73
|
+
|
|
74
|
+
@v_args(inline=True)
|
|
75
|
+
def bool_param(self, name):
|
|
76
|
+
return f"<{name}>"
|
|
77
|
+
|
|
78
|
+
@v_args(inline=True)
|
|
79
|
+
def event_hat(self, event_name):
|
|
80
|
+
return f"when ({event_name})"
|
|
81
|
+
|
|
82
|
+
def block_hat(self, items):
|
|
83
|
+
name, *params = items
|
|
84
|
+
params_str = ", ".join(params)
|
|
85
|
+
return f"custom_block {name} ({params_str})"
|
|
86
|
+
|
|
87
|
+
@v_args(inline=True)
|
|
88
|
+
def PREPROC_INSTR(self, content):
|
|
89
|
+
return f"{content}"
|
|
90
|
+
|
|
91
|
+
@v_args(inline=True)
|
|
92
|
+
def COMMMENT(self, content):
|
|
93
|
+
return f"{content}"
|
|
94
|
+
|
|
95
|
+
def block(self, items):
|
|
96
|
+
params = []
|
|
97
|
+
inner_blocks = []
|
|
98
|
+
comments = []
|
|
99
|
+
for i in items[1:]:
|
|
100
|
+
if not isinstance(i, Tree):
|
|
101
|
+
continue
|
|
102
|
+
if str(i.data) == "block_content":
|
|
103
|
+
inner_blocks.extend(i.children)
|
|
104
|
+
if str(i.data) == "block_params":
|
|
105
|
+
params.extend(i.children)
|
|
106
|
+
if str(i.data) == "comments":
|
|
107
|
+
comments.extend(i.children)
|
|
108
|
+
block_name = items[0]
|
|
109
|
+
block_text = f"{block_name}({', '.join(params)})" if params or not inner_blocks else f"{block_name}"
|
|
110
|
+
if inner_blocks:
|
|
111
|
+
blocks_content = "\n".join(inner_blocks)
|
|
112
|
+
indented_content = self._indent(blocks_content)
|
|
113
|
+
block_text += f" {{\n{indented_content}\n}}"
|
|
114
|
+
if comments:
|
|
115
|
+
block_text += f" {' '.join(comments)}"
|
|
116
|
+
return block_text
|
|
117
|
+
|
|
118
|
+
def LITERAL_NUMBER(self, number: str):
|
|
119
|
+
return number
|
|
120
|
+
|
|
121
|
+
def expr(self, items):
|
|
122
|
+
text = items[0]
|
|
123
|
+
if len(items) > 1:
|
|
124
|
+
text += f" {' '.join(items[1].children)}"
|
|
125
|
+
return text
|
|
126
|
+
|
|
127
|
+
def low_expr1(self, items):
|
|
128
|
+
text = f"({items[0]})" if " " in items[0] else items[0]
|
|
129
|
+
if len(items) > 1:
|
|
130
|
+
text += f" {' '.join(items[1].children)}"
|
|
131
|
+
return text
|
|
132
|
+
|
|
133
|
+
@v_args(inline=True)
|
|
134
|
+
def low_expr2(self, item):
|
|
135
|
+
return item
|
|
136
|
+
|
|
137
|
+
def addition(self, items):
|
|
138
|
+
return items[0] + " + " + items[1]
|
|
139
|
+
|
|
140
|
+
def subtraction(self, items):
|
|
141
|
+
return items[0] + " - " + items[1]
|
|
142
|
+
|
|
143
|
+
def multiplication(self, items):
|
|
144
|
+
return items[0] + " * " + items[1]
|
|
145
|
+
|
|
146
|
+
def division(self, items):
|
|
147
|
+
return items[0] + " / " + items[1]
|
|
148
|
+
|
|
149
|
+
def top_level_block(self, items):
|
|
150
|
+
first_item = items[0]
|
|
151
|
+
if first_item.startswith("%%") or first_item.startswith("##"):
|
|
152
|
+
return first_item
|
|
153
|
+
|
|
154
|
+
hat, *blocks = items
|
|
155
|
+
blocks_content = "\n".join(blocks)
|
|
156
|
+
indented_content = self._indent(blocks_content)
|
|
157
|
+
return f"{hat} {{\n{indented_content}\n}}"
|
|
158
|
+
|
|
159
|
+
def start(self, items):
|
|
160
|
+
return "\n\n".join(items)
|
|
161
|
+
|
|
162
|
+
def pretty_unparse(tree: Tree):
|
|
163
|
+
return PrettyUnparser().transform(tree)
|
|
164
|
+
|
|
165
|
+
if __name__ == "__main__":
|
|
166
|
+
EXAMPLE_FILE = Path(__file__).parent / "example.txt"
|
|
167
|
+
tree = parse(EXAMPLE_FILE)
|
|
168
|
+
print(tree.pretty())
|
|
169
|
+
print()
|
|
170
|
+
print()
|
|
171
|
+
print(tree)
|
|
172
|
+
print()
|
|
173
|
+
print()
|
|
174
|
+
print(unparse(tree))
|
|
175
|
+
print()
|
|
176
|
+
print()
|
|
177
|
+
print(pretty_unparse(tree))
|
editor/comment.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from . import base, block, sprite, build_defaulting
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Comment(base.IDComponent):
|
|
8
|
+
"""
|
|
9
|
+
Represents a comment in the scratch editor.
|
|
10
|
+
"""
|
|
11
|
+
def __init__(self, _id: Optional[str] = None, _block: Optional[block.Block] = None, x: int = 0, y: int = 0, width: int = 200,
|
|
12
|
+
height: int = 200, minimized: bool = False, text: str = '', *, _block_id: Optional[str] = None,
|
|
13
|
+
_sprite: sprite.Sprite = build_defaulting.SPRITE_DEFAULT, pos: Optional[tuple[int, int]] = None):
|
|
14
|
+
self.block = _block
|
|
15
|
+
self._block_id = _block_id
|
|
16
|
+
"""
|
|
17
|
+
ID of connected block. Will be set to None upon sprite initialization when the block attribute is updated to the relevant Block.
|
|
18
|
+
"""
|
|
19
|
+
if pos is not None:
|
|
20
|
+
x, y = pos
|
|
21
|
+
|
|
22
|
+
self.x = x
|
|
23
|
+
self.y = y
|
|
24
|
+
|
|
25
|
+
self.width = width
|
|
26
|
+
self.height = height
|
|
27
|
+
|
|
28
|
+
self.minimized = minimized
|
|
29
|
+
self.text = text
|
|
30
|
+
|
|
31
|
+
super().__init__(_id, _sprite)
|
|
32
|
+
|
|
33
|
+
def __repr__(self):
|
|
34
|
+
return f"Comment<{self.text[:10]!r}...>"
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def block_id(self):
|
|
38
|
+
"""
|
|
39
|
+
Retrieve the id of the associateed block (if applicable)
|
|
40
|
+
"""
|
|
41
|
+
if self.block is not None:
|
|
42
|
+
return self.block.id
|
|
43
|
+
elif self._block_id is not None:
|
|
44
|
+
return self._block_id
|
|
45
|
+
else:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def from_json(data: tuple[str, dict]):
|
|
50
|
+
assert len(data) == 2
|
|
51
|
+
_id, data = data
|
|
52
|
+
|
|
53
|
+
_block_id = data.get("blockId")
|
|
54
|
+
|
|
55
|
+
x = data.get("x", 0)
|
|
56
|
+
y = data.get("y", 0)
|
|
57
|
+
|
|
58
|
+
width = data.get("width", 100)
|
|
59
|
+
height = data.get("height", 100)
|
|
60
|
+
|
|
61
|
+
minimized = data.get("minimized", False)
|
|
62
|
+
text = data.get("text")
|
|
63
|
+
|
|
64
|
+
ret = Comment(_id, None, x, y, width, height, minimized, text, _block_id=_block_id)
|
|
65
|
+
return ret
|
|
66
|
+
|
|
67
|
+
def to_json(self) -> dict:
|
|
68
|
+
return {
|
|
69
|
+
"blockId": self.block_id,
|
|
70
|
+
"x": self.x, "y": self.y,
|
|
71
|
+
"width": self.width, "height": self.height,
|
|
72
|
+
"minimized": self.minimized,
|
|
73
|
+
"text": self.text,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
def link_using_sprite(self):
|
|
77
|
+
if self._block_id is not None:
|
|
78
|
+
self.block = self.sprite.find_block(self._block_id, "id")
|
|
79
|
+
if self.block is not None:
|
|
80
|
+
self._block_id = None
|