Pass indentation context into expression rendering for upcoming function definition support.
This commit is contained in:
parent
351e7060b8
commit
3a9b3a7b3c
@ -110,27 +110,31 @@ class Statement(ConvertedAction):
|
|||||||
raise NotImplementedError(f"{self.__class__.__name__} does not implement render()!")
|
raise NotImplementedError(f"{self.__class__.__name__} does not implement render()!")
|
||||||
|
|
||||||
|
|
||||||
def object_ref(obj: Any) -> str:
|
def object_ref(obj: Any, parent_prefix: str) -> str:
|
||||||
if isinstance(obj, (GenericObject, Variable, Member, MethodCall, FunctionCall)):
|
if isinstance(obj, (GenericObject, Variable, Member, MethodCall, FunctionCall, Register)):
|
||||||
return obj.render(nested=True)
|
return obj.render(parent_prefix, nested=True)
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Unsupported objectref {obj} ({type(obj)})")
|
raise Exception(f"Unsupported objectref {obj} ({type(obj)})")
|
||||||
|
|
||||||
|
|
||||||
def value_ref(param: Any, parens: bool = False) -> str:
|
def value_ref(param: Any, parent_prefix: str, parens: bool = False) -> str:
|
||||||
if isinstance(param, Expression):
|
if isinstance(param, StringConstant):
|
||||||
return param.render(nested=parens)
|
# Treat this as a string constant.
|
||||||
|
return repr(param.render(parent_prefix))
|
||||||
|
elif isinstance(param, Expression):
|
||||||
|
return param.render(parent_prefix, nested=parens)
|
||||||
elif isinstance(param, (str, int, float)):
|
elif isinstance(param, (str, int, float)):
|
||||||
return repr(param)
|
return repr(param)
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Unsupported valueref {param} ({type(param)})")
|
raise Exception(f"Unsupported valueref {param} ({type(param)})")
|
||||||
|
|
||||||
|
|
||||||
def name_ref(param: Any) -> str:
|
def name_ref(param: Any, parent_prefix: str) -> str:
|
||||||
|
# Reference a name, so strings should not be quoted.
|
||||||
if isinstance(param, str):
|
if isinstance(param, str):
|
||||||
return param
|
return param
|
||||||
elif isinstance(param, StringConstant):
|
elif isinstance(param, StringConstant):
|
||||||
return param.render()
|
return param.render(parent_prefix)
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Unsupported nameref {param} ({type(param)})")
|
raise Exception(f"Unsupported nameref {param} ({type(param)})")
|
||||||
|
|
||||||
@ -202,10 +206,10 @@ class ExpressionStatement(Statement):
|
|||||||
self.expr = expr
|
self.expr = expr
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"{self.expr.render()}"
|
return f"{self.expr.render('')}"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
return [f"{prefix}{self.expr.render()};"]
|
return [f"{prefix}{self.expr.render(prefix)};"]
|
||||||
|
|
||||||
|
|
||||||
class StopMovieStatement(Statement):
|
class StopMovieStatement(Statement):
|
||||||
@ -232,11 +236,11 @@ class DebugTraceStatement(Statement):
|
|||||||
self.trace = trace
|
self.trace = trace
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
trace = value_ref(self.trace)
|
trace = value_ref(self.trace, "")
|
||||||
return f"builtin_DebugTrace({trace})"
|
return f"builtin_DebugTrace({trace})"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
trace = value_ref(self.trace)
|
trace = value_ref(self.trace, prefix)
|
||||||
return [f"{prefix}builtin_DebugTrace({trace});"]
|
return [f"{prefix}builtin_DebugTrace({trace});"]
|
||||||
|
|
||||||
|
|
||||||
@ -246,11 +250,11 @@ class GotoFrameStatement(Statement):
|
|||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
frame = value_ref(self.frame)
|
frame = value_ref(self.frame, "")
|
||||||
return f"builtin_GotoFrame({frame})"
|
return f"builtin_GotoFrame({frame})"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
frame = value_ref(self.frame)
|
frame = value_ref(self.frame, prefix)
|
||||||
return [f"{prefix}builtin_GotoFrame({frame});"]
|
return [f"{prefix}builtin_GotoFrame({frame});"]
|
||||||
|
|
||||||
|
|
||||||
@ -262,15 +266,15 @@ class CloneSpriteStatement(Statement):
|
|||||||
self.depth = depth
|
self.depth = depth
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
obj = object_ref(self.obj_to_clone)
|
obj = object_ref(self.obj_to_clone, "")
|
||||||
name = value_ref(self.name)
|
name = value_ref(self.name, "")
|
||||||
depth = value_ref(self.depth)
|
depth = value_ref(self.depth, "")
|
||||||
return f"builtin_CloneSprite({obj}, {name}, {depth})"
|
return f"builtin_CloneSprite({obj}, {name}, {depth})"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
obj = object_ref(self.obj_to_clone)
|
obj = object_ref(self.obj_to_clone, prefix)
|
||||||
name = value_ref(self.name)
|
name = value_ref(self.name, prefix)
|
||||||
depth = value_ref(self.depth)
|
depth = value_ref(self.depth, prefix)
|
||||||
return [f"{prefix}builtin_CloneSprite({obj}, {name}, {depth});"]
|
return [f"{prefix}builtin_CloneSprite({obj}, {name}, {depth});"]
|
||||||
|
|
||||||
|
|
||||||
@ -281,13 +285,13 @@ class ArithmeticExpression(Expression):
|
|||||||
self.right = right
|
self.right = right
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
left = value_ref(self.left, parens=True)
|
left = value_ref(self.left, "", parens=True)
|
||||||
right = value_ref(self.right, parens=True)
|
right = value_ref(self.right, "", parens=True)
|
||||||
return f"{left} {self.op} {right}"
|
return f"{left} {self.op} {right}"
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
left = value_ref(self.left, parens=True)
|
left = value_ref(self.left, parent_prefix, parens=True)
|
||||||
right = value_ref(self.right, parens=True)
|
right = value_ref(self.right, parent_prefix, parens=True)
|
||||||
|
|
||||||
if nested and self.op == '-':
|
if nested and self.op == '-':
|
||||||
return f"({left} {self.op} {right})"
|
return f"({left} {self.op} {right})"
|
||||||
@ -301,10 +305,10 @@ class Array(Expression):
|
|||||||
self.params = params
|
self.params = params
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.render()
|
return self.render("")
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
params = [value_ref(param) for param in self.params]
|
params = [value_ref(param, parent_prefix) for param in self.params]
|
||||||
return f"[{', '.join(params)}]"
|
return f"[{', '.join(params)}]"
|
||||||
|
|
||||||
|
|
||||||
@ -315,29 +319,35 @@ class FunctionCall(Expression):
|
|||||||
self.params = params
|
self.params = params
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.render()
|
return self.render("")
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, parent_prefix)
|
||||||
params = [value_ref(param) for param in self.params]
|
params = [value_ref(param, parent_prefix) for param in self.params]
|
||||||
return f"{name}({', '.join(params)})"
|
return f"{name}({', '.join(params)})"
|
||||||
|
|
||||||
|
|
||||||
class MethodCall(Expression):
|
class MethodCall(Expression):
|
||||||
# Call a method on an object.
|
# Call a method on an object.
|
||||||
def __init__(self, objectref: Any, name: Union[str, StringConstant], params: List[Any]) -> None:
|
def __init__(self, objectref: Any, name: Union[str, int, Expression], params: List[Any]) -> None:
|
||||||
self.objectref = objectref
|
self.objectref = objectref
|
||||||
self.name = name
|
self.name = name
|
||||||
self.params = params
|
self.params = params
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.render()
|
return self.render("")
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
obj = object_ref(self.objectref)
|
try:
|
||||||
name = name_ref(self.name)
|
obj = object_ref(self.objectref, parent_prefix)
|
||||||
params = [value_ref(param) for param in self.params]
|
name = name_ref(self.name, parent_prefix)
|
||||||
|
params = [value_ref(param, parent_prefix) for param in self.params]
|
||||||
return f"{obj}.{name}({', '.join(params)})"
|
return f"{obj}.{name}({', '.join(params)})"
|
||||||
|
except Exception:
|
||||||
|
obj = object_ref(self.objectref, parent_prefix)
|
||||||
|
name = value_ref(self.name, parent_prefix)
|
||||||
|
params = [value_ref(param, parent_prefix) for param in self.params]
|
||||||
|
return f"{obj}[{name}]({', '.join(params)})"
|
||||||
|
|
||||||
|
|
||||||
class NewFunction(Expression):
|
class NewFunction(Expression):
|
||||||
@ -348,9 +358,9 @@ class NewFunction(Expression):
|
|||||||
self.body = body
|
self.body = body
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.render()
|
return self.render("")
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
val = f"new function({repr(self.funcname) or '<anonymous function>'}, {hex(self.flags)}, 'TODO: ByteCode')"
|
val = f"new function({repr(self.funcname) or '<anonymous function>'}, {hex(self.flags)}, 'TODO: ByteCode')"
|
||||||
if nested:
|
if nested:
|
||||||
return f"({val})"
|
return f"({val})"
|
||||||
@ -365,11 +375,11 @@ class NewObject(Expression):
|
|||||||
self.params = params
|
self.params = params
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.render()
|
return self.render('')
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
objname = name_ref(self.objname)
|
objname = name_ref(self.objname, parent_prefix)
|
||||||
params = [value_ref(param) for param in self.params]
|
params = [value_ref(param, parent_prefix) for param in self.params]
|
||||||
val = f"new {objname}({', '.join(params)})"
|
val = f"new {objname}({', '.join(params)})"
|
||||||
if nested:
|
if nested:
|
||||||
return f"({val})"
|
return f"({val})"
|
||||||
@ -386,28 +396,28 @@ class SetMemberStatement(Statement):
|
|||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
try:
|
try:
|
||||||
ref = object_ref(self.objectref)
|
ref = object_ref(self.objectref, "")
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, "")
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, "")
|
||||||
return f"{ref}.{name} = {val}"
|
return f"{ref}.{name} = {val}"
|
||||||
except Exception:
|
except Exception:
|
||||||
# This is not a simple string object reference.
|
# This is not a simple string object reference.
|
||||||
ref = object_ref(self.objectref)
|
ref = object_ref(self.objectref, "")
|
||||||
name = value_ref(self.name)
|
name = value_ref(self.name, "")
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, "")
|
||||||
return f"{ref}[{name}] = {val}"
|
return f"{ref}[{name}] = {val}"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
try:
|
try:
|
||||||
ref = object_ref(self.objectref)
|
ref = object_ref(self.objectref, prefix)
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, prefix)
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, prefix)
|
||||||
return [f"{prefix}{ref}.{name} = {val};"]
|
return [f"{prefix}{ref}.{name} = {val};"]
|
||||||
except Exception:
|
except Exception:
|
||||||
# This is not a simple string object reference.
|
# This is not a simple string object reference.
|
||||||
ref = object_ref(self.objectref)
|
ref = object_ref(self.objectref, prefix)
|
||||||
name = value_ref(self.name)
|
name = value_ref(self.name, prefix)
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, prefix)
|
||||||
return [f"{prefix}{ref}[{name}] = {val};"]
|
return [f"{prefix}{ref}[{name}] = {val};"]
|
||||||
|
|
||||||
|
|
||||||
@ -417,11 +427,11 @@ class DeleteVariableStatement(Statement):
|
|||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, "")
|
||||||
return f"del {name}"
|
return f"del {name}"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, prefix)
|
||||||
return [f"{prefix}del {name};"]
|
return [f"{prefix}del {name};"]
|
||||||
|
|
||||||
|
|
||||||
@ -432,12 +442,12 @@ class StoreRegisterStatement(Statement):
|
|||||||
self.valueref = valueref
|
self.valueref = valueref
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, "")
|
||||||
return f"{self.register.render()} = {val}"
|
return f"{self.register.render('')} = {val}"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, prefix)
|
||||||
return [f"{prefix}{self.register.render()} = {val};"]
|
return [f"{prefix}{self.register.render(prefix)} = {val};"]
|
||||||
|
|
||||||
|
|
||||||
class SetVariableStatement(Statement):
|
class SetVariableStatement(Statement):
|
||||||
@ -447,13 +457,13 @@ class SetVariableStatement(Statement):
|
|||||||
self.valueref = valueref
|
self.valueref = valueref
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, "")
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, "")
|
||||||
return f"{name} = {val}"
|
return f"{name} = {val}"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, prefix)
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, prefix)
|
||||||
return [f"{prefix}{name} = {val};"]
|
return [f"{prefix}{name} = {val};"]
|
||||||
|
|
||||||
|
|
||||||
@ -464,13 +474,13 @@ class SetLocalStatement(Statement):
|
|||||||
self.valueref = valueref
|
self.valueref = valueref
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, "")
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, "")
|
||||||
return f"local {name} = {val}"
|
return f"local {name} = {val}"
|
||||||
|
|
||||||
def render(self, prefix: str) -> List[str]:
|
def render(self, prefix: str) -> List[str]:
|
||||||
name = name_ref(self.name)
|
name = name_ref(self.name, prefix)
|
||||||
val = value_ref(self.valueref)
|
val = value_ref(self.valueref, prefix)
|
||||||
return [f"{prefix}local {name} = {val};"]
|
return [f"{prefix}local {name} = {val};"]
|
||||||
|
|
||||||
|
|
||||||
@ -485,7 +495,7 @@ class IsUndefinedIf(IfExpr):
|
|||||||
self.negate = negate
|
self.negate = negate
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
val = value_ref(self.conditional, parens=True)
|
val = value_ref(self.conditional, "", parens=True)
|
||||||
if self.negate:
|
if self.negate:
|
||||||
return f"if ({val} is not UNDEFINED)"
|
return f"if ({val} is not UNDEFINED)"
|
||||||
else:
|
else:
|
||||||
@ -498,7 +508,7 @@ class IsBooleanIf(IfExpr):
|
|||||||
self.negate = negate
|
self.negate = negate
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
val = value_ref(self.conditional, parens=True)
|
val = value_ref(self.conditional, "", parens=True)
|
||||||
if self.negate:
|
if self.negate:
|
||||||
return f"if ({val} is False)"
|
return f"if ({val} is False)"
|
||||||
else:
|
else:
|
||||||
@ -512,8 +522,8 @@ class IsEqualIf(IfExpr):
|
|||||||
self.negate = negate
|
self.negate = negate
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
val1 = value_ref(self.conditional1, parens=True)
|
val1 = value_ref(self.conditional1, "", parens=True)
|
||||||
val2 = value_ref(self.conditional2, parens=True)
|
val2 = value_ref(self.conditional2, "", parens=True)
|
||||||
return f"if ({val1} {'!=' if self.negate else '=='} {val2})"
|
return f"if ({val1} {'!=' if self.negate else '=='} {val2})"
|
||||||
|
|
||||||
|
|
||||||
@ -524,8 +534,8 @@ class IsStrictEqualIf(IfExpr):
|
|||||||
self.negate = negate
|
self.negate = negate
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
val1 = value_ref(self.conditional1, parens=True)
|
val1 = value_ref(self.conditional1, "", parens=True)
|
||||||
val2 = value_ref(self.conditional2, parens=True)
|
val2 = value_ref(self.conditional2, "", parens=True)
|
||||||
return f"if ({val1} {'!==' if self.negate else '==='} {val2})"
|
return f"if ({val1} {'!==' if self.negate else '==='} {val2})"
|
||||||
|
|
||||||
|
|
||||||
@ -536,8 +546,8 @@ class MagnitudeIf(IfExpr):
|
|||||||
self.negate = negate
|
self.negate = negate
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
val1 = value_ref(self.conditional1, parens=True)
|
val1 = value_ref(self.conditional1, "", parens=True)
|
||||||
val2 = value_ref(self.conditional2, parens=True)
|
val2 = value_ref(self.conditional2, "", parens=True)
|
||||||
return f"if ({val1} {'<' if self.negate else '>'} {val2})"
|
return f"if ({val1} {'<' if self.negate else '>'} {val2})"
|
||||||
|
|
||||||
|
|
||||||
@ -548,8 +558,8 @@ class MagnitudeEqualIf(IfExpr):
|
|||||||
self.negate = negate
|
self.negate = negate
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
val1 = value_ref(self.conditional1, parens=True)
|
val1 = value_ref(self.conditional1, "", parens=True)
|
||||||
val2 = value_ref(self.conditional2, parens=True)
|
val2 = value_ref(self.conditional2, "", parens=True)
|
||||||
return f"if ({val1} {'<=' if self.negate else '>='} {val2})"
|
return f"if ({val1} {'<=' if self.negate else '>='} {val2})"
|
||||||
|
|
||||||
|
|
||||||
@ -780,10 +790,10 @@ class Variable(Expression):
|
|||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Variable({name_ref(self.name)})"
|
return f"Variable({name_ref(self.name, '')})"
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
return name_ref(self.name)
|
return name_ref(self.name, parent_prefix)
|
||||||
|
|
||||||
|
|
||||||
class Member(Expression):
|
class Member(Expression):
|
||||||
@ -794,17 +804,17 @@ class Member(Expression):
|
|||||||
self.member = member
|
self.member = member
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.render()
|
return self.render("")
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
try:
|
try:
|
||||||
member = name_ref(self.member)
|
member = name_ref(self.member, parent_prefix)
|
||||||
ref = object_ref(self.objectref)
|
ref = object_ref(self.objectref, parent_prefix)
|
||||||
return f"{ref}.{member}"
|
return f"{ref}.{member}"
|
||||||
except Exception:
|
except Exception:
|
||||||
# This is not a simple string object reference.
|
# This is not a simple string object reference.
|
||||||
member = value_ref(self.member)
|
member = value_ref(self.member, parent_prefix)
|
||||||
ref = object_ref(self.objectref)
|
ref = object_ref(self.objectref, parent_prefix)
|
||||||
return f"{ref}[{member}]"
|
return f"{ref}[{member}]"
|
||||||
|
|
||||||
|
|
||||||
@ -1854,7 +1864,7 @@ class ByteCodeDecompiler(VerboseOutput):
|
|||||||
|
|
||||||
if action.opcode == AP2Action.CALL_METHOD:
|
if action.opcode == AP2Action.CALL_METHOD:
|
||||||
method_name = stack.pop()
|
method_name = stack.pop()
|
||||||
if not isinstance(method_name, (str, StringConstant)):
|
if not isinstance(method_name, (str, int, Expression)):
|
||||||
raise Exception("Logic error!")
|
raise Exception("Logic error!")
|
||||||
object_reference = stack.pop()
|
object_reference = stack.pop()
|
||||||
num_params = stack.pop()
|
num_params = stack.pop()
|
||||||
@ -1977,8 +1987,8 @@ class ByteCodeDecompiler(VerboseOutput):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if action.opcode == AP2Action.ADD2:
|
if action.opcode == AP2Action.ADD2:
|
||||||
expr1 = stack.pop()
|
|
||||||
expr2 = stack.pop()
|
expr2 = stack.pop()
|
||||||
|
expr1 = stack.pop()
|
||||||
stack.append(ArithmeticExpression(expr1, "+", expr2))
|
stack.append(ArithmeticExpression(expr1, "+", expr2))
|
||||||
|
|
||||||
chunk.actions[i] = NopStatement()
|
chunk.actions[i] = NopStatement()
|
||||||
@ -1998,6 +2008,7 @@ class ByteCodeDecompiler(VerboseOutput):
|
|||||||
stack.append(ArithmeticExpression(expr1, "*", expr2))
|
stack.append(ArithmeticExpression(expr1, "*", expr2))
|
||||||
|
|
||||||
chunk.actions[i] = NopStatement()
|
chunk.actions[i] = NopStatement()
|
||||||
|
continue
|
||||||
|
|
||||||
if action.opcode == AP2Action.DIVIDE:
|
if action.opcode == AP2Action.DIVIDE:
|
||||||
expr2 = stack.pop()
|
expr2 = stack.pop()
|
||||||
@ -2006,7 +2017,6 @@ class ByteCodeDecompiler(VerboseOutput):
|
|||||||
|
|
||||||
chunk.actions[i] = NopStatement()
|
chunk.actions[i] = NopStatement()
|
||||||
continue
|
continue
|
||||||
continue
|
|
||||||
|
|
||||||
if action.opcode == AP2Action.MODULO:
|
if action.opcode == AP2Action.MODULO:
|
||||||
expr2 = stack.pop()
|
expr2 = stack.pop()
|
||||||
@ -2069,6 +2079,10 @@ class ByteCodeDecompiler(VerboseOutput):
|
|||||||
self.vprint(stack)
|
self.vprint(stack)
|
||||||
raise Exception(f"TODO: {action}")
|
raise Exception(f"TODO: {action}")
|
||||||
|
|
||||||
|
# Make sure we consumed the stack.
|
||||||
|
if stack:
|
||||||
|
raise Exception(f"Stack not empty, contains {stack}!")
|
||||||
|
|
||||||
# Now, clean up code generation.
|
# Now, clean up code generation.
|
||||||
new_actions: List[ConvertedAction] = []
|
new_actions: List[ConvertedAction] = []
|
||||||
for action in chunk.actions:
|
for action in chunk.actions:
|
||||||
|
@ -417,7 +417,7 @@ class AP2Action:
|
|||||||
# Similar to STORE_REGISTER but does not preserve the value on the stack afterwards.
|
# Similar to STORE_REGISTER but does not preserve the value on the stack afterwards.
|
||||||
STORE_REGISTER2 = 74
|
STORE_REGISTER2 = 74
|
||||||
|
|
||||||
# Take one opcode parameter for the number of registers to in it, and then one opcode parameter
|
# Take one opcode parameter for the number of registers to init, and then one opcode parameter
|
||||||
# per the number of registers param as the register number to init, initializing that register
|
# per the number of registers param as the register number to init, initializing that register
|
||||||
# as an "Undefined" object.
|
# as an "Undefined" object.
|
||||||
INIT_REGISTER = 75
|
INIT_REGISTER = 75
|
||||||
@ -618,7 +618,7 @@ class DefineFunction2Action(AP2Action):
|
|||||||
class Expression:
|
class Expression:
|
||||||
# Any thing that can be evaluated for a result, such as a variable
|
# Any thing that can be evaluated for a result, such as a variable
|
||||||
# reference, function call, or mathematical operation.
|
# reference, function call, or mathematical operation.
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
raise NotImplementedError(f"{self.__class__.__name__} does not implement render()!")
|
raise NotImplementedError(f"{self.__class__.__name__} does not implement render()!")
|
||||||
|
|
||||||
|
|
||||||
@ -630,7 +630,7 @@ class GenericObject(Expression):
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
@ -650,7 +650,7 @@ class Register(Expression):
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Register({self.no})"
|
return f"Register({self.no})"
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
return f"registers[{self.no}]"
|
return f"registers[{self.no}]"
|
||||||
|
|
||||||
|
|
||||||
@ -2600,7 +2600,7 @@ class StringConstant(Expression):
|
|||||||
else:
|
else:
|
||||||
return f"StringConstant({hex(self.const)}: {StringConstant.property_to_name(self.const)})"
|
return f"StringConstant({hex(self.const)}: {StringConstant.property_to_name(self.const)})"
|
||||||
|
|
||||||
def render(self, nested: bool = False) -> str:
|
def render(self, parent_prefix: str, nested: bool = False) -> str:
|
||||||
if self.alias:
|
if self.alias:
|
||||||
return self.alias
|
return self.alias
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user