( set decimal numbers )
10 0 !
-: . 0 sys ;
-: emit 1 sys ;
-
-: over 1 pick ;
-: -rot rot rot ;
-: nip swap drop ;
-: tuck swap over ;
-
-: +! swap over @ + swap ! ;
-
-: 1+ 1 + ;
-: 1- 1 - ;
-
-: 0= 0 = ;
-: >= < 0= ;
-
-: 2drop drop drop ;
-: 2dup over over ;
-: 2over 3 pick 3 pick ;
-: 2swap rot >r rot r> ;
-
-: and & ;
-: or | ;
-: xor ^ ;
-: lshift << ;
-: rshift >> ;
-: 2* 2 * ;
-: 2/ 2 / ;
-
-: , here ! 1 allot ;
-: c! ! ;
-: c, , ;
-: c@ @ ;
-: cell+ 1+ ;
-: cells ;
-: char+ 1+ ;
-: chars ;
-
-: cr 9 emit ;
-: bl 32 ;
+: . 0 sys ;
+: emit 1 sys ;
+: over 1 pick ;
+: -rot rot rot ;
+: nip swap drop ;
+: tuck swap over ;
+
+: and & ;
+: or | ;
+: xor ^ ;
+: lshift << ;
+: rshift >> ;
+: mod % ;
+: 2* 2 * ;
+: 2/ 2 / ;
+
+: 0= 0 = ;
+: 0< 0 < ;
+: <= 2dup < -rot = and ;
+: > <= 0= ;
+
+: 1+ 1 + ;
+: 1- 1 - ;
+
+: 2drop drop drop ;
+: 2dup over over ;
+: 2over 3 pick 3 pick ;
+: 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 @ ;
+
+: cr 9 emit ;
+: bl 32 ;
+: space bl emit ;
+
+: state 1 ;
: base 0 ;
: decimal 1 2* base ! 1010 base ! ;
+: ?dup dup if dup then ;
+
+: negate -1 * ;
+: abs dup 0< if negate then ;
+: min 2dup <= if drop else nip then ;
+: max 2dup <= if nip else drop then ;
+
+: align ;
+: aligned ;
+
case 29: return op_if;
case 30: return op_then;
case 31: return op_else;
- case 32: return op_literal;
- case 33: return op_jump;
+ case 32: return op_depth;
+ case 33: return op_literal;
+ case 34: return op_jump;
default: return nullptr;
}
}
}
int CoreWords::op_semic(State& state) {
- if (!state.compiling) {
+ if (!state.compiling()) {
state.ip = state.popr();
} else {
auto begin = state.popr();
((begin - state.dict.latest) << 6));
state.dict.latest = begin;
- state.compiling = false;
+ state.compiling(false);
}
return 0;
int CoreWords::op_if(State& state)
{
- if (state.compiling) {
+ if (state.compiling()) {
state.push(state.dict.here);
state.dict.add(0);
} else {
int CoreWords::op_then(State& state)
{
- if (state.compiling) {
+ if (state.compiling()) {
const auto ifaddr = state.pop();
if (state.dict.read(ifaddr) == 0)
state.dict.write(ifaddr, state.dict.here);
int CoreWords::op_else(State& state)
{
- if (state.compiling) {
+ if (state.compiling()) {
const auto ifaddr = state.pop();
state.push(state.dict.here);
state.dict.add(0);
return 0;
}
+int CoreWords::op_depth(State& state)
+{
+ state.push(state.size());
+ return 0;
+}
+
int CoreWords::findi(std::string_view str)
{
std::size_t i;
class CoreWords
{
public:
- constexpr static std::size_t VisibleWordCount = 32; // size
+ constexpr static std::size_t VisibleWordCount = 33; // size
constexpr static auto HiddenWordLiteral = VisibleWordCount; // index
constexpr static auto HiddenWordJump = VisibleWordCount + 1; // index
constexpr static auto WordCount = HiddenWordJump + 1; // size
"=\0<\0allot\0&\0|\0"
"^\0<<\0>>\0(\0:\0"
";\1here\0imm\0const\0"
- "if\1then\1else\1";
+ "if\1then\1else\1depth\0";
static Func get(int);
static int op_if(State&);
static int op_then(State&);
static int op_else(State&);
+ static int op_depth(State&);
};
#endif // ALEEFORTH_COREWORDS_HPP
class Dictionary
{
public:
- Addr here = 1; // address zero will be used for BASE.
+ constexpr static Addr Base = 0;
+ constexpr static Addr Compiling = 1;
+
+ Addr here = 2;
Addr latest = 0;
virtual Cell read(Addr) const = 0;
break;
case Pass::Colon:
state.pass = Pass::None;
- state.compiling = true;
+ state.compiling(true);
state.dict.addDefinition(sub);
break;
case Pass::Constant:
state.pass = Pass::None;
- state.compiling = true;
+ state.compiling(true);
state.dict.addDefinition(sub);
state.dict.add(CoreWords::HiddenWordLiteral);
state.dict.add(state.pop());
}
} else {
if (auto i = CoreWords::findi(sub); i >= 0) {
- if (state.compiling)
+ if (state.compiling())
state.dict.add(i & ~CoreWords::CoreImmediate);
- if (!state.compiling || (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);
- if (state.compiling) {
+ if (state.compiling()) {
if (state.dict.read(j) & CoreWords::Immediate) {
- state.compiling = false;
+ state.compiling(false);
Executor::fullexec(state, e);
- state.compiling = true;
+ state.compiling(true);
} else {
state.dict.add(CoreWords::HiddenWordJump);
state.dict.add(e);
const auto l = static_cast<Cell>(std::strtol(sub.data(), &p, base));
if (p != sub.data()) {
- if (state.compiling) {
+ if (state.compiling()) {
state.dict.add(CoreWords::HiddenWordLiteral);
state.dict.add(l);
} else {
#include <iterator>
+bool State::compiling() const
+{
+ return dict.read(Dictionary::Compiling);
+}
+
+void State::compiling(bool yes)
+{
+ dict.write(Dictionary::Compiling, yes);
+}
+
Cell State::beyondip() const
{
return dict.read(ip + 1);
Cell *rsp = rstack - 1;
public:
- bool compiling = false;
Addr ip = 0;
Pass pass = Pass::None;
Dictionary& dict;
constexpr State(Dictionary& d): dict(d) {}
+ bool compiling() const;
+ void compiling(bool);
+
Cell beyondip() const;
void pushr(Cell);