nadesiko3 3.2.36 → 3.2.37
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/package.json +1 -1
- package/release/_hash.txt +24 -24
- package/release/_script-tags.txt +13 -13
- 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/editor.js +1 -1
- package/release/nako_gen_async.js +1 -1
- package/release/stats.json +1 -1
- package/release/version.js +1 -1
- package/release/wnako3.js +1 -1
- package/release/wnako3webworker.js +1 -1
- package/release/yoyakugo.json +2 -0
- package/src/nako_from_dncl.js +50 -74
- package/src/nako_gen.js +21 -0
- package/src/nako_parser3.js +96 -44
- package/src/nako_reserved_words.js +2 -0
- package/src/nako_version.js +2 -2
- package/src/plugin_system.js +24 -0
- package/test/common/basic_test.js +11 -0
- package/test/common/dncl_test.js +2 -0
package/release/yoyakugo.json
CHANGED
package/src/nako_from_dncl.js
CHANGED
|
@@ -77,20 +77,65 @@ function dncl2nako(src, filename) {
|
|
|
77
77
|
'を実行し,そうでなければ': '違えば',
|
|
78
78
|
'を実行し、そうでなければ': '違えば',
|
|
79
79
|
'を繰り返す': 'ここまで',
|
|
80
|
-
'改行なしで表示': '
|
|
80
|
+
'改行なしで表示': '連続無改行表示',
|
|
81
81
|
'のすべての値を0にする': '=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]',
|
|
82
82
|
'ずつ増やしながら':'ずつ増やし繰り返す',
|
|
83
83
|
'ずつ減らしながら':'ずつ減らし繰り返す',
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
let peekChar = () => src.charAt(0)
|
|
86
|
+
let nextChar = () => {
|
|
87
|
+
let ch = src.charAt(0)
|
|
88
|
+
src = src.substring(1)
|
|
89
|
+
return ch
|
|
90
|
+
}
|
|
91
|
+
// 文字列を判定するフラグ
|
|
92
|
+
let flagStr = false
|
|
93
|
+
let poolStr = ''
|
|
94
|
+
let endStr = ''
|
|
95
|
+
// 結果
|
|
86
96
|
let result = ''
|
|
87
97
|
while (src !='') {
|
|
88
98
|
// 代入記号を変更
|
|
89
99
|
const ch = src.charAt(0)
|
|
100
|
+
if (flagStr) {
|
|
101
|
+
if (ch === endStr) {
|
|
102
|
+
result += poolStr + endStr
|
|
103
|
+
poolStr = ''
|
|
104
|
+
flagStr = false
|
|
105
|
+
nextChar()
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
poolStr += nextChar()
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
// 文字列?
|
|
112
|
+
if (ch == '"') {
|
|
113
|
+
flagStr = true
|
|
114
|
+
endStr = '"'
|
|
115
|
+
poolStr = nextChar()
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
if (ch == '「') {
|
|
119
|
+
flagStr = true
|
|
120
|
+
endStr = '」'
|
|
121
|
+
poolStr = nextChar()
|
|
122
|
+
continue
|
|
123
|
+
}
|
|
124
|
+
if (ch == '『') {
|
|
125
|
+
flagStr = true
|
|
126
|
+
endStr = '』'
|
|
127
|
+
poolStr = nextChar()
|
|
128
|
+
continue
|
|
129
|
+
}
|
|
90
130
|
// 空白を飛ばす
|
|
91
131
|
if (ch === ' ' || ch === ' ' || ch == '\t') {
|
|
92
|
-
result +=
|
|
93
|
-
|
|
132
|
+
result += nextChar()
|
|
133
|
+
continue
|
|
134
|
+
}
|
|
135
|
+
// 表示を連続表示に置き換える
|
|
136
|
+
if (src.substring(0, 3) === 'を表示') {
|
|
137
|
+
result += 'を連続表示'
|
|
138
|
+
src = src.substring(3)
|
|
94
139
|
continue
|
|
95
140
|
}
|
|
96
141
|
// 1行先読み
|
|
@@ -101,74 +146,6 @@ function dncl2nako(src, filename) {
|
|
|
101
146
|
} else {
|
|
102
147
|
line = src
|
|
103
148
|
}
|
|
104
|
-
//「var を n 増やす」を「var = var + 1」と置き換える
|
|
105
|
-
const r = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*を\s*([0-9a-zA-Z_]+)\s*(増やす|減らす)/)
|
|
106
|
-
if (r) {
|
|
107
|
-
const var_name = r[1]
|
|
108
|
-
const inc_val = r[2]
|
|
109
|
-
const inc_dec = r[3]
|
|
110
|
-
if (inc_dec == '増やす') {
|
|
111
|
-
result += `${var_name} = ${var_name} + ${inc_val};`
|
|
112
|
-
} else {
|
|
113
|
-
result += `${var_name} = ${var_name} - ${inc_val};`
|
|
114
|
-
}
|
|
115
|
-
src = src.substring(r[0].length)
|
|
116
|
-
continue
|
|
117
|
-
}
|
|
118
|
-
//「S1とS2とS3を表示する」を「(S1)&(S2)&S3)を表示」と置き換える
|
|
119
|
-
// あまりスマートではないが手抜きで
|
|
120
|
-
if (line.indexOf('表示') >= 0) {
|
|
121
|
-
const r6 = line.match(/^(.+?)と(.+?)と(.+?)と(.+?)と(.+?)と(.+?)(を|と)表示/)
|
|
122
|
-
if (r6) {
|
|
123
|
-
const s1 = r6[1]
|
|
124
|
-
const s2 = r6[2]
|
|
125
|
-
const s3 = r6[3]
|
|
126
|
-
const s4 = r6[4]
|
|
127
|
-
const s5 = r6[5]
|
|
128
|
-
const s6 = r6[6]
|
|
129
|
-
result += `(${s1})&(${s2})&(${s3})&(${s4})&(${s5})&(${s6})を表示`
|
|
130
|
-
src = src.substring(r6[0].length)
|
|
131
|
-
continue
|
|
132
|
-
}
|
|
133
|
-
const r5 = line.match(/^(.+?)と(.+?)と(.+?)と(.+?)と(.+?)(を|と)表示/)
|
|
134
|
-
if (r5) {
|
|
135
|
-
const s1 = r5[1]
|
|
136
|
-
const s2 = r5[2]
|
|
137
|
-
const s3 = r5[3]
|
|
138
|
-
const s4 = r5[4]
|
|
139
|
-
const s5 = r5[5]
|
|
140
|
-
result += `(${s1})&(${s2})&(${s3})&(${s4})&(${s5})を表示`
|
|
141
|
-
src = src.substring(r5[0].length)
|
|
142
|
-
continue
|
|
143
|
-
}
|
|
144
|
-
const r4 = line.match(/^(.+?)と(.+?)と(.+?)と(.+?)(を|と)表示/)
|
|
145
|
-
if (r4) {
|
|
146
|
-
const s1 = r4[1]
|
|
147
|
-
const s2 = r4[2]
|
|
148
|
-
const s3 = r4[3]
|
|
149
|
-
const s4 = r4[4]
|
|
150
|
-
result += `(${s1})&(${s2})&(${s3})&(${s4})を表示`
|
|
151
|
-
src = src.substring(r4[0].length)
|
|
152
|
-
continue
|
|
153
|
-
}
|
|
154
|
-
const r3 = line.match(/^(.+?)と(.+?)と(.+?)(を|と)表示/)
|
|
155
|
-
if (r3) {
|
|
156
|
-
const s1 = r3[1]
|
|
157
|
-
const s2 = r3[2]
|
|
158
|
-
const s3 = r3[3]
|
|
159
|
-
result += `(${s1})&(${s2})&(${s3})を表示`
|
|
160
|
-
src = src.substring(r3[0].length)
|
|
161
|
-
continue
|
|
162
|
-
}
|
|
163
|
-
const r2 = line.match(/^(.+?)と(.+?)を表示/)
|
|
164
|
-
if (r2) {
|
|
165
|
-
const s1 = r2[1]
|
|
166
|
-
const s2 = r2[2]
|
|
167
|
-
result += `(${s1})&(${s2})を表示`
|
|
168
|
-
src = src.substring(r2[0].length)
|
|
169
|
-
continue
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
149
|
// 『もしj>hakosuならばhakosu←jを実行する』のような単文のもし文
|
|
173
150
|
const rif = line.match(/^もし(.+)を実行する(。|.)*/)
|
|
174
151
|
if (rif) {
|
|
@@ -193,8 +170,7 @@ function dncl2nako(src, filename) {
|
|
|
193
170
|
}
|
|
194
171
|
|
|
195
172
|
// 1文字削る
|
|
196
|
-
|
|
197
|
-
result += ch
|
|
173
|
+
result += nextChar()
|
|
198
174
|
}
|
|
199
175
|
return result
|
|
200
176
|
}
|
package/src/nako_gen.js
CHANGED
|
@@ -476,6 +476,9 @@ try {
|
|
|
476
476
|
case 'let':
|
|
477
477
|
code += this.convLet(node)
|
|
478
478
|
break
|
|
479
|
+
case 'inc':
|
|
480
|
+
code += this.convInc(node)
|
|
481
|
+
break
|
|
479
482
|
case 'word':
|
|
480
483
|
case 'variable':
|
|
481
484
|
code += this.convGetVar(node)
|
|
@@ -1376,6 +1379,24 @@ try {
|
|
|
1376
1379
|
return `(${left} ${op} ${right})`
|
|
1377
1380
|
}
|
|
1378
1381
|
|
|
1382
|
+
convInc (node) {
|
|
1383
|
+
// もし値が省略されていたら、変数「それ」に代入する
|
|
1384
|
+
let value = null
|
|
1385
|
+
if (this.speedMode.invalidSore === 0) { value = this.varname('それ') }
|
|
1386
|
+
if (node.value) { value = this._convGen(node.value, true) }
|
|
1387
|
+
if (value == null) {
|
|
1388
|
+
throw NakoSyntaxError.fromNode('加算する先の変数名がありません。', node)
|
|
1389
|
+
}
|
|
1390
|
+
// 変数名
|
|
1391
|
+
const name = node.name.value
|
|
1392
|
+
const res = this.findVar(name)
|
|
1393
|
+
let code = ''
|
|
1394
|
+
if (res === null) { this.varsSet.names.add(name) }
|
|
1395
|
+
code += `if (typeof(${this.varname(name)}) === 'undefined') { ${this.varname(name)} = 0; }`
|
|
1396
|
+
code += `${this.varname(name)} += ${value}`
|
|
1397
|
+
return ';' + this.convLineno(node, false) + code + '\n'
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1379
1400
|
convLet (node) {
|
|
1380
1401
|
// もし値が省略されていたら、変数「それ」に代入する
|
|
1381
1402
|
let value = null
|
package/src/nako_parser3.js
CHANGED
|
@@ -96,6 +96,7 @@ class NakoParser extends NakoParserBase {
|
|
|
96
96
|
/** @returns {Ast | null} */
|
|
97
97
|
ySentence () {
|
|
98
98
|
const map = this.peekSourceMap()
|
|
99
|
+
|
|
99
100
|
// 最初の語句が決まっている構文
|
|
100
101
|
if (this.check('eol')) { return this.yEOL() }
|
|
101
102
|
if (this.check('もし')) { return this.yIF() }
|
|
@@ -103,18 +104,11 @@ class NakoParser extends NakoParserBase {
|
|
|
103
104
|
if (this.check('逐次実行')) { return this.yTikuji() }
|
|
104
105
|
if (this.accept(['抜ける'])) { return { type: 'break', josi: '', ...map, end: this.peekSourceMap() } }
|
|
105
106
|
if (this.accept(['続ける'])) { return { type: 'continue', josi: '', ...map, end: this.peekSourceMap() } }
|
|
106
|
-
if (this.accept(['require', 'string', '取込'])) {
|
|
107
|
-
return {
|
|
108
|
-
type: 'require',
|
|
109
|
-
value: this.y[1].value,
|
|
110
|
-
josi: '',
|
|
111
|
-
...map,
|
|
112
|
-
end: this.peekSourceMap()
|
|
113
|
-
}
|
|
114
|
-
}
|
|
107
|
+
if (this.accept(['require', 'string', '取込'])) { return { type: 'require', value: this.y[1].value, josi: '', ...map, end: this.peekSourceMap() } }
|
|
115
108
|
if (this.accept(['not', '非同期モード'])) { return this.yASyncMode() }
|
|
116
109
|
if (this.accept(['not', 'DNCLモード'])) { return this.yDNCLMode() }
|
|
117
110
|
if (this.accept(['not', 'string', 'モード設定'])) { return this.ySetGenMode(this.y[1].value) }
|
|
111
|
+
|
|
118
112
|
// 関数呼び出し演算子
|
|
119
113
|
if (this.check2(['func', '←'])) { return this.yCallOp() }
|
|
120
114
|
if (this.check2(['func', 'eq'])) {
|
|
@@ -128,7 +122,9 @@ class NakoParser extends NakoParserBase {
|
|
|
128
122
|
if (this.accept([this.yLet])) { return this.y[0] }
|
|
129
123
|
if (this.accept([this.yDefTest])) { return this.y[0] }
|
|
130
124
|
if (this.accept([this.yDefFunc])) { return this.y[0] }
|
|
131
|
-
|
|
125
|
+
|
|
126
|
+
// 関数呼び出しの他、各種構文の実装
|
|
127
|
+
if (this.accept([this.yCall])) {
|
|
132
128
|
const c1 = this.y[0]
|
|
133
129
|
if (c1.josi === 'して') { // 連文をblockとして接続する(もし構文、逐次実行構文などのため)
|
|
134
130
|
const c2 = this.ySentence()
|
|
@@ -944,52 +940,107 @@ class NakoParser extends NakoParserBase {
|
|
|
944
940
|
}
|
|
945
941
|
}
|
|
946
942
|
|
|
943
|
+
/** @returns {import('./nako3').Ast | null | undefined} */
|
|
944
|
+
yDainyu () {
|
|
945
|
+
const map = this.peekSourceMap()
|
|
946
|
+
const dainyu = this.get() // 代入
|
|
947
|
+
if (dainyu === null) { return null }
|
|
948
|
+
const value = this.popStack(['を'])
|
|
949
|
+
const word = this.popStack(['へ', 'に'])
|
|
950
|
+
if (!word || (word.type !== 'word' && word.type !== 'func' && word.type !== '配列参照')) {
|
|
951
|
+
throw NakoSyntaxError.fromNode('代入文で代入先の変数が見当たりません。『(変数名)に(値)を代入』のように使います。', dainyu)
|
|
952
|
+
}
|
|
953
|
+
// 配列への代入
|
|
954
|
+
if (word.type === '配列参照') {
|
|
955
|
+
return {
|
|
956
|
+
type: 'let_array',
|
|
957
|
+
name: word.name,
|
|
958
|
+
index: word.index,
|
|
959
|
+
value: value,
|
|
960
|
+
josi: '',
|
|
961
|
+
checkInit: this.flagCheckArrayInit,
|
|
962
|
+
...map, end: this.peekSourceMap()
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
// 一般的な変数への代入
|
|
966
|
+
return {
|
|
967
|
+
type: 'let', name: word,
|
|
968
|
+
value: value, josi: '',
|
|
969
|
+
...map, end: this.peekSourceMap()
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/** @returns {import('./nako3').Ast | null | undefined} */
|
|
974
|
+
ySadameru () {
|
|
975
|
+
const map = this.peekSourceMap()
|
|
976
|
+
const sadameru = this.get() // 定める
|
|
977
|
+
if (sadameru === null) { return null }
|
|
978
|
+
const word = this.popStack(['を'])
|
|
979
|
+
const value = this.popStack(['へ', 'に'])
|
|
980
|
+
console.log(word)
|
|
981
|
+
if (!word || (word.type !== 'word' && word.type !== 'func' && word.type !== '配列参照')) {
|
|
982
|
+
throw NakoSyntaxError.fromNode('『定める』文で定数が見当たりません。『(定数名)を(値)に定める』のように使います。', sadameru)
|
|
983
|
+
}
|
|
984
|
+
return {
|
|
985
|
+
type: 'def_local_var', name: word, vartype: '定数',
|
|
986
|
+
value: value, josi: '',
|
|
987
|
+
...map, end: this.peekSourceMap()
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/** @returns {import('./nako3').Ast | null | undefined} */
|
|
992
|
+
yIncDec () {
|
|
993
|
+
const map = this.peekSourceMap()
|
|
994
|
+
const action = this.get() // (増やす|減らす)
|
|
995
|
+
if (action === null) { return null }
|
|
996
|
+
|
|
997
|
+
// 『Nずつ増やして繰り返す』文か?
|
|
998
|
+
if (this.check('繰返')) {
|
|
999
|
+
this.pushStack({type: 'word', value: action.value, josi: action.josi, ...map, end: this.peekSourceMap})
|
|
1000
|
+
return this.yFor();
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
// スタックから引数をポップ
|
|
1004
|
+
let value = this.popStack(['だけ', '']);
|
|
1005
|
+
const word = this.popStack(['を'])
|
|
1006
|
+
if (!word || (word.type !== 'word' && word.type !== '配列参照')) {
|
|
1007
|
+
throw NakoSyntaxError.fromNode(
|
|
1008
|
+
`『${action.type}』文で定数が見当たりません。『(変数名)を(値)だけ${action.type}』のように使います。`,
|
|
1009
|
+
action)
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// 減らすなら-1かける
|
|
1013
|
+
if (action.value === '減') {
|
|
1014
|
+
value = { type: 'op', operator: '*', left: value, right: {type: 'number', value: -1, line: action.line}, josi: '', ...map }
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
return {
|
|
1018
|
+
type: 'inc',
|
|
1019
|
+
name: word,
|
|
1020
|
+
value: value,
|
|
1021
|
+
josi: action.josi,
|
|
1022
|
+
...map, end: this.peekSourceMap()
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
|
|
947
1026
|
/** @returns {import('./nako3').Ast | null | undefined} */
|
|
948
1027
|
yCall () {
|
|
949
1028
|
if (this.isEOF()) { return null }
|
|
1029
|
+
|
|
1030
|
+
// スタックに積んでいく
|
|
950
1031
|
while (!this.isEOF()) {
|
|
951
|
-
|
|
1032
|
+
if (this.check('ここから')) { this.get() }
|
|
952
1033
|
// 代入
|
|
953
|
-
if (this.check('代入')) {
|
|
954
|
-
|
|
955
|
-
const value = this.popStack(['を'])
|
|
956
|
-
const word = this.popStack(['へ', 'に'])
|
|
957
|
-
if (!word || (word.type !== 'word' && word.type !== 'func' && word.type !== '配列参照')) {
|
|
958
|
-
throw NakoSyntaxError.fromNode('代入文で代入先の変数が見当たりません。', dainyu)
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
switch (word.type) {
|
|
962
|
-
case '配列参照': // 配列への代入
|
|
963
|
-
return { type: 'let_array', name: word.name, index: word.index, value: value, josi: '', checkInit: this.flagCheckArrayInit, ...map, end: this.peekSourceMap() }
|
|
964
|
-
default:
|
|
965
|
-
return { type: 'let', name: word, value: value, josi: '', ...map, end: this.peekSourceMap() }
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
if (this.check('定める')) {
|
|
969
|
-
const dainyu = this.get()
|
|
970
|
-
const word = this.popStack(['を'])
|
|
971
|
-
const value = this.popStack(['に'])
|
|
972
|
-
if (!word || word.type !== 'word') {
|
|
973
|
-
throw NakoSyntaxError.fromNode('代入文で代入先の変数が見当たりません。', dainyu)
|
|
974
|
-
}
|
|
975
|
-
return {
|
|
976
|
-
type: 'def_local_var',
|
|
977
|
-
name: word,
|
|
978
|
-
vartype: '定数',
|
|
979
|
-
value: value,
|
|
980
|
-
...map,
|
|
981
|
-
end: this.peekSourceMap()
|
|
982
|
-
}
|
|
983
|
-
}
|
|
1034
|
+
if (this.check('代入')) { return this.yDainyu(); }
|
|
1035
|
+
if (this.check('定める')) { return this.ySadameru(); }
|
|
984
1036
|
// 制御構文
|
|
985
|
-
if (this.check('ここから')) { this.get() }
|
|
986
1037
|
if (this.check('回')) { return this.yRepeatTime() }
|
|
987
1038
|
if (this.check('間')) { return this.yWhile() }
|
|
988
1039
|
if (this.check('繰返') || this.check('増繰返') || this.check('減繰返')) { return this.yFor() }
|
|
989
1040
|
if (this.check('反復')) { return this.yForEach() }
|
|
990
1041
|
if (this.check('条件分岐')) { return this.ySwitch() }
|
|
991
|
-
// 戻す
|
|
992
1042
|
if (this.check('戻る')) { return this.yReturn() }
|
|
1043
|
+
if (this.check('増') || this.check('減')) { return this.yIncDec() }
|
|
993
1044
|
// C言語風関数
|
|
994
1045
|
if (this.check2([['func', 'word'], '(']) && this.peek().josi === '') { // C言語風
|
|
995
1046
|
const t = this.yValue()
|
|
@@ -1020,6 +1071,7 @@ class NakoParser extends NakoParserBase {
|
|
|
1020
1071
|
}
|
|
1021
1072
|
break
|
|
1022
1073
|
} // end of while
|
|
1074
|
+
|
|
1023
1075
|
// 助詞が余ってしまった場合
|
|
1024
1076
|
if (this.stack.length > 0) {
|
|
1025
1077
|
this.logger.debug('--- stack dump ---\n' + JSON.stringify(this.stack, null, 2) + '\npeek: ' + JSON.stringify(this.peek(), null, 2))
|
package/src/nako_version.js
CHANGED
package/src/plugin_system.js
CHANGED
|
@@ -202,6 +202,30 @@ const PluginSystem = {
|
|
|
202
202
|
},
|
|
203
203
|
return_none: true
|
|
204
204
|
},
|
|
205
|
+
'連続表示': { // @引数に指定した引数を全て表示する // @れんぞく表示
|
|
206
|
+
type: 'func',
|
|
207
|
+
josi: [['と', 'を']],
|
|
208
|
+
isVariableJosi: true,
|
|
209
|
+
pure: true,
|
|
210
|
+
fn: function (...a) {
|
|
211
|
+
const sys = a.pop()
|
|
212
|
+
const v = a.join('')
|
|
213
|
+
sys.__exec('表示', [v, sys])
|
|
214
|
+
},
|
|
215
|
+
return_none: true
|
|
216
|
+
},
|
|
217
|
+
'連続無改行表示': { // @引数に指定した引数を全て表示する(改行しない) // @れんぞくむかいぎょうひょうじ
|
|
218
|
+
type: 'func',
|
|
219
|
+
josi: [['と', 'を']],
|
|
220
|
+
isVariableJosi: true,
|
|
221
|
+
pure: true,
|
|
222
|
+
fn: function (...a) {
|
|
223
|
+
const sys = a.pop()
|
|
224
|
+
const v = a.join('')
|
|
225
|
+
sys.__exec('継続表示', [v, sys])
|
|
226
|
+
},
|
|
227
|
+
return_none: true
|
|
228
|
+
},
|
|
205
229
|
'表示ログ': { type: 'const', value: '' }, // @ひょうじろぐ
|
|
206
230
|
'表示ログクリア': { // @表示ログを空にする // @ひょうじろぐくりあ
|
|
207
231
|
type: 'func',
|
|
@@ -314,4 +314,15 @@ describe('basic', () => {
|
|
|
314
314
|
it('もし文で「ならば」の前の空行でエラー #1079', () => {
|
|
315
315
|
cmp('A=5;もし、A > 3 ならば「OK」と表示;', 'OK')
|
|
316
316
|
})
|
|
317
|
+
it('『増やす』『減らす』文の追加 #1145', () => {
|
|
318
|
+
// 増やす
|
|
319
|
+
cmp('A=0;Aを1増やす。Aと表示;', '1')
|
|
320
|
+
cmp('A=0;Aを123だけ増やす。Aと表示;', '123')
|
|
321
|
+
// 減らす
|
|
322
|
+
cmp('A=10;Aを1減らす。Aと表示;', '9')
|
|
323
|
+
cmp('A=10;Aを5だけ減らす。Aと表示;', '5')
|
|
324
|
+
// 初期化しないで使うと0になる
|
|
325
|
+
cmp('Aを3増やす;Aと表示;', '3')
|
|
326
|
+
cmp('Aを3減らす;Aと表示;', '-3')
|
|
327
|
+
})
|
|
317
328
|
})
|
package/test/common/dncl_test.js
CHANGED
|
@@ -58,6 +58,8 @@ describe('dncl (#1140)', () => {
|
|
|
58
58
|
it('表示エミュレート', () => {
|
|
59
59
|
cmpNako('!DNCLモード\nx←10,y←20\nxと"-"とyを表示する。', '10-20')
|
|
60
60
|
cmpNako('!DNCLモード\nx←10,y←20\n"("とxと","とyと")"を表示する。', '(10,20)')
|
|
61
|
+
cmpNako('!DNCLモード\nx←10,y←20,z←30\n"("とxと","とyと","とzと")"を表示する。', '(10,20,30)')
|
|
62
|
+
cmpNako('!DNCLモード\nx←10,y←20\n「<」とxと","とyと「>」を表示する。', '<10,20>')
|
|
61
63
|
})
|
|
62
64
|
})
|
|
63
65
|
|