nadesiko3 3.7.22 → 3.7.23

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 (79) hide show
  1. package/README.md +20 -1
  2. package/batch/generate_command_list.mjs +102 -0
  3. package/batch/search_command.mjs +34 -0
  4. package/batch/search_command.nako3 +430 -0
  5. package/core/package.json +4 -1
  6. package/core/sample/algorithms/README.md +43 -0
  7. package/core/sample/algorithms/graph/dijkstra.nako3 +47 -0
  8. package/core/sample/algorithms/graph/kruskal.nako3 +69 -0
  9. package/core/sample/algorithms/math/euclidean_gcd.nako3 +15 -0
  10. package/core/sample/algorithms/math/sieve_of_eratosthenes.nako3 +26 -0
  11. package/core/sample/algorithms/search/binary_search.nako3 +17 -0
  12. package/core/sample/algorithms/search/breadth_first_search.nako3 +33 -0
  13. package/core/sample/algorithms/search/depth_first_search.nako3 +25 -0
  14. package/core/sample/algorithms/sort/heap_sort.nako3 +37 -0
  15. package/core/sample/algorithms/sort/insertion_sort.nako3 +18 -0
  16. package/core/sample/algorithms/sort/merge_sort.nako3 +40 -0
  17. package/core/sample/algorithms/sort/quick_sort.nako3 +36 -0
  18. package/core/sample/algorithms/string/knuth_morris_pratt.nako3 +50 -0
  19. package/core/sample/algorithms/string/run_length_encoding.nako3 +25 -0
  20. package/core/src/nako_core_version.mts +2 -2
  21. package/core/src/nako_gen.mts +30 -8
  22. package/core/src/nako_global.mts +18 -0
  23. package/core/src/nako_parser3.mts +5 -1
  24. package/core/src/nako_parser_async.mts +86 -18
  25. package/core/src/nako_runner.mts +21 -4
  26. package/core/test/algorithm_samples_test.mjs +58 -0
  27. package/core/test/algorithms/graph/dijkstra_test.nako3 +21 -0
  28. package/core/test/algorithms/graph/kruskal_test.nako3 +21 -0
  29. package/core/test/algorithms/helper.mjs +13 -0
  30. package/core/test/algorithms/math/euclidean_gcd_test.nako3 +13 -0
  31. package/core/test/algorithms/math/sieve_of_eratosthenes_test.nako3 +10 -0
  32. package/core/test/algorithms/search/binary_search_test.nako3 +15 -0
  33. package/core/test/algorithms/search/breadth_first_search_test.nako3 +13 -0
  34. package/core/test/algorithms/search/depth_first_search_test.nako3 +13 -0
  35. package/core/test/algorithms/sort/heap_sort_test.nako3 +13 -0
  36. package/core/test/algorithms/sort/insertion_sort_test.nako3 +13 -0
  37. package/core/test/algorithms/sort/merge_sort_test.nako3 +18 -0
  38. package/core/test/algorithms/sort/quick_sort_test.nako3 +34 -0
  39. package/core/test/algorithms/string/knuth_morris_pratt_test.nako3 +16 -0
  40. package/core/test/algorithms/string/run_length_encoding_test.nako3 +13 -0
  41. package/core/test/array_test.mjs +3 -0
  42. package/core/test/func_call.mjs +18 -0
  43. package/core/test/func_test.mjs +28 -0
  44. package/core/test/nako_event_test.mjs +42 -0
  45. package/core/test/nako_parser_async_test.mjs +284 -11
  46. package/core/test/nako_runner_test.mjs +60 -0
  47. package/core/test/plugin_system_debug_test.mjs +0 -3
  48. package/demo/browsers.html +1 -1
  49. package/doc/SETUP.md +1 -1
  50. package/doc/ai-code-generation.md +136 -0
  51. package/doc/browsers.md +1 -1
  52. package/doc/command_list.json +16842 -0
  53. package/doc/search_command.md +222 -0
  54. package/doc/syntax-nako3.md +344 -0
  55. package/package.json +13 -6
  56. package/release/_hash.txt +20 -20
  57. package/release/_script-tags.txt +16 -16
  58. package/release/plugin_caniuse.js +1 -1
  59. package/release/plugin_caniuse.js.map +2 -2
  60. package/release/version.js +1 -1
  61. package/release/version_main.js +1 -1
  62. package/release/version_main.js.map +1 -1
  63. package/release/wnako3.js +119 -103
  64. package/release/wnako3.js.map +3 -3
  65. package/release/wnako3webworker.js +78 -62
  66. package/release/wnako3webworker.js.map +3 -3
  67. package/src/browsers.mjs +1 -1
  68. package/src/browsers.txt +0 -1
  69. package/src/nako_version.mjs +2 -2
  70. package/src/nako_version.mts +2 -2
  71. package/test/nako3edit/index_nako3_test.mjs +282 -0
  72. package/test/nako3server/index_nako3_test.mjs +239 -0
  73. package/test/node/ai_code_generation_guide_test.mjs +29 -0
  74. package/test/node/node_version_support_test.mjs +45 -0
  75. package/test/node/search_command_test.mjs +174 -0
  76. package/tools/nako3edit/AGENTS.md +23 -0
  77. package/tools/nako3edit/index.nako3 +404 -0
  78. package/tools/nako3server/AGENTS.md +23 -0
  79. package/tools/nako3server/index.nako3 +156 -23
package/README.md CHANGED
@@ -13,6 +13,7 @@
13
13
  はじめて「なでしこ」に挑戦する方は、次のチュートリアルから始めることをオススメします。日本語プログラミング言語の雰囲気が容易に理解できます。
14
14
 
15
15
  - [チュートリアル](https://nadesi.com/v3/doc/go.php?997)
16
+ - [生成AIになでしこ3のプログラムを作ってもらう](doc/ai-code-generation.md)
16
17
 
17
18
  ## 対応機器/ブラウザ
18
19
 
@@ -22,7 +23,7 @@
22
23
  2. コマンドライン(cnako) - JavaScriptの実行エンジン「Node.js」上で動作
23
24
  3. 配付パッケージ - Electronを利用してローカルPC上で動作
24
25
 
25
- 具体的な対応ブラウザについて詳しくは、[対応機器/ブラウザ](doc/browsers.md) をご覧ください。Node.jsの対応バージョンは、v20以上です。
26
+ 具体的な対応ブラウザについて詳しくは、[対応機器/ブラウザ](doc/browsers.md) をご覧ください。Node.jsの対応バージョンは、v22以上です。
26
27
 
27
28
  ## ブラウザで利用する方法
28
29
 
@@ -124,6 +125,24 @@ npm start
124
125
  npm run nako3edit
125
126
  ```
126
127
 
128
+ ## 命令を検索するコマンド
129
+
130
+ なでしこ3の命令一覧(`doc/command_list.json`)を、ターミナルから検索できます。
131
+ 検索処理は、なでしこ3自身(`batch/search_command.nako3`)で書かれています。
132
+
133
+ ```sh
134
+ # 命令名・読み方・説明から部分一致検索
135
+ npm run search:command -- ファイル
136
+ # Node.js版で使える命令だけを検索
137
+ npm run search:command -- ファイル --target cnako
138
+ # JSON形式で出力(AIエージェントや別ツール向け)
139
+ npm run search:command -- CSV --json
140
+ # 使い方を表示
141
+ npm run search:command -- --help
142
+ ```
143
+
144
+ 詳しくは、[doc/search_command.md](doc/search_command.md) をご覧ください。
145
+
127
146
  ## Colabでなでしこを使って作業をする場合
128
147
 
129
148
  以下にColabを使ってなでしこを使う場合の作業用テンプレートを用意しました。
@@ -0,0 +1,102 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { fileURLToPath } from 'url'
4
+
5
+ const __filename = fileURLToPath(import.meta.url)
6
+ const __dirname = path.dirname(__filename)
7
+
8
+ const projectRoot = path.resolve(__dirname, '..')
9
+ const inputPath = path.join(projectRoot, 'batch', 'command.txt')
10
+ const outputDir = path.join(projectRoot, 'doc')
11
+ const outputPath = path.join(outputDir, 'command_list.json')
12
+
13
+ function main () {
14
+ if (!fs.existsSync(inputPath)) {
15
+ console.error(`Input file not found: ${inputPath}`)
16
+ process.exit(1)
17
+ }
18
+
19
+ const content = fs.readFileSync(inputPath, 'utf-8')
20
+ const lines = content.split(/\r?\n/)
21
+
22
+ let currentPlugin = ''
23
+ let currentGroup = ''
24
+ let currentTarget = []
25
+ let currentCategory = ''
26
+
27
+ const result = []
28
+
29
+ for (const line of lines) {
30
+ const trimmed = line.trim()
31
+ if (!trimmed) {
32
+ continue
33
+ }
34
+
35
+ // プラグイン宣言行: ■plugin_system(基本プラグイン,wnako,cnako,phpnako) または ■plugin_system
36
+ const pluginMatch = trimmed.match(/^■([^\(]+)(?:\((.+)\))?/)
37
+ if (pluginMatch) {
38
+ currentPlugin = pluginMatch[1].trim()
39
+ if (pluginMatch[2]) {
40
+ const params = pluginMatch[2].split(',').map((s) => s.trim())
41
+ currentGroup = params[0] || ''
42
+ currentTarget = params.slice(1)
43
+ } else {
44
+ currentGroup = ''
45
+ currentTarget = []
46
+ }
47
+ currentCategory = ''
48
+ continue
49
+ }
50
+
51
+ // カテゴリ宣言行: ●システム定数
52
+ const categoryMatch = trimmed.match(/^●(.+)/)
53
+ if (categoryMatch) {
54
+ currentCategory = categoryMatch[1].trim()
55
+ continue
56
+ }
57
+
58
+ // 命令・定数データ行: | タイプ | 名前 | 引数 | 説明または値 | よみ | URL
59
+ if (trimmed.startsWith('|')) {
60
+ const parts = trimmed.split('|').map((s) => s.trim())
61
+ // split('|') の先頭は空文字列(| の前)
62
+ // parts[1]: タイプ, parts[2]: 名前, parts[3]: 引数, parts[4]: 説明/値, parts[5]: よみ, parts[6]: URL
63
+ if (parts.length >= 7) {
64
+ const type = parts[1]
65
+ const name = parts[2]
66
+ const args = parts[3]
67
+ const descOrVal = parts[4]
68
+ const yomi = parts[5]
69
+ const url = parts[6]
70
+
71
+ const item = {
72
+ type,
73
+ name,
74
+ args,
75
+ yomi,
76
+ plugin: currentPlugin,
77
+ group: currentGroup,
78
+ target: currentTarget,
79
+ category: currentCategory,
80
+ url
81
+ }
82
+
83
+ if (type === '定数') {
84
+ item.value = descOrVal
85
+ } else {
86
+ item.description = descOrVal
87
+ }
88
+
89
+ result.push(item)
90
+ }
91
+ }
92
+ }
93
+
94
+ if (!fs.existsSync(outputDir)) {
95
+ fs.mkdirSync(outputDir, { recursive: true })
96
+ }
97
+
98
+ fs.writeFileSync(outputPath, JSON.stringify(result, null, 2), 'utf-8')
99
+ console.log(`Successfully generated ${outputPath} (${result.length} commands)`)
100
+ }
101
+
102
+ main()
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ // なでしこ3の命令一覧を検索するCLIの起動用ラッパー (#2385)
3
+ //
4
+ // cnako3は、なでしこのスクリプト名より後ろの引数も自前のオプション解析にかけるため、
5
+ // 「--help」などを直接渡すとcnako3自身のヘルプが表示されてしまう。
6
+ // そこで利用者の指定した引数は環境変数に入れて渡し、cnako3には渡さないようにする。
7
+ // 検索処理の本体は batch/search_command.nako3 (なでしこ3) にある。
8
+ import os from 'node:os'
9
+ import path from 'node:path'
10
+ import url from 'node:url'
11
+ import { spawn } from 'node:child_process'
12
+
13
+ const thisDir = path.dirname(url.fileURLToPath(import.meta.url))
14
+ const rootDir = path.resolve(thisDir, '..')
15
+ const cnako3Path = path.join(rootDir, 'src', 'cnako3.mjs')
16
+ const scriptPath = path.join(thisDir, 'search_command.nako3')
17
+
18
+ const child = spawn(process.execPath, [cnako3Path, scriptPath], {
19
+ stdio: 'inherit',
20
+ env: { ...process.env, NAKO3_SEARCH_ARGS: JSON.stringify(process.argv.slice(2)) }
21
+ })
22
+ child.on('error', (err) => {
23
+ console.error(`[エラー] 検索CLIを起動できませんでした: ${err.message}`)
24
+ process.exit(3)
25
+ })
26
+ child.on('exit', (code, signal) => {
27
+ if (signal) {
28
+ // シグナルで終了した場合は、検索結果の終了コード(1=一致なし)と混ざらないように
29
+ // シェルの慣習にならって 128+シグナル番号 を返す。
30
+ const signo = os.constants.signals[signal] || 0
31
+ process.exit(128 + signo)
32
+ }
33
+ process.exit(code === null ? 3 : code)
34
+ })
@@ -0,0 +1,430 @@
1
+ #-------------------------------------------------
2
+ # なでしこ3の命令一覧を検索するCLI (#2385)
3
+ #-------------------------------------------------
4
+ # 入力: doc/command_list.json
5
+ # 引数: 環境変数『NAKO3_SEARCH_ARGS』にJSON配列で指定する
6
+ # 起動: node batch/search_command.mjs (または npm run search:command)
7
+ #-------------------------------------------------
8
+
9
+ 命令ファイル=母艦パスを「../doc/command_list.json」で相対パス展開。
10
+
11
+ #-------------------------------------------------
12
+ # 引数の取得と解析
13
+ #-------------------------------------------------
14
+ # 環境変数から引数の配列を取得する
15
+ ●コマンド引数取得()
16
+ S=「NAKO3_SEARCH_ARGS」の環境変数取得。
17
+ もし、(Sの変数型確認)≠「string」ならば、[]で戻る。
18
+ もし、S=「」ならば、[]で戻る。
19
+ SをJSONデコード。
20
+ それで戻る。
21
+ ここまで。
22
+
23
+ # 『--option=値』の形式を『--option』『値』の2つに分解する
24
+ ●引数展開(ARGSを)
25
+ R=[]
26
+ ARGSを反復
27
+ A=「{対象}」
28
+ P=0
29
+ もし、Aが「--」で文字始ならば
30
+ P=Aで「=」が何文字目か。
31
+ ここまで。
32
+ もし、P>2ならば
33
+ NCNT=P-1
34
+ VCNT=(Aの文字数)-P
35
+ RにAのNCNTだけ文字左部分を配列追加。
36
+ RにAのVCNTだけ文字右部分を配列追加。
37
+ 違えば
38
+ RにAを配列追加。
39
+ ここまで。
40
+ ここまで。
41
+ Rで戻る。
42
+ ここまで。
43
+
44
+ # 引数の配列を解析して設定の辞書を返す
45
+ ●引数解析(ARGSを)
46
+ OPT=空辞書。
47
+ OPT['target']=「」
48
+ OPT['group']=「」
49
+ OPT['plugin']=「」
50
+ OPT['type']=「」
51
+ OPT['limit']=「50」
52
+ OPT['json']=オフ。
53
+ OPT['help']=オフ。
54
+ OPT['error']=「」
55
+ OPT['words']=[]
56
+ LIST=ARGSを引数展開。
57
+ N=LISTの要素数。
58
+ I=0
59
+ (I<N)の間、繰り返す
60
+ A=「{LIST[I]}」
61
+ もし、Aが「--」で文字始ならば
62
+ NCNT=(Aの文字数)-2
63
+ NAME=AのNCNTだけ文字右部分。
64
+ 値必要=オフ。
65
+ もし、(NAME=「target」)または(NAME=「group」)または(NAME=「plugin」)または(NAME=「type」)または(NAME=「limit」)ならば
66
+ 値必要=オン。
67
+ ここまで。
68
+ もし、値必要=オンならば
69
+ I=I+1
70
+ もし、I>=Nならば
71
+ OPT['error']=「オプション『{A}』には値の指定が必要です。」
72
+ 違えば
73
+ OPT[NAME]=「{LIST[I]}」
74
+ ここまで。
75
+ 違えば
76
+ もし、NAME=「help」ならば
77
+ OPT['help']=オン。
78
+ 違えば
79
+ もし、NAME=「json」ならば
80
+ OPT['json']=オン。
81
+ 違えば
82
+ OPT['error']=「不明なオプション『{A}』です。」
83
+ ここまで。
84
+ ここまで。
85
+ ここまで。
86
+ 違えば
87
+ もし、A=「-h」ならば
88
+ OPT['help']=オン。
89
+ 違えば
90
+ もし、(Aが「-」で文字始)かつ((Aの文字数)>1)ならば
91
+ OPT['error']=「不明なオプション『{A}』です。」
92
+ 違えば
93
+ OPT['words']にAを配列追加。
94
+ ここまで。
95
+ ここまで。
96
+ ここまで。
97
+ I=I+1
98
+ ここまで。
99
+ OPTで戻る。
100
+ ここまで。
101
+
102
+ # グループ名の指定を『基本プラグイン』『拡張プラグイン』に正規化する
103
+ ●グループ正規化(Gの)
104
+ G2=Gを小文字変換。
105
+ もし、(G2=「basic」)または(G=「基本」)または(G=「基本プラグイン」)ならば、「基本プラグイン」で戻る。
106
+ もし、(G2=「extra」)または(G2=「extended」)または(G=「拡張」)または(G=「拡張プラグイン」)ならば、「拡張プラグイン」で戻る。
107
+ 「」で戻る。
108
+ ここまで。
109
+
110
+ # オプションの値が正しいかを調べてエラーメッセージを返す(問題なければ空文字)
111
+ ●オプション検査(OPTを)
112
+ T=OPT['target']
113
+ もし、T≠「」ならば
114
+ TLIST=「cnako,wnako,phpnako,enako」
115
+ IDX=「,{TLIST},」で「,{T},」が何文字目か。
116
+ もし、IDX=0ならば
117
+ 「オプション『--target』には {TLIST} のいずれかを指定してください。指定値=『{T}』」で戻る。
118
+ ここまで。
119
+ ここまで。
120
+ G=OPT['group']
121
+ もし、G≠「」ならば
122
+ G2=Gのグループ正規化。
123
+ もし、G2=「」ならば
124
+ 「オプション『--group』には basic(基本プラグイン)またはextra(拡張プラグイン)を指定してください。指定値=『{G}』」で戻る。
125
+ ここまで。
126
+ ここまで。
127
+ TY=OPT['type']
128
+ もし、TY≠「」ならば
129
+ もし、(TY≠「関数」)かつ(TY≠「変数」)かつ(TY≠「定数」)ならば
130
+ 「オプション『--type』には 関数/変数/定数 のいずれかを指定してください。指定値=『{TY}』」で戻る。
131
+ ここまで。
132
+ ここまで。
133
+ L=OPT['limit']を整数変換。
134
+ もし、(「{L}」=「NaN」)または(L<0)ならば
135
+ 「オプション『--limit』には0以上の整数を指定してください。指定値=『{OPT['limit']}』」で戻る。
136
+ ここまで。
137
+ 「」で戻る。
138
+ ここまで。
139
+
140
+ #-------------------------------------------------
141
+ # 命令一覧の読み込み
142
+ #-------------------------------------------------
143
+ # doc/command_list.jsonを読み込んで検索しやすい形に整えて返す
144
+ ●命令一覧取得()
145
+ もし、(命令ファイルが存在)=偽ならば
146
+ 「[エラー] 命令一覧が見つかりません: {命令ファイル}」を表示。
147
+ 「先に『npm run build:command』を実行してください。」を表示。
148
+ []で戻る。
149
+ ここまで。
150
+ LIST=[]
151
+ エラー監視
152
+ S=命令ファイルを開く。
153
+ RAW=SをJSONデコード。
154
+ RAWを反復
155
+ C=対象。
156
+ D=空辞書。
157
+ D['type']=「{C['type']}」
158
+ D['name']=「{C['name']}」
159
+ D['args']=「{C['args']}」
160
+ D['yomi']=「{C['yomi']}」
161
+ D['plugin']=「{C['plugin']}」
162
+ D['group']=「{C['group']}」
163
+ D['target']=C['target']
164
+ D['description']=「」
165
+ もし、(C['description']の変数型確認)=「string」ならば
166
+ D['description']=C['description']
167
+ ここまで。
168
+ D['name_lc']=D['name']を小文字変換。
169
+ D['text_lc']=「{D['name']} {D['yomi']} {D['description']}」を小文字変換。
170
+ LISTにDを配列追加。
171
+ ここまで。
172
+ エラーならば
173
+ 「[エラー] 命令一覧を読み込めません: {エラーメッセージ}」を表示。
174
+ []で戻る。
175
+ ここまで。
176
+ LISTで戻る。
177
+ ここまで。
178
+
179
+ #-------------------------------------------------
180
+ # 検索と絞り込み
181
+ #-------------------------------------------------
182
+ # 命令Cが絞り込み条件OPTに合うかを返す
183
+ ●条件一致(CがOPTに)
184
+ T=OPT['target']
185
+ もし、T≠「」ならば
186
+ TS=C['target']を「,」で配列結合。
187
+ IDX=「,{TS},」で「,{T},」が何文字目か。
188
+ もし、IDX=0ならば、偽で戻る。
189
+ ここまで。
190
+ G=OPT['group']
191
+ もし、G≠「」ならば
192
+ G2=Gのグループ正規化。
193
+ もし、C['group']≠G2ならば、偽で戻る。
194
+ ここまで。
195
+ P=OPT['plugin']
196
+ もし、P≠「」ならば
197
+ IDX2=(C['plugin']を小文字変換)で(Pを小文字変換)が何文字目か。
198
+ もし、IDX2=0ならば、偽で戻る。
199
+ ここまで。
200
+ TY=OPT['type']
201
+ もし、TY≠「」ならば
202
+ もし、C['type']≠TYならば、偽で戻る。
203
+ ここまで。
204
+ 真で戻る。
205
+ ここまで。
206
+
207
+ # 命令Cが検索語WORDSをすべて含むかを返す
208
+ ●語一致(CがWORDSに)
209
+ HAY=C['text_lc']
210
+ WORDSを反復
211
+ W=(「{対象}」のトリム)を小文字変換。
212
+ もし、W≠「」ならば
213
+ IDX=HAYでWが何文字目か。
214
+ もし、IDX=0ならば、偽で戻る。
215
+ ここまで。
216
+ ここまで。
217
+ 真で戻る。
218
+ ここまで。
219
+
220
+ # 命令の一覧を検索して並び替えた配列を返す
221
+ ●命令検索(LISTをOPTで)
222
+ WORDS=OPT['words']
223
+ B0=[]
224
+ B1=[]
225
+ B2=[]
226
+ B3=[]
227
+ W=「」
228
+ もし、(WORDSの要素数)>0ならば
229
+ W=(「{WORDS[0]}」のトリム)を小文字変換。
230
+ ここまで。
231
+ LISTを反復
232
+ C=対象。
233
+ 合致=オン。
234
+ もし、(CがOPTに条件一致)=偽ならば、合致=オフ。
235
+ もし、(合致=オン)かつ((CがWORDSに語一致)=偽)ならば、合致=オフ。
236
+ もし、合致=オンならば
237
+ NM=C['name_lc']
238
+ もし、W=「」ならば
239
+ B3にCを配列追加。
240
+ 違えば
241
+ もし、NM=Wならば
242
+ B0にCを配列追加。
243
+ 違えば
244
+ もし、NMがWで文字始ならば
245
+ B1にCを配列追加。
246
+ 違えば
247
+ IDX=NMでWが何文字目か。
248
+ もし、IDX>0ならば
249
+ B2にCを配列追加。
250
+ 違えば
251
+ B3にCを配列追加。
252
+ ここまで。
253
+ ここまで。
254
+ ここまで。
255
+ ここまで。
256
+ ここまで。
257
+ ここまで。
258
+ R=[]
259
+ B0を反復、Rに対象を配列追加。
260
+ B1を反復、Rに対象を配列追加。
261
+ B2を反復、Rに対象を配列追加。
262
+ B3を反復、Rに対象を配列追加。
263
+ Rで戻る。
264
+ ここまで。
265
+
266
+ #-------------------------------------------------
267
+ # 出力
268
+ #-------------------------------------------------
269
+ # 使い方を表示する
270
+ ●ヘルプ表示()
271
+ 「なでしこ3 命令検索CLI - doc/command_list.jsonから命令を検索します」を表示。
272
+ 「」を表示。
273
+ 「使い方: npm run search:command -- [検索語...] [オプション]」を表示。
274
+ 「 node batch/search_command.mjs [検索語...] [オプション]」を表示。
275
+ 「」を表示。
276
+ 「検索語は命令名・読み方・説明から部分一致で検索します(複数指定するとAND条件)。」を表示。
277
+ 「」を表示。
278
+ 「オプション:」を表示。
279
+ 「 --target <名前> 実行環境で絞り込む (cnako/wnako/phpnako/enako)」を表示。
280
+ 「 --group <名前> 種別で絞り込む (basic=基本プラグイン, extra=拡張プラグイン)」を表示。
281
+ 「 --plugin <名前> プラグイン名で絞り込む (部分一致) 例: plugin_node」を表示。
282
+ 「 --type <種類> 命令の種類で絞り込む (関数/変数/定数)」を表示。
283
+ 「 --limit <件数> 表示する最大件数 (既定値=50、0で無制限)」を表示。
284
+ 「 --json JSON形式で出力する」を表示。
285
+ 「 --help, -h この使い方を表示する」を表示。
286
+ 「」を表示。
287
+ 「例:」を表示。
288
+ 「 npm run search:command -- ファイル --target cnako」を表示。
289
+ 「 npm run search:command -- DOM --target wnako --group basic」を表示。
290
+ 「 npm run search:command -- CSV --json」を表示。
291
+ 「」を表示。
292
+ 「終了コード: 0=見つかった / 1=一致なし / 2=引数エラー / 3=読み込みエラー」を表示。
293
+ ここまで。
294
+
295
+ # 命令Cを2行で表示する
296
+ ●命令表示(Cを)
297
+ S=「[{C['type']}] {C['name']}」
298
+ もし、C['args']≠「」ならば
299
+ S=「{S} ({C['args']})」
300
+ ここまで。
301
+ TS=C['target']を「,」で配列結合。
302
+ S=「{S} {C['plugin']} <{TS}>」
303
+ Sを表示。
304
+ もし、C['description']≠「」ならば
305
+ 「 {C['description']}」を表示。
306
+ ここまで。
307
+ ここまで。
308
+
309
+ # 検索条件を人が読める文字列にする
310
+ ●検索条件文字列(OPTを)
311
+ WORDS=OPT['words']
312
+ S=「(すべての命令)」
313
+ もし、(WORDSの要素数)>0ならば
314
+ WS=WORDSを「 」で配列結合。
315
+ S=「『{WS}』」
316
+ ここまで。
317
+ JOKEN=[]
318
+ もし、OPT['target']≠「」ならば、JOKENに「target={OPT['target']}」を配列追加。
319
+ もし、OPT['group']≠「」ならば
320
+ GN=OPT['group']のグループ正規化。
321
+ JOKENに「group={GN}」を配列追加。
322
+ ここまで。
323
+ もし、OPT['plugin']≠「」ならば、JOKENに「plugin={OPT['plugin']}」を配列追加。
324
+ もし、OPT['type']≠「」ならば、JOKENに「type={OPT['type']}」を配列追加。
325
+ もし、(JOKENの要素数)>0ならば
326
+ JS=JOKENを「, 」で配列結合。
327
+ S=「{S} ({JS})」
328
+ ここまで。
329
+ Sで戻る。
330
+ ここまで。
331
+
332
+ # 検索結果を通常の形式で表示する
333
+ ●結果表示(RESULTをOPTで)
334
+ 「検索: {OPTを検索条件文字列}」を表示。
335
+ CNT=RESULTの要素数。
336
+ もし、CNT=0ならば
337
+ 「一致する命令は見つかりませんでした。」を表示。
338
+ 戻る。
339
+ ここまで。
340
+ 「{CNT}件見つかりました。」を表示。
341
+ 「」を表示。
342
+ LIMIT=OPT['limit']を整数変換。
343
+ もし、LIMIT=0ならば、LIMIT=CNT。
344
+ I=0
345
+ RESULTを反復
346
+ もし、I>=LIMITならば、抜ける。
347
+ 対象を命令表示。
348
+ I=I+1
349
+ ここまで。
350
+ もし、CNT>LIMITならば
351
+ NOKORI=CNT-LIMIT
352
+ 「」を表示。
353
+ 「... 他 {NOKORI}件(すべて表示するには --limit 0 を指定してください)」を表示。
354
+ ここまで。
355
+ ここまで。
356
+
357
+ # 検索結果をJSON形式で表示する
358
+ ●結果JSON表示(RESULTをOPTで)
359
+ LIMIT=OPT['limit']を整数変換。
360
+ CNT=RESULTの要素数。
361
+ もし、LIMIT=0ならば、LIMIT=CNT。
362
+ OUT=[]
363
+ I=0
364
+ RESULTを反復
365
+ もし、I>=LIMITならば、抜ける。
366
+ C=対象。
367
+ D=空辞書。
368
+ D['type']=C['type']
369
+ D['name']=C['name']
370
+ D['args']=C['args']
371
+ D['yomi']=C['yomi']
372
+ D['description']=C['description']
373
+ D['plugin']=C['plugin']
374
+ D['group']=C['group']
375
+ D['target']=C['target']
376
+ OUTにDを配列追加。
377
+ I=I+1
378
+ ここまで。
379
+ OUTをJSONエンコード整形して表示。
380
+ ここまで。
381
+
382
+ #-------------------------------------------------
383
+ # メイン処理(戻り値は終了コード)
384
+ #-------------------------------------------------
385
+ ●メイン処理()
386
+ ARGS=コマンド引数取得()
387
+ OPT=ARGSを引数解析。
388
+ # ヘルプの表示
389
+ もし、OPT['help']=オンならば
390
+ ヘルプ表示。
391
+ 0で戻る。
392
+ ここまで。
393
+ # 引数のエラー
394
+ もし、OPT['error']≠「」ならば
395
+ 「[エラー] {OPT['error']}」を表示。
396
+ 「」を表示。
397
+ ヘルプ表示。
398
+ 2で戻る。
399
+ ここまで。
400
+ EMSG=OPTをオプション検査。
401
+ もし、EMSG≠「」ならば
402
+ 「[エラー] {EMSG}」を表示。
403
+ 2で戻る。
404
+ ここまで。
405
+ # 検索語も絞り込みもないなら使い方を表示
406
+ ジョウケン数=(OPT['words']の要素数)
407
+ もし、OPT['target']≠「」ならば、ジョウケン数=ジョウケン数+1。
408
+ もし、OPT['group']≠「」ならば、ジョウケン数=ジョウケン数+1。
409
+ もし、OPT['plugin']≠「」ならば、ジョウケン数=ジョウケン数+1。
410
+ もし、OPT['type']≠「」ならば、ジョウケン数=ジョウケン数+1。
411
+ もし、ジョウケン数=0ならば
412
+ ヘルプ表示。
413
+ 2で戻る。
414
+ ここまで。
415
+ # 命令一覧を読み込む
416
+ LIST=命令一覧取得()
417
+ もし、(LISTの要素数)=0ならば、3で戻る。
418
+ # 検索する
419
+ RESULT=LISTをOPTで命令検索。
420
+ もし、OPT['json']=オンならば
421
+ RESULTをOPTで結果JSON表示。
422
+ 違えば
423
+ RESULTをOPTで結果表示。
424
+ ここまで。
425
+ もし、(RESULTの要素数)=0ならば、1で戻る。
426
+ 0で戻る。
427
+ ここまで。
428
+
429
+ 終了コード=メイン処理()
430
+ 「process.exitCode={終了コード}」をJS実行。
package/core/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nadesiko3core",
3
- "version": "3.7.22",
3
+ "version": "3.7.23",
4
4
  "description": "Japanese Programming Language Nadesiko v3 core",
5
5
  "main": "index.mjs",
6
6
  "type": "module",
@@ -29,6 +29,9 @@
29
29
  "url": "https://github.com/kujirahand/nadesiko3core/issues"
30
30
  },
31
31
  "homepage": "https://github.com/kujirahand/nadesiko3core#readme",
32
+ "engines": {
33
+ "node": ">=22.0.0"
34
+ },
32
35
  "files": [
33
36
  "src",
34
37
  "batch",
@@ -0,0 +1,43 @@
1
+ # なでしこ3のアルゴリズム集
2
+
3
+ `doc/syntax-nako3.md` に記載された文法を中心に、有名なアルゴリズムをなでしこ3で実装するためのサンプル集です。
4
+
5
+ ## 追加規約
6
+
7
+ - アルゴリズムは種類ごとのディレクトリに分け、1ファイルに1つ実装します。
8
+ - ファイル名には、英語のスネークケースを使います。
9
+ - ユーザー定義関数は標準命令と区別できるよう、`クイックソート処理`のように末尾へ`処理`を付けます。補助関数にも同じ規則を適用します。
10
+ - 関数内のローカル変数は、`F左値`や`F中央値`のように先頭へ`F`を付けます。
11
+ - ファイルの冒頭に、入出力、元データを変更するか、計算量を記載します。
12
+ - サンプルファイルには関数定義だけを置き、実行時に表示などの副作用を発生させません。
13
+ - アルゴリズムと同じ処理を行う組み込み命令には処理を委譲せず、アルゴリズムそのものを実装します。
14
+ - 対応するなでしこのテストを `core/test/algorithms/` 以下の同じ分類へ、`実装名_test.nako3` という名前で追加します。
15
+ - テストの入力、期待値、比較はなでしこで記述し、`ASSERT等` で検証します。
16
+
17
+ ## 分類
18
+
19
+ - `sort/` - ソートアルゴリズム
20
+ - `search/` - 探索アルゴリズム
21
+ - `math/` - 数学アルゴリズム
22
+ - `graph/` - グラフアルゴリズム
23
+ - `string/` - 文字列アルゴリズム
24
+
25
+ ## 収録アルゴリズム
26
+
27
+ - `sort/` - クイックソート、マージソート、ヒープソート、挿入ソート
28
+ - `search/` - 二分探索、幅優先探索、深さ優先探索
29
+ - `math/` - ユークリッドの互除法、エラトステネスの篩
30
+ - `graph/` - ダイクストラ法、クラスカル法
31
+ - `string/` - KMP法、ランレングス圧縮
32
+
33
+ ## テスト
34
+
35
+ 全アルゴリズムの `*_test.nako3` は、`core/test/algorithm_samples_test.mjs` が自動的に検出します。JavaScript側は実装とテストを読み込むだけで、実際のテストケースはなでしこで実行されます。個別確認と全体の回帰確認は、リポジトリのルートで次のように実行します。
36
+
37
+ ```sh
38
+ node --test --test-name-pattern sort/quick_sort \
39
+ --import ./test/node-test-globals.mjs \
40
+ core/test/algorithm_samples_test.mjs
41
+
42
+ npm test
43
+ ```