return *rp++;
}
- forth& add(std::string_view name, func entry = nullptr) {
+ auto begin_def(std::string_view name) -> word_base * {
const auto namesz = (name.size() + 1 + sizeof(cell) - 1) & ~(sizeof(cell) - 1);
const auto size = (sizeof(word_base) + namesz) / sizeof(cell);
//assert<error::dictionary_overflow>(state->here + size < &dictionary.back());
const auto h = std::exchange(here, here + size);
- next = new (h) word_base (next, namesz);
+ auto def = new (h) word_base (next, namesz);
std::copy(name.begin(), name.end(),
std::bit_cast<char *>(h) + sizeof(word_base));
- if (entry)
- *here++ = std::bit_cast<cell>(entry);
- return *this;
+
+ compiling = true;
+ return def;
}
auto parse() -> std::string_view {
fthp->ip = fthp->rpop();
};
+ constexpr static func comma = [](auto) { *fthp->here++ = fthp->pop(); };
+
constexpr static func lit_impl = [](auto) {
auto ptr = std::bit_cast<cell *>(++fthp->ip);
fthp->push(*ptr);
, S{"DEPTH"}, [](auto) { fthp->push(std::distance(fthp->sp, fthp->dstack.end())); }, 0
, S{"UNUSED"}, [](auto) { fthp->push(sizeof(cell) * std::distance(fthp->here, fthp->dict.end())); }, 0
, S{"_LIT" }, lit_impl, 0
+ , S{"," }, comma, 0
, S{"SWAP" }, [](auto) { auto a = fthp->pop(); auto b = fthp->pop(); fthp->push(a, b); }, 0
, S{"DROP" }, [](auto) { fthp->pop(); }, 0
, S{"DUP" }, [](auto) { fthp->push(fthp->top()); }, 0
addr v = fthp->pop();
addr w = fthp->pop();
fthp->push(-(w < v)); }, 0
+ , S{"FIND" }, [](auto) {
+ const auto caddr = std::bit_cast<const char *>(fthp->pop());
+ std::string_view w {caddr + 1, std::bit_cast<unsigned char>(caddr[0])};
+ if (auto g = fthp->get(w); !g.has_value())
+ fthp->push(std::bit_cast<cell>(caddr), 0);
+ else
+ fthp->push(std::bit_cast<cell>((*g)->body()), (*g)->is_immediate() ? 1 : -1); }, 0
, S{"\'" }, [](auto) {
auto w = fthp->parse();
auto g = fthp->get(w);
fthp->push(g ? std::bit_cast<cell>((*g)->body()) : 0); }, 0
, S{":" }, [](auto) {
auto w = fthp->parse();
- fthp->add(w);
- *fthp->here++ = std::bit_cast<cell>(prologue);
- fthp->compiling = true; }, 0
- , S{";" }, [](auto) { *fthp->here++ = 0; fthp->compiling = false; }, word_base::immediate
+ auto d = std::bit_cast<func *>(fthp->begin_def(w));
+ fthp->rpush(d);
+ *fthp->here++ = std::bit_cast<cell>(prologue); }, 0
+ , S{";" }, [](auto) {
+ *fthp->here++ = 0;
+ fthp->next = std::bit_cast<word_base *>(fthp->rpop());
+ fthp->compiling = false; }, word_base::immediate
, S{"\\" }, [](auto) { fthp->sourcei = std::string_view::npos; }, word_base::immediate
, S{"CELL" }, [](auto) { fthp->push(sizeof(cell)); }, 0
, S{"_JMP" }, [](auto) {
auto w = fthp->parse();
auto g = fthp->get(w);
assert<error::word_not_found>(g.has_value());
- *fthp->here++ = std::bit_cast<cell>((*g)->body()); }, word_base::immediate
+
+ if ((*g)->is_immediate()) {
+ *fthp->here++ = std::bit_cast<cell>((*g)->body());
+ } else {
+ *fthp->here++ = std::bit_cast<cell>(&lit_impl);
+ *fthp->here++ = std::bit_cast<cell>((*g)->body());
+ *fthp->here++ = std::bit_cast<cell>(&comma);
+ } }, word_base::immediate
, S{"SOURCE"}, [](auto) {
auto len = 0u;
while (fthp->source[len])
fthp->push(fthp->source[fthp->sourcei++]);
else
fthp->push(0); }, 0
+ , S{"EVALUATE"}, [](auto) {
+ const auto u = std::bit_cast<addr>(fthp->pop());
+ const auto caddr = std::bit_cast<const char *>(fthp->pop());
+ const auto olds = fthp->source;
+ const auto oldi = fthp->sourcei;
+ fthp->parse_line({caddr, u});
+ fthp->source = olds;
+ fthp->sourcei = oldi; }, 0
>::word;
constexpr static auto& dict2 = comp_dict<prologue, &dict1
+ , S{"RECURSE"}, S{"R> R> DUP >R SWAP >R >XT ,"}, word_base::immediate
+ , S{">XT" }, S{"CELL+ DUP @ 127 AND + CELL+"}, 0
, S{"ALIGN" }, S{"HERE DUP ALIGNED SWAP - ALLOT"}, 0
, S{"ALIGNED"}, S{"CELL 1- + CELL 1- INVERT AND"}, 0
, S{"DECIMAL"}, S{"10 BASE !"}, 0
, S{"2@" }, S{"DUP CELL+ @ SWAP @"}, 0
, S{"C," }, S{"HERE C! 1 ALLOT"}, 0
, S{"EXIT" }, S{"0 ,"}, word_base::immediate
- , S{"," }, S{"HERE ! CELL ALLOT"}, 0
, S{"ALLOT" }, S{"DP +!"}, 0
, S{"+!" }, S{"DUP >R SWAP R> @ + SWAP !"}, 0
, S{"2SWAP" }, S{"ROT >R ROT R>"}, 0
, S{"2DUP" }, S{"OVER OVER"}, 0
, S{"2OVER" }, S{"3 PICK 3 PICK"}, 0
+ , S{"2R>" }, S{"R> R> R> ROT >R SWAP"}, 0
+ , S{"2>R" }, S{"R> -ROT SWAP >R >R >R"}, 0
+ , S{"R@" }, S{"R> R> DUP >R SWAP >R"}, 0
, S{">R" }, S{"RP@ CELL - RP ! RP@ CELL+ @ RP@ ! RP@ CELL+ !"}, 0
, S{"R>" }, S{"RP@ @ RP@ CELL+ RP ! RP@ @ SWAP RP@ !"}, 0
, S{"OVER" }, S{"1 PICK"}, 0