aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2023-02-25 08:25:31 -0500
committerClyne Sullivan <clyne@bitgloo.com>2023-02-25 08:25:31 -0500
commit34e5d76f9851f13a2c6611de065c229bafb17378 (patch)
tree7ee094718de01f949877d5f00b8fc5dc1f5f35d8
parent0b88b4596e6265863e75e7aabcca52734e147fae (diff)
double-width mul/div; error strings
-rw-r--r--alee.cpp14
-rw-r--r--compat.txt14
-rw-r--r--core.fth14
-rw-r--r--corewords.cpp19
-rw-r--r--corewords.hpp2
-rw-r--r--state.hpp4
-rw-r--r--types.hpp1
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<int>(State::Error::push):
+ std::cout << "stack overflow" << std::endl;
+ break;
+ case static_cast<int>(State::Error::pushr):
+ std::cout << "return stack overflow" << std::endl;
+ break;
+ case static_cast<int>(State::Error::popr):
+ std::cout << "return stack underflow" << std::endl;
+ break;
+ case static_cast<int>(State::Error::pop):
+ case static_cast<int>(State::Error::top):
+ case static_cast<int>(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 <csetjmp>
#include <cstddef>
-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