@m100/core 0.9.7 → 0.12.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.
- package/dist/commentUtils.js +16 -45
- package/dist/commentUtils.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lexer/lex.d.ts +9 -0
- package/dist/lexer/lex.js +157 -0
- package/dist/lexer/lex.js.map +1 -0
- package/dist/pack/pack.js +28 -68
- package/dist/pack/pack.js.map +1 -1
- package/dist/removeComments/removeComments.d.ts +11 -2
- package/dist/removeComments/removeComments.js +100 -52
- package/dist/removeComments/removeComments.js.map +1 -1
- package/dist/squash/squash.d.ts +5 -1
- package/dist/squash/squash.js +21 -13
- package/dist/squash/squash.js.map +1 -1
- package/dist/tokenize/tokenizeProgram.js +68 -59
- package/dist/tokenize/tokenizeProgram.js.map +1 -1
- package/dist/utils/programAnalysis.js +116 -97
- package/dist/utils/programAnalysis.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { findCommentStart } from '../commentUtils.js';
|
|
2
|
+
import { collectProgramStructure } from '../utils/programAnalysis.js';
|
|
2
3
|
/**
|
|
3
4
|
* Parse a single BASIC line into line number and code.
|
|
4
5
|
*/
|
|
@@ -18,76 +19,123 @@ function parseLine(line) {
|
|
|
18
19
|
/**
|
|
19
20
|
* Collect all line references (GOTO, GOSUB targets) from BASIC code.
|
|
20
21
|
*/
|
|
21
|
-
function collectLineReferences(basicCode) {
|
|
22
|
-
const references = new Set();
|
|
23
|
-
const lines = basicCode.split(/\r?\n/);
|
|
24
|
-
// Keywords that reference line numbers
|
|
25
|
-
const referenceKeywords = [
|
|
26
|
-
'GOTO', 'GOSUB', 'THEN', 'ELSE', 'RUN', 'RESUME', 'RESTORE',
|
|
27
|
-
'ON.*GOTO', 'ON.*GOSUB'
|
|
28
|
-
];
|
|
29
|
-
for (const line of lines) {
|
|
30
|
-
const commentStart = findCommentStart(line);
|
|
31
|
-
const codeOnly = commentStart === undefined ? line : line.slice(0, commentStart);
|
|
32
|
-
const upper = codeOnly.toUpperCase();
|
|
33
|
-
// Simple line reference detection
|
|
34
|
-
for (const keyword of referenceKeywords) {
|
|
35
|
-
const regex = new RegExp(`\\b${keyword}\\s+(\\d+)`, 'gi');
|
|
36
|
-
let match;
|
|
37
|
-
while ((match = regex.exec(upper)) !== null) {
|
|
38
|
-
const target = parseInt(match[1], 10);
|
|
39
|
-
if (!isNaN(target)) {
|
|
40
|
-
references.add(target);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
// Handle comma-separated targets (ON...GOTO/GOSUB)
|
|
45
|
-
const onMatch = /\bON\s+.+?\s+(GOTO|GOSUB)\s+([\d,\s]+)/gi.exec(upper);
|
|
46
|
-
if (onMatch) {
|
|
47
|
-
const targets = onMatch[2].split(',');
|
|
48
|
-
for (const target of targets) {
|
|
49
|
-
const num = parseInt(target.trim(), 10);
|
|
50
|
-
if (!isNaN(num)) {
|
|
51
|
-
references.add(num);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return references;
|
|
57
|
-
}
|
|
58
22
|
/**
|
|
59
23
|
* Remove all comments from BASIC code while preserving line structure.
|
|
60
|
-
*
|
|
24
|
+
* Line references that point to removed lines are updated to the next line
|
|
25
|
+
* containing non-comment tokens. The last line in range is never removed.
|
|
61
26
|
*
|
|
62
27
|
* @param basicCode - BASIC source code with line numbers
|
|
28
|
+
* @param options - Optional range bounds for removal
|
|
63
29
|
* @returns Code with comments removed
|
|
64
30
|
*/
|
|
65
|
-
export function removeComments(basicCode) {
|
|
31
|
+
export function removeComments(basicCode, options = {}) {
|
|
66
32
|
const lines = basicCode.split(/\r?\n/);
|
|
67
|
-
const
|
|
33
|
+
const parsedLines = [];
|
|
34
|
+
const inRangeByIndex = new Map();
|
|
35
|
+
const startLine = options.startLine;
|
|
36
|
+
const endLine = options.endLine;
|
|
37
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38
|
+
const parsed = parseLine(lines[i]);
|
|
39
|
+
if (!parsed) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const commentStart = findCommentStart(parsed.code);
|
|
43
|
+
const codeNoComment = commentStart === undefined ? parsed.code : parsed.code.slice(0, commentStart);
|
|
44
|
+
const codeTrimmed = codeNoComment.replace(/[\s:]+$/g, '');
|
|
45
|
+
const hasNonCommentToken = Boolean(codeTrimmed.trim());
|
|
46
|
+
const inRange = (startLine === undefined || parsed.lineNumber >= startLine) &&
|
|
47
|
+
(endLine === undefined || parsed.lineNumber <= endLine);
|
|
48
|
+
parsedLines.push({
|
|
49
|
+
index: i,
|
|
50
|
+
lineNumber: parsed.lineNumber,
|
|
51
|
+
inRange,
|
|
52
|
+
hasNonCommentToken,
|
|
53
|
+
});
|
|
54
|
+
inRangeByIndex.set(i, inRange);
|
|
55
|
+
}
|
|
56
|
+
let lastRangeIndex;
|
|
57
|
+
for (const entry of parsedLines) {
|
|
58
|
+
if (entry.inRange) {
|
|
59
|
+
lastRangeIndex = entry.index;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const removedTargets = new Map();
|
|
63
|
+
for (const entry of parsedLines) {
|
|
64
|
+
if (!entry.inRange) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (entry.index === lastRangeIndex) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (entry.hasNonCommentToken) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const next = findNextNonCommentLine(entry.index, parsedLines);
|
|
74
|
+
if (next !== undefined) {
|
|
75
|
+
removedTargets.set(entry.lineNumber, next);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const replacementsByLine = new Map();
|
|
79
|
+
const structure = collectProgramStructure(basicCode);
|
|
80
|
+
for (const reference of structure.references) {
|
|
81
|
+
const newTarget = removedTargets.get(reference.target);
|
|
82
|
+
if (newTarget === undefined || newTarget === reference.target) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (!replacementsByLine.has(reference.lineIndex)) {
|
|
86
|
+
replacementsByLine.set(reference.lineIndex, []);
|
|
87
|
+
}
|
|
88
|
+
replacementsByLine.get(reference.lineIndex).push({
|
|
89
|
+
start: reference.start,
|
|
90
|
+
end: reference.end,
|
|
91
|
+
value: newTarget.toString(),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
for (const [lineIndex, replacements] of replacementsByLine.entries()) {
|
|
95
|
+
let text = lines[lineIndex];
|
|
96
|
+
const sorted = replacements.sort((a, b) => b.start - a.start);
|
|
97
|
+
for (const replacement of sorted) {
|
|
98
|
+
text =
|
|
99
|
+
text.slice(0, replacement.start) +
|
|
100
|
+
replacement.value +
|
|
101
|
+
text.slice(replacement.end);
|
|
102
|
+
}
|
|
103
|
+
lines[lineIndex] = text;
|
|
104
|
+
}
|
|
68
105
|
const resultLines = [];
|
|
69
|
-
for (
|
|
70
|
-
const parsed = parseLine(
|
|
106
|
+
for (let i = 0; i < lines.length; i++) {
|
|
107
|
+
const parsed = parseLine(lines[i]);
|
|
71
108
|
if (!parsed) {
|
|
72
|
-
continue;
|
|
109
|
+
continue;
|
|
73
110
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
111
|
+
if (!inRangeByIndex.get(i)) {
|
|
112
|
+
resultLines.push(lines[i].trimEnd());
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const commentStart = findCommentStart(parsed.code);
|
|
116
|
+
const codeNoComment = commentStart === undefined ? parsed.code : parsed.code.slice(0, commentStart);
|
|
79
117
|
const codeTrimmed = codeNoComment.replace(/[\s:]+$/g, '');
|
|
80
|
-
// If line becomes empty, keep it only if it's a GOTO/GOSUB target
|
|
81
118
|
if (!codeTrimmed.trim()) {
|
|
82
|
-
if (
|
|
83
|
-
resultLines.push(`${lineNumber} REM`);
|
|
119
|
+
if (i === lastRangeIndex) {
|
|
120
|
+
resultLines.push(`${parsed.lineNumber} REM`);
|
|
84
121
|
}
|
|
85
122
|
continue;
|
|
86
123
|
}
|
|
87
|
-
resultLines.push(`${lineNumber} ${codeTrimmed.trim()}`);
|
|
124
|
+
resultLines.push(`${parsed.lineNumber} ${codeTrimmed.trim()}`);
|
|
88
125
|
}
|
|
89
126
|
return resultLines.join('\n');
|
|
90
127
|
}
|
|
128
|
+
function findNextNonCommentLine(currentIndex, entries) {
|
|
129
|
+
for (const entry of entries) {
|
|
130
|
+
if (entry.index <= currentIndex) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (entry.hasNonCommentToken) {
|
|
134
|
+
return entry.lineNumber;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
91
139
|
/**
|
|
92
140
|
* Remove comments from a .DO file (file-based API).
|
|
93
141
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removeComments.js","sourceRoot":"","sources":["../../src/removeComments/removeComments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"removeComments.js","sourceRoot":"","sources":["../../src/removeComments/removeComments.ts"],"names":[],"mappings":"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"}
|
package/dist/squash/squash.d.ts
CHANGED
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
* @param basicCode - BASIC source code with line numbers
|
|
11
11
|
* @returns Squashed code
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
13
|
+
export interface SquashOptions {
|
|
14
|
+
startLine?: number;
|
|
15
|
+
endLine?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function squashBasicCode(basicCode: string, options?: SquashOptions): string;
|
|
14
18
|
/**
|
|
15
19
|
* Squash a single BASIC line.
|
|
16
20
|
*
|
package/dist/squash/squash.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { findCommentStart } from '../commentUtils.js';
|
|
2
|
-
|
|
3
|
-
* TRS-80 Model 100 BASIC Squash - Core Logic
|
|
4
|
-
*
|
|
5
|
-
* Squashes BASIC code by removing unnecessary whitespace and optimizing PRINT statements.
|
|
6
|
-
* Preserves REM, DATA, and string literals.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Squash BASIC code by removing unnecessary whitespace.
|
|
10
|
-
*
|
|
11
|
-
* @param basicCode - BASIC source code with line numbers
|
|
12
|
-
* @returns Squashed code
|
|
13
|
-
*/
|
|
14
|
-
export function squashBasicCode(basicCode) {
|
|
2
|
+
export function squashBasicCode(basicCode, options = {}) {
|
|
15
3
|
const lines = basicCode.split(/\r?\n/);
|
|
16
4
|
const resultLines = [];
|
|
5
|
+
const startLine = options.startLine;
|
|
6
|
+
const endLine = options.endLine;
|
|
17
7
|
for (const line of lines) {
|
|
8
|
+
if (startLine !== undefined || endLine !== undefined) {
|
|
9
|
+
const lineNumber = parseLineNumber(line);
|
|
10
|
+
const inRange = lineNumber !== undefined &&
|
|
11
|
+
(startLine === undefined || lineNumber >= startLine) &&
|
|
12
|
+
(endLine === undefined || lineNumber <= endLine);
|
|
13
|
+
if (!inRange) {
|
|
14
|
+
resultLines.push(line);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
18
|
const squashed = squashLine(line);
|
|
19
19
|
if (squashed !== undefined) {
|
|
20
20
|
resultLines.push(squashed);
|
|
@@ -78,6 +78,14 @@ function shouldSkipBody(body) {
|
|
|
78
78
|
}
|
|
79
79
|
return upper.startsWith('REM');
|
|
80
80
|
}
|
|
81
|
+
function parseLineNumber(line) {
|
|
82
|
+
const match = /^\s*(\d+)/.exec(line);
|
|
83
|
+
if (!match) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const value = parseInt(match[1], 10);
|
|
87
|
+
return Number.isNaN(value) ? undefined : value;
|
|
88
|
+
}
|
|
81
89
|
export function removeWhitespaceOutsideStrings(text) {
|
|
82
90
|
let result = '';
|
|
83
91
|
let inString = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"squash.js","sourceRoot":"","sources":["../../src/squash/squash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"squash.js","sourceRoot":"","sources":["../../src/squash/squash.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { TOKENS } from '../tokens.js';
|
|
2
|
+
import { lexLine } from '../lexer/lex.js';
|
|
3
|
+
import { TokenizeError } from './errors.js';
|
|
2
4
|
/**
|
|
3
5
|
* Tokenize ASCII BASIC line code to binary bytes.
|
|
4
6
|
*
|
|
@@ -7,68 +9,63 @@ import { TOKENS } from '../tokens.js';
|
|
|
7
9
|
*/
|
|
8
10
|
function tokenizeLine(asciiCode) {
|
|
9
11
|
const tokenized = [];
|
|
10
|
-
|
|
11
|
-
let
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
inString = !inString;
|
|
16
|
-
tokenized.push('"'.charCodeAt(0));
|
|
17
|
-
i++;
|
|
18
|
-
continue;
|
|
12
|
+
const tokens = lexLine(asciiCode);
|
|
13
|
+
let cursor = 0;
|
|
14
|
+
const pushAscii = (text) => {
|
|
15
|
+
for (let i = 0; i < text.length; i++) {
|
|
16
|
+
tokenized.push(text.charCodeAt(i));
|
|
19
17
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
tokenized.push(0x8E); // REM token
|
|
25
|
-
tokenized.push(0xFF); // Quote token
|
|
26
|
-
// Skip rest of line (it's a comment)
|
|
27
|
-
break;
|
|
18
|
+
};
|
|
19
|
+
for (const token of tokens) {
|
|
20
|
+
if (token.start > cursor) {
|
|
21
|
+
pushAscii(asciiCode.slice(cursor, token.start));
|
|
28
22
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
if (token.kind === 'comment') {
|
|
24
|
+
if (token.text.startsWith("'")) {
|
|
25
|
+
tokenized.push(0x3A);
|
|
26
|
+
tokenized.push(TOKENS.REM);
|
|
27
|
+
tokenized.push(TOKENS["'"]);
|
|
28
|
+
return new Uint8Array(tokenized);
|
|
29
|
+
}
|
|
30
|
+
if (token.text.toUpperCase().startsWith('REM')) {
|
|
31
|
+
tokenized.push(TOKENS.REM);
|
|
32
|
+
pushAscii(token.text.slice(3));
|
|
33
|
+
return new Uint8Array(tokenized);
|
|
34
|
+
}
|
|
35
|
+
pushAscii(token.text);
|
|
36
|
+
return new Uint8Array(tokenized);
|
|
34
37
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
i += keywordLen;
|
|
46
|
-
matched = true;
|
|
47
|
-
// Special handling for REM and DATA: rest of line is literal
|
|
48
|
-
if (upperCandidate === 'REM' || upperCandidate === 'DATA') {
|
|
49
|
-
// Copy rest of line as-is after REM/DATA
|
|
50
|
-
for (let j = i; j < asciiCode.length; j++) {
|
|
51
|
-
tokenized.push(asciiCode.charCodeAt(j));
|
|
52
|
-
}
|
|
53
|
-
i = asciiCode.length;
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
// Special handling: ELSE token must be preceded by colon
|
|
57
|
-
if (upperCandidate === 'ELSE') {
|
|
58
|
-
// Ensure there's a colon before ELSE
|
|
59
|
-
if (tokenized.length > 1 && tokenized[tokenized.length - 2] !== 0x3A) {
|
|
60
|
-
// Insert colon before ELSE token
|
|
61
|
-
tokenized.splice(tokenized.length - 1, 0, 0x3A);
|
|
62
|
-
}
|
|
38
|
+
if (token.kind === 'keyword' && token.keyword) {
|
|
39
|
+
const keyword = token.keyword;
|
|
40
|
+
tokenized.push(TOKENS[keyword]);
|
|
41
|
+
if (keyword === 'REM' || keyword === 'DATA') {
|
|
42
|
+
pushAscii(asciiCode.slice(token.end));
|
|
43
|
+
return new Uint8Array(tokenized);
|
|
44
|
+
}
|
|
45
|
+
if (keyword === 'ELSE') {
|
|
46
|
+
if (tokenized.length > 1 && tokenized[tokenized.length - 2] !== 0x3A) {
|
|
47
|
+
tokenized.splice(tokenized.length - 1, 0, 0x3A);
|
|
63
48
|
}
|
|
64
|
-
break;
|
|
65
49
|
}
|
|
50
|
+
cursor = token.end;
|
|
51
|
+
continue;
|
|
66
52
|
}
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
53
|
+
if (token.kind === 'operator') {
|
|
54
|
+
const upper = token.text.toUpperCase();
|
|
55
|
+
if (upper in TOKENS) {
|
|
56
|
+
tokenized.push(TOKENS[upper]);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
pushAscii(token.text);
|
|
60
|
+
}
|
|
61
|
+
cursor = token.end;
|
|
62
|
+
continue;
|
|
71
63
|
}
|
|
64
|
+
pushAscii(token.text);
|
|
65
|
+
cursor = token.end;
|
|
66
|
+
}
|
|
67
|
+
if (cursor < asciiCode.length) {
|
|
68
|
+
pushAscii(asciiCode.slice(cursor));
|
|
72
69
|
}
|
|
73
70
|
return new Uint8Array(tokenized);
|
|
74
71
|
}
|
|
@@ -102,10 +99,19 @@ function createTokenizedFile(inputText, baseAddress = 0x8001) {
|
|
|
102
99
|
const lines = inputText.split(/\r?\n/);
|
|
103
100
|
// Parse and tokenize lines
|
|
104
101
|
const tokenizedLines = [];
|
|
105
|
-
for (
|
|
102
|
+
for (let index = 0; index < lines.length; index++) {
|
|
103
|
+
const line = lines[index];
|
|
104
|
+
if (!line.trim()) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
106
107
|
const parsed = parseLine(line);
|
|
107
108
|
if (!parsed) {
|
|
108
|
-
|
|
109
|
+
const firstNonWhitespace = line.search(/\S/);
|
|
110
|
+
const col = firstNonWhitespace === -1 ? 1 : firstNonWhitespace + 1;
|
|
111
|
+
throw new TokenizeError('PARSE_ERROR', 'Line does not start with a line number.', index + 1, col);
|
|
112
|
+
}
|
|
113
|
+
if (parsed.lineNumber < 0 || parsed.lineNumber > 65529) {
|
|
114
|
+
throw new TokenizeError('LINE_NUMBER_INVALID', `Invalid line number ${parsed.lineNumber}. Allowed: 0–65529.`, index + 1, 1);
|
|
109
115
|
}
|
|
110
116
|
try {
|
|
111
117
|
const tokenizedCode = tokenizeLine(parsed.code);
|
|
@@ -115,8 +121,11 @@ function createTokenizedFile(inputText, baseAddress = 0x8001) {
|
|
|
115
121
|
});
|
|
116
122
|
}
|
|
117
123
|
catch (error) {
|
|
118
|
-
|
|
119
|
-
|
|
124
|
+
if (error instanceof TokenizeError) {
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
128
|
+
throw new TokenizeError('PARSE_ERROR', `Tokenization failed: ${message}`, index + 1, 1);
|
|
120
129
|
}
|
|
121
130
|
}
|
|
122
131
|
// Calculate addresses for all lines first
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenizeProgram.js","sourceRoot":"","sources":["../../src/tokenize/tokenizeProgram.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"tokenizeProgram.js","sourceRoot":"","sources":["../../src/tokenize/tokenizeProgram.ts"],"names":[],"mappings":"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"}
|