From 0810456e9c5c19a47511a682eeabc71008632a2c Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 9 Nov 2023 06:39:02 -0500 Subject: [PATCH] MaxDistance constant; some .cpp comments --- libalee/corewords.cpp | 4 ++-- libalee/dictionary.cpp | 12 ++++++------ libalee/dictionary.hpp | 8 ++++---- libalee/parser.cpp | 10 +++++++++- libalee/types.cpp | 1 + 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp index 534f1da..661590f 100644 --- a/libalee/corewords.cpp +++ b/libalee/corewords.cpp @@ -154,11 +154,11 @@ execute: cell = state.pop(); dcell = cell - state.dict.latest(); - if (dcell > (1 << (sizeof(Cell) * 8 - 6)) - 1) { + if (dcell >= Dictionary::MaxDistance) { // Large distance to previous entry: store in dedicated cell. state.dict.write(static_cast(cell) + sizeof(Cell), static_cast(dcell)); - dcell = ((1 << (sizeof(Cell) * 8 - 6)) - 1); + dcell = Dictionary::MaxDistance; } state.dict.write(cell, (state.dict.read(cell) & 0x1F) | static_cast(dcell << 6)); diff --git a/libalee/dictionary.cpp b/libalee/dictionary.cpp index 6c359bd..f2ad231 100644 --- a/libalee/dictionary.cpp +++ b/libalee/dictionary.cpp @@ -37,7 +37,7 @@ Addr Dictionary::allot(Cell amount) noexcept if (neww < capacity()) { write(Here, static_cast(neww)); } else { - // TODO + // TODO how to handle allot failure? Error code? } return old; @@ -64,7 +64,7 @@ void Dictionary::addDefinition(Word word) noexcept Cell wsize = word.size(); add(wsize); - if (alignhere() - latest() >= ((1 << (sizeof(Cell) * 8 - 6)) - 1)) + if (alignhere() - latest() >= MaxDistance) add(0); auto addr = allot(wsize); @@ -86,7 +86,7 @@ Addr Dictionary::find(Word word) noexcept const Addr len = l & 0x1F; Word lw; - if ((l >> 6) < 1023) { + if ((l >> 6) < MaxDistance) { lw = Word::fromLength(lt + sizeof(Cell), len); if (equal(word, lw)) return lt; @@ -114,7 +114,7 @@ Addr Dictionary::getexec(Addr addr) noexcept const Addr len = l & 0x1Fu; addr += sizeof(Cell); - if ((l >> 6) == 1023) + if ((l >> 6) == MaxDistance) addr += sizeof(Cell); addr += len; @@ -125,7 +125,7 @@ bool Dictionary::hasInput() const noexcept { const Addr src = read(Dictionary::Source); const Addr end = read(Dictionary::SourceLen); - uint8_t idx = read(Dictionary::Input) & 0xFFu; + auto idx = static_cast(read(Dictionary::Input)); while (idx < end) { auto ch = readbyte(src + idx); @@ -146,7 +146,7 @@ Word Dictionary::input() noexcept { const Addr src = read(Dictionary::Source); const Addr end = read(Dictionary::SourceLen); - uint8_t idx = read(Dictionary::Input) & 0xFFu; + auto idx = static_cast(read(Dictionary::Input)); Addr wstart = src + idx; Addr wend = wstart; diff --git a/libalee/dictionary.hpp b/libalee/dictionary.hpp index 7cf1c9d..f6f6bbe 100644 --- a/libalee/dictionary.hpp +++ b/libalee/dictionary.hpp @@ -41,7 +41,7 @@ * - bits 0..4: Length of name * - bit 5: Set if word is immediate * - bits 6..15: Distance (backwards) to the next entry - * - If bits 6..15 are all one-bits then distance is in the following cell. + * - If bits 6..15 are all one-bits then "long" distance in following cell. * - "Length" bytes of name * - Zero or more bytes for address alignment * - Zero or more bytes of the definition's contents @@ -70,10 +70,10 @@ public: /** Stores the dictionary's "beginning" i.e. where new definitions begin. */ constexpr static Addr Begin = sizeof(Cell) * 8 + InputCells; - /** - * The "immediate" identifier bit used in a definition's information cell. - */ + /** "Immediate" marker bit for a word's definition. */ constexpr static Cell Immediate = (1 << 5); + /** Maximum "short" distance between two definitions. */ + constexpr static Cell MaxDistance = (1 << (sizeof(Cell) * 8 - 6)) - 1; /** Returns the value of the cell at the given address. */ virtual Cell read(Addr) const noexcept = 0; diff --git a/libalee/parser.cpp b/libalee/parser.cpp index 328198a..3699d5f 100644 --- a/libalee/parser.cpp +++ b/libalee/parser.cpp @@ -29,14 +29,17 @@ Error Parser::parse(State& state, const char *str) { auto addr = Dictionary::Input; + // Set source and input length const auto len = static_cast(std::strlen(str)); state.dict.write(addr, 0); state.dict.write(Dictionary::SourceLen, len); + // Fill input buffer with string contents addr += sizeof(Cell); while (*str) state.dict.writebyte(addr++, *str++); + // Zero the remaining input buffer while (addr < Dictionary::Input + Dictionary::InputCells) state.dict.writebyte(addr++, '\0'); @@ -56,8 +59,10 @@ Error Parser::parseSource(State& state) Error Parser::parseWord(State& state, Word word) { bool imm; - Addr ins = state.dict.find(word); + Addr ins; + // Search order: dictionary, core word-set, number, custom parse. + ins = state.dict.find(word); if (ins == 0) { auto cw = CoreWords::findi(state, word); @@ -121,6 +126,9 @@ void Parser::processLiteral(State& state, Cell value) if (state.compiling()) { constexpr auto ins = CoreWords::token("_lit"); + // Literal compression: opcodes between WordCount and Begin are unused, + // so we assign literals to them to save space. Opcode "WordCount" + // pushes zero to the stack, "WordCount + 1" pushes a one, etc. const Cell maxlit = Dictionary::Begin - CoreWords::WordCount; if (value >= 0 && value < maxlit) value += CoreWords::WordCount; diff --git a/libalee/types.cpp b/libalee/types.cpp index 83cf1f7..bfff2ae 100644 --- a/libalee/types.cpp +++ b/libalee/types.cpp @@ -56,3 +56,4 @@ bool Word::iterator::operator!=(const iterator& other) { return dict != other.dict || addr != other.addr; } +