nadesiko3 3.7.21 → 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 (212) hide show
  1. package/README.md +20 -1
  2. package/batch/command.txt +370 -334
  3. package/batch/generate_command_list.mjs +102 -0
  4. package/batch/jsplugin2text.nako3 +1 -1
  5. package/batch/pickup_command.nako3 +12 -0
  6. package/batch/search_command.mjs +34 -0
  7. package/batch/search_command.nako3 +430 -0
  8. package/core/command/snako.mts +5 -1
  9. package/core/deno/snako.ts +5 -1
  10. package/core/package-lock.json +382 -21
  11. package/core/package.json +7 -4
  12. package/core/sample/algorithms/README.md +43 -0
  13. package/core/sample/algorithms/graph/dijkstra.nako3 +47 -0
  14. package/core/sample/algorithms/graph/kruskal.nako3 +69 -0
  15. package/core/sample/algorithms/math/euclidean_gcd.nako3 +15 -0
  16. package/core/sample/algorithms/math/sieve_of_eratosthenes.nako3 +26 -0
  17. package/core/sample/algorithms/search/binary_search.nako3 +17 -0
  18. package/core/sample/algorithms/search/breadth_first_search.nako3 +33 -0
  19. package/core/sample/algorithms/search/depth_first_search.nako3 +25 -0
  20. package/core/sample/algorithms/sort/heap_sort.nako3 +37 -0
  21. package/core/sample/algorithms/sort/insertion_sort.nako3 +18 -0
  22. package/core/sample/algorithms/sort/merge_sort.nako3 +40 -0
  23. package/core/sample/algorithms/sort/quick_sort.nako3 +36 -0
  24. package/core/sample/algorithms/string/knuth_morris_pratt.nako3 +50 -0
  25. package/core/sample/algorithms/string/run_length_encoding.nako3 +25 -0
  26. package/core/src/nako3.mts +178 -614
  27. package/core/src/nako_basic_plugins.mts +39 -0
  28. package/core/src/nako_core_version.mts +2 -2
  29. package/core/src/nako_csv.mts +0 -1
  30. package/core/src/nako_event.mts +49 -0
  31. package/core/src/nako_gen.mts +320 -209
  32. package/core/src/nako_global.mts +18 -0
  33. package/core/src/nako_indent_inline.mts +2 -2
  34. package/core/src/nako_lex_rules.mts +1 -1
  35. package/core/src/nako_parser3.mts +111 -166
  36. package/core/src/nako_parser_async.mts +165 -0
  37. package/core/src/nako_parser_base.mts +4 -55
  38. package/core/src/nako_parser_message.mts +105 -0
  39. package/core/src/nako_parser_operator.mts +93 -0
  40. package/core/src/nako_plugin_manager.mts +260 -0
  41. package/core/src/nako_require.mts +292 -0
  42. package/core/src/nako_runner.mts +208 -0
  43. package/core/src/nako_tokenizer.mts +221 -0
  44. package/core/src/plugin_csv.mts +1 -1
  45. package/core/src/plugin_system.mts +34 -3259
  46. package/core/src/plugin_system_array.mts +699 -0
  47. package/core/src/plugin_system_datetime.mts +368 -0
  48. package/core/src/plugin_system_debug.mts +403 -0
  49. package/core/src/plugin_system_dict.mts +85 -0
  50. package/core/src/plugin_system_json.mts +73 -0
  51. package/core/src/plugin_system_math.mts +383 -0
  52. package/core/src/plugin_system_regexp.mts +120 -0
  53. package/core/src/plugin_system_stdio.mts +86 -0
  54. package/core/src/plugin_system_string.mts +666 -0
  55. package/core/src/plugin_system_timer.mts +152 -0
  56. package/core/src/plugin_system_types.mts +151 -0
  57. package/core/src/plugin_system_url.mts +193 -0
  58. package/core/src/plugin_toml.mts +3 -3
  59. package/core/test/algorithm_samples_test.mjs +58 -0
  60. package/core/test/algorithms/graph/dijkstra_test.nako3 +21 -0
  61. package/core/test/algorithms/graph/kruskal_test.nako3 +21 -0
  62. package/core/test/algorithms/helper.mjs +13 -0
  63. package/core/test/algorithms/math/euclidean_gcd_test.nako3 +13 -0
  64. package/core/test/algorithms/math/sieve_of_eratosthenes_test.nako3 +10 -0
  65. package/core/test/algorithms/search/binary_search_test.nako3 +15 -0
  66. package/core/test/algorithms/search/breadth_first_search_test.nako3 +13 -0
  67. package/core/test/algorithms/search/depth_first_search_test.nako3 +13 -0
  68. package/core/test/algorithms/sort/heap_sort_test.nako3 +13 -0
  69. package/core/test/algorithms/sort/insertion_sort_test.nako3 +13 -0
  70. package/core/test/algorithms/sort/merge_sort_test.nako3 +18 -0
  71. package/core/test/algorithms/sort/quick_sort_test.nako3 +34 -0
  72. package/core/test/algorithms/string/knuth_morris_pratt_test.nako3 +16 -0
  73. package/core/test/algorithms/string/run_length_encoding_test.nako3 +13 -0
  74. package/core/test/array_test.mjs +3 -0
  75. package/core/test/fixtures/README.md +39 -0
  76. package/core/test/fixtures/make_parser_ast_golden.mjs +31 -0
  77. package/core/test/fixtures/parser_ast_golden.json +8027 -0
  78. package/core/test/fixtures/parser_corpus.mjs +120 -0
  79. package/core/test/func_call.mjs +18 -0
  80. package/core/test/func_test.mjs +28 -0
  81. package/core/test/indent_test.mjs +6 -0
  82. package/core/test/nako_basic_plugins_test.mjs +44 -0
  83. package/core/test/nako_event_test.mjs +127 -0
  84. package/core/test/nako_gen_perf_test.mjs +178 -0
  85. package/core/test/nako_parser_async_test.mjs +385 -0
  86. package/core/test/nako_parser_test.mjs +160 -0
  87. package/core/test/nako_plugin_manager_test.mjs +185 -0
  88. package/core/test/nako_require_test.mjs +153 -0
  89. package/core/test/nako_runner_test.mjs +174 -0
  90. package/core/test/nako_tokenizer_test.mjs +115 -0
  91. package/core/test/plugin_system_debug_test.mjs +138 -0
  92. package/core/test/plugin_system_split_test.mjs +179 -0
  93. package/core/test/plugin_system_test.mjs +6 -0
  94. package/core/tsconfig.json +0 -1
  95. package/demo/browsers.html +1 -1
  96. package/doc/SETUP.md +1 -1
  97. package/doc/ai-code-generation.md +136 -0
  98. package/doc/browsers.md +1 -1
  99. package/doc/command_list.json +16842 -0
  100. package/doc/search_command.md +222 -0
  101. package/doc/syntax-nako3.md +344 -0
  102. package/package.json +29 -26
  103. package/release/_hash.txt +40 -40
  104. package/release/_script-tags.txt +16 -16
  105. package/release/command.json +1 -1
  106. package/release/command.json.js +1 -1
  107. package/release/command_cnako3.json +1 -1
  108. package/release/command_list.json +1 -1
  109. package/release/edit_main.js +6 -6
  110. package/release/edit_main.js.map +3 -3
  111. package/release/editor.js +6 -6
  112. package/release/plugin_caniuse.js +1 -1
  113. package/release/plugin_caniuse.js.map +2 -2
  114. package/release/plugin_keigo.js.map +3 -3
  115. package/release/plugin_markup.js +46 -46
  116. package/release/plugin_markup.js.map +3 -3
  117. package/release/plugin_weykturtle3d.js +1 -1
  118. package/release/plugin_weykturtle3d.js.map +3 -3
  119. package/release/version.js +2 -2
  120. package/release/version_main.js +2 -2
  121. package/release/version_main.js.map +1 -1
  122. package/release/wnako3.js +219 -230
  123. package/release/wnako3.js.map +4 -4
  124. package/release/wnako3webworker.js +193 -204
  125. package/release/wnako3webworker.js.map +4 -4
  126. package/src/browsers.mjs +1 -1
  127. package/src/browsers.txt +0 -1
  128. package/src/cnako3mod.mjs +7 -2
  129. package/src/cnako3mod.mts +7 -2
  130. package/src/nako_version.mjs +2 -2
  131. package/src/nako_version.mts +2 -2
  132. package/src/plugin_browser_ajax.mjs +4 -4
  133. package/src/plugin_browser_ajax.mts +4 -4
  134. package/src/plugin_browser_audio.mjs +10 -10
  135. package/src/plugin_browser_audio.mts +10 -10
  136. package/src/plugin_browser_camera.mjs +4 -4
  137. package/src/plugin_browser_camera.mts +4 -4
  138. package/src/plugin_browser_canvas.mjs +2 -2
  139. package/src/plugin_browser_canvas.mts +2 -2
  140. package/src/plugin_browser_crypto.mjs +3 -3
  141. package/src/plugin_browser_crypto.mts +3 -3
  142. package/src/plugin_browser_dom_event.mjs +1 -1
  143. package/src/plugin_browser_dom_event.mts +1 -1
  144. package/src/plugin_browser_geolocation.mjs +1 -1
  145. package/src/plugin_browser_geolocation.mts +1 -1
  146. package/src/plugin_browser_hotkey.mjs +1 -1
  147. package/src/plugin_browser_hotkey.mts +1 -1
  148. package/src/plugin_browser_html.mjs +1 -1
  149. package/src/plugin_browser_html.mts +1 -1
  150. package/src/plugin_browser_location.mjs +1 -1
  151. package/src/plugin_browser_location.mts +1 -1
  152. package/src/plugin_browser_speech.mjs +1 -1
  153. package/src/plugin_browser_speech.mts +1 -1
  154. package/src/plugin_browser_storage.mjs +2 -2
  155. package/src/plugin_browser_storage.mts +2 -2
  156. package/src/plugin_httpserver.mjs +3 -3
  157. package/src/plugin_httpserver.mts +3 -3
  158. package/src/plugin_keigo.mjs +2 -2
  159. package/src/plugin_keigo.mts +2 -2
  160. package/src/plugin_node.mjs +48 -48
  161. package/src/plugin_node.mts +53 -53
  162. package/src/plugin_weykturtle3d.mjs +56 -56
  163. package/src/plugin_weykturtle3d.mts +56 -56
  164. package/src/wnako3.mjs +1 -1
  165. package/src/wnako3.mts +1 -1
  166. package/src/wnako3_editor.mjs +5 -5
  167. package/src/wnako3_editor.mts +5 -5
  168. package/src/wnako3mod.mjs +2 -2
  169. package/src/wnako3mod.mts +2 -2
  170. package/test/nako3edit/index_nako3_test.mjs +282 -0
  171. package/test/nako3server/index_nako3_test.mjs +239 -0
  172. package/test/node/ai_code_generation_guide_test.mjs +29 -0
  173. package/test/node/node_version_support_test.mjs +45 -0
  174. package/test/node/search_command_test.mjs +174 -0
  175. package/tools/nako3edit/AGENTS.md +23 -0
  176. package/tools/nako3edit/index.nako3 +404 -0
  177. package/tools/nako3server/AGENTS.md +23 -0
  178. package/tools/nako3server/index.nako3 +156 -23
  179. package/core/src/nako3.mjs +0 -1021
  180. package/core/src/nako_ast.mjs +0 -4
  181. package/core/src/nako_colors.mjs +0 -77
  182. package/core/src/nako_core_version.mjs +0 -8
  183. package/core/src/nako_csv.mjs +0 -193
  184. package/core/src/nako_errors.mjs +0 -166
  185. package/core/src/nako_from_dncl.mjs +0 -285
  186. package/core/src/nako_from_dncl2.mjs +0 -347
  187. package/core/src/nako_gen.mjs +0 -2500
  188. package/core/src/nako_global.mjs +0 -138
  189. package/core/src/nako_indent.mjs +0 -442
  190. package/core/src/nako_indent_chars.mjs +0 -29
  191. package/core/src/nako_indent_inline.mjs +0 -361
  192. package/core/src/nako_josi_list.mjs +0 -47
  193. package/core/src/nako_lex_rules.mjs +0 -319
  194. package/core/src/nako_lexer.mjs +0 -794
  195. package/core/src/nako_logger.mjs +0 -221
  196. package/core/src/nako_parser3.mjs +0 -3250
  197. package/core/src/nako_parser_base.mjs +0 -403
  198. package/core/src/nako_parser_const.mjs +0 -37
  199. package/core/src/nako_prepare.mjs +0 -329
  200. package/core/src/nako_reserved_words.mjs +0 -42
  201. package/core/src/nako_source_mapping.mjs +0 -207
  202. package/core/src/nako_test.mjs +0 -37
  203. package/core/src/nako_token.mjs +0 -1
  204. package/core/src/nako_tools.mjs +0 -53
  205. package/core/src/nako_types.mjs +0 -14
  206. package/core/src/plugin_api.mjs +0 -4
  207. package/core/src/plugin_csv.mjs +0 -97
  208. package/core/src/plugin_math.mjs +0 -352
  209. package/core/src/plugin_promise.mjs +0 -102
  210. package/core/src/plugin_system.mjs +0 -3810
  211. package/core/src/plugin_test.mjs +0 -52
  212. package/core/src/plugin_toml.mjs +0 -39
@@ -0,0 +1,138 @@
1
+ /* eslint-disable no-undef */
2
+ /**
3
+ * plugin_system_debug.mts のテスト (#2351)
4
+ *
5
+ * plugin_system.mts から分割した「特殊命令」「デバッグ支援」「プラグイン管理」の
6
+ * 命令が、分割後も plugin_system の一部として正しく動作することを確認する。
7
+ */
8
+ import { describe, it } from 'node:test'
9
+ import assert from 'assert'
10
+ import { NakoCompiler } from '../src/nako3.mjs'
11
+ import PluginSystem from '../src/plugin_system.mjs'
12
+ import PluginSystemDebug from '../src/plugin_system_debug.mjs'
13
+
14
+ describe('plugin_system_debug_test', async () => {
15
+ const cmp = async (/** @type {string} */ code, /** @type {string} */ res) => {
16
+ const nako = new NakoCompiler()
17
+ nako.getLogger().debug('code=' + code)
18
+ const g = await nako.runAsync(code, 'main.nako3')
19
+ assert.strictEqual(g.log, res)
20
+ }
21
+
22
+ // --- 分割ファイルの構造 ---
23
+ it('分割ファイルはメタ情報や初期化を持たない', async () => {
24
+ assert.strictEqual(PluginSystemDebug.meta, undefined)
25
+ assert.strictEqual(PluginSystemDebug['初期化'], undefined)
26
+ assert.strictEqual(PluginSystemDebug['!クリア'], undefined)
27
+ })
28
+ it('分割ファイルの命令が plugin_system にマージされている', async () => {
29
+ for (const key of Object.keys(PluginSystemDebug)) {
30
+ assert.strictEqual(PluginSystem[key], PluginSystemDebug[key], `『${key}』がマージされていません`)
31
+ }
32
+ })
33
+ it('分割してもプラグインは plugin_system のまま', async () => {
34
+ assert.strictEqual(PluginSystem.meta.value.pluginName, 'plugin_system')
35
+ await cmp('プラグイン一覧取得して「:」で配列結合して表示', 'plugin_system:plugin_math:plugin_promise:plugin_test:plugin_csv:plugin_toml')
36
+ })
37
+
38
+ // --- 特殊命令 ---
39
+ it('特殊命令 - JS実行', async () => {
40
+ await cmp('「3*7」をJS実行して表示', '21')
41
+ })
42
+ it('特殊命令 - JS関数実行', async () => {
43
+ await cmp('「Math.max」を[3,9,5]でJS関数実行して表示', '9')
44
+ })
45
+ it('特殊命令 - JSメソッド実行', async () => {
46
+ await cmp('「[1,2,3]」の「join」を[「-」]でJSメソッド実行して表示', '1-2-3')
47
+ })
48
+ it('特殊命令 - JSオブジェクト取得', async () => {
49
+ await cmp('A=5;「A」のJSオブジェクト取得して表示', '5')
50
+ })
51
+ it('特殊命令 - 実行', async () => {
52
+ await cmp('F=関数()\n「呼ばれた」を表示\nここまで\nFを実行', '呼ばれた')
53
+ await cmp('●テスト関数とは\n「OK」を表示\nここまで\n「テスト関数」を実行', 'OK')
54
+ // 関数でも文字列(関数名)でもない値はそのまま返る (#938)
55
+ await cmp('123を実行して表示', '123')
56
+ })
57
+ it('特殊命令 - 実行時間計測', async () => {
58
+ await cmp('F=関数()\nそれは1\nここまで\nFの実行時間計測;もし、(それ>=0)ならば「OK」を表示', 'OK')
59
+ })
60
+ it('特殊命令 - AWAIT実行', async () => {
61
+ const nako = new NakoCompiler()
62
+ const code = 'F=「a=>a*2」をJS実行\nFを[21]でAWAIT実行して表示'
63
+ const g = await nako.runAsync(code, 'main.nako3')
64
+ assert.strictEqual(g.log, '42')
65
+ })
66
+ it('特殊命令 - AWAIT実行(配列以外の引数)', async () => {
67
+ const nako = new NakoCompiler()
68
+ const code = 'F=「a=>a*2」をJS実行\nFを21でAWAIT実行して表示'
69
+ const g = await nako.runAsync(code, 'main.nako3')
70
+ assert.strictEqual(g.log, '42')
71
+ })
72
+ it('特殊命令 - ナデシコ', async () => {
73
+ await cmp('『「なでしこ」を表示』をナデシコ', 'なでしこ')
74
+ })
75
+
76
+ // --- デバッグ支援 ---
77
+ it('デバッグ支援 - デバッグ表示', async () => {
78
+ const nako = new NakoCompiler()
79
+ const g = await nako.runAsync('「メッセージ」をデバッグ表示', 'main.nako3')
80
+ // 「ファイル名(行番号): メッセージ」の形式で出力される
81
+ assert.ok(g.log.indexOf('メッセージ') >= 0, `想定外の出力: ${g.log}`)
82
+ assert.ok(g.log.indexOf('main.nako3') >= 0, `想定外の出力: ${g.log}`)
83
+ })
84
+ it('デバッグ支援 - ハテナ関数設定と実行', async () => {
85
+ await cmp('「表示」をハテナ関数設定; ?? 2*5', '10')
86
+ await cmp('["JSON_E","表示"]をハテナ関数設定; ?? [1,2]', '[1,2]')
87
+ })
88
+ it('デバッグ支援 - エラー発生', async () => {
89
+ const nako = new NakoCompiler()
90
+ try {
91
+ await nako.runAsync('「わざとエラー」のエラー発生', 'main.nako3')
92
+ } catch (err) {
93
+ assert.ok(String(err.message).indexOf('わざとエラー') >= 0)
94
+ return
95
+ }
96
+ assert.fail('エラーが発生しませんでした')
97
+ })
98
+ it('デバッグ支援 - システム関数一覧取得', async () => {
99
+ await cmp('A=システム関数一覧取得;I=Aから「表示」を配列検索;もし、(I>=0)ならば「OK」を表示', 'OK')
100
+ // 分割ファイル側の命令も一覧に含まれる
101
+ await cmp('A=システム関数一覧取得;I=Aから「デバッグ表示」を配列検索;もし、(I>=0)ならば「OK」を表示', 'OK')
102
+ })
103
+ it('デバッグ支援 - システム関数存在', async () => {
104
+ await cmp('もし、「デバッグ表示」のシステム関数存在ならば「OK」を表示', 'OK')
105
+ await cmp('もし、「存在しない命令XYZ」のシステム関数存在でなければ「OK」を表示', 'OK')
106
+ })
107
+ it('デバッグ支援 - グローバル関数一覧取得', async () => {
108
+ // ユーザー定義関数は「モジュール名__関数名」の形式で登録される
109
+ await cmp(
110
+ '●ホゲとは\n' +
111
+ 'それは1\n' +
112
+ 'ここまで\n' +
113
+ 'A=グローバル関数一覧取得\n' +
114
+ 'I=Aから「main__ホゲ」を配列検索\n' +
115
+ 'もし、(I>=0)ならば「OK」を表示',
116
+ 'OK')
117
+ })
118
+ it('デバッグ支援 - モジュール一覧取得', async () => {
119
+ await cmp('A=モジュール一覧取得;もし、(Aの配列要素数)>=0ならば「OK」を表示', 'OK')
120
+ })
121
+ it('デバッグ支援 - 助詞一覧取得と予約語一覧取得', async () => {
122
+ await cmp('A=助詞一覧取得;もし、(Aの配列要素数)>0ならば「OK」を表示', 'OK')
123
+ await cmp('A=予約語一覧取得;もし、(Aの配列要素数)>0ならば「OK」を表示', 'OK')
124
+ })
125
+
126
+ // --- プラグイン管理 ---
127
+ it('プラグイン管理 - プラグイン名', async () => {
128
+ await cmp('プラグイン名を表示', 'メイン')
129
+ })
130
+ it('プラグイン管理 - プラグイン名設定', async () => {
131
+ await cmp('「テストプラグイン」にプラグイン名設定;プラグイン名を表示', 'テストプラグイン')
132
+ })
133
+ it('プラグイン管理 - 名前空間設定と名前空間ポップ', async () => {
134
+ await cmp('「サブ空間」に名前空間設定;名前空間を表示;名前空間ポップ', 'サブ空間')
135
+ // ポップすると設定前の名前空間に戻る
136
+ await cmp('元=名前空間;「サブ空間」に名前空間設定;名前空間ポップ;もし、(名前空間=元)ならば「OK」を表示', 'OK')
137
+ })
138
+ })
@@ -0,0 +1,179 @@
1
+ /* eslint-disable no-undef */
2
+ /**
3
+ * plugin_system.mts の分割ファイルのテスト (#2351)
4
+ *
5
+ * 肥大化した plugin_system.mts を役割ごとに以下へ分割した。
6
+ * - plugin_system_math.mts : 四則演算・論理演算・ビット演算
7
+ * - plugin_system_string.mts : 文字列処理・置換/トリム・文字変換・指定形式・文字種類
8
+ * - plugin_system_array.mts : 配列操作・二次元配列処理
9
+ * - plugin_system_datetime.mts : 日時処理(簡易)
10
+ * - plugin_system_url.mts : URLエンコード・パラメータ・BASE64・パス操作
11
+ * - plugin_system_types.mts : 型変換
12
+ * - plugin_system_json.mts : JSON
13
+ * - plugin_system_regexp.mts : 正規表現
14
+ * - plugin_system_dict.mts : 辞書型変数の操作・ハッシュ
15
+ * - plugin_system_stdio.mts : 標準出力
16
+ * - plugin_system_timer.mts : タイマー処理
17
+ * いずれも単独のプラグインではなく、plugin_system.mts に実行時マージされる。
18
+ * 個々の命令の詳細な動作テストは plugin_system_test.mjs で従来通りカバーされているため、
19
+ * ここでは「分割ファイルが正しくマージされているか」と代表的な命令の疎通確認を行う。
20
+ */
21
+ import { describe, it } from 'node:test'
22
+ import assert from 'assert'
23
+ import { NakoCompiler } from '../src/nako3.mjs'
24
+ import PluginSystem from '../src/plugin_system.mjs'
25
+ import PluginSystemMath from '../src/plugin_system_math.mjs'
26
+ import PluginSystemString from '../src/plugin_system_string.mjs'
27
+ import PluginSystemArray from '../src/plugin_system_array.mjs'
28
+ import PluginSystemDatetime from '../src/plugin_system_datetime.mjs'
29
+ import PluginSystemUrl from '../src/plugin_system_url.mjs'
30
+ import PluginSystemTypes from '../src/plugin_system_types.mjs'
31
+ import PluginSystemJson from '../src/plugin_system_json.mjs'
32
+ import PluginSystemRegexp from '../src/plugin_system_regexp.mjs'
33
+ import PluginSystemDict from '../src/plugin_system_dict.mjs'
34
+ import PluginSystemStdio from '../src/plugin_system_stdio.mjs'
35
+ import PluginSystemTimer from '../src/plugin_system_timer.mjs'
36
+
37
+ describe('plugin_system_split_test', async () => {
38
+ const cmp = async (/** @type {string} */ code, /** @type {string} */ res) => {
39
+ const nako = new NakoCompiler()
40
+ nako.getLogger().debug('code=' + code)
41
+ const g = await nako.runAsync(code, 'main.nako3')
42
+ assert.strictEqual(g.log, res)
43
+ }
44
+
45
+ const parts = {
46
+ math: PluginSystemMath,
47
+ string: PluginSystemString,
48
+ array: PluginSystemArray,
49
+ datetime: PluginSystemDatetime,
50
+ url: PluginSystemUrl,
51
+ types: PluginSystemTypes,
52
+ json: PluginSystemJson,
53
+ regexp: PluginSystemRegexp,
54
+ dict: PluginSystemDict,
55
+ stdio: PluginSystemStdio,
56
+ timer: PluginSystemTimer
57
+ }
58
+
59
+ it('分割ファイルはメタ情報や初期化を持たない', async () => {
60
+ for (const [name, part] of Object.entries(parts)) {
61
+ assert.strictEqual(part.meta, undefined, `${name}にmetaがあります`)
62
+ assert.strictEqual(part['初期化'], undefined, `${name}に初期化があります`)
63
+ assert.strictEqual(part['!クリア'], undefined, `${name}に!クリアがあります`)
64
+ }
65
+ })
66
+
67
+ it('分割ファイルの命令が plugin_system にマージされている', async () => {
68
+ for (const [name, part] of Object.entries(parts)) {
69
+ for (const key of Object.keys(part)) {
70
+ assert.strictEqual(PluginSystem[key], part[key], `${name}の『${key}』がマージされていません`)
71
+ }
72
+ }
73
+ })
74
+
75
+ it('分割してもプラグインは plugin_system のまま', async () => {
76
+ assert.strictEqual(PluginSystem.meta.value.pluginName, 'plugin_system')
77
+ await cmp('プラグイン一覧取得して「:」で配列結合して表示', 'plugin_system:plugin_math:plugin_promise:plugin_test:plugin_csv:plugin_toml')
78
+ })
79
+
80
+ // --- plugin_system_math.mts の疎通確認 ---
81
+ it('四則演算', async () => {
82
+ await cmp('3に4を掛けて表示', '12')
83
+ })
84
+ it('論理演算', async () => {
85
+ await cmp('もし、(1と1の論理AND)ならば「OK」を表示', 'OK')
86
+ })
87
+ it('ビット演算', async () => {
88
+ await cmp('5と3のANDを表示', '1')
89
+ })
90
+
91
+ // --- plugin_system_string.mts の疎通確認 ---
92
+ it('文字列処理', async () => {
93
+ await cmp('「なでしこ」の文字数を表示', '4')
94
+ })
95
+ it('置換・トリム', async () => {
96
+ await cmp('「 殿 」のトリムを表示', '殿')
97
+ })
98
+ it('文字変換', async () => {
99
+ await cmp('「abc」の大文字変換を表示', 'ABC')
100
+ })
101
+ it('指定形式', async () => {
102
+ await cmp('123を5でゼロ埋して表示', '00123')
103
+ })
104
+ it('文字種類', async () => {
105
+ await cmp('もし、「あ」のかなか判定ならば「OK」を表示', 'OK')
106
+ })
107
+
108
+ // --- plugin_system_array.mts の疎通確認 ---
109
+ it('配列操作', async () => {
110
+ await cmp('[1,2,3]を「-」で配列結合して表示', '1-2-3')
111
+ })
112
+ it('二次元配列処理', async () => {
113
+ const g = await new NakoCompiler().runAsync('A=[[3,1],[1,2]];Aの0を表ソート;Aを JSON変換して表示', 'main.nako3')
114
+ assert.strictEqual(g.log, '[[1,2],[3,1]]')
115
+ })
116
+
117
+ // --- plugin_system_datetime.mts の疎通確認 ---
118
+ it('日時処理(簡易)', async () => {
119
+ await cmp('「2024/01/01」の曜日を表示', '月')
120
+ })
121
+
122
+ // --- plugin_system_url.mts の疎通確認 ---
123
+ it('URLエンコード・デコード', async () => {
124
+ await cmp('「あ」をURLエンコードしてURLデコードして表示', 'あ')
125
+ })
126
+ it('BASE64', async () => {
127
+ await cmp('「なでしこ」をBASE64エンコードしてBASE64デコードして表示', 'なでしこ')
128
+ })
129
+ it('パス操作', async () => {
130
+ await cmp('「/a/b/c.txt」のファイル名抽出を表示', 'c.txt')
131
+ await cmp('「/a/b/c.txt」の拡張子抽出を表示', '.txt')
132
+ })
133
+
134
+ // --- plugin_system_types.mts の疎通確認 ---
135
+ it('型変換', async () => {
136
+ await cmp('「3.14」を文字列変換して表示', '3.14')
137
+ await cmp('「3.14」を整数変換して表示', '3')
138
+ await cmp('TYPEOF(123)を表示', 'number')
139
+ await cmp('3と4の5でRGBを表示', '#030405')
140
+ })
141
+
142
+ // --- plugin_system_json.mts の疎通確認 ---
143
+ it('JSON', async () => {
144
+ await cmp('[1,2,3]をJSON変換して表示', '[1,2,3]')
145
+ await cmp('「[1,2,3]」をJSON取得してJSON変換して表示', '[1,2,3]')
146
+ })
147
+
148
+ // --- plugin_system_regexp.mts の疎通確認 ---
149
+ it('正規表現', async () => {
150
+ await cmp('「abc123」を『/([a-z]+)(\\d+)/』で正規表現マッチして表示', 'abc123')
151
+ await cmp('「abc123」を『/([a-z]+)(\\d+)/』で正規表現マッチ;抽出文字列を「,」で配列結合して表示', 'abc,123')
152
+ })
153
+
154
+ // --- plugin_system_dict.mts の疎通確認 ---
155
+ it('辞書型変数の操作', async () => {
156
+ await cmp('A={"a":1,"b":2};Aの辞書キー列挙を「,」で配列結合して表示', 'a,b')
157
+ })
158
+ it('ハッシュ', async () => {
159
+ await cmp('A={"a":1,"b":2};Aのハッシュキー列挙を「,」で配列結合して表示', 'a,b')
160
+ })
161
+
162
+ // --- plugin_system_stdio.mts の疎通確認 ---
163
+ it('標準出力', async () => {
164
+ await cmp('「あ」と継続表示;「い」を表示', 'あい')
165
+ await cmp('「a」と「b」と「c」を連続表示', 'abc')
166
+ })
167
+
168
+ // --- plugin_system_timer.mts の疎通確認 ---
169
+ it('タイマー処理', async () => {
170
+ // 秒後で発行したタイマーIDが取得でき、タイマー停止できること
171
+ await cmp(
172
+ 'F=関数()\n' +
173
+ 'ここまで\n' +
174
+ 'Fを0.01秒後\n' +
175
+ 'もし、(対象>0)ならば「OK」を表示\n' +
176
+ '対象のタイマー停止',
177
+ 'OK')
178
+ })
179
+ })
@@ -477,6 +477,8 @@ describe('plugin_system_test', async () => {
477
477
  it('URLパラメータ解析', async () => {
478
478
  await cmp('「http://hoge.com/」のURLパラメータ解析してJSONエンコードして表示', '{}')
479
479
  await cmp('「https://nadesi.com/?a=3&b=5」のURLパラメータ解析;それ["a"]を表示;それ["b"]を表示。', '3\n5')
480
+ await cmp('「https://nadesi.com/?a=3=3&b=5」のURLパラメータ解析;それ["a"]を表示;それ["b"]を表示。', '3=3\n5')
481
+ await cmp('「https://nadesi.com/?a&b=5」のURLパラメータ解析;それ["a"]を表示;それ["b"]を表示。', '\n5')
480
482
  })
481
483
  it('助詞省略形のコマンド', async () => {
482
484
  await cmp('3が1以上。もし、そうなら「OK」と表示。', 'OK')
@@ -776,6 +778,10 @@ describe('plugin_system_test', async () => {
776
778
  await cmp('S=「💧🔥🍵」;Sの2から1文字削除して表示', '💧🍵')
777
779
  await cmp('S=「1💧3🔥5🍵」;Sの3から2文字削除して表示', '1💧5🍵')
778
780
  })
781
+ it('数字の文字数が0になる不具合 #2342', async () => {
782
+ await cmp('30の文字数を表示', '2')
783
+ await cmp('12345の文字数を表示', '5')
784
+ })
779
785
  it('左トリム', async () => {
780
786
  await cmp('S=「 \t💧🔥🍵」;Sを左トリムして表示', '💧🔥🍵')
781
787
  await cmp('S=「 ABC 」;Sを左トリムして「|」を追加して表示', 'ABC |')
@@ -25,7 +25,6 @@
25
25
  /* Modules */
26
26
  "module": "ESNext", /* Specify what module code is generated. */
27
27
  // "rootDir": "./", /* Specify the root folder within your source files. */
28
- "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
29
28
  "ignoreDeprecations": "6.0", /* TypeScript 6.0 の非推奨警告を抑制する */
30
29
  // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
31
30
  "paths": {
@@ -13,7 +13,7 @@
13
13
  <li>Chrome (145/144/143/142/139/133/131/125/112/109以上)</li>
14
14
  <li>Safari (26.3/26.2以上)</li>
15
15
  <li>Opera (125/124以上)</li>
16
- <li>Node.js (25.1.0/24.11.0/22.21.0/20.19.0以上)</li>
16
+ <li>Node.js (25.1.0/24.11.0/22.21.0以上)</li>
17
17
  </ul>
18
18
 
19
19
  <h2>モバイル</h2>
package/doc/SETUP.md CHANGED
@@ -31,7 +31,7 @@ npm install -g windows-build-tools
31
31
 
32
32
  ## 【共通】
33
33
 
34
- コマンドラインから以下を実行して、nadesiko3のリポジトリをcloneし、必要なライブラリをインストール。ただし、Node.jsのバージョンv10以上が必要。もし、Ubuntuで古いNode.jsをインストールした場合などは最新安定版のNode.jsを利用してください。
34
+ コマンドラインから以下を実行して、nadesiko3のリポジトリをcloneし、必要なライブラリをインストール。ただし、Node.jsのバージョンv22以上が必要。もし、Ubuntuで古いNode.jsをインストールした場合などは最新安定版のNode.jsを利用してください。
35
35
 
36
36
  なお、gitでリポジトリを取得する際、サブモジュールを利用するので、--recursiveを指定するのを忘れないようにしましょう。
37
37
 
@@ -0,0 +1,136 @@
1
+ # 生成AIになでしこ3のプログラムを作ってもらう
2
+
3
+ 生成AIに目的を伝えると、なでしこ3のプログラムを作成してもらえます。ただし、生成AIがなでしこ3の命令名や助詞を推測すると、存在しない命令や正しくない文法を使うことがあります。
4
+
5
+ このチュートリアルでは、リポジトリ内の文法資料と命令一覧をAIに参照させ、生成したプログラムを実行して確かめる方法を紹介します。
6
+
7
+ ## 準備
8
+
9
+ GitHubからなでしこ3を取得し、依存パッケージをインストールします。
10
+
11
+ ```sh
12
+ git clone https://github.com/kujirahand/nadesiko3.git
13
+ cd nadesiko3
14
+ npm install
15
+ ```
16
+
17
+ CodexやClaude Codeなど、リポジトリ内のファイルを読み書きしてコマンドを実行できるAIエージェントで、このディレクトリを開きます。
18
+
19
+ ## 最初のプログラムを作る
20
+
21
+ まず、AIエージェントに次のように依頼します。
22
+
23
+ ```text
24
+ 1から10までの合計を表示する、なでしこ3のプログラムを作ってください。
25
+ Node.js版のcnako3で動くようにして、sample.nako3へ保存してください。
26
+ 作成後に実行し、正しく動くことを確認してください。
27
+ ```
28
+
29
+ AIは、このリポジトリの`AGENTS.md`に記載された手順に従い、文法と命令を確認してからコードを生成します。生成されるプログラムは、例えば次のようになります。
30
+
31
+ <!-- ai-code-generation-example:start -->
32
+ ```nako3
33
+ 答=0
34
+ Iで1から10まで繰り返す:
35
+ 答=答+I
36
+ 「合計は{答}です」と表示
37
+ ```
38
+ <!-- ai-code-generation-example:end -->
39
+
40
+ 次のコマンドで実行できます。
41
+
42
+ ```sh
43
+ node src/cnako3.mjs sample.nako3
44
+ ```
45
+
46
+ 実行結果は次の通りです。
47
+
48
+ ```text
49
+ 合計は55です
50
+ ```
51
+
52
+ ## AIが参照する資料
53
+
54
+ AIには、次の2つのファイルを正本として使わせます。
55
+
56
+ - `doc/syntax-nako3.md`: 変数、条件分岐、繰り返し、関数定義などの文法
57
+ - `doc/command_list.json`: 命令名、引数と助詞、説明、実行環境などの命令情報
58
+
59
+ `doc/command_list.json`の各項目で、特に重要なフィールドは次の通りです。
60
+
61
+ - `name`: 命令名
62
+ - `args`: 引数と助詞。例えば`Sを/Sと`なら、「を」または「と」で引数を渡せる
63
+ - `target`: 対応する実行環境。`cnako`はNode.js版、`wnako`はブラウザ版
64
+ - `group`: `基本プラグイン`または`拡張プラグイン`
65
+ - `description`: 命令の説明
66
+ - `url`: 命令を定義しているソースコード
67
+
68
+ 命令一覧は大きなファイルです。AIにはファイル全体を回答へ貼り付けさせず、目的や命令名に合わせて必要な項目だけを検索させてください。
69
+
70
+ ## より正確に作ってもらうためのプロンプト
71
+
72
+ 実用的なプログラムでは、目的だけでなく、実行環境、入力、出力、制約、確認方法も伝えます。
73
+
74
+ ```text
75
+ なでしこ3で、CSVファイルを読み込み、2列目の数値の合計を表示する
76
+ プログラムを作ってください。
77
+
78
+ 条件:
79
+ - Node.js版のcnako3で動かす
80
+ - doc/syntax-nako3.mdの文法に従う
81
+ - 使用する命令はdoc/command_list.jsonで確認する
82
+ - targetにcnakoを含む命令だけを使う
83
+ - 命令のargsに記載された助詞を守る
84
+ - 拡張プラグインが必要なら、コードを作る前に説明する
85
+ - sample.nako3へ保存する
86
+ - node src/cnako3.mjs sample.nako3で実行確認する
87
+ - エラーになった場合は、原因を調べて修正し、再実行する
88
+ ```
89
+
90
+ ブラウザ版のプログラムが必要な場合は、`Node.js版のcnako3`を`ブラウザ版のwnako3`に置き換えます。その場合、`target`に`wnako`を含む命令を使うように指定してください。
91
+
92
+ ## 既存のプログラムを修正してもらう
93
+
94
+ エラーが発生するプログラムを直してもらう場合は、対象ファイルと実行方法を伝えます。
95
+
96
+ ```text
97
+ sample.nako3を実行するとエラーになります。
98
+ doc/syntax-nako3.mdとdoc/command_list.jsonを確認して修正してください。
99
+ 修正後、node src/cnako3.mjs sample.nako3を実行し、結果を確認してください。
100
+ ```
101
+
102
+ 実行環境を持たないチャット型AIを使う場合は、エラーメッセージを省略せずに貼り付けて、修正を依頼してください。
103
+
104
+ ## よくある失敗
105
+
106
+ ### 存在しない命令を使う
107
+
108
+ AIが、意味から命令名を推測してしまうことがあります。`doc/command_list.json`を検索し、実在する命令だけを使うように依頼してください。
109
+
110
+ ### 助詞が合っていない
111
+
112
+ なでしこ3では、命令へ引数を渡す助詞が決まっています。命令一覧の`args`を確認してください。
113
+
114
+ ### 実行環境が違う
115
+
116
+ DOM操作などはブラウザ専用、ファイル操作などはNode.js専用の場合があります。命令一覧の`target`に、目的の実行環境が含まれるか確認してください。
117
+
118
+ ### 拡張プラグインの命令をそのまま使う
119
+
120
+ `group`が`拡張プラグイン`の命令は、別パッケージのインストールや取り込みが必要になることがあります。AIに導入方法も確認させてください。
121
+
122
+ ### 命令名を変数名に使う
123
+
124
+ 命令名と同じ名前を変数へ使うと、代入時に文法エラーになることがあります。エラーが出た場合は、命令一覧を検索して変数名と命令名が衝突していないか確認してください。
125
+
126
+ ## 最後に確認すること
127
+
128
+ AIがプログラムを生成したら、次を確認します。
129
+
130
+ 1. 希望した`cnako`または`wnako`向けになっているか。
131
+ 2. 使用した命令が`doc/command_list.json`に存在するか。
132
+ 3. 命令の助詞が`args`と一致しているか。
133
+ 4. 必要な入力例と期待する出力が示されているか。
134
+ 5. 実際に実行し、エラーなく期待した結果が得られるか。
135
+
136
+ 生成AIの回答をそのまま完成品とせず、「資料を確認する」「実行する」「エラーを直す」という手順を繰り返すと、正確ななでしこ3プログラムを作りやすくなります。
package/doc/browsers.md CHANGED
@@ -9,7 +9,7 @@
9
9
  - Chrome (145/144/143/142/139/133/131/125/112/109以上)
10
10
  - Safari (26.3/26.2以上)
11
11
  - Opera (125/124以上)
12
- - Node.js (25.1.0/24.11.0/22.21.0/20.19.0以上)
12
+ - Node.js (25.1.0/24.11.0/22.21.0以上)
13
13
 
14
14
  ## モバイル
15
15