common error enum; eval to _ev

llvm
Clyne 2 years ago
parent f8270776e7
commit bc3e952b48

@ -66,14 +66,15 @@ int main()
serputs("\n\r");
if (auto r = Parser::parse(state, strbuf); r == 0) {
if (auto r = Parser::parse(state, strbuf); r == Error::none) {
serputs(state.compiling() ? " compiled" : " ok");
} else {
switch (r) {
case Parser::UnknownWord:
case Error::noword:
serputs("unknown word...");
break;
default:
serputs("error...");
break;
}
}

@ -79,7 +79,6 @@ static void load(State& state)
state.dict.writebyte(i++, file.get());
}
#include <cstring>
void user_sys(State& state)
{
char buf[32] = {0};
@ -107,55 +106,41 @@ void user_sys(State& state)
std::cout << buf << ' ';
}
break;
case 5: // eval
{
auto oldip = state.ip;
std::jmp_buf oldjb;
memcpy(oldjb, state.jmpbuf, sizeof(std::jmp_buf));
state.ip = 0;
Parser::parseSource(state);
memcpy(state.jmpbuf, oldjb, sizeof(std::jmp_buf));
state.ip = oldip;
}
default:
break;
}
}
void parseLine(State& state, const std::string& line)
{
if (auto r = Parser::parse(state, line.c_str()); r == 0) {
if (auto r = Parser::parse(state, line.c_str()); r == Error::none) {
if (okay)
std::cout << (state.compiling() ? "compiled" : "ok") << std::endl;
std::cout << (state.compiling() ? " compiled" : " ok") << std::endl;
} else {
switch (r) {
case Parser::UnknownWord:
case Error::noword:
std::cout << "word not found in: " << line << std::endl;
break;
case static_cast<int>(State::Error::push):
case Error::push:
std::cout << "stack overflow" << std::endl;
break;
case static_cast<int>(State::Error::pushr):
case Error::pushr:
std::cout << "return stack overflow" << std::endl;
break;
case static_cast<int>(State::Error::popr):
case Error::popr:
std::cout << "return stack underflow" << std::endl;
break;
case static_cast<int>(State::Error::pop):
case static_cast<int>(State::Error::top):
case static_cast<int>(State::Error::pick):
case Error::pop:
case Error::top:
case Error::pick:
std::cout << "stack underflow" << std::endl;
break;
default:
std::cout << "error: " << r << std::endl;
std::cout << "unknown error" << std::endl;
break;
}
while (state.size())
state.pop();
while (state.rsize())
state.popr();
state.dict.write(Dictionary::Compiling, 0);
state.ip = 0;
state.reset();
}
}

@ -26,7 +26,7 @@
static bool okay = false;
static void readchar(State& state);
static void readchar(State&);
static void parseLine(State&, const std::string&);
static void parseFile(State&, std::istream&);
@ -76,12 +76,10 @@ static void load(State& state)
{
std::ifstream file ("alee.dat", std::ios::binary);
Addr i = 0;
while (file.good())
state.dict.writebyte(i++, file.get());
for (Addr i = 0; file.good(); i++)
state.dict.writebyte(i, file.get());
}
#include <cstring>
void user_sys(State& state)
{
char buf[32] = {0};
@ -109,55 +107,41 @@ void user_sys(State& state)
std::cout << buf << ' ';
}
break;
case 5: // eval
{
auto oldip = state.ip;
std::jmp_buf oldjb;
memcpy(oldjb, state.jmpbuf, sizeof(std::jmp_buf));
state.ip = 0;
Parser::parseSource(state);
memcpy(state.jmpbuf, oldjb, sizeof(std::jmp_buf));
state.ip = oldip;
}
default:
break;
}
}
void parseLine(State& state, const std::string& line)
{
if (auto r = Parser::parse(state, line.c_str()); r == 0) {
if (auto r = Parser::parse(state, line.c_str()); r == Error::none) {
if (okay)
std::cout << (state.compiling() ? "compiled" : "ok") << std::endl;
std::cout << (state.compiling() ? " compiled" : " ok") << std::endl;
} else {
switch (r) {
case Parser::UnknownWord:
case Error::noword:
std::cout << "word not found in: " << line << std::endl;
break;
case static_cast<int>(State::Error::push):
case Error::push:
std::cout << "stack overflow" << std::endl;
break;
case static_cast<int>(State::Error::pushr):
case Error::pushr:
std::cout << "return stack overflow" << std::endl;
break;
case static_cast<int>(State::Error::popr):
case Error::popr:
std::cout << "return stack underflow" << std::endl;
break;
case static_cast<int>(State::Error::pop):
case static_cast<int>(State::Error::top):
case static_cast<int>(State::Error::pick):
case Error::pop:
case Error::top:
case Error::pick:
std::cout << "stack underflow" << std::endl;
break;
default:
std::cout << "error: " << r << std::endl;
std::cout << "unknown error" << std::endl;
break;
}
while (state.size())
state.pop();
while (state.rsize())
state.popr();
state.dict.write(Dictionary::Compiling, 0);
state.ip = 0;
state.reset();
}
}

@ -199,5 +199,5 @@
: :noname 0 , here ] ;
: evaluate _source @ >r _sourceu @ >r >in @ >r
0 >in ! _sourceu ! _source ! 5 sys
0 >in ! _sourceu ! _source ! _ev
r> >in ! r> _sourceu ! r> _source ! ;

@ -17,6 +17,7 @@
*/
#include "corewords.hpp"
#include "parser.hpp"
#include <cstring>
#include <utility>
@ -171,10 +172,8 @@ execute:
goto execute;
case 25: // exit
state.ip = state.popr();
if (state.ip == 0) {
std::longjmp(state.jmpbuf,
static_cast<int>(State::Error::exit));
}
if (state.ip == 0)
std::longjmp(state.jmpbuf, static_cast<int>(Error::exit));
break;
case 26: // semic
{
@ -206,6 +205,14 @@ execute:
case 31: // _in
state.input(state);
break;
case 32: // _ex
{
const auto st = state.save();
state.ip = 0;
Parser::parseSource(state);
state.load(st);
}
break;
default:
state.push(index - WordCount);
break;

@ -27,7 +27,7 @@ void user_sys(State&);
class CoreWords
{
public:
constexpr static std::size_t WordCount = 32;
constexpr static std::size_t WordCount = 33;
constexpr static Cell Immediate = (1 << 5);
@ -44,7 +44,7 @@ public:
"<\0&\0|\0^\0"
"<<\0>>\0:\0_'\0execute\0"
"exit\0;\0_jmp0\0_jmp\0"
"depth\0_rdepth\0_in\0";
"depth\0_rdepth\0_in\0_ev\0";
};
#endif // ALEEFORTH_COREWORDS_HPP

@ -22,7 +22,7 @@
#include <cstring>
int Parser::parse(State& state, const char *str)
Error Parser::parse(State& state, const char *str)
{
auto addr = Dictionary::Input;
state.dict.write(addr, 0);
@ -38,20 +38,20 @@ int Parser::parse(State& state, const char *str)
return parseSource(state);
}
int Parser::parseSource(State& state)
Error Parser::parseSource(State& state)
{
auto word = state.dict.input();
while (word.size() > 0) {
if (auto ret = parseWord(state, word); ret)
if (auto ret = parseWord(state, word); ret != Error::none)
return ret;
word = state.dict.input();
}
return 0;
return Error::none;
}
int Parser::parseWord(State& state, Word word)
Error Parser::parseWord(State& state, Word word)
{
int ins, imm;
@ -71,13 +71,13 @@ int Parser::parseWord(State& state, Word word)
if (state.compiling() && !imm)
state.dict.add(ins);
else if (auto stat = state.execute(ins); stat != State::Error::none)
return static_cast<int>(stat);
else if (auto stat = state.execute(ins); stat != Error::none)
return stat;
return 0;
return Error::none;
}
int Parser::parseNumber(State& state, Word word)
Error Parser::parseNumber(State& state, Word word)
{
const auto base = state.dict.read(Dictionary::Base);
DoubleCell result = 0;
@ -97,7 +97,7 @@ int Parser::parseNumber(State& state, Word word)
result *= base;
result += 10 + (c > 'a' ? c - 'a' : c - 'A');
} else {
return UnknownWord;
return Error::noword;
}
if (++i < word.wend)
@ -121,6 +121,6 @@ int Parser::parseNumber(State& state, Word word)
state.push(value);
}
return 0;
return Error::none;
}

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

@ -19,6 +19,7 @@
#include "corewords.hpp"
#include "state.hpp"
#include <cstring>
#include <iterator>
bool State::compiling() const
@ -31,11 +32,25 @@ void State::compiling(bool yes)
dict.write(Dictionary::Compiling, yes);
}
State::Error State::execute(Addr addr)
std::pair<Addr, std::jmp_buf> State::save()
{
auto stat = static_cast<State::Error>(setjmp(jmpbuf));
std::pair<Addr, std::jmp_buf> st;
st.first = ip;
std::memcpy(st.second, jmpbuf, sizeof(std::jmp_buf));
return st;
}
void State::load(const std::pair<Addr, std::jmp_buf>& st)
{
ip = st.first;
std::memcpy(jmpbuf, st.second, sizeof(std::jmp_buf));
}
Error State::execute(Addr addr)
{
auto stat = static_cast<Error>(setjmp(jmpbuf));
if (stat == State::Error::none) {
if (stat == Error::none) {
CoreWords::run(addr, *this);
if (ip >= Dictionary::Begin) {
@ -46,13 +61,24 @@ State::Error State::execute(Addr addr)
// addr was a CoreWord, all done now.
ip = 0;
}
} else if (stat == State::Error::exit) {
stat = State::Error::none;
} else if (stat == Error::exit) {
stat = Error::none;
}
return stat;
}
void State::reset()
{
while (size())
pop();
while (rsize())
popr();
dict.write(Dictionary::Compiling, 0);
ip = 0;
}
std::size_t State::size() const noexcept
{
return std::distance(dstack, static_cast<const Cell *>(dsp));

@ -24,6 +24,7 @@
#include <csetjmp>
#include <cstddef>
#include <tuple>
constexpr unsigned DataStackSize = 16;
constexpr unsigned ReturnStackSize = 16;
@ -31,17 +32,6 @@ constexpr unsigned ReturnStackSize = 16;
class State
{
public:
enum class Error : int {
none = 0,
push,
pop,
pushr,
popr,
top,
pick,
exit
};
Addr ip = 0;
Dictionary& dict;
void (*input)(State&);
@ -54,7 +44,11 @@ public:
bool compiling() const;
void compiling(bool);
std::pair<Addr, std::jmp_buf> save();
void load(const std::pair<Addr, std::jmp_buf>&);
Error execute(Addr);
void reset();
std::size_t size() const noexcept;
std::size_t rsize() const noexcept;

@ -32,6 +32,18 @@ using Func = void (*)(State&);
constexpr unsigned int MaxCellNumberChars = 6; // -32768
enum class Error : int {
none = 0,
push,
pop,
pushr,
popr,
top,
pick,
exit,
noword
};
struct Word
{
struct iterator;

Loading…
Cancel
Save