From e887550e77ddbba9747c4987a1c317516ee7cd5f Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 4 Jan 2025 07:06:28 -0500 Subject: [PATCH] reduce casting --- sforth/forth.hpp | 87 ++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/sforth/forth.hpp b/sforth/forth.hpp index 64cf50c..b86ce7d 100644 --- a/sforth/forth.hpp +++ b/sforth/forth.hpp @@ -32,6 +32,12 @@ extern bool sforth_debug_hook(); namespace sforth { +template +concept CellSized = (sizeof(cell) == sizeof(T)); + +template +concept CellConvertible = !std::same_as && CellSized; + constexpr bool enable_exceptions = true; constexpr bool enable_debugger = false; @@ -87,7 +93,7 @@ template<> struct catcher { std::jmp_buf buf = {}; void operator()(error e) { - std::longjmp(buf, static_cast(e)); + std::longjmp(buf, std::to_underlying(e)); } std::optional set() { @@ -117,13 +123,17 @@ struct forth : public word_list } } - void push(cell v) { + void push1(cell v) { assert(sp != dstack.begin()); *--sp = v; } - void push(cell v, auto... vs) { - push(v); (push(vs), ...); + void push1(CellConvertible auto v) { + push1(std::bit_cast(v)); + } + + void push(auto v, auto... vs) { + push1(v); (push(vs), ...); } void rpush(func *v) { @@ -131,14 +141,16 @@ struct forth : public word_list *--rp = v; } - cell& top() { + template + T& top() { assert(sp != dstack.end()); - return *sp; + return *std::bit_cast(sp); } - cell pop() { + template + T pop() { assert(sp != dstack.end()); - return *sp++; + return std::bit_cast(*sp++); } auto rpop() -> func * { @@ -146,6 +158,10 @@ struct forth : public word_list return *rp++; } + void comma(CellSized auto v) { + *here++ = std::bit_cast(v); + } + 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); @@ -188,7 +204,7 @@ struct forth : public word_list auto body = (*ent)->body(); if (compiling && ((*ent)->flags_len & word_base::immediate) == 0) - *here++ = std::bit_cast(body); + comma(body); else execute(body); } @@ -248,8 +264,7 @@ constexpr auto initialize() constexpr static func comma = [](auto) { *fthp->here++ = fthp->pop(); }; constexpr static func lit_impl = [](auto) { - auto ptr = std::bit_cast(++fthp->ip); - fthp->push(*ptr); + fthp->push(*++fthp->ip); }; constexpr static func jmp_impl = [](auto){ @@ -264,7 +279,7 @@ constexpr auto initialize() }; constexpr static auto& dict1 = native_dict< - S{"_D" }, [](auto) { fthp->push(std::bit_cast(fthp)); }, 0 + S{"_D" }, [](auto) { fthp->push(fthp); }, 0 , 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 // required by parser @@ -280,48 +295,48 @@ constexpr auto initialize() , S{"LSHIFT"}, [](auto) { fthp->top() <<= fthp->pop(); }, 0 , S{"RSHIFT"}, [](auto) { const auto shift = fthp->pop(); - fthp->push(static_cast(fthp->pop()) >> shift); }, 0 + fthp->push(fthp->template pop() >> shift); }, 0 , S{"M*" }, [](auto) { dcell a = fthp->pop(); a *= fthp->pop(); fthp->push(a, a >> (8 * sizeof(cell))); }, 0 , S{"UM*" }, [](auto) { - daddr a = std::bit_cast(fthp->pop()); - a *= std::bit_cast(fthp->pop()); + daddr a = fthp->template pop(); + a *= fthp->template pop(); fthp->push(a, a >> (8 * sizeof(addr))); }, 0 , S{"LITERAL"}, [](auto x) { if (fthp->compiling) { - *fthp->here++ = std::bit_cast(&lit_impl); - *fthp->here++ = fthp->pop(); + fthp->comma(&lit_impl); + fthp->comma(fthp->pop()); } else { lit_impl(x); } }, word_base::immediate - , S{"@" }, [](auto) { fthp->top() = *std::bit_cast(fthp->top()); }, 0 - , S{"!" }, [](auto) { auto p = fthp->pop(); *std::bit_cast(p) = fthp->pop(); }, 0 - , S{"C@" }, [](auto) { fthp->top() = *std::bit_cast(fthp->top()); }, 0 - , S{"C!" }, [](auto) { auto p = fthp->pop(); *std::bit_cast(p) = fthp->pop(); }, 0 + , S{"@" }, [](auto) { fthp->top() = *fthp->template top(); }, 0 + , S{"!" }, [](auto) { auto p = fthp->template pop(); *p = fthp->pop(); }, 0 + , S{"C@" }, [](auto) { fthp->top() = *fthp->template top(); }, 0 + , S{"C!" }, [](auto) { auto p = fthp->template pop(); *p = fthp->pop(); }, 0 , S{"=" }, [](auto) { auto v = fthp->pop(); fthp->top() = -(fthp->top() == v); }, 0 , S{"<" }, [](auto) { auto v = fthp->pop(); fthp->top() = -(fthp->top() < v); }, 0 , S{"U<" }, [](auto) { - addr v = fthp->pop(); - addr w = fthp->pop(); + const auto v = fthp->template pop(); + const auto w = fthp->template pop(); fthp->push(-(w < v)); }, 0 , S{":" }, [](auto) { auto w = fthp->parse(); auto d = std::bit_cast(fthp->begin_def(w)); fthp->rpush(d); - *fthp->here++ = std::bit_cast(prologue); }, 0 + fthp->comma(prologue); }, 0 , S{"CELL" }, [](auto) { fthp->push(sizeof(cell)); }, 0 - , S{"_JMP" }, [](auto) { fthp->push(std::bit_cast(&jmp_impl)); }, 0 - , S{"_JMP0"}, [](auto) { fthp->push(std::bit_cast(&jmp0_impl)); }, 0 + , S{"_JMP" }, [](auto) { fthp->push(&jmp_impl); }, 0 + , S{"_JMP0"}, [](auto) { fthp->push(&jmp0_impl); }, 0 , S{"_PARSE"}, [](auto) { auto w = fthp->parse(); - fthp->push(std::bit_cast(w.data()), w.size()); }, 0 + fthp->push(w.data(), w.size()); }, 0 , S{"_GET"}, [](auto) { - const addr u = fthp->pop(); - const auto caddr = std::bit_cast(fthp->pop()); + const auto u = fthp->template pop(); + const auto caddr = fthp->template pop(); auto g = fthp->get({caddr, u}); - fthp->push(g.has_value() ? std::bit_cast(*g) : 0); }, 0 + fthp->push(g.has_value() ? *g : nullptr); }, 0 , S{"POSTPONE"}, [](auto) { fthp->template assert(fthp->compiling); auto w = fthp->parse(); @@ -329,11 +344,11 @@ constexpr auto initialize() fthp->template assert(g.has_value()); if ((*g)->is_immediate()) { - *fthp->here++ = std::bit_cast((*g)->body()); + fthp->comma((*g)->body()); } else { - *fthp->here++ = std::bit_cast(&lit_impl); - *fthp->here++ = std::bit_cast((*g)->body()); - *fthp->here++ = std::bit_cast(&comma); + fthp->comma(&lit_impl); + fthp->comma((*g)->body()); + fthp->comma(&comma); } }, word_base::immediate , S{"KEY"}, [](auto) { if (fthp->sourcei != std::string_view::npos) @@ -341,8 +356,8 @@ constexpr auto initialize() else fthp->push(0); }, 0 , S{"_eval"}, [](auto) { - const addr u = fthp->pop(); - const auto caddr = std::bit_cast(fthp->pop()); + const auto u = fthp->template pop(); + const auto caddr = fthp->template pop(); fthp->parse_line({caddr, u}); }, 0 >::word;