nadesiko3 3.7.20 → 3.7.22
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 +483 -445
- package/batch/jsplugin2text.nako3 +1 -1
- package/batch/pickup_command.nako3 +12 -0
- package/core/command/snako.mts +5 -1
- package/core/deno/snako.ts +5 -1
- package/core/package-lock.json +382 -21
- package/core/package.json +4 -4
- package/core/src/README.md +98 -0
- package/core/src/nako3.mts +178 -614
- package/core/src/nako_basic_plugins.mts +39 -0
- package/core/src/nako_core_version.mts +2 -2
- package/core/src/nako_csv.mts +0 -1
- package/core/src/nako_event.mts +49 -0
- package/core/src/nako_gen.mts +291 -202
- package/core/src/nako_indent_inline.mts +2 -2
- package/core/src/nako_lex_rules.mts +1 -1
- package/core/src/nako_parser3.mts +106 -165
- package/core/src/nako_parser_async.mts +97 -0
- package/core/src/nako_parser_base.mts +4 -55
- package/core/src/nako_parser_message.mts +105 -0
- package/core/src/nako_parser_operator.mts +93 -0
- package/core/src/nako_plugin_manager.mts +260 -0
- package/core/src/nako_require.mts +292 -0
- package/core/src/nako_runner.mts +191 -0
- package/core/src/nako_tokenizer.mts +221 -0
- package/core/src/plugin_csv.mts +1 -1
- package/core/src/plugin_system.mts +34 -3259
- package/core/src/plugin_system_array.mts +699 -0
- package/core/src/plugin_system_datetime.mts +368 -0
- package/core/src/plugin_system_debug.mts +403 -0
- package/core/src/plugin_system_dict.mts +85 -0
- package/core/src/plugin_system_json.mts +73 -0
- package/core/src/plugin_system_math.mts +383 -0
- package/core/src/plugin_system_regexp.mts +120 -0
- package/core/src/plugin_system_stdio.mts +86 -0
- package/core/src/plugin_system_string.mts +666 -0
- package/core/src/plugin_system_timer.mts +152 -0
- package/core/src/plugin_system_types.mts +151 -0
- package/core/src/plugin_system_url.mts +193 -0
- package/core/src/plugin_toml.mts +3 -3
- package/core/test/fixtures/README.md +39 -0
- package/core/test/fixtures/make_parser_ast_golden.mjs +31 -0
- package/core/test/fixtures/parser_ast_golden.json +8027 -0
- package/core/test/fixtures/parser_corpus.mjs +120 -0
- package/core/test/indent_test.mjs +6 -0
- package/core/test/nako_basic_plugins_test.mjs +44 -0
- package/core/test/nako_event_test.mjs +85 -0
- package/core/test/nako_gen_perf_test.mjs +178 -0
- package/core/test/nako_parser_async_test.mjs +112 -0
- package/core/test/nako_parser_test.mjs +160 -0
- package/core/test/nako_plugin_manager_test.mjs +185 -0
- package/core/test/nako_require_test.mjs +153 -0
- package/core/test/nako_runner_test.mjs +114 -0
- package/core/test/nako_tokenizer_test.mjs +115 -0
- package/core/test/plugin_system_debug_test.mjs +141 -0
- package/core/test/plugin_system_split_test.mjs +179 -0
- package/core/test/plugin_system_test.mjs +6 -0
- package/core/tsconfig.json +0 -1
- package/package.json +24 -34
- package/release/_hash.txt +40 -40
- package/release/_script-tags.txt +16 -16
- 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/edit_main.js +6 -6
- package/release/edit_main.js.map +3 -3
- package/release/editor.js +6 -6
- package/release/plugin_datetime.js +1 -1
- package/release/plugin_datetime.js.map +3 -3
- package/release/plugin_keigo.js.map +3 -3
- package/release/plugin_markup.js +47 -47
- package/release/plugin_markup.js.map +3 -3
- package/release/plugin_weykturtle3d.js +1 -1
- package/release/plugin_weykturtle3d.js.map +3 -3
- package/release/version.js +2 -2
- package/release/version_main.js +2 -2
- package/release/version_main.js.map +2 -2
- package/release/wnako3.js +187 -214
- package/release/wnako3.js.map +4 -4
- package/release/wnako3webworker.js +172 -199
- package/release/wnako3webworker.js.map +4 -4
- package/src/cnako3mod.mjs +8 -4
- package/src/cnako3mod.mts +8 -4
- package/src/nako_version.mjs +2 -2
- package/src/nako_version.mts +2 -2
- package/src/plugin_browser_ajax.mjs +4 -4
- package/src/plugin_browser_ajax.mts +4 -4
- package/src/plugin_browser_audio.mjs +10 -10
- package/src/plugin_browser_audio.mts +10 -10
- package/src/plugin_browser_camera.mjs +4 -4
- package/src/plugin_browser_camera.mts +4 -4
- package/src/plugin_browser_canvas.mjs +2 -2
- package/src/plugin_browser_canvas.mts +2 -2
- package/src/plugin_browser_crypto.mjs +3 -3
- package/src/plugin_browser_crypto.mts +3 -3
- package/src/plugin_browser_dom_event.mjs +1 -1
- package/src/plugin_browser_dom_event.mts +1 -1
- package/src/plugin_browser_geolocation.mjs +1 -1
- package/src/plugin_browser_geolocation.mts +1 -1
- package/src/plugin_browser_hotkey.mjs +1 -1
- package/src/plugin_browser_hotkey.mts +1 -1
- package/src/plugin_browser_html.mjs +1 -1
- package/src/plugin_browser_html.mts +1 -1
- package/src/plugin_browser_location.mjs +1 -1
- package/src/plugin_browser_location.mts +1 -1
- package/src/plugin_browser_speech.mjs +1 -1
- package/src/plugin_browser_speech.mts +1 -1
- package/src/plugin_browser_storage.mjs +2 -2
- package/src/plugin_browser_storage.mts +2 -2
- package/src/plugin_httpserver.mjs +186 -15
- package/src/plugin_httpserver.mts +178 -12
- package/src/plugin_keigo.mjs +2 -2
- package/src/plugin_keigo.mts +2 -2
- package/src/plugin_node.mjs +48 -49
- package/src/plugin_node.mts +53 -54
- package/src/plugin_weykturtle3d.mjs +56 -56
- package/src/plugin_weykturtle3d.mts +56 -56
- package/src/wnako3.mjs +1 -1
- package/src/wnako3.mts +1 -1
- package/src/wnako3_editor.mjs +5 -5
- package/src/wnako3_editor.mts +5 -5
- package/src/wnako3mod.mjs +5 -2
- package/src/wnako3mod.mts +5 -2
- package/test/common/wnako3mod_test.mjs +48 -0
- package/test/node/package_json_test.mjs +17 -0
- package/test/node/plugin_httpserver_test.mjs +239 -0
- package/tools/nako3server/index.nako3 +4 -2
- package/core/src/nako3.mjs +0 -1021
- package/core/src/nako_ast.mjs +0 -4
- package/core/src/nako_colors.mjs +0 -77
- package/core/src/nako_core_version.mjs +0 -8
- package/core/src/nako_csv.mjs +0 -193
- package/core/src/nako_errors.mjs +0 -166
- package/core/src/nako_from_dncl.mjs +0 -285
- package/core/src/nako_from_dncl2.mjs +0 -347
- package/core/src/nako_gen.mjs +0 -2500
- package/core/src/nako_global.mjs +0 -138
- package/core/src/nako_indent.mjs +0 -442
- package/core/src/nako_indent_chars.mjs +0 -29
- package/core/src/nako_indent_inline.mjs +0 -361
- package/core/src/nako_josi_list.mjs +0 -47
- package/core/src/nako_lex_rules.mjs +0 -319
- package/core/src/nako_lexer.mjs +0 -794
- package/core/src/nako_logger.mjs +0 -221
- package/core/src/nako_parser3.mjs +0 -3250
- package/core/src/nako_parser_base.mjs +0 -403
- package/core/src/nako_parser_const.mjs +0 -37
- package/core/src/nako_prepare.mjs +0 -329
- package/core/src/nako_reserved_words.mjs +0 -42
- package/core/src/nako_source_mapping.mjs +0 -207
- package/core/src/nako_test.mjs +0 -37
- package/core/src/nako_token.mjs +0 -1
- package/core/src/nako_tools.mjs +0 -53
- package/core/src/nako_types.mjs +0 -14
- package/core/src/plugin_api.mjs +0 -4
- package/core/src/plugin_csv.mjs +0 -97
- package/core/src/plugin_math.mjs +0 -352
- package/core/src/plugin_promise.mjs +0 -102
- package/core/src/plugin_system.mjs +0 -3810
- package/core/src/plugin_test.mjs +0 -52
- package/core/src/plugin_toml.mjs +0 -39
package/core/src/nako_gen.mts
CHANGED
|
@@ -37,6 +37,37 @@ interface FunctionContext {
|
|
|
37
37
|
varsIndex: number;
|
|
38
38
|
usesClosure: boolean;
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
/** 生成したコードの各行を n段だけインデントする (空行は捨てる) */
|
|
42
|
+
function indentLines (text: string, n: number): string {
|
|
43
|
+
let result = ''
|
|
44
|
+
for (const line of text.split('\n')) {
|
|
45
|
+
if (line !== '') {
|
|
46
|
+
result += ' '.repeat(n) + line + '\n'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* パフォーマンスモニタの計測結果を `__self.__performance_monitor[key]` に記録するコードを生成する。
|
|
54
|
+
* ユーザ関数・システム関数本体・システム関数の3箇所で共通して使う。(#2333)
|
|
55
|
+
* @param timeVar 経過時間(マイクロ秒)が入っているJS変数名
|
|
56
|
+
*/
|
|
57
|
+
function genPerfMonitorUpdate (timeVar: string): string {
|
|
58
|
+
const rec = `{ called:1, totel_usec: ${timeVar}, min_usec: ${timeVar}, max_usec: ${timeVar}, type: type }`
|
|
59
|
+
return 'if (!__self.__performance_monitor) {\n' +
|
|
60
|
+
'__self.__performance_monitor={};\n' +
|
|
61
|
+
`__self.__performance_monitor[key] = ${rec};\n` +
|
|
62
|
+
'} else if (!__self.__performance_monitor[key]) {\n' +
|
|
63
|
+
`__self.__performance_monitor[key] = ${rec};\n` +
|
|
64
|
+
'} else {\n' +
|
|
65
|
+
'__self.__performance_monitor[key].called++;\n' +
|
|
66
|
+
`__self.__performance_monitor[key].totel_usec+=${timeVar};\n` +
|
|
67
|
+
`if(__self.__performance_monitor[key].min_usec>${timeVar}){__self.__performance_monitor[key].min_usec=${timeVar};}\n` +
|
|
68
|
+
`if(__self.__performance_monitor[key].max_usec<${timeVar}){__self.__performance_monitor[key].max_usec=${timeVar};}\n` +
|
|
69
|
+
'}'
|
|
70
|
+
}
|
|
40
71
|
interface FindVarResult {
|
|
41
72
|
i: number;
|
|
42
73
|
name: string;
|
|
@@ -44,6 +75,15 @@ interface FindVarResult {
|
|
|
44
75
|
js: string,
|
|
45
76
|
js_set: string
|
|
46
77
|
}
|
|
78
|
+
/** 関数呼び出しコードを組み立てるための部品 (convCallFunc) */
|
|
79
|
+
interface CallCodeParts {
|
|
80
|
+
funcDef: string; // 'function' または 'async function'
|
|
81
|
+
funcCall: string; // 関数を呼び出す式
|
|
82
|
+
funcBegin: string; // 呼び出しの直前に実行するコード
|
|
83
|
+
funcEnd: string; // 呼び出しの後に必ず実行するコード
|
|
84
|
+
isAsync: boolean; // 非同期関数の呼び出しか
|
|
85
|
+
sysPerfKey: string | null; // システム関数の計測キー。計測しないときはnull
|
|
86
|
+
}
|
|
47
87
|
/** コード生成オプション */
|
|
48
88
|
export class NakoGenOptions {
|
|
49
89
|
isTest: boolean
|
|
@@ -872,31 +912,9 @@ export class NakoGen {
|
|
|
872
912
|
let performanceMonitorInjectAtStart = ''
|
|
873
913
|
let performanceMonitorInjectAtEnd = ''
|
|
874
914
|
if (this.performanceMonitor.userFunction !== 0) {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
this.performanceMonitor.mumeiId = 0
|
|
879
|
-
}
|
|
880
|
-
this.performanceMonitor.mumeiId++
|
|
881
|
-
key = `anous_${this.performanceMonitor.mumeiId}`
|
|
882
|
-
}
|
|
883
|
-
performanceMonitorInjectAtStart = 'const performanceMonitorEnd = (function (key, type) {\n' +
|
|
884
|
-
'const uf_start = performance.now() * 1000;\n' +
|
|
885
|
-
'return function () {\n' +
|
|
886
|
-
'const el_time = performance.now() * 1000 - uf_start;\n' +
|
|
887
|
-
'if (!__self.__performance_monitor) {\n' +
|
|
888
|
-
'__self.__performance_monitor={};\n' +
|
|
889
|
-
'__self.__performance_monitor[key] = { called:1, totel_usec: el_time, min_usec: el_time, max_usec: el_time, type: type };\n' +
|
|
890
|
-
'} else if (!__self.__performance_monitor[key]) {\n' +
|
|
891
|
-
'__self.__performance_monitor[key] = { called:1, totel_usec: el_time, min_usec: el_time, max_usec: el_time, type: type };\n' +
|
|
892
|
-
'} else {\n' +
|
|
893
|
-
'__self.__performance_monitor[key].called++;\n' +
|
|
894
|
-
'__self.__performance_monitor[key].totel_usec+=el_time;\n' +
|
|
895
|
-
'if(__self.__performance_monitor[key].min_usec>el_time){__self.__performance_monitor[key].min_usec=el_time;}\n' +
|
|
896
|
-
'if(__self.__performance_monitor[key].max_usec<el_time){__self.__performance_monitor[key].max_usec=el_time;}\n' +
|
|
897
|
-
`}};})('${key}', 'user');` +
|
|
898
|
-
'try {\n'
|
|
899
|
-
performanceMonitorInjectAtEnd = '} finally { performanceMonitorEnd(); }\n'
|
|
915
|
+
const inject = this.genPerfMonitorInject(this.getPerfMonitorKey(name))
|
|
916
|
+
performanceMonitorInjectAtStart = inject[0]
|
|
917
|
+
performanceMonitorInjectAtEnd = inject[1]
|
|
900
918
|
}
|
|
901
919
|
let variableDeclarations = ''
|
|
902
920
|
const indent = ' '
|
|
@@ -1019,7 +1037,9 @@ export class NakoGen {
|
|
|
1019
1037
|
const tof = (this.usedAsyncFn) ? topOfFunctionAsync : topOfFunction
|
|
1020
1038
|
// 関数コード全体を構築
|
|
1021
1039
|
const lineInfo = ' ' + this.convLineno(node, true, 1) + '\n'
|
|
1022
|
-
|
|
1040
|
+
// パフォーマンスモニタのinjectは、PUSH STACKのtry/finallyの内側に入れる。
|
|
1041
|
+
// 外側に置くと __localvars の宣言をまたいでしまい ReferenceError になる (#2333)
|
|
1042
|
+
code = tof + pushStack + performanceMonitorInjectAtStart + variableDeclarations + lineInfo + code + popStack
|
|
1023
1043
|
code += endOfFunction
|
|
1024
1044
|
if (funcContext.isAnonymous && funcContext.usesClosure) {
|
|
1025
1045
|
const parentClosure = `(typeof __nako_closure === 'undefined' ? null : __nako_closure)`
|
|
@@ -1412,8 +1432,8 @@ export class NakoGen {
|
|
|
1412
1432
|
* @param {boolean} isExpression
|
|
1413
1433
|
*/
|
|
1414
1434
|
convPerformanceMonitor(node: AstBlocks, isExpression: boolean): string {
|
|
1415
|
-
const prev = { ...this.performanceMonitor }
|
|
1416
1435
|
if (!node.options) { return '' }
|
|
1436
|
+
const prev = { ...this.performanceMonitor }
|
|
1417
1437
|
if (node.options['ユーザ関数']) {
|
|
1418
1438
|
this.performanceMonitor.userFunction++
|
|
1419
1439
|
}
|
|
@@ -1430,6 +1450,63 @@ export class NakoGen {
|
|
|
1430
1450
|
}
|
|
1431
1451
|
}
|
|
1432
1452
|
|
|
1453
|
+
/**
|
|
1454
|
+
* パフォーマンスモニタの計測キーを決める。名前が無ければ無名関数用のIDを採番する。(#2333)
|
|
1455
|
+
* @param name 関数名
|
|
1456
|
+
* @param suffix キーに付ける接尾辞 ('_body' / '_sys' など)
|
|
1457
|
+
*/
|
|
1458
|
+
private getPerfMonitorKey (name: string, suffix = ''): string {
|
|
1459
|
+
if (name) { return `${name}${suffix}` }
|
|
1460
|
+
this.performanceMonitor.mumeiId++
|
|
1461
|
+
return `anous_${this.performanceMonitor.mumeiId}${suffix}`
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
/**
|
|
1465
|
+
* コードを、実行時間を計測する即時実行関数で包む。(#2333)
|
|
1466
|
+
* システム関数本体・システム関数の計測で使う。
|
|
1467
|
+
* @param body 計測対象。isExprなら式、そうでなければ文の並び
|
|
1468
|
+
* @param key 計測結果を記録するキー
|
|
1469
|
+
* @param type 計測の種別
|
|
1470
|
+
* @param opts isExpr:bodyが式か / isAsync:非同期か / startVar,timeVar:使用するJS変数名
|
|
1471
|
+
*/
|
|
1472
|
+
private wrapPerfMonitor (body: string, key: string, type: string,
|
|
1473
|
+
opts: { isExpr: boolean, isAsync: boolean, startVar: string, timeVar: string }): string {
|
|
1474
|
+
const funcDef = opts.isAsync ? 'async function' : 'function'
|
|
1475
|
+
// 式なら値を返す必要がある。文ならそのまま実行する。
|
|
1476
|
+
const inner = opts.isExpr ? `return ${body};\n` : `${body}\n`
|
|
1477
|
+
// 末尾に改行を置かないこと。行頭のセミコロンは cleanGeneratedCode で消えてしまい、
|
|
1478
|
+
// 直後の文が `(` で始まると関数呼び出しとして繋がってしまう (#2333)
|
|
1479
|
+
let code = `(${funcDef} (key, type) {\n` +
|
|
1480
|
+
`const ${opts.startVar} = performance.now() * 1000;\n` +
|
|
1481
|
+
'try {\n' +
|
|
1482
|
+
inner +
|
|
1483
|
+
'} finally {\n' +
|
|
1484
|
+
`const ${opts.timeVar} = performance.now() * 1000 - ${opts.startVar};\n` +
|
|
1485
|
+
genPerfMonitorUpdate(opts.timeVar) +
|
|
1486
|
+
`}})('${key}', '${type}')`
|
|
1487
|
+
// 非同期関数を包んだ場合、待たないと計測対象が完了しない (#2333)
|
|
1488
|
+
if (opts.isAsync) { code = `await ${code}` }
|
|
1489
|
+
// 文として包んだ場合は、ここで文を閉じる
|
|
1490
|
+
return opts.isExpr ? code : code + ';\n'
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
/**
|
|
1494
|
+
* ユーザ関数の実行時間を計測するために、関数の本体の前後へ挿入するコードを返す。(#2333)
|
|
1495
|
+
* @param key 計測結果を記録するキー
|
|
1496
|
+
* @returns [関数本体の直前に挿入するコード, 関数本体の直後に挿入するコード]
|
|
1497
|
+
*/
|
|
1498
|
+
private genPerfMonitorInject (key: string): [string, string] {
|
|
1499
|
+
const injectAtStart = 'const performanceMonitorEnd = (function (key, type) {\n' +
|
|
1500
|
+
'const uf_start = performance.now() * 1000;\n' +
|
|
1501
|
+
'return function () {\n' +
|
|
1502
|
+
'const el_time = performance.now() * 1000 - uf_start;\n' +
|
|
1503
|
+
genPerfMonitorUpdate('el_time') +
|
|
1504
|
+
`};})('${key}', 'user');` +
|
|
1505
|
+
'try {\n'
|
|
1506
|
+
const injectAtEnd = '} finally { performanceMonitorEnd(); }\n'
|
|
1507
|
+
return [injectAtStart, injectAtEnd]
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1433
1510
|
convWhile(node: AstWhile): string {
|
|
1434
1511
|
const exprAst = node.blocks[0]
|
|
1435
1512
|
const blockAst = node.blocks[1]
|
|
@@ -1534,18 +1611,14 @@ export class NakoGen {
|
|
|
1534
1611
|
}
|
|
1535
1612
|
|
|
1536
1613
|
/**
|
|
1537
|
-
*
|
|
1538
|
-
* @
|
|
1539
|
-
* @param {boolean} isExpression
|
|
1540
|
-
* @returns string コード
|
|
1614
|
+
* どの関数を呼び出すのか関数を特定する (convCallFunc用)
|
|
1615
|
+
* @returns 変数の検索結果 res と、関数の定義 func
|
|
1541
1616
|
*/
|
|
1542
|
-
|
|
1543
|
-
const funcName = NakoGen.getFuncName(node.name)
|
|
1617
|
+
private resolveCallTarget (funcName: string, node: AstCallFunc): { res: FindVarResult, func: any } {
|
|
1544
1618
|
const res = this.findVar(funcName)
|
|
1545
1619
|
if (res === null) {
|
|
1546
1620
|
throw NakoSyntaxError.fromNode(`関数『${funcName}』が見当たりません。有効プラグイン=[` + this.getPluginList().join(', ') + ']', node)
|
|
1547
1621
|
}
|
|
1548
|
-
// どの関数を呼び出すのか関数を特定する
|
|
1549
1622
|
let func
|
|
1550
1623
|
if (res.i === 0) { // plugin function
|
|
1551
1624
|
func = this.__self.getFunc(funcName)
|
|
@@ -1558,6 +1631,155 @@ export class NakoGen {
|
|
|
1558
1631
|
// 無名関数の可能性
|
|
1559
1632
|
if (func === undefined) { func = { return_none: false, asyncFn: !!node.asyncFn } }
|
|
1560
1633
|
}
|
|
1634
|
+
return { res, func }
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
/**
|
|
1638
|
+
* 関数内からpureでないプラグイン関数を呼び出すとき、呼び出しの前後で
|
|
1639
|
+
* ローカル変数を __self.__locals と同期するコードを生成する。
|
|
1640
|
+
* @returns 呼び出し前に実行するコード begin と、呼び出し後に実行するコード end
|
|
1641
|
+
*/
|
|
1642
|
+
private genLocalVarsSyncCode (): { begin: string, end: string } {
|
|
1643
|
+
let begin = ''
|
|
1644
|
+
let end = ''
|
|
1645
|
+
// 展開されたローカル変数の列挙
|
|
1646
|
+
const localVars = []
|
|
1647
|
+
for (const name of Array.from(this.varsSet.names.values())) {
|
|
1648
|
+
if (NakoGen.isValidIdentifier(name)) {
|
|
1649
|
+
localVars.push({ str: JSON.stringify(name), js: this.varname_get(name) })
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
// --- 実行前 ---
|
|
1654
|
+
// 全ての展開されていないローカル変数を __self.__locals にコピーする
|
|
1655
|
+
begin += '__self.__locals = __vars;\n'
|
|
1656
|
+
// 全ての展開されたローカル変数を __self.__locals に保存する
|
|
1657
|
+
if (localVars.length > 0) {
|
|
1658
|
+
begin += '/* 全ての展開されたローカル変数を __self.__locals に保存 */\n'
|
|
1659
|
+
for (const v of localVars) {
|
|
1660
|
+
begin += `__self.__locals.set(${v.str}, ${v.js});\n`
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
// --- 実行後 ---
|
|
1665
|
+
// 全ての展開されたローカル変数を __self.__locals から受け取る
|
|
1666
|
+
// 「それ」は関数の実行結果を受け取るために使うためスキップ。
|
|
1667
|
+
if (localVars.length > 0) {
|
|
1668
|
+
end += '/* 全ての展開されたローカル変数を __self.__locals から受け取る */\n'
|
|
1669
|
+
for (const v of localVars) {
|
|
1670
|
+
if (v.js !== 'それ') {
|
|
1671
|
+
end += `__self.__varslist[2].set(${v.str}, __self.__locals.get(${v.str}));\n`
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
return { begin, end }
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
/**
|
|
1679
|
+
* 引数のリストを連結してJSの実引数のコードにする。
|
|
1680
|
+
* 必要に応じて、引数のundefinedチェックのコードを挟む。
|
|
1681
|
+
*/
|
|
1682
|
+
private genCallArgsCode (funcName: string, res: FindVarResult, args: string[], node: AstCallFunc): string {
|
|
1683
|
+
if ((!this.warnUndefinedCallingUserFunc && res.i !== 0) || (!this.warnUndefinedCallingSystemFunc && res.i === 0)) {
|
|
1684
|
+
return args.join(',')
|
|
1685
|
+
}
|
|
1686
|
+
// 引数チェックの例外 #1260
|
|
1687
|
+
const noCheckFuncs: {[key: string]: boolean} = { 'TYPEOF': true, '変数型確認': true }
|
|
1688
|
+
const argsA: string[] = []
|
|
1689
|
+
args.forEach((arg: string) => {
|
|
1690
|
+
if (arg === '__self' || noCheckFuncs[funcName] === true) { // #1260
|
|
1691
|
+
argsA.push(`${arg}`)
|
|
1692
|
+
} else {
|
|
1693
|
+
// 引数のundefinedチェックのコードを入れる
|
|
1694
|
+
const msg = (res.i === 0) ? '命令『$0』の引数にundefinedを渡しています。' : 'ユーザ命令『$0』の引数にundefinedを渡しています。'
|
|
1695
|
+
const poolIndex = this.addConstPool(msg, [funcName], node.file, node.line)
|
|
1696
|
+
// argが空になる対策 #1315
|
|
1697
|
+
const argStr = (arg === '') ? '""' : arg
|
|
1698
|
+
argsA.push(`(__self.chk(${argStr}, ${poolIndex}))`)
|
|
1699
|
+
}
|
|
1700
|
+
})
|
|
1701
|
+
return argsA.join(', ')
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* 関数の戻り値を変数「それ」に代入するためのラッパを返す。
|
|
1706
|
+
* @returns [前置するコード, 後置するコード]
|
|
1707
|
+
*/
|
|
1708
|
+
private getSoreWrap (): [string, string] {
|
|
1709
|
+
if (this.speedMode.invalidSore !== 0) { return ['', ''] }
|
|
1710
|
+
return ['__self.__setSore(', ')']
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
/** 戻り値のない関数呼び出しのコードを組み立てる */
|
|
1714
|
+
private genVoidCallCode (node: AstCallFunc, parts: CallCodeParts): string {
|
|
1715
|
+
const { funcCall, funcBegin, funcEnd } = parts
|
|
1716
|
+
let code: string
|
|
1717
|
+
if (funcEnd === '') {
|
|
1718
|
+
code = `/*VOID関数呼出*/${funcBegin}${funcCall}\n`
|
|
1719
|
+
} else {
|
|
1720
|
+
code = `/*VOID関数呼出(前後処理付)*/${funcBegin}try {\n${indentLines(funcCall, 1)};\n} finally {\n${indentLines(funcEnd, 1)}}\n`
|
|
1721
|
+
}
|
|
1722
|
+
// パフォーマンスモニタ:システム関数。ここでのcodeは式ではなく文なので、文として包む (#2333)
|
|
1723
|
+
if (parts.sysPerfKey) {
|
|
1724
|
+
code = this.wrapPerfMonitor(code, parts.sysPerfKey, 'system',
|
|
1725
|
+
{ isExpr: false, isAsync: parts.isAsync, startVar: 'sf_start', timeVar: 'sl_time' })
|
|
1726
|
+
}
|
|
1727
|
+
// 行番号を追加
|
|
1728
|
+
return this.convLineno(node, false) + code
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
/** 戻り値のある関数呼び出しのコードを組み立てる */
|
|
1732
|
+
private genValueCallCode (node: AstCallFunc, isExpression: boolean, parts: CallCodeParts): string {
|
|
1733
|
+
const { funcDef, funcCall, funcBegin, funcEnd, isAsync } = parts
|
|
1734
|
+
// 関数の戻り値を「それ」に記録する
|
|
1735
|
+
const [sorePrefix, sorePostfix] = this.getSoreWrap()
|
|
1736
|
+
let code: string
|
|
1737
|
+
if (funcBegin === '' && funcEnd === '') {
|
|
1738
|
+
code = `${sorePrefix}${funcCall}${sorePostfix}`
|
|
1739
|
+
} else if (funcEnd === '') {
|
|
1740
|
+
const funcBody = `${sorePrefix}${funcCall}${sorePostfix}`
|
|
1741
|
+
const funcObj = `${funcDef}(){ return ${funcBody} }`
|
|
1742
|
+
const funcCallThis = `(${funcObj}).call(this)`
|
|
1743
|
+
code = `/* funcCallThis1 */${funcCallThis}`
|
|
1744
|
+
} else { // つまり、pure=falseの場合
|
|
1745
|
+
const varI = `$nako_i${this.loopId}`
|
|
1746
|
+
this.loopId++
|
|
1747
|
+
code = `/* funcCallThis2 */(${funcDef}(){\n` +
|
|
1748
|
+
indentLines(funcBegin, 1) + '\n' +
|
|
1749
|
+
indentLines('try {', 1) + '\n' +
|
|
1750
|
+
indentLines(`let ${varI} = ${funcCall};`, 2) + '\n' +
|
|
1751
|
+
indentLines(`return ${varI};`, 2) + '\n' +
|
|
1752
|
+
indentLines('} finally {', 2) + '\n' +
|
|
1753
|
+
indentLines(funcEnd, 1) + '\n' +
|
|
1754
|
+
indentLines('}', 1) + '\n' +
|
|
1755
|
+
'}).call(this)'
|
|
1756
|
+
if (isAsync) {
|
|
1757
|
+
code = `await (${code})`
|
|
1758
|
+
}
|
|
1759
|
+
code = `${sorePrefix}${code}${sorePostfix}`
|
|
1760
|
+
}
|
|
1761
|
+
// パフォーマンスモニタ:システム関数。ここでのcodeは式なので、値を返す形で包む (#2333)
|
|
1762
|
+
if (parts.sysPerfKey) {
|
|
1763
|
+
code = this.wrapPerfMonitor(code, parts.sysPerfKey, 'system',
|
|
1764
|
+
{ isExpr: true, isAsync, startVar: 'sf_start', timeVar: 'sl_time' })
|
|
1765
|
+
}
|
|
1766
|
+
// ...して
|
|
1767
|
+
if (node.josi === 'して' || (node.josi === '' && !isExpression)) {
|
|
1768
|
+
code = this.convLineno(node, false) + code
|
|
1769
|
+
code += ';\n'
|
|
1770
|
+
}
|
|
1771
|
+
return code
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
/**
|
|
1775
|
+
* 関数の呼び出し
|
|
1776
|
+
* @param {Ast} node
|
|
1777
|
+
* @param {boolean} isExpression
|
|
1778
|
+
* @returns string コード
|
|
1779
|
+
*/
|
|
1780
|
+
convCallFunc(node: AstCallFunc, isExpression: boolean): string {
|
|
1781
|
+
const funcName = NakoGen.getFuncName(node.name)
|
|
1782
|
+
const { res, func } = this.resolveCallTarget(funcName, node)
|
|
1561
1783
|
// 関数の参照渡しか?
|
|
1562
1784
|
if (node.type === 'func_pointer') {
|
|
1563
1785
|
return res.js
|
|
@@ -1589,73 +1811,15 @@ export class NakoGen {
|
|
|
1589
1811
|
// 関数内 (__varslist.length > 3) からプラグイン関数 (res.i === 0) を呼び出すとき、 そのプラグイン関数がpureでなければ
|
|
1590
1812
|
// 呼び出しの直前に全てのローカル変数をthis.__localsに入れる。
|
|
1591
1813
|
if (res.i === 0 && this.varslistSet.length > 3 && func.pure !== true && this.speedMode.forcePure === 0) { // undefinedはfalseとみなす
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
if (NakoGen.isValidIdentifier(name)) {
|
|
1596
|
-
localVars.push({ str: JSON.stringify(name), js: this.varname_get(name) })
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
// --- 実行前 ---
|
|
1601
|
-
// 全ての展開されていないローカル変数を __self.__locals にコピーする
|
|
1602
|
-
funcBegin += '__self.__locals = __vars;\n'
|
|
1603
|
-
// 全ての展開されたローカル変数を __self.__locals に保存する
|
|
1604
|
-
if (localVars.length > 0) {
|
|
1605
|
-
funcBegin += '/* 全ての展開されたローカル変数を __self.__locals に保存 */\n'
|
|
1606
|
-
for (const v of localVars) {
|
|
1607
|
-
funcBegin += `__self.__locals.set(${v.str}, ${v.js});\n`
|
|
1608
|
-
}
|
|
1609
|
-
}
|
|
1610
|
-
|
|
1611
|
-
// --- 実行後 ---
|
|
1612
|
-
// 全ての展開されたローカル変数を __self.__locals から受け取る
|
|
1613
|
-
// 「それ」は関数の実行結果を受け取るために使うためスキップ。
|
|
1614
|
-
if (localVars.length > 0) {
|
|
1615
|
-
funcEnd += '/* 全ての展開されたローカル変数を __self.__locals から受け取る */\n'
|
|
1616
|
-
for (const v of localVars) {
|
|
1617
|
-
if (v.js !== 'それ') {
|
|
1618
|
-
funcEnd += `__self.__varslist[2].set(${v.str}, __self.__locals[${v.str}]);\n`
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1814
|
+
const sync = this.genLocalVarsSyncCode()
|
|
1815
|
+
funcBegin += sync.begin
|
|
1816
|
+
funcEnd += sync.end
|
|
1622
1817
|
}
|
|
1623
1818
|
// 変数「それ」が補完されていることをヒントとして出力
|
|
1624
1819
|
if (argsOpts.sore) { funcBegin += '/*[sore]*/' }
|
|
1625
1820
|
|
|
1626
|
-
const indent = (text: string, n: number) => {
|
|
1627
|
-
let result = ''
|
|
1628
|
-
for (const line of text.split('\n')) {
|
|
1629
|
-
if (line !== '') {
|
|
1630
|
-
result += ' '.repeat(n) + line + '\n'
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
return result
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
// 引数チェックの例外 #1260
|
|
1637
|
-
const noCheckFuncs: {[key: string]: boolean} = { 'TYPEOF': true, '変数型確認': true }
|
|
1638
1821
|
// 関数呼び出しコードの構築
|
|
1639
|
-
|
|
1640
|
-
if ((!this.warnUndefinedCallingUserFunc && res.i !== 0) || (!this.warnUndefinedCallingSystemFunc && res.i === 0)) {
|
|
1641
|
-
argsCode = args.join(',')
|
|
1642
|
-
} else {
|
|
1643
|
-
const argsA: string[] = []
|
|
1644
|
-
args.forEach((arg: string) => {
|
|
1645
|
-
if (arg === '__self' || noCheckFuncs[funcName] === true) { // #1260
|
|
1646
|
-
argsA.push(`${arg}`)
|
|
1647
|
-
} else {
|
|
1648
|
-
// 引数のundefinedチェックのコードを入れる
|
|
1649
|
-
const msg = (res.i === 0) ? '命令『$0』の引数にundefinedを渡しています。' : 'ユーザ命令『$0』の引数にundefinedを渡しています。'
|
|
1650
|
-
const poolIndex = this.addConstPool(msg, [funcName], node.file, node.line)
|
|
1651
|
-
// argが空になる対策 #1315
|
|
1652
|
-
const argStr = (arg === '') ? '""' : arg
|
|
1653
|
-
argsA.push(`(__self.chk(${argStr}, ${poolIndex}))`)
|
|
1654
|
-
}
|
|
1655
|
-
})
|
|
1656
|
-
argsCode = argsA.join(', ')
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1822
|
+
const argsCode = this.genCallArgsCode(funcName, res, args, node)
|
|
1659
1823
|
let funcCall = `${res.js}(${argsCode})`
|
|
1660
1824
|
if (func.asyncFn) {
|
|
1661
1825
|
funcDef = `async ${funcDef}`
|
|
@@ -1668,111 +1832,20 @@ export class NakoGen {
|
|
|
1668
1832
|
funcBegin += `const __local_async${varI} = __self.__vars;\n`
|
|
1669
1833
|
funcEnd += `__self.__vars = __local_async${varI};\n`
|
|
1670
1834
|
}
|
|
1835
|
+
// パフォーマンスモニタ:システム関数本体 (呼び出しコードを除く)
|
|
1671
1836
|
if (res.i === 0 && this.performanceMonitor.systemFunctionBody !== 0) {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
if (typeof this.performanceMonitor.mumeiId === 'undefined') {
|
|
1675
|
-
this.performanceMonitor.mumeiId = 0
|
|
1676
|
-
}
|
|
1677
|
-
this.performanceMonitor.mumeiId++
|
|
1678
|
-
key = `anous_${this.performanceMonitor.mumeiId}`
|
|
1679
|
-
}
|
|
1680
|
-
funcCall = `(${funcDef} (key, type) {\n` +
|
|
1681
|
-
'const sbf_start = performance.now() * 1000;\n' +
|
|
1682
|
-
'try {\n' +
|
|
1683
|
-
'return ' + funcCall + ';\n' +
|
|
1684
|
-
'} finally {\n' +
|
|
1685
|
-
'const sbl_time = performance.now() * 1000 - sbf_start;\n' +
|
|
1686
|
-
'if (!__self.__performance_monitor) {\n' +
|
|
1687
|
-
'__self.__performance_monitor={};\n' +
|
|
1688
|
-
'__self.__performance_monitor[key] = { called:1, totel_usec: sbl_time, min_usec: sbl_time, max_usec: sbl_time, type: type };\n' +
|
|
1689
|
-
'} else if (!__self.__performance_monitor[key]) {\n' +
|
|
1690
|
-
'__self.__performance_monitor[key] = { called:1, totel_usec: sbl_time, min_usec: sbl_time, max_usec: sbl_time, type: type };\n' +
|
|
1691
|
-
'} else {\n' +
|
|
1692
|
-
'__self.__performance_monitor[key].called++;\n' +
|
|
1693
|
-
'__self.__performance_monitor[key].totel_usec+=sbl_time;\n' +
|
|
1694
|
-
'if(__self.__performance_monitor[key].min_usec>sbl_time){__self.__performance_monitor[key].min_usec=sbl_time;}\n' +
|
|
1695
|
-
'if(__self.__performance_monitor[key].max_usec<sbl_time){__self.__performance_monitor[key].max_usec=sbl_time;}\n' +
|
|
1696
|
-
`}}})('${funcName}_body', 'sysbody')\n`
|
|
1697
|
-
}
|
|
1698
|
-
|
|
1699
|
-
let code = ''
|
|
1700
|
-
if (func.return_none) {
|
|
1701
|
-
// ------------------------------------
|
|
1702
|
-
// 戻り値のない関数の場合
|
|
1703
|
-
// ------------------------------------
|
|
1704
|
-
if (funcEnd === '') {
|
|
1705
|
-
code = `/*VOID関数呼出*/${funcBegin}${funcCall}\n`
|
|
1706
|
-
} else {
|
|
1707
|
-
code = `/*VOID関数呼出(前後処理付)*/${funcBegin}try {\n${indent(funcCall, 1)};\n} finally {\n${indent(funcEnd, 1)}}\n`
|
|
1708
|
-
}
|
|
1709
|
-
// 行番号を追加
|
|
1710
|
-
code = this.convLineno(node, false) + code
|
|
1711
|
-
} else {
|
|
1712
|
-
// ------------------------------------
|
|
1713
|
-
// 戻り値のある関数の場合
|
|
1714
|
-
// ------------------------------------
|
|
1715
|
-
let sorePrefex = ''
|
|
1716
|
-
let sorePostfix = ''
|
|
1717
|
-
if (this.speedMode.invalidSore === 0) {
|
|
1718
|
-
// 関数の戻り値を記録
|
|
1719
|
-
sorePrefex = '__self.__setSore('
|
|
1720
|
-
sorePostfix = ')'
|
|
1721
|
-
}
|
|
1722
|
-
if (funcBegin === '' && funcEnd === '') {
|
|
1723
|
-
code = `${sorePrefex}${funcCall}${sorePostfix}`
|
|
1724
|
-
} else {
|
|
1725
|
-
if (funcEnd === '') {
|
|
1726
|
-
const funcBody = `${sorePrefex}${funcCall}${sorePostfix}`
|
|
1727
|
-
const funcObj = `${funcDef}(){ return ${funcBody} }`
|
|
1728
|
-
const funcCallThis = `(${funcObj}).call(this)`
|
|
1729
|
-
code = `/* funcCallThis1 */${funcCallThis}`
|
|
1730
|
-
} else { // つまり、pure=falseの場合
|
|
1731
|
-
const varI = `$nako_i${this.loopId}`
|
|
1732
|
-
this.loopId++
|
|
1733
|
-
code = `/* funcCallThis2 */(${funcDef}(){\n` +
|
|
1734
|
-
indent(funcBegin, 1) + '\n' +
|
|
1735
|
-
indent('try {', 1) + '\n' +
|
|
1736
|
-
indent(`let ${varI} = ${funcCall};`, 2) + '\n' +
|
|
1737
|
-
indent(`return ${varI};`, 2) + '\n' +
|
|
1738
|
-
indent('} finally {', 2) + '\n' +
|
|
1739
|
-
indent(funcEnd, 1) + '\n' +
|
|
1740
|
-
indent('}', 1) + '\n' +
|
|
1741
|
-
'}).call(this)'
|
|
1742
|
-
if (func.asyncFn) {
|
|
1743
|
-
code = `await (${code})`
|
|
1744
|
-
}
|
|
1745
|
-
code = `${sorePrefex}${code}${sorePostfix}`
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
// ...して
|
|
1749
|
-
if (node.josi === 'して' || (node.josi === '' && !isExpression)) {
|
|
1750
|
-
code = this.convLineno(node, false) + code
|
|
1751
|
-
code += ';\n'
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
|
-
if (res.i === 0 && this.performanceMonitor.systemFunction !== 0) {
|
|
1756
|
-
code = '(function (key, type) {\n' +
|
|
1757
|
-
'const sf_start = performance.now() * 1000;\n' +
|
|
1758
|
-
'try {\n' +
|
|
1759
|
-
'return ' + code + ';\n' +
|
|
1760
|
-
'} finally {\n' +
|
|
1761
|
-
'const sl_time = performance.now() * 1000 - sf_start;\n' +
|
|
1762
|
-
'if (!__self.__performance_monitor) {\n' +
|
|
1763
|
-
'__self.__performance_monitor={};\n' +
|
|
1764
|
-
'__self.__performance_monitor[key] = { called:1, totel_usec: sl_time, min_usec: sl_time, max_usec: sl_time, type: type };\n' +
|
|
1765
|
-
'} else if (!__self.__performance_monitor[key]) {\n' +
|
|
1766
|
-
'__self.__performance_monitor[key] = { called:1, totel_usec: sl_time, min_usec: sl_time, max_usec: sl_time, type: type };\n' +
|
|
1767
|
-
'} else {\n' +
|
|
1768
|
-
'__self.__performance_monitor[key].called++;\n' +
|
|
1769
|
-
'__self.__performance_monitor[key].totel_usec+=sl_time;\n' +
|
|
1770
|
-
'if(__self.__performance_monitor[key].min_usec>sl_time){__self.__performance_monitor[key].min_usec=sl_time;}\n' +
|
|
1771
|
-
'if(__self.__performance_monitor[key].max_usec<sl_time){__self.__performance_monitor[key].max_usec=sl_time;}\n' +
|
|
1772
|
-
`}}})('${funcName}_sys', 'system')\n`
|
|
1837
|
+
funcCall = this.wrapPerfMonitor(funcCall, this.getPerfMonitorKey(funcName, '_body'), 'sysbody',
|
|
1838
|
+
{ isExpr: true, isAsync: !!func.asyncFn, startVar: 'sbf_start', timeVar: 'sbl_time' })
|
|
1773
1839
|
}
|
|
1840
|
+
// パフォーマンスモニタ:システム関数 (呼び出しコードを含む) はコードの組み立て中に適用する
|
|
1841
|
+
const sysPerfKey = (res.i === 0 && this.performanceMonitor.systemFunction !== 0)
|
|
1842
|
+
? this.getPerfMonitorKey(funcName, '_sys')
|
|
1843
|
+
: null
|
|
1774
1844
|
|
|
1775
|
-
|
|
1845
|
+
const parts: CallCodeParts = { funcDef, funcCall, funcBegin, funcEnd, isAsync: !!func.asyncFn, sysPerfKey }
|
|
1846
|
+
return (func.return_none)
|
|
1847
|
+
? this.genVoidCallCode(node, parts)
|
|
1848
|
+
: this.genValueCallCode(node, isExpression, parts)
|
|
1776
1849
|
}
|
|
1777
1850
|
|
|
1778
1851
|
convCallValue(node: AstBlocks, isExpression: boolean): string {
|
|
@@ -1783,9 +1856,8 @@ export class NakoGen {
|
|
|
1783
1856
|
if (isExpression) {
|
|
1784
1857
|
return funcCall
|
|
1785
1858
|
}
|
|
1786
|
-
const
|
|
1787
|
-
|
|
1788
|
-
return this.convLineno(node, false) + `${sorePrefex}${funcCall}${sorePostfix};\n`
|
|
1859
|
+
const [sorePrefix, sorePostfix] = this.getSoreWrap()
|
|
1860
|
+
return this.convLineno(node, false) + `${sorePrefix}${funcCall}${sorePostfix};\n`
|
|
1789
1861
|
}
|
|
1790
1862
|
|
|
1791
1863
|
convRenbun(node: AstOperator): string {
|
|
@@ -2337,8 +2409,25 @@ ${syncMain}(__self)
|
|
|
2337
2409
|
// デバッグメッセージ
|
|
2338
2410
|
let codeImportFiles = ''
|
|
2339
2411
|
const importNames = []
|
|
2412
|
+
// プラグインとして登録せず、コピーだけが必要なファイル
|
|
2413
|
+
// (plugin_system_*.mjs は plugin_system.mjs 側でマージ済みのため二重登録しない) #2351
|
|
2414
|
+
const noRegisterFiles = [
|
|
2415
|
+
'nako_errors.mjs',
|
|
2416
|
+
'plugin_system_debug.mjs',
|
|
2417
|
+
'plugin_system_math.mjs',
|
|
2418
|
+
'plugin_system_string.mjs',
|
|
2419
|
+
'plugin_system_array.mjs',
|
|
2420
|
+
'plugin_system_datetime.mjs',
|
|
2421
|
+
'plugin_system_url.mjs',
|
|
2422
|
+
'plugin_system_types.mjs',
|
|
2423
|
+
'plugin_system_json.mjs',
|
|
2424
|
+
'plugin_system_regexp.mjs',
|
|
2425
|
+
'plugin_system_dict.mjs',
|
|
2426
|
+
'plugin_system_stdio.mjs',
|
|
2427
|
+
'plugin_system_timer.mjs'
|
|
2428
|
+
]
|
|
2340
2429
|
for (const f of opt.importFiles) {
|
|
2341
|
-
if (f
|
|
2430
|
+
if (noRegisterFiles.includes(f)) { continue }
|
|
2342
2431
|
const ff = 'nako3runtime_' + f.replace(/\.(js|mjs)$/, '').replace(/[^a-zA-Z0-9_]/g, '_')
|
|
2343
2432
|
importNames.push(ff)
|
|
2344
2433
|
codeImportFiles += `import ${ff} from './nako3runtime/${f}'\n`
|
|
@@ -221,7 +221,7 @@ const INDENT_MODE_KEYWORDS = ['!インデント構文', '!ここまでだるい'
|
|
|
221
221
|
/** インデント構文 --- インデントを見て"ここまで"を自動挿入 (#596) */
|
|
222
222
|
export function convertIndentSyntax(tokens: Token[]): Token[] {
|
|
223
223
|
// インデント構文の変換が必要か?
|
|
224
|
-
if (!
|
|
224
|
+
if (!useIndentSyntax(tokens)) { return tokens }
|
|
225
225
|
// 『ここまで』があったらエラーを出す
|
|
226
226
|
for (const t of tokens) {
|
|
227
227
|
if (t.type === 'ここまで') {
|
|
@@ -321,7 +321,7 @@ export function convertIndentSyntax(tokens: Token[]): Token[] {
|
|
|
321
321
|
return result
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
function
|
|
324
|
+
function useIndentSyntax(tokens: Token[]) : boolean {
|
|
325
325
|
// インデント構文が必要かチェック (最初の100個をチェック)
|
|
326
326
|
for (let i = 0; i < tokens.length; i++) {
|
|
327
327
|
if (i > 100) { break }
|
|
@@ -42,7 +42,7 @@ export const rules: NakoLexRule[] = [
|
|
|
42
42
|
{ name: 'eol', pattern: /^\n/ },
|
|
43
43
|
{ name: 'eol', pattern: /^;/ },
|
|
44
44
|
// eslint-disable-next-line no-irregular-whitespace
|
|
45
|
-
{ name: 'space', pattern: /^(\x20|\
|
|
45
|
+
{ name: 'space', pattern: /^(\x20|\t| |・|⎿ |└||)+/ }, // #877,#1015
|
|
46
46
|
{ name: 'comma', pattern: /^,/ },
|
|
47
47
|
{ name: 'line_comment', pattern: /^#[^\n]*/ },
|
|
48
48
|
{ name: 'line_comment', pattern: /^\/\/[^\n]*/ },
|