feat: support user-defined functions and classes in Ren'Py python
- Converter: def/return/global/nonlocal, class (inheritance, property, staticmethod, classmethod), lambda, *args/**kwargs and call-site unpacking. Unsupported dunder methods, generators and unknown decorators are still refused - Player: closures, super(), instances that survive save/load, isinstance, hasattr/getattr/setattr, map/filter/sorted(key=), recursion limit - audit_ir accepts calls to names, classes and methods the game defines itself; unknown renpy.* calls still block the import. Volume/pan/pause/replay calls are accepted as presentation-only no-ops; build.* settings are skipped - Tests: IR fixture compiled from tests/fixtures/classes.py (tests/make_ir.py) and run in the interpreter; converter tests updated Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
12ec82c7e6
commit
962595c925
12 files changed
+782
-23
No files matched your search
+1
@@ -0,0 +1 @@
|
||||
[{"op":"class","name":"Perk","bases":[{"k":"name","id":"object"}],"body":[{"op":"set","t":{"k":"name","id":"count"},"v":{"k":"const","v":0}},{"op":"def","name":"__init__","params":[{"n":"self","d":null,"kind":"p"},{"n":"name","d":null,"kind":"p"},{"n":"cost","d":{"k":"const","v":1},"kind":"p"}],"body":[{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"name"},"v":{"k":"name","id":"name"}},{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"cost"},"v":{"k":"name","id":"cost"}},{"op":"aug","t":{"k":"attr","o":{"k":"name","id":"Perk"},"a":"count"},"o":"+","v":{"k":"const","v":1}}],"decos":[]},{"op":"def","name":"__str__","params":[{"n":"self","d":null,"kind":"p"}],"body":[{"op":"return","v":{"k":"bin","op":"%","l":{"k":"const","v":"Perk(%s)"},"r":{"k":"attr","o":{"k":"name","id":"self"},"a":"name"}}}],"decos":[]}]},{"op":"class","name":"Player","bases":[{"k":"name","id":"object"}],"body":[{"op":"def","name":"__init__","params":[{"n":"self","d":null,"kind":"p"},{"n":"name","d":null,"kind":"p"},{"n":"perks","d":null,"kind":"*"},{"n":"extra","d":null,"kind":"**"}],"body":[{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"name"},"v":{"k":"name","id":"name"}},{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"perks"},"v":{"k":"call","f":{"k":"name","id":"list"},"a":[{"k":"name","id":"perks"}],"kw":{}}},{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"extra"},"v":{"k":"name","id":"extra"}},{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"_hp"},"v":{"k":"const","v":10}}],"decos":[]},{"op":"def","name":"has_perk","params":[{"n":"self","d":null,"kind":"p"},{"n":"name","d":null,"kind":"p"}],"body":[{"op":"return","v":{"k":"call","f":{"k":"name","id":"any"},"a":[{"k":"comp","e":{"k":"cmp","l":{"k":"attr","o":{"k":"name","id":"p"},"a":"name"},"ops":["=="],"r":[{"k":"name","id":"name"}]},"t":{"k":"name","id":"p"},"it":{"k":"attr","o":{"k":"name","id":"self"},"a":"perks"},"if":[]}],"kw":{}}}],"decos":[]},{"op":"def","name":"add","params":[{"n":"self","d":null,"kind":"p"},{"n":"perk","d":null,"kind":"p"}],"body":[{"op":"eval","e":{"k":"call","f":{"k":"attr","o":{"k":"attr","o":{"k":"name","id":"self"},"a":"perks"},"a":"append"},"a":[{"k":"name","id":"perk"}],"kw":{}}},{"op":"return","v":{"k":"name","id":"self"}}],"decos":[]},{"op":"def","name":"hp","params":[{"n":"self","d":null,"kind":"p"}],"body":[{"op":"return","v":{"k":"attr","o":{"k":"name","id":"self"},"a":"_hp"}}],"decos":[{"k":"name","id":"property"}]},{"op":"def","name":"hp","params":[{"n":"self","d":null,"kind":"p"},{"n":"value","d":null,"kind":"p"}],"body":[{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"_hp"},"v":{"k":"call","f":{"k":"name","id":"max"},"a":[{"k":"const","v":0},{"k":"name","id":"value"}],"kw":{}}}],"decos":[{"k":"attr","o":{"k":"name","id":"hp"},"a":"setter"}]},{"op":"def","name":"make","params":[{"n":"name","d":null,"kind":"p"}],"body":[{"op":"return","v":{"k":"call","f":{"k":"name","id":"Player"},"a":[{"k":"name","id":"name"}],"kw":{}}}],"decos":[{"k":"name","id":"staticmethod"}]},{"op":"def","name":"label","params":[{"n":"cls","d":null,"kind":"p"}],"body":[{"op":"return","v":{"k":"cmp","l":{"k":"name","id":"cls"},"ops":["is"],"r":[{"k":"name","id":"Player"}]}}],"decos":[{"k":"name","id":"classmethod"}]}]},{"op":"class","name":"Hero","bases":[{"k":"name","id":"Player"}],"body":[{"op":"def","name":"__init__","params":[{"n":"self","d":null,"kind":"p"},{"n":"name","d":null,"kind":"p"}],"body":[{"op":"eval","e":{"k":"call","f":{"k":"attr","o":{"k":"call","f":{"k":"name","id":"super"},"a":[],"kw":{}},"a":"__init__"},"a":[{"k":"name","id":"name"},{"k":"call","f":{"k":"name","id":"Perk"},"a":[{"k":"const","v":"brave"}],"kw":{}}],"kw":{"role":{"k":"const","v":"hero"}}}},{"op":"set","t":{"k":"attr","o":{"k":"name","id":"self"},"a":"level"},"v":{"k":"const","v":1}}],"decos":[]},{"op":"def","name":"has_perk","params":[{"n":"self","d":null,"kind":"p"},{"n":"name","d":null,"kind":"p"}],"body":[{"op":"return","v":{"k":"bool","op":"or","v":[{"k":"cmp","l":{"k":"name","id":"name"},"ops":["=="],"r":[{"k":"const","v":"legend"}]},{"k":"call","f":{"k":"attr","o":{"k":"call","f":{"k":"name","id":"super"},"a":[],"kw":{}},"a":"has_perk"},"a":[{"k":"name","id":"name"}],"kw":{}}]}}],"decos":[]}]},{"op":"set","t":{"k":"name","id":"total"},"v":{"k":"const","v":0}},{"op":"def","name":"bump","params":[{"n":"step","d":{"k":"const","v":1},"kind":"p"},{"n":"scale","d":{"k":"const","v":2},"kind":"k"}],"body":[{"op":"global","names":["total"]},{"op":"aug","t":{"k":"name","id":"total"},"o":"+","v":{"k":"bin","op":"*","l":{"k":"name","id":"step"},"r":{"k":"name","id":"scale"}}},{"op":"return","v":{"k":"name","id":"total"}}],"decos":[]},{"op":"def","name":"fact","params":[{"n":"n","d":null,"kind":"p"}],"body":[{"op":"return","v":{"k":"if","c":{"k":"cmp","l":{"k":"name","id":"n"},"ops":["<="],"r":[{"k":"const","v":1}]},"t":{"k":"const","v":1},"e":{"k":"bin","op":"*","l":{"k":"name","id":"n"},"r":{"kLine truncated
|
||||
Reference in new issue
Block a user