nadesiko3 3.4.13 → 3.4.14
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/batch/command.txt +292 -292
- package/core/package.json +1 -1
- package/core/src/nako_core_version.mjs +2 -2
- package/core/src/nako_core_version.mts +2 -2
- package/core/src/nako_from_dncl2.mjs +34 -2
- package/core/src/nako_from_dncl2.mts +31 -2
- package/core/src/nako_gen.mjs +110 -76
- package/core/src/nako_gen.mts +114 -75
- package/core/src/plugin_system.mjs +13 -3
- package/core/src/plugin_system.mts +11 -3
- package/core/test/dncl2_test.mjs +161 -152
- package/package.json +4 -33
- package/release/_hash.txt +20 -20
- package/release/_script-tags.txt +14 -14
- package/release/nako_gen_async.js +1 -1
- package/release/nako_gen_async.js.map +1 -1
- package/release/plugin_datetime.js +1 -1
- package/release/plugin_datetime.js.map +1 -1
- package/release/stats.json +1 -1
- package/release/version.js +1 -1
- package/release/version.js.map +1 -1
- package/release/wnako3.js +1 -1
- package/release/wnako3.js.map +1 -1
- package/release/wnako3webworker.js +1 -1
- package/release/wnako3webworker.js.map +1 -1
- package/src/nako_version.mjs +2 -2
- package/src/nako_version.mts +2 -2
- package/src/plugin_browser.mjs +1 -1
- package/src/plugin_browser.mts +1 -1
- package/src/plugin_browser_ajax.mjs +6 -6
- package/src/plugin_browser_ajax.mts +8 -8
- package/src/plugin_browser_canvas.mjs +2 -2
- package/src/plugin_browser_canvas.mts +2 -2
- package/src/plugin_browser_chart.mjs +17 -13
- package/src/plugin_browser_chart.mts +25 -21
- package/src/plugin_browser_crypto.mjs +1 -1
- package/src/plugin_browser_crypto.mts +2 -2
- package/src/plugin_browser_dom_basic.mjs +5 -5
- package/src/plugin_browser_dom_basic.mts +5 -5
- package/src/plugin_browser_dom_event.mjs +17 -17
- package/src/plugin_browser_dom_event.mts +17 -17
- package/src/plugin_browser_dom_parts.mjs +21 -21
- package/src/plugin_browser_dom_parts.mts +21 -21
- package/src/plugin_browser_geolocation.mjs +2 -2
- package/src/plugin_browser_geolocation.mts +2 -2
- package/src/plugin_browser_storage.mjs +3 -3
- package/src/plugin_browser_storage.mts +3 -3
- package/src/plugin_datetime.mjs +9 -9
- package/src/plugin_node.mjs +3 -3
- package/src/plugin_node.mts +3 -3
- package/test/node/plugin_node_test.mjs +181 -180
package/core/package.json
CHANGED
|
@@ -45,10 +45,10 @@ export function convertDNCL2(tokens) {
|
|
|
45
45
|
line.splice(nai, 1);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
// そうでなければ(そう|でなければ) → 違えば
|
|
48
|
+
// そうでなければ(そう|でなければ) or そうでなく → 違えば
|
|
49
49
|
for (let ni = 0; ni < line.length; ni++) {
|
|
50
50
|
const t = line[ni];
|
|
51
|
-
if (t.value === 'そう' && t.josi === 'でなければ') {
|
|
51
|
+
if ((t.value === 'そう' || t.value === 'それ') && (t.josi === 'でなければ' || t.josi === 'でなく')) {
|
|
52
52
|
t.type = '違えば';
|
|
53
53
|
t.value = '違えば';
|
|
54
54
|
t.josi = '';
|
|
@@ -92,6 +92,38 @@ export function convertDNCL2(tokens) {
|
|
|
92
92
|
}
|
|
93
93
|
break;
|
|
94
94
|
}
|
|
95
|
+
// 'そうでなく': '違えば',
|
|
96
|
+
for (;;) {
|
|
97
|
+
const ni = findTokens(line, ['word:そう', 'word:なく']);
|
|
98
|
+
if (ni < 0) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
const sou = line[ni];
|
|
102
|
+
if (sou.josi === 'で') {
|
|
103
|
+
sou.type = '違えば';
|
|
104
|
+
sou.value = '違えば';
|
|
105
|
+
sou.josi = '';
|
|
106
|
+
line.splice(ni + 1, 1);
|
|
107
|
+
// console.log('@@@', line.map(v => v.value).join('|'))
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
// 'そうでなくもし': '違えば,もし'
|
|
113
|
+
for (;;) {
|
|
114
|
+
const ni = findTokens(line, ['word:そう', 'word:なくもし']);
|
|
115
|
+
if (ni < 0) {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
const sou = line[ni];
|
|
119
|
+
const nakumosi = line[ni + 1];
|
|
120
|
+
sou.type = '違えば';
|
|
121
|
+
sou.value = '違えば';
|
|
122
|
+
sou.josi = '';
|
|
123
|
+
nakumosi.type = 'もし';
|
|
124
|
+
nakumosi.value = 'もし';
|
|
125
|
+
nakumosi.josi = '';
|
|
126
|
+
}
|
|
95
127
|
// Iを1から100まで1(ずつ)|増やしな(が)|ら
|
|
96
128
|
for (;;) {
|
|
97
129
|
const ni = findTokens(line, ['word:増', 'word:ら']);
|
|
@@ -47,10 +47,10 @@ export function convertDNCL2 (tokens: Token[]): Token[] {
|
|
|
47
47
|
line.splice(nai, 1)
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
// そうでなければ(そう|でなければ) → 違えば
|
|
50
|
+
// そうでなければ(そう|でなければ) or そうでなく → 違えば
|
|
51
51
|
for (let ni = 0; ni < line.length; ni++) {
|
|
52
52
|
const t = line[ni]
|
|
53
|
-
if (t.value === 'そう' && t.josi === 'でなければ') {
|
|
53
|
+
if ((t.value === 'そう' || t.value === 'それ') && (t.josi === 'でなければ' || t.josi === 'でなく')) {
|
|
54
54
|
t.type = '違えば'
|
|
55
55
|
t.value = '違えば'
|
|
56
56
|
t.josi = ''
|
|
@@ -90,6 +90,35 @@ export function convertDNCL2 (tokens: Token[]): Token[] {
|
|
|
90
90
|
break
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
// 'そうでなく': '違えば',
|
|
94
|
+
for (;;) {
|
|
95
|
+
const ni = findTokens(line, ['word:そう', 'word:なく'])
|
|
96
|
+
if (ni < 0) { break }
|
|
97
|
+
const sou = line[ni]
|
|
98
|
+
if (sou.josi === 'で') {
|
|
99
|
+
sou.type = '違えば'
|
|
100
|
+
sou.value = '違えば'
|
|
101
|
+
sou.josi = ''
|
|
102
|
+
line.splice(ni + 1, 1)
|
|
103
|
+
// console.log('@@@', line.map(v => v.value).join('|'))
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
// 'そうでなくもし': '違えば,もし'
|
|
109
|
+
for (;;) {
|
|
110
|
+
const ni = findTokens(line, ['word:そう', 'word:なくもし'])
|
|
111
|
+
if (ni < 0) { break }
|
|
112
|
+
const sou = line[ni]
|
|
113
|
+
const nakumosi = line[ni + 1]
|
|
114
|
+
sou.type = '違えば'
|
|
115
|
+
sou.value = '違えば'
|
|
116
|
+
sou.josi = ''
|
|
117
|
+
nakumosi.type = 'もし'
|
|
118
|
+
nakumosi.value = 'もし'
|
|
119
|
+
nakumosi.josi = ''
|
|
120
|
+
}
|
|
121
|
+
|
|
93
122
|
// Iを1から100まで1(ずつ)|増やしな(が)|ら
|
|
94
123
|
for (;;) {
|
|
95
124
|
const ni = findTokens(line, ['word:増', 'word:ら'])
|
package/core/src/nako_gen.mjs
CHANGED
|
@@ -86,6 +86,7 @@ export class NakoGen {
|
|
|
86
86
|
*/
|
|
87
87
|
this.warnUndefinedVar = true;
|
|
88
88
|
this.constPools = [];
|
|
89
|
+
this.constPoolsTemplate = [];
|
|
89
90
|
// 暫定変数
|
|
90
91
|
this.warnUndefinedReturnUserFunc = 1;
|
|
91
92
|
this.warnUndefinedCallingUserFunc = 1;
|
|
@@ -220,6 +221,7 @@ export class NakoGen {
|
|
|
220
221
|
code += `__v0.useDebug = ${this.debugOption.useDebug};\n`;
|
|
221
222
|
// 定数を埋め込む
|
|
222
223
|
code += 'self.constPools = ' + JSON.stringify(this.constPools) + ';\n';
|
|
224
|
+
code += 'self.constPoolsTemplate = ' + JSON.stringify(this.constPoolsTemplate) + ';\n';
|
|
223
225
|
// なでしこの関数定義を行う
|
|
224
226
|
let nakoFuncCode = '';
|
|
225
227
|
for (const key in this.nakoFuncList) {
|
|
@@ -633,15 +635,35 @@ export class NakoGen {
|
|
|
633
635
|
return lno + `return ${value};`;
|
|
634
636
|
}
|
|
635
637
|
else {
|
|
636
|
-
const poolIndex = this.
|
|
637
|
-
this.constPools.push({
|
|
638
|
-
msg: 'ユーザ関数からundefinedが返されています',
|
|
639
|
-
file: node.file,
|
|
640
|
-
line: node.line
|
|
641
|
-
});
|
|
638
|
+
const poolIndex = this.addConstPool('ユーザ関数からundefinedが返されています', [], node.file, node.line);
|
|
642
639
|
return lno + `return (__self.chk(${value}, ${poolIndex}));`;
|
|
643
640
|
}
|
|
644
641
|
}
|
|
642
|
+
getConstPoolsTemplateId(msg) {
|
|
643
|
+
let id = this.constPoolsTemplate.indexOf(msg);
|
|
644
|
+
if (id < 0) {
|
|
645
|
+
id = this.constPoolsTemplate.length;
|
|
646
|
+
this.constPoolsTemplate[id] = msg;
|
|
647
|
+
}
|
|
648
|
+
return id;
|
|
649
|
+
}
|
|
650
|
+
addConstPool(msg, args, file, line) {
|
|
651
|
+
// file
|
|
652
|
+
file = '' + file;
|
|
653
|
+
const fileNo = this.getConstPoolsTemplateId(file);
|
|
654
|
+
// msg
|
|
655
|
+
const msgNo = this.getConstPoolsTemplateId(msg);
|
|
656
|
+
// args
|
|
657
|
+
const args2 = [];
|
|
658
|
+
for (const i in args) {
|
|
659
|
+
const arg = '' + args[i];
|
|
660
|
+
const argNo = this.getConstPoolsTemplateId(arg);
|
|
661
|
+
args2.push(argNo);
|
|
662
|
+
}
|
|
663
|
+
const poolIndex = this.constPools.length;
|
|
664
|
+
this.constPools.push([msgNo, args2, fileNo, line]);
|
|
665
|
+
return poolIndex;
|
|
666
|
+
}
|
|
645
667
|
convCheckLoop(node, cmd) {
|
|
646
668
|
// ループの中であれば利用可能
|
|
647
669
|
if (!this.flagLoop) {
|
|
@@ -1268,21 +1290,8 @@ export class NakoGen {
|
|
|
1268
1290
|
}
|
|
1269
1291
|
else {
|
|
1270
1292
|
// 引数のundefinedチェックのコードを入れる
|
|
1271
|
-
const
|
|
1272
|
-
|
|
1273
|
-
this.constPools.push({
|
|
1274
|
-
msg: `命令『${funcName}』の引数にundefinedを渡しています。`,
|
|
1275
|
-
file: node.file,
|
|
1276
|
-
line: node.line
|
|
1277
|
-
});
|
|
1278
|
-
}
|
|
1279
|
-
else {
|
|
1280
|
-
this.constPools.push({
|
|
1281
|
-
msg: `ユーザ関数『『${funcName}』の引数にundefinedを渡しています。`,
|
|
1282
|
-
file: node.file,
|
|
1283
|
-
line: node.line
|
|
1284
|
-
});
|
|
1285
|
-
}
|
|
1293
|
+
const msg = (res.i === 0) ? '命令『$0』の引数にundefinedを渡しています。' : 'ユーザ命令『$0』の引数にundefinedを渡しています。';
|
|
1294
|
+
const poolIndex = this.addConstPool(msg, [funcName], node.file, node.line);
|
|
1286
1295
|
// argが空になる対策 #1315
|
|
1287
1296
|
const argStr = (arg === '') ? '""' : arg;
|
|
1288
1297
|
argsA.push(`(__self.chk(${argStr}, ${poolIndex}))`);
|
|
@@ -1588,6 +1597,68 @@ export class NakoGen {
|
|
|
1588
1597
|
return code;
|
|
1589
1598
|
}
|
|
1590
1599
|
}
|
|
1600
|
+
/** template of standalone js code */
|
|
1601
|
+
const STANDALONE_CODE = `
|
|
1602
|
+
// === generated by nadesiko3 ===
|
|
1603
|
+
// <nadesiko3standalone>
|
|
1604
|
+
// --- import
|
|
1605
|
+
import path from 'path'
|
|
1606
|
+
import { NakoRuntimeError } from './nako3runtime/nako_errors.mjs'
|
|
1607
|
+
__codeImportFiles__
|
|
1608
|
+
// --- init global self
|
|
1609
|
+
const self = {}
|
|
1610
|
+
self.coreVersion = '__coreVersion__'
|
|
1611
|
+
self.version = '__version__'
|
|
1612
|
+
self.logger = {
|
|
1613
|
+
error: (message) => { console.error(message) },
|
|
1614
|
+
warn: (message) => { console.warn(message) },
|
|
1615
|
+
send: (level, message) => { console.log(message) },
|
|
1616
|
+
runtimeError: (message, lineInfo) => { console.error(message, lineInfo) }
|
|
1617
|
+
};
|
|
1618
|
+
self.__varslist = [{}, {}, {}]
|
|
1619
|
+
self.__v0 = self.__varslist[0]
|
|
1620
|
+
self.initFuncList = []
|
|
1621
|
+
self.clearFuncList = []
|
|
1622
|
+
// --- jsInit ---
|
|
1623
|
+
__jsInit__
|
|
1624
|
+
// --- Copy module functions ---
|
|
1625
|
+
for (const mod of __importNames__) {
|
|
1626
|
+
for (const funcName in mod) {
|
|
1627
|
+
if (funcName === '初期化') {
|
|
1628
|
+
self.initFuncList.push(mod[funcName].fn)
|
|
1629
|
+
continue
|
|
1630
|
+
}
|
|
1631
|
+
if (funcName === '!クリア') {
|
|
1632
|
+
self.clearFuncList.push(mod[funcName].fn)
|
|
1633
|
+
continue
|
|
1634
|
+
}
|
|
1635
|
+
self.__varslist[0][funcName] = mod[funcName].fn
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
self.__vars = self.__varslist[2];
|
|
1639
|
+
self.__module = {};
|
|
1640
|
+
self.__locals = {};
|
|
1641
|
+
self.__genMode = 'sync';
|
|
1642
|
+
// プラグインの初期化コードを実行
|
|
1643
|
+
self.initFuncList.map(f => f(self))
|
|
1644
|
+
try {
|
|
1645
|
+
// ---------------------------
|
|
1646
|
+
// <prepareMainCode>
|
|
1647
|
+
__codeStandalone__
|
|
1648
|
+
// </prepareMainCode>
|
|
1649
|
+
// ---------------------------
|
|
1650
|
+
// <mainCode>
|
|
1651
|
+
__codeJS__
|
|
1652
|
+
// </mainCode>
|
|
1653
|
+
// ---------------------------
|
|
1654
|
+
// standaloneCodeでは、即時プラグインのクリアコードを実行
|
|
1655
|
+
self.clearFuncList.map(f => f(self))
|
|
1656
|
+
} catch (err) {
|
|
1657
|
+
self.logger.error(err);
|
|
1658
|
+
throw err;
|
|
1659
|
+
}
|
|
1660
|
+
// </nadesiko3standalone>
|
|
1661
|
+
`;
|
|
1591
1662
|
/**
|
|
1592
1663
|
* @param com
|
|
1593
1664
|
* @param ast
|
|
@@ -1619,7 +1690,6 @@ export function generateJS(com, ast, opt) {
|
|
|
1619
1690
|
// --------------------------------------------------
|
|
1620
1691
|
// <nadesiko3::gen::async id="${funcID}" times="${gen.numAsyncFn}">
|
|
1621
1692
|
async function ${asyncMain}(self) {
|
|
1622
|
-
${jsInit}
|
|
1623
1693
|
${js}
|
|
1624
1694
|
} // end of ${asyncMain}
|
|
1625
1695
|
${asyncMain}.call(self, self)
|
|
@@ -1644,7 +1714,6 @@ ${asyncMain}.call(self, self)
|
|
|
1644
1714
|
// <nadesiko3::gen::syncMode>
|
|
1645
1715
|
function ${syncMain}(self) {
|
|
1646
1716
|
try {
|
|
1647
|
-
${jsInit}
|
|
1648
1717
|
${js}
|
|
1649
1718
|
} catch (err) {
|
|
1650
1719
|
if (err.message === '__終わる__') { return }
|
|
@@ -1669,58 +1738,6 @@ ${syncMain}(self)
|
|
|
1669
1738
|
importNames.push(ff);
|
|
1670
1739
|
codeImportFiles += `import ${ff} from './nako3runtime/${f}'\n`;
|
|
1671
1740
|
}
|
|
1672
|
-
const standaloneJSCode = `\
|
|
1673
|
-
// <standaloneCode>
|
|
1674
|
-
import path from 'path'
|
|
1675
|
-
import { NakoRuntimeError } from './nako3runtime/nako_errors.mjs'
|
|
1676
|
-
${codeImportFiles}
|
|
1677
|
-
const self = {}
|
|
1678
|
-
self.coreVersion = '${com.coreVersion}'
|
|
1679
|
-
self.version = '${com.version}'
|
|
1680
|
-
self.logger = {
|
|
1681
|
-
error: (message) => { console.error(message) },
|
|
1682
|
-
warn: (message) => { console.warn(message) },
|
|
1683
|
-
send: (level, message) => { console.log(message) },
|
|
1684
|
-
};
|
|
1685
|
-
self.__varslist = [{}, {}, {}]
|
|
1686
|
-
self.__v0 = self.__varslist[0]
|
|
1687
|
-
self.initFuncList = []
|
|
1688
|
-
self.clearFuncList = []
|
|
1689
|
-
// Copy module functions
|
|
1690
|
-
for (const mod of [${importNames.join(', ')}]) {
|
|
1691
|
-
for (const funcName in mod) {
|
|
1692
|
-
if (funcName === '初期化') {
|
|
1693
|
-
self.initFuncList.push(mod[funcName].fn)
|
|
1694
|
-
continue
|
|
1695
|
-
}
|
|
1696
|
-
if (funcName === '!クリア') {
|
|
1697
|
-
self.clearFuncList.push(mod[funcName].fn)
|
|
1698
|
-
continue
|
|
1699
|
-
}
|
|
1700
|
-
self.__varslist[0][funcName] = mod[funcName].fn
|
|
1701
|
-
}
|
|
1702
|
-
}
|
|
1703
|
-
self.__vars = self.__varslist[2];
|
|
1704
|
-
self.__module = {};
|
|
1705
|
-
self.__locals = {};
|
|
1706
|
-
self.__genMode = 'sync';
|
|
1707
|
-
|
|
1708
|
-
// プラグインの初期化コードを実行
|
|
1709
|
-
self.initFuncList.map(f => f(self))
|
|
1710
|
-
|
|
1711
|
-
try {
|
|
1712
|
-
${opt.codeStandalone}
|
|
1713
|
-
// <JS:standalone>
|
|
1714
|
-
${js}
|
|
1715
|
-
// </JS:standalone>
|
|
1716
|
-
// standaloneCodeでは、即時プラグインのクリアコードを実行
|
|
1717
|
-
self.clearFuncList.map(f => f(self))
|
|
1718
|
-
} catch (err) {
|
|
1719
|
-
self.logger.error(err);
|
|
1720
|
-
throw err;
|
|
1721
|
-
}
|
|
1722
|
-
// </standaloneCode>
|
|
1723
|
-
`;
|
|
1724
1741
|
// ---
|
|
1725
1742
|
const initCode = gen.getPluginInitCode();
|
|
1726
1743
|
const runtimeEnvCode = `
|
|
@@ -1736,8 +1753,25 @@ ${js}
|
|
|
1736
1753
|
// なでしこの実行環境ありの場合(thisが有効)
|
|
1737
1754
|
runtimeEnv: runtimeEnvCode,
|
|
1738
1755
|
// JavaScript単体で動かす場合
|
|
1739
|
-
standalone:
|
|
1756
|
+
standalone: replaceTemplateCode(STANDALONE_CODE, {
|
|
1757
|
+
codeImportFiles,
|
|
1758
|
+
'coreVersion': com.coreVersion,
|
|
1759
|
+
'version': com.version,
|
|
1760
|
+
'importNames': ('[' + importNames.join(', ') + ']'),
|
|
1761
|
+
'codeStandalone': opt.codeStandalone,
|
|
1762
|
+
'codeJS': js,
|
|
1763
|
+
jsInit
|
|
1764
|
+
}),
|
|
1740
1765
|
// コード生成に使ったNakoGenのインスタンス
|
|
1741
1766
|
gen
|
|
1742
1767
|
};
|
|
1743
1768
|
}
|
|
1769
|
+
// template
|
|
1770
|
+
function replaceTemplateCode(template, values) {
|
|
1771
|
+
for (const key in values) {
|
|
1772
|
+
const pat = `__${key}__`;
|
|
1773
|
+
const val = values[key];
|
|
1774
|
+
template = template.split(pat).join(val);
|
|
1775
|
+
}
|
|
1776
|
+
return template;
|
|
1777
|
+
}
|
package/core/src/nako_gen.mts
CHANGED
|
@@ -63,6 +63,7 @@ export class NakoGen {
|
|
|
63
63
|
private loopId: number // ループを生成する際にダミーのループ変数を管理するため
|
|
64
64
|
private flagLoop: boolean // 変換中のソースがループの中かどうかを判定する
|
|
65
65
|
private constPools: Array<any> // 定数プール用
|
|
66
|
+
private constPoolsTemplate: string[] // 定数プール生成用テンプレート
|
|
66
67
|
// コード生成オプション
|
|
67
68
|
private speedMode: SpeedMode
|
|
68
69
|
private performanceMonitor: PerformanceMonitor
|
|
@@ -158,6 +159,7 @@ export class NakoGen {
|
|
|
158
159
|
*/
|
|
159
160
|
this.warnUndefinedVar = true
|
|
160
161
|
this.constPools = []
|
|
162
|
+
this.constPoolsTemplate = []
|
|
161
163
|
|
|
162
164
|
// 暫定変数
|
|
163
165
|
this.warnUndefinedReturnUserFunc = 1
|
|
@@ -293,6 +295,7 @@ export class NakoGen {
|
|
|
293
295
|
code += `__v0.useDebug = ${this.debugOption.useDebug};\n`
|
|
294
296
|
// 定数を埋め込む
|
|
295
297
|
code += 'self.constPools = ' + JSON.stringify(this.constPools) + ';\n'
|
|
298
|
+
code += 'self.constPoolsTemplate = ' + JSON.stringify(this.constPoolsTemplate) + ';\n'
|
|
296
299
|
// なでしこの関数定義を行う
|
|
297
300
|
let nakoFuncCode = ''
|
|
298
301
|
for (const key in this.nakoFuncList) {
|
|
@@ -690,16 +693,38 @@ export class NakoGen {
|
|
|
690
693
|
if (this.warnUndefinedReturnUserFunc === 0) {
|
|
691
694
|
return lno + `return ${value};`
|
|
692
695
|
} else {
|
|
693
|
-
const poolIndex = this.
|
|
694
|
-
this.constPools.push({
|
|
695
|
-
msg: 'ユーザ関数からundefinedが返されています',
|
|
696
|
-
file: node.file,
|
|
697
|
-
line: node.line
|
|
698
|
-
})
|
|
696
|
+
const poolIndex = this.addConstPool('ユーザ関数からundefinedが返されています', [], node.file, node.line)
|
|
699
697
|
return lno + `return (__self.chk(${value}, ${poolIndex}));`
|
|
700
698
|
}
|
|
701
699
|
}
|
|
702
700
|
|
|
701
|
+
getConstPoolsTemplateId (msg: string): number {
|
|
702
|
+
let id = this.constPoolsTemplate.indexOf(msg)
|
|
703
|
+
if (id < 0) {
|
|
704
|
+
id = this.constPoolsTemplate.length
|
|
705
|
+
this.constPoolsTemplate[id] = msg
|
|
706
|
+
}
|
|
707
|
+
return id
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
addConstPool (msg: string, args: string[], file: any, line: any): number {
|
|
711
|
+
// file
|
|
712
|
+
file = '' + file
|
|
713
|
+
const fileNo = this.getConstPoolsTemplateId(file)
|
|
714
|
+
// msg
|
|
715
|
+
const msgNo = this.getConstPoolsTemplateId(msg)
|
|
716
|
+
// args
|
|
717
|
+
const args2: number[] = []
|
|
718
|
+
for (const i in args) {
|
|
719
|
+
const arg = '' + args[i]
|
|
720
|
+
const argNo = this.getConstPoolsTemplateId(arg)
|
|
721
|
+
args2.push(argNo)
|
|
722
|
+
}
|
|
723
|
+
const poolIndex = this.constPools.length
|
|
724
|
+
this.constPools.push([msgNo, args2, fileNo, line])
|
|
725
|
+
return poolIndex
|
|
726
|
+
}
|
|
727
|
+
|
|
703
728
|
convCheckLoop (node: Ast, cmd: string): string {
|
|
704
729
|
// ループの中であれば利用可能
|
|
705
730
|
if (!this.flagLoop) {
|
|
@@ -1336,20 +1361,8 @@ export class NakoGen {
|
|
|
1336
1361
|
argsA.push(`${arg}`)
|
|
1337
1362
|
} else {
|
|
1338
1363
|
// 引数のundefinedチェックのコードを入れる
|
|
1339
|
-
const
|
|
1340
|
-
|
|
1341
|
-
this.constPools.push({
|
|
1342
|
-
msg: `命令『${funcName}』の引数にundefinedを渡しています。`,
|
|
1343
|
-
file: node.file,
|
|
1344
|
-
line: node.line
|
|
1345
|
-
})
|
|
1346
|
-
} else {
|
|
1347
|
-
this.constPools.push({
|
|
1348
|
-
msg: `ユーザ関数『『${funcName}』の引数にundefinedを渡しています。`,
|
|
1349
|
-
file: node.file,
|
|
1350
|
-
line: node.line
|
|
1351
|
-
})
|
|
1352
|
-
}
|
|
1364
|
+
const msg = (res.i === 0) ? '命令『$0』の引数にundefinedを渡しています。' : 'ユーザ命令『$0』の引数にundefinedを渡しています。'
|
|
1365
|
+
const poolIndex = this.addConstPool(msg, [funcName], node.file, node.line)
|
|
1353
1366
|
// argが空になる対策 #1315
|
|
1354
1367
|
const argStr = (arg === '') ? '""' : arg
|
|
1355
1368
|
argsA.push(`(__self.chk(${argStr}, ${poolIndex}))`)
|
|
@@ -1654,6 +1667,69 @@ export interface NakoGenResult {
|
|
|
1654
1667
|
gen: any
|
|
1655
1668
|
}
|
|
1656
1669
|
|
|
1670
|
+
/** template of standalone js code */
|
|
1671
|
+
const STANDALONE_CODE = `
|
|
1672
|
+
// === generated by nadesiko3 ===
|
|
1673
|
+
// <nadesiko3standalone>
|
|
1674
|
+
// --- import
|
|
1675
|
+
import path from 'path'
|
|
1676
|
+
import { NakoRuntimeError } from './nako3runtime/nako_errors.mjs'
|
|
1677
|
+
__codeImportFiles__
|
|
1678
|
+
// --- init global self
|
|
1679
|
+
const self = {}
|
|
1680
|
+
self.coreVersion = '__coreVersion__'
|
|
1681
|
+
self.version = '__version__'
|
|
1682
|
+
self.logger = {
|
|
1683
|
+
error: (message) => { console.error(message) },
|
|
1684
|
+
warn: (message) => { console.warn(message) },
|
|
1685
|
+
send: (level, message) => { console.log(message) },
|
|
1686
|
+
runtimeError: (message, lineInfo) => { console.error(message, lineInfo) }
|
|
1687
|
+
};
|
|
1688
|
+
self.__varslist = [{}, {}, {}]
|
|
1689
|
+
self.__v0 = self.__varslist[0]
|
|
1690
|
+
self.initFuncList = []
|
|
1691
|
+
self.clearFuncList = []
|
|
1692
|
+
// --- jsInit ---
|
|
1693
|
+
__jsInit__
|
|
1694
|
+
// --- Copy module functions ---
|
|
1695
|
+
for (const mod of __importNames__) {
|
|
1696
|
+
for (const funcName in mod) {
|
|
1697
|
+
if (funcName === '初期化') {
|
|
1698
|
+
self.initFuncList.push(mod[funcName].fn)
|
|
1699
|
+
continue
|
|
1700
|
+
}
|
|
1701
|
+
if (funcName === '!クリア') {
|
|
1702
|
+
self.clearFuncList.push(mod[funcName].fn)
|
|
1703
|
+
continue
|
|
1704
|
+
}
|
|
1705
|
+
self.__varslist[0][funcName] = mod[funcName].fn
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
self.__vars = self.__varslist[2];
|
|
1709
|
+
self.__module = {};
|
|
1710
|
+
self.__locals = {};
|
|
1711
|
+
self.__genMode = 'sync';
|
|
1712
|
+
// プラグインの初期化コードを実行
|
|
1713
|
+
self.initFuncList.map(f => f(self))
|
|
1714
|
+
try {
|
|
1715
|
+
// ---------------------------
|
|
1716
|
+
// <prepareMainCode>
|
|
1717
|
+
__codeStandalone__
|
|
1718
|
+
// </prepareMainCode>
|
|
1719
|
+
// ---------------------------
|
|
1720
|
+
// <mainCode>
|
|
1721
|
+
__codeJS__
|
|
1722
|
+
// </mainCode>
|
|
1723
|
+
// ---------------------------
|
|
1724
|
+
// standaloneCodeでは、即時プラグインのクリアコードを実行
|
|
1725
|
+
self.clearFuncList.map(f => f(self))
|
|
1726
|
+
} catch (err) {
|
|
1727
|
+
self.logger.error(err);
|
|
1728
|
+
throw err;
|
|
1729
|
+
}
|
|
1730
|
+
// </nadesiko3standalone>
|
|
1731
|
+
`
|
|
1732
|
+
|
|
1657
1733
|
/**
|
|
1658
1734
|
* @param com
|
|
1659
1735
|
* @param ast
|
|
@@ -1690,7 +1766,6 @@ export function generateJS (com: NakoCompiler, ast: Ast, opt: NakoGenOptions): N
|
|
|
1690
1766
|
// --------------------------------------------------
|
|
1691
1767
|
// <nadesiko3::gen::async id="${funcID}" times="${gen.numAsyncFn}">
|
|
1692
1768
|
async function ${asyncMain}(self) {
|
|
1693
|
-
${jsInit}
|
|
1694
1769
|
${js}
|
|
1695
1770
|
} // end of ${asyncMain}
|
|
1696
1771
|
${asyncMain}.call(self, self)
|
|
@@ -1714,7 +1789,6 @@ ${asyncMain}.call(self, self)
|
|
|
1714
1789
|
// <nadesiko3::gen::syncMode>
|
|
1715
1790
|
function ${syncMain}(self) {
|
|
1716
1791
|
try {
|
|
1717
|
-
${jsInit}
|
|
1718
1792
|
${js}
|
|
1719
1793
|
} catch (err) {
|
|
1720
1794
|
if (err.message === '__終わる__') { return }
|
|
@@ -1737,58 +1811,6 @@ ${syncMain}(self)
|
|
|
1737
1811
|
importNames.push(ff)
|
|
1738
1812
|
codeImportFiles += `import ${ff} from './nako3runtime/${f}'\n`
|
|
1739
1813
|
}
|
|
1740
|
-
const standaloneJSCode = `\
|
|
1741
|
-
// <standaloneCode>
|
|
1742
|
-
import path from 'path'
|
|
1743
|
-
import { NakoRuntimeError } from './nako3runtime/nako_errors.mjs'
|
|
1744
|
-
${codeImportFiles}
|
|
1745
|
-
const self = {}
|
|
1746
|
-
self.coreVersion = '${com.coreVersion}'
|
|
1747
|
-
self.version = '${com.version}'
|
|
1748
|
-
self.logger = {
|
|
1749
|
-
error: (message) => { console.error(message) },
|
|
1750
|
-
warn: (message) => { console.warn(message) },
|
|
1751
|
-
send: (level, message) => { console.log(message) },
|
|
1752
|
-
};
|
|
1753
|
-
self.__varslist = [{}, {}, {}]
|
|
1754
|
-
self.__v0 = self.__varslist[0]
|
|
1755
|
-
self.initFuncList = []
|
|
1756
|
-
self.clearFuncList = []
|
|
1757
|
-
// Copy module functions
|
|
1758
|
-
for (const mod of [${importNames.join(', ')}]) {
|
|
1759
|
-
for (const funcName in mod) {
|
|
1760
|
-
if (funcName === '初期化') {
|
|
1761
|
-
self.initFuncList.push(mod[funcName].fn)
|
|
1762
|
-
continue
|
|
1763
|
-
}
|
|
1764
|
-
if (funcName === '!クリア') {
|
|
1765
|
-
self.clearFuncList.push(mod[funcName].fn)
|
|
1766
|
-
continue
|
|
1767
|
-
}
|
|
1768
|
-
self.__varslist[0][funcName] = mod[funcName].fn
|
|
1769
|
-
}
|
|
1770
|
-
}
|
|
1771
|
-
self.__vars = self.__varslist[2];
|
|
1772
|
-
self.__module = {};
|
|
1773
|
-
self.__locals = {};
|
|
1774
|
-
self.__genMode = 'sync';
|
|
1775
|
-
|
|
1776
|
-
// プラグインの初期化コードを実行
|
|
1777
|
-
self.initFuncList.map(f => f(self))
|
|
1778
|
-
|
|
1779
|
-
try {
|
|
1780
|
-
${opt.codeStandalone}
|
|
1781
|
-
// <JS:standalone>
|
|
1782
|
-
${js}
|
|
1783
|
-
// </JS:standalone>
|
|
1784
|
-
// standaloneCodeでは、即時プラグインのクリアコードを実行
|
|
1785
|
-
self.clearFuncList.map(f => f(self))
|
|
1786
|
-
} catch (err) {
|
|
1787
|
-
self.logger.error(err);
|
|
1788
|
-
throw err;
|
|
1789
|
-
}
|
|
1790
|
-
// </standaloneCode>
|
|
1791
|
-
`
|
|
1792
1814
|
// ---
|
|
1793
1815
|
const initCode = gen.getPluginInitCode()
|
|
1794
1816
|
const runtimeEnvCode = `
|
|
@@ -1804,8 +1826,25 @@ ${js}
|
|
|
1804
1826
|
// なでしこの実行環境ありの場合(thisが有効)
|
|
1805
1827
|
runtimeEnv: runtimeEnvCode,
|
|
1806
1828
|
// JavaScript単体で動かす場合
|
|
1807
|
-
standalone:
|
|
1829
|
+
standalone: replaceTemplateCode(STANDALONE_CODE, {
|
|
1830
|
+
codeImportFiles,
|
|
1831
|
+
'coreVersion': com.coreVersion,
|
|
1832
|
+
'version': com.version,
|
|
1833
|
+
'importNames': ('[' + importNames.join(', ') + ']'),
|
|
1834
|
+
'codeStandalone': opt.codeStandalone,
|
|
1835
|
+
'codeJS': js,
|
|
1836
|
+
jsInit
|
|
1837
|
+
}),
|
|
1808
1838
|
// コード生成に使ったNakoGenのインスタンス
|
|
1809
1839
|
gen
|
|
1810
1840
|
}
|
|
1811
1841
|
}
|
|
1842
|
+
// template
|
|
1843
|
+
function replaceTemplateCode (template: string, values: any): string {
|
|
1844
|
+
for (const key in values) {
|
|
1845
|
+
const pat = `__${key}__`
|
|
1846
|
+
const val = values[key]
|
|
1847
|
+
template = template.split(pat).join(val)
|
|
1848
|
+
}
|
|
1849
|
+
return template
|
|
1850
|
+
}
|
|
@@ -133,7 +133,14 @@ export default {
|
|
|
133
133
|
sys.chk = (value, constId) => {
|
|
134
134
|
if (typeof value === 'undefined') {
|
|
135
135
|
const cp = sys.constPools[constId];
|
|
136
|
-
|
|
136
|
+
const { msgNo, msgArgs, fileNo, lineNo } = cp;
|
|
137
|
+
let msg = sys.constPoolsTemplate[msgNo];
|
|
138
|
+
for (const i in msgArgs) {
|
|
139
|
+
const arg = sys.constPoolsTemplate[msgArgs[i]];
|
|
140
|
+
msg = msg.split(`$${i}`).join(arg);
|
|
141
|
+
}
|
|
142
|
+
const fileStr = sys.constPoolsTemplate[fileNo];
|
|
143
|
+
sys.logger.warn(msg, { file: fileStr, line: lineNo });
|
|
137
144
|
}
|
|
138
145
|
return value;
|
|
139
146
|
};
|
|
@@ -2324,7 +2331,7 @@ export default {
|
|
|
2324
2331
|
'秒後': {
|
|
2325
2332
|
type: 'func',
|
|
2326
2333
|
josi: [['を'], ['']],
|
|
2327
|
-
pure:
|
|
2334
|
+
pure: true,
|
|
2328
2335
|
fn: function (f, n, sys) {
|
|
2329
2336
|
// 文字列で指定された関数をオブジェクトに変換
|
|
2330
2337
|
if (typeof f === 'string') {
|
|
@@ -2828,7 +2835,10 @@ export default {
|
|
|
2828
2835
|
sys.__v0['__DEBUG強制待機'] = 0;
|
|
2829
2836
|
// ブレイクポイント or __DEBUG強制待機 が指定されたか?
|
|
2830
2837
|
if (breakpoints.indexOf(curLine) >= 0 || forceLine) {
|
|
2831
|
-
|
|
2838
|
+
if (sys.__v0['プラグイン名'] !== 'メイン') {
|
|
2839
|
+
return;
|
|
2840
|
+
} // 現状メインのみデバッグする
|
|
2841
|
+
console.log(`@__DEBUG_BP_WAIT(${curLine})`);
|
|
2832
2842
|
const timerId = setInterval(() => {
|
|
2833
2843
|
if (sys.__v0['__DEBUG待機フラグ'] === 1) {
|
|
2834
2844
|
sys.__v0['__DEBUG待機フラグ'] = 0;
|