Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing the bug preventing usage of custom dumpers #151

Closed
wants to merge 1 commit into from
Closed

Fixing the bug preventing usage of custom dumpers #151

wants to merge 1 commit into from

Conversation

KOLANICH
Copy link
Contributor

No description provided.

Copy link
Owner

@berkerpeksag berkerpeksag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please give us more information about your use case? It would be even better if you could share a snippet that demonstrates the bug you're trying to fix.

Thank you!

@KOLANICH
Copy link
Contributor Author

KOLANICH commented Jul 29, 2019

@berkerpeksag,

KaitaiPowerWorkaround.py
from plumbum import cli
from ast import *
import astor  # https://patch-diff.githubusercontent.com/raw/berkerpeksag/astor/pull/151.patch is absolutely needed, as fixes a bug in astor, https://patch-diff.githubusercontent.com/raw/berkerpeksag/astor/pull/152.patch is needed for using hex to make the expr a bit shorter
import typing


class KaitaiGen(astor.SourceGenerator):
	def visit_IfExp(self, node):
		with self.delimit(node) as delimiters:
			astor.code_gen.set_precedence(delimiters.p + 1, node.body, node.test)
			astor.code_gen.set_precedence(delimiters.p, node.orelse)
			self.write("(", node.test, " ? ", node.body, " : ", node.orelse, ")")


def extractPowerOf2(base: int) -> (int, int):
	c = 0
	while base % 2 == 0:
		base //= 2
		c += 1
	return base, c


SGT = typing.Type[KaitaiGen]


def square_and_multiply(base: int, bits: int = 8, argName: str = "log", generator: SGT = None) -> str:
	"""ONLY FOR POSITIVE POWERS!!! Process negative ones yourself."""
	if generator is None:
		generator = KaitaiGen
	baseR, powOf2 = extractPowerOf2(base)

	if powOf2 != 0:
		if powOf2 != 1:
			sh = BinOp(left=Name(id=argName), op=Mult(), right=Num(n=powOf2))
		else:
			sh = Name(id=argName)
		res = BinOp(left=Num(n=1), op=LShift(), right=sh)
	else:
		res = Num(n=1)

	if baseR != 1:
		exp = baseR
		b2Base = 1
		for i in range(bits):
			res = BinOp(
				left=res,
				op=Mult(),
				right=IfExp(
					test=Attribute(
						value=BinOp(
							left=Name(id=argName), op=BitAnd(), right=Num(n=b2Base)
						),
						attr="as<b1>",
					),
					body=Num(n=exp),
					orelse=Num(n=1),
				),
			)
			exp *= exp
			b2Base = b2Base << 1
	return astor.to_source(res, indent_with="", source_generator_class=generator, pretty_source=lambda source: "".join(source)).strip()


class PowerWorkaroundCLI(cli.Application):
	def main(self, base: int, bits: int = 8, argName: str = "log"):
		print("".join("# "+l for l in square_and_multiply.__doc__.splitlines()))
		print('value: "'+square_and_multiply(base, bits, argName)+'"')


if __name__ == "__main__":
	PowerWorkaroundCLI.run()

Please note that the functionality I am fixing in this PR is already present in astor, it is just broken because of a mistake.

@berkerpeksag
Copy link
Owner

Thank you very much! This has been fixed in 51c9e70.

@KOLANICH KOLANICH deleted the patch-1 branch December 8, 2019 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants