108 lines
2.1 KiB
C++
108 lines
2.1 KiB
C++
#include "io.h"
|
|
#include "parser.h"
|
|
#include "stack.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#ifdef __linux__
|
|
#include "linux.h"
|
|
#endif // __linux__
|
|
|
|
static char ok[] = "ok.\n";
|
|
static char bye[] = "bye";
|
|
|
|
// dstack is the data stack.
|
|
static Stack<KF_INT> dstack;
|
|
|
|
|
|
static void
|
|
write_dstack(IO &interface)
|
|
{
|
|
KF_INT tmp;
|
|
interface.wrch('<');
|
|
for (size_t i = 0; i < dstack.size(); i++) {
|
|
if (i > 0) {
|
|
interface.wrch(' ');
|
|
}
|
|
|
|
dstack.get(i, tmp);
|
|
write_num(interface, tmp);
|
|
}
|
|
interface.wrch('>');
|
|
}
|
|
|
|
static bool
|
|
parser(IO &interface, const char *buf, const size_t buflen)
|
|
{
|
|
static size_t offset = 0;
|
|
static struct Token token;
|
|
static PARSE_RESULT result = PARSE_FAIL;
|
|
|
|
offset = 0;
|
|
|
|
// reset token
|
|
token.token = nullptr;
|
|
token.length = 0;
|
|
|
|
while ((result = parse_next(buf, buflen, &offset, &token)) == PARSE_OK) {
|
|
interface.wrbuf((char *)"token: ", 7);
|
|
interface.wrbuf(token.token, token.length);
|
|
interface.wrln((char *)".", 1);
|
|
|
|
if (!parse_num(&token, dstack)) {
|
|
interface.wrln((char *)"failed to parse numeric", 23);
|
|
}
|
|
|
|
// Temporary hack until the interpreter is working further.
|
|
if (match_token(token.token, token.length, bye, 3)) {
|
|
interface.wrln((char *)"Goodbye!", 8);
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
switch (result) {
|
|
case PARSE_EOB:
|
|
interface.wrbuf(ok, 4);
|
|
return true;
|
|
case PARSE_LEN:
|
|
interface.wrln((char *)"parse error: token too long", 27);
|
|
return false;
|
|
case PARSE_FAIL:
|
|
interface.wrln((char *)"parser failure", 14);
|
|
return false;
|
|
default:
|
|
interface.wrln((char *)"*** the world is broken ***", 27);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
static void
|
|
interpreter(IO &interface)
|
|
{
|
|
static size_t buflen = 0;
|
|
static char linebuf[81];
|
|
|
|
while (true) {
|
|
write_dstack(interface);
|
|
interface.wrch('\n');
|
|
interface.wrch('?');
|
|
interface.wrch(' ');
|
|
buflen = interface.rdbuf(linebuf, 80, true, '\n');
|
|
parser(interface, linebuf, buflen);
|
|
}
|
|
}
|
|
|
|
static char banner[] = "kforth interpreter\n";
|
|
const size_t bannerlen = 19;
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
#ifdef __linux__
|
|
Console interface;
|
|
#endif
|
|
interface.wrbuf(banner, bannerlen);
|
|
interpreter(interface);
|
|
return 0;
|
|
} |