#include #include #include #include #include #include "forth.h" #include "fh_runtime.h" #include "fh_print.h" int main(int argc, char *argv[]) { enum fh_error rv; struct fh_thread_s fh; rv = fh_init(&fh); if (rv != FH_OK) { LOGE("Error in forth init: %s", fherr_name(rv)); return 1; } fh_globals.verbose = false; fh_globals.interactive = isatty(STDIN_FILENO); FILE *infile = stdin; // TODO use getopt for (int a = 1; a < argc; a++) { if (argv[a][0] == '-' && argv[a][1] != '-') { // opt char *cc = argv[a] + 1; char c; while (0 != (c = *cc++)) { switch (c) { case 'v': fh_globals.verbose = 1; break; default: LOGE("Unknown flag: %c", c); return 1; } } } else { infile = fopen(argv[a], "r"); fh_globals.interactive = false; if (!infile) { LOGE("Error opening infile: %s", argv[a]); return 1; } } } /* process input line by line */ int linecnt = 0; char linebuf[MAXLINE]; while (fh.state != FH_STATE_SHUTDOWN && fgets(linebuf, MAXLINE, infile)) { linecnt++; // trim size_t end = strlen(linebuf) - 1; while (isspace(linebuf[end])) { linebuf[end] = 0; } if (!linebuf[0]) { continue; } rv = fh_process_line(&fh, linebuf); if (rv == FH_OK) { FHPRINT_SVC(" ok\n"); } else { LOGE("ERROR %s on line %d", fherr_name(rv), linecnt); if (!fh_globals.interactive) { return 1; } /* reset state */ fh_setstate(&fh, FH_STATE_INTERPRET, FH_SUBSTATE_NONE); } } // Show resource usage LOG("\nResources used: DS %dW, RS %dW, CS %dW, heap %dB, program %dB, dict %dx\n", (int) fh.data_stack_hwm, (int) fh.return_stack_hwm, (int) fh.control_stack_hwm, (int) fh.heap_top, (int) fh.compile_top, (int) fh.dict_top); FHPRINT_SVC("Bye.\n"); return 0; }