To make Tabloid truly Turing complete, add a way for Tabloid to take input

This commit is contained in:
Linus Lee 2020-10-24 13:07:19 -04:00
parent 2435a7cd5e
commit 25bc958e04
2 changed files with 29 additions and 0 deletions

View File

@ -112,6 +112,7 @@ const T = {
ExpertsClaim: Symbol('ExpertsClaim'), ExpertsClaim: Symbol('ExpertsClaim'),
ToBe: Symbol('ToBe'), ToBe: Symbol('ToBe'),
YouWontWantToMiss: Symbol('YouWontWantToMiss'), YouWontWantToMiss: Symbol('YouWontWantToMiss'),
LatestNewsOn: Symbol('LatestNewsOn'),
TotallyRight: Symbol('TotallyRight'), TotallyRight: Symbol('TotallyRight'),
CompletelyWrong: Symbol('CompletelyWrong'), CompletelyWrong: Symbol('CompletelyWrong'),
IsActually: Symbol('IsActually'), IsActually: Symbol('IsActually'),
@ -201,6 +202,12 @@ function tokenize(prog) {
tokens.push(T.YouWontWantToMiss); tokens.push(T.YouWontWantToMiss);
break; break;
} }
case 'LATEST': {
reader.expect('NEWS');
reader.expect('ON');
tokens.push(T.LatestNewsOn);
break;
}
case 'IS': { case 'IS': {
reader.expect('ACTUALLY'); reader.expect('ACTUALLY');
tokens.push(T.IsActually); tokens.push(T.IsActually);
@ -308,6 +315,7 @@ const N = {
ReturnExpr: Symbol('ReturnExpr'), ReturnExpr: Symbol('ReturnExpr'),
ProgEndExpr: Symbol('ProgEndExpr'), ProgEndExpr: Symbol('ProgEndExpr'),
PrintExpr: Symbol('PrintExpr'), PrintExpr: Symbol('PrintExpr'),
InputExpr: Symbol('InputExpr'),
} }
class Parser { class Parser {
@ -334,6 +342,7 @@ class Parser {
* ReturnExpr * ReturnExpr
* ProgEndExpr * ProgEndExpr
* PrintExpr * PrintExpr
* InputExpr
* *
*/ */
parse() { parse() {
@ -485,6 +494,12 @@ class Parser {
type: N.PrintExpr, type: N.PrintExpr,
val: this.expr(), val: this.expr(),
} }
} else if (next === T.LatestNewsOn) {
// input expr
return {
type: N.InputExpr,
val: this.expr(),
}
} }
this.tokens.backstep(); this.tokens.backstep();
@ -538,6 +553,7 @@ class Environment {
/** /**
* Runtime contains the following functions: * Runtime contains the following functions:
* - print(s) * - print(s)
* - input(s)
*/ */
this.runtime = runtime; this.runtime = runtime;
this.scopes = [{}]; // begin with global scope this.scopes = [{}]; // begin with global scope
@ -666,6 +682,16 @@ class Environment {
this.runtime.print(val); this.runtime.print(val);
return val; return val;
} }
case N.InputExpr: {
let val = this.eval(node.val);
// shim for boolean to-string's
if (val === true) {
val = 'TOTALLY RIGHT';
} else if (val === false) {
val = 'COMPLETELY WRONG';
}
return this.runtime.input(val);
}
default: default:
console.log(JSON.stringify(node, null, 2)); console.log(JSON.stringify(node, null, 2));
throw new Error(`Runtime error: Unknown AST Node of type ${ throw new Error(`Runtime error: Unknown AST Node of type ${

View File

@ -102,6 +102,9 @@ class Editor extends Component {
this.output += s.toString().toUpperCase() + '!\n'; this.output += s.toString().toUpperCase() + '!\n';
this.render(); this.render();
}, },
input: s => {
return prompt(s);
},
}); });
env.run(nodes); env.run(nodes);
} catch (e) { } catch (e) {