Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
    }
  }
}