mirror of
https://github.com/remko/waforth
synced 2024-12-27 09:59:29 +01:00
Support reading long strings
This commit is contained in:
parent
ff84035919
commit
236ad04aa5
3 changed files with 57 additions and 38 deletions
|
@ -2758,14 +2758,16 @@
|
||||||
(local $result i32)
|
(local $result i32)
|
||||||
(local $tos i32)
|
(local $tos i32)
|
||||||
(local.tee $tos (global.get $tos))
|
(local.tee $tos (global.get $tos))
|
||||||
|
(block $endLoop (param i32) (result i32)
|
||||||
|
(loop $loop (param i32) (result i32)
|
||||||
(call $REFILL)
|
(call $REFILL)
|
||||||
(drop (call $pop))
|
(br_if $endLoop (i32.eqz (call $pop)))
|
||||||
(local.set $result (call $interpret))
|
(local.set $result (call $interpret))
|
||||||
(global.set $tos)
|
(local.set $tos)
|
||||||
|
|
||||||
;; Check for stack underflow
|
;; Check for stack underflow
|
||||||
(if (i32.lt_s (global.get $tos) (i32.const 0x10000 (; = STACK_BASE ;)))
|
(if (i32.lt_s (local.get $tos) (i32.const 0x10000 (; = STACK_BASE ;)))
|
||||||
(drop (call $fail (global.get $tos) (i32.const 0x200B2 (; stack empty ;)))))
|
(drop (call $fail (local.get $tos) (i32.const 0x200B2 (; stack empty ;)))))
|
||||||
|
|
||||||
(if (i32.ge_s (local.get $result) (i32.const 0))
|
(if (i32.ge_s (local.get $result) (i32.const 0))
|
||||||
(then
|
(then
|
||||||
|
@ -2780,6 +2782,9 @@
|
||||||
(call $shell_emit (i32.const 111))
|
(call $shell_emit (i32.const 111))
|
||||||
(call $shell_emit (i32.const 114))))
|
(call $shell_emit (i32.const 114))))
|
||||||
(call $shell_emit (i32.const 10))
|
(call $shell_emit (i32.const 10))
|
||||||
|
(local.get $tos)
|
||||||
|
(br $loop)))
|
||||||
|
(global.set $tos)
|
||||||
(local.get $result))
|
(local.get $result))
|
||||||
|
|
||||||
(func (export "push") (param $v i32)
|
(func (export "push") (param $v i32)
|
||||||
|
|
|
@ -222,6 +222,15 @@ function loadTests() {
|
||||||
expect(() => core.interpret()).to.throw();
|
expect(() => core.interpret()).to.throw();
|
||||||
expect(output.trim()).to.eql("undefined word: 23FOO");
|
expect(output.trim()).to.eql("undefined word: 23FOO");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should interpret a long string", () => {
|
||||||
|
const p = ["1"];
|
||||||
|
for (let i = 0; i < 1000; i++) {
|
||||||
|
p.push(`${1} +`);
|
||||||
|
}
|
||||||
|
forth.interpret(p.join("\n"));
|
||||||
|
expect(stackValues()).to.eql([1001]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("DUP", () => {
|
describe("DUP", () => {
|
||||||
|
|
|
@ -46,7 +46,7 @@ function saveString(s: string, memory: WebAssembly.Memory, addr: number) {
|
||||||
* */
|
* */
|
||||||
class WAForth {
|
class WAForth {
|
||||||
core?: WebAssembly.Instance;
|
core?: WebAssembly.Instance;
|
||||||
#buffer?: number[];
|
#buffer?: string;
|
||||||
#fns: Record<string, (f: WAForth) => void>;
|
#fns: Record<string, (f: WAForth) => void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +96,7 @@ class WAForth {
|
||||||
async load() {
|
async load() {
|
||||||
let table: WebAssembly.Table;
|
let table: WebAssembly.Table;
|
||||||
let memory: WebAssembly.Memory;
|
let memory: WebAssembly.Memory;
|
||||||
this.#buffer = [];
|
this.#buffer = "";
|
||||||
|
|
||||||
const instance = await WebAssembly.instantiate(wasmModule, {
|
const instance = await WebAssembly.instantiate(wasmModule, {
|
||||||
shell: {
|
shell: {
|
||||||
|
@ -111,17 +111,22 @@ class WAForth {
|
||||||
},
|
},
|
||||||
|
|
||||||
read: (addr: number, length: number): number => {
|
read: (addr: number, length: number): number => {
|
||||||
let data = new Uint8Array(
|
let input: string;
|
||||||
(this.core!.exports.memory as WebAssembly.Memory).buffer,
|
if (this.#buffer!.length <= length) {
|
||||||
addr,
|
input = this.#buffer!;
|
||||||
length
|
this.#buffer = "";
|
||||||
);
|
} else {
|
||||||
let n = 0;
|
const i = this.#buffer!.lastIndexOf("\n", length - 1);
|
||||||
while (this.#buffer!.length > 0 && n < length) {
|
input = this.#buffer!.substring(0, i + 1);
|
||||||
data[n] = this.#buffer!.shift()!;
|
this.#buffer = this.#buffer!.substring(i + 1);
|
||||||
n += 1;
|
|
||||||
}
|
}
|
||||||
return n;
|
// console.log("read: %s (%d remaining)", input, this.#buffer!.length);
|
||||||
|
saveString(
|
||||||
|
input,
|
||||||
|
this.core!.exports.memory as WebAssembly.Memory,
|
||||||
|
addr
|
||||||
|
);
|
||||||
|
return input.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
key: () => {
|
key: () => {
|
||||||
|
@ -215,16 +220,16 @@ class WAForth {
|
||||||
* Read data `s` into the input buffer without interpreting it.
|
* Read data `s` into the input buffer without interpreting it.
|
||||||
*/
|
*/
|
||||||
read(s: string) {
|
read(s: string) {
|
||||||
const data = new TextEncoder().encode(s);
|
this.#buffer = this.#buffer + s;
|
||||||
for (let i = 0, len = data.length; i < len; ++i) {
|
|
||||||
this.#buffer!.push(data[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read data `s` into the input buffer, and interpret.
|
* Read data `s` into the input buffer, and interpret.
|
||||||
*/
|
*/
|
||||||
interpret(s: string) {
|
interpret(s: string) {
|
||||||
|
if (!s.endsWith("\n")) {
|
||||||
|
s = s + "\n";
|
||||||
|
}
|
||||||
this.read(s);
|
this.read(s);
|
||||||
try {
|
try {
|
||||||
return (this.core!.exports.interpret as any)();
|
return (this.core!.exports.interpret as any)();
|
||||||
|
|
Loading…
Reference in a new issue