aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-02-25 19:50:27 -0500
committerClyne Sullivan <clyne@bitgloo.com>2023-02-25 19:50:27 -0500
commiteb6009acbf97b364c63f4ada1dfde29d9e224d55 (patch)
treeec3ddbc8d2dae76828a42b9fd4334f42bb54428f
parent4af14b8c3e2b8c0ef230158b91e8a890dc34e523 (diff)
streamline single execution
-rw-r--r--Makefile2
-rw-r--r--corewords.cpp68
-rw-r--r--state.cpp19
3 files changed, 49 insertions, 40 deletions
diff --git a/Makefile b/Makefile
index 45011b6..30e210b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \
-Wall -Wextra -pedantic -Werror \
- -fno-exceptions -fno-rtti #-fstack-usage
+ -fno-exceptions -fno-rtti #-fstack-usage
CXXFILES := corewords.cpp dictionary.cpp parser.cpp state.cpp
OBJFILES := $(subst .cpp,.o,$(CXXFILES))
diff --git a/corewords.cpp b/corewords.cpp
index 02fcb53..6aec5ab 100644
--- a/corewords.cpp
+++ b/corewords.cpp
@@ -21,36 +21,41 @@
#include <cstring>
#include <utility>
-void CoreWords::run(unsigned int index, State& state)
+Word getword(State& state)
{
- auto getword = [&state] {
- auto word = state.dict.input();
- while (word.size() == 0) {
- state.input(state);
- word = state.dict.input();
- }
- return word;
- };
- auto newdef = [](Dictionary& dict, Word word) {
- auto addr = dict.alignhere();
- dict.addDefinition(word);
- dict.write(addr,
- (dict.read(addr) & 0x1F) |
- ((addr - dict.latest()) << 6));
- dict.latest(addr);
- };
- auto tick = [&state](Word word) {
- if (auto j = state.dict.find(word); j > 0)
- state.push(state.dict.getexec(j));
- else if (auto i = CoreWords::findi(state, word); i >= 0)
- state.push(i & ~CoreWords::Immediate);
- else
- state.push(0);
- };
+ auto word = state.dict.input();
+ while (word.size() == 0) {
+ state.input(state);
+ word = state.dict.input();
+ }
+ return word;
+}
+void newdef(Dictionary& dict, Word word)
+{
+ auto addr = dict.alignhere();
+ dict.addDefinition(word);
+ dict.write(addr,
+ (dict.read(addr) & 0x1F) |
+ ((addr - dict.latest()) << 6));
+ dict.latest(addr);
+};
+void tick(State& state)
+{
+ auto word = getword(state);
+ if (auto j = state.dict.find(word); j > 0)
+ state.push(state.dict.getexec(j));
+ else if (auto i = CoreWords::findi(state, word); i >= 0)
+ state.push(i & ~CoreWords::Immediate);
+ else
+ state.push(0);
+}
+void CoreWords::run(unsigned int index, State& state)
+{
Cell cell;
DoubleCell dcell;
+execute:
switch (index) {
default:
// must be calling a defined subroutine
@@ -91,13 +96,15 @@ void CoreWords::run(unsigned int index, State& state)
break;
case 9: // div ( d n -- n )
cell = state.pop();
- dcell = state.pop() << (sizeof(Cell) * 8);
+ dcell = state.pop();
+ dcell <<= sizeof(Cell) * 8;
dcell |= state.pop();
state.push(dcell / cell);
break;
case 10: // mod ( d n -- n )
cell = state.pop();
- dcell = state.pop() << (sizeof(Cell) * 8);
+ dcell = state.pop();
+ dcell <<= sizeof(Cell) * 8;
dcell |= state.pop();
state.push(dcell % cell);
break;
@@ -149,14 +156,15 @@ void CoreWords::run(unsigned int index, State& state)
state.top() >>= cell;
break;
case 22: // colon
- newdef(state.dict, getword());
+ newdef(state.dict, getword(state));
state.compiling(true);
break;
case 23: // tick
- tick(getword());
+ tick(state);
break;
case 24: // execute
- run(state.pop(), state);
+ index = state.pop();
+ goto execute;
break;
case 25: // exit
state.ip = state.popr();
diff --git a/state.cpp b/state.cpp
index 1510352..56ad8cd 100644
--- a/state.cpp
+++ b/state.cpp
@@ -35,16 +35,17 @@ State::Error State::execute(Addr addr)
{
auto stat = setjmp(jmpbuf);
if (!stat) {
- if (addr < CoreWords::WordCount) {
- CoreWords::run(addr, *this);
- } else {
- pushr(0);
- ip = addr - sizeof(Cell);
+ ip = 0;
- do {
- ip += sizeof(Cell);
- CoreWords::run(dict.read(ip), *this);
- } while (ip);
+ auto ins = addr;
+ for (;;) {
+ CoreWords::run(ins, *this);
+
+ if (!ip)
+ break;
+
+ ip += sizeof(Cell);
+ ins = dict.read(ip);
}
} else {
return static_cast<State::Error>(stat);