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.
Files changed (34) hide show
  1. {coco-tools-0.18 → coco-tools-0.19}/PKG-INFO +11 -4
  2. {coco-tools-0.18 → coco-tools-0.19}/README.md +10 -3
  3. {coco-tools-0.18 → coco-tools-0.19}/coco/__init__.py +1 -1
  4. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/compiler.py +16 -2
  5. coco-tools-0.19/coco/b09/configs.py +37 -0
  6. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/elements.py +68 -20
  7. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/grammar.py +1 -1
  8. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/parser.py +9 -3
  9. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/visitors.py +49 -24
  10. {coco-tools-0.18 → coco-tools-0.19}/coco/decb_to_b09.py +8 -0
  11. {coco-tools-0.18 → coco-tools-0.19}/coco/resources/ecb.b09 +8 -0
  12. {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/PKG-INFO +11 -4
  13. {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/SOURCES.txt +1 -0
  14. {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/requires.txt +2 -0
  15. {coco-tools-0.18 → coco-tools-0.19}/setup.py +3 -1
  16. {coco-tools-0.18 → coco-tools-0.19}/LICENSE +0 -0
  17. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/__init__.py +0 -0
  18. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/error_handler.py +0 -0
  19. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/procbank.py +0 -0
  20. {coco-tools-0.18 → coco-tools-0.19}/coco/b09/prog.py +0 -0
  21. {coco-tools-0.18 → coco-tools-0.19}/coco/cm3toppm.py +0 -0
  22. {coco-tools-0.18 → coco-tools-0.19}/coco/hrstoppm.py +0 -0
  23. {coco-tools-0.18 → coco-tools-0.19}/coco/maxtoppm.py +0 -0
  24. {coco-tools-0.18 → coco-tools-0.19}/coco/mge_viewer2.py +0 -0
  25. {coco-tools-0.18 → coco-tools-0.19}/coco/mgetoppm.py +0 -0
  26. {coco-tools-0.18 → coco-tools-0.19}/coco/pixtopgm.py +0 -0
  27. {coco-tools-0.18 → coco-tools-0.19}/coco/rattoppm.py +0 -0
  28. {coco-tools-0.18 → coco-tools-0.19}/coco/resources/__init__.py +0 -0
  29. {coco-tools-0.18 → coco-tools-0.19}/coco/util.py +0 -0
  30. {coco-tools-0.18 → coco-tools-0.19}/coco/veftopng.py +0 -0
  31. {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/dependency_links.txt +0 -0
  32. {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/entry_points.txt +0 -0
  33. {coco-tools-0.18 → coco-tools-0.19}/coco_tools.egg-info/top_level.txt +0 -0
  34. {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.18
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] program.bas program.b09
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.8
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
- options:
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] program.bas program.b09
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.8
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
- options:
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.18"
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.extend_prefix_lines(declare_array_visitor.dim_statements)
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__(self, dim_vars: List["BasicArrayRef | BasicVar"]):
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
- @default_str_storage.setter
1003
- def default_str_storage(self, val):
1004
- self._default_str_storage = val
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(dim_var, BasicLiteral("" if dim_var.is_str_expr else 0)),
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
- str_vars_text: str = (
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
- str_vars,
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
- + ("\n" if non_str_vars else "")
1077
- if str_vars
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: str = (
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
- init_text = "\n".join(
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
- init_text = "\n" + init_text if init_text else ""
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": "VAL",
52
+ "VAL": "RUN ecb_val",
53
53
  "LEN": "LEN",
54
54
  }
55
55
 
@@ -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
- return BasicFunctionCall(
522
- STR_NUM_FUNCTIONS[func.text], BasicExpressionList([exp])
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
- BasicLine(
235
- None,
236
- BasicStatements(
237
- [
238
- BasicAssignment(
239
- BasicVar(var, is_str_expr=var.endswith("$")),
240
- BasicLiteral(
241
- "" if var.endswith("$") else 0.0,
242
- is_str_expr=var.endswith("$"),
243
- ),
244
- )
245
- for var in sorted(vars_to_assign)
246
- if ((var.endswith("$") and len(var) <= 3) or len(var) <= 2)
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.18
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] program.bas program.b09
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.8
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
- options:
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
@@ -14,6 +14,7 @@ setup.py
14
14
  ./coco/veftopng.py
15
15
  ./coco/b09/__init__.py
16
16
  ./coco/b09/compiler.py
17
+ ./coco/b09/configs.py
17
18
  ./coco/b09/elements.py
18
19
  ./coco/b09/error_handler.py
19
20
  ./coco/b09/grammar.py
@@ -1,3 +1,5 @@
1
1
  parsimonious>=0.10.0
2
2
  Pillow>=7.0.0
3
3
  pypng>=0.0.18
4
+ pydantic>=2.0.0
5
+ pydantic-yaml>=1.3.0
@@ -3,7 +3,7 @@
3
3
  import setuptools
4
4
 
5
5
  # VERSION MUST be defined on line 6
6
- VERSION = "0.18"
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