diff --git a/Makefile b/Makefile index 36e299d..94d425d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ CXXFLAGS += -std=c++17 -g3 -ggdb -O0 -CXXFILES := corewords.cpp dictionary.cpp executor.cpp parser.cpp state.cpp \ - types.cpp +CXXFILES := corewords.cpp dictionary.cpp parser.cpp state.cpp types.cpp OBJFILES := $(subst .cpp,.o,$(CXXFILES)) LIBFILE := libalee.a EXEFILE := alee diff --git a/alee.cpp b/alee.cpp index b38f8a0..c8dee45 100644 --- a/alee.cpp +++ b/alee.cpp @@ -59,7 +59,7 @@ int main(int argc, char *argv[]) return 0; } -int user_sys(State& state) +void user_sys(State& state) { switch (state.pop()) { case 0: @@ -69,16 +69,11 @@ int user_sys(State& state) std::cout << static_cast(state.pop()) << std::endl; break; } - - return 0; } void parseLine(Parser& parser, State& state, std::string_view line) { - ParseStatus r; - do { - r = parser.parse(state, line); - } while (r == ParseStatus::Continue); + auto r = parser.parse(state, line); if (r == ParseStatus::Finished) { if (okay) diff --git a/corewords.cpp b/corewords.cpp index 6a47392..3312ef1 100644 --- a/corewords.cpp +++ b/corewords.cpp @@ -60,156 +60,133 @@ Func CoreWords::get(int index) } } -int CoreWords::op_drop(State& state) +void CoreWords::op_drop(State& state) { state.pop(); - return 0; } -int CoreWords::op_dup(State& state) +void CoreWords::op_dup(State& state) { state.push(state.top()); - return 0; } -int CoreWords::op_swap(State& state) +void CoreWords::op_swap(State& state) { std::swap(state.top(), state.pick(1)); - return 0; } -int CoreWords::op_pick(State& state) +void CoreWords::op_pick(State& state) { state.push(state.pick(state.pop())); - return 0; } -int CoreWords::op_sys(State& state) +void CoreWords::op_sys(State& state) { return user_sys(state); } -int CoreWords::op_add(State& state) +void CoreWords::op_add(State& state) { const auto a = state.pop(); state.top() += a; - return 0; } -int CoreWords::op_sub(State& state) +void CoreWords::op_sub(State& state) { const auto a = state.pop(); state.top() -= a; - return 0; } -int CoreWords::op_mul(State& state) { +void CoreWords::op_mul(State& state) { const auto a = state.pop(); state.top() *= a; - return 0; } -int CoreWords::op_div(State& state) { +void CoreWords::op_div(State& state) { const auto a = state.pop(); state.top() /= a; - return 0; } -int CoreWords::op_mod(State& state) { +void CoreWords::op_mod(State& state) { const auto a = state.pop(); state.top() %= a; - return 0; } -int CoreWords::op_peek(State& state) { +void CoreWords::op_peek(State& state) { 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) { +void CoreWords::op_poke(State& state) { const auto w = state.pop(); const auto addr = state.pop(); if (w == 1) state.dict.writebyte(addr, state.pop()); else state.dict.write(addr, state.pop()); - return 0; } -int CoreWords::op_rot(State& state) { +void CoreWords::op_rot(State& state) { std::swap(state.pick(2), state.pick(1)); std::swap(state.pick(1), state.pick(0)); - return 0; } -int CoreWords::op_pushr(State& state) { +void CoreWords::op_pushr(State& state) { state.pushr(state.pop()); - return 0; } -int CoreWords::op_popr(State& state) { +void CoreWords::op_popr(State& state) { state.push(state.popr()); - return 0; } -int CoreWords::op_eq(State& state) { +void CoreWords::op_eq(State& state) { const auto a = state.pop(); state.top() = state.top() == a; - return 0; } -int CoreWords::op_lt(State& state) { +void CoreWords::op_lt(State& state) { const auto a = state.pop(); state.top() = state.top() < a; - return 0; } -int CoreWords::op_allot(State& state) { +void CoreWords::op_allot(State& state) { state.dict.allot(state.pop()); - return 0; } -int CoreWords::op_and(State& state) { +void CoreWords::op_and(State& state) { const auto a = state.pop(); state.top() &= a; - return 0; } -int CoreWords::op_or(State& state) { +void CoreWords::op_or(State& state) { const auto a = state.pop(); state.top() |= a; - return 0; } -int CoreWords::op_xor(State& state) { +void CoreWords::op_xor(State& state) { const auto a = state.pop(); state.top() ^= a; - return 0; } -int CoreWords::op_shl(State& state) { +void CoreWords::op_shl(State& state) { const auto a = state.pop(); state.top() <<= a; - return 0; } -int CoreWords::op_shr(State& state) { +void CoreWords::op_shr(State& state) { const auto a = state.pop(); state.top() >>= a; - return 0; } -int CoreWords::op_comment(State& state) { +void CoreWords::op_comment(State& state) { do { op_key(state); } while (state.pop() != ')'); - return 0; } -int CoreWords::op_colon(State& state) { +void CoreWords::op_colon(State& state) { if (state.compiling()) { Word word = state.dict.input(); while (word.size() == 0) { @@ -221,10 +198,9 @@ int CoreWords::op_colon(State& state) { state.dict.addDefinition(word); } - return 0; } -int CoreWords::op_semic(State& state) { +void CoreWords::op_semic(State& state) { if (!state.compiling()) { state.ip = state.popr(); } else { @@ -238,22 +214,19 @@ int CoreWords::op_semic(State& state) { state.compiling(false); } - return 0; } -int CoreWords::op_here(State& state) { +void CoreWords::op_here(State& state) { state.push(state.dict.here); - return 0; } -int CoreWords::op_imm(State& state) +void CoreWords::op_imm(State& state) { state.dict.write(state.dict.latest, state.dict.read(state.dict.latest) | Immediate); - return 0; } -int CoreWords::op_const(State& state) +void CoreWords::op_const(State& state) { if (state.compiling()) { Word word = state.dict.input(); @@ -271,24 +244,21 @@ int CoreWords::op_const(State& state) state.compiling(false); } - return 0; } -int CoreWords::op_literal(State& state) +void CoreWords::op_literal(State& state) { state.push(state.beyondip()); state.ip += sizeof(Cell); - return 0; } -int CoreWords::op_jump(State& state) +void CoreWords::op_jump(State& state) { state.pushr(state.ip + sizeof(Cell)); state.ip = state.beyondip() - sizeof(Cell); - return 0; } -int CoreWords::op_if(State& state) +void CoreWords::op_if(State& state) { if (state.compiling()) { state.push(state.dict.here); @@ -300,10 +270,9 @@ int CoreWords::op_if(State& state) state.ip = state.beyondip() - sizeof(Cell); } - return 0; } -int CoreWords::op_then(State& state) +void CoreWords::op_then(State& state) { if (state.compiling()) { const auto ifaddr = state.pop(); @@ -311,10 +280,9 @@ int CoreWords::op_then(State& state) state.dict.write(ifaddr, state.dict.here); } - return 0; } -int CoreWords::op_else(State& state) +void CoreWords::op_else(State& state) { if (state.compiling()) { const auto ifaddr = state.pop(); @@ -325,16 +293,14 @@ int CoreWords::op_else(State& state) state.ip = state.beyondip() - sizeof(Cell); } - return 0; } -int CoreWords::op_depth(State& state) +void CoreWords::op_depth(State& state) { state.push(state.size()); - return 0; } -int CoreWords::op_key(State& state) +void CoreWords::op_key(State& state) { auto len = state.dict.read(Dictionary::Input); while (len <= 0) @@ -346,7 +312,6 @@ int CoreWords::op_key(State& state) Cell val = state.dict.readbyte(addr); state.push(val); - return 0; } int CoreWords::findi(State& state, Word word) diff --git a/corewords.hpp b/corewords.hpp index ed57dd6..babb5aa 100644 --- a/corewords.hpp +++ b/corewords.hpp @@ -22,7 +22,7 @@ #include "types.hpp" #include "state.hpp" -int user_sys(State&); +void user_sys(State&); class CoreWords { @@ -51,43 +51,43 @@ private: static Func get(int); - static int op_drop(State&); - static int op_dup(State&); - static int op_swap(State&); - static int op_pick(State&); - static int op_sys(State&); - static int op_add(State&); - static int op_sub(State&); - static int op_mul(State&); - static int op_div(State&); - static int op_mod(State&); - static int op_peek(State&); - static int op_poke(State&); - static int op_rot(State&); - static int op_pushr(State&); - static int op_popr(State&); - static int op_eq(State&); - static int op_lt(State&); - static int op_allot(State&); - static int op_and(State&); - static int op_or(State&); - static int op_xor(State&); - static int op_shl(State&); - static int op_shr(State&); - static int op_comment(State&); - static int op_colon(State&); - static int op_semic(State&); - static int op_here(State&); - static int op_imm(State&); - static int op_const(State&); - static int op_literal(State&); - static int op_jump(State&); - static int op_if(State&); - static int op_then(State&); - static int op_else(State&); - static int op_depth(State&); - static int op_key(State&); - static int op_word(State&); + static void op_drop(State&); + static void op_dup(State&); + static void op_swap(State&); + static void op_pick(State&); + static void op_sys(State&); + static void op_add(State&); + static void op_sub(State&); + static void op_mul(State&); + static void op_div(State&); + static void op_mod(State&); + static void op_peek(State&); + static void op_poke(State&); + static void op_rot(State&); + static void op_pushr(State&); + static void op_popr(State&); + static void op_eq(State&); + static void op_lt(State&); + static void op_allot(State&); + static void op_and(State&); + static void op_or(State&); + static void op_xor(State&); + static void op_shl(State&); + static void op_shr(State&); + static void op_comment(State&); + static void op_colon(State&); + static void op_semic(State&); + static void op_here(State&); + static void op_imm(State&); + static void op_const(State&); + static void op_literal(State&); + static void op_jump(State&); + static void op_if(State&); + static void op_then(State&); + static void op_else(State&); + static void op_depth(State&); + static void op_key(State&); + static void op_word(State&); }; #endif // ALEEFORTH_COREWORDS_HPP diff --git a/dictionary.cpp b/dictionary.cpp index e1153cc..c240cca 100644 --- a/dictionary.cpp +++ b/dictionary.cpp @@ -47,21 +47,6 @@ void Dictionary::addDefinition(Word word) writebyte(allot(1), readbyte(word.start + i)); } -bool Dictionary::issame(Addr addr, std::string_view str, std::size_t n) -{ - if (str.size() != n) - return false; - - for (char c : str) { - if (read(addr) != c) - return false; - - addr += sizeof(Cell); - } - - return true; -} - Addr Dictionary::find(Word word) { if (latest == 0) diff --git a/dictionary.hpp b/dictionary.hpp index b2c2107..90234ba 100644 --- a/dictionary.hpp +++ b/dictionary.hpp @@ -34,27 +34,25 @@ public: constexpr static Addr InputCells = 80; // bytes! constexpr static Addr Begin = Input + sizeof(Cell) + InputCells; - Word input(); - bool equal(Word, std::string_view) const; - bool equal(Word, Word) const; - Addr here = Begin; Addr latest = Begin; virtual Cell read(Addr) const = 0; - virtual int write(Addr, Cell) = 0; + virtual void write(Addr, Cell) = 0; virtual uint8_t readbyte(Addr) const = 0; - virtual int writebyte(Addr, uint8_t) = 0; + virtual void writebyte(Addr, uint8_t) = 0; Addr alignhere(); Addr allot(Cell); void add(Cell); void addDefinition(Word); + Addr find(Word); Addr getexec(Addr); + Word input(); -private: - bool issame(Addr, std::string_view, std::size_t); + bool equal(Word, std::string_view) const; + bool equal(Word, Word) const; }; #endif // ALEEFORTH_DICTIONARY_HPP diff --git a/executor.cpp b/executor.cpp deleted file mode 100644 index 0309ca7..0000000 --- a/executor.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Alee Forth: A portable and concise Forth implementation in modern C++. - * Copyright (C) 2023 Clyne Sullivan - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "corewords.hpp" -#include "executor.hpp" - -int Executor::fullexec(State& state, Addr addr) -{ - state.pushr(0); - state.ip = addr - sizeof(Cell); - - do { - state.ip += sizeof(Cell); - CoreWords::run(state.dict.read(state.ip), state); - } while (state.ip); - - return 0; -} - diff --git a/executor.hpp b/executor.hpp deleted file mode 100644 index 66c675b..0000000 --- a/executor.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Alee Forth: A portable and concise Forth implementation in modern C++. - * Copyright (C) 2023 Clyne Sullivan - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef ALEEFORTH_EXECUTOR_HPP -#define ALEEFORTH_EXECUTOR_HPP - -#include "types.hpp" - -class Executor -{ -public: - static int fullexec(State&, Addr); -}; - -#endif // ALEEFORTH_EXECUTOR_HPP - diff --git a/memdict.hpp b/memdict.hpp index 6209f3b..b956d5d 100644 --- a/memdict.hpp +++ b/memdict.hpp @@ -32,18 +32,16 @@ public: return *reinterpret_cast(dict + addr); } - virtual int write(Addr addr, Cell value) final { + virtual void 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 { + virtual void writebyte(Addr addr, uint8_t value) final { dict[addr] = value; - return 0; } }; diff --git a/parser.cpp b/parser.cpp index 2d6e9ff..b4c2d1c 100644 --- a/parser.cpp +++ b/parser.cpp @@ -17,7 +17,6 @@ */ #include "corewords.hpp" -#include "executor.hpp" #include "parser.hpp" #include @@ -40,7 +39,7 @@ ParseStatus Parser::parseSource(State& state) { auto word = state.dict.input(); while (word.size() > 0) { - if (auto ret = parseWord(state, word); ret == ParseStatus::Error) + if (auto ret = parseWord(state, word); ret != ParseStatus::Finished) return ret; word = state.dict.input(); @@ -52,11 +51,10 @@ ParseStatus Parser::parseSource(State& state) ParseStatus Parser::parseWord(State& state, Word word) { if (auto i = CoreWords::findi(state, word); i >= 0) { - if (state.compiling()) { + if (state.compiling()) state.dict.add(i & ~CoreWords::CoreImmediate); - } else if (state.dict.equal(word, ":")) { + else if (state.dict.equal(word, ":")) state.compiling(true); - } if (!state.compiling() || (i & CoreWords::CoreImmediate)) CoreWords::run(i & ~CoreWords::CoreImmediate, state); @@ -66,14 +64,14 @@ ParseStatus Parser::parseWord(State& state, Word word) if (state.compiling()) { if (state.dict.read(j) & CoreWords::Immediate) { state.compiling(false); - Executor::fullexec(state, e); + state.execute(e); state.compiling(true); } else { state.dict.add(CoreWords::HiddenWordJump); state.dict.add(e); } } else { - Executor::fullexec(state, e); + state.execute(e); } } else { char buf[word.size()]; @@ -82,7 +80,7 @@ ParseStatus Parser::parseWord(State& state, Word word) char *p; const auto base = state.dict.read(0); - const auto l = static_cast(std::strtol(buf, &p, base)); + const Cell l = std::strtol(buf, &p, base); if (p != buf) { if (state.compiling()) { @@ -92,27 +90,10 @@ ParseStatus Parser::parseWord(State& state, Word word) state.push(l); } } else { - return ParseStatus::Error; + return ParseStatus::NotAWord; } } return ParseStatus::Finished; } - //case Pass::Colon: - // state.pass = Pass::None; - // state.compiling(true); - // state.dict.addDefinition(sub); - // break; - //case Pass::Constant: - // state.pass = Pass::None; - // state.compiling(true); - // state.dict.addDefinition(sub); - // state.dict.add(CoreWords::HiddenWordLiteral); - // state.dict.add(state.pop()); - // state.dict.add(CoreWords::findi(";")); - // CoreWords::run(CoreWords::findi(";"), state); - // break; - //default: - // break; - //} diff --git a/state.cpp b/state.cpp index ae9c059..0fe0905 100644 --- a/state.cpp +++ b/state.cpp @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include "corewords.hpp" #include "state.hpp" #include @@ -37,6 +38,17 @@ void State::compiling(bool yes) dict.write(Dictionary::Compiling, yes); } +void State::execute(Addr addr) +{ + pushr(0); + ip = addr - sizeof(Cell); + + do { + ip += sizeof(Cell); + CoreWords::run(dict.read(ip), *this); + } while (ip); +} + Cell State::beyondip() const { return dict.read(ip + sizeof(Cell)); diff --git a/state.hpp b/state.hpp index 0308238..73bd8eb 100644 --- a/state.hpp +++ b/state.hpp @@ -45,6 +45,8 @@ public: bool compiling() const; void compiling(bool); + void execute(Addr); + Cell beyondip() const; void pushr(Cell); diff --git a/types.cpp b/types.cpp index c1fc822..6afe7e5 100644 --- a/types.cpp +++ b/types.cpp @@ -22,8 +22,7 @@ std::string_view to_string(ParseStatus ps) { switch (ps) { case ParseStatus::Finished: return "Finished"; - case ParseStatus::Continue: return "Continue"; - case ParseStatus::Error: return "Error"; + case ParseStatus::NotAWord: return "Not a word"; default: return "???"; } } diff --git a/types.hpp b/types.hpp index 5c4d358..d4f1882 100644 --- a/types.hpp +++ b/types.hpp @@ -26,7 +26,7 @@ struct State; using Addr = uint16_t; using Cell = int16_t; -using Func = int (*)(State&); +using Func = void (*)(State&); struct Word { @@ -41,8 +41,7 @@ struct Word enum class ParseStatus { Finished, - Continue, - Error + NotAWord }; std::string_view to_string(ParseStatus);