diff options
Diffstat (limited to 'corewords.cpp')
-rw-r--r-- | corewords.cpp | 179 |
1 files changed, 88 insertions, 91 deletions
diff --git a/corewords.cpp b/corewords.cpp index 3312ef1..9b43fcf 100644 --- a/corewords.cpp +++ b/corewords.cpp @@ -20,44 +20,19 @@ Func CoreWords::get(int index) { - switch (index) { - case 0: return op_drop; - case 1: return op_dup; - case 2: return op_swap; - case 3: return op_pick; - case 4: return op_sys; - case 5: return op_add; - case 6: return op_sub; - case 7: return op_mul; - case 8: return op_div; - case 9: return op_mod; - case 10: return op_peek; - case 11: return op_poke; - case 12: return op_rot; - case 13: return op_pushr; - case 14: return op_popr; - case 15: return op_eq; - case 16: return op_lt; - case 17: return op_allot; - case 18: return op_and; - case 19: return op_or; - case 20: return op_xor; - case 21: return op_shl; - case 22: return op_shr; - case 23: return op_comment; - case 24: return op_colon; - case 25: return op_semic; // :267 - case 26: return op_here; - case 27: return op_imm; - case 28: return op_const; - case 29: return op_if; - case 30: return op_then; - case 31: return op_else; - case 32: return op_depth; - case 33: return op_literal; - case 34: return op_jump; - default: return nullptr; - } + static const Func ops[WordCount] = { + op_drop, op_dup, op_swap, op_pick, op_sys, + op_add, op_sub, op_mul, op_div, op_mod, + op_peek, op_poke, op_rot, op_pushr, op_popr, + op_eq, op_lt, op_allot, op_and, op_or, + op_xor, op_shl, op_shr, op_comment, op_colon, + op_semic, op_here, op_imm, op_const, op_depth, + op_key, op_exit, op_tick, op_execute, op_jmp, + op_jmp0, op_lit, op_literal, + op_jump + }; + + return index >= 0 && index < WordCount ? ops[index] : nullptr; } void CoreWords::op_drop(State& state) @@ -197,13 +172,37 @@ void CoreWords::op_colon(State& state) { state.pushr(state.dict.alignhere()); state.dict.addDefinition(word); } +} +void CoreWords::op_tick(State& state) { + Word word = state.dict.input(); + while (word.size() == 0) { + state.input(state); + word = state.dict.input(); + } + + Cell xt = 0; + if (auto i = CoreWords::findi(state, word); i >= 0) { + xt = i & ~CoreWords::Compiletime; + } else if (auto j = state.dict.find(word); j > 0) { + xt = state.dict.getexec(j) - sizeof(Cell); + } + + state.push(xt); +} + +void CoreWords::op_execute(State& state) { + state.execute(state.pop()); +} + +void CoreWords::op_exit(State& state) { + state.ip = state.popr(); } void CoreWords::op_semic(State& state) { - if (!state.compiling()) { - state.ip = state.popr(); - } else { + if (state.compiling()) { + state.dict.add(findi("exit")); + auto begin = state.popr(); state.dict.write(begin, @@ -213,7 +212,6 @@ void CoreWords::op_semic(State& state) { state.dict.latest = begin; state.compiling(false); } - } void CoreWords::op_here(State& state) { @@ -228,71 +226,50 @@ void CoreWords::op_imm(State& state) void CoreWords::op_const(State& state) { - if (state.compiling()) { - Word word = state.dict.input(); - while (word.size() == 0) { - state.input(state); - word = state.dict.input(); - } - - state.pushr(state.dict.alignhere()); - state.dict.addDefinition(word); - state.dict.add(CoreWords::HiddenWordLiteral); - state.dict.add(state.pop()); - state.dict.add(25 | CoreImmediate); - op_semic(state); - state.compiling(false); + Word word = state.dict.input(); + while (word.size() == 0) { + state.input(state); + word = state.dict.input(); } + state.pushr(state.dict.alignhere()); + state.dict.addDefinition(word); + state.dict.add(findi("_lit")); + state.dict.add(state.pop()); + op_semic(state); } -void CoreWords::op_literal(State& state) +void CoreWords::op_lit(State& state) { state.push(state.beyondip()); state.ip += sizeof(Cell); } -void CoreWords::op_jump(State& state) -{ - state.pushr(state.ip + sizeof(Cell)); - state.ip = state.beyondip() - sizeof(Cell); -} - -void CoreWords::op_if(State& state) +void CoreWords::op_literal(State& state) { if (state.compiling()) { - state.push(state.dict.here); - state.dict.add(0); - } else { - if (state.pop()) - state.ip += sizeof(Cell); - else - state.ip = state.beyondip() - sizeof(Cell); + state.dict.add(findi("_lit")); + state.dict.add(state.pop()); } - } -void CoreWords::op_then(State& state) +void CoreWords::op_jump(State& state) { - if (state.compiling()) { - const auto ifaddr = state.pop(); - if (state.dict.read(ifaddr) == 0) - state.dict.write(ifaddr, state.dict.here); - } - + state.pushr(state.ip + sizeof(Cell)); + state.ip = state.beyondip() - sizeof(Cell); } -void CoreWords::op_else(State& state) +void CoreWords::op_jmp(State& state) { - if (state.compiling()) { - const auto ifaddr = state.pop(); - state.push(state.dict.here); - state.dict.add(0); - state.dict.write(ifaddr, state.dict.here); - } else { - state.ip = state.beyondip() - sizeof(Cell); - } + state.ip = state.beyondip() - sizeof(Cell); +} +void CoreWords::op_jmp0(State& state) +{ + if (state.pop()) + state.ip += sizeof(Cell); + else + op_jmp(state); } void CoreWords::op_depth(State& state) @@ -314,6 +291,26 @@ void CoreWords::op_key(State& state) state.push(val); } +int CoreWords::findi(std::string_view word) +{ + std::size_t i; + int wordsi = 0; + + std::string_view words (wordsarr, sizeof(wordsarr)); + + for (i = 0; i < words.size();) { + const auto end = words.find_first_of({"\0\1", 2}, i); + + if (word == words.substr(i, end - i)) + return words[end] == '\0' ? wordsi : (wordsi | Compiletime); + + ++wordsi; + i = end + 1; + } + + return -1; +} + int CoreWords::findi(State& state, Word word) { std::size_t i; @@ -325,7 +322,7 @@ int CoreWords::findi(State& state, Word word) const auto end = words.find_first_of({"\0\1", 2}, i); if (state.dict.equal(word, words.substr(i, end - i))) - return words[end] == '\0' ? wordsi : (wordsi | CoreImmediate); + return words[end] == '\0' ? wordsi : (wordsi | Compiletime); ++wordsi; i = end + 1; @@ -337,12 +334,12 @@ int CoreWords::findi(State& state, Word word) Func CoreWords::find(State& state, Word word) { const auto i = findi(state, word); - return i >= 0 ? get(i & ~CoreWords::CoreImmediate) : nullptr; + return i >= 0 ? get(i & ~Compiletime) : nullptr; } void CoreWords::run(int i, State& state) { - i &= ~CoreWords::CoreImmediate; + i &= ~Compiletime; if (i >= 0 && i < WordCount) get(i)(state); |