Browse Source

LOOPY LOOP

feature/flow-control
mark 8 months ago
parent
commit
8913c1daf9
4 changed files with 59 additions and 5 deletions
  1. +2
    -1
      dictionary.js
  2. +2
    -1
      index.js
  3. +38
    -1
      memeforth.js
  4. +17
    -2
      test/memeforth.test.js

+ 2
- 1
dictionary.js View File

@@ -477,7 +477,8 @@ const dictionary = {
OR: or,
NOT: not,
":": colon,
SLICE: strSlice
SLICE: strSlice,
I: "_I @".split(" ")
};

module.exports = dictionary;

+ 2
- 1
index.js View File

@@ -7,4 +7,5 @@ module.exports = {
interpret: mf.interpret
};

module.exports.dictionary["IF"] = mf.ifword;
module.exports.dictionary["IF"] = mf.ifword;
module.exports.dictionary["DO"] = mf.doWord;

+ 38
- 1
memeforth.js View File

@@ -2,6 +2,7 @@

const dictionary = require("./dictionary");

// TODO: Ensure IF/DO constructs can only be done in compile mode.
const ifword = state => {
const condition = state.stack.pop();
let ifBody = [];
@@ -32,7 +33,42 @@ const ifword = state => {
state = interpret(innerState);
}
}

return state;
};

const doLoop = state => {
const begin = state.stack.pop();
const end = state.stack.pop();
const incr = "_I @ 1 + _I !".split(" ");
let newState;

if (!state.words["_I"]) {
const oldTokens = state.tokens;
const init = `_I DEFVAR ${begin} _I !`.split(" ");
newState = state;
newState.tokens = init;
state = interpret(newState);
state.tokens = oldTokens;
} else {
const oldTokens = state.tokens;
const init = `${begin} _I !`.split(" ");
newState = state;
newState.tokens = init;
state = interpret(newState);
state.tokens = oldTokens;
}

const loopBody = state.tokens.slice(0, state.tokens.indexOf("LOOP"));

for (let i = begin; i < end; i++) {
newState = state;
newState.tokens = loopBody;
newState = interpret(newState);
newState.tokens = incr;
state = interpret(newState);
}

return state;
};

@@ -58,6 +94,7 @@ const interpret = state => {
if (!state.output) state.output = "";

state.words["IF"] = ifword;
state.words["DO"] = doLoop;

let copytok = state.tokens.slice(0);



+ 17
- 2
test/memeforth.test.js View File

@@ -1,4 +1,4 @@
const mf = require("../memeforth");
const mf = require("../index");
const expect = require("expect.js");

describe("interpreter", () => {
@@ -228,7 +228,7 @@ describe("interpreter", () => {
});

it("should run SLICE", () => {
const prog = "yeet 1 3 SLICE"
const prog = "yeet 1 3 SLICE";
expect(mf.run(prog).stack).to.eql(["ee"]);
});
});
@@ -346,5 +346,20 @@ describe("interpreter", () => {
":sm64_y: :sm64_e: :sm64_e: :sm64_t:"
]);
});

it("should compile and perform DO loops", () => {
const program = "10 0 DO _I @ . LOOP";
const result = mf.run(program);

expect(result.memory).to.not.be.empty();
expect(result.output).to.be("0 1 2 3 4 5 6 7 8 9");
});

it("should use the I keyword within loops", () => {
const program = "10 0 DO I . LOOP";
const result = mf.run(program);

expect(result.output).to.be("0 1 2 3 4 5 6 7 8 9");
});
});
});

Loading…
Cancel
Save