]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
Merge branch 'documentation'
authorClyne Sullivan <clyne@bitgloo.com>
Tue, 14 Nov 2023 03:04:32 +0000 (22:04 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Tue, 14 Nov 2023 03:04:32 +0000 (22:04 -0500)
1  2 
libalee/corewords.cpp
libalee/corewords.hpp
libalee/ctype.hpp
libalee/dictionary.cpp
libalee/dictionary.hpp
libalee/parser.cpp
libalee/parser.hpp
libalee/state.hpp
libalee/types.hpp
memdict.hpp

index b7681635e3e9ad81a15b84d2942905ccc9ddb5e0,661590f8140971982a8a6e5dd564ca9e52349ae4..7c79aea4e2e1a6ef133161da2f7431c6944bd1da
  
  #include <utility>
  
- LIBALEE_SECTION
- void find(State& state, Word word)
- {
-     Cell tok = 0;
-     Cell imm = 0;
-     if (auto j = state.dict.find(word); j > 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);
- }
+ static void find(State&, Word);
+ static DoubleCell popd(State&);
+ static void pushd(State&, DoubleCell);
  
 +LIBALEE_SECTION
  void CoreWords::run(Cell ins, State& state)
  {
      Cell cell;
@@@ -259,3 -235,33 +236,34 @@@ Cell CoreWords::findi(State& state, Wor
      return findi(word.begin(&state.dict), word.size());
  }
  
++LIBALEE_SECTION
+ void find(State& state, Word word)
+ {
+     Cell tok = 0;
+     Cell imm = 0;
+     if (auto j = state.dict.find(word); j > 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::token(";")) ? 1 : -1;
+     }
+     state.push(tok);
+     state.push(imm);
+ }
+ DoubleCell popd(State& s)
+ {
+     DoubleCell dcell = s.pop();
+     dcell <<= sizeof(Cell) * 8;
+     dcell |= static_cast<Addr>(s.pop());
+     return dcell;
+ }
+ void pushd(State& s, DoubleCell d)
+ {
+     s.push(static_cast<Cell>(d));
+     s.push(static_cast<Cell>(d >> (sizeof(Cell) * 8)));
+ }
index f4ab851ebc29601bf402f529469e8953f9e969a3,630f3cf163ef2be4880b84081e1210e74cc0ba53..30d0a42d10b500d791588a786a8c50fe9369bf5f
  #ifndef ALEEFORTH_COREWORDS_HPP
  #define ALEEFORTH_COREWORDS_HPP
  
- #include "types.hpp"
 +#include "config.hpp"
 -#include "state.hpp"
 +#include "dictionary.hpp"
+ #include "types.hpp"
 -#include <cstring>
+ #include <algorithm>
++
++class State;
  
  /**
   * To be implemented by the user, this function is called when the `sys` word
@@@ -32,16 -41,23 +43,23 @@@ void user_sys(State& state)
  class CoreWords
  {
  public:
-     constexpr static Cell WordCount = 37;
-     constexpr static Cell Semicolon = 26;
+     /**
+      * Searches for the token/index of the given word if it is part of the
+      * fundamental word-set.
+      * @param state Current execution state object.
+      * @param word Word (stored in state's dictionary memory) to look up.
+      * @return The token/index of the word or -1 if not found.
+      */
+     static Cell findi(State& state, Word word);
  
      /**
-      * Finds execution token that corresponds to the given word.
-      * Returns -1 if not found.
+      * Looks up the token/index of the given fundamental word.
+      * Primarily used for compile-time lookup.
+      * @param word The word to look up.
+      * @return The token/index of the word or -1 if not found.
       */
-     static Cell findi(State&, Word);
-     consteval static Cell findi(const char *word) {
+     consteval static Cell token(const char *word) {
 -        return findi(word, std::strlen(word));
 +        return findi(word, strlen(word));
      }
  
      /**
          "depth\0_rdepth\0_in\0_ev\0find\0"
          "_uma\0u<\0um/mod\0";
  
+     /**
+      * Count of total fundamental words.
+      */
+     constexpr static Cell WordCount = [] {
+         return std::count(wordsarr, wordsarr + sizeof(wordsarr), '\0'); }();
  private:
+     /**
+      * Generic implementation of findi(). Private; use public implementations.
+      * @param it Beginning iterator of the word to search for.
+      * @param size Size of the searched-for word i.e. end == it + size.
+      * @return The token/index of the word or -1 if not found.
+      */
      template<typename Iter>
 +    LIBALEE_SECTION
      constexpr static Cell findi(Iter it, std::size_t size)
      {
          const char *ptr = CoreWords::wordsarr;
index b0df174f01ceeb06c4ea88a13a8f45dd64d95cd0,5252edaab5700ec989e0314473723001c605e9f2..f7ce3fb2eb39ef7a99f95a170d4a4ae4de72d8b3
  #ifndef ALEEFORTH_CTYPE_HPP
  #define ALEEFORTH_CTYPE_HPP
  
- /**
-  * We implement our own character comparison functions to keep them lean.
-  */
  #include <cstdint>
  
++/** Determines the length of a null-terminated string. */
 +constexpr inline unsigned strlen(const char * const s) {
 +    unsigned i = 0;
 +    while (s[i]) i++;
 +    return i;
 +}
 +
+ /** Tests if given character represents whitespace. */
  constexpr inline bool isspace(uint8_t c) {
      return c == ' ' || c == '\t' || c == '\r' || c == '\n';
  }
@@@ -43,10 -38,7 +45,12 @@@ constexpr inline bool isupper(uint8_t c
      return c >= 'A' && c <= 'Z';
  }
  
++/** Tests if given character is a lowercase letter. */
 +constexpr inline bool islower(uint8_t c) {
 +    return c >= 'a' && c <= 'z';
 +}
 +
+ /** Tests if given character is a letter. */
  constexpr inline bool isalpha(uint8_t c) {
      return isupper(c) || (c >= 'a' && c <= 'z');
  }
Simple merge
index 27edf68762fb7a935fa4fccf4821a74f2503e926,f6f6bbe42db4beaa1e96b10baad6fe2ebb438a79..ad1ee02afd42f658a5dc602286d3cfd5ace88be4
@@@ -73,30 -96,59 +97,63 @@@ public
       */
      void initialize();
  
+     /**
+      * Gets the address stored in `here`.
+      */
 +    LIBALEE_SECTION
      Addr here() const noexcept { return read(Here); }
+     /**
+      * Sets the address stored in `here`.
+      */
 +    LIBALEE_SECTION
      void here(Addr l) noexcept { write(Here, l); }
  
+     /**
+      * Gets the value of `latest`.
+      */
 +    LIBALEE_SECTION
      Addr latest() const noexcept { return read(Latest); }
+     /**
+      * Sets the value of `latest`.
+      */
 +    LIBALEE_SECTION
      void latest(Addr l) noexcept { write(Latest, l); }
  
-     // Aligns the given address.
-     static Addr aligned(Addr);
-     // Aligns `here`.
+     /**
+      * Aligns the given address to the next Cell boundary if necessary.
+      * @param addr The address to align.
+      * @return The resulting aligned address.
+      */
+     static Addr aligned(Addr addr);
+     /**
+      * Aligns `here` to the next Cell boundary if necessary.
+      * @return The new aligned address stored in `here`.
+      */
      Addr alignhere() noexcept;
-     // Advances `here` by the given number of bytes.
-     Addr allot(Cell) noexcept;
-     // Stores value to `here`, then adds sizeof(Cell) to `here`.
-     void add(Cell) noexcept;
  
      /**
-      * Uses add() to store a new definition entry starting at `here`.
-      * The entry does not become active until a semicolon is executed.
+      * Allocates memory by returning and then increasing the current `here`.
+      * @param count The number of bytes to increase `here` by.
+      * @return The address stored in `here` before the increase.
       */
-     void addDefinition(Word) noexcept;
+     Addr allot(Cell count) noexcept;
+     /**
+      * Stores the given value to `here` then calls allot to "save" that cell.
+      * @param value The value to store.
+      * @see allot(Cell)
+      */
+     void add(Cell value) noexcept;
+     /**
+      * Stores the beginning of a new word definition in the dictionary.
+      * The word must eventually have its definition concluded via semicolon.
+      * @param word The dictionary-stored name of the new word.
+      */
+     void addDefinition(Word word) noexcept;
  
      /**
       * Searches the dictionary for an entry for the given word.
      bool hasInput() const noexcept;
  
      /**
-      * Checks if this dictionary's word is equivalent to the given string/size.
+      * Checks if the dictionary-stored word is equivalent to the given string.
+      * @param word Dictionary-stored word to compare against.
+      * @param str String to compare to.
+      * @param size Size of the string to compare to.
+      * @return True if the two words are equivalent.
       */
-     bool equal(Word, const char *, unsigned) const noexcept;
+     bool equal(Word word, const char *str, unsigned size) const noexcept;
  
      /**
-      * Checks if two words in this dictionary's word are equivalent.
+      * Checks if two words stored in this dictionary are equivalent.
+      * @param word1 First word to compare
+      * @param word2 Second word to compare
+      * @return True if the words are equivalent.
       */
-     bool equal(Word, Word) const noexcept;
+     bool equal(Word word1, Word word2) const noexcept;
  
-     // Used for case-insensitive comparison between two iterators.
+     /**
+      * Generic equality comparison using our own case-insensitive comparator.
+      * Arguments and return value identical to std::equal.
+      */
      template<typename Iter1, typename Iter2>
 +    LIBALEE_SECTION
      constexpr static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) {
          return std::equal(b1, e1, b2, eqchars);
      }
  
 -    virtual ~Dictionary() = default;
 +    virtual ~Dictionary() {};
  
  private:
-     // Case-insensitive comparison.
+     /**
+      * Case-insensitive character comparison used for dictionary lookup.
+      * @return True if the characters are equivalent.
+      */
 +    LIBALEE_SECTION
      constexpr static bool eqchars(char c1, char c2) {
          if (isalpha(static_cast<uint8_t>(c1)))
              c1 |= 32;
index b3e82114c8328d21cf78472bec8fb7d3780196bc,3699d5f3bae27448c9074a16ce13993e16d1b026..11aba381a0db076ce7592894dd8b4f9b9efd65d3
@@@ -25,7 -29,8 +25,8 @@@ Error Parser::parse(State& state, cons
  {
      auto addr = Dictionary::Input;
  
 -    const auto len = static_cast<Cell>(std::strlen(str));
+     // Set source and input length
 +    const auto len = static_cast<Cell>(strlen(str));
      state.dict.write(addr, 0);
      state.dict.write(Dictionary::SourceLen, len);
  
Simple merge
index 0ac9a7c9b5226a863efa59d8f443fdb53c5401c7,60ff95f1b6b470a01c56e6b460a1d6ead2275d56..a5e49b535044155ef9bddff9b3af47cbc2c15b89
@@@ -58,12 -81,12 +82,14 @@@ public
       */
      void reset();
  
+     /** Returns a reference to the instruction pointer. */
 +    LIBALEE_SECTION
      Addr& ip() noexcept {
          return context.ip;
      }
  
+     /** Calls the user input function with this state as the argument. */
 +    LIBALEE_SECTION
      void input() noexcept {
          inputfunc(*this);
      }
       */
      void load(const Context&);
  
+     /**
+      * Pushes the given value to the data stack.
+      */
 +    LIBALEE_SECTION
      inline void push(Cell value) {
          verify(dsp < dstack + DataStackSize, Error::push);
          *dsp++ = value;
      }
  
+     /**
+      * Pops a value from the data stack and returns that value.
+      */
 +    LIBALEE_SECTION
      inline Cell pop() {
          verify(dsp > dstack, Error::pop);
          return *--dsp;
      }
  
+     /**
+      * Pushes the given value to the return stack.
+      */
 +    LIBALEE_SECTION
      inline void pushr(Cell value) {
          verify(rsp < rstack + ReturnStackSize, Error::pushr);
          *rsp++ = value;
      }
  
+     /**
+      * Pops a value from the return stack and returns that value.
+      */
 +    LIBALEE_SECTION
      inline Cell popr() {
          verify(rsp > rstack, Error::popr);
          return *--rsp;
      }
  
+     /**
+      * Returns the value stored at the current data stack position.
+      */
 +    LIBALEE_SECTION
      inline Cell& top() {
          verify(dsp > dstack, Error::top);
          return *(dsp - 1);
      }
  
+     /**
+      * Picks a value currently stored on the data stack.
+      * @param i Index from current position to fetch from
+      * @return The value stored at the given index
+      */
 +    LIBALEE_SECTION
      inline Cell& pick(std::size_t i) {
          verify(dsp - i > dstack, Error::pick);
          return *(dsp - i - 1);
      }
  
-     // Advances the instruction pointer and returns that cell's contents.
+     /**
+      * Advances the instruction pointer and returns that cell's contents.
+      */
 +    LIBALEE_SECTION
      inline Cell beyondip() {
          context.ip += sizeof(Cell);
          return dict.read(context.ip);
      }
  
+     /**
+      * Asserts the given condition is true, longjmp-ing if false.
+      * Used as an exception handler and the method of exiting execution.
+      * @param condition Condition to be tested
+      * @param error Error code to report via longjmp() on false condition
+      */
 +    LIBALEE_SECTION
      inline void verify(bool condition, Error error) {
          if (!condition)
              std::longjmp(context.jmpbuf, static_cast<int>(error));
index 028c49011429f49badc34b6fc5dd7f58265c5fea,a122c8450888e3d7d5c3ba4ac105c73b11b5ba7c..7b5bb6288fc1528a4eb1f96b05e933212414c145
@@@ -61,7 -73,12 +73,13 @@@ public
      constexpr explicit Word(Addr s = 0, Addr e = 0):
          start(s), wend(e) {}
  
+     /**
+      * Constructs a word using beginning index and length.
+      * @param s Beginning/start index of word
+      * @param l Count of bytes until end of word
+      * @return Resulting Word object
+      */
 +    LIBALEE_SECTION
      static constexpr Word fromLength(Addr s, Addr l) {
          return Word(s, s + l);
      }
diff --cc memdict.hpp
index 003b3a7e023e446d2c52ddf83b0d5ebb7f7bf84a,b1dbe55ab27227f81b9cbe1321db72112c8fe996..9861921cc8f70b76465b35656657b759c6e4f434
  #ifndef ALEEFORTH_MEMDICT_HPP
  #define ALEEFORTH_MEMDICT_HPP
  
 -#include "alee.hpp"
 +#include "libalee/alee.hpp"
  
  #ifndef MEMDICTSIZE
+ /** Default dictionary size in bytes. */
  #define MEMDICTSIZE (65536)
  #endif
+ /** Size in bytes of a MemDict. */
  constexpr unsigned long int MemDictSize = MEMDICTSIZE;
  
+ /**
+  * @class MemDict
+  * Dictionary implementation that uses a large block of memory.
+  */
  class MemDict : public Dictionary
  {
+     /** Block of memory to contain dictionary's contents. */
      uint8_t dict[MemDictSize] = {0};
  
  public: