]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
remove ParseStatus; reduce stack usage
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 24 Feb 2023 13:50:28 +0000 (08:50 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 24 Feb 2023 13:50:28 +0000 (08:50 -0500)
Makefile
alee.cpp
dictionary.cpp
parser.cpp
parser.hpp
types.cpp [deleted file]
types.hpp

index 4307ca03fe576bf049862ed77d7017e6198aa804..65dc7912d04b4b3af7317399b14f3ca15eb62844 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \
             -Wall -Wextra -pedantic -Wno-vla -Werror
 
-CXXFILES := corewords.cpp dictionary.cpp parser.cpp state.cpp types.cpp
+CXXFILES := corewords.cpp dictionary.cpp parser.cpp state.cpp
 OBJFILES := $(subst .cpp,.o,$(CXXFILES))
 LIBFILE := libalee.a
 EXEFILE := alee
index 6c2c1357a10f1326383865347b687fce04e547a9..41610e4ec83a1649bd76c9e58ba39a182e3f1cc0 100644 (file)
--- a/alee.cpp
+++ b/alee.cpp
 
 static bool okay = false;
 
+static void readchar(State& state);
 static void parseLine(Parser&, State&, std::string_view);
 static void parseFile(Parser&, State&, std::istream&);
 
-static void readchar(State& state)
-{
-    auto len = state.dict.read(Dictionary::Input);
-    Addr addr = Dictionary::Input + sizeof(Cell) +
-                Dictionary::InputCells - len - 1;
-
-    for (Addr i = 0; i < len; ++i, ++addr)
-        state.dict.writebyte(addr, state.dict.readbyte(addr + 1));
-
-    auto c = std::cin.get();
-    state.dict.writebyte(addr, c ? c : ' ');
-    state.dict.write(Dictionary::Input, len + 1);
-}
-
 int main(int argc, char *argv[])
 {
     MemDict dict;
@@ -65,6 +52,20 @@ int main(int argc, char *argv[])
     return 0;
 }
 
+static void readchar(State& state)
+{
+    auto len = state.dict.read(Dictionary::Input);
+    Addr addr = Dictionary::Input + sizeof(Cell) +
+                Dictionary::InputCells - len - 1;
+
+    for (Addr i = 0; i < len; ++i, ++addr)
+        state.dict.writebyte(addr, state.dict.readbyte(addr + 1));
+
+    auto c = std::cin.get();
+    state.dict.writebyte(addr, c ? c : ' ');
+    state.dict.write(Dictionary::Input, len + 1);
+}
+
 static void save(State& state)
 {
     std::ofstream file ("alee.dat", std::ios::binary);
@@ -106,13 +107,17 @@ void user_sys(State& state)
 
 void parseLine(Parser& parser, State& state, std::string_view line)
 {
-    auto r = parser.parse(state, line);
-
-    if (r == ParseStatus::Finished) {
+    if (auto r = parser.parse(state, line); r == 0) {
         if (okay)
             std::cout << (state.compiling() ? "compiled" : "ok") << std::endl;
     } else {
-        std::cout << to_string(r) << ": " << line << std::endl;
+        switch (r) {
+        case Parser::UnknownWord:
+            std::cout << "word not found in: " << line << std::endl;
+            break;
+        default:
+            break;
+        }
     }
 }
 
@@ -123,6 +128,7 @@ void parseFile(Parser& parser, State& state, std::istream& file)
         std::getline(file, line);
         if (line == "bye")
             exit(0);
+
         parseLine(parser, state, line);
     }
 }
index 1ac28396305a3d405f399f0b6482bf5141de7d70..cf04cb4e953ffd35c7b7a1531d5e456a4fe417fa 100644 (file)
@@ -50,8 +50,8 @@ Addr Dictionary::alignhere()
 void Dictionary::addDefinition(Word word)
 {
     add(word.size());
-    for (unsigned i = 0; i < word.size(); ++i)
-        writebyte(allot(1), readbyte(word.start + i));
+    for (auto w = word.start; w != word.end; ++w)
+        writebyte(allot(1), readbyte(w));
 
     alignhere();
 }
@@ -85,29 +85,27 @@ Addr Dictionary::getexec(Addr addr)
 
 Word Dictionary::input()
 {
-    const auto len = read(Dictionary::Input);
-    if (len == 0)
-        return {};
-
-    Addr wordstart = Dictionary::Input + sizeof(Cell) + Dictionary::InputCells
-                     - len;
-    Addr wordend = wordstart;
-
-    auto cnt = len;
-    while (cnt) {
-        auto b = readbyte(wordend);
-        if (isspace(b)) {
-            if (wordstart != wordend) {
-                Word word {wordstart, wordend};
-                writebyte(Dictionary::Input, cnt - 1);
-                return word;
-            } else {
+    auto len = read(Dictionary::Input);
+    if (len != 0) {
+        Addr wordstart = Dictionary::Input + sizeof(Cell) + Dictionary::InputCells
+                         - len;
+        Addr wordend = wordstart;
+
+        while (len) {
+            auto b = readbyte(wordend);
+
+            if (isspace(b)) {
+                if (wordstart != wordend) {
+                    writebyte(Dictionary::Input, len - 1);
+                    return {wordstart, wordend};
+                }
+
                 ++wordstart;
             }
-        }
 
-        ++wordend;
-        --cnt;
+            ++wordend;
+            --len;
+        }
     }
 
     return {};
@@ -115,12 +113,14 @@ Word Dictionary::input()
 
 bool Dictionary::equal(Word word, std::string_view sv) const
 {
-    if (sv.size() != static_cast<Addr>(word.end - word.start))
+    if (word.size() != sv.size())
         return false;
 
-    for (unsigned i = 0; i < sv.size(); ++i) {
-        if (sv[i] != readbyte(word.start + i))
+    for (auto w = word.start; w != word.end; ++w) {
+        if (readbyte(w) != sv.front())
             return false;
+
+        sv = sv.substr(1);
     }
 
     return true;
@@ -131,9 +131,12 @@ bool Dictionary::equal(Word word, Word other) const
     if (word.size() != other.size())
         return false;
 
-    for (unsigned i = 0; i < word.size(); ++i) {
-        if (readbyte(word.start + i) != readbyte(other.start + i))
+    auto w = word.start, o = other.start;
+    while (w != word.end) {
+        if (readbyte(w) != readbyte(o))
             return false;
+
+        ++w, ++o;
     }
 
     return true;
index 088323051f8d88a4a870e0545763f245ce2ca810..01dbb9048c10ea5afd86bcf23a6f4d08debbed03 100644 (file)
@@ -22,9 +22,7 @@
 #include <cctype>
 #include <cstdlib>
 
-#include <iostream>
-
-ParseStatus Parser::parse(State& state, std::string_view& str)
+int Parser::parse(State& state, std::string_view& str)
 {
     auto addr = Dictionary::Input;
     state.dict.write(addr, str.size() + 1);
@@ -37,20 +35,20 @@ ParseStatus Parser::parse(State& state, std::string_view& str)
     return parseSource(state);
 }
 
-ParseStatus Parser::parseSource(State& state)
+int Parser::parseSource(State& state)
 {
     auto word = state.dict.input();
     while (word.size() > 0) {
-        if (auto ret = parseWord(state, word); ret != ParseStatus::Finished)
+        if (auto ret = parseWord(state, word); ret)
             return ret;
 
         word = state.dict.input();
     }
 
-    return ParseStatus::Finished;
+    return 0;
 }
 
-ParseStatus Parser::parseWord(State& state, Word word)
+int Parser::parseWord(State& state, Word word)
 {
     int ins, imm;
 
@@ -79,21 +77,22 @@ ParseStatus Parser::parseWord(State& state, Word word)
         state.execute(ins);
     }
 
-    return ParseStatus::Finished;
+    return 0;
 }
 
-ParseStatus Parser::parseNumber(State& state, Word word)
+int Parser::parseNumber(State& state, Word word)
 {
-    char buf[word.size() + 1];
-    for (unsigned i = 0; i < word.size(); ++i)
+    char buf[MaxCellNumberChars + 1];
+    unsigned i;
+    for (i = 0; i < std::min(MaxCellNumberChars, word.size()); ++i)
         buf[i] = state.dict.readbyte(word.start + i);
-    buf[word.size()] = '\0';
+    buf[i] = '\0';
 
     char *p;
     const auto base = state.dict.read(0);
     const Cell l = std::strtol(buf, &p, base);
 
-    if (std::distance(buf, p) == word.size()) {
+    if (static_cast<Addr>(std::distance(buf, p)) == word.size()) {
         if (state.compiling()) {
             state.dict.add(CoreWords::findi("_lit"));
             state.dict.add(l);
@@ -101,10 +100,9 @@ ParseStatus Parser::parseNumber(State& state, Word word)
             state.push(l);
         }
 
-        return ParseStatus::Finished;
+        return 0;
     } else {
-        std::cout << "word not found: " << buf << std::endl;
-        return ParseStatus::NotAWord;
+        return UnknownWord;
     }
 }
 
index ccd5647dc6faff8349f0633659cf692e9105ff79..8a322e27d5aa2a9c1af8c44729c3784897853f30 100644 (file)
 class Parser
 {
 public:
-    ParseStatus parse(State&, std::string_view&);
+    constexpr static int UnknownWord = -1;
+
+    int parse(State&, std::string_view&);
 
 private:
-    ParseStatus parseSource(State&);
-    ParseStatus parseWord(State&, Word);
-    ParseStatus parseNumber(State&, Word);
+    int parseSource(State&);
+    int parseWord(State&, Word);
+    int parseNumber(State&, Word);
 };
 
 #endif // ALEEFORTH_PARSER_HPP
diff --git a/types.cpp b/types.cpp
deleted file mode 100644 (file)
index 6afe7e5..0000000
--- a/types.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Alee Forth: A portable and concise Forth implementation in modern C++.
- * Copyright (C) 2023  Clyne Sullivan <clyne@bitgloo.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "types.hpp"
-
-std::string_view to_string(ParseStatus ps)
-{
-    switch (ps) {
-    case ParseStatus::Finished: return "Finished";
-    case ParseStatus::NotAWord: return "Not a word";
-    default: return "???";
-    }
-}
-
index d4f1882b1e5775edf229e70bf5e753f96b09a904..b6391baa887d5729bb930acc22b93ebbc6699015 100644 (file)
--- a/types.hpp
+++ b/types.hpp
@@ -20,7 +20,6 @@
 #define ALEEFORTH_TYPES_HPP
 
 #include <cstdint>
-#include <string_view>
 
 struct State;
 
@@ -28,6 +27,8 @@ using Addr = uint16_t;
 using Cell = int16_t;
 using Func = void (*)(State&);
 
+constexpr unsigned int MaxCellNumberChars = 6; // -32768
+
 struct Word
 {
     Addr start = 0;
@@ -38,13 +39,5 @@ struct Word
     }
 };
 
-enum class ParseStatus
-{
-    Finished,
-    NotAWord
-};
-
-std::string_view to_string(ParseStatus);
-
 #endif // ALEEFORTH_TYPES_HPP