void Console_key_execute(Console* self) { glyph_list *start, *end; int open_bracket_count, close_bracket_count; bool have_token; wchar_t *code; Expression *expression, *ret; if (self->cursor->previous && self->cursor->character == '\n') { end = self->cursor->previous; } else { end = self->cursor; } while (end && (end != self->head)) { switch (end->character) { case '\n': printf("nada empty line\n"); return; case ' ': break; case '\t': break; default: goto have_end; } end = end->previous; } have_end: start = end; open_bracket_count = 0; close_bracket_count = 0; have_token = false; while (start) { switch (start->character) { case '(': open_bracket_count++; if (have_token && (close_bracket_count - open_bracket_count) == 0) goto have_start; break; case ')': if ((close_bracket_count - open_bracket_count) < 0) { printf("Nada 4\n"); return; } close_bracket_count++; if (have_token && (close_bracket_count - open_bracket_count) == 0) goto have_start; break; case '\n': if (have_token && (close_bracket_count - open_bracket_count) == 0) goto have_start; default: have_token = true; } start = start->previous; } have_start: if ((close_bracket_count - open_bracket_count) != 0) { printf("nada brackets\n"); return; } else if ((end - start) == 0) { printf("nada empty\n"); return; } else if (start == null) { start = self->head; } code = Console_range_to_char(self, start, end); if (code) { expression = Expression_parse(code, wcslen(code), &self->lithp->symbol_list); if (expression == null || expression == nil_) { wprintf(L"Could not parse expression: %S\n", code); return; }; printf("(EVAL '"); Expression_dump(expression, -1); printf(")\n"); _gc_protect(expression); ret = Expression_eval(expression, self->lithp->environment); _gc_unprotect(expression); if (ret == null) { printf("Could not evaluate expression\n"); return; }; wchar_t buf[1024]; memset(buf, 0, 1024); Expression_to_string(ret, buf, 1024); printf("%S\n", buf); Console_insert(self, '\n'); for (size_t t = 0; t < wcslen(buf); t++) { Console_insert(self, buf[t]); } Console_insert(self, '\n'); } }
int main(int argc, char* argv[]) { Context* ctx = Context_new(); register_math(ctx); for(nextLine(); !feof(stdin); nextLine()) { /* Strip trailing newline */ char* end; if((end = strchr(line, '\n')) != NULL) *end = '\0'; if((end = strchr(line, '\r')) != NULL) *end = '\0'; if((end = strchr(line, '#')) != NULL) *end = '\0'; const char* p = line; /* Get verbosity level */ int verbose = 0; while(p[0] == '?') { verbose++; p++; } trimSpaces(&p); if(*p == '~') { /* Variable deletion */ p++; char* name = nextToken(&p); if(name == NULL) { /* '~~~' means reset interpreter */ if(p[0] == '~' && p[1] == '~') { /* Wipe out context */ Context_free(ctx); ctx = Context_new(); register_math(ctx); continue; } if(*p == '\0') { RAISE(earlyEnd()); continue; } RAISE(badChar(*p)); continue; } Context_del(ctx, name); free(name); continue; } /* Parse the user's input */ Expression* expr = Expression_parse(&p); /* Print expression depending on verbosity */ Expression_print(expr, ctx, verbose); /* Error? Go to next loop iteration */ if(Expression_didError(expr)) { Expression_free(expr); continue; } /* Evaluate expression */ Value* result = Expression_eval(expr, ctx); Expression_free(expr); /* Print result */ Value_print(result, ctx); Value_free(result); } Context_free(ctx); return 0; }