aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-11-09 14:48:49 -0500
committerClyne Sullivan <clyne@bitgloo.com>2023-11-09 14:48:49 -0500
commit4b50a9fafe793abf3c2c16e203072a98a0702814 (patch)
tree52283545e15153a2adeba8145d8e018f97699cfe
parent3dc947a7575bd23703644996d8e853e5e618b2e3 (diff)
move main execution to State; bring back verify()optimize
-rw-r--r--forth/core.fth4
-rw-r--r--forth/fib.fth4
-rw-r--r--libalee/corewords.cpp24
-rw-r--r--libalee/corewords.hpp2
-rw-r--r--libalee/state.cpp26
-rw-r--r--libalee/state.hpp11
6 files changed, 41 insertions, 30 deletions
diff --git a/forth/core.fth b/forth/core.fth
index 8ec5b71..e9fc133 100644
--- a/forth/core.fth
+++ b/forth/core.fth
@@ -51,8 +51,8 @@
: else ['] _jmp , here 0 , swap here swap ! ; imm
: postpone _' dup 0 = if exit then
- 1 = swap ['] _lit , , if ['] execute ,
- else ['] , , then ; imm
+ 1 = swap ['] _lit , , if ['] execute
+ else ['] , then , ; imm
: over 1 pick ;
: rot >r swap r> swap ;
diff --git a/forth/fib.fth b/forth/fib.fth
index 671528a..3efdd2c 100644
--- a/forth/fib.fth
+++ b/forth/fib.fth
@@ -9,10 +9,10 @@
5 sys fib 5 sys >r 2drop r> ;
variable avg 0 avg !
-2000 constant iters
+1000 constant iters
: bench ( -- )
- iters 0 do 100 fibbench avg +! loop
+ iters 0 do 1000 fibbench avg +! loop
avg @ iters / avg ! ;
bench ." avg time: " avg @ . ." us" cr
diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp
index 138ade4..b177565 100644
--- a/libalee/corewords.cpp
+++ b/libalee/corewords.cpp
@@ -37,21 +37,12 @@ void find(State& state, Word word)
state.push(imm);
}
-void CoreWords::run(Cell ins, State& state)
+bool CoreWords::run(Cell ins, State& state)
{
DoubleCell dcell;
- Addr index = ins;
auto& ip = state.ip();
-execute:
- if (index >= Dictionary::Begin) {
- // must be calling a defined subroutine
- state.pushr(ip);
- ip = index;
- return;
- } else if (index >= WordCount) {
- state.push(static_cast<Cell>(index - WordCount));
- } else switch (index) {
+ switch (ins) {
case 0: // _lit
state.push(state.beyondip());
break;
@@ -149,8 +140,7 @@ execute:
find(state, state.dict.input());
break;
case 24: // execute
- index = state.pop();
- goto execute;
+ return true;
case 25: // exit
ip = state.popr();
if (ip == 0)
@@ -180,8 +170,8 @@ execute:
}
[[fallthrough]];
case 28: // _jmp
- ip = state.beyondip();
- return;
+ ip = static_cast<Addr>(state.beyondip() - sizeof(Cell));
+ break;
case 29: // depth
state.push(static_cast<Cell>(state.size()));
break;
@@ -191,7 +181,7 @@ execute:
case 31: // _in
state.input();
break;
- case 32: // _ex
+ case 32: // _ev
{
const auto st = state.save();
ip = 0;
@@ -235,7 +225,7 @@ execute:
break;
}
- ip += sizeof(Cell);
+ return false;
}
Cell CoreWords::findi(State& state, Word word)
diff --git a/libalee/corewords.hpp b/libalee/corewords.hpp
index 25f6a6e..e56baa3 100644
--- a/libalee/corewords.hpp
+++ b/libalee/corewords.hpp
@@ -48,7 +48,7 @@ public:
/**
* Executes the given CoreWord execution token using the given state.
*/
- static void run(Cell, State&);
+ static bool run(Cell, State&);
constexpr static char wordsarr[] =
"_lit\0drop\0dup\0swap\0pick\0sys\0"
diff --git a/libalee/state.cpp b/libalee/state.cpp
index 6e12999..34e4936 100644
--- a/libalee/state.cpp
+++ b/libalee/state.cpp
@@ -42,17 +42,39 @@ void State::load(const State::Context& ctx)
context = ctx;
}
+void State::execute1(Addr ins)
+{
+repeat:
+ if (ins >= Dictionary::Begin) [[likely]] {
+ // Subroutine call
+ pushr(context.ip);
+ context.ip = ins;
+ } else {
+ if (ins < CoreWords::WordCount) {
+ if (CoreWords::run(ins, *this)) [[unlikely]] {
+ ins = pop();
+ goto repeat;
+ }
+ } else {
+ push(static_cast<Cell>(ins - CoreWords::WordCount));
+ }
+
+ context.ip += sizeof(Cell);
+ }
+}
+
Error State::execute(Addr addr)
{
auto stat = static_cast<Error>(setjmp(context.jmpbuf));
if (stat == Error::none) {
- CoreWords::run(addr, *this);
+ context.ip = 0;
+ execute1(addr);
if (context.ip >= Dictionary::Begin) {
// longjmp will exit this loop.
for (;;)
- CoreWords::run(dict.read(context.ip), *this);
+ execute1(dict.read(context.ip));
} else {
// addr was a CoreWord, all done now.
context.ip = 0;
diff --git a/libalee/state.hpp b/libalee/state.hpp
index abf7a1e..529f118 100644
--- a/libalee/state.hpp
+++ b/libalee/state.hpp
@@ -25,8 +25,6 @@
#include <csetjmp>
#include <cstddef>
-#define verify(C, E)
-
constexpr unsigned DataStackSize = 64;
constexpr unsigned ReturnStackSize = 64;
@@ -52,6 +50,7 @@ public:
* Encountering an error will cause this function to exit immediately.
*/
Error execute(Addr);
+ void execute1(Addr);
/**
* Clears the data and return stacks, sets ip to zero, and clears the
@@ -135,10 +134,10 @@ public:
return dict.read(context.ip);
}
-// inline void verify(bool condition, Error error) {
-// if (!condition)
-// std::longjmp(context.jmpbuf, static_cast<int>(error));
-// }
+ inline void verify(bool condition, Error error) {
+ if (!condition)
+ std::longjmp(context.jmpbuf, static_cast<int>(error));
+ }
private:
InputFunc inputfunc; // User-provided function to collect "stdin" input.