From a506b65bdd589997195e3f93222c37a539a29a28 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Tue, 14 Feb 2023 14:35:29 -0500 Subject: [PATCH] allow byte indexing --- core.fth | 29 +++++++++++++++++------------ corewords.cpp | 27 +++++++++++++++++---------- corewords.hpp | 4 ++-- dictionary.cpp | 23 +++++++++++++++++------ dictionary.hpp | 13 +++++++++---- executor.cpp | 4 ++-- memdict.hpp | 13 +++++++++++-- state.cpp | 21 ++++++++++++++------- 8 files changed, 89 insertions(+), 45 deletions(-) diff --git a/core.fth b/core.fth index 4d1393c..d9c7a59 100644 --- 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 ^ ; @@ -35,15 +52,6 @@ : 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 ; - diff --git a/corewords.cpp b/corewords.cpp index f0f8d5d..de5066e 100644 --- a/corewords.cpp +++ b/corewords.cpp @@ -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; diff --git a/corewords.hpp b/corewords.hpp index 2d894a1..24e1415 100644 --- a/corewords.hpp +++ b/corewords.hpp @@ -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); diff --git a/dictionary.cpp b/dictionary.cpp index e1165d2..e047488 100644 --- a/dictionary.cpp +++ b/dictionary.cpp @@ -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); } diff --git a/dictionary.hpp b/dictionary.hpp index 5c6471a..fd27920 100644 --- a/dictionary.hpp +++ b/dictionary.hpp @@ -22,20 +22,25 @@ #include "types.hpp" #include +#include #include 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); diff --git a/executor.cpp b/executor.cpp index 30d43fc..0309ca7 100644 --- a/executor.cpp +++ b/executor.cpp @@ -22,10 +22,10 @@ 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); diff --git a/memdict.hpp b/memdict.hpp index 8606da2..6209f3b 100644 --- a/memdict.hpp +++ b/memdict.hpp @@ -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(dict + addr); } virtual int write(Addr addr, Cell value) final { + *reinterpret_cast(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; } diff --git a/state.cpp b/state.cpp index 6165ce4..ae9c059 100644 --- a/state.cpp +++ b/state.cpp @@ -20,6 +20,13 @@ #include +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); }