Remove plans for looping constructs -- we don't need em

This commit is contained in:
Linus Lee 2020-09-24 07:46:06 -04:00
parent 4b487e7a38
commit d7c1ae4f76
2 changed files with 49 additions and 23 deletions

View File

@ -110,6 +110,8 @@ const T = {
ExpertsClaim: Symbol('ExpertsClaim'),
ToBe: Symbol('ToBe'),
YouWontWantToMiss: Symbol('YouWontWantToMiss'),
TotallyRight: Symbol('TotallyRight'),
CompletelyWrong: Symbol('CompletelyWrong'),
IsActually: Symbol('IsActually'),
And: Symbol('And'),
Or: Symbol('Or'),
@ -122,12 +124,6 @@ const T = {
SmallerThan: Symbol('SmallerThan'), // <
ShockingDevelopment: Symbol('ShockingDevelopment'),
PleaseLikeAndSubscribe: Symbol('PleaseLikeAndSubscribe'),
// not implemented yet
StayTuned: Symbol('StayTuned'),
Unexpectedly: Symbol('Unexpectedly'),
TotallyRight: Symbol('TotallyRight'),
CompletelyWrong: Symbol('CompletelyWrong'),
}
const BINARY_OPS = [
@ -256,15 +252,6 @@ function tokenize(prog) {
tokens.push(T.PleaseLikeAndSubscribe);
break;
}
case 'STAY': {
reader.expect('TUNED');
tokens.push(T.StayTuned);
break;
}
case 'UNEXPECTEDLY': {
tokens.push(T.Unexpectedly);
break;
}
case 'TOTALLY': {
reader.expect('RIGHT');
tokens.push(T.TotallyRight);
@ -306,6 +293,7 @@ function tokenize(prog) {
const N = {
NumberLiteral: Symbol('NumberLiteral'),
StringLiteral: Symbol('StringLiteral'),
BoolLiteral: Symbol('BoolLiteral'),
FnDecl: Symbol('FnDecl'),
FnCall: Symbol('FnCall'),
Ident: Symbol('Ident'),
@ -327,6 +315,7 @@ class Parser {
* Ident
* NumberLiteral
* StringLiteral
* BoolLiteral
* FnCall
* FnDecl
* ExprGroup
@ -379,6 +368,16 @@ class Parser {
return this.fnCall(ident);
}
return ident;
} else if (next === T.TotallyRight) {
return {
type: N.BoolLiteral,
val: true,
}
} else if (next === T.CompletelyWrong) {
return {
type: N.BoolLiteral,
val: false,
}
} else if (next === T.DiscoverHowTo) {
// fn literal
const fnName = this.tokens.next();
@ -460,7 +459,7 @@ class Parser {
return {
type: N.ProgEndExpr,
}
} else if (next == T.YouWontWantToMiss) {
} else if (next === T.YouWontWantToMiss) {
// print expr
return {
type: N.PrintExpr,
@ -585,15 +584,26 @@ class Environment {
const left = this.eval(node.left);
const right = this.eval(node.right);
switch (node.op) {
// TODO: other ops
case T.IsActually:
return left === right;
case T.And:
return left && right;
case T.Or:
return left || right;
case T.Add:
return left + right;
case T.Subtract:
return left - right;
case T.Multiply:
return left * right;
case T.Divide:
return left / right;
case T.Modulo:
return left % right;
case T.Beats:
return left > right;
case T.SmallerThan:
return left < right;
default:
throw new Error(`Runtime error: Unknown binary op ${node.op.toString()}`);
}
@ -607,7 +617,11 @@ class Environment {
}
}
case N.ExprGroup: {
let rv = false; // TODO: make null value? make this illegal?
if (!node.exprs.length) {
throw new Error('Runtime error: Empty expression group with no expressions');
}
let rv;
for (const expr of node.exprs) {
rv = this.eval(expr);
}
@ -622,7 +636,13 @@ class Environment {
break;
}
case N.PrintExpr: {
const val = this.eval(node.val);
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';
}
this.runtime.print(val);
return val;
}

View File

@ -115,7 +115,7 @@ class App extends Component {
<a href="#" onclick=${evt => {
evt.preventDefault();
this.render();
}}>Rewrite headline!</a>
}}>NEW headline!</a>
<a href="https://dotink.co/posts/tabloid/"
target="_blank" noopener noreferer>Blog post</a>
</nav>
@ -147,13 +147,17 @@ class App extends Component {
Declare a function by writing <code class="inline fixed
block">DISCOVER HOW TO ... WITH</code>. Truly, a more
gripping way to declare a function can't possibly exist!
</li>
<li>
Assign to a variable by writing <code class="inline fixed
Similarly, assign to a variable with <code class="inline fixed
block">EXPERTS CLAIM ... TO BE</code>. On the Internet,
anyone can be an expert, and Tabloid gives YOU the power to
wield that responsibility and declare anything you'd like!
</li>
<li>
There are <strong>no built-in constructs for looping</strong>. The news
cycle is moving too fast! Nobody has time for yesterday's
loops or last week's break statements. If you must loop,
use recursion.
</li>
<li>
To return from a function, simply write <code class="inline
fixed block">SHOCKING DEVELOPMENT</code>! You're going
@ -203,6 +207,8 @@ class App extends Component {
<li><code class="inline fixed block">END OF STORY</code> end a block scope</li>
<li><code class="inline fixed block">EXPERTS CLAIM...TO BE</code> declare or assign to a variable</li>
<li><code class="inline fixed block">YOU WON'T WANT TO MISS</code> print output</li>
<li><code class="inline fixed block">TOTALLY RIGHT</code> true</li>
<li><code class="inline fixed block">COMPLETELY WRONG</code> false</li>
<li><code class="inline fixed block">IS ACTUALLY</code> is equal to</li>
<li><code class="inline fixed block">BEATS / SMALLER THAN</code> greater than / less than</li>
<li><code class="inline fixed block">SHOCKING DEVELOPMENT</code> return from a function</li>