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,2109 @@
1
+ // @ts-nocheck
2
+ const { NakoRuntimeError } = require('./nako_errors')
3
+ const NakoVersion = require('./nako_version')
4
+
5
+ const PluginSystem = {
6
+ 'meta': {
7
+ type: 'const',
8
+ value: {
9
+ pluginName: 'plugin_system', // プラグインの名前
10
+ pluginVersion: '3.2.24', // プラグインのバージョン
11
+ nakoRuntime: ['wnako', 'cnako', 'phpnako'], // 対象ランタイム
12
+ nakoVersion: '^3.2.24' // 要求なでしこバージョン
13
+ }
14
+ },
15
+ '初期化': {
16
+ type: 'func',
17
+ josi: [],
18
+ pure: false,
19
+ fn: function (sys) {
20
+ sys.__v0['ナデシコバージョン'] = typeof NakoVersion === 'undefined' ? '?' : NakoVersion.version
21
+ // なでしこの関数や変数を探して返す
22
+ sys.__findVar = function (nameStr, def) {
23
+ if (typeof nameStr === 'function') { return nameStr }
24
+ if (sys.__locals[nameStr]) { return sys.__locals[nameStr] }
25
+ for (let i = 2; i >= 0; i--) {
26
+ const scope = sys.__varslist[i]
27
+ if (scope[nameStr]) { return scope[nameStr] }
28
+ }
29
+ return def
30
+ }
31
+ // 文字列から関数を探す
32
+ sys.__findFunc = function (nameStr, parentFunc) {
33
+ const f = sys.__findVar(nameStr)
34
+ if (typeof f === 'function') { return f }
35
+ throw new Error(`『${parentFunc}』に実行できない関数が指定されました。`)
36
+ }
37
+ // システム関数を実行
38
+ sys.__exec = function (func, params) {
39
+ // システム命令を優先
40
+ const f0 = sys.__v0[func]
41
+ if (f0) { return f0.apply(this, params) }
42
+ // グローバル・ローカルを探す
43
+ const f = sys.__findVar(func)
44
+ if (!f) { throw new Error('システム関数でエイリアスの指定ミス:' + func) }
45
+ return f.apply(this, params)
46
+ }
47
+ // タイマーに関する処理(タイマーは「!クリア」で全部停止する)
48
+ sys.__timeout = []
49
+ sys.__interval = []
50
+ }
51
+ },
52
+ '!クリア': {
53
+ type: 'func',
54
+ josi: [],
55
+ pure: false,
56
+ fn: function (sys) {
57
+ sys.__exec('全タイマー停止', [sys])
58
+ if (sys.__genMode === '非同期モード') { sys.__stopAsync(sys) }
59
+ }
60
+ },
61
+
62
+ // @システム定数
63
+ 'ナデシコバージョン': { type: 'const', value: '?' }, // @なでしこばーじょん
64
+ 'ナデシコエンジン': { type: 'const', value: 'nadesi.com/v3' }, // @なでしこえんじん
65
+ 'ナデシコ種類': { type: 'const', value: 'wnako3/cnako3' }, // @なでしこしゅるい
66
+ 'はい': { type: 'const', value: 1 }, // @はい
67
+ 'いいえ': { type: 'const', value: 0 }, // @いいえ
68
+ '真': { type: 'const', value: 1 }, // @しん
69
+ '偽': { type: 'const', value: 0 }, // @ぎ
70
+ '永遠': { type: 'const', value: 1 }, // @えいえん
71
+ 'オン': { type: 'const', value: 1 }, // @おん
72
+ 'オフ': { type: 'const', value: 0 }, // @おふ
73
+ '改行': { type: 'const', value: '\n' }, // @かいぎょう
74
+ 'タブ': { type: 'const', value: '\t' }, // @たぶ
75
+ 'カッコ': { type: 'const', value: '「' }, // @かっこ
76
+ 'カッコ閉': { type: 'const', value: '」' }, // @かっことじ
77
+ '波カッコ': { type: 'const', value: '{' }, // @なみかっこ
78
+ '波カッコ閉': { type: 'const', value: '}' }, // @なみかっことじ
79
+ 'OK': { type: 'const', value: true }, // @OK
80
+ 'NG': { type: 'const', value: false }, // @NG
81
+ 'キャンセル': { type: 'const', value: 0 }, // @きゃんせる
82
+ 'PI': { type: 'const', value: Math.PI }, // @PI
83
+ '空': { type: 'const', value: '' }, // @から
84
+ 'NULL': { type: 'const', value: null }, // @NULL
85
+ 'undefined': { type: 'const', value: undefined }, // @undefined
86
+ '未定義': { type: 'const', value: undefined }, // @みていぎ
87
+ 'エラーメッセージ': { type: 'const', value: '' }, // @えらーめっせーじ
88
+ '対象': { type: 'const', value: '' }, // @たいしょう
89
+ '対象キー': { type: 'const', value: '' }, // @たいしょうきー
90
+ '回数': { type: 'const', value: '' }, // @かいすう
91
+ 'CR': { type: 'const', value: '\r' }, // @CR
92
+ 'LF': { type: 'const', value: '\n' }, // @LF
93
+ '非数': { type: 'const', value: NaN }, // @ひすう
94
+ '無限大': { type: 'const', value: Infinity }, // @むげんだい
95
+ '空配列': { // @空の配列を返す。『[]』と同義。 // @からはいれつ
96
+ type: 'func',
97
+ josi: [],
98
+ pure: true,
99
+ fn: function (sys) {
100
+ return []
101
+ }
102
+ },
103
+ '空辞書': { // @空の辞書型を返す。『{}』と同義。 // @からじしょ
104
+ type: 'func',
105
+ josi: [],
106
+ pure: true,
107
+ fn: function (sys) {
108
+ return {}
109
+ }
110
+ },
111
+ '空ハッシュ': { // @空のハッシュを返す(v3.2以降非推奨) // @からはっしゅ
112
+ type: 'func',
113
+ josi: [],
114
+ pure: true,
115
+ fn: function (sys) {
116
+ return {}
117
+ }
118
+ },
119
+ '空オブジェクト': { // @空のオブジェクトを返す(v3.2以降非推奨) // @からおぶじぇくと
120
+ type: 'func',
121
+ josi: [],
122
+ pure: false,
123
+ fn: function (sys) {
124
+ return sys.__exec('空ハッシュ', [sys])
125
+ }
126
+ },
127
+
128
+ // @標準出力
129
+ '表示': { // @Sを表示 // @ひょうじ
130
+ type: 'func',
131
+ josi: [['を', 'と']],
132
+ pure: true,
133
+ fn: function (s, sys) {
134
+ sys.__varslist[0]['表示ログ'] += (s + '\n')
135
+ sys.logger.send('stdout', s + '')
136
+ },
137
+ return_none: true
138
+ },
139
+ '表示ログ': { type: 'const', value: '' }, // @ひょうじろぐ
140
+ '表示ログクリア': { // @表示ログを空にする // @ひょうじろぐくりあ
141
+ type: 'func',
142
+ josi: [],
143
+ pure: true,
144
+ fn: function (sys) {
145
+ sys.__varslist[0]['表示ログ'] = ''
146
+ },
147
+ return_none: true
148
+ },
149
+ '言': { // @Sを表示 // @いう
150
+ type: 'func',
151
+ josi: [['を', 'と']],
152
+ pure: true,
153
+ fn: function (s, sys) {
154
+ sys.logger.send('stdout', s + '')
155
+ },
156
+ return_none: true
157
+ },
158
+ 'コンソール表示': { // @Sをコンソール表示する(console.log) // @こんそーるひょうじ
159
+ type: 'func',
160
+ josi: [['を', 'と']],
161
+ pure: true,
162
+ fn: function (s, sys) {
163
+ console.log(s)
164
+ },
165
+ return_none: true
166
+ },
167
+
168
+ // @四則演算
169
+ '足': { // @AとBを足す // @たす
170
+ type: 'func',
171
+ josi: [['に', 'と'], ['を']],
172
+ isVariableJosi: false,
173
+ pure: true,
174
+ fn: function (a, b) {
175
+ return a + b
176
+ }
177
+ },
178
+ '引': { // @AからBを引く // @ひく
179
+ type: 'func',
180
+ josi: [['から'], ['を']],
181
+ pure: true,
182
+ fn: function (a, b) {
183
+ return a - b
184
+ }
185
+ },
186
+ '掛': { // @AにBを掛ける // @かける
187
+ type: 'func',
188
+ josi: [['に', 'と'], ['を']],
189
+ pure: true,
190
+ fn: function (a, b) {
191
+ return a * b
192
+ }
193
+ },
194
+ '倍': { // @AのB倍を求める // @ばい
195
+ type: 'func',
196
+ josi: [['の'], ['']],
197
+ pure: true,
198
+ fn: function (a, b) {
199
+ return a * b
200
+ }
201
+ },
202
+ '割': { // @AをBで割る // @わる
203
+ type: 'func',
204
+ josi: [['を'], ['で']],
205
+ pure: true,
206
+ fn: function (a, b) {
207
+ return a / b
208
+ }
209
+ },
210
+ '割余': { // @AをBで割った余りを求める // @わったあまり
211
+ type: 'func',
212
+ josi: [['を'], ['で']],
213
+ pure: true,
214
+ fn: function (a, b) {
215
+ return a % b
216
+ }
217
+ },
218
+ '以上': { // @AがB以上か // @いじょう
219
+ type: 'func',
220
+ josi: [['が'], ['']],
221
+ pure: true,
222
+ fn: function (a, b) {
223
+ return a >= b
224
+ }
225
+ },
226
+ '以下': { // @AがB以下か // @いか
227
+ type: 'func',
228
+ josi: [['が'], ['']],
229
+ pure: true,
230
+ fn: function (a, b) {
231
+ return a <= b
232
+ }
233
+ },
234
+ '未満': { // @AがB未満か // @みまん
235
+ type: 'func',
236
+ josi: [['が'], ['']],
237
+ pure: true,
238
+ fn: function (a, b) {
239
+ return a < b
240
+ }
241
+ },
242
+ '超': { // @AがB超か // @ちょう
243
+ type: 'func',
244
+ josi: [['が'], ['']],
245
+ pure: true,
246
+ fn: function (a, b) {
247
+ return a > b
248
+ }
249
+ },
250
+ '等': { // @AがBと等しいか // @ひとしい
251
+ type: 'func',
252
+ josi: [['が'], ['と']],
253
+ pure: true,
254
+ fn: function (a, b) {
255
+ return a === b
256
+ }
257
+ },
258
+ '等無': { // @AがBと等しくないか // @ひとしくない
259
+ type: 'func',
260
+ josi: [['が'], ['と']],
261
+ pure: true,
262
+ fn: function (a, b) {
263
+ return a !== b
264
+ }
265
+ },
266
+ '一致': { // @AがBと一致するか(配列や辞書も比較可能) // @いっち
267
+ type: 'func',
268
+ josi: [['が'], ['と']],
269
+ pure: true,
270
+ fn: function (a, b) {
271
+ // オブジェクトの場合、JSONに変換して比較
272
+ if (typeof (a) === 'object') {
273
+ const jsonA = JSON.stringify(a)
274
+ const jsonB = JSON.stringify(b)
275
+ return jsonA === jsonB
276
+ }
277
+ return a === b
278
+ }
279
+ },
280
+ '不一致': { // @AがBと不一致か(配列や辞書も比較可能) // @ふいっち
281
+ type: 'func',
282
+ josi: [['が'], ['と']],
283
+ pure: true,
284
+ fn: function (a, b) {
285
+ // オブジェクトの場合、JSONに変換して比較
286
+ if (typeof (a) === 'object') {
287
+ const jsonA = JSON.stringify(a)
288
+ const jsonB = JSON.stringify(b)
289
+ return jsonA !== jsonB
290
+ }
291
+ return a !== b
292
+ }
293
+ },
294
+ '範囲内': { // @VがAからBの範囲内か // @はんいない
295
+ type: 'func',
296
+ josi: [['が'], ['から'], ['の']],
297
+ pure: true,
298
+ fn: function (v, a, b) {
299
+ return (a <= v) && (v <= b)
300
+ }
301
+ },
302
+ '連続加算': { // @A1+A2+A3...にBを足す // @れんぞくかさん
303
+ type: 'func',
304
+ josi: [['を'], ['に', 'と']],
305
+ isVariableJosi: true,
306
+ pure: true,
307
+ fn: function (b, ...a) {
308
+ // 末尾のシステム変数を除外
309
+ a.pop()
310
+ a.push(b)
311
+ return a.reduce((p, c) => p + c)
312
+ }
313
+ },
314
+
315
+ // @敬語
316
+ 'ください': { // @敬語対応のため // @ください
317
+ type: 'func',
318
+ josi: [],
319
+ pure: true,
320
+ fn: function (sys) {
321
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
322
+ sys.__reisetu++
323
+ },
324
+ return_none: true
325
+ },
326
+ 'お願': { // @ソースコードを読む人を気持ちよくする // @おねがいします
327
+ type: 'func',
328
+ josi: [],
329
+ pure: true,
330
+ fn: function (sys) {
331
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
332
+ sys.__reisetu++
333
+ },
334
+ return_none: true
335
+ },
336
+ 'です': { // @ソースコードを読む人を気持ちよくする // @です
337
+ type: 'func',
338
+ josi: [],
339
+ pure: true,
340
+ fn: function (sys) {
341
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
342
+ sys.__reisetu++
343
+ },
344
+ return_none: true
345
+ },
346
+ '拝啓': { // @ソースコードを読む人を気持ちよくする // @はいけい
347
+ type: 'func',
348
+ josi: [],
349
+ pure: true,
350
+ fn: function (sys) {
351
+ sys.__reisetu = 0
352
+ },
353
+ return_none: true
354
+ },
355
+ '礼節レベル取得': { // @(お遊び)敬語を何度使ったか返す // @おねがいします
356
+ type: 'func',
357
+ josi: [],
358
+ pure: true,
359
+ fn: function (sys) {
360
+ if (!sys.__reisetu) { sys.__reisetu = 0 }
361
+ return sys.__reisetu
362
+ }
363
+ },
364
+
365
+ // @特殊命令
366
+ 'JS実行': { // @JavaScriptのコードSRCを実行する(変数sysでなでしこシステムを参照できる) // @JSじっこう
367
+ type: 'func',
368
+ josi: [['を', 'で']],
369
+ pure: true,
370
+ fn: function (src, sys) {
371
+ return eval(src) // eslint-disable-line
372
+ }
373
+ },
374
+ 'JSオブジェクト取得': { // @なでしこで定義した関数や変数nameのJavaScriptオブジェクトを取得する // @JSおぶじぇくとしゅとく
375
+ type: 'func',
376
+ josi: [['の']],
377
+ pure: false,
378
+ fn: function (name, sys) {
379
+ return sys.__findVar(name, null)
380
+ }
381
+ },
382
+ 'JS関数実行': { // @JavaScriptの関数NAMEを引数ARGS(配列)で実行する // @JSかんすうしゅとく
383
+ type: 'func',
384
+ josi: [['を'], ['で']],
385
+ fn: function (name, args, sys) {
386
+ // nameが文字列ならevalして関数を得る
387
+ // eslint-disable-next-line no-eval
388
+ if (typeof name === 'string') { name = eval(name) }
389
+ if (typeof name !== 'function') { throw new Error('JS関数取得で実行できません。') }
390
+
391
+ // argsがArrayでなければArrayに変換する
392
+ if (!(args instanceof Array)) { args = [args] }
393
+
394
+ // 実行
395
+ return name.apply(null, args)
396
+ }
397
+ },
398
+ 'JSメソッド実行': { // @JavaScriptのオブジェクトOBJのメソッドMを引数ARGS(配列)で実行する // @JSめそっどじっこう
399
+ type: 'func',
400
+ josi: [['の'], ['を'], ['で']],
401
+ fn: function (obj, m, args, sys) {
402
+ // objが文字列ならevalして関数を得る
403
+ // eslint-disable-next-line no-eval
404
+ if (typeof obj === 'string') { obj = eval(obj) }
405
+ if (typeof obj !== 'object') { throw new Error('JSオブジェクトを取得できませんでした。') }
406
+
407
+ // method を求める
408
+ if (typeof m !== 'function') {
409
+ m = obj[m]
410
+ }
411
+
412
+ // argsがArrayでなければArrayに変換する
413
+ if (!(args instanceof Array)) { args = [args] }
414
+
415
+ // 実行
416
+ return m.apply(obj, args)
417
+ }
418
+ },
419
+
420
+ 'ナデシコ': { // @なでしこのコードCODEを実行する // @なでしこする
421
+ type: 'func',
422
+ josi: [['を', 'で']],
423
+ fn: function (code, sys) {
424
+ sys.__varslist[0]['表示ログ'] = ''
425
+ sys.__self.runEx(code, 'immediate-code.nako3', { resetEnv: false, resetLog: true })
426
+ const out = sys.__varslist[0]['表示ログ'] + ''
427
+ if (out) {
428
+ sys.logger.send('stdout', out)
429
+ }
430
+ return out
431
+ }
432
+ },
433
+ 'ナデシコ続': { // @なでしこのコードCODEを実行する // @なでしこつづける
434
+ type: 'func',
435
+ josi: [['を', 'で']],
436
+ fn: function (code, sys) {
437
+ sys.__self.runEx(code, 'immediate-code.nako3', { resetEnv: false, resetLog: false })
438
+ const out = sys.__varslist[0]['表示ログ'] + ''
439
+ if (out) {
440
+ sys.logger.send('stdout', out)
441
+ }
442
+ return out
443
+ }
444
+ },
445
+ '実行': { // @ 無名関数(あるいは、文字列で関数名を指定)Fを実行する(Fが関数でなければ無視する) // @じっこう
446
+ type: 'func',
447
+ josi: [['を', 'に', 'で']],
448
+ pure: false,
449
+ fn: function (f, sys) {
450
+ // #938 の規則に従って処理
451
+ // 引数が関数なら実行
452
+ if (typeof f === 'function') { return f(sys) }
453
+ // 文字列なら関数に変換できるか判定して実行
454
+ if (typeof f === 'string') {
455
+ const tf = sys.__findFunc(f, '実行')
456
+ if (typeof tf === 'function') {
457
+ return tf(sys)
458
+ }
459
+ }
460
+ // それ以外ならそのまま値を返す
461
+ return f
462
+ }
463
+ },
464
+ '実行時間計測': { // @ 関数Fを実行して要した時間をミリ秒で返す // @じっこうじかんけいそく
465
+ type: 'func',
466
+ josi: [['の']],
467
+ pure: false,
468
+ fn: function (f, sys) {
469
+ if (typeof f === 'string') { f = sys.__findFunc(f, '実行時間計測') }
470
+ //
471
+ if (performance && performance.now) {
472
+ const t1 = performance.now()
473
+ f(sys)
474
+ const t2 = performance.now()
475
+ return (t2 - t1)
476
+ } else {
477
+ const t1 = Date.now()
478
+ f(sys)
479
+ const t2 = Date.now()
480
+ return (t2 - t1)
481
+ }
482
+ }
483
+ },
484
+
485
+ // @型変換
486
+ '変数型確認': { // @変数Vの型を返す // @へんすうかたかくにん
487
+ type: 'func',
488
+ josi: [['の']],
489
+ pure: true,
490
+ fn: function (v) {
491
+ return typeof (v)
492
+ }
493
+ },
494
+ 'TYPEOF': { // @変数Vの型を返す // @TYPEOF
495
+ type: 'func',
496
+ josi: [['の']],
497
+ pure: true,
498
+ fn: function (v) {
499
+ return typeof (v)
500
+ }
501
+ },
502
+ '文字列変換': { // @値Vを文字列に変換 // @もじれつへんかん
503
+ type: 'func',
504
+ josi: [['を']],
505
+ pure: true,
506
+ fn: function (v) {
507
+ return String(v)
508
+ }
509
+ },
510
+ 'TOSTR': { // @値Vを文字列に変換 // @TOSTR
511
+ type: 'func',
512
+ josi: [['を']],
513
+ pure: true,
514
+ fn: function (v) {
515
+ return String(v)
516
+ }
517
+ },
518
+ '整数変換': { // @値Vを整数に変換 // @せいすうへんかん
519
+ type: 'func',
520
+ josi: [['を']],
521
+ pure: true,
522
+ fn: function (v) {
523
+ return parseInt(v)
524
+ }
525
+ },
526
+ 'TOINT': { // @値Vを整数に変換 // @TOINT
527
+ type: 'func',
528
+ josi: [['を']],
529
+ pure: true,
530
+ fn: function (v) {
531
+ return parseInt(v)
532
+ }
533
+ },
534
+ '実数変換': { // @値Vを実数に変換 // @じっすうへんかん
535
+ type: 'func',
536
+ josi: [['を']],
537
+ pure: true,
538
+ fn: function (v) {
539
+ return parseFloat(v)
540
+ }
541
+ },
542
+ 'TOFLOAT': { // @値Vを実数に変換 // @TOFLOAT
543
+ type: 'func',
544
+ josi: [['を']],
545
+ pure: true,
546
+ fn: function (v) {
547
+ return parseFloat(v)
548
+ }
549
+ },
550
+ 'INT': { // @値Vを整数に変換 // @INT
551
+ type: 'func',
552
+ josi: [['の']],
553
+ pure: true,
554
+ fn: function (v) {
555
+ return parseInt(v)
556
+ }
557
+ },
558
+ 'FLOAT': { // @値Vを実数に変換 // @FLOAT
559
+ type: 'func',
560
+ josi: [['の']],
561
+ pure: true,
562
+ fn: function (v) {
563
+ return parseFloat(v)
564
+ }
565
+ },
566
+ 'NAN判定': { // @値VがNaNかどうかを判定 // @NANはんてい
567
+ type: 'func',
568
+ josi: [['を']],
569
+ pure: true,
570
+ fn: function (v) {
571
+ return isNaN(v)
572
+ }
573
+ },
574
+ 'HEX': { // @値Vを16進数に変換 // @HEX
575
+ type: 'func',
576
+ josi: [['の']],
577
+ pure: true,
578
+ fn: function (a) {
579
+ return parseInt(a).toString(16)
580
+ }
581
+ },
582
+ '進数変換': { // @値VをN進数に変換 // @しんすうへんかん
583
+ type: 'func',
584
+ josi: [['を', 'の'],['']],
585
+ pure: true,
586
+ fn: function (v, n) {
587
+ return parseInt(v).toString(n)
588
+ }
589
+ },
590
+ 'RGB': { // @HTML用のカラーコードを返すRGB(R,G,B)で各値は0-255 // @RGB
591
+ type: 'func',
592
+ josi: [['と'], ['の'], ['で']],
593
+ pure: true,
594
+ fn: function (r, g, b) {
595
+ const z2 = (v) => {
596
+ const v2 = '00' + parseInt(v).toString(16)
597
+ return v2.substr(v2.length - 2, 2)
598
+ }
599
+ return '#' + z2(r) + z2(g) + z2(b)
600
+ }
601
+ },
602
+
603
+ // @論理演算
604
+ '論理OR': { // @(ビット演算で)AとBの論理和を返す(v1非互換)。 // @ろんりOR
605
+ type: 'func',
606
+ josi: [['と'], ['の']],
607
+ pure: true,
608
+ fn: function (a, b) {
609
+ return (a || b)
610
+ }
611
+ },
612
+ '論理AND': { // @(ビット演算で)AとBの論理積を返す(v1非互換)。日本語の「AかつB」に相当する // @ろんりAND
613
+ type: 'func',
614
+ josi: [['と'], ['の']],
615
+ pure: true,
616
+ fn: function (a, b) {
617
+ return (a && b)
618
+ }
619
+ },
620
+ '論理NOT': { // @値Vが0ならば1、それ以外ならば0を返す(v1非互換) // @ろんりNOT
621
+ type: 'func',
622
+ josi: [['の']],
623
+ pure: true,
624
+ fn: function (v) {
625
+ return (!v) ? 1 : 0
626
+ }
627
+ },
628
+
629
+ // @ビット演算
630
+ 'OR': { // @(ビット演算で)AとBの論理和を返す。 // @OR
631
+ type: 'func',
632
+ josi: [['と'], ['の']],
633
+ pure: true,
634
+ fn: function (a, b) {
635
+ return (a | b)
636
+ }
637
+ },
638
+ 'AND': { // @(ビット演算で)AとBの論理積を返す。日本語の「AかつB」に相当する // @AND
639
+ type: 'func',
640
+ josi: [['と'], ['の']],
641
+ pure: true,
642
+ fn: function (a, b) {
643
+ return (a & b)
644
+ }
645
+ },
646
+ 'XOR': { // @(ビット演算で)AとBの排他的論理和を返す。// @XOR
647
+ type: 'func',
648
+ josi: [['と'], ['の']],
649
+ pure: true,
650
+ fn: function (a, b) {
651
+ return (a ^ b)
652
+ }
653
+ },
654
+ 'NOT': { // @(ビット演算で)vの各ビットを反転して返す。// @NOT
655
+ type: 'func',
656
+ josi: [['の']],
657
+ pure: true,
658
+ fn: function (v) {
659
+ return (~v)
660
+ }
661
+ },
662
+ 'SHIFT_L': { // @VをAビット左へシフトして返す // @SHIFT_L
663
+ type: 'func',
664
+ josi: [['を'], ['で']],
665
+ pure: true,
666
+ fn: function (a, b) {
667
+ return (a << b)
668
+ }
669
+ },
670
+ 'SHIFT_R': { // @VをAビット右へシフトして返す(符号を維持する) // @SHIFT_R
671
+ type: 'func',
672
+ josi: [['を'], ['で']],
673
+ pure: true,
674
+ fn: function (a, b) {
675
+ return (a >> b)
676
+ }
677
+ },
678
+ 'SHIFT_UR': { // @VをAビット右へシフトして返す(符号を維持しない、0で埋める) // @SHIFT_UR
679
+ type: 'func',
680
+ josi: [['を'], ['で']],
681
+ pure: true,
682
+ fn: function (a, b) {
683
+ return (a >>> b)
684
+ }
685
+ },
686
+
687
+ // @文字列処理
688
+ '文字数': { // @文字列Vの文字数を返す // @もじすう
689
+ type: 'func',
690
+ josi: [['の']],
691
+ pure: true,
692
+ fn: function (v) {
693
+ if (!Array.from) { return String(v).length }
694
+ return Array.from(v).length
695
+ }
696
+ },
697
+ '何文字目': { // @文字列SでAが何文字目にあるか調べて返す // @なんもじめ
698
+ type: 'func',
699
+ josi: [['で', 'の'], ['が']],
700
+ pure: true,
701
+ fn: function (s, a) {
702
+ return String(s).indexOf(a) + 1
703
+ }
704
+ },
705
+ 'CHR': { // @文字コードから文字を返す // @CHR
706
+ type: 'func',
707
+ josi: [['の']],
708
+ pure: true,
709
+ fn: function (v) {
710
+ if (!String.fromCodePoint) { return String.fromCharCode(v) }
711
+ return String.fromCodePoint(v)
712
+ }
713
+ },
714
+ 'ASC': { // @文字列Vの最初の文字の文字コードを返す // @ASC
715
+ type: 'func',
716
+ josi: [['の']],
717
+ pure: true,
718
+ fn: function (v) {
719
+ if (!String.prototype.codePointAt) { return String(v).charCodeAt(0) }
720
+ return String(v).codePointAt(0)
721
+ }
722
+ },
723
+ '文字挿入': { // @文字列SのI文字目に文字列Aを挿入する // @もじそうにゅう
724
+ type: 'func',
725
+ josi: [['で', 'の'], ['に', 'へ'], ['を']],
726
+ pure: true,
727
+ fn: function (s, i, a) {
728
+ if (i <= 0) { i = 1 }
729
+ const ss = String(s)
730
+ const mae = ss.substr(0, i - 1)
731
+ const usi = ss.substr(i - 1)
732
+ return mae + a + usi
733
+ }
734
+ },
735
+ '文字検索': { // @文字列Sで文字列A文字目からBを検索。見つからなければ0を返す。(類似命令に『何文字目』がある)(v1非互換) // @もじけんさく
736
+ type: 'func',
737
+ josi: [['で', 'の'], ['から'], ['を']],
738
+ pure: true,
739
+ fn: function (s, a, b) {
740
+ let str = String(s)
741
+ str = str.substr(a)
742
+ const res = str.indexOf(b)
743
+ if (res === -1) { return 0 }
744
+ return res + 1 + a
745
+ }
746
+ },
747
+ '追加': { // @文字列SにAを追加して返す(v1非互換) // @ついか
748
+ type: 'func',
749
+ josi: [['で', 'に', 'へ'], ['を']],
750
+ pure: true,
751
+ fn: function (s, a) {
752
+ return String(s) + String(a)
753
+ }
754
+ },
755
+ '一行追加': { // @文字列SにAと改行を追加して返す(v1非互換) // @いちぎょうついか
756
+ type: 'func',
757
+ josi: [['で', 'に', 'へ'], ['を']],
758
+ pure: true,
759
+ fn: function (s, a) {
760
+ return String(s) + String(a) + '\n'
761
+ }
762
+ },
763
+ '文字列分解': { // @文字列Vを一文字ずつに分解して返す // @もじれつぶんかい
764
+ type: 'func',
765
+ josi: [['を', 'の', 'で']],
766
+ pure: true,
767
+ fn: function (v) {
768
+ if (!Array.from) { return String(v).split('') }
769
+ return Array.from(v)
770
+ }
771
+ },
772
+ 'リフレイン': { // @文字列VをCNT回繰り返す(v1非互換) // @りふれいん
773
+ type: 'func',
774
+ josi: [['を', 'の'], ['で']],
775
+ pure: true,
776
+ fn: function (v, cnt) {
777
+ let s = ''
778
+ for (let i = 0; i < cnt; i++) { s += String(v) }
779
+ return s
780
+ }
781
+ },
782
+ '出現回数': { // @文字列SにAが何回出現するか数える // @しゅつげんかいすう
783
+ type: 'func',
784
+ josi: [['で'], ['の']],
785
+ pure: true,
786
+ fn: function (s, a) {
787
+ let cnt = 0
788
+ const re = new RegExp(a.replace(/(.)/g, '\\$1'), 'g')
789
+ String(s).replace(re, m => {
790
+ cnt++
791
+ })
792
+ return cnt
793
+ }
794
+ },
795
+ 'MID': { // @文字列SのA文字目からCNT文字を抽出する // @MID
796
+ type: 'func',
797
+ josi: [['で', 'の'], ['から'], ['を']],
798
+ pure: true,
799
+ fn: function (s, a, cnt) {
800
+ cnt = cnt || undefined
801
+ return (String(s).substr(a - 1, cnt))
802
+ }
803
+ },
804
+ '文字抜出': { // @文字列SのA文字目からCNT文字を抽出する // @もじぬきだす
805
+ type: 'func',
806
+ josi: [['で', 'の'], ['から'], ['を', '']],
807
+ pure: true,
808
+ fn: function (s, a, cnt) {
809
+ cnt = cnt || undefined
810
+ return (String(s).substr(a - 1, cnt))
811
+ }
812
+ },
813
+ 'LEFT': { // @文字列Sの左端からCNT文字を抽出する // @LEFT
814
+ type: 'func',
815
+ josi: [['の', 'で'], ['だけ']],
816
+ pure: true,
817
+ fn: function (s, cnt) {
818
+ return (String(s).substr(0, cnt))
819
+ }
820
+ },
821
+ '文字左部分': { // @文字列Sの左端からCNT文字を抽出する // @もじひだりぶぶん
822
+ type: 'func',
823
+ josi: [['の', 'で'], ['だけ', '']],
824
+ pure: true,
825
+ fn: function (s, cnt) {
826
+ return (String(s).substr(0, cnt))
827
+ }
828
+ },
829
+ 'RIGHT': { // @文字列Sの右端からCNT文字を抽出する // @RIGHT
830
+ type: 'func',
831
+ josi: [['の', 'で'], ['だけ']],
832
+ pure: true,
833
+ fn: function (s, cnt) {
834
+ s = '' + s
835
+ return (s.substr(s.length - cnt, cnt))
836
+ }
837
+ },
838
+ '文字右部分': { // @文字列Sの右端からCNT文字を抽出する // @もじみぎぶぶん
839
+ type: 'func',
840
+ josi: [['の', 'で'], ['だけ', '']],
841
+ pure: true,
842
+ fn: function (s, cnt) {
843
+ s = '' + s
844
+ return (s.substr(s.length - cnt, cnt))
845
+ }
846
+ },
847
+ '区切': { // @文字列Sを区切り文字Aで区切って配列で返す // @くぎる
848
+ type: 'func',
849
+ josi: [['の', 'を'], ['で']],
850
+ pure: true,
851
+ fn: function (s, a) {
852
+ return ('' + s).split('' + a)
853
+ }
854
+ },
855
+ '切取': { // @文字列Sから文字列Aまでの部分を抽出する(v1非互換) // @きりとる
856
+ type: 'func',
857
+ josi: [['から', 'の'], ['まで', 'を']],
858
+ pure: true,
859
+ fn: function (s, a) {
860
+ s = String(s)
861
+ const i = s.indexOf(a)
862
+ if (i < 0) { return s }
863
+ return s.substr(0, i)
864
+ }
865
+ },
866
+ '文字削除': { // @文字列SのA文字目からB文字分を削除して返す // @もじさくじょ
867
+ type: 'func',
868
+ josi: [['の'], ['から'], ['だけ', 'を', '']],
869
+ pure: true,
870
+ fn: function (s, a, b) {
871
+ s = '' + s
872
+ const mae = s.substr(0, a - 1)
873
+ const usi = s.substr((a - 1 + b))
874
+ return mae + usi
875
+ }
876
+ },
877
+
878
+ // @置換・トリム
879
+ '置換': { // @文字列Sのうち文字列AをBに全部置換して返す // @ちかん
880
+ type: 'func',
881
+ josi: [['の', 'で'], ['を', 'から'], ['に', 'へ']],
882
+ pure: true,
883
+ fn: function (s, a, b) {
884
+ return String(s).split(a).join(b)
885
+ }
886
+ },
887
+ '単置換': { // @文字列Sのうち、最初に出現するAだけをBに置換して返す // @たんちかん
888
+ type: 'func',
889
+ josi: [['の', 'で'], ['を'], ['に', 'へ']],
890
+ pure: true,
891
+ fn: function (s, a, b) {
892
+ s = String(s)
893
+ const re = new RegExp(a.replace(/(.)/g, '\\$1'), '')
894
+ return s.replace(re, b)
895
+ }
896
+ },
897
+ 'トリム': { // @文字列Sの前後にある空白を削除する // @とりむ
898
+ type: 'func',
899
+ josi: [['の', 'を']],
900
+ pure: true,
901
+ fn: function (s) {
902
+ s = String(s).replace(/^\s+/, '').replace(/\s+$/, '')
903
+ return s
904
+ }
905
+ },
906
+ '空白除去': { // @文字列Sの前後にある空白を削除する // @くうはくじょきょ
907
+ type: 'func',
908
+ josi: [['の', 'を']],
909
+ pure: true,
910
+ fn: function (s) {
911
+ s = String(s).replace(/^\s+/, '').replace(/\s+$/, '')
912
+ return s
913
+ }
914
+ },
915
+
916
+ // @文字変換
917
+ '大文字変換': { // @アルファベットの文字列Sを大文字に変換 // @おおもじへんかん
918
+ type: 'func',
919
+ josi: [['の', 'を']],
920
+ pure: true,
921
+ fn: function (s) {
922
+ return String(s).toUpperCase()
923
+ }
924
+ },
925
+ '小文字変換': { // @アルファベットの文字列Sを小文字に変換 // @こもじへんかん
926
+ type: 'func',
927
+ josi: [['の', 'を']],
928
+ pure: true,
929
+ fn: function (s) {
930
+ return String(s).toLowerCase()
931
+ }
932
+ },
933
+ '平仮名変換': { // @文字列Sのカタカナをひらがなに変換 // @ひらがなへんかん
934
+ type: 'func',
935
+ josi: [['の', 'を']],
936
+ pure: true,
937
+ fn: function (s) {
938
+ const kanaToHira = (str) => {
939
+ return String(str).replace(/[\u30a1-\u30f6]/g, function (m) {
940
+ const chr = m.charCodeAt(0) - 0x60
941
+ return String.fromCharCode(chr)
942
+ })
943
+ }
944
+ return kanaToHira(s)
945
+ }
946
+ },
947
+ 'カタカナ変換': { // @文字列Sのひらがなをカタカナに変換 // @かたかなへんかん
948
+ type: 'func',
949
+ josi: [['の', 'を']],
950
+ pure: true,
951
+ fn: function (s) {
952
+ const hiraToKana = (str) => {
953
+ return String(str).replace(/[\u3041-\u3096]/g, function (m) {
954
+ const chr = m.charCodeAt(0) + 0x60
955
+ return String.fromCharCode(chr)
956
+ })
957
+ }
958
+ return hiraToKana(s)
959
+ }
960
+ },
961
+ '英数全角変換': { // @文字列Sの半角英数文字を全角に変換 // @えいすうぜんかくへんかん
962
+ type: 'func',
963
+ josi: [['の', 'を']],
964
+ pure: true,
965
+ fn: function (s) {
966
+ return String(s).replace(/[A-Za-z0-9]/g, function (v) {
967
+ return String.fromCharCode(v.charCodeAt(0) + 0xFEE0)
968
+ })
969
+ }
970
+ },
971
+ '英数半角変換': { // @文字列Sの全角英数文字を半角に変換 // @えいすうはんかくへんかん
972
+ type: 'func',
973
+ josi: [['の', 'を']],
974
+ pure: true,
975
+ fn: function (s) {
976
+ return String(s).replace(/[A-Za-z0-9]/g, function (v) {
977
+ return String.fromCharCode(v.charCodeAt(0) - 0xFEE0)
978
+ })
979
+ }
980
+ },
981
+ '英数記号全角変換': { // @文字列Sの半角英数記号文字を全角に変換 // @えいすうきごうぜんかくへんかん
982
+ type: 'func',
983
+ josi: [['の', 'を']],
984
+ pure: true,
985
+ fn: function (s) {
986
+ return String(s).replace(/[\x20-\x7F]/g, function (v) {
987
+ return String.fromCharCode(v.charCodeAt(0) + 0xFEE0)
988
+ })
989
+ }
990
+ },
991
+ '英数記号半角変換': { // @文字列Sの記号文字を半角に変換 // @えいすうきごうはんかくへんかん
992
+ type: 'func',
993
+ josi: [['の', 'を']],
994
+ pure: true,
995
+ fn: function (s) {
996
+ return String(s).replace(/[\uFF00-\uFF5F]/g, function (v) {
997
+ return String.fromCharCode(v.charCodeAt(0) - 0xFEE0)
998
+ })
999
+ }
1000
+ },
1001
+ 'カタカナ全角変換': { // @文字列Sの半角カタカナを全角に変換 // @かたかなぜんかくへんかん
1002
+ type: 'func',
1003
+ josi: [['の', 'を']],
1004
+ pure: true,
1005
+ fn: function (s, sys) {
1006
+ // 半角カタカナ
1007
+ const zen1 = sys.__v0['全角カナ一覧']
1008
+ const han1 = sys.__v0['半角カナ一覧']
1009
+ const zen2 = sys.__v0['全角カナ濁音一覧']
1010
+ const han2 = sys.__v0['半角カナ濁音一覧']
1011
+ let str = ''
1012
+ let i = 0
1013
+ while (i < s.length) {
1014
+ // 濁点の変換
1015
+ const c2 = s.substr(i, 2)
1016
+ const n2 = han2.indexOf(c2)
1017
+ if (n2 >= 0) {
1018
+ str += zen2.charAt(n2 / 2)
1019
+ i += 2
1020
+ continue
1021
+ }
1022
+ // 濁点以外の変換
1023
+ const c = s.charAt(i)
1024
+ const n = han1.indexOf(c)
1025
+ if (n >= 0) {
1026
+ str += zen1.charAt(n)
1027
+ i++
1028
+ continue
1029
+ }
1030
+ str += c
1031
+ i++
1032
+ }
1033
+ return str
1034
+ }
1035
+ },
1036
+ 'カタカナ半角変換': { // @文字列Sの全角カタカナを半角に変換 // @かたかなはんかくへんかん
1037
+ type: 'func',
1038
+ josi: [['の', 'を']],
1039
+ pure: true,
1040
+ fn: function (s, sys) {
1041
+ // 半角カタカナ
1042
+ const zen1 = sys.__v0['全角カナ一覧']
1043
+ const han1 = sys.__v0['半角カナ一覧']
1044
+ const zen2 = sys.__v0['全角カナ濁音一覧']
1045
+ const han2 = sys.__v0['半角カナ濁音一覧']
1046
+ return s.split('').map((c) => {
1047
+ const i = zen1.indexOf(c)
1048
+ if (i >= 0) {
1049
+ return han1.charAt(i)
1050
+ }
1051
+ const j = zen2.indexOf(c)
1052
+ if (j >= 0) {
1053
+ return han2.substr(j * 2, 2)
1054
+ }
1055
+ return c
1056
+ }).join('')
1057
+ }
1058
+ },
1059
+ '全角変換': { // @文字列Sの半角文字を全角に変換 // @ぜんかくへんかん
1060
+ type: 'func',
1061
+ josi: [['の', 'を']],
1062
+ pure: false,
1063
+ fn: function (s, sys) {
1064
+ let result = s
1065
+ result = sys.__exec('カタカナ全角変換', [result, sys])
1066
+ result = sys.__exec('英数記号全角変換', [result, sys])
1067
+ return result
1068
+ }
1069
+ },
1070
+ '半角変換': { // @文字列Sの全角文字を半角に変換 // @はんかくへんかん
1071
+ type: 'func',
1072
+ josi: [['の', 'を']],
1073
+ pure: false,
1074
+ fn: function (s, sys) {
1075
+ let result = s
1076
+ result = sys.__exec('カタカナ半角変換', [result, sys])
1077
+ result = sys.__exec('英数記号半角変換', [result, sys])
1078
+ return result
1079
+ }
1080
+ },
1081
+ '全角カナ一覧': { type: 'const', value: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ、。ー「」' }, // @ぜんかくかないちらん
1082
+ '全角カナ濁音一覧': { type: 'const', value: 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ' }, // @ぜんかくかなだくおんいちらん
1083
+ '半角カナ一覧': { type: 'const', value: 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ、。ー「」゙゚' }, // @はんかくかないちらん
1084
+ '半角カナ濁音一覧': { type: 'const', value: 'ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ' }, // @はんかくかなだくおんいちらん
1085
+
1086
+ // @JSON
1087
+ 'JSONエンコード': { // @オブジェクトVをJSON形式にエンコードして返す // @JSONえんこーど
1088
+ type: 'func',
1089
+ josi: [['を', 'の']],
1090
+ pure: true,
1091
+ fn: function (v) {
1092
+ return JSON.stringify(v)
1093
+ }
1094
+ },
1095
+ 'JSONエンコード整形': { // @オブジェクトVをJSON形式にエンコードして整形して返す // @JSONえんこーどせいけい
1096
+ type: 'func',
1097
+ josi: [['を', 'の']],
1098
+ pure: true,
1099
+ fn: function (v) {
1100
+ return JSON.stringify(v, null, 2)
1101
+ }
1102
+ },
1103
+ 'JSONデコード': { // @JSON文字列Sをオブジェクトにデコードして返す // @JSONでこーど
1104
+ type: 'func',
1105
+ josi: [['を', 'の', 'から']],
1106
+ pure: true,
1107
+ fn: function (s) {
1108
+ return JSON.parse(s)
1109
+ }
1110
+ },
1111
+
1112
+ // @正規表現
1113
+ '正規表現マッチ': { // @文字列Aを正規表現パターンBでマッチして結果を返す(パターンBは「/pat/opt」の形式で指定。optにgの指定がなければ部分マッチが『抽出文字列』に入る) // @せいきひょうげんまっち
1114
+ type: 'func',
1115
+ josi: [['を', 'が'], ['で', 'に']],
1116
+ pure: true,
1117
+ fn: function (a, b, sys) {
1118
+ let re
1119
+ const f = b.match(/^\/(.+)\/([a-zA-Z]*)$/)
1120
+ // パターンがない場合
1121
+ if (f === null) { re = new RegExp(b, 'g') } else { re = new RegExp(f[1], f[2]) }
1122
+
1123
+ const sa = sys.__varslist[0]['抽出文字列'] = []
1124
+ const m = String(a).match(re)
1125
+ let result = m
1126
+ if (re.global) {
1127
+ // no groups
1128
+ } else if (m) {
1129
+ // has group?
1130
+ if (m.length > 0) {
1131
+ result = m[0]
1132
+ for (let i = 1; i < m.length; i++) { sa[i - 1] = m[i] }
1133
+ }
1134
+ }
1135
+ return result
1136
+ }
1137
+ },
1138
+ '抽出文字列': { type: 'const', value: [] }, // @ちゅうしゅつもじれつ
1139
+ '正規表現置換': { // @文字列Sの正規表現パターンAをBに置換して結果を返す(パターンAは/pat/optで指定) // @せいきひょうげんちかん
1140
+ type: 'func',
1141
+ josi: [['の'], ['を', 'から'], ['で', 'に', 'へ']],
1142
+ pure: true,
1143
+ fn: function (s, a, b) {
1144
+ let re
1145
+ const f = a.match(/^\/(.+)\/([a-zA-Z]*)/)
1146
+ if (f === null) { re = new RegExp(a, 'g') } else { re = new RegExp(f[1], f[2]) }
1147
+
1148
+ return String(s).replace(re, b)
1149
+ }
1150
+ },
1151
+ '正規表現区切': { // @文字列Sを正規表現パターンAで区切って配列で返す(パターンAは/pat/optで指定) // @せいきひょうげんくぎる
1152
+ type: 'func',
1153
+ josi: [['を'], ['で']],
1154
+ pure: true,
1155
+ fn: function (s, a) {
1156
+ let re
1157
+ const f = a.match(/^\/(.+)\/([a-zA-Z]*)/)
1158
+ if (f === null) { re = new RegExp(a, 'g') } else { re = new RegExp(f[1], f[2]) }
1159
+
1160
+ return String(s).split(re)
1161
+ }
1162
+ },
1163
+
1164
+ // @指定形式
1165
+ '通貨形式': { // @数値Vを三桁ごとにカンマで区切る // @つうかけいしき
1166
+ type: 'func',
1167
+ josi: [['を', 'の']],
1168
+ pure: true,
1169
+ fn: function (v) {
1170
+ return String(v).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
1171
+ }
1172
+ },
1173
+ 'ゼロ埋': { // @数値VをA桁の0で埋める // @ぜろうめ
1174
+ type: 'func',
1175
+ josi: [['を'], ['で']],
1176
+ pure: true,
1177
+ fn: function (v, a) {
1178
+ v = String(v)
1179
+ let z = '0'
1180
+ for (let i = 0; i < a; i++) { z += '0' }
1181
+ a = parseInt(a)
1182
+ if (a < v.length) { a = v.length }
1183
+ const s = z + String(v)
1184
+ return s.substr(s.length - a, a)
1185
+ }
1186
+ },
1187
+ '空白埋': { // @文字列VをA桁の空白で埋める // @くうはくうめ
1188
+ type: 'func',
1189
+ josi: [['を'], ['で']],
1190
+ pure: true,
1191
+ fn: function (v, a) {
1192
+ v = String(v)
1193
+ let z = ' '
1194
+ for (let i = 0; i < a; i++) { z += ' ' }
1195
+ a = parseInt(a)
1196
+ if (a < v.length) { a = v.length }
1197
+ const s = z + String(v)
1198
+ return s.substr(s.length - a, a)
1199
+ }
1200
+ },
1201
+
1202
+ // @文字種類
1203
+ 'かなか判定': { // @文字列Sの1文字目がひらがなか判定 // @かなかはんてい
1204
+ type: 'func',
1205
+ josi: [['を', 'の', 'が']],
1206
+ pure: true,
1207
+ fn: function (s) {
1208
+ const c = String(s).charCodeAt(0)
1209
+ return (c >= 0x3041 && c <= 0x309F)
1210
+ }
1211
+ },
1212
+ 'カタカナ判定': { // @文字列Sの1文字目がカタカナか判定 // @かたかなかはんてい
1213
+ type: 'func',
1214
+ josi: [['を', 'の', 'が']],
1215
+ pure: true,
1216
+ fn: function (s) {
1217
+ const c = String(s).charCodeAt(0)
1218
+ return (c >= 0x30A1 && c <= 0x30FA)
1219
+ }
1220
+ },
1221
+ '数字判定': { // @文字列Sの1文字目が数字か判定 // @すうじかはんてい
1222
+ type: 'func',
1223
+ josi: [['を', 'が']],
1224
+ pure: true,
1225
+ fn: function (s) {
1226
+ const c = String(s).charAt(0)
1227
+ return ((c >= '0' && c <= '9') || (c >= '0' && c <= '9'))
1228
+ }
1229
+ },
1230
+ '数列判定': { // @文字列S全部が数字か判定 // @すうれつかはんてい
1231
+ type: 'func',
1232
+ josi: [['を', 'が']],
1233
+ pure: true,
1234
+ fn: function (s) {
1235
+ return (String(s).match(/^[0-9.]+$/) !== null)
1236
+ }
1237
+ },
1238
+
1239
+ // @配列操作
1240
+ '配列結合': { // @配列Aを文字列Sでつなげて文字列で返す // @はいれつけつごう
1241
+ type: 'func',
1242
+ josi: [['を'], ['で']],
1243
+ pure: true,
1244
+ fn: function (a, s) {
1245
+ // 配列ならOK
1246
+ if (a instanceof Array) { return a.join('' + s) }
1247
+
1248
+ const a2 = String(a).split('\n') // 配列でなければ無理矢理改行で区切ってみる
1249
+ return a2.join('' + s)
1250
+ }
1251
+ },
1252
+ '配列検索': { // @配列Aから文字列Sを探してインデックス番号(0起点)を返す。見つからなければ-1を返す。 // @はいれつけんさく
1253
+ type: 'func',
1254
+ josi: [['の', 'から'], ['を']],
1255
+ pure: true,
1256
+ fn: function (a, s) {
1257
+ if (a instanceof Array) { return a.indexOf(s) }// 配列ならOK
1258
+
1259
+ return -1
1260
+ }
1261
+ },
1262
+ '配列要素数': { // @配列Aの要素数を返す // @はいれつようそすう
1263
+ type: 'func',
1264
+ josi: [['の']],
1265
+ pure: true,
1266
+ fn: function (a) {
1267
+ if (a instanceof Array) { return a.length }// 配列ならOK
1268
+
1269
+ if (a instanceof Object) { return Object.keys(a).length }
1270
+
1271
+ return 1
1272
+ }
1273
+ },
1274
+ '要素数': { // @配列Aの要素数を返す // @ようそすう
1275
+ type: 'func',
1276
+ josi: [['の']],
1277
+ pure: false,
1278
+ fn: function (a, sys) {
1279
+ return sys.__exec('配列要素数', [a])
1280
+ }
1281
+ },
1282
+ '配列挿入': { // @配列AのI番目(0起点)に要素Sを追加して返す(v1非互換) // @はいれつそうにゅう
1283
+ type: 'func',
1284
+ josi: [['の'], ['に', 'へ'], ['を']],
1285
+ pure: true,
1286
+ fn: function (a, i, s) {
1287
+ if (a instanceof Array) { return a.splice(i, 0, s) } // 配列ならOK
1288
+
1289
+ throw new Error('『配列挿入』で配列以外の要素への挿入。')
1290
+ }
1291
+ },
1292
+ '配列一括挿入': { // @配列AのI番目(0起点)に配列bを追加して返す(v1非互換) // @はいれついっかつそうにゅう
1293
+ type: 'func',
1294
+ josi: [['の'], ['に', 'へ'], ['を']],
1295
+ pure: true,
1296
+ fn: function (a, i, b) {
1297
+ if (a instanceof Array && b instanceof Array) { // 配列ならOK
1298
+ for (let j = 0; j < b.length; j++) { a.splice(i + j, 0, b[j]) }
1299
+
1300
+ return a
1301
+ }
1302
+ throw new Error('『配列一括挿入』で配列以外の要素への挿入。')
1303
+ }
1304
+ },
1305
+ '配列ソート': { // @配列Aをソートして返す(A自体を変更) // @はいれつそーと
1306
+ type: 'func',
1307
+ josi: [['の', 'を']],
1308
+ pure: true,
1309
+ fn: function (a) {
1310
+ if (a instanceof Array) { return a.sort() } // 配列ならOK
1311
+
1312
+ throw new Error('『配列ソート』で配列以外が指定されました。')
1313
+ }
1314
+ },
1315
+ '配列数値ソート': { // @配列Aをソートして返す(A自体を変更) // @はいれつすうちそーと
1316
+ type: 'func',
1317
+ josi: [['の', 'を']],
1318
+ pure: true,
1319
+ fn: function (a) {
1320
+ // 配列ならOK
1321
+ if (a instanceof Array) {
1322
+ return a.sort((a, b) => {
1323
+ return parseFloat(a) - parseFloat(b)
1324
+ })
1325
+ }
1326
+
1327
+ throw new Error('『配列数値ソート』で配列以外が指定されました。')
1328
+ }
1329
+ },
1330
+ '配列カスタムソート': { // @関数Fで配列Aをソートして返す(引数A自体を変更) // @はいれつかすたむそーと
1331
+ type: 'func',
1332
+ josi: [['で'], ['の', 'を']],
1333
+ pure: false,
1334
+ fn: function (f, a, sys) {
1335
+ let ufunc = f
1336
+ if (typeof f === 'string') {
1337
+ ufunc = sys.__findFunc(f, '配列カスタムソート')
1338
+ }
1339
+ if (a instanceof Array) {
1340
+ return a.sort(ufunc)
1341
+ }
1342
+ throw new Error('『配列カスタムソート』で配列以外が指定されました。')
1343
+ }
1344
+ },
1345
+ '配列逆順': { // @配列Aを逆にして返す。Aを書き換える(A自体を変更)。 // @はいれつぎゃくじゅん
1346
+ type: 'func',
1347
+ josi: [['の', 'を']],
1348
+ pure: true,
1349
+ fn: function (a) {
1350
+ if (a instanceof Array) { return a.reverse() } // 配列ならOK
1351
+ throw new Error('『配列ソート』で配列以外が指定されました。')
1352
+ }
1353
+ },
1354
+ '配列シャッフル': { // @配列Aをシャッフルして返す。Aを書き換える // @はいれつしゃっふる
1355
+ type: 'func',
1356
+ josi: [['の', 'を']],
1357
+ pure: true,
1358
+ fn: function (a) {
1359
+ if (a instanceof Array) { // 配列ならOK
1360
+ for (let i = a.length - 1; i > 0; i--) {
1361
+ const r = Math.floor(Math.random() * (i + 1))
1362
+ const tmp = a[i]
1363
+ a[i] = a[r]
1364
+ a[r] = tmp
1365
+ }
1366
+ return a
1367
+ }
1368
+ throw new Error('『配列シャッフル』で配列以外が指定されました。')
1369
+ }
1370
+ },
1371
+ '配列削除': { // @配列AのI番目(0起点)の要素を削除して返す。Aの内容を書き換える。辞書型変数ならキーIを削除する。 // @はいれつさくじょ
1372
+ type: 'func',
1373
+ josi: [['の', 'から'], ['を']],
1374
+ pure: false,
1375
+ fn: function (a, i, sys) {
1376
+ return sys.__exec('配列切取', [a, i, sys])
1377
+ }
1378
+ },
1379
+ '配列切取': { // @配列AのI番目(0起点)の要素を切り取って返す。Aの内容を書き換える。辞書型変数ならキーIを削除する。 // @はいれつきりとる
1380
+ type: 'func',
1381
+ josi: [['の', 'から'], ['を']],
1382
+ pure: true,
1383
+ fn: function (a, i) {
1384
+ // 配列変数のとき
1385
+ if (a instanceof Array) {
1386
+ const b = a.splice(i, 1)
1387
+ if (b instanceof Array) { return b[0] } // 切り取った戻り値は必ずArrayになるので。
1388
+ return null
1389
+ }
1390
+ // 辞書型変数のとき
1391
+ if (a instanceof Object && typeof (i) === 'string') { // 辞書型変数も許容
1392
+ if (a[i]) {
1393
+ const old = a[i]
1394
+ delete a[i]
1395
+ return old
1396
+ }
1397
+ return undefined
1398
+ }
1399
+ throw new Error('『配列切取』で配列以外を指定。')
1400
+ }
1401
+ },
1402
+ '配列取出': { // @配列AのI番目(0起点)からCNT個の要素を取り出して返す。Aの内容を書き換える // @はいれつとりだし
1403
+ type: 'func',
1404
+ josi: [['の'], ['から'], ['を']],
1405
+ pure: true,
1406
+ fn: function (a, i, cnt) {
1407
+ if (a instanceof Array) { return a.splice(i, cnt) }
1408
+ throw new Error('『配列取出』で配列以外を指定。')
1409
+ }
1410
+ },
1411
+ '配列ポップ': { // @配列Aの末尾を取り出して返す。Aの内容を書き換える。 // @はいれつぽっぷ
1412
+ type: 'func',
1413
+ josi: [['の', 'から']],
1414
+ pure: true,
1415
+ fn: function (a) {
1416
+ if (a instanceof Array) { return a.pop() }
1417
+ throw new Error('『配列ポップ』で配列以外の処理。')
1418
+ }
1419
+ },
1420
+ '配列追加': { // @配列Aの末尾にBを追加して返す。Aの内容を書き換える。 // @はいれつついか
1421
+ type: 'func',
1422
+ josi: [['に', 'へ'], ['を']],
1423
+ pure: true,
1424
+ fn: function (a, b) {
1425
+ if (a instanceof Array) { // 配列ならOK
1426
+ a.push(b)
1427
+ return a
1428
+ }
1429
+ throw new Error('『配列追加』で配列以外の処理。')
1430
+ }
1431
+ },
1432
+ '配列複製': { // @配列Aを複製して返す。 // @はいれつふくせい
1433
+ type: 'func',
1434
+ josi: [['を']],
1435
+ pure: true,
1436
+ fn: function (a) {
1437
+ return JSON.parse(JSON.stringify(a))
1438
+ }
1439
+ },
1440
+ '配列足': { // @配列Aに配列Bを足し合わせて返す。 // @はいれつたす
1441
+ type: 'func',
1442
+ josi: [['に', 'へ', 'と'], ['を']],
1443
+ pure: true,
1444
+ fn: function (a, b) {
1445
+ if (a instanceof Array) {
1446
+ return a.concat(b)
1447
+ }
1448
+ return JSON.parse(JSON.stringify(a))
1449
+ }
1450
+ },
1451
+ '配列最大値': { // @配列Aの値の最大値を調べて返す。 // @はいれつさいだいち
1452
+ type: 'func',
1453
+ josi: [['の']],
1454
+ pure: true,
1455
+ fn: function (a) {
1456
+ return a.reduce((x, y) => Math.max(x, y))
1457
+ }
1458
+ },
1459
+ '配列最小値': { // @配列Aの値の最小値を調べて返す。 // @はいれつさいしょうち
1460
+ type: 'func',
1461
+ josi: [['の']],
1462
+ pure: true,
1463
+ fn: function (a) {
1464
+ return a.reduce((x, y) => Math.min(x, y))
1465
+ }
1466
+ },
1467
+ '配列合計': { // @配列Aの値を全て足して返す。配列の各要素を数値に変換して計算する。数値に変換できない文字列は0になる。 // @はいれつごうけい
1468
+ type: 'func',
1469
+ josi: [['の']],
1470
+ pure: true,
1471
+ fn: function (a) {
1472
+ if (a instanceof Array) {
1473
+ let v = 0
1474
+ a.forEach((n) => {
1475
+ const nn = parseFloat(n)
1476
+ if (isNaN(nn)) { return }
1477
+ v += nn
1478
+ })
1479
+ return v
1480
+ }
1481
+ throw new Error('『配列合計』で配列変数以外の値が指定されました。')
1482
+ }
1483
+ },
1484
+ // @二次元配列処理
1485
+ '表ソート': { // @二次元配列AでB列目(0起点)(あるいはキー名)をキーに文字列順にソートする。Aの内容を書き換える。 // @ひょうそーと
1486
+ type: 'func',
1487
+ josi: [['の'], ['を']],
1488
+ pure: true,
1489
+ fn: function (a, no) {
1490
+ if (!(a instanceof Array)) {
1491
+ throw new Error('『表ソート』には配列を指定する必要があります。')
1492
+ }
1493
+ a.sort((n, m) => {
1494
+ const ns = n[no]
1495
+ const ms = m[no]
1496
+
1497
+ if (ns === ms) {
1498
+ return 0
1499
+ } else if (ns < ms) {
1500
+ return -1
1501
+ } else {
1502
+ return 1
1503
+ }
1504
+ })
1505
+ return a
1506
+ }
1507
+ },
1508
+ // @二次元配列処理
1509
+ '表数値ソート': { // @二次元配列AでB列目(0起点)(あるいはキー名)をキーに数値順にソートする。Aの内容を書き換える。 // @ひょうすうちそーと
1510
+ type: 'func',
1511
+ josi: [['の'], ['を']],
1512
+ pure: true,
1513
+ fn: function (a, no) {
1514
+ if (!(a instanceof Array)) {
1515
+ throw new Error('『表数値ソート』には配列を指定する必要があります。')
1516
+ }
1517
+ a.sort((n, m) => {
1518
+ const ns = n[no]
1519
+ const ms = m[no]
1520
+ return ns - ms
1521
+ })
1522
+ return a
1523
+ }
1524
+ },
1525
+ '表ピックアップ': { // @配列Aの列番号B(0起点)(あるいはキー名)で検索文字列Sを含む行を返す // @ひょうぴっくあっぷ
1526
+ type: 'func',
1527
+ josi: [['の'], ['から'], ['を', 'で']],
1528
+ pure: true,
1529
+ fn: function (a, no, s) {
1530
+ if (!(a instanceof Array)) { throw new Error('『表ピックアップ』には配列を指定する必要があります。') }
1531
+ return a.filter((row) => String(row[no]).indexOf(s) >= 0)
1532
+ }
1533
+ },
1534
+ '表完全一致ピックアップ': { // @配列Aの列番号B(0起点)(あるいはキー名)で検索文字列Sと一致する行を返す // @ひょうぴっくあっぷ
1535
+ type: 'func',
1536
+ josi: [['の'], ['から'], ['を', 'で']],
1537
+ pure: true,
1538
+ fn: function (a, no, s) {
1539
+ if (!(a instanceof Array)) { throw new Error('『表完全ピックアップ』には配列を指定する必要があります。') }
1540
+ return a.filter((row) => row[no] === s)
1541
+ }
1542
+ },
1543
+ '表検索': { // @二次元配列AでCOL列目(0起点)からキーSを含む行をROW行目から検索して何行目にあるか返す。見つからなければ-1を返す。 // @ひょうけんさく
1544
+ type: 'func',
1545
+ josi: [['の'], ['で', 'に'], ['から'], ['を']],
1546
+ pure: true,
1547
+ fn: function (a, col, row, s) {
1548
+ if (!(a instanceof Array)) { throw new Error('『表検索』には配列を指定する必要があります。') }
1549
+ for (let i = row; i < a.length; i++) {
1550
+ if (a[i][col] === s) { return i }
1551
+ }
1552
+ return -1
1553
+ }
1554
+ },
1555
+ '表列数': { // @二次元配列Aの列数を調べて返す。 // @ひょうれつすう
1556
+ type: 'func',
1557
+ josi: [['の']],
1558
+ pure: true,
1559
+ fn: function (a) {
1560
+ if (!(a instanceof Array)) { throw new Error('『表列数』には配列を指定する必要があります。') }
1561
+ let cols = 1
1562
+ for (let i = 0; i < a.length; i++) {
1563
+ if (a[i].length > cols) { cols = a[i].length }
1564
+ }
1565
+ return cols
1566
+ }
1567
+ },
1568
+ '表行数': { // @二次元配列Aの行数を調べて返す。 // @ひょうぎょうすう
1569
+ type: 'func',
1570
+ josi: [['の']],
1571
+ pure: true,
1572
+ fn: function (a) {
1573
+ if (!(a instanceof Array)) { throw new Error('『表行数』には配列を指定する必要があります。') }
1574
+ return a.length
1575
+ }
1576
+ },
1577
+ '表行列交換': { // @二次元配列Aの行と列を交換して返す。 // @ひょうぎょうれつこうかん
1578
+ type: 'func',
1579
+ josi: [['の', 'を']],
1580
+ pure: false,
1581
+ fn: function (a, sys) {
1582
+ if (!(a instanceof Array)) { throw new Error('『表行列交換』には配列を指定する必要があります。') }
1583
+ const cols = sys.__exec('表列数', [a])
1584
+ const rows = a.length
1585
+ const res = []
1586
+ for (let r = 0; r < cols; r++) {
1587
+ const row = []
1588
+ res.push(row)
1589
+ for (let c = 0; c < rows; c++) {
1590
+ row[c] = a[c][r] ? a[c][r] : ''
1591
+ }
1592
+ }
1593
+ return res
1594
+ }
1595
+ },
1596
+ '表右回転': { // @二次元配列Aを90度回転して返す。 // @ひょうみぎかいてん
1597
+ type: 'func',
1598
+ josi: [['の', 'を']],
1599
+ pure: false,
1600
+ fn: function (a, sys) {
1601
+ if (!(a instanceof Array)) { throw new Error('『表右回転』には配列を指定する必要があります。') }
1602
+ const cols = sys.__exec('表列数', [a])
1603
+ const rows = a.length
1604
+ const res = []
1605
+ for (let r = 0; r < cols; r++) {
1606
+ const row = []
1607
+ res.push(row)
1608
+ for (let c = 0; c < rows; c++) {
1609
+ row[c] = a[rows - c - 1][r]
1610
+ }
1611
+ }
1612
+ return res
1613
+ }
1614
+ },
1615
+ '表重複削除': { // @二次元配列AのI列目にある重複項目を削除して返す。 // @ひょうじゅうふくさくじょ
1616
+ type: 'func',
1617
+ josi: [['の'], ['を', 'で']],
1618
+ pure: true,
1619
+ fn: function (a, i, sys) {
1620
+ if (!(a instanceof Array)) { throw new Error('『表重複削除』には配列を指定する必要があります。') }
1621
+ const res = []
1622
+ const keys = {}
1623
+ for (let n = 0; n < a.length; n++) {
1624
+ const k = a[n][i]
1625
+ if (undefined === keys[k]) {
1626
+ keys[k] = true
1627
+ res.push(a[n])
1628
+ }
1629
+ }
1630
+ return res
1631
+ }
1632
+ },
1633
+ '表列取得': { // @二次元配列AのI列目を返す。 // @ひょうれつしゅとく
1634
+ type: 'func',
1635
+ josi: [['の'], ['を']],
1636
+ pure: true,
1637
+ fn: function (a, i, sys) {
1638
+ if (!(a instanceof Array)) { throw new Error('『表列取得』には配列を指定する必要があります。') }
1639
+ const res = a.map(row => row[i])
1640
+ return res
1641
+ }
1642
+ },
1643
+ '表列挿入': { // @二次元配列Aの(0から数えて)I列目に配列Sを挿入して返す // @ひょうれつそうにゅう
1644
+ type: 'func',
1645
+ josi: [['の'], ['に', 'へ'], ['を']],
1646
+ pure: true,
1647
+ fn: function (a, i, s) {
1648
+ if (!(a instanceof Array)) { throw new Error('『表列挿入』には配列を指定する必要があります。') }
1649
+ const res = []
1650
+ a.forEach((row, idx) => {
1651
+ let nr = []
1652
+ if (i > 0) { nr = nr.concat(row.slice(0, i)) }
1653
+ nr.push(s[idx])
1654
+ nr = nr.concat(row.slice(i))
1655
+ res.push(nr)
1656
+ })
1657
+ return res
1658
+ }
1659
+ },
1660
+ '表列削除': { // @二次元配列Aの(0から数えて)I列目削除して返す // @ひょうれつそうにゅう
1661
+ type: 'func',
1662
+ josi: [['の'], ['を']],
1663
+ pure: true,
1664
+ fn: function (a, i) {
1665
+ if (!(a instanceof Array)) { throw new Error('『表列削除』には配列を指定する必要があります。') }
1666
+ const res = []
1667
+ a.forEach((row, idx) => {
1668
+ const nr = row.slice(0)
1669
+ nr.splice(i, 1)
1670
+ res.push(nr)
1671
+ })
1672
+ return res
1673
+ }
1674
+ },
1675
+ '表列合計': { // @二次元配列Aの(0から数えて)I列目を合計して返す。 // @ひょうれつごうけい
1676
+ type: 'func',
1677
+ josi: [['の'], ['を', 'で']],
1678
+ pure: true,
1679
+ fn: function (a, i) {
1680
+ if (!(a instanceof Array)) { throw new Error('『表列合計』には配列を指定する必要があります。') }
1681
+ let sum = 0
1682
+ a.forEach((row) => { sum += row[i] })
1683
+ return sum
1684
+ }
1685
+ },
1686
+ '表曖昧検索': { // @二次元配列AのROW行目からCOL列目(0起点)で正規表現Sにマッチする行を検索して何行目にあるか返す。見つからなければ-1を返す。(v1非互換) // @ひょうれつあいまいけんさく
1687
+ type: 'func',
1688
+ josi: [['の'], ['から'], ['で'], ['を']],
1689
+ pure: true,
1690
+ fn: function (a, row, col, s) {
1691
+ if (!(a instanceof Array)) { throw new Error('『表曖昧検索』には配列を指定する必要があります。') }
1692
+ const re = new RegExp(s)
1693
+ for (let i = 0; i < a.length; i++) {
1694
+ const row = a[i]
1695
+ if (re.test(row[col])) { return i }
1696
+ }
1697
+ return -1
1698
+ }
1699
+ },
1700
+ '表正規表現ピックアップ': { // @二次元配列AでI列目(0起点)から正規表現パターンSにマッチする行をピックアップして返す。 // @ひょうせいきひょうげんぴっくあっぷ
1701
+ type: 'func',
1702
+ josi: [['の', 'で'], ['から'], ['を']],
1703
+ pure: true,
1704
+ fn: function (a, col, s) {
1705
+ if (!(a instanceof Array)) { throw new Error('『表正規表現ピックアップ』には配列を指定する必要があります。') }
1706
+ const re = new RegExp(s)
1707
+ const res = []
1708
+ for (let i = 0; i < a.length; i++) {
1709
+ const row = a[i]
1710
+ if (re.test(row[col])) { res.push(row.slice(0)) }
1711
+ }
1712
+ return res
1713
+ }
1714
+ },
1715
+ // @辞書型変数の操作
1716
+ '辞書キー列挙': { // @辞書型変数Aのキーの一覧を配列で返す。 // @じしょきーれっきょ
1717
+ type: 'func',
1718
+ josi: [['の']],
1719
+ pure: true,
1720
+ fn: function (a) {
1721
+ const keys = []
1722
+ if (a instanceof Object) { // オブジェクトのキーを返す
1723
+ for (const key in a) { keys.push(key) }
1724
+ return keys
1725
+ }
1726
+ if (a instanceof Array) { // 配列なら数字を返す
1727
+ for (let i = 0; i < a.length; i++) { keys.push(i) }
1728
+ return keys
1729
+ }
1730
+ throw new Error('『辞書キー列挙』でハッシュ以外が与えられました。')
1731
+ }
1732
+ },
1733
+ '辞書キー削除': { // @辞書型変数AからキーKEYを削除して返す(A自体を変更する)。 // @じしょきーさくじょ
1734
+ type: 'func',
1735
+ josi: [['から', 'の'], ['を']],
1736
+ pure: true,
1737
+ fn: function (a, key) {
1738
+ if (a instanceof Object) { // オブジェクトのキーを返す
1739
+ if (a[key]) { delete a[key] }
1740
+ return a
1741
+ }
1742
+ throw new Error('『辞書キー削除』でハッシュ以外が与えられました。')
1743
+ }
1744
+ },
1745
+ '辞書キー存在': { // @辞書型変数AのキーKEYが存在するか確認 // @じしょきーそんざい
1746
+ type: 'func',
1747
+ josi: [['の', 'に'], ['が']],
1748
+ pure: true,
1749
+ fn: function (a, key) {
1750
+ return key in a
1751
+ }
1752
+ },
1753
+ // @ハッシュ
1754
+ 'ハッシュキー列挙': { // @ハッシュAのキー一覧を配列で返す。 // @はっしゅきーれっきょ
1755
+ type: 'func',
1756
+ josi: [['の']],
1757
+ pure: false,
1758
+ fn: function (a, sys) {
1759
+ return sys.__exec('辞書キー列挙', [a, sys])
1760
+ }
1761
+ },
1762
+ 'ハッシュ内容列挙': { // @ハッシュAの内容一覧を配列で返す。 // @はっしゅないようれっきょ
1763
+ type: 'func',
1764
+ josi: [['の']],
1765
+ pure: true,
1766
+ fn: function (a) {
1767
+ const body = []
1768
+ if (a instanceof Object) { // オブジェクトのキーを返す
1769
+ for (const key in a) { body.push(a[key]) }
1770
+ return body
1771
+ }
1772
+ throw new Error('『ハッシュ内容列挙』でハッシュ以外が与えられました。')
1773
+ }
1774
+ },
1775
+ 'ハッシュキー削除': { // @ハッシュAからキーKEYを削除して返す。 // @はっしゅきーさくじょ
1776
+ type: 'func',
1777
+ josi: [['から', 'の'], ['を']],
1778
+ pure: false,
1779
+ fn: function (a, key, sys) {
1780
+ return sys.__exec('辞書キー削除', [a, key, sys])
1781
+ }
1782
+ },
1783
+ 'ハッシュキー存在': { // @ハッシュAのキーKEYが存在するか確認 // @はっしゅきーそんざい
1784
+ type: 'func',
1785
+ josi: [['の', 'に'], ['が']],
1786
+ pure: true,
1787
+ fn: function (a, key) {
1788
+ return key in a
1789
+ }
1790
+ },
1791
+ // @タイマー
1792
+ '秒待機': { // @ 「!非同期モード」または「逐次実行構文」にて、N秒の間待機する // @びょうたいき
1793
+ type: 'func',
1794
+ josi: [['']],
1795
+ pure: false,
1796
+ fn: function (n, sys) {
1797
+ if (sys.__genMode === '非同期モード') {
1798
+ sys.async = true
1799
+ setTimeout(() => {
1800
+ sys.nextAsync(sys)
1801
+ }, n * 1000)
1802
+ } else {
1803
+ if (sys.resolve === undefined) { throw new Error('『秒待機』命令は『!非同期モード』で使ってください。') }
1804
+ sys.__exec('秒逐次待機', [n, sys])
1805
+ }
1806
+ },
1807
+ return_none: true
1808
+ },
1809
+ '秒逐次待機': { // @ 逐次実行構文にて、N秒の間待機する // @びょうちくじたいき
1810
+ type: 'func',
1811
+ josi: [['']],
1812
+ pure: true,
1813
+ fn: function (n, sys) {
1814
+ if (sys.resolve === undefined) { throw new Error('『秒逐次待機』命令は『逐次実行』構文と一緒に使ってください。') }
1815
+ const resolve = sys.resolve
1816
+ // const reject = sys.reject
1817
+ sys.resolveCount++
1818
+ const timerId = setTimeout(function () {
1819
+ const idx = sys.__timeout.indexOf(timerId)
1820
+ if (idx >= 0) { sys.__timeout.splice(idx, 1) }
1821
+ resolve()
1822
+ }, n * 1000)
1823
+ sys.__timeout.unshift(timerId)
1824
+ },
1825
+ return_none: true
1826
+ },
1827
+ '秒後': { // @無名関数(あるいは、文字列で関数名を指定)FをN秒後に実行する。変数『対象』にタイマーIDを代入する。 // @びょうご
1828
+ type: 'func',
1829
+ josi: [['を'], ['']],
1830
+ pure: false,
1831
+ fn: function (f, n, sys) {
1832
+ // 文字列で指定された関数をオブジェクトに変換
1833
+ if (typeof f === 'string') { f = sys.__findFunc(f, '秒後') }
1834
+ // 1回限りのタイマーをセット
1835
+ const timerId = setTimeout(() => {
1836
+ // 使用中リストに追加したIDを削除
1837
+ const i = sys.__timeout.indexOf(timerId)
1838
+ if (i >= 0) { sys.__timeout.splice(i, 1) }
1839
+ try {
1840
+ f(timerId, sys)
1841
+ } catch (e) {
1842
+ let err = e
1843
+ if (!(e instanceof NakoRuntimeError)) {
1844
+ err = new NakoRuntimeError(e, sys.__varslist[0].line)
1845
+ }
1846
+ sys.logger.error(err)
1847
+ }
1848
+ }, parseFloat(n) * 1000)
1849
+ sys.__timeout.unshift(timerId)
1850
+ sys.__v0['対象'] = timerId
1851
+ return timerId
1852
+ }
1853
+ },
1854
+ '秒毎': { // @無名関数(あるいは、文字列で関数名を指定)FをN秒ごとに実行する(『タイマー停止』で停止できる)。変数『対象』にタイマーIDを代入する。 // @びょうごと
1855
+ type: 'func',
1856
+ josi: [['を'], ['']],
1857
+ pure: false,
1858
+ fn: function (f, n, sys) {
1859
+ // 文字列で指定された関数をオブジェクトに変換
1860
+ if (typeof f === 'string') { f = sys.__findFunc(f, '秒毎') }
1861
+ // タイマーをセット
1862
+ const timerId = setInterval(() => {
1863
+ f(timerId, sys)
1864
+ }, parseFloat(n) * 1000)
1865
+ // タイマーIDを追加
1866
+ sys.__interval.unshift(timerId)
1867
+ sys.__v0['対象'] = timerId
1868
+ return timerId
1869
+ }
1870
+ },
1871
+ '秒タイマー開始時': { // @無名関数(あるいは、文字列で関数名を指定)FをN秒ごとに実行する(『秒毎』と同じ) // @びょうたいまーかいししたとき
1872
+ type: 'func',
1873
+ josi: [['を'], ['']],
1874
+ pure: false,
1875
+ fn: function (f, n, sys) {
1876
+ return sys.__exec('秒毎', [f, n, sys])
1877
+ }
1878
+ },
1879
+ 'タイマー停止': { // @『秒毎』『秒後』や『秒タイマー開始』で開始したタイマーを停止する // @たいまーていし
1880
+ type: 'func',
1881
+ josi: [['の', 'で']],
1882
+ pure: true,
1883
+ fn: function (timerId, sys) {
1884
+ const i = sys.__interval.indexOf(timerId)
1885
+ if (i >= 0) {
1886
+ sys.__interval.splice(i, 1)
1887
+ clearInterval(timerId)
1888
+ return true
1889
+ }
1890
+ const j = sys.__timeout.indexOf(timerId)
1891
+ if (j >= 0) {
1892
+ sys.__timeout.splice(j, 1)
1893
+ clearTimeout(timerId)
1894
+ return true
1895
+ }
1896
+ return false
1897
+ },
1898
+ return_none: false
1899
+ },
1900
+ '全タイマー停止': { // @『秒毎』『秒後』や『秒タイマー開始』で開始したタイマーを全部停止する // @ぜんたいまーていし
1901
+ type: 'func',
1902
+ josi: [],
1903
+ pure: true,
1904
+ fn: function (sys) {
1905
+ // clearInterval
1906
+ for (let i = 0; i < sys.__interval.length; i++) {
1907
+ const timerId = sys.__interval[i]
1908
+ clearInterval(timerId)
1909
+ }
1910
+ sys.__interval = []
1911
+ // clearTimeout
1912
+ for (let i = 0; i < sys.__timeout.length; i++) {
1913
+ const timerId = sys.__timeout[i]
1914
+ clearTimeout(timerId)
1915
+ }
1916
+ sys.__timeout = []
1917
+ },
1918
+ return_none: true
1919
+ },
1920
+ // @日時処理(簡易)
1921
+ '今': { // @現在時刻を「HH:mm:ss」の形式で返す // @いま
1922
+ type: 'func',
1923
+ josi: [],
1924
+ pure: true,
1925
+ fn: function () {
1926
+ const z2 = (n) => {
1927
+ n = '00' + n
1928
+ return n.substr(n.length - 2, 2)
1929
+ }
1930
+ const t = new Date()
1931
+ return z2(t.getHours()) + ':' + z2(t.getMinutes()) + ':' + z2(t.getSeconds())
1932
+ }
1933
+ },
1934
+ 'システム時間': { // @現在のUNIX時間 (UTC(1970/1/1)からの経過秒数) を返す // @しすてむじかん
1935
+ type: 'func',
1936
+ josi: [],
1937
+ pure: true,
1938
+ fn: function () {
1939
+ const now = new Date()
1940
+ return now.getTime() / 1000
1941
+ }
1942
+ },
1943
+ '今日': { // @今日の日付を「YYYY/MM/DD」の形式で返す // @きょう
1944
+ type: 'func',
1945
+ josi: [],
1946
+ pure: true,
1947
+ fn: function () {
1948
+ const z2 = (n) => {
1949
+ n = '00' + n
1950
+ return n.substr(n.length - 2, 2)
1951
+ }
1952
+ const t = new Date()
1953
+ return t.getFullYear() + '/' + z2(t.getMonth() + 1) + '/' + z2(t.getDate())
1954
+ }
1955
+ },
1956
+ '曜日番号取得': { // @Sに指定した日付の曜日番号をで返す。不正な日付の場合は今日の曜日番号を返す。(0=日/1=月/2=火/3=水/4=木/5=金/6=土) // @ようびばんごうしゅとく
1957
+ type: 'func',
1958
+ josi: [['の']],
1959
+ pure: true,
1960
+ fn: function (s) {
1961
+ const a = s.split('/')
1962
+ const t = new Date(a[0], a[1] - 1, a[2])
1963
+ return t.getDay()
1964
+ }
1965
+ },
1966
+ '時間ミリ秒取得': { // @ミリ秒単位の時間を数値で返す。結果は実装に依存する。 // @じかんみりびょうしゅとく
1967
+ type: 'func',
1968
+ josi: [],
1969
+ pure: true,
1970
+ fn: function () {
1971
+ if (performance && performance.now) {
1972
+ return performance.now()
1973
+ } else if (Date.now) {
1974
+ return Date.now()
1975
+ } else {
1976
+ const now = new Date()
1977
+ return now.getTime()
1978
+ }
1979
+ }
1980
+ },
1981
+ // @デバッグ支援
1982
+ 'エラー発生': { // @故意にエラーSを発生させる // @えらーはっせい
1983
+ type: 'func',
1984
+ josi: [['の', 'で']],
1985
+ pure: true,
1986
+ fn: function (s) {
1987
+ throw new Error(s)
1988
+ }
1989
+ },
1990
+ 'システム関数一覧取得': { // @システム関数の一覧を取得 // @しすてむかんすういちらんしゅとく
1991
+ type: 'func',
1992
+ josi: [],
1993
+ pure: true,
1994
+ fn: function (sys) {
1995
+ const f = []
1996
+ for (const key in sys.__v0) {
1997
+ const ff = sys.__v0[key]
1998
+ if (typeof ff === 'function') { f.push(key) }
1999
+ }
2000
+ return f
2001
+ }
2002
+ },
2003
+ 'システム関数存在': { // @文字列で関数名を指定してシステム関数が存在するかを調べる // @しすてむかんすうそんざい
2004
+ type: 'func',
2005
+ josi: [['が', 'の']],
2006
+ pure: true,
2007
+ fn: function (fname, sys) {
2008
+ return (typeof sys.__v0[fname] !== 'undefined')
2009
+ }
2010
+ },
2011
+ 'プラグイン一覧取得': { // @利用中のプラグイン一覧を得る // @ぷらぐいんいちらんしゅとく
2012
+ type: 'func',
2013
+ josi: [],
2014
+ pure: true,
2015
+ fn: function (sys) {
2016
+ const a = []
2017
+ for (const f in sys.pluginfiles) { a.push(f) }
2018
+
2019
+ return a
2020
+ }
2021
+ },
2022
+ 'モジュール一覧取得': { // @取り込んだモジュール一覧を得る // @もじゅーるいちらんしゅとく
2023
+ type: 'func',
2024
+ josi: [],
2025
+ pure: true,
2026
+ fn: function (sys) {
2027
+ const a = []
2028
+ for (const f in sys.__module) { a.push(f) }
2029
+
2030
+ return a
2031
+ }
2032
+ },
2033
+ '助詞一覧取得': { // @文法として定義されている助詞の一覧を取得する // @じょしいちらんしゅとく
2034
+ type: 'func',
2035
+ josi: [],
2036
+ pure: true,
2037
+ fn: function () {
2038
+ const josi = require('./nako_josi_list.js')
2039
+ return josi.josiList
2040
+ }
2041
+ },
2042
+ '予約語一覧取得': { // @文法として定義されている予約語の一覧を取得する // @よやくごいちらんしゅとく
2043
+ type: 'func',
2044
+ josi: [],
2045
+ pure: true,
2046
+ fn: function () {
2047
+ const words = require('./nako_reserved_words.js')
2048
+ const w = []
2049
+ for (const key in words) {
2050
+ w.push(key)
2051
+ }
2052
+ return w
2053
+ }
2054
+ },
2055
+ // @プラグイン管理
2056
+ 'プラグイン名': { type: 'const', value: 'メイン' }, // @ぷらぐいんめい
2057
+ 'プラグイン名設定': { // @プラグイン名をSに変更する // @プラグインめいせってい
2058
+ type: 'func',
2059
+ josi: [['に', 'へ']],
2060
+ pure: false,
2061
+ fn: function (s, sys) {
2062
+ sys.__v0['プラグイン名'] = s
2063
+ },
2064
+ return_none: true
2065
+ },
2066
+
2067
+ // @URLエンコードとパラメータ
2068
+ 'URLエンコード': { // @URLエンコードして返す // @URLえんこーど
2069
+ type: 'func',
2070
+ josi: [['を', 'から']],
2071
+ pure: true,
2072
+ fn: function (text) {
2073
+ return encodeURIComponent(text)
2074
+ }
2075
+ },
2076
+ 'URLデコード': { // @URLデコードして返す // @URLでこーど
2077
+ type: 'func',
2078
+ josi: [['を', 'へ', 'に']],
2079
+ pure: true,
2080
+ fn: function (text) {
2081
+ return decodeURIComponent(text)
2082
+ }
2083
+ },
2084
+ 'URLパラメータ解析': { // @URLパラメータを解析してハッシュで返す // @URLぱらめーたかいせき
2085
+ type: 'func',
2086
+ josi: [['を', 'の', 'から']],
2087
+ pure: false,
2088
+ fn: function (url, sys) {
2089
+ const res = {}
2090
+ if (typeof url !== 'string') {
2091
+ return res
2092
+ }
2093
+ const p = url.split('?')
2094
+ if (p.length <= 1) {
2095
+ return res
2096
+ }
2097
+ const params = p[1].split('&')
2098
+ for (const line of params) {
2099
+ const line2 = line + '='
2100
+ const kv = line2.split('=')
2101
+ const k = sys.__exec('URLデコード', [kv[0]])
2102
+ res[k] = sys.__exec('URLデコード', [kv[1]])
2103
+ }
2104
+ return res
2105
+ }
2106
+ }
2107
+ }
2108
+
2109
+ module.exports = PluginSystem