Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ Tabloid supports binary infix operators for arithmetic and logic.

`IS ACTUALLY` is a way to test equality, like `==` in most other languages. We can also make comparisons with `X BEATS Y` (`x > y`) and `X SMALLER THAN Y` (`x < y`).

We can initialize and assign variables in the current scope with `EXPERTS CLAIM...TO BE`, and reassign variables using `EVIDENCE SHOWS...TO BE`.

```
EXPERTS CLAIM your_mom TO BE 'big'
EVIDENCE SHOWS your_mom TO BE 'massive'
```

We can print the result of any expression with `YOU WON'T WANT TO MISS`. You won't want to miss what you're printing, and now you never will!

```
Expand Down
28 changes: 27 additions & 1 deletion static/js/lang.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const T = {
LiesBang: Symbol('LiesBang'),
EndOfStory: Symbol('EndOfStory'),
ExpertsClaim: Symbol('ExpertsClaim'),
EvidenceShows: Symbol('EvidenceShows'),
ToBe: Symbol('ToBe'),
YouWontWantToMiss: Symbol('YouWontWantToMiss'),
LatestNewsOn: Symbol('LatestNewsOn'),
Expand Down Expand Up @@ -189,6 +190,11 @@ function tokenize(prog) {
tokens.push(T.ExpertsClaim);
break;
}
case 'EVIDENCE': {
reader.expect('SHOWS');
tokens.push(T.EvidenceShows);
break;
}
case 'TO': {
reader.expect('BE');
tokens.push(T.ToBe);
Expand Down Expand Up @@ -477,6 +483,17 @@ class Parser {
name,
val,
}
} else if (next === T.EvidenceShows) {
// assignment
const name = this.expectIdentString();
this.tokens.expect(T.ToBe);
const val = this.expr();
return {
type: N.Assignment,
name,
val,
lookup: true,
}
} else if (next === T.ShockingDevelopment) {
// return
return {
Expand Down Expand Up @@ -613,7 +630,16 @@ class Environment {
throw new Error(`Runtime error: Undefined variable "${node.val}"`);
}
case N.Assignment: {
scope[node.name] = this.eval(node.val);
if (node.lookup) {
let i = this.scopes.length - 1;
while (i >= 0) {
if (node.name in this.scopes[i]) {
return this.scopes[i][node.name] = this.eval(node.val);
}
i --;
}
throw new Error(`Runtime error: Variable "${node.name}" does not exist`);
} else scope[node.name] = this.eval(node.val);
return scope[node.name];
}
case N.BinaryOp: {
Expand Down
6 changes: 5 additions & 1 deletion static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ class App extends Component {
</li>
<li>
<code class="inline fixed block">EXPERTS CLAIM...TO BE</code>
declare or assign to a variable
declare or assign to a variable (in the current scope)
</li>
<li>
<code class="inline fixed block">EVIDENCE SHOWS...TO BE</code>
reassign a variable
</li>
<li>
<code class="inline fixed block">YOU WON'T WANT TO MISS</code>
Expand Down