I have very specific issue, I'm not sure maybe it's some kind of Garbage collection or other issue with node.js process that finish while the app is running.
So I have Scheme implementation written in JavaScript and I'm trying to run Scheme code that is node-gtk basic example of app with label. The issue is that the label is not inserted into window I've got broken window with background from below the screen, that stay when I move the window.
I have node.js executable that have this shebang:
#!/usr/bin/env node
and my scheme code is 1-1 demo from node-gtk but in Scheme, that have this as shebang:
#!/home/kuba/projects/jcubic/lips/bin/lips.js
temporary local instance, because I'm working on next version. It also works with:
#!/usr/bin/env lips
Here is part of the code of my REPL and execution of files:
if (options._.length === 1) {
fs.readFile(options._[0], function(err, data) {
var e = env.inherit('name');
if (err) {
console.error(err);
} else {
boostrap(e).then(function() {
return run(data.toString().replace(/^#!.*\n/, ''), e);
});
console.log('HELLO');
}
});
} else if (options.h) {
var name = process.argv[1];
console.log(format('%s\nusage:\n%s [-h]|[-c <code>]|<filename>\n\n\t-h this help message\n\t-c execute' +
' code\n\nif called without arguments it will run REPL and if called with one argument' +
'\nit will treat it as filename and execute it.', intro, name));
} else {
if (process.stdin.isTTY) {
console.log(banner);
}
var prompt = 'lips> ';
var continuePrompt = '... ';
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: prompt,
terminal: !!process.stdin.isTTY
});
if (process.stdin.isTTY) {
rl.prompt();
}
var code = '';
var multiline = false;
var resolve;
var e = env.inherit('name', {
stdin: InputPort(function() {
return new Promise(function(resolve) {
rl.question('', resolve);
});
}),
stdout: OutputPort(function(x) {
//rl.write(this.get('repr')(x));
console.log(this.get('repr')(x));
})
});
boostrap(e).then(function() {
rl.on('line', function(line) {
code += line + '\n';
if (balanced_parenthesis(code)) {
rl.pause();
run(code, e).then(function(result) {
if (process.stdin.isTTY) {
print(result);
if (multiline) {
rl.setPrompt(prompt);
}
rl.prompt();
}
rl.resume();
}).catch(function() {
if (process.stdin.isTTY) {
if (multiline) {
rl.setPrompt(prompt);
}
rl.prompt();
}
});
code = '';
} else {
multiline = true;
var i = indent(code, 2, prompt.length - continuePrompt.length);
rl.setPrompt(continuePrompt);
rl.prompt();
rl.write(new Array(i + 1).join(' '));
}
});
});
}
If I execute first if statement the node-gtk app is broken like on the proved screen, but If I run as REPL with readline and copy paste the same code it works. Same if I run this:
../lips/bin/lips.js < ./run.scm
but got extra "..." from multiline case of the repl. What is the proper way to execute this scheme script?
I've also created an issue in node-gtk repo https://github.com/romgrk/node-gtk/issues/170
I've also tried to use promises:
// this is the object that hold references
// while the scheme code is running
let e = env.inherit('name');
fs.promises.readFile(options._[0]).then(function(data) {
return boostrap(e).then(function() {
return run(data.toString().replace(/^#!.*\n/, ''), e);
});
}).catch(err => {
console.error(err);
});
but the issue remain.
bootstrap function just load external files, and run just evaluate the code as string were variables created in Scheme code are saved in environment (which is plain object in e.env).
Working Hack:
If I add this code:
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
before my code it works, it's kind of hack. Why this works and is there a better way? I would like to understand why this is happening and how this works.
