@andrivet/z80-assembler 1.3.2 → 1.4.0

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 (197) hide show
  1. package/.editorconfig +13 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.json +35 -0
  4. package/.github/workflows/node.js.yml +47 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +3 -0
  7. package/.vscode/extensions.json +7 -0
  8. package/README.md +53 -27
  9. package/apps/.gitkeep +0 -0
  10. package/apps/z80-assembler-app/.eslintrc.json +18 -0
  11. package/apps/z80-assembler-app/index.html +16 -0
  12. package/apps/z80-assembler-app/postcss.config.js +24 -0
  13. package/apps/z80-assembler-app/project.json +70 -0
  14. package/apps/z80-assembler-app/public/favicon.ico +0 -0
  15. package/apps/z80-assembler-app/public/logo.png +0 -0
  16. package/apps/z80-assembler-app/public/logo192.png +0 -0
  17. package/apps/z80-assembler-app/public/logo512.png +0 -0
  18. package/apps/z80-assembler-app/public/manifest.json +25 -0
  19. package/apps/z80-assembler-app/public/robots.txt +3 -0
  20. package/apps/z80-assembler-app/src/app/app.module.css +0 -0
  21. package/apps/z80-assembler-app/src/app/app.tsx +122 -0
  22. package/apps/z80-assembler-app/src/app/binary.tsx +39 -0
  23. package/apps/z80-assembler-app/src/app/editor.tsx +228 -0
  24. package/apps/z80-assembler-app/src/app/errors.tsx +31 -0
  25. package/apps/z80-assembler-app/src/app/footer.tsx +20 -0
  26. package/apps/z80-assembler-app/src/app/header.tsx +57 -0
  27. package/apps/z80-assembler-app/src/app/misc.ts +13 -0
  28. package/apps/z80-assembler-app/src/app/opcodes.tsx +335 -0
  29. package/apps/z80-assembler-app/src/assets/.gitkeep +0 -0
  30. package/apps/z80-assembler-app/src/assets/images/logo192.png +0 -0
  31. package/apps/z80-assembler-app/src/main.tsx +22 -0
  32. package/apps/z80-assembler-app/src/styles.css +8 -0
  33. package/apps/z80-assembler-app/tailwind.config.js +28 -0
  34. package/apps/z80-assembler-app/tsconfig.app.json +22 -0
  35. package/apps/z80-assembler-app/tsconfig.json +21 -0
  36. package/apps/z80-assembler-app/tsconfig.spec.json +23 -0
  37. package/apps/z80-assembler-app/vite.config.ts +64 -0
  38. package/assets/images/compile.png +0 -0
  39. package/assets/images/logo.png +0 -0
  40. package/assets/images/menu.png +0 -0
  41. package/assets/images/opcodes-load8.png +0 -0
  42. package/assets/images/opcodes.png +0 -0
  43. package/assets/images/open-dir.png +0 -0
  44. package/assets/images/z80-assembler-app.png +0 -0
  45. package/docs/assembly.md +551 -0
  46. package/docs/images/ZX81-0x00.png +0 -0
  47. package/docs/images/ZX81-0x0B.png +0 -0
  48. package/docs/images/ZX81-0x0C.png +0 -0
  49. package/docs/images/ZX81-0x0D.png +0 -0
  50. package/docs/images/ZX81-0x0E.png +0 -0
  51. package/docs/images/ZX81-0x0F.png +0 -0
  52. package/docs/images/ZX81-0x10.png +0 -0
  53. package/docs/images/ZX81-0x11.png +0 -0
  54. package/docs/images/ZX81-0x12.png +0 -0
  55. package/docs/images/ZX81-0x13.png +0 -0
  56. package/docs/images/ZX81-0x14.png +0 -0
  57. package/docs/images/ZX81-0x15.png +0 -0
  58. package/docs/images/ZX81-0x16.png +0 -0
  59. package/docs/images/ZX81-0x17.png +0 -0
  60. package/docs/images/ZX81-0x18.png +0 -0
  61. package/docs/images/ZX81-0x19.png +0 -0
  62. package/docs/images/ZX81-0x1A.png +0 -0
  63. package/docs/images/ZX81-0x1B.png +0 -0
  64. package/docs/images/ZX81-0x1C.png +0 -0
  65. package/docs/images/ZX81-0x1D.png +0 -0
  66. package/docs/images/ZX81-0x1E.png +0 -0
  67. package/docs/images/ZX81-0x1F.png +0 -0
  68. package/docs/images/ZX81-0x20.png +0 -0
  69. package/docs/images/ZX81-0x21.png +0 -0
  70. package/docs/images/ZX81-0x22.png +0 -0
  71. package/docs/images/ZX81-0x23.png +0 -0
  72. package/docs/images/ZX81-0x24.png +0 -0
  73. package/docs/images/ZX81-0x25.png +0 -0
  74. package/docs/images/ZX81-0x26.png +0 -0
  75. package/docs/images/ZX81-0x27.png +0 -0
  76. package/docs/images/ZX81-0x28.png +0 -0
  77. package/docs/images/ZX81-0x29.png +0 -0
  78. package/docs/images/ZX81-0x2A.png +0 -0
  79. package/docs/images/ZX81-0x2B.png +0 -0
  80. package/docs/images/ZX81-0x2C.png +0 -0
  81. package/docs/images/ZX81-0x2D.png +0 -0
  82. package/docs/images/ZX81-0x2E.png +0 -0
  83. package/docs/images/ZX81-0x2F.png +0 -0
  84. package/docs/images/ZX81-0x30.png +0 -0
  85. package/docs/images/ZX81-0x31.png +0 -0
  86. package/docs/images/ZX81-0x32.png +0 -0
  87. package/docs/images/ZX81-0x33.png +0 -0
  88. package/docs/images/ZX81-0x34.png +0 -0
  89. package/docs/images/ZX81-0x35.png +0 -0
  90. package/docs/images/ZX81-0x36.png +0 -0
  91. package/docs/images/ZX81-0x37.png +0 -0
  92. package/docs/images/ZX81-0x38.png +0 -0
  93. package/docs/images/ZX81-0x39.png +0 -0
  94. package/docs/images/ZX81-0x3A.png +0 -0
  95. package/docs/images/ZX81-0x3B.png +0 -0
  96. package/docs/images/ZX81-0x3C.png +0 -0
  97. package/docs/images/ZX81-0x3D.png +0 -0
  98. package/docs/images/ZX81-0x3E.png +0 -0
  99. package/docs/images/ZX81-0x3F.png +0 -0
  100. package/docs/images/ZX81-0x80.png +0 -0
  101. package/docs/images/ZX81-0x8B.png +0 -0
  102. package/docs/images/ZX81-0x8C.png +0 -0
  103. package/docs/images/ZX81-0x8D.png +0 -0
  104. package/docs/images/ZX81-0x8E.png +0 -0
  105. package/docs/images/ZX81-0x8F.png +0 -0
  106. package/docs/images/ZX81-0x90.png +0 -0
  107. package/docs/images/ZX81-0x91.png +0 -0
  108. package/docs/images/ZX81-0x92.png +0 -0
  109. package/docs/images/ZX81-0x93.png +0 -0
  110. package/docs/images/ZX81-0x94.png +0 -0
  111. package/docs/images/ZX81-0x95.png +0 -0
  112. package/docs/images/ZX81-0x96.png +0 -0
  113. package/docs/images/ZX81-0x97.png +0 -0
  114. package/docs/images/ZX81-0x98.png +0 -0
  115. package/docs/images/ZX81-0x99.png +0 -0
  116. package/docs/images/ZX81-0x9A.png +0 -0
  117. package/docs/images/ZX81-0x9B.png +0 -0
  118. package/docs/images/ZX81-0x9C.png +0 -0
  119. package/docs/images/ZX81-0x9D.png +0 -0
  120. package/docs/images/ZX81-0x9E.png +0 -0
  121. package/docs/images/ZX81-0x9F.png +0 -0
  122. package/docs/images/ZX81-0xA0.png +0 -0
  123. package/docs/images/ZX81-0xA1.png +0 -0
  124. package/docs/images/ZX81-0xA2.png +0 -0
  125. package/docs/images/ZX81-0xA3.png +0 -0
  126. package/docs/images/ZX81-0xA4.png +0 -0
  127. package/docs/images/ZX81-0xA5.png +0 -0
  128. package/docs/images/ZX81-0xA6.png +0 -0
  129. package/docs/images/ZX81-0xA7.png +0 -0
  130. package/docs/images/ZX81-0xA8.png +0 -0
  131. package/docs/images/ZX81-0xA9.png +0 -0
  132. package/docs/images/ZX81-0xAA.png +0 -0
  133. package/docs/images/ZX81-0xAB.png +0 -0
  134. package/docs/images/ZX81-0xAC.png +0 -0
  135. package/docs/images/ZX81-0xAD.png +0 -0
  136. package/docs/images/ZX81-0xAE.png +0 -0
  137. package/docs/images/ZX81-0xAF.png +0 -0
  138. package/docs/images/ZX81-0xB0.png +0 -0
  139. package/docs/images/ZX81-0xB1.png +0 -0
  140. package/docs/images/ZX81-0xB2.png +0 -0
  141. package/docs/images/ZX81-0xB3.png +0 -0
  142. package/docs/images/ZX81-0xB4.png +0 -0
  143. package/docs/images/ZX81-0xB5.png +0 -0
  144. package/docs/images/ZX81-0xB6.png +0 -0
  145. package/docs/images/ZX81-0xB7.png +0 -0
  146. package/docs/images/ZX81-0xB8.png +0 -0
  147. package/docs/images/ZX81-0xB9.png +0 -0
  148. package/docs/images/ZX81-0xBA.png +0 -0
  149. package/docs/images/ZX81-0xBB.png +0 -0
  150. package/docs/images/ZX81-0xBC.png +0 -0
  151. package/docs/images/ZX81-0xBD.png +0 -0
  152. package/docs/images/ZX81-0xBE.png +0 -0
  153. package/docs/images/ZX81-0xBF.png +0 -0
  154. package/libs/.gitkeep +0 -0
  155. package/libs/z80-assembler/.eslintrc.json +18 -0
  156. package/libs/z80-assembler/package.json +20 -0
  157. package/libs/z80-assembler/project.json +35 -0
  158. package/libs/z80-assembler/public/README.md +54 -0
  159. package/{index.d.ts → libs/z80-assembler/src/index.ts} +1 -1
  160. package/libs/z80-assembler/src/lib/assets/code/basic-end.zx81 +4 -0
  161. package/libs/z80-assembler/src/lib/assets/code/basic-line1.zx81 +4 -0
  162. package/libs/z80-assembler/src/lib/assets/code/basic-line2.zx81 +9 -0
  163. package/libs/z80-assembler/src/lib/assets/code/characters.zx81 +190 -0
  164. package/libs/z80-assembler/src/lib/assets/code/display.zx81 +50 -0
  165. package/libs/z80-assembler/src/lib/assets/code/system-variables.zx81 +46 -0
  166. package/{lib/compiler/Assets.d.ts → libs/z80-assembler/src/lib/compiler/Assets.ts} +6 -1
  167. package/libs/z80-assembler/src/lib/compiler/Ast.ts +545 -0
  168. package/libs/z80-assembler/src/lib/compiler/Compiler.test.ts +2141 -0
  169. package/libs/z80-assembler/src/lib/compiler/Compiler.ts +185 -0
  170. package/libs/z80-assembler/src/lib/compiler/Formatter.ts +43 -0
  171. package/libs/z80-assembler/src/lib/compiler/Generator.ts +255 -0
  172. package/libs/z80-assembler/src/lib/compiler/Labels.ts +165 -0
  173. package/libs/z80-assembler/src/lib/grammar/LowLevel.ts +163 -0
  174. package/libs/z80-assembler/src/lib/grammar/Parse.ts +128 -0
  175. package/libs/z80-assembler/src/lib/grammar/z80.peg +1252 -0
  176. package/libs/z80-assembler/src/lib/grammar/z80.ts +10649 -0
  177. package/libs/z80-assembler/src/lib/types/Error.ts +105 -0
  178. package/{lib/types/Types.d.ts → libs/z80-assembler/src/lib/types/Types.ts} +26 -11
  179. package/libs/z80-assembler/tsconfig.json +23 -0
  180. package/libs/z80-assembler/tsconfig.lib.json +10 -0
  181. package/libs/z80-assembler/tsconfig.spec.json +19 -0
  182. package/libs/z80-assembler/vite.config.ts +58 -0
  183. package/nx.json +57 -0
  184. package/package.json +52 -14
  185. package/tsconfig.base.json +22 -0
  186. package/index.js +0 -312
  187. package/index.mjs +0 -6441
  188. package/lib/compiler/Ast.d.ts +0 -210
  189. package/lib/compiler/Compiler.d.ts +0 -53
  190. package/lib/compiler/Formatter.d.ts +0 -23
  191. package/lib/compiler/Generator.d.ts +0 -40
  192. package/lib/compiler/Labels.d.ts +0 -47
  193. package/lib/grammar/LowLevel.d.ts +0 -68
  194. package/lib/grammar/Parse.d.ts +0 -48
  195. package/lib/grammar/z80.d.ts +0 -2938
  196. package/lib/types/Error.d.ts +0 -62
  197. /package/{CHANGELOG.md → libs/z80-assembler/public/CHANGELOG.md} +0 -0
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Z80 Assembler in Typescript
3
+ *
4
+ * File: LoweLevel.ts
5
+ * Description: Low level functions for the parser
6
+ * Author: Sebastien Andrivet
7
+ * License: GPLv3
8
+ * Copyrights: Copyright (C) 2023 Sebastien Andrivet
9
+ */
10
+
11
+ import {byte} from "../types/Types";
12
+
13
+ /**
14
+ * Compute the binary representation of the r argument.
15
+ * @param r The argument of the opcode.
16
+ * @param offset The number of bits to shift to the left.
17
+ */
18
+ export function r_bits(r: string, offset = 0): byte {
19
+ switch(r.toLowerCase()) {
20
+ case 'b': return 0b000 << offset;
21
+ case 'c': return 0b001 << offset;
22
+ case 'd': return 0b010 << offset;
23
+ case 'e': return 0b011 << offset;
24
+ case 'h': return 0b100 << offset;
25
+ case 'l': return 0b101 << offset;
26
+ case 'a': return 0b111 << offset;
27
+ default: console.log(`Invalid register name: ${r}`); return 0;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Compute the binary representation of the dd argument.
33
+ * @param dd The argument of the opcode.
34
+ * @param offset The number of bits to shift to the left.
35
+ */
36
+ export function dd_bits(dd: string, offset = 0): byte {
37
+ switch(dd.toLowerCase()) {
38
+ case 'bc': return 0b00000000 << offset;
39
+ case 'de': return 0b00000001 << offset;
40
+ case 'hl': return 0b00000010 << offset;
41
+ case 'sp': return 0b00000011 << offset;
42
+ default: console.log(`Invalid register name: ${dd}`); return 0;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Compute the binary representation of the qq argument.
48
+ * @param qq The argument of the opcode.
49
+ * @param offset The number of bits to shift to the left.
50
+ */
51
+ export function qq_bits(qq: string, offset = 0): byte {
52
+ switch(qq.toLowerCase()) {
53
+ case 'bc': return 0b00000000 << offset;
54
+ case 'de': return 0b00000001 << offset;
55
+ case 'hl': return 0b00000010 << offset;
56
+ case 'af': return 0b00000011 << offset;
57
+ default: console.log(`Invalid register name: ${qq}`); return 0;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Compute the binary representation of the ss argument.
63
+ * @param ss The argument of the opcode.
64
+ * @param offset The number of bits to shift to the left.
65
+ */
66
+ export function ss_bits(ss: string, offset = 0): byte {
67
+ switch(ss.toLowerCase()) {
68
+ case 'bc': return 0b00000000 << offset;
69
+ case 'de': return 0b00000001 << offset;
70
+ case 'hl': return 0b00000010 << offset;
71
+ case 'sp': return 0b00000011 << offset;
72
+ default: console.log(`Invalid register name: ${ss}`); return 0;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Compute the binary representation of the pp argument.
78
+ * @param pp The argument of the opcode.
79
+ * @param offset The number of bits to shift to the left.
80
+ */
81
+ export function pp_bits(pp: string, offset = 0): byte {
82
+ switch(pp.toLowerCase()) {
83
+ case 'bc': return 0b00000000 << offset;
84
+ case 'de': return 0b00000001 << offset;
85
+ case 'ix': return 0b00000010 << offset;
86
+ case 'sp': return 0b00000011 << offset;
87
+ default: console.log(`Invalid register name: ${pp}`); return 0;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Compute the binary representation of the rr argument.
93
+ * @param rr The argument of the opcode.
94
+ * @param offset The number of bits to shift to the left.
95
+ */
96
+ export function rr_bits(rr: string, offset = 0): byte {
97
+ switch(rr.toLowerCase()) {
98
+ case 'bc': return 0b00000000 << offset;
99
+ case 'de': return 0b00000001 << offset;
100
+ case 'iy': return 0b00000010 << offset;
101
+ case 'sp': return 0b00000011 << offset;
102
+ default: console.log(`Invalid register name: ${rr}`); return 0;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Compute the binary representation of the cc argument.
108
+ * @param cc The argument of the opcode.
109
+ * @param offset The number of bits to shift to the left.
110
+ */
111
+ export function cc_bits(cc: string, offset = 0): byte {
112
+ switch(cc.toLowerCase()) {
113
+ case 'nz': return 0b00000000 << offset;
114
+ case 'z': return 0b00000001 << offset;
115
+ case 'nc': return 0b00000010 << offset;
116
+ case 'c': return 0b00000011 << offset;
117
+ case 'po': return 0b00000100 << offset;
118
+ case 'pe': return 0b00000101 << offset;
119
+ case 'p': return 0b00000110 << offset;
120
+ case 's':
121
+ case 'm': return 0b00000111 << offset;
122
+ default: console.log(`Invalid jump condition: ${cc}`); return 0;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Compute the binary representation of the jj argument.
128
+ * @param jj The argument of the opcode.
129
+ */
130
+ export function jj_bits(jj = ''): byte {
131
+ switch(jj.toLowerCase()) {
132
+ case '': return 0x18;
133
+ case 'nz': return 0x20;
134
+ case 'z': return 0x28;
135
+ case 'nc': return 0x30;
136
+ case 'c': return 0x38;
137
+ default: console.log(`Invalid relative jump condition: ${jj}`); return 0;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Compute the binary representation of the p argument.
143
+ * @param p The argument of the opcode.
144
+ * @param offset The number of bits to shift to the left.
145
+ */
146
+ export function p_bits(p: number, offset = 0): byte {
147
+ if(p < 0 || p > 0x38 || p % 8 !== 0)
148
+ console.log(`Invalid argument for RST: ${p}`);
149
+ return (p / 8) << offset;
150
+ }
151
+
152
+ /**
153
+ * Compute the binary representation of the mode argument.
154
+ * @param mode The argument of the opcode.
155
+ */
156
+ export function imode(mode: string): byte {
157
+ switch (mode) {
158
+ case '0': return 0x46;
159
+ case '1': return 0x56;
160
+ case '2': return 0x5E;
161
+ default: console.log(`Invalid interrupt mode: ${mode}`); return 0;
162
+ }
163
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Z80 Assembler in Typescript
3
+ *
4
+ * File: Parse.ts
5
+ * Description: Fonctions uses by the parser to convert strings
6
+ * Author: Sebastien Andrivet
7
+ * License: GPLv3
8
+ * Copyrights: Copyright (C) 2023 Sebastien Andrivet
9
+ */
10
+
11
+ import {PosInfo} from "./z80";
12
+ import {CompilationError} from "../types/Error";
13
+ import {parseData} from '../compiler/Compiler';
14
+
15
+ /**
16
+ * Parse a number.
17
+ * @param pos Position of the number in the source code.
18
+ * @param str The characters of the number.
19
+ * @param base The base of the number.
20
+ * @param nbBytes The number of bytes to represent this number (1 or 2)
21
+ */
22
+ export function parseNumber(pos: PosInfo, str: string, base: number, nbBytes: number): number {
23
+ // Convert the string to a number.
24
+ let v = parseInt(str, base);
25
+ if(isNaN(v)) throw new CompilationError({filename: parseData.fileName, pos: pos},
26
+ `Number '${str}' is invalid in base ${base}.`)
27
+ switch(nbBytes) {
28
+ case 1:
29
+ // Must be able to fit this number into 8 bits.
30
+ if(v > 255 || v < -256) throw new CompilationError({filename: parseData.fileName, pos: pos},
31
+ `Number '${str}' does not fit into a byte.`);
32
+ // If negative, take the 2-complement.
33
+ if(v < 0) v = 256 + v;
34
+ break;
35
+
36
+ case 2:
37
+ // Must be able to fit this number into 16 bits.
38
+ if(v > 65535 || v < -65536) throw new CompilationError({filename: parseData.fileName, pos: pos},
39
+ `Number '${str}' does not fit into a word.`);
40
+ // If negative, take the 2-complement.
41
+ if(v < 0) v = 65536 + v;
42
+ break;
43
+
44
+ default:
45
+ throw new CompilationError({filename: parseData.fileName, pos: pos},
46
+ `Invalid number of bytes (${nbBytes})`);
47
+ }
48
+
49
+ return v;
50
+ }
51
+
52
+ /**
53
+ * Parse a simple escape, i.e. a backslash followed by a character.
54
+ * @param pos Position of the character in the source code.
55
+ * @param c The character after the backslash.
56
+ */
57
+ export function parseSimpleEscape(pos: PosInfo, c: string): number[] {
58
+ switch(c) {
59
+ case 'n': return [0x0B];
60
+ case '"': return [0x0B];
61
+ default: throw new CompilationError({filename: parseData.fileName, pos: pos},
62
+ `Invalid escape: \\${c}`);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Parse an octal value.
68
+ * @param pos Position of the value in the source code.
69
+ * @param value The characters representing the value.
70
+ */
71
+ export function parseOctalEscape(pos: PosInfo, value: string): number[] {
72
+ const v = parseInt(value, 8);
73
+ if(v > 255) throw new CompilationError({filename: parseData.fileName, pos: pos},
74
+ `Number '${value}' in octal escape sequence does not fit into a byte.`);
75
+ return [v];
76
+ }
77
+
78
+ /**
79
+ * Parse a hexadecimal value.
80
+ * @param pos Position of the value in the source code.
81
+ * @param value The characters representing the value.
82
+ */
83
+ export function parseHexadecimalEscape(pos: PosInfo, value: string): number[] {
84
+ const v = parseInt(value, 16);
85
+ if(v > 255) throw new CompilationError({filename: parseData.fileName, pos: pos},
86
+ `Number '${value}' in hexadecimal escape sequence does not fit into a byte.`);
87
+ return [v];
88
+ }
89
+
90
+ /**
91
+ * Map between ASCII and ZX81 characters set.
92
+ */
93
+ const zx81chars = new Map<string, number>([
94
+ [' ', 0x00], ['"', 0x0B], ['£', 0x0C], ['$', 0x0D], [':', 0x0E], ['?', 0x0F],
95
+ ['(', 0x10], [')', 0x11], ['>', 0x12], ['<', 0x13], ['=', 0x14], ['+', 0x15], ['-', 0x16], ['*', 0x17],
96
+ ['/', 0x18], [';', 0x19], [',', 0x1A], ['.', 0x1B],
97
+ ['_', 0x80]
98
+ ]);
99
+
100
+ /**
101
+ * Parse a ZX81 character written in ASCII.
102
+ * @param pos Position of the character in the source code.
103
+ * @param c The ASCII character.
104
+ */
105
+ export function parseZX81Char(pos: PosInfo, c: string): [number] {
106
+ // Convert capital letters to their ZX81 counterparts.
107
+ if(c >= 'A' && c <= 'Z') return [c.charCodeAt(0) - 0x41 + 0x26];
108
+ // Convert lowercase letters to their uppercase and inverted ZX81 counterparts.
109
+ if(c >= 'a' && c <= 'z') return [c.charCodeAt(0) - 0x61 + 0xA6];
110
+ // Convert digits to their ZX81 counterparts.
111
+ if(c >= '0' && c <= '9') return [c.charCodeAt(0) - 0x30 + 0x1C];
112
+ // Is it possible to convert this symbol?
113
+ if(!zx81chars.has(c)) throw new CompilationError({filename: parseData.fileName, pos: pos},
114
+ `Invalid ZX81 character: ${c}`);
115
+ // eslint-disable-next-line
116
+ return [zx81chars.get(c)!];
117
+ }
118
+
119
+ /**
120
+ * Parse a ZX81 string written in ASCII.
121
+ * @param pos Position of the string in the source code.
122
+ * @param str The ASCII string.
123
+ */
124
+ export function parseZX81String(pos: PosInfo, str: string): number[] {
125
+ // Convert each character.
126
+ // On convertit chaque caractère.
127
+ return [...str].reduce((r: number[], c) => r.concat(parseZX81Char(pos, c)), []);
128
+ }