ArchiCat 0.0.1__tar.gz

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.
archicat-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jasper-91
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: ArchiCat
3
+ Version: 0.0.1
4
+ Summary: Text based Scratch
5
+ Author: jasper-91
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jasper-91/ArchiCat
8
+ Project-URL: Issues, https://github.com/jasper-91/ArchiCat/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: lark
15
+ Requires-Dist: pydantic>=2.0.0
16
+ Dynamic: license-file
17
+
18
+ # ArchiCat - Text-based Scratch
19
+
20
+ ArchiCat is a text-based representation of the visual programming language [Scratch](https://scratch.mit.edu). This project features a transpiler that converts text- into .sb3-Files.
21
+ Its main purpose is simplifying the generation of .sb3-Files by computers.
22
+
23
+ ## Installation
24
+
25
+ The installation of ArchiCat is really simple as it can be installed with `pip`, Python's built-in package manager. It requires Python >= 3.12.
26
+ `python3 -m pip install archicat`
27
+ (The Python command might vary depending on your OS)
28
+
29
+ ## Example
30
+
31
+ ```
32
+ sprite Cat {
33
+ costume CatCostume = "./assets/CatCostume.svg"
34
+
35
+ default {
36
+ x = 0
37
+ y = 0
38
+ }
39
+
40
+ WhenFlagClicked {
41
+ SayForSecs("Hello!",2)
42
+ Repeat(360,{
43
+ TurnLeft(1)
44
+ })
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Limitations
50
+
51
+ ArchiCat does support all blocks included by default in Scratch, but does not support extensions yet. All other major features of Scratch are supported.
@@ -0,0 +1,34 @@
1
+ # ArchiCat - Text-based Scratch
2
+
3
+ ArchiCat is a text-based representation of the visual programming language [Scratch](https://scratch.mit.edu). This project features a transpiler that converts text- into .sb3-Files.
4
+ Its main purpose is simplifying the generation of .sb3-Files by computers.
5
+
6
+ ## Installation
7
+
8
+ The installation of ArchiCat is really simple as it can be installed with `pip`, Python's built-in package manager. It requires Python >= 3.12.
9
+ `python3 -m pip install archicat`
10
+ (The Python command might vary depending on your OS)
11
+
12
+ ## Example
13
+
14
+ ```
15
+ sprite Cat {
16
+ costume CatCostume = "./assets/CatCostume.svg"
17
+
18
+ default {
19
+ x = 0
20
+ y = 0
21
+ }
22
+
23
+ WhenFlagClicked {
24
+ SayForSecs("Hello!",2)
25
+ Repeat(360,{
26
+ TurnLeft(1)
27
+ })
28
+ }
29
+ }
30
+ ```
31
+
32
+ ## Limitations
33
+
34
+ ArchiCat does support all blocks included by default in Scratch, but does not support extensions yet. All other major features of Scratch are supported.
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools >= 77.0.3"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ArchiCat"
7
+ version = "0.0.1"
8
+ authors = [
9
+ { name="jasper-91" },
10
+ ]
11
+ description = "Text based Scratch"
12
+ readme = "README.md"
13
+ requires-python = ">=3.12"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Operating System :: OS Independent",
17
+ ]
18
+ license = "MIT"
19
+ license-files = ["LICEN[CS]E*"]
20
+ dependencies = [
21
+ "lark",
22
+ "pydantic>=2.0.0"
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/jasper-91/ArchiCat"
27
+ Issues = "https://github.com/jasper-91/ArchiCat/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: ArchiCat
3
+ Version: 0.0.1
4
+ Summary: Text based Scratch
5
+ Author: jasper-91
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jasper-91/ArchiCat
8
+ Project-URL: Issues, https://github.com/jasper-91/ArchiCat/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: lark
15
+ Requires-Dist: pydantic>=2.0.0
16
+ Dynamic: license-file
17
+
18
+ # ArchiCat - Text-based Scratch
19
+
20
+ ArchiCat is a text-based representation of the visual programming language [Scratch](https://scratch.mit.edu). This project features a transpiler that converts text- into .sb3-Files.
21
+ Its main purpose is simplifying the generation of .sb3-Files by computers.
22
+
23
+ ## Installation
24
+
25
+ The installation of ArchiCat is really simple as it can be installed with `pip`, Python's built-in package manager. It requires Python >= 3.12.
26
+ `python3 -m pip install archicat`
27
+ (The Python command might vary depending on your OS)
28
+
29
+ ## Example
30
+
31
+ ```
32
+ sprite Cat {
33
+ costume CatCostume = "./assets/CatCostume.svg"
34
+
35
+ default {
36
+ x = 0
37
+ y = 0
38
+ }
39
+
40
+ WhenFlagClicked {
41
+ SayForSecs("Hello!",2)
42
+ Repeat(360,{
43
+ TurnLeft(1)
44
+ })
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Limitations
50
+
51
+ ArchiCat does support all blocks included by default in Scratch, but does not support extensions yet. All other major features of Scratch are supported.
@@ -0,0 +1,27 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/ArchiCat.egg-info/PKG-INFO
5
+ src/ArchiCat.egg-info/SOURCES.txt
6
+ src/ArchiCat.egg-info/dependency_links.txt
7
+ src/ArchiCat.egg-info/requires.txt
8
+ src/ArchiCat.egg-info/top_level.txt
9
+ src/archicat/__init__.py
10
+ src/archicat/__main__.py
11
+ src/archicat/block.py
12
+ src/archicat/cli.py
13
+ src/archicat/components.py
14
+ src/archicat/error.py
15
+ src/archicat/extension.py
16
+ src/archicat/parser.py
17
+ src/archicat/transformer.py
18
+ src/archicat/writer.py
19
+ src/archicat/blocks/arguments.py
20
+ src/archicat/blocks/control.py
21
+ src/archicat/blocks/data.py
22
+ src/archicat/blocks/event.py
23
+ src/archicat/blocks/looks.py
24
+ src/archicat/blocks/motion.py
25
+ src/archicat/blocks/operator.py
26
+ src/archicat/blocks/sensing.py
27
+ src/archicat/blocks/sound.py
@@ -0,0 +1,2 @@
1
+ lark
2
+ pydantic>=2.0.0
@@ -0,0 +1 @@
1
+ archicat
@@ -0,0 +1,16 @@
1
+ from .transformer import ScratchFileBuilder
2
+ from .parser import parse
3
+
4
+ from pathlib import Path
5
+
6
+
7
+ def transpile(source: str,target: Path | str):
8
+ target = str(target)
9
+ builder = ScratchFileBuilder()
10
+ builder.visit(parse(source))
11
+ builder.save(target)
12
+
13
+ def transpile_file(source: Path | str,target: Path | str):
14
+ with open(str(source)) as file:
15
+ transpile(file.read(),target)
16
+
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()
@@ -0,0 +1,200 @@
1
+ from archicat import components
2
+
3
+ from enum import EnumType,Enum
4
+ from typing import Optional,TYPE_CHECKING,Any,Callable,Type,Self
5
+
6
+ if TYPE_CHECKING:
7
+ from .transformer import ScratchFileBuilder
8
+
9
+ class BlockAccessModifier(Enum):
10
+ ALL = 'all'
11
+ STAGE = 'stage'
12
+ SPRITE = 'sprite'
13
+
14
+ def _enum_has_value(enum: EnumType,value: Any) -> bool:
15
+ return value in set(item.value for item in enum)
16
+
17
+
18
+ type Value = str | float | int
19
+
20
+ type InputItem = components.Id | Value | None
21
+
22
+ type FieldOrInput = Callable[[ScratchFileBuilder,InputItem],components.Input | components.Field]
23
+
24
+
25
+ def field(builder: ScratchFileBuilder,value: str,id: Optional[components.Id] = None) -> components.Field:
26
+ return components.Field(value,id)
27
+
28
+ def variable_field(builder: ScratchFileBuilder,name: str) -> components.Field:
29
+ return field(builder,name,builder._get_variable(name))
30
+
31
+ def list_field(builder: ScratchFileBuilder,name: str) -> components.Field:
32
+ return field(builder,name,builder._get_list(name))
33
+
34
+ def message_field(builder: ScratchFileBuilder,name: str) -> components.Field:
35
+ return field(builder,name,builder._get_message(name))
36
+
37
+ def costume_field(builder: ScratchFileBuilder,name: str) -> components.Field:
38
+ return field(builder,name)
39
+
40
+ def sound_field(builder: ScratchFileBuilder,name: str) -> components.Field:
41
+ return field(builder,name)
42
+
43
+ def option_field(options: Optional[Type[EnumType]] = None) -> FieldOrInput:
44
+ def _option_field(builder: ScratchFileBuilder,value: str | Enum) -> components.Field:
45
+ if isinstance(value,options):
46
+ return field(builder,value.value)
47
+ elif isinstance(value,str) and (options is None or _enum_has_value(options,value)):
48
+ return field(builder,value)
49
+ return _option_field
50
+
51
+
52
+ def input(builder: ScratchFileBuilder,type: components.InputType | int,
53
+ value: InputItem,shadow: Optional[InputItem] = None) -> components.Input:
54
+ if isinstance(value,components.Id):
55
+ if isinstance(block := builder._block_by_id(value),components.Block):
56
+ block.parent = builder.parent_block_stack[-1]
57
+ if components.InputType(type) == components.InputType.SHADOW:
58
+ builder._block_by_id(value).shadow = True
59
+ if isinstance(shadow,components.Id):
60
+ builder._block_by_id(value).parent = builder.parent_block_stack[-1]
61
+ builder._block_by_id(value).shadow = True
62
+ return components.Input(type,value,shadow)
63
+
64
+ def bool_input(builder: ScratchFileBuilder,value: components.Id) -> components.Input:
65
+ return input(builder,components.InputType.NO_SHADOW,value)
66
+
67
+ def _value_input(builder: ScratchFileBuilder,type: components.InputType,value: Any) -> components.Input:
68
+ if isinstance(value,components.Id):
69
+ return input(builder,components.InputType.OBSCURED_SHADOW,value,
70
+ components.Value(type,''))
71
+ else:
72
+ return input(builder,components.InputType.SHADOW,
73
+ components.Value(type,value))
74
+
75
+ def int_input(builder: ScratchFileBuilder,value: int | components.Id) -> components.Input:
76
+ return _value_input(builder,components.ValueType.INT,value)
77
+
78
+ def float_input(builder: ScratchFileBuilder,value: float | components.Id) -> components.Input:
79
+ return _value_input(builder,components.ValueType.FLOAT,value)
80
+
81
+ def unsigned_int_input(builder: ScratchFileBuilder,value: int | components.Id) -> components.Input:
82
+ return _value_input(builder,components.ValueType.UNSIGNED_INT,value)
83
+
84
+ def unsigned_float_input(builder: ScratchFileBuilder,value: float | components.Id) -> components.Input:
85
+ return _value_input(builder,components.ValueType.UNSIGNED_FLOAT,value)
86
+
87
+ def angle_input(builder: ScratchFileBuilder,value: float | components.Id) -> components.Input:
88
+ return _value_input(builder,components.ValueType.ANGLE,value)
89
+
90
+ def color_input(builder: ScratchFileBuilder,value: str | components.Id) -> components.Input:
91
+ return _value_input(builder,components.ValueType.COLOR,value)
92
+
93
+ def string_input(builder: ScratchFileBuilder,value: str | components.Id) -> components.Input:
94
+ return _value_input(builder,components.ValueType.STRING,value)
95
+
96
+ def chain_input(builder: ScratchFileBuilder,value: components.Id) -> components.Input:
97
+ return input(builder,components.InputType.NO_SHADOW,value)
98
+
99
+ def costume_input(builder: ScratchFileBuilder,value: components.Id | str) -> components.Input:
100
+ input_block = Block('looks_costume',COSTUME=field)
101
+ if isinstance(value,components.Id):
102
+ return input(builder,components.InputType.OBSCURED_SHADOW,value,
103
+ input_block(builder,builder.current_target.costumes[0].name))
104
+ else:
105
+ return input(builder,components.InputType.SHADOW,input_block(builder,value))
106
+
107
+ def sound_input(builder: ScratchFileBuilder,value: components.Id | str) -> components.Input:
108
+ input_block = Block('sound_sounds_menu',SOUNDS_MENU=field)
109
+ if isinstance(value,components.Id):
110
+ return input(builder,components.InputType.OBSCURED_SHADOW,value,
111
+ input_block(builder,builder.current_target.sounds[0].name))
112
+ else:
113
+ return input(builder,components.InputType.SHADOW,input_block(builder,value))
114
+
115
+ def option_input(options: Type[EnumType],shadow: str | Enum,input_block: Block) -> FieldOrInput:
116
+ def _option_input(builder: ScratchFileBuilder,value: components.Id | str | Enum) -> components.Input:
117
+ if isinstance(value,components.Id):
118
+ return input(builder,components.InputType.OBSCURED_SHADOW,value,input_block(builder,shadow))
119
+ elif isinstance(value,(options,value)):
120
+ return input(builder,components.InputType.SHADOW,input_block(value.value))
121
+ else:
122
+ return input(builder,components.InputType.SHADOW,input_block(value))
123
+ return _option_input
124
+
125
+ def message_input(builder: ScratchFileBuilder,message: components.Id | str) -> components.Input:
126
+ if isinstance(message,components.Id):
127
+ id,name = builder.stage.broadcasts.items()[0]
128
+ return input(builder,components.InputType.OBSCURED_SHADOW,
129
+ message,components.VariableValue(components.VariableType,name,id))
130
+ else:
131
+ return input(builder,components.InputType.SHADOW,
132
+ components.VariableValue(components.VariableType.MESSAGE,message,
133
+ builder._get_message(message)))
134
+
135
+
136
+ class Block:
137
+ opcode: str
138
+ mutation: Optional[components.Mutation] = None
139
+ args: list[tuple[str,FieldOrInput]]
140
+ attached_options: EnumType
141
+
142
+ def __init__(self,opcode: str,mutation: Optional[components.Mutation]=None,**kwargs: FieldOrInput):
143
+ self.opcode = opcode
144
+ self.mutation = mutation
145
+ self.args = kwargs.items()
146
+ self.attached_options = [None] * len(self.args)
147
+
148
+ def attach_options(self,*args: EnumType,**kwargs: EnumType) -> Self:
149
+ self.attached_options[:len(args)] = args
150
+ for name,options in kwargs.items():
151
+ self.attached_options[list(map(lambda arg: arg[0],self.args)).index(name)] = options
152
+ return self
153
+
154
+ def apply_args(self,builder: ScratchFileBuilder,*args: InputItem) -> components.Block:
155
+ inputs = {}
156
+ fields = {}
157
+ for arg,(name,func) in zip(args,self.args):
158
+ arg = func(builder,arg)
159
+ if isinstance(arg,components.Field):
160
+ fields[name] = arg
161
+ elif isinstance(arg,components.Input) and arg[1] is not None:
162
+ inputs[name] = arg
163
+ if self.mutation is None:
164
+ block = components.Block(self.opcode,inputs=inputs,fields=fields)
165
+ else:
166
+ block = components.MutationBlock(self.opcode,inputs=inputs,fields=fields,mutation=self.mutation)
167
+ return block
168
+
169
+ def __call__(self,builder: ScratchFileBuilder,*args: InputItem,id: Optional[components.Id] = None) -> components.Id:
170
+ return builder._register_block(self.apply_args(builder,*args),id)
171
+
172
+
173
+ class Monitor:
174
+ opcode: str
175
+ attached_options: Optional[EnumType]
176
+
177
+ def __init__(self,opcode: str):
178
+ self.opcode = opcode
179
+ self.attached_options = None
180
+
181
+ def attach_options(self,options: EnumType) -> Self:
182
+ self.attached_options = options
183
+ return self
184
+
185
+ def __call__(self,builder: ScratchFileBuilder,x: int = 0,y: int = 0,visible: bool = True) -> components.Monitor:
186
+ return components.ListMonitor(
187
+ self.opcode.split('_',1)[-1],
188
+ self.opcode,
189
+ x=x,
190
+ y=y,
191
+ visible=visible
192
+ )
193
+
194
+
195
+ class SpriteSpecificMonitor(Monitor):
196
+ def __call__(self,builder: ScratchFileBuilder,*args,**kwargs) -> components.Monitor:
197
+ monitor = super().__call__(builder,*args,**kwargs)
198
+ if not builder.current_target.isStage:
199
+ monitor.spriteName = builder.current_target.name
200
+ return monitor
@@ -0,0 +1,10 @@
1
+ from ..block import *
2
+ from ..extension import Extension
3
+
4
+ ARCHICAT_EXTENSION = Extension('arguments')
5
+
6
+ ARCHICAT_EXTENSION.create_reporters(
7
+ Block('argument_reporter_boolean',VALUE=field),
8
+ Block('argument_reporter_string_number',VALUE=field),
9
+ access=BlockAccessModifier.ALL
10
+ )
@@ -0,0 +1,51 @@
1
+ from ..block import *
2
+ from ..extension import Extension
3
+
4
+ from enum import Enum
5
+ from typing import Optional
6
+
7
+ class StopOptions(Enum):
8
+ ALL = 'all'
9
+ THIS_SCRIPT = 'this script'
10
+ OTHER_SCRIPTS = 'other scripts in sprite'
11
+
12
+ class CreateCloneOfOptions(Enum):
13
+ MYSELF = '_myself_'
14
+
15
+ class StopBlock(Block):
16
+ def __call__(self,builder: ScratchFileBuilder,*args: InputItem | StopOptions,id: Optional[components.Id] = None) -> components.Id:
17
+ id = super().__call__(builder,*args,id=id)
18
+ block = builder._block_by_id(id)
19
+ if StopOptions(block.fields['STOP_OPTION'].value) == StopOptions.OTHER_SCRIPTS:
20
+ block.mutation = components.ControlStop()
21
+ else:
22
+ block.mutation = components.ControlStop(hasnext=components.HasNext.FALSE)
23
+ return id
24
+
25
+ ARCHICAT_EXTENSION = Extension('control')
26
+
27
+ ARCHICAT_EXTENSION.create_statements(
28
+ Block('control_wait',DURATION=unsigned_float_input),
29
+ Block('control_repeat',TIMES=unsigned_int_input,SUBSTACK=chain_input),
30
+ Block('control_forever',SUBSTACK=chain_input,
31
+ mutation=components.ControlStop(hasnext=components.HasNext.FALSE)),
32
+ Block('control_if',CONDITION=bool_input,SUBSTACK=chain_input),
33
+ Block('control_if_else',CONDITION=bool_input,SUBSTACK=chain_input,SUBSTACK2=chain_input),
34
+ Block('control_wait_until',CONDITION=bool_input),
35
+ Block('control_repeat_until',CONDITION=bool_input,SUBSTACK=chain_input),
36
+ StopBlock('control_stop',STOP_OPTION=option_field(StopOptions)).attach_options(StopOptions),
37
+ Block('control_create_clone_of',CLONE_OPTION=option_input(CreateCloneOfOptions,CreateCloneOfOptions.MYSELF,
38
+ Block('control_create_clone_of_options',CLONE_OPTIONS=option_field(CreateCloneOfOptions)))
39
+ ).attach_options(CreateCloneOfOptions),
40
+ access=BlockAccessModifier.ALL
41
+ )
42
+
43
+ ARCHICAT_EXTENSION.create_statements(
44
+ Block('control_delete_this_clone',
45
+ mutation=components.ControlStop(hasnext=components.HasNext.FALSE))
46
+ )
47
+
48
+ ARCHICAT_EXTENSION.create_hats(
49
+ Block('control_start_as_clone'),
50
+ access=BlockAccessModifier.SPRITE
51
+ )
@@ -0,0 +1,62 @@
1
+ from ..block import *
2
+ from ..extension import Extension
3
+
4
+
5
+ class VariableMonitor(Monitor):
6
+ def __call__(self,builder: ScratchFileBuilder,variable: str,mode: str = 'default',
7
+ sliderMin: int = 0,sliderMax: int = 100,isDiscrete: bool = True,**kwargs) -> components.Monitor:
8
+ monitor = super().__call__(builder,**kwargs)
9
+ monitor.id = builder._get_variable(variable)
10
+ monitor.params = {'VARIABLE': variable}
11
+ if not builder.current_target.isStage:
12
+ monitor.spriteName = builder.current_target.name
13
+ monitor.mode = mode
14
+ monitor.sliderMin = sliderMin
15
+ monitor.sliderMax = sliderMax
16
+ monitor.isDiscrete = isDiscrete
17
+ return monitor
18
+
19
+ class ListMonitor(Monitor):
20
+ def __call__(self,builder: ScratchFileBuilder,list: str,width: int = 100,height: int = 200,**kwargs) -> components.ListMonitor:
21
+ monitor = super().__call__(builder,**kwargs)
22
+ monitor.id = builder._get_list(list)
23
+ monitor.params = {'LIST': list}
24
+ if not builder.current_target.isStage:
25
+ monitor.spriteName = builder.current_target.name
26
+ monitor.mode = 'list'
27
+ monitor.value = []
28
+ monitor.width = width
29
+ monitor.height = height
30
+ return monitor
31
+
32
+ ARCHICAT_EXTENSION = Extension('data')
33
+
34
+ ARCHICAT_EXTENSION.create_statements(
35
+ Block('data_setvariableto',VARIABLE=variable_field,VALUE=string_input),
36
+ Block('data_changevariableby',VARIABLE=variable_field,VALUE=float_input),
37
+ Block('data_showvariable',VARIABLE=variable_field),
38
+ Block('data_hidevariable',VARIABLE=variable_field),
39
+ Block('data_addtolist',LIST=list_field,ITEM=string_input),
40
+ Block('data_deleteoflist',LIST=list_field,INDEX=unsigned_int_input),
41
+ Block('data_deletealloflist',LIST=list_field),
42
+ Block('data_insertatlist',LIST=list_field,INDEX=unsigned_int_input,ITEM=string_input),
43
+ Block('data_replaceitemoflist',LIST=list_field,INDEX=unsigned_int_input,ITEM=string_input),
44
+ Block('data_showlist',LIST=list_field),
45
+ Block('data_hidelist',LIST=list_field),
46
+ access=BlockAccessModifier.ALL
47
+ )
48
+
49
+ ARCHICAT_EXTENSION.create_reporters(
50
+ Block('data_variable',VARIABLE=variable_field),
51
+ Block('data_listcontents',LIST=list_field),
52
+ Block('data_itemoflist',LIST=list_field,INDEX=unsigned_int_input),
53
+ Block('data_itemnumoflist',LIST=list_field,ITEM=string_input),
54
+ Block('data_lengthoflist',LIST=list_field),
55
+ Block('data_listcontainsitem',LIST=list_field,ITEM=string_input),
56
+ access=BlockAccessModifier.ALL
57
+ )
58
+
59
+ ARCHICAT_EXTENSION.create_monitors(
60
+ VariableMonitor('data_variable'),
61
+ ListMonitor('data_listcontents')
62
+ )
@@ -0,0 +1,36 @@
1
+ from ..block import *
2
+ from ..extension import Extension
3
+
4
+ from enum import Enum
5
+
6
+ class WhenGreaterThanOptions(Enum):
7
+ LOUDNESS = 'LOUDNESS'
8
+ TIMER = 'TIMER'
9
+
10
+ ARCHICAT_EXTENSION = Extension('event')
11
+
12
+ ARCHICAT_EXTENSION.create_statements(
13
+ Block('event_broadcast',BROADCAST_INPUT=message_input),
14
+ Block('event_broadcastandwait',BROADCAST_INPUT=message_input),
15
+ access=BlockAccessModifier.ALL,
16
+ )
17
+
18
+ ARCHICAT_EXTENSION.create_hats(
19
+ Block('event_whenflagclicked'),
20
+ Block('event_whenkeypressed',KEY_OPTION=field),
21
+ Block('event_whenbackdropswitchesto',backdrop=costume_field),
22
+ Block('event_whengreaterthan',WHENGREATERTHANMENU=option_field(WhenGreaterThanOptions),VALUE=unsigned_float_input
23
+ ).attach_options(WhenGreaterThanOptions),
24
+ Block('event_whenbroadcastreceived',BROADCAST_OPTION=message_field),
25
+ access=BlockAccessModifier.ALL,
26
+ )
27
+
28
+ ARCHICAT_EXTENSION.create_hats(
29
+ Block('event_whenthisspriteclicked'),
30
+ access=BlockAccessModifier.SPRITE,
31
+ )
32
+
33
+ ARCHICAT_EXTENSION.create_hats(
34
+ Block('event_whenstageclicked'),
35
+ access=BlockAccessModifier.STAGE,
36
+ )