]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
corewords get their own functions
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 17 Nov 2023 22:15:04 +0000 (17:15 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 17 Nov 2023 22:15:04 +0000 (17:15 -0500)
libalee/corewords.cpp
libalee/corewords.hpp

index 7c79aea4e2e1a6ef133161da2f7431c6944bd1da..d47e0929408b7c64c82ac40ca8e09e4b14a80fac 100644 (file)
@@ -27,9 +27,6 @@ static void pushd(State&, DoubleCell);
 LIBALEE_SECTION
 void CoreWords::run(Cell ins, State& state)
 {
-    Cell cell;
-    DoubleCell dcell;
-
     Addr index = ins;
     auto& ip = state.ip();
 
@@ -40,191 +37,46 @@ execute:
         ip = index;
         return;
     } else switch (index) {
-    case token("_lit"): // Execution semantics of `literal`.
-        state.push(state.beyondip());
-        break;
-    case token("drop"):
-        state.pop();
-        break;
-    case token("dup"):
-        state.push(state.top());
-        break;
-    case token("swap"):
-        std::swap(state.top(), state.pick(1));
-        break;
-    case token("pick"):
-        state.push(state.pick(state.pop()));
-        break;
-    case token("sys"): // Calls user-defined "system" handler.
-        user_sys(state);
-        break;
-    case token("+"):
-        cell = state.pop();
-        state.top() += cell;
-        break;
-    case token("-"):
-        cell = state.pop();
-        state.top() -= cell;
-        break;
-    case token("m*"): // ( n n -- d )
-        cell = state.pop();
-        dcell = state.pop() * cell;
-        pushd(state, dcell);
-        break;
-    case token("_/"): // ( d n -- n )
-        cell = state.pop();
-        dcell = popd(state);
-        state.push(static_cast<Cell>(dcell / cell));
-        break;
-    case token("_%"): // ( d n -- n )
-        cell = state.pop();
-        dcell = popd(state);
-        state.push(static_cast<Cell>(dcell % cell));
-        break;
-    case token("_@"): // ( addr cell? -- n )
-        if (state.pop())
-            state.push(state.dict.read(state.pop()));
-        else
-            state.push(state.dict.readbyte(state.pop()));
-        break;
-    case token("_!"): // ( n addr cell? -- )
-        cell = state.pop();
-        if (auto addr = state.pop(); cell)
-            state.dict.write(addr, state.pop());
-        else
-            state.dict.writebyte(addr, state.pop() & 0xFFu);
-        break;
-    case token(">r"):
-        state.pushr(state.pop());
-        break;
-    case token("r>"):
-        state.push(state.popr());
-        break;
-    case token("="):
-        cell = state.pop();
-        state.top() = state.top() == cell ? -1 : 0;
-        break;
-    case token("<"):
-        cell = state.pop();
-        state.top() = state.top() < cell ? -1 : 0;
-        break;
-    case token("&"):
-        cell = state.pop();
-        state.top() &= cell;
-        break;
-    case token("|"):
-        cell = state.pop();
-        state.top() |= cell;
-        break;
-    case token("^"):
-        cell = state.pop();
-        state.top() ^= cell;
-        break;
-    case token("<<"):
-        cell = state.pop();
-        reinterpret_cast<Addr&>(state.top()) <<= static_cast<Addr>(cell);
-        break;
-    case token(">>"):
-        cell = state.pop();
-        reinterpret_cast<Addr&>(state.top()) >>= static_cast<Addr>(cell);
-        break;
-    case token(":"): // Begins definition/compilation of new word.
-        state.push(state.dict.alignhere());
-        state.dict.write(Dictionary::CompToken, state.top());
-        while (!state.dict.hasInput())
-            state.input();
-        state.dict.addDefinition(state.dict.input());
-        state.compiling(true);
-        break;
-    case token("_'"): // Collects input word and finds execution token.
-        while (!state.dict.hasInput())
-            state.input();
-        find(state, state.dict.input());
-        break;
+    case token("_lit"): word_lit(state); break;// Execution semantics of `literal`.
+    case token("drop"): word_drop(state); break;
+    case token("dup"): word_dup(state); break;
+    case token("swap"): word_swap(state); break;
+    case token("pick"): word_pick(state); break;
+    case token("sys"): word_sys(state); break; // Calls user-defined "system" handler.
+    case token("+"): word_add(state); break;
+    case token("-"): word_sub(state); break;
+    case token("m*"): word_mul(state); break; // ( n n -- d )
+    case token("_/"): word_div(state); break; // ( d n -- n )
+    case token("_%"): word_mod(state); break; // ( d n -- n )
+    case token("_@"): word_peek(state); break; // ( addr cell? -- n )
+    case token("_!"): word_poke(state); break; // ( n addr cell? -- )
+    case token(">r"): word_rpush(state); break;
+    case token("r>"): word_rpop(state); break;
+    case token("="): word_eq(state); break;
+    case token("<"): word_lt(state); break;
+    case token("&"): word_and(state); break;
+    case token("|"): word_or(state); break;
+    case token("^"): word_xor(state); break;
+    case token("<<"): word_shl(state); break;
+    case token(">>"): word_shr(state); break;
+    case token(":"): word_colon(state); break; // Begins definition/compilation of new word.
+    case token("_'"): word_tick(state); break; // Collects input word and finds execution token.
     case token("execute"):
+        // TODO reimplement
         index = state.pop();
         goto execute;
-    case token("exit"):
-        ip = state.popr();
-        state.verify(ip != 0, Error::exit);
-        break;
-    case token(";"): // Concludes word definition.
-        state.dict.add(token("exit"));
-        state.compiling(false);
-
-        cell = state.pop();
-        dcell = cell - state.dict.latest();
-        if (dcell >= Dictionary::MaxDistance) {
-            // Large distance to previous entry: store in dedicated cell.
-            state.dict.write(static_cast<Addr>(cell) + sizeof(Cell),
-                static_cast<Cell>(dcell));
-            dcell = Dictionary::MaxDistance;
-        }
-        state.dict.write(cell,
-            (state.dict.read(cell) & 0x1F) | static_cast<Cell>(dcell << 6));
-        state.dict.latest(cell);
-        break;
-    case token("_jmp0"): // Jump if popped value equals zero.
-        if (state.pop()) {
-            state.beyondip();
-            break;
-        }
-        [[fallthrough]];
-    case token("_jmp"): // Unconditional jump.
-        ip = state.beyondip();
-        return;
-    case token("depth"):
-        state.push(static_cast<Cell>(state.size()));
-        break;
-    case token("_rdepth"):
-        state.push(static_cast<Cell>(state.rsize()));
-        break;
-    case token("_in"): // Fetches more input from the user input source.
-        state.input();
-        break;
-    case token("_ev"): // Evaluates words from current input source.
-        {
-        const auto st = state.save();
-        ip = 0;
-        Parser::parseSource(state);
-        state.load(st);
-        }
-        break;
-    case token("find"):
-        cell = state.pop();
-        find(state,
-             Word::fromLength(static_cast<Addr>(cell + 1),
-                              state.dict.readbyte(cell)));
-        break;
-    case token("_uma"): // ( d u u -- d ): Unsigned multiply-add.
-        {
-        const auto plus = state.pop();
-        cell = state.pop();
-        dcell = popd(state);
-        dcell *= static_cast<Addr>(cell);
-        dcell += static_cast<Addr>(plus);
-        pushd(state, dcell);
-        }
-        break;
-    case token("u<"):
-        cell = state.pop();
-        state.top() = static_cast<Addr>(state.top()) <
-                      static_cast<Addr>(cell) ? -1 : 0;
-        break;
-    case token("um/mod"):
-        cell = state.pop();
-        dcell = popd(state);
-
-        state.push(static_cast<Cell>(
-            static_cast<DoubleAddr>(dcell) %
-            static_cast<Addr>(cell)));
-        state.push(static_cast<Cell>(
-            static_cast<DoubleAddr>(dcell) /
-            static_cast<Addr>(cell)));
-        break;
-    default: // Compacted literals (WordCount <= ins < Begin).
-        state.push(ins - WordCount);
-        break;
+    case token("exit"): word_exit(state); break;
+    case token(";"): word_semic(state); break; // Concludes word definition.
+    case token("_jmp0"): word_jmp0(state); break; // Jump if popped value equals zero.
+    case token("_jmp"): word_jmp(state); break; // Unconditional jump.
+    case token("depth"): word_depth(state); break;
+    case token("_rdepth"): word_rdepth(state); break;
+    case token("_in"): word_in(state); break; // Fetches more input from the user input source.
+    case token("_ev"): word_ev(state); break; // Evaluates words from current input source.
+    case token("find"): word_find(state); break;
+    case token("_uma"): word_uma(state); break; // ( d u u -- d ): Unsigned multiply-add.
+    case token("u<"): word_ult(state); break;
+    case token("um/mod"): word_ummod(state); break;
     }
 
     ip += sizeof(Cell);
@@ -267,3 +119,184 @@ void pushd(State& s, DoubleCell d)
     s.push(static_cast<Cell>(d >> (sizeof(Cell) * 8)));
 }
 
+void CoreWords::word_lit(State& state) { // Execution semantics of `literal`.
+    state.push(state.beyondip());
+}
+void CoreWords::word_drop(State& state) {
+    state.pop();
+}
+void CoreWords::word_dup(State& state) {
+    state.push(state.top());
+}
+void CoreWords::word_swap(State& state) {
+    std::swap(state.top(), state.pick(1));
+}
+void CoreWords::word_pick(State& state) {
+    state.push(state.pick(state.pop()));
+}
+void CoreWords::word_sys(State& state) { // Calls user-defined "system" handler.
+    user_sys(state);
+}
+void CoreWords::word_add(State& state) {
+    auto cell = state.pop();
+    state.top() += cell;
+}
+void CoreWords::word_sub(State& state) {
+    auto cell = state.pop();
+    state.top() -= cell;
+}
+void CoreWords::word_mul(State& state) { // ( n n -- d )
+    auto cell = state.pop();
+    auto dcell = state.pop() * cell;
+    pushd(state, dcell);
+}
+void CoreWords::word_div(State& state) { // ( d n -- n )
+    auto cell = state.pop();
+    auto dcell = popd(state);
+    state.push(static_cast<Cell>(dcell / cell));
+}
+void CoreWords::word_mod(State& state) { // ( d n -- n )
+    auto cell = state.pop();
+    auto dcell = popd(state);
+    state.push(static_cast<Cell>(dcell % cell));
+}
+void CoreWords::word_peek(State& state) { // ( addr cell? -- n )
+    if (state.pop())
+        state.push(state.dict.read(state.pop()));
+    else
+        state.push(state.dict.readbyte(state.pop()));
+}
+void CoreWords::word_poke(State& state) { // ( n addr cell? -- )
+    auto cell = state.pop();
+    if (auto addr = state.pop(); cell)
+        state.dict.write(addr, state.pop());
+    else
+        state.dict.writebyte(addr, state.pop() & 0xFFu);
+}
+void CoreWords::word_rpush(State& state) {
+    state.pushr(state.pop());
+}
+void CoreWords::word_rpop(State& state) {
+    state.push(state.popr());
+}
+void CoreWords::word_eq(State& state) {
+    auto cell = state.pop();
+    state.top() = state.top() == cell ? -1 : 0;
+}
+void CoreWords::word_lt(State& state) {
+    auto cell = state.pop();
+    state.top() = state.top() < cell ? -1 : 0;
+}
+void CoreWords::word_and(State& state) {
+    auto cell = state.pop();
+    state.top() &= cell;
+}
+void CoreWords::word_or(State& state) {
+    auto cell = state.pop();
+    state.top() |= cell;
+}
+void CoreWords::word_xor(State& state) {
+    auto cell = state.pop();
+    state.top() ^= cell;
+}
+void CoreWords::word_shl(State& state) {
+    auto cell = state.pop();
+    reinterpret_cast<Addr&>(state.top()) <<= static_cast<Addr>(cell);
+}
+void CoreWords::word_shr(State& state) {
+    auto cell = state.pop();
+    reinterpret_cast<Addr&>(state.top()) >>= static_cast<Addr>(cell);
+}
+void CoreWords::word_colon(State& state) { // Begins definition/compilation of new word.
+    state.push(state.dict.alignhere());
+    state.dict.write(Dictionary::CompToken, state.top());
+    while (!state.dict.hasInput())
+        state.input();
+    state.dict.addDefinition(state.dict.input());
+    state.compiling(true);
+}
+void CoreWords::word_tick(State& state) { // Collects input word and finds execution token.
+    while (!state.dict.hasInput())
+        state.input();
+    find(state, state.dict.input());
+}
+void CoreWords::word_execute(State& state) {
+    /*index =*/ state.pop();
+    /* TODO goto execute; */
+}
+void CoreWords::word_exit(State& state) {
+    state.ip() = state.popr();
+    state.verify(state.ip() != 0, Error::exit);
+}
+void CoreWords::word_semic(State& state) { // Concludes word definition.
+    state.dict.add(token("exit"));
+    state.compiling(false);
+
+    auto cell = state.pop();
+    auto dcell = cell - state.dict.latest();
+    if (dcell >= Dictionary::MaxDistance) {
+        // Large distance to previous entry: store in dedicated cell.
+        state.dict.write(static_cast<Addr>(cell) + sizeof(Cell),
+            static_cast<Cell>(dcell));
+        dcell = Dictionary::MaxDistance;
+    }
+    state.dict.write(cell,
+        (state.dict.read(cell) & 0x1F) | static_cast<Cell>(dcell << 6));
+    state.dict.latest(cell);
+}
+void CoreWords::word_jmp0(State& state) { // Jump if popped value equals zero.
+    if (state.pop()) {
+        state.beyondip();
+    } else {
+        state.ip() = static_cast<Addr>(state.beyondip() - sizeof(Cell));
+    }
+}
+void CoreWords::word_jmp(State& state) { // Unconditional jump.
+    state.ip() = static_cast<Addr>(state.beyondip() - sizeof(Cell));
+}
+void CoreWords::word_depth(State& state) {
+    state.push(static_cast<Cell>(state.size()));
+}
+void CoreWords::word_rdepth(State& state) {
+    state.push(static_cast<Cell>(state.rsize()));
+}
+void CoreWords::word_in(State& state) { // Fetches more input from the user input source.
+    state.input();
+}
+void CoreWords::word_ev(State& state) { // Evaluates words from current input source.
+    const auto st = state.save();
+    state.ip() = 0;
+    Parser::parseSource(state);
+    state.load(st);
+}
+void CoreWords::word_find(State& state) {
+    auto cell = state.pop();
+    find(state,
+         Word::fromLength(static_cast<Addr>(cell + 1),
+                          state.dict.readbyte(cell)));
+}
+void CoreWords::word_uma(State& state) { // ( d u u -- d ): Unsigned multiply-add.
+    const auto plus = state.pop();
+    auto cell = state.pop();
+    auto dcell = popd(state);
+    dcell *= static_cast<Addr>(cell);
+    dcell += static_cast<Addr>(plus);
+    pushd(state, dcell);
+}
+void CoreWords::word_ult(State& state) {
+    auto cell = state.pop();
+    state.top() = static_cast<Addr>(state.top()) <
+                  static_cast<Addr>(cell) ? -1 : 0;
+}
+void CoreWords::word_ummod(State& state) {
+    auto cell = state.pop();
+    auto dcell = popd(state);
+
+    state.push(static_cast<Cell>(
+        static_cast<DoubleAddr>(dcell) %
+        static_cast<Addr>(cell)));
+    state.push(static_cast<Cell>(
+        static_cast<DoubleAddr>(dcell) /
+        static_cast<Addr>(cell)));
+}
+
index 30d0a42d10b500d791588a786a8c50fe9369bf5f..959d2e86ebb2b2f1d02b4285ace66af4906d167d 100644 (file)
@@ -113,6 +113,44 @@ private:
 
         return -1;
     }
+
+    static void word_lit(State&);
+    static void word_drop(State&);
+    static void word_dup(State&);
+    static void word_swap(State&);
+    static void word_pick(State&);
+    static void word_sys(State&);
+    static void word_add(State&);
+    static void word_sub(State&);
+    static void word_mul(State&);
+    static void word_div(State&);
+    static void word_mod(State&);
+    static void word_peek(State&);
+    static void word_poke(State&);
+    static void word_rpush(State&);
+    static void word_rpop(State&);
+    static void word_eq(State&);
+    static void word_lt(State&);
+    static void word_and(State&);
+    static void word_or(State&);
+    static void word_xor(State&);
+    static void word_shl(State&);
+    static void word_shr(State&);
+    static void word_colon(State&);
+    static void word_tick(State&);
+    static void word_execute(State&);
+    static void word_exit(State&);
+    static void word_semic(State&);
+    static void word_jmp0(State&);
+    static void word_jmp(State&);
+    static void word_depth(State&);
+    static void word_rdepth(State&);
+    static void word_in(State&);
+    static void word_ev(State&);
+    static void word_find(State&);
+    static void word_uma(State&);
+    static void word_ult(State&);
+    static void word_ummod(State&);
 };
 
 #endif // ALEEFORTH_COREWORDS_HPP