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.
- package/README.md +20 -1
- package/batch/command.txt +370 -334
- package/batch/generate_command_list.mjs +102 -0
- package/batch/jsplugin2text.nako3 +1 -1
- package/batch/pickup_command.nako3 +12 -0
- package/batch/search_command.mjs +34 -0
- package/batch/search_command.nako3 +430 -0
- package/core/command/snako.mts +5 -1
- package/core/deno/snako.ts +5 -1
- package/core/package-lock.json +382 -21
- package/core/package.json +7 -4
- package/core/sample/algorithms/README.md +43 -0
- package/core/sample/algorithms/graph/dijkstra.nako3 +47 -0
- package/core/sample/algorithms/graph/kruskal.nako3 +69 -0
- package/core/sample/algorithms/math/euclidean_gcd.nako3 +15 -0
- package/core/sample/algorithms/math/sieve_of_eratosthenes.nako3 +26 -0
- package/core/sample/algorithms/search/binary_search.nako3 +17 -0
- package/core/sample/algorithms/search/breadth_first_search.nako3 +33 -0
- package/core/sample/algorithms/search/depth_first_search.nako3 +25 -0
- package/core/sample/algorithms/sort/heap_sort.nako3 +37 -0
- package/core/sample/algorithms/sort/insertion_sort.nako3 +18 -0
- package/core/sample/algorithms/sort/merge_sort.nako3 +40 -0
- package/core/sample/algorithms/sort/quick_sort.nako3 +36 -0
- package/core/sample/algorithms/string/knuth_morris_pratt.nako3 +50 -0
- package/core/sample/algorithms/string/run_length_encoding.nako3 +25 -0
- package/core/src/nako3.mts +178 -614
- package/core/src/nako_basic_plugins.mts +39 -0
- package/core/src/nako_core_version.mts +2 -2
- package/core/src/nako_csv.mts +0 -1
- package/core/src/nako_event.mts +49 -0
- package/core/src/nako_gen.mts +320 -209
- package/core/src/nako_global.mts +18 -0
- package/core/src/nako_indent_inline.mts +2 -2
- package/core/src/nako_lex_rules.mts +1 -1
- package/core/src/nako_parser3.mts +111 -166
- package/core/src/nako_parser_async.mts +165 -0
- package/core/src/nako_parser_base.mts +4 -55
- package/core/src/nako_parser_message.mts +105 -0
- package/core/src/nako_parser_operator.mts +93 -0
- package/core/src/nako_plugin_manager.mts +260 -0
- package/core/src/nako_require.mts +292 -0
- package/core/src/nako_runner.mts +208 -0
- package/core/src/nako_tokenizer.mts +221 -0
- package/core/src/plugin_csv.mts +1 -1
- package/core/src/plugin_system.mts +34 -3259
- package/core/src/plugin_system_array.mts +699 -0
- package/core/src/plugin_system_datetime.mts +368 -0
- package/core/src/plugin_system_debug.mts +403 -0
- package/core/src/plugin_system_dict.mts +85 -0
- package/core/src/plugin_system_json.mts +73 -0
- package/core/src/plugin_system_math.mts +383 -0
- package/core/src/plugin_system_regexp.mts +120 -0
- package/core/src/plugin_system_stdio.mts +86 -0
- package/core/src/plugin_system_string.mts +666 -0
- package/core/src/plugin_system_timer.mts +152 -0
- package/core/src/plugin_system_types.mts +151 -0
- package/core/src/plugin_system_url.mts +193 -0
- package/core/src/plugin_toml.mts +3 -3
- package/core/test/algorithm_samples_test.mjs +58 -0
- package/core/test/algorithms/graph/dijkstra_test.nako3 +21 -0
- package/core/test/algorithms/graph/kruskal_test.nako3 +21 -0
- package/core/test/algorithms/helper.mjs +13 -0
- package/core/test/algorithms/math/euclidean_gcd_test.nako3 +13 -0
- package/core/test/algorithms/math/sieve_of_eratosthenes_test.nako3 +10 -0
- package/core/test/algorithms/search/binary_search_test.nako3 +15 -0
- package/core/test/algorithms/search/breadth_first_search_test.nako3 +13 -0
- package/core/test/algorithms/search/depth_first_search_test.nako3 +13 -0
- package/core/test/algorithms/sort/heap_sort_test.nako3 +13 -0
- package/core/test/algorithms/sort/insertion_sort_test.nako3 +13 -0
- package/core/test/algorithms/sort/merge_sort_test.nako3 +18 -0
- package/core/test/algorithms/sort/quick_sort_test.nako3 +34 -0
- package/core/test/algorithms/string/knuth_morris_pratt_test.nako3 +16 -0
- package/core/test/algorithms/string/run_length_encoding_test.nako3 +13 -0
- package/core/test/array_test.mjs +3 -0
- package/core/test/fixtures/README.md +39 -0
- package/core/test/fixtures/make_parser_ast_golden.mjs +31 -0
- package/core/test/fixtures/parser_ast_golden.json +8027 -0
- package/core/test/fixtures/parser_corpus.mjs +120 -0
- package/core/test/func_call.mjs +18 -0
- package/core/test/func_test.mjs +28 -0
- package/core/test/indent_test.mjs +6 -0
- package/core/test/nako_basic_plugins_test.mjs +44 -0
- package/core/test/nako_event_test.mjs +127 -0
- package/core/test/nako_gen_perf_test.mjs +178 -0
- package/core/test/nako_parser_async_test.mjs +385 -0
- package/core/test/nako_parser_test.mjs +160 -0
- package/core/test/nako_plugin_manager_test.mjs +185 -0
- package/core/test/nako_require_test.mjs +153 -0
- package/core/test/nako_runner_test.mjs +174 -0
- package/core/test/nako_tokenizer_test.mjs +115 -0
- package/core/test/plugin_system_debug_test.mjs +138 -0
- package/core/test/plugin_system_split_test.mjs +179 -0
- package/core/test/plugin_system_test.mjs +6 -0
- package/core/tsconfig.json +0 -1
- package/demo/browsers.html +1 -1
- package/doc/SETUP.md +1 -1
- package/doc/ai-code-generation.md +136 -0
- package/doc/browsers.md +1 -1
- package/doc/command_list.json +16842 -0
- package/doc/search_command.md +222 -0
- package/doc/syntax-nako3.md +344 -0
- package/package.json +29 -26
- package/release/_hash.txt +40 -40
- package/release/_script-tags.txt +16 -16
- package/release/command.json +1 -1
- package/release/command.json.js +1 -1
- package/release/command_cnako3.json +1 -1
- package/release/command_list.json +1 -1
- package/release/edit_main.js +6 -6
- package/release/edit_main.js.map +3 -3
- package/release/editor.js +6 -6
- package/release/plugin_caniuse.js +1 -1
- package/release/plugin_caniuse.js.map +2 -2
- package/release/plugin_keigo.js.map +3 -3
- package/release/plugin_markup.js +46 -46
- package/release/plugin_markup.js.map +3 -3
- package/release/plugin_weykturtle3d.js +1 -1
- package/release/plugin_weykturtle3d.js.map +3 -3
- package/release/version.js +2 -2
- package/release/version_main.js +2 -2
- package/release/version_main.js.map +1 -1
- package/release/wnako3.js +219 -230
- package/release/wnako3.js.map +4 -4
- package/release/wnako3webworker.js +193 -204
- package/release/wnako3webworker.js.map +4 -4
- package/src/browsers.mjs +1 -1
- package/src/browsers.txt +0 -1
- package/src/cnako3mod.mjs +7 -2
- package/src/cnako3mod.mts +7 -2
- package/src/nako_version.mjs +2 -2
- package/src/nako_version.mts +2 -2
- package/src/plugin_browser_ajax.mjs +4 -4
- package/src/plugin_browser_ajax.mts +4 -4
- package/src/plugin_browser_audio.mjs +10 -10
- package/src/plugin_browser_audio.mts +10 -10
- package/src/plugin_browser_camera.mjs +4 -4
- package/src/plugin_browser_camera.mts +4 -4
- package/src/plugin_browser_canvas.mjs +2 -2
- package/src/plugin_browser_canvas.mts +2 -2
- package/src/plugin_browser_crypto.mjs +3 -3
- package/src/plugin_browser_crypto.mts +3 -3
- package/src/plugin_browser_dom_event.mjs +1 -1
- package/src/plugin_browser_dom_event.mts +1 -1
- package/src/plugin_browser_geolocation.mjs +1 -1
- package/src/plugin_browser_geolocation.mts +1 -1
- package/src/plugin_browser_hotkey.mjs +1 -1
- package/src/plugin_browser_hotkey.mts +1 -1
- package/src/plugin_browser_html.mjs +1 -1
- package/src/plugin_browser_html.mts +1 -1
- package/src/plugin_browser_location.mjs +1 -1
- package/src/plugin_browser_location.mts +1 -1
- package/src/plugin_browser_speech.mjs +1 -1
- package/src/plugin_browser_speech.mts +1 -1
- package/src/plugin_browser_storage.mjs +2 -2
- package/src/plugin_browser_storage.mts +2 -2
- package/src/plugin_httpserver.mjs +3 -3
- package/src/plugin_httpserver.mts +3 -3
- package/src/plugin_keigo.mjs +2 -2
- package/src/plugin_keigo.mts +2 -2
- package/src/plugin_node.mjs +48 -48
- package/src/plugin_node.mts +53 -53
- package/src/plugin_weykturtle3d.mjs +56 -56
- package/src/plugin_weykturtle3d.mts +56 -56
- package/src/wnako3.mjs +1 -1
- package/src/wnako3.mts +1 -1
- package/src/wnako3_editor.mjs +5 -5
- package/src/wnako3_editor.mts +5 -5
- package/src/wnako3mod.mjs +2 -2
- package/src/wnako3mod.mts +2 -2
- package/test/nako3edit/index_nako3_test.mjs +282 -0
- package/test/nako3server/index_nako3_test.mjs +239 -0
- package/test/node/ai_code_generation_guide_test.mjs +29 -0
- package/test/node/node_version_support_test.mjs +45 -0
- package/test/node/search_command_test.mjs +174 -0
- package/tools/nako3edit/AGENTS.md +23 -0
- package/tools/nako3edit/index.nako3 +404 -0
- package/tools/nako3server/AGENTS.md +23 -0
- package/tools/nako3server/index.nako3 +156 -23
- package/core/src/nako3.mjs +0 -1021
- package/core/src/nako_ast.mjs +0 -4
- package/core/src/nako_colors.mjs +0 -77
- package/core/src/nako_core_version.mjs +0 -8
- package/core/src/nako_csv.mjs +0 -193
- package/core/src/nako_errors.mjs +0 -166
- package/core/src/nako_from_dncl.mjs +0 -285
- package/core/src/nako_from_dncl2.mjs +0 -347
- package/core/src/nako_gen.mjs +0 -2500
- package/core/src/nako_global.mjs +0 -138
- package/core/src/nako_indent.mjs +0 -442
- package/core/src/nako_indent_chars.mjs +0 -29
- package/core/src/nako_indent_inline.mjs +0 -361
- package/core/src/nako_josi_list.mjs +0 -47
- package/core/src/nako_lex_rules.mjs +0 -319
- package/core/src/nako_lexer.mjs +0 -794
- package/core/src/nako_logger.mjs +0 -221
- package/core/src/nako_parser3.mjs +0 -3250
- package/core/src/nako_parser_base.mjs +0 -403
- package/core/src/nako_parser_const.mjs +0 -37
- package/core/src/nako_prepare.mjs +0 -329
- package/core/src/nako_reserved_words.mjs +0 -42
- package/core/src/nako_source_mapping.mjs +0 -207
- package/core/src/nako_test.mjs +0 -37
- package/core/src/nako_token.mjs +0 -1
- package/core/src/nako_tools.mjs +0 -53
- package/core/src/nako_types.mjs +0 -14
- package/core/src/plugin_api.mjs +0 -4
- package/core/src/plugin_csv.mjs +0 -97
- package/core/src/plugin_math.mjs +0 -352
- package/core/src/plugin_promise.mjs +0 -102
- package/core/src/plugin_system.mjs +0 -3810
- package/core/src/plugin_test.mjs +0 -52
- package/core/src/plugin_toml.mjs +0 -39
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
// batch/search_command.nako3 (命令検索CLI)のテスト (#2385)
|
|
3
|
+
// ラッパー batch/search_command.mjs を子プロセスとして実行して動作を確認する。
|
|
4
|
+
import assert from 'assert'
|
|
5
|
+
import path from 'path'
|
|
6
|
+
import url from 'url'
|
|
7
|
+
import { spawnSync } from 'child_process'
|
|
8
|
+
|
|
9
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
10
|
+
const __dirname = path.dirname(__filename)
|
|
11
|
+
const rootDir = path.resolve(__dirname, '../../')
|
|
12
|
+
const cliPath = path.join(rootDir, 'batch/search_command.mjs')
|
|
13
|
+
|
|
14
|
+
/** 命令検索CLIを実行して {code, stdout} を返す */
|
|
15
|
+
function runCLI (args) {
|
|
16
|
+
const r = spawnSync(process.execPath, [cliPath, ...args], {
|
|
17
|
+
cwd: rootDir,
|
|
18
|
+
encoding: 'utf-8',
|
|
19
|
+
// npm test は --test-timeout=15000 で実行されるので、それより短くして
|
|
20
|
+
// ハング時にテスト側のタイムアウトより先に原因が分かるようにする
|
|
21
|
+
timeout: 10000
|
|
22
|
+
})
|
|
23
|
+
if (r.error) { throw r.error }
|
|
24
|
+
if (r.signal) {
|
|
25
|
+
throw new Error(`検索CLIがシグナル${r.signal}で終了しました(タイムアウトの可能性)。\n出力=${r.stdout}${r.stderr}`)
|
|
26
|
+
}
|
|
27
|
+
return { code: r.status, stdout: r.stdout || '', stderr: r.stderr || '' }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe('search_command(命令検索CLI)', () => {
|
|
31
|
+
it('検索語で部分一致検索ができる', () => {
|
|
32
|
+
const r = runCLI(['ファイル'])
|
|
33
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
34
|
+
assert.ok(r.stdout.indexOf('件見つかりました。') >= 0)
|
|
35
|
+
assert.ok(r.stdout.indexOf('ファイル') >= 0)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('命令名が完全一致するものが先頭に表示される', () => {
|
|
39
|
+
const r = runCLI(['表示', '--limit', '5'])
|
|
40
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
41
|
+
const lines = r.stdout.split('\n').filter((s) => s.indexOf('[関数] ') === 0)
|
|
42
|
+
assert.ok(lines.length > 0)
|
|
43
|
+
assert.ok(lines[0].indexOf('[関数] 表示 ') === 0, lines[0])
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('--targetで実行環境を絞り込める', () => {
|
|
47
|
+
const r = runCLI(['ファイル', '--target', 'cnako', '--json'])
|
|
48
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
49
|
+
const list = JSON.parse(r.stdout)
|
|
50
|
+
assert.ok(list.length > 0)
|
|
51
|
+
for (const c of list) {
|
|
52
|
+
assert.ok(c.target.indexOf('cnako') >= 0, JSON.stringify(c))
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('--groupで基本/拡張プラグインを絞り込める(英語指定)', () => {
|
|
57
|
+
const r = runCLI(['表示', '--group', 'basic', '--json'])
|
|
58
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
59
|
+
const list = JSON.parse(r.stdout)
|
|
60
|
+
assert.ok(list.length > 0)
|
|
61
|
+
for (const c of list) {
|
|
62
|
+
assert.strictEqual(c.group, '基本プラグイン')
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('--groupは日本語でも指定できる', () => {
|
|
67
|
+
// 拡張プラグインの命令は環境によって有無が変わるため、英語指定と日本語指定の
|
|
68
|
+
// 結果が一致することで、日本語の指定が使えることを確認する。
|
|
69
|
+
const r1 = runCLI(['表示', '--group', 'basic', '--json'])
|
|
70
|
+
const r2 = runCLI(['表示', '--group', '基本プラグイン', '--json'])
|
|
71
|
+
assert.strictEqual(r1.code, 0, r1.stdout + r1.stderr)
|
|
72
|
+
assert.strictEqual(r2.code, r1.code)
|
|
73
|
+
assert.deepStrictEqual(JSON.parse(r2.stdout), JSON.parse(r1.stdout))
|
|
74
|
+
const r3 = runCLI(['ファイル', '--group', '拡張プラグイン', '--json'])
|
|
75
|
+
assert.ok(r3.code === 0 || r3.code === 1, `exit=${r3.code}`)
|
|
76
|
+
for (const c of JSON.parse(r3.stdout)) {
|
|
77
|
+
assert.strictEqual(c.group, '拡張プラグイン')
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('--plugin と --type で絞り込める', () => {
|
|
82
|
+
const r = runCLI(['--plugin', 'plugin_node', '--type', '関数', '--limit', '0', '--json'])
|
|
83
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
84
|
+
const list = JSON.parse(r.stdout)
|
|
85
|
+
assert.ok(list.length > 0)
|
|
86
|
+
for (const c of list) {
|
|
87
|
+
assert.ok(c.plugin.indexOf('plugin_node') >= 0, c.plugin)
|
|
88
|
+
assert.strictEqual(c.type, '関数')
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('--option=値 の形式でも指定できる', () => {
|
|
93
|
+
const r = runCLI(['ファイル', '--target=cnako', '--limit=3', '--json'])
|
|
94
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
95
|
+
const list = JSON.parse(r.stdout)
|
|
96
|
+
assert.strictEqual(list.length, 3)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('検索語を複数指定するとAND条件になる', () => {
|
|
100
|
+
const r1 = runCLI(['ファイル', '--json', '--limit', '0'])
|
|
101
|
+
const r2 = runCLI(['ファイル', 'コピー', '--json', '--limit', '0'])
|
|
102
|
+
assert.strictEqual(r1.code, 0)
|
|
103
|
+
assert.strictEqual(r2.code, 0)
|
|
104
|
+
const list1 = JSON.parse(r1.stdout)
|
|
105
|
+
const list2 = JSON.parse(r2.stdout)
|
|
106
|
+
assert.ok(list2.length > 0)
|
|
107
|
+
assert.ok(list2.length < list1.length)
|
|
108
|
+
for (const c of list2) {
|
|
109
|
+
const text = `${c.name} ${c.yomi} ${c.description}`
|
|
110
|
+
assert.ok(text.indexOf('コピー') >= 0, JSON.stringify(c))
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('一致なしのとき終了コード1になる', () => {
|
|
115
|
+
const r = runCLI(['ぜったいにない命令名XYZ'])
|
|
116
|
+
assert.strictEqual(r.code, 1)
|
|
117
|
+
assert.ok(r.stdout.indexOf('一致する命令は見つかりませんでした。') >= 0)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('一致なしのJSON出力は空配列になる', () => {
|
|
121
|
+
const r = runCLI(['ぜったいにない命令名XYZ', '--json'])
|
|
122
|
+
assert.strictEqual(r.code, 1)
|
|
123
|
+
assert.deepStrictEqual(JSON.parse(r.stdout), [])
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('JSON出力は必要なキーだけを含む', () => {
|
|
127
|
+
const r = runCLI(['CSV変換', '--json'])
|
|
128
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
129
|
+
const list = JSON.parse(r.stdout)
|
|
130
|
+
assert.ok(list.length > 0)
|
|
131
|
+
const keys = Object.keys(list[0]).sort()
|
|
132
|
+
assert.deepStrictEqual(keys, ['args', 'description', 'group', 'name', 'plugin', 'target', 'type', 'yomi'])
|
|
133
|
+
assert.strictEqual(list[0].name, 'CSV変換')
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('--limitで表示件数を制限できる', () => {
|
|
137
|
+
const r = runCLI(['ファイル', '--limit', '2'])
|
|
138
|
+
assert.strictEqual(r.code, 0, r.stdout + r.stderr)
|
|
139
|
+
const lines = r.stdout.split('\n').filter((s) => /^\[(関数|変数|定数)\] /.test(s))
|
|
140
|
+
assert.strictEqual(lines.length, 2)
|
|
141
|
+
assert.ok(r.stdout.indexOf('--limit 0') >= 0)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('--helpで使い方を表示する', () => {
|
|
145
|
+
const r = runCLI(['--help'])
|
|
146
|
+
assert.strictEqual(r.code, 0)
|
|
147
|
+
assert.ok(r.stdout.indexOf('なでしこ3 命令検索CLI') >= 0)
|
|
148
|
+
assert.ok(r.stdout.indexOf('--target') >= 0)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('引数がないときは使い方を表示して終了コード2になる', () => {
|
|
152
|
+
const r = runCLI([])
|
|
153
|
+
assert.strictEqual(r.code, 2)
|
|
154
|
+
assert.ok(r.stdout.indexOf('使い方:') >= 0)
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('不明なオプションは終了コード2になる', () => {
|
|
158
|
+
const r = runCLI(['ファイル', '--unknown'])
|
|
159
|
+
assert.strictEqual(r.code, 2)
|
|
160
|
+
assert.ok(r.stdout.indexOf('不明なオプション') >= 0)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it('オプションの値がないときは終了コード2になる', () => {
|
|
164
|
+
const r = runCLI(['ファイル', '--target'])
|
|
165
|
+
assert.strictEqual(r.code, 2)
|
|
166
|
+
assert.ok(r.stdout.indexOf('値の指定が必要です') >= 0)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('不正な値を指定したときは終了コード2になる', () => {
|
|
170
|
+
const r = runCLI(['ファイル', '--target', 'xxx'])
|
|
171
|
+
assert.strictEqual(r.code, 2)
|
|
172
|
+
assert.ok(r.stdout.indexOf('--target') >= 0)
|
|
173
|
+
})
|
|
174
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ゴール
|
|
2
|
+
|
|
3
|
+
Node.js(JavaScript)で書かれたnako3edit用のサーバー`index.mjs`を、完全に、なでしこ3のプログラムとして書き直すことを目標とします。
|
|
4
|
+
|
|
5
|
+
作成したプログラムは、`index.nako3`として、なでしこ3のプログラムとして実行できるようにします。
|
|
6
|
+
|
|
7
|
+
## コンテキスト
|
|
8
|
+
|
|
9
|
+
なでしこの文法は、`doc/syntax-nako3.md`にまとめられています。
|
|
10
|
+
|
|
11
|
+
## デバッグについて
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
# プログラム index.nako3を実行する
|
|
15
|
+
cnako3 index.nako3
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
プログラムの構造を理解するには、次のコマンドで、プログラムの構造(文法構造ツリー)を表示することができます。
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
# ASTを表示する
|
|
22
|
+
cnako3 --ast index.nako3
|
|
23
|
+
```
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
#!/usr/bin/env cnako3
|
|
2
|
+
# nako3edit用の超簡易サーバ(なでしこ3だけで簡単HTTPサーバ)
|
|
3
|
+
# もともと index.mjs (Node.js) で書かれていたものを、なでしこ3で書き直したものです。
|
|
4
|
+
!「plugin_httpserver.mjs」を取り込む。
|
|
5
|
+
|
|
6
|
+
# --- 定数 ---
|
|
7
|
+
定数のルートパス=母艦パスを絶対パス変換。
|
|
8
|
+
定数のリリースパス=「{母艦パス}/../../release」を絶対パス変換。
|
|
9
|
+
定数のCNAKO3パス=「{母艦パス}/../../src/cnako3.mjs」を絶対パス変換。
|
|
10
|
+
定数のNODEパス=コマンドライン[0]
|
|
11
|
+
定数の既定ポート=8888
|
|
12
|
+
定数の環境変数一覧=環境変数一覧取得。
|
|
13
|
+
定数のアプリキー=「k{(4294967295の乱数)のHEX}{(4294967295の乱数)のHEX}{(4294967295の乱数)のHEX}{(4294967295の乱数)のHEX}」
|
|
14
|
+
定数のMIME一覧={
|
|
15
|
+
".html": "text/html",
|
|
16
|
+
".css": "text/css",
|
|
17
|
+
".js": "text/javascript",
|
|
18
|
+
".png": "image/png",
|
|
19
|
+
".gif": "image/gif",
|
|
20
|
+
".svg": "image/svg+xml"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# --- 小さな便利関数 ---
|
|
24
|
+
|
|
25
|
+
# 文字列Sが文字列Pで始まるかどうかを調べる
|
|
26
|
+
●(SがPで)先頭一致とは
|
|
27
|
+
((Sで1からPを文字検索)=1)を戻す。
|
|
28
|
+
ここまで。
|
|
29
|
+
|
|
30
|
+
# 環境変数KEYの値を返す。未設定なら既定値Dを返す。
|
|
31
|
+
●(KEYとDの)環境変数参照とは
|
|
32
|
+
もし、(環境変数一覧のKEYが辞書キー存在)ならば
|
|
33
|
+
(環境変数一覧[KEY])を戻す。
|
|
34
|
+
ここまで。
|
|
35
|
+
Dを戻す。
|
|
36
|
+
ここまで。
|
|
37
|
+
|
|
38
|
+
# ユーザーが作成したなでしこファイルを保存するフォルダを返す
|
|
39
|
+
●ユーザーフォルダ取得とは
|
|
40
|
+
もし、(OS取得=「win32」)ならば
|
|
41
|
+
ホーム=「USERPROFILE」と「.」の環境変数参照。
|
|
42
|
+
違えば
|
|
43
|
+
ホーム=「HOME」と「.」の環境変数参照。
|
|
44
|
+
ここまで。
|
|
45
|
+
「{ホーム}/nadesiko3_user」を絶対パス変換して戻す。
|
|
46
|
+
ここまで。
|
|
47
|
+
|
|
48
|
+
# パスPATHからMIMEタイプを求めて返す
|
|
49
|
+
●(PATHの)MIMEタイプ取得とは
|
|
50
|
+
拡張子=「.txt」
|
|
51
|
+
部品=PATHを「.」で区切る。
|
|
52
|
+
もし、((部品の要素数)>1)ならば
|
|
53
|
+
拡張子=「.{(部品[(部品の要素数)-1])を小文字変換}」
|
|
54
|
+
ここまで。
|
|
55
|
+
もし、(MIME一覧の拡張子が辞書キー存在)ならば
|
|
56
|
+
(MIME一覧[拡張子])を戻す。
|
|
57
|
+
ここまで。
|
|
58
|
+
「text/plain」を戻す。
|
|
59
|
+
ここまで。
|
|
60
|
+
|
|
61
|
+
# ファイル名に利用できない記号を置き換える
|
|
62
|
+
●(Sの)ファイル名サニタイズとは
|
|
63
|
+
S=Sの『/['"`\\?\/<\>\*]/g』を「_」で正規表現置換。
|
|
64
|
+
S=Sの『/_{2,}/g』を「」で正規表現置換。
|
|
65
|
+
Sを戻す。
|
|
66
|
+
ここまで。
|
|
67
|
+
|
|
68
|
+
# 共通のContent-Typeヘッダを付けて200を返す
|
|
69
|
+
●(本文を種類で)正常返信とは
|
|
70
|
+
ヘッダ={"Content-Type": 種類}
|
|
71
|
+
200でヘッダを簡易HTTPサーバヘッダ出力。
|
|
72
|
+
本文を簡易HTTPサーバ出力。
|
|
73
|
+
ここまで。
|
|
74
|
+
|
|
75
|
+
# 共通のContent-Typeヘッダを付けて500を返す
|
|
76
|
+
●(本文を種類で)サーバエラー返信とは
|
|
77
|
+
ヘッダ={"Content-Type": 種類}
|
|
78
|
+
500でヘッダを簡易HTTPサーバヘッダ出力。
|
|
79
|
+
本文を簡易HTTPサーバ出力。
|
|
80
|
+
ここまで。
|
|
81
|
+
|
|
82
|
+
# アプリキーを確認する。正しければ真を返す。
|
|
83
|
+
●(PARAMSの)アプリキー確認とは
|
|
84
|
+
もし、((PARAMSの「appkey」が辞書キー存在)=偽)ならば、偽を戻す。
|
|
85
|
+
(PARAMS["appkey"]=アプリキー)を戻す。
|
|
86
|
+
ここまで。
|
|
87
|
+
|
|
88
|
+
# --- 起動前の準備 ---
|
|
89
|
+
|
|
90
|
+
# ポート番号を検証して、安全な値のみを利用する
|
|
91
|
+
●サーバポート解決とは
|
|
92
|
+
生ポート=「NAKO3EDIT_PORT」と「」の環境変数参照。
|
|
93
|
+
# 環境変数になければコマンドライン引数を見る(cnako3ではスクリプト名の次が引数)
|
|
94
|
+
もし、(生ポート=「」)ならば
|
|
95
|
+
もし、((コマンドラインの要素数)>3)ならば
|
|
96
|
+
生ポート=コマンドライン[3]
|
|
97
|
+
ここまで。
|
|
98
|
+
ここまで。
|
|
99
|
+
もし、(生ポート=「」)ならば、既定ポートを戻す。
|
|
100
|
+
ポート番号=生ポートを整数変換。
|
|
101
|
+
もし、((ポート番号を非数判定)または(ポート番号<0)または(ポート番号>65535))ならば
|
|
102
|
+
「[ERROR] 無効なポート番号です: {生ポート}」と表示。
|
|
103
|
+
「[ERROR] 環境変数 NAKO3EDIT_PORT またはコマンドライン引数には 0 から 65535 の整数を指定してください。」と表示。
|
|
104
|
+
終了。
|
|
105
|
+
ここまで。
|
|
106
|
+
ポート番号を戻す。
|
|
107
|
+
ここまで。
|
|
108
|
+
|
|
109
|
+
定数のサーバポート=サーバポート解決。
|
|
110
|
+
定数のユーザーパス=ユーザーフォルダ取得。
|
|
111
|
+
もし、((ユーザーパスがフォルダ存在)=偽)ならば、ユーザーパスをフォルダ作成。
|
|
112
|
+
|
|
113
|
+
# --- API ---
|
|
114
|
+
|
|
115
|
+
# ユーザーフォルダのファイル一覧を返す
|
|
116
|
+
●APIファイル一覧とは
|
|
117
|
+
ファイル一覧=ユーザーパスのファイル列挙。
|
|
118
|
+
(ファイル一覧をJSONエンコード)を「application/json」で正常返信。
|
|
119
|
+
ここまで。
|
|
120
|
+
|
|
121
|
+
# ファイルを読み込む。存在しなければ新規ファイル用の初期値を返す。
|
|
122
|
+
●(PARAMSの)API読込とは
|
|
123
|
+
ファイル名=PARAMS["file"]のファイル名サニタイズ。
|
|
124
|
+
フルパス=「{ユーザーパス}/{ファイル名}」
|
|
125
|
+
「load= {フルパス}」と表示。
|
|
126
|
+
本文=「# 新規ファイル{改行}」&『「こんにちは」と表示。』
|
|
127
|
+
もし、(フルパスが存在)ならば、本文=フルパスを読。
|
|
128
|
+
本文を「text/plain」で正常返信。
|
|
129
|
+
ここまで。
|
|
130
|
+
|
|
131
|
+
# ファイルを保存する
|
|
132
|
+
●(PARAMSの)API保存とは
|
|
133
|
+
もし、((PARAMSのアプリキー確認)=偽)ならば
|
|
134
|
+
「[ERROR] キーが違います」を「text/plain; charset=utf-8」で正常返信。
|
|
135
|
+
戻る。
|
|
136
|
+
ここまで。
|
|
137
|
+
ファイル名=PARAMS["file"]のファイル名サニタイズ。
|
|
138
|
+
本文=PARAMS["body"]
|
|
139
|
+
フルパス=「{ユーザーパス}/{ファイル名}」
|
|
140
|
+
保存成功=真
|
|
141
|
+
エラー監視
|
|
142
|
+
本文をフルパスへ保存。
|
|
143
|
+
エラーならば
|
|
144
|
+
保存成功=偽
|
|
145
|
+
ここまで。
|
|
146
|
+
もし、保存成功ならば
|
|
147
|
+
「[save] file= {フルパス}」と表示。
|
|
148
|
+
「body= {本文}」と表示。
|
|
149
|
+
「--------------------------------」と表示。
|
|
150
|
+
「ok」を「text/plain; charset=utf-8」で正常返信。
|
|
151
|
+
違えば
|
|
152
|
+
「[ERROR] 保存に失敗しました😭」を「text/plain; charset=utf-8」で正常返信。
|
|
153
|
+
ここまで。
|
|
154
|
+
ここまで。
|
|
155
|
+
|
|
156
|
+
# 指定したファイルをcnako3で実行して結果を返す
|
|
157
|
+
●(ファイル名の)ファイル実行とは
|
|
158
|
+
フルパス=「{ユーザーパス}/{ファイル名}」
|
|
159
|
+
コマンド=「"{NODEパス}" "{CNAKO3パス}" "{フルパス}"」
|
|
160
|
+
「@run= {コマンド}」と表示。
|
|
161
|
+
実行成功=真
|
|
162
|
+
エラー監視
|
|
163
|
+
実行結果=コマンドを起動待機。
|
|
164
|
+
エラーならば
|
|
165
|
+
実行成功=偽
|
|
166
|
+
実行結果=エラーメッセージ
|
|
167
|
+
ここまで。
|
|
168
|
+
もし、(実行成功=偽)ならば
|
|
169
|
+
「[ERROR]実行に失敗しました。{実行結果}」を戻す。
|
|
170
|
+
ここまで。
|
|
171
|
+
「[run] file= {ファイル名}」と表示。
|
|
172
|
+
「--------------------------------」と表示。
|
|
173
|
+
実行結果を表示。
|
|
174
|
+
「--------------------------------」と表示。
|
|
175
|
+
実行結果を戻す。
|
|
176
|
+
ここまで。
|
|
177
|
+
|
|
178
|
+
# 保存してからファイルを実行する
|
|
179
|
+
●(PARAMSの)API実行とは
|
|
180
|
+
もし、((PARAMSのアプリキー確認)=偽)ならば
|
|
181
|
+
「[ERROR] キーが違います」を「text/plain; charset=utf-8」で正常返信。
|
|
182
|
+
戻る。
|
|
183
|
+
ここまで。
|
|
184
|
+
ファイル名=PARAMS["file"]のファイル名サニタイズ。
|
|
185
|
+
本文=PARAMS["body"]
|
|
186
|
+
フルパス=「{ユーザーパス}/{ファイル名}」
|
|
187
|
+
保存成功=真
|
|
188
|
+
エラー監視
|
|
189
|
+
本文をフルパスへ保存。
|
|
190
|
+
エラーならば
|
|
191
|
+
保存成功=偽
|
|
192
|
+
ここまで。
|
|
193
|
+
もし、(保存成功=偽)ならば
|
|
194
|
+
「[ERROR] 実行に失敗しました。」を「text/plain; charset=utf-8」で正常返信。
|
|
195
|
+
戻る。
|
|
196
|
+
ここまで。
|
|
197
|
+
実行結果=ファイル名のファイル実行。
|
|
198
|
+
実行結果を「text/plain; charset=utf-8」で正常返信。
|
|
199
|
+
ここまで。
|
|
200
|
+
|
|
201
|
+
# 保存済みのファイルを直接実行する
|
|
202
|
+
●(PARAMSの)API直接実行とは
|
|
203
|
+
もし、((PARAMSのアプリキー確認)=偽)ならば
|
|
204
|
+
「[ERROR] キーが違います」を「text/plain; charset=utf-8」で正常返信。
|
|
205
|
+
戻る。
|
|
206
|
+
ここまで。
|
|
207
|
+
ファイル名=PARAMS["file"]のファイル名サニタイズ。
|
|
208
|
+
実行結果=ファイル名のファイル実行。
|
|
209
|
+
実行結果を「text/plain; charset=utf-8」で正常返信。
|
|
210
|
+
ここまで。
|
|
211
|
+
|
|
212
|
+
# ファイルを削除する
|
|
213
|
+
●(PARAMSの)API削除とは
|
|
214
|
+
もし、((PARAMSのアプリキー確認)=偽)ならば
|
|
215
|
+
『"[ERROR] キーが違います"』を「text/plain; charset=utf-8」で正常返信。
|
|
216
|
+
戻る。
|
|
217
|
+
ここまで。
|
|
218
|
+
ファイル名=PARAMS["file"]のファイル名サニタイズ。
|
|
219
|
+
フルパス=「{ユーザーパス}/{ファイル名}」
|
|
220
|
+
もし、((フルパスが存在)=偽)ならば
|
|
221
|
+
『"[ERROR] ファイルが見つかりません。"』を「text/plain; charset=utf-8」で正常返信。
|
|
222
|
+
戻る。
|
|
223
|
+
ここまで。
|
|
224
|
+
削除成功=真
|
|
225
|
+
エラー監視
|
|
226
|
+
フルパスをファイル削除。
|
|
227
|
+
エラーならば
|
|
228
|
+
削除成功=偽
|
|
229
|
+
削除エラー=エラーメッセージ
|
|
230
|
+
ここまで。
|
|
231
|
+
もし、削除成功ならば
|
|
232
|
+
『"ok"』を「text/plain; charset=utf-8」で正常返信。
|
|
233
|
+
違えば
|
|
234
|
+
「error:{削除エラー}」を「text/plain; charset=utf-8」で正常返信。
|
|
235
|
+
ここまで。
|
|
236
|
+
ここまで。
|
|
237
|
+
|
|
238
|
+
# 未使用のファイル名を返す
|
|
239
|
+
●API新規ファイル名取得とは
|
|
240
|
+
ファイル名=「newfile.nako3」
|
|
241
|
+
番号で1から9999まで繰り返す
|
|
242
|
+
ファイル名=「file{番号}.nako3」
|
|
243
|
+
フルパス=「{ユーザーパス}/{ファイル名}」
|
|
244
|
+
もし、((フルパスが存在)=偽)ならば、抜ける。
|
|
245
|
+
ここまで。
|
|
246
|
+
「"{ファイル名}"」を「text/plain; charset=utf-8」で正常返信。
|
|
247
|
+
ここまで。
|
|
248
|
+
|
|
249
|
+
# npmから利用可能なプラグイン一覧を取得する
|
|
250
|
+
●(PARAMSの)APIプラグイン取得とは
|
|
251
|
+
もし、((PARAMSのアプリキー確認)=偽)ならば
|
|
252
|
+
『"[ERROR] キーが違います"』を「text/plain; charset=utf-8」で正常返信。
|
|
253
|
+
戻る。
|
|
254
|
+
ここまで。
|
|
255
|
+
取得成功=真
|
|
256
|
+
エラー監視
|
|
257
|
+
結果=『npm search "nadesiko3\-" --json』を起動待機。
|
|
258
|
+
エラーならば
|
|
259
|
+
取得成功=偽
|
|
260
|
+
ここまで。
|
|
261
|
+
もし、取得成功ならば
|
|
262
|
+
結果を「text/plain; charset=utf-8」で正常返信。
|
|
263
|
+
違えば
|
|
264
|
+
『"[ERROR] プラグインの取得に失敗しました。"』を「text/plain; charset=utf-8」で正常返信。
|
|
265
|
+
ここまで。
|
|
266
|
+
ここまで。
|
|
267
|
+
|
|
268
|
+
# npmプラグインを追加する
|
|
269
|
+
●(PARAMSの)APIプラグイン追加とは
|
|
270
|
+
もし、((PARAMSのアプリキー確認)=偽)ならば
|
|
271
|
+
『"[ERROR] キーが違います"』を「text/plain; charset=utf-8」で正常返信。
|
|
272
|
+
戻る。
|
|
273
|
+
ここまで。
|
|
274
|
+
もし、((PARAMSの「name」が辞書キー存在)=偽)または(PARAMS["name"]=「」)ならば
|
|
275
|
+
『"[ERROR] プラグイン名が指定されていません。"』を「text/plain; charset=utf-8」で正常返信。
|
|
276
|
+
戻る。
|
|
277
|
+
ここまで。
|
|
278
|
+
追加成功=真
|
|
279
|
+
エラー監視
|
|
280
|
+
名前=PARAMS["name"]
|
|
281
|
+
コマンド=「npm install "{名前}"」
|
|
282
|
+
結果=コマンドを起動待機。
|
|
283
|
+
エラーならば
|
|
284
|
+
追加成功=偽
|
|
285
|
+
ここまで。
|
|
286
|
+
もし、追加成功ならば
|
|
287
|
+
「実行しました:{結果}」を「text/plain; charset=utf-8」で正常返信。
|
|
288
|
+
違えば
|
|
289
|
+
『"[ERROR] プラグインの取得に失敗しました。"』を「text/plain; charset=utf-8」で正常返信。
|
|
290
|
+
ここまで。
|
|
291
|
+
ここまで。
|
|
292
|
+
|
|
293
|
+
# --- 静的ファイル ---
|
|
294
|
+
|
|
295
|
+
# 404エラーを返す
|
|
296
|
+
●(URIとFPATHで)エラー404返信とは
|
|
297
|
+
「[ERROR] 404 {URI}」と表示。
|
|
298
|
+
「| file= {FPATH}」と表示。
|
|
299
|
+
ヘッダ={"Content-Type": "text/html; charset=utf-8"}
|
|
300
|
+
404でヘッダを簡易HTTPサーバヘッダ出力。
|
|
301
|
+
「<html><meta charset="utf-8"><body><h1>404 残念(ToT) ファイルがありません。</h1></body></html>」を簡易HTTPサーバ出力。
|
|
302
|
+
ここまで。
|
|
303
|
+
|
|
304
|
+
# URIを元にして返信すべきファイルのパスを求める
|
|
305
|
+
●(URIの)ファイルパス取得とは
|
|
306
|
+
安全URI=URIの「..」を「」に置換。
|
|
307
|
+
もし、(安全URIが「/release/」で先頭一致)ならば
|
|
308
|
+
相対URI=安全URIの『/^\/release/』を「」で正規表現置換。
|
|
309
|
+
FPATH=「{リリースパス}/{相対URI}」
|
|
310
|
+
違えば
|
|
311
|
+
FPATH=「{ルートパス}/{安全URI}」
|
|
312
|
+
ここまで。
|
|
313
|
+
FPATH=FPATHの「//」を「/」に置換。
|
|
314
|
+
もし、(FPATHがフォルダ存在)ならば
|
|
315
|
+
FPATH=「{FPATH}/index.html」の「//」を「/」に置換。
|
|
316
|
+
ここまで。
|
|
317
|
+
FPATHを戻す。
|
|
318
|
+
ここまで。
|
|
319
|
+
|
|
320
|
+
# 静的ファイルを返す
|
|
321
|
+
●(URIの)静的ファイル返信とは
|
|
322
|
+
FPATH=URIのファイルパス取得。
|
|
323
|
+
もし、((FPATHが存在)=偽)ならば
|
|
324
|
+
URIとFPATHでエラー404返信。
|
|
325
|
+
戻る。
|
|
326
|
+
ここまで。
|
|
327
|
+
読込成功=真
|
|
328
|
+
エラー監視
|
|
329
|
+
データ=FPATHをバイナリ読。
|
|
330
|
+
エラーならば
|
|
331
|
+
読込成功=偽
|
|
332
|
+
ここまで。
|
|
333
|
+
もし、(読込成功=偽)ならば
|
|
334
|
+
「Failed to read file.」を「text/plain」でサーバエラー返信。
|
|
335
|
+
戻る。
|
|
336
|
+
ここまで。
|
|
337
|
+
データを(FPATHのMIMEタイプ取得)で正常返信。
|
|
338
|
+
ここまで。
|
|
339
|
+
|
|
340
|
+
# リクエストされたURIを処理して返信する
|
|
341
|
+
●リクエスト処理とは
|
|
342
|
+
URI=GETデータ["?URL"]
|
|
343
|
+
PARAMS=GETデータ
|
|
344
|
+
「[ようこそ] {URIをJSONエンコード}」と表示。
|
|
345
|
+
もし、(URI=「/」)ならば
|
|
346
|
+
移動先=「/html/files.html?appkey={アプリキー}」
|
|
347
|
+
ヘッダ={"Location": 移動先}
|
|
348
|
+
302でヘッダを簡易HTTPサーバヘッダ出力。
|
|
349
|
+
「<a href="/html/files.html">HTML</a>」を簡易HTTPサーバ出力。
|
|
350
|
+
戻る。
|
|
351
|
+
ここまで。
|
|
352
|
+
もし、(URI=「/files」)ならば
|
|
353
|
+
APIファイル一覧。
|
|
354
|
+
戻る。
|
|
355
|
+
ここまで。
|
|
356
|
+
もし、(URI=「/load」)ならば
|
|
357
|
+
PARAMSのAPI読込。
|
|
358
|
+
戻る。
|
|
359
|
+
ここまで。
|
|
360
|
+
もし、(URI=「/save」)ならば
|
|
361
|
+
PARAMSのAPI保存。
|
|
362
|
+
戻る。
|
|
363
|
+
ここまで。
|
|
364
|
+
もし、(URI=「/run」)ならば
|
|
365
|
+
PARAMSのAPI実行。
|
|
366
|
+
戻る。
|
|
367
|
+
ここまで。
|
|
368
|
+
もし、(URI=「/run_direct」)ならば
|
|
369
|
+
PARAMSのAPI直接実行。
|
|
370
|
+
戻る。
|
|
371
|
+
ここまで。
|
|
372
|
+
もし、(URI=「/get_new_filename」)ならば
|
|
373
|
+
API新規ファイル名取得。
|
|
374
|
+
戻る。
|
|
375
|
+
ここまで。
|
|
376
|
+
もし、(URI=「/deletefile」)ならば
|
|
377
|
+
PARAMSのAPI削除。
|
|
378
|
+
戻る。
|
|
379
|
+
ここまで。
|
|
380
|
+
もし、(URI=「/get_plugins」)ならば
|
|
381
|
+
PARAMSのAPIプラグイン取得。
|
|
382
|
+
戻る。
|
|
383
|
+
ここまで。
|
|
384
|
+
もし、(URI=「/add_plugins」)ならば
|
|
385
|
+
PARAMSのAPIプラグイン追加。
|
|
386
|
+
戻る。
|
|
387
|
+
ここまで。
|
|
388
|
+
URIの静的ファイル返信。
|
|
389
|
+
ここまで。
|
|
390
|
+
|
|
391
|
+
# --- ここからメイン処理 ---
|
|
392
|
+
定数のサーバホスト=「NAKO3EDIT_HOST」と「localhost」の環境変数参照。
|
|
393
|
+
定数の自動起動=「NAKO3EDIT_OPEN」と「1」の環境変数参照。
|
|
394
|
+
|
|
395
|
+
サーバポートで簡易HTTPサーバ起動時には
|
|
396
|
+
サーバURL=「http://{サーバホスト}:{サーバポート}」
|
|
397
|
+
「### 超簡易Webサーバが起動しました」と表示。
|
|
398
|
+
「[URL] {サーバURL}」と表示。
|
|
399
|
+
もし、(自動起動≠「0」)ならば、サーバURLをブラウザ起動。
|
|
400
|
+
ここまで。
|
|
401
|
+
|
|
402
|
+
「/」で簡易HTTPサーバ受信した時には
|
|
403
|
+
リクエスト処理。
|
|
404
|
+
ここまで。
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ゴール
|
|
2
|
+
|
|
3
|
+
Node.js(JavaScript)で書かれたサーバー`index.mjs`を、完全に、なでしこ3のプログラムとして書き直すことを目標とします。
|
|
4
|
+
|
|
5
|
+
作成したプログラムは、`index.nako3`として、なでしこ3のプログラムとして実行できるようにします。
|
|
6
|
+
|
|
7
|
+
## コンテキスト
|
|
8
|
+
|
|
9
|
+
なでしこの文法は、`doc/syntax-nako3.md`にまとめられています。
|
|
10
|
+
|
|
11
|
+
## デバッグについて
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
# プログラム index.nako3を実行する
|
|
15
|
+
cnako3 index.nako3
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
プログラムの構造を理解するには、次のコマンドで、プログラムの構造(文法構造ツリー)を表示することができます。
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
# ASTを表示する
|
|
22
|
+
cnako3 --ast index.nako3
|
|
23
|
+
```
|