coco-tools 0.8__tar.gz → 0.17__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.
Files changed (40) hide show
  1. {coco-tools-0.8/coco_tools.egg-info → coco-tools-0.17}/PKG-INFO +25 -5
  2. {coco-tools-0.8 → coco-tools-0.17}/README.md +24 -4
  3. {coco-tools-0.8 → coco-tools-0.17}/coco/__init__.py +1 -1
  4. coco-tools-0.17/coco/b09/__init__.py +1 -0
  5. coco-tools-0.17/coco/b09/compiler.py +260 -0
  6. coco-tools-0.17/coco/b09/elements.py +1427 -0
  7. coco-tools-0.17/coco/b09/error_handler.py +65 -0
  8. coco-tools-0.17/coco/b09/grammar.py +503 -0
  9. coco-tools-0.17/coco/b09/parser.py +1334 -0
  10. {coco-tools-0.8/coco → coco-tools-0.17/coco/b09}/procbank.py +37 -17
  11. coco-tools-0.17/coco/b09/prog.py +42 -0
  12. coco-tools-0.17/coco/b09/visitors.py +509 -0
  13. {coco-tools-0.8 → coco-tools-0.17}/coco/cm3toppm.py +1 -3
  14. coco-tools-0.17/coco/decb_to_b09.py +97 -0
  15. {coco-tools-0.8 → coco-tools-0.17}/coco/hrstoppm.py +2 -6
  16. {coco-tools-0.8 → coco-tools-0.17}/coco/maxtoppm.py +13 -43
  17. {coco-tools-0.8 → coco-tools-0.17}/coco/mge_viewer2.py +3 -1
  18. {coco-tools-0.8 → coco-tools-0.17}/coco/mgetoppm.py +2 -10
  19. {coco-tools-0.8 → coco-tools-0.17}/coco/pixtopgm.py +2 -4
  20. {coco-tools-0.8 → coco-tools-0.17}/coco/rattoppm.py +2 -4
  21. coco-tools-0.17/coco/resources/ecb.b09 +1417 -0
  22. {coco-tools-0.8 → coco-tools-0.17}/coco/util.py +4 -8
  23. {coco-tools-0.8 → coco-tools-0.17}/coco/veftopng.py +2 -7
  24. {coco-tools-0.8 → coco-tools-0.17/coco_tools.egg-info}/PKG-INFO +25 -5
  25. {coco-tools-0.8 → coco-tools-0.17}/coco_tools.egg-info/SOURCES.txt +9 -4
  26. coco-tools-0.17/coco_tools.egg-info/top_level.txt +1 -0
  27. coco-tools-0.17/setup.py +66 -0
  28. coco-tools-0.8/coco/b09.py +0 -2187
  29. coco-tools-0.8/coco/decb_to_b09.py +0 -78
  30. coco-tools-0.8/coco/resources/ecb.b09 +0 -261
  31. coco-tools-0.8/coco_tools.egg-info/top_level.txt +0 -2
  32. coco-tools-0.8/setup.py +0 -77
  33. coco-tools-0.8/tests/__init__.py +0 -0
  34. coco-tools-0.8/tests/coco_tests/fixtures/__init__.py +0 -0
  35. {coco-tools-0.8 → coco-tools-0.17}/LICENSE +0 -0
  36. {coco-tools-0.8 → coco-tools-0.17}/coco/resources/__init__.py +0 -0
  37. {coco-tools-0.8 → coco-tools-0.17}/coco_tools.egg-info/dependency_links.txt +0 -0
  38. {coco-tools-0.8 → coco-tools-0.17}/coco_tools.egg-info/entry_points.txt +0 -0
  39. {coco-tools-0.8 → coco-tools-0.17}/coco_tools.egg-info/requires.txt +0 -0
  40. {coco-tools-0.8 → coco-tools-0.17}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: coco-tools
3
- Version: 0.8
3
+ Version: 0.17
4
4
  Summary: TRS-80 Color Computer Tools
5
5
  Home-page: https://github.com/jamieleecho/coco-tools
6
6
  Author: Jamie Cho
@@ -12,7 +12,7 @@ Classifier: Intended Audience :: Developers
12
12
  Classifier: Topic :: Software Development :: Build Tools
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Programming Language :: Python :: 3
15
- Requires-Python: >=3.7
15
+ Requires-Python: >=3.9.19
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
 
@@ -35,14 +35,14 @@ python3 setup.py
35
35
 
36
36
  ## Tools
37
37
 
38
- ### [decb-to-b09](README.decb-to-b09.md)
38
+ ### [decb-to-b09](./README.decb-to-b09.md)
39
39
 
40
40
  ```
41
- usage: decb-to-b09 [-h] [--version] [-l] [-z] program.bas program.b09
41
+ usage: decb-to-b09 [-h] [--version] [-l] [-z] [-D] [-w] program.bas program.b09
42
42
 
43
43
  Convert a Color BASIC program to a BASIC09 program
44
44
  Copyright (c) 2023 by Jamie Cho
45
- Version: 0.7
45
+ Version: 0.8
46
46
 
47
47
  positional arguments:
48
48
  program.bas input DECB text program file
@@ -55,6 +55,10 @@ options:
55
55
  Filter out line numbers not referenced by the program
56
56
  -z, --dont-initialize-vars
57
57
  Don't pre-initialize all variables
58
+ -D, --dont-output-dependencies
59
+ Don't output required dependencies
60
+ -w, --dont-run-width-32
61
+ if set don't run the default width 32
58
62
  ```
59
63
 
60
64
  ### cm3toppm
@@ -246,4 +250,20 @@ docker-compose run test
246
250
 
247
251
  # Run tests using the source on the host computer
248
252
  docker-compose run testv
253
+
254
+ # To make changes and develop locally
255
+ pip install -r requirements.txt
256
+ pre-commit install
249
257
  ```
258
+
259
+ ## Credits
260
+ The programs in the examples/decb and examples/other-decb-examples-to-try directories are from the following sources:
261
+ * alien4k0.bas -- https://github.com/jggames/trs80mc10/blob/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Arcade/4K/Alien4K/ALIEN4K0.TXT#L4
262
+ * bach.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/bach.c10
263
+ * banner.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/banner.c10
264
+ * cadnza.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cadnza.c10
265
+ * cflip.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cflip.c10
266
+ * loops.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
267
+ * f15eagle.bas -- https://colorcomputerarchive.com/repo/Disks/Magazines/Rainbow%20On%20Disk.zip
268
+ * mars.bas -- https://github.com/jggames/trs80mc10/tree/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Text%20Adventures/WorkInProgress/Mars
269
+ * saints.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
@@ -17,14 +17,14 @@ python3 setup.py
17
17
 
18
18
  ## Tools
19
19
 
20
- ### [decb-to-b09](README.decb-to-b09.md)
20
+ ### [decb-to-b09](./README.decb-to-b09.md)
21
21
 
22
22
  ```
23
- usage: decb-to-b09 [-h] [--version] [-l] [-z] program.bas program.b09
23
+ usage: decb-to-b09 [-h] [--version] [-l] [-z] [-D] [-w] program.bas program.b09
24
24
 
25
25
  Convert a Color BASIC program to a BASIC09 program
26
26
  Copyright (c) 2023 by Jamie Cho
27
- Version: 0.7
27
+ Version: 0.8
28
28
 
29
29
  positional arguments:
30
30
  program.bas input DECB text program file
@@ -37,6 +37,10 @@ options:
37
37
  Filter out line numbers not referenced by the program
38
38
  -z, --dont-initialize-vars
39
39
  Don't pre-initialize all variables
40
+ -D, --dont-output-dependencies
41
+ Don't output required dependencies
42
+ -w, --dont-run-width-32
43
+ if set don't run the default width 32
40
44
  ```
41
45
 
42
46
  ### cm3toppm
@@ -228,4 +232,20 @@ docker-compose run test
228
232
 
229
233
  # Run tests using the source on the host computer
230
234
  docker-compose run testv
231
- ```
235
+
236
+ # To make changes and develop locally
237
+ pip install -r requirements.txt
238
+ pre-commit install
239
+ ```
240
+
241
+ ## Credits
242
+ The programs in the examples/decb and examples/other-decb-examples-to-try directories are from the following sources:
243
+ * alien4k0.bas -- https://github.com/jggames/trs80mc10/blob/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Arcade/4K/Alien4K/ALIEN4K0.TXT#L4
244
+ * bach.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/bach.c10
245
+ * banner.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/banner.c10
246
+ * cadnza.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cadnza.c10
247
+ * cflip.bas -- https://colorcomputerarchive.com/repo/MC-10/Software/Books/TRS-80%20Color%20Computer%20%26%20MC-10%20Programs/cflip.c10
248
+ * loops.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
249
+ * f15eagle.bas -- https://colorcomputerarchive.com/repo/Disks/Magazines/Rainbow%20On%20Disk.zip
250
+ * mars.bas -- https://github.com/jggames/trs80mc10/tree/9df4c9578250009d68a03101d626faa3c22e7445/quicktype/Text%20Adventures/WorkInProgress/Mars
251
+ * saints.bas -- https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%203%20Extended%20Basic%20(Tandy).pdf
@@ -1,2 +1,2 @@
1
1
  # __version__ MUST be defined on line 2
2
- __version__ = "0.8"
2
+ __version__ = "0.17"
@@ -0,0 +1 @@
1
+ DEFAULT_STR_STORAGE: int = 32
@@ -0,0 +1,260 @@
1
+ from typing import List
2
+
3
+ from coco import b09
4
+ from coco.b09 import error_handler
5
+ from coco.b09.elements import (
6
+ Basic09CodeStatement,
7
+ BasicExpressionList,
8
+ BasicLine,
9
+ BasicLiteral,
10
+ BasicOnBrkGoStatement,
11
+ BasicOnErrGoStatement,
12
+ BasicRunCall,
13
+ BasicVar,
14
+ )
15
+ from coco.b09.grammar import grammar, PROCNAME_REGEX
16
+ from coco.b09.parser import BasicVisitor
17
+ from coco.b09.procbank import ProcedureBank
18
+ from coco.b09.prog import BasicProg
19
+ from coco.b09.visitors import (
20
+ BasicEmptyDataElementVisitor,
21
+ BasicFunctionalExpressionPatcherVisitor,
22
+ BasicHbuffPresenceVisitor,
23
+ BasicInputStatementPatcherVisitor,
24
+ BasicNextPatcherVisitor,
25
+ BasicPrintStatementPatcherVisitor,
26
+ BasicReadStatementPatcherVisitor,
27
+ DeclareImplicitArraysVisitor,
28
+ GetDimmedArraysVisitor,
29
+ JoystickVisitor,
30
+ LineNumberFilterVisitor,
31
+ LineNumberCheckerVisitor,
32
+ LineReferenceVisitor,
33
+ LineZeroFilterVisitor,
34
+ SetDimStringStorageVisitor,
35
+ StatementCollectorVisitor,
36
+ StrVarAllocatorVisitor,
37
+ VarInitializerVisitor,
38
+ )
39
+
40
+
41
+ class ParseError(Exception):
42
+ pass
43
+
44
+
45
+ def convert(
46
+ progin: str,
47
+ *,
48
+ add_standard_prefix: bool = True,
49
+ add_suffix: bool = True,
50
+ default_str_storage: int = b09.DEFAULT_STR_STORAGE,
51
+ default_width32: bool = True,
52
+ filter_unused_linenum: bool = False,
53
+ initialize_vars: bool = False,
54
+ output_dependencies: bool = False,
55
+ procname: str = "",
56
+ skip_procedure_headers: bool = False,
57
+ ) -> str:
58
+ tree = grammar.parse(progin)
59
+ bv = BasicVisitor()
60
+ basic_prog: BasicProg = bv.visit(tree)
61
+
62
+ if add_standard_prefix:
63
+ prefix_lines = [
64
+ BasicLine(None, Basic09CodeStatement("base 0")),
65
+ BasicLine(
66
+ None,
67
+ Basic09CodeStatement(
68
+ "type display_t = tpth, vpth, wpth, hpth, pal(16), blnk, "
69
+ "undrln, bck, fore, brdr, hbck, hfore, hscl, hpy, hagl, hdsc: byte; hpx: integer"
70
+ ),
71
+ ),
72
+ BasicLine(None, Basic09CodeStatement("dim display: display_t")),
73
+ BasicLine(None, Basic09CodeStatement("dim erno: real")),
74
+ BasicLine(None, Basic09CodeStatement("erno := -1")),
75
+ BasicLine(
76
+ None,
77
+ BasicRunCall(
78
+ "RUN _ecb_start",
79
+ BasicExpressionList(
80
+ [
81
+ BasicVar("display"),
82
+ BasicLiteral(1 if default_width32 else 0),
83
+ ]
84
+ ),
85
+ ),
86
+ ),
87
+ BasicLine(
88
+ None, Basic09CodeStatement("TYPE play_t=oct,octo,lnt,tne,vol,dot:BYTE")
89
+ ),
90
+ BasicLine(None, Basic09CodeStatement("DIM play: play_t")),
91
+ BasicLine(None, Basic09CodeStatement("play.oct := 3")),
92
+ BasicLine(None, Basic09CodeStatement("play.octo := 0")),
93
+ BasicLine(None, Basic09CodeStatement("play.lnt := 4")),
94
+ BasicLine(None, Basic09CodeStatement("play.tne := 2")),
95
+ BasicLine(None, Basic09CodeStatement("play.vol := 15")),
96
+ BasicLine(None, Basic09CodeStatement("play.dot := 0")),
97
+ ]
98
+ basic_prog.insert_lines_at_beginning(prefix_lines)
99
+
100
+ if skip_procedure_headers := skip_procedure_headers or not output_dependencies:
101
+ procname = ""
102
+ else:
103
+ procname = procname if PROCNAME_REGEX.match(procname) else "program"
104
+ basic_prog.set_procname(procname)
105
+
106
+ # Patch INPUT statements
107
+ basic_prog.visit(BasicInputStatementPatcherVisitor())
108
+
109
+ # Patch up READ statements to handle empty DATA elements
110
+ empty_data_elements_visitor = BasicEmptyDataElementVisitor()
111
+ basic_prog.visit(empty_data_elements_visitor)
112
+ if empty_data_elements_visitor.has_empty_data_elements:
113
+ basic_prog.visit(BasicReadStatementPatcherVisitor())
114
+
115
+ # Update joystk stuff
116
+ joystk_initializer = JoystickVisitor()
117
+ basic_prog.visit(joystk_initializer)
118
+ basic_prog.extend_prefix_lines(joystk_initializer.joystk_var_statements)
119
+
120
+ # Patch PRINT statements
121
+ basic_prog.visit(BasicPrintStatementPatcherVisitor())
122
+
123
+ # transform functions to proc calls
124
+ basic_prog.visit(BasicFunctionalExpressionPatcherVisitor())
125
+
126
+ set_string_storage_vistor: SetDimStringStorageVisitor = SetDimStringStorageVisitor(
127
+ default_str_storage=default_str_storage
128
+ )
129
+ basic_prog.visit(set_string_storage_vistor)
130
+
131
+ # Declare implicitly declared arrays
132
+ dimmed_array_visitor = GetDimmedArraysVisitor()
133
+ basic_prog.visit(dimmed_array_visitor)
134
+ declare_array_visitor = DeclareImplicitArraysVisitor(
135
+ dimmed_var_names=dimmed_array_visitor.dimmed_var_names,
136
+ )
137
+ basic_prog.visit(declare_array_visitor)
138
+ basic_prog.extend_prefix_lines(declare_array_visitor.dim_statements)
139
+
140
+ # allocate sufficient string storage
141
+ str_var_allocator: StrVarAllocatorVisitor = StrVarAllocatorVisitor(
142
+ default_str_storage=default_str_storage,
143
+ dimmed_var_names=set_string_storage_vistor.dimmed_var_names,
144
+ )
145
+ basic_prog.visit(str_var_allocator)
146
+ basic_prog.extend_prefix_lines(str_var_allocator.allocation_lines)
147
+
148
+ # initialize variables
149
+ if initialize_vars:
150
+ var_initializer = VarInitializerVisitor()
151
+ basic_prog.visit(var_initializer)
152
+ basic_prog.extend_prefix_lines(var_initializer.assignment_lines)
153
+
154
+ # remove unused line numbers
155
+ line_ref_visitor = LineReferenceVisitor()
156
+ basic_prog.visit(line_ref_visitor)
157
+ line_num_filter = (
158
+ LineNumberFilterVisitor(line_ref_visitor.references)
159
+ if filter_unused_linenum
160
+ else LineZeroFilterVisitor(line_ref_visitor.references)
161
+ )
162
+ basic_prog.visit(line_num_filter)
163
+
164
+ # make sure line numbers exist and are not too big
165
+ line_checker: LineNumberCheckerVisitor = LineNumberCheckerVisitor(
166
+ line_ref_visitor.references
167
+ )
168
+ basic_prog.visit(line_checker)
169
+ if len(line_checker.undefined_lines) > 0:
170
+ raise ParseError(
171
+ f"The following lines are undefined: {', '.join(str(linenum) for linenum in line_checker.undefined_lines)}"
172
+ )
173
+
174
+ # make sure there are no more than 1 ON ERR statement
175
+ on_err_collector: StatementCollectorVisitor = StatementCollectorVisitor(
176
+ BasicOnErrGoStatement
177
+ )
178
+ basic_prog.visit(on_err_collector)
179
+ if len(on_err_collector.statements) > 1:
180
+ raise ParseError("At most 1 ON ERR GOTO statement is allowed.")
181
+ err_line: BasicOnErrGoStatement = (
182
+ on_err_collector.statements[0].linenum if on_err_collector.statements else None
183
+ )
184
+
185
+ # make sure there are no more than 1 ON BRK statement
186
+ on_brk_collector: StatementCollectorVisitor = StatementCollectorVisitor(
187
+ BasicOnBrkGoStatement
188
+ )
189
+ basic_prog.visit(on_brk_collector)
190
+ if len(on_brk_collector.statements) > 1:
191
+ raise ParseError("At most 1 ON BRK GOTO statement is allowed.")
192
+ brk_line: BasicOnBrkGoStatement = (
193
+ on_brk_collector.statements[0].linenum if on_brk_collector.statements else None
194
+ )
195
+
196
+ # try to patch up empty next statements
197
+ basic_prog.visit(BasicNextPatcherVisitor())
198
+ suffix_lines: List[BasicLine] = error_handler.generate(
199
+ brk_line=brk_line,
200
+ err_line=err_line,
201
+ )
202
+ if add_suffix:
203
+ basic_prog.append_lines(suffix_lines)
204
+
205
+ # detect hbuff
206
+ if add_standard_prefix:
207
+ hbuff_visitor = BasicHbuffPresenceVisitor()
208
+ basic_prog.visit(hbuff_visitor)
209
+ if hbuff_visitor.has_hbuff:
210
+ basic_prog.insert_lines_at_beginning(
211
+ [
212
+ BasicLine(None, Basic09CodeStatement("dim pid: integer")),
213
+ BasicLine(
214
+ None,
215
+ BasicRunCall(
216
+ "RUN _ecb_init_hbuff",
217
+ BasicExpressionList([BasicVar("pid")]),
218
+ ),
219
+ ),
220
+ ]
221
+ )
222
+
223
+ # output the program
224
+ program = basic_prog.basic09_text(0)
225
+ if output_dependencies and procname:
226
+ procedure_bank = ProcedureBank(
227
+ default_str_storage=default_str_storage,
228
+ )
229
+ procedure_bank.add_from_resource("ecb.b09")
230
+ procedure_bank.add_from_str(program)
231
+ program = procedure_bank.get_procedure_and_dependencies(procname)
232
+
233
+ return program + "\n"
234
+
235
+
236
+ def convert_file(
237
+ input_program_file: str,
238
+ output_program_file: str,
239
+ *,
240
+ add_standard_prefix: bool = True,
241
+ default_width32: bool = True,
242
+ default_str_storage: int = b09.DEFAULT_STR_STORAGE,
243
+ filter_unused_linenum: bool = False,
244
+ initialize_vars: bool = False,
245
+ output_dependencies: bool = False,
246
+ procname: str = "",
247
+ ) -> None:
248
+ progin = input_program_file.read()
249
+ progout = convert(
250
+ progin,
251
+ add_standard_prefix=add_standard_prefix,
252
+ default_str_storage=default_str_storage,
253
+ default_width32=default_width32,
254
+ filter_unused_linenum=filter_unused_linenum,
255
+ initialize_vars=initialize_vars,
256
+ output_dependencies=output_dependencies,
257
+ procname=procname,
258
+ )
259
+ progout = progout.replace("\n", "\r")
260
+ output_program_file.write(progout)