nadesiko3 3.7.21 → 3.7.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/batch/command.txt +370 -334
  2. package/batch/jsplugin2text.nako3 +1 -1
  3. package/batch/pickup_command.nako3 +12 -0
  4. package/core/command/snako.mts +5 -1
  5. package/core/deno/snako.ts +5 -1
  6. package/core/package-lock.json +382 -21
  7. package/core/package.json +4 -4
  8. package/core/src/nako3.mts +178 -614
  9. package/core/src/nako_basic_plugins.mts +39 -0
  10. package/core/src/nako_core_version.mts +2 -2
  11. package/core/src/nako_csv.mts +0 -1
  12. package/core/src/nako_event.mts +49 -0
  13. package/core/src/nako_gen.mts +291 -202
  14. package/core/src/nako_indent_inline.mts +2 -2
  15. package/core/src/nako_lex_rules.mts +1 -1
  16. package/core/src/nako_parser3.mts +106 -165
  17. package/core/src/nako_parser_async.mts +97 -0
  18. package/core/src/nako_parser_base.mts +4 -55
  19. package/core/src/nako_parser_message.mts +105 -0
  20. package/core/src/nako_parser_operator.mts +93 -0
  21. package/core/src/nako_plugin_manager.mts +260 -0
  22. package/core/src/nako_require.mts +292 -0
  23. package/core/src/nako_runner.mts +191 -0
  24. package/core/src/nako_tokenizer.mts +221 -0
  25. package/core/src/plugin_csv.mts +1 -1
  26. package/core/src/plugin_system.mts +34 -3259
  27. package/core/src/plugin_system_array.mts +699 -0
  28. package/core/src/plugin_system_datetime.mts +368 -0
  29. package/core/src/plugin_system_debug.mts +403 -0
  30. package/core/src/plugin_system_dict.mts +85 -0
  31. package/core/src/plugin_system_json.mts +73 -0
  32. package/core/src/plugin_system_math.mts +383 -0
  33. package/core/src/plugin_system_regexp.mts +120 -0
  34. package/core/src/plugin_system_stdio.mts +86 -0
  35. package/core/src/plugin_system_string.mts +666 -0
  36. package/core/src/plugin_system_timer.mts +152 -0
  37. package/core/src/plugin_system_types.mts +151 -0
  38. package/core/src/plugin_system_url.mts +193 -0
  39. package/core/src/plugin_toml.mts +3 -3
  40. package/core/test/fixtures/README.md +39 -0
  41. package/core/test/fixtures/make_parser_ast_golden.mjs +31 -0
  42. package/core/test/fixtures/parser_ast_golden.json +8027 -0
  43. package/core/test/fixtures/parser_corpus.mjs +120 -0
  44. package/core/test/indent_test.mjs +6 -0
  45. package/core/test/nako_basic_plugins_test.mjs +44 -0
  46. package/core/test/nako_event_test.mjs +85 -0
  47. package/core/test/nako_gen_perf_test.mjs +178 -0
  48. package/core/test/nako_parser_async_test.mjs +112 -0
  49. package/core/test/nako_parser_test.mjs +160 -0
  50. package/core/test/nako_plugin_manager_test.mjs +185 -0
  51. package/core/test/nako_require_test.mjs +153 -0
  52. package/core/test/nako_runner_test.mjs +114 -0
  53. package/core/test/nako_tokenizer_test.mjs +115 -0
  54. package/core/test/plugin_system_debug_test.mjs +141 -0
  55. package/core/test/plugin_system_split_test.mjs +179 -0
  56. package/core/test/plugin_system_test.mjs +6 -0
  57. package/core/tsconfig.json +0 -1
  58. package/package.json +17 -21
  59. package/release/_hash.txt +36 -36
  60. package/release/_script-tags.txt +16 -16
  61. package/release/command.json +1 -1
  62. package/release/command.json.js +1 -1
  63. package/release/command_cnako3.json +1 -1
  64. package/release/command_list.json +1 -1
  65. package/release/edit_main.js +6 -6
  66. package/release/edit_main.js.map +3 -3
  67. package/release/editor.js +6 -6
  68. package/release/plugin_keigo.js.map +3 -3
  69. package/release/plugin_markup.js +46 -46
  70. package/release/plugin_markup.js.map +3 -3
  71. package/release/plugin_weykturtle3d.js +1 -1
  72. package/release/plugin_weykturtle3d.js.map +3 -3
  73. package/release/version.js +2 -2
  74. package/release/version_main.js +2 -2
  75. package/release/version_main.js.map +1 -1
  76. package/release/wnako3.js +186 -213
  77. package/release/wnako3.js.map +4 -4
  78. package/release/wnako3webworker.js +172 -199
  79. package/release/wnako3webworker.js.map +4 -4
  80. package/src/cnako3mod.mjs +7 -2
  81. package/src/cnako3mod.mts +7 -2
  82. package/src/nako_version.mjs +2 -2
  83. package/src/nako_version.mts +2 -2
  84. package/src/plugin_browser_ajax.mjs +4 -4
  85. package/src/plugin_browser_ajax.mts +4 -4
  86. package/src/plugin_browser_audio.mjs +10 -10
  87. package/src/plugin_browser_audio.mts +10 -10
  88. package/src/plugin_browser_camera.mjs +4 -4
  89. package/src/plugin_browser_camera.mts +4 -4
  90. package/src/plugin_browser_canvas.mjs +2 -2
  91. package/src/plugin_browser_canvas.mts +2 -2
  92. package/src/plugin_browser_crypto.mjs +3 -3
  93. package/src/plugin_browser_crypto.mts +3 -3
  94. package/src/plugin_browser_dom_event.mjs +1 -1
  95. package/src/plugin_browser_dom_event.mts +1 -1
  96. package/src/plugin_browser_geolocation.mjs +1 -1
  97. package/src/plugin_browser_geolocation.mts +1 -1
  98. package/src/plugin_browser_hotkey.mjs +1 -1
  99. package/src/plugin_browser_hotkey.mts +1 -1
  100. package/src/plugin_browser_html.mjs +1 -1
  101. package/src/plugin_browser_html.mts +1 -1
  102. package/src/plugin_browser_location.mjs +1 -1
  103. package/src/plugin_browser_location.mts +1 -1
  104. package/src/plugin_browser_speech.mjs +1 -1
  105. package/src/plugin_browser_speech.mts +1 -1
  106. package/src/plugin_browser_storage.mjs +2 -2
  107. package/src/plugin_browser_storage.mts +2 -2
  108. package/src/plugin_httpserver.mjs +3 -3
  109. package/src/plugin_httpserver.mts +3 -3
  110. package/src/plugin_keigo.mjs +2 -2
  111. package/src/plugin_keigo.mts +2 -2
  112. package/src/plugin_node.mjs +48 -48
  113. package/src/plugin_node.mts +53 -53
  114. package/src/plugin_weykturtle3d.mjs +56 -56
  115. package/src/plugin_weykturtle3d.mts +56 -56
  116. package/src/wnako3.mjs +1 -1
  117. package/src/wnako3.mts +1 -1
  118. package/src/wnako3_editor.mjs +5 -5
  119. package/src/wnako3_editor.mts +5 -5
  120. package/src/wnako3mod.mjs +2 -2
  121. package/src/wnako3mod.mts +2 -2
  122. package/core/src/nako3.mjs +0 -1021
  123. package/core/src/nako_ast.mjs +0 -4
  124. package/core/src/nako_colors.mjs +0 -77
  125. package/core/src/nako_core_version.mjs +0 -8
  126. package/core/src/nako_csv.mjs +0 -193
  127. package/core/src/nako_errors.mjs +0 -166
  128. package/core/src/nako_from_dncl.mjs +0 -285
  129. package/core/src/nako_from_dncl2.mjs +0 -347
  130. package/core/src/nako_gen.mjs +0 -2500
  131. package/core/src/nako_global.mjs +0 -138
  132. package/core/src/nako_indent.mjs +0 -442
  133. package/core/src/nako_indent_chars.mjs +0 -29
  134. package/core/src/nako_indent_inline.mjs +0 -361
  135. package/core/src/nako_josi_list.mjs +0 -47
  136. package/core/src/nako_lex_rules.mjs +0 -319
  137. package/core/src/nako_lexer.mjs +0 -794
  138. package/core/src/nako_logger.mjs +0 -221
  139. package/core/src/nako_parser3.mjs +0 -3250
  140. package/core/src/nako_parser_base.mjs +0 -403
  141. package/core/src/nako_parser_const.mjs +0 -37
  142. package/core/src/nako_prepare.mjs +0 -329
  143. package/core/src/nako_reserved_words.mjs +0 -42
  144. package/core/src/nako_source_mapping.mjs +0 -207
  145. package/core/src/nako_test.mjs +0 -37
  146. package/core/src/nako_token.mjs +0 -1
  147. package/core/src/nako_tools.mjs +0 -53
  148. package/core/src/nako_types.mjs +0 -14
  149. package/core/src/plugin_api.mjs +0 -4
  150. package/core/src/plugin_csv.mjs +0 -97
  151. package/core/src/plugin_math.mjs +0 -352
  152. package/core/src/plugin_promise.mjs +0 -102
  153. package/core/src/plugin_system.mjs +0 -3810
  154. package/core/src/plugin_test.mjs +0 -52
  155. package/core/src/plugin_toml.mjs +0 -39
@@ -0,0 +1,383 @@
1
+ /**
2
+ * @fileOverview なでしこ3 plugin_system の分割ファイル
3
+ *
4
+ * 四則演算・論理演算・ビット演算の命令を定義する。
5
+ * このファイルは単独のプラグインではなく、plugin_system.mts へマージされる。(#2351)
6
+ */
7
+ export default {
8
+ // @四則演算
9
+ '足': { // @AとBを足す(算術演算を行う) // @たす
10
+ type: 'func',
11
+ josi: [['に', 'と'], ['を']],
12
+ isVariableJosi: false,
13
+ pure: true,
14
+ fn: function(a: any, b: any) {
15
+ if (typeof (a) === 'bigint' || typeof (b) === 'bigint') {
16
+ return BigInt(a) + BigInt(b)
17
+ }
18
+ return parseFloat(a) + parseFloat(b)
19
+ }
20
+ },
21
+ '合計': { // @引数(可変)に指定した値を全て合計して返す // @ごうけい
22
+ type: 'func',
23
+ josi: [['と', 'を', 'の']],
24
+ isVariableJosi: true,
25
+ pure: true,
26
+ fn: function(...a: any) {
27
+ const sys = a.pop() // remove NakoSystem
28
+ if (a.length >= 1 && a[0] instanceof Array) {
29
+ return sys.__exec('配列合計', [a[0], sys])
30
+ }
31
+ let isBigInt = false
32
+ let sum = 0
33
+ for (const v of a) {
34
+ if (typeof (v) === 'bigint') {
35
+ isBigInt = true
36
+ break
37
+ }
38
+ sum += parseFloat(v)
39
+ }
40
+ if (isBigInt) {
41
+ let bigsum = 0n
42
+ for (const v of a) {
43
+ bigsum += BigInt(v)
44
+ }
45
+ return bigsum
46
+ }
47
+ return sum
48
+ }
49
+ },
50
+ '引': { // @AからBを引く // @ひく
51
+ type: 'func',
52
+ josi: [['から'], ['を']],
53
+ pure: true,
54
+ fn: function(a: any, b: any) {
55
+ return a - b
56
+ }
57
+ },
58
+ '掛': { // @AにBを掛ける // @かける
59
+ type: 'func',
60
+ josi: [['に', 'と'], ['を']],
61
+ pure: true,
62
+ fn: function(a: any, b: any) {
63
+ // 数値の掛け算
64
+ if (typeof a === 'number') {
65
+ return a * b
66
+ }
67
+ // 文字列の掛け算(文字列の繰り返し)
68
+ if (typeof a === 'string') {
69
+ let s = ''
70
+ for (let i = 0; i < parseInt(b); i++) {
71
+ s += a
72
+ }
73
+ return s
74
+ }
75
+ // 配列の繰り返し
76
+ if (a instanceof Array) {
77
+ const aa: any[] = []
78
+ for (let i = 0; i < parseInt(b); i++) {
79
+ aa.push(...a)
80
+ }
81
+ return aa
82
+ }
83
+ return a * b
84
+ }
85
+ },
86
+ '倍': { // @AのB倍を求める // @ばい
87
+ type: 'func',
88
+ josi: [['の', 'を'], ['']],
89
+ pure: true,
90
+ fn: function(a: any, b: any) {
91
+ return a * b
92
+ }
93
+ },
94
+ '割': { // @AをBで割る // @わる
95
+ type: 'func',
96
+ josi: [['を'], ['で']],
97
+ pure: true,
98
+ fn: function(a: any, b: any) {
99
+ return a / b
100
+ }
101
+ },
102
+ '割余': { // @AをBで割った余りを求める // @わったあまり
103
+ type: 'func',
104
+ josi: [['を'], ['で']],
105
+ pure: true,
106
+ fn: function(a: any, b: any) {
107
+ return a % b
108
+ }
109
+ },
110
+ '偶数': { // @Aが偶数なら真を返す // @ぐうすう
111
+ type: 'func',
112
+ josi: [['が']],
113
+ pure: true,
114
+ fn: function(a: any) {
115
+ return (parseInt(a) % 2 === 0)
116
+ }
117
+ },
118
+ '奇数': { // @Aが奇数なら真を返す // @きすう
119
+ type: 'func',
120
+ josi: [['が']],
121
+ pure: true,
122
+ fn: function(a: any) {
123
+ return (parseInt(a) % 2 === 1)
124
+ }
125
+ },
126
+ '二乗': { // @Aを二乗する // @にじょう
127
+ type: 'func',
128
+ josi: [['の', 'を']],
129
+ pure: true,
130
+ fn: function(a: any) {
131
+ return a * a
132
+ }
133
+ },
134
+ 'べき乗': { // @AのB乗を求める // @べきじょう
135
+ type: 'func',
136
+ josi: [['の'], ['の']],
137
+ pure: true,
138
+ fn: function(a: any, b: any) {
139
+ return Math.pow(a, b)
140
+ }
141
+ },
142
+ '以上': { // @AがB以上か // @いじょう
143
+ type: 'func',
144
+ josi: [['が'], ['']],
145
+ pure: true,
146
+ fn: function(a: any, b: any) {
147
+ return a >= b
148
+ }
149
+ },
150
+ '以下': { // @AがB以下か // @いか
151
+ type: 'func',
152
+ josi: [['が'], ['']],
153
+ pure: true,
154
+ fn: function(a: any, b: any) {
155
+ return a <= b
156
+ }
157
+ },
158
+ '未満': { // @AがB未満か // @みまん
159
+ type: 'func',
160
+ josi: [['が'], ['']],
161
+ pure: true,
162
+ fn: function(a: any, b: any) {
163
+ return a < b
164
+ }
165
+ },
166
+ '超': { // @AがB超か // @ちょう
167
+ type: 'func',
168
+ josi: [['が'], ['']],
169
+ pure: true,
170
+ fn: function(a: any, b: any) {
171
+ return a > b
172
+ }
173
+ },
174
+ '等': { // @AがBと等しいか // @ひとしい
175
+ type: 'func',
176
+ josi: [['が'], ['と']],
177
+ pure: true,
178
+ fn: function(a: any, b: any) {
179
+ return a === b
180
+ }
181
+ },
182
+ '等無': { // @AがBと等しくないか // @ひとしくない
183
+ type: 'func',
184
+ josi: [['が'], ['と']],
185
+ pure: true,
186
+ fn: function(a: any, b: any) {
187
+ return a !== b
188
+ }
189
+ },
190
+ '一致': { // @AがBと一致するか(配列や辞書も比較可能) // @いっち
191
+ type: 'func',
192
+ josi: [['が'], ['と']],
193
+ pure: true,
194
+ fn: function(a: any, b: any) {
195
+ // オブジェクトの場合、JSONに変換して比較
196
+ if (typeof (a) === 'object') {
197
+ const jsonA = JSON.stringify(a)
198
+ const jsonB = JSON.stringify(b)
199
+ return jsonA === jsonB
200
+ }
201
+ return a === b
202
+ }
203
+ },
204
+ '不一致': { // @AがBと不一致か(配列や辞書も比較可能) // @ふいっち
205
+ type: 'func',
206
+ josi: [['が'], ['と']],
207
+ pure: true,
208
+ fn: function(a: any, b: any) {
209
+ // オブジェクトの場合、JSONに変換して比較
210
+ if (typeof (a) === 'object') {
211
+ const jsonA = JSON.stringify(a)
212
+ const jsonB = JSON.stringify(b)
213
+ return jsonA !== jsonB
214
+ }
215
+ return a !== b
216
+ }
217
+ },
218
+ '範囲内': { // @VがAからBの範囲内か // @はんいない
219
+ type: 'func',
220
+ josi: [['が'], ['から'], ['の', 'までの']],
221
+ pure: true,
222
+ fn: function(v: any, a: any, b: any) {
223
+ return (a <= v) && (v <= b)
224
+ }
225
+ },
226
+ '範囲': { // @AからBの範囲を表現する範囲オブジェクトを返す // @はんい
227
+ type: 'func',
228
+ josi: [['から'], ['の', 'までの']],
229
+ pure: true,
230
+ fn: function(a: any, b: any) {
231
+ return {
232
+ '先頭': a,
233
+ '末尾': b
234
+ }
235
+ }
236
+ },
237
+ '連続加算': { // @A1+A2+A3...にBを足す // @れんぞくかさん
238
+ type: 'func',
239
+ josi: [['を'], ['に', 'と']],
240
+ isVariableJosi: true,
241
+ pure: true,
242
+ fn: function(b: any, ...a: any) {
243
+ a.pop() // 必ず末尾に sys があるので、末尾のシステム変数を除外
244
+ a.push(b)
245
+
246
+ return a.reduce((p: any, c: any) => p + c)
247
+ }
248
+ },
249
+ 'MAX': { // @2個以上の数値のうち最大値を返す。// @MAX
250
+ type: 'func',
251
+ josi: [['の'], ['と']],
252
+ isVariableJosi: true,
253
+ pure: true,
254
+ fn: function(b: number, ...a: any): number {
255
+ const sys = a.pop()
256
+ return sys.__exec('最大値', [b, ...a, sys])
257
+ }
258
+ },
259
+ '最大値': { // @2個以上の数値のうち最大値を返す。// @さいだいち
260
+ type: 'func',
261
+ josi: [['の'], ['と']],
262
+ isVariableJosi: true,
263
+ pure: true,
264
+ fn: function(b: number, ...a: any): number {
265
+ a.pop() // 必ず末尾に sys があるので、末尾のシステム変数を除外
266
+ a.push(b)
267
+ return a.reduce((p: number, c: number) => Math.max(p, c))
268
+ }
269
+ },
270
+ 'MIN': { // @2個以上の数値のうち最小値を返す。// @MIN
271
+ type: 'func',
272
+ josi: [['の'], ['と']],
273
+ isVariableJosi: true,
274
+ pure: true,
275
+ fn: function(b: number, ...a: any): number {
276
+ const sys = a.pop()
277
+ return sys.__exec('最小値', [b, ...a, sys])
278
+ }
279
+ },
280
+ '最小値': { // @2個以上の数値のうち最小値を返す。// @さいしょうち
281
+ type: 'func',
282
+ josi: [['の'], ['と']],
283
+ isVariableJosi: true,
284
+ pure: true,
285
+ fn: function(b: number, ...a: any): number {
286
+ a.pop() // 必ず末尾に sys があるので、末尾のシステム変数を除外
287
+ a.push(b)
288
+ return a.reduce((p: number, c: number) => Math.min(p, c))
289
+ }
290
+ },
291
+ 'CLAMP': { // @数値を下限から上限の範囲内に収めた値を返す。// @CLAMP
292
+ type: 'func',
293
+ josi: [['の', 'を'], ['から'], ['までの', 'で']],
294
+ pure: true,
295
+ fn: function(x: number, a: number, b: number): number {
296
+ return Math.min(Math.max(x, a), b)
297
+ }
298
+ },
299
+
300
+ // @論理演算
301
+ '論理OR': { // @AとBの論理和を返す(v1非互換)。 // @ろんりOR
302
+ type: 'func',
303
+ josi: [['と'], ['の']],
304
+ pure: true,
305
+ fn: function(a: any, b: any): any {
306
+ return (a || b)
307
+ }
308
+ },
309
+ '論理AND': { // @AとBの論理積を返す(v1非互換)。日本語の「AかつB」に相当する // @ろんりAND
310
+ type: 'func',
311
+ josi: [['と'], ['の']],
312
+ pure: true,
313
+ fn: function(a: any, b: any): boolean {
314
+ return (a && b)
315
+ }
316
+ },
317
+ '論理NOT': { // @値Vが0や空ならばtrue、それ以外ならばfalseを返す(v1非互換) // @ろんりNOT
318
+ type: 'func',
319
+ josi: [['の']],
320
+ pure: true,
321
+ fn: function(v: any): boolean {
322
+ return (!v)
323
+ }
324
+ },
325
+
326
+ // @ビット演算
327
+ 'OR': { // @(ビット演算で)AとBの論理和を返す。 // @OR
328
+ type: 'func',
329
+ josi: [['と'], ['の']],
330
+ pure: true,
331
+ fn: function(a: any, b: any): any {
332
+ return (a | b)
333
+ }
334
+ },
335
+ 'AND': { // @(ビット演算で)AとBの論理積を返す。日本語の「AかつB」に相当する // @AND
336
+ type: 'func',
337
+ josi: [['と'], ['の']],
338
+ pure: true,
339
+ fn: function(a: any, b: any): any {
340
+ return (a & b)
341
+ }
342
+ },
343
+ 'XOR': { // @(ビット演算で)AとBの排他的論理和を返す。// @XOR
344
+ type: 'func',
345
+ josi: [['と'], ['の']],
346
+ pure: true,
347
+ fn: function(a: any, b: any): any {
348
+ return (a ^ b)
349
+ }
350
+ },
351
+ 'NOT': { // @(ビット演算で)Vの各ビットを反転して返す。// @NOT
352
+ type: 'func',
353
+ josi: [['の']],
354
+ pure: true,
355
+ fn: function(v: any): any {
356
+ return (~v)
357
+ }
358
+ },
359
+ 'SHIFT_L': { // @VをAビット左へシフトして返す // @SHIFT_L
360
+ type: 'func',
361
+ josi: [['を'], ['で']],
362
+ pure: true,
363
+ fn: function(v: number, a: number): number {
364
+ return (v << a)
365
+ }
366
+ },
367
+ 'SHIFT_R': { // @VをAビット右へシフトして返す(符号を維持する) // @SHIFT_R
368
+ type: 'func',
369
+ josi: [['を'], ['で']],
370
+ pure: true,
371
+ fn: function(v: number, a: number): number {
372
+ return (v >> a)
373
+ }
374
+ },
375
+ 'SHIFT_UR': { // @VをAビット右へシフトして返す(符号を維持しない、0で埋める) // @SHIFT_UR
376
+ type: 'func',
377
+ josi: [['を'], ['で']],
378
+ pure: true,
379
+ fn: function(v: number, a: number): number {
380
+ return (v >>> a)
381
+ }
382
+ },
383
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * @fileOverview なでしこ3 plugin_system の分割ファイル
3
+ *
4
+ * 正規表現の命令を定義する。
5
+ * このファイルは単独のプラグインではなく、plugin_system.mts へマージされる。(#2351)
6
+ */
7
+ export default {
8
+ // @正規表現
9
+ '正規表現マッチ': { // @文字列Aを正規表現パターンBでマッチして結果を返す(パターンBは「/pat/opt」の形式で指定。optにgの指定がなければ部分マッチが『抽出文字列』に入る) // @せいきひょうげんまっち
10
+ type: 'func',
11
+ josi: [['を', 'が'], ['で', 'に']],
12
+ pure: true,
13
+ fn: function(a: string, b: string, sys: any): string {
14
+ let re
15
+ const f = ('' + b).match(/^\/(.+)\/([a-zA-Z]*)$/)
16
+ // パターンがない場合
17
+ if (f === null) { re = new RegExp(b, 'g') } else { re = new RegExp(f[1], f[2]) }
18
+ const sa: any[] = sys.__getSysVar('抽出文字列')
19
+ sa.splice(0, sa.length) // clear
20
+ const m = String(a).match(re)
21
+ let result: any = m
22
+ if (re.global) {
23
+ // no groups
24
+ } else if (m) {
25
+ // has group?
26
+ if (m.length > 0) {
27
+ result = m[0]
28
+ for (let i = 1; i < m.length; i++) { sa[i - 1] = m[i] }
29
+ }
30
+ }
31
+ return result
32
+ }
33
+ },
34
+ '正規表現抽出': { // @文字列Sを正規表現パターンREで正規表現マッチし、すべてのキャプチャグループ( )を一次元配列として返す。抽出文字列には二次元配列を返す// @せいきひょうげんちゅうしゅつ
35
+ type: 'func',
36
+ josi: [['から','を'], ['で']],
37
+ pure: true,
38
+ fn: function(a: string, b: string, sys: any): any[] {
39
+ let pattern = '' + b
40
+ let flags = 'g'
41
+ const f = pattern.match(/^\/(.+)\/([a-zA-Z]*)$/)
42
+ if (f) {
43
+ pattern = f[1]
44
+ flags = f[2] || ''
45
+ }
46
+ if (!flags.includes('g')) flags += 'g'
47
+
48
+ const re = new RegExp(pattern, flags)
49
+
50
+ const sa: any[] = sys.__getSysVar('抽出文字列')
51
+ sa.splice(0, sa.length) // clear
52
+
53
+ const result: any[] = [] // 一次元配列
54
+ const caps2d: any[] = [] // 二次元配列(sa に入れる)
55
+
56
+ for (const m of String(a).matchAll(re)) {
57
+
58
+ // ★ 名前付きキャプチャがある場合
59
+ if (m.groups && Object.keys(m.groups).length > 0) {
60
+ const row: Record<string, string> = {}
61
+
62
+ for (const [key, val] of Object.entries(m.groups)) {
63
+ row[key] = val
64
+ result.push(val) // result は平坦化
65
+ }
66
+
67
+ caps2d.push(row)
68
+ continue
69
+ }
70
+
71
+ // ★ 通常キャプチャ(従来どおり)
72
+ let caps = [...m].slice(1)
73
+
74
+ if (caps.length === 0) {
75
+ caps = [m[0]] //キャプチャがない場合
76
+ }
77
+
78
+ caps2d.push(caps)
79
+ result.push(...caps)
80
+ }
81
+
82
+ // マッチなし → 両方空のまま
83
+ if (caps2d.length === 0) {
84
+ return result
85
+ }
86
+
87
+ // sa に二次元配列をコピー
88
+ for (const row of caps2d) {
89
+ sa.push(row)
90
+ }
91
+
92
+ return result
93
+ }
94
+ },
95
+ '抽出文字列': { type: 'const', value: [] }, // @ちゅうしゅつもじれつ
96
+ '正規表現置換': { // @文字列Sの正規表現パターンAをBに置換して結果を返す(パターンAは/pat/optで指定) // @せいきひょうげんちかん
97
+ type: 'func',
98
+ josi: [['の'], ['を', 'から'], ['で', 'に', 'へ']],
99
+ pure: true,
100
+ fn: function(s: string, a: string, b: string): string {
101
+ let re
102
+ const f = a.match(/^\/(.+)\/([a-zA-Z]*)/)
103
+ if (f === null) { re = new RegExp(a, 'g') } else { re = new RegExp(f[1], f[2]) }
104
+
105
+ return String(s).replace(re, b)
106
+ }
107
+ },
108
+ '正規表現区切': { // @文字列Sを正規表現パターンAで区切って配列で返す(パターンAは/pat/optで指定) // @せいきひょうげんくぎる
109
+ type: 'func',
110
+ josi: [['を'], ['で']],
111
+ pure: true,
112
+ fn: function(s: any, a: any) {
113
+ let re
114
+ const f = a.match(/^\/(.+)\/([a-zA-Z]*)/)
115
+ if (f === null) { re = new RegExp(a, 'g') } else { re = new RegExp(f[1], f[2]) }
116
+
117
+ return String(s).split(re)
118
+ }
119
+ },
120
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @fileOverview なでしこ3 plugin_system の分割ファイル
3
+ *
4
+ * 標準出力の命令を定義する。
5
+ * このファイルは単独のプラグインではなく、plugin_system.mts へマージされる。(#2351)
6
+ */
7
+ import { NakoSystem } from './plugin_api.mjs'
8
+
9
+ export default {
10
+ // @標準出力
11
+ '表示': { // @Sを表示 // @ひょうじ
12
+ type: 'func',
13
+ josi: [['を', 'と']],
14
+ pure: true,
15
+ fn: function(s: string, sys: any) {
16
+ // 継続表示の一時プールを出力
17
+ s = String(sys.__printPool) + s
18
+ sys.__printPool = ''
19
+ //
20
+ sys.__setSysVar('表示ログ', String(sys.__getSysVar('表示ログ')) + s + '\n')
21
+ sys.logger.send('stdout', s + '')
22
+ },
23
+ return_none: true
24
+ },
25
+ '継続表示': { // @Sを改行なしで表示(ただし「表示」命令を使うことで画面出力される) // @けいぞくひょうじ
26
+ type: 'func',
27
+ josi: [['を', 'と']],
28
+ pure: true,
29
+ fn: function(s: string, sys: any) {
30
+ sys.__printPool += s
31
+ },
32
+ return_none: true
33
+ },
34
+ '連続表示': { // @引数に指定した引数を全て表示する // @れんぞくひょうじ
35
+ type: 'func',
36
+ josi: [['と', 'を']],
37
+ isVariableJosi: true,
38
+ pure: true,
39
+ fn: function(...a: any) {
40
+ const sys = a.pop()
41
+ const v = a.join('')
42
+ sys.__exec('表示', [v, sys])
43
+ },
44
+ return_none: true
45
+ },
46
+ '連続無改行表示': { // @引数に指定した引数を全て表示する(改行しない) // @れんぞくむかいぎょうひょうじ
47
+ type: 'func',
48
+ josi: [['と', 'を']],
49
+ isVariableJosi: true,
50
+ pure: true,
51
+ fn: function(...a: any) {
52
+ const sys = a.pop()
53
+ const v = a.join('')
54
+ sys.__exec('継続表示', [v, sys])
55
+ },
56
+ return_none: true
57
+ },
58
+ '表示ログ': { type: 'const', value: '' }, // @ひょうじろぐ
59
+ '表示ログクリア': { // @表示ログを空にする // @ひょうじろぐくりあ
60
+ type: 'func',
61
+ josi: [],
62
+ pure: true,
63
+ fn: function(sys: NakoSystem) {
64
+ sys.__setSysVar('表示ログ', '')
65
+ },
66
+ return_none: true
67
+ },
68
+ '言': { // @Sを表示 // @いう
69
+ type: 'func',
70
+ josi: [['を', 'と']],
71
+ pure: true,
72
+ fn: function(s: string, sys: any) {
73
+ sys.logger.send('stdout', s + '')
74
+ },
75
+ return_none: true
76
+ },
77
+ 'コンソール表示': { // @Sをコンソール表示する(console.log) // @こんそーるひょうじ
78
+ type: 'func',
79
+ josi: [['を', 'と']],
80
+ pure: true,
81
+ fn: function(s: string) {
82
+ console.log(s)
83
+ },
84
+ return_none: true
85
+ },
86
+ }