From 78507c65c4ab649bbb0655d9485bf2f6e712af5c Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 9 Feb 2023 20:15:16 -0500 Subject: [PATCH] implement if and then --- alee.cpp | 9 ++++++++- corewords.cpp | 52 +++++++++++++++++++++++++++++++++++--------------- corewords.hpp | 18 +++++++++-------- dictionary.cpp | 5 +---- parser.cpp | 8 ++++---- 5 files changed, 60 insertions(+), 32 deletions(-) diff --git a/alee.cpp b/alee.cpp index f87831f..be71730 100644 --- a/alee.cpp +++ b/alee.cpp @@ -23,6 +23,8 @@ #include #include +static bool okay = false; + static void parseLine(Parser&, State&, std::string_view); static void parseFile(Parser&, State&, std::istream&); @@ -38,6 +40,7 @@ int main(int argc, char *argv[]) parseFile(parser, state, file); } + okay = true; //std::cout << state.size() << ' ' << state.compiling << "> "; parseFile(parser, state, std::cin); @@ -65,8 +68,12 @@ void parseLine(Parser& parser, State& state, std::string_view line) r = parser.parse(state, line); } while (r == ParseStatus::Continue); - if (r != ParseStatus::Finished) + if (r == ParseStatus::Finished) { + if (okay) + std::cout << " ok" << std::endl; + } else { std::cout << to_string(r) << ": " << line << std::endl; + } } void parseFile(Parser& parser, State& state, std::istream& file) diff --git a/corewords.cpp b/corewords.cpp index 8fbcfbd..6aac65e 100644 --- a/corewords.cpp +++ b/corewords.cpp @@ -48,11 +48,12 @@ Func CoreWords::get(int index) case 24: return op_colon; case 25: return op_semic; case 26: return op_here; - case 27: return op_exit; - case 28: return op_imm; - case 29: return op_const; - case 30: return op_literal; - case 31: return op_jump; + case 27: return op_imm; + case 28: return op_const; + case 29: return op_if; + case 30: return op_then; + case 31: return op_literal; + case 32: return op_jump; default: return nullptr; } } @@ -225,12 +226,6 @@ int CoreWords::op_here(State& state) { return 0; } -int CoreWords::op_exit(State& state) -{ - state.ip = state.popr(); - return 0; -} - int CoreWords::op_imm(State& state) { state.dict.write(state.dict.latest, @@ -259,6 +254,31 @@ int CoreWords::op_jump(State& state) return 0; } +int CoreWords::op_if(State& state) +{ + if (state.compiling) { + state.push(state.dict.here); + state.dict.add(0); + } else { + if (state.pop()) + ++state.ip; + else + state.ip = state.beyondip() - 1; + } + + return 0; +} + +int CoreWords::op_then(State& state) +{ + if (state.compiling) { + const auto ifaddr = state.pop(); + state.dict.write(ifaddr, state.dict.here); + } + + return 0; +} + int CoreWords::findi(std::string_view str) { std::size_t i; @@ -267,26 +287,28 @@ int CoreWords::findi(std::string_view str) std::string_view words (wordsarr, sizeof(wordsarr)); for (i = 0; i < words.size();) { - const auto end = words.find('\0', i); + const auto end = words.find_first_of({"\0\1", 2}, i); if (words.compare(i, end - i, str) == 0) - break; + return words[end] == '\0' ? wordsi : (wordsi | CoreImmediate); ++wordsi; i = end + 1; } - return wordsi < VisibleWordCount ? wordsi : -1; + return -1; } Func CoreWords::find(std::string_view str) { const auto i = findi(str); - return i >= 0 ? get(i) : nullptr; + return i >= 0 ? get(i & ~CoreWords::CoreImmediate) : nullptr; } void CoreWords::run(int i, State& state) { + i &= ~CoreWords::CoreImmediate; + if (i >= 0 && i < WordCount) get(i)(state); } diff --git a/corewords.hpp b/corewords.hpp index 54e02f1..7edc139 100644 --- a/corewords.hpp +++ b/corewords.hpp @@ -27,12 +27,13 @@ int user_sys(State&); class CoreWords { public: - constexpr static std::size_t VisibleWordCount = 30; // size - constexpr static std::size_t HiddenWordLiteral = 30; // index - constexpr static std::size_t HiddenWordJump = 31; // index - constexpr static std::size_t WordCount = 32; // size + constexpr static std::size_t VisibleWordCount = 31; // size + constexpr static auto HiddenWordLiteral = VisibleWordCount; // index + constexpr static auto HiddenWordJump = VisibleWordCount + 1; // index + constexpr static auto WordCount = HiddenWordJump + 1; // size - constexpr static Cell Immediate = (1 << 5); + constexpr static Cell Immediate = (1 << 5); + constexpr static Cell CoreImmediate = (1 << 6); static int findi(std::string_view); static Func find(std::string_view); @@ -45,8 +46,8 @@ private: "@\0!\0rot\0>r\0r>\0" "=\0<\0allot\0&\0|\0" "^\0<<\0>>\0(\0:\0" - ";\0here\0exit\0imm\0const\0"; - // lit, jmp, jmp0, ', lits + ";\1here\0imm\0const\0" + "if\1then\1"; static Func get(int); @@ -77,11 +78,12 @@ private: static int op_colon(State&); static int op_semic(State&); static int op_here(State&); - static int op_exit(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&); }; #endif // ALEEFORTH_COREWORDS_HPP diff --git a/dictionary.cpp b/dictionary.cpp index dced709..e1165d2 100644 --- a/dictionary.cpp +++ b/dictionary.cpp @@ -35,9 +35,6 @@ void Dictionary::addDefinition(std::string_view str) add(str.size()); for (char c : str) add(c); - - if (here & 1) - allot(1); } bool Dictionary::issame(Addr addr, std::string_view str, std::size_t n) @@ -75,6 +72,6 @@ Addr Dictionary::find(std::string_view str) Addr Dictionary::getexec(Addr addr) { const auto len = read(addr) & 0x1F; - return ((addr + 1 + len) + 1) & ~1; + return addr + 1 + len; } diff --git a/parser.cpp b/parser.cpp index 99cbc8b..19ef34a 100644 --- a/parser.cpp +++ b/parser.cpp @@ -39,7 +39,7 @@ ParseStatus Parser::parse(State& state, std::string_view& str) break; case Pass::Colon: state.pass = Pass::None; - state.compiling = true; + state.compiling = true; state.dict.addDefinition(sub); break; case Pass::Constant: @@ -57,9 +57,9 @@ ParseStatus Parser::parse(State& state, std::string_view& str) } else { if (auto i = CoreWords::findi(sub); i >= 0) { if (state.compiling) - state.dict.add(i); - if (!state.compiling || sub.front() == ';') - CoreWords::run(i, state); + state.dict.add(i & ~CoreWords::CoreImmediate); + if (!state.compiling || (i & CoreWords::CoreImmediate)) + CoreWords::run(i & ~CoreWords::CoreImmediate, state); } else if (auto j = state.dict.find(sub); j > 0) { auto e = state.dict.getexec(j);