void calculate_expr( node_t* node, node_t* parent) { // recurse to bottom, and evaluate bottom-up if( node == NULL ) return; if( node->type.index != expression_n.index ) return; if(node->n_children > 0) for(int i = 0; i < node->n_children; i++) calculate_expr(node->children[i], node); if(node->n_children == 2 && node->children[0]->type.index == INTEGER && node->children[1]->type.index == INTEGER) { doOp(node, parent); } char* c; if(node->data != NULL) c = (char*)node->data; if(node->n_children==1 && *c == '-' && node->children[0]->type.index == INTEGER) { unary_minus(node); } }
void dfs( node_t* current, node_t* parent ) { if(current == NULL) return; flatten_list(current); prune_print_list(current, parent); for(int i = 0; i < current->n_children; i++) { dfs(current->children[i], current); } if(current->type.index == EXPRESSION) calculate_expr(current, parent); }
int main(int argc, char **argv) { // Check command-line options char *p; int a = 1; Fl::args(argc, argv, a); Fl::scheme(NULL); // NULL causes libr. to look up style in .Xdefaults memset(ExprEntry_str, '\0', sizeof(ExprEntry_str)); clear_content(); /* printf("fround(0.0) is %1.2lf\n", fround(0.0)); printf("fround(0.1) is %1.2lf\n", fround(0.1)); printf("fround(0.49) is %1.2lf\n", fround(0.49)); printf("fround(0.50) is %1.2lf\n", fround(0.50)); printf("fround(0.51) is %1.2lf\n", fround(0.51)); printf("fround(0.9) is %1.2lf\n", fround(0.9)); printf("fround(1.0) is %1.2lf\n", fround(1.0)); printf("fround(1.1) is %1.2lf\n", fround(1.1)); printf("fround(-0.1) is %1.2lf\n", fround(-0.1)); printf("fround(-0.4) is %1.2lf\n", fround(-0.4)); printf("fround(-0.5) is %1.2lf\n", fround(-0.5)); printf("fround(-0.51) is %1.2lf\n", fround(-0.51)); printf("fround(-0.9) is %1.2lf\n", fround(-0.9)); printf("fround(-1.0) is %1.2lf\n", fround(-1.0)); printf("fround(-1.1) is %1.2lf\n", fround(-1.1)); printf("fround(-1.4) is %1.2lf\n", fround(-1.4)); printf("fround(-1.5) is %1.2lf\n", fround(-1.5)); printf("fround(-1.6) is %1.2lf\n", fround(-1.6)); printf("fround(-1.9) is %1.2lf\n", fround(-1.9)); printf("\n"); printf("123.34 has %d significant digits\n", sig_digits(123.45)); printf("7 has %d significant digits\n", sig_digits(7)); printf("654.00001 has %d significant digits\n", sig_digits(654.00001)); printf("-123.34 has %d significant digits\n", sig_digits(-123.45)); printf("-7 has %d significant digits\n", sig_digits(-7)); printf("-654.00001 has %d significant digits\n", sig_digits(-654.00001)); printf("1.234e10 has %d significant digits\n", sig_digits(1.234e10)); printf("0.0001200560000 has %d significant digits\n", sig_digits(0.0001200560000)); printf("-1.20056e-4 has %d significant digits\n", sig_digits(-1.20056e-4)); //return 0; */ char num_str[8]; int i; for(i = 0; i < MAXENTRY; i++) { sprintf(num_str, "%d\n", i); strcat(RowLabels_str, num_str); } //printf("argc is %d\n", argc); fflush(0); char cmdline_expr[MAXENTRYLEN] = ""; char expr_prepped_str[MAXENTRYLEN] = ""; while (a < argc) { p = argv[a]; if (*p == '-' && *(p+1) == '-') { // OK, it's some kind of option char option = *(p+2); if (option == 't') { // Change terseness/verbosity threshold if (*(p+3)) { SayThreshold = *(p+3) - '0'; SAY(1, "Terseness level is %d\n", SayThreshold); } else if (a+1 < argc) { a++; p = argv[a]; SayThreshold = *p - '0'; SAY(1, "Terseness level is %d\n", SayThreshold); } } else if (option == 'd') { // Change angle encoding to degrees AngleUnitsAreDegrees = 1; SAY(1, "Angles expressed as degrees\n"); } else if (option == 'r') { // Change angle encoding to radians AngleUnitsAreDegrees = 0; SAY(1, "Angles expressed as radians\n"); } else if (option == 'p') { // Switch to Reverse Polish Notation (RPN) entry syntax InputMode = RPN_INPUT; SAY(1, "Input syntanx mode is RPN (Reverse Polish Notation)\n"); fflush(0); } else if (option == 'v') { // Print name and version update_main_win_title(); printf("%s\n", Title_str); fflush(0); } else if (option == 'f') { // Pre-load a specific workspace content file char filespec_str[MAXENTRYLEN] = ""; if (*(p+3)) { strcpy (CurrentFileSpec_str, (p+3)); } else { a++; if (*argv[a]) { strcpy (CurrentFileSpec_str, argv[a]); } } if (!*CurrentFileSpec_str) { fl_alert("File not specified!\n"); } } a++; } else { // assume the remainder of command-line is math expression while (a < argc) { strncat(cmdline_expr, argv[a], 32); strcat(cmdline_expr, " "); a++; } SAY(1, "Commandline expression is '%s'\n", cmdline_expr); if (strlen(cmdline_expr)) { int rc = calculate_expr(cmdline_expr, ExprEntry_str[Result], Result); if (rc == CALC_SUCCESS) { char result_str[64]; render_item(result_str, &ResultList[Result]); printf("%s = %s\n", ExprEntry_str[Result], result_str); return 0; } else { if (rc == CALC_UNBALANCED) { printf("Expression is unbalanced! Check parentheses carefully.\n"); } else if (rc == CALC_ERROR) { printf("Expression cannot be calculated!\n"); } return 1; } } } } //fl_register_images(); update_main_win_title(); MainWin_p = new Fl_Window(560,352, Title_str); MainWin_p->begin(); Fl_Scroll expr_win_scroll(6, 12, 546, 258); expr_win_scroll.begin(); Fl_Pack expr_win_group(6, 12, 546, 1024); expr_win_group.type(FL_HORIZONTAL); expr_win_group.begin(); RowLabels_p = new Fl_Multiline_Output(6, 12, 30, 1024 ); RowLabels_p->box(FL_FLAT_BOX); RowLabels_p->color(FL_BACKGROUND_COLOR); RowLabels_p->align(FL_ALIGN_RIGHT); RowLabels_p->value(RowLabels_str); WorkArea_p = new Fl_Multiline_Input(40, 10, 500, 1024 ); WorkArea_p->box(FL_FLAT_BOX); WorkArea_p->label(""); WorkArea_p->when(FL_WHEN_ENTER_KEY); WorkArea_p->callback(workarea_callback); WorkArea_p->take_focus(); update_results_display(); WorkArea_p->position(0,0); expr_win_group.end(); expr_win_scroll.end(); QuitBtn_p = new Fl_Button(30, 280, 60, 30, "Quit"); QuitBtn_p->callback(quit_callback); QuitBtn_p->shortcut(FL_Escape); OpenBtn_p = new Fl_Button(120, 280, 60, 30, "Open..."); OpenBtn_p->callback(open_callback); OpenBtn_p->shortcut(FL_CTRL + 'o'); SaveBtn_p = new Fl_Button(210, 280, 60, 30, "Save..."); SaveBtn_p->callback(save_callback); SaveBtn_p->deactivate(); SaveBtn_p->shortcut(FL_CTRL + 's'); ClearBtn_p = new Fl_Button(300, 280, 60, 30, "Clear"); ClearBtn_p->callback(clear_callback); ClearBtn_p->shortcut(FL_CTRL + 'c'); HintBtn_p = new Fl_Button(420, 280, 30, 30, "!"); HintBtn_p->callback(hint_callback); HintBtn_p->tooltip("Hints"); HintBtn_p->shortcut(FL_CTRL + 'i'); AboutBtn_p = new Fl_Button(460, 280, 30, 30, "a"); AboutBtn_p->callback(about_callback); AboutBtn_p->tooltip("About Flume"); AboutBtn_p->shortcut(FL_CTRL + 'a'); HelpBtn_p = new Fl_Button(500, 280, 30, 30, "?"); HelpBtn_p->callback(help_callback); HelpBtn_p->tooltip("Help (F1)"); HelpBtn_p->shortcut(FL_F + 1); Fl_Box* pAngleLabel = new Fl_Box(20, 325, 40, 12, "Angles:"); pAngleLabel->box(FL_FLAT_BOX); RadAngleBtn_p = new Fl_Round_Button(72, 324, 80, 16, "Radians"); RadAngleBtn_p->value(AngleUnitsAreDegrees ? 0 : 1); RadAngleBtn_p->callback(radians_callback); DegAngleBtn_p = new Fl_Round_Button(152, 324, 80, 16, "Degrees"); DegAngleBtn_p->value(AngleUnitsAreDegrees ? 1 : 0); DegAngleBtn_p->callback(degrees_callback); RpnModeChk_p = new Fl_Check_Button(280, 324, 96, 16, "RPN mode"); RpnModeChk_p->value((InputMode == RPN_INPUT) ? 1 : 0); RpnModeChk_p->callback(rpn_callback); TrackSigChk_p = new Fl_Check_Button(392, 324, 140, 16, "Track significance"); TrackSigChk_p->value(TrackSignificance); TrackSigChk_p->callback(track_sig_callback); MainWin_p->end(); if (*CurrentFileSpec_str) { if (!load_content(CurrentFileSpec_str)) { fl_alert("File not loadable!\n"); } } MainWin_p->show(argc, argv); Running = 1; while(Running && Fl::wait()); return 0; }
void workarea_callback(Fl_Widget* w) { struct item eval_list[MAXITEMS]; char disp_str[MAXENTRY*1024] = "\0"; char expr_input_str[MAXENTRYLEN] = {0}; char expr_prepped_str[MAXENTRYLEN] = {0}; Result = 0; strcpy(disp_str, WorkArea_p->value()); //printf("buf content is '%s'\n", disp_str); fflush(0); //printf("Result is %d\n", Result); const char * ep = disp_str; const char * p = ep; int disp_len = strlen(disp_str); while (Result < MAXENTRY && *ep && (ep - disp_str) < disp_len) { while (*p && *p != '\n' /*&& *p != '='*/) p++; int len = p - ep; if (len > (MAXENTRYLEN - 1)) { fl_alert("Entry is too long! (%d chars)", len); WorkArea_p->position(p - disp_str); return; } strncpy(expr_input_str, ep, len); expr_input_str[len] = '\0'; SAY(0, "Expression entry %d is '%s'\n", Result, expr_input_str); fflush(0); int rc = calculate_expr(expr_input_str, ExprEntry_str[Result], Result); if (rc == CALC_SUCCESS) { Result++; } else { if (rc == CALC_UNBALANCED) { fl_alert("Expression on row %d is unbalanced!\nCheck parentheses carefully.", Result); } else if (rc == CALC_ERROR) { fl_alert("Expression on row %d cannot be calculated!\nCheck expression carefully.", Result); } else if (rc == CALC_EXPRLENGTH) { fl_alert("Expression on row %d too long!\nBreak into smaller parts.", Result); } WorkArea_p->position(p - disp_str); return; } //printf("*p is '%c', char # %d in buffer\n", *p, p - disp_str); fflush(0); while (*p && *p != '\n') p++; if (*p == '\n') p++; ep = p; //printf("(after) *p is '%c', char # %d in buffer\n", *p, p - disp_str); fflush(0); //printf("*ep is '%c', char # %d in buffer\n", *ep, ep - disp_str); fflush(0); Unsaved = 1; SaveBtn_p->activate(); } if (p - disp_str < disp_len) { fl_alert("Row limit reached,\nremaining %d characters will be ignored!", disp_len - (p - disp_str)); } update_results_display(); }