Skip to content

Commit

Permalink
added tests for return operator #145
Browse files Browse the repository at this point in the history
  • Loading branch information
tmptrash committed May 10, 2018
1 parent b65be38 commit e25a1df
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 96 deletions.
14 changes: 8 additions & 6 deletions client/src/vm/Operators.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Num = require('./Num');
const Helper = require('./../../../common/src/Helper');

const OPERATOR_AMOUNT = 11;
const MAX_STACK_SIZE = 10000;
const MAX_STACK_SIZE = 30000;

class Operators {
/**
Expand Down Expand Up @@ -288,7 +288,7 @@ class Operators {
const data = num << ${opBits};
const offs = this.funcs[(data >>> ${ifBit}) & 1 === 0 ? ((this.vars[data << 1 >>> ${varBits}] + .5) << 0 >>> 0) % ${funcs} : data << 1 >>> ${fnBits}];
if (typeof offs !== 'undefined') {
if (this.stack.length > ${MAX_STACK_SIZE} * 3) {
if (this.stack.length > ${MAX_STACK_SIZE}) {
org.energy -= org.vm.size;
return ++line;
}
Expand All @@ -304,7 +304,8 @@ class Operators {
* Compiles all variants of return operator and stores they in
* this._compiledOperators map. 'xx' means, that amount of bits
* depends on configuration. '...' means, that all other bits are
* ignored. Example:
* ignored. Returns fro custom function. If returns appears outside
* the function, then interpreter jumps into zero line. Example:
*
* bits : 6
* number: 100111 ...
Expand All @@ -316,12 +317,13 @@ class Operators {
const vars = Math.pow(2, OConfig.codeBitsPerVar);

eval(`Operators.global.fn = function ret(line) {
if (this.stack.length > 0) {
const stackVars = this.stack.pop();
const stack = this.stack;
if (stack.length > 0) {
const stackVars = stack.pop();
const vars = this.vars;
for (let i = 0; i < ${vars}; i++) {vars[i] = stackVars[i]}
stack.pop();
return this.stack.pop();
return stack.pop();
}
return 0;
}`);
Expand Down
195 changes: 105 additions & 90 deletions client/src/vm/OperatorsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -880,101 +880,101 @@ describe("client/src/vm/Operators", () => {
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 1)).toEqual(3);
});
});

xdescribe('function declaration 3bits per var', () => {
let bpv;
let ops;
let vars;
let offs;
beforeAll (() => {
bpv = OConfig.codeBitsPerVar;
OConfig.codeBitsPerVar = 3;
Operators.compile();
});
afterAll (() => Operators.compile());
beforeEach(() => {
vars = [0,1,2,3,4,5,6,7];
offs = new Array(10);
ops = new Operators(offs, vars);
});
afterEach (() => {
ops.destroy();
ops = null;
offs = null;
vars = null;
OConfig.codeBitsPerVar = bpv;
});
xdescribe('function declaration 3bits per var', () => {
let bpv;
let ops;
let vars;
let offs;
beforeAll (() => {
bpv = OConfig.codeBitsPerVar;
OConfig.codeBitsPerVar = 3;
Operators.compile();
});
afterAll (() => Operators.compile());
beforeEach(() => {
vars = [0,1,2,3,4,5,6,7];
offs = new Array(10);
ops = new Operators(offs, vars);
});
afterEach (() => {
ops.destroy();
ops = null;
offs = null;
vars = null;
OConfig.codeBitsPerVar = bpv;
});

it('Func declaration should be skipped during run', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1() {
h('100000 000 001 11111111111111111111'), // v0 = v1
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(3);
});
it('Two func declaration should be skipped during run', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('100000 000 001 11111111111111111111'), // v0 = v1
h('101000 00000000000000000000000000'), // }
h('100101 00000001 000000000000000000'), // func 2() {
h('100000 000 001 11111111111111111111'), // v0 = v1
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(3);
expect(ops.operators[h('100101')].call(ops, 3)).toEqual(6);
});
it('func inside func should work', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('100101 00000001 000000000000000000'), // func 2 {
h('101000 00000000000000000000000000'), // }
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 1)).toEqual(3);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(4);
});
it('func without closed bracket should work', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('100000 000 001 11111111111111111111') // v0 = v1
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(1);
});
it('one line func should work', () => {
const code = [
h('100101 00000001 000000000000000000') // func 1 {
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(1);
});
it('func with two closed brackets should work', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('101000 00000000000000000000000000'), // }
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(2);
});
it('func with two closed brackets should work', () => {
const code = [
h('101000 00000000000000000000000000'), // }
h('100101 00000001 000000000000000000'), // func 1 {
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 1)).toEqual(3);
it('Func declaration should be skipped during run', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1() {
h('100000 000 001 11111111111111111111'), // v0 = v1
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(3);
});
it('Two func declaration should be skipped during run', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('100000 000 001 11111111111111111111'), // v0 = v1
h('101000 00000000000000000000000000'), // }
h('100101 00000001 000000000000000000'), // func 2() {
h('100000 000 001 11111111111111111111'), // v0 = v1
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(3);
expect(ops.operators[h('100101')].call(ops, 3)).toEqual(6);
});
it('func inside func should work', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('100101 00000001 000000000000000000'), // func 2 {
h('101000 00000000000000000000000000'), // }
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 1)).toEqual(3);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(4);
});
it('func without closed bracket should work', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('100000 000 001 11111111111111111111') // v0 = v1
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(1);
});
it('one line func should work', () => {
const code = [
h('100101 00000001 000000000000000000') // func 1 {
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(1);
});
it('func with two closed brackets should work', () => {
const code = [
h('100101 00000001 000000000000000000'), // func 1 {
h('101000 00000000000000000000000000'), // }
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(2);
});
it('func with two closed brackets should work', () => {
const code = [
h('101000 00000000000000000000000000'), // }
h('100101 00000001 000000000000000000'), // func 1 {
h('101000 00000000000000000000000000') // }
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 1)).toEqual(3);
});
});
});

describe('function call 2bits per var', () => {
xdescribe('function call', () => {
it('Func call should work', () => {
const code = [
h('100101 00000000000000000000000000'), // func 0() {
Expand Down Expand Up @@ -1014,4 +1014,19 @@ describe("client/src/vm/Operators", () => {
expect(ops.operators[h('101000')].call(ops, 2, code[2], {}, code)).toEqual(5);
});
});

describe('return', () => {
it('Func call should work', () => {
const code = [
h('100101 00000000000000000000000000'), // func 0() {
h('100111 00000000000000000000000000'), // return
h('101000 00000000000000000000000000'), // }
h('100110 1 00000000 00000000000000000') // call 0()
];
ops.updateIndexes(code);
expect(ops.operators[h('100101')].call(ops, 0)).toEqual(3);
expect(ops.operators[h('100110')].call(ops, 3, code[3], {}, code)).toEqual(1);
expect(ops.operators[h('100111')].call(ops, 1, code[1], {}, code)).toEqual(4);
});
});
});

0 comments on commit e25a1df

Please sign in to comment.