Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/dc/bcode.c
Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
static struct bmachine bmachine; | static struct bmachine bmachine; | ||||
static __inline int readch(void); | static __inline int readch(void); | ||||
static __inline void unreadch(void); | static __inline void unreadch(void); | ||||
static __inline char *readline(void); | static __inline char *readline(void); | ||||
static __inline void src_free(void); | static __inline void src_free(void); | ||||
static __inline u_int max(u_int, u_int); | |||||
static u_long get_ulong(struct number *); | static u_long get_ulong(struct number *); | ||||
static __inline void push_number(struct number *); | static __inline void push_number(struct number *); | ||||
static __inline void push_string(char *); | static __inline void push_string(char *); | ||||
static __inline void push(struct value *); | static __inline void push(struct value *); | ||||
static __inline struct value *tos(void); | static __inline struct value *tos(void); | ||||
static __inline struct number *pop_number(void); | static __inline struct number *pop_number(void); | ||||
static __inline char *pop_string(void); | static __inline char *pop_string(void); | ||||
▲ Show 20 Lines • Show All 251 Lines • ▼ Show 20 Lines | if (p == NULL) | ||||
err(1, "BN_bn2dec failed"); | err(1, "BN_bn2dec failed"); | ||||
fputs(str, stderr); | fputs(str, stderr); | ||||
fprintf(stderr, " %s\n", p); | fprintf(stderr, " %s\n", p); | ||||
OPENSSL_free(p); | OPENSSL_free(p); | ||||
} | } | ||||
#endif | #endif | ||||
static __inline u_int | |||||
max(u_int a, u_int b) | |||||
{ | |||||
return (a > b ? a : b); | |||||
} | |||||
static unsigned long factors[] = { | static unsigned long factors[] = { | ||||
0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | 0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, | ||||
100000000, 1000000000 | 100000000, 1000000000 | ||||
}; | }; | ||||
/* Multiply n by 10^s */ | |||||
void | void | ||||
scale_number(BIGNUM *n, int s) | scale_number(BIGNUM *n, int s) | ||||
{ | { | ||||
unsigned int abs_scale; | unsigned int abs_scale; | ||||
if (s == 0) | if (s == 0) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | else if (n->scale < sizeof(factors)/sizeof(factors[0])) { | ||||
bn_check(BN_exp(a, a, p, ctx)); | bn_check(BN_exp(a, a, p, ctx)); | ||||
bn_check(BN_div(i, f, n->number, a, ctx)); | bn_check(BN_div(i, f, n->number, a, ctx)); | ||||
BN_CTX_free(ctx); | BN_CTX_free(ctx); | ||||
BN_free(a); | BN_free(a); | ||||
BN_free(p); | BN_free(p); | ||||
} | } | ||||
} | } | ||||
/* Change the scale of n to s. Reducing scale may truncate the mantissa */ | |||||
void | void | ||||
normalize(struct number *n, u_int s) | normalize(struct number *n, u_int s) | ||||
{ | { | ||||
scale_number(n->number, s - n->scale); | scale_number(n->number, s - n->scale); | ||||
n->scale = s; | n->scale = s; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 640 Lines • ▼ Show 20 Lines | bmul(void) | ||||
free_number(a); | free_number(a); | ||||
free_number(b); | free_number(b); | ||||
} | } | ||||
static void | static void | ||||
bdiv(void) | bdiv(void) | ||||
{ | { | ||||
struct number *a, *b, *r; | struct number *a, *b, *r; | ||||
BN_CTX *ctx; | |||||
u_int scale; | |||||
a = pop_number(); | a = pop_number(); | ||||
if (a == NULL) | if (a == NULL) | ||||
return; | return; | ||||
b = pop_number(); | b = pop_number(); | ||||
if (b == NULL) { | if (b == NULL) { | ||||
push_number(a); | push_number(a); | ||||
return; | return; | ||||
} | } | ||||
r = new_number(); | r = div_number(b, a, bmachine.scale); | ||||
r->scale = bmachine.scale; | |||||
scale = max(a->scale, b->scale); | |||||
if (BN_is_zero(a->number)) | |||||
warnx("divide by zero"); | |||||
else { | |||||
normalize(a, scale); | |||||
normalize(b, scale + r->scale); | |||||
ctx = BN_CTX_new(); | |||||
bn_checkp(ctx); | |||||
bn_check(BN_div(r->number, NULL, b->number, a->number, ctx)); | |||||
BN_CTX_free(ctx); | |||||
} | |||||
push_number(r); | push_number(r); | ||||
free_number(a); | free_number(a); | ||||
free_number(b); | free_number(b); | ||||
} | } | ||||
static void | static void | ||||
bmod(void) | bmod(void) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 571 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void | static void | ||||
parse_number(void) | parse_number(void) | ||||
{ | { | ||||
unreadch(); | unreadch(); | ||||
push_number(readnumber(&bmachine.readstack[bmachine.readsp], | push_number(readnumber(&bmachine.readstack[bmachine.readsp], | ||||
bmachine.ibase)); | bmachine.ibase, bmachine.scale)); | ||||
} | } | ||||
static void | static void | ||||
unknown(void) | unknown(void) | ||||
{ | { | ||||
int ch = bmachine.readstack[bmachine.readsp].lastchar; | int ch = bmachine.readstack[bmachine.readsp].lastchar; | ||||
warnx("%c (0%o) is unimplemented", ch, ch); | warnx("%c (0%o) is unimplemented", ch, ch); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 85 Lines • Show Last 20 Lines |