nadesiko3 3.2.47 → 3.2.48

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.
@@ -2,7 +2,7 @@
2
2
  * なでしこ3字句解析のためのルール
3
3
  */
4
4
 
5
- const kanakanji = /^[\u3005\u4E00-\u9FCF_a-zA-Z0-9ァ-ヶー]+/
5
+ const kanakanji = /^[\u3005\u4E00-\u9FCF_a-zA-Z0-9ァ-ヶー\u2460-\u24FF\u2776-\u277F\u3251-\u32BF]+/
6
6
  const nakoJosiList = require('./nako_josi_list')
7
7
  const josiRE = nakoJosiList.josiRE
8
8
  const removeJosiMap = nakoJosiList.removeJosiMap
@@ -53,9 +53,9 @@ module.exports = {
53
53
  { name: 'lteq', pattern: /^(≦|<=|=<)/ },
54
54
  { name: 'noteq', pattern: /^(≠|<>|!=)/ },
55
55
  { name: '←', pattern: /^(←|<--)/ }, // 関数呼び出し演算子 #891 #899
56
- { name: 'eq', pattern: /^=/ },
56
+ { name: 'eq', pattern: /^(=|🟰)/ },
57
57
  { name: 'line_comment', pattern: /^!(インデント構文|ここまでだるい)[^\n]*/ },
58
- { name: 'not', pattern: /^!/ },
58
+ { name: 'not', pattern: /^(!|💡)/ }, // #1184
59
59
  { name: 'gt', pattern: /^>/ },
60
60
  { name: 'lt', pattern: /^</ },
61
61
  { name: 'and', pattern: /^(かつ|&&)/ },
@@ -96,7 +96,7 @@ module.exports = {
96
96
  // 単語句
97
97
  {
98
98
  name: 'word',
99
- pattern: /^[_a-zA-Z\u3005\u4E00-\u9FCFぁ-んァ-ヶ]/,
99
+ pattern: /^[_a-zA-Z\u3005\u4E00-\u9FCFぁ-んァ-ヶ\u2460-\u24FF\u2776-\u277F\u3251-\u32BF]/,
100
100
  cbParser: cbWordParser
101
101
  }
102
102
  ],
@@ -551,13 +551,13 @@ class NakoParser extends NakoParserBase {
551
551
  }
552
552
  }
553
553
 
554
- /** @returns {Ast | null} */
555
- yGetArg () {
556
- // 値を一つ読む
557
- const value1 = this.yValue()
558
- if (value1 === null) { return null }
559
- // 計算式がある場合を考慮
560
- const args = [value1]
554
+ /**
555
+ * 1つ目の値を与え、その後に続く計算式を取得し、優先規則に沿って並び替えして戻す
556
+ * @param {Ast | null} firstValue
557
+ * @returns {Ast | null}
558
+ */
559
+ yGetArgOperator (firstValue) {
560
+ const args = [firstValue]
561
561
  while (!this.isEOF()) {
562
562
  // 演算子がある?
563
563
  const op = this.peek()
@@ -568,7 +568,7 @@ class NakoParser extends NakoParserBase {
568
568
  if (v === null) {
569
569
  throw NakoSyntaxError.fromNode(
570
570
  `計算式で演算子『${op.value}』後に値がありません`,
571
- value1)
571
+ firstValue)
572
572
  }
573
573
  args.push(v)
574
574
  continue
@@ -580,6 +580,15 @@ class NakoParser extends NakoParserBase {
580
580
  return this.infixToAST(args)
581
581
  }
582
582
 
583
+ /** @returns {Ast | null} */
584
+ yGetArg () {
585
+ // 値を一つ読む
586
+ const value1 = this.yValue()
587
+ if (value1 === null) { return null }
588
+ // 計算式がある場合を考慮
589
+ return this.yGetArgOperator(value1)
590
+ }
591
+
583
592
  infixToPolish (list) {
584
593
  // 中間記法から逆ポーランドに変換
585
594
  const priority = (t) => {
@@ -832,8 +841,11 @@ class NakoParser extends NakoParserBase {
832
841
  yReturn () {
833
842
  const map = this.peekSourceMap()
834
843
  if (!this.check('戻る')) { return null }
835
- this.get() // skip '戻る'
844
+ const modoru = this.get() // skip '戻る'
836
845
  const v = this.popStack(['で', 'を'])
846
+ if (this.stack.length > 0) {
847
+ throw NakoSyntaxError.fromNode('『戻』文の直前に未解決の引数があります。『(式)を戻す』のように式をカッコで括ってください。', modoru)
848
+ }
837
849
  return {
838
850
  type: 'return',
839
851
  value: v,
@@ -1101,7 +1113,11 @@ class NakoParser extends NakoParserBase {
1101
1113
  this.pushStack(r)
1102
1114
  continue
1103
1115
  }
1104
- return r
1116
+ // 関数呼び出しの直後に、四則演算があるか?
1117
+ if (!this.checkTypes(operatorList)) { return r } // なければ関数呼び出しを戻す
1118
+ // 四則演算があった場合、計算してスタックに載せる
1119
+ this.pushStack(this.yGetArgOperator(r))
1120
+ continue
1105
1121
  }
1106
1122
  // 値のとき → スタックに載せる
1107
1123
  const t = this.yGetArg()
@@ -122,7 +122,11 @@ class NakoPrepare {
122
122
  0x3011: ']', // '】'
123
123
  // 読点は「,」に変換する (#877)
124
124
  0x3001: ',', // 読点 --- JSON記法で「,」と「、」を区別したいので読点は変換しないことに。(#276)
125
- 0xFF0C: ',' // 読点 ',' 論文などで利用、ただし句点はドットと被るので変換しない (#735)
125
+ 0xFF0C: ',', // 読点 ',' 論文などで利用、ただし句点はドットと被るので変換しない (#735)
126
+ 0x2716: '*', // ×の絵文字 (#1183)
127
+ 0x2795: '+', // +の絵文字 (#1183)
128
+ 0x2796: '-', // -の絵文字 (#1183)
129
+ 0x2797: '÷' // ÷の絵文字 (#1183)
126
130
  }
127
131
  }
128
132
 
@@ -1,8 +1,8 @@
1
1
  // なでしこバージョン
2
2
  const nakoVersion = {
3
- version: '3.2.47',
3
+ version: '3.2.48',
4
4
  major: 3,
5
5
  minor: 2,
6
- patch: 47
6
+ patch: 48
7
7
  }
8
8
  module.exports = nakoVersion
@@ -136,4 +136,9 @@ describe('calc_test.js', () => {
136
136
  cmp('N=「」;もし、N=0ならば「OK」と表示。', 'OK')
137
137
  cmp('N=「」;もし、N===0ならば「NG」と表示。違えば「OK」と表示。', 'OK')
138
138
  })
139
+ it('なでしこ式関数呼び出しで、途中に四則演算がある場合の処理 (#1188)', () => {
140
+ cmp('3.14のINT+2を表示。', '5')
141
+ cmp('3の5倍×2を表示', '30')
142
+ cmp('1+3の2倍×2を表示', '16')
143
+ })
139
144
  })
@@ -146,4 +146,10 @@ describe('lex_test', () => {
146
146
  it('助詞の前後に空白があるとエラーになる問題 #1079', () => {
147
147
  cmp('x=1;x と 2 と "3" を連続表示', '123')
148
148
  })
149
+ it('丸付き数字が変数名として使えない #1185', () => {
150
+ cmp('⓪=0;①=1;㊿=50;❿=10;⓪+①+㊿+❿を表示', '61')
151
+ })
152
+ it('絵文字の四則演算を認識する #1183', () => {
153
+ cmp('リンゴ🟰3✖5;ミカン🟰9➗3;リンゴ+ミカンを表示', '18')
154
+ })
149
155
  })
@@ -1,6 +1,6 @@
1
1
  const assert = require('assert')
2
2
  const CNako3 = require('../../src/cnako3')
3
-
3
+ const path = require('path')
4
4
  describe('plugin_test', () => {
5
5
  const nako = new CNako3()
6
6
  // nako.logger.addListener('trace', ({ browserConsole }) => { console.log(...browserConsole) })
@@ -11,6 +11,8 @@ describe('plugin_test', () => {
11
11
  assert.strictEqual(ret.log, res)
12
12
  }
13
13
  it('「取り込む」', () => {
14
- cmp('!「nadesiko3-hoge」を取り込む。\n3と5をHOGE足して、表示。', '8')
14
+ const plug = path.join(__dirname, '..', '..', 'src', 'plugin_keigo.js')
15
+ cmp(`!「${plug}」を取り込む。\n拝啓。お世話になっております。礼節レベル取得して表示。`, '1')
15
16
  })
16
17
  })
18
+