nadesiko3 3.3.13 → 3.3.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/src/cnako3mod.mjs CHANGED
@@ -1,11 +1,10 @@
1
- // @ts-nocheck
2
1
  /**
3
2
  * コマンドライン版のなでしこ3をモジュールとして定義
4
3
  * 実際には cnako3.js から読み込まれる
5
4
  */
6
5
  import fs from 'fs'
7
6
  import { exec } from 'child_process'
8
- import path from 'path'
7
+ import path, { resolve } from 'path'
9
8
  import { NakoCompiler } from './nako3.mjs'
10
9
  import PluginNode from './plugin_node.mjs'
11
10
  import { NakoImportError } from './nako_errors.mjs'
@@ -23,7 +22,7 @@ export class CNako3 extends NakoCompiler {
23
22
  super({ useBasicPlugin: true })
24
23
  this.silent = false
25
24
  if (!opts.nostd) {
26
- this.addPluginFile('PluginNode', path.join(__dirname, 'plugin_node.js'), PluginNode)
25
+ this.addPluginFile('PluginNode', path.join(__dirname, 'plugin_node.mjs'), PluginNode)
27
26
  }
28
27
  this.__varslist[0]['ナデシコ種類'] = 'cnako3'
29
28
  }
@@ -61,12 +60,23 @@ export class CNako3 extends NakoCompiler {
61
60
 
62
61
  /**
63
62
  * コマンドライン引数を解析
64
- * @returns {{warn: boolean, debug: boolean, compile: any | boolean, test: any | boolean, one_liner: any | boolean, trace: any, run: any | boolean, repl: any | boolean, source: any | string}}
63
+ * @returns {{
64
+ * warn: boolean,
65
+ * debug: boolean,
66
+ * compile: any | boolean,
67
+ * test: any | boolean,
68
+ * one_liner: any | boolean,
69
+ * trace: any | boolean,
70
+ * run: any | boolean,
71
+ * repl: any | boolean,
72
+ * source: any | string,
73
+ * mainfile: any | string,
74
+ * }}
65
75
  */
66
76
  checkArguments () {
67
77
  const app = this.registerCommands()
68
78
 
69
- /** @type {import('./nako_logger').LogLevel} */
79
+ /** @type {import('./nako_logger.mjs').LogLevel} */
70
80
  let logLevel = 'error'
71
81
  if (app.trace) {
72
82
  logLevel = 'trace'
@@ -99,21 +109,23 @@ export class CNako3 extends NakoCompiler {
99
109
  }
100
110
  args.mainfile = app.args[0]
101
111
  args.output = app.output
112
+
113
+ // todo: ESModule 対応の '.mjs' のコードを履く #1217
114
+ const ext = '.js'
102
115
  if (/\.(nako|nako3|txt|bak)$/.test(args.mainfile)) {
103
116
  if (!args.output) {
104
117
  if (args.test) {
105
- args.output = args.mainfile.replace(/\.(nako|nako3)$/, '.spec.js')
118
+ args.output = args.mainfile.replace(/\.(nako|nako3)$/, '.spec' + ext)
106
119
  } else {
107
- // todo: 将来的に mjs のコードを履くように修正する↓ '.mjs'
108
- args.output = args.mainfile.replace(/\.(nako|nako3)$/, '.js')
120
+ args.output = args.mainfile.replace(/\.(nako|nako3)$/, ext)
109
121
  }
110
122
  }
111
123
  } else {
112
124
  if (!args.output) {
113
125
  if (args.test) {
114
- args.output = args.mainfile + '.spec.js'
126
+ args.output = args.mainfile + '.spec' + ext
115
127
  } else {
116
- args.output = args.mainfile + '.js'
128
+ args.output = args.mainfile + ext
117
129
  }
118
130
  }
119
131
  args.mainfile += '.nako3'
@@ -201,6 +213,28 @@ export class CNako3 extends NakoCompiler {
201
213
  const jscode = this.compileStandalone(src, this.filename, isTest)
202
214
  console.log(opt.output)
203
215
  fs.writeFileSync(opt.output, jscode, 'utf-8')
216
+
217
+ /*
218
+ // 実行に必要なファイルをコピー
219
+ const nakoRuntime = __dirname
220
+ const outRuntime = path.join(path.dirname(opt.output), 'nako3runtime')
221
+ if (!fs.existsSync(outRuntime)) { fs.mkdirSync(outRuntime) }
222
+ for (let mod of ['nako_version.mjs', 'nako_errors.mjs', 'plugin_node.mjs']) {
223
+ fs.copyFileSync(path.join(nakoRuntime, mod), path.join(outRuntime, mod))
224
+ }
225
+ // todo: 必要に応じてnode_modulesをコピー (時間が掛かりすぎるのでコピーしない)
226
+ const dstModule = path.join(path.dirname(opt.output), 'node_modules')
227
+ const orgModule = path.join(__dirname, '..', 'node_modules')
228
+ if (!fs.existsSync(dstModule)) {
229
+ fs.mkdirSync(dstModule)
230
+ fse.copySync(path.join(orgModule), path.join(dstModule))
231
+ }
232
+ // or 以下のコピーだと依存ファイルがコピーされない package.jsonを見てコピーする必要がある
233
+ for (let mod of ['fs-extra', 'iconv-lite', 'opener', 'clipboardy', 'sendkeys-js']) {
234
+ fse.copySync(path.join(orgModule, mod), path.join(dstModule, mod))
235
+ }
236
+ */
237
+
204
238
  if (opt.run) {
205
239
  exec(`node ${opt.output}`, function (err, stdout, stderr) {
206
240
  if (err) { console.log('[ERROR]', stderr) }
@@ -321,7 +355,7 @@ export class CNako3 extends NakoCompiler {
321
355
  /** @type {string[]} */
322
356
  const log = []
323
357
  const tools = {}
324
- tools.resolvePath = (name, token) => {
358
+ tools.resolvePath = (name, token, fromFile) => {
325
359
  // JSプラグインのパスを解決する
326
360
  if (/\.(js|mjs)(\.txt)?$/.test(name) || /^[^.]*$/.test(name)) {
327
361
  const jspath = CNako3.findJSPluginFile(name, this.filename, __dirname, log)
@@ -336,28 +370,36 @@ export class CNako3 extends NakoCompiler {
336
370
  return { filePath: path.resolve(name), type: 'nako3' }
337
371
  } else {
338
372
  // filename が undefined のとき token.file が undefined になる。
339
- if (token.file === undefined) {
340
- throw new Error('ファイル名を指定してください。')
341
- }
342
- return { filePath: path.resolve(path.join(path.dirname(token.file), name)), type: 'nako3' }
373
+ if (token.file === undefined) { throw new Error('ファイル名を指定してください。') }
374
+ const dir = path.dirname(fromFile)
375
+ return { filePath: path.resolve(path.join(dir, name)), type: 'nako3' }
343
376
  }
344
377
  }
345
378
  return { filePath: name, type: 'invalid' }
346
379
  }
347
380
  tools.readNako3 = (name, token) => {
348
- if (!fs.existsSync(name)) {
349
- throw new NakoImportError(`ファイル ${name} が存在しません。`, token.file, token.line)
350
- }
351
- return { sync: true, value: fs.readFileSync(name).toString() }
381
+ // ファイルチェックだけ先に実行
382
+ if (!fs.existsSync(name)) {
383
+ throw new NakoImportError(`ファイル ${name} が存在しません。`, token.file, token.line)
384
+ }
385
+ // 非同期で読み込む
386
+ const loader = {task: null}
387
+ loader.task = (new Promise((resolve, reject) => {
388
+ fs.readFile(name, {encoding: 'utf-8'}, (err, data) => {
389
+ if (err) { return reject(err) }
390
+ resolve(data)
391
+ })
392
+ }))
393
+ return loader
352
394
  }
353
395
  tools.readJs = (filePath, token) => {
354
- const content = {sync: false, value: null}
396
+ const loader = {task: null}
355
397
  if (process.platform === 'win32') {
356
398
  if (filePath.substring(1, 3) === ':\\') {
357
399
  filePath = 'file://' + filePath
358
400
  }
359
401
  }
360
- content.value = (
402
+ loader.task = (
361
403
  new Promise((resolve, reject) => {
362
404
  import(filePath).then((mod) => {
363
405
  // プラグインは export default で宣言されている? (moduleプラグインの場合)
@@ -369,7 +411,7 @@ export class CNako3 extends NakoCompiler {
369
411
  })
370
412
  })
371
413
  )
372
- return content
414
+ return loader
373
415
  }
374
416
  return tools
375
417
  }
package/src/nako3.mjs CHANGED
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  /**
3
2
  * nadesiko v3
4
3
  */
@@ -177,18 +176,20 @@ export class NakoCompiler {
177
176
 
178
177
  /**
179
178
  * プログラムが依存するファイルを再帰的に取得する。
180
- * - .jsであれば評価してthis.addPluginFileを呼び出し、.nako3であればファイルをfetchしてdependenciesに保存し再帰する。
181
- * - resolvePathはファイルを検索して正規化する必要がある。
182
- * - readNako3やreadJsのsyncを確認してfalseならPromiseを返すので並列処理し、そうでなければ同期的に処理する。
183
- * - readNako3はソースコードを返す。readJsはrequireあるいはevalする関数を返す。
179
+ * - 依存するファイルがJavaScriptファイルの場合、そのファイルを実行して評価結果をthis.addPluginFileに渡す。
180
+ * - 依存するファイルがなでしこ言語の場合、ファイルの中身を取得して変数に保存し、再帰する。
181
+ *
184
182
  * @param {string} code
185
183
  * @param {string} filename
186
184
  * @param {string} preCode
187
185
  * @param {{
188
- * resolvePath: (name: string, token: TokenWithSourceMap) => { type: 'nako3' | 'js' | 'invalid', filePath: string }
189
- * readNako3: (filePath: string, token: TokenWithSourceMap) => { sync: true, value: string } | { sync: false, value: Promise<string> }
190
- * readJs: (filePath: string, token: TokenWithSourceMap) => { sync: true, value: () => object } | { sync: false, value: Promise<() => object> }
191
- * }} tools
186
+ * resolvePath: (name: string, token: TokenWithSourceMap, fromFile: string) => { type: 'nako3' | 'js' | 'invalid', filePath: string }
187
+ * readNako3: (filePath: string, token: TokenWithSourceMap) => { task: Promise<string> }
188
+ * readJs: (filePath: string, token: TokenWithSourceMap) => { task: Promise<() => object> }
189
+ * }} tools - 実行環境 (ブラウザ or Node.js) によって外部ファイルの取得・実行方法は異なるため、引数でそれらを行う関数を受け取る。
190
+ * - resolvePath は指定した名前をもつファイルを検索し、正規化されたファイル名を返す関数。返されたファイル名はreadNako3かreadJsの引数になる。
191
+ * - readNako3は指定されたファイルの中身を返す関数。
192
+ * - readJsは指定したファイルをJavaScriptのプログラムとして実行し、`export default` でエクスポートされた値を返す関数。
192
193
  * @returns {Promise<unknown> | void}
193
194
  * @protected
194
195
  */
@@ -200,10 +201,12 @@ export class NakoCompiler {
200
201
  const loadJS = (item, tasks) => {
201
202
  // jsならプラグインとして読み込む。(ESMでは必ず動的に読む)
202
203
  const obj = tools.readJs(item.filePath, item.firstToken)
203
- tasks.push(obj.value.then((res) => {
204
- dependencies[item.filePath].addPluginFile = () => {
205
- this.addPluginFile(item.value, item.filePath, dependencies[item.filePath].funclist = res(), false)
206
- }}))
204
+ tasks.push(obj.task.then((res) => {
205
+ const pluginFuncs = res()
206
+ this.addPluginFile(item.value, item.filePath, pluginFuncs, false)
207
+ dependencies[item.filePath].funclist = pluginFuncs
208
+ dependencies[item.filePath].addPluginFile = () => { this.addPluginFile(item.value, item.filePath, pluginFuncs, false) }
209
+ }))
207
210
  }
208
211
  const loadNako3 = (item, tasks) => {
209
212
  // nako3ならファイルを読んでdependenciesに保存する。
@@ -221,15 +224,11 @@ export class NakoCompiler {
221
224
  const funclist = {}
222
225
  NakoLexer.preDefineFunc(cloneAsJSON(tokens), this.logger, funclist)
223
226
  dependencies[item.filePath].funclist = funclist
224
-
225
227
  // 再帰
226
228
  return loadRec(code, item.filePath, '')
227
229
  }
228
- if (content.sync) {
229
- registerFile(content.value)
230
- } else {
231
- tasks.push(content.value.then((res) => registerFile(res)))
232
- }
230
+ // 取り込み構文における問題を減らすため、必ず非同期でプログラムを読み込む仕様とした #1219
231
+ tasks.push(content.task.then((res) => registerFile(res)))
233
232
  }
234
233
  /** @param {string} code @param {string} filename @param {string} preCode @returns {Promise<unknown> | void} */
235
234
  const loadRec = (code, filename, preCode) => {
@@ -238,7 +237,7 @@ export class NakoCompiler {
238
237
  // 取り込みが必要な情報一覧を調べる(トークン分割して、取り込みタグを得る)
239
238
  const tags = NakoCompiler.listRequireStatements(compiler.rawtokenize(code, 0, filename, preCode))
240
239
  // パスを解決する
241
- const tagsResolvePath = tags.map((v) => ({ ...v, ...tools.resolvePath(v.value, v.firstToken) }))
240
+ const tagsResolvePath = tags.map((v) => ({ ...v, ...tools.resolvePath(v.value, v.firstToken, filename) }))
242
241
  // 取り込み開始
243
242
  for (const item of tagsResolvePath) {
244
243
  // 2回目以降の読み込み
package/src/nako_gen.mjs CHANGED
@@ -1,5 +1,4 @@
1
1
  /**
2
- * file: nako_gen.js
3
2
  * パーサーが生成した中間オブジェクトを実際のJavaScriptのコードに変換する。
4
3
  * なお速度優先で忠実にJavaScriptのコードを生成する。
5
4
  */
@@ -7,12 +6,6 @@
7
6
  import { NakoSyntaxError, NakoError, NakoRuntimeError } from './nako_errors.mjs'
8
7
  import { NakoLexer } from './nako_lexer.mjs'
9
8
  import nakoVersion from './nako_version.mjs'
10
- const isIE11 = () => {
11
- if (typeof(window) == 'object' && window.navigator && window.navigator.userAgent) {
12
- return (window.navigator.userAgent.indexOf('MSIE') >= 0)
13
- }
14
- return false
15
- }
16
9
 
17
10
  // なでしこで定義した関数の開始コードと終了コード
18
11
  const topOfFunction = '(function(){\n'
@@ -1546,7 +1539,7 @@ export class NakoGen {
1546
1539
 
1547
1540
 
1548
1541
  /**
1549
- * @param {import('./nako3')} com
1542
+ * @param {import('./nako3.mjs').NakoCompiler} com
1550
1543
  * @param {Ast} ast
1551
1544
  * @param {boolean | string} isTest 文字列なら1つのテストだけを実行する
1552
1545
  */
@@ -1573,21 +1566,19 @@ export function generateJS (com, ast, isTest) {
1573
1566
  }
1574
1567
  // async method
1575
1568
  if (gen.numAsyncFn > 0) {
1576
- let canAsync = !isIE11()
1577
- if (canAsync) {
1578
- js = `
1569
+ js = `
1579
1570
  // <nadesiko3::gen::async>
1580
1571
  (async () => { // async::main
1581
1572
  ${js}
1582
1573
  }).call(this).catch(err => {
1583
- if (!(err instanceof this.NakoRuntimeError)) {
1584
- err = new this.NakoRuntimeError(err, this.__varslist[0].line);
1585
- }
1586
- this.logger.error(err);
1587
- throw err;
1574
+ if (typeof(NakoRuntimeError) === 'undefined') { NakoRuntimeError = this.NakoRuntimeError }
1575
+ if (!(err instanceof NakoRuntimeError)) {
1576
+ err = new NakoRuntimeError(err, this.__varslist[0].line);
1577
+ }
1578
+ this.logger.error(err);
1579
+ throw err;
1588
1580
  }); // async::main
1589
1581
  // <nadesiko3::gen::async>\n`
1590
- }
1591
1582
  }
1592
1583
 
1593
1584
  // デバッグメッセージ
@@ -1595,36 +1586,37 @@ throw err;
1595
1586
  // todo: 将来的に mjs のコードを履くように修正する
1596
1587
  const standaloneJSCode = `\
1597
1588
  // <standaloneCode>
1589
+ // 将来的に ESModule に対応する #1217
1590
+ // import path from 'path'
1591
+ // import PluginNode from './nako3runtime/plugin_node.mjs'
1592
+ // import {NakoRuntimeError} from './nako3runtime/nako_errors.mjs'
1593
+
1598
1594
  const path = require('path')
1599
- const nakoVersion = ${JSON.stringify(nakoVersion)};
1600
1595
  ${NakoError.toString()}
1601
- ${NakoRuntimeError.toString()}
1602
- function __nako3safunc() {
1603
- this.logger = {
1596
+ ${NakoRuntimeError.toString()}
1597
+ const nakoVersion = ${JSON.stringify(nakoVersion)};
1598
+ const self = this
1599
+ self.logger = {
1604
1600
  error: (message) => { console.error(message) },
1605
1601
  send: (level, message) => { console.log(message) },
1606
1602
  };
1607
- this.__varslist = [{}, {}, {}];
1608
- this.__vars = this.__varslist[2];
1609
- this.__module = {};
1610
- this.__locals = {};
1611
- this.__genMode = 'sync';
1603
+ self.__varslist = [{}, {}, {}];
1604
+ self.__vars = self.__varslist[2];
1605
+ self.__module = {};
1606
+ self.__locals = {};
1607
+ self.__genMode = 'sync';
1612
1608
  try {
1613
1609
  ${gen.getVarsCode()}
1614
1610
  ${js}
1615
1611
  } catch (err) {
1616
1612
  if (!(err instanceof NakoRuntimeError)) {
1617
- err = new NakoRuntimeError(err, __varslist[0].line);
1613
+ err = new NakoRuntimeError(err, self.__varslist[0].line);
1618
1614
  }
1619
- this.logger.error(err);
1615
+ self.logger.error(err);
1620
1616
  throw err;
1621
1617
  }
1622
- //
1623
- } // end of __nako3safunc function
1624
- __nako3safunc();
1625
1618
  // </standaloneCode>
1626
- `
1627
-
1619
+ `
1628
1620
  return {
1629
1621
  // なでしこの実行環境ありの場合
1630
1622
  runtimeEnv: js,
@@ -1,7 +1,7 @@
1
1
  // なでしこバージョン
2
2
  export default {
3
- version: '3.3.13',
3
+ version: '3.3.14',
4
4
  major: 3,
5
5
  minor: 3,
6
- patch: 13
6
+ patch: 14
7
7
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * file: plugin_node.js
2
+ * file: plugin_node.mjs
3
3
  * node.js のためのプラグイン
4
4
  */
5
5
  import fs from 'fs'
@@ -11,9 +11,8 @@ import iconv from 'iconv-lite'
11
11
  import opener from 'opener'
12
12
  import clipboardy from 'clipboardy'
13
13
  import assert from 'assert'
14
- // 「標準入力取得時」で利用
15
- import * as readline from 'readline'
16
- import { stdin as input, stdout as output } from 'process'
14
+ // 「標準入力取得時」「尋」で利用
15
+ import readline from 'readline'
17
16
  // ハッシュ関数で利用
18
17
  import crypto from 'crypto'
19
18
  import os from 'os'
@@ -585,11 +584,15 @@ export default {
585
584
  josi: [['と', 'を']],
586
585
  pure: true,
587
586
  asyncFn: true,
588
- fn: async function (msg, sys) {
589
- const rl = readline.createInterface({ input, output });
590
- const res = await rl.question(msg)
591
- if (res.match(/^[0-9.]+$/)) { return parseFloat(res) }
592
- return res
587
+ fn: function (msg, sys) {
588
+ return new Promise((resolve, _reject) => {
589
+ const rl = readline.createInterface(process.stdin, process.stdout)
590
+ rl.question(msg, (buf) => {
591
+ rl.close()
592
+ if (buf && buf.match(/^[0-9.]+$/)) { buf = parseFloat(buf) }
593
+ resolve(buf)
594
+ })
595
+ })
593
596
  }
594
597
  },
595
598
  // @テスト
@@ -598,7 +601,6 @@ export default {
598
601
  josi: [['と'], ['が']],
599
602
  pure: true,
600
603
  fn: function (a, b, sys) {
601
-
602
604
  assert.strictEqual(a, b)
603
605
  }
604
606
  },
package/src/wnako3.mjs CHANGED
@@ -53,17 +53,15 @@ class WebNakoCompiler extends NakoCompiler {
53
53
  // eslint-disable-next-line no-prototype-builtins
54
54
  if (localFiles.hasOwnProperty(filePath)) {
55
55
  return {
56
- sync: true,
57
- value: () => {
56
+ task: (async () => () => {
58
57
  // eslint-disable-next-line no-new-func
59
58
  Function(localFiles[filePath])()
60
59
  return {}
61
- }
60
+ })()
62
61
  }
63
62
  }
64
63
  return {
65
- sync: false,
66
- value: (async () => {
64
+ task: (async () => {
67
65
  const res = await fetch(filePath)
68
66
  if (!res.ok) {
69
67
  throw new NakoImportError(`ファイル『${filePath}』のダウンロードに失敗しました: ${res.status} ${res.statusText}`, token.file, token.line)
@@ -93,11 +91,10 @@ class WebNakoCompiler extends NakoCompiler {
93
91
  readNako3: (filePath, token) => {
94
92
  // eslint-disable-next-line no-prototype-builtins
95
93
  if (localFiles.hasOwnProperty(filePath)) {
96
- return { sync: true, value: localFiles[filePath] }
94
+ return {task: (async () => { return localFiles[filePath] })}
97
95
  }
98
96
  return {
99
- sync: false,
100
- value: (async () => {
97
+ task: (async () => {
101
98
  const res = await fetch(filePath)
102
99
  if (!res.ok) {
103
100
  throw new NakoImportError(`ファイル ${filePath} のダウンロードに失敗しました: ${res.status} ${res.statusText}`, token.file, token.line)
@@ -106,7 +103,7 @@ class WebNakoCompiler extends NakoCompiler {
106
103
  })()
107
104
  }
108
105
  },
109
- resolvePath: (name, token) => {
106
+ resolvePath: (name, token, fromFile) => {
110
107
  // ローカルにファイルが存在するならそれを使う。そうでなければURLとして解釈する。
111
108
  let pathname = name
112
109
  // eslint-disable-next-line no-prototype-builtins
@@ -116,10 +113,13 @@ class WebNakoCompiler extends NakoCompiler {
116
113
  } catch (e) {
117
114
  // 単純にパスに変換できなければ、loccation.hrefを参考にパスを組み立てる
118
115
  try {
119
- const href_a = window.location.href.split('/')
120
- const href_dir = href_a.splice(0, href_a.length - 1).join('/');
121
- const href = href_dir + '/' + name
122
- pathname = new URL(href).pathname
116
+ let baseDir = dirname(fromFile)
117
+ if (baseDir === '') {
118
+ // https://2/3/4.html
119
+ const a = window.location.href.split('/')
120
+ baseDir = '/' + a.slice(3,a.length - 1).join('/')
121
+ }
122
+ pathname = resolveURL(baseDir, name)
123
123
  } catch (e) {
124
124
  throw new NakoImportError(`取り込み文の引数でパスが解決できません。https:// か http:// で始まるアドレスを指定してください。\n${e}`, token.file, token.line)
125
125
  }
@@ -127,11 +127,11 @@ class WebNakoCompiler extends NakoCompiler {
127
127
  }
128
128
  // .js および .mjs なら JSプラグイン
129
129
  if (pathname.endsWith('.js') || pathname.endsWith('.js.txt') || pathname.endsWith('.mjs') || pathname.endsWith('.mjs.txt')) {
130
- return { filePath: name, type: 'js' }
130
+ return { filePath: pathname, type: 'js' }
131
131
  }
132
132
  // .nako3 なら なでしこ3プラグイン
133
133
  if (pathname.endsWith('.nako3') || pathname.endsWith('.nako3.txt')) {
134
- return { filePath: name, type: 'nako3' }
134
+ return { filePath: pathname, type: 'nako3' }
135
135
  }
136
136
  // ファイル拡張子が未指定の場合
137
137
  throw new NakoImportError(`ファイル『${name}』は拡張子が(.nako3|.js|.js.txt|.mjs|.mjs.txt)以外なので取り込めません。`, token.file, token.line)
@@ -166,6 +166,29 @@ class WebNakoCompiler extends NakoCompiler {
166
166
  }
167
167
  }
168
168
 
169
+ function dirname(s) {
170
+ const a = s.split('/')
171
+ if (a && a.length > 1) {
172
+ return a.slice(0, a.length - 1).join('/')
173
+ }
174
+ return ''
175
+ }
176
+
177
+ function resolveURL(base, s) {
178
+ const baseA = base.split('/')
179
+ const sA = s.split('/')
180
+ for (let p of sA) {
181
+ if (p === '') {continue}
182
+ if (p === '.') {continue}
183
+ if (p === '..') {
184
+ baseA.pop()
185
+ continue
186
+ }
187
+ baseA.push(p)
188
+ }
189
+ return baseA.join('/')
190
+ }
191
+
169
192
  // ブラウザなら navigator.nako3 になでしこを登録
170
193
  if (typeof (navigator) === 'object' && !navigator.exportWNako3) {
171
194
  const nako3 = navigator.nako3 = new WebNakoCompiler()
@@ -9,7 +9,7 @@ const __filename = url.fileURLToPath(import.meta.url);
9
9
  const __dirname = path.dirname(__filename);
10
10
 
11
11
  const nakoHome = path.resolve(path.join(__dirname, '../../'))
12
- const cnako3 = path.resolve(path.join(nakoHome, 'src/cnako3.js'))
12
+ const cnako3 = path.resolve(path.join(nakoHome, 'src/cnako3.mjs'))
13
13
  const nako3edit = path.resolve(path.join(__dirname, 'index.nako3'))
14
14
 
15
15
  let proc = spawn('node', [cnako3, nako3edit])