コード例 #1
0
ファイル: shunting-yard.c プロジェクト: ivzb/c-shunting-yard
Status apply_operator(const Operator *operator, Stack **operands)
{
    if (!operator || !*operands)
    {
        return ERROR_SYNTAX;
    }

    if (operator->arity == OPERATOR_UNARY)
    {
        return apply_unary_operator(operator, operands);
    }

    double y = pop_double(operands);

    if (!*operands)
    {
        return ERROR_SYNTAX;
    }

    double x = pop_double(operands);
    Status status = OK;

    switch (operator->symbol)
    {
        case '^':
            x = pow(x, y);
            break;
        case '*':
            x = x * y;
            break;
        case '/':
            x = x / y;
            break;
        case '%':
            x = fmod(x, y);
            break;
        case '+':
            x = x + y;
            break;
        case '-':
            x = x - y;
            break;
        default:
            return ERROR_UNRECOGNIZED;
    }

    push_double(x, operands);

    return status;
}
コード例 #2
0
ファイル: draw.cpp プロジェクト: ComputerNerd/eigenmath
void
setup_yrange_f(void)
{
	// default range is (-10,10)

	ymin = -10.0;

	ymax = 10.0;

	p1 = usr_symbol("yrange");

	if (!issymbol(p1))
		return;

	p1 = get_binding(p1);

	// must be two element vector

	if (!istensor(p1) || p1->u.tensor->ndim != 1 || p1->u.tensor->nelem != 2)
		return;

	push(p1->u.tensor->elem[0]);
	eval();
	yyfloat();
	eval();
	p2 = pop();

	push(p1->u.tensor->elem[1]);
	eval();
	yyfloat();
	eval();
	p3 = pop();

	if (!isnum(p2) || !isnum(p3))
		return;

	push(p2);
	ymin = pop_double();

	push(p3);
	ymax = pop_double();

	if (ymin == ymax)
		stop("draw: yrange is zero");
}
コード例 #3
0
ファイル: draw.cpp プロジェクト: ComputerNerd/eigenmath
void
setup_trange_f(void)
{
	// default range is (-pi, pi)

	tmin = -M_PI;

	tmax = M_PI;

	p1 = usr_symbol("trange");

	if (!issymbol(p1))
		return;

	p1 = get_binding(p1);

	// must be two element vector

	if (!istensor(p1) || p1->u.tensor->ndim != 1 || p1->u.tensor->nelem != 2)
		return;

	push(p1->u.tensor->elem[0]);
	eval();
	yyfloat();
	eval();
	p2 = pop();

	push(p1->u.tensor->elem[1]);
	eval();
	yyfloat();
	eval();
	p3 = pop();

	if (!isnum(p2) || !isnum(p3))
		return;

	push(p2);
	tmin = pop_double();

	push(p3);
	tmax = pop_double();

	if (tmin == tmax)
		stop("draw: trange is zero");
}
コード例 #4
0
ファイル: draw.cpp プロジェクト: ComputerNerd/eigenmath
void
new_point(double t)
{
	double x, y;

	if (draw_count >= YMAX)
		return;

	draw_buf[draw_count].x = -10000;
	draw_buf[draw_count].y = -10000;
	draw_buf[draw_count].t = t;

	draw_count++;

	get_xy(t);

	if (!isnum(XT) || !isnum(YT))
		return;

	push(XT);
	x = pop_double();
	x = (x - xmin) / (xmax - xmin);
	x = (double) DIMX * x + 0.5; // map 0-1 to 0-DIM, +0.5 so draw(x^3) looks right

	push(YT);
	y = pop_double();
	y = (y - ymin) / (ymax - ymin);
	y = (double) DIMY * y + 0.5; // map 0-1 to 0-DIM, +0.5 so draw(x^3) looks right

	if (x < -10000.0)
		x = -10000.0;
	if (x > 10000.0)
		x = 10000.0;
	if (y < -10000.0)
		y = -10000.0;
	if (y > 10000.0)
		y = 10000.0;

	draw_buf[draw_count - 1].x = (int) x;
	draw_buf[draw_count - 1].y = (int) y;
}
コード例 #5
0
ファイル: shunting-yard.c プロジェクト: ivzb/c-shunting-yard
Status shunting_yard(const char *expression, double *result)
{
    Token *tokens = tokenize(expression);
    Stack *operands = NULL, *operators = NULL, *functions = NULL;
    Status status = parse(tokens, &operands, &operators, &functions);

    if (operands)
    {
        *result = round(pop_double(&operands) * 10e14) / 10e14;
    }
    else if (status == OK)
    {
        status = ERROR_NO_INPUT;
    }

    Token *token;
    for (token = tokens; token->type != TOKEN_NONE; token++)
    {
        free(token->value);
    }

    free(tokens);

    while (operands)
    {
        pop_double(&operands);
    }

    while (operators)
    {
        stack_pop(&operators);
    }

    while (functions)
    {
        stack_pop(&functions);
    }

    return status;
}
コード例 #6
0
ファイル: shunting-yard.c プロジェクト: ivzb/c-shunting-yard
Status apply_function(const char *function, Stack **operands)
{
    if (!*operands)
    {
        return ERROR_FUNCTION_ARGUMENTS;
    }

    double x = pop_double(operands);

    if (strcasecmp(function, "abs") == 0)
    {
        x = fabs(x);
    }
    else if (strcasecmp(function, "sqrt") == 0)
    {
        x = sqrt(x);
    }
    else if (strcasecmp(function, "ln") == 0)
    {
        x = log(x);
    }
    else if (strcasecmp(function, "lb") == 0)
    {
        x = log2(x);
    }
    else if (strcasecmp(function, "lg") == 0 || strcasecmp(function, "log") == 0)
    {
        x = log10(x);
    }
    else if (strcasecmp(function, "cos") == 0)
    {
        x = cos(x);
    }
    else if (strcasecmp(function, "sin") == 0)
    {
        x = sin(x);
    }
    else if (strcasecmp(function, "tan") == 0)
    {
        x = tan(x);
    }
    else
    {
        return ERROR_UNDEFINED_FUNCTION;
    }

    push_double(x, operands);

    return OK;
}
コード例 #7
0
ファイル: shunting-yard.c プロジェクト: ivzb/c-shunting-yard
Status apply_unary_operator(const Operator *operator, Stack **operands)
{
    double x = pop_double(operands);

    switch (operator->symbol)
    {
        case '+':
            break;
        case '-':
            x = -x;
            break;
        case '!':
            x = tgamma(x + 1);
            break;
        default:
            return ERROR_UNRECOGNIZED;
    }

    push_double(x, operands);

    return OK;
}
コード例 #8
0
void NativeGenerator::generate_native_math_entries() {
  comment_section("Native entry points for math functions");
  int offset = 0;

#if ENABLE_FLOAT

  stop_code_segment();
  start_data_segment();

  stop_data_segment();
  start_code_segment();

  // Generate sinus entry.
  offset = 0;
  rom_linkable_entry("native_math_sin_entry");
  comment("store return address");
  popl(edi);
  pop_double(eax, ecx);
  pushl(ecx);
  pushl(eax);
  call(Constant("jvm_sin"));
  addl(esp, Constant(8));
  push_from_fpu_stack(double_tag, offset, true);
  jmp(edi);
  rom_linkable_entry_end(); // native_math_sin_entry

  // Generate cosinus entry.
  offset = 0;
  rom_linkable_entry("native_math_cos_entry");
  comment("store return address");
  popl(edi);
  pop_double(eax, ecx);
  pushl(ecx);
  pushl(eax);
  call(Constant("jvm_cos"));
  addl(esp, Constant(8));
  push_from_fpu_stack(double_tag, offset, true);
  jmp(edi);
  rom_linkable_entry_end(); // native_math_cos_entry

  // Generate tangent entry.
  offset = 0;
  rom_linkable_entry("native_math_tan_entry");
  comment("store return address");
  popl(edi);
  pop_double(eax, ecx);
  pushl(ecx);
  pushl(eax);
  call(Constant("jvm_tan"));
  addl(esp, Constant(8));
  push_from_fpu_stack(double_tag, offset, true);
  jmp(edi);
  rom_linkable_entry_end(); // native_math_tan_entry

  // Generate square root entry.
  offset = 0;
  rom_linkable_entry("native_math_sqrt_entry");
  comment("store return address");
  popl(edi);
  pop_double(eax, ecx);
  pushl(ecx);
  pushl(eax);
  call(Constant("jvm_sqrt"));
  addl(esp, Constant(8));
  push_from_fpu_stack(double_tag, offset, true);
  jmp(edi);
  rom_linkable_entry_end(); // native_math_sqrt_entry

  // Generate ceil entry.
  offset = 0;
  rom_linkable_entry("native_math_ceil_entry");
  comment("store return address");
  popl(edi);
  pop_double(eax, ecx);
  pushl(ecx);
  pushl(eax);
  call(Constant("jvm_ceil"));
  addl(esp, Constant(8));
  push_from_fpu_stack(double_tag, offset, true);
  jmp(edi);
  rom_linkable_entry_end(); // native_math_ceil_entry

  // Generate floor entry.
  offset = 0;
  rom_linkable_entry("native_math_floor_entry");
  comment("store return address");
  popl(edi);
  pop_double(eax, ecx);
  pushl(ecx);
  pushl(eax);
  call(Constant("jvm_floor"));
  addl(esp, Constant(8));
  push_from_fpu_stack(double_tag, offset, true);
  jmp(edi);
  rom_linkable_entry_end(); // native_math_floor_entry

#endif /* ENABLE_FLOAT */
}