Skip to content

Commit c8a6647

Browse files
committed
Implemented RET. Functions now work end to end
1 parent 6f325c9 commit c8a6647

File tree

7 files changed

+71
-3
lines changed

7 files changed

+71
-3
lines changed

src/commands/call.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class Call extends Command {
2525
*/
2626
execute(regs, flags, stack, programCounter) {
2727
stack.push(programCounter.getNextLineNumber());
28+
programCounter.setNextLineByName(this.fnName);
29+
return { regs, flags };
2830
}
2931
}
3032

src/commands/commandFactories.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const PrnReg = require('./prnReg.js');
2222
const Push = require('./push.js');
2323
const Pop = require('./pop.js');
2424
const Func = require('./func.js');
25+
const Call = require('./call.js');
26+
const Ret = require('./ret.js');
2527

2628
const isRegister = arg => arg.toString().match(/^[ABCD]$/i);
2729
const isNumericalValue = arg => arg.toString().match(/^[0-9]+$/i);
@@ -142,4 +144,17 @@ factories.func = args => {
142144
return new Func(args[0].toUpperCase());
143145
};
144146

147+
factories.call = args => {
148+
if (args.length != 1 || !isValidFunctionName(args[0]))
149+
throw new InvalidInstructionException();
150+
151+
return new Call(args[0].toUpperCase());
152+
};
153+
154+
factories.ret = args => {
155+
if (args.length != 0) throw new InvalidInstructionException();
156+
157+
return new Ret();
158+
};
159+
145160
module.exports = factories;

src/commands/ret.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const Command = require('./command.js');
2+
3+
class Ret extends Command {
4+
execute(regs, flags, stack, pc) {
5+
let retLine = stack.pop();
6+
pc.setNextLine(retLine);
7+
return { regs, flags };
8+
}
9+
}
10+
11+
module.exports = Ret;

src/lines.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class Lines {
1515
let { regs, flags, stack } = initState;
1616
let state = { regs, flags, halt: false };
1717
let lineNumbers = this.lines.map(l => l.getLineNumber());
18-
let programCounter = new ProgramCounter(lineNumbers);
18+
console.log(this.fnTable);
19+
let programCounter = new ProgramCounter(lineNumbers, this.fnTable);
1920
let executor = () => {
2021
let line = this.lines[programCounter.getCurrentLineIndex()];
2122
state = line.execute(state.regs, state.flags, stack, programCounter);

test/testCall.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,14 @@ describe('Call execution', () => {
1313
call.execute(currRegs, currFlags, stack, pc);
1414
assert.deepEqual(['20'], stack.asArray());
1515
});
16+
17+
it('should modify the program counter to reflect the new line to jump to', () => {
18+
let currFlags = { EQ: 0, NE: 0, LT: 0, GT: 0 };
19+
let currRegs = { A: 0, B: 0, C: 0, D: 0 };
20+
let stack = new Stack();
21+
let pc = new ProgramCounter([10, 20, 30], { MUL: '30' });
22+
let call = new Call('MUL');
23+
call.execute(currRegs, currFlags, stack, pc);
24+
assert.equal('30', pc.getNextLineNumber());
25+
});
1626
});

test/testMachine.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,20 +487,21 @@ describe('Source mapping at the machine level', function() {
487487
});
488488
});
489489

490-
describe.skip('Machine with functions', () => {
490+
describe('Machine with functions', () => {
491491
it('should execute a basic function', () => {
492492
const machine = new Machine();
493493
const program = [
494494
'10 START',
495495
'20 JMP 60',
496496
'30 FUNC A10',
497497
'40 MOV A,10',
498+
'41 ADD A,20',
498499
'50 RET',
499500
'60 CALL A10',
500501
'70 STOP'
501502
];
502503
machine.load(stitch(program));
503504
machine.execute();
504-
assert.deepEqual({ A: 10, B: 0, C: 0, D: 0 }, machine.getRegs());
505+
assert.deepEqual({ A: 30, B: 0, C: 0, D: 0 }, machine.getRegs());
505506
});
506507
});

test/testRet.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const assert = require('assert');
2+
const Ret = require('../src/commands/ret.js');
3+
const Stack = require('../src/stack.js');
4+
const ProgramCounter = require('../src/programCounter.js');
5+
6+
describe('Ret execution', () => {
7+
it('should remove the line number to return to from the stack', () => {
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('30');
12+
let pc = new ProgramCounter([10, 20, 30], { MUL: '30' });
13+
let ret = new Ret('MUL');
14+
ret.execute(currRegs, currFlags, stack, pc);
15+
assert.deepEqual([], stack.asArray());
16+
});
17+
18+
it('should change the program counter to reflect the line to return to', () => {
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('30');
23+
let pc = new ProgramCounter([10, 20, 30], { MUL: '30' });
24+
let ret = new Ret('MUL');
25+
ret.execute(currRegs, currFlags, stack, pc);
26+
assert.deepEqual('30', pc.getNextLineNumber());
27+
});
28+
});

0 commit comments

Comments
 (0)