Move Gir to use modules
This commit is contained in:
parent
e203efdb47
commit
21832b0bb5
|
@ -18,12 +18,16 @@ Gir supports following optimizations:
|
||||||
* Add offsets to commands that modify tape, to reduce moving tape head
|
* Add offsets to commands that modify tape, to reduce moving tape head
|
||||||
* Turn multiply loops into one command
|
* Turn multiply loops into one command
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
`ircbot.js` is an implementation of an IRC bot's brainfuck interpreter
|
||||||
|
function. Smaller examples are available in `api.md`
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
### gir.html
|
### gir.html
|
||||||
* Implement a UI
|
* Implement a UI
|
||||||
|
|
||||||
### General
|
### General
|
||||||
* Make Gir use modules
|
|
||||||
* Get this on NPM?
|
* Get this on NPM?
|
||||||
* Move into subdirectories?
|
* Move into subdirectories?
|
||||||
|
|
17
gir.html
17
gir.html
|
@ -3,8 +3,23 @@
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
<title>Gir testbench</title>
|
<title>Gir testbench</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Implement "module" support
|
||||||
|
let exports = {};
|
||||||
|
</script>
|
||||||
<script type="text/javascript" src="gir.js"></script>
|
<script type="text/javascript" src="gir.js"></script>
|
||||||
<script type="text/javascript" src="example.js"></script>
|
<script type="text/javascript">
|
||||||
|
let girExports = exports;
|
||||||
|
// Implement "module" support
|
||||||
|
// This is possibly not quite compliant
|
||||||
|
function require(string) {
|
||||||
|
return girExports;
|
||||||
|
}
|
||||||
|
require.main = 'foo';
|
||||||
|
module = 'bar';
|
||||||
|
exports = {};
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="ircbot.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<html>
|
<html>
|
||||||
<p>Open the JavaScript console</p>
|
<p>Open the JavaScript console</p>
|
||||||
|
|
7
gir.js
7
gir.js
|
@ -947,3 +947,10 @@ function decodeUTF8(encoded) {
|
||||||
function compile(program, enableExtensions = true) {
|
function compile(program, enableExtensions = true) {
|
||||||
return optimize(parse(program, enableExtensions));
|
return optimize(parse(program, enableExtensions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.compile = compile;
|
||||||
|
exports.prettifyIR = prettifyIR;
|
||||||
|
exports.newVM = newVM;
|
||||||
|
exports.runVM = runVM;
|
||||||
|
exports.encodeUTF8 = encodeUTF8;
|
||||||
|
exports.decodeUTF8 = decodeUTF8;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const gir = require('./gir.js');
|
||||||
|
|
||||||
class IntParseError extends Error {}
|
class IntParseError extends Error {}
|
||||||
|
|
||||||
const programCacheSize = 16;
|
const programCacheSize = 16;
|
||||||
|
@ -15,7 +17,7 @@ function cachedCompile(program, enableExtensions = true) {
|
||||||
programCache.delete(program);
|
programCache.delete(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
let compiled = compile(program, enableExtensions);
|
let compiled = gir.compile(program, enableExtensions);
|
||||||
programCache.set(program, {compiled: compiled,
|
programCache.set(program, {compiled: compiled,
|
||||||
extensions: enableExtensions});
|
extensions: enableExtensions});
|
||||||
|
|
||||||
|
@ -58,10 +60,10 @@ function cachedCompile(program, enableExtensions = true) {
|
||||||
// (string, string, int) → string
|
// (string, string, int) → string
|
||||||
function ircbotRun(program, input, maxCycles = 400000) {
|
function ircbotRun(program, input, maxCycles = 400000) {
|
||||||
let compiled = cachedCompile(program);
|
let compiled = cachedCompile(program);
|
||||||
let vm = newVM(compiled, encodeUTF8(input));
|
let vm = gir.newVM(compiled, gir.encodeUTF8(input));
|
||||||
|
|
||||||
let result = runVM(vm, maxCycles);
|
let result = gir.runVM(vm, maxCycles);
|
||||||
let output = decodeUTF8(result.state.output);
|
let output = gir.decodeUTF8(result.state.output);
|
||||||
|
|
||||||
// Replace all characters < 0x20 except for IRC formatting codes
|
// Replace all characters < 0x20 except for IRC formatting codes
|
||||||
// with their graphical representations at U+24xx
|
// with their graphical representations at U+24xx
|
||||||
|
@ -157,9 +159,32 @@ function ircbotRun(program, input, maxCycles = 400000) {
|
||||||
|
|
||||||
// If there was a problem with parsing an int, throw an Error
|
// If there was a problem with parsing an int, throw an Error
|
||||||
if(result.intParseFailed) {
|
if(result.intParseFailed) {
|
||||||
let context = decodeUTF8(result.state.input).slice(0, 3);
|
let context = gir.decodeUTF8(result.state.input).slice(0, 3);
|
||||||
throw new IntParseError(`';': couldn't read number (near '${context})'`);
|
throw new IntParseError(`';': couldn't read number (near '${context})'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.ircbotRun = ircbotRun;
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const readline = require('readline');
|
||||||
|
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout,
|
||||||
|
prompt: 'program!input> '
|
||||||
|
});
|
||||||
|
rl.prompt();
|
||||||
|
|
||||||
|
rl.on('line', line => {
|
||||||
|
let [program, input] = line.split('!');
|
||||||
|
console.log(ircbotRun(program, input));
|
||||||
|
rl.prompt();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(require.main === module) {
|
||||||
|
main();
|
||||||
|
}
|
Loading…
Reference in New Issue