common error enum; eval to _ev

llvm
Clyne 2 years ago
parent f8270776e7
commit bc3e952b48

@ -66,14 +66,15 @@ int main()
serputs("\n\r"); 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"); serputs(state.compiling() ? " compiled" : " ok");
} else { } else {
switch (r) { switch (r) {
case Parser::UnknownWord: case Error::noword:
serputs("unknown word..."); serputs("unknown word...");
break; break;
default: default:
serputs("error...");
break; break;
} }
} }

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

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

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

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

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

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

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

@ -19,6 +19,7 @@
#include "corewords.hpp" #include "corewords.hpp"
#include "state.hpp" #include "state.hpp"
#include <cstring>
#include <iterator> #include <iterator>
bool State::compiling() const bool State::compiling() const
@ -31,11 +32,25 @@ void State::compiling(bool yes)
dict.write(Dictionary::Compiling, 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); CoreWords::run(addr, *this);
if (ip >= Dictionary::Begin) { if (ip >= Dictionary::Begin) {
@ -46,13 +61,24 @@ State::Error State::execute(Addr addr)
// addr was a CoreWord, all done now. // addr was a CoreWord, all done now.
ip = 0; ip = 0;
} }
} else if (stat == State::Error::exit) { } else if (stat == Error::exit) {
stat = State::Error::none; stat = Error::none;
} }
return stat; 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 std::size_t State::size() const noexcept
{ {
return std::distance(dstack, static_cast<const Cell *>(dsp)); return std::distance(dstack, static_cast<const Cell *>(dsp));

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

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

Loading…
Cancel
Save