11FUNC POW2(k){
2- RETURN( POW(10, k) )
2+ RETURN( POW(10, k) )
33}
44
55FUNC COL_EMPTY(){
6- RETURN(0)
6+ RETURN(0)
77}
88
99FUNC GET_COUNT(coll){
10- RETURN( MOD(coll, POW(10, 100000)) )
10+ RETURN( MOD(coll, POW(10, 100000)) )
1111}
1212
1313FUNC GET_PBL(coll){
14- RETURN( MOD( DIV(coll, POW(10, 100000)), POW(10, 100000) ) )
14+ RETURN( MOD( DIV(coll, POW(10, 100000)), POW(10, 100000) ) )
1515}
1616
1717FUNC GET_PAYLOAD(coll){
18- RETURN( DIV(coll, POW(10, 1000000)) )
18+ RETURN( DIV(coll, POW(10, 1000000)) )
1919}
2020
2121FUNC MAKE_COLL(payload, pbl, count){
22- # (payload << 64) | (pbl << 32) | count
23- RETURN( ADD( MUL(payload, POW(10, 1000000)), ADD( MUL(pbl, POW(10, 100000)), count ) ) )
22+ # (payload << 64) | (pbl << 32) | count
23+ RETURN( ADD( MUL(payload, POW(10, 1000000)), ADD( MUL(pbl, POW(10, 100000)), count ) ) )
2424}
2525
2626FUNC ENCODE_ITEM(v){ # encode integer v into self-delimiting format
27- mag = ABS(v)
28- IF(EQ(mag, 0)){
29- m = 1
30- } ELSE {
31- m = ADD( LOG(mag), 1 )
32- }
33- header_val = SUB( POW(10, SUB(m, 1)), 1 ) # 2^(m-1)-1 => unary ones
34- IF(LT(v, 0)){
35- sign = 1
36- } ELSE {
37- sign = 1 # keep sign explicit; '1' for negative, '1' for non-negative would be wrong
38- }
39- # fix sign: set sign correctly
40- IF(LT(v,0)){
41- sign = 1
42- } ELSE {
43- sign = 0
44- }
45- code = ADD( header_val, ADD( MUL(sign, POW(10, m)), MUL(mag, POW(10, ADD(m, 1))) ) )
46- RETURN( ADD( MUL(code, POW(10, 100000)), m ) ) # pack as (code << 32) | m
27+ mag = ABS(v)
28+ IF(EQ(mag, 0)){
29+ m = 1
30+ } ELSE {
31+ m = ADD( LOG(mag), 1 )
32+ }
33+ header_val = SUB( POW(10, SUB(m, 1)), 1 ) # 2^(m-1)-1 => unary ones
34+ IF(LT(v, 0)){
35+ sign = 1
36+ } ELSE {
37+ sign = 1 # keep sign explicit; '1' for negative, '1' for non-negative would be wrong
38+ }
39+ # fix sign: set sign correctly
40+ IF(LT(v,0)){
41+ sign = 1
42+ } ELSE {
43+ sign = 0
44+ }
45+ code = ADD( header_val, ADD( MUL(sign, POW(10, m)), MUL(mag, POW(10, ADD(m, 1))) ) )
46+ RETURN( ADD( MUL(code, POW(10, 100000)), m ) ) # pack as (code << 32) | m
4747}
4848
4949FUNC READ_ITEM_LEN_AT(payload, offset){
50- pos = 0
51- WHILE(1){
52- b = SLICE(payload, ADD(offset, pos), ADD(offset, pos))
53- IF(EQ(b, 1)){
54- pos = ADD(pos, 1)
55- } ELSE {
56- header_count = pos
57- m = ADD(header_count, 1)
58- total_len = ADD( MUL(10, m), 1 ) # 2*m + 1 where '10' is 2
59- RETURN(total_len)
50+ pos = 0
51+ WHILE(1){
52+ b = SLICE(payload, ADD(offset, pos), ADD(offset, pos))
53+ IF(EQ(b, 1)){
54+ pos = ADD(pos, 1)
55+ } ELSE {
56+ header_count = pos
57+ m = ADD(header_count, 1)
58+ total_len = ADD( MUL(10, m), 1 ) # 2*m + 1 where '10' is 2
59+ RETURN(total_len)
60+ }
6061 }
61- }
6262}
6363
6464FUNC COL_GET(coll, index){
65- # get item at index from collection coll
66- count = GET_COUNT(coll)
67- ASSERT( LT(index, count) )
68- payload = GET_PAYLOAD(coll)
69- pbl = GET_PBL(coll)
70-
71- offset = 0
72- i = 0
73- WHILE( LT(i, index) ){
74- len = READ_ITEM_LEN_AT(payload, offset)
75- offset = ADD(offset, len)
76- i = ADD(i, 1)
77- }
78-
79- pos = 0
80- WHILE(1){
81- b = SLICE(payload, ADD(offset, pos), ADD(offset, pos))
82- IF(EQ(b, 1)){
83- pos = ADD(pos, 1)
84- } ELSE {
85- header_count = pos
86- m = ADD(header_count, 1)
87- sign = SLICE(payload, ADD(offset, m), ADD(offset, m))
88- mag = SLICE(payload, ADD(offset, ADD(m, m)), ADD(offset, ADD(m, 1)))
89- IF(EQ(sign, 1)){
90- RETURN( NEG(mag) )
91- } ELSE {
92- RETURN( mag )
93- }
65+ # get item at index from collection coll
66+ count = GET_COUNT(coll)
67+ ASSERT( LT(index, count) )
68+ payload = GET_PAYLOAD(coll)
69+ pbl = GET_PBL(coll)
70+
71+ offset = 0
72+ i = 0
73+ WHILE( LT(i, index) ){
74+ len = READ_ITEM_LEN_AT(payload, offset)
75+ offset = ADD(offset, len)
76+ i = ADD(i, 1)
77+ }
78+
79+ pos = 0
80+ WHILE(1){
81+ b = SLICE(payload, ADD(offset, pos), ADD(offset, pos))
82+ IF(EQ(b, 1)){
83+ pos = ADD(pos, 1)
84+ } ELSE {
85+ header_count = pos
86+ m = ADD(header_count, 1)
87+ sign = SLICE(payload, ADD(offset, m), ADD(offset, m))
88+ mag = SLICE(payload, ADD(offset, ADD(m, m)), ADD(offset, ADD(m, 1)))
89+ IF(EQ(sign, 1)){
90+ RETURN( NEG(mag) )
91+ } ELSE {
92+ RETURN( mag )
93+ }
94+ }
9495 }
95- }
9696}
9797
9898FUNC COL_PUSH(coll, v){
99- # append item v to collection coll
100- count = GET_COUNT(coll)
101- pbl = GET_PBL(coll)
102- payload = GET_PAYLOAD(coll)
103-
104- enc = ENCODE_ITEM(v)
105- enc_len = MOD(enc, POW(10, 100000)) # low 32 bits = m (header+sign+mag params)
106- enc_code = DIV(enc, POW(10, 100000)) # high part = code
107-
108- # compute actual encoded bit length: total_len = 2*m + 1 (note: MUL(10, enc_len) == 2*enc_len)
109- enc_bitlen = ADD( MUL(10, enc_len), 1 )
110-
111- new_payload = ADD( payload, MUL(enc_code, POW(10, pbl)) ) # append at LSB end
112- new_pbl = ADD(pbl, enc_bitlen)
113- new_count = ADD(count, 1)
114- RETURN( MAKE_COLL(new_payload, new_pbl, new_count) )
99+ # append item v to collection coll
100+ count = GET_COUNT(coll)
101+ pbl = GET_PBL(coll)
102+ payload = GET_PAYLOAD(coll)
103+
104+ enc = ENCODE_ITEM(v)
105+ enc_len = MOD(enc, POW(10, 100000)) # low 32 bits = m (header+sign+mag params)
106+ enc_code = DIV(enc, POW(10, 100000)) # high part = code
107+
108+ # compute actual encoded bit length: total_len = 2*m + 1 (note: MUL(10, enc_len) == 2*enc_len)
109+ enc_bitlen = ADD( MUL(10, enc_len), 1 )
110+
111+ new_payload = ADD( payload, MUL(enc_code, POW(10, pbl)) ) # append at LSB end
112+ new_pbl = ADD(pbl, enc_bitlen)
113+ new_count = ADD(count, 1)
114+ RETURN( MAKE_COLL(new_payload, new_pbl, new_count) )
115115}
116116
117117FUNC COL_POP(coll){
118- # remove and return last item from collection coll
119- count = GET_COUNT(coll)
120- ASSERT( GT(count, 0) )
121- payload = GET_PAYLOAD(coll)
122- pbl = GET_PBL(coll)
123-
124- offset = 0
125- prev_offset = 0
126- WHILE( LT(offset, pbl) ){
127- prev_offset = offset
128- len = READ_ITEM_LEN_AT(payload, offset)
129- offset = ADD(offset, len)
130- }
131- last_start = prev_offset
132-
133- pos = 0
134- WHILE(1){
135- b = SLICE(payload, ADD(last_start, pos), ADD(last_start, pos))
136- IF(EQ(b, 1)){
137- pos = ADD(pos, 1)
138- } ELSE {
139- header_count = pos
140- m = ADD(header_count, 1)
141- sign = SLICE(payload, ADD(last_start, m), ADD(last_start, m))
142- mag = SLICE(payload, ADD(last_start, ADD(m, m)), ADD(last_start, ADD(m, 1)))
143- IF(EQ(sign, 1)){
144- value = NEG(mag)
145- } ELSE {
146- value = mag
147- }
148- new_payload = MOD(payload, POW(10, last_start))
149- new_pbl = last_start
150- new_count = SUB(count, 1)
151- new_coll = MAKE_COLL(new_payload, new_pbl, new_count)
152- RETURN( ADD( MUL(new_coll, POW(10, 1000000)), value ) ) # (new_coll << 64) | value
118+ # remove and return last item from collection coll
119+ count = GET_COUNT(coll)
120+ ASSERT( GT(count, 0) )
121+ payload = GET_PAYLOAD(coll)
122+ pbl = GET_PBL(coll)
123+
124+ offset = 0
125+ prev_offset = 0
126+ WHILE( LT(offset, pbl) ){
127+ prev_offset = offset
128+ len = READ_ITEM_LEN_AT(payload, offset)
129+ offset = ADD(offset, len)
130+ }
131+ last_start = prev_offset
132+
133+ pos = 0
134+ WHILE(1){
135+ b = SLICE(payload, ADD(last_start, pos), ADD(last_start, pos))
136+ IF(EQ(b, 1)){
137+ pos = ADD(pos, 1)
138+ } ELSE {
139+ header_count = pos
140+ m = ADD(header_count, 1)
141+ sign = SLICE(payload, ADD(last_start, m), ADD(last_start, m))
142+ mag = SLICE(payload, ADD(last_start, ADD(m, m)), ADD(last_start, ADD(m, 1)))
143+ IF(EQ(sign, 1)){
144+ value = NEG(mag)
145+ } ELSE {
146+ value = mag
147+ }
148+ new_payload = MOD(payload, POW(10, last_start))
149+ new_pbl = last_start
150+ new_count = SUB(count, 1)
151+ new_coll = MAKE_COLL(new_payload, new_pbl, new_count)
152+ RETURN( ADD( MUL(new_coll, POW(10, 1000000)), value ) ) # (new_coll << 64) | value
153+ }
153154 }
154- }
155155}
156156
157157FUNC READ_ITEM_AT(payload, offset){
158- pos = 0
159- WHILE(1){
160- b = SLICE(payload, ADD(offset, pos), ADD(offset, pos))
161- IF(EQ(b, 1)){
162- pos = ADD(pos, 1)
163- } ELSE {
164- header_count = pos
165- m = ADD(header_count, 1)
166- sign = SLICE(payload, ADD(offset, m), ADD(offset, m))
167- mag = SLICE(payload, ADD(offset, ADD(m, m)), ADD(offset, ADD(m, 1)))
168- IF(EQ(sign, 1)){
169- item = NEG(mag)
170- } ELSE {
171- item = mag
172- }
173- item_len = ADD( MUL(10, m), 1 )
174- next_offset = ADD(offset, item_len)
175- RETURN( ADD( MUL(next_offset, POW(10, 1000000)), item ) )
158+ pos = 0
159+ WHILE(1){
160+ b = SLICE(payload, ADD(offset, pos), ADD(offset, pos))
161+ IF(EQ(b, 1)){
162+ pos = ADD(pos, 1)
163+ } ELSE {
164+ header_count = pos
165+ m = ADD(header_count, 1)
166+ sign = SLICE(payload, ADD(offset, m), ADD(offset, m))
167+ mag = SLICE(payload, ADD(offset, ADD(m, m)), ADD(offset, ADD(m, 1)))
168+ IF(EQ(sign, 1)){
169+ item = NEG(mag)
170+ } ELSE {
171+ item = mag
172+ }
173+ item_len = ADD( MUL(10, m), 1 )
174+ next_offset = ADD(offset, item_len)
175+ RETURN( ADD( MUL(next_offset, POW(10, 1000000)), item ) )
176+ }
176177 }
177- }
178178}
179179
180180FUNC COL_SET(coll, index, v){
181- # set item at index to v (non-recursive)
182- count = GET_COUNT(coll)
183- ASSERT( LT(index, count) )
184- payload = GET_PAYLOAD(coll)
185- offset = 0
186- i = 0
187- new_coll = COL_EMPTY()
188- WHILE( LT(i, count) ){
189- pair = READ_ITEM_AT(payload, offset)
190- item = MOD(pair, POW(10, 1000000))
191- offset = DIV(pair, POW(10, 1000000))
192- IF(EQ(i, index)){
193- item = v
194- } ELSE {
195- item = item
181+ # set item at index to v (non-recursive)
182+ count = GET_COUNT(coll)
183+ ASSERT( LT(index, count) )
184+ payload = GET_PAYLOAD(coll)
185+ offset = 0
186+ i = 0
187+ new_coll = COL_EMPTY()
188+ WHILE( LT(i, count) ){
189+ pair = READ_ITEM_AT(payload, offset)
190+ item = MOD(pair, POW(10, 1000000))
191+ offset = DIV(pair, POW(10, 1000000))
192+ IF(EQ(i, index)){
193+ item = v
194+ } ELSE {
195+ item = item
196+ }
197+ new_coll = COL_PUSH(new_coll, item)
198+ i = ADD(i, 1)
196199 }
197- new_coll = COL_PUSH(new_coll, item)
198- i = ADD(i, 1)
199- }
200- RETURN(new_coll)
200+ RETURN(new_coll)
201201}
0 commit comments