]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
consteval and other refactoring
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 14 Oct 2023 21:38:57 +0000 (17:38 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 14 Oct 2023 21:38:57 +0000 (17:38 -0400)
libalee/corewords.cpp
libalee/corewords.hpp
libalee/ctype.cpp [deleted file]
libalee/ctype.hpp
libalee/dictionary.cpp
libalee/dictionary.hpp
libalee/parser.cpp

index e9b9f47690a01a4d05ac684b5b1dfbaa5bd7fa48..62b03223b6514875659b99dfa193a0b8f0023312 100644 (file)
 #include "corewords.hpp"
 #include "parser.hpp"
 
-#include <cstring>
 #include <utility>
 
 void find(State& state, Word word)
 {
+    Cell tok = 0;
+    Cell imm = 0;
+
     if (auto j = state.dict.find(word); j > 0) {
-        state.push(state.dict.getexec(j));
-        auto imm = state.dict.read(j) & Dictionary::Immediate;
-        state.push(imm ? 1 : -1);
-    } else if (auto i = CoreWords::findi(state, word); i >= 0) {
-        state.push(i);
-        state.push(i == CoreWords::Semicolon ? 1 : -1);
-    } else {
-        state.push(0);
-        state.push(0);
+        tok = state.dict.getexec(j);
+        imm = (state.dict.read(j) & Dictionary::Immediate) ? 1 : -1;
+    } else if (tok = CoreWords::findi(state, word); tok >= 0) {
+        imm = (tok == CoreWords::Semicolon) ? 1 : -1;
     }
+
+    state.push(tok);
+    state.push(imm);
 }
 
 void CoreWords::run(Cell ins, State& state)
@@ -248,35 +248,8 @@ execute:
     ip += sizeof(Cell);
 }
 
-template<typename Iter>
-Cell findi(Iter it, std::size_t size)
-{
-    auto ptr = CoreWords::wordsarr;
-    Cell wordsi = 0;
-
-    while (ptr < CoreWords::wordsarr + sizeof(CoreWords::wordsarr)) {
-        auto end = ptr;
-        while (*end)
-            ++end;
-
-        std::size_t wordsize = end - ptr;
-        if (wordsize == size && Dictionary::equal(ptr, end, it))
-            return wordsi;
-
-        ++wordsi;
-        ptr = end + 1;
-    }
-
-    return -1;
-}
-
-Cell CoreWords::findi(const char *word)
-{
-    return ::findi(word, strlen(word));
-}
-
 Cell CoreWords::findi(State& state, Word word)
 {
-    return ::findi(word.begin(&state.dict), word.size());
+    return findi(word.begin(&state.dict), word.size());
 }
 
index d4d7ef2b1edf2236633693dc7a3da2cd80e7763c..25f6a6ec2ab5a716283b836c98b07a0113f2a3ac 100644 (file)
@@ -22,6 +22,8 @@
 #include "types.hpp"
 #include "state.hpp"
 
+#include <cstring>
+
 /**
  * To be implemented by the user, this function is called when the `sys` word
  * is executed.
@@ -38,8 +40,10 @@ public:
      * Finds execution token that corresponds to the given word.
      * Returns -1 if not found.
      */
-    static Cell findi(const char *);
     static Cell findi(State&, Word);
+    consteval static Cell findi(const char *word) {
+        return findi(word, std::strlen(word));
+    }
 
     /**
      * Executes the given CoreWord execution token using the given state.
@@ -55,6 +59,24 @@ public:
         "exit\0;\0_jmp0\0_jmp\0"
         "depth\0_rdepth\0_in\0_ev\0find\0"
         "_uma\0u<\0um/mod\0";
+
+private:
+    template<typename Iter>
+    constexpr static Cell findi(Iter it, std::size_t size)
+    {
+        const char *ptr = CoreWords::wordsarr;
+
+        for (Cell wordsi = 0; wordsi < WordCount; ++wordsi) {
+            std::size_t wordsize = std::strlen(ptr);
+
+            if (wordsize == size && Dictionary::equal(ptr, ptr + wordsize, it))
+                return wordsi;
+
+            ptr += wordsize + 1;
+        }
+
+        return -1;
+    }
 };
 
 #endif // ALEEFORTH_COREWORDS_HPP
diff --git a/libalee/ctype.cpp b/libalee/ctype.cpp
deleted file mode 100644 (file)
index 547cd11..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Alee Forth: A portable and concise Forth implementation in modern C++.
- * Copyright (C) 2023  Clyne Sullivan <clyne@bitgloo.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "ctype.hpp"
-
-bool isspace(uint8_t c) {
-    return c == ' ' || c == '\t' || c == '\r' || c == '\n';
-}
-
-bool isdigit(uint8_t c) {
-    return c >= '0' && c <= '9';
-}
-
-bool isalpha(uint8_t c) {
-    return isupper(c) || (c >= 'a' && c <= 'z');
-}
-
-bool isupper(uint8_t c) {
-    return c >= 'A' && c <= 'Z';
-}
-
index 5842dfbf66418baf58cd7e101ce3ef50a64e69aa..878c747329d0a3e5b3639e0ff2792f77ddd3a5ca 100644 (file)
 
 #include <cstdint>
 
-bool isspace(uint8_t);
-bool isdigit(uint8_t);
-bool isalpha(uint8_t);
-bool isupper(uint8_t);
+constexpr inline bool isspace(uint8_t c) {
+    return c == ' ' || c == '\t' || c == '\r' || c == '\n';
+}
+
+constexpr inline bool isdigit(uint8_t c) {
+    return c >= '0' && c <= '9';
+}
+
+constexpr inline bool isupper(uint8_t c) {
+    return c >= 'A' && c <= 'Z';
+}
+
+constexpr inline bool isalpha(uint8_t c) {
+    return isupper(c) || (c >= 'a' && c <= 'z');
+}
 
 #endif // ALEEFORTH_CTYPE_HPP
 
index 64c0ac2b22d43f992a324bc1c5bda3a4a56d60f8..0d225e052d83681d9af3cb7fab7b77849df5153f 100644 (file)
@@ -16,7 +16,6 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-#include "ctype.hpp"
 #include "dictionary.hpp"
 
 #include <cstring>
@@ -49,15 +48,9 @@ void Dictionary::add(Cell value) noexcept
     write(allot(sizeof(Cell)), value);
 }
 
-Addr Dictionary::aligned(Addr addr) const noexcept
+Addr Dictionary::aligned(Addr addr)
 {
-    Addr unaligned = addr & (sizeof(Cell) - sizeof(uint8_t));
-    if (unaligned) {
-        addr += sizeof(Cell);
-        addr -= unaligned;
-    }
-
-    return addr;
+    return (addr + (sizeof(Cell) - 1)) & ~(sizeof(Cell) - 1);
 }
 
 Addr Dictionary::alignhere() noexcept
@@ -71,11 +64,12 @@ void Dictionary::addDefinition(Word word) noexcept
     Cell wsize = word.size();
     add(wsize);
 
+    auto addr = allot(wsize);
     auto it = word.begin(this);
     const auto end = word.end(this);
 
     while (it != end)
-        writebyte(allot(1), *it++);
+        writebyte(addr++, *it++);
 
     alignhere();
 }
@@ -83,6 +77,7 @@ void Dictionary::addDefinition(Word word) noexcept
 Addr Dictionary::find(Word word) noexcept
 {
     Addr lt = latest();
+
     for (;;) {
         const Addr l = read(lt);
         const Addr len = l & 0x1F;
@@ -159,19 +154,11 @@ Word Dictionary::input() noexcept
 
 bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept
 {
-    return word.size() == len &&
-           equal(word.begin(this), word.end(this), str);
+    return word.size() == len && equal(word.begin(this), word.end(this), str);
 }
 
 bool Dictionary::equal(Word word, Word other) const noexcept
 {
-    return word.size() == other.size() &&
-           equal(word.begin(this), word.end(this), other.begin(this));
-}
-
-bool Dictionary::eqchars(char c1, char c2)
-{
-    return c1 == c2 ||
-        (isalpha(c1) && isalpha(c2) && (c1 | 32) == (c2 | 32));
+    return word.size() == other.size() && equal(word.begin(this), word.end(this), other.begin(this));
 }
 
index 14366a5898324a0dd1f897655f6d92db1d0ceda5..b43ea2e7ba198dab0bd1960bbe9d377fd246d2e9 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef ALEEFORTH_DICTIONARY_HPP
 #define ALEEFORTH_DICTIONARY_HPP
 
+#include "ctype.hpp"
 #include "types.hpp"
 
 #include <algorithm>
@@ -78,7 +79,7 @@ public:
     void latest(Addr l) noexcept { write(Latest, l); }
 
     // Aligns the given address.
-    Addr aligned(Addr) const noexcept;
+    static Addr aligned(Addr);
     // Aligns `here`.
     Addr alignhere() noexcept;
     // Advances `here` by the given number of bytes.
@@ -123,7 +124,7 @@ public:
 
     // Used for case-insensitive comparison between two iterators.
     template<typename Iter1, typename Iter2>
-    static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) {
+    constexpr static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) {
         return std::equal(b1, e1, b2, eqchars);
     }
 
@@ -131,7 +132,15 @@ public:
 
 private:
     // Case-insensitive comparison.
-    static bool eqchars(char c1, char c2);
+    constexpr static bool eqchars(char c1, char c2) {
+        if (isalpha(static_cast<uint8_t>(c1)))
+            c1 |= 32;
+        if (isalpha(static_cast<uint8_t>(c2)))
+            c2 |= 32;
+
+        return c1 == c2;
+    }
+
 };
 
 #endif // ALEEFORTH_DICTIONARY_HPP
index da7ae0b5cf92c246bb36147766f72a389a87e80e..16281d336077a88917598377bb11c1a0083b5662 100644 (file)
@@ -111,12 +111,12 @@ Error Parser::parseNumber(State& state, Word word)
         auto ins = CoreWords::findi("_lit");
 
         const Cell maxlit = Dictionary::Begin - CoreWords::WordCount;
-        if (value >= 0 && value < maxlit) {
-            state.dict.add(value + CoreWords::WordCount);
-        } else {
+        if (value >= 0 && value < maxlit)
+            value += CoreWords::WordCount;
+        else
             state.dict.add(ins);
-            state.dict.add(value);
-        }
+
+        state.dict.add(value);
     } else {
         state.push(value);
     }