Skip to content

Commit

Permalink
Merge pull request #1877 from kujirahand/hatena_customize_debug
Browse files Browse the repository at this point in the history
「??」をカスタマイズできるようにする #1852
  • Loading branch information
kujirahand authored Dec 20, 2024
2 parents 08278c6 + 09baabd commit b650193
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 14 deletions.
1 change: 0 additions & 1 deletion core/src/nako_lex_rules.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* なでしこ3字句解析のためのルール
*/

import { NakoLexerError } from './nako_errors.mjs'
import { josiRE, removeJosiMap } from './nako_josi_list.mjs'
import { TokenType } from './nako_token.mjs'

Expand Down
11 changes: 5 additions & 6 deletions core/src/nako_parser3.mts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,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.check('??')) { return this.yDebugPrint() }
// 実行モードの指定
if (this.accept(['DNCLモード'])) { return this.yDNCLMode(1) }
if (this.accept(['DNCL2モード'])) { return this.yDNCLMode(2) }
Expand Down Expand Up @@ -699,9 +699,8 @@ export class NakoParser extends NakoParserBase {

/**
* 表示(関数)を返す 「??」のエイリアスで利用 (#1745)
* @returns {AstCallFunc | null}
*/
yPrint (): AstCallFunc | null {
yDebugPrint (): AstCallFunc | null {
const map = this.peekSourceMap()
const t = this.get() // skip '??'
if (!t || t.value !== '??') {
Expand All @@ -711,11 +710,11 @@ export class NakoParser extends NakoParserBase {
if (!arg) {
throw NakoSyntaxError.fromNode('『??(計算式)』で指定してください。', map)
}
const meta = this.funclist.get('表示')
if (!meta) { throw new Error('関数『表示』が見つかりません。plugin_systemをシステムに追加してください。') }
const meta = this.funclist.get('ハテナ関数実行')
if (!meta) { throw new Error('関数『ハテナ関数実行』が見つかりません。plugin_systemをシステムに追加してください。') }
return {
type: 'func',
name: '表示',
name: 'ハテナ関数実行',
blocks: [arg],
josi: '',
meta,
Expand Down
1 change: 1 addition & 0 deletions core/src/plugin_api.mts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface NakoSystem {
__setSore(v: any): void;
__getSore(): any;
__loadScript(url: string): Promise<void>; // JSのスクリプトを読み込む (ex) グラフ描画(plguin_browser_chart.mts)
__hatena: (s: string, sys: NakoSystem) => void; // 「??」記法の関数キャッシュ #1852
logger: any; // Logger
// 便利なメソッド
__zero (s: string, keta: number): string; // 桁を指定してゼロ埋めする
Expand Down
66 changes: 65 additions & 1 deletion core/src/plugin_system.mts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ export default {
obj.__getProp = obj.__setProp = null
}
}

// 「??」ハテナ関数の設定
sys.__hatena = sys.__getSysVar('デバッグ表示')
}
},
'!クリア': {
Expand Down Expand Up @@ -2918,6 +2919,69 @@ export default {
}
},
// @デバッグ支援
'デバッグ表示': { // @デバッグ用にSを表示する // @でばっぐひょうじ
type: 'func',
josi: [['と', 'を', 'の']],
pure: true,
fn: function (s: any, sys: NakoSystem) {
// 行番号の情報を得る
const lineInfo: string = sys.__getSysVar('__line', 0) + '::'
const a = lineInfo.split(':', 2)
const no = parseInt(String(a[0]).replace('l', '')) + 1
const fname = a[1]
// オブジェクトならJSON文字列に変換
if (typeof s == 'object') {
s = JSON.stringify(s)
}
s = `${fname}(${no}): ${s}`
sys.__exec('表示', [s, sys])
},
return_none: true
},
'ハテナ関数設定': { // @ハテナ関数「?? (計算式)」の動作をカスタマイズする。文字列の配列を指定可能で、システム関数名か「js:code」を指定可能。 // @はてなかんすうせってい
type: 'func',
josi: [['を', 'の']],
pure: true,
fn: function (s: any, sys: NakoSystem) {
if (typeof s === 'function') {
sys.__hatena = s
return
}
if (typeof s === 'string') {
sys.__hatena = sys.__getSysVar(s, 'デバッグ表示')
return
}
if (s instanceof Array) {
const fa: ((s: string, sys: NakoSystem)=>string)[] = (s as Array<string>).map((fstr: string) => {
if (fstr.substring(0, 3) === 'JS:') {
const code = fstr.substring(3)
return sys.__evalJS(code, sys)
} else {
return sys.__getSysVar(fstr, 'デバッグ表示')
}
})
sys.__hatena = (p: any, sys: NakoSystem) => {
let param: any = p
for (const f of fa) {
param = f(param, sys)
}
return
}
return
}
sys.__hatena = sys.__getSysVar('デバッグ表示')
},
return_none: true
},
'ハテナ関数実行': { // @『ハテナ関数設定』で設定した関数を実行する // @はてなかんすうじっこう
type: 'func',
josi: [['の', 'を', 'と']],
pure: true,
fn: function (s: any, sys: NakoSystem) {
sys.__hatena(s, sys)
},
return_none: true
},
'エラー発生': { // @故意にエラーSを発生させる // @えらーはっせい
type: 'func',
josi: [['の', 'で']],
Expand Down
18 changes: 12 additions & 6 deletions core/test/plugin_system_test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -690,11 +690,6 @@ 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')
})
it('ASC/CHRの配列 #1853', async () => {
await cmp('["a","b","c"]のASCをJSON_Eして表示', '[97,98,99]') // 配列なら全ての文字のASC
await cmp('「abc」のASCをJSON_Eして表示', '97') // 文字列なら最初の文字のみ
Expand All @@ -707,4 +702,15 @@ describe('plugin_system_test', async () => {
await cmp('「 abc 」を右トリムして表示', ' abc')
await cmp('「 abc 」を末尾空白除去して表示', ' abc')
})
it('「?? 計算式文」 #1745', async () => {
await cmp('「表示」をハテナ関数設定; ?? 1+1', '2')
await cmp('「表示」をハテナ関数設定; ?? 1+2*3', '7')
await cmp('「表示」をハテナ関数設定; ?? (1+2)*3', '9')
})
it('「??」のカスタマイズ機能を追加 #1852', async () => {
await cmp('["JSON_E","表示"]をハテナ関数設定; ?? [1,2,3]', '[1,2,3]')
await cmp('["文字列分解", "ASC", "JSON_E","表示"]をハテナ関数設定; ?? "abc"', '[97,98,99]')
await cmp('["JS:Math.ceil","表示"]をハテナ関数設定; ?? 3.2', '4')
await cmp('[『JS:(function(v,sys){return Math.ceil(v);})』,"表示"]をハテナ関数設定; ?? 3.2', '4')
})
})

0 comments on commit b650193

Please sign in to comment.