From 34e5d76f9851f13a2c6611de065c229bafb17378 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 25 Feb 2023 08:25:31 -0500 Subject: [PATCH] double-width mul/div; error strings --- alee.cpp | 14 ++++++++++++++ compat.txt | 14 +++++++------- core.fth | 14 +++++++++++++- corewords.cpp | 19 +++++++++++++------ corewords.hpp | 2 +- state.hpp | 4 ++-- types.hpp | 1 + 7 files changed, 51 insertions(+), 17 deletions(-) diff --git a/alee.cpp b/alee.cpp index 0f270a8..f65b700 100644 --- a/alee.cpp +++ b/alee.cpp @@ -115,6 +115,20 @@ void parseLine(Parser& parser, State& state, const std::string& line) case Parser::UnknownWord: std::cout << "word not found in: " << line << std::endl; break; + case static_cast(State::Error::push): + std::cout << "stack overflow" << std::endl; + break; + case static_cast(State::Error::pushr): + std::cout << "return stack overflow" << std::endl; + break; + case static_cast(State::Error::popr): + std::cout << "return stack underflow" << std::endl; + break; + case static_cast(State::Error::pop): + case static_cast(State::Error::top): + case static_cast(State::Error::pick): + std::cout << "stack underflow" << std::endl; + break; default: std::cout << "error: " << r << std::endl; break; diff --git a/compat.txt b/compat.txt index 6307bfc..7685f8c 100644 --- a/compat.txt +++ b/compat.txt @@ -7,8 +7,8 @@ yes 6.1.0010 ! yes 6.1.0070 ' yes 6.1.0080 ( yes 6.1.0090 * - 6.1.0100 */ - 6.1.0110 */MOD +yes 6.1.0100 */ +yes 6.1.0110 */MOD yes 6.1.0120 yes 6.1.0130 +! yes 6.1.0140 +LOOP @@ -17,7 +17,7 @@ yes 6.1.0160 - yes 6.1.0180 . yes 6.1.0190 ." yes 6.1.0230 / - 6.1.0240 /MOD +yes 6.1.0240 /MOD yes 6.1.0250 0< yes 6.1.0270 0= yes 6.1.0290 1+ @@ -79,7 +79,7 @@ yes 6.1.1370 EXECUTE yes 6.1.1380 EXIT yes 6.1.1540 FILL 6.1.1550 FIND - 6.1.1561 FM/MOD +yes 6.1.1561 FM/MOD yes 6.1.1650 HERE 6.1.1670 HOLD yes 6.1.1680 I @@ -92,7 +92,7 @@ yes 6.1.1750 KEY yes 6.1.1780 LITERAL yes 6.1.1800 LOOP yes 6.1.1805 LSHIFT - 6.1.1810 M* +yes 6.1.1810 M* yes 6.1.1870 MAX yes 6.1.1880 MIN yes 6.1.1890 MOD @@ -109,9 +109,9 @@ yes 6.1.2140 REPEAT yes 6.1.2160 ROT yes 6.1.2162 RSHIFT yes 6.1.2165 S" - 6.1.2170 S>D +yes 6.1.2170 S>D 6.1.2210 SIGN - 6.1.2214 SM/REM +yes 6.1.2214 SM/REM yes 6.1.2216 SOURCE yes 6.1.2220 SPACE yes 6.1.2230 SPACES diff --git a/core.fth b/core.fth index 85744a7..0f00ba8 100644 --- a/core.fth +++ b/core.fth @@ -1,7 +1,10 @@ +: * m* drop ; +: / 0 swap _/ ; +: % 0 swap _% ; + : cell+ 2 + ; : cells 2 * ; - : . 0 sys ; : emit 1 sys ; @@ -92,6 +95,15 @@ : 2* 2 * ; : 2/ 2 / ; +: /mod 2dup % -rot / ; +: s>d 1 m* ; +: */ >r m* r> _/ ; +: */mod >r m* 2dup r@ _% r> _/ ; +: sm/rem >r 2dup r@ _% -rot r> _/ ; +: fm/mod 2dup dup >r ^ >r sm/rem swap dup + if r> 0< if r> + swap 1- else swap r> drop then + else swap 2r> 2drop then ; + : cr 10 emit ; : bl 32 ; : space bl emit ; diff --git a/corewords.cpp b/corewords.cpp index c0cec48..63ccc7d 100644 --- a/corewords.cpp +++ b/corewords.cpp @@ -49,6 +49,7 @@ void CoreWords::run(unsigned int index, State& state) }; Cell cell; + DoubleCell dcell; switch (index) { default: @@ -79,17 +80,23 @@ void CoreWords::run(unsigned int index, State& state) cell = state.pop(); state.top() -= cell; break; - case 7: // mul + case 7: // mul ( n n -- d ) cell = state.pop(); - state.top() *= cell; + dcell = state.pop() * cell; + state.push(dcell); + state.push(dcell >> (sizeof(Cell) * 8)); break; - case 8: // div + case 8: // div ( d n -- n ) cell = state.pop(); - state.top() /= cell; + dcell = state.pop() << (sizeof(Cell) * 8); + dcell |= state.pop(); + state.push(dcell / cell); break; - case 9: // mod + case 9: // mod ( d n -- n ) cell = state.pop(); - state.top() %= cell; + dcell = state.pop() << (sizeof(Cell) * 8); + dcell |= state.pop(); + state.push(dcell % cell); break; case 10: // peek if (state.pop()) diff --git a/corewords.hpp b/corewords.hpp index ab34c78..4eb9d42 100644 --- a/corewords.hpp +++ b/corewords.hpp @@ -41,7 +41,7 @@ private: // Ends with '\1': compile-only word constexpr static char wordsarr[] = "drop\0dup\0swap\0pick\0sys\0" - "+\0-\0*\0/\0%\0" + "+\0-\0m*\0_/\0_%\0" "_@\0_!\0>r\0r>\0=\0" "<\0allot\0&\0|\0^\0" "<<\0>>\0:\0'\0execute\0" diff --git a/state.hpp b/state.hpp index 22f0d74..69db2f6 100644 --- a/state.hpp +++ b/state.hpp @@ -25,8 +25,8 @@ #include #include -constexpr unsigned DataStackSize = 8; -constexpr unsigned ReturnStackSize = 8; +constexpr unsigned DataStackSize = 16; +constexpr unsigned ReturnStackSize = 16; struct State { diff --git a/types.hpp b/types.hpp index b6391ba..530ff4f 100644 --- a/types.hpp +++ b/types.hpp @@ -25,6 +25,7 @@ struct State; using Addr = uint16_t; using Cell = int16_t; +using DoubleCell = int32_t; using Func = void (*)(State&); constexpr unsigned int MaxCellNumberChars = 6; // -32768