From d1e59e383a70472896e37161fcf5ce1738c516f9 Mon Sep 17 00:00:00 2001 From: kujirahand Date: Sun, 22 Sep 2024 13:54:03 +0900 Subject: [PATCH] =?UTF-8?q?=E8=A8=88=E7=AE=97=E7=B5=90=E6=9E=9C=E3=82=92?= =?UTF-8?q?=E6=89=8B=E8=BB=BD=E3=81=AB=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=80=8C=3F=3F=20=E8=A8=88=E7=AE=97=E5=BC=8F=E6=96=87=E3=80=8D?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E8=A3=85=E3=81=99=E3=82=8B=20#1745?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/nako_lex_rules.mts | 1 + core/src/nako_parser3.mts | 31 ++++++++++++++++++++++++++++++- core/src/nako_token.mts | 1 + core/test/plugin_system_test.mjs | 7 ++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/core/src/nako_lex_rules.mts b/core/src/nako_lex_rules.mts index 90511990..cd4660e4 100644 --- a/core/src/nako_lex_rules.mts +++ b/core/src/nako_lex_rules.mts @@ -100,6 +100,7 @@ export const rules: NakoLexRule[] = [ { name: '(', pattern: /^\(/ }, { name: ')', pattern: /^\)/, readJosi: true }, { name: '|', pattern: /^\|/ }, + { name: '??', pattern: /^\?\?/ }, // 「表示」のエイリアス #1745 { name: 'string', pattern: /^🌿/, cbParser: src => cbString('🌿', '🌿', src) }, { name: 'string_ex', pattern: /^🌴/, cbParser: src => cbString('🌴', '🌴', src) }, { name: 'string_ex', pattern: /^「/, cbParser: src => cbString('「', '」', src) }, diff --git a/core/src/nako_parser3.mts b/core/src/nako_parser3.mts index 5eaffe91..6dd0d814 100644 --- a/core/src/nako_parser3.mts +++ b/core/src/nako_parser3.mts @@ -140,6 +140,7 @@ export class NakoParser extends NakoParserBase { if (this.check('エラー監視')) { return this.yTryExcept() } if (this.accept(['抜ける'])) { return { type: 'break', josi: '', ...map, end: this.peekSourceMap() } } if (this.accept(['続ける'])) { return { type: 'continue', josi: '', ...map, end: this.peekSourceMap() } } + if (this.check('??')) { return this.yPrint() } // 実行モードの指定 if (this.accept(['DNCLモード'])) { return this.yDNCLMode(1) } if (this.accept(['DNCL2モード'])) { return this.yDNCLMode(2) } @@ -671,7 +672,7 @@ export class NakoParser extends NakoParserBase { * @param kara * @returns {AstCallFunc | null} */ - yRange(kara: Ast): AstCallFunc | null { + yRange (kara: Ast): AstCallFunc | null { // 範囲オブジェクト? if (!this.check('…')) { return null } const map = this.peekSourceMap() @@ -694,6 +695,34 @@ export class NakoParser extends NakoParserBase { } } + /** + * 表示(関数)を返す 「??」のエイリアスで利用 (#1745) + * @returns {AstCallFunc | null} + */ + yPrint (): AstCallFunc | null { + const map = this.peekSourceMap() + const t = this.get() // skip '??' + if (!t || t.value !== '??') { + throw NakoSyntaxError.fromNode('『??』で指定してください。', map) + } + const arg: Ast|null = this.yGetArg() + if (!arg) { + throw NakoSyntaxError.fromNode('『??(計算式)』で指定してください。', map) + } + const meta = this.funclist.get('表示') + if (!meta) { throw new Error('関数『表示』が見つかりません。plugin_systemをシステムに追加してください。') } + return { + type: 'func', + name: '表示', + blocks: [arg], + josi: '', + meta, + asyncFn: false, + ...map, + end: this.peekSourceMap() + } + } + yGetArg (): Ast|null { // 値を一つ読む const value1 = this.yValue() diff --git a/core/src/nako_token.mts b/core/src/nako_token.mts index 3b5a0293..a6a44d35 100644 --- a/core/src/nako_token.mts +++ b/core/src/nako_token.mts @@ -101,6 +101,7 @@ export type TokenType = '?' | '厳チェック' // 厳しくチェック (#1698) | '」' // error - エラーチェックのため | '』' // error - エラーチェックのため + | '??' // 「表示」のエイリアス // トークン export interface Token { diff --git a/core/test/plugin_system_test.mjs b/core/test/plugin_system_test.mjs index 04891cf0..7f3dc250 100644 --- a/core/test/plugin_system_test.mjs +++ b/core/test/plugin_system_test.mjs @@ -11,7 +11,7 @@ describe('plugin_system_test', async () => { const g = await nako.runAsync(code, 'main.nako3') assert.strictEqual(g.log, res) } - const cmpex = async (/** @type {string} */ code, /** @type { name: String, message: string } */ exinfo) => { + const cmpex = async (/** @type {string} */ code, /** @type { name: string, message: string } */ exinfo) => { const nako = new NakoCompiler() nako.getLogger().debug('code=' + code) try { @@ -693,4 +693,9 @@ describe('plugin_system_test', async () => { await cmp('A=[0,1,2,3];Aから0...5を参照してJSONエンコードして表示', '[0,1,2,3]') // 範囲を超えて指定もエラーにならない await cmp('A=[0,1,2,3];Aから5...9を参照してJSONエンコードして表示', '[]') // 範囲を超えて指定もエラーにならない }) + it('「?? 計算式文」 #1745', async () => { + await cmp('??1+1', '2') + await cmp('??1+2*3', '7') + await cmp('??(1+2)*3', '9') + }) })