remove ParseStatus; reduce stack usage

llvm
Clyne 2 years ago
parent 81b2fa5d3c
commit dac0553eb5
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

@ -1,7 +1,7 @@
CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \ CXXFLAGS += -std=c++17 -g3 -ggdb -O0 \
-Wall -Wextra -pedantic -Wno-vla -Werror -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)) OBJFILES := $(subst .cpp,.o,$(CXXFILES))
LIBFILE := libalee.a LIBFILE := libalee.a
EXEFILE := alee EXEFILE := alee

@ -25,23 +25,10 @@
static bool okay = false; static bool okay = false;
static void readchar(State& state);
static void parseLine(Parser&, State&, std::string_view); static void parseLine(Parser&, State&, std::string_view);
static void parseFile(Parser&, State&, std::istream&); 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[]) int main(int argc, char *argv[])
{ {
MemDict dict; MemDict dict;
@ -65,6 +52,20 @@ int main(int argc, char *argv[])
return 0; 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) static void save(State& state)
{ {
std::ofstream file ("alee.dat", std::ios::binary); 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) void parseLine(Parser& parser, State& state, std::string_view line)
{ {
auto r = parser.parse(state, line); if (auto r = parser.parse(state, line); r == 0) {
if (r == ParseStatus::Finished) {
if (okay) if (okay)
std::cout << (state.compiling() ? "compiled" : "ok") << std::endl; std::cout << (state.compiling() ? "compiled" : "ok") << std::endl;
} else { } 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); std::getline(file, line);
if (line == "bye") if (line == "bye")
exit(0); exit(0);
parseLine(parser, state, line); parseLine(parser, state, line);
} }
} }

@ -50,8 +50,8 @@ Addr Dictionary::alignhere()
void Dictionary::addDefinition(Word word) void Dictionary::addDefinition(Word word)
{ {
add(word.size()); add(word.size());
for (unsigned i = 0; i < word.size(); ++i) for (auto w = word.start; w != word.end; ++w)
writebyte(allot(1), readbyte(word.start + i)); writebyte(allot(1), readbyte(w));
alignhere(); alignhere();
} }
@ -85,29 +85,27 @@ Addr Dictionary::getexec(Addr addr)
Word Dictionary::input() Word Dictionary::input()
{ {
const auto len = read(Dictionary::Input); auto len = read(Dictionary::Input);
if (len == 0) if (len != 0) {
return {};
Addr wordstart = Dictionary::Input + sizeof(Cell) + Dictionary::InputCells Addr wordstart = Dictionary::Input + sizeof(Cell) + Dictionary::InputCells
- len; - len;
Addr wordend = wordstart; Addr wordend = wordstart;
auto cnt = len; while (len) {
while (cnt) {
auto b = readbyte(wordend); auto b = readbyte(wordend);
if (isspace(b)) { if (isspace(b)) {
if (wordstart != wordend) { if (wordstart != wordend) {
Word word {wordstart, wordend}; writebyte(Dictionary::Input, len - 1);
writebyte(Dictionary::Input, cnt - 1); return {wordstart, wordend};
return word;
} else {
++wordstart;
} }
++wordstart;
} }
++wordend; ++wordend;
--cnt; --len;
}
} }
return {}; return {};
@ -115,12 +113,14 @@ Word Dictionary::input()
bool Dictionary::equal(Word word, std::string_view sv) const 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; return false;
for (unsigned i = 0; i < sv.size(); ++i) { for (auto w = word.start; w != word.end; ++w) {
if (sv[i] != readbyte(word.start + i)) if (readbyte(w) != sv.front())
return false; return false;
sv = sv.substr(1);
} }
return true; return true;
@ -131,9 +131,12 @@ bool Dictionary::equal(Word word, Word other) const
if (word.size() != other.size()) if (word.size() != other.size())
return false; return false;
for (unsigned i = 0; i < word.size(); ++i) { auto w = word.start, o = other.start;
if (readbyte(word.start + i) != readbyte(other.start + i)) while (w != word.end) {
if (readbyte(w) != readbyte(o))
return false; return false;
++w, ++o;
} }
return true; return true;

@ -22,9 +22,7 @@
#include <cctype> #include <cctype>
#include <cstdlib> #include <cstdlib>
#include <iostream> int Parser::parse(State& state, std::string_view& str)
ParseStatus Parser::parse(State& state, std::string_view& str)
{ {
auto addr = Dictionary::Input; auto addr = Dictionary::Input;
state.dict.write(addr, str.size() + 1); state.dict.write(addr, str.size() + 1);
@ -37,20 +35,20 @@ ParseStatus Parser::parse(State& state, std::string_view& str)
return parseSource(state); return parseSource(state);
} }
ParseStatus Parser::parseSource(State& state) int Parser::parseSource(State& state)
{ {
auto word = state.dict.input(); auto word = state.dict.input();
while (word.size() > 0) { while (word.size() > 0) {
if (auto ret = parseWord(state, word); ret != ParseStatus::Finished) if (auto ret = parseWord(state, word); ret)
return ret; return ret;
word = state.dict.input(); 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; int ins, imm;
@ -79,21 +77,22 @@ ParseStatus Parser::parseWord(State& state, Word word)
state.execute(ins); 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]; char buf[MaxCellNumberChars + 1];
for (unsigned i = 0; i < word.size(); ++i) unsigned i;
for (i = 0; i < std::min(MaxCellNumberChars, word.size()); ++i)
buf[i] = state.dict.readbyte(word.start + i); buf[i] = state.dict.readbyte(word.start + i);
buf[word.size()] = '\0'; buf[i] = '\0';
char *p; char *p;
const auto base = state.dict.read(0); const auto base = state.dict.read(0);
const Cell l = std::strtol(buf, &p, base); 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()) { if (state.compiling()) {
state.dict.add(CoreWords::findi("_lit")); state.dict.add(CoreWords::findi("_lit"));
state.dict.add(l); state.dict.add(l);
@ -101,10 +100,9 @@ ParseStatus Parser::parseNumber(State& state, Word word)
state.push(l); state.push(l);
} }
return ParseStatus::Finished; return 0;
} else { } else {
std::cout << "word not found: " << buf << std::endl; return UnknownWord;
return ParseStatus::NotAWord;
} }
} }

@ -26,12 +26,14 @@
class Parser class Parser
{ {
public: public:
ParseStatus parse(State&, std::string_view&); constexpr static int UnknownWord = -1;
int parse(State&, std::string_view&);
private: private:
ParseStatus parseSource(State&); int parseSource(State&);
ParseStatus parseWord(State&, Word); int parseWord(State&, Word);
ParseStatus parseNumber(State&, Word); int parseNumber(State&, Word);
}; };
#endif // ALEEFORTH_PARSER_HPP #endif // ALEEFORTH_PARSER_HPP

@ -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 "???";
}
}

@ -20,7 +20,6 @@
#define ALEEFORTH_TYPES_HPP #define ALEEFORTH_TYPES_HPP
#include <cstdint> #include <cstdint>
#include <string_view>
struct State; struct State;
@ -28,6 +27,8 @@ using Addr = uint16_t;
using Cell = int16_t; using Cell = int16_t;
using Func = void (*)(State&); using Func = void (*)(State&);
constexpr unsigned int MaxCellNumberChars = 6; // -32768
struct Word struct Word
{ {
Addr start = 0; Addr start = 0;
@ -38,13 +39,5 @@ struct Word
} }
}; };
enum class ParseStatus
{
Finished,
NotAWord
};
std::string_view to_string(ParseStatus);
#endif // ALEEFORTH_TYPES_HPP #endif // ALEEFORTH_TYPES_HPP

Loading…
Cancel
Save