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
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DNCLに対応する構文
|
|
3
|
-
*/
|
|
4
|
-
// import { NakoIndentError } from './nako_errors.mjs'
|
|
5
|
-
import { NewEmptyToken } from './nako_types.mjs';
|
|
6
|
-
import { joinTokenLines, splitTokens } from './nako_indent_inline.mjs';
|
|
7
|
-
// DNCLモードのキーワード
|
|
8
|
-
const DNCL_KEYWORDS = ['!DNCLモード', '💡DNCLモード'];
|
|
9
|
-
// 単純な置換チェック
|
|
10
|
-
const DNCL_SIMPLES = {
|
|
11
|
-
'←:←': ['eq', '='],
|
|
12
|
-
'÷:÷': ['÷÷', '÷÷'],
|
|
13
|
-
'{:{': ['[', '['],
|
|
14
|
-
'}:}': [']', ']'],
|
|
15
|
-
'word:を実行': ['ここまで', 'ここまで'],
|
|
16
|
-
'word:乱数': ['word', '乱数範囲'],
|
|
17
|
-
'word:表示': ['word', '連続表示']
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* DNCLのソースコードをなでしこに変換する
|
|
21
|
-
*/
|
|
22
|
-
export function convertDNCL(tokens) {
|
|
23
|
-
if (!useDNCLmode(tokens)) {
|
|
24
|
-
return tokens;
|
|
25
|
-
}
|
|
26
|
-
// 一行ずつに分ける
|
|
27
|
-
const lines = splitTokens(tokens, 'eol');
|
|
28
|
-
for (let i = 0; i < lines.length; i++) {
|
|
29
|
-
const line = lines[i];
|
|
30
|
-
if (line.length <= 1) {
|
|
31
|
-
continue;
|
|
32
|
-
} // 空行は飛ばす
|
|
33
|
-
// 行頭の | はただのインデント
|
|
34
|
-
for (let j = 0; j < line.length; j++) {
|
|
35
|
-
if (line[j].type === '|') {
|
|
36
|
-
line[j].type = 'range_comment';
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
// 後判定の繰り返しの実装のため
|
|
42
|
-
const t = line[0];
|
|
43
|
-
if (t.type === 'word' && t.value === '繰返') {
|
|
44
|
-
line.splice(0, line.length, NewEmptyToken('word', '後判定', t.indent, t.line, t.file), NewEmptyToken('word', '繰返', t.indent, t.line, t.file));
|
|
45
|
-
}
|
|
46
|
-
// ^\s*を,?(.+)になるまで(繰り返す|実行する)/
|
|
47
|
-
const fi = findTokens(line, ['word:なる', 'word:繰返']);
|
|
48
|
-
if (fi > 0) {
|
|
49
|
-
replaceAtohantei(line, fi);
|
|
50
|
-
}
|
|
51
|
-
const fi2 = findTokens(line, ['word:なる', 'word:実行']);
|
|
52
|
-
if (fi2 > 0) {
|
|
53
|
-
replaceAtohantei(line, fi2);
|
|
54
|
-
}
|
|
55
|
-
// もし(条件)でないならば → もし(条件)でなければ
|
|
56
|
-
const nai = findTokens(line, ['word:ない']);
|
|
57
|
-
if (nai >= 1) {
|
|
58
|
-
const tt = line[nai];
|
|
59
|
-
if (tt.josi === 'ならば') {
|
|
60
|
-
line[nai - 1].josi = 'でなければ';
|
|
61
|
-
line.splice(nai, 1);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// 二進で表示 (255) → 二進表示(255)
|
|
65
|
-
for (;;) {
|
|
66
|
-
const ni = findTokens(line, ['word:二進', 'word:表示']);
|
|
67
|
-
if (ni < 0) {
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
line[ni].value = '二進表示';
|
|
71
|
-
line[ni].josi = '';
|
|
72
|
-
line.splice(ni + 1, 1);
|
|
73
|
-
}
|
|
74
|
-
// '改行なしで表示' → '連続無改行表示'
|
|
75
|
-
for (;;) {
|
|
76
|
-
const ni = findTokens(line, ['word:改行', 'word:表示']);
|
|
77
|
-
if (ni < 0) {
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
// ここ「改行なしで表示」でも「改行ありで表示」でも同じになってしまう
|
|
81
|
-
// なでしこの制限のため仕方なし
|
|
82
|
-
// 「改行ありで表示」は今のところDNCLに存在しないので無視する
|
|
83
|
-
// もし将来的に区別が必要なら、プリプロセス処理でマクロ的に置換処理を行うことで対応できると思う
|
|
84
|
-
const t = line[ni];
|
|
85
|
-
t.value = '連続無改行表示';
|
|
86
|
-
t.josi = '';
|
|
87
|
-
line.splice(ni + 1, 1);
|
|
88
|
-
}
|
|
89
|
-
// 'を実行し,そうでなければ': '違えば',
|
|
90
|
-
for (;;) {
|
|
91
|
-
const ni = findTokens(line, ['word:を実行', 'comma:,', 'word:そう']);
|
|
92
|
-
if (ni < 0) {
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
const sou = line[ni + 2];
|
|
96
|
-
if (sou.josi === 'でなければ') {
|
|
97
|
-
sou.type = '違えば';
|
|
98
|
-
sou.value = '違えば';
|
|
99
|
-
sou.josi = '';
|
|
100
|
-
line.splice(ni, 3, sou);
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
else if (sou.josi === 'で') {
|
|
104
|
-
const nakumosi = line[ni + 3];
|
|
105
|
-
if (nakumosi.value.substring(0, 4) === 'なくもし') {
|
|
106
|
-
sou.type = '違えば';
|
|
107
|
-
sou.value = '違えば';
|
|
108
|
-
sou.josi = '';
|
|
109
|
-
line.splice(ni, 3, sou);
|
|
110
|
-
if (nakumosi.value.length > 4) {
|
|
111
|
-
const nakumosiTudukiStr = nakumosi.value.substring(4);
|
|
112
|
-
const nakumosiToken = NewEmptyToken('word', nakumosiTudukiStr, nakumosi.indent, nakumosi.line, nakumosi.file);
|
|
113
|
-
if (nakumosiTudukiStr.match(/^\d/)) {
|
|
114
|
-
nakumosiToken.type = 'number';
|
|
115
|
-
}
|
|
116
|
-
line.splice(ni + 2, 0, nakumosiToken);
|
|
117
|
-
nakumosi.value = nakumosi.value.substring(0, 4);
|
|
118
|
-
}
|
|
119
|
-
nakumosi.type = 'もし';
|
|
120
|
-
nakumosi.value = 'もし';
|
|
121
|
-
nakumosi.josi = '';
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
// Iを1から100まで1(ずつ)|増やしな(が)|ら
|
|
128
|
-
for (;;) {
|
|
129
|
-
const ni = findTokens(line, ['word:増', 'word:ら']);
|
|
130
|
-
if (ni < 0) {
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
const fu = line[ni];
|
|
134
|
-
fu.type = 'word';
|
|
135
|
-
fu.value = '増繰返';
|
|
136
|
-
fu.josi = '';
|
|
137
|
-
line.splice(ni, 2, fu);
|
|
138
|
-
}
|
|
139
|
-
// Iを1から100まで1(ずつ)|増やしな(が)|ら
|
|
140
|
-
for (;;) {
|
|
141
|
-
const ni = findTokens(line, ['word:減', 'word:ら']);
|
|
142
|
-
if (ni < 0) {
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
const fu = line[ni];
|
|
146
|
-
fu.type = 'word';
|
|
147
|
-
fu.value = '減繰返';
|
|
148
|
-
fu.josi = '';
|
|
149
|
-
line.splice(ni, 2, fu);
|
|
150
|
-
}
|
|
151
|
-
// を繰り返す → ここまで
|
|
152
|
-
for (;;) {
|
|
153
|
-
const ni = findTokens(line, ['word:を繰り返']);
|
|
154
|
-
if (ni < 0) {
|
|
155
|
-
break;
|
|
156
|
-
}
|
|
157
|
-
const fu = line[ni];
|
|
158
|
-
fu.type = 'ここまで';
|
|
159
|
-
fu.value = 'ここまで';
|
|
160
|
-
fu.josi = '';
|
|
161
|
-
}
|
|
162
|
-
// 'のすべての要素を0にする'
|
|
163
|
-
// 'のすべての要素に0を代入する'
|
|
164
|
-
for (;;) {
|
|
165
|
-
const ni = findTokens(line, ['word:すべて', 'word:要素']);
|
|
166
|
-
if (ni >= 1) {
|
|
167
|
-
replaceAllElementV(line, ni);
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// 'のすべての値を0にする'
|
|
174
|
-
for (;;) {
|
|
175
|
-
const ni = findTokens(line, ['word:すべて', 'word:値']);
|
|
176
|
-
if (ni >= 1) {
|
|
177
|
-
replaceAllElementV(line, ni);
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
break;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
// 一つずつチェック
|
|
184
|
-
let j = 0;
|
|
185
|
-
while (j < line.length) {
|
|
186
|
-
const t = line[j];
|
|
187
|
-
// 減と増の分割
|
|
188
|
-
if (t.type === 'word' && t.value.length >= 2) {
|
|
189
|
-
const c = t.value.charAt(t.value.length - 1);
|
|
190
|
-
if (c === '減' || c === '増') {
|
|
191
|
-
t.value = t.value.substring(0, t.value.length - 1);
|
|
192
|
-
t.josi = 'だけ';
|
|
193
|
-
line.splice(j + 1, 0, NewEmptyToken('word', c, t.indent, t.line, t.file));
|
|
194
|
-
}
|
|
195
|
-
j++;
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
j++;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
// 最後に単純な置換を行う
|
|
202
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
203
|
-
const t = tokens[i];
|
|
204
|
-
const a = DNCL_SIMPLES[String(t.type) + ':' + String(t.value)];
|
|
205
|
-
if (a !== undefined) {
|
|
206
|
-
t.type = a[0];
|
|
207
|
-
t.value = a[1];
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
tokens = joinTokenLines(lines);
|
|
211
|
-
return tokens;
|
|
212
|
-
}
|
|
213
|
-
function replaceAllElementV(line, ni) {
|
|
214
|
-
//
|
|
215
|
-
// const ni = findTokens(line, ['word:すべて', 'word:要素'])
|
|
216
|
-
//
|
|
217
|
-
const t = line[ni];
|
|
218
|
-
line[ni - 1].josi = '';
|
|
219
|
-
const eq = NewEmptyToken('eq', '=', t.indent, t.line, t.file);
|
|
220
|
-
const begin = NewEmptyToken('[', '[', t.indent, t.line, t.file);
|
|
221
|
-
const end = NewEmptyToken(']', ']', t.indent, t.line, t.file);
|
|
222
|
-
end.josi = 'に';
|
|
223
|
-
const val = line[ni + 2];
|
|
224
|
-
val.josi = '';
|
|
225
|
-
const times = NewEmptyToken('number', 100, t.indent, t.line, t.file);
|
|
226
|
-
times.josi = 'を';
|
|
227
|
-
const mul = NewEmptyToken('word', '掛', t.indent, t.line, t.file);
|
|
228
|
-
line.splice(ni, 4, eq, begin, val, end, times, mul);
|
|
229
|
-
}
|
|
230
|
-
function replaceAtohantei(tokens, fi) {
|
|
231
|
-
// `ここまで、(${r[1]})になるまでの間`
|
|
232
|
-
const wo = findTokens(tokens, ['word:を']);
|
|
233
|
-
if (wo >= 0) {
|
|
234
|
-
tokens[wo].type = 'ここまで';
|
|
235
|
-
tokens[wo].value = 'ここまで';
|
|
236
|
-
}
|
|
237
|
-
const ga = findTokens(tokens, ['word:が']);
|
|
238
|
-
if (ga >= 0) {
|
|
239
|
-
tokens[ga].type = 'ここまで';
|
|
240
|
-
tokens[ga].value = 'ここまで';
|
|
241
|
-
}
|
|
242
|
-
// なる:まで(fi) 実行(fi+1)
|
|
243
|
-
tokens[fi + 1].value = '間';
|
|
244
|
-
}
|
|
245
|
-
function findTokens(tokens, findTypeValue) {
|
|
246
|
-
const findA = findTypeValue.map(s => s.split(':'));
|
|
247
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
248
|
-
let flag = true;
|
|
249
|
-
for (let j = 0; j < findA.length; j++) {
|
|
250
|
-
const f = findA[j];
|
|
251
|
-
const idx = i + j;
|
|
252
|
-
if (idx >= tokens.length) {
|
|
253
|
-
return -1;
|
|
254
|
-
}
|
|
255
|
-
if (tokens[idx].type === f[0] && tokens[idx].value === f[1]) {
|
|
256
|
-
continue;
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
flag = false;
|
|
260
|
-
break;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
if (flag) {
|
|
264
|
-
return i;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
return -1;
|
|
268
|
-
}
|
|
269
|
-
function useDNCLmode(tokens) {
|
|
270
|
-
// 先頭の100語調べる
|
|
271
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
272
|
-
if (i > 100) {
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
|
-
const t = tokens[i];
|
|
276
|
-
if (t.type === 'line_comment' && DNCL_KEYWORDS.indexOf(t.value) >= 0) {
|
|
277
|
-
t.type = 'DNCLモード';
|
|
278
|
-
return true;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
export const NakoDncl = {
|
|
284
|
-
convert: convertDNCL
|
|
285
|
-
};
|
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DNCL ver2 に対応する構文
|
|
3
|
-
*/
|
|
4
|
-
// import { NakoIndentError } from './nako_errors.mjs'
|
|
5
|
-
import { NewEmptyToken } from './nako_types.mjs';
|
|
6
|
-
import { joinTokenLines, splitTokens } from './nako_indent_inline.mjs';
|
|
7
|
-
import { newToken, debugTokens } from './nako_tools.mjs';
|
|
8
|
-
const IS_DEBUG = false;
|
|
9
|
-
const DNCL_ARRAY_INIT_COUNT = 30;
|
|
10
|
-
// DNCL2モードのキーワード
|
|
11
|
-
const DNCL2_KEYWORDS = ['!DNCL2モード', '💡DNCL2モード', '!DNCL2', '💡DNCL2'];
|
|
12
|
-
// 単純な置換チェック
|
|
13
|
-
const DNCL_SIMPLES = {
|
|
14
|
-
'←:←': ['eq', '='],
|
|
15
|
-
'÷:÷': ['÷÷', '÷÷'],
|
|
16
|
-
'{:{': ['[', '['],
|
|
17
|
-
'}:}': [']', ']'],
|
|
18
|
-
// 'word:and': ['and', 'かつ'],
|
|
19
|
-
// 'word:or': ['or', 'または'],
|
|
20
|
-
'word:not': ['not', '!'],
|
|
21
|
-
'word:乱数': ['word', '乱数範囲'],
|
|
22
|
-
'word:表示': ['word', '連続表示'],
|
|
23
|
-
'word:と定義': ['ここまで', 'ここまで'] // 「と定義」→「ここまで」
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* DNCLのソースコードをなでしこに変換する
|
|
27
|
-
*/
|
|
28
|
-
export function convertDNCL2(tokens) {
|
|
29
|
-
if (!useDNCL2mode(tokens)) {
|
|
30
|
-
return tokens;
|
|
31
|
-
}
|
|
32
|
-
// 一行ずつに分ける
|
|
33
|
-
const lines = splitTokens(tokens, 'eol');
|
|
34
|
-
for (let i = 0; i < lines.length; i++) {
|
|
35
|
-
const line = lines[i];
|
|
36
|
-
if (line.length <= 1) {
|
|
37
|
-
continue;
|
|
38
|
-
} // 空行は飛ばす
|
|
39
|
-
// --- 制御構文の変換 ---
|
|
40
|
-
// もし(条件)でないならば → もし(条件)でなければ
|
|
41
|
-
const nai = findTokens(line, ['word:ない']);
|
|
42
|
-
if (nai >= 1) {
|
|
43
|
-
const tt = line[nai];
|
|
44
|
-
if (tt.josi === 'ならば') {
|
|
45
|
-
line[nai - 1].josi = 'でなければ';
|
|
46
|
-
line.splice(nai, 1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// そうでなければ(そう|でなければ) or そうでなく → 違えば
|
|
50
|
-
for (let ni = 0; ni < line.length; ni++) {
|
|
51
|
-
const t = line[ni];
|
|
52
|
-
if ((t.value === 'そう' || t.value === 'それ') && (t.josi === 'でなければ' || t.josi === 'でなく')) {
|
|
53
|
-
t.type = '違えば';
|
|
54
|
-
t.value = '違えば';
|
|
55
|
-
t.josi = '';
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// 'を実行し,そうでなければ': '違えば',
|
|
59
|
-
for (;;) {
|
|
60
|
-
const ni = findTokens(line, ['word:を実行', 'comma:,', 'word:そう']);
|
|
61
|
-
if (ni < 0) {
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
const sou = line[ni + 2];
|
|
65
|
-
if (sou.josi === 'でなければ') {
|
|
66
|
-
sou.type = '違えば';
|
|
67
|
-
sou.value = '違えば';
|
|
68
|
-
sou.josi = '';
|
|
69
|
-
line.splice(ni, 3, sou);
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
else if (sou.josi === 'で') {
|
|
73
|
-
const nakumosi = line[ni + 3];
|
|
74
|
-
if (nakumosi.value.substring(0, 4) === 'なくもし') {
|
|
75
|
-
sou.type = '違えば';
|
|
76
|
-
sou.value = '違えば';
|
|
77
|
-
sou.josi = '';
|
|
78
|
-
line.splice(ni, 3, sou);
|
|
79
|
-
if (nakumosi.value.length > 4) {
|
|
80
|
-
const nakumosiTudukiStr = nakumosi.value.substring(4);
|
|
81
|
-
const nakumosiToken = NewEmptyToken('word', nakumosiTudukiStr, nakumosi.indent, nakumosi.line, nakumosi.file);
|
|
82
|
-
if (nakumosiTudukiStr.match(/^\d/)) {
|
|
83
|
-
nakumosiToken.type = 'number';
|
|
84
|
-
}
|
|
85
|
-
line.splice(ni + 2, 0, nakumosiToken);
|
|
86
|
-
nakumosi.value = nakumosi.value.substring(0, 4);
|
|
87
|
-
}
|
|
88
|
-
nakumosi.type = 'もし';
|
|
89
|
-
nakumosi.value = 'もし';
|
|
90
|
-
nakumosi.josi = '';
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
// 'そうでなく': '違えば',
|
|
97
|
-
for (;;) {
|
|
98
|
-
const ni = findTokens(line, ['word:そう', 'word:なく']);
|
|
99
|
-
if (ni < 0) {
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
const sou = line[ni];
|
|
103
|
-
if (sou.josi === 'で') {
|
|
104
|
-
sou.type = '違えば';
|
|
105
|
-
sou.value = '違えば';
|
|
106
|
-
sou.josi = '';
|
|
107
|
-
line.splice(ni + 1, 1);
|
|
108
|
-
// console.log('@@@', line.map(v => v.value).join('|'))
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
// 'そうでなくもし': '違えば,もし'
|
|
114
|
-
for (;;) {
|
|
115
|
-
const ni = findTokens(line, ['word:そう', 'word:なくもし']);
|
|
116
|
-
if (ni < 0) {
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
const sou = line[ni];
|
|
120
|
-
const nakumosi = line[ni + 1];
|
|
121
|
-
sou.type = '違えば';
|
|
122
|
-
sou.value = '違えば';
|
|
123
|
-
sou.josi = '';
|
|
124
|
-
nakumosi.type = 'もし';
|
|
125
|
-
nakumosi.value = 'もし';
|
|
126
|
-
nakumosi.josi = '';
|
|
127
|
-
}
|
|
128
|
-
// Iを1から100まで1(ずつ)|増やしな(が)|ら
|
|
129
|
-
for (;;) {
|
|
130
|
-
const ni = findTokens(line, ['word:増', 'word:ら']);
|
|
131
|
-
if (ni < 0) {
|
|
132
|
-
break;
|
|
133
|
-
}
|
|
134
|
-
const fu = line[ni];
|
|
135
|
-
fu.type = 'word';
|
|
136
|
-
fu.value = '増繰返';
|
|
137
|
-
fu.josi = '';
|
|
138
|
-
line.splice(ni, 2, fu);
|
|
139
|
-
}
|
|
140
|
-
// Iを1から100まで1(ずつ)|増やしな(が)|ら
|
|
141
|
-
for (;;) {
|
|
142
|
-
const ni = findTokens(line, ['word:減', 'word:ら']);
|
|
143
|
-
if (ni < 0) {
|
|
144
|
-
break;
|
|
145
|
-
}
|
|
146
|
-
const fu = line[ni];
|
|
147
|
-
fu.type = 'word';
|
|
148
|
-
fu.value = '減繰返';
|
|
149
|
-
fu.josi = '';
|
|
150
|
-
line.splice(ni, 2, fu);
|
|
151
|
-
}
|
|
152
|
-
// Iを1から100まで1(ずつ)|増やしな(が)|ら繰り返(す)
|
|
153
|
-
for (;;) {
|
|
154
|
-
const ni = findTokens(line, ['word:増', 'word:ら繰り返']);
|
|
155
|
-
if (ni < 0) {
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
const fu = line[ni];
|
|
159
|
-
fu.type = 'word';
|
|
160
|
-
fu.value = '増繰返';
|
|
161
|
-
fu.josi = '';
|
|
162
|
-
line.splice(ni, 2, fu);
|
|
163
|
-
}
|
|
164
|
-
// Iを1から100まで1(ずつ)|増やしな(が)|ら繰り返す
|
|
165
|
-
for (;;) {
|
|
166
|
-
const ni = findTokens(line, ['word:減', 'word:ら繰り返']);
|
|
167
|
-
if (ni < 0) {
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
const fu = line[ni];
|
|
171
|
-
fu.type = 'word';
|
|
172
|
-
fu.value = '減繰返';
|
|
173
|
-
fu.josi = '';
|
|
174
|
-
line.splice(ni, 2, fu);
|
|
175
|
-
}
|
|
176
|
-
// --- 配列変数周りの変換 ---
|
|
177
|
-
for (let i = 0; i < line.length; i++) {
|
|
178
|
-
// 配列|Hindoの|すべての|(要素に|値に)|10を|代入する
|
|
179
|
-
if (tokenEq([['word:配列', 'word:配列変数'], 'word', 'word:すべて', ['word:要素', 'word:値'], '*', 'word:代入'], line, i)) {
|
|
180
|
-
const varToken = line[i + 1];
|
|
181
|
-
varToken.josi = '';
|
|
182
|
-
const valToken = line[i + 4];
|
|
183
|
-
valToken.josi = '';
|
|
184
|
-
line.splice(i, 6, varToken, newToken('eq', '=', varToken), newToken('word', '掛'), newToken('(', '('), newToken('[', '['), valToken, newToken(']', ']'), newToken('comma', ','), newToken('number', DNCL_ARRAY_INIT_COUNT), newToken(')', ')'));
|
|
185
|
-
i += 6; // skip
|
|
186
|
-
}
|
|
187
|
-
// Hensuの|すべての|(要素を|値を)|0に|する
|
|
188
|
-
if (tokenEq(['word', 'word:すべて', ['word:要素', 'word:値'], ['number', 'string', 'word'], 'word:する'], line, i)) {
|
|
189
|
-
const varToken = line[i];
|
|
190
|
-
varToken.josi = '';
|
|
191
|
-
const valToken = line[i + 3];
|
|
192
|
-
valToken.josi = '';
|
|
193
|
-
line.splice(i, 5, varToken, newToken('eq', '=', varToken), newToken('word', '掛'), newToken('(', '('), newToken('[', '['), valToken, newToken(']', ']'), newToken('comma', ','), newToken('number', DNCL_ARRAY_INIT_COUNT), newToken(')', ')'));
|
|
194
|
-
}
|
|
195
|
-
// 配列変数 | xxを | 初期化する
|
|
196
|
-
if (tokenEq([['word:配列変数', 'word:配列'], 'word', 'word:初期化'], line, i)) {
|
|
197
|
-
const varToken = line[i + 1];
|
|
198
|
-
varToken.josi = '';
|
|
199
|
-
line.splice(i, 3, varToken, newToken('eq', '=', varToken), newToken('word', '掛'), newToken('(', '('), newToken('[', '['), newToken('number', 0), newToken(']', ']'), newToken('comma', ','), newToken('number', DNCL_ARRAY_INIT_COUNT), newToken(')', ')'));
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// --- その他の変換 ---
|
|
203
|
-
// 二進で表示 (255) → 二進表示(255)
|
|
204
|
-
for (;;) {
|
|
205
|
-
const ni = findTokens(line, ['word:二進', 'word:表示']);
|
|
206
|
-
if (ni < 0) {
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
line[ni].value = '二進表示';
|
|
210
|
-
line[ni].josi = '';
|
|
211
|
-
line.splice(ni + 1, 1);
|
|
212
|
-
}
|
|
213
|
-
// '改行なしで表示' → '連続無改行表示'
|
|
214
|
-
for (;;) {
|
|
215
|
-
const ni = findTokens(line, ['word:改行', 'word:表示']);
|
|
216
|
-
if (ni < 0) {
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
// ここ「改行なしで表示」でも「改行ありで表示」でも同じになってしまう
|
|
220
|
-
// なでしこの制限のため仕方なし
|
|
221
|
-
// 「改行ありで表示」は今のところDNCLに存在しないので無視する
|
|
222
|
-
// もし将来的に区別が必要なら、プリプロセス処理でマクロ的に置換処理を行うことで対応できると思う
|
|
223
|
-
const t = line[ni];
|
|
224
|
-
t.value = '連続無改行表示';
|
|
225
|
-
t.josi = '';
|
|
226
|
-
line.splice(ni + 1, 1);
|
|
227
|
-
}
|
|
228
|
-
// 一つずつチェック
|
|
229
|
-
let j = 0;
|
|
230
|
-
while (j < line.length) {
|
|
231
|
-
const t = line[j];
|
|
232
|
-
// 減と増の分割
|
|
233
|
-
if (t.type === 'word' && t.value.length >= 2) {
|
|
234
|
-
const c = t.value.charAt(t.value.length - 1);
|
|
235
|
-
if (c === '減' || c === '増') {
|
|
236
|
-
t.value = t.value.substring(0, t.value.length - 1);
|
|
237
|
-
t.josi = 'だけ';
|
|
238
|
-
line.splice(j + 1, 0, NewEmptyToken('word', c, t.indent, t.line, t.file));
|
|
239
|
-
}
|
|
240
|
-
j++;
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
j++;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
// 最後に単純な置換を行う
|
|
247
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
248
|
-
const t = tokens[i];
|
|
249
|
-
const a = DNCL_SIMPLES[String(t.type) + ':' + String(t.value)];
|
|
250
|
-
if (a !== undefined) {
|
|
251
|
-
t.type = a[0];
|
|
252
|
-
t.value = a[1];
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
tokens = joinTokenLines(lines);
|
|
256
|
-
if (IS_DEBUG) {
|
|
257
|
-
console.log('// DEBUG---DNCL:tokens---BEGIN');
|
|
258
|
-
console.log(debugTokens(tokens));
|
|
259
|
-
console.log('// DEBUG---DNCL:tokens---END');
|
|
260
|
-
}
|
|
261
|
-
return tokens;
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* トークンが合致するかを確認する
|
|
265
|
-
* @param typeValues ['word:それ']のようなタイプ名と値の配列/'*'でワイルドカードが使える/":"がなればタイプだけ確認/配列で選択
|
|
266
|
-
* @param lines 差し替え
|
|
267
|
-
* @param fromIndex 検索場所
|
|
268
|
-
* @returns 合致したかどうか
|
|
269
|
-
*/
|
|
270
|
-
function tokenEq(typeValues, lines, fromIndex) {
|
|
271
|
-
const check = (pattern, t) => {
|
|
272
|
-
if (pattern instanceof Array) {
|
|
273
|
-
for (let i = 0; i < pattern.length; i++) {
|
|
274
|
-
if (check(pattern[i], t)) {
|
|
275
|
-
return true;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
if (pattern === '*') {
|
|
281
|
-
return true;
|
|
282
|
-
}
|
|
283
|
-
if (pattern.indexOf(':') < 0) {
|
|
284
|
-
if (pattern === t.type) {
|
|
285
|
-
return true;
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
return false;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
const tv = `${t.type}:${t.value}`;
|
|
292
|
-
if (pattern === tv) {
|
|
293
|
-
return true;
|
|
294
|
-
}
|
|
295
|
-
return false;
|
|
296
|
-
};
|
|
297
|
-
for (let i = 0; i < typeValues.length; i++) {
|
|
298
|
-
const idx = i + fromIndex;
|
|
299
|
-
if (idx >= lines.length) {
|
|
300
|
-
return false;
|
|
301
|
-
}
|
|
302
|
-
const pat = typeValues[i];
|
|
303
|
-
const t = lines[idx];
|
|
304
|
-
if (!check(pat, t)) {
|
|
305
|
-
return false;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return true;
|
|
309
|
-
}
|
|
310
|
-
function findTokens(tokens, findTypeValue) {
|
|
311
|
-
const findA = findTypeValue.map(s => s.split(':'));
|
|
312
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
313
|
-
let flag = true;
|
|
314
|
-
for (let j = 0; j < findA.length; j++) {
|
|
315
|
-
const f = findA[j];
|
|
316
|
-
const idx = i + j;
|
|
317
|
-
if (idx >= tokens.length) {
|
|
318
|
-
return -1;
|
|
319
|
-
}
|
|
320
|
-
if (tokens[idx].type === f[0] && tokens[idx].value === f[1]) {
|
|
321
|
-
continue;
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
flag = false;
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
if (flag) {
|
|
329
|
-
return i;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return -1;
|
|
333
|
-
}
|
|
334
|
-
function useDNCL2mode(tokens) {
|
|
335
|
-
// 先頭の100語調べる
|
|
336
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
337
|
-
if (i > 100) {
|
|
338
|
-
break;
|
|
339
|
-
}
|
|
340
|
-
const t = tokens[i];
|
|
341
|
-
if (t.type === 'line_comment' && DNCL2_KEYWORDS.indexOf(t.value) >= 0) {
|
|
342
|
-
t.type = 'DNCL2モード';
|
|
343
|
-
return true;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
return false;
|
|
347
|
-
}
|