allow byte indexing

llvm
Clyne 2 years ago
parent 18bcd5dd0e
commit a506b65bdd
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

@ -1,6 +1,21 @@
( : variable create 0 , ; )
( : create here const ; )
: ! 2 _! ;
: @ 2 _@ ;
: , here ! 2 allot ;
: cell+ 2 + ;
: cells 2 * ;
: c! 1 _! ;
: c@ 1 _@ ;
: c, here c! 1 allot ;
: char+ 1+ ;
: chars ;
: align here 1 & if 1 allot then ;
: aligned dup 1 & if 1 + then ;
( set decimal numbers )
10 0 !
@ -12,6 +27,8 @@
: nip swap drop ;
: tuck swap over ;
: +! swap over @ + swap ! ;
: and & ;
: or | ;
: xor ^ ;
@ -35,15 +52,6 @@
: 2swap rot >r rot r> ;
: r@ r> dup >r ;
: , here ! 1 allot ;
: +! swap over @ + swap ! ;
: c! ! ;
: c, , ;
: c@ @ ;
: cell+ 1+ ;
: cells ;
: char+ 1+ ;
: chars ;
: 2! swap over ! cell+ ! ;
: 2@ dup cell+ @ swap @ ;
@ -62,6 +70,3 @@
: min 2dup <= if drop else nip then ;
: max 2dup <= if nip else drop then ;
: align ;
: aligned ;

@ -122,12 +122,19 @@ int CoreWords::op_mod(State& state) {
}
int CoreWords::op_peek(State& state) {
if (auto w = state.pop(); w == 1)
state.push(state.dict.readbyte(state.pop()));
else
state.push(state.dict.read(state.pop()));
return 0;
}
int CoreWords::op_poke(State& state) {
const auto w = state.pop();
const auto addr = state.pop();
if (w == 1)
state.dict.writebyte(addr, state.pop());
else
state.dict.write(addr, state.pop());
return 0;
}
@ -202,7 +209,7 @@ int CoreWords::op_comment(State& state) {
int CoreWords::op_colon(State& state) {
state.pass = Pass::Colon;
state.pushr(state.dict.here);
state.pushr(state.dict.alignhere());
return 0;
}
@ -238,21 +245,21 @@ int CoreWords::op_imm(State& state)
int CoreWords::op_const(State& state)
{
state.pass = Pass::Constant;
state.pushr(state.dict.here);
state.pushr(state.dict.alignhere());
return 0;
}
int CoreWords::op_literal(State& state)
{
state.push(state.beyondip());
++state.ip;
state.ip += sizeof(Cell);
return 0;
}
int CoreWords::op_jump(State& state)
{
state.pushr(state.ip + 1);
state.ip = state.beyondip() - 1;
state.pushr(state.ip + sizeof(Cell));
state.ip = state.beyondip() - sizeof(Cell);
return 0;
}
@ -263,9 +270,9 @@ int CoreWords::op_if(State& state)
state.dict.add(0);
} else {
if (state.pop())
++state.ip;
state.ip += sizeof(Cell);
else
state.ip = state.beyondip() - 1;
state.ip = state.beyondip() - sizeof(Cell);
}
return 0;
@ -290,7 +297,7 @@ int CoreWords::op_else(State& state)
state.dict.add(0);
state.dict.write(ifaddr, state.dict.here);
} else {
state.ip = state.beyondip() - 1;
state.ip = state.beyondip() - sizeof(Cell);
}
return 0;

@ -43,7 +43,7 @@ private:
constexpr static char wordsarr[] =
"drop\0dup\0swap\0pick\0sys\0"
"+\0-\0*\0/\0%\0"
"@\0!\0rot\0>r\0r>\0"
"_@\0_!\0rot\0>r\0r>\0"
"=\0<\0allot\0&\0|\0"
"^\0<<\0>>\0(\0:\0"
";\1here\0imm\0const\0"

@ -27,7 +27,15 @@ Addr Dictionary::allot(Cell amount)
void Dictionary::add(Cell value)
{
write(here++, value);
write(allot(sizeof(Cell)), value);
}
Addr Dictionary::alignhere()
{
if (here & (sizeof(Cell) - sizeof(uint8_t)))
here = (here + sizeof(Cell)) & ~(sizeof(Cell) - sizeof(uint8_t));
return here;
}
void Dictionary::addDefinition(std::string_view str)
@ -43,8 +51,10 @@ bool Dictionary::issame(Addr addr, std::string_view str, std::size_t n)
return false;
for (char c : str) {
if (read(addr++) != c)
if (read(addr) != c)
return false;
addr += sizeof(Cell);
}
return true;
@ -55,16 +65,17 @@ Addr Dictionary::find(std::string_view str)
if (latest == 0)
return 0;
auto lt = latest;
Addr lt = latest, oldlt;
do {
oldlt = lt;
const auto l = read(lt);
const auto len = l & 0x1F;
if (issame(lt + 1, str, len))
if (issame(lt + sizeof(Cell), str, len))
return lt;
else
lt -= l >> 6;
} while (lt);
} while (lt != oldlt);
return 0;
}
@ -72,6 +83,6 @@ Addr Dictionary::find(std::string_view str)
Addr Dictionary::getexec(Addr addr)
{
const auto len = read(addr) & 0x1F;
return addr + 1 + len;
return addr + (1 + len) * sizeof(Cell);
}

@ -22,20 +22,25 @@
#include "types.hpp"
#include <cstddef>
#include <cstdint>
#include <string_view>
class Dictionary
{
public:
constexpr static Addr Base = 0;
constexpr static Addr Compiling = 1;
constexpr static Addr Base = 0 * sizeof(Cell);
constexpr static Addr Compiling = 1 * sizeof(Cell);
constexpr static Addr Begin = 2 * sizeof(Cell);
Addr here = 2;
Addr latest = 0;
Addr here = Begin;
Addr latest = Begin;
virtual Cell read(Addr) const = 0;
virtual int write(Addr, Cell) = 0;
virtual uint8_t readbyte(Addr) const = 0;
virtual int writebyte(Addr, uint8_t) = 0;
Addr alignhere();
Addr allot(Cell);
void add(Cell);
void addDefinition(std::string_view);

@ -22,10 +22,10 @@
int Executor::fullexec(State& state, Addr addr)
{
state.pushr(0);
state.ip = addr - 1;
state.ip = addr - sizeof(Cell);
do {
++state.ip;
state.ip += sizeof(Cell);
CoreWords::run(state.dict.read(state.ip), state);
} while (state.ip);

@ -25,14 +25,23 @@ constexpr unsigned long int MemDictSize = 4096;
class MemDict : public Dictionary
{
Cell dict[MemDictSize];
uint8_t dict[MemDictSize];
public:
virtual Cell read(Addr addr) const final {
return dict[addr];
return *reinterpret_cast<const Cell *>(dict + addr);
}
virtual int write(Addr addr, Cell value) final {
*reinterpret_cast<Cell *>(dict + addr) = value;
return 0;
}
virtual uint8_t readbyte(Addr addr) const final {
return dict[addr];
}
virtual int writebyte(Addr addr, uint8_t value) final {
dict[addr] = value;
return 0;
}

@ -20,6 +20,13 @@
#include <iterator>
struct pop {};
struct push {};
struct popr {};
struct pushr {};
struct top {};
struct pick {};
bool State::compiling() const
{
return dict.read(Dictionary::Compiling);
@ -32,48 +39,48 @@ void State::compiling(bool yes)
Cell State::beyondip() const
{
return dict.read(ip + 1);
return dict.read(ip + sizeof(Cell));
}
void State::pushr(Cell value)
{
if (rsize() == ReturnStackSize)
throw;
throw ::pushr();
*++rsp = value;
}
Cell State::popr()
{
if (rsize() == 0)
throw;
throw ::popr();
return *rsp--;
}
void State::push(Cell value)
{
if (size() == DataStackSize)
throw;
throw ::push();
*++dsp = value;
}
Cell State::pop()
{
if (size() == 0)
throw;
throw ::pop();
return *dsp--;
}
Cell& State::top()
{
if (size() == 0)
throw;
throw ::top();
return *dsp;
}
Cell& State::pick(std::size_t i)
{
if (i >= size())
throw;
throw ::pick();
return *(dsp - i);
}

Loading…
Cancel
Save