nadesiko3 3.2.52 → 3.3.3
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/README.md +1 -1
- package/bin/cnako3 +1 -1
- package/bin/cnako3.bat +1 -1
- package/demo/browsers.html +9 -10
- package/demo/flow.html +1 -0
- package/demo/runscript3.html +35 -0
- package/demo/turtle3.html +18 -17
- package/demo/turtle3d.html +1 -1
- package/demo/turtle3d2.html +1 -1
- package/doc/browsers.md +9 -10
- package/package.json +58 -57
- package/release/_hash.txt +57 -52
- package/release/_script-tags.txt +14 -13
- package/release/command.json +1 -1
- package/release/command.json.js +1 -1
- package/release/command_cnako3.json +1 -1
- package/release/command_list.json +1 -1
- package/release/editor.js +1 -1
- package/release/editor.js.LICENSE.txt +9 -12
- package/release/nako_gen_async.js +1 -1
- package/release/nako_gen_async.js.LICENSE.txt +10 -666
- package/release/plugin_caniuse.js +1 -1
- package/release/plugin_caniuse.js.LICENSE.txt +9 -425
- package/release/plugin_csv.js +1 -1
- package/release/plugin_csv.js.LICENSE.txt +3 -419
- package/release/plugin_datetime.js +1 -1
- package/release/plugin_datetime.js.LICENSE.txt +6 -530
- package/release/plugin_kansuji.js +1 -1
- package/release/plugin_kansuji.js.LICENSE.txt +3 -559
- package/release/plugin_markup.js +1 -1
- package/release/plugin_markup.js.LICENSE.txt +4 -420
- package/release/plugin_turtle.js +1 -1
- package/release/plugin_turtle.js.LICENSE.txt +12 -500
- package/release/plugin_webworker.js +1 -1
- package/release/plugin_webworker.js.LICENSE.txt +3 -563
- package/release/plugin_weykturtle3d.js +1 -0
- package/release/plugin_weykturtle3d.js.LICENSE.txt +3 -0
- package/release/stats.json +1 -1
- package/release/version.js +1 -1
- package/release/version.js.LICENSE.txt +9 -12
- package/release/wnako3.js +1 -1
- package/release/wnako3.js.LICENSE.txt +1 -1
- package/release/wnako3webworker.js +1 -1
- package/release/wnako3webworker.js.LICENSE.txt +1 -1117
- package/src/browsers.mjs +1 -0
- package/src/browsers.txt +15 -15
- package/src/browsers_agents.mjs +1 -0
- package/src/cnako3.mjs +13 -0
- package/src/{cnako3.js → cnako3mod.mjs} +119 -101
- package/src/{commander_ja.js → commander_ja.mjs} +16 -11
- package/src/{enako3.js → enako3.mjs} +0 -0
- package/src/{era.json → era.mjs} +1 -1
- package/src/image_turtle-elephant.mjs +5 -0
- package/src/image_turtle-panda.mjs +5 -0
- package/src/image_turtle64.mjs +5 -0
- package/src/index.mjs +9 -0
- package/src/{nako3.js → nako3.mjs} +69 -57
- package/src/{nako3_assert.js → nako3_assert.mjs} +7 -6
- package/src/{nako3server.js → nako3server.mjs} +12 -5
- package/src/{nako_colors.js → nako_colors.mjs} +1 -1
- package/src/{nako_errors.js → nako_errors.mjs} +10 -20
- package/src/{nako_from_dncl.js → nako_from_dncl.mjs} +11 -8
- package/src/{nako_gen.js → nako_gen.mjs} +93 -87
- package/src/{nako_gen_async.js → nako_gen_async.mjs} +5 -8
- package/src/{nako_global.js → nako_global.mjs} +4 -5
- package/src/{nako_indent.js → nako_indent.mjs} +29 -25
- package/src/{nako_josi_list.js → nako_josi_list.mjs} +16 -14
- package/src/nako_lex_rules.mjs +244 -0
- package/src/{nako_lexer.js → nako_lexer.mjs} +7 -10
- package/src/{nako_logger.js → nako_logger.mjs} +3 -4
- package/src/{nako_parser3.js → nako_parser3.mjs} +5 -5
- package/src/{nako_parser_base.js → nako_parser_base.mjs} +1 -9
- package/src/{nako_parser_const.js → nako_parser_const.mjs} +2 -6
- package/src/{nako_prepare.js → nako_prepare.mjs} +46 -8
- package/src/{nako_reserved_words.js → nako_reserved_words.mjs} +1 -1
- package/src/{nako_source_mapping.js → nako_source_mapping.mjs} +4 -11
- package/src/{nako_test.js → nako_test.mjs} +0 -0
- package/src/nako_version.mjs +7 -0
- package/src/{plugin_browser.js → plugin_browser.mjs} +30 -30
- package/src/{plugin_browser_ajax.js → plugin_browser_ajax.mjs} +7 -7
- package/src/{plugin_browser_audio.js → plugin_browser_audio.mjs} +1 -1
- package/src/{plugin_browser_canvas.js → plugin_browser_canvas.mjs} +1 -1
- package/src/{plugin_browser_chart.js → plugin_browser_chart.mjs} +1 -1
- package/src/{plugin_browser_color.js → plugin_browser_color.mjs} +1 -1
- package/src/{plugin_browser_crypto.js → plugin_browser_crypto.mjs} +1 -1
- package/src/{plugin_browser_dialog.js → plugin_browser_dialog.mjs} +1 -1
- package/src/{plugin_browser_dom_basic.js → plugin_browser_dom_basic.mjs} +1 -1
- package/src/{plugin_browser_dom_event.js → plugin_browser_dom_event.mjs} +1 -1
- package/src/{plugin_browser_dom_parts.js → plugin_browser_dom_parts.mjs} +1 -1
- package/src/{plugin_browser_geolocation.js → plugin_browser_geolocation.mjs} +1 -1
- package/src/{plugin_browser_hotkey.js → plugin_browser_hotkey.mjs} +2 -2
- package/src/{plugin_browser_html.js → plugin_browser_html.mjs} +1 -1
- package/src/{plugin_browser_in_worker.js → plugin_browser_in_worker.mjs} +4 -4
- package/src/{plugin_browser_location.js → plugin_browser_location.mjs} +1 -1
- package/src/{plugin_browser_speech.js → plugin_browser_speech.mjs} +1 -1
- package/src/{plugin_browser_storage.js → plugin_browser_storage.mjs} +1 -1
- package/src/{plugin_browser_system.js → plugin_browser_system.mjs} +1 -1
- package/src/{plugin_browser_websocket.js → plugin_browser_websocket.mjs} +1 -1
- package/src/{plugin_caniuse.js → plugin_caniuse.mjs} +8 -3
- package/src/{plugin_csv.js → plugin_csv.mjs} +4 -5
- package/src/{plugin_datetime.js → plugin_datetime.mjs} +19 -26
- package/src/{plugin_express.js → plugin_express.mjs} +4 -3
- package/src/{plugin_kansuji.js → plugin_kansuji.mjs} +1 -1
- package/src/{plugin_keigo.js → plugin_keigo.mjs} +1 -1
- package/src/{plugin_markup.js → plugin_markup.mjs} +6 -6
- package/src/{plugin_math.js → plugin_math.mjs} +1 -4
- package/src/{plugin_node.js → plugin_node.mjs} +25 -57
- package/src/{plugin_promise.js → plugin_promise.mjs} +1 -3
- package/src/{plugin_system.js → plugin_system.mjs} +32 -15
- package/src/{plugin_test.js → plugin_test.mjs} +1 -3
- package/src/{plugin_turtle.js → plugin_turtle.mjs} +5 -4
- package/src/{plugin_webworker.js → plugin_webworker.mjs} +3 -3
- package/src/{plugin_weykturtle3d.js → plugin_weykturtle3d.mjs} +1 -3
- package/src/{plugin_worker.js → plugin_worker.mjs} +4 -1
- package/src/{wnako3.js → wnako3.mjs} +24 -14
- package/src/{wnako3_editor.js → wnako3_editor.mjs} +28 -22
- package/src/{wnako3webworker.js → wnako3webworker.mjs} +0 -0
- package/test/async/{async_basic_test.js → async_basic_test.mjs} +3 -4
- package/test/browser/karma.config.js +9 -0
- package/test/browser/test/plugin_browser_test.js +2 -2
- package/test/browser/test/plugin_turtle_test.js +2 -2
- package/test/browser/test/plugin_webworker_test.js +3 -3
- package/test/browser/test/require_test.js +2 -2
- package/test/common/{array_test.js → array_test.mjs} +3 -3
- package/test/common/{basic_test.js → basic_test.mjs} +3 -13
- package/test/common/{calc_test.js → calc_test.mjs} +2 -2
- package/test/common/{debug_test.js → debug_test.mjs} +2 -2
- package/test/common/{dncl_test.js → dncl_test.mjs} +3 -3
- package/test/common/{error_test.js → error_test.mjs} +2 -2
- package/test/common/{flow_test.js → flow_test.mjs} +2 -2
- package/test/common/{func_call.js → func_call.mjs} +3 -3
- package/test/common/{func_test.js → func_test.mjs} +2 -2
- package/test/common/{indent_test.js → indent_test.mjs} +3 -2
- package/test/common/{lex_test.js → lex_test.mjs} +2 -2
- package/test/common/{literal_test.js → literal_test.mjs} +3 -2
- package/test/common/{nako_logger_test.js → nako_logger_test.mjs} +3 -3
- package/test/common/{plugin_browser_test.js → plugin_browser_test.mjs} +4 -4
- package/test/common/{plugin_browser_ut_audio_test.js → plugin_browser_ut_audio_test.mjs} +4 -4
- package/test/common/{plugin_browser_ut_color_test.js → plugin_browser_ut_color_test.mjs} +2 -2
- package/test/common/{plugin_browser_ut_dialog_test.js → plugin_browser_ut_dialog_test.mjs} +3 -3
- package/test/common/{plugin_browser_ut_html_test.js → plugin_browser_ut_html_test.mjs} +2 -2
- package/test/common/{plugin_browser_ut_system_test.js → plugin_browser_ut_system_test.mjs} +2 -2
- package/test/common/{plugin_csv_test.js → plugin_csv_test.mjs} +3 -3
- package/test/common/{plugin_datetime_test.js → plugin_datetime_test.mjs} +4 -4
- package/test/common/{plugin_kansuji_test.js → plugin_kansuji_test.mjs} +3 -3
- package/test/common/{plugin_markup_test.js → plugin_markup_test.mjs} +3 -3
- package/test/common/{plugin_promise_test.js → plugin_promise_test.mjs} +2 -2
- package/test/common/{plugin_system_test.js → plugin_system_test.mjs} +2 -2
- package/test/common/{prepare_test.js → prepare_test.mjs} +2 -2
- package/test/common/{re_test.js → re_test.mjs} +2 -2
- package/test/common/{variable_scope_test.js → variable_scope_test.mjs} +2 -2
- package/test/karma.config.js +3 -3
- package/test/node/{async_test.js → async_test.mjs} +4 -2
- package/test/node/{commander_ja_test.js → commander_ja_test.mjs} +17 -12
- package/test/node/{error_message_test.js → error_message_test.mjs} +13 -10
- package/test/node/node_test.mjs +57 -0
- package/test/node/{plugin_browser_ut_ajax_test.js → plugin_browser_ut_ajax_test.mjs} +7 -5
- package/test/node/{plugin_browser_ut_location_test.js → plugin_browser_ut_location_test.mjs} +3 -3
- package/test/node/{plugin_markup_test.js → plugin_markup_test.mjs} +6 -7
- package/test/node/{plugin_math_test.js → plugin_math_test.mjs} +5 -5
- package/test/node/{plugin_node_test.js → plugin_node_test.mjs} +11 -7
- package/test/node/{plugin_test.js → plugin_test.mjs} +11 -5
- package/test/node/{require_nako3_test.js → require_nako3_test.mjs} +19 -12
- package/test/node/{side_effects_test.js → side_effects_test.mjs} +24 -13
- package/test/node/{wnako3_editor_test.js → wnako3_editor_test.mjs} +16 -9
- package/tools/nako3edit/html/daisyui/LICENSE +22 -0
- package/tools/nako3edit/html/daisyui/full.css +1 -0
- package/tools/nako3edit/html/daisyui/tailwind.min.css +1 -0
- package/tools/nako3edit/html/daisyui/version_2.14.1 +1 -0
- package/tools/nako3edit/html/edit.html +104 -19
- package/tools/nako3edit/html/files.html +84 -8
- package/tools/nako3edit/html/nako3edit.css +6 -7
- package/tools/nako3edit/index.nako3 +45 -6
- package/tools/nako3edit/{run.js → run.mjs} +8 -2
- package/src/index.js +0 -5
- package/src/nako_lex_rules.js +0 -260
- package/src/nako_version.js +0 -8
- package/test/node/node_test.js +0 -43
package/src/browsers.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {"and_chr":["100"],"and_ff":["99"],"and_qq":["10.4"],"and_uc":["12.12"],"android":["100"],"baidu":["7.12"],"chrome":["100","99","98","97"],"edge":["100","99","98"],"firefox":["99","98","97","91"],"ios_saf":["15.4","15.2-15.3","15.0-15.1","14.5-14.8","14.0-14.4","12.2-12.5"],"kaios":["2.5"],"node":["17.9.0","16.14.0","14.19.0","12.22.0"],"op_mini":["all"],"op_mob":["64"],"opera":["83","82"],"safari":["15.4","15.2-15.3","14.1"],"samsung":["16.0","15.0"]}
|
package/src/browsers.txt
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
and_chr
|
|
2
|
-
and_ff
|
|
1
|
+
and_chr 100
|
|
2
|
+
and_ff 99
|
|
3
3
|
and_qq 10.4
|
|
4
4
|
and_uc 12.12
|
|
5
|
-
android
|
|
5
|
+
android 100
|
|
6
6
|
baidu 7.12
|
|
7
|
+
chrome 100
|
|
8
|
+
chrome 99
|
|
7
9
|
chrome 98
|
|
8
10
|
chrome 97
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
edge 100
|
|
12
|
+
edge 99
|
|
11
13
|
edge 98
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
firefox
|
|
15
|
-
firefox 95
|
|
14
|
+
firefox 99
|
|
15
|
+
firefox 98
|
|
16
|
+
firefox 97
|
|
16
17
|
firefox 91
|
|
17
|
-
|
|
18
|
-
ie 11
|
|
18
|
+
ios_saf 15.4
|
|
19
19
|
ios_saf 15.2-15.3
|
|
20
20
|
ios_saf 15.0-15.1
|
|
21
21
|
ios_saf 14.5-14.8
|
|
22
22
|
ios_saf 14.0-14.4
|
|
23
23
|
ios_saf 12.2-12.5
|
|
24
24
|
kaios 2.5
|
|
25
|
-
node 17.
|
|
26
|
-
node 16.
|
|
27
|
-
node 14.
|
|
25
|
+
node 17.9.0
|
|
26
|
+
node 16.14.0
|
|
27
|
+
node 14.19.0
|
|
28
28
|
node 12.22.0
|
|
29
29
|
op_mini all
|
|
30
30
|
op_mob 64
|
|
31
31
|
opera 83
|
|
32
32
|
opera 82
|
|
33
|
+
safari 15.4
|
|
33
34
|
safari 15.2-15.3
|
|
34
|
-
safari 15.1
|
|
35
35
|
safari 14.1
|
|
36
36
|
samsung 16.0
|
|
37
37
|
samsung 15.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {"ie":"IE","edge":"Edge","firefox":"Firefox","chrome":"Chrome","safari":"Safari","opera":"Opera","ios_saf":"Safari on iOS","op_mini":"Opera Mini","android":"Android Browser","bb":"Blackberry Browser","op_mob":"Opera Mobile","and_chr":"Chrome for Android","and_ff":"Firefox for Android","ie_mob":"IE Mobile","and_uc":"UC Browser for Android","samsung":"Samsung Internet","and_qq":"QQ Browser","baidu":"Baidu Browser","kaios":"KaiOS Browser"}
|
package/src/cnako3.mjs
ADDED
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
// @ts-nocheck
|
|
3
2
|
/**
|
|
4
|
-
* コマンドライン版のなでしこ3
|
|
3
|
+
* コマンドライン版のなでしこ3をモジュールとして定義
|
|
4
|
+
* 実際には cnako3.js から読み込まれる
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import fs from 'fs'
|
|
7
|
+
import { exec } from 'child_process'
|
|
8
|
+
import path from 'path'
|
|
9
|
+
import { NakoCompiler } from './nako3.mjs'
|
|
10
|
+
import PluginNode from './plugin_node.mjs'
|
|
11
|
+
import { NakoImportError } from './nako_errors.mjs'
|
|
12
|
+
import app from './commander_ja.mjs'
|
|
13
|
+
import nakoVersion from './nako_version.mjs'
|
|
14
|
+
import fetch from 'node-fetch'
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const NakoGenASync = require('./nako_gen_async')
|
|
16
|
+
// __dirname のために
|
|
17
|
+
import url from 'url'
|
|
18
|
+
const __filename = url.fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = path.dirname(__filename);
|
|
14
20
|
|
|
15
|
-
class CNako3 extends NakoCompiler {
|
|
21
|
+
export class CNako3 extends NakoCompiler {
|
|
16
22
|
/** @param {{ nostd?: boolean }} [opts] */
|
|
17
23
|
constructor (opts = {}) {
|
|
18
24
|
super({ useBasicPlugin: true })
|
|
19
25
|
this.silent = false
|
|
20
|
-
this.addCodeGenerator('非同期モード', NakoGenASync) // 「!非同期モード」をサポート
|
|
21
26
|
if (!opts.nostd) {
|
|
22
27
|
this.addPluginFile('PluginNode', path.join(__dirname, 'plugin_node.js'), PluginNode)
|
|
23
28
|
}
|
|
@@ -30,12 +35,11 @@ class CNako3 extends NakoCompiler {
|
|
|
30
35
|
if (process.argv.length <= 2) { process.argv.push('-h') }
|
|
31
36
|
|
|
32
37
|
// commanderを使って引数を解析する
|
|
33
|
-
const app = require('./commander_ja.js')
|
|
34
|
-
const nakoVersion = require('./nako_version.js')
|
|
35
38
|
app
|
|
36
39
|
.title('日本語プログラミング言語「なでしこ」v' + nakoVersion.version)
|
|
37
40
|
.version(nakoVersion.version, '-v, --version')
|
|
38
41
|
.usage('[オプション] 入力ファイル.nako3')
|
|
42
|
+
.option('-h, --help', 'コマンドの使い方を表示')
|
|
39
43
|
.option('-w, --warn', '警告を表示する')
|
|
40
44
|
.option('-d, --debug', 'デバッグモードの指定')
|
|
41
45
|
.option('-D, --trace', '詳細デバッグモードの指定')
|
|
@@ -85,7 +89,7 @@ class CNako3 extends NakoCompiler {
|
|
|
85
89
|
source: app.eval || '',
|
|
86
90
|
man: app.man || '',
|
|
87
91
|
one_liner: app.eval || false,
|
|
88
|
-
debug: this.debug,
|
|
92
|
+
debug: this.debug || false,
|
|
89
93
|
trace: app.trace,
|
|
90
94
|
warn: app.warn,
|
|
91
95
|
repl: app.repl || false,
|
|
@@ -101,6 +105,7 @@ class CNako3 extends NakoCompiler {
|
|
|
101
105
|
if (args.test) {
|
|
102
106
|
args.output = args.mainfile.replace(/\.(nako|nako3)$/, '.spec.js')
|
|
103
107
|
} else {
|
|
108
|
+
// todo: 将来的に mjs のコードを履くように修正する↓ '.mjs'
|
|
104
109
|
args.output = args.mainfile.replace(/\.(nako|nako3)$/, '.js')
|
|
105
110
|
}
|
|
106
111
|
}
|
|
@@ -118,8 +123,10 @@ class CNako3 extends NakoCompiler {
|
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
// 実行する
|
|
121
|
-
execCommand () {
|
|
126
|
+
async execCommand () {
|
|
127
|
+
// コマンドを解析
|
|
122
128
|
const opt = this.checkArguments()
|
|
129
|
+
// 使い方の表示か?
|
|
123
130
|
if (opt.man) {
|
|
124
131
|
this.cnakoMan(opt.man)
|
|
125
132
|
return
|
|
@@ -141,7 +148,7 @@ class CNako3 extends NakoCompiler {
|
|
|
141
148
|
// メインプログラムを読み込む
|
|
142
149
|
const src = fs.readFileSync(opt.mainfile, 'utf-8')
|
|
143
150
|
if (opt.compile) {
|
|
144
|
-
this.nakoCompile(opt, src, false)
|
|
151
|
+
await this.nakoCompile(opt, src, false)
|
|
145
152
|
return
|
|
146
153
|
}
|
|
147
154
|
if (opt.ast) {
|
|
@@ -150,10 +157,11 @@ class CNako3 extends NakoCompiler {
|
|
|
150
157
|
}
|
|
151
158
|
try {
|
|
152
159
|
if (opt.test) {
|
|
153
|
-
this.loadDependencies(src, opt.mainfile, '')
|
|
160
|
+
await this.loadDependencies(src, opt.mainfile, '')
|
|
154
161
|
this.test(src, opt.mainfile)
|
|
155
162
|
} else {
|
|
156
|
-
|
|
163
|
+
// run はコンパイルと実行を行うメソッド
|
|
164
|
+
await this.run(src, opt.mainfile)
|
|
157
165
|
}
|
|
158
166
|
if (opt.test && this.numFailures > 0) {
|
|
159
167
|
process.exit(1)
|
|
@@ -172,8 +180,9 @@ class CNako3 extends NakoCompiler {
|
|
|
172
180
|
* @param {string} src
|
|
173
181
|
* @param {boolean} isTest
|
|
174
182
|
*/
|
|
175
|
-
nakoCompile (opt, src, isTest) {
|
|
183
|
+
async nakoCompile (opt, src, isTest) {
|
|
176
184
|
// system
|
|
185
|
+
await this.loadDependencies(src, this.filename, '')
|
|
177
186
|
const jscode = this.compileStandalone(src, this.filename, isTest)
|
|
178
187
|
console.log(opt.output)
|
|
179
188
|
fs.writeFileSync(opt.output, jscode, 'utf-8')
|
|
@@ -271,7 +280,8 @@ class CNako3 extends NakoCompiler {
|
|
|
271
280
|
// マニュアルを表示する
|
|
272
281
|
cnakoMan (command) {
|
|
273
282
|
try {
|
|
274
|
-
const
|
|
283
|
+
const path_commands = path.join(__dirname, '../release/command_cnako3.json')
|
|
284
|
+
const commands = JSON.parse(fs.readFileSync(path_commands, 'utf-8'))
|
|
275
285
|
const data = commands[command]
|
|
276
286
|
for (const key in data) {
|
|
277
287
|
console.log(`${key}: ${data[key]}`)
|
|
@@ -296,15 +306,20 @@ class CNako3 extends NakoCompiler {
|
|
|
296
306
|
* @param {string} filename
|
|
297
307
|
* @param {string} preCode
|
|
298
308
|
*/
|
|
299
|
-
loadDependencies (code, filename, preCode) {
|
|
309
|
+
async loadDependencies (code, filename, preCode) {
|
|
300
310
|
/** @type {string[]} */
|
|
301
311
|
const log = []
|
|
302
|
-
|
|
303
|
-
const tasks = super._loadDependencies(code, filename, preCode, {
|
|
312
|
+
const tools = {
|
|
304
313
|
resolvePath: (name, token) => {
|
|
305
|
-
|
|
306
|
-
|
|
314
|
+
// JSプラグインのパスを解決する
|
|
315
|
+
if (/\.(js|mjs)(\.txt)?$/.test(name) || /^[^.]*$/.test(name)) {
|
|
316
|
+
const jspath = CNako3.findJSPluginFile(name, this.filename, __dirname, log)
|
|
317
|
+
if (jspath === '') {
|
|
318
|
+
throw new NakoImportError(`ファイル『${name}』が見つかりません。以下のパスを検索しました。\n${log.join('\n')}`, token.file, token.line)
|
|
319
|
+
}
|
|
320
|
+
return { filePath: jspath, type: 'js' }
|
|
307
321
|
}
|
|
322
|
+
// なでしこプラグインのパスを解決する
|
|
308
323
|
if (/\.nako3?(\.txt)?$/.test(name)) {
|
|
309
324
|
if (path.isAbsolute(name)) {
|
|
310
325
|
return { filePath: path.resolve(name), type: 'nako3' }
|
|
@@ -320,30 +335,33 @@ class CNako3 extends NakoCompiler {
|
|
|
320
335
|
},
|
|
321
336
|
readNako3: (name, token) => {
|
|
322
337
|
if (!fs.existsSync(name)) {
|
|
323
|
-
throw new NakoImportError(`ファイル ${name} が存在しません。`, token.
|
|
338
|
+
throw new NakoImportError(`ファイル ${name} が存在しません。`, token.file, token.line)
|
|
324
339
|
}
|
|
325
340
|
return { sync: true, value: fs.readFileSync(name).toString() }
|
|
326
341
|
},
|
|
327
|
-
readJs: (
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return require(name)
|
|
333
|
-
} catch (/** @type {unknown} */err) {
|
|
334
|
-
let msg = `プラグイン ${name} の取り込みに失敗: ${err instanceof Error ? err.message : err + ''}`
|
|
335
|
-
if (err instanceof Error && err.message.startsWith('Cannot find module')) {
|
|
336
|
-
msg += `\n次の場所を検索しました: ${log.join(', ')}`
|
|
337
|
-
}
|
|
338
|
-
throw new NakoImportError(msg, token.line, token.file)
|
|
339
|
-
}
|
|
342
|
+
readJs: (filePath, token) => {
|
|
343
|
+
const content = {sync: false, value: null}
|
|
344
|
+
if (process.platform === 'win32') {
|
|
345
|
+
if (filePath.substring(1, 3) === ':\\') {
|
|
346
|
+
filePath = 'file://' + filePath
|
|
340
347
|
}
|
|
341
348
|
}
|
|
349
|
+
content.value = (
|
|
350
|
+
new Promise((resolve, reject) => {
|
|
351
|
+
import(filePath).then((mod) => {
|
|
352
|
+
// プラグインは export default で宣言されている? (moduleプラグインの場合)
|
|
353
|
+
const obj = Object.assign({}, mod)
|
|
354
|
+
resolve(() => { return obj.default })
|
|
355
|
+
}).catch((err) => {
|
|
356
|
+
const err2 = new NakoImportError(`ファイル『${filePath}』が読み込めません。${err}`, token.file, token.line)
|
|
357
|
+
reject(err2)
|
|
358
|
+
})
|
|
359
|
+
})
|
|
360
|
+
)
|
|
361
|
+
return content
|
|
342
362
|
}
|
|
343
|
-
})
|
|
344
|
-
if (tasks !== undefined) {
|
|
345
|
-
throw new Error('assertion error')
|
|
346
363
|
}
|
|
364
|
+
return super._loadDependencies(code, filename, preCode, tools)
|
|
347
365
|
}
|
|
348
366
|
|
|
349
367
|
/**
|
|
@@ -351,88 +369,96 @@ class CNako3 extends NakoCompiler {
|
|
|
351
369
|
* @param {string} fname
|
|
352
370
|
* @param {string} [preCode]
|
|
353
371
|
*/
|
|
354
|
-
run (code, fname, preCode = '') {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
372
|
+
async run (code, fname, preCode = '') {
|
|
373
|
+
// 取り込む文の処理
|
|
374
|
+
await this.loadDependencies(code, fname, preCode).catch((err) => {
|
|
375
|
+
this.logger.error(err)
|
|
376
|
+
})
|
|
377
|
+
// 実行
|
|
359
378
|
return this._runEx(code, fname, {}, preCode)
|
|
360
379
|
}
|
|
361
380
|
|
|
362
381
|
/**
|
|
363
382
|
* プラグインファイルの検索を行う
|
|
364
|
-
* @param {string} pname
|
|
365
|
-
* @param {string} filename
|
|
383
|
+
* @param {string} pname プラグインの名前
|
|
384
|
+
* @param {string} filename 取り込み元ファイル名
|
|
366
385
|
* @param {string} srcDir このファイルが存在するディレクトリ
|
|
367
386
|
* @param {string[]} [log]
|
|
368
|
-
* @return {string}
|
|
387
|
+
* @return {string} フルパス、失敗した時は、''を返す
|
|
369
388
|
*/
|
|
370
|
-
static
|
|
389
|
+
static findJSPluginFile (pname, filename, srcDir, log = []) {
|
|
371
390
|
log.length = 0
|
|
391
|
+
const cachePath = {}
|
|
372
392
|
/** @type {string[]} */
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
return pname
|
|
378
|
-
}
|
|
379
|
-
// 各パスを調べる
|
|
380
|
-
const exists = (f, desc) => {
|
|
381
|
-
const result = fs.existsSync(f)
|
|
393
|
+
const exists = (f, _desc) => {
|
|
394
|
+
// 同じパスを何度も検索することがないように
|
|
395
|
+
if (cachePath[f]) { return false }
|
|
396
|
+
cachePath[f] = true
|
|
382
397
|
log.push(f)
|
|
383
|
-
|
|
384
|
-
return
|
|
398
|
+
const stat = fs.statSync(f, {throwIfNoEntry: false})
|
|
399
|
+
if (!stat) { return false }
|
|
400
|
+
return stat.isFile()
|
|
385
401
|
}
|
|
402
|
+
// 普通にファイルをチェック
|
|
386
403
|
const fCheck = (pathTest) => {
|
|
387
|
-
//
|
|
404
|
+
// 素直に指定されたパスをチェック
|
|
388
405
|
let fpath = path.join(pathTest, pname)
|
|
389
406
|
if (exists(fpath, 'direct')) { return fpath }
|
|
390
|
-
|
|
391
|
-
// プラグイン名を分解してチェック
|
|
392
|
-
const m = pname.match(/^(plugin_|nadesiko3-)([a-zA-Z0-9_-]+)/)
|
|
393
|
-
if (!m) { return false }
|
|
394
|
-
const name = m[2]
|
|
395
|
-
// plugin_xxx.js
|
|
396
|
-
// eslint-disable-next-line camelcase
|
|
397
|
-
const plugin_xxx_js = 'plugin_' + name + '.js'
|
|
398
|
-
fpath = path.join(pathTest, plugin_xxx_js)
|
|
399
|
-
if (exists(fpath, 'plugin_xxx.js')) { return fpath }
|
|
400
|
-
fpath = path.join(pathTest, 'src', plugin_xxx_js)
|
|
401
|
-
if (exists(fpath, 'src/plugin_xxx.js')) { return fpath }
|
|
402
|
-
// nadesiko3-xxx
|
|
403
|
-
// eslint-disable-next-line camelcase
|
|
404
|
-
const nadesiko3_xxx = 'nadesiko3-' + name
|
|
405
|
-
fpath = path.join(pathTest, nadesiko3_xxx)
|
|
406
|
-
if (exists(fpath, 'nadesiko3-xxx')) { return fpath }
|
|
407
|
-
fpath = path.join(pathTest, 'node_modules', nadesiko3_xxx)
|
|
408
|
-
if (exists(fpath, 'node_modules/nadesiko3-xxx')) { return fpath }
|
|
409
407
|
return false
|
|
410
408
|
}
|
|
409
|
+
// ファイル および node_modules 以下を調べる
|
|
410
|
+
const fCheckEx = (pathTest) => {
|
|
411
|
+
const defPath = fCheck(pathTest)
|
|
412
|
+
if (defPath) { return defPath }
|
|
413
|
+
const fpath = path.join(pathTest, 'node_modules', pname)
|
|
414
|
+
const json = path.join(fpath, 'package.json')
|
|
415
|
+
if (exists(json)) {
|
|
416
|
+
// package.jsonを見つけたので、メインファイルを調べて取り込む (CommonJSモジュール対策)
|
|
417
|
+
const json_txt = fs.readFileSync(json, 'utf-8')
|
|
418
|
+
const obj = JSON.parse(json_txt)
|
|
419
|
+
if (!obj['main']) { return false }
|
|
420
|
+
const mainFile = path.join(pathTest, 'node_modules', pname, obj['main'])
|
|
421
|
+
return mainFile
|
|
422
|
+
}
|
|
423
|
+
return false
|
|
424
|
+
}
|
|
425
|
+
// 各パスを検索していく
|
|
426
|
+
const p1 = pname.substring(0, 1)
|
|
427
|
+
// フルパス指定か?
|
|
428
|
+
if (p1 === '/') {
|
|
429
|
+
if (exists(pname)) { return pname }
|
|
430
|
+
const fileFullpath = fCheckEx(pname)
|
|
431
|
+
if (fileFullpath) { return fileFullpath }
|
|
432
|
+
return '' // フルパスの場合別のフォルダは調べない
|
|
433
|
+
}
|
|
411
434
|
// 相対パスか?
|
|
412
|
-
if (p1 === '.') {
|
|
435
|
+
if (p1 === '.' || pname.indexOf('/') >= 0) {
|
|
413
436
|
// 相対パス指定なので、なでしこのプログラムからの相対指定を調べる
|
|
414
437
|
const pathRelative = path.resolve(path.dirname(filename))
|
|
415
|
-
const fileRelative =
|
|
438
|
+
const fileRelative = fCheckEx(pathRelative)
|
|
416
439
|
if (fileRelative) { return fileRelative }
|
|
440
|
+
return '' // 相対パスの場合も別のフォルダは調べない
|
|
417
441
|
}
|
|
418
|
-
//
|
|
442
|
+
// plugin_xxx.mjs のようにファイル名のみが指定された場合のみ、いくつかのパスを調べる
|
|
443
|
+
// 母艦パス(元ファイルと同じフォルダ)か?
|
|
419
444
|
const pathScript = path.resolve(path.dirname(filename))
|
|
420
|
-
const fileScript =
|
|
445
|
+
const fileScript = fCheckEx(pathScript)
|
|
421
446
|
if (fileScript) { return fileScript }
|
|
422
447
|
|
|
423
448
|
// ランタイムパス/src
|
|
424
|
-
const pathRuntimeSrc = path.resolve(srcDir)
|
|
449
|
+
const pathRuntimeSrc = path.resolve(srcDir) // cnako3mod.mjs は ランタイム/src に配置されていることが前提
|
|
425
450
|
const fileRuntimeSrc = fCheck(pathRuntimeSrc)
|
|
426
451
|
if (fileRuntimeSrc) { return fileRuntimeSrc }
|
|
452
|
+
|
|
427
453
|
// ランタイムパス
|
|
428
|
-
const pathRuntime = path.dirname(
|
|
429
|
-
const fileRuntime =
|
|
454
|
+
const pathRuntime = path.resolve(path.dirname(srcDir))
|
|
455
|
+
const fileRuntime = fCheckEx(pathRuntime)
|
|
430
456
|
if (fileRuntime) { return fileRuntime }
|
|
431
457
|
|
|
432
458
|
// 環境変数 NAKO_HOMEか?
|
|
433
459
|
if (process.env.NAKO_HOME) {
|
|
434
460
|
const NAKO_HOME = path.resolve(process.env.NAKO_HOME)
|
|
435
|
-
const fileHome =
|
|
461
|
+
const fileHome = fCheckEx(NAKO_HOME)
|
|
436
462
|
if (fileHome) { return fileHome }
|
|
437
463
|
// NAKO_HOME/src ?
|
|
438
464
|
const pathNakoHomeSrc = path.join(NAKO_HOME, 'src')
|
|
@@ -442,18 +468,10 @@ class CNako3 extends NakoCompiler {
|
|
|
442
468
|
// 環境変数 NODE_PATH (global) 以下にあるか?
|
|
443
469
|
if (process.env.NODE_PATH) {
|
|
444
470
|
const pathNode = path.resolve(process.env.NODE_PATH)
|
|
445
|
-
const fileNode =
|
|
471
|
+
const fileNode = fCheckEx(pathNode)
|
|
446
472
|
if (fileNode) { return fileNode }
|
|
447
473
|
}
|
|
448
|
-
// Node
|
|
449
|
-
return
|
|
474
|
+
// Nodeのパス検索には任せない(importで必ず失敗するので)
|
|
475
|
+
return ''
|
|
450
476
|
}
|
|
451
477
|
}
|
|
452
|
-
|
|
453
|
-
// メイン
|
|
454
|
-
if (require.main === module) { // 直接実行する
|
|
455
|
-
const cnako3 = new CNako3()
|
|
456
|
-
cnako3.execCommand()
|
|
457
|
-
} else { // モジュールとして使う場合
|
|
458
|
-
module.exports = CNako3
|
|
459
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// commander_ja.js
|
|
2
|
-
|
|
2
|
+
export default {
|
|
3
3
|
args: /** @type {string[]} */([]),
|
|
4
4
|
_alias: /** @type {Record<string, string>} */({}),
|
|
5
5
|
_hasarg: /** @type {Record<string, boolean>} */({}),
|
|
@@ -7,6 +7,16 @@ const app = {
|
|
|
7
7
|
_usage: '',
|
|
8
8
|
_version: '1.0.0',
|
|
9
9
|
_title: '',
|
|
10
|
+
reset: function () {
|
|
11
|
+
this.args = []
|
|
12
|
+
this._alias = {}
|
|
13
|
+
this._hasarg = {}
|
|
14
|
+
this._help = []
|
|
15
|
+
this._usage = ''
|
|
16
|
+
this._version = '1.0.0'
|
|
17
|
+
this._title = ''
|
|
18
|
+
this.option('-h, --help', '使い方を表示する')
|
|
19
|
+
},
|
|
10
20
|
/**
|
|
11
21
|
* set version info
|
|
12
22
|
* @param {*} ver version info
|
|
@@ -36,7 +46,7 @@ const app = {
|
|
|
36
46
|
* @param {string} desc
|
|
37
47
|
*/
|
|
38
48
|
option (cmd, desc) {
|
|
39
|
-
|
|
49
|
+
this._help.push([cmd, desc])
|
|
40
50
|
let name1 = ''
|
|
41
51
|
const name2 = /** @type {string[]} */([])
|
|
42
52
|
const cmdList = cmd.split(',')
|
|
@@ -87,12 +97,12 @@ const app = {
|
|
|
87
97
|
continue
|
|
88
98
|
}
|
|
89
99
|
// Options
|
|
90
|
-
if (arg.
|
|
91
|
-
lastOpt = arg.
|
|
100
|
+
if (arg.substring(0, 2) === '--') {
|
|
101
|
+
lastOpt = arg.substring(2)
|
|
92
102
|
if (lastOpt === 'version') { lastOpt = 'version_' }
|
|
93
103
|
} else {
|
|
94
104
|
// Short Option
|
|
95
|
-
const shortName = arg.
|
|
105
|
+
const shortName = arg.substring(1)
|
|
96
106
|
if (this._alias[shortName]) {
|
|
97
107
|
lastOpt = this._alias[shortName]
|
|
98
108
|
} else {
|
|
@@ -142,13 +152,8 @@ const app = {
|
|
|
142
152
|
const spc = ' '
|
|
143
153
|
this._help.forEach((c) => {
|
|
144
154
|
const opt = c[0] + spc
|
|
145
|
-
ss += ' ' + opt.
|
|
155
|
+
ss += ' ' + opt.substring(0, 20) + ' ' + c[1] + '\n'
|
|
146
156
|
})
|
|
147
157
|
return ss
|
|
148
158
|
}
|
|
149
159
|
}
|
|
150
|
-
|
|
151
|
-
app.option('-h, --help', 'コマンドの使い方を表示')
|
|
152
|
-
|
|
153
|
-
// register app
|
|
154
|
-
module.exports = app
|
|
File without changes
|
package/src/{era.json → era.mjs}
RENAMED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
// file:turtle-elephant.png
|
|
3
|
+
export default 'data:image/png;base64,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'
|
|
4
|
+
//
|
|
5
|
+
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
// file:turtle-panda.png
|
|
3
|
+
export default 'data:image/png;base64,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'
|
|
4
|
+
//
|
|
5
|
+
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
// file:turtle64.png
|
|
3
|
+
export default 'data:image/png;base64,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'
|
|
4
|
+
//
|
|
5
|
+
|