diff --git a/Makefile b/Makefile index 1978ffb..f61f58d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ #CXX := clang++-19 -CXXFLAGS += -O0 -std=c++23 -Wall -Wextra -Wpedantic -ggdb -g3 +CXXFLAGS += -m32 -Os -std=c++23 -Wall -Wextra -Wpedantic -ggdb -g3 all: main diff --git a/forth.hpp b/forth.hpp index 560cafd..48ebbc0 100644 --- a/forth.hpp +++ b/forth.hpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -68,16 +69,16 @@ struct forth addr flags_len; auto name() const -> std::string_view { - return {reinterpret_cast(this + 1)}; + return {std::bit_cast(this + 1)}; } auto body() const -> const func * { - auto ptr = reinterpret_cast(this + 1) - + (flags_len & 0xFF); - return reinterpret_cast(ptr); + const auto ptr = std::bit_cast(this + 1); + const auto fptr = ptr + (flags_len & 0xFF); + return std::bit_cast(fptr); } - void make_immediate() { + constexpr void make_immediate() { flags_len |= immediate; } }; @@ -113,7 +114,7 @@ struct forth void rpush(func *v) { assert(rp != rstack.begin()); - *--rp = reinterpret_cast(v); + *--rp = v; } cell& top() { @@ -123,16 +124,12 @@ struct forth cell pop() { assert(sp != dstack.end()); - auto ret = *sp; - *sp++ = -1; - return ret;//*sp++; + return *sp++; } auto rpop() -> func * { assert(rp != rstack.end()); - auto ret = reinterpret_cast(*rp); - *rp++ = -1; - return ret; + return *rp++; } template @@ -154,12 +151,11 @@ struct forth //assert(state->here + size < &dictionary.back()); const auto h = std::exchange(here, here + size); - auto w = new (h) word_base (nullptr, namesz); - w->next = std::exchange(latest, w); + latest = new (h) word_base (latest, namesz); std::copy(name.begin(), name.end(), - reinterpret_cast(h) + sizeof(word_base)); + std::bit_cast(h) + sizeof(word_base)); if (entry) - *here++ = reinterpret_cast(entry); + *here++ = std::bit_cast(entry); return *this; } @@ -185,7 +181,7 @@ struct forth auto body = (*ent)->body(); if (compiling && ((*ent)->flags_len & word_base::immediate) == 0) { - *here++ = reinterpret_cast(body); + *here++ = std::bit_cast(body); } else { execute(body); } @@ -225,7 +221,7 @@ struct forth fth.rpush(fth.ip); for (fth.ip = body + 1; *fth.ip; fth.ip++) - fth.execute(reinterpret_cast(*fth.ip)); + fth.execute(std::bit_cast(*fth.ip)); fth.ip = fth.rpop(); } @@ -238,10 +234,10 @@ struct forth static auto& fth = **fthp; constexpr static func lit_impl = [](auto) { - auto ptr = reinterpret_cast(++fth.ip); + auto ptr = std::bit_cast(++fth.ip); fth.push(*ptr); }; - auto f_dict = [](auto) { fth.push(reinterpret_cast(&fth)); }; + auto f_dict = [](auto) { fth.push(std::bit_cast(&fth)); }; auto f_add = [](auto) { fth.top() += fth.pop(); }; auto f_minus = [](auto) { fth.top() -= fth.pop(); }; auto f_times = [](auto) { fth.top() *= fth.pop(); }; @@ -258,16 +254,16 @@ struct forth const_cast(fth.latest)->make_immediate(); }; auto f_lit = [](auto) { //assert(fth.compiling); - *fth.here++ = reinterpret_cast(&lit_impl); + *fth.here++ = std::bit_cast(&lit_impl); *fth.here++ = fth.pop(); }; - auto f_peek = [](auto) { fth.push(*reinterpret_cast(fth.pop())); }; + auto f_peek = [](auto) { fth.push(*std::bit_cast(fth.pop())); }; auto f_poke = [](auto) { auto [p, v] = fth.pop<2>(); - *reinterpret_cast(p) = v; }; - auto f_cpeek = [](auto) { fth.push(*reinterpret_cast(fth.pop())); }; + *std::bit_cast(p) = v; }; + auto f_cpeek = [](auto) { fth.push(*std::bit_cast(fth.pop())); }; auto f_cpoke = [](auto) { auto [p, v] = fth.pop<2>(); - *reinterpret_cast(p) = v; }; + *std::bit_cast(p) = v; }; auto f_swap = [](auto) { auto [a, b] = fth.pop<2>(); fth.push(a, b); }; auto f_drop = [](auto) { fth.pop(); }; auto f_dup = [](auto) { fth.push(fth.top()); }; @@ -278,26 +274,27 @@ struct forth auto w = fth.parse(); if (auto g = fth.get(w); g) - fth.push(reinterpret_cast((*g)->body())); + fth.push(std::bit_cast((*g)->body())); else fth.push(0); }; auto f_colon = [](auto) { + const auto prologue = forth::prologue; auto w = fth.parse(); fth.add(w); - *fth.here++ = reinterpret_cast(forth::prologue); + *fth.here++ = std::bit_cast(prologue); fth.compiling = true; }; auto f_semic = [](auto) { *fth.here++ = 0; fth.compiling = false; }; auto f_comm = [](auto) { fth.sourcei = npos; }; auto f_cell = [](auto) { fth.push(sizeof(cell)); }; auto f_jmp = [](auto) { auto ptr = ++fth.ip; - fth.ip = *reinterpret_cast(ptr) - 1; + fth.ip = *std::bit_cast(ptr) - 1; }; auto f_jmp0 = [](auto) { auto ptr = ++fth.ip; if (fth.pop() == 0) - fth.ip = *reinterpret_cast(ptr) - 1; + fth.ip = *std::bit_cast(ptr) - 1; }; auto f_postpone = [](auto) { assert(fth.compiling); @@ -307,7 +304,7 @@ struct forth assert(g.has_value()); - *fth.here++ = reinterpret_cast((*g)->body()); + *fth.here++ = std::bit_cast((*g)->body()); }; constexpr static word w_dict {"_d", f_dict}; @@ -372,9 +369,9 @@ struct forth } cell *sp; - cell *rp; + func **rp; func *ip = nullptr; - cell *here = reinterpret_cast(this + 1); + cell *here = std::bit_cast(this + 1); const word_base *latest = nullptr; const char *source = nullptr; std::size_t sourcei = npos; @@ -382,7 +379,7 @@ struct forth cell *end = nullptr; cell base = 10; std::array dstack; - std::array rstack; + std::array rstack; }; static_assert(offsetof(forth::word_base, flags_len) == 1 * sizeof(forth::cell)); diff --git a/main.cpp b/main.cpp index 16de440..d3bbe42 100644 --- a/main.cpp +++ b/main.cpp @@ -38,6 +38,7 @@ int main(int argc, const char *argv[]) std::cout << buf << ' '; }); fth->add("emit", [](auto) { std::cout << static_cast(fth->pop()); }); + fth->add("dictsize", [](auto) { fth->push(dict.size() * sizeof(forth::cell)); }); for (auto arg : args) { if (std::ifstream file {arg}; parse_stream(fth, file))