-
Notifications
You must be signed in to change notification settings - Fork 0
/
real_api.p
145 lines (122 loc) · 3.84 KB
/
real_api.p
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
compile("libdecnum_api")
compile("decContext_api")
compile("stdio_api")
compile("stdlib_api")
compile("string_api")
use libdecnum_api as real
use stdlib_api as lib
use string_api as str
use stdio_api as io
signature plexus number
plexus numset_t (
real.decQuad_api.decQuad dn,
byte string[256]
)
plexus number (
int size,
numset_t ref set,
real.decContext_api.decContext ref context,
func ref free <> (number ref set),
//
// Since the these are lambdas, they need to be prototyped with ::
// because lambdas use our own ABI
//
func ref printnth ::: (number ref set, int n),
func ref printnthln ::: (number ref set, int n),
func ref print ::: (real.decQuad_api.decQuad ref dn),
func ref println ::: (real.decQuad_api.decQuad ref dn)
)
//
// The way we process the variable arguments is using our own ABI
// since lambda are NOT linux-ABI specific.
// Hence the use of ::: instead of <>
//
signature func init_real_set43 ::: number ref (byte ref args, ...)
//
// If we provide signatures to lambdas then
// it allows us to not cast arguments when ::ing the lambdas.
//
signature func printnth ::: (number ref _ds, int nth)
signature func printnthln ::: (number ref _ds, int nth)
signature func print ::: (real.decQuad_api.decQuad ref dn)
signature func println ::: (real.decQuad_api.decQuad ref dn)
lambda printnth (_ds, nth) <- func {
number ref ds <- cast(_ds to number ref)
::(io.printf, "%s", ds-->set[nth].string)
}
lambda printnthln (_ds, nth) <- func {
number ref ds <- cast(_ds to number ref)
::(io.printf, "%s\n", ds-->set[nth].string)
}
lambda print (_dn) <- func {
real.decQuad_api.decQuad ref dn <- cast(_dn to real.decQuad_api.decQuad ref)
byte string[256]
::(io.printf, "%s", ::(real.decQuad_api.decQuadToString, dn, string))
}
lambda println (_dn) <- func {
real.decQuad_api.decQuad ref dn <- cast(_dn to real.decQuad_api.decQuad ref)
byte string[256]
::(io.printf, "%s\n", ::(real.decQuad_api.decQuadToString, dn, string))
}
//
// Initialize a set of real (decimal) numbers
// with 43 decimal digits.
//
// each subsequent argument is expected to be a string
// represending a decimal numerical value.
//
// the last parameter needs to be 0 to signify end of arguments.
//
// Return a vector (array) of those numbers
// each vector node contains the number and
// its string represendation.
//
func initialize_real_set43 ::: number ref (byte ref args, ...) {
number ref ds
int ref ref va
int i <- 0
int n <- 32
byte ref s
closure setup_context <- {
ds <- cast(::(lib.malloc, capacity of (number)) to number ref)
ds-->context <- cast(::(lib.malloc, capacity of(real.decContext_api.decContext)) to real.decContext_api.decContext ref)
::(real.decApiInit.setDECUnits, 43)
::(real.decApiInit.setDECflags)
::(real.decApiInit.setDECgroupingFlags)
::(real.decContext_api.decContextDefault, ds-->context, real.decContext_api.DEC_INIT_BASE)
ds-->set <- cast(::(lib.malloc, capacity of(numset_t) * n) to numset_t ref)
}
closure init_numbers <- {
va <- cast(addr args to int ref ref)
while true do {
s <- cast(ref va to int ref)
if (not s) then
done
va <- va + 1
::(str.memmove, ds-->set[i].string, s, ::(str.strlen, s)) // gets the null as well
::(real.decQuad_api.decQuadFromString, addr ds-->set[i].dn, s, ds-->context)
i <- i + 1
if i > n then {
n <- n * 2
ds-->set <- cast(::(lib.realloc, cast(ds-->set to byte ref), capacity of(numset_t) * n) to numset_t ref)
}
}
ds-->size <- i
}
closure init_methods <- {
ds-->printnth <- printnth
ds-->printnthln <- printnthln
ds-->print <- print
ds-->println <- println
}
(setup_context)
(init_numbers)
(init_methods)
return (ds)
}
lambda deinitialize_real_set43(_decset) <- func {
number ref ds <- cast(_decset to number ref)
::(lib.free, cast(ds-->set to byte ref))
::(lib.free, cast(ds-->context to byte ref))
::(lib.free, cast(ds to byte ref))
}