aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-11-09 06:39:02 -0500
committerClyne Sullivan <clyne@bitgloo.com>2023-11-09 06:39:02 -0500
commit0810456e9c5c19a47511a682eeabc71008632a2c (patch)
tree9153fe7d3f42fde88491090b59aeb77519d270dc
parent513136558e55f8a843f8f326ccafe1503acf67e4 (diff)
MaxDistance constant; some .cpp comments
-rw-r--r--libalee/corewords.cpp4
-rw-r--r--libalee/dictionary.cpp12
-rw-r--r--libalee/dictionary.hpp8
-rw-r--r--libalee/parser.cpp10
-rw-r--r--libalee/types.cpp1
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<Addr>(cell) + sizeof(Cell),
static_cast<Cell>(dcell));
- dcell = ((1 << (sizeof(Cell) * 8 - 6)) - 1);
+ dcell = Dictionary::MaxDistance;
}
state.dict.write(cell,
(state.dict.read(cell) & 0x1F) | static_cast<Cell>(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<Addr>(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<uint8_t>(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<uint8_t>(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<Cell>(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;
}
+