-Wconversion

llvm
Clyne 2 years ago
parent 74753670d5
commit d36bb13f52

@ -1,5 +1,5 @@
CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \ 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 -fno-exceptions -fno-threadsafe-statics -fno-rtti #-fstack-usage
CXXFILES := $(wildcard libalee/*.cpp) CXXFILES := $(wildcard libalee/*.cpp)
@ -10,6 +10,7 @@ all: alee
msp430: CXX := msp430-elf32-g++ msp430: CXX := msp430-elf32-g++
msp430: AR := msp430-elf32-gcc-ar msp430: AR := msp430-elf32-gcc-ar
msp430: CXXFLAGS += -I.
msp430: CXXFLAGS += -Os -mmcu=msp430g2553 -ffunction-sections -fdata-sections msp430: CXXFLAGS += -Os -mmcu=msp430g2553 -ffunction-sections -fdata-sections
msp430: CXXFLAGS += -DMEMDICTSIZE=200 -flto msp430: CXXFLAGS += -DMEMDICTSIZE=200 -flto
msp430: LDFLAGS += -L/opt/msp430-elf32/include -Tmsp430/msp430g2553.ld -Wl,-gc-sections msp430: LDFLAGS += -L/opt/msp430-elf32/include -Tmsp430/msp430g2553.ld -Wl,-gc-sections

@ -51,10 +51,10 @@ int main(int argc, char *argv[])
static void readchar(State& state) 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; Addr addr = Dictionary::Input + sizeof(Cell) + idx;
auto c = std::cin.get(); auto c = static_cast<char>(std::cin.get());
if (isupper(c)) if (isupper(c))
c += 32; c += 32;
state.dict.writebyte(addr, c ? c : ' '); state.dict.writebyte(addr, c ? c : ' ');
@ -76,7 +76,7 @@ static void load(State& state)
Addr i = 0; Addr i = 0;
while (file.good()) while (file.good())
state.dict.writebyte(i++, file.get()); state.dict.writebyte(i++, file.get() & 0xFFu);
} }
void user_sys(State& state) void user_sys(State& state)

@ -54,9 +54,9 @@ int main(int argc, char *argv[])
static void readchar(State& state) static void readchar(State& state)
{ {
auto idx = state.dict.read(Dictionary::Input); 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)) if (isupper(c))
c += 32; c += 32;
state.dict.writebyte(addr, c ? c : ' '); state.dict.writebyte(addr, c ? c : ' ');
@ -77,7 +77,7 @@ static void load(State& state)
std::ifstream file ("alee.dat", std::ios::binary); std::ifstream file ("alee.dat", std::ios::binary);
for (Addr i = 0; file.good(); i++) 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) void user_sys(State& state)

@ -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; Cell cell;
DoubleCell dcell; 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: execute:
if (index >= Dictionary::Begin) { if (index >= Dictionary::Begin) {
// must be calling a defined subroutine // must be calling a defined subroutine
@ -95,22 +109,17 @@ execute:
case 8: // mul ( n n -- d ) case 8: // mul ( n n -- d )
cell = state.pop(); cell = state.pop();
dcell = state.pop() * cell; dcell = state.pop() * cell;
state.push(dcell); pushd(state, dcell);
state.push(dcell >> (sizeof(Cell) * 8));
break; break;
case 9: // div ( d n -- n ) case 9: // div ( d n -- n )
cell = state.pop(); cell = state.pop();
dcell = state.pop(); dcell = popd(state);
dcell <<= sizeof(Cell) * 8; state.push(static_cast<Cell>(dcell / cell));
dcell |= static_cast<Addr>(state.pop());
state.push(dcell / cell);
break; break;
case 10: // mod ( d n -- n ) case 10: // mod ( d n -- n )
cell = state.pop(); cell = state.pop();
dcell = state.pop(); dcell = popd(state);
dcell <<= sizeof(Cell) * 8; state.push(static_cast<Cell>(dcell % cell));
dcell |= static_cast<Addr>(state.pop());
state.push(dcell % cell);
break; break;
case 11: // peek case 11: // peek
if (state.pop()) if (state.pop())
@ -123,7 +132,7 @@ execute:
if (auto addr = state.pop(); cell) if (auto addr = state.pop(); cell)
state.dict.write(addr, state.pop()); state.dict.write(addr, state.pop());
else else
state.dict.writebyte(addr, state.pop()); state.dict.writebyte(addr, state.pop() & 0xFFu);
break; break;
case 13: // pushr case 13: // pushr
state.pushr(state.pop()); state.pushr(state.pop());
@ -175,16 +184,14 @@ execute:
std::longjmp(state.jmpbuf, static_cast<int>(Error::exit)); std::longjmp(state.jmpbuf, static_cast<int>(Error::exit));
break; break;
case 26: // semic case 26: // semic
{
state.dict.add(findi("exit")); state.dict.add(findi("exit"));
state.compiling(false); state.compiling(false);
auto addr = state.pop(); cell = state.pop();
state.dict.write(addr, dcell = (cell - state.dict.latest()) << 6;
(state.dict.read(addr) & 0x1F) | state.dict.write(cell,
((addr - state.dict.latest()) << 6)); (state.dict.read(cell) & 0x1F) | static_cast<Cell>(dcell));
state.dict.latest(addr); state.dict.latest(cell);
}
break; break;
case 27: // _jmp0 case 27: // _jmp0
if (state.pop()) { if (state.pop()) {
@ -196,10 +203,10 @@ execute:
state.ip = state.beyondip(); state.ip = state.beyondip();
return; return;
case 29: // depth case 29: // depth
state.push(state.size()); state.push(static_cast<Cell>(state.size()));
break; break;
case 30: // _rdepth case 30: // _rdepth
state.push(state.rsize()); state.push(static_cast<Cell>(state.rsize()));
break; break;
case 31: // _in case 31: // _in
state.input(state); state.input(state);
@ -213,26 +220,19 @@ execute:
} }
break; break;
case 33: // find case 33: // find
{ cell = state.pop();
const Addr caddr = state.pop(); find(state,
const Word word { Word::fromLength(static_cast<Addr>(cell + 1),
static_cast<Addr>(caddr + 1), state.dict.readbyte(cell)));
static_cast<Addr>(caddr + 1 + state.dict.readbyte(caddr))
};
find(state, word);
}
break; break;
case 34: // _uma case 34: // _uma
{ {
const auto plus = state.pop(); const auto plus = state.pop();
cell = state.pop(); cell = state.pop();
dcell = state.pop(); dcell = popd(state);
dcell <<= sizeof(Cell) * 8;
dcell |= static_cast<Addr>(state.pop());
dcell *= static_cast<Addr>(cell); dcell *= static_cast<Addr>(cell);
dcell += static_cast<Addr>(plus); dcell += static_cast<Addr>(plus);
state.push(dcell); pushd(state, dcell);
state.push(dcell >> (sizeof(Cell) * 8));
} }
break; break;
case 35: // u< case 35: // u<
@ -242,17 +242,17 @@ execute:
break; break;
case 36: // um/mod case 36: // um/mod
cell = state.pop(); cell = state.pop();
dcell = state.pop(); dcell = popd(state);
dcell <<= sizeof(Cell) * 8;
dcell |= static_cast<Addr>(state.pop());
state.push(static_cast<DoubleAddr>(dcell) % state.push(static_cast<Cell>(
static_cast<Addr>(cell)); static_cast<DoubleAddr>(dcell) %
state.push(static_cast<DoubleAddr>(dcell) / static_cast<Addr>(cell)));
static_cast<Addr>(cell)); state.push(static_cast<Cell>(
static_cast<DoubleAddr>(dcell) /
static_cast<Addr>(cell)));
break; break;
default: default:
state.push(index - WordCount); state.push(ins - WordCount);
break; break;
} }
@ -260,17 +260,18 @@ execute:
} }
template<typename Iter> template<typename Iter>
int findi(Iter it, int size) Cell findi(Iter it, std::size_t size)
{ {
auto ptr = CoreWords::wordsarr; auto ptr = CoreWords::wordsarr;
int wordsi = 0; Cell wordsi = 0;
while (ptr < CoreWords::wordsarr + sizeof(CoreWords::wordsarr)) { while (ptr < CoreWords::wordsarr + sizeof(CoreWords::wordsarr)) {
auto end = ptr; auto end = ptr;
while (*end) while (*end)
++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; return wordsi;
++wordsi; ++wordsi;
@ -280,12 +281,12 @@ int findi(Iter it, int size)
return -1; return -1;
} }
int CoreWords::findi(const char *word) Cell CoreWords::findi(const char *word)
{ {
return ::findi(word, strlen(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()); return ::findi(word.begin(&state.dict), word.size());
} }

@ -31,20 +31,20 @@ void user_sys(State&);
class CoreWords class CoreWords
{ {
public: public:
constexpr static std::size_t WordCount = 37; constexpr static Cell WordCount = 37;
constexpr static int Semicolon = 26; constexpr static Cell Semicolon = 26;
/** /**
* Finds execution token that corresponds to the given word. * Finds execution token that corresponds to the given word.
* Returns -1 if not found. * Returns -1 if not found.
*/ */
static int findi(const char *); static Cell findi(const char *);
static int findi(State&, Word); static Cell findi(State&, Word);
/** /**
* Executes the given CoreWord execution token using the given state. * 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[] = constexpr static char wordsarr[] =
"_lit\0drop\0dup\0swap\0pick\0sys\0" "_lit\0drop\0dup\0swap\0pick\0sys\0"

@ -22,31 +22,15 @@ bool isspace(uint8_t c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n'; return c == ' ' || c == '\t' || c == '\r' || c == '\n';
} }
bool isspace(char c) {
return isspace(static_cast<uint8_t>(c));
}
bool isdigit(uint8_t c) { bool isdigit(uint8_t c) {
return c >= '0' && c <= '9'; return c >= '0' && c <= '9';
} }
bool isdigit(char c) {
return isdigit(static_cast<uint8_t>(c));
}
bool isalpha(uint8_t c) { bool isalpha(uint8_t c) {
return isupper(c) || (c >= 'a' && c <= 'z'); return isupper(c) || (c >= 'a' && c <= 'z');
} }
bool isalpha(char c) {
return isalpha(static_cast<uint8_t>(c));
}
bool isupper(uint8_t c) { bool isupper(uint8_t c) {
return c >= 'A' && c <= 'Z'; return c >= 'A' && c <= 'Z';
} }
bool isupper(char c) {
return isupper(static_cast<uint8_t>(c));
}

@ -26,16 +26,9 @@
#include <cstdint> #include <cstdint>
bool isspace(uint8_t); bool isspace(uint8_t);
bool isspace(char);
bool isdigit(uint8_t); bool isdigit(uint8_t);
bool isdigit(char);
bool isalpha(uint8_t); bool isalpha(uint8_t);
bool isalpha(char);
bool isupper(uint8_t); bool isupper(uint8_t);
bool isupper(char);
#endif // ALEEFORTH_CTYPE_HPP #endif // ALEEFORTH_CTYPE_HPP

@ -33,7 +33,14 @@ void Dictionary::initialize()
Addr Dictionary::allot(Cell amount) noexcept Addr Dictionary::allot(Cell amount) noexcept
{ {
Addr old = here(); Addr old = here();
here(old + amount); decltype(capacity()) neww = old + amount;
if (neww < capacity()) {
write(Here, static_cast<Addr>(neww));
} else {
// TODO
}
return old; return old;
} }
@ -44,9 +51,11 @@ void Dictionary::add(Cell value) noexcept
Addr Dictionary::aligned(Addr addr) const noexcept Addr Dictionary::aligned(Addr addr) const noexcept
{ {
auto unaligned = addr & (sizeof(Cell) - sizeof(uint8_t)); Addr unaligned = addr & (sizeof(Cell) - sizeof(uint8_t));
if (unaligned) if (unaligned) {
addr += sizeof(Cell) - unaligned; addr += sizeof(Cell);
addr -= unaligned;
}
return addr; return addr;
} }
@ -59,7 +68,9 @@ Addr Dictionary::alignhere() noexcept
void Dictionary::addDefinition(Word word) 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) for (auto w = word.start; w != word.wend; ++w)
writebyte(allot(1), readbyte(w)); writebyte(allot(1), readbyte(w));
@ -70,12 +81,11 @@ Addr Dictionary::find(Word word) noexcept
{ {
Addr lt = latest(); Addr lt = latest();
for (;;) { for (;;) {
const auto l = static_cast<Addr>(read(lt)); const Addr l = read(lt);
const Addr len = l & 0x1F; const Addr len = l & 0x1F;
const Word lw { Word lw;
static_cast<Addr>(lt + sizeof(Cell)), lw.start = lt + sizeof(Cell);
static_cast<Addr>(lt + sizeof(Cell) + len) lw.wend = lw.start + len;
};
if (equal(word, lw)) if (equal(word, lw))
return lt; return lt;
@ -90,20 +100,21 @@ Addr Dictionary::find(Word word) noexcept
Addr Dictionary::getexec(Addr addr) noexcept Addr Dictionary::getexec(Addr addr) noexcept
{ {
const auto len = read(addr) & 0x1F; const Addr len = read(addr) & 0x1Fu;
return aligned(addr + sizeof(Cell) + len); addr += sizeof(Cell);
addr += len;
return aligned(addr);
} }
Word Dictionary::input() noexcept Word Dictionary::input() noexcept
{ {
const auto src = read(Dictionary::Source); const Addr src = read(Dictionary::Source);
const auto end = read(Dictionary::SourceLen); const Addr end = read(Dictionary::SourceLen);
auto idx = read(Dictionary::Input); uint8_t idx = read(Dictionary::Input) & 0xFFu;
Word word { Word word;
static_cast<Addr>(src + idx), word.start = src + idx;
static_cast<Addr>(src + idx) word.wend = word.start;
};
while (idx < end) { while (idx < end) {
auto ch = readbyte(word.wend); auto ch = readbyte(word.wend);
@ -121,7 +132,7 @@ Word Dictionary::input() noexcept
++idx; ++idx;
} }
writebyte(Dictionary::Input, idx + 1); writebyte(Dictionary::Input, ++idx);
return word; return word;
} }

@ -64,6 +64,7 @@ public:
virtual void write(Addr, Cell) noexcept = 0; virtual void write(Addr, Cell) noexcept = 0;
virtual uint8_t readbyte(Addr) const noexcept = 0; virtual uint8_t readbyte(Addr) const noexcept = 0;
virtual void writebyte(Addr, uint8_t) 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. * Does initial dictionary setup, required before use for execution.

@ -20,13 +20,16 @@
#include "ctype.hpp" #include "ctype.hpp"
#include "parser.hpp" #include "parser.hpp"
#include <cstring>
Error Parser::parse(State& state, const char *str) Error Parser::parse(State& state, const char *str)
{ {
auto addr = Dictionary::Input; auto addr = Dictionary::Input;
Cell len = 0;
for (auto ptr = str; *ptr; ++ptr)
++len;
state.dict.write(addr, 0); state.dict.write(addr, 0);
state.dict.write(Dictionary::SourceLen, std::strlen(str)); state.dict.write(Dictionary::SourceLen, len);
addr += sizeof(Cell); addr += sizeof(Cell);
while (*str) while (*str)
@ -53,17 +56,18 @@ Error Parser::parseSource(State& state)
Error Parser::parseWord(State& state, Word word) 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) { if (cw < 0) {
ins = CoreWords::findi(state, word);
if (ins < 0)
return parseNumber(state, word); return parseNumber(state, word);
else } else {
ins = cw;
imm = ins == CoreWords::Semicolon; imm = ins == CoreWords::Semicolon;
}
} else { } else {
imm = state.dict.read(ins) & Dictionary::Immediate; imm = state.dict.read(ins) & Dictionary::Immediate;
ins = state.dict.getexec(ins); ins = state.dict.getexec(ins);
@ -107,11 +111,12 @@ Error Parser::parseNumber(State& state, Word word)
if (inv) if (inv)
result *= -1; result *= -1;
Cell value = static_cast<Cell>(result); auto value = static_cast<Cell>(result);
if (state.compiling()) { if (state.compiling()) {
auto ins = CoreWords::findi("_lit"); 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); state.dict.add(value + CoreWords::WordCount);
} else { } else {
state.dict.add(ins); state.dict.add(ins);

@ -81,11 +81,11 @@ void State::reset()
std::size_t State::size() const noexcept 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 std::size_t State::rsize() const noexcept
{ {
return std::distance(rstack, static_cast<const Cell *>(rsp)); return rsp - rstack;
} }

@ -19,7 +19,7 @@
#include "dictionary.hpp" #include "dictionary.hpp"
#include "types.hpp" #include "types.hpp"
unsigned Word::size() const noexcept Addr Word::size() const noexcept
{ {
return wend - start; return wend - start;
} }

@ -52,14 +52,20 @@ enum class Error : int {
*/ */
struct Word struct Word
{ {
struct iterator; Addr start;
Addr wend;
constexpr explicit Word(Addr s = 0, Addr e = 0):
start(s), wend(e) {}
Addr start = 0; static constexpr Word fromLength(Addr s, Addr l) {
Addr wend = 0; return Word(s, s + l);
}
unsigned size() const noexcept; Addr size() const noexcept;
// Iterators provided for std::equal. // Iterators provided for std::equal.
struct iterator;
iterator begin(const Dictionary *); iterator begin(const Dictionary *);
iterator end(const Dictionary *); iterator end(const Dictionary *);

@ -46,6 +46,10 @@ public:
virtual void writebyte(Addr addr, uint8_t value) noexcept final { virtual void writebyte(Addr addr, uint8_t value) noexcept final {
dict[addr] = value; dict[addr] = value;
} }
virtual unsigned long int capacity() const noexcept final {
return sizeof(dict);
}
}; };
#endif // ALEEFORTH_MEMDICT_HPP #endif // ALEEFORTH_MEMDICT_HPP

@ -153,7 +153,7 @@ void user_sys(State& state)
break; break;
case 3: case 3:
{ auto addr = state.pop(); { auto addr = state.pop();
*reinterpret_cast<uint8_t *>(addr) = state.pop(); } *reinterpret_cast<uint8_t *>(addr) = state.pop() & 0xFFu; }
break; break;
case 4: case 4:
state.push(*reinterpret_cast<uint8_t *>(state.pop())); state.push(*reinterpret_cast<uint8_t *>(state.pop()));

@ -35,6 +35,10 @@ class SplitMemDict : public Dictionary
uint8_t rwdict[MemDictSize - Dictionary::Begin] = {0}; uint8_t rwdict[MemDictSize - Dictionary::Begin] = {0};
uint8_t extra[Dictionary::Begin]; uint8_t extra[Dictionary::Begin];
Addr convertAddress(Addr addr) const noexcept {
return addr < RON ? addr : static_cast<Addr>(addr - RON);
}
public: public:
constexpr explicit SplitMemDict(const uint8_t *rod): constexpr explicit SplitMemDict(const uint8_t *rod):
rodict(rod) rodict(rod)
@ -51,14 +55,12 @@ public:
virtual Cell read(Addr addr) const noexcept final { virtual Cell read(Addr addr) const noexcept final {
const uint8_t *dict; const uint8_t *dict;
if (addr < RON) { if (addr < RON)
dict = addr < Dictionary::Begin ? extra : rodict; dict = addr < Dictionary::Begin ? extra : rodict;
} else { else
dict = rwdict; 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 { virtual void write(Addr addr, Cell value) noexcept final {
@ -70,14 +72,12 @@ public:
virtual uint8_t readbyte(Addr addr) const noexcept final { virtual uint8_t readbyte(Addr addr) const noexcept final {
const uint8_t *dict; const uint8_t *dict;
if (addr < RON) { if (addr < RON)
dict = addr < Dictionary::Begin ? extra : rodict; dict = addr < Dictionary::Begin ? extra : rodict;
} else { else
dict = rwdict; dict = rwdict;
addr -= RON;
}
return dict[addr]; return dict[convertAddress(addr)];
} }
virtual void writebyte(Addr addr, uint8_t value) noexcept final { virtual void writebyte(Addr addr, uint8_t value) noexcept final {
@ -86,6 +86,10 @@ public:
else if (addr < Dictionary::Begin) else if (addr < Dictionary::Begin)
extra[addr] = value; extra[addr] = value;
} }
virtual unsigned long int capacity() const noexcept final {
return RON + sizeof(extra) + sizeof(rwdict);
}
}; };
#endif // ALEEFORTH_SPLITMEMDICT_HPP #endif // ALEEFORTH_SPLITMEMDICT_HPP

Loading…
Cancel
Save