]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
implement if and then
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 10 Feb 2023 01:15:16 +0000 (20:15 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 10 Feb 2023 01:15:16 +0000 (20:15 -0500)
alee.cpp
corewords.cpp
corewords.hpp
dictionary.cpp
parser.cpp

index f87831fb16e6d2e86665269b4d7df8cc7a9625fa..be717309d184e0daf1a0ea0055c69060441d49f6 100644 (file)
--- a/alee.cpp
+++ b/alee.cpp
@@ -23,6 +23,8 @@
 #include <iostream>
 #include <vector>
 
+static bool okay = false;
+
 static void parseLine(Parser&, State&, std::string_view);
 static void parseFile(Parser&, State&, std::istream&);
 
@@ -38,6 +40,7 @@ int main(int argc, char *argv[])
         parseFile(parser, state, file);
     }
 
+    okay = true;
     //std::cout << state.size() << ' ' << state.compiling << "> ";
     parseFile(parser, state, std::cin);
 
@@ -65,8 +68,12 @@ void parseLine(Parser& parser, State& state, std::string_view line)
         r = parser.parse(state, line);
     } while (r == ParseStatus::Continue);
 
-    if (r != ParseStatus::Finished)
+    if (r == ParseStatus::Finished) {
+        if (okay)
+            std::cout << " ok" << std::endl;
+    } else {
         std::cout << to_string(r) << ": " << line << std::endl;
+    }
 }
 
 void parseFile(Parser& parser, State& state, std::istream& file)
index 8fbcfbd669377c3db82da003b4b22308fe89e5fa..6aac65eb75adaa1107ea958a8ab518fcb8327ccf 100644 (file)
@@ -48,11 +48,12 @@ Func CoreWords::get(int index)
     case 24: return op_colon;
     case 25: return op_semic;
     case 26: return op_here;
-    case 27: return op_exit;
-    case 28: return op_imm;
-    case 29: return op_const;
-    case 30: return op_literal;
-    case 31: return op_jump;
+    case 27: return op_imm;
+    case 28: return op_const;
+    case 29: return op_if;
+    case 30: return op_then;
+    case 31: return op_literal;
+    case 32: return op_jump;
     default: return nullptr;
     }
 }
@@ -225,12 +226,6 @@ int CoreWords::op_here(State& state) {
     return 0;
 }
 
-int CoreWords::op_exit(State& state)
-{
-    state.ip = state.popr();
-    return 0;
-}
-
 int CoreWords::op_imm(State& state)
 {
     state.dict.write(state.dict.latest,
@@ -259,6 +254,31 @@ int CoreWords::op_jump(State& state)
     return 0;
 }
 
+int CoreWords::op_if(State& state)
+{
+    if (state.compiling) {
+        state.push(state.dict.here);
+        state.dict.add(0);
+    } else {
+        if (state.pop())
+            ++state.ip;
+        else
+            state.ip = state.beyondip() - 1;
+    }
+
+    return 0;
+}
+
+int CoreWords::op_then(State& state)
+{
+    if (state.compiling) {
+        const auto ifaddr = state.pop();
+        state.dict.write(ifaddr, state.dict.here);
+    }
+
+    return 0;
+}
+
 int CoreWords::findi(std::string_view str)
 {
     std::size_t i;
@@ -267,26 +287,28 @@ int CoreWords::findi(std::string_view str)
     std::string_view words (wordsarr, sizeof(wordsarr));
 
     for (i = 0; i < words.size();) {
-        const auto end = words.find('\0', i);
+        const auto end = words.find_first_of({"\0\1", 2}, i);
 
         if (words.compare(i, end - i, str) == 0)
-            break;
+            return words[end] == '\0' ? wordsi : (wordsi | CoreImmediate);
 
         ++wordsi;
         i = end + 1;
     }
 
-    return wordsi < VisibleWordCount ? wordsi : -1;
+    return -1;
 }
 
 Func CoreWords::find(std::string_view str)
 {
     const auto i = findi(str);
-    return i >= 0 ? get(i) : nullptr;
+    return i >= 0 ? get(i & ~CoreWords::CoreImmediate) : nullptr;
 }
 
 void CoreWords::run(int i, State& state)
 {
+    i &= ~CoreWords::CoreImmediate;
+
     if (i >= 0 && i < WordCount)
         get(i)(state);
 }
index 54e02f19d2708ddd9e5115120d1a3b419bc5b9ef..7edc1398762c798b0a6a1ddf5bef6c6f3b151e64 100644 (file)
@@ -27,12 +27,13 @@ int user_sys(State&);
 class CoreWords
 {
 public:
-    constexpr static std::size_t VisibleWordCount = 30;  // size
-    constexpr static std::size_t HiddenWordLiteral = 30; // index
-    constexpr static std::size_t HiddenWordJump = 31;    // index
-    constexpr static std::size_t WordCount = 32;         // size
+    constexpr static std::size_t VisibleWordCount = 31;             // size
+    constexpr static auto HiddenWordLiteral = VisibleWordCount;     // index
+    constexpr static auto HiddenWordJump    = VisibleWordCount + 1; // index
+    constexpr static auto WordCount         = HiddenWordJump + 1;   // size
 
-    constexpr static Cell Immediate = (1 << 5);
+    constexpr static Cell Immediate     = (1 << 5);
+    constexpr static Cell CoreImmediate = (1 << 6);
 
     static int findi(std::string_view);
     static Func find(std::string_view);
@@ -45,8 +46,8 @@ private:
         "@\0!\0rot\0>r\0r>\0"
         "=\0<\0allot\0&\0|\0"
         "^\0<<\0>>\0(\0:\0"
-        ";\0here\0exit\0imm\0const\0";
-    // lit, jmp, jmp0, ', lits
+        ";\1here\0imm\0const\0"
+       "if\1then\1";
 
     static Func get(int);
 
@@ -77,11 +78,12 @@ private:
     static int op_colon(State&);
     static int op_semic(State&);
     static int op_here(State&);
-    static int op_exit(State&);
     static int op_imm(State&);
     static int op_const(State&);
     static int op_literal(State&);
     static int op_jump(State&);
+    static int op_if(State&);
+    static int op_then(State&);
 };
 
 #endif // ALEEFORTH_COREWORDS_HPP
index dced709a4ea79f3c33fe4c075b503144d48cb784..e1165d2c075e9340c6c9c3e28cd8a98637a8c0b0 100644 (file)
@@ -35,9 +35,6 @@ void Dictionary::addDefinition(std::string_view str)
     add(str.size());
     for (char c : str)
         add(c);
-
-    if (here & 1)
-        allot(1);
 }
 
 bool Dictionary::issame(Addr addr, std::string_view str, std::size_t n)
@@ -75,6 +72,6 @@ Addr Dictionary::find(std::string_view str)
 Addr Dictionary::getexec(Addr addr)
 {
     const auto len = read(addr) & 0x1F;
-    return ((addr + 1 + len) + 1) & ~1;
+    return addr + 1 + len;
 }
 
index 99cbc8b46b03df46bdabb675cc8a3b1842aa8819..19ef34a267e9f02b716888a7bd7b5fa465d01a43 100644 (file)
@@ -39,7 +39,7 @@ 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:
@@ -57,9 +57,9 @@ ParseStatus Parser::parse(State& state, std::string_view& str)
     } else {
         if (auto i = CoreWords::findi(sub); i >= 0) {
             if (state.compiling)
-                state.dict.add(i);
-            if (!state.compiling || sub.front() == ';')
-                CoreWords::run(i, state);
+                state.dict.add(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);