Skip to content

Commit

Permalink
Merge pull request #1447 from TumoiYorozu/stdinout
Browse files Browse the repository at this point in the history
cnakoの「尋」命令をパイプで複数回呼べるように
  • Loading branch information
kujirahand committed Apr 8, 2023
2 parents 265c22d + dd70656 commit 2025dde
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 84 deletions.
103 changes: 61 additions & 42 deletions src/plugin_node.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ export default {
sys.__v0['ナデシコランタイム'] = path.basename(process.argv[0]);
sys.__v0['母艦パス'] = sys.__getBokanPath();
sys.__v0['AJAX:ONERROR'] = null;
// 『尋』『文字尋』『標準入力取得時』『標準入力全取得』のための一時変数
// .pause() しないと Ctrl+D するまで永遠に入力待ちになる
// .resume() することで標準入力の受け取り待ちになる
sys.__linereader = readline.createInterface({ input: process.stdin, output: process.stdout });
if (sys.__linereader === null) {
sys.__linegetter = null;
}
else {
sys.__linegetter = (function () {
const getLineGen = (async function* () {
for await (const line of sys.__linereader) {
yield line;
}
})();
return async () => ((await getLineGen.next()).value);
})();
sys.__linereader.pause();
}
}
},
// @ファイル入出力
Expand Down Expand Up @@ -668,12 +686,12 @@ export default {
type: 'func',
josi: [['を']],
pure: true,
fn: function (callback) {
const reader = readline.createInterface({
input: process.stdin,
output: process.stdout
});
reader.on('line', function (line) {
fn: function (callback, sys) {
if (!sys.__linereader) {
throw new Error('『標準入力取得時』命令で標準入力が取得できません');
}
sys.__linereader.resume();
sys.__linereader.on('line', function (line) {
callback(line);
});
}
Expand All @@ -683,60 +701,61 @@ export default {
josi: [['と', 'を']],
pure: true,
asyncFn: true,
fn: function (msg, sys) {
return new Promise((resolve, reject) => {
// process.stdin.resume()
const cli = readline.createInterface(process.stdin, process.stdout);
if (!cli) {
reject(new Error('『尋』命令で標準入力が取得できません'));
return;
}
cli.question(msg, (line) => {
if (line & line.match(/^[0-9.]+$/)) {
line = parseFloat(line);
}
cli.close();
resolve(line);
});
});
fn: async function (msg, sys) {
if (!sys.__linereader) {
throw new Error('『尋』命令で標準入力が取得できません');
}
sys.__linereader.resume();
if (msg !== undefined)
process.stdout.write(msg);
let line = await sys.__linegetter();
if (!line) {
throw new Error('『尋』命令で標準入力が取得できません。最後の入力が終わった可能性があります');
}
sys.__linereader.pause();
if (line.match(/^[0-9.]+$/)) {
line = parseFloat(line);
}
return line;
}
},
'文字尋': {
type: 'func',
josi: [['と', 'を']],
pure: true,
asyncFn: true,
fn: function (msg) {
return new Promise((resolve, reject) => {
const cli = readline.createInterface(process.stdin, process.stdout);
if (!cli) {
reject(new Error('『尋』命令で標準入力が取得できません'));
return;
}
cli.question(msg, (buf) => {
cli.close();
resolve(buf);
});
});
fn: async function (msg, sys) {
if (!sys.__linereader) {
throw new Error('『文字尋』命令で標準入力が取得できません');
}
sys.__linereader.resume();
if (msg !== undefined)
process.stdout.write(msg);
let line = await sys.__linegetter();
if (!line) {
throw new Error('『文字尋』命令で標準入力が取得できません。最後の入力が終わった可能性があります');
}
sys.__linereader.pause();
return line;
}
},
'標準入力全取得': {
type: 'func',
josi: [],
pure: true,
asyncFn: true,
fn: function () {
fn: function (sys) {
return new Promise((resolve, _reject) => {
let dataStr = '';
const reader = readline.createInterface({
input: process.stdin,
output: process.stdout
});
reader.on('line', (line) => {
if (!sys.__linereader) {
throw new Error('『標準入力全取得』命令で標準入力が取得できません');
}
sys.__linereader.resume();
sys.__linereader.on('line', (line) => {
dataStr += line + '\n';
});
reader.on('close', () => {
reader.close();
sys.__linereader.on('close', () => {
sys.__linereader.close();
resolve(dataStr);
});
});
Expand Down
102 changes: 60 additions & 42 deletions src/plugin_node.mts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,25 @@ export default {
sys.__v0['ナデシコランタイム'] = path.basename(process.argv[0])
sys.__v0['母艦パス'] = sys.__getBokanPath()
sys.__v0['AJAX:ONERROR'] = null


// 『尋』『文字尋』『標準入力取得時』『標準入力全取得』のための一時変数
// .pause() しないと Ctrl+D するまで永遠に入力待ちになる
// .resume() することで標準入力の受け取り待ちになる
sys.__linereader = readline.createInterface({ input: process.stdin , output: process.stdout })
if (sys.__linereader === null) {
sys.__linegetter = null
} else {
sys.__linegetter = (function () {
const getLineGen = (async function* () {
for await (const line of sys.__linereader) {
yield line
}
})()
return async () => ((await getLineGen.next()).value)
})()
sys.__linereader.pause()
}
}
},
// @ファイル入出力
Expand Down Expand Up @@ -617,12 +636,12 @@ export default {
type: 'func',
josi: [['を']],
pure: true,
fn: function (callback: any) {
const reader = readline.createInterface({
input: process.stdin,
output: process.stdout
})
reader.on('line', function (line) {
fn: function (callback: any, sys: any) {
if (!sys.__linereader) {
throw new Error('『標準入力取得時』命令で標準入力が取得できません')
}
sys.__linereader.resume()
sys.__linereader.on('line', function (line :string) {
callback(line)
})
}
Expand All @@ -632,60 +651,59 @@ export default {
josi: [['と', 'を']],
pure: true,
asyncFn: true,
fn: function (msg: string, sys: any): Promise<string> {
return new Promise((resolve, reject) => {
// process.stdin.resume()
const cli = readline.createInterface(process.stdin, process.stdout)
if (!cli) {
reject(new Error('『尋』命令で標準入力が取得できません'))
return
}
cli.question(msg, (line: any) => {
if (line & line.match(/^[0-9.]+$/)) {
line = parseFloat(line)
}
cli.close()
resolve(line)
})
})
fn: async function (msg: string, sys: any) {
if (!sys.__linereader) {
throw new Error('『尋』命令で標準入力が取得できません')
}
sys.__linereader.resume()
if (msg !== undefined) process.stdout.write(msg)
let line = await sys.__linegetter()
if (!line) {
throw new Error('『尋』命令で標準入力が取得できません。最後の入力が終わった可能性があります')
}
sys.__linereader.pause()
if (line.match(/^[0-9.]+$/)) {
line = parseFloat(line)
}
return line
}
},
'文字尋': { // @標準入力を一行取得する。ただし自動で数値に変換しない // @もじたずねる
type: 'func',
josi: [['と', 'を']],
pure: true,
asyncFn: true,
fn: function (msg: string): Promise<any> {
return new Promise((resolve, reject) => {
const cli = readline.createInterface(process.stdin, process.stdout)
if (!cli) {
reject(new Error('『尋』命令で標準入力が取得できません'))
return
}
cli.question(msg, (buf: any) => {
cli.close()
resolve(buf)
})
})
fn: async function (msg: string, sys: any) {
if (!sys.__linereader) {
throw new Error('『文字尋』命令で標準入力が取得できません')
}
sys.__linereader.resume()
if (msg !== undefined) process.stdout.write(msg)
let line = await sys.__linegetter()
if (!line) {
throw new Error('『文字尋』命令で標準入力が取得できません。最後の入力が終わった可能性があります')
}
sys.__linereader.pause()
return line
}
},
'標準入力全取得': { // @標準入力を全部取得して返す // @ひょうじゅんにゅうりょくぜんしゅとく
type: 'func',
josi: [],
pure: true,
asyncFn: true,
fn: function (): Promise<string> {
fn: function (sys: any): Promise<string> {
return new Promise((resolve, _reject) => {
let dataStr = ''
const reader = readline.createInterface({
input: process.stdin,
output: process.stdout
})
reader.on('line', (line) => {
if (!sys.__linereader) {
throw new Error('『標準入力全取得』命令で標準入力が取得できません')
}
sys.__linereader.resume()
sys.__linereader.on('line', (line : string) => {
dataStr += line + '\n'
})
reader.on('close', () => {
reader.close()
sys.__linereader.on('close', () => {
sys.__linereader.close()
resolve(dataStr)
})
})
Expand Down

0 comments on commit 2025dde

Please sign in to comment.