nadesiko3 3.2.27

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 (283) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +107 -0
  3. package/bin/cnako3 +10 -0
  4. package/bin/cnako3.bat +11 -0
  5. package/bin/nako3server.bat +6 -0
  6. package/demo/ace_editor.html +90 -0
  7. package/demo/ace_editor_tabs.html +162 -0
  8. package/demo/basic.html +71 -0
  9. package/demo/browsers.html +128 -0
  10. package/demo/css/basic.css +3 -0
  11. package/demo/css/common.css +157 -0
  12. package/demo/css/editor.css +8 -0
  13. package/demo/css/flow.css +3 -0
  14. package/demo/css/index.css +3 -0
  15. package/demo/extlib/ace@1.4.12/ace.js +17 -0
  16. package/demo/extlib/ace@1.4.12/ext-code_lens.min.js +1 -0
  17. package/demo/extlib/ace@1.4.12/ext-language_tools.min.js +1 -0
  18. package/demo/extlib/ace@1.4.12/ext-options.min.js +1 -0
  19. package/demo/extlib/ace@1.4.12/ext-settings_menu.js +8 -0
  20. package/demo/extlib/ace@1.4.12/keybinding-vscode.js +8 -0
  21. package/demo/extlib/ace@1.4.12/theme-monokai.js +8 -0
  22. package/demo/extlib/ace@1.4.12/theme-xcode.js +8 -0
  23. package/demo/extlib/chart.js@3.2.1/chart.min.js +13 -0
  24. package/demo/extlib/pure-min.css +11 -0
  25. package/demo/flow.html +97 -0
  26. package/demo/graph.html +53 -0
  27. package/demo/image/nako.png +0 -0
  28. package/demo/image/nakopad-icon256.png +0 -0
  29. package/demo/image/turtle.fla +0 -0
  30. package/demo/image/turtle.png +0 -0
  31. package/demo/index.html +134 -0
  32. package/demo/js/common.js +17 -0
  33. package/demo/js/turtle3d_test.js +44 -0
  34. package/demo/js/turtle_test.js +44 -0
  35. package/demo/runscript.html +47 -0
  36. package/demo/runscript2.html +33 -0
  37. package/demo/turtle.html +58 -0
  38. package/demo/turtle2.html +141 -0
  39. package/demo/turtle3.html +278 -0
  40. package/demo/turtle3d.html +58 -0
  41. package/demo/turtle3d2.html +107 -0
  42. package/demo/version.html +24 -0
  43. package/doc/SETUP.md +172 -0
  44. package/doc/about.md +34 -0
  45. package/doc/browsers.md +60 -0
  46. package/doc/docgen.md +21 -0
  47. package/doc/editor.md +44 -0
  48. package/doc/files.md +37 -0
  49. package/doc/plugins.md +195 -0
  50. package/doc/release.md +78 -0
  51. package/doc/win32.md +57 -0
  52. package/package.json +196 -0
  53. package/release/_hash.txt +65 -0
  54. package/release/_script-tags.txt +13 -0
  55. package/release/command.json +1 -0
  56. package/release/command.json.js +1 -0
  57. package/release/command_cnako3.json +1 -0
  58. package/release/command_list.json +1 -0
  59. package/release/editor.js +2 -0
  60. package/release/editor.js.LICENSE.txt +32 -0
  61. package/release/josi.json +48 -0
  62. package/release/nako_gen_async.js +1 -0
  63. package/release/nako_gen_async.js.LICENSE.txt +595 -0
  64. package/release/plugin_caniuse.js +1 -0
  65. package/release/plugin_caniuse.js.LICENSE.txt +411 -0
  66. package/release/plugin_csv.js +1 -0
  67. package/release/plugin_csv.js.LICENSE.txt +367 -0
  68. package/release/plugin_datetime.js +1 -0
  69. package/release/plugin_datetime.js.LICENSE.txt +471 -0
  70. package/release/plugin_kansuji.js +1 -0
  71. package/release/plugin_kansuji.js.LICENSE.txt +491 -0
  72. package/release/plugin_markup.js +1 -0
  73. package/release/plugin_markup.js.LICENSE.txt +363 -0
  74. package/release/plugin_turtle.js +1 -0
  75. package/release/plugin_turtle.js.LICENSE.txt +435 -0
  76. package/release/plugin_webworker.js +1 -0
  77. package/release/plugin_webworker.js.LICENSE.txt +491 -0
  78. package/release/version.js +2 -0
  79. package/release/version.js.LICENSE.txt +32 -0
  80. package/release/wnako3.js +2 -0
  81. package/release/wnako3.js.LICENSE.txt +1 -0
  82. package/release/wnako3webworker.js +1 -0
  83. package/release/wnako3webworker.js.LICENSE.txt +847 -0
  84. package/release/yoyakugo.json +30 -0
  85. package/src/browsers.md +60 -0
  86. package/src/cnako3.js +466 -0
  87. package/src/commander_ja.js +154 -0
  88. package/src/enako3.js +69 -0
  89. package/src/era.json +22 -0
  90. package/src/index.js +5 -0
  91. package/src/nako3.js +836 -0
  92. package/src/nako3_assert.js +37 -0
  93. package/src/nako3editorfix.sfd +106 -0
  94. package/src/nako3editorfix.woff +0 -0
  95. package/src/nako3server.js +51 -0
  96. package/src/nako_colors.js +86 -0
  97. package/src/nako_errors.js +176 -0
  98. package/src/nako_gen.js +1459 -0
  99. package/src/nako_gen_async.js +1622 -0
  100. package/src/nako_global.js +113 -0
  101. package/src/nako_indent.js +480 -0
  102. package/src/nako_josi_list.js +46 -0
  103. package/src/nako_lex_rules.js +259 -0
  104. package/src/nako_lexer.js +576 -0
  105. package/src/nako_logger.js +138 -0
  106. package/src/nako_parser3.js +1768 -0
  107. package/src/nako_parser_base.js +265 -0
  108. package/src/nako_parser_const.js +37 -0
  109. package/src/nako_prepare.js +293 -0
  110. package/src/nako_reserved_words.js +35 -0
  111. package/src/nako_source_mapping.js +251 -0
  112. package/src/nako_test.js +37 -0
  113. package/src/nako_version.js +8 -0
  114. package/src/plugin_browser.js +191 -0
  115. package/src/plugin_browser_ajax.js +352 -0
  116. package/src/plugin_browser_audio.js +109 -0
  117. package/src/plugin_browser_canvas.js +462 -0
  118. package/src/plugin_browser_chart.js +296 -0
  119. package/src/plugin_browser_color.js +49 -0
  120. package/src/plugin_browser_crypto.js +26 -0
  121. package/src/plugin_browser_dialog.js +53 -0
  122. package/src/plugin_browser_dom_basic.js +322 -0
  123. package/src/plugin_browser_dom_event.js +193 -0
  124. package/src/plugin_browser_dom_parts.js +163 -0
  125. package/src/plugin_browser_geolocation.js +51 -0
  126. package/src/plugin_browser_hotkey.js +25 -0
  127. package/src/plugin_browser_html.js +59 -0
  128. package/src/plugin_browser_in_worker.js +44 -0
  129. package/src/plugin_browser_location.js +21 -0
  130. package/src/plugin_browser_speech.js +111 -0
  131. package/src/plugin_browser_storage.js +121 -0
  132. package/src/plugin_browser_system.js +12 -0
  133. package/src/plugin_browser_websocket.js +73 -0
  134. package/src/plugin_caniuse.js +24 -0
  135. package/src/plugin_csv.js +57 -0
  136. package/src/plugin_datetime.js +414 -0
  137. package/src/plugin_express.js +212 -0
  138. package/src/plugin_kansuji.js +224 -0
  139. package/src/plugin_keigo.js +55 -0
  140. package/src/plugin_markup.js +32 -0
  141. package/src/plugin_math.js +319 -0
  142. package/src/plugin_node.js +1018 -0
  143. package/src/plugin_promise.js +94 -0
  144. package/src/plugin_system.js +2109 -0
  145. package/src/plugin_test.js +38 -0
  146. package/src/plugin_turtle.js +646 -0
  147. package/src/plugin_webworker.js +334 -0
  148. package/src/plugin_weykturtle3d.js +1216 -0
  149. package/src/plugin_worker.js +92 -0
  150. package/src/repl.nako3 +63 -0
  151. package/src/turtle-elephant.png +0 -0
  152. package/src/turtle-panda.png +0 -0
  153. package/src/turtle64.png +0 -0
  154. package/src/wnako3.js +162 -0
  155. package/src/wnako3_editor.css +215 -0
  156. package/src/wnako3_editor.js +1645 -0
  157. package/src/wnako3_editor_marker_red.png +0 -0
  158. package/src/wnako3_editor_marker_red.xcf +0 -0
  159. package/src/wnako3_editor_marker_yellow.png +0 -0
  160. package/src/wnako3_editor_marker_yellow.xcf +0 -0
  161. package/src/wnako3webworker.js +70 -0
  162. package/test/ace_editor/karma.config.js +94 -0
  163. package/test/ace_editor/test/.babelrc.json +3 -0
  164. package/test/ace_editor/test/ace_editor_test.js +178 -0
  165. package/test/ace_editor/test/html/custom_context.html +140 -0
  166. package/test/async/async_basic_test.js +124 -0
  167. package/test/browser/karma.config.js +212 -0
  168. package/test/browser/test/.babelrc.json +3 -0
  169. package/test/browser/test/compare_util.js +50 -0
  170. package/test/browser/test/html/canvas_basic.html +1 -0
  171. package/test/browser/test/html/div_basic.html +2 -0
  172. package/test/browser/test/html/event_dom_form.html +4 -0
  173. package/test/browser/test/html/event_dom_scrolldiv.html +5 -0
  174. package/test/browser/test/image/canvas_test1.png +0 -0
  175. package/test/browser/test/image/canvas_test2.png +0 -0
  176. package/test/browser/test/image/canvas_test3.png +0 -0
  177. package/test/browser/test/image/canvas_test4.png +0 -0
  178. package/test/browser/test/image/canvas_test7.png +0 -0
  179. package/test/browser/test/image/canvas_test8.png +0 -0
  180. package/test/browser/test/image/canvas_test_blank.png +0 -0
  181. package/test/browser/test/image/elephant_kana.png +0 -0
  182. package/test/browser/test/image/panda_kana.png +0 -0
  183. package/test/browser/test/image/turtle_kana.png +0 -0
  184. package/test/browser/test/import_plugin_checker.js +24 -0
  185. package/test/browser/test/plugin_browser_test.js +52 -0
  186. package/test/browser/test/plugin_browser_test_ajax.js +123 -0
  187. package/test/browser/test/plugin_browser_test_color.js +18 -0
  188. package/test/browser/test/plugin_browser_test_dialog.js +72 -0
  189. package/test/browser/test/plugin_browser_test_dom_event.js +598 -0
  190. package/test/browser/test/plugin_browser_test_dom_parts.js +125 -0
  191. package/test/browser/test/plugin_browser_test_system.js +9 -0
  192. package/test/browser/test/plugin_turtle_test.js +817 -0
  193. package/test/browser/test/plugin_webworker_test.js +87 -0
  194. package/test/browser/test/require_test.js +71 -0
  195. package/test/bundled/karma.config.base.js +117 -0
  196. package/test/bundled/karma.config.js +86 -0
  197. package/test/bundled/test/.babelrc.json +3 -0
  198. package/test/bundled/test/bundled_test.js +69 -0
  199. package/test/bundled/test/html/custom_context.html +65 -0
  200. package/test/bundled/test/html/custom_debug.html +66 -0
  201. package/test/bundled/test4b.cmd +52 -0
  202. package/test/bundled/test_base/.babelrc.json +3 -0
  203. package/test/bundled/test_base/_checktool_test.js +25 -0
  204. package/test/bundled/test_base/basic_ajax_test.js +56 -0
  205. package/test/bundled/test_base/basic_async_test.js +18 -0
  206. package/test/bundled/test_base/basic_test.js +153 -0
  207. package/test/bundled/test_base/calc_test.js +132 -0
  208. package/test/bundled/test_base/css/browsers_box.css +114 -0
  209. package/test/bundled/test_base/html/custom_context.html +69 -0
  210. package/test/bundled/test_base/html/custom_debug.html +71 -0
  211. package/test/bundled/test_base/js/browsers_box.js +72 -0
  212. package/test/bundled/test_base/plugin_csv_test.js +37 -0
  213. package/test/bundled/test_base/plugin_datetime_test.js +115 -0
  214. package/test/bundled/test_base/plugin_kansuji_test.js +49 -0
  215. package/test/bundled/test_base/plugin_system_test.js +410 -0
  216. package/test/bundled/test_base/plugin_webworker_test.js +53 -0
  217. package/test/bundled/test_base/resources/ok.txt +1 -0
  218. package/test/bundled/test_base/test_utils.js +191 -0
  219. package/test/common/array_test.js +40 -0
  220. package/test/common/basic_test.js +317 -0
  221. package/test/common/calc_test.js +139 -0
  222. package/test/common/debug_test.js +16 -0
  223. package/test/common/error_test.js +16 -0
  224. package/test/common/flow_test.js +360 -0
  225. package/test/common/func_call.js +136 -0
  226. package/test/common/func_test.js +149 -0
  227. package/test/common/indent_test.js +362 -0
  228. package/test/common/lex_test.js +146 -0
  229. package/test/common/literal_test.js +72 -0
  230. package/test/common/nako_logger_test.js +26 -0
  231. package/test/common/plugin_browser_test.js +24 -0
  232. package/test/common/plugin_browser_ut_audio_test.js +88 -0
  233. package/test/common/plugin_browser_ut_color_test.js +21 -0
  234. package/test/common/plugin_browser_ut_dialog_test.js +100 -0
  235. package/test/common/plugin_browser_ut_html_test.js +13 -0
  236. package/test/common/plugin_browser_ut_system_test.js +10 -0
  237. package/test/common/plugin_csv_test.js +39 -0
  238. package/test/common/plugin_datetime_test.js +120 -0
  239. package/test/common/plugin_kansuji_test.js +59 -0
  240. package/test/common/plugin_promise_test.js +18 -0
  241. package/test/common/plugin_system_test.js +451 -0
  242. package/test/common/prepare_test.js +93 -0
  243. package/test/common/re_test.js +20 -0
  244. package/test/common/variable_scope_test.js +105 -0
  245. package/test/jsconfig.json +19 -0
  246. package/test/karma.config.js +91 -0
  247. package/test/node/add_test.nako3 +1 -0
  248. package/test/node/async_test.js +80 -0
  249. package/test/node/commander_ja_test.js +82 -0
  250. package/test/node/error_message_test.js +244 -0
  251. package/test/node/kai_test.nako3 +6 -0
  252. package/test/node/node_test.js +43 -0
  253. package/test/node/plugin_broken.js.txt +3 -0
  254. package/test/node/plugin_browser_ut_ajax_test.js +355 -0
  255. package/test/node/plugin_browser_ut_location_test.js +32 -0
  256. package/test/node/plugin_markup_test.js +44 -0
  257. package/test/node/plugin_math_test.js +42 -0
  258. package/test/node/plugin_node_test.js +93 -0
  259. package/test/node/plugin_test.js +16 -0
  260. package/test/node/relative_import_test_1.nako3 +1 -0
  261. package/test/node/relative_import_test_2.nako3 +2 -0
  262. package/test/node/require_nako3_test.js +59 -0
  263. package/test/node/requiretest.nako3 +4 -0
  264. package/test/node/requiretest_indirect.nako3 +1 -0
  265. package/test/node/requiretest_name.nako3 +5 -0
  266. package/test/node/runtime_error.nako3 +2 -0
  267. package/test/node/side_effects_test.js +106 -0
  268. package/test/node/sjis.txt +5 -0
  269. package/test/node/syntax_error.nako3 +2 -0
  270. package/test/node/wnako3_editor_test.js +360 -0
  271. package/tools/README.md +7 -0
  272. package/tools/nako3edit/html/edit.html +83 -0
  273. package/tools/nako3edit/html/edit_plugin.js +6 -0
  274. package/tools/nako3edit/html/files.html +49 -0
  275. package/tools/nako3edit/html/nako3edit.css +66 -0
  276. package/tools/nako3edit/index.nako3 +145 -0
  277. package/tools/nako3edit/run.js +12 -0
  278. package/tools/nako3server/html/edit.html +104 -0
  279. package/tools/nako3server/html/edit_plugin.js +6 -0
  280. package/tools/nako3server/html/files.html +53 -0
  281. package/tools/nako3server/html/nako3edit.css +66 -0
  282. package/tools/nako3server/index.nako3 +129 -0
  283. package/tools/nako3server/run.js +12 -0
@@ -0,0 +1,1459 @@
1
+ /**
2
+ * file: nako_gen.js
3
+ * パーサーが生成した中間オブジェクトを実際のJavaScriptのコードに変換する。
4
+ * なお速度優先で忠実にJavaScriptのコードを生成する。
5
+ */
6
+
7
+ 'use strict'
8
+
9
+ const { NakoSyntaxError, NakoError, NakoRuntimeError } = require('./nako_errors')
10
+ const nakoVersion = require('./nako_version')
11
+
12
+ /**
13
+ * @typedef {import("./nako3").Ast} Ast
14
+ */
15
+ /**
16
+ * 構文木からJSのコードを生成するクラス
17
+ */
18
+ class NakoGen {
19
+ /**
20
+ * @param {import('./nako3')} com
21
+ * @param {Ast} ast
22
+ * @param {boolean | string} isTest 文字列なら1つのテストだけを実行する
23
+ */
24
+ static generate (com, ast, isTest) {
25
+ const gen = new NakoGen(com)
26
+
27
+ // ユーザー定義関数をシステムに登録する
28
+ gen.registerFunction(ast)
29
+
30
+ // JSコードを生成する
31
+ let js = gen.convGen(ast, !!isTest)
32
+
33
+ // JSコードを実行するための事前ヘッダ部分の生成
34
+ js = gen.getDefFuncCode(isTest) + js
35
+
36
+ // テストの実行
37
+ if (js && isTest) {
38
+ js += '\n__self._runTests(__tests);\n'
39
+ }
40
+
41
+ // デバッグメッセージ
42
+ com.logger.trace('--- generate ---\n' + js)
43
+
44
+ return {
45
+ // なでしこの実行環境ありの場合
46
+ runtimeEnv: js,
47
+ // JavaScript単体で動かす場合
48
+ standalone:
49
+ `\
50
+ const nakoVersion = ${JSON.stringify(nakoVersion)};
51
+ ${NakoError.toString()}
52
+ ${NakoRuntimeError.toString()}
53
+ this.logger = {
54
+ error(message) { console.error(message) },
55
+ send(level, message) { console.log(message) },
56
+ };
57
+ this.__varslist = [{}, {}, {}];
58
+ this.__vars = this.__varslist[2];
59
+ this.__module = {};
60
+ this.__locals = {};
61
+ this.__genMode = 'sync';
62
+ try {
63
+ ${gen.getVarsCode()}
64
+ ${js}
65
+ } catch (err) {
66
+ if (!(err instanceof NakoRuntimeError)) {
67
+ err = new NakoRuntimeError(err, __varslist[0].line);
68
+ }
69
+ this.logger.error(err);
70
+ throw err;
71
+ }`,
72
+ // コード生成に使ったNakoGenのインスタンス
73
+ gen
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @param {import('./nako3')} com コンパイラのインスタンス
79
+ */
80
+ constructor (com) {
81
+ /**
82
+ * 出力するJavaScriptコードのヘッダー部分で定義する必要のある関数。fnはjsのコード。
83
+ * プラグイン関数は含まれない。
84
+ */
85
+ this.nako_func = { ...com.nako_func }
86
+
87
+ /**
88
+ * なでしこで定義したテストの一覧
89
+ * @type {Record<string, { josi: string[][], fn: string, type: 'test_func' }>}
90
+ */
91
+ this.nako_test = {}
92
+
93
+ /**
94
+ * プログラム内で参照された関数のリスト。プラグインの命令を含む。
95
+ * JavaScript単体で実行するとき、このリストにある関数の定義をJavaScriptコードの先頭に付け足す。
96
+ * @type {Set<string>}
97
+ */
98
+ this.used_func = new Set()
99
+
100
+ /**
101
+ * ループ時の一時変数が被らないようにIDで管理
102
+ * @type {number}
103
+ */
104
+ this.loop_id = 1
105
+
106
+ /**
107
+ * 変換中の処理が、ループの中かどうかを判定する
108
+ * @type {boolean}
109
+ */
110
+ this.flagLoop = false
111
+
112
+ this.__self = com
113
+
114
+ /**
115
+ * コードジェネレータの種類
116
+ * @type {string}
117
+ */
118
+ this.genMode = 'sync'
119
+
120
+ /**
121
+ * 行番号とファイル名が分かるときは `l123:main.nako3`、行番号だけ分かるときは `l123`、そうでなければ任意の文字列。
122
+ * @type {string | null}
123
+ */
124
+ this.lastLineNo = null
125
+
126
+ /**
127
+ * スタック
128
+ * @type {{ isFunction: boolean, names: Set<string>, readonly: Set<string> }[]}
129
+ */
130
+ this.varslistSet = com.__varslist.map((v) => ({ isFunction: false, names: new Set(Object.keys(v)), readonly: new Set() }))
131
+
132
+ /**
133
+ * スタックトップ
134
+ * @type {{ isFunction: boolean, names: Set<string>, readonly: Set<string> }}
135
+ */
136
+ this.varsSet = { isFunction: false, names: new Set(), readonly: new Set() }
137
+ this.varslistSet[2] = this.varsSet
138
+
139
+ // 1以上のとき高速化する。
140
+ // 実行速度優先ブロック内で1増える。
141
+ this.speedMode = {
142
+ lineNumbers: 0, // 行番号を出力しない
143
+ implicitTypeCasting: 0, // 数値加算でparseFloatを出力しない
144
+ invalidSore: 0, // 「それ」を用いない
145
+ forcePure: 0 // 全てのシステム命令をpureとして扱う。命令からローカル変数への参照が出来なくなる。
146
+ }
147
+
148
+ // 1以上のとき測定をinjectする。
149
+ // パフォーマンスモニタのブロック内で1増える。
150
+ this.performanceMonitor = {
151
+ userFunction: 0, // 呼び出されたユーザ関数
152
+ systemFunction: 0, // システム関数(呼び出しコードを含む)
153
+ systemFunctionBody: 0 // システム関数(呼び出しコードを除く)
154
+ }
155
+
156
+ // 暫定変数
157
+ this.warnUndefinedReturnUserFunc = 1
158
+ this.warnUndefinedCallingUserFuncArgs = 1
159
+ this.warnUndefinedCallingSystemFuncArgs = 1
160
+ this.warnUndefinedCalledUserFuncArgs = 1
161
+ }
162
+
163
+ /**
164
+ * @param {string} name
165
+ */
166
+ static isValidIdentifier (name) {
167
+ // TODO: いらなそうな部分は削る
168
+ // https://stackoverflow.com/a/9337047
169
+ // eslint-disable-next-line no-misleading-character-class
170
+ return /^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)[$A-Z_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/.test(name)
171
+ }
172
+
173
+ /**
174
+ * @param {import("./nako3").Ast} node
175
+ * @param {boolean} forceUpdate
176
+ */
177
+ convLineno (node, forceUpdate) {
178
+ if (this.speedMode.lineNumbers > 0) { return '' }
179
+
180
+ /** @type {string} */
181
+ let lineNo
182
+ if (typeof node.line !== 'number') {
183
+ lineNo = 'unknown'
184
+ } else if (typeof node.file !== 'string') {
185
+ lineNo = `l${node.line}`
186
+ } else {
187
+ lineNo = `l${node.line}:${node.file}`
188
+ }
189
+
190
+ // 強制的に行番号をアップデートするか
191
+ if (!forceUpdate) {
192
+ if (lineNo === this.lastLineNo) { return '' }
193
+ this.lastLineNo = lineNo
194
+ }
195
+ // 例: __v0.line='l1:main.nako3'
196
+ return `__v0.line=${JSON.stringify(lineNo)};`
197
+ }
198
+
199
+ /**
200
+ * ローカル変数のJavaScriptコードを生成する。
201
+ * @param {string} name
202
+ */
203
+ varname (name) {
204
+ if (this.varslistSet.length === 3) {
205
+ // グローバル
206
+ return `__varslist[${2}][${JSON.stringify(name)}]`
207
+ } else {
208
+ // 関数内
209
+ if (NakoGen.isValidIdentifier(name)) {
210
+ return name
211
+ } else {
212
+ return `__vars[${JSON.stringify(name)}]`
213
+ }
214
+ }
215
+ }
216
+
217
+ /** @param {string} name */
218
+ static getFuncName (name) {
219
+ let name2 = name.replace(/[ぁ-ん]+$/, '')
220
+ if (name2 === '') { name2 = name }
221
+ return name2
222
+ }
223
+
224
+ /** @param {Ast} node */
225
+ static convPrint (node) {
226
+ return `__print(${node});`
227
+ }
228
+
229
+ /** @param {Ast} node */
230
+ static convRequire (node) {
231
+ const moduleName = node.value
232
+ return this.convLineno(node, false) +
233
+ `__module['${moduleName}'] = require('${moduleName}');\n`
234
+ }
235
+
236
+ /**
237
+ * プログラムの実行に必要な関数を書き出す(システム領域)
238
+ * @returns {string}
239
+ */
240
+ getVarsCode () {
241
+ let code = ''
242
+
243
+ // プログラム中で使った関数を列挙して書き出す
244
+ for (const key of Array.from(this.used_func.values())) {
245
+ const f = this.__self.__varslist[0][key]
246
+ const name = `this.__varslist[0]["${key}"]`
247
+ if (typeof (f) === 'function') { code += name + '=' + f.toString() + ';\n' } else { code += name + '=' + JSON.stringify(f) + ';\n' }
248
+ }
249
+ return code
250
+ }
251
+
252
+ /**
253
+ * プログラムの実行に必要な関数定義を書き出す(グローバル領域)
254
+ * convGenの結果を利用するため、convGenの後に呼び出すこと。
255
+ * @param {boolean | string} isTest テストかどうか。stringの場合は1つのテストのみ。
256
+ * @returns {string}
257
+ */
258
+ getDefFuncCode (isTest) {
259
+ let code = ''
260
+ // よく使う変数のショートカット
261
+ code += 'const __self = this.__self = this;\n'
262
+ code += 'const __varslist = this.__varslist;\n'
263
+ code += 'const __module = this.__module;\n'
264
+ code += 'const __v0 = this.__v0 = this.__varslist[0];\n'
265
+ code += 'const __v1 = this.__v1 = this.__varslist[1];\n'
266
+ code += 'const __vars = this.__vars = this.__varslist[2];\n'
267
+
268
+ // なでしこの関数定義を行う
269
+ let nakoFuncCode = ''
270
+ for (const key in this.nako_func) {
271
+ const f = this.nako_func[key].fn
272
+ nakoFuncCode += '' +
273
+ `//[DEF_FUNC name='${key}']\n` +
274
+ `__v1["${key}"]=${f};\n;` +
275
+ `//[/DEF_FUNC name='${key}']\n`
276
+ }
277
+ if (nakoFuncCode !== '') { code += '__v0.line=\'関数の定義\';\n' + nakoFuncCode }
278
+
279
+ // プラグインの初期化関数を実行する
280
+ let pluginCode = ''
281
+ for (const name in this.__self.__module) {
282
+ const initkey = `!${name}:初期化`
283
+ if (this.varslistSet[0].names.has(initkey)) {
284
+ this.used_func.add(`!${name}:初期化`)
285
+ pluginCode += `__v0["!${name}:初期化"](__self);\n`
286
+ }
287
+ }
288
+ if (pluginCode !== '') { code += '__v0.line=\'プラグインの初期化\';\n' + pluginCode }
289
+
290
+ // テストの定義を行う
291
+ if (isTest) {
292
+ let testCode = 'const __tests = [];\n'
293
+
294
+ for (const key in this.nako_test) {
295
+ if (isTest === true || (typeof isTest === 'string' && isTest === key)) {
296
+ const f = this.nako_test[key].fn
297
+ testCode += `${f};\n;`
298
+ }
299
+ }
300
+
301
+ if (testCode !== '') {
302
+ code += '__v0.line=\'テストの定義\';\n'
303
+ code += testCode + '\n'
304
+ }
305
+ }
306
+
307
+ return code
308
+ }
309
+
310
+ /**
311
+ * プラグイン・オブジェクトを追加
312
+ * @param po プラグイン・オブジェクト
313
+ */
314
+ addPlugin (po) {
315
+ return this.__self.addPlugin(po)
316
+ }
317
+
318
+ /**
319
+ * プラグイン・オブジェクトを追加(ブラウザ向け)
320
+ * @param name オブジェクト名
321
+ * @param po 関数リスト
322
+ */
323
+ addPluginObject (name, po) {
324
+ this.__self.addPluginObject(name, po)
325
+ }
326
+
327
+ /**
328
+ * プラグイン・ファイルを追加(Node.js向け)
329
+ * @param objName オブジェクト名
330
+ * @param path ファイルパス
331
+ * @param po 登録するオブジェクト
332
+ */
333
+ addPluginFile (objName, path, po) {
334
+ this.__self.addPluginFile(objName, path, po)
335
+ }
336
+
337
+ /**
338
+ * 関数を追加する
339
+ * @param key 関数名
340
+ * @param josi 助詞
341
+ * @param fn 関数
342
+ */
343
+ addFunc (key, josi, fn) {
344
+ this.__self.addFunc(key, josi, fn)
345
+ }
346
+
347
+ /**
348
+ * 関数をセットする
349
+ * @param key 関数名
350
+ * @param fn 関数
351
+ */
352
+ setFunc (key, fn) {
353
+ this.__self.setFunc(key, fn)
354
+ }
355
+
356
+ /**
357
+ * プラグイン関数を参照する
358
+ * @param key プラグイン関数の関数名
359
+ * @returns プラグイン・オブジェクト
360
+ */
361
+ getFunc (key) {
362
+ return this.__self.getFunc(key)
363
+ }
364
+
365
+ /**
366
+ * 関数を先に登録してしまう
367
+ */
368
+ registerFunction (ast) {
369
+ if (ast.type !== 'block') { throw NakoSyntaxError.fromNode('構文解析に失敗しています。構文は必ずblockが先頭になります', ast) }
370
+
371
+ const registFunc = (node) => {
372
+ for (let i = 0; i < node.block.length; i++) {
373
+ const t = node.block[i]
374
+ if (t.type === 'def_func') {
375
+ const name = t.name.value
376
+ this.used_func.add(name)
377
+ this.__self.__varslist[1][name] = function () { } // 事前に適当な値を設定
378
+ this.nako_func[name] = {
379
+ josi: t.name.meta.josi,
380
+ fn: '',
381
+ type: 'func'
382
+ }
383
+ } else
384
+ if (t.type === 'speed_mode') {
385
+ if (t.block.type === 'block') {
386
+ registFunc(t.block)
387
+ } else {
388
+ registFunc(t)
389
+ }
390
+ } else
391
+ if (t.type === 'performance_monitor') {
392
+ if (t.block.type === 'block') {
393
+ registFunc(t.block)
394
+ } else {
395
+ registFunc(t)
396
+ }
397
+ }
398
+ }
399
+ }
400
+ registFunc(ast)
401
+
402
+ // __self.__varslistの変更を反映
403
+ const initialNames = new Set()
404
+ if (this.speedMode.invalidSore === 0) {
405
+ initialNames.add('それ')
406
+ }
407
+ this.varsSet = { isFunction: false, names: initialNames, readonly: new Set() }
408
+ this.varslistSet = this.__self.__varslist.map((v) => ({ isFunction: false, names: new Set(Object.keys(v)), readonly: new Set() }))
409
+ this.varslistSet[2] = this.varsSet
410
+ }
411
+
412
+ /**
413
+ * @param {Ast} node
414
+ * @param {boolean} isTest
415
+ */
416
+ convGen (node, isTest) {
417
+ const result = this.convLineno(node, false) + this._convGen(node, true)
418
+ if (isTest) {
419
+ return ''
420
+ } else {
421
+ return result
422
+ }
423
+ }
424
+
425
+ /**
426
+ * @param {Ast} node
427
+ * @param {boolean} isExpression
428
+ */
429
+ _convGen (node, isExpression) {
430
+ let code = ''
431
+ if (node instanceof Array) {
432
+ for (let i = 0; i < node.length; i++) {
433
+ const n = node[i]
434
+ code += this._convGen(n, isExpression)
435
+ }
436
+ return code
437
+ }
438
+ if (node === null) { return 'null' }
439
+ if (node === undefined) { return 'undefined' }
440
+ if (typeof (node) !== 'object') { return '' + node }
441
+ // switch
442
+ switch (node.type) {
443
+ case 'nop':
444
+ break
445
+ case 'block':
446
+ for (let i = 0; i < node.block.length; i++) {
447
+ const b = node.block[i]
448
+ code += this._convGen(b, false)
449
+ }
450
+ break
451
+ case 'comment':
452
+ case 'eol':
453
+ code += this.convComment(node)
454
+ break
455
+ case 'break':
456
+ code += this.convCheckLoop(node, 'break')
457
+ break
458
+ case 'continue':
459
+ code += this.convCheckLoop(node, 'continue')
460
+ break
461
+ case 'end':
462
+ code += '__varslist[0][\'終\']();'
463
+ break
464
+ case 'number':
465
+ code += node.value
466
+ break
467
+ case 'string':
468
+ code += this.convString(node)
469
+ break
470
+ case 'def_local_var':
471
+ code += this.convDefLocalVar(node)
472
+ break
473
+ case 'def_local_varlist':
474
+ code += this.convDefLocalVarlist(node)
475
+ break
476
+ case 'let':
477
+ code += this.convLet(node)
478
+ break
479
+ case 'word':
480
+ case 'variable':
481
+ code += this.convGetVar(node)
482
+ break
483
+ case 'op':
484
+ case 'calc':
485
+ code += this.convOp(node)
486
+ break
487
+ case 'renbun':
488
+ code += this.convRenbun(node)
489
+ break
490
+ case 'not':
491
+ code += '((' + this._convGen(node.value, true) + ')?0:1)'
492
+ break
493
+ case 'func':
494
+ case 'func_pointer':
495
+ case 'calc_func':
496
+ code += this.convFunc(node, isExpression)
497
+ break
498
+ case 'if':
499
+ code += this.convIf(node)
500
+ break
501
+ case 'tikuji':
502
+ code += this.convTikuji(node)
503
+ break
504
+ case 'for':
505
+ code += this.convFor(node)
506
+ break
507
+ case 'foreach':
508
+ code += this.convForeach(node)
509
+ break
510
+ case 'repeat_times':
511
+ code += this.convRepeatTimes(node)
512
+ break
513
+ case 'speed_mode':
514
+ code += this.convSpeedMode(node, isExpression)
515
+ break
516
+ case 'performance_monitor':
517
+ code += this.convPerformanceMonitor(node, isExpression)
518
+ break
519
+ case 'while':
520
+ code += this.convWhile(node)
521
+ break
522
+ case 'switch':
523
+ code += this.convSwitch(node)
524
+ break
525
+ case 'let_array':
526
+ code += this.convLetArray(node)
527
+ break
528
+ case '配列参照':
529
+ code += this.convRefArray(node)
530
+ break
531
+ case 'json_array':
532
+ code += this.convJsonArray(node)
533
+ break
534
+ case 'json_obj':
535
+ code += this.convJsonObj(node)
536
+ break
537
+ case 'func_obj':
538
+ code += this.convFuncObj(node)
539
+ break
540
+ case 'bool':
541
+ code += (node.value) ? 'true' : 'false'
542
+ break
543
+ case 'null':
544
+ code += 'null'
545
+ break
546
+ case 'def_test':
547
+ code += this.convDefTest(node)
548
+ break
549
+ case 'def_func':
550
+ code += this.convDefFunc(node)
551
+ break
552
+ case 'return':
553
+ code += this.convReturn(node)
554
+ break
555
+ case 'try_except':
556
+ code += this.convTryExcept(node)
557
+ break
558
+ case 'require':
559
+ code += NakoGen.convRequire(node)
560
+ break
561
+ default:
562
+ throw new Error('System Error: unknown_type=' + node.type)
563
+ }
564
+ return code
565
+ }
566
+
567
+ /**
568
+ * @param {string} name
569
+ * @returns {{i: number, name: string, isTop: boolean, js: string} | null}
570
+ */
571
+ findVar (name) {
572
+ // __vars ? (ローカル変数)
573
+ if (this.varslistSet.length > 3 && this.varsSet.names.has(name)) {
574
+ return { i: this.varslistSet.length - 1, name, isTop: true, js: this.varname(name) }
575
+ }
576
+ // __varslist ?
577
+ for (let i = 2; i >= 0; i--) {
578
+ if (this.varslistSet[i].names.has(name)) {
579
+ // ユーザーの定義したグローバル変数 (__varslist[2]) は、変数展開されている(そのままの名前で定義されている)可能性がある。
580
+ // それ以外の変数は、必ず__varslistに入っている。
581
+ return { i, name, isTop: false, js: `__varslist[${i}][${JSON.stringify(name)}]` }
582
+ }
583
+ }
584
+
585
+ return null
586
+ }
587
+
588
+ /**
589
+ * 定義済みの変数の参照
590
+ * @param {string} name
591
+ * @param {Ast} position
592
+ */
593
+ genVar (name, position) {
594
+ const res = this.findVar(name)
595
+ const lno = position.line
596
+ if (res === null) {
597
+ // 定義されていない名前の参照は変数の定義とみなす。
598
+ // 多くの場合はundefined値を持つ変数であり分かりづらいバグを引き起こすが、
599
+ // 「ナデシコする」などの命令の中で定義された変数の参照の場合があるため警告に留める。
600
+ // ただし、自動的に定義される変数『引数』『それ』などは例外 #952
601
+ if (name === '引数' || name === 'それ' || name === '対象' || name === '対象キー') {
602
+ // デフォルト定義されている変数名
603
+ } else {
604
+ this.__self.logger.warn(`変数『${name}』は定義されていません。`, position)
605
+ }
606
+ this.varsSet.names.add(name)
607
+ return this.varname(name)
608
+ }
609
+
610
+ const i = res.i
611
+ // システム関数・変数の場合
612
+ if (i === 0) {
613
+ const pv = this.__self.funclist[name]
614
+ if (!pv) { return `${res.js}/*err:${lno}*/` }
615
+ if (pv.type === 'const' || pv.type === 'var') { return res.js }
616
+ if (pv.type === 'func') {
617
+ if (pv.josi.length === 0) { return `(${res.js}())` }
618
+
619
+ throw NakoSyntaxError.fromNode(`『${name}』が複文で使われました。単文で記述してください。(v1非互換)`, position)
620
+ }
621
+ throw NakoSyntaxError.fromNode(`『${name}』は関数であり参照できません。`, position)
622
+ }
623
+ return res.js
624
+ }
625
+
626
+ convGetVar (node) {
627
+ const name = node.value
628
+ return this.genVar(name, node)
629
+ }
630
+
631
+ convComment (node) {
632
+ let commentSrc = String(node.value)
633
+ commentSrc = commentSrc.replace(/\n/g, '¶')
634
+ const lineNo = this.convLineno(node, false)
635
+ if (commentSrc === '' && lineNo === '') { return ';' }
636
+ if (commentSrc === '') {
637
+ return ';' + lineNo + '\n'
638
+ }
639
+ return ';' + lineNo + '//' + commentSrc + '\n'
640
+ }
641
+
642
+ convReturn (node) {
643
+ // 関数の中であれば利用可能
644
+ if (this.varsSet.names.has('!関数')) { throw NakoSyntaxError.fromNode('『戻る』がありますが、関数定義内のみで使用可能です。', node) }
645
+
646
+ const lno = this.convLineno(node, false)
647
+ let value
648
+ if (node.value) {
649
+ value = this._convGen(node.value, true)
650
+ } else
651
+ if (this.speedMode.invalidSore === 0) {
652
+ value = this.varname('それ')
653
+ } else {
654
+ return lno + 'return;'
655
+ }
656
+ if (this.warnUndefinedReturnUserFunc === 0) {
657
+ return lno + `return ${value};`
658
+ } else {
659
+ return lno + `return (function(a){if(a===undefined){__self.logger.warn('ユーザ関数からundefinedが返されています',{file:'${node.file}',line:${node.line}});};return a;})(${value});`
660
+ }
661
+ }
662
+
663
+ convCheckLoop (node, cmd) {
664
+ // ループの中であれば利用可能
665
+ if (!this.flagLoop) {
666
+ const cmdj = (cmd === 'continue') ? '続ける' : '抜ける'
667
+ throw NakoSyntaxError.fromNode(`『${cmdj}』文がありますが、それは繰り返しの中で利用してください。`, node)
668
+ }
669
+ return this.convLineno(node.line) + cmd + ';'
670
+ }
671
+
672
+ convDefFuncCommon (node, name) {
673
+ // パフォーマンスモニタ:ユーザ関数のinjectの定義
674
+ let performanceMonitorInjectAtStart = ''
675
+ let performanceMonitorInjectAtEnd = ''
676
+ if (this.performanceMonitor.userFunction !== 0) {
677
+ let key = name
678
+ if (!key) {
679
+ if (typeof this.performanceMonitor.mumeiId === 'undefined') {
680
+ this.performanceMonitor.mumeiId = 0
681
+ }
682
+ this.performanceMonitor.mumeiId++
683
+ key = `anous_${this.performanceMonitor.mumeiId}`
684
+ }
685
+ performanceMonitorInjectAtStart = 'const performanceMonitorEnd = (function (key, type) {\n' +
686
+ 'const uf_start = performance.now() * 1000;\n' +
687
+ 'return function () {\n' +
688
+ 'const el_time = performance.now() * 1000 - uf_start;\n' +
689
+ 'if (!__self.__performance_monitor) {\n' +
690
+ '__self.__performance_monitor={};\n' +
691
+ '__self.__performance_monitor[key] = { called:1, totel_usec: el_time, min_usec: el_time, max_usec: el_time, type: type };\n' +
692
+ '} else if (!__self.__performance_monitor[key]) {\n' +
693
+ '__self.__performance_monitor[key] = { called:1, totel_usec: el_time, min_usec: el_time, max_usec: el_time, type: type };\n' +
694
+ '} else {\n' +
695
+ '__self.__performance_monitor[key].called++;\n' +
696
+ '__self.__performance_monitor[key].totel_usec+=el_time;\n' +
697
+ 'if(__self.__performance_monitor[key].min_usec>el_time){__self.__performance_monitor[key].min_usec=el_time;}\n' +
698
+ 'if(__self.__performance_monitor[key].max_usec<el_time){__self.__performance_monitor[key].max_usec=el_time;}\n' +
699
+ `}};})('${key}', 'user');` +
700
+ 'try {\n'
701
+ performanceMonitorInjectAtEnd = '} finally { performanceMonitorEnd(); }\n'
702
+ }
703
+ const topOfFunction = '(function(){\n'
704
+ const endOfFunction = '})'
705
+ let variableDeclarations = ''
706
+ const initialNames = new Set()
707
+ if (this.speedMode.invalidSore === 0) {
708
+ initialNames.add('それ')
709
+ }
710
+ this.varsSet = { isFunction: true, names: initialNames, readonly: new Set() }
711
+ // ローカル変数をPUSHする
712
+ this.varslistSet.push(this.varsSet)
713
+ // JSの引数と引数をバインド
714
+ variableDeclarations += ' var 引数 = arguments;\n'
715
+ // 宣言済みの名前を保存
716
+ const varsDeclared = Array.from(this.varsSet.names.values())
717
+ let code = ''
718
+ // 引数をローカル変数に設定
719
+ const meta = (!name) ? node.meta : node.name.meta
720
+ for (let i = 0; i < meta.varnames.length; i++) {
721
+ const word = meta.varnames[i]
722
+ if (this.warnUndefinedCalledUserFunc === 0) {
723
+ code += ` ${this.varname(word)} = arguments[${i}];\n`
724
+ } else
725
+ if (name) {
726
+ code += ` ${this.varname(word)} = (function(a){if(a===undefined){__self.logger.warn('ユーザ関数(${name})の引数(${this.varname(word)})にundefinedが渡されました',{file:'${node.file}',line:${node.line}});};return a;})(arguments[${i}]);\n`
727
+ } else {
728
+ code += ` ${this.varname(word)} = (function(a){if(a===undefined){__self.logger.warn('匿名関数の引数(${this.varname(word)})にundefinedが渡されました',{file:'${node.file}',line:${node.line}});};return a;})(arguments[${i}]);\n`
729
+ }
730
+ this.varsSet.names.add(word)
731
+ }
732
+ // 関数定義は、グローバル領域で。
733
+ if (name) {
734
+ this.used_func.add(name)
735
+ this.varslistSet[1].names.add(name)
736
+ this.nako_func[name] = {
737
+ josi: node.name.meta.josi,
738
+ fn: '',
739
+ type: 'func'
740
+ }
741
+ }
742
+ // ブロックを解析
743
+ const block = this._convGen(node.block, false)
744
+ code += block.split('\n').map((line) => ' ' + line).join('\n') + '\n'
745
+ // 関数の最後に、変数「それ」をreturnするようにする
746
+ if (this.speedMode.invalidSore === 0) {
747
+ code += ` return (${this.varname('それ')});\n`
748
+ }
749
+ // パフォーマンスモニタ:ユーザ関数のinject
750
+ code += performanceMonitorInjectAtEnd
751
+ // 関数の末尾に、ローカル変数をPOP
752
+ code += endOfFunction
753
+
754
+ // 関数内で定義されたローカル変数の宣言
755
+ let needsVarsObject = false
756
+ for (const name of Array.from(this.varsSet.names.values())) {
757
+ if (!varsDeclared.includes(name)) {
758
+ if (NakoGen.isValidIdentifier(name)) {
759
+ variableDeclarations += ` var ${name};\n`
760
+ } else {
761
+ needsVarsObject = true
762
+ }
763
+ }
764
+ }
765
+ if (!NakoGen.isValidIdentifier('それ') && this.speedMode.invalidSore === 0) {
766
+ needsVarsObject = true
767
+ }
768
+ // 一度でも__varsを使ったら、それも宣言する。
769
+ if (needsVarsObject) {
770
+ variableDeclarations += ' var __vars = {};\n'
771
+ }
772
+ if (this.speedMode.invalidSore === 0) {
773
+ if (NakoGen.isValidIdentifier('それ')) {
774
+ variableDeclarations += ' var それ = \'\';\n'
775
+ } else {
776
+ variableDeclarations += ` ${this.varname('それ')} = '';`
777
+ }
778
+ }
779
+ code = topOfFunction + performanceMonitorInjectAtStart + variableDeclarations + code
780
+
781
+ if (name) { this.nako_func[name].fn = code }
782
+
783
+ this.varslistSet.pop()
784
+ this.varsSet = this.varslistSet[this.varslistSet.length - 1]
785
+ if (name) { this.__self.__varslist[1][name] = code }
786
+
787
+ return code
788
+ }
789
+
790
+ convDefTest (node) {
791
+ const name = node.name.value
792
+ let code = `__tests.push({ name: '${name}', f: () => {\n`
793
+
794
+ // ブロックを解析
795
+ const block = this._convGen(node.block, false)
796
+
797
+ code += ` ${block}\n` +
798
+ '}});'
799
+
800
+ this.nako_test[name] = {
801
+ josi: node.name.meta.josi,
802
+ fn: code,
803
+ type: 'test_func'
804
+ }
805
+
806
+ // ★この時点ではテストコードを生成しない★
807
+ // プログラム冒頭でコード生成時にテストの定義を行う
808
+ return ''
809
+ }
810
+
811
+ convDefFunc (node) {
812
+ const name = NakoGen.getFuncName(node.name.value)
813
+ this.convDefFuncCommon(node, name)
814
+ // ★この時点では関数のコードを生成しない★
815
+ // プログラム冒頭でコード生成時に関数定義を行う
816
+ return ''
817
+ }
818
+
819
+ convFuncObj (node) {
820
+ return this.convDefFuncCommon(node, '')
821
+ }
822
+
823
+ convJsonObj (node) {
824
+ const list = node.value
825
+ const codelist = list.map((e) => {
826
+ const key = this._convGen(e.key, true)
827
+ const val = this._convGen(e.value, true)
828
+ return `${key}:${val}`
829
+ })
830
+ return '{' + codelist.join(',') + '}'
831
+ }
832
+
833
+ convJsonArray (node) {
834
+ const list = node.value
835
+ const codelist = list.map((e) => {
836
+ return this._convGen(e, true)
837
+ })
838
+ return '[' + codelist.join(',') + ']'
839
+ }
840
+
841
+ convRefArray (node) {
842
+ const name = this._convGen(node.name, true)
843
+ const list = node.index
844
+ let code = name
845
+ for (let i = 0; i < list.length; i++) {
846
+ const idx = this._convGen(list[i], true)
847
+ code += '[' + idx + ']'
848
+ }
849
+ return code
850
+ }
851
+
852
+ convLetArray (node) {
853
+ const name = this._convGen(node.name, true)
854
+ const list = node.index
855
+ let code = name
856
+ for (let i = 0; i < list.length; i++) {
857
+ const idx = this._convGen(list[i], true)
858
+ code += '[' + idx + ']'
859
+ }
860
+ const value = this._convGen(node.value, true)
861
+ code += ' = ' + value + ';\n'
862
+ return this.convLineno(node, false) + code
863
+ }
864
+
865
+ convGenLoop (node) {
866
+ const tmpflag = this.flagLoop
867
+ this.flagLoop = true
868
+ try {
869
+ return this._convGen(node, false)
870
+ } finally {
871
+ this.flagLoop = tmpflag
872
+ }
873
+ }
874
+
875
+ convFor (node) {
876
+ // ループ変数について
877
+ let word
878
+ if (node.word !== null) { // ループ変数を使う時
879
+ const varName = node.word.value
880
+ this.varsSet.names.add(varName)
881
+ word = this.varname(varName)
882
+ } else {
883
+ this.varsSet.names.add('dummy')
884
+ word = this.varname('dummy')
885
+ }
886
+ const idLoop = this.loop_id++
887
+ const varI = `$nako_i${idLoop}`
888
+ // ループ条件を確認
889
+ const kara = this._convGen(node.from, true)
890
+ const made = this._convGen(node.to, true)
891
+ // ループ内のブロック内容を得る
892
+ const block = this.convGenLoop(node.block)
893
+ // ループ条件を変数に入れる用
894
+ const varFrom = `$nako_from${idLoop}`
895
+ const varTo = `$nako_to${idLoop}`
896
+ let sorePrefex = ''
897
+ if (this.speedMode.invalidSore === 0) {
898
+ sorePrefex = `${this.varname('それ')} = `
899
+ }
900
+ const code =
901
+ `\n//[FOR id=${idLoop}]\n` +
902
+ `const ${varFrom} = ${kara};\n` +
903
+ `const ${varTo} = ${made};\n` +
904
+ `if (${varFrom} <= ${varTo}) { // up\n` +
905
+ ` for (let ${varI} = ${varFrom}; ${varI} <= ${varTo}; ${varI}++) {\n` +
906
+ ` ${sorePrefex}${word} = ${varI};\n` +
907
+ ` ${block}\n` +
908
+ ' };\n' +
909
+ '} else { // down\n' +
910
+ ` for (let ${varI} = ${varFrom}; ${varI} >= ${varTo}; ${varI}--) {\n` +
911
+ ` ${sorePrefex}${word} = ${varI};` + '\n' +
912
+ ` ${block}\n` +
913
+ ' };\n' +
914
+ `};\n//[/FOR id=${idLoop}]\n`
915
+ return this.convLineno(node, false) + code
916
+ }
917
+
918
+ convForeach (node) {
919
+ let target
920
+ if (node.target === null) {
921
+ if (this.speedMode.invalidSore === 0) {
922
+ target = this.varname('それ')
923
+ } else {
924
+ throw NakoSyntaxError.fromNode('『反復』の対象がありません。', node)
925
+ }
926
+ } else { target = this._convGen(node.target, true) }
927
+
928
+ // blockより早く変数を定義する必要がある
929
+ let nameS = '__v0["対象"]'
930
+ if (node.name) {
931
+ nameS = this.varname(node.name.value)
932
+ this.varsSet.names.add(node.name.value)
933
+ }
934
+
935
+ const block = this.convGenLoop(node.block)
936
+ const id = this.loop_id++
937
+ const key = '__v0["対象キー"]'
938
+ let sorePrefex = ''
939
+ if (this.speedMode.invalidSore === 0) {
940
+ sorePrefex = `${this.varname('それ')} = `
941
+ }
942
+ const code =
943
+ `let $nako_foreach_v${id}=${target};\n` +
944
+ `for (let $nako_i${id} in $nako_foreach_v${id})` + '{\n' +
945
+ ` if ($nako_foreach_v${id}.hasOwnProperty($nako_i${id})) {\n` +
946
+ ` ${nameS} = ${sorePrefex}$nako_foreach_v${id}[$nako_i${id}];` + '\n' +
947
+ ` ${key} = $nako_i${id};\n` +
948
+ ` ${block}\n` +
949
+ ' }\n' +
950
+ '};\n'
951
+ return this.convLineno(node, false) + code
952
+ }
953
+
954
+ convRepeatTimes (node) {
955
+ const id = this.loop_id++
956
+ const value = this._convGen(node.value, true)
957
+ const block = this.convGenLoop(node.block)
958
+ const kaisu = '__v0["回数"]'
959
+ let sorePrefex = ''
960
+ if (this.speedMode.invalidSore === 0) {
961
+ sorePrefex = `${this.varname('それ')} = `
962
+ }
963
+ const code =
964
+ `let $nako_times_v${id} = ${value};\n` +
965
+ `for(var $nako_i${id} = 1; $nako_i${id} <= $nako_times_v${id}; $nako_i${id}++)` + '{\n' +
966
+ ` ${sorePrefex}${kaisu} = $nako_i${id};` + '\n' +
967
+ ' ' + block + '\n}\n'
968
+ return this.convLineno(node, false) + code
969
+ }
970
+
971
+ /**
972
+ * @param {Ast} node
973
+ * @param {boolean} isExpression
974
+ */
975
+ convSpeedMode (node, isExpression) {
976
+ const prev = { ...this.speedMode }
977
+ if (node.options['行番号無し']) {
978
+ this.speedMode.lineNumbers++
979
+ }
980
+ if (node.options['暗黙の型変換無し']) {
981
+ this.speedMode.implicitTypeCasting++
982
+ }
983
+ if (node.options['強制ピュア']) {
984
+ this.speedMode.forcePure++
985
+ }
986
+ if (node.options['それ無効']) {
987
+ this.speedMode.invalidSore++
988
+ }
989
+ try {
990
+ return this._convGen(node.block, isExpression)
991
+ } finally {
992
+ this.speedMode = prev
993
+ }
994
+ }
995
+
996
+ /**
997
+ * @param {Ast} node
998
+ * @param {boolean} isExpression
999
+ */
1000
+ convPerformanceMonitor (node, isExpression) {
1001
+ const prev = { ...this.performanceMonitor }
1002
+ if (node.options['ユーザ関数']) {
1003
+ this.performanceMonitor.userFunction++
1004
+ }
1005
+ if (node.options['システム関数本体']) {
1006
+ this.performanceMonitor.systemFunctionBody++
1007
+ }
1008
+ if (node.options['システム関数']) {
1009
+ this.performanceMonitor.systemFunction++
1010
+ }
1011
+ try {
1012
+ return this._convGen(node.block, isExpression)
1013
+ } finally {
1014
+ this.performanceMonitor = prev
1015
+ }
1016
+ }
1017
+
1018
+ convWhile (node) {
1019
+ const cond = this._convGen(node.cond, true)
1020
+ const block = this.convGenLoop(node.block)
1021
+ const code =
1022
+ `while (${cond})` + '{\n' +
1023
+ ` ${block}` + '\n' +
1024
+ '}\n'
1025
+ return this.convLineno(node, false) + code
1026
+ }
1027
+
1028
+ convSwitch (node) {
1029
+ const value = this._convGen(node.value, true)
1030
+ const cases = node.cases
1031
+ let body = ''
1032
+ for (let i = 0; i < cases.length; i++) {
1033
+ const cvalue = cases[i][0]
1034
+ const cblock = this.convGenLoop(cases[i][1])
1035
+ if (cvalue.type === '違えば') {
1036
+ body += ' default:\n'
1037
+ } else {
1038
+ const cvalueCode = this._convGen(cvalue, true)
1039
+ body += ` case ${cvalueCode}:\n`
1040
+ }
1041
+ body += ` ${cblock}\n` +
1042
+ ' break\n'
1043
+ }
1044
+ const code =
1045
+ `switch (${value})` + '{\n' +
1046
+ `${body}` + '\n' +
1047
+ '}\n'
1048
+ return this.convLineno(node, false) + code
1049
+ }
1050
+
1051
+ convIf (node) {
1052
+ const expr = this._convGen(node.expr, true)
1053
+ const block = this._convGen(node.block, false)
1054
+ const falseBlock = (node.false_block === null)
1055
+ ? ''
1056
+ : 'else {' + this._convGen(node.false_block, false) + '};\n'
1057
+ return this.convLineno(node, false) +
1058
+ `if (${expr}) {\n ${block}\n}` + falseBlock + ';\n'
1059
+ }
1060
+
1061
+ convTikuji (node) {
1062
+ const pid = this.loop_id++
1063
+ // gen tikuji blocks
1064
+ const curName = `__tikuji${pid}`
1065
+ let code = `const ${curName} = []\n`
1066
+ for (let i = 0; i < node.blocks.length; i++) {
1067
+ const block = this._convGen(node.blocks[i], false).replace(/\s+$/, '') + '\n'
1068
+ const blockLineNo = this.convLineno(node.blocks[i], true)
1069
+ const blockCode =
1070
+ `${curName}.push(function(resolve, reject) {\n` +
1071
+ ' __self.resolve = resolve;\n' +
1072
+ ' __self.reject = reject;\n' +
1073
+ ' __self.resolveCount = 0;\n' +
1074
+ ` ${blockLineNo}\n` +
1075
+ ` ${block}` +
1076
+ ' if (__self.resolveCount === 0) resolve();\n' +
1077
+ // eslint-disable-next-line no-template-curly-in-string
1078
+ '}); // end of tikuji__${pid}[{$i}]\n'
1079
+ code += blockCode
1080
+ }
1081
+ code += `// end of ${curName} \n`
1082
+ // gen error block
1083
+ let errorCode =
1084
+ ` ${curName}.splice(0);\n` + // clear
1085
+ ' __v0["エラーメッセージ"]=errMsg;\n'
1086
+ if (node.errorBlock != null) {
1087
+ const errBlock = this._convGen(node.errorBlock, false).replace(/\s+$/, '') + '\n'
1088
+ errorCode += errBlock
1089
+ }
1090
+ code += `const ${curName}__reject = function(errMsg){\n${errorCode}};\n`
1091
+ // gen run block
1092
+ code += '__self.resolve = undefined;\n'
1093
+ code += `const ${curName}__resolve = function(){\n`
1094
+ code += ' setTimeout(function(){\n'
1095
+ code += ` if (${curName}.length == 0) {return}\n`
1096
+ code += ` const f = ${curName}.shift()\n`
1097
+ code += ` f(${curName}__resolve, ${curName}__reject);\n`
1098
+ code += ' }, 0);\n'
1099
+ code += '};\n'
1100
+ code += `${curName}__resolve()\n`
1101
+ return this.convLineno(node, false) + code
1102
+ }
1103
+
1104
+ convFuncGetArgsCalcType (funcName, func, node) {
1105
+ const args = []
1106
+ const opts = {}
1107
+ for (let i = 0; i < node.args.length; i++) {
1108
+ const arg = node.args[i]
1109
+ if (i === 0 && arg === null && this.speedMode.invalidSore === 0) {
1110
+ args.push(this.varname('それ'))
1111
+ opts.sore = true
1112
+ } else { args.push(this._convGen(arg, true)) }
1113
+ }
1114
+ return [args, opts]
1115
+ }
1116
+
1117
+ getPluginList () {
1118
+ const r = []
1119
+ for (const name in this.__self.__module) { r.push(name) }
1120
+ return r
1121
+ }
1122
+
1123
+ /**
1124
+ * 関数の呼び出し
1125
+ * @param {Ast} node
1126
+ * @param {boolean} isExpression
1127
+ * @returns string コード
1128
+ */
1129
+ convFunc (node, isExpression) {
1130
+ const funcName = NakoGen.getFuncName(node.name)
1131
+ const res = this.findVar(funcName)
1132
+ if (res === null) {
1133
+ throw NakoSyntaxError.fromNode(`関数『${funcName}』が見当たりません。有効プラグイン=[` + this.getPluginList().join(', ') + ']', node)
1134
+ }
1135
+ let func
1136
+ if (res.i === 0) { // plugin function
1137
+ func = this.__self.funclist[funcName]
1138
+ if (func.type !== 'func') {
1139
+ throw NakoSyntaxError.fromNode(`『${funcName}』は関数ではありません。`, node)
1140
+ }
1141
+ } else {
1142
+ func = this.nako_func[funcName]
1143
+ // 無名関数の可能性
1144
+ if (func === undefined) { func = { return_none: false } }
1145
+ }
1146
+ // 関数の参照渡しか?
1147
+ if (node.type === 'func_pointer') {
1148
+ return res.js
1149
+ }
1150
+ // なでしこで定義した関数?
1151
+ // const isUserFunc = (typeof(func.fn) === 'string')
1152
+ // console.log('@@@', funcName, typeof(func.fn))
1153
+
1154
+ // 関数の参照渡しでない場合
1155
+ // 関数定義より助詞を一つずつ調べる
1156
+ const argsInfo = this.convFuncGetArgsCalcType(funcName, func, node)
1157
+ const args = argsInfo[0]
1158
+ const argsOpts = argsInfo[1]
1159
+ // function
1160
+ this.used_func.add(funcName)
1161
+
1162
+ // 関数呼び出しで、引数の末尾にthisを追加する-システム情報を参照するため
1163
+ args.push('__self')
1164
+ const funcDef = 'function'
1165
+ let funcBegin = ''
1166
+ let funcEnd = ''
1167
+ // setter?
1168
+ if (node.setter) {
1169
+ funcBegin += ';__self.isSetter = true;\n'
1170
+ funcEnd += ';__self.isSetter = false;\n'
1171
+ }
1172
+ // 関数内 (__varslist.length > 3) からプラグイン関数 (res.i === 0) を呼び出すとき、 そのプラグイン関数がpureでなければ
1173
+ // 呼び出しの直前に全てのローカル変数をthis.__localsに入れる。
1174
+ if (res.i === 0 && this.varslistSet.length > 3 && func.pure !== true && this.speedMode.forcePure === 0) { // undefinedはfalseとみなす
1175
+ // 展開されたローカル変数の列挙
1176
+ const localVars = []
1177
+ for (const name of Array.from(this.varsSet.names.values())) {
1178
+ if (NakoGen.isValidIdentifier(name)) {
1179
+ localVars.push({ str: JSON.stringify(name), js: this.varname(name) })
1180
+ }
1181
+ }
1182
+
1183
+ // --- 実行前 ---
1184
+
1185
+ // 全ての展開されていないローカル変数を __self.__locals にコピーする
1186
+ funcBegin += '__self.__locals = __vars;\n'
1187
+
1188
+ // 全ての展開されたローカル変数を __self.__locals に保存する
1189
+ for (const v of localVars) {
1190
+ funcBegin += `__self.__locals[${v.str}] = ${v.js};\n`
1191
+ }
1192
+
1193
+ // --- 実行後 ---
1194
+
1195
+ // 全ての展開されたローカル変数を __self.__locals から受け取る
1196
+ // 「それ」は関数の実行結果を受け取るために使うためスキップ。
1197
+ for (const v of localVars) {
1198
+ if (v.js !== 'それ') {
1199
+ funcEnd += `${v.js} = __self.__locals[${v.str}];\n`
1200
+ }
1201
+ }
1202
+ }
1203
+ // 変数「それ」が補完されていることをヒントとして出力
1204
+ if (argsOpts.sore) { funcBegin += '/*[sore]*/' }
1205
+
1206
+ const indent = (text, n) => {
1207
+ let result = ''
1208
+ for (const line of text.split('\n')) {
1209
+ if (line !== '') {
1210
+ result += ' '.repeat(n) + line + '\n'
1211
+ }
1212
+ }
1213
+ return result
1214
+ }
1215
+
1216
+ // 関数呼び出しコードの構築
1217
+ let argsCode
1218
+ if ((this.warnUndefinedCallingUserFunc === 0 && res.i !== 0) || (this.warnUndefinedCallingSystemFunc === 0 && res.i === 0)) {
1219
+ argsCode = args.join(',')
1220
+ } else {
1221
+ argsCode = ''
1222
+ args.forEach(arg => {
1223
+ if (arg === '__self') {
1224
+ argsCode += `,${arg}`
1225
+ } else {
1226
+ if (res.i === 0) {
1227
+ argsCode += `,(function(a){if(a===undefined){__self.logger.warn('命令『${funcName}』の引数にundefinedを渡しています。',{file:'${node.file}',line:${node.line}});};return a;})(${arg})`
1228
+ } else {
1229
+ argsCode += `,(function(a){if(a===undefined){__self.logger.warn('ユーザ関数『${funcName}』の引数にundefinedを渡しています。',{file:'${node.file}',line:${node.line}});};return a;})(${arg})`
1230
+ }
1231
+ }
1232
+ })
1233
+ argsCode = argsCode.substring(1)
1234
+ }
1235
+
1236
+ let funcCall = `${res.js}(${argsCode})`
1237
+
1238
+ if (res.i === 0 && this.performanceMonitor.systemFunctionBody !== 0) {
1239
+ let key = funcName
1240
+ if (!key) {
1241
+ if (typeof this.performanceMonitor.mumeiId === 'undefined') {
1242
+ this.performanceMonitor.mumeiId = 0
1243
+ }
1244
+ this.performanceMonitor.mumeiId++
1245
+ key = `anous_${this.performanceMonitor.mumeiId}`
1246
+ }
1247
+ funcCall = `(${funcDef} (key, type) {\n` +
1248
+ 'const sbf_start = performance.now() * 1000;\n' +
1249
+ 'try {\n' +
1250
+ 'return ' + funcCall + ';\n' +
1251
+ '} finally {\n' +
1252
+ 'const sbl_time = performance.now() * 1000 - sbf_start;\n' +
1253
+ 'if (!__self.__performance_monitor) {\n' +
1254
+ '__self.__performance_monitor={};\n' +
1255
+ '__self.__performance_monitor[key] = { called:1, totel_usec: sbl_time, min_usec: sbl_time, max_usec: sbl_time, type: type };\n' +
1256
+ '} else if (!__self.__performance_monitor[key]) {\n' +
1257
+ '__self.__performance_monitor[key] = { called:1, totel_usec: sbl_time, min_usec: sbl_time, max_usec: sbl_time, type: type };\n' +
1258
+ '} else {\n' +
1259
+ '__self.__performance_monitor[key].called++;\n' +
1260
+ '__self.__performance_monitor[key].totel_usec+=sbl_time;\n' +
1261
+ 'if(__self.__performance_monitor[key].min_usec>sbl_time){__self.__performance_monitor[key].min_usec=sbl_time;}\n' +
1262
+ 'if(__self.__performance_monitor[key].max_usec<sbl_time){__self.__performance_monitor[key].max_usec=sbl_time;}\n' +
1263
+ `}}})('${funcName}_body', 'sysbody')\n`
1264
+ }
1265
+
1266
+ let code = ''
1267
+ if (func.return_none) {
1268
+ if (funcEnd === '') {
1269
+ if (funcBegin === '') {
1270
+ code = `${funcCall};\n`
1271
+ } else {
1272
+ code = `${funcBegin} ${funcCall};\n`
1273
+ }
1274
+ } else {
1275
+ code = `${funcBegin}try {\n${indent(funcCall, 1)};\n} finally {\n${indent(funcEnd, 1)}}\n`
1276
+ }
1277
+ } else {
1278
+ let sorePrefex = ''
1279
+ if (this.speedMode.invalidSore === 0) {
1280
+ sorePrefex = `${this.varname('それ')} = `
1281
+ }
1282
+ if (funcBegin === '' && funcEnd === '') {
1283
+ code = `(${sorePrefex}${funcCall})`
1284
+ } else {
1285
+ if (funcEnd === '') {
1286
+ code = `(${funcDef}(){\n${indent(`${funcBegin};\nreturn ${sorePrefex} ${funcCall}`, 1)}}).call(this)`
1287
+ } else {
1288
+ code = `(${funcDef}(){\n${indent(`${funcBegin}try {\n${indent(`return ${sorePrefex}${funcCall};`, 1)}\n} finally {\n${indent(funcEnd, 1)}}`, 1)}}).call(this)`
1289
+ }
1290
+ }
1291
+ // ...して
1292
+ if (node.josi === 'して' || (node.josi === '' && !isExpression)) { code += ';\n' }
1293
+ }
1294
+
1295
+ if (res.i === 0 && this.performanceMonitor.systemFunction !== 0) {
1296
+ code = '(function (key, type) {\n' +
1297
+ 'const sf_start = performance.now() * 1000;\n' +
1298
+ 'try {\n' +
1299
+ 'return ' + code + ';\n' +
1300
+ '} finally {\n' +
1301
+ 'const sl_time = performance.now() * 1000 - sf_start;\n' +
1302
+ 'if (!__self.__performance_monitor) {\n' +
1303
+ '__self.__performance_monitor={};\n' +
1304
+ '__self.__performance_monitor[key] = { called:1, totel_usec: sl_time, min_usec: sl_time, max_usec: sl_time, type: type };\n' +
1305
+ '} else if (!__self.__performance_monitor[key]) {\n' +
1306
+ '__self.__performance_monitor[key] = { called:1, totel_usec: sl_time, min_usec: sl_time, max_usec: sl_time, type: type };\n' +
1307
+ '} else {\n' +
1308
+ '__self.__performance_monitor[key].called++;\n' +
1309
+ '__self.__performance_monitor[key].totel_usec+=sl_time;\n' +
1310
+ 'if(__self.__performance_monitor[key].min_usec>sl_time){__self.__performance_monitor[key].min_usec=sl_time;}\n' +
1311
+ 'if(__self.__performance_monitor[key].max_usec<sl_time){__self.__performance_monitor[key].max_usec=sl_time;}\n' +
1312
+ `}}})('${funcName}_sys', 'system')\n`
1313
+ }
1314
+
1315
+ return code
1316
+ }
1317
+
1318
+ convRenbun (node) {
1319
+ const right = this._convGen(node.right, true)
1320
+ const left = this._convGen(node.left, false)
1321
+ return `(function(){${left}; return ${right}}).call(this)`
1322
+ }
1323
+
1324
+ convOp (node) {
1325
+ const OP_TBL = { // トークン名からJS演算子
1326
+ '&': '+""+',
1327
+ eq: '==',
1328
+ noteq: '!=',
1329
+ '===': '===',
1330
+ '!==': '!==',
1331
+ gt: '>',
1332
+ lt: '<',
1333
+ gteq: '>=',
1334
+ lteq: '<=',
1335
+ and: '&&',
1336
+ or: '||',
1337
+ shift_l: '<<',
1338
+ shift_r: '>>',
1339
+ shift_r0: '>>>'
1340
+ }
1341
+ let op = node.operator // 演算子
1342
+ let right = this._convGen(node.right, true)
1343
+ let left = this._convGen(node.left, true)
1344
+ if (op === '+' && this.speedMode.implicitTypeCasting === 0) {
1345
+ if (node.left.type !== 'number') {
1346
+ left = `parseFloat(${left})`
1347
+ }
1348
+ if (node.right.type !== 'number') {
1349
+ right = `parseFloat(${right})`
1350
+ }
1351
+ }
1352
+ // 階乗
1353
+ if (op === '^') { return '(Math.pow(' + left + ',' + right + '))' }
1354
+
1355
+ // 一般的なオペレータに変換
1356
+ if (OP_TBL[op]) { op = OP_TBL[op] }
1357
+ //
1358
+ return `(${left} ${op} ${right})`
1359
+ }
1360
+
1361
+ convLet (node) {
1362
+ // もし値が省略されていたら、変数「それ」に代入する
1363
+ let value = null
1364
+ if (this.speedMode.invalidSore === 0) { value = this.varname('それ') }
1365
+ if (node.value) { value = this._convGen(node.value, true) }
1366
+ if (value == null) {
1367
+ throw NakoSyntaxError.fromNode('代入する先の変数名がありません。', node)
1368
+ }
1369
+ // 変数名
1370
+ const name = node.name.value
1371
+ const res = this.findVar(name)
1372
+ let code = ''
1373
+ if (res === null) {
1374
+ this.varsSet.names.add(name)
1375
+ code = `${this.varname(name)}=${value};`
1376
+ } else {
1377
+ // 定数ならエラーを出す
1378
+ if (this.varslistSet[res.i].readonly.has(name)) {
1379
+ throw NakoSyntaxError.fromNode(
1380
+ `定数『${name}』は既に定義済みなので、値を代入することはできません。`, node)
1381
+ }
1382
+ code = `${res.js}=${value};`
1383
+ }
1384
+
1385
+ return ';' + this.convLineno(node, false) + code + '\n'
1386
+ }
1387
+
1388
+ convDefLocalVar (node) {
1389
+ const value = (node.value === null) ? 'null' : this._convGen(node.value, true)
1390
+ const name = node.name.value
1391
+ const vtype = node.vartype // 変数 or 定数
1392
+ // 二重定義?
1393
+ if (this.varsSet.names.has(name)) { throw NakoSyntaxError.fromNode(`${vtype}『${name}』の二重定義はできません。`, node) }
1394
+
1395
+ //
1396
+ this.varsSet.names.add(name)
1397
+ if (vtype === '定数') {
1398
+ this.varsSet.readonly.add(name)
1399
+ }
1400
+ const code = `${this.varname(name)}=${value};\n`
1401
+ return this.convLineno(node, false) + code
1402
+ }
1403
+
1404
+ // #563 複数変数への代入
1405
+ convDefLocalVarlist (node) {
1406
+ let code = ''
1407
+ const vtype = node.vartype // 変数 or 定数
1408
+ const value = (node.value === null) ? 'null' : this._convGen(node.value, true)
1409
+ this.loop_id++
1410
+ const varI = `$nako_i${this.loop_id}`
1411
+ code += `${varI}=${value}\n`
1412
+ code += `if (!(${varI} instanceof Array)) { ${varI}=[${varI}] }\n`
1413
+ for (const i in node.names) {
1414
+ const nameObj = node.names[i]
1415
+ const name = nameObj.value
1416
+ // 二重定義?
1417
+ if (this.varsSet.names.has(name)) {
1418
+ // 複数変数文では、二重定義も許容する #1027
1419
+ // throw NakoSyntaxError.fromNode(`${vtype}『${name}』の二重定義はできません。`, node)
1420
+ }
1421
+ this.varsSet.names.add(name)
1422
+ if (vtype === '定数') {
1423
+ this.varsSet.readonly.add(name)
1424
+ }
1425
+ const vname = this.varname(name)
1426
+ code += `${vname}=${varI}[${i}];\n`
1427
+ }
1428
+ return this.convLineno(node, false) + code
1429
+ }
1430
+
1431
+ convString (node) {
1432
+ let value = '' + node.value
1433
+ const mode = node.mode
1434
+ value = value.replace(/\\/g, '\\\\')
1435
+ value = value.replace(/"/g, '\\"')
1436
+ value = value.replace(/\r/g, '\\r')
1437
+ value = value.replace(/\n/g, '\\n')
1438
+ if (mode === 'ex') {
1439
+ const rf = (a, name) => {
1440
+ return '"+' + this.genVar(name, node) + '+"'
1441
+ }
1442
+ value = value.replace(/\{(.+?)\}/g, rf)
1443
+ value = value.replace(/{(.+?)}/g, rf)
1444
+ }
1445
+ return '"' + value + '"'
1446
+ }
1447
+
1448
+ convTryExcept (node) {
1449
+ const block = this._convGen(node.block, false)
1450
+ const errBlock = this._convGen(node.errBlock, false)
1451
+ return this.convLineno(node, false) +
1452
+ `try {\n${block}\n} catch (e) {\n` +
1453
+ ' __v0["エラーメッセージ"] = e.message;\n' +
1454
+ ';\n' +
1455
+ `${errBlock}}\n`
1456
+ }
1457
+ }
1458
+
1459
+ module.exports = NakoGen