]> code.bitgloo.com Git - clyne/sforth.git/commitdiff
native_dict
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 30 Nov 2024 11:29:56 +0000 (06:29 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 30 Nov 2024 11:29:56 +0000 (06:29 -0500)
forth.hpp

index 14c7fb0b30c2f2c7f3c9106307d36158a36c47c8..8f71946c132eaedae39b426afd8ea0458ac8fbf1 100644 (file)
--- a/forth.hpp
+++ b/forth.hpp
@@ -94,7 +94,7 @@ struct ctstring {
     }
 };
 
-template<ctstring Name, ctstring Body, auto& Prev>
+template<ctstring Name, ctstring Body, auto *Prev = (const word_base *)nullptr>
 struct comp_word : public word_base
 {
     constexpr static auto N = (sizeof(Name) + sizeof(cell) - 1) & ~(sizeof(cell) - 1);
@@ -107,7 +107,7 @@ struct comp_word : public word_base
                 const auto word = parse(Body.data, sourcei);
 
                 b++;
-                if (!Prev.get_ct(word))
+                if (!Prev->get_ct(word))
                     b++;
             }
             return b;
@@ -125,12 +125,14 @@ struct comp_word : public word_base
     consteval const func *get_ct(std::string_view name) const {
         if (name == std::string_view{Name.data})
             return &prologue;
+        else if (Prev)
+            return Prev->get_ct(name);
         else
-            return Prev.get_ct(name);
+            return nullptr;
     }
 
     consteval comp_word(const func prol, addr flags = 0):
-        word_base{&Prev, N | flags}, namebuf{}, prologue{prol}, bodybuf{}
+        word_base{Prev, N | flags}, namebuf{}, prologue{prol}, bodybuf{}
     {
         std::copy(Name.data, Name.data + sizeof(Name), namebuf.data());
 
@@ -157,7 +159,7 @@ struct comp_word : public word_base
     }
 };
 
-template<ctstring Name, auto *Prev = (const word_base *)nullptr>
+template<ctstring Name, func Body, auto *Prev = (const word_base *)nullptr>
 struct native_word : public word_base
 {
     constexpr static auto N = (sizeof(Name) + sizeof(cell) - 1) & ~(sizeof(cell) - 1);
@@ -173,13 +175,37 @@ struct native_word : public word_base
             return nullptr;
     }
 
-    consteval native_word(func bod, addr flags = 0):
-        word_base{Prev, N | flags}, namebuf{}, body{bod}
+    consteval native_word(addr flags = 0):
+        word_base{Prev, N | flags}, namebuf{}, body{Body}
     {
         std::copy(Name.data, Name.data + sizeof(Name), namebuf.data());
     }
 };
 
+template<ctstring Name, func Body, addr Flags, auto... Next>
+struct native_dict
+{
+    constexpr static native_word<Name, Body,
+        [] {
+            if constexpr (sizeof...(Next))
+                return &native_dict<Next...>::word;
+            else
+                return (const word_base *)nullptr;
+        }()> word {Flags};
+};
+
+template<ctstring Name, ctstring Body, addr Flags, auto... Next>
+struct comp_dict
+{
+    constexpr static comp_word<Name, Body,
+        [] {
+            if constexpr (sizeof...(Next))
+                return &native_dict<Next...>::word;
+            else
+                return (const word_base *)nullptr;
+        }()> word {Flags};
+};
+
 struct forth : public word_list
 {
     static constexpr bool enable_exceptions = true;
@@ -398,54 +424,51 @@ struct forth : public word_list
             *fth.here++ = std::bit_cast<cell>((*g)->body());
         };
 
-        constexpr static native_word<"_d">             w_dict  {f_dict};
-        constexpr static native_word<"_lit", &w_dict>  w_liti  {lit_impl};
-        constexpr static native_word<"swap", &w_liti>  w_swap  {f_swap};
-        constexpr static native_word<"drop", &w_swap>  w_drop  {f_drop};
-        constexpr static native_word<"dup",  &w_drop>  w_dup   {f_dup};
-        constexpr static native_word<"rot",  &w_dup>   w_rot   {f_rot};
-        constexpr static native_word<"+",    &w_rot>   w_add   {f_add};
-        constexpr static native_word<"-",    &w_add>   w_minus {f_minus};
-        constexpr static native_word<"*",    &w_minus> w_times {f_times};
-        constexpr static native_word<"/",    &w_times> w_divid {f_divide};
-        constexpr static native_word<"mod",  &w_divid> w_mod   {f_mod};
-        constexpr static native_word<"and",  &w_mod>   w_and   {f_bitand};
-        constexpr static native_word<"or",   &w_and>   w_or    {f_bitor};
-        constexpr static native_word<"xor",  &w_or>    w_xor   {f_bitxor}; 
-        constexpr static native_word<"lshift", &w_xor> w_lsh   {f_lshift};
-        constexpr static native_word<"rshift", &w_lsh> w_rsh   {f_rshift};
-        constexpr static native_word<"[",    &w_rsh>   w_lbrac {f_lbrac,
-            word_base::immediate};
-        constexpr static native_word<"]",    &w_lbrac> w_rbrac {f_rbrac};
-        constexpr static native_word<"immediate", &w_rbrac> w_imm {f_imm};
-        constexpr static native_word<"literal", &w_imm> w_lit  {f_lit,
-            word_base::immediate};
-        constexpr static native_word<"@",    &w_lit>   w_peek  {f_peek};
-        constexpr static native_word<"!",    &w_peek>  w_poke  {f_poke};
-        constexpr static native_word<"c@",   &w_poke>  w_cpeek {f_cpeek};
-        constexpr static native_word<"c!",   &w_cpeek> w_cpoke {f_cpoke};
-        constexpr static native_word<"=",    &w_cpoke> w_eq    {f_eq};
-        constexpr static native_word<"<",    &w_eq>    w_lt    {f_lt};
-        constexpr static native_word<"\'",   &w_lt>    w_tick  {f_tick};
-        constexpr static native_word<":",    &w_tick>  w_colon {f_colon};
-        constexpr static native_word<";",    &w_colon> w_semic {f_semic,
-            word_base::immediate};
-        constexpr static native_word<"\\",   &w_semic> w_comm  {f_comm,
-            word_base::immediate};
-        constexpr static native_word<"cell", &w_comm>  w_cell  {f_cell};
-        constexpr static native_word<"_jmp", &w_cell>  w_jmp   {f_jmp};
-        constexpr static native_word<"_jmp0", &w_jmp>  w_jmp0  {f_jmp0};
-        constexpr static native_word<"postpone", &w_jmp0> w_postp {f_postpone,
-            word_base::immediate};
-        constexpr static comp_word<"cell+", "cell +", w_postp> w_cellp
+        constexpr static auto& asdf = native_dict<
+            ctstring{"_d"}, f_dict, 0,
+            ctstring{"_lit"}, lit_impl, 0,
+            ctstring{"swap"}, f_swap, 0,
+            ctstring{"drop"}, f_drop, 0,
+            ctstring{"dup"}, f_dup, 0,
+            ctstring{"rot"}, f_rot, 0,
+            ctstring{"+"}, f_add, 0,
+            ctstring{"-"}, f_minus, 0,
+            ctstring{"*"}, f_times, 0,
+            ctstring{"/"}, f_divide, 0,
+            ctstring{"mod"}, f_mod, 0,
+            ctstring{"and"}, f_bitand, 0,
+            ctstring{"or"}, f_bitor, 0,
+            ctstring{"xor"}, f_bitxor, 0,
+            ctstring{"lshift"}, f_lshift, 0,
+            ctstring{"rshift"}, f_rshift, 0,
+            ctstring{"["}, f_lbrac, word_base::immediate,
+            ctstring{"]"}, f_rbrac, 0,
+            ctstring{"immediate"}, f_imm, 0,
+            ctstring{"literal"}, f_lit, word_base::immediate,
+            ctstring{"@"}, f_peek, 0,
+            ctstring{"!"}, f_poke, 0,
+            ctstring{"c@"}, f_cpeek, 0,
+            ctstring{"c!"}, f_cpoke, 0,
+            ctstring{"="}, f_eq, 0,
+            ctstring{"<"}, f_lt, 0,
+            ctstring{"\'"}, f_tick, 0,
+            ctstring{":"}, f_colon, 0,
+            ctstring{";"}, f_semic, word_base::immediate,
+            ctstring{"\\"}, f_comm, word_base::immediate,
+            ctstring{"cell"}, f_cell, 0,
+            ctstring{"_jmp"}, f_jmp, 0,
+            ctstring{"_jmp0"}, f_jmp0, 0,
+            ctstring{"postpone"}, f_postpone, word_base::immediate
+        >::word;
+        constexpr static comp_word<"cell+", "cell +", &asdf> w_cellp
             {forth::prologue<fthp>};
-        constexpr static comp_word<"cells", "cell *", w_cellp> w_cells
+        constexpr static comp_word<"cells", "cell *", &w_cellp> w_cells
             {forth::prologue<fthp>};
-        constexpr static comp_word<"char+", "1 +", w_cells> w_charp
+        constexpr static comp_word<"char+", "1 +", &w_cells> w_charp
             {forth::prologue<fthp>};
-        constexpr static comp_word<"1+", "1 +", w_charp> w_inc
+        constexpr static comp_word<"1+", "1 +", &w_charp> w_inc
             {forth::prologue<fthp>};
-        constexpr static comp_word<"1-", "1 -", w_inc> w_dec
+        constexpr static comp_word<"1-", "1 -", &w_inc> w_dec
             {forth::prologue<fthp>};
 
         fth.next = &w_dec;