@@ -225,6 +225,74 @@ template evalBinOp(c: var EvalContext; n: var Cursor; opr: untyped) {.dirty.} =
225225 else :
226226 evalOrdBinOp (c, n, opr)
227227
228+ proc intToToken (result: var TokenBuf ; x: int ; typ: Cursor ) =
229+ case typ.typeKind
230+ of IT :
231+ result .addIntLit x
232+ of UT :
233+ result .addUIntLit uint x
234+ of CT :
235+ result .add charToken (char x, NoLineInfo )
236+ else :
237+ assert false , " Got unexpected type: " & toString (typ)
238+
239+ proc bitSetToTokens (result: var TokenBuf ; x: seq [uint8 ]; elementTyp: Cursor ; info: PackedLineInfo ) =
240+ result .addParLe SetConstrX , info
241+ result .buildTree TagId (SetT ), NoLineInfo :
242+ result .addSubtree elementTyp
243+
244+ var start = - 1
245+ for i in 0 ..< x.len:
246+ for j in 0 .. 7 :
247+ let val = i * 8 + j
248+ if (x[i] and (1 'u8 shl j)) == 0 :
249+ if start != - 1 :
250+ if val - start < 5 :
251+ for k in start ..< val:
252+ result .intToToken k, elementTyp
253+ else :
254+ result .addParLe RangeU
255+ result .intToToken start, elementTyp
256+ result .intToToken (val - 1 ), elementTyp
257+ result .addParRi
258+ start = - 1
259+ else :
260+ if start == - 1 :
261+ start = val
262+
263+ result .addParRi
264+
265+ proc evalBitSet * (n, typ: Cursor ): seq [uint8 ]
266+
267+ proc evalPlusSet (c: var EvalContext ; n: var Cursor ): Cursor =
268+ let info = n.info
269+ inc n # tag
270+ assert n.typeKind == SetT
271+ var elementTyp = n
272+ inc elementTyp
273+ skip n # skip type
274+ var a = eval (c, n)
275+ var b = eval (c, n)
276+ skipParRi n # skip last parRi
277+ assert a.exprKind == SetConstrX , " got " & toString (a)
278+ assert b.exprKind == SetConstrX , " got " & toString (b)
279+ var typeA = a
280+ inc typeA
281+ var typeB = b
282+ inc typeB
283+ assert sameTrees (typeA, typeB) # must be the same type
284+ let setA = evalBitSet (a, typeA)
285+ let setB = evalBitSet (b, typeB)
286+ assert setA.len == setB.len
287+ var setRes = newSeq [uint8 ](setA.len)
288+ for i in 0 ..< setA.len:
289+ setRes[i] = setA[i] or setB[i]
290+
291+ let valPos = c.values.len
292+ c.values.add createTokenBuf ()
293+ c.values[valPos].bitSetToTokens (setRes, elementTyp, info)
294+ result = cursorAt (c.values[valPos], 0 )
295+
228296proc eval * (c: var EvalContext ; n: var Cursor ): Cursor =
229297 template propagateError (r: Cursor ): Cursor =
230298 let val = r
@@ -408,6 +476,8 @@ proc eval*(c: var EvalContext; n: var Cursor): Cursor =
408476 of CallKinds :
409477 result = evalCall (c, n)
410478 skip n
479+ of PlusSetX :
480+ result = evalPlusSet (c, n)
411481 else :
412482 if n.tagId == ErrT :
413483 result = n
0 commit comments