coco-tools 0.18__tar.gz → 0.20__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.
- {coco-tools-0.18/coco_tools.egg-info → coco_tools-0.20}/PKG-INFO +71 -17
- coco-tools-0.18/PKG-INFO → coco_tools-0.20/README.md +58 -27
- {coco-tools-0.18 → coco_tools-0.20}/coco/__init__.py +1 -1
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/compiler.py +16 -2
- coco_tools-0.20/coco/b09/configs.py +37 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/elements.py +70 -22
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/grammar.py +15 -15
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/parser.py +10 -4
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/visitors.py +49 -24
- {coco-tools-0.18 → coco_tools-0.20}/coco/decb_to_b09.py +8 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/maxtoppm.py +1 -1
- {coco-tools-0.18 → coco_tools-0.20}/coco/resources/ecb.b09 +8 -0
- coco-tools-0.18/README.md → coco_tools-0.20/coco_tools.egg-info/PKG-INFO +81 -9
- coco_tools-0.20/coco_tools.egg-info/SOURCES.txt +67 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco_tools.egg-info/requires.txt +2 -0
- coco_tools-0.20/coco_tools.egg-info/top_level.txt +5 -0
- coco_tools-0.20/pyproject.toml +87 -0
- coco_tools-0.20/tests/coco_tests/b09/__init__.py +0 -0
- coco_tools-0.20/tests/coco_tests/b09/test_b09.py +1465 -0
- coco_tools-0.20/tests/coco_tests/b09/test_configs.py +66 -0
- coco_tools-0.20/tests/coco_tests/b09/test_visitors.py +105 -0
- coco_tools-0.20/tests/coco_tests/fixtures/__init__.py +0 -0
- coco_tools-0.20/tests/test_error_handler.py +31 -0
- coco-tools-0.18/coco_tools.egg-info/SOURCES.txt +0 -31
- coco-tools-0.18/coco_tools.egg-info/top_level.txt +0 -1
- coco-tools-0.18/setup.py +0 -66
- {coco-tools-0.18 → coco_tools-0.20}/LICENSE +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/__init__.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/error_handler.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/procbank.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/b09/prog.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/cm3toppm.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/hrstoppm.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/mge_viewer2.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/mgetoppm.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/pixtopgm.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/rattoppm.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/resources/__init__.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/util.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco/veftopng.py +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco_tools.egg-info/dependency_links.txt +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/coco_tools.egg-info/entry_points.txt +0 -0
- {coco-tools-0.18 → coco_tools-0.20}/setup.cfg +0 -0
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: coco-tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20
|
|
4
4
|
Summary: TRS-80 Color Computer Tools
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Keywords: coco
|
|
5
|
+
Author-email: Jamie Cho <jamieleecho@gmail.com>
|
|
6
|
+
License-Expression: GPL-2.0
|
|
7
|
+
Project-URL: Repository, https://github.com/jamieleecho/coco-tools
|
|
8
|
+
Project-URL: Issues, https://github.com/jamieleecho/coco-tools/issues
|
|
9
|
+
Keywords: coco,image,conversion,trs-80,tandy
|
|
10
10
|
Classifier: Development Status :: 3 - Alpha
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Topic :: Software Development :: Build Tools
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
13
|
Classifier: Programming Language :: Python :: 3
|
|
15
14
|
Requires-Python: >=3.9.19
|
|
16
15
|
Description-Content-Type: text/markdown
|
|
17
16
|
License-File: LICENSE
|
|
17
|
+
Requires-Dist: parsimonious>=0.10.0
|
|
18
|
+
Requires-Dist: Pillow>=7.0.0
|
|
19
|
+
Requires-Dist: pypng>=0.0.18
|
|
20
|
+
Requires-Dist: pydantic>=2.0.0
|
|
21
|
+
Requires-Dist: pydantic-yaml>=1.3.0
|
|
22
|
+
Dynamic: license-file
|
|
18
23
|
|
|
19
24
|
# coco-tools
|
|
20
25
|
|
|
@@ -30,35 +35,63 @@ pip install coco-tools
|
|
|
30
35
|
# To install from source
|
|
31
36
|
git clone https://github.com/jamieleecho/coco-tools.git
|
|
32
37
|
cd coco-tools
|
|
33
|
-
|
|
38
|
+
make install-pre-commit
|
|
39
|
+
make install
|
|
34
40
|
```
|
|
35
41
|
|
|
42
|
+
The `Makefile` makes it easy to perform the most common operations:
|
|
43
|
+
* `make all` transpiles several exapmle ECB programs to Basic09
|
|
44
|
+
* `make check-all` runs linting and `uv.lock` checks
|
|
45
|
+
* `make check-lint` checks for linting issues
|
|
46
|
+
* `make check-lock` verifies the `uv.lock` is aligned to `pyproject.toml`
|
|
47
|
+
* `make clean` cleans the virtual environment and caches
|
|
48
|
+
* `make default` runs a default set of checks on the code
|
|
49
|
+
* `make fix-all` formats the code, fixes lint errors and runs locks `uv.lock` to `pyproject.toml`
|
|
50
|
+
* `make fix-format` formats the code
|
|
51
|
+
* `make fix-lint` fixes linting issues
|
|
52
|
+
* `make fix-lint-unsafe` fixes linting issues potentially adding inadvertant bugs
|
|
53
|
+
* `make help` outputs the different make options
|
|
54
|
+
* `make install` build install the distribution
|
|
55
|
+
* `make install-pre-commit` installs pre-commit hooks
|
|
56
|
+
* `make lock` locks `uv.lock` to `pyproject.toml`
|
|
57
|
+
* `make install-pre-commit` installs pre-commit hooks
|
|
58
|
+
* `make run-tests` runs the unit tests
|
|
59
|
+
* `make sync` syncs the python environment with `uv.lock`
|
|
60
|
+
|
|
61
|
+
`.vscode/settings.json` is set so that unit tests can be run without further configuration.
|
|
62
|
+
|
|
36
63
|
## Tools
|
|
37
64
|
|
|
38
65
|
### [decb-to-b09](./README.decb-to-b09.md)
|
|
39
66
|
|
|
40
67
|
```
|
|
41
|
-
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-D] [-w]
|
|
68
|
+
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-s DEFAULT_STRING_STORAGE] [-D] [-w]
|
|
69
|
+
[-c CONFIG_FILE]
|
|
70
|
+
program.bas program.b09
|
|
42
71
|
|
|
43
72
|
Convert a Color BASIC program to a BASIC09 program
|
|
44
73
|
Copyright (c) 2023 by Jamie Cho
|
|
45
|
-
Version: 0.
|
|
74
|
+
Version: 0.18
|
|
46
75
|
|
|
47
76
|
positional arguments:
|
|
48
77
|
program.bas input DECB text program file
|
|
49
78
|
program.b09 output BASIC09 text program file
|
|
50
79
|
|
|
51
|
-
|
|
80
|
+
optional arguments:
|
|
52
81
|
-h, --help show this help message and exit
|
|
53
82
|
--version show program's version number and exit
|
|
54
83
|
-l, --filter-unused-linenum
|
|
55
84
|
Filter out line numbers not referenced by the program
|
|
56
85
|
-z, --dont-initialize-vars
|
|
57
86
|
Don't pre-initialize all variables
|
|
87
|
+
-s DEFAULT_STRING_STORAGE, --default-string-storage DEFAULT_STRING_STORAGE
|
|
88
|
+
Bytes to allocate for each string
|
|
58
89
|
-D, --dont-output-dependencies
|
|
59
90
|
Don't output required dependencies
|
|
60
91
|
-w, --dont-run-width-32
|
|
61
92
|
if set don't run the default width 32
|
|
93
|
+
-c CONFIG_FILE, --config-file CONFIG_FILE
|
|
94
|
+
Optional compiler configuration file
|
|
62
95
|
```
|
|
63
96
|
|
|
64
97
|
### cm3toppm
|
|
@@ -242,18 +275,38 @@ options:
|
|
|
242
275
|
## Developing and Testing
|
|
243
276
|
|
|
244
277
|
```
|
|
278
|
+
# To set up pre-commit checks
|
|
279
|
+
pre-commit install
|
|
280
|
+
|
|
245
281
|
# Build the docker image
|
|
246
|
-
docker
|
|
282
|
+
docker compose build test
|
|
247
283
|
|
|
248
284
|
# Run tests using the source on the docker image
|
|
249
|
-
docker
|
|
285
|
+
docker compose run test
|
|
250
286
|
|
|
251
287
|
# Run tests using the source on the host computer
|
|
252
|
-
docker
|
|
288
|
+
docker compose run testv
|
|
253
289
|
|
|
254
|
-
# To
|
|
290
|
+
# To develop locally
|
|
255
291
|
pip install -r requirements.txt
|
|
256
|
-
|
|
292
|
+
|
|
293
|
+
# Run linting, build example disk images for basic conversion
|
|
294
|
+
make
|
|
295
|
+
|
|
296
|
+
# Remove built artifacts
|
|
297
|
+
make clean
|
|
298
|
+
|
|
299
|
+
# Reformats the code
|
|
300
|
+
make format
|
|
301
|
+
|
|
302
|
+
# Only runs linting
|
|
303
|
+
make lint
|
|
304
|
+
|
|
305
|
+
# Only run tests
|
|
306
|
+
make test
|
|
307
|
+
|
|
308
|
+
# Build basic and os-9 eample images
|
|
309
|
+
make basic.dsk os9boot.dsk
|
|
257
310
|
```
|
|
258
311
|
|
|
259
312
|
## Credits
|
|
@@ -263,6 +316,7 @@ The programs in the examples/decb and examples/other-decb-examples-to-try direct
|
|
|
263
316
|
* banner.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/banner.c10
|
|
264
317
|
* cadnza.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cadnza.c10
|
|
265
318
|
* cflip.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cflip.c10
|
|
319
|
+
* flip.bas -- https://github.com/daftspaniel/RetroCornerRedux/blob/main/Dragon/Originals/FlipBits/flip.bas
|
|
266
320
|
* loops.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
|
|
267
321
|
* f15eagle.bas -- https://colorcomputerarchive.com/repo/Disks/Magazines/Rainbow%20On%20Disk.zip
|
|
268
322
|
* mars.bas -- https://github.com/jggames/trs80mc10/tree/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Text%20Adventures/WorkInProgress/Mars
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: coco-tools
|
|
3
|
-
Version: 0.18
|
|
4
|
-
Summary: TRS-80 Color Computer Tools
|
|
5
|
-
Home-page: https://github.com/jamieleecho/coco-tools
|
|
6
|
-
Author: Jamie Cho
|
|
7
|
-
Author-email: jamieleecho+coco_tools@gmail.com
|
|
8
|
-
License: GPLv2
|
|
9
|
-
Keywords: coco image conversion trs-80 tandy
|
|
10
|
-
Classifier: Development Status :: 3 - Alpha
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: Topic :: Software Development :: Build Tools
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Requires-Python: >=3.9.19
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
License-File: LICENSE
|
|
18
|
-
|
|
19
1
|
# coco-tools
|
|
20
2
|
|
|
21
3
|
This is a simple collection of tools to assist with developing software for
|
|
@@ -30,35 +12,63 @@ pip install coco-tools
|
|
|
30
12
|
# To install from source
|
|
31
13
|
git clone https://github.com/jamieleecho/coco-tools.git
|
|
32
14
|
cd coco-tools
|
|
33
|
-
|
|
15
|
+
make install-pre-commit
|
|
16
|
+
make install
|
|
34
17
|
```
|
|
35
18
|
|
|
19
|
+
The `Makefile` makes it easy to perform the most common operations:
|
|
20
|
+
* `make all` transpiles several exapmle ECB programs to Basic09
|
|
21
|
+
* `make check-all` runs linting and `uv.lock` checks
|
|
22
|
+
* `make check-lint` checks for linting issues
|
|
23
|
+
* `make check-lock` verifies the `uv.lock` is aligned to `pyproject.toml`
|
|
24
|
+
* `make clean` cleans the virtual environment and caches
|
|
25
|
+
* `make default` runs a default set of checks on the code
|
|
26
|
+
* `make fix-all` formats the code, fixes lint errors and runs locks `uv.lock` to `pyproject.toml`
|
|
27
|
+
* `make fix-format` formats the code
|
|
28
|
+
* `make fix-lint` fixes linting issues
|
|
29
|
+
* `make fix-lint-unsafe` fixes linting issues potentially adding inadvertant bugs
|
|
30
|
+
* `make help` outputs the different make options
|
|
31
|
+
* `make install` build install the distribution
|
|
32
|
+
* `make install-pre-commit` installs pre-commit hooks
|
|
33
|
+
* `make lock` locks `uv.lock` to `pyproject.toml`
|
|
34
|
+
* `make install-pre-commit` installs pre-commit hooks
|
|
35
|
+
* `make run-tests` runs the unit tests
|
|
36
|
+
* `make sync` syncs the python environment with `uv.lock`
|
|
37
|
+
|
|
38
|
+
`.vscode/settings.json` is set so that unit tests can be run without further configuration.
|
|
39
|
+
|
|
36
40
|
## Tools
|
|
37
41
|
|
|
38
42
|
### [decb-to-b09](./README.decb-to-b09.md)
|
|
39
43
|
|
|
40
44
|
```
|
|
41
|
-
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-D] [-w]
|
|
45
|
+
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-s DEFAULT_STRING_STORAGE] [-D] [-w]
|
|
46
|
+
[-c CONFIG_FILE]
|
|
47
|
+
program.bas program.b09
|
|
42
48
|
|
|
43
49
|
Convert a Color BASIC program to a BASIC09 program
|
|
44
50
|
Copyright (c) 2023 by Jamie Cho
|
|
45
|
-
Version: 0.
|
|
51
|
+
Version: 0.18
|
|
46
52
|
|
|
47
53
|
positional arguments:
|
|
48
54
|
program.bas input DECB text program file
|
|
49
55
|
program.b09 output BASIC09 text program file
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
optional arguments:
|
|
52
58
|
-h, --help show this help message and exit
|
|
53
59
|
--version show program's version number and exit
|
|
54
60
|
-l, --filter-unused-linenum
|
|
55
61
|
Filter out line numbers not referenced by the program
|
|
56
62
|
-z, --dont-initialize-vars
|
|
57
63
|
Don't pre-initialize all variables
|
|
64
|
+
-s DEFAULT_STRING_STORAGE, --default-string-storage DEFAULT_STRING_STORAGE
|
|
65
|
+
Bytes to allocate for each string
|
|
58
66
|
-D, --dont-output-dependencies
|
|
59
67
|
Don't output required dependencies
|
|
60
68
|
-w, --dont-run-width-32
|
|
61
69
|
if set don't run the default width 32
|
|
70
|
+
-c CONFIG_FILE, --config-file CONFIG_FILE
|
|
71
|
+
Optional compiler configuration file
|
|
62
72
|
```
|
|
63
73
|
|
|
64
74
|
### cm3toppm
|
|
@@ -242,18 +252,38 @@ options:
|
|
|
242
252
|
## Developing and Testing
|
|
243
253
|
|
|
244
254
|
```
|
|
255
|
+
# To set up pre-commit checks
|
|
256
|
+
pre-commit install
|
|
257
|
+
|
|
245
258
|
# Build the docker image
|
|
246
|
-
docker
|
|
259
|
+
docker compose build test
|
|
247
260
|
|
|
248
261
|
# Run tests using the source on the docker image
|
|
249
|
-
docker
|
|
262
|
+
docker compose run test
|
|
250
263
|
|
|
251
264
|
# Run tests using the source on the host computer
|
|
252
|
-
docker
|
|
265
|
+
docker compose run testv
|
|
253
266
|
|
|
254
|
-
# To
|
|
267
|
+
# To develop locally
|
|
255
268
|
pip install -r requirements.txt
|
|
256
|
-
|
|
269
|
+
|
|
270
|
+
# Run linting, build example disk images for basic conversion
|
|
271
|
+
make
|
|
272
|
+
|
|
273
|
+
# Remove built artifacts
|
|
274
|
+
make clean
|
|
275
|
+
|
|
276
|
+
# Reformats the code
|
|
277
|
+
make format
|
|
278
|
+
|
|
279
|
+
# Only runs linting
|
|
280
|
+
make lint
|
|
281
|
+
|
|
282
|
+
# Only run tests
|
|
283
|
+
make test
|
|
284
|
+
|
|
285
|
+
# Build basic and os-9 eample images
|
|
286
|
+
make basic.dsk os9boot.dsk
|
|
257
287
|
```
|
|
258
288
|
|
|
259
289
|
## Credits
|
|
@@ -263,6 +293,7 @@ The programs in the examples/decb and examples/other-decb-examples-to-try direct
|
|
|
263
293
|
* banner.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/banner.c10
|
|
264
294
|
* cadnza.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cadnza.c10
|
|
265
295
|
* cflip.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cflip.c10
|
|
296
|
+
* flip.bas -- https://github.com/daftspaniel/RetroCornerRedux/blob/main/Dragon/Originals/FlipBits/flip.bas
|
|
266
297
|
* loops.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
|
|
267
298
|
* f15eagle.bas -- https://colorcomputerarchive.com/repo/Disks/Magazines/Rainbow%20On%20Disk.zip
|
|
268
299
|
* mars.bas -- https://github.com/jggames/trs80mc10/tree/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Text%20Adventures/WorkInProgress/Mars
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# __version__ MUST be defined on line 2
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.20"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from pathlib import Path
|
|
1
2
|
from typing import List
|
|
2
3
|
|
|
3
4
|
from coco import b09
|
|
@@ -12,6 +13,7 @@ from coco.b09.elements import (
|
|
|
12
13
|
BasicRunCall,
|
|
13
14
|
BasicVar,
|
|
14
15
|
)
|
|
16
|
+
from coco.b09.configs import CompilerConfigs
|
|
15
17
|
from coco.b09.grammar import grammar, PROCNAME_REGEX
|
|
16
18
|
from coco.b09.parser import BasicVisitor
|
|
17
19
|
from coco.b09.procbank import ProcedureBank
|
|
@@ -32,6 +34,7 @@ from coco.b09.visitors import (
|
|
|
32
34
|
LineReferenceVisitor,
|
|
33
35
|
LineZeroFilterVisitor,
|
|
34
36
|
SetDimStringStorageVisitor,
|
|
37
|
+
SetInitializeVisitor,
|
|
35
38
|
StatementCollectorVisitor,
|
|
36
39
|
StrVarAllocatorVisitor,
|
|
37
40
|
VarInitializerVisitor,
|
|
@@ -47,6 +50,7 @@ def convert(
|
|
|
47
50
|
*,
|
|
48
51
|
add_standard_prefix: bool = True,
|
|
49
52
|
add_suffix: bool = True,
|
|
53
|
+
compiler_configs: CompilerConfigs = None,
|
|
50
54
|
default_str_storage: int = b09.DEFAULT_STR_STORAGE,
|
|
51
55
|
default_width32: bool = True,
|
|
52
56
|
filter_unused_linenum: bool = False,
|
|
@@ -55,6 +59,7 @@ def convert(
|
|
|
55
59
|
procname: str = "",
|
|
56
60
|
skip_procedure_headers: bool = False,
|
|
57
61
|
) -> str:
|
|
62
|
+
compiler_configs = compiler_configs or CompilerConfigs()
|
|
58
63
|
tree = grammar.parse(progin)
|
|
59
64
|
bv = BasicVisitor()
|
|
60
65
|
basic_prog: BasicProg = bv.visit(tree)
|
|
@@ -124,7 +129,8 @@ def convert(
|
|
|
124
129
|
basic_prog.visit(BasicFunctionalExpressionPatcherVisitor())
|
|
125
130
|
|
|
126
131
|
set_string_storage_vistor: SetDimStringStorageVisitor = SetDimStringStorageVisitor(
|
|
127
|
-
default_str_storage=default_str_storage
|
|
132
|
+
default_str_storage=default_str_storage,
|
|
133
|
+
string_configs=compiler_configs.string_configs,
|
|
128
134
|
)
|
|
129
135
|
basic_prog.visit(set_string_storage_vistor)
|
|
130
136
|
|
|
@@ -133,9 +139,10 @@ def convert(
|
|
|
133
139
|
basic_prog.visit(dimmed_array_visitor)
|
|
134
140
|
declare_array_visitor = DeclareImplicitArraysVisitor(
|
|
135
141
|
dimmed_var_names=dimmed_array_visitor.dimmed_var_names,
|
|
142
|
+
initialize_vars=initialize_vars,
|
|
136
143
|
)
|
|
137
144
|
basic_prog.visit(declare_array_visitor)
|
|
138
|
-
basic_prog.
|
|
145
|
+
basic_prog.insert_lines_at_beginning(declare_array_visitor.dim_statements)
|
|
139
146
|
|
|
140
147
|
# allocate sufficient string storage
|
|
141
148
|
str_var_allocator: StrVarAllocatorVisitor = StrVarAllocatorVisitor(
|
|
@@ -150,6 +157,8 @@ def convert(
|
|
|
150
157
|
var_initializer = VarInitializerVisitor()
|
|
151
158
|
basic_prog.visit(var_initializer)
|
|
152
159
|
basic_prog.extend_prefix_lines(var_initializer.assignment_lines)
|
|
160
|
+
set_init_visitor = SetInitializeVisitor(initialize_vars)
|
|
161
|
+
basic_prog.visit(set_init_visitor)
|
|
153
162
|
|
|
154
163
|
# remove unused line numbers
|
|
155
164
|
line_ref_visitor = LineReferenceVisitor()
|
|
@@ -238,6 +247,7 @@ def convert_file(
|
|
|
238
247
|
output_program_file: str,
|
|
239
248
|
*,
|
|
240
249
|
add_standard_prefix: bool = True,
|
|
250
|
+
config_file: str = None,
|
|
241
251
|
default_width32: bool = True,
|
|
242
252
|
default_str_storage: int = b09.DEFAULT_STR_STORAGE,
|
|
243
253
|
filter_unused_linenum: bool = False,
|
|
@@ -246,9 +256,13 @@ def convert_file(
|
|
|
246
256
|
procname: str = "",
|
|
247
257
|
) -> None:
|
|
248
258
|
progin = input_program_file.read()
|
|
259
|
+
compiler_configs = (
|
|
260
|
+
CompilerConfigs.load(Path(config_file)) if config_file else CompilerConfigs()
|
|
261
|
+
)
|
|
249
262
|
progout = convert(
|
|
250
263
|
progin,
|
|
251
264
|
add_standard_prefix=add_standard_prefix,
|
|
265
|
+
compiler_configs=compiler_configs,
|
|
252
266
|
default_str_storage=default_str_storage,
|
|
253
267
|
default_width32=default_width32,
|
|
254
268
|
filter_unused_linenum=filter_unused_linenum,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
from pydantic_yaml import parse_yaml_raw_as
|
|
5
|
+
from typing import Dict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class StringConfigs(BaseModel):
|
|
9
|
+
strname_to_size: Dict[str, int] = Field(default_factory=lambda: {})
|
|
10
|
+
|
|
11
|
+
@field_validator("strname_to_size")
|
|
12
|
+
@classmethod
|
|
13
|
+
def check_mappings(cls, val: Dict[str, int]):
|
|
14
|
+
valid_var_regex = re.compile(r"[A-Z][A-Z_0-9]?")
|
|
15
|
+
|
|
16
|
+
for key, sz in val.items():
|
|
17
|
+
assert key.endswith("$") or key.endswith(
|
|
18
|
+
"$()"
|
|
19
|
+
), f"{key} must end with a $ or $()"
|
|
20
|
+
assert key == key.upper(), f"{key} must be all caps"
|
|
21
|
+
var_only = key[: key.find("$")]
|
|
22
|
+
assert 1 <= len(var_only) <= 2, f"{var_only} must be 1 or 2 characters"
|
|
23
|
+
assert valid_var_regex.match(
|
|
24
|
+
var_only
|
|
25
|
+
), f"{var_only} must be a valid BASIC name"
|
|
26
|
+
assert 0 < sz < 32767, f"{sz} for {key} must be between 0 and 32767"
|
|
27
|
+
return val
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CompilerConfigs(BaseModel):
|
|
31
|
+
string_configs: StringConfigs = Field(default_factory=lambda: StringConfigs())
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def load(cls, path: Path) -> "CompilerConfigs":
|
|
35
|
+
with open(path) as handle:
|
|
36
|
+
yaml = handle.read()
|
|
37
|
+
return parse_yaml_raw_as(cls, yaml)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
+
from collections import defaultdict
|
|
2
3
|
from itertools import chain
|
|
3
|
-
from typing import List, Literal, TYPE_CHECKING, Union
|
|
4
|
+
from typing import Dict, List, Literal, TYPE_CHECKING, Union
|
|
4
5
|
|
|
5
6
|
from coco.b09 import DEFAULT_STR_STORAGE
|
|
6
7
|
|
|
@@ -492,7 +493,7 @@ class BasicLine(AbstractBasicConstruct):
|
|
|
492
493
|
|
|
493
494
|
def basic09_text(self, indent_level) -> str:
|
|
494
495
|
if self._is_referenced and self._num is not None:
|
|
495
|
-
return f"{self._num}
|
|
496
|
+
return f"{self._num} {self._statements.basic09_text(indent_level)}"
|
|
496
497
|
return f"{self._statements.basic09_text(indent_level)}"
|
|
497
498
|
|
|
498
499
|
def visit(self, visitor: "BasicConstructVisitor") -> None:
|
|
@@ -826,7 +827,7 @@ class BasicFunctionCall(AbstractBasicExpression):
|
|
|
826
827
|
self._args = args
|
|
827
828
|
|
|
828
829
|
def basic09_text(self, indent_level: int) -> str:
|
|
829
|
-
return f"{self._func}
|
|
830
|
+
return f"{self._func}{self._args.basic09_text(indent_level)}"
|
|
830
831
|
|
|
831
832
|
|
|
832
833
|
class BasicDataStatement(AbstractBasicStatement):
|
|
@@ -969,8 +970,15 @@ class BasicJoystkExpression(BasicFunctionalExpression):
|
|
|
969
970
|
class BasicDimStatement(AbstractBasicStatement):
|
|
970
971
|
_default_str_storage: int
|
|
971
972
|
_dim_vars: List["BasicArrayRef | BasicVar"]
|
|
973
|
+
_initialize_vars: bool
|
|
974
|
+
_strname_to_size: Dict[str, int]
|
|
972
975
|
|
|
973
|
-
def __init__(
|
|
976
|
+
def __init__(
|
|
977
|
+
self,
|
|
978
|
+
dim_vars: List["BasicArrayRef | BasicVar"],
|
|
979
|
+
*,
|
|
980
|
+
initialize_vars: bool = False,
|
|
981
|
+
):
|
|
974
982
|
super().__init__()
|
|
975
983
|
self._default_str_storage = DEFAULT_STR_STORAGE
|
|
976
984
|
self._dim_vars = [
|
|
@@ -990,24 +998,44 @@ class BasicDimStatement(AbstractBasicStatement):
|
|
|
990
998
|
)
|
|
991
999
|
for var in dim_vars
|
|
992
1000
|
]
|
|
1001
|
+
self._initialize_vars = initialize_vars
|
|
1002
|
+
self._strname_to_size = {}
|
|
993
1003
|
|
|
994
1004
|
@property
|
|
995
1005
|
def default_str_storage(self):
|
|
996
1006
|
return self._default_str_storage
|
|
997
1007
|
|
|
1008
|
+
@default_str_storage.setter
|
|
1009
|
+
def default_str_storage(self, val):
|
|
1010
|
+
self._default_str_storage = val
|
|
1011
|
+
|
|
998
1012
|
@property
|
|
999
1013
|
def dim_vars(self) -> List["BasicArrayRef | BasicVar"]:
|
|
1000
1014
|
return self._dim_vars
|
|
1001
1015
|
|
|
1002
|
-
@
|
|
1003
|
-
def
|
|
1004
|
-
self.
|
|
1016
|
+
@property
|
|
1017
|
+
def initialize_vars(self) -> bool:
|
|
1018
|
+
return self._initialize_vars
|
|
1019
|
+
|
|
1020
|
+
@initialize_vars.setter
|
|
1021
|
+
def initialize_vars(self, val: bool) -> None:
|
|
1022
|
+
self._initialize_vars = val
|
|
1023
|
+
|
|
1024
|
+
@property
|
|
1025
|
+
def strname_to_size(self):
|
|
1026
|
+
return self._strname_to_size
|
|
1027
|
+
|
|
1028
|
+
@strname_to_size.setter
|
|
1029
|
+
def strname_to_size(self, val):
|
|
1030
|
+
self._strname_to_size = val
|
|
1005
1031
|
|
|
1006
1032
|
def init_text_for_var(self, dim_var: "BasicArrayRef | BasicVar") -> str:
|
|
1007
1033
|
if isinstance(dim_var, BasicVar):
|
|
1008
1034
|
return BasicStatements(
|
|
1009
1035
|
[
|
|
1010
|
-
BasicAssignment(
|
|
1036
|
+
BasicAssignment(
|
|
1037
|
+
dim_var, BasicLiteral("" if dim_var.is_str_expr else 0)
|
|
1038
|
+
),
|
|
1011
1039
|
],
|
|
1012
1040
|
multi_line=False,
|
|
1013
1041
|
).basic09_text(0)
|
|
@@ -1065,19 +1093,39 @@ class BasicDimStatement(AbstractBasicStatement):
|
|
|
1065
1093
|
)
|
|
1066
1094
|
]
|
|
1067
1095
|
|
|
1068
|
-
|
|
1096
|
+
str_var_names_to_exp = {
|
|
1097
|
+
str_var.name()
|
|
1098
|
+
if isinstance(str_var, BasicVar)
|
|
1099
|
+
else str_var.var.name(): str_var
|
|
1100
|
+
for str_var in str_vars
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
str_var_to_size = {
|
|
1104
|
+
str_var: self.strname_to_size[str_name]
|
|
1105
|
+
if str_name in self.strname_to_size
|
|
1106
|
+
else self.default_str_storage
|
|
1107
|
+
for str_name, str_var in str_var_names_to_exp.items()
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
str_size_to_strs: Dict[int, List[BasicVar | BasicArrayRef]] = defaultdict(list)
|
|
1111
|
+
for var, size in str_var_to_size.items():
|
|
1112
|
+
str_size_to_strs[size].append(var)
|
|
1113
|
+
|
|
1114
|
+
str_vars_text_list: List[str] = [
|
|
1069
1115
|
self._basic09_text(
|
|
1070
|
-
|
|
1071
|
-
""
|
|
1072
|
-
if self.default_str_storage == DEFAULT_STR_STORAGE
|
|
1073
|
-
else f": STRING[{self._default_str_storage}]",
|
|
1116
|
+
list_vars,
|
|
1117
|
+
"" if size == DEFAULT_STR_STORAGE else f": STRING[{size}]",
|
|
1074
1118
|
indent_level,
|
|
1075
1119
|
)
|
|
1076
|
-
|
|
1077
|
-
|
|
1120
|
+
for size, list_vars in str_size_to_strs.items()
|
|
1121
|
+
]
|
|
1122
|
+
|
|
1123
|
+
str_vars_text = (
|
|
1124
|
+
("\n".join(str_vars_text_list) + ("\n" if non_str_vars else ""))
|
|
1125
|
+
if str_vars_text_list
|
|
1078
1126
|
else ""
|
|
1079
1127
|
)
|
|
1080
|
-
non_str_vars_text
|
|
1128
|
+
non_str_vars_text = (
|
|
1081
1129
|
self._basic09_text(non_str_vars, "", indent_level) if non_str_vars else ""
|
|
1082
1130
|
)
|
|
1083
1131
|
|
|
@@ -1089,13 +1137,13 @@ class BasicDimStatement(AbstractBasicStatement):
|
|
|
1089
1137
|
dim_var_text: str = ", ".join(
|
|
1090
1138
|
(dim_var.basic09_text(indent_level) for dim_var in dim_vars)
|
|
1091
1139
|
)
|
|
1092
|
-
|
|
1093
|
-
(
|
|
1094
|
-
self.init_text_for_var(dim_var)
|
|
1095
|
-
for dim_var in dim_vars
|
|
1140
|
+
if self.initialize_vars:
|
|
1141
|
+
init_text = "\n".join(
|
|
1142
|
+
(self.init_text_for_var(dim_var) for dim_var in dim_vars)
|
|
1096
1143
|
)
|
|
1097
|
-
|
|
1098
|
-
|
|
1144
|
+
init_text = "\n" + init_text if init_text else ""
|
|
1145
|
+
else:
|
|
1146
|
+
init_text = ""
|
|
1099
1147
|
|
|
1100
1148
|
return (
|
|
1101
1149
|
f"{super().basic09_text(indent_level)}"
|
|
@@ -49,7 +49,7 @@ QUOTED_STR3_FUNCTION_NAMES = [f'"{name}"' for name in STR3_FUNCTIONS]
|
|
|
49
49
|
|
|
50
50
|
STR_NUM_FUNCTIONS = {
|
|
51
51
|
"ASC": "ASC",
|
|
52
|
-
"VAL": "
|
|
52
|
+
"VAL": "RUN ecb_val",
|
|
53
53
|
"LEN": "LEN",
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -133,7 +133,7 @@ KEYWORDS = "|".join(
|
|
|
133
133
|
"GOSUB",
|
|
134
134
|
"GOTO",
|
|
135
135
|
"HBUFF",
|
|
136
|
-
"
|
|
136
|
+
"HGETHCIRCLE",
|
|
137
137
|
"HCLS",
|
|
138
138
|
"HCOLOR",
|
|
139
139
|
"HEX$",
|
|
@@ -299,8 +299,8 @@ grammar = Grammar(
|
|
|
299
299
|
/ hget_statement
|
|
300
300
|
/ hput_statement
|
|
301
301
|
/ hpaint_statement
|
|
302
|
-
statement2 = ({
|
|
303
|
-
statement3 = ({
|
|
302
|
+
statement2 = ({" / ".join(QUOTED_STATEMENTS2_NAMES)}) space* "(" space* exp space* "," space* exp space* ")" space*
|
|
303
|
+
statement3 = ({" / ".join(QUOTED_STATEMENTS3_NAMES)}) space* "(" space* exp space* "," space* exp space* "," space* exp space* ")" space*
|
|
304
304
|
statements = statement? space* statements_elements space* last_statement?
|
|
305
305
|
last_statement = comment / partial_str_arr_assign / partial_str_assign
|
|
306
306
|
partial_str_arr_assign = "LET"? space* str_array_ref_exp space* "=" space* partial_str_lit
|
|
@@ -342,8 +342,8 @@ grammar = Grammar(
|
|
|
342
342
|
num_power_exp = val_exp space* num_power_sub_exps
|
|
343
343
|
num_power_sub_exps = num_power_sub_exp*
|
|
344
344
|
num_power_sub_exp = ("^" space* val_exp space*)
|
|
345
|
-
func_exp = ({
|
|
346
|
-
func_str_exp = ({
|
|
345
|
+
func_exp = ({" / ".join(QUOTED_FUNCTION_NAMES)}) space* "(" space* exp space* ")" space*
|
|
346
|
+
func_str_exp = ({" / ".join(QUOTED_STR_NUM_FUNCTIONS_NAMES)}) space* "(" space* str_exp space* ")" space*
|
|
347
347
|
val_exp = num_literal
|
|
348
348
|
/ hex_literal
|
|
349
349
|
/ paren_exp
|
|
@@ -363,11 +363,11 @@ grammar = Grammar(
|
|
|
363
363
|
str_exp = str_simple_exp space* str_exp_elements
|
|
364
364
|
str_exp_elements = str_exp_element*
|
|
365
365
|
str_exp_element = "+" space* str_simple_exp space*
|
|
366
|
-
str2_func_exp = ({
|
|
367
|
-
str3_func_exp = ({
|
|
368
|
-
num_str_func_exp = ({
|
|
369
|
-
num_str_func_exp_statements = ({
|
|
370
|
-
str_func_exp_statements = ({
|
|
366
|
+
str2_func_exp = ({" / ".join(QUOTED_STR2_FUNCTION_NAMES)}) space* "(" space* str_exp space* "," space* exp space* ")" space*
|
|
367
|
+
str3_func_exp = ({" / ".join(QUOTED_STR3_FUNCTION_NAMES)}) space* "(" space* str_exp space* "," space* exp space* "," space* exp space* ")" space*
|
|
368
|
+
num_str_func_exp = ({" / ".join(QUOTED_NUM_STR_FUNCTIONS_NAMES)}) space* "(" space* exp space* ")" space*
|
|
369
|
+
num_str_func_exp_statements = ({" / ".join(QUOTED_NUM_STR_FUNCTIONS_TO_STATEMENTS_NAMES)}) space* "(" space* exp space* ")" space*
|
|
370
|
+
str_func_exp_statements = ({" / ".join(QUOTED_STR_FUNCTIONS_TO_STATEMENTS_NAMES)}) space*
|
|
371
371
|
str_simple_exp = str_literal
|
|
372
372
|
/ str2_func_exp
|
|
373
373
|
/ str3_func_exp
|
|
@@ -413,7 +413,7 @@ grammar = Grammar(
|
|
|
413
413
|
linenum_list = linenum space* linenum_list0
|
|
414
414
|
linenum_list0 = linenum_list_elem*
|
|
415
415
|
linenum_list_elem = "," space* linenum space*
|
|
416
|
-
functions = ~r"{
|
|
416
|
+
functions = ~r"{"|".join(FUNCTIONS.keys())}"
|
|
417
417
|
data_statement = "DATA" space* data_elements space*
|
|
418
418
|
data_elements = data_element space* data_elements0
|
|
419
419
|
data_element = data_num_element / data_str_element
|
|
@@ -425,7 +425,7 @@ grammar = Grammar(
|
|
|
425
425
|
data_str_element0 = space* str_literal space*
|
|
426
426
|
data_str_element1 = space* data_str_literal
|
|
427
427
|
data_str_literal = ~r'[^",:\n]*'
|
|
428
|
-
single_kw_statement = ({
|
|
428
|
+
single_kw_statement = ({" / ".join(QUOTED_SINGLE_KEYWORD_STATEMENTS)}) space*
|
|
429
429
|
for_statement = "FOR" space* var space* "=" space* exp space* "TO" space* exp space*
|
|
430
430
|
for_step_statement = "FOR" space* var space* "=" space* exp space* "TO" space* exp space* "STEP" space* exp space*
|
|
431
431
|
next_statement = next_var_statement / next_empty_statement
|
|
@@ -434,8 +434,8 @@ grammar = Grammar(
|
|
|
434
434
|
var_list = var space* var_list_elements
|
|
435
435
|
var_list_elements = var_list_element*
|
|
436
436
|
var_list_element = "," space* var space*
|
|
437
|
-
func_to_statements = ({
|
|
438
|
-
func_to_statements2 = ({
|
|
437
|
+
func_to_statements = ({" / ".join(QUOTED_FUNCTIONS_TO_STATEMENTS_NAMES)}) space* "(" space* exp space* ")" space*
|
|
438
|
+
func_to_statements2 = ({" / ".join(QUOTED_FUNCTIONS_TO_STATEMENTS2_NAMES)}) space* "(" space* exp space* "," space* exp space*")" space*
|
|
439
439
|
joystk_to_statement = "JOYSTK" space* "(" space* exp space* ")" space*
|
|
440
440
|
dim_element0 = (int_literal / int_hex_literal)
|
|
441
441
|
dim_var = (dim_array_var / str_var / var)
|