streamline single execution

llvm
Clyne 2 years ago
parent 4af14b8c3e
commit eb6009acbf

@ -1,6 +1,6 @@
CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \ CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \
-Wall -Wextra -pedantic -Werror \ -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 CXXFILES := corewords.cpp dictionary.cpp parser.cpp state.cpp
OBJFILES := $(subst .cpp,.o,$(CXXFILES)) OBJFILES := $(subst .cpp,.o,$(CXXFILES))

@ -21,36 +21,41 @@
#include <cstring> #include <cstring>
#include <utility> #include <utility>
void CoreWords::run(unsigned int index, State& state) Word getword(State& state)
{ {
auto getword = [&state] { auto word = state.dict.input();
auto word = state.dict.input(); while (word.size() == 0) {
while (word.size() == 0) { state.input(state);
state.input(state); word = state.dict.input();
word = state.dict.input(); }
} return word;
return word; }
}; void newdef(Dictionary& dict, Word word)
auto newdef = [](Dictionary& dict, Word word) { {
auto addr = dict.alignhere(); auto addr = dict.alignhere();
dict.addDefinition(word); dict.addDefinition(word);
dict.write(addr, dict.write(addr,
(dict.read(addr) & 0x1F) | (dict.read(addr) & 0x1F) |
((addr - dict.latest()) << 6)); ((addr - dict.latest()) << 6));
dict.latest(addr); dict.latest(addr);
}; };
auto tick = [&state](Word word) { void tick(State& state)
if (auto j = state.dict.find(word); j > 0) {
state.push(state.dict.getexec(j)); auto word = getword(state);
else if (auto i = CoreWords::findi(state, word); i >= 0) if (auto j = state.dict.find(word); j > 0)
state.push(i & ~CoreWords::Immediate); state.push(state.dict.getexec(j));
else else if (auto i = CoreWords::findi(state, word); i >= 0)
state.push(0); state.push(i & ~CoreWords::Immediate);
}; else
state.push(0);
}
void CoreWords::run(unsigned int index, State& state)
{
Cell cell; Cell cell;
DoubleCell dcell; DoubleCell dcell;
execute:
switch (index) { switch (index) {
default: default:
// must be calling a defined subroutine // must be calling a defined subroutine
@ -91,13 +96,15 @@ void CoreWords::run(unsigned int index, State& state)
break; break;
case 9: // div ( d n -- n ) case 9: // div ( d n -- n )
cell = state.pop(); cell = state.pop();
dcell = state.pop() << (sizeof(Cell) * 8); dcell = state.pop();
dcell <<= sizeof(Cell) * 8;
dcell |= state.pop(); dcell |= state.pop();
state.push(dcell / cell); state.push(dcell / cell);
break; break;
case 10: // mod ( d n -- n ) case 10: // mod ( d n -- n )
cell = state.pop(); cell = state.pop();
dcell = state.pop() << (sizeof(Cell) * 8); dcell = state.pop();
dcell <<= sizeof(Cell) * 8;
dcell |= state.pop(); dcell |= state.pop();
state.push(dcell % cell); state.push(dcell % cell);
break; break;
@ -149,14 +156,15 @@ void CoreWords::run(unsigned int index, State& state)
state.top() >>= cell; state.top() >>= cell;
break; break;
case 22: // colon case 22: // colon
newdef(state.dict, getword()); newdef(state.dict, getword(state));
state.compiling(true); state.compiling(true);
break; break;
case 23: // tick case 23: // tick
tick(getword()); tick(state);
break; break;
case 24: // execute case 24: // execute
run(state.pop(), state); index = state.pop();
goto execute;
break; break;
case 25: // exit case 25: // exit
state.ip = state.popr(); state.ip = state.popr();

@ -35,16 +35,17 @@ State::Error State::execute(Addr addr)
{ {
auto stat = setjmp(jmpbuf); auto stat = setjmp(jmpbuf);
if (!stat) { if (!stat) {
if (addr < CoreWords::WordCount) { ip = 0;
CoreWords::run(addr, *this);
} else {
pushr(0);
ip = addr - sizeof(Cell);
do { auto ins = addr;
ip += sizeof(Cell); for (;;) {
CoreWords::run(dict.read(ip), *this); CoreWords::run(ins, *this);
} while (ip);
if (!ip)
break;
ip += sizeof(Cell);
ins = dict.read(ip);
} }
} else { } else {
return static_cast<State::Error>(stat); return static_cast<State::Error>(stat);

Loading…
Cancel
Save