]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
-Wconversion
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 18 Mar 2023 16:40:46 +0000 (12:40 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 18 Mar 2023 16:40:46 +0000 (12:40 -0400)
16 files changed:
Makefile
alee-standalone.cpp
alee.cpp
libalee/corewords.cpp
libalee/corewords.hpp
libalee/ctype.cpp
libalee/ctype.hpp
libalee/dictionary.cpp
libalee/dictionary.hpp
libalee/parser.cpp
libalee/state.cpp
libalee/types.cpp
libalee/types.hpp
memdict.hpp
msp430/alee-msp430.cpp
splitmemdict.hpp

index 3ae2e234cad0bfe608db9e7962f23b55be838239..9deec8b58fbb719c0afc3c869934052a4fa0d527 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \
-            -pedantic -Wall -Wextra -Werror -Weffc++ \
+            -pedantic -Wall -Wextra -Werror -Weffc++ -Wconversion \
             -fno-exceptions -fno-threadsafe-statics -fno-rtti #-fstack-usage
 
 CXXFILES := $(wildcard libalee/*.cpp)
@@ -10,6 +10,7 @@ all: alee
 
 msp430: CXX := msp430-elf32-g++
 msp430: AR := msp430-elf32-gcc-ar
+msp430: CXXFLAGS += -I.
 msp430: CXXFLAGS += -Os -mmcu=msp430g2553 -ffunction-sections -fdata-sections
 msp430: CXXFLAGS += -DMEMDICTSIZE=200 -flto
 msp430: LDFLAGS += -L/opt/msp430-elf32/include -Tmsp430/msp430g2553.ld -Wl,-gc-sections
index 5c9f8a89936c9f2c98188dc3ae13d7709680f15c..488d3baf6be15c852597a57e49d0d1b52cc1d916 100644 (file)
@@ -51,10 +51,10 @@ int main(int argc, char *argv[])
 
 static void readchar(State& state)
 {
-    auto idx = state.dict.read(Dictionary::Input);
+    Addr idx = state.dict.read(Dictionary::Input);
     Addr addr = Dictionary::Input + sizeof(Cell) + idx;
 
-    auto c = std::cin.get();
+    auto c = static_cast<char>(std::cin.get());
     if (isupper(c))
         c += 32;
     state.dict.writebyte(addr, c ? c : ' ');
@@ -76,7 +76,7 @@ static void load(State& state)
 
     Addr i = 0;
     while (file.good())
-        state.dict.writebyte(i++, file.get());
+        state.dict.writebyte(i++, file.get() & 0xFFu);
 }
 
 void user_sys(State& state)
index dfe85d1c417bf1d7fa09aaae802ed17074c5ebed..c7c9ddf16e0572864c0b2d6388a9bc6d8000871e 100644 (file)
--- a/alee.cpp
+++ b/alee.cpp
@@ -54,9 +54,9 @@ int main(int argc, char *argv[])
 static void readchar(State& state)
 {
     auto idx = state.dict.read(Dictionary::Input);
-    Addr addr = Dictionary::Input + sizeof(Cell) + idx;
+    auto addr = static_cast<Addr>(Dictionary::Input + sizeof(Cell) + idx);
 
-    auto c = std::cin.get();
+    auto c = static_cast<char>(std::cin.get());
     if (isupper(c))
         c += 32;
     state.dict.writebyte(addr, c ? c : ' ');
@@ -77,7 +77,7 @@ static void load(State& state)
     std::ifstream file ("alee.dat", std::ios::binary);
 
     for (Addr i = 0; file.good(); i++)
-        state.dict.writebyte(i, file.get());
+        state.dict.writebyte(i, file.get() & 0xFFu);
 }
 
 void user_sys(State& state)
index 9fef7b1c2565b8b73391ae2ebc655830fb1c19a9..1344ca067c031812445a1fe55c28366bbfcdd36f 100644 (file)
@@ -54,11 +54,25 @@ void find(State& state, Word word)
     }
 }
 
-void CoreWords::run(unsigned int index, State& state)
+void CoreWords::run(Cell ins, State& state)
 {
     Cell cell;
     DoubleCell dcell;
 
+    Addr index = ins;
+
+    auto popd = [](State& s) {
+        DoubleCell dcell = s.pop();
+        dcell <<= sizeof(Cell) * 8;
+        dcell |= static_cast<Addr>(s.pop());
+        return dcell;
+    };
+
+    auto pushd = [](State& s, DoubleCell d) {
+        s.push(static_cast<Cell>(d));
+        s.push(static_cast<Cell>(d >> (sizeof(Cell) * 8)));
+    };
+
 execute:
     if (index >= Dictionary::Begin) {
         // must be calling a defined subroutine
@@ -95,22 +109,17 @@ execute:
     case 8: // mul ( n n -- d )
         cell = state.pop();
         dcell = state.pop() * cell;
-        state.push(dcell);
-        state.push(dcell >> (sizeof(Cell) * 8));
+        pushd(state, dcell);
         break;
     case 9: // div ( d n -- n )
         cell = state.pop();
-        dcell = state.pop();
-        dcell <<= sizeof(Cell) * 8;
-        dcell |= static_cast<Addr>(state.pop());
-        state.push(dcell / cell);
+        dcell = popd(state);
+        state.push(static_cast<Cell>(dcell / cell));
         break;
     case 10: // mod ( d n -- n )
         cell = state.pop();
-        dcell = state.pop();
-        dcell <<= sizeof(Cell) * 8;
-        dcell |= static_cast<Addr>(state.pop());
-        state.push(dcell % cell);
+        dcell = popd(state);
+        state.push(static_cast<Cell>(dcell % cell));
         break;
     case 11: // peek
         if (state.pop())
@@ -123,7 +132,7 @@ execute:
         if (auto addr = state.pop(); cell)
             state.dict.write(addr, state.pop());
         else
-            state.dict.writebyte(addr, state.pop());
+            state.dict.writebyte(addr, state.pop() & 0xFFu);
         break;
     case 13: // pushr
         state.pushr(state.pop());
@@ -175,16 +184,14 @@ execute:
             std::longjmp(state.jmpbuf, static_cast<int>(Error::exit));
         break;
     case 26: // semic
-        {
         state.dict.add(findi("exit"));
         state.compiling(false);
 
-        auto addr = state.pop();
-        state.dict.write(addr,
-            (state.dict.read(addr) & 0x1F) |
-            ((addr - state.dict.latest()) << 6));
-        state.dict.latest(addr);
-        }
+        cell = state.pop();
+        dcell = (cell - state.dict.latest()) << 6;
+        state.dict.write(cell,
+            (state.dict.read(cell) & 0x1F) | static_cast<Cell>(dcell));
+        state.dict.latest(cell);
         break;
     case 27: // _jmp0
         if (state.pop()) {
@@ -196,10 +203,10 @@ execute:
         state.ip = state.beyondip();
         return;
     case 29: // depth
-        state.push(state.size());
+        state.push(static_cast<Cell>(state.size()));
         break;
     case 30: // _rdepth
-        state.push(state.rsize());
+        state.push(static_cast<Cell>(state.rsize()));
         break;
     case 31: // _in
         state.input(state);
@@ -213,26 +220,19 @@ execute:
         }
         break;
     case 33: // find
-        {
-        const Addr caddr = state.pop();
-        const Word word {
-            static_cast<Addr>(caddr + 1),
-            static_cast<Addr>(caddr + 1 + state.dict.readbyte(caddr))
-        };
-        find(state, word);
-        }
+        cell = state.pop();
+        find(state,
+             Word::fromLength(static_cast<Addr>(cell + 1),
+                              state.dict.readbyte(cell)));
         break;
     case 34: // _uma
         {
         const auto plus = state.pop();
         cell = state.pop();
-        dcell = state.pop();
-        dcell <<= sizeof(Cell) * 8;
-        dcell |= static_cast<Addr>(state.pop());
+        dcell = popd(state);
         dcell *= static_cast<Addr>(cell);
         dcell += static_cast<Addr>(plus);
-        state.push(dcell);
-        state.push(dcell >> (sizeof(Cell) * 8));
+        pushd(state, dcell);
         }
         break;
     case 35: // u<
@@ -242,17 +242,17 @@ execute:
         break;
     case 36: // um/mod
         cell = state.pop();
-        dcell = state.pop();
-        dcell <<= sizeof(Cell) * 8;
-        dcell |= static_cast<Addr>(state.pop());
+        dcell = popd(state);
 
-        state.push(static_cast<DoubleAddr>(dcell) %
-                   static_cast<Addr>(cell));
-        state.push(static_cast<DoubleAddr>(dcell) /
-                   static_cast<Addr>(cell));
+        state.push(static_cast<Cell>(
+            static_cast<DoubleAddr>(dcell) %
+            static_cast<Addr>(cell)));
+        state.push(static_cast<Cell>(
+            static_cast<DoubleAddr>(dcell) /
+            static_cast<Addr>(cell)));
         break;
     default:
-        state.push(index - WordCount);
+        state.push(ins - WordCount);
         break;
     }
 
@@ -260,17 +260,18 @@ execute:
 }
 
 template<typename Iter>
-int findi(Iter it, int size)
+Cell findi(Iter it, std::size_t size)
 {
     auto ptr = CoreWords::wordsarr;
-    int wordsi = 0;
+    Cell wordsi = 0;
 
     while (ptr < CoreWords::wordsarr + sizeof(CoreWords::wordsarr)) {
         auto end = ptr;
         while (*end)
             ++end;
 
-        if (end - ptr == size &&  Dictionary::equal(ptr, end, it))
+        std::size_t wordsize = end - ptr;
+        if (wordsize == size && Dictionary::equal(ptr, end, it))
             return wordsi;
 
         ++wordsi;
@@ -280,12 +281,12 @@ int findi(Iter it, int size)
     return -1;
 }
 
-int CoreWords::findi(const char *word)
+Cell CoreWords::findi(const char *word)
 {
     return ::findi(word, strlen(word));
 }
 
-int CoreWords::findi(State& state, Word word)
+Cell CoreWords::findi(State& state, Word word)
 {
     return ::findi(word.begin(&state.dict), word.size());
 }
index 993a42042d41938b2faabaf4613cada05e5ada9b..d4d7ef2b1edf2236633693dc7a3da2cd80e7763c 100644 (file)
@@ -31,20 +31,20 @@ void user_sys(State&);
 class CoreWords
 {
 public:
-    constexpr static std::size_t WordCount = 37;
-    constexpr static int Semicolon = 26;
+    constexpr static Cell WordCount = 37;
+    constexpr static Cell Semicolon = 26;
 
     /**
      * Finds execution token that corresponds to the given word.
      * Returns -1 if not found.
      */
-    static int findi(const char *);
-    static int findi(State&, Word);
+    static Cell findi(const char *);
+    static Cell findi(State&, Word);
 
     /**
      * Executes the given CoreWord execution token using the given state.
      */
-    static void run(unsigned int, State&);
+    static void run(Cell, State&);
 
     constexpr static char wordsarr[] =
         "_lit\0drop\0dup\0swap\0pick\0sys\0"
index a0c8dc19f673b518b3ba8b832b407764bc756837..547cd11ecc4fe0400efc3f7541f01e4a1aa5a327 100644 (file)
@@ -22,31 +22,15 @@ bool isspace(uint8_t c) {
     return c == ' ' || c == '\t' || c == '\r' || c == '\n';
 }
 
-bool isspace(char c) {
-    return isspace(static_cast<uint8_t>(c));
-}
-
 bool isdigit(uint8_t c) {
     return c >= '0' && c <= '9';
 }
 
-bool isdigit(char c) {
-    return isdigit(static_cast<uint8_t>(c));
-}
-
 bool isalpha(uint8_t c) {
     return isupper(c) || (c >= 'a' && c <= 'z');
 }
 
-bool isalpha(char c) {
-    return isalpha(static_cast<uint8_t>(c));
-}
-
 bool isupper(uint8_t c) {
     return c >= 'A' && c <= 'Z';
 }
 
-bool isupper(char c) {
-    return isupper(static_cast<uint8_t>(c));
-}
-
index dfc6f50e79f280c38035f85935a3a70781dad127..5842dfbf66418baf58cd7e101ce3ef50a64e69aa 100644 (file)
 #include <cstdint>
 
 bool isspace(uint8_t);
-bool isspace(char);
-
 bool isdigit(uint8_t);
-bool isdigit(char);
-
 bool isalpha(uint8_t);
-bool isalpha(char);
-
 bool isupper(uint8_t);
-bool isupper(char);
 
 #endif // ALEEFORTH_CTYPE_HPP
 
index 81b5c646f6cfa2cabacdd145183985f518783db3..7ae004339d9dd64930386633dbd26126a9e21c7b 100644 (file)
@@ -33,7 +33,14 @@ void Dictionary::initialize()
 Addr Dictionary::allot(Cell amount) noexcept
 {
     Addr old = here();
-    here(old + amount);
+    decltype(capacity()) neww = old + amount;
+
+    if (neww < capacity()) {
+        write(Here, static_cast<Addr>(neww));
+    } else {
+        // TODO
+    }
+
     return old;
 }
 
@@ -44,9 +51,11 @@ void Dictionary::add(Cell value) noexcept
 
 Addr Dictionary::aligned(Addr addr) const noexcept
 {
-    auto unaligned = addr & (sizeof(Cell) - sizeof(uint8_t));
-    if (unaligned)
-        addr += sizeof(Cell) - unaligned;
+    Addr unaligned = addr & (sizeof(Cell) - sizeof(uint8_t));
+    if (unaligned) {
+        addr += sizeof(Cell);
+        addr -= unaligned;
+    }
 
     return addr;
 }
@@ -59,7 +68,9 @@ Addr Dictionary::alignhere() noexcept
 
 void Dictionary::addDefinition(Word word) noexcept
 {
-    add(word.size());
+    Cell wsize = word.size();
+    add(wsize);
+
     for (auto w = word.start; w != word.wend; ++w)
         writebyte(allot(1), readbyte(w));
 
@@ -70,12 +81,11 @@ Addr Dictionary::find(Word word) noexcept
 {
     Addr lt = latest();
     for (;;) {
-        const auto l = static_cast<Addr>(read(lt));
+        const Addr l = read(lt);
         const Addr len = l & 0x1F;
-        const Word lw {
-            static_cast<Addr>(lt + sizeof(Cell)),
-            static_cast<Addr>(lt + sizeof(Cell) + len)
-        };
+        Word lw;
+        lw.start = lt + sizeof(Cell);
+        lw.wend = lw.start + len;
 
         if (equal(word, lw))
             return lt;
@@ -90,20 +100,21 @@ Addr Dictionary::find(Word word) noexcept
 
 Addr Dictionary::getexec(Addr addr) noexcept
 {
-    const auto len = read(addr) & 0x1F;
-    return aligned(addr + sizeof(Cell) + len);
+    const Addr len = read(addr) & 0x1Fu;
+    addr += sizeof(Cell);
+    addr += len;
+    return aligned(addr);
 }
 
 Word Dictionary::input() noexcept
 {
-    const auto src = read(Dictionary::Source);
-    const auto end = read(Dictionary::SourceLen);
-    auto idx = read(Dictionary::Input);
+    const Addr src = read(Dictionary::Source);
+    const Addr end = read(Dictionary::SourceLen);
+    uint8_t idx = read(Dictionary::Input) & 0xFFu;
 
-    Word word {
-        static_cast<Addr>(src + idx),
-        static_cast<Addr>(src + idx)
-    };
+    Word word;
+    word.start = src + idx;
+    word.wend = word.start;
 
     while (idx < end) {
         auto ch = readbyte(word.wend);
@@ -121,7 +132,7 @@ Word Dictionary::input() noexcept
         ++idx;
     }
 
-    writebyte(Dictionary::Input, idx + 1);
+    writebyte(Dictionary::Input, ++idx);
     return word;
 }
 
index 02fb1cce81628b17f0e8f544f6b5acdbd700abdd..2f17a7771640e96b999aa0021710c2c35ce25149 100644 (file)
@@ -64,6 +64,7 @@ public:
     virtual void write(Addr, Cell) noexcept = 0;
     virtual uint8_t readbyte(Addr) const noexcept = 0;
     virtual void writebyte(Addr, uint8_t) noexcept = 0;
+    virtual unsigned long int capacity() const noexcept = 0;
 
     /**
      * Does initial dictionary setup, required before use for execution.
index 464bc2fb0e883709f15f19bdea3cce04dcab2d54..cdec1a5a681d5c21705979488d868b91d76e8886 100644 (file)
 #include "ctype.hpp"
 #include "parser.hpp"
 
-#include <cstring>
-
 Error Parser::parse(State& state, const char *str)
 {
     auto addr = Dictionary::Input;
+
+    Cell len = 0;
+    for (auto ptr = str; *ptr; ++ptr)
+        ++len;
+
     state.dict.write(addr, 0);
-    state.dict.write(Dictionary::SourceLen, std::strlen(str));
+    state.dict.write(Dictionary::SourceLen, len);
 
     addr += sizeof(Cell);
     while (*str)
@@ -53,17 +56,18 @@ Error Parser::parseSource(State& state)
 
 Error Parser::parseWord(State& state, Word word)
 {
-    int ins, imm;
+    bool imm;
+    Addr ins = state.dict.find(word);
 
-    ins = state.dict.find(word);
+    if (ins == 0) {
+        auto cw = CoreWords::findi(state, word);
 
-    if (ins <= 0) {
-        ins = CoreWords::findi(state, word);
-
-        if (ins < 0)
+        if (cw < 0) {
             return parseNumber(state, word);
-        else
+        } else {
+            ins = cw;
             imm = ins == CoreWords::Semicolon;
+        }
     } else {
         imm = state.dict.read(ins) & Dictionary::Immediate;
         ins = state.dict.getexec(ins);
@@ -107,11 +111,12 @@ Error Parser::parseNumber(State& state, Word word)
     if (inv)
         result *= -1;
 
-    Cell value = static_cast<Cell>(result);
+    auto value = static_cast<Cell>(result);
     if (state.compiling()) {
         auto ins = CoreWords::findi("_lit");
 
-        if (value >= 0 && value < static_cast<Cell>(Dictionary::Begin - CoreWords::WordCount)) {
+        const Cell maxlit = Dictionary::Begin - CoreWords::WordCount;
+        if (value >= 0 && value < maxlit) {
             state.dict.add(value + CoreWords::WordCount);
         } else {
             state.dict.add(ins);
index bfd29d113fd6331727e2791a8729e1097f11eb7e..b19d291b87eca7d7f943f248bca560591cc67b81 100644 (file)
@@ -81,11 +81,11 @@ void State::reset()
 
 std::size_t State::size() const noexcept
 {
-    return std::distance(dstack, static_cast<const Cell *>(dsp));
+    return dsp - dstack;
 }
 
 std::size_t State::rsize() const noexcept
 {
-    return std::distance(rstack, static_cast<const Cell *>(rsp));
+    return rsp - rstack;
 }
 
index fe6210e3191f2e431445ac010f83fcc30b9dc327..baaa5ce3b7bbc296cd5d7cac308a04e944c4de92 100644 (file)
@@ -19,7 +19,7 @@
 #include "dictionary.hpp"
 #include "types.hpp"
 
-unsigned Word::size() const noexcept
+Addr Word::size() const noexcept
 {
     return wend - start;
 }
index f23f92e285feb395533d3e5f2e6a1181bb6a462e..95daee65f856613813a6bbda0e069895d88e4d24 100644 (file)
@@ -52,14 +52,20 @@ enum class Error : int {
  */
 struct Word
 {
-    struct iterator;
+    Addr start;
+    Addr wend;
+
+    constexpr explicit Word(Addr s = 0, Addr e = 0):
+        start(s), wend(e) {}
 
-    Addr start = 0;
-    Addr wend = 0;
+    static constexpr Word fromLength(Addr s, Addr l) {
+        return Word(s, s + l);
+    }
 
-    unsigned size() const noexcept;
+    Addr size() const noexcept;
 
     // Iterators provided for std::equal.
+    struct iterator;
     iterator begin(const Dictionary *);
     iterator end(const Dictionary *);
 
index 22841c5d50f3fbcbe8ed937587e0bc6372128081..c88bc7d245029a4c93c137b6730db66ce3bbfa66 100644 (file)
@@ -46,6 +46,10 @@ public:
     virtual void writebyte(Addr addr, uint8_t value) noexcept final {
         dict[addr] = value;
     }
+
+    virtual unsigned long int capacity() const noexcept final {
+        return sizeof(dict);
+    }
 };
 
 #endif // ALEEFORTH_MEMDICT_HPP
index 0ec6c886ecdfb429c7124d0f5acbffe6b424817c..b4f1b04526fcb4b46ea4bbbd160858c7e4b07527 100644 (file)
@@ -153,7 +153,7 @@ void user_sys(State& state)
         break;
     case 3:
         { auto addr = state.pop();
-          *reinterpret_cast<uint8_t *>(addr) = state.pop(); }
+          *reinterpret_cast<uint8_t *>(addr) = state.pop() & 0xFFu; }
         break;
     case 4:
         state.push(*reinterpret_cast<uint8_t *>(state.pop()));
index 45a9ee1c4df3c02de278ca59ad73b423fbe995c5..730d103ee44062d96f632b439feeeebaf8b8db87 100644 (file)
@@ -35,6 +35,10 @@ class SplitMemDict : public Dictionary
     uint8_t rwdict[MemDictSize - Dictionary::Begin] = {0};
     uint8_t extra[Dictionary::Begin];
 
+    Addr convertAddress(Addr addr) const noexcept {
+        return addr < RON ? addr : static_cast<Addr>(addr - RON);
+    }
+
 public:
     constexpr explicit SplitMemDict(const uint8_t *rod):
         rodict(rod)
@@ -51,14 +55,12 @@ public:
 
     virtual Cell read(Addr addr) const noexcept final {
         const uint8_t *dict;
-        if (addr < RON) {
+        if (addr < RON)
             dict = addr < Dictionary::Begin ? extra : rodict;
-        } else {
+        else
             dict = rwdict;
-            addr -= RON;
-        }
 
-        return *reinterpret_cast<const Cell *>(dict + addr);
+        return *reinterpret_cast<const Cell *>(dict + convertAddress(addr));
     }
 
     virtual void write(Addr addr, Cell value) noexcept final {
@@ -70,14 +72,12 @@ public:
 
     virtual uint8_t readbyte(Addr addr) const noexcept final {
         const uint8_t *dict;
-        if (addr < RON) {
+        if (addr < RON)
             dict = addr < Dictionary::Begin ? extra : rodict;
-        } else {
+        else
             dict = rwdict;
-            addr -= RON;
-        }
 
-        return dict[addr];
+        return dict[convertAddress(addr)];
     }
 
     virtual void writebyte(Addr addr, uint8_t value) noexcept final {
@@ -86,6 +86,10 @@ public:
         else if (addr < Dictionary::Begin)
             extra[addr] = value;
     }
+
+    virtual unsigned long int capacity() const noexcept final {
+        return RON + sizeof(extra) + sizeof(rwdict);
+    }
 };
 
 #endif // ALEEFORTH_SPLITMEMDICT_HPP