Files
dev/third_party/python/rpycdec/src/renpy/atl.py

320 lines
8.0 KiB
Python

from . import util, ast, astsupport
from .object import Object
class Context(object):
pass
class ATLTransformBase(Object):
pass
class RawStatement(object):
pass
class Statement(Object):
pass
class RawBlock(RawStatement):
statements = None
"""
https://www.renpy.org/doc/html/transforms.html#block-statement
atl_block_stmt ::= "block" ":"
atl_block
"""
def get_code(self, **kwargs) -> str:
if (
not self.animation
and len(self.statements) == 1
and isinstance(self.statements[0], RawBlock)
):
return util.get_code(self.statements[0], **kwargs)
rv = []
if self.animation:
"""
https://www.renpy.org/doc/html/transforms.html#animation-statement
atl_animation ::= "animation"
image eileen vhappy moving:
animation
"eileen vhappy"
xalign 0.0
linear 5.0 xalign 1.0
repeat
"""
rv.append("animation")
statements = self.statements
if statements:
for statement in statements:
if statement is None:
rv.append("pass")
else:
rv.append(util.get_code(statement, **kwargs))
else:
rv.append("pass")
return "\n".join(rv)
class Block(Statement):
pass
class RawMultipurpose(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#interpolation-statement
atl_interp ::= ((warper simple_expression) | ("warp" simple_expression simple_expression)) (atl_interp_target+ | (":"
atl_interp_target+ ))
atl_interp_target ::= (atl_property+ ("knot" simple_expression)* )
| atl_transform_expression
| "clockwise"
| "counterclockwise"
| ("circles" simple_expression)
"""
def get_code(self, **kwargs) -> str:
start = ""
warp_fun, duration, wrap = self.warp_function, self.duration, self.warper
if warp_fun and wrap is None:
# warp {warp_function:expr} {duration:expr}
start = f"warp {util.get_code(warp_fun, **kwargs)} {util.get_code(duration, **kwargs)}"
elif not warp_fun and wrap:
# {wrap} {duration:expr}
start = f"{wrap} {util.get_code(duration, **kwargs)}"
elif not warp_fun and not wrap and duration == "0":
pass
rv = []
revolution = self.revolution
if revolution:
rv.append(revolution)
circles = self.circles
if circles and circles != "0":
# circles {expression}
rv.append(f"circles {util.get_code(circles, **kwargs)}")
for prop, expr in self.properties:
rv.append(f"{prop} {util.get_code(expr, **kwargs)}")
for prop, exprs in self.splines:
last, exprs = exprs[-1], exprs[:-1]
knots = " ".join(f"knot {util.get_code(expr, **kwargs)}" for expr in exprs)
rv.append(f"{prop} {util.get_code(last, **kwargs)} {knots}")
for expr, with_expr in self.expressions:
if with_expr is None:
rv.append(str(expr))
continue
if isinstance(with_expr, ast.PyExpr):
valstr = f"with {with_expr}"
elif isinstance(with_expr, astsupport.PyExpr):
valstr = f"with {with_expr}"
else:
valstr = str(with_expr)
rv.append(f"{expr} {valstr}")
if not start:
return " ".join(rv)
if not rv:
# if no properties, return just the warp
return start
if len(rv) < 3:
# if only few properties, return them in one line
return start + " " + " ".join(rv)
return start + ":\n" + util.indent(" ".join(rv))
class RawContainsExpr(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#inline-contains-statement
atl_contains ::= "contains" simple_expression
"""
def get_code(self, **kwargs) -> str:
"""
Returns the code for a contains expression.
"""
expression = util.attr(self, "expression")
if expression:
return f"contains {util.get_code(expression, **kwargs)}"
return "contains"
# This allows us to have multiple ATL transforms as children.
class RawChild(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#contains-block-statement
atl_counts ::= "contains" ":"
atl_block
"""
def get_code(self, **kwargs) -> str:
children = util.attr(self, "children")
if not children:
return "contains:\n pass"
rv = ["contains:"]
rv.append(util.indent(util.get_code(children, **kwargs)))
return "\n".join(rv)
# This changes the child of this statement, optionally with a transition.
class Child(Statement):
pass
# This causes interpolation to occur.
class Interpolation(Statement):
pass
class RawRepeat(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#repeat-statement
atl_repeat ::= "repeat" (simple_expression)?
"""
def get_code(self, **kwargs) -> str:
if self.repeats:
return f"repeat {util.get_code(self.repeats, **kwargs)}"
return "repeat"
class Repeat(Statement):
pass
class RawParallel(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#parallel-statement
atl_parallel ::= ("parallel" ":"
atl_block)+
"""
def get_code(self, **kwargs) -> str:
rv = ["parallel:"]
blocks = util.attr(self, "blocks")
if not blocks:
rv.append(util.indent("pass"))
else:
rv.append(util.indent(util.get_code(blocks, **kwargs)))
return "\n".join(rv)
class Parallel(Statement):
pass
class RawChoice(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#choice-statement
atl_choice ::= ("choice" (simple_expression)? ":"
atl_block)+
"""
def get_code(self, **kwargs) -> str:
rv = []
for text, stmt in self.choices:
rv.append(f"choice {text}:")
rv.append(util.indent(util.get_code(stmt, **kwargs)))
return "\n".join(rv)
class Choice(Statement):
pass
class RawTime(RawStatement):
"""
https://www.renpy.org/doc/html/atl.html#time-statement
atl_time ::= "time" (simple_expression)?
"""
def get_code(self, **kwargs) -> str:
time = util.attr(self, "time")
if time:
return f"time {util.get_code(time, **kwargs)}"
return "time"
class Time(Statement):
pass
class RawOn(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#on-statement
atl_on ::= "on" name [ "," name ] * ":"
atl_block
on show:
alpha 0.0
linear .5 alpha 1.0
on hide:
linear .5 alpha 0.0
"""
def get_code(self, **kwargs) -> str:
rv = []
for text, stmt in self.handlers.items():
rv.append(f"on {text}:")
rv.append(util.indent(util.get_code(stmt, **kwargs)))
return "\n".join(rv)
class On(Statement):
pass
class RawEvent(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#event-statement
atl_event ::= "event" name
"""
def get_code(self, **kwargs) -> str:
name = util.attr(self, "name")
if name:
return f"event {name}"
return "event"
class Event(Statement):
pass
class RawFunction(RawStatement):
"""
https://www.renpy.org/doc/html/transforms.html#function-statement
atl_function ::= "function" simple_expression
"""
def get_code(self, **kwargs) -> str:
if self.expr:
return "function " + str(self.expr)
else:
return "function"
class Function(Statement):
pass