MaxDistance constant; some .cpp comments

master
Clyne 1 year ago
parent 513136558e
commit 0810456e9c
Signed by: clyne
GPG Key ID: 1B74EE6C49C96795

@ -154,11 +154,11 @@ execute:
cell = state.pop(); cell = state.pop();
dcell = cell - state.dict.latest(); 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. // Large distance to previous entry: store in dedicated cell.
state.dict.write(static_cast<Addr>(cell) + sizeof(Cell), state.dict.write(static_cast<Addr>(cell) + sizeof(Cell),
static_cast<Cell>(dcell)); static_cast<Cell>(dcell));
dcell = ((1 << (sizeof(Cell) * 8 - 6)) - 1); dcell = Dictionary::MaxDistance;
} }
state.dict.write(cell, state.dict.write(cell,
(state.dict.read(cell) & 0x1F) | static_cast<Cell>(dcell << 6)); (state.dict.read(cell) & 0x1F) | static_cast<Cell>(dcell << 6));

@ -37,7 +37,7 @@ Addr Dictionary::allot(Cell amount) noexcept
if (neww < capacity()) { if (neww < capacity()) {
write(Here, static_cast<Addr>(neww)); write(Here, static_cast<Addr>(neww));
} else { } else {
// TODO // TODO how to handle allot failure? Error code?
} }
return old; return old;
@ -64,7 +64,7 @@ void Dictionary::addDefinition(Word word) noexcept
Cell wsize = word.size(); Cell wsize = word.size();
add(wsize); add(wsize);
if (alignhere() - latest() >= ((1 << (sizeof(Cell) * 8 - 6)) - 1)) if (alignhere() - latest() >= MaxDistance)
add(0); add(0);
auto addr = allot(wsize); auto addr = allot(wsize);
@ -86,7 +86,7 @@ Addr Dictionary::find(Word word) noexcept
const Addr len = l & 0x1F; const Addr len = l & 0x1F;
Word lw; Word lw;
if ((l >> 6) < 1023) { if ((l >> 6) < MaxDistance) {
lw = Word::fromLength(lt + sizeof(Cell), len); lw = Word::fromLength(lt + sizeof(Cell), len);
if (equal(word, lw)) if (equal(word, lw))
return lt; return lt;
@ -114,7 +114,7 @@ Addr Dictionary::getexec(Addr addr) noexcept
const Addr len = l & 0x1Fu; const Addr len = l & 0x1Fu;
addr += sizeof(Cell); addr += sizeof(Cell);
if ((l >> 6) == 1023) if ((l >> 6) == MaxDistance)
addr += sizeof(Cell); addr += sizeof(Cell);
addr += len; addr += len;
@ -125,7 +125,7 @@ bool Dictionary::hasInput() const noexcept
{ {
const Addr src = read(Dictionary::Source); const Addr src = read(Dictionary::Source);
const Addr end = read(Dictionary::SourceLen); 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) { while (idx < end) {
auto ch = readbyte(src + idx); auto ch = readbyte(src + idx);
@ -146,7 +146,7 @@ Word Dictionary::input() noexcept
{ {
const Addr src = read(Dictionary::Source); const Addr src = read(Dictionary::Source);
const Addr end = read(Dictionary::SourceLen); 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 wstart = src + idx;
Addr wend = wstart; Addr wend = wstart;

@ -41,7 +41,7 @@
* - bits 0..4: Length of name * - bits 0..4: Length of name
* - bit 5: Set if word is immediate * - bit 5: Set if word is immediate
* - bits 6..15: Distance (backwards) to the next entry * - 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 * - "Length" bytes of name
* - Zero or more bytes for address alignment * - Zero or more bytes for address alignment
* - Zero or more bytes of the definition's contents * - 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. */ /** Stores the dictionary's "beginning" i.e. where new definitions begin. */
constexpr static Addr Begin = sizeof(Cell) * 8 + InputCells; constexpr static Addr Begin = sizeof(Cell) * 8 + InputCells;
/** /** "Immediate" marker bit for a word's definition. */
* The "immediate" identifier bit used in a definition's information cell.
*/
constexpr static Cell Immediate = (1 << 5); 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. */ /** Returns the value of the cell at the given address. */
virtual Cell read(Addr) const noexcept = 0; virtual Cell read(Addr) const noexcept = 0;

@ -29,14 +29,17 @@ Error Parser::parse(State& state, const char *str)
{ {
auto addr = Dictionary::Input; auto addr = Dictionary::Input;
// Set source and input length
const auto len = static_cast<Cell>(std::strlen(str)); const auto len = static_cast<Cell>(std::strlen(str));
state.dict.write(addr, 0); state.dict.write(addr, 0);
state.dict.write(Dictionary::SourceLen, len); state.dict.write(Dictionary::SourceLen, len);
// Fill input buffer with string contents
addr += sizeof(Cell); addr += sizeof(Cell);
while (*str) while (*str)
state.dict.writebyte(addr++, *str++); state.dict.writebyte(addr++, *str++);
// Zero the remaining input buffer
while (addr < Dictionary::Input + Dictionary::InputCells) while (addr < Dictionary::Input + Dictionary::InputCells)
state.dict.writebyte(addr++, '\0'); state.dict.writebyte(addr++, '\0');
@ -56,8 +59,10 @@ Error Parser::parseSource(State& state)
Error Parser::parseWord(State& state, Word word) Error Parser::parseWord(State& state, Word word)
{ {
bool imm; 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) { if (ins == 0) {
auto cw = CoreWords::findi(state, word); auto cw = CoreWords::findi(state, word);
@ -121,6 +126,9 @@ void Parser::processLiteral(State& state, Cell value)
if (state.compiling()) { if (state.compiling()) {
constexpr auto ins = CoreWords::token("_lit"); 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; const Cell maxlit = Dictionary::Begin - CoreWords::WordCount;
if (value >= 0 && value < maxlit) if (value >= 0 && value < maxlit)
value += CoreWords::WordCount; value += CoreWords::WordCount;

@ -56,3 +56,4 @@ bool Word::iterator::operator!=(const iterator& other)
{ {
return dict != other.dict || addr != other.addr; return dict != other.dict || addr != other.addr;
} }

Loading…
Cancel
Save