diff --git a/core.fth b/core.fth index 06aad0a..4d1393c 100644 --- a/core.fth +++ b/core.fth @@ -4,47 +4,64 @@ ( 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 ; + diff --git a/corewords.cpp b/corewords.cpp index d016ba1..f0f8d5d 100644 --- a/corewords.cpp +++ b/corewords.cpp @@ -53,8 +53,9 @@ Func CoreWords::get(int index) 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; } } @@ -206,7 +207,7 @@ int CoreWords::op_colon(State& state) { } int CoreWords::op_semic(State& state) { - if (!state.compiling) { + if (!state.compiling()) { state.ip = state.popr(); } else { auto begin = state.popr(); @@ -216,7 +217,7 @@ int CoreWords::op_semic(State& state) { ((begin - state.dict.latest) << 6)); state.dict.latest = begin; - state.compiling = false; + state.compiling(false); } return 0; @@ -257,7 +258,7 @@ int CoreWords::op_jump(State& state) int CoreWords::op_if(State& state) { - if (state.compiling) { + if (state.compiling()) { state.push(state.dict.here); state.dict.add(0); } else { @@ -272,7 +273,7 @@ int CoreWords::op_if(State& state) 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); @@ -283,7 +284,7 @@ int CoreWords::op_then(State& state) 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); @@ -295,6 +296,12 @@ int CoreWords::op_else(State& state) 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; diff --git a/corewords.hpp b/corewords.hpp index 0b84b0e..2d894a1 100644 --- a/corewords.hpp +++ b/corewords.hpp @@ -27,7 +27,7 @@ int user_sys(State&); 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 @@ -47,7 +47,7 @@ private: "=\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); @@ -85,6 +85,7 @@ private: static int op_if(State&); static int op_then(State&); static int op_else(State&); + static int op_depth(State&); }; #endif // ALEEFORTH_COREWORDS_HPP diff --git a/dictionary.hpp b/dictionary.hpp index 2a54a5d..5c6471a 100644 --- a/dictionary.hpp +++ b/dictionary.hpp @@ -27,7 +27,10 @@ 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; diff --git a/parser.cpp b/parser.cpp index 19ef34a..d58b4ed 100644 --- a/parser.cpp +++ b/parser.cpp @@ -39,12 +39,12 @@ 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: state.pass = Pass::None; - state.compiling = true; + state.compiling(true); state.dict.addDefinition(sub); state.dict.add(CoreWords::HiddenWordLiteral); state.dict.add(state.pop()); @@ -56,18 +56,18 @@ ParseStatus Parser::parse(State& state, std::string_view& str) } } 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); @@ -81,7 +81,7 @@ ParseStatus Parser::parse(State& state, std::string_view& str) const auto l = static_cast(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 { diff --git a/state.cpp b/state.cpp index 0b5c8fe..6165ce4 100644 --- a/state.cpp +++ b/state.cpp @@ -20,6 +20,16 @@ #include +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); diff --git a/state.hpp b/state.hpp index 6311949..e17d324 100644 --- a/state.hpp +++ b/state.hpp @@ -35,13 +35,15 @@ class State 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);