Skip to content

Commit

Permalink
Implement simple REPL.
Browse files Browse the repository at this point in the history
  • Loading branch information
junjis0203 committed May 24, 2020
1 parent 443f5ca commit 2fe910e
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 25 deletions.
70 changes: 51 additions & 19 deletions joke.js
@@ -1,37 +1,69 @@
import JokeEngine from 'joke';
import fs from 'fs';

if (!process.argv[2]) {
console.log(`Usage: node joke.js sourceFile`);
process.exit(0);
}
import readline from 'readline';

let debug = false;
let argc = 2;
while (true) {
if (process.argv[argc][0] != '-') {
if (!process.argv[argc] || process.argv[argc][0] != '-') {
break;
}

switch (process.argv[argc]) {
case '-d':
debug = true;
break;
case '-h':
console.log('Usage: node joke.js [options] [sourceFile]\n');
console.log('Options:');
console.group();
console.log('-d\tEnable debug mode (dump compiler output)')
console.groupEnd();
process.exit(0);
}
argc++;
}

const sourceFile = process.argv[argc];
fs.readFile(sourceFile, 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
function runSourceFile(sourceFile) {
fs.readFile(sourceFile, 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}

try {
const joke = new JokeEngine(debug);
joke.run(sourceFile, data);
} catch (e) {
console.error(`${e.name}: ${e.message}`);
}
});
}

try {
const joke = new JokeEngine(debug);
joke.run(sourceFile, data);
} catch (e) {
console.error(`${e.name}: ${e.message}`);
}
});
function executeRepl() {
const joke = new JokeEngine(debug);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: '> '
});
rl.on('line', (line) => {
try {
joke.run('<stdin>', line);
} catch (e) {
console.error(`${e.name}: ${e.message}`);
}
rl.prompt();
});
rl.on('close', () => {
process.exit(0);
})
rl.prompt();
}

const sourceFile = process.argv[argc];
if (sourceFile) {
runSourceFile(sourceFile);
} else {
executeRepl();
}
16 changes: 13 additions & 3 deletions lib/joke.js
Expand Up @@ -8,6 +8,17 @@ import { initializeGlobalScope } from './object.js';
export default class JokeEngine {
constructor(debug = false) {
this.debug = debug;
// preserve scope for REPL
this.globalScope = initializeGlobalScope();
}

makeScopeForValidator() {
let names = this.globalScope.getObjectNames();
const scope = {};
for (const name of names) {
scope[name] = true;
}
return scope;
}

/*
Expand Down Expand Up @@ -37,7 +48,7 @@ export default class JokeEngine {
}

const validator = new Validator();
validator.validate(node);
validator.validate(node, this.makeScopeForValidator());

const assembler = new Assembler();
const insns = assembler.assemble(node);
Expand All @@ -50,7 +61,6 @@ export default class JokeEngine {
}

const vm = new Vm();
const globalScope = initializeGlobalScope();
vm.run(insns, globalScope);
vm.run(insns, this.globalScope);
}
}
8 changes: 7 additions & 1 deletion lib/object.js
@@ -1,9 +1,15 @@
export function createScope() {
return {
names: [],

getObjectNames() {
return this.names;
},
getObject(name) {
return this[name];
},
defineObject(name, declarationType) {
this.names.push(name);
this[name] = {declarationType};
},
setObject(name, value, initialize=false) {
Expand All @@ -18,7 +24,7 @@ export function createScope() {
}
};
}

export function createObject() {
return {
getProperty(name) {
Expand Down
3 changes: 1 addition & 2 deletions lib/validator.js
Expand Up @@ -30,8 +30,7 @@ function validateNode(node, scopes) {
}

export default class Validator {
validate(node) {
const scope = {};
validate(node, scope) {
const scopes = [scope];
validateNode(node, scopes);
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -6,6 +6,7 @@
"type": "module",
"exports": "./lib/joke.js",
"scripts": {
"joke": "node --experimental-modules joke.js",
"test": "node --experimental-modules test.js"
},
"keywords": [],
Expand Down

0 comments on commit 2fe910e

Please sign in to comment.