takomusic 1.3.18 → 2.1.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/__tests__/checker.test.js +88 -247
- package/dist/__tests__/checker.test.js.map +1 -1
- package/dist/__tests__/compiler.test.js +69 -184
- package/dist/__tests__/compiler.test.js.map +1 -1
- package/dist/__tests__/generators.test.js +14 -14
- package/dist/__tests__/interpreter.test.js +150 -215
- package/dist/__tests__/interpreter.test.js.map +1 -1
- package/dist/__tests__/parser.test.js +171 -92
- package/dist/__tests__/parser.test.js.map +1 -1
- package/dist/checker/checker.d.ts +7 -3
- package/dist/checker/checker.d.ts.map +1 -1
- package/dist/checker/checker.js +149 -101
- package/dist/checker/checker.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +100 -333
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/compiler/compiler.d.ts +0 -1
- package/dist/compiler/compiler.d.ts.map +1 -1
- package/dist/compiler/compiler.js +4 -28
- package/dist/compiler/compiler.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -9
- package/dist/errors.js.map +1 -1
- package/dist/formatter/formatter.d.ts +8 -2
- package/dist/formatter/formatter.d.ts.map +1 -1
- package/dist/formatter/formatter.js +155 -36
- package/dist/formatter/formatter.js.map +1 -1
- package/dist/generators/musicxml.d.ts.map +1 -1
- package/dist/generators/musicxml.js +202 -179
- package/dist/generators/musicxml.js.map +1 -1
- package/dist/importers/musicxml.d.ts.map +1 -1
- package/dist/importers/musicxml.js +146 -130
- package/dist/importers/musicxml.js.map +1 -1
- package/dist/interpreter/interpreter.d.ts +12 -3
- package/dist/interpreter/interpreter.d.ts.map +1 -1
- package/dist/interpreter/interpreter.js +391 -92
- package/dist/interpreter/interpreter.js.map +1 -1
- package/dist/interpreter/trackState.d.ts +2 -1
- package/dist/interpreter/trackState.d.ts.map +1 -1
- package/dist/interpreter/trackState.js.map +1 -1
- package/dist/lexer/lexer.d.ts +2 -0
- package/dist/lexer/lexer.d.ts.map +1 -1
- package/dist/lexer/lexer.js +47 -3
- package/dist/lexer/lexer.js.map +1 -1
- package/dist/parser/parser.d.ts +31 -4
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +713 -76
- package/dist/parser/parser.js.map +1 -1
- package/dist/types/ast.d.ts +143 -33
- package/dist/types/ast.d.ts.map +1 -1
- package/dist/types/ast.js +1 -1
- package/dist/types/ast.js.map +1 -1
- package/dist/types/ir/core.d.ts +50 -3
- package/dist/types/ir/core.d.ts.map +1 -1
- package/dist/types/ir/core.js +1 -1
- package/dist/types/ir/core.js.map +1 -1
- package/dist/types/token.d.ts +23 -0
- package/dist/types/token.d.ts.map +1 -1
- package/dist/types/token.js +53 -2
- package/dist/types/token.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,28 +2,27 @@ import { describe, it, expect } from 'vitest';
|
|
|
2
2
|
import { Lexer } from '../lexer/index.js';
|
|
3
3
|
import { Parser } from '../parser/index.js';
|
|
4
4
|
import { Checker } from '../checker/checker.js';
|
|
5
|
-
import * as fs from 'fs';
|
|
6
5
|
import * as path from 'path';
|
|
7
|
-
|
|
8
|
-
describe('Checker', () => {
|
|
6
|
+
describe('Checker v2.0', () => {
|
|
9
7
|
function check(source, filePath = 'test.mf') {
|
|
10
8
|
const lexer = new Lexer(source, filePath);
|
|
11
9
|
const tokens = lexer.tokenize();
|
|
12
10
|
const parser = new Parser(tokens, filePath);
|
|
13
|
-
const
|
|
11
|
+
const score = parser.parse();
|
|
14
12
|
const checker = new Checker(path.dirname(filePath));
|
|
15
|
-
return checker.check(
|
|
13
|
+
return checker.check(score, filePath);
|
|
16
14
|
}
|
|
17
|
-
it('should pass valid
|
|
15
|
+
it('should pass valid score', () => {
|
|
18
16
|
const source = `
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
tempo(120);
|
|
17
|
+
score "Test" {
|
|
18
|
+
tempo 120
|
|
19
|
+
time 4/4
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
part Vocal {
|
|
22
|
+
phrase {
|
|
23
|
+
notes: | C4 q |;
|
|
24
|
+
lyrics mora: あ;
|
|
25
|
+
}
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
`;
|
|
@@ -31,104 +30,68 @@ describe('Checker', () => {
|
|
|
31
30
|
const errors = diagnostics.filter(d => d.severity === 'error');
|
|
32
31
|
expect(errors.length).toBe(0);
|
|
33
32
|
});
|
|
34
|
-
it('should detect
|
|
33
|
+
it('should detect E100 (lyric count mismatch)', () => {
|
|
35
34
|
const source = `
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`;
|
|
40
|
-
const diagnostics = check(source);
|
|
41
|
-
expect(diagnostics.some(d => d.code === 'E400' && d.message.includes('main'))).toBe(true);
|
|
42
|
-
});
|
|
43
|
-
it('should detect E400 (undefined symbol)', () => {
|
|
44
|
-
const source = `
|
|
45
|
-
export proc main() {
|
|
46
|
-
ppq(480);
|
|
47
|
-
timeSig(4, 4);
|
|
48
|
-
tempo(120);
|
|
49
|
-
const x = undefinedVar;
|
|
50
|
-
}
|
|
51
|
-
`;
|
|
52
|
-
const diagnostics = check(source);
|
|
53
|
-
expect(diagnostics.some(d => d.code === 'E400' && d.message.includes('undefinedVar'))).toBe(true);
|
|
54
|
-
});
|
|
55
|
-
it('should detect E050 (global after track)', () => {
|
|
56
|
-
const source = `
|
|
57
|
-
export proc main() {
|
|
58
|
-
ppq(480);
|
|
59
|
-
timeSig(4, 4);
|
|
60
|
-
tempo(120);
|
|
35
|
+
score "Test" {
|
|
36
|
+
tempo 120
|
|
37
|
+
time 4/4
|
|
61
38
|
|
|
62
|
-
|
|
63
|
-
|
|
39
|
+
part Vocal {
|
|
40
|
+
phrase {
|
|
41
|
+
notes: | C4 q D4 q E4 q F4 q |;
|
|
42
|
+
lyrics mora: あ い;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
64
45
|
}
|
|
65
46
|
`;
|
|
66
47
|
const diagnostics = check(source);
|
|
67
|
-
expect(diagnostics.some(d => d.code === '
|
|
48
|
+
expect(diagnostics.some(d => d.code === 'E100')).toBe(true);
|
|
68
49
|
});
|
|
69
|
-
it('should
|
|
50
|
+
it('should detect E211 (kanji in lyrics)', () => {
|
|
70
51
|
const source = `
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
52
|
+
score "Test" {
|
|
53
|
+
tempo 120
|
|
54
|
+
time 4/4
|
|
74
55
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
56
|
+
part Vocal {
|
|
57
|
+
phrase {
|
|
58
|
+
notes: | C4 q |;
|
|
59
|
+
lyrics mora: 音;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
80
62
|
}
|
|
81
63
|
`;
|
|
82
64
|
const diagnostics = check(source);
|
|
83
|
-
|
|
84
|
-
expect(diagnostics.some(d => d.code === 'W310' && d.severity === 'warning')).toBe(true);
|
|
65
|
+
expect(diagnostics.some(d => d.code === 'E211')).toBe(true);
|
|
85
66
|
});
|
|
86
|
-
it('should warn
|
|
67
|
+
it('should warn W110 (vocal pitch out of range)', () => {
|
|
87
68
|
const source = `
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
69
|
+
score "Test" {
|
|
70
|
+
tempo 120
|
|
71
|
+
time 4/4
|
|
91
72
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
ppq(480);
|
|
98
|
-
timeSig(4, 4);
|
|
99
|
-
tempo(120);
|
|
100
|
-
foo();
|
|
101
|
-
}
|
|
102
|
-
`;
|
|
103
|
-
const diagnostics = check(source);
|
|
104
|
-
// Changed from E310 error to W310 warning
|
|
105
|
-
expect(diagnostics.some(d => d.code === 'W310' && d.severity === 'warning')).toBe(true);
|
|
106
|
-
});
|
|
107
|
-
it('should warn W401 (for range not constant with let)', () => {
|
|
108
|
-
const source = `
|
|
109
|
-
export proc main() {
|
|
110
|
-
ppq(480);
|
|
111
|
-
timeSig(4, 4);
|
|
112
|
-
tempo(120);
|
|
113
|
-
let n = 4;
|
|
114
|
-
for (i in 1..=n) {
|
|
115
|
-
const x = i;
|
|
73
|
+
part Vocal {
|
|
74
|
+
phrase {
|
|
75
|
+
notes: | C2 q |;
|
|
76
|
+
lyrics mora: あ;
|
|
77
|
+
}
|
|
116
78
|
}
|
|
117
79
|
}
|
|
118
80
|
`;
|
|
119
81
|
const diagnostics = check(source);
|
|
120
|
-
|
|
121
|
-
expect(diagnostics.some(d => d.code === 'W401' && d.severity === 'warning')).toBe(true);
|
|
82
|
+
expect(diagnostics.some(d => d.code === 'W110')).toBe(true);
|
|
122
83
|
});
|
|
123
|
-
it('should allow
|
|
84
|
+
it('should allow tied notes with fewer lyrics', () => {
|
|
124
85
|
const source = `
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
86
|
+
score "Test" {
|
|
87
|
+
tempo 120
|
|
88
|
+
time 4/4
|
|
89
|
+
|
|
90
|
+
part Vocal {
|
|
91
|
+
phrase {
|
|
92
|
+
notes: | C4 h~ C4 h |;
|
|
93
|
+
lyrics mora: あ;
|
|
94
|
+
}
|
|
132
95
|
}
|
|
133
96
|
}
|
|
134
97
|
`;
|
|
@@ -136,103 +99,17 @@ describe('Checker', () => {
|
|
|
136
99
|
const errors = diagnostics.filter(d => d.severity === 'error');
|
|
137
100
|
expect(errors.length).toBe(0);
|
|
138
101
|
});
|
|
139
|
-
it('should
|
|
140
|
-
const source = `
|
|
141
|
-
export proc main() {
|
|
142
|
-
ppq(480);
|
|
143
|
-
timeSig(4, 4);
|
|
144
|
-
tempo(120);
|
|
145
|
-
track(midi, t1, { ch: 1 }) {
|
|
146
|
-
note(C10, 1/4);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
`;
|
|
150
|
-
const diagnostics = check(source);
|
|
151
|
-
expect(diagnostics.some(d => d.code === 'E110')).toBe(true);
|
|
152
|
-
});
|
|
153
|
-
it('should warn W110 (vocal pitch out of typical range)', () => {
|
|
102
|
+
it('should allow melisma', () => {
|
|
154
103
|
const source = `
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const diagnostics = check(source);
|
|
165
|
-
expect(diagnostics.some(d => d.code === 'W110')).toBe(true);
|
|
166
|
-
});
|
|
167
|
-
it('should warn W100 (extremely short note)', () => {
|
|
168
|
-
const source = `
|
|
169
|
-
export proc main() {
|
|
170
|
-
ppq(480);
|
|
171
|
-
timeSig(4, 4);
|
|
172
|
-
tempo(120);
|
|
173
|
-
track(midi, t1, { ch: 1 }) {
|
|
174
|
-
note(C4, 1/128);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
`;
|
|
178
|
-
const diagnostics = check(source);
|
|
179
|
-
expect(diagnostics.some(d => d.code === 'W100')).toBe(true);
|
|
180
|
-
});
|
|
181
|
-
it('should warn W200 (too many tempo events)', () => {
|
|
182
|
-
let tempoLines = '';
|
|
183
|
-
for (let i = 0; i < 130; i++) {
|
|
184
|
-
tempoLines += `tempo(${120 + i});\n`;
|
|
185
|
-
}
|
|
186
|
-
const source = `
|
|
187
|
-
export proc main() {
|
|
188
|
-
ppq(480);
|
|
189
|
-
timeSig(4, 4);
|
|
190
|
-
${tempoLines}
|
|
191
|
-
}
|
|
192
|
-
`;
|
|
193
|
-
const diagnostics = check(source);
|
|
194
|
-
expect(diagnostics.some(d => d.code === 'W200')).toBe(true);
|
|
195
|
-
});
|
|
196
|
-
it('should detect E300 (top-level execution in import)', () => {
|
|
197
|
-
// Create a temp file for the import
|
|
198
|
-
const tmpDir = os.tmpdir();
|
|
199
|
-
const libPath = path.join(tmpDir, 'test_lib.mf');
|
|
200
|
-
const mainPath = path.join(tmpDir, 'test_main.mf');
|
|
201
|
-
fs.writeFileSync(libPath, `
|
|
202
|
-
note(C4, 1/4, "あ");
|
|
203
|
-
export proc FOO() { }
|
|
204
|
-
`);
|
|
205
|
-
const mainSource = `
|
|
206
|
-
import { FOO } from "./test_lib.mf";
|
|
207
|
-
export proc main() {
|
|
208
|
-
ppq(480);
|
|
209
|
-
timeSig(4, 4);
|
|
210
|
-
tempo(120);
|
|
211
|
-
FOO();
|
|
212
|
-
}
|
|
213
|
-
`;
|
|
214
|
-
fs.writeFileSync(mainPath, mainSource);
|
|
215
|
-
const lexer = new Lexer(mainSource, mainPath);
|
|
216
|
-
const tokens = lexer.tokenize();
|
|
217
|
-
const parser = new Parser(tokens, mainPath);
|
|
218
|
-
const program = parser.parse();
|
|
219
|
-
const checker = new Checker(tmpDir);
|
|
220
|
-
const diagnostics = checker.check(program, mainPath);
|
|
221
|
-
// Cleanup
|
|
222
|
-
fs.unlinkSync(libPath);
|
|
223
|
-
fs.unlinkSync(mainPath);
|
|
224
|
-
expect(diagnostics.some(d => d.code === 'E300')).toBe(true);
|
|
225
|
-
});
|
|
226
|
-
it('should allow drum names without E400', () => {
|
|
227
|
-
const source = `
|
|
228
|
-
export proc main() {
|
|
229
|
-
ppq(480);
|
|
230
|
-
timeSig(4, 4);
|
|
231
|
-
tempo(120);
|
|
232
|
-
track(midi, drums, { ch: 10 }) {
|
|
233
|
-
drum(kick, 1/4);
|
|
234
|
-
drum(snare, 1/4);
|
|
235
|
-
drum(hhc, 1/4);
|
|
104
|
+
score "Test" {
|
|
105
|
+
tempo 120
|
|
106
|
+
time 4/4
|
|
107
|
+
|
|
108
|
+
part Vocal {
|
|
109
|
+
phrase {
|
|
110
|
+
notes: | C4 q D4 q E4 q |;
|
|
111
|
+
lyrics mora: あ _ _;
|
|
112
|
+
}
|
|
236
113
|
}
|
|
237
114
|
}
|
|
238
115
|
`;
|
|
@@ -240,74 +117,38 @@ describe('Checker', () => {
|
|
|
240
117
|
const errors = diagnostics.filter(d => d.severity === 'error');
|
|
241
118
|
expect(errors.length).toBe(0);
|
|
242
119
|
});
|
|
243
|
-
it('should
|
|
120
|
+
it('should pass valid MIDI part', () => {
|
|
244
121
|
const source = `
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
`;
|
|
254
|
-
const diagnostics = check(source);
|
|
255
|
-
expect(diagnostics.some(d => d.code === 'E210')).toBe(true);
|
|
256
|
-
});
|
|
257
|
-
it('should detect E210 (vocal note empty lyric)', () => {
|
|
258
|
-
const source = `
|
|
259
|
-
export proc main() {
|
|
260
|
-
ppq(480);
|
|
261
|
-
timeSig(4, 4);
|
|
262
|
-
tempo(120);
|
|
263
|
-
track(vocal, v1, {}) {
|
|
264
|
-
note(C4, 1/4, "");
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
`;
|
|
268
|
-
const diagnostics = check(source);
|
|
269
|
-
expect(diagnostics.some(d => d.code === 'E210')).toBe(true);
|
|
270
|
-
});
|
|
271
|
-
it('should detect E220 (drum in vocal track)', () => {
|
|
272
|
-
const source = `
|
|
273
|
-
export proc main() {
|
|
274
|
-
ppq(480);
|
|
275
|
-
timeSig(4, 4);
|
|
276
|
-
tempo(120);
|
|
277
|
-
track(vocal, v1, {}) {
|
|
278
|
-
drum(kick, 1/4);
|
|
122
|
+
score "Test" {
|
|
123
|
+
tempo 120
|
|
124
|
+
time 4/4
|
|
125
|
+
|
|
126
|
+
part Piano {
|
|
127
|
+
midi ch:1 program:0
|
|
128
|
+
| C4 q E4 q G4 q C5 q |
|
|
279
129
|
}
|
|
280
130
|
}
|
|
281
131
|
`;
|
|
282
132
|
const diagnostics = check(source);
|
|
283
|
-
|
|
133
|
+
const errors = diagnostics.filter(d => d.severity === 'error');
|
|
134
|
+
expect(errors.length).toBe(0);
|
|
284
135
|
});
|
|
285
|
-
it('should
|
|
136
|
+
it('should pass score with multiple parts', () => {
|
|
286
137
|
const source = `
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
138
|
+
score "Test" {
|
|
139
|
+
tempo 120
|
|
140
|
+
time 4/4
|
|
141
|
+
|
|
142
|
+
part Vocal {
|
|
143
|
+
phrase {
|
|
144
|
+
notes: | C4 q D4 q |;
|
|
145
|
+
lyrics mora: あ い;
|
|
146
|
+
}
|
|
293
147
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
});
|
|
299
|
-
it('should pass valid vocal track', () => {
|
|
300
|
-
const source = `
|
|
301
|
-
export proc main() {
|
|
302
|
-
ppq(480);
|
|
303
|
-
timeSig(4, 4);
|
|
304
|
-
tempo(120);
|
|
305
|
-
track(vocal, v1, {}) {
|
|
306
|
-
at(1:1);
|
|
307
|
-
note(C4, 1/4, "あ");
|
|
308
|
-
note(D4, 1/4, "い");
|
|
309
|
-
rest(1/4);
|
|
310
|
-
note(E4, 1/4, "う");
|
|
148
|
+
|
|
149
|
+
part Piano {
|
|
150
|
+
midi ch:1 program:0
|
|
151
|
+
| [C3 E3 G3] h [F3 A3 C4] h |
|
|
311
152
|
}
|
|
312
153
|
}
|
|
313
154
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checker.test.js","sourceRoot":"","sources":["../../src/__tests__/checker.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"checker.test.js","sourceRoot":"","sources":["../../src/__tests__/checker.test.ts"],"names":[],"mappings":"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"}
|