diff --git a/src/standard-testsuite/core.f b/src/standard-testsuite/core.f index dc96731..c91e3f2 100644 --- a/src/standard-testsuite/core.f +++ b/src/standard-testsuite/core.f @@ -971,17 +971,17 @@ T{ OUTPUT-TEST -> }T \ ------------------------------------------------------------------------ \ TESTING INPUT: ACCEPT -\ -\ CREATE ABUF 50 CHARS ALLOT -\ -\ : ACCEPT-TEST -\ CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR -\ ABUF 50 ACCEPT -\ CR ." RECEIVED: " [CHAR] " EMIT -\ ABUF SWAP TYPE [CHAR] " EMIT CR -\ ; -\ -\ T{ ACCEPT-TEST -> }T + +CREATE ABUF 50 CHARS ALLOT + +: ACCEPT-TEST + CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR + ABUF 50 ACCEPT + CR ." RECEIVED: " [CHAR] " EMIT + ABUF SWAP TYPE [CHAR] " EMIT CR +; + +T{ ACCEPT-TEST -> }T \ ------------------------------------------------------------------------ TESTING DICTIONARY SEARCH RULES diff --git a/src/waforth.wat b/src/waforth.wat index a934749..a2bf2ef 100644 --- a/src/waforth.wat +++ b/src/waforth.wat @@ -15,8 +15,6 @@ (import "shell" "emit" (func $shell_emit (param i32))) (import "shell" "getc" (func $shell_getc (result i32))) (import "shell" "key" (func $shell_key (result i32))) - (import "shell" "accept" (func $shell_accept (param i32) (param i32) (result i32))) - ;; (import "shell" "debug" (func $shell_debug (param i32))) ;; Load a webassembly module. ;; Parameters: memory offset, size, table index where the new module will @@ -712,9 +710,23 @@ (func $ACCEPT (param $tos i32) (result i32) (local $btos i32) (local $bbtos i32) - (i32.store (local.tee $bbtos (i32.sub (local.get $tos) (i32.const 8))) - (call $shell_accept (i32.load (local.get $bbtos)) - (i32.load (local.tee $btos (i32.sub (local.get $tos) (i32.const 4)))))) + (local $addr i32) + (local $p i32) + (local $endp i32) + (local $c i32) + (local.set $endp + (i32.add + (local.tee $addr (i32.load (local.tee $bbtos (i32.sub (local.get $tos) (i32.const 8))))) + (i32.load (local.tee $btos (i32.sub (local.get $tos) (i32.const 4)))))) + (local.set $p (local.get $addr)) + (block $endLoop + (loop $loop + (br_if $endLoop (i32.eq (local.tee $c (call $shell_key)) (i32.const 0xa))) + (i32.store8 (local.get $p) (local.get $c)) + (local.set $p (i32.add (local.get $p) (i32.const 1))) + (call $shell_emit (local.get $c)) + (br_if $loop (i32.lt_u (local.get $p) (local.get $endp))))) + (i32.store (local.get $bbtos) (i32.sub (local.get $p) (local.get $addr))) (local.get $btos)) (data (i32.const 135744) "4\12\02\00" "\06" "ACCEPT\00" "<\00\00\00") (elem (i32.const 0x3c) $ACCEPT) diff --git a/src/web/tests/suite.js b/src/web/tests/suite.js index ff2d625..45f4018 100644 --- a/src/web/tests/suite.js +++ b/src/web/tests/suite.js @@ -14,6 +14,14 @@ function loadTests() { output = output + c; // console.log(output); }; + let k = 0; + const keyString = + "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + forth.key = () => { + const c = keyString.charCodeAt(k); + k = (k + 1) % keyString.length; + return c; + }; const x = forth.load().then( () => { core = forth.core.exports; @@ -1576,6 +1584,9 @@ function loadTests() { "YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:\n SIGNED: -80000000 7FFFFFFF \n" ); expect(output).to.include("UNSIGNED: 0 FFFFFFFF \n"); + expect(output).to.include( + `RECEIVED: "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr"\n` + ); }); }); }); diff --git a/src/web/waforth.ts b/src/web/waforth.ts index 8dd80b4..72c51d6 100644 --- a/src/web/waforth.ts +++ b/src/web/waforth.ts @@ -55,6 +55,7 @@ class WAForth { * `c` is the ASCII code of the character to be emitted. */ onEmit?: (c: string) => void; + key: () => number; constructor() { this.#fns = {}; @@ -70,6 +71,21 @@ class WAForth { } }; })(); + + const keyBuffer: string[] = []; + this.key = () => { + while (keyBuffer.length === 0) { + const c = window.prompt("Enter text"); + if (c == null) { + continue; + } + keyBuffer.push(...c.split("")); + if (c.length === 0 || c.length > 1) { + keyBuffer.push("\n"); + } + } + return keyBuffer.shift()!.charCodeAt(0); + }; } /** @@ -101,26 +117,8 @@ class WAForth { return buffer.pop(); }, - debug: (d: number) => { - console.log("DEBUG: ", d, String.fromCharCode(d)); - }, - key: () => { - let c: string | null = null; - while (c == null || c == "") { - c = window.prompt("Enter character"); - } - return c.charCodeAt(0); - }, - - accept: (p: number, n: number) => { - const input = (window.prompt("Enter text") || "").substring(0, n); - const target = new Uint8Array(memory.buffer, p, input.length); - for (let i = 0; i < input.length; ++i) { - target[i] = input.charCodeAt(i); - } - console.log("ACCEPT", p, n, input.length); - return input.length; + return this.key(); }, ////////////////////////////////////////