-
Notifications
You must be signed in to change notification settings - Fork 9
/
string.integer.spin
186 lines (141 loc) · 6.42 KB
/
string.integer.spin
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
' Original authors: Chip Gracey, Jon Williams
{{
Provides simple numeric conversion methods; all methods return a pointer to
a string.
}}
CON
MAX_LEN = 64 ' 63 chars + zero terminator
VAR
long idx ' pointer into string
byte nstr[MAX_LEN] ' string for numeric data
PUB Dec(value)
{{
Returns pointer to signed-decimal string
}}
ClearStr(@nstr, MAX_LEN) ' clear output string
return DecToStr(value) ' return pointer to numeric string
PUB DecPadded(value, width) | t_val, field
{{
Returns pointer to signed-decimal, fixed-width (space padded) string
}}
ClearStr(@nstr, MAX_LEN)
width := 1 #> width <# constant(MAX_LEN - 1) ' qualify field width
t_val := ||value ' work with absolute
field~ ' clear field
repeat while t_val > 0 ' count number of digits
field++
t_val /= 10
field #>= 1 ' min field width is 1
if value < 0 ' if value is negative
field++ ' bump field for neg sign indicator
if field < width ' need padding?
repeat (width - field) ' yes
nstr[idx++] := " " ' pad with space(s)
return DecToStr(value)
PUB DecZeroed(value, digits) | div
{{
Returns pointer to zero-padded, signed-decimal string
-- if value is negative, field width is digits+1
}}
ClearStr(@nstr, MAX_LEN)
digits := 1 #> digits <# 10
if (value < 0) ' negative value?
-value ' yes, make positive
nstr[idx++] := "-" ' and print sign indicator
div := 1_000_000_000 ' initialize divisor
if digits < 10 ' less than 10 digits?
repeat (10 - digits) ' yes, adjust divisor
div /= 10
value //= (div * 10) ' truncate unused digits
repeat digits
nstr[idx++] := (value / div + "0") ' convert digit to ASCII
value //= div ' update value
div /= 10 ' update divisor
return @nstr
PUB Hex(value, digits)
{{
Returns pointer to a digits-wide hexadecimal string
}}
ClearStr(@nstr, MAX_LEN)
return HexToStr(value, digits)
PUB HexIndicated(value, digits)
{{
Returns pointer to a digits-wide, indicated (with $) hexadecimal string
}}
ClearStr(@nstr, MAX_LEN)
nstr[idx++] := "$"
return HexToStr(value, digits)
PUB Bin(value, digits)
{{
Returns pointer to a digits-wide binary string
}}
ClearStr(@nstr, MAX_LEN)
return BinToStr(value, digits)
PUB BinIndicated(value, digits)
{{
Returns pointer to a digits-wide, indicated (with %) binary string
}}
ClearStr(@nstr, MAX_LEN)
nstr[idx++] := "%" ' preface with binary indicator
return BinToStr(value, digits)
PRI ClearStr(strAddr, size)
{{
Clears string at strAddr
-- also resets global character pointer (idx)
}}
bytefill(strAddr, 0, size) ' clear string to zeros
idx~ ' reset index
PRI DecToStr(value) | div, z_pad
{{
Converts value to signed-decimal string equivalent
-- characters written to current position of idx
-- returns pointer to nstr
}}
if (value < 0) ' negative value?
-value ' yes, make positive
nstr[idx++] := "-" ' and print sign indicator
div := 1_000_000_000 ' initialize divisor
z_pad~ ' clear zero-pad flag
repeat 10
if (value => div) ' printable character?
nstr[idx++] := (value / div + "0") ' yes, print ASCII digit
value //= div ' update value
z_pad~~ ' set zflag
elseif z_pad or (div == 1) ' printing or last column?
nstr[idx++] := "0"
div /= 10
return @nstr
PRI HexToStr(value, digits)
{{
Converts value to digits-wide hexadecimal string equivalent
-- characters written to current position of idx
-- returns pointer to nstr
}}
digits := 1 #> digits <# 8 ' qualify digits
value <<= (8 - digits) << 2 ' prep most significant digit
repeat digits
nstr[idx++] := lookupz((value <-= 4) & $F : "0".."9", "A".."F")
return @nstr
PRI BinToStr(value, digits)
{{
Converts value to digits-wide binary string equivalent
-- characters written to current position of idx
-- returns pointer to nstr
}}
digits := 1 #> digits <# 32 ' qualify digits
value <<= 32 - digits ' prep MSB
repeat digits
nstr[idx++] := (value <-= 1) & 1 + "0" ' move digits (ASCII) to string
return @nstr
PUB StrToBase(stringptr, base) : value | chr, index
{{
Converts a zero terminated string representation of a number to a value in the designated base.
Ignores all non-digit characters (except negative (-) when base is decimal (10)).
}}
value := index := 0
repeat until ((chr := byte[stringptr][index++]) == 0)
chr := -15 + --chr & %11011111 + 39*(chr > 56) ' Make "0"-"9","A"-"F","a"-"f" be 0 - 15, others out of range
if (chr > -1) and (chr < base) ' Accumulate valid values into result; ignore others
value := value * base + chr
if (base == 10) and (byte[stringptr] == "-") ' If decimal, address negative sign; ignore otherwise
value := - value