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.
Files changed (51) hide show
  1. package/batch/command.txt +292 -292
  2. package/core/package.json +1 -1
  3. package/core/src/nako_core_version.mjs +2 -2
  4. package/core/src/nako_core_version.mts +2 -2
  5. package/core/src/nako_from_dncl2.mjs +34 -2
  6. package/core/src/nako_from_dncl2.mts +31 -2
  7. package/core/src/nako_gen.mjs +110 -76
  8. package/core/src/nako_gen.mts +114 -75
  9. package/core/src/plugin_system.mjs +13 -3
  10. package/core/src/plugin_system.mts +11 -3
  11. package/core/test/dncl2_test.mjs +161 -152
  12. package/package.json +4 -33
  13. package/release/_hash.txt +20 -20
  14. package/release/_script-tags.txt +14 -14
  15. package/release/nako_gen_async.js +1 -1
  16. package/release/nako_gen_async.js.map +1 -1
  17. package/release/plugin_datetime.js +1 -1
  18. package/release/plugin_datetime.js.map +1 -1
  19. package/release/stats.json +1 -1
  20. package/release/version.js +1 -1
  21. package/release/version.js.map +1 -1
  22. package/release/wnako3.js +1 -1
  23. package/release/wnako3.js.map +1 -1
  24. package/release/wnako3webworker.js +1 -1
  25. package/release/wnako3webworker.js.map +1 -1
  26. package/src/nako_version.mjs +2 -2
  27. package/src/nako_version.mts +2 -2
  28. package/src/plugin_browser.mjs +1 -1
  29. package/src/plugin_browser.mts +1 -1
  30. package/src/plugin_browser_ajax.mjs +6 -6
  31. package/src/plugin_browser_ajax.mts +8 -8
  32. package/src/plugin_browser_canvas.mjs +2 -2
  33. package/src/plugin_browser_canvas.mts +2 -2
  34. package/src/plugin_browser_chart.mjs +17 -13
  35. package/src/plugin_browser_chart.mts +25 -21
  36. package/src/plugin_browser_crypto.mjs +1 -1
  37. package/src/plugin_browser_crypto.mts +2 -2
  38. package/src/plugin_browser_dom_basic.mjs +5 -5
  39. package/src/plugin_browser_dom_basic.mts +5 -5
  40. package/src/plugin_browser_dom_event.mjs +17 -17
  41. package/src/plugin_browser_dom_event.mts +17 -17
  42. package/src/plugin_browser_dom_parts.mjs +21 -21
  43. package/src/plugin_browser_dom_parts.mts +21 -21
  44. package/src/plugin_browser_geolocation.mjs +2 -2
  45. package/src/plugin_browser_geolocation.mts +2 -2
  46. package/src/plugin_browser_storage.mjs +3 -3
  47. package/src/plugin_browser_storage.mts +3 -3
  48. package/src/plugin_datetime.mjs +9 -9
  49. package/src/plugin_node.mjs +3 -3
  50. package/src/plugin_node.mts +3 -3
  51. package/test/node/plugin_node_test.mjs +181 -180
package/core/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nadesiko3core",
3
- "version": "3.4.13",
3
+ "version": "3.4.14",
4
4
  "description": "Japanese Programming Language Nadesiko v3 core",
5
5
  "main": "index.mjs",
6
6
  "type": "module",
@@ -1,8 +1,8 @@
1
1
  // 実際のバージョン定義 (自動生成されるので以下を編集しない)
2
2
  const coreVersion = {
3
- version: '3.4.13',
3
+ version: '3.4.14',
4
4
  major: 3,
5
5
  minor: 4,
6
- patch: 13
6
+ patch: 14
7
7
  };
8
8
  export default coreVersion;
@@ -11,9 +11,9 @@ export interface NakoCoreVersion {
11
11
  }
12
12
  // 実際のバージョン定義 (自動生成されるので以下を編集しない)
13
13
  const coreVersion: NakoCoreVersion = {
14
- version: '3.4.13',
14
+ version: '3.4.14',
15
15
  major: 3,
16
16
  minor: 4,
17
- patch: 13
17
+ patch: 14
18
18
  }
19
19
  export default coreVersion
@@ -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:ら'])
@@ -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.constPools.length;
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 poolIndex = this.constPools.length;
1272
- if (res.i === 0) {
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: standaloneJSCode,
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
+ }
@@ -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.constPools.length
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 poolIndex = this.constPools.length
1340
- if (res.i === 0) {
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: standaloneJSCode,
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
- sys.logger.warn(cp.msg, { file: cp.file, line: cp.line });
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: false,
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
- console.log('@STOP!!!! cur=', curLine);
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;