print("func", node.func.id)
if node.func.id != 'concat':
return [node]
+ if node.keywords: # a repeated list-constant, don't optimise
+ return [node]
return node.args
+# identify SelectableInt pattern
+def identify_sint_mul_pattern(p):
+ if not isinstance(p[3], ast.Constant):
+ return False
+ if not isinstance(p[1], ast.List):
+ return False
+ l = p[1].elts
+ if len(l) != 1:
+ return False
+ elt = l[0]
+ return isinstance(elt, ast.Constant)
+
+
########## Parser (tokens -> AST) ######
# also part of Ply
p[0] = ast.Call(ast.Name("concat"), l, [])
elif p[2] in ['<', '>', '=', '<=', '>=']:
p[0] = binary_ops[p[2]]((p[1], p[3]))
+ elif identify_sint_mul_pattern(p):
+ keywords=[ast.keyword(arg='repeat', value=p[3])]
+ l = p[1].elts
+ p[0] = ast.Call(ast.Name("concat"), l, keywords)
else:
p[0] = ast.BinOp(p[1], binary_ops[p[2]], p[3])
elif len(p) == 3:
lhs[t] = rhs[f]
-def selectconcat(*args):
+def selectconcat(*args, repeat=1):
+ if repeat != 1 and len(args) == 1 and isinstance(args[0], int):
+ args = [SelectableInt(args[0], 1)]
+ if repeat != 1: # multiplies the incoming arguments
+ tmp = []
+ for i in range(repeat):
+ tmp += args
+ args = tmp
res = copy(args[0])
for i in args[1:]:
assert isinstance(i, SelectableInt), "can only concat SIs, sorry"
res.bits += i.bits
res.value = (res.value << i.bits) | i.value
+ print ("concat", repeat, res)
return res