Skip to content

Commit

Permalink
JOKE step2-3.
Browse files Browse the repository at this point in the history
  • Loading branch information
junjis0203 committed May 17, 2020
1 parent 7f1e00e commit 443f5ca
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ Self hosting.
# Current status

* Can call "native" method
* Variable(const and let. no var and don't allow no declaration)
11 changes: 9 additions & 2 deletions lib/assembler.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ function assembleNode(node, insns) {
{
for (const statement of node.statements) {
assembleNode(statement, insns);
// maybe only pop if statement is expression
insns.push({command: 'POP'});
}
}
break;
case 'EXPRESSION_STATEMENT':
assembleNode(node.expression, insns);
insns.push({command: 'POP'});
break;
case 'MEMBER':
assembleNode(node.object, insns);
insns.push({command: 'PUSH', operand: node.property});
Expand Down Expand Up @@ -50,6 +52,11 @@ function assembleNode(node, insns) {
insns.push({command: 'PUSH', operand: node.left.identifier});
insns.push({command: 'ASSIGN'});
break;
case 'BLOCK':
insns.push({command: 'PUSH_SCOPE'});
assembleNode(node.block, insns);
insns.push({command: 'POP_SCOPE'});
break;
default:
throw new Error(`Unknown node type: ${node.type}`);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export function createScope() {
},
setObject(name, value, initialize=false) {
const object = this[name];
if (!object) {
throw new ReferenceError(name);
}
if (!initialize && object.declarationType == 'const') {
throw new TypeError('Assignment to const');
}
Expand Down
29 changes: 27 additions & 2 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,17 +246,42 @@ function Expression(scanner) {
// support comma?
}

function Block(scanner) {
if (checkCharToken(scanner.token, '{')) {
scanner.next();
let node = StatementList(scanner);
assertCharToken(scanner, '}');
node = {
type: 'BLOCK',
block: node
};
return node;
}
}

function BlockStatement(scanner) {
return Block(scanner);
}

function ExpressionStatement(scanner) {
// TODO: check current token is not {, function, class, let [
const node = Expression(scanner);
let node = Expression(scanner);
if (node) {
node = {
type: 'EXPRESSION_STATEMENT',
expression: node
};
assertSemicolon(scanner);
}
return node;
}

function Statement(scanner) {
let node;
node = BlockStatement(scanner);
if (node) {
return node;
}
node = ExpressionStatement(scanner);
if (node) {
return node;
Expand Down Expand Up @@ -352,7 +377,7 @@ function StatementList(scanner) {
break;
}
// how to regognize end?
if (scanner.token.type == 'END') {
if (scanner.token.type == 'END' || checkCharToken(scanner.token, '}')) {
break;
}
}
Expand Down
8 changes: 8 additions & 0 deletions lib/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ function validateNode(node, scopes) {
}
}
break;
case 'BLOCK':
{
const newScope = {};
scopes.unshift(newScope);
validateNode(node.block, scopes);
scopes.shift();
}
break;
}
}

Expand Down
11 changes: 11 additions & 0 deletions lib/vm.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { createScope } from './object.js';

function lookupObject(scopes, name) {
for (const scope of scopes) {
const object = scope.getObject(name);
Expand Down Expand Up @@ -40,6 +42,15 @@ function executeInsn(insn, stack, scopes) {
stack.push(value);
}
break;
case 'PUSH_SCOPE':
{
const newScope = createScope();
scopes.unshift(newScope);
}
break;
case 'POP_SCOPE':
scopes.shift();
break;
case 'LOOKUP':
{
const objectName = stack.pop();
Expand Down
10 changes: 10 additions & 0 deletions step/step0002_03.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
Lexical scope.
*/
const s1 = "foo";
const s2 = "bar";

{
const s1 = "FOO";
console.log(s1, s2);
}
1 change: 1 addition & 0 deletions step/step0002_03.js.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FOO bar

0 comments on commit 443f5ca

Please sign in to comment.