]> code.bitgloo.com Git - clyne/sforth.git/commitdiff
reduce casting
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 4 Jan 2025 12:06:28 +0000 (07:06 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 4 Jan 2025 12:06:28 +0000 (07:06 -0500)
sforth/forth.hpp

index 64cf50c3d552e73e34a862755151883a30ca0a19..b86ce7d67a598b98c3f55b209f9239dce9972b5f 100644 (file)
@@ -32,6 +32,12 @@ extern bool sforth_debug_hook();
 
 namespace sforth {
 
+template<typename T>
+concept CellSized = (sizeof(cell) == sizeof(T));
+
+template<typename T>
+concept CellConvertible = !std::same_as<cell, T> && CellSized<T>;
+
 constexpr bool enable_exceptions = true;
 constexpr bool enable_debugger = false;
 
@@ -87,7 +93,7 @@ template<> struct catcher<false> {
     std::jmp_buf buf = {};
 
     void operator()(error e) {
-        std::longjmp(buf, static_cast<int>(e));
+        std::longjmp(buf, std::to_underlying(e));
     }
 
     std::optional<error> set() {
@@ -117,13 +123,17 @@ struct forth : public word_list
         }
     }
 
-    void push(cell v) {
+    void push1(cell v) {
         assert<error::stack_overflow>(sp != dstack.begin());
         *--sp = v;
     }
 
-    void push(cell v, auto... vs) {
-        push(v); (push(vs), ...);
+    void push1(CellConvertible auto v) {
+        push1(std::bit_cast<cell>(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<typename T = cell>
+    T& top() {
         assert<error::stack_underflow>(sp != dstack.end());
-        return *sp;
+        return *std::bit_cast<T*>(sp);
     }
 
-    cell pop() {
+    template<typename T = cell>
+    T pop() {
         assert<error::stack_underflow>(sp != dstack.end());
-        return *sp++;
+        return std::bit_cast<T>(*sp++);
     }
 
     auto rpop() -> func * {
@@ -146,6 +158,10 @@ struct forth : public word_list
         return *rp++;
     }
 
+    void comma(CellSized auto v) {
+        *here++ = std::bit_cast<cell>(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<cell>(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<cell *>(++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<cell>(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<addr>(fthp->pop()) >> shift); }, 0
+            fthp->push(fthp->template pop<addr>() >> 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<addr>(fthp->pop());
-            a *= std::bit_cast<addr>(fthp->pop());
+            daddr a = fthp->template pop<addr>();
+            a *= fthp->template pop<addr>();
             fthp->push(a, a >> (8 * sizeof(addr))); }, 0
         , S{"LITERAL"}, [](auto x) {
             if (fthp->compiling) {
-                *fthp->here++ = std::bit_cast<cell>(&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<cell *>(fthp->top()); }, 0
-        , S{"!"    }, [](auto) { auto p = fthp->pop(); *std::bit_cast<cell *>(p) = fthp->pop(); }, 0
-        , S{"C@"   }, [](auto) { fthp->top() = *std::bit_cast<char *>(fthp->top()); }, 0
-        , S{"C!"   }, [](auto) { auto p = fthp->pop(); *std::bit_cast<char *>(p) = fthp->pop(); }, 0
+        , S{"@"    }, [](auto) { fthp->top() = *fthp->template top<cell *>(); }, 0
+        , S{"!"    }, [](auto) { auto p = fthp->template pop<cell *>(); *p = fthp->pop(); }, 0
+        , S{"C@"   }, [](auto) { fthp->top() = *fthp->template top<char *>(); }, 0
+        , S{"C!"   }, [](auto) { auto p = fthp->template pop<char *>(); *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<addr>();
+            const auto w = fthp->template pop<addr>();
             fthp->push(-(w < v)); }, 0
         , S{":"    }, [](auto) {
             auto w = fthp->parse();
             auto d = std::bit_cast<func *>(fthp->begin_def(w));
             fthp->rpush(d);
-            *fthp->here++ = std::bit_cast<cell>(prologue); }, 0
+            fthp->comma(prologue); }, 0
         , S{"CELL" }, [](auto) { fthp->push(sizeof(cell)); }, 0
-        , S{"_JMP" }, [](auto) { fthp->push(std::bit_cast<cell>(&jmp_impl)); }, 0
-        , S{"_JMP0"}, [](auto) { fthp->push(std::bit_cast<cell>(&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<cell>(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<const char *>(fthp->pop());
+            const auto u = fthp->template pop<addr>();
+            const auto caddr = fthp->template pop<const char *>();
             auto g = fthp->get({caddr, u});
-            fthp->push(g.has_value() ? std::bit_cast<cell>(*g) : 0); }, 0
+            fthp->push(g.has_value() ? *g : nullptr); }, 0
         , S{"POSTPONE"}, [](auto) {
             fthp->template assert<error::compile_only_word>(fthp->compiling);
             auto w = fthp->parse();
@@ -329,11 +344,11 @@ constexpr auto initialize()
             fthp->template assert<error::word_not_found>(g.has_value());
 
             if ((*g)->is_immediate()) {
-                *fthp->here++ = std::bit_cast<cell>((*g)->body());
+                fthp->comma((*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);
+                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<const char *>(fthp->pop());
+            const auto u = fthp->template pop<addr>();
+            const auto caddr = fthp->template pop<const char *>();
             fthp->parse_line({caddr, u}); }, 0
     >::word;