mirror of
https://github.com/remko/waforth
synced 2024-12-26 09:59:09 +01:00
Documentation
This commit is contained in:
parent
71ec9e341a
commit
5a4efef6c8
5 changed files with 40 additions and 25 deletions
|
@ -11,7 +11,7 @@
|
|||
#define CORE_TABLE_EXPORT_INDEX 0
|
||||
#define CORE_MEMORY_EXPORT_INDEX 1
|
||||
#define CORE_ERROR_EXPORT_INDEX 6
|
||||
#define CORE_INTERPRET_EXPORT_INDEX 7
|
||||
#define CORE_RUN_EXPORT_INDEX 7
|
||||
|
||||
#define ERR_UNKNOWN 0x1
|
||||
#define ERR_QUIT 0x2
|
||||
|
@ -172,8 +172,8 @@ int main(int argc, char *argv_main[]) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
const wasm_func_t *interpret_fn = wasm_extern_as_func(exports.data[CORE_INTERPRET_EXPORT_INDEX]);
|
||||
if (interpret_fn == NULL) {
|
||||
const wasm_func_t *run_fn = wasm_extern_as_func(exports.data[CORE_RUN_EXPORT_INDEX]);
|
||||
if (run_fn == NULL) {
|
||||
printf("error accessing `interpret` export\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -185,16 +185,16 @@ int main(int argc, char *argv_main[]) {
|
|||
}
|
||||
|
||||
printf("WAForth (" VERSION ")\n");
|
||||
wasm_val_t interpret_as[1] = {WASM_I32_VAL(0)};
|
||||
wasm_val_vec_t interpret_args = WASM_ARRAY_VEC(interpret_as);
|
||||
wasm_val_vec_t interpret_results = WASM_EMPTY_VEC;
|
||||
wasm_val_t run_as[1] = {WASM_I32_VAL(0)};
|
||||
wasm_val_vec_t run_args = WASM_ARRAY_VEC(run_as);
|
||||
wasm_val_vec_t run_results = WASM_EMPTY_VEC;
|
||||
|
||||
wasm_val_vec_t err_args = WASM_EMPTY_VEC;
|
||||
wasm_val_t err_results_vs[] = {WASM_INIT_VAL};
|
||||
wasm_val_vec_t err_results = WASM_ARRAY_VEC(err_results_vs);
|
||||
|
||||
for (int stopped = 0; !stopped;) {
|
||||
trap = wasm_func_call(interpret_fn, &interpret_args, &interpret_results);
|
||||
trap = wasm_func_call(run_fn, &run_args, &run_results);
|
||||
wasm_trap_t *etrap = wasm_func_call(error_fn, &err_args, &err_results);
|
||||
assert(etrap == NULL);
|
||||
switch (err_results.data[0].of.i32) {
|
||||
|
|
|
@ -2829,24 +2829,31 @@
|
|||
;; API Functions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(func (export "tos") (result i32)
|
||||
(global.get $tos))
|
||||
|
||||
(func (export "here") (result i32)
|
||||
(global.get $here))
|
||||
|
||||
(func (export "error") (result i32)
|
||||
(global.get $error))
|
||||
|
||||
(func (export "interpret") (param $silent i32)
|
||||
;; Run the interpreter loop, until no more user input is available (or until
|
||||
;; execution is aborted using QUIT)
|
||||
(func $run (export "run") (param $silent i32)
|
||||
(local $state i32)
|
||||
(local $tos i32)
|
||||
|
||||
;; Load the top-of-stack (TOS) pointer as a local, and thread it through the execution.
|
||||
;; The global TOS pointer will not be accurate until it is reset at the end of the loop,
|
||||
;; at abort time, or at shell `call` time.
|
||||
;;
|
||||
;; Put the local value on the WASM operand stack, so it is threaded through the loop.
|
||||
(local.tee $tos (global.get $tos))
|
||||
|
||||
;; In case a trap occurs, make sure the error is set to an unknown error.
|
||||
;; We'll reset the error to a real value later if no trap occurs.
|
||||
(global.set $error (i32.const 0x1 (; = ERR_UNKNOWN ;)))
|
||||
|
||||
;; Start looping until there is no more input
|
||||
(block $endLoop (param i32) (result i32)
|
||||
(loop $loop (param i32) (result i32)
|
||||
;; Fill the input buffer with user input
|
||||
(call $REFILL)
|
||||
(br_if $endLoop (i32.eqz (call $pop)))
|
||||
|
||||
;; Run the interpreter loop on the entire input buffer
|
||||
(local.set $tos (call $interpret))
|
||||
|
||||
;; Check for stack underflow
|
||||
|
@ -2871,7 +2878,11 @@
|
|||
(call $shell_emit (i32.const 10))))
|
||||
(local.get $tos)
|
||||
(br $loop)))
|
||||
|
||||
;; Reset the global TOS pointer to the current local value (still on the WASM operand stack)
|
||||
(global.set $tos)
|
||||
|
||||
;; End of input was reached
|
||||
(global.set $error (i32.const 0x4 (; = ERR_EOI ;))))
|
||||
|
||||
(func (export "push") (param $v i32)
|
||||
|
@ -2883,6 +2894,10 @@
|
|||
(global.set $tos)
|
||||
(local.get $result))
|
||||
|
||||
(func (export "tos") (result i32) (global.get $tos))
|
||||
(func (export "here") (result i32) (global.get $here))
|
||||
(func (export "error") (result i32) (global.get $error))
|
||||
|
||||
;; Used for experiments
|
||||
(func (export "set_state") (param $latest i32) (param $here i32)
|
||||
(global.set $latest (local.get $latest))
|
||||
|
|
|
@ -21,7 +21,7 @@ function run(s) {
|
|||
for (let i = data.length - 1; i >= 0; --i) {
|
||||
buffer.push(data[i]);
|
||||
}
|
||||
return core.exports.interpret();
|
||||
return core.exports.run();
|
||||
}
|
||||
|
||||
function latest() {
|
||||
|
|
|
@ -192,38 +192,38 @@ function loadTests() {
|
|||
describe("interpret", () => {
|
||||
it("should return an error when word is not found", () => {
|
||||
forth.read("BADWORD");
|
||||
expect(() => core.interpret()).to.throw();
|
||||
expect(() => core.run()).to.throw();
|
||||
expect(output.trim()).to.eql("undefined word: BADWORD");
|
||||
});
|
||||
|
||||
it("should interpret a positive number", () => {
|
||||
forth.read("123");
|
||||
core.interpret();
|
||||
core.run();
|
||||
expect(core.error()).to.eql(4);
|
||||
expect(stackValues()[0]).to.eql(123);
|
||||
});
|
||||
|
||||
it("should interpret a negative number", () => {
|
||||
forth.read("-123");
|
||||
core.interpret();
|
||||
core.run();
|
||||
expect(core.error()).to.eql(4);
|
||||
expect(stackValues()[0]).to.eql(-123);
|
||||
});
|
||||
it("should interpret a hex", () => {
|
||||
forth.read("16 BASE ! DF");
|
||||
core.interpret();
|
||||
core.run();
|
||||
expect(core.error()).to.eql(4);
|
||||
expect(stackValues()[0]).to.eql(223);
|
||||
});
|
||||
it("should not interpret hex in decimal mode", () => {
|
||||
forth.read("DF");
|
||||
expect(() => core.interpret()).to.throw();
|
||||
expect(() => core.run()).to.throw();
|
||||
expect(output.trim()).to.eql("undefined word: DF");
|
||||
});
|
||||
|
||||
it("should fail on half a word", () => {
|
||||
forth.read("23FOO");
|
||||
expect(() => core.interpret()).to.throw();
|
||||
expect(() => core.run()).to.throw();
|
||||
expect(output.trim()).to.eql("undefined word: 23FOO");
|
||||
});
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ class WAForth {
|
|||
}
|
||||
this.read(s);
|
||||
try {
|
||||
return (this.core!.exports.interpret as any)(silent);
|
||||
return (this.core!.exports.run as any)(silent);
|
||||
} catch (e) {
|
||||
// Exceptions thrown from the core means QUIT or ABORT is called, or an error
|
||||
// has occurred.
|
||||
|
|
Loading…
Reference in a new issue