#include "dict.h" #include "io.h" #include "parser.h" #include "system.h" #include #include #ifdef __linux__ #include "linux.h" #endif // __linux__ static char ok[] = "ok.\n"; static char bye[] = "bye"; static System sys; static void write_dstack() { KF_INT tmp; sys.interface->wrch('<'); for (size_t i = 0; i < sys.dstack.size(); i++) { if (i > 0) { sys.interface->wrch(' '); } sys.dstack.get(i, tmp); write_num(sys.interface, tmp); } sys.interface->wrch('>'); } static bool parser(const char *buf, const size_t buflen) { static size_t offset = 0; static struct Token token; static PARSE_RESULT result = PARSE_FAIL; static LOOKUP lresult = LOOKUP_FAILED; static bool stop = false; offset = 0; // reset token token.token = nullptr; token.length = 0; while ((result = parse_next(buf, buflen, &offset, &token)) == PARSE_OK) { lresult = lookup(&token, &sys); switch (lresult) { case LOOKUP_OK: continue; case LOOKUP_NOTFOUND: sys.interface->wrln((char *)"word not found", 15); stop = true; break; case LOOKUP_FAILED: sys.interface->wrln((char *)"execution failed", 17); stop = true; break; default: sys.interface->wrln((char *)"*** the world is broken ***", 27); exit(1); } if (stop) { stop = false; break; } // Temporary hack until the interpreter is working further. if (match_token(token.token, token.length, bye, 3)) { sys.interface->wrln((char *)"Goodbye!", 8); exit(0); } } switch (result) { case PARSE_OK: return false; case PARSE_EOB: sys.interface->wrbuf(ok, 4); return true; case PARSE_LEN: sys.interface->wrln((char *)"parse error: token too long", 27); return false; case PARSE_FAIL: sys.interface->wrln((char *)"parser failure", 14); return false; default: sys.interface->wrln((char *)"*** the world is broken ***", 27); exit(1); } } static void interpreter() { static size_t buflen = 0; static char linebuf[81]; while (true) { write_dstack(); sys.interface->wrch('\n'); sys.interface->wrch('?'); sys.interface->wrch(' '); buflen = sys.interface->rdbuf(linebuf, 80, true, '\n'); parser(linebuf, buflen); } } static char banner[] = "kforth interpreter\n"; const size_t bannerlen = 19; int main(void) { init_dict(); #ifdef __linux__ Console interface; sys.interface = &interface; #endif sys.interface->wrbuf(banner, bannerlen); interpreter(); return 0; }