coco-tools 0.18__tar.gz → 0.19__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-0.19}/PKG-INFO +11 -4
- {coco-tools-0.18 → coco-tools-0.19}/README.md +10 -3
- {coco-tools-0.18 → coco-tools-0.19}/coco/__init__.py +1 -1
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/compiler.py +16 -2
- coco-tools-0.19/coco/b09/configs.py +37 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/elements.py +68 -20
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/grammar.py +1 -1
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/parser.py +9 -3
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/visitors.py +49 -24
- {coco-tools-0.18 → coco-tools-0.19}/coco/decb_to_b09.py +8 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/resources/ecb.b09 +8 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/PKG-INFO +11 -4
- {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/SOURCES.txt +1 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/requires.txt +2 -0
- {coco-tools-0.18 → coco-tools-0.19}/setup.py +3 -1
- {coco-tools-0.18 → coco-tools-0.19}/LICENSE +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/__init__.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/error_handler.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/procbank.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/b09/prog.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/cm3toppm.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/hrstoppm.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/maxtoppm.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/mge_viewer2.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/mgetoppm.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/pixtopgm.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/rattoppm.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/resources/__init__.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/util.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco/veftopng.py +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/dependency_links.txt +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/entry_points.txt +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/top_level.txt +0 -0
- {coco-tools-0.18 → coco-tools-0.19}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: coco-tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19
|
|
4
4
|
Summary: TRS-80 Color Computer Tools
|
|
5
5
|
Home-page: https://github.com/jamieleecho/coco-tools
|
|
6
6
|
Author: Jamie Cho
|
|
@@ -38,27 +38,33 @@ python3 setup.py
|
|
|
38
38
|
### [decb-to-b09](./README.decb-to-b09.md)
|
|
39
39
|
|
|
40
40
|
```
|
|
41
|
-
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-D] [-w]
|
|
41
|
+
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-s DEFAULT_STRING_STORAGE] [-D] [-w]
|
|
42
|
+
[-c CONFIG_FILE]
|
|
43
|
+
program.bas program.b09
|
|
42
44
|
|
|
43
45
|
Convert a Color BASIC program to a BASIC09 program
|
|
44
46
|
Copyright (c) 2023 by Jamie Cho
|
|
45
|
-
Version: 0.
|
|
47
|
+
Version: 0.18
|
|
46
48
|
|
|
47
49
|
positional arguments:
|
|
48
50
|
program.bas input DECB text program file
|
|
49
51
|
program.b09 output BASIC09 text program file
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
optional arguments:
|
|
52
54
|
-h, --help show this help message and exit
|
|
53
55
|
--version show program's version number and exit
|
|
54
56
|
-l, --filter-unused-linenum
|
|
55
57
|
Filter out line numbers not referenced by the program
|
|
56
58
|
-z, --dont-initialize-vars
|
|
57
59
|
Don't pre-initialize all variables
|
|
60
|
+
-s DEFAULT_STRING_STORAGE, --default-string-storage DEFAULT_STRING_STORAGE
|
|
61
|
+
Bytes to allocate for each string
|
|
58
62
|
-D, --dont-output-dependencies
|
|
59
63
|
Don't output required dependencies
|
|
60
64
|
-w, --dont-run-width-32
|
|
61
65
|
if set don't run the default width 32
|
|
66
|
+
-c CONFIG_FILE, --config-file CONFIG_FILE
|
|
67
|
+
Optional compiler configuration file
|
|
62
68
|
```
|
|
63
69
|
|
|
64
70
|
### cm3toppm
|
|
@@ -263,6 +269,7 @@ The programs in the examples/decb and examples/other-decb-examples-to-try direct
|
|
|
263
269
|
* banner.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/banner.c10
|
|
264
270
|
* cadnza.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cadnza.c10
|
|
265
271
|
* cflip.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cflip.c10
|
|
272
|
+
* flip.bas -- https://github.com/daftspaniel/RetroCornerRedux/blob/main/Dragon/Originals/FlipBits/flip.bas
|
|
266
273
|
* loops.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
|
|
267
274
|
* f15eagle.bas -- https://colorcomputerarchive.com/repo/Disks/Magazines/Rainbow%20On%20Disk.zip
|
|
268
275
|
* mars.bas -- https://github.com/jggames/trs80mc10/tree/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Text%20Adventures/WorkInProgress/Mars
|
|
@@ -20,27 +20,33 @@ python3 setup.py
|
|
|
20
20
|
### [decb-to-b09](./README.decb-to-b09.md)
|
|
21
21
|
|
|
22
22
|
```
|
|
23
|
-
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-D] [-w]
|
|
23
|
+
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-s DEFAULT_STRING_STORAGE] [-D] [-w]
|
|
24
|
+
[-c CONFIG_FILE]
|
|
25
|
+
program.bas program.b09
|
|
24
26
|
|
|
25
27
|
Convert a Color BASIC program to a BASIC09 program
|
|
26
28
|
Copyright (c) 2023 by Jamie Cho
|
|
27
|
-
Version: 0.
|
|
29
|
+
Version: 0.18
|
|
28
30
|
|
|
29
31
|
positional arguments:
|
|
30
32
|
program.bas input DECB text program file
|
|
31
33
|
program.b09 output BASIC09 text program file
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
optional arguments:
|
|
34
36
|
-h, --help show this help message and exit
|
|
35
37
|
--version show program's version number and exit
|
|
36
38
|
-l, --filter-unused-linenum
|
|
37
39
|
Filter out line numbers not referenced by the program
|
|
38
40
|
-z, --dont-initialize-vars
|
|
39
41
|
Don't pre-initialize all variables
|
|
42
|
+
-s DEFAULT_STRING_STORAGE, --default-string-storage DEFAULT_STRING_STORAGE
|
|
43
|
+
Bytes to allocate for each string
|
|
40
44
|
-D, --dont-output-dependencies
|
|
41
45
|
Don't output required dependencies
|
|
42
46
|
-w, --dont-run-width-32
|
|
43
47
|
if set don't run the default width 32
|
|
48
|
+
-c CONFIG_FILE, --config-file CONFIG_FILE
|
|
49
|
+
Optional compiler configuration file
|
|
44
50
|
```
|
|
45
51
|
|
|
46
52
|
### cm3toppm
|
|
@@ -245,6 +251,7 @@ The programs in the examples/decb and examples/other-decb-examples-to-try direct
|
|
|
245
251
|
* banner.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/banner.c10
|
|
246
252
|
* cadnza.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cadnza.c10
|
|
247
253
|
* cflip.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cflip.c10
|
|
254
|
+
* flip.bas -- https://github.com/daftspaniel/RetroCornerRedux/blob/main/Dragon/Originals/FlipBits/flip.bas
|
|
248
255
|
* loops.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
|
|
249
256
|
* f15eagle.bas -- https://colorcomputerarchive.com/repo/Disks/Magazines/Rainbow%20On%20Disk.zip
|
|
250
257
|
* 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.19"
|
|
@@ -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
|
|
|
@@ -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)}"
|
|
@@ -518,9 +518,15 @@ class BasicVisitor(NodeVisitor):
|
|
|
518
518
|
|
|
519
519
|
def visit_func_str_exp(self, _, visited_children) -> AbstractBasicExpression:
|
|
520
520
|
func, _, _, _, exp, _, _, _ = visited_children
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
521
|
+
func_name = STR_NUM_FUNCTIONS[func.text]
|
|
522
|
+
if func_name.startswith("RUN "):
|
|
523
|
+
return BasicFunctionalExpression(
|
|
524
|
+
STR_NUM_FUNCTIONS[func.text], BasicExpressionList([exp])
|
|
525
|
+
)
|
|
526
|
+
else:
|
|
527
|
+
return BasicFunctionCall(
|
|
528
|
+
STR_NUM_FUNCTIONS[func.text], BasicExpressionList([exp])
|
|
529
|
+
)
|
|
524
530
|
|
|
525
531
|
def visit_num_assign(self, _, visited_children):
|
|
526
532
|
let_kw, _, var, _, _, _, val = visited_children
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
from typing import Dict, List, Set, TYPE_CHECKING
|
|
2
|
+
|
|
1
3
|
from coco import b09
|
|
4
|
+
from coco.b09.configs import StringConfigs
|
|
2
5
|
from coco.b09.elements import (
|
|
3
6
|
AbstractBasicExpression,
|
|
4
7
|
AbstractBasicStatement,
|
|
@@ -27,8 +30,6 @@ from coco.b09.elements import (
|
|
|
27
30
|
BasicVar,
|
|
28
31
|
)
|
|
29
32
|
|
|
30
|
-
from typing import List, Set, TYPE_CHECKING
|
|
31
|
-
|
|
32
33
|
if TYPE_CHECKING:
|
|
33
34
|
from coco.b09.prog import BasicProg
|
|
34
35
|
|
|
@@ -230,24 +231,28 @@ class VarInitializerVisitor(BasicConstructVisitor):
|
|
|
230
231
|
@property
|
|
231
232
|
def assignment_lines(self) -> List[BasicLine]:
|
|
232
233
|
vars_to_assign = self._vars - self._dimmed_var_names
|
|
233
|
-
return
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
234
|
+
return (
|
|
235
|
+
[
|
|
236
|
+
BasicLine(
|
|
237
|
+
None,
|
|
238
|
+
BasicStatements(
|
|
239
|
+
[
|
|
240
|
+
BasicAssignment(
|
|
241
|
+
BasicVar(var, is_str_expr=var.endswith("$")),
|
|
242
|
+
BasicLiteral(
|
|
243
|
+
"" if var.endswith("$") else 0.0,
|
|
244
|
+
is_str_expr=var.endswith("$"),
|
|
245
|
+
),
|
|
246
|
+
)
|
|
247
|
+
for var in sorted(vars_to_assign)
|
|
248
|
+
if ((var.endswith("$") and len(var) <= 3) or len(var) <= 2)
|
|
249
|
+
]
|
|
250
|
+
),
|
|
251
|
+
)
|
|
252
|
+
]
|
|
253
|
+
if vars_to_assign
|
|
254
|
+
else []
|
|
255
|
+
)
|
|
251
256
|
|
|
252
257
|
def visit_var(self, var) -> None:
|
|
253
258
|
self._vars.add(var.name())
|
|
@@ -301,14 +306,22 @@ class StrVarAllocatorVisitor(BasicConstructVisitor):
|
|
|
301
306
|
class SetDimStringStorageVisitor(BasicConstructVisitor):
|
|
302
307
|
_default_str_storage: int
|
|
303
308
|
_dimmed_var_names: Set[str]
|
|
309
|
+
_string_configs: StringConfigs
|
|
310
|
+
_strname_to_size: Dict[str, int]
|
|
304
311
|
|
|
305
|
-
def __init__(self, *, default_str_storage: int):
|
|
312
|
+
def __init__(self, *, default_str_storage: int, string_configs: StringConfigs):
|
|
306
313
|
self._default_str_storage = default_str_storage
|
|
307
314
|
self._dimmed_var_names = set()
|
|
315
|
+
self.string_configs = string_configs
|
|
316
|
+
self._strname_to_size = {
|
|
317
|
+
var if var.endswith("$") else f"arr_{var[:-3]}$": size
|
|
318
|
+
for var, size in string_configs.strname_to_size.items()
|
|
319
|
+
}
|
|
308
320
|
|
|
309
321
|
def visit_statement(self, statement: BasicStatement) -> None:
|
|
310
322
|
if isinstance(statement, BasicDimStatement):
|
|
311
323
|
statement.default_str_storage = self._default_str_storage
|
|
324
|
+
statement.strname_to_size = self._strname_to_size
|
|
312
325
|
self._dimmed_var_names.update(
|
|
313
326
|
[
|
|
314
327
|
var.name() if isinstance(var, BasicVar) else var.var.name()
|
|
@@ -344,10 +357,12 @@ class GetDimmedArraysVisitor(BasicConstructVisitor):
|
|
|
344
357
|
|
|
345
358
|
class DeclareImplicitArraysVisitor(BasicConstructVisitor):
|
|
346
359
|
_dimmed_var_names: Set[str]
|
|
360
|
+
_initialize_vars: bool
|
|
347
361
|
_referenced_var_names: Set[str]
|
|
348
362
|
|
|
349
|
-
def __init__(self, *, dimmed_var_names: Set[str]):
|
|
363
|
+
def __init__(self, *, dimmed_var_names: Set[str], initialize_vars: bool = False):
|
|
350
364
|
self._dimmed_var_names = dimmed_var_names
|
|
365
|
+
self._initialize_vars = initialize_vars
|
|
351
366
|
self._referenced_var_names = set()
|
|
352
367
|
|
|
353
368
|
def visit_array_ref(self, array_ref: BasicArrayRef) -> None:
|
|
@@ -366,8 +381,9 @@ class DeclareImplicitArraysVisitor(BasicConstructVisitor):
|
|
|
366
381
|
BasicVar(var[4:], is_str_expr=var.endswith("$")),
|
|
367
382
|
BasicExpressionList([BasicLiteral(10)]),
|
|
368
383
|
is_str_expr=var.endswith("$"),
|
|
369
|
-
)
|
|
370
|
-
]
|
|
384
|
+
),
|
|
385
|
+
],
|
|
386
|
+
initialize_vars=self._initialize_vars,
|
|
371
387
|
)
|
|
372
388
|
for var in self.implicitly_declared_arrays
|
|
373
389
|
]
|
|
@@ -521,3 +537,12 @@ class BasicHbuffPresenceVisitor(BasicConstructVisitor):
|
|
|
521
537
|
@property
|
|
522
538
|
def has_hbuff(self) -> bool:
|
|
523
539
|
return self._hasHbuff
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
class SetInitializeVisitor(BasicConstructVisitor):
|
|
543
|
+
def __init__(self, initialize_vars: bool):
|
|
544
|
+
self._initialize_vars = initialize_vars
|
|
545
|
+
|
|
546
|
+
def visit_statement(self, statement: BasicStatement) -> None:
|
|
547
|
+
if isinstance(statement, BasicDimStatement):
|
|
548
|
+
statement.initialize_vars = self._initialize_vars
|
|
@@ -73,6 +73,13 @@ def start(argv):
|
|
|
73
73
|
action="store_true",
|
|
74
74
|
help="if set don't run the default width 32",
|
|
75
75
|
)
|
|
76
|
+
parser.add_argument(
|
|
77
|
+
"-c",
|
|
78
|
+
"--config-file",
|
|
79
|
+
type=str,
|
|
80
|
+
help="Optional compiler configuration file",
|
|
81
|
+
required=False,
|
|
82
|
+
)
|
|
76
83
|
|
|
77
84
|
args = parser.parse_args(argv)
|
|
78
85
|
procname = os.path.splitext(
|
|
@@ -82,6 +89,7 @@ def start(argv):
|
|
|
82
89
|
convert_file(
|
|
83
90
|
args.input_decb_text_program_file,
|
|
84
91
|
args.output_b09_text_program_file,
|
|
92
|
+
config_file=args.config_file,
|
|
85
93
|
default_width32=not args.dont_run_width_32,
|
|
86
94
|
default_str_storage=args.default_string_storage,
|
|
87
95
|
filter_unused_linenum=args.filter_unused_linenum,
|
|
@@ -1005,6 +1005,14 @@ for ii=1 to count
|
|
|
1005
1005
|
next ii
|
|
1006
1006
|
|
|
1007
1007
|
|
|
1008
|
+
PROCEDURE ecb_val
|
|
1009
|
+
PARAM str: STRING
|
|
1010
|
+
PARAM valout: REAL
|
|
1011
|
+
valout = 0.0
|
|
1012
|
+
ON ERROR GOTO 10
|
|
1013
|
+
valout = VAL(str)
|
|
1014
|
+
10 REM
|
|
1015
|
+
|
|
1008
1016
|
procedure _ecb_cursor_color
|
|
1009
1017
|
param v: integer
|
|
1010
1018
|
dim tmp_buffer(2): byte
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: coco-tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19
|
|
4
4
|
Summary: TRS-80 Color Computer Tools
|
|
5
5
|
Home-page: https://github.com/jamieleecho/coco-tools
|
|
6
6
|
Author: Jamie Cho
|
|
@@ -38,27 +38,33 @@ python3 setup.py
|
|
|
38
38
|
### [decb-to-b09](./README.decb-to-b09.md)
|
|
39
39
|
|
|
40
40
|
```
|
|
41
|
-
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-D] [-w]
|
|
41
|
+
usage: decb-to-b09 [-h] [--version] [-l] [-z] [-s DEFAULT_STRING_STORAGE] [-D] [-w]
|
|
42
|
+
[-c CONFIG_FILE]
|
|
43
|
+
program.bas program.b09
|
|
42
44
|
|
|
43
45
|
Convert a Color BASIC program to a BASIC09 program
|
|
44
46
|
Copyright (c) 2023 by Jamie Cho
|
|
45
|
-
Version: 0.
|
|
47
|
+
Version: 0.18
|
|
46
48
|
|
|
47
49
|
positional arguments:
|
|
48
50
|
program.bas input DECB text program file
|
|
49
51
|
program.b09 output BASIC09 text program file
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
optional arguments:
|
|
52
54
|
-h, --help show this help message and exit
|
|
53
55
|
--version show program's version number and exit
|
|
54
56
|
-l, --filter-unused-linenum
|
|
55
57
|
Filter out line numbers not referenced by the program
|
|
56
58
|
-z, --dont-initialize-vars
|
|
57
59
|
Don't pre-initialize all variables
|
|
60
|
+
-s DEFAULT_STRING_STORAGE, --default-string-storage DEFAULT_STRING_STORAGE
|
|
61
|
+
Bytes to allocate for each string
|
|
58
62
|
-D, --dont-output-dependencies
|
|
59
63
|
Don't output required dependencies
|
|
60
64
|
-w, --dont-run-width-32
|
|
61
65
|
if set don't run the default width 32
|
|
66
|
+
-c CONFIG_FILE, --config-file CONFIG_FILE
|
|
67
|
+
Optional compiler configuration file
|
|
62
68
|
```
|
|
63
69
|
|
|
64
70
|
### cm3toppm
|
|
@@ -263,6 +269,7 @@ The programs in the examples/decb and examples/other-decb-examples-to-try direct
|
|
|
263
269
|
* banner.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/banner.c10
|
|
264
270
|
* cadnza.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cadnza.c10
|
|
265
271
|
* cflip.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cflip.c10
|
|
272
|
+
* flip.bas -- https://github.com/daftspaniel/RetroCornerRedux/blob/main/Dragon/Originals/FlipBits/flip.bas
|
|
266
273
|
* loops.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
|
|
267
274
|
* f15eagle.bas -- https://colorcomputerarchive.com/repo/Disks/Magazines/Rainbow%20On%20Disk.zip
|
|
268
275
|
* mars.bas -- https://github.com/jggames/trs80mc10/tree/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Text%20Adventures/WorkInProgress/Mars
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import setuptools
|
|
4
4
|
|
|
5
5
|
# VERSION MUST be defined on line 6
|
|
6
|
-
VERSION = "0.
|
|
6
|
+
VERSION = "0.19"
|
|
7
7
|
|
|
8
8
|
with open("README.md", "r") as fh:
|
|
9
9
|
long_description = fh.read()
|
|
@@ -37,6 +37,8 @@ setuptools.setup(
|
|
|
37
37
|
"parsimonious>=0.10.0",
|
|
38
38
|
"Pillow>=7.0.0",
|
|
39
39
|
"pypng>=0.0.18",
|
|
40
|
+
"pydantic>=2.0.0",
|
|
41
|
+
"pydantic-yaml>=1.3.0",
|
|
40
42
|
],
|
|
41
43
|
python_requires=">=3.9.19",
|
|
42
44
|
# What does your project relate to?
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|