Example #1
0
AP_T pop(void) {
	if (!Stack_empty(sp))
		return Stack_pop(sp);
	else {
		Fmt_fprint(stderr, "?stack underflow\n");
		return AP_new(0);
	}
}
Example #2
0
File: ap.c Project: KoyoA/patterns
T AP_pow(T x, T y, T p) {
    T z;
    assert(x);
    assert(y);
    assert(y->sign == 1);
    assert( (!p) || (p->sign==1 && !iszero(p) && !isone(p)));
    if (iszero(x))
        return AP_new(0);
    if (iszero(y))
        return AP_new(1);
    if (isone(x))
        return AP_new((((y)->digits[0]&1) == 0) ? 1 : x->sign);
    if (p)
        if (isone(y))
            z = AP_mod(x, p);
        else {
            T y2 = AP_rshift(y, 1), t = AP_pow(x, y2, p);
            z = mulmod(t, t, p);
            AP_free(&y2);
            AP_free(&t);
            if (!(((y)->digits[0]&1) == 0)) {
                z = mulmod(y2 = AP_mod(x, p), t = z, p);
                AP_free(&y2);
                AP_free(&t);
            }
        }
    else if (isone(y))
        z = AP_addi(x, 0);
    else {
        T y2 = AP_rshift(y, 1), t = AP_pow(x, y2, NULL);
        z = AP_mul(t, t);
        AP_free(&y2);
        AP_free(&t);
        if (!(((y)->digits[0]&1) == 0)) {
            z = AP_mul(x, t = z);
            AP_free(&t);
        }
    }
    return z;
}
Example #3
0
File: ap.c Project: KoyoA/patterns
T AP_rshift(T x, int s) {
    assert(x);
    assert(s >= 0);
    if (s >= 8*x->ndigits)
        return AP_new(0);
    else {
        T z = mk(x->ndigits - s/8);
        XP_rshift(z->size, z->digits, x->ndigits,
                  x->digits, s, 0);
        normalize(z, z->size);
        z->sign = iszero(z) ? 1 : x->sign;
        return z;
    }
}
Example #4
0
File: ap.c Project: KoyoA/patterns
T AP_fromstr(const char *str, int base, char **end) {
    T z;
    const char *p = str;
    char *endp, sign = '\0';
    int carry;
    assert(p);
    assert(base >= 2 && base <= 36);
    while (*p && isspace(*p))
        p++;
    if (*p == '-' || *p == '+')
        sign = *p++;
    {
        const char *start;
        int k, n = 0;
        for ( ; *p == '0' && p[1] == '0'; p++)
            ;
        start = p;
        for ( ; (  ('0' <= *p && *p <= '9' && *p < '0' + base)
                   || ('a' <= *p && *p <= 'z' && *p < 'a' + base - 10)
                   || ('A' <= *p && *p <= 'Z' && *p < 'A' + base - 10)); p++)
            n++;
        for (k = 1; (1<<k) < base; k++)
            ;
        z = mk(((k*n + 7)&~7)/8);
        p = start;
    }
    carry = XP_fromstr(z->size, z->digits, p,
                       base, &endp);
    assert(carry == 0);
    normalize(z, z->size);
    if (endp == p) {
        endp = (char *)str;
        z = AP_new(0);
    } else
        z->sign = iszero(z) || sign != '-' ? 1 : -1;
    if (end)
        *end = (char *)endp;
    return z;
}
Example #5
0
int main(int argc, char *argv[]) {
	int c;
	sp = Stack_new();
	Fmt_register('D', AP_fmt);
	while ((c = getchar()) != EOF)
		switch (c) {
		case ' ': case '\t': case '\n': case '\f': case '\r':
			break;
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9': {
			char buf[512];
			{
				int i = 0;
				for ( ; c != EOF && isdigit(c); c = getchar(), i++)
					if (i < (int)sizeof (buf) - 1)
						buf[i] = c;
				if (i > (int)sizeof (buf) - 1) {
					i = (int)sizeof (buf) - 1;
					Fmt_fprint(stderr,
						"?integer constant exceeds %d digits\n", i);
				}
				buf[i] = 0;
				if (c != EOF)
					ungetc(c, stdin);
			}
			Stack_push(sp, AP_fromstr(buf, 10, NULL));
			break;
		}
		case '+': {
			AP_T y = pop(), x = pop();
			Stack_push(sp, AP_add(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '-': {
			AP_T y = pop(), x = pop();
			Stack_push(sp, AP_sub(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '*': {
			AP_T y = pop(), x = pop();
			Stack_push(sp, AP_mul(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '/': {
			AP_T y = pop(), x = pop();
			if (AP_cmpi(y, 0) == 0) {
				Fmt_fprint(stderr, "?/ by 0\n");
				Stack_push(sp, AP_new(0));
			} else
				Stack_push(sp, AP_div(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '%': {
			AP_T y = pop(), x = pop();
			if (AP_cmpi(y, 0) == 0) {
				Fmt_fprint(stderr, "?%% by 0\n");
				Stack_push(sp, AP_new(0));
			} else
				Stack_push(sp, AP_mod(x, y));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case '^': {
			AP_T y = pop(), x = pop();
			if (AP_cmpi(y, 0) <= 0) {
				Fmt_fprint(stderr, "?nonpositive power\n");
				Stack_push(sp, AP_new(0));
			} else
				Stack_push(sp, AP_pow(x, y, NULL));
			AP_free(&x);
			AP_free(&y);
			break;
		}
		case 'd': {
			AP_T x = pop();
			Stack_push(sp, x);
			Stack_push(sp, AP_addi(x, 0));
			break;
		}
		case 'p': {
			AP_T x = pop();
			Fmt_print("%D\n", x);
			Stack_push(sp, x);
			break;
		}
		case 'f':
			if (!Stack_empty(sp)) {
				Stack_T tmp = Stack_new();
				while (!Stack_empty(sp)) {
					AP_T x = pop();
					Fmt_print("%D\n", x);
					Stack_push(tmp, x);
				}
				while (!Stack_empty(tmp))
					Stack_push(sp, Stack_pop(tmp));
				Stack_free(&tmp);
			}
			break;
		case '~': {
			AP_T x = pop();
			Stack_push(sp, AP_neg(x));
			AP_free(&x);
			break;
		}
		case 'c': while (!Stack_empty(sp)) {
			  	AP_T x = Stack_pop(sp);
			  	AP_free(&x);
			  } break;
		case 'q': while (!Stack_empty(sp)) {
			  	AP_T x = Stack_pop(sp);
			  	AP_free(&x);
			  }
			  Stack_free(&sp);
			  return EXIT_SUCCESS;
		default:
			if (isprint(c))
				Fmt_fprint(stderr, "?'%c'", c);
			else
				Fmt_fprint(stderr, "?'\\%03o'", c);
			Fmt_fprint(stderr, " is unimplemented\n");
			break;
		}
	while (!Stack_empty(sp)) {
		AP_T x = Stack_pop(sp);
		AP_free(&x);
	}
	Stack_free(&sp);
	return EXIT_SUCCESS;
}