# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['zdcode']

package_data = \
{'': ['*']}

install_requires = \
['attrs>=20.3.0,<21.0.0', 'parsy>=1.3.0,<2.0.0']

entry_points = \
{'console_scripts': ['zake = zdcode.program:main_zake',
                     'zdcode = zdcode.program:main']}

setup_kwargs = {
    'name': 'zdcode',
    'version': '2.12.2',
    'description': 'A ZDoom DECORATE transpiler and mod content build system',
    'long_description': '# ZDCode 2.0\n\n"The language that compiles to ye olde DECORATE!"\n\nZDCode is a project that aims to make writing DECORATE _better_; that is,\nto expand the possibilities not only of what the code itself can do, but\nalso of how it can be written, or concerted with other ZDCode projects\nand authors, or distributed to modders and players alike. ZDCode is\nan attempt to make modding for ZDoom-based platforms, like Zandronum,\nmuch more similar to the ecosystem of an actual language, like a C linker,\nor a JavaScript web bundler.\n\nTake this example:\n\n```c\n#UNDEFINE ANNOYING\n\nclass RunZombie inherits ZombieMan replaces ZombieMan #2055\n{\n    set Gravity to 0.4; // high up...\n    set Speed to 0;\n    is NOBLOCKMONST;\n    set Speed to 0;\n\n    label See\n    {\n        inject SeeCheck;\n        POSS AB 5 A_Recoil(-0.7);\n        inject SeeCheck;\n        POSS AB 4 A_Recoil(-0.7);\n        inject SeeCheck;\n        POSS ABCD 3 A_Recoil(-0.7);\n        inject SeeCheck;\n        goto RunLoop;\n    };\n\n    macro SeeCheck\n    {\n        TNT1 A 0 A_Chase;\n        POSS A 0 A_FaceTarget();\n    };\n\n    macro ZombieJump\n    {\n        if ( health > 5 )\n            return;\n\n        while ( z == floorz )\n        {\n            POSS A 5 [Bright];\n            POSS A 11 ThrustThingZ(0, 30, 0, 1);\n        };\n\n        #ifndef ANNOYING\n        while ( z > floorz )\n        {\n            POSS AB 4;\n        };\n\n        POSS G 9;\n        POSS B 22;\n        #endif\n\n        POSS AB 2 A_Chase;\n    };\n\n    label RunLoop\n    {\n        x 2\n        {\n            POSS ABCD 2 A_Recoil(-0.7);\n            inject SeeCheck;\n        };\n\n        inject ZombieJump;\n        loop;\n    };\n}\n```\n\nThis is what happens when that beauty goes through **ZDCode 2.0**:\n\n```\nActor _Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_0 : Inventory {Inventory.MaxAmount 1}\nActor _Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_1 : Inventory {Inventory.MaxAmount 1}\nActor _Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_2 : Inventory {Inventory.MaxAmount 1}\nActor _Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_3 : Inventory {Inventory.MaxAmount 1}\nActor _Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_4 : Inventory {Inventory.MaxAmount 1}\nActor _Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_5 : Inventory {Inventory.MaxAmount 1}\nActor _Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_6 : Inventory {Inventory.MaxAmount 1}\n\n\nActor RunZombie : ZombieMan replaces ZombieMan 2055\n{\n    Gravity 0.4\n    Speed 0\n    Speed 0\n\n    +NOBLOCKMONST\n\n    States {\n        F_SeeCheck:\n            TNT1 A 0 A_Chase\n            POSS A 0 A_FaceTarget\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_0", 1, "_CLabel0")\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_1", 1, "_CLabel1")\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_2", 1, "_CLabel2")\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_3", 1, "_CLabel3")\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_4", 1, "_CLabel4")\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_5", 1, "_CLabel5")\n            TNT1 A -1\n\n            F_ZombieJump:\n            TNT1 A 0 A_JumpIf(!(health > 5), 2)\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_6", 1, "_CLabel6")\n            Stop\n            TNT1 A 0\n        _WhileBlock0:\n            TNT1 A 0 A_JumpIf(!(z == floorz), 3)\n            POSS A 5  Bright\n            POSS A 11 ThrustThingZ(0, 30, 0, 1)\n            Goto _WhileBlock0\n            TNT1 A 0\n        _WhileBlock1:\n            TNT1 A 0 A_JumpIf(!(z > floorz), 3)\n            POSS A 4\n            POSS B 4\n            Goto _WhileBlock1\n            TNT1 A 0\n            POSS G 9\n            POSS B 22\n            POSS A 2 A_Chase\n            POSS B 2 A_Chase\n            TNT1 A 0 A_JumpIfInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_6", 1, "_CLabel6")\n            TNT1 A -1\n\n        See:\n            TNT1 A 0 A_GiveInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_0")\n            Goto F_SeeCheck\n        _CLabel0:\n            TNT1 A 0 A_TakeInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_0")\n            POSS A 5 A_Recoil(-0.7)\n            POSS B 5 A_Recoil(-0.7)\n            TNT1 A 0 A_GiveInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_1")\n            Goto F_SeeCheck\n        _CLabel1:\n            TNT1 A 0 A_TakeInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_1")\n            POSS A 4 A_Recoil(-0.7)\n            POSS B 4 A_Recoil(-0.7)\n            TNT1 A 0 A_GiveInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_2")\n            Goto F_SeeCheck\n        _CLabel2:\n            TNT1 A 0 A_TakeInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_2")\n            POSS A 3 A_Recoil(-0.7)\n            POSS B 3 A_Recoil(-0.7)\n            POSS C 3 A_Recoil(-0.7)\n            POSS D 3 A_Recoil(-0.7)\n            TNT1 A 0 A_GiveInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_3")\n            Goto F_SeeCheck\n        _CLabel3:\n            TNT1 A 0 A_TakeInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_3")\n            goto RunLoop\n\n        RunLoop:\n            POSS A 2 A_Recoil(-0.7)\n            POSS B 2 A_Recoil(-0.7)\n            POSS C 2 A_Recoil(-0.7)\n            POSS D 2 A_Recoil(-0.7)\n            TNT1 A 0 A_GiveInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_4")\n            Goto F_SeeCheck\n        _CLabel4:\n            TNT1 A 0 A_TakeInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_4")\n            POSS A 2 A_Recoil(-0.7)\n            POSS B 2 A_Recoil(-0.7)\n            POSS C 2 A_Recoil(-0.7)\n            POSS D 2 A_Recoil(-0.7)\n            TNT1 A 0 A_GiveInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_5")\n            Goto F_SeeCheck\n        _CLabel5:\n            TNT1 A 0 A_TakeInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_5")\n            TNT1 A 0 A_GiveInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_6")\n            Goto F_ZombieJump\n        _CLabel6:\n            TNT1 A 0 A_TakeInventory("_Call_NPaLK2i4Etrk1DERaszVFVbnG6JiT6KwJHX_6")\n            Goto RunLoop\n    }\n}\n```\n\nWhile the compile output does look unreadable, expecting readability from it is akin to expecting\nreadability from a binary executable file. This is the principle of using ZDCode instead of\nDECORATE, after all – a more readable, concise, and organized, way to write DECORATE.\n\nJust slap the output in your WAD and... [look at what happens!](https://i.imgur.com/mr5wJ85.gifv)\n\n\n\n# Design Concepts\n\n\n\n### Bundling\n\nSimilar to web bundling technologies, such as Browserify, ZDCode tackles the issue of incompatibilities\namong different generated DECORATE files by instead focusing on _bundling_ the ZDCode input into a single\nDECORATE file.\n\nThe compiled output of ZDCode, much like a compiled C program after being linked, is treated as an\nindivisible, integral, and immutable chunk of instructions, to be read and interpreted exclusively by\nZDoom. Instead of attempting to merge separate DECORATE outputs, it is much easier, and in fact more\nplausible, to link other ZDCode projects, libraries, and source code in general, akin to libraries\nin interpreted languages, like Python. This is also how web bundling technologies operate.\n\n\n### Non-[Imperativity](https://en.wikipedia.org/wiki/Imperative_programming) and other lower-level limitations\n\nUnlike other programming languages, ZDCode has a very specific purpose.\n\nC is a portable way of writing a relatively abstract representation of machine instructions (e.g.\n`myNum += 1` instead of `ADD EAX, 1`), and interpreted languages are instructions for an interpreter\'s\nvirtual machine, whose computations do still, in the end, reflect machine code.\n\nZDCode does not have the same capabilities of using any arbitrary computer resources, because DECORATE\nitself doesn\'t. Rather, DECORATE is a mere form of expressing "classes" (which are only templates for\nobjects in ZDoom-based source ports, rather than actual object-oriented programming constructs), which\nin turn guide "actors" (fancy name for game objects, instead of being strictly actor model constructs),\nincluding their actions, properties, and states (frames).\n\nFor this reason, ZDCode is not concerned with concepts of actual imperative programming, like actual `for`\nloops that actually increment a discrete integer variable towards an arbitrary limit. Rather, it tries\nto make it easier, simpler, more programming-friendly and more systematic to write DECORATE behaviour for\nZDoom, without relying on ZScript and requiring modern GZDoom versions for mere language support\nreasons. Zandronum does not support ZScript.\n\nDECORATE itself does not support sharing behaviour between separate actor classes; rather, it supports\nusing actor classes from other classes, but only in indirect ways, such as spawning other actors. It\nhas very limited interaction among different actors, which are more centered around basic concepts that\nevery physical actor has (such as collision, movement, and to an extent AI behaviour), without allowing\nactual actor-model-esque messages to be passed directly between those game objects. At this point,\nwriting DECORATE in any way that attempts to concert multiple objects becomes contrived and relies on\nmostly unrelated behaviour intended for very different things; trying to send a message between two\nactors is similar to using a bottle, usually a small liquid container, as a means of propagating a\nmessage across a river, or a lake. It does work, but it relies on the buoyancy and imperviousness\nof the bottle. It\'s much better to use something designed for this, like in this example, it could be\nradio waves, or an actual wire.\n\nUnfortunately, ZDCode is not able to overcome these limitations at run-time. It still cannot have\nimp Bob tell imp Joe that the marine is coming, and that they should ambush from different hiding\nspots. What it _can_ do, however, is make the _writing_ part of the code a lot simpler, by providing\ntools to exploit behaviours.\n\n\n### Distribution\n\nThe concept of _distribution_ in ZDCode is intimately related to that of bundling, specifically\nbecause it concerns with the ease of availability of libraries to the programmer, and also the\nease of distribution and dependency management.\n\nAt one point, it was planned to create a rather standardized format for fetching ZDCode packages\nusing indexes stored in Git. However, this has been wholly deemed unnecessary. Instead, the\ncurrent roadmap is to add simple support via transports like HTTP, Git and FTP, and allowing\nother transport implementations as well, using a termina-friendly URI-like format. This is very\nreminiscent of the syntax Go package management uses, e.g. `go get github.com/someone/something`.\n\nThis deals with two issues at the same time: it ensures both that players can easily retrieve mods (and\nupdates thereof) directly from the Internet (automatically bundling them if necessary), whilst at\nthe same time enabling ZDCode mod authors to both obtain and share code more efficiently, both for libraries\nand finished mods.\n\n\n# Programming Constructs\n\nWelcome to the main attractions!\n\n\n## Code Blocking\n\nThis may seem like a primitive part of a programming language, but DECORATE uses states\nand labels, instead of code blocking. It\'s more akin to Assembly (or oldschool C), with\njumps rather than groups of statements.\n\nZDCode allows the programmer to group their state code into blocks, useful for statements\nlike repetition (`x 5 { A_Print ("I\'m said five times!") }`), control flow, or even\nmere readability.\n\n\n\n## Macros\n\nMacros are a way to inject common behaviour into different locations, as states that are\nused multiple times.\n\n```\n// Global macros!\nmacro ThrustUpward(amount) {\n    TNT1 A 0 ThrustThingZ(0, amount, 0, 1);  // My, DECORATE has some convoluted things sometimes.\n}\n\nclass YipYipHurrahMan extends ZombieMan {\n    // Class-local macros!\n    macro Yip {\n        inject ThrustUpward(20);\n    };\n\n    macro Hurrah {\n        inject ThrustUpward(90);\n    };\n\n    label Spawn {\n        POSS A 12;   // \'12\' means short yips\n          inject Yip;\n        POSS B 12;\n          inject Yip;\n        POSS D 50;   // \'50\' means long hurrahs\n          inject Hurrah;\n          loop;\n    };\n}\n```\n\nThey are simple, because the states in them are simply copied at compile time, instead of\ncalled at runtime. (Functions are legacy, unreliable, and now deprecated.) They support\nstatic parameters, as well. They can\'t change at runtime, but they do make life easier too.\n\n\n\n## Conditions\n\nIn contrast to DECORATE\'s highly manual and tediously finnicky (and almost Assembly-like)\nstate jumps, ZDCode boasts a much nicer format, that does not require offset maintenance\nin the source code, nor separate state labels, and that is easier to both integrate with\nexisting code, extend with new code, or nest with more conditions and other constructs.\n\n```\nclass RedBlue {\n    label Spawn {\n        if (z > floorz + 64) {\n            // Red sprite, normal gravity (except half, but you know).\n            RDBL R 2 A_SetGravity(0.5);\n        };\n\n        else {\n            // Blue sprite, reverse gravity.\n            RDBL B 2 A_SetGravity(-0.5);\n        };\n        \n        loop;\n    };\n}\n```\n\n\n## Preprocessor\n\nYes, there is a C-like preprocessor in ZDCode! It has the usual `#DEFINE`, `#IFDEF`,\n`#IFNDEF`, and the fundamental part of using any library - `#INCLUDE`. Among other things,\ntoo.\n\n```\nclass LocalizedZombie extends Zombieman replaces Zombieman {\n    // This is a merely illustrative example.\n    // For actual locatization, please just use ZDoom\'s LANGUAGE lump instead.\n    // Apart from that, it demonstrates the effectiveness of the otherwise\n    // simple and rudimentary preprocessor ZDCode uses.\n\n    macro SeeMessage(message) {\n        invisi A_Print(message); // invisi == TNT1, also duration defaults to 0\n\n        // Any better ideas for a message printing macro? I\'m all ears!\n    };\n\n    label See {\n        #ifdef LANG\n            #ifeq LANG EN_US\n                inject SeeMessage("Hey, you!");\n            #else\n            #ifeq LANG PT_BR\n                inject SeeMessage("Ei, você!");\n            #else // I know, not very pretty. Python gets away with it, though!\n            #ifeq LANG DE_DE\n                inject SeeMessage("Achtung! Halt!");\n            #else\n                inject SeeMessage("/!\\"); // Attention?\n            #endif\n            #endif\n            #endif\n            #endif\n        #endif\n        goto Super.See;\n    };\n}\n```\n\n\n## Templates\n\nIt was already possible to have a class inherit another. It is very simple DECORATE\nbehaviour that ZDCode of course permits as well, although with a bit cleaner syntax.\n\nIn addition to that, ZDCode allows instantiating multiple classes that differ slightly\nfrom a base _template_. The difference between this and inheritance is that, rather than\nhappening at load time (where ZDoom reads the DECORATE), it happens at compile-time, which\nmeans many cool tricks can be done by using this alongside other ZDCode features.\n\n```\nclass<size> ZombieSizes extends Zombieman {\n    set Scale to size;\n};\n\nderive SmallZombie  as ZombieSizes::(0.5);\nderive BiggerZombie as ZombieSizes::(1.3);\nderive SuperZombie  as ZombieSizes::(2.2);\n```\n\nDerivations can optionally include extra definitions, including the ability to \'implement\'\n**abstract macros**, **abstract labels** and define the values of **abstract arrays** that\nthe template may specify.\n\n```\nclass<> FiveNumbers {\n    abstract array numbers;\n\n    abstract macro PrintNumber(n);\n\n    label Spawn {\n        // for ranges are not supported yet\n        \n        inject PrintNumber(numbers[0]);\n        inject PrintNumber(numbers[1]);\n        inject PrintNumber(numbers[2]);\n        inject PrintNumber(numbers[3]);\n        inject PrintNumber(numbers[4]);\n\n        stop;\n    };\n}\n\nderive PlainFibonacci as FiveNumbers::() {\n    macro PrintNumber(n) {\n        TNT1 A 0 A_Log(n);\n    };\n\n    array numbers { 1, 1, 2, 3, 5 };\n}\n```\n\nIt is recommended that classes that derive a template also inherit a base class, even\nif for purely symbolic reasons, since it helps organize the code a bit, and so classes\nthat derive from such templates can be listed property by ZDoom\'s `dumpclasses` command\n(using the inheritance base class as an argument), among other things.\n\n\n## Groups and Group Iteration\n\nA _group_ is a compile-time sequence of literals that can be iterated using a `for in` loop.\nClass syntax allows adding the class\' name to a group. More importantly, templates can also\nspecify a group, but rather than the template itself, the names of all derived classes are\nadded to the group when the code is parsed by the ZDCode compiler.\n\n```\ngroup fruits;\n\nclass<name> Fruit group fruits {\n    macro PrintMe() {\n        TNT1 A 0 A_Print(name);\n    };\n}\n\nderive Orange as Fruit::("Orange");\nderive Banana as Fruit::("Banana");\nderive Lemon  as Fruit::("Lemon");\nderive Grapes as Fruit::("Grapes");\n\nclass FruitPrinter {\n    label Spawn {\n        // \'index ___\' is optional, but retrieves\n        // the # of the iteration, like the i in a\n        // C \'for (i = 0; i < n; i++)\' loop, and can be\n        // quite useful\n        \n        for fruitname index ind in fruits {\n            // Log the index and fruit classname, like some sort of debug example\n            \n            TNT1 A 0 A_Log("Fruit #, Fruit Name");\n            TNT1 A 0 A_Log(ind);\n            TNT1 A 0 A_Log(fruitname);\n\n            // Call the derived class macro from FruitPrinter. Yes.\n            // The \'from\' keyword means that the macro is from a\n            // different class. The at sign means that the class\n            // name is taken from the parameter \'fruitname\', rather\n            // than it being the name of the class itself. It can\n            // also be used in the macro name part for interesting\n            // tricks, similar to C\'s function pointer syntax.\n\n            from @fruitname inject PrintMe();\n        };\n\n        stop;\n    };\n}\n```\n\n\n## State Modifiers\n\nAnother powerful feature of ZDCode is the ability to modify states at runtime,\nwhere each modifier applies certain effects based on certain selectors.\n\nEach modifier is actually a list of clause, where a clause pairs a selector with\none or more effects.\n\n```\nclass DiscoZombie extends Zombieman {\n    mod DiscoLight {\n        (sprite(TNT1)) suffix TNT1 A 0 A_PlaySound("disco/yeah"); // now we can use TNT1 frames to play some weird sound!\n\n        (all) +flag Bright; // Always bright, all the time!\n    };\n\n    label Spawn {\n        apply DiscoLight {\n            POSS AB 4;\n        };\n\n        loop;\n    };\n\n    // You can also apply the modifier to other state labels (like See or Missile)\n    // using the apply syntax, but you get the gist.\n}\n```\n\n\n\n\n',
    'author': 'Gustavo6046',
    'author_email': 'rehermann6046@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.9,<4.0',
}


setup(**setup_kwargs)
