Skip to content

Commit a6d86da

Browse files
committed
Added a stack, push and pop. Only instructions. Not wired to machine yet
1 parent 8f997d5 commit a6d86da

File tree

7 files changed

+199
-0
lines changed

7 files changed

+199
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
out/
2+
.vscode
13
.nyc_output/
24
node_modules/
35
.DS_Store

src/commands/pop.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* The Pop command pops the stack and puts the popped value into the given register at execution time.
3+
*/
4+
class Pop {
5+
/**
6+
* Keeps note of the register to pop into from the stack
7+
* @param {string} reg - The register to push into
8+
*/
9+
constructor(reg) {
10+
this.reg = reg;
11+
}
12+
13+
/**
14+
* Execute will pop the top of the stack and stores the value in the register specified.
15+
* @param {Object} currRegs - The current state of the registers
16+
* @param {Object} currFlags - The current state of the flags
17+
* @param {Object} stack - The stack
18+
* @returns {Object} current registers and current flags are returned unchanged with the popped value in the specified register
19+
*/
20+
execute(currRegs, currFlags, stack) {
21+
let {A,B,C,D} = currRegs;
22+
let newRegs = {A,B,C,D};
23+
let value = stack.pop();
24+
newRegs[this.reg] = value;
25+
return { regs: newRegs, flags: currFlags };
26+
}
27+
}
28+
29+
module.exports = Pop;

src/commands/push.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* The Push command pushes a given register on to the stack at execution time.
3+
*/
4+
class Push {
5+
/**
6+
* Keeps note of the register to push onto stack
7+
* @param {string} reg - The register to push onto the stack
8+
*/
9+
constructor(reg) {
10+
this.reg = reg;
11+
}
12+
13+
/**
14+
* Execute will push the value of the register specified in the constructor onto the stack.
15+
* @param {Object} currRegs - The current state of the registers
16+
* @param {Object} currFlags - The current state of the flags
17+
* @param {Object} stack - The stack
18+
* @returns {Object} current registers and current flags are returned unchanged
19+
*/
20+
execute(currRegs, currFlags, stack) {
21+
let value = currRegs[this.reg];
22+
stack.push(value);
23+
return { regs: currRegs, flags: currFlags };
24+
}
25+
}
26+
27+
module.exports = Push;

src/stack.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* A simple Stack representation that Machine will use to keep track of a call stack
3+
*/
4+
class Stack {
5+
/**
6+
* Initialises a stack
7+
*/
8+
constructor() {
9+
this.stack = [];
10+
}
11+
12+
/**
13+
* Pushes the given value onto the stack
14+
* @param {number} value - The value to be pushed onto a stack.
15+
*/
16+
push(value) {
17+
this.stack.push(value);
18+
}
19+
20+
/**
21+
* Pops the topmost value from the stack
22+
* @returns {number}
23+
*/
24+
pop() {
25+
return this.stack.pop();
26+
}
27+
28+
/**
29+
* Returns an array representation of the stack
30+
* @returns {number[]} The stack represented as an array with the last number pushed at the tail of the array and the first number pushed at the head of the array.
31+
*/
32+
asArray() {
33+
return this.stack.map(a => a);
34+
}
35+
}
36+
37+
module.exports = Stack;

test/testPop.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const assert = require('assert');
2+
const Pop = require('../src/commands/pop.js');
3+
const Stack = require('../src/stack.js');
4+
5+
describe('Pop execution', () => {
6+
it('should pop from the stack to the A register', () => {
7+
let pop = new Pop('A');
8+
let currFlags = { EQ: 0, NE: 0, LT: 0, GT: 0 };
9+
let currRegs = { A: 0, B: 0, C: 0, D: 0 };
10+
let stack = new Stack();
11+
stack.push(10)
12+
let {regs} = pop.execute(currRegs, currFlags, stack);
13+
assert.deepEqual([], stack.asArray());
14+
assert.deepEqual({ A: 10, B: 0, C: 0, D: 0 },regs);
15+
});
16+
17+
it('should pop from the stack to the B register', () => {
18+
let pop = new Pop('B');
19+
let currFlags = { EQ: 0, NE: 0, LT: 0, GT: 0 };
20+
let currRegs = { A: 0, B: 0, C: 0, D: 0 };
21+
let stack = new Stack();
22+
stack.push(10)
23+
let {regs} = pop.execute(currRegs, currFlags, stack);
24+
assert.deepEqual([], stack.asArray());
25+
assert.deepEqual({ A: 0, B: 10, C: 0, D: 0 },regs);
26+
});
27+
28+
it('should not modify the current flags', () => {
29+
let pop = new Pop('A');
30+
let currFlags = { EQ: 0, NE: 0, LT: 0, GT: 0 };
31+
let currRegs = { A: 0, B: 0, C: 0, D: 0 };
32+
let stack = new Stack();
33+
stack.push(10)
34+
let {regs,flags} = pop.execute(currRegs, currFlags, stack);
35+
assert.deepEqual([], stack.asArray());
36+
assert.deepEqual({ A: 10, B: 0, C: 0, D: 0 },regs);
37+
assert.deepEqual({ EQ: 0, NE: 0, LT: 0, GT: 0 },flags);
38+
});
39+
});

test/testPush.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const assert = require('assert');
2+
const Push = require('../src/commands/push.js');
3+
const Stack = require('../src/stack.js');
4+
5+
describe('Push execution', () => {
6+
it('should push the A register to stack', () => {
7+
let push = new Push('A');
8+
let currFlags = { EQ: 0, NE: 0, LT: 0, GT: 0 };
9+
let currRegs = { A: 10, B: 0, C: 0, D: 0 };
10+
let stack = new Stack();
11+
push.execute(currRegs, currFlags, stack);
12+
assert.deepEqual([10], stack.asArray());
13+
});
14+
15+
it('should push the B register to stack', () => {
16+
let push = new Push('B');
17+
let currFlags = { EQ: 0, NE: 0, LT: 0, GT: 0 };
18+
let currRegs = { A: 0, B: 10, C: 0, D: 0 };
19+
let stack = new Stack();
20+
push.execute(currRegs, currFlags, stack);
21+
assert.deepEqual([10], stack.asArray());
22+
});
23+
24+
it('should not modify the current registers or flags', () => {
25+
let push = new Push('A');
26+
let currFlags = { EQ: 0, NE: 0, LT: 0, GT: 0 };
27+
let currRegs = { A: 10, B: 0, C: 0, D: 0 };
28+
let stack = new Stack();
29+
let { regs, flags } = push.execute(currRegs, currFlags, stack);
30+
assert.deepEqual({ EQ: 0, NE: 0, LT: 0, GT: 0 }, flags);
31+
assert.deepEqual({ A: 10, B: 0, C: 0, D: 0 }, regs);
32+
});
33+
});

test/testStack.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const assert = require('assert');
2+
const Stack = require('../src/stack.js');
3+
4+
describe('Stack ', () => {
5+
it('should be able to push a value on to a stack', () => {
6+
let stack = new Stack();
7+
stack.push(5);
8+
assert.deepEqual([5], stack.asArray());
9+
});
10+
11+
it('should be able to push more than one value on to a stack', () => {
12+
let stack = new Stack();
13+
stack.push(5);
14+
stack.push(6);
15+
assert.deepEqual([5, 6], stack.asArray());
16+
});
17+
18+
it('should be able to pop a value from the stack', () => {
19+
let stack = new Stack();
20+
stack.push(5);
21+
assert.equal(5, stack.pop());
22+
assert.deepEqual([], stack.asArray());
23+
});
24+
25+
it('should only pop the topmost value from the stack', () => {
26+
let stack = new Stack();
27+
stack.push(5);
28+
stack.push(6);
29+
assert.equal(6, stack.pop());
30+
assert.deepEqual([5], stack.asArray());
31+
});
32+
});

0 commit comments

Comments
 (0)