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 \
-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

@ -25,23 +25,10 @@
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);
}
}

@ -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 {};
auto len = read(Dictionary::Input);
if (len != 0) {
Addr wordstart = Dictionary::Input + sizeof(Cell) + Dictionary::InputCells
- len;
Addr wordend = wordstart;
auto cnt = len;
while (cnt) {
while (len) {
auto b = readbyte(wordend);
if (isspace(b)) {
if (wordstart != wordend) {
Word word {wordstart, wordend};
writebyte(Dictionary::Input, cnt - 1);
return word;
} else {
++wordstart;
writebyte(Dictionary::Input, len - 1);
return {wordstart, wordend};
}
++wordstart;
}
++wordend;
--cnt;
--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;

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

@ -26,12 +26,14 @@
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

@ -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
#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

Loading…
Cancel
Save