msp430: CXXFLAGS += -I. -I/usr/msp430-elf/usr/include
msp430: CXXFLAGS += -Os -mmcu=msp430fr2476 -ffunction-sections -fdata-sections
msp430: CXXFLAGS += -flto -fno-asynchronous-unwind-tables -fno-threadsafe-statics -fno-stack-protector
+msp430: CXXFLAGS += -DALEE_MSP430_HOST
msp430: LDFLAGS += -L msp430 -T msp430fr2476.ld -Wl,-gc-sections -Wl,--no-warn-rwx-segments
msp430: msp430/alee-msp430
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "alee.hpp"
+#include "libalee/alee.hpp"
#include "splitmemdict.hpp"
#include <array>
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "alee.hpp"
+#include "libalee/alee.hpp"
#include "memdict.hpp"
#include <charconv>
+++ /dev/null
-#include "libalee/parser.hpp"
-#include "libalee/state.hpp"
-
--- /dev/null
+#include "config.hpp"
+#include "corewords.hpp"
+#include "ctype.hpp"
+#include "dictionary.hpp"
+#include "parser.hpp"
+#include "state.hpp"
+#include "types.hpp"
--- /dev/null
+#ifndef ALEE_MSP430_HOST
+#define LIBALEE_SECTION
+#else
+#define LIBALEE_SECTION __attribute__((section(".libalee")))
+#endif
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "corewords.hpp"
-#include "parser.hpp"
+#include "alee.hpp"
#include <utility>
+LIBALEE_SECTION
void find(State& state, Word word)
{
Cell tok = 0;
state.push(imm);
}
+LIBALEE_SECTION
void CoreWords::run(Cell ins, State& state)
{
Cell cell;
ip += sizeof(Cell);
}
+LIBALEE_SECTION
Cell CoreWords::findi(State& state, Word word)
{
return findi(word.begin(&state.dict), word.size());
#ifndef ALEEFORTH_COREWORDS_HPP
#define ALEEFORTH_COREWORDS_HPP
-#include "ctype.hpp"
+#include "config.hpp"
#include "types.hpp"
-#include "state.hpp"
+#include "dictionary.hpp"
/**
* To be implemented by the user, this function is called when the `sys` word
private:
template<typename Iter>
+ LIBALEE_SECTION
constexpr static Cell findi(Iter it, std::size_t size)
{
const char *ptr = CoreWords::wordsarr;
return c >= 'A' && c <= 'Z';
}
+constexpr inline bool islower(uint8_t c) {
+ return c >= 'a' && c <= 'z';
+}
+
constexpr inline bool isalpha(uint8_t c) {
return isupper(c) || (c >= 'a' && c <= 'z');
}
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "dictionary.hpp"
+#include "alee.hpp"
+LIBALEE_SECTION
void Dictionary::initialize()
{
write(Base, 10);
write(Source, Input + sizeof(Cell));
}
+LIBALEE_SECTION
Addr Dictionary::allot(Cell amount) noexcept
{
Addr old = here();
return old;
}
+LIBALEE_SECTION
void Dictionary::add(Cell value) noexcept
{
write(allot(sizeof(Cell)), value);
}
+LIBALEE_SECTION
Addr Dictionary::aligned(Addr addr)
{
return (addr + (sizeof(Cell) - 1)) & ~(sizeof(Cell) - 1);
}
+LIBALEE_SECTION
Addr Dictionary::alignhere() noexcept
{
here(aligned(here()));
return here();
}
+LIBALEE_SECTION
void Dictionary::addDefinition(Word word) noexcept
{
Cell wsize = word.size();
alignhere();
}
+LIBALEE_SECTION
Addr Dictionary::find(Word word) noexcept
{
Addr lt = latest();
return 0;
}
+LIBALEE_SECTION
Addr Dictionary::getexec(Addr addr) noexcept
{
const Addr l = read(addr);
return aligned(addr);
}
+LIBALEE_SECTION
bool Dictionary::hasInput() const noexcept
{
const Addr src = read(Dictionary::Source);
return false;
}
+LIBALEE_SECTION
Word Dictionary::input() noexcept
{
const Addr src = read(Dictionary::Source);
return Word(wstart, wend);
}
+LIBALEE_SECTION
bool Dictionary::equal(Word word, const char *str, unsigned len) const noexcept
{
return word.size() == len && equal(word.begin(this), word.end(this), str);
}
+LIBALEE_SECTION
bool Dictionary::equal(Word word, Word other) const noexcept
{
return word.size() == other.size() && equal(word.begin(this), word.end(this), other.begin(this));
#ifndef ALEEFORTH_DICTIONARY_HPP
#define ALEEFORTH_DICTIONARY_HPP
-#include "ctype.hpp"
+#include "config.hpp"
#include "types.hpp"
+#include "ctype.hpp"
#include <algorithm>
#include <cstddef>
*/
void initialize();
+ LIBALEE_SECTION
Addr here() const noexcept { return read(Here); }
+ LIBALEE_SECTION
void here(Addr l) noexcept { write(Here, l); }
+ LIBALEE_SECTION
Addr latest() const noexcept { return read(Latest); }
+ LIBALEE_SECTION
void latest(Addr l) noexcept { write(Latest, l); }
// Aligns the given address.
// Used for case-insensitive comparison between two iterators.
template<typename Iter1, typename Iter2>
+ LIBALEE_SECTION
constexpr static bool equal(Iter1 b1, Iter1 e1, Iter2 b2) {
return std::equal(b1, e1, b2, eqchars);
}
private:
// Case-insensitive comparison.
+ LIBALEE_SECTION
constexpr static bool eqchars(char c1, char c2) {
if (isalpha(static_cast<uint8_t>(c1)))
c1 |= 32;
return c1 == c2;
}
-
};
#endif // ALEEFORTH_DICTIONARY_HPP
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "corewords.hpp"
-#include "ctype.hpp"
-#include "parser.hpp"
+#include "alee.hpp"
Error (*Parser::customParse)(State&, Word) = nullptr;
+LIBALEE_SECTION
Error Parser::parse(State& state, const char *str)
{
auto addr = Dictionary::Input;
return parseSource(state);
}
+LIBALEE_SECTION
Error Parser::parseSource(State& state)
{
auto err = Error::none;
return err;
}
+LIBALEE_SECTION
Error Parser::parseWord(State& state, Word word)
{
bool imm;
return Error::none;
}
+LIBALEE_SECTION
Error Parser::parseNumber(State& state, Word word)
{
const auto base = state.dict.read(Dictionary::Base);
return Error::none;
}
+LIBALEE_SECTION
void Parser::processLiteral(State& state, Cell value)
{
if (state.compiling()) {
#ifndef ALEEFORTH_PARSER_HPP
#define ALEEFORTH_PARSER_HPP
+#include "config.hpp"
#include "types.hpp"
+#include "state.hpp"
#include <string_view>
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "corewords.hpp"
-#include "state.hpp"
+#include "alee.hpp"
#include <iterator>
+LIBALEE_SECTION
bool State::compiling() const
{
return dict.read(Dictionary::Compiling);
}
+LIBALEE_SECTION
void State::compiling(bool yes)
{
dict.write(Dictionary::Compiling, yes);
}
+LIBALEE_SECTION
State::Context State::save()
{
return context;
}
+LIBALEE_SECTION
void State::load(const State::Context& ctx)
{
context = ctx;
}
+LIBALEE_SECTION
Error State::execute(Addr addr)
{
auto stat = static_cast<Error>(setjmp(context.jmpbuf));
return stat;
}
+LIBALEE_SECTION
void State::reset()
{
while (size())
context.ip = 0;
}
+LIBALEE_SECTION
std::size_t State::size() const noexcept
{
return dsp - dstack;
}
+LIBALEE_SECTION
std::size_t State::rsize() const noexcept
{
return rsp - rstack;
#ifndef ALEEFORTH_STATE_HPP
#define ALEEFORTH_STATE_HPP
+#include "config.hpp"
#include "dictionary.hpp"
#include "types.hpp"
*/
void reset();
+ LIBALEE_SECTION
Addr& ip() noexcept {
return context.ip;
}
+ LIBALEE_SECTION
void input() noexcept {
inputfunc(*this);
}
*/
void load(const Context&);
+ LIBALEE_SECTION
inline void push(Cell value) {
verify(dsp < dstack + DataStackSize, Error::push);
*dsp++ = value;
}
+ LIBALEE_SECTION
inline Cell pop() {
verify(dsp > dstack, Error::pop);
return *--dsp;
}
+ LIBALEE_SECTION
inline void pushr(Cell value) {
verify(rsp < rstack + ReturnStackSize, Error::pushr);
*rsp++ = value;
}
+ LIBALEE_SECTION
inline Cell popr() {
verify(rsp > rstack, Error::popr);
return *--rsp;
}
+ LIBALEE_SECTION
inline Cell& top() {
verify(dsp > dstack, Error::top);
return *(dsp - 1);
}
+ LIBALEE_SECTION
inline Cell& pick(std::size_t i) {
verify(dsp - i > dstack, Error::pick);
return *(dsp - i - 1);
}
// Advances the instruction pointer and returns that cell's contents.
+ LIBALEE_SECTION
inline Cell beyondip() {
context.ip += sizeof(Cell);
return dict.read(context.ip);
}
+ LIBALEE_SECTION
inline void verify(bool condition, Error error) {
if (!condition)
std::longjmp(context.jmpbuf, static_cast<int>(error));
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "dictionary.hpp"
-#include "types.hpp"
+#include "alee.hpp"
+LIBALEE_SECTION
Addr Word::size() const noexcept
{
return wend - start;
}
+LIBALEE_SECTION
Word::iterator Word::begin(const Dictionary *dict)
{
return iterator(start, dict);
}
+LIBALEE_SECTION
Word::iterator Word::end(const Dictionary *dict)
{
return iterator(wend, dict);
}
+LIBALEE_SECTION
Word::iterator& Word::iterator::operator++()
{
addr++;
return *this;
}
+LIBALEE_SECTION
Word::iterator Word::iterator::operator++(int)
{
const auto copy = *this;
return copy;
}
+LIBALEE_SECTION
Word::iterator::value_type Word::iterator::operator*()
{
return dict->readbyte(addr);
}
+LIBALEE_SECTION
bool Word::iterator::operator!=(const iterator& other)
{
return dict != other.dict || addr != other.addr;
}
+
constexpr explicit Word(Addr s = 0, Addr e = 0):
start(s), wend(e) {}
+ LIBALEE_SECTION
static constexpr Word fromLength(Addr s, Addr l) {
return Word(s, s + l);
}
#ifndef ALEEFORTH_MEMDICT_HPP
#define ALEEFORTH_MEMDICT_HPP
-#include "alee.hpp"
+#include "libalee/alee.hpp"
#ifndef MEMDICTSIZE
#define MEMDICTSIZE (65536)
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "alee.hpp"
-#include "libalee/ctype.hpp"
+#include "libalee/alee.hpp"
#include "lzss.h"
static const
#include "msp430fr2476_all.h"
static void Software_Trim();
#define MCLK_FREQ_MHZ (16)
-#define ALEE_RODICTSIZE (9400)
+static void alee_main();
+
+#define ALEE_RODICTSIZE (9088)
__attribute__((section(".lodict")))
#include "core.fth.h"
int main()
{
WDTCTL = WDTPW | WDTHOLD;
+
+ extern char __libaleebegin;
+ extern char __libaleeend;
+ extern char __libaleedst;
+ std::copy(&__libaleebegin, &__libaleeend, &__libaleedst);
+
initGPIO();
initClock();
initUART();
SYSCFG0 = FRWPPW;
+ alee_main();
+}
+
+LIBALEE_SECTION
+void alee_main()
+{
(void)alee_dat_len;
State state (dict, readchar);
Parser::customParse = findword;
}
}
+LIBALEE_SECTION
void readchar(State& state)
{
auto idx = state.dict.read(Dictionary::Input);
state.dict.writebyte(addr, c ? c : ' ');
}
+LIBALEE_SECTION
void serput(int c)
{
while (!(UCA0IFG & UCTXIFG));
UCA0TXBUF = static_cast<char>(c);
}
+LIBALEE_SECTION
void serputs(const char *s)
{
while (*s)
serput(*s++);
}
+LIBALEE_SECTION
void printint(DoubleCell n, char *buf, int base)
{
static const char digit[] = "0123456789ABCDEF";
serput(' ');
}
+LIBALEE_SECTION
void user_sys(State& state)
{
switch (state.pop()) {
case 17:
exitLpm |= true;
break;
+ case 50:
+ Parser::customParse = nullptr;
+ extern char _etext;
+ state.push((Addr)&_etext);
+ break;
default:
break;
}
uint8_t *ptr = lzword;
for (auto it = word.begin(&state.dict); it != word.end(&state.dict); ++it) {
*ptr = *it;
- if (!isupper(*ptr))
+ if (islower(*ptr))
*ptr -= 32;
++ptr;
}
BOOTCODE : ORIGIN = 0x1C00, LENGTH = 0x0400 /* END=0x1FFF, size 1024 */\r
ROMLIB : ORIGIN = 0xC0000, LENGTH = 0x4000 /* END=0xC3FFF, size 16384 */\r
BSL1 : ORIGIN = 0xFFC00, LENGTH = 0x0400 /* END=0xFFFFF, size 1024 */\r
- RAM : ORIGIN = 0x2000, LENGTH = 0x2000 /* END=0x3FFF, size 8192 */\r
+ RAM (rwx) : ORIGIN = 0x2000, LENGTH = 0x2000 /* END=0x3FFF, size 8192 */\r
INFOMEM : ORIGIN = 0x1800, LENGTH = 0x0200 /* END=0x19FF, size 512 */\r
FRAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x7F80 /* END=0xFF7F, size 32640 */\r
HIFRAM (rxw) : ORIGIN = 0x10000, LENGTH = 0x00007FFF\r
PROVIDE (__dict = .);\r
} > TINYRAM\r
\r
+ .libalee : {\r
+ . = ALIGN(2);\r
+ PROVIDE (__libaleedst = .);\r
+ *(.libalee)\r
+ } > RAM AT> FRAM\r
+ PROVIDE(__libaleebegin = LOADADDR(.libalee));\r
+ PROVIDE (__libaleeend = LOADADDR(.libalee) + SIZEOF(.libalee));\r
+\r
.data :\r
{\r
. = ALIGN(2);\r
KEEP (*(.init))\r
KEEP (*(.fini))\r
KEEP (*(.tm_clone_table))\r
+\r
+ . = ALIGN(2);\r
+ PROVIDE (_etext = .);\r
} > FRAM\r
\r
.lodict :\r
{\r
- . = ALIGN(2);\r
+ . = ALIGN(1024);\r
*(.lodict)\r
} > FRAM\r
\r
#ifndef ALEEFORTH_SPLITMEMDICT_HPP
#define ALEEFORTH_SPLITMEMDICT_HPP
-#include "alee.hpp"
+#include "libalee/alee.hpp"
#include <algorithm>
#ifndef ALEEFORTH_SPLITMEMDICTRW_HPP
#define ALEEFORTH_SPLITMEMDICTRW_HPP
-#include "alee.hpp"
+#include "libalee/alee.hpp"
#include <algorithm>