double _parse(gchar *args, struct global_vars *gvars) { gchar mul_char = '*'; gdouble minus_one = -1.0; gchar null = 0; gint args_len = strlen(args); struct stack *arguments = stack_init(sizeof(gdouble)); struct stack *operators = stack_init(sizeof(gchar)); gint i = 0; gint j = 0; gint local_nest_level = 0; gint8 last_p = 0; /** priority of last parsed operator */ gboolean coef_flag = FALSE; /** set if value might preceed a bracket and thus become a coefficient */ gboolean func_flag = FALSE; /** set if result of next bracket is to be passed as an argument to function <symbol> */ gboolean nest_flag = FALSE; /** indicates characters are being collected and not parsed */ gboolean nest_init_flag = FALSE; /** necessary to skip first character '(' during string collection */ gboolean neg_flag = TRUE; /** set if next '-' will make number signed and not be an operator */ gboolean frac_flag = FALSE; //char nested_term[100] = { 0 }; /** collector string for contents of nested term */ GString *nested_term = g_string_new(&null); //char symbol[100] = { 0 }; /** collector string for symbol name */ GString *symbol = g_string_new(&null); for (i=0; i < args_len; i++) { if (nest_init_flag) {nest_init_flag = FALSE;} /** lock computing by raising nest level, substitute '*' if coefficient exists */ if (args[i] == '(') { if (!nest_flag) /** nested interpreting is just about to be initialized */ { if (coef_flag) {stack_push(operators, &mul_char); last_p = priority(mul_char);} coef_flag = TRUE; nest_flag = TRUE; nest_init_flag = TRUE; gvars->nest_level += 1; nested_term = g_string_new(&null); } else /** nested interpreting is in progress */ { local_nest_level += 1; } } else if (args[i] == ')') { if (nest_flag && local_nest_level == 0) /** nesting has reached end */ { nest_flag = FALSE; gdouble nested_term_result = _parse(nested_term->str, gvars); gvars->nest_level -= 1; g_string_free(nested_term, TRUE); nested_term = g_string_new(&null); if (func_flag) { gdouble compute_function_results = compute_function(symbol->str, nested_term_result, gvars); stack_push(arguments, &compute_function_results); func_flag = FALSE; g_string_free(symbol, TRUE); symbol = g_string_new(&null); } else {stack_push(arguments, &nested_term_result);} } else /** nested interpreting is in progress, passing by uninterpreted ')' */ { local_nest_level -= 1; } } if (!nest_flag) { if (args[i] == '.' || args[i] == ',') { if (g_ascii_isdigit(char_at(args,i+1))) {frac_flag = TRUE;} else {gvars->error_type = 3; return 0;} } else if (g_ascii_isdigit(args[i])) /** parse number */ { if (gvars->debug) {for (j=0;j<gvars->nest_level;j++) {g_printf(" ");} g_printf("args[%d] is digit\n", i);} gint8 dig = to_d(args[i]); stack_push(gvars->digits, &dig); if (frac_flag) {gvars->frac_point -= 1;} /** check if there is more than one digit or fractal part */ if (!(g_ascii_isdigit(char_at(args, i+1)) || char_at(args, i+1) == '.' || char_at(args, i+1) == ',')) { if (coef_flag) {stack_push(operators, &mul_char); last_p = priority(mul_char);} gdouble joined_dig = join_digits(gvars->digits, gvars->frac_point); stack_push(arguments, &joined_dig); neg_flag = FALSE; coef_flag = TRUE; frac_flag = FALSE; gvars->frac_point = 0; } } else if (isoperator(args[i])) /** parse operators */ { if (gvars->debug) {for (j=0;j<gvars->nest_level;j++) {g_printf(" ");} g_printf("args[%d] is operator\n", i);} if (neg_flag && args[i] == '-') /** check if preceeding minus changes sign of next symbol */ { neg_flag = FALSE; stack_push(arguments, &minus_one); stack_push(operators, &mul_char); last_p = priority(mul_char); } else { if (stack_length(arguments) <= stack_length(operators)) {gvars->error_type = 4; break;} /** check beforehand if lower priority operator is encountered */ if (priority(args[i]) < last_p) {compute(arguments, operators, gvars);} last_p = priority(args[i]); stack_push(operators, &args[i]); coef_flag = FALSE; neg_flag = TRUE; } } else if (g_ascii_isalpha(args[i])) /** parse letters */ { if (gvars->debug) {for (j=0;j<gvars->nest_level;j++) {g_printf(" ");} printf("args[%d] is letter\n", i);} if (coef_flag) {coef_flag = FALSE; stack_push(operators, &mul_char); last_p = priority(mul_char);} if (neg_flag) {neg_flag = FALSE;} g_string_append_c(symbol, args[i]); if (char_at(args,i+1) == '(') { compute_function(symbol->str, 1.337, gvars); if (gvars->error_type != 0) { gvars->error_type = 0; gdouble looked_up_c = lookup_constant(symbol->str, gvars); stack_push(arguments, &looked_up_c); //+symbol = ""; g_string_free(symbol, TRUE); symbol = g_string_new(&null); coef_flag = TRUE; } else {func_flag = TRUE;} } else if (!g_ascii_isalpha(char_at(args,i+1))) { gdouble looked_up_c = lookup_constant(symbol->str, gvars); stack_push(arguments, &looked_up_c); g_string_free(symbol, TRUE); symbol = g_string_new(&null); coef_flag = TRUE; } } } else if (!nest_init_flag) /** this collector block needs to be skipped once so the first '(' isn't collected */ { g_string_append_c(nested_term, args[i]); } if (args[i] == ' ') {coef_flag = FALSE;} if (char_at(args,i) == '#') {break;} /** failsafe, in case array bounds are left */ } if (gvars->debug) {printf("<args>\n");stack_dump(arguments, 'd');printf("<ops>\n");stack_dump(operators, 'c');printf("<>\n");} if (local_nest_level != 0 && gvars->error_type == 0) {gvars->error_type = 1;} if (neg_flag && gvars->error_type == 0) {gvars->error_type = 4;} if (gvars->error_type == 0) {compute(arguments, operators, gvars);} if (stack_length(arguments) > 1 && gvars->error_type == 0) {gvars->error_type = 4;printf("no2\n");} gdouble return_value = 0; if (gvars->error_type == 0) {stack_pop(arguments, &return_value);} stack_destroy(arguments); stack_destroy(operators); return return_value; }
void on_controller(S2D_Event e) { puts("=== Controller Event ==="); printf("Controller #%i\n", e.which); // Axes if (e.type == S2D_AXIS) { printf("Axis movement: #%i ", e.axis); switch (e.axis) { case S2D_AXIS_INVALID: S2D_Error("Controller", "Invalid axis!"); break; case S2D_AXIS_LEFTX: puts("(LEFTX)"); axis_LEFTX = to_d(e.value) * scale; break; case S2D_AXIS_LEFTY: puts("(LEFTY)"); axis_LEFTY = to_d(e.value) * scale; break; case S2D_AXIS_RIGHTX: puts("(RIGHTX)"); axis_RIGHTX = to_d(e.value) * scale; break; case S2D_AXIS_RIGHTY: puts("(RIGHTY)"); axis_RIGHTY = to_d(e.value) * scale; break; case S2D_AXIS_TRIGGERLEFT: puts("(TRIGGERLEFT)"); axis_TRIGGERLEFT = to_d(e.value) * scale; break; case S2D_AXIS_TRIGGERRIGHT: puts("(TRIGGERRIGHT)"); axis_TRIGGERRIGHT = to_d(e.value) * scale; break; case S2D_AXIS_MAX: puts("(MAX)"); break; } printf("Value: %i\n", e.value); // Buttons } else { switch (e.type) { case S2D_BUTTON_DOWN: printf("Button down: #%i ", e.button); break; case S2D_BUTTON_UP: printf("Button up: #%i ", e.button); break; } bool pressed = e.type == S2D_BUTTON_DOWN ? true : false; switch (e.button) { case S2D_BUTTON_INVALID: S2D_Error("Controller", "Invalid button!"); case S2D_BUTTON_A: puts("(A)"); btn_A = pressed; break; case S2D_BUTTON_B: puts("(B)"); btn_B = pressed; break; case S2D_BUTTON_X: puts("(X)"); btn_X = pressed; break; case S2D_BUTTON_Y: puts("(Y)"); btn_Y = pressed; break; case S2D_BUTTON_BACK: puts("(BACK)"); btn_BACK = pressed; break; case S2D_BUTTON_GUIDE: puts("(GUIDE)"); btn_GUIDE = pressed; break; case S2D_BUTTON_START: puts("(START)"); btn_START = pressed; break; case S2D_BUTTON_LEFTSTICK: puts("(LEFTSTICK)"); btn_LEFTSTICK = pressed; break; case S2D_BUTTON_RIGHTSTICK: puts("(RIGHTSTICK)"); btn_RIGHTSTICK = pressed; break; case S2D_BUTTON_LEFTSHOULDER: puts("(LEFTSHOULDER)"); btn_LEFTSHOULDER = pressed; break; case S2D_BUTTON_RIGHTSHOULDER: puts("(RIGHTSHOULDER)"); btn_RIGHTSHOULDER = pressed; break; case S2D_BUTTON_DPAD_UP: puts("(DPAD_UP)"); btn_DPAD_UP = pressed; break; case S2D_BUTTON_DPAD_DOWN: puts("(DPAD_DOWN)"); btn_DPAD_DOWN = pressed; break; case S2D_BUTTON_DPAD_LEFT: puts("(DPAD_LEFT)"); btn_DPAD_LEFT = pressed; break; case S2D_BUTTON_DPAD_RIGHT: puts("(DPAD_RIGHT)"); btn_DPAD_RIGHT = pressed; break; case S2D_BUTTON_MAX: puts("(MAX)"); btn_MAX = pressed; break; } } }