]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
packed literals; faster execution
authorClyne Sullivan <clyne@bitgloo.com>
Mon, 27 Feb 2023 00:31:00 +0000 (19:31 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Mon, 27 Feb 2023 00:31:00 +0000 (19:31 -0500)
Makefile
core.fth
corewords.cpp
corewords.hpp
dictionary.cpp
parser.cpp
state.cpp
state.hpp

index 30e210b6e62f881221f3f13bbf2d3501ca54361d..66d9132c45d4f7006492ce777e9fffe3f0169f76 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ msp430: alee-msp430
 small: CXXFLAGS += -Os
 small: alee
 
-fast: CXXFLAGS += -O3 -march=native -mtune=native
+fast: CXXFLAGS += -O3 -march=native -mtune=native -flto
 fast: alee
 
 alee: $(LIBFILE)
index 24ef53699a7d44d9b60fa00f2bb2613849b32e7a..147522401257bde84005cb48f73094183cdefad0 100644 (file)
--- a/core.fth
+++ b/core.fth
@@ -19,7 +19,7 @@
 : here     1 cells @ ;
 : allot    1 cells +! ;
 : _latest  2 cells ;
-: imm      _latest @ dup @ 1 5 << | swap ! ;
+: imm      _latest @ dup @ 1 6 << | swap ! ;
 : state    3 cells ;
 : postpone 1 4 cells ! ; imm
 : _input   5 cells ;
@@ -46,7 +46,7 @@
 : decimal  10 base ! ;
 : hex      16 base ! ;
 
-: literal  0 , , ; imm
+: literal  1 , , ; imm
 : [']      ' postpone literal ; imm
 : [        0 state ! ; imm
 : ]        1 state ! ;
 
 : create   align here bl word count nip cell+ allot align
            ['] _lit , here 3 cells + , ['] exit dup , ,
-           dup @ 31 & over _latest @ - 6 << or over ! _latest ! ;
+           dup @ 31 & over _latest @ - 7 << or over ! _latest ! ;
 : _latword _latest @
            dup @ 31 & + cell+ aligned ;
 : _does>   _latword 2 cells +
index 9043dba428060a63b6fdafdfe450f2b174119c15..1ee7928f0504b9d47d8d2a6b943d3f420d4dc5fb 100644 (file)
@@ -36,7 +36,7 @@ void newdef(Dictionary& dict, Word word)
     dict.addDefinition(word);
     dict.write(addr,
         (dict.read(addr) & 0x1F) |
-        ((addr - dict.latest()) << 6));
+        ((addr - dict.latest()) << 7));
     dict.latest(addr);
 };
 void tick(State& state)
@@ -45,7 +45,7 @@ void tick(State& state)
     if (auto j = state.dict.find(word); j > 0)
         state.push(state.dict.getexec(j));
     else if (auto i = CoreWords::findi(state, word); i >= 0)
-        state.push(i & ~CoreWords::Immediate);
+        state.push(((i & ~CoreWords::Immediate) << 1) | 1);
     else
         state.push(0);
 }
@@ -56,14 +56,14 @@ void CoreWords::run(unsigned int index, State& state)
     DoubleCell dcell;
 
 execute:
-    switch (index) {
-    default:
+    if ((index & 1) == 0) {
         // must be calling a defined subroutine
         state.pushr(state.ip);
         state.ip = index;
         return;
+    } else switch ((index & 0x3E) >> 1) {
     case 0: // _lit
-        state.push(state.beyondip());
+        state.push((index & 0xFF00) ? (index >> 8) - 1 : state.beyondip());
         break;
     case 1: // drop
         state.pop();
@@ -165,7 +165,6 @@ execute:
     case 24: // execute
         index = state.pop();
         goto execute;
-        break;
     case 25: // exit
         state.ip = state.popr();
         if (state.ip == 0) {
@@ -174,7 +173,7 @@ execute:
         }
         break;
     case 26: // semic
-        state.dict.add(findi("exit"));
+        state.dict.add((findi("exit") << 1) | 1);
         state.compiling(false);
         break;
     case 27: // _jmp0
@@ -213,17 +212,16 @@ execute:
 
 int CoreWords::findi(const char *word)
 {
-    const auto size = std::strlen(word);
-    std::size_t i;
+    std::size_t i = 0;
     int wordsi = 0;
 
-    for (i = 0; i < sizeof(wordsarr);) {
+    while (i < sizeof(wordsarr)) {
         auto end = i;
-        while (wordsarr[end] > '\1')
+        while (wordsarr[end])
             ++end;
 
-        if (size == end - i && !std::strncmp(word, wordsarr + i, size))
-            return wordsarr[end] == '\0' ? wordsi : (wordsi | Immediate);
+        if (!std::strcmp(word, wordsarr + i))
+            return wordsi;
 
         ++wordsi;
         i = end + 1;
@@ -234,16 +232,16 @@ int CoreWords::findi(const char *word)
 
 int CoreWords::findi(State& state, Word word)
 {
-    std::size_t i;
+    std::size_t i = 0;
     int wordsi = 0;
 
-    for (i = 0; i < sizeof(wordsarr);) {
+    while (i < sizeof(wordsarr)) {
         auto end = i;
-        while (wordsarr[end] > '\1')
+        while (wordsarr[end])
             ++end;
 
         if (state.dict.equal(word, wordsarr + i, end - i))
-            return wordsarr[end] == '\0' ? wordsi : (wordsi | Immediate);
+            return wordsi;
 
         ++wordsi;
         i = end + 1;
index 020694f7878783274a5a8a7dbe134d4dccbbb45e..56f7703a5dc4297fc2954d642f10c9fb20a1dd79 100644 (file)
@@ -29,22 +29,22 @@ class CoreWords
 public:
     constexpr static std::size_t WordCount = 32;
 
-    constexpr static Cell Immediate = (1 << 5);
+    constexpr static Cell Immediate = (1 << 6);
+
+    constexpr static int Semicolon = 26;
 
     static int findi(const char *);
     static int findi(State&, Word);
     static void run(unsigned int, State&);
 
 private:
-    // Ends with '\0': regular word
-    // Ends with '\1': compile-only word
     constexpr static char wordsarr[] =
         "_lit\0drop\0dup\0swap\0pick\0sys\0"
         "+\0-\0m*\0_/\0_%\0"
         "_@\0_!\0>r\0r>\0=\0"
         "<\0&\0|\0^\0"
         "<<\0>>\0:\0'\0execute\0"
-        "exit\0;\1_jmp0\0_jmp\0"
+        "exit\0;\0_jmp0\0_jmp\0"
         "depth\0_rdepth\0key\0";
 };
 
index 199f3ed16ee28cd163a56b7168623fc82c5af1d7..fe19684f42238f04173590663b6216ec99e87d78 100644 (file)
@@ -72,7 +72,7 @@ Addr Dictionary::find(Word word) noexcept
         if (equal(word, lw))
             return lt;
         else
-            lt -= l >> 6;
+            lt -= l >> 7;
     } while (lt != oldlt);
 
     return 0;
index 91c4e5c7a76f4ddc8ab739dc77a90c1edc1088eb..7335f9018259f0c2c8ab5f7e34b98996ef7d2ee7 100644 (file)
@@ -62,8 +62,9 @@ int Parser::parseWord(State& state, Word word)
         if (ins < 0) {
             return parseNumber(state, word);
         } else {
-            imm = ins & CoreWords::Immediate;
+            imm = ins == CoreWords::Semicolon;
             ins &= ~CoreWords::Immediate;
+            ins = (ins << 1) | 1;
         }
     } else {
         imm = state.dict.read(ins) & CoreWords::Immediate;
@@ -97,8 +98,14 @@ int Parser::parseNumber(State& state, Word word)
 
     if (ec == std::errc() && ptr == buf + i) {
         if (state.compiling()) {
-            state.dict.add(CoreWords::findi("_lit"));
-            state.dict.add(l);
+            auto ins = (CoreWords::findi("_lit") << 1) | 1;
+
+            if (l >= 0 && l < 0xFF) {
+                state.dict.add(ins | ((l + 1) << 8));
+            } else {
+                state.dict.add(ins);
+                state.dict.add(l);
+            }
         } else {
             state.push(l);
         }
index 8e0f78dbcacc8689ecae74531d3f75b9c0c60865..ea6c6018714776a83643502ecd65807d1adbec5d 100644 (file)
--- a/state.cpp
+++ b/state.cpp
@@ -33,25 +33,24 @@ void State::compiling(bool yes)
 
 State::Error State::execute(Addr addr)
 {
-    auto stat = setjmp(jmpbuf);
-    if (!stat) {
-        if (addr < CoreWords::WordCount) {
-            CoreWords::run(addr, *this);
-            ip = 0;
-        } else {
-            auto ins = addr;
+    auto stat = static_cast<State::Error>(setjmp(jmpbuf));
+
+    if (stat == State::Error::none) {
+        CoreWords::run(addr, *this);
 
-            for (;;) {
-                CoreWords::run(ins, *this);
-                ins = dict.read(ip);
-            }
+        if (ip >= Dictionary::Begin) {
+            // longjmp will exit this loop.
+            for (;;)
+                CoreWords::run(dict.read(ip), *this);
+        } else {
+            // addr was a CoreWord, all done now.
+            ip = 0;
         }
-    } else {
-        auto err = static_cast<State::Error>(stat);
-        return err == State::Error::exit ? State::Error::none : err;
+    } else if (stat == State::Error::exit) {
+        stat = State::Error::none;
     }
 
-    return State::Error::none;
+    return stat;
 }
 
 std::size_t State::size() const noexcept
index 76b3c677e9344b7e73f868117dd071bdaed8d9a8..28396dc37e5a3a574c578bebed4b153bc973c987 100644 (file)
--- a/state.hpp
+++ b/state.hpp
@@ -31,7 +31,7 @@ constexpr unsigned ReturnStackSize = 16;
 struct State
 {
     enum class Error : int {
-        none,
+        none = 0,
         push,
         pop,
         pushr,