]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
allow byte indexing
authorClyne Sullivan <clyne@bitgloo.com>
Tue, 14 Feb 2023 19:35:29 +0000 (14:35 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Tue, 14 Feb 2023 19:35:29 +0000 (14:35 -0500)
core.fth
corewords.cpp
corewords.hpp
dictionary.cpp
dictionary.hpp
executor.cpp
memdict.hpp
state.cpp

index 4d1393c0cb44ea5c0e1b361a2bfd087be27a1bfc..d9c7a59a95adcc6a5d466c1dc540916af443f985 100644 (file)
--- a/core.fth
+++ b/core.fth
@@ -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     ^ ;
 : 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 ;
-
index f0f8d5d63c6f2a918281ad160f49602a3ad76eac..de5066ef096053608a832894a3e7fad2dc7d2144 100644 (file)
@@ -122,13 +122,20 @@ int CoreWords::op_mod(State& state) {
 }
 
 int CoreWords::op_peek(State& state) {
-    state.push(state.dict.read(state.pop()));
+    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();
-    state.dict.write(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;
index 2d894a10226cd1a47f8662372f5cb5978a0ae3dc..24e1415068719672d858892eea7e0d39d11a2220 100644 (file)
@@ -43,11 +43,11 @@ 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"
-       "if\1then\1else\1depth\0";
+        "if\1then\1else\1depth\0";
 
     static Func get(int);
 
index e1165d2c075e9340c6c9c3e28cd8a98637a8c0b0..e047488159c5022161ff6b1e597c744a9dae0f3c 100644 (file)
@@ -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);
 }
 
index 5c6471acab0db8420c8afd58533330826d5fed02..fd27920420c41964ce8aa127631459d744174fd1 100644 (file)
 #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);
index 30d43fcd87b778fce1f6f73b5f0988a3666760d9..0309ca78e8e739ca1b5c0c469d3ef248b79d51d6 100644 (file)
 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);
     
index 8606da2c595570f8c37ff3b13d98cc7e7491fa4b..6209f3b22194c46c4e55cd5f521cb579e613a44d 100644 (file)
@@ -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;
     }
index 6165ce4efc910fc832c19792e465ec0b79d7970b..ae9c0598548412c42e30b15b870a8ecf49aad0cf 100644 (file)
--- a/state.cpp
+++ b/state.cpp
 
 #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);
 }