source: proto/s2k/trunk/demo/strtoll/strtoll_demo.py @ 3678

Last change on this file since 3678 was 3678, checked in by ksherdy, 5 years ago

Restructed s2k demo and compiler directory.

File size: 11.5 KB
Line 
1#
2# Ken Herdy
3# Dec 22, 2013
4#
5# Program Flow
6#
7# StreamInput` -> Transpose` -> Classify -> MarkDigits -> StringToInteger -> StreamOutput`
8#                                       
9# Back ticks ` denote functionality provided by a hand-coded C++ template.
10#
11# A very simple example to demonstrate ASCII to integer conversion
12# in a manner similar to the BSD strtoll utility. This demo converts to 16 bit integers.
13#
14# See,
15#
16# - http://linux.die.net/man/3/strtoll,
17# - http://www.opensource.apple.com/source/lukemftp/lukemftp-12/tnftp/libnetbsd/strtoll.c
18#
19# Character Class Definitions
20#
21# lex.ws                = [\x0D\x0A\x09 ]
22# lex.neg   = [-]
23# lex.pos   = [+]
24# lex.sign  = [-+]
25# lex.digit = [0-9]
26#
27# ASCII Base 10 Integer Lexical Grammar.
28#
29# ws*(sign)?digit+
30#
31# Whitespace or Sign Delimited ASCII Base 10 Integers.
32#
33# ws*(sign)?digit+(ws*(sign)?digit+)*
34
35import sys
36from lib import pablo
37from lib import bitutil
38from lib import vstreams
39from lib import hstreams
40from lib import estreams
41from lib import mstreams
42import optparse
43import strtoll_demo_config
44
45class Basis_bits():     
46        bit_7 = 0
47        bit_6 = 0
48        bit_5 = 0
49        bit_4 = 0
50        bit_3 = 0
51        bit_2 = 0
52        bit_1 = 0
53        bit_0 = 0
54
55class Lex():
56        ws              = 0
57        neg   = 0
58        pos   = 0       
59        sign    = 0
60        digit = 0
61
62class Digits():
63        starts                                                          = 0
64        pos_starts                                              = 0
65        neg_starts                                              = 0
66        follows                                                         = 0
67        expect_ws_sign_digit    = 0
68        expect_digit                                    = 0
69        expect_ws_sign                          = 0
70
71def ClassifyBytes(basis_bits, lex):
72        temp1 = (basis_bits.bit_0 | basis_bits.bit_1)
73        temp2 = (basis_bits.bit_2 | basis_bits.bit_3)
74        temp3 = (temp1 | temp2)
75        temp4 = (basis_bits.bit_4 & basis_bits.bit_5)
76        temp5 = (basis_bits.bit_7 &~ basis_bits.bit_6)
77        temp6 = (temp4 & temp5)
78        temp7 = (basis_bits.bit_4 &~ basis_bits.bit_5)
79        temp8 = (basis_bits.bit_6 &~ basis_bits.bit_7)
80        temp9 = (temp7 & temp8)
81        temp10 = (temp6 | temp9)
82        temp11 = (temp7 & temp5)
83        temp12 = (temp10 | temp11)
84        temp13 = (temp12 &~ temp3)
85        temp14 = (basis_bits.bit_2 &~ basis_bits.bit_3)
86        temp15 = (temp14 &~ temp1)
87        temp16 = (basis_bits.bit_4 | basis_bits.bit_5)
88        temp17 = (basis_bits.bit_6 | basis_bits.bit_7)
89        temp18 = (temp16 | temp17)
90        temp19 = (temp15 &~ temp18)
91        lex.ws = (temp13 | temp19)
92        lex.neg = (temp15 & temp6)
93        temp20 = (basis_bits.bit_6 & basis_bits.bit_7)
94        temp21 = (temp7 & temp20)
95        lex.pos = (temp15 & temp21)
96        temp22 = (temp6 | temp21)
97        lex.sign = (temp15 & temp22)
98        temp23 = (basis_bits.bit_2 & basis_bits.bit_3)
99        temp24 = (temp23 &~ temp1)
100        temp25 = (basis_bits.bit_5 | basis_bits.bit_6)
101        temp26 = (basis_bits.bit_4 & temp25)
102        lex.digit = (temp24 &~ temp26)
103
104def MarkDigits(lex, digits):
105        ws_scope1                                                                               = ~pablo.Advance(~lex.ws)
106        pos_scope1                                                                              = pablo.Advance(lex.pos)
107        neg_scope1                                                                              = pablo.Advance(lex.neg)
108        digits.expect_ws_sign_digit             = pablo.inFile(ws_scope1) &~ (lex.ws | lex.sign | lex.digit)
109        digits.expect_digit                                     = pablo.inFile(pos_scope1|neg_scope1) &~ lex.digit
110        digits.pos_starts                                               = (ws_scope1 | pos_scope1) & lex.digit
111        digits.neg_starts                                               = neg_scope1 & lex.digit
112        digits.starts                                                                   =       digits.pos_starts | digits.neg_starts                                           
113        digits.follows                                                          = pablo.ScanThru(digits.starts, lex.digit)
114        digits.expect_ws_sign                           = pablo.inFile(digits.follows) &~ (lex.ws | lex.sign)
115
116basis_bits                                              =       Basis_bits()
117lex                                             = Lex()
118digits                                                  = Digits()
119
120if __name__ == "__main__":
121
122        option_parser = strtoll_demo_config.get_option_parser() 
123        options, args = option_parser.parse_args(sys.argv[1:])
124
125        if len(args) != 1:
126                option_parser.print_usage()
127                sys.exit()
128        else:
129                input_file = args[0]
130
131  # ReadStreamInput(data)
132        global data
133        global lgth
134
135        data = bitutil.readfile(input_file)
136        data = data[:-2] # -1 strip EOF
137
138        data_le                         = data[::-1] # reverse
139        s_76543210                      = bitutil.bytes_to_bstr(data_le)
140        lgth                                            = len(s_76543210)
141        lgth_nybbles            = lgth/2
142        lgth_pairs                      = lgth/4
143        lgth_bits                       = lgth/8
144
145        pablo.EOF_mask = pablo.transpose_streams(data, basis_bits) 
146
147        ClassifyBytes(basis_bits, lex)
148        MarkDigits(lex, digits)
149
150  #
151        ### Demo
152        #       
153        print "Source Data                                 " + bitutil.format_fields(data_le,1) 
154#       print "s_76543210                                  " + bitutil.format_fields(s_76543210)
155        print "pablo.EOF_mask                              " + bitutil.format_fields(bin(pablo.EOF_mask)[2:],1)
156        print "basis_bits_le.bit_7                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_0,lgth_bits),1)
157        print "basis_bits_le.bit_6                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_1,lgth_bits),1)
158        print "basis_bits_le.bit_5                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_2,lgth_bits),1)
159        print "basis_bits_le.bit_4                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_3,lgth_bits),1)
160        print "basis_bits_le.bit_3                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_4,lgth_bits),1)
161        print "basis_bits_le.bit_2                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_5,lgth_bits),1)
162        print "basis_bits_le.bit_1                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_6,lgth_bits),1)
163        print "basis_bits_le.bit_0                         " + bitutil.format_fields(bitutil.strm_to_bstr(basis_bits.bit_7,lgth_bits),1)
164        print "lex.neg                                     " + bitutil.format_fields(bitutil.strm_to_bstr(lex.neg,lgth_bits),1)
165        print "lex.pos                                     " + bitutil.format_fields(bitutil.strm_to_bstr(lex.pos,lgth_bits),1)
166        print "lex.digit                                   " + bitutil.format_fields(bitutil.strm_to_bstr(lex.digit,lgth_bits),1)
167
168        # BitBlock ascii_lo_4                                                   = hsimd<8>::packl(source_lo_128, source_hi_128);
169        ascii_lo_4 = hstreams.packl(8, bitutil.bstr_to_strm(s_76543210), lgth)
170        print "stream<4> ascii_lo_4 = packl(4, s_76543210) " + bitutil.format_fields(bitutil.strm_to_bstr(ascii_lo_4, lgth_nybbles), 4) 
171
172        ###     Reverse nybbles using inductive doubling and rotation 
173 
174        #       BitBlock digits_rot_4                           = simd_or(simd<8>::slli<4>(ascii_lo_4), simd<8>::srli<4>(ascii_lo_4));
175        digits_rot_4 = mstreams.slli(8,4,ascii_lo_4, lgth_nybbles) | mstreams.srli(8,4,ascii_lo_4, lgth_nybbles)
176        print "digits_rot_4                                " + bitutil.format_fields(bitutil.strm_to_bstr(digits_rot_4, lgth_nybbles), 4)
177
178        #       BitBlock digits_rot_8                           = simd_or(simd<16>::slli<8>(digits_rot_4), simd<16>::srli<8>(digits_rot_4));
179        digits_rot_8 = mstreams.slli(16,8,digits_rot_4, lgth_nybbles) | mstreams.srli(16,8,digits_rot_4, lgth_nybbles)
180        print "digits_rot_8                                " + bitutil.format_fields(bitutil.strm_to_bstr(digits_rot_8, lgth_nybbles), 4)
181
182        #       BitBlock digits_rot_16                          = simd_or(simd<32>::slli<16>(digits_rot_8), simd<32>::srli<16>(digits_rot_8));
183        digits_rot_16 = mstreams.slli(32,16,digits_rot_8, lgth_nybbles) | mstreams.srli(32,16,digits_rot_8, lgth_nybbles)
184        print "digits_rot_16                               " + bitutil.format_fields(bitutil.strm_to_bstr(digits_rot_16, lgth_nybbles), 4)
185
186
187        ### Parallel ASCII to integer conversion (aligned 8 byte ASCII values to 16 bit integer values)
188
189        # Step 1 - Convert nybble pairs
190        digits_hi_4                                     = mstreams.srli(8,4,digits_rot_16, lgth_nybbles)
191        lomask_8                                                = vstreams.lomask(8, lgth_nybbles);
192        digits_lo_4                                     = digits_rot_16 & lomask_8
193        constant_10                                     = vstreams.constant(8,10, lgth_nybbles);
194        temp_10s                                                = vstreams.mul(8,digits_hi_4, constant_10, lgth_nybbles);       # TODO bitcast to 8
195        result_10s                                      = vstreams.add(8,temp_10s, digits_lo_4, lgth_nybbles);
196
197        print "digits_hi_4                                 " + bitutil.format_fields(bitutil.strm_to_bstr(digits_hi_4, lgth_nybbles), 4)       
198        print "lomask_8                                    " + bitutil.format_fields(bitutil.strm_to_bstr(lomask_8, lgth_nybbles), 4)
199        print "digits_lo_4                                 " + bitutil.format_fields(bitutil.strm_to_bstr(digits_lo_4, lgth_nybbles), 4)
200        print "constant_10                                 " + bitutil.format_fields(bitutil.strm_to_bstr(constant_10, lgth_nybbles), 4)
201        print "temp_10s                                    " + bitutil.format_fields(bitutil.strm_to_bstr(temp_10s, lgth_nybbles), 8)
202        print "result_10s                                  " + bitutil.format_fields(bitutil.strm_to_bstr(result_10s, lgth_nybbles), 8)
203
204        # Step 2 - Convert byte pairs
205
206        digits_hi_8                                     = mstreams.srli(8*2,4*2, result_10s, lgth_nybbles)
207        lomask_16                                       = vstreams.lomask(8*2, lgth_nybbles);
208        digits_lo_8                                     = result_10s & lomask_16
209        constant_100                            = vstreams.constant(8*2,10*10, lgth_nybbles);
210        temp_100s                                               = vstreams.mul(8*2,digits_hi_8, constant_100, lgth_nybbles);    # TODO bitcast to 8
211        result_100s                                     = vstreams.add(8*2,temp_100s, digits_lo_8, lgth_nybbles);
212
213        print "digits_hi_8                                 " + bitutil.format_fields(bitutil.strm_to_bstr(digits_hi_8, lgth_nybbles), 8)       
214        print "lomask_16                                   " + bitutil.format_fields(bitutil.strm_to_bstr(lomask_16, lgth_nybbles), 8)
215        print "digits_lo_8                                 " + bitutil.format_fields(bitutil.strm_to_bstr(digits_lo_8, lgth_nybbles), 8)
216        print "constant_100                                " + bitutil.format_fields(bitutil.strm_to_bstr(constant_100, lgth_nybbles), 8)
217        print "temp_100s                                   " + bitutil.format_fields(bitutil.strm_to_bstr(temp_100s, lgth_nybbles), 16)
218        print "result_100s                                 " + bitutil.format_fields(bitutil.strm_to_bstr(result_100s, lgth_nybbles), 16)
219
220        # Step 3 - Convert double-byte pairs
221
222        digits_hi_16                            = mstreams.srli(8*2*2,4*2*2, result_100s, lgth_nybbles)
223        lomask_32                                       = vstreams.lomask(8*2*2, lgth_nybbles);
224        digits_lo_16                            = result_100s & lomask_32
225        constant_10000                  = vstreams.constant(8*2*2,10*10*10*10, lgth_nybbles);
226        temp_10000s                                     = vstreams.mul(8*2*2,digits_hi_16, constant_10000, lgth_nybbles);       # TODO bitcast to 8
227        result_10000s                           = vstreams.add(8*2*2,temp_10000s, digits_lo_16, lgth_nybbles);
228
229        print "digits_hi_16                                " + bitutil.format_fields(bitutil.strm_to_bstr(digits_hi_16, lgth_nybbles), 8)       
230        print "lomask_32                                   " + bitutil.format_fields(bitutil.strm_to_bstr(lomask_32, lgth_nybbles), 8)
231        print "digits_lo_16                                " + bitutil.format_fields(bitutil.strm_to_bstr(digits_lo_16, lgth_nybbles), 8)
232        print "constant_1000                               " + bitutil.format_fields(bitutil.strm_to_bstr(constant_10000, lgth_nybbles), 8)
233        print "temp_10000s                                 " + bitutil.format_fields(bitutil.strm_to_bstr(temp_10000s, lgth_nybbles), 16)
234        print "result_10000s                               " + bitutil.format_fields(bitutil.strm_to_bstr(result_10000s, lgth_nybbles), 16)
235
236        pack_result_10000s      = hstreams.packl(32,result_10000s,lgth_nybbles)
237        print "pack_result_10000s                          " + bitutil.format_fields(bitutil.strm_to_bstr(pack_result_10000s, lgth_nybbles/2), 16)
238
239  # WriteStreamOutput(Output)
240
241#
242### Some Samples
243#
244
245#       t                                               = vstreams.add_hl(8,s_76543210)
246#       t                                               = vstreams.add_hl(4,s_7654)
247# t                                             = vstreams.add_hl(2,s_10)
248#       t                                               = vstreams.lomask(2,s_10)
249#       t                                               = vstreams.himask(4,s_3210)
250#       t                                               = vstreams.himask(8,s_76543210)
251#       t                                               = vstreams.constant(4,10,s_3210)
252#       t                                               = vstreams.constant(8,100,s_76543210)
253
254#       m                                       = vstreams.AndC(cast.bitcast(1,s_76543210), cast.bitcast(1,flow.Advance(s_76543210)))
255#       s                                               = cast.bitcast(24,s_76543210)
256#       r                                               = flow.ScanThru(m,s)
257
258#       t                                               = cast.bitcast(8, r)
259#       m                                       = cast.bitcast(8,m)
260#       s                                       = cast.bitcast(8,s)
261#       t                                       = cast.bitcast(8,t)
262
263#       t                                       = estreams.paligned_extract(8, 8, m, s_76543210)
264
265# if a strm had a length we would know how to pad out the zeroes before the chop
266
Note: See TracBrowser for help on using the repository browser.