Esempio n. 1
0
    def add_page(self):
        mbr = c.Var('memory_buffer')
        mar = c.Var('memory_address')
        self.define_objective('memory_buffer', None)
        self.define_objective('memory_address', None)

        def pair_name(fn, pair):
            return 'memory/%s_%d_%d' % (fn, pair.min, pair.max)

        def create_function(pair, force=False):
            getter = []
            setter = []
            def gen_fn(fn, p):
                return c.ExecuteChain() \
                       .cond('if') \
                       .score_range(mar, c.ScoreRange(p.min, p.max)) \
                       .run(c.Function(pair_name(fn, p)))
            def gen_assign(n, g=True):
                slot = c.Var('memory_slot_%d' % n)
                self.define_objective('memory_slot_%d' % n, None)
                return c.ExecuteChain() \
                        .cond('if') \
                        .score_range(mar, c.ScoreRange(n, n)) \
                        .run(c.OpAssign(mbr if g else slot, slot if g else mbr))

            if pair.left and pair.left.left:
                getter.append(gen_fn('mem_get', pair.left))
                setter.append(gen_fn('mem_set', pair.left))
            if pair.right and pair.right.right:
                getter.append(gen_fn('mem_get', pair.right))
                setter.append(gen_fn('mem_set', pair.right))

            if not pair.left and not pair.right and not force:
                # Don't do anything here, it's done in the next level up
                return

            if pair.left and not pair.left.left or force:
                getter.append(gen_assign(pair.min))
                setter.append(gen_assign(pair.min, False))
            if pair.right and not pair.right.right:
                getter.append(gen_assign(pair.max))
                setter.append(gen_assign(pair.max, False))

            name_get = pair_name('mem_get', pair)
            name_set = pair_name('mem_set', pair)
            self.scope.add_function_names((name_get, name_set))
            self.add_function(name_get, getter)
            self.add_function(name_set, setter)

        entry_point = self.generate_bin_tree(self.page_size, create_function)
        if not entry_point.left and not entry_point.right:
            create_function(entry_point, force=True)

        # Redirect mem_get and mem_set to the actual entry point
        getter = [c.Function(pair_name('mem_get', entry_point))]
        setter = [c.Function(pair_name('mem_set', entry_point))]
        self.scope.add_function_names(('mem_get', 'mem_set'))
        self.add_function('mem_get', getter)
        self.add_function('mem_set', setter)
Esempio n. 2
0
    def apply(self, out, func):
        # Validate arguments and return type
        self.func.validate_args(self.fnargs, self.retvars)

        frame = self.setup_frame(out, func)
        out.write(c.Function(self.func.global_name))
        self.destroy_frame(out, func, frame)
    def apply(self, out, func):
        # Validate arguments and return type
        self.func.validate_args(self.fnargs, self.retvars)

        # See also: IRFunction.configure_parameters
        # Build invocation frame
        # list of:
        #  - arguments
        #  - return variable pointers
        #  - saved registers
        allargs = []

        # Arguments
        args_start = 0
        if self.fnargs:
            allargs.extend(self.fnargs)

        # Returns
        ret_start = len(allargs)
        if self.retvars:
            # default return variable = default for the type
            allargs.extend([var.type for var in self.retvars])

        # Save registers
        reg_start = len(allargs)
        registers = func.get_registers()
        # Optimization - don't save registers used as return pointers
        if self.retvars:
            registers = [var for var in registers if var not in self.retvars]
        allargs.extend(registers)

        if allargs:
            make_stack_frame_from(allargs, out)
        out.write(c.Function(self.func.global_name))

        # Restore registers
        if registers:
            for i, reg in enumerate(registers):
                src = LocalStackVariable(reg.type, reg_start + i)
                # shouldn't need to realign because they're registers,
                # but just to be safe
                reg.realign_frame(1)
                src.clone_to(reg, out)
                reg.realign_frame(-1)

        # Copy return values into return variables
        if self.retvars:
            for i, var in enumerate(self.retvars):
                if var is None:
                    continue
                src = LocalStackVariable(var.type, ret_start + i)
                var.realign_frame(1)
                src.clone_to(var, out)
                var.realign_frame(-1)

        # Pop invocation frame
        if allargs:
            out.write(c.DataRemove(c.GlobalEntity.ref,
                                   c.StackPath(STACK_HEAD)))
Esempio n. 4
0
 def apply(self, out, func):
     with self.exec.apply(out) as chain:
         if isinstance(self.func, FunctionLike):
             if isinstance(self.func, BasicBlock):
                 assert self.func.is_function, self.func
             cmd = c.Function(self.func.global_name)
         else:
             cmd = self.func.as_cmd()
         out.write(chain.run(cmd))
Esempio n. 5
0
 def _get_style(self, out, out_func):
     style = dict(self.style)
     if self._click_func is not None:
         action, func = self._click_func
         if isinstance(func.val, FunctionLike):
             cmd = c.Function(func.val.global_name)
         else:
             cmd = func.val.as_cmd(out_func)
         style['clickEvent'] = c.TextClickAction(action, cmd)
     return style
def _branch_apply(out, if_true, if_false, apply):
    inverted = not if_true
    if inverted:
        if_true, if_false = if_false, if_true
    have_false = if_false is not None
    if have_false:
        # Workaround: execute store doesn't set success to 0 if failed
        # See MC-125058
        # Can't use execute store anyway because it locks the success
        # tracker. See MC-125145
        out.write(c.SetConst(c.Var('success_tracker'), 0))
    true_fn = c.Function(if_true.global_name)
    out.write(
        apply(c.ExecuteChain().cond('unless' if inverted else 'if')).run(
            true_fn))
    if have_false:
        false_fn = c.Function(if_false.global_name)
        out.write(c.ExecuteChain().cond('if').score_range(
            c.Var('success_tracker'), c.ScoreRange(0, 0)).run(false_fn))
    def apply(self, out, func):
        # TODO verify self.func has run_callback_on_exit
        self.func.validate_args(self.fnargs, self.retvars)

        # Create a trampoline function as the real callback
        tr_name = self.retblock._name + '/trampoline'
        out.func_writer.write_func_table([tr_name])

        # Setup frame and call function as before
        frame = self.setup_frame(out, func)
        out.write(c.Function(self.func.global_name))

        # Write frame destruction to the trampoline function
        tr_out = CmdWriter(out.func_writer, out.temp_gen)
        self.destroy_frame(tr_out, frame)
        # Clear zero tick block
        tr_out.write(_zt.clear())
        tr_out.write(_zt.reset_last_exec())

        # Finally, make the trampoline bounce to the desired callback
        tr_out.write(c.Function(self.retblock.global_name))
        out.func_writer.write_function(tr_name, tr_out.get_output())
Esempio n. 8
0
 def _set_value(self, tag):
     tag.set('cmd', FutureNBTString(c.Function(self.func.global_name)))
Esempio n. 9
0
import shutil
import re
import sys
import commands
from tools import *
#import convert

packName = "Generated Data Pack"
packId = "generated_data_pack"
packDesc = "Data pack generated from a Minecraft Programming Language compiler"
packShort = "gdp"
defaultPackInfo = False
useSnapshots = False

preinitFunction = commands.Function(
    packId, "internal/preload",
    "It is necessary to delay the load function by 1 second so that it may be run on world load correctly.",
    0)
initFunction = commands.Function(
    packId, "internal/load",
    "This function is run when the datapack is loaded.", 0)
uninstallFunction = commands.Function(
    packId, "uninstall",
    "Can be called to remove the pack and any trace it was ever installed", 0)
tickFunction = commands.Function(
    packId, "internal/tick",
    "This function is run every tick after this datapack is loaded.", 0)
customFunctions = {
    "exists":
    commands.Function(
        packId, "exists",
        "If you can successfully run this function, the pack exists.", 0)
 def get_cmd(self):
     tag = NBTCompound()
     tag.set('cmd', FutureNBTString(c.Function(self.func.global_name)))
     return c.DataModifyStack(None, None, 'append', tag, c.StackFrameHead)
 def get_cmd(self):
     tag = NBTCompound()
     tag.set('Command', FutureNBTString(c.Function(self.func.global_name)))
     return c.DataMerge(c.UtilBlockPos.ref, tag)
Esempio n. 12
0
def main():
    global packId
    global packDesc
    global packName
    global useSnapshots
    global packDesc
    global variables
    global playerPreference
    global packShort
    global requiredPacks

    print("Start")

    mainCode = []
    with open("main.mcscript", "r") as data:
        print("found main file")
        print("Saving the file as a copy in the datapack")
        codeList = noComments(data)
        #A list of each separate statement or definition without any new lines or tabs
        mainCode = words(";", "".join(codeList),
                         [['"', '"', True], ["'", "'", True], ["(", ")"],
                          ["[", "]"], ["{", "}"]], False, True)
    """print("main file contents:")
    for i in range(0,len(mainCode)):
      print(f"\t{i}: {mainCode[i]}")"""

    if segment("pack-info: ", 0, mainCode[0]):
        info = packId = words(" ", mainCode[0],
                              [['"', '"', True], ["'", "'", True]], False,
                              False)[1:]
        packName = info[0]
        packId = info[1]
        packShort = info[2]
        packDesc = info[3]
        print(f'got pack name "{packName}" with id "{packId}"')
        useSnapshots = info[4].lower().capitalize()
        if useSnapshots == "True":
            print("Snapshots have been enabled. Pack format changed to 7.")
        else:
            print("No snapshots are in use. Pack format is 6.")
        playerPreference = info[5].lower()
        defaultPackInfo = False
        print("Converting to data pack form")
    else:
        print(
            f'no pack info specified. Default values will be used (name "{packName}" id {packId})'
        )
        defaultPackInfo = True

    if os.path.isdir(f".generated/packs/{packName}"):
        print("Cleaning up previous generation files")
        while os.path.isdir(f".generated/packs/{packName}"):
            shutil.rmtree(f".generated/packs/{packName}")

    print("Saving main.mcscript as a copy in the datapack")
    os.makedirs(f".generated/packs/{packName}/source", exist_ok=True)
    shutil.copyfile("main.mcscript",
                    f".generated/packs/{packName}/source/main.mcscript")

    print("Populating default function statements")
    commands.Statement(
        f"schedule function {packId}:{initFunction.name} 1s replace",
        preinitFunction).implement()

    commands.Statement(f"scoreboard objectives add {packShort}_temp dummy",
                       initFunction).implement()
    commands.Statement(f"scoreboard objectives remove {packShort}_temp",
                       uninstallFunction).implement()
    commands.Statement(f"scoreboard players set {packId} {packShort}_temp 0",
                       initFunction).implement()
    #This line is only here so that the variable will register itself as visible to the rest of the program.
    #Initialization and manipulation are covered by other lines.
    commands.Variable(packId, f"{packShort}_temp", "entity", "int", "0",
                      f"Temporary score for this pack.", False)
    if playerPreference == "single":
        commands.Statement("", initFunction).implement()
        commands.Comment("Ensure the game is run in singleplayer",
                         initFunction).implement()
        commands.Statement(
            f"execute as @a run scoreboard players add {packId} {packShort}_temp 1",
            initFunction).implement()
        commands.Statement(
            f'execute if score {packId} {packShort}_temp matches 2.. run tellraw @a [{{"text":"The pack "}},{{"text":"\\"{packName}\\"","color":"green","hoverEvent":{{"action":"show_text","contents":[{{"text":"{packId} - {packShort}\\n{packDesc}"}}]}}}},{{"text":" is only compatible with singleplayer.\\nDisabling the pack to avoid unexpected behavior.\\nUse "}},{{"text":"/datapack enable \\"file/{packName}\\"","color":"green","hoverEvent":{{"action":"show_text","contents":[{{"text":"Click to copy this command to the chat bar."}}]}},"clickEvent":{{"action":"suggest_command","value":"/datapack enable \\"file/{packName}\\""}}}},{{"text":" To reenable."}}]',
            initFunction).implement()
        commands.Statement(
            f'execute if score {packId} {packShort}_temp matches 2.. run datapack disable "file/{packName}"',
            initFunction).implement()
        commands.Statement(
            f'execute store success storage {packId} isCompatible int 1 if score {packId} {packShort}_temp matches ..1',
            initFunction).implement()
    elif playerPreference == "multi":
        commands.Statement("", initFunction).implement()
        commands.Comment("Ensure the game is run in multiplayer",
                         initFunction).implement()
        commands.Statement(
            f"execute as @a run scoreboard players add {packId} {packShort}_temp 1",
            initFunction).implement()
        commands.Statement(
            f'execute if score {packId} {packShort}_temp matches ..1 run tellraw @a [{{"text":"The pack "}},{{"text":"\\"{packName}\\"","color":"green","hoverEvent":{{"action":"show_text","contents":[{{"text":"{packId} - {packShort}\\n{packDesc}"}}]}}}},{{"text":" is only compatible with multiplayer.\\nDisabling the pack to avoid unexpected behavior.\\nUse "}},{{"text":"/datapack enable \\"file/{packName}\\"","color":"green","hoverEvent":{{"action":"show_text","contents":[{{"text":"Click to copy this command to the chat bar."}}]}},"clickEvent":{{"action":"suggest_command","value":"/datapack enable \\"file/{packName}\\""}}}},{{"text":" To reenable."}}]',
            initFunction).implement()
        commands.Statement(
            f'execute if score {packId} {packShort}_temp matches ..1 run datapack disable "file/{packName}"',
            initFunction).implement()
        commands.Statement(
            f'execute store success storage {packId} isCompatible int 1 if score {packId} {packShort}_temp matches 2..',
            initFunction).implement()

    #Add a new line to the function
    commands.Statement("", initFunction).implement()

    if defaultPackInfo:
        generateCode(mainCode[1:], None, "", "main.mcscript", "main")
    else:
        generateCode(mainCode, None, "", "main.mcscript", "main")

    libraryFiles = []
    libraryNamespaces = []
    print("looking for other files")
    for subdir, dirs, files in os.walk(os.getcwd()):
        dirs[:] = [
            d for d in dirs if not d[0] == "." and not d == "__pycache__"
        ]
        for file in files:
            if not file == "main.mcscript":
                path = os.path.relpath(os.path.join(subdir, file))
                if file.endswith(".mcscript"):
                    print(f"found file \"{path}\"")
                    with open(path) as data:
                        print("Converting to data pack form")
                        generateCode(
                            words(";", "".join(noComments(data)),
                                  [['"', '"', True], ["'", "'", True],
                                   ["{", "}"]], False, True), None,
                            "/".join(path.split("/")[:-1]), file,
                            file.split(".")[:-1])

                    print("Saving the file as a copy in the datapack")
                    os.makedirs(
                        f".generated/packs/{packName}/source/{os.path.relpath(subdir)}",
                        exist_ok=True)
                    shutil.copyfile(
                        path, f".generated/packs/{packName}/source/{path}")
                elif not file.endswith(".mctag") and not file.endswith(
                        ".py") and not path == "README.md":
                    print(f"found file \"{path}\"")
                    print("copying it to the datapack")

                    if path[0] == "#":
                        print("copying as library file")
                        pathList = []
                        if sys.platform == "win32":
                            pathList = path.split("\\")
                        else:
                            pathList = path.split("/")

                        pathList[0] = pathList[0][1:]
                        oldPathList = list(pathList)
                        name = pathList[0]
                        if not name in libraryNamespaces:
                            libraryNamespaces.append(name)
                        if len(pathList) > 2:
                            pathList[0], pathList[1] = pathList[1], pathList[0]
                            p = "/".join(pathList[1:-1]
                                         ) + "/" + pathList[-1].split(".")[0]
                            if pathList[0] == "functions" and pathList[
                                    -1].endswith(".mcfunction"):
                                customFunctions[p] = commands.Function(
                                    packId, p, "Imported from a library", 0)

                        pathList = pathList[:-1]
                        oldPathList = oldPathList[:-1]
                        os.makedirs(
                            f".generated/packs/{packName}/data/{packId}/{'/'.join(pathList)}",
                            exist_ok=True)
                        shutil.copyfile(
                            path,
                            f".generated/packs/{packName}/data/{packId}/{'/'.join(pathList)}/{file}"
                        )
                        print("Saving to the datapack as a copy")
                        os.makedirs(
                            f".generated/packs/{packName}/source/#{'/'.join(oldPathList)}",
                            exist_ok=True)
                        shutil.copyfile(
                            path,
                            f".generated/packs/{packName}/source/#{'/'.join(oldPathList)}/{file}"
                        )
                        if not f".generated/packs/{packName}/data/{packId}/{'/'.join(pathList)}/{file}" in libraryFiles:
                            libraryFiles.append(
                                f".generated/packs/{packName}/data/{packId}/{'/'.join(pathList)}/{file}"
                            )
                    else:
                        os.makedirs(
                            f".generated/packs/{packName}/data/{packId}/{os.path.relpath(subdir)}",
                            exist_ok=True)
                        shutil.copyfile(
                            path,
                            f".generated/packs/{packName}/data/{packId}/{path}"
                        )

                        print("Saving the file as a copy in the datapack")
                        os.makedirs(
                            f".generated/packs/{packName}/source/{os.path.relpath(subdir)}",
                            exist_ok=True)
                        shutil.copyfile(
                            path, f".generated/packs/{packName}/source/{path}")

    for name in libraryNamespaces:
        libraries.append(name)
        print(f'updating namespace calls from "{name}" to "{packId}:{name}/"')
        for path in libraryFiles:
            update_namespace(path, packId, name)

    print("Requiring packs")
    if len(requiredPacks) > 0:
        commands.Comment("Ensure all required packs are installed.",
                         initFunction).implement()
        for pack in requiredPacks:
            commands.Statement(
                f"execute if data storage {packId} {{isCompatible:1}} store success score {packId} {packShort}_temp run function {pack}:exists",
                initFunction).implement()
            commands.Statement(
                f'execute if score {packId} {packShort}_temp matches 0 run tellraw @a {{"text":"The required pack \"{pack}\" was not detected to exist.\\n Disabling to avoid unexpected behavior.","color":"red"}}',
                initFunction).implement()
            commands.Statement(
                f'execute if score {packId} {packShort}_temp matches 0 run datapack disable "file/{packName}"',
                initFunction).implement()
            commands.Statement(
                f'execute store success storage {packId} isCompatible int 1 if score {packId} {packShort}_temp matches 1',
                initFunction).implement()
            commands.Statement("", initFunction).implement()

    print("Setting up listener calls")
    for key in listeners:
        if not key in internalListeners:
            scoresToReset = []
            listeners[key].sort(key=lambda x: x.priority)
            for function in listeners[key]:
                if not function.scoreId in variables:
                    commands.Comment(
                        f"Used for listener {function.listenerId}",
                        initFunction).implement()
                    commands.Statement(
                        f'scoreboard objectives add {function.scoreId[:min([len(function.scoreId), 16])]} {function.listenerId}',
                        initFunction).implement()
                    #This line is only here so that the variable will register itself as visible to the rest of the program.
                    #Initialization and manipulation are covered by other lines.
                    commands.Variable(
                        packId, function.scoreId, "entity", "int", "0",
                        f"Used for listener {function.listenerId}", False)

                commands.Statement("", tickFunction).implement()
                commands.Comment("Run listeners", tickFunction).implement()
                commands.Statement(
                    f'execute as @e[scores={{{function.scoreId[:min([len(function.scoreId), 16])]}=1..}}] at @s run function {function.namespace}:{function.name}',
                    tickFunction).implement()
                scoresToReset.append(
                    function.scoreId[:min([len(function.scoreId), 16])])

            if len(scoresToReset) > 0:
                commands.Statement("", tickFunction).implement()
                commands.Comment("Reset listener scores",
                                 tickFunction).implement()
            for score in scoresToReset:
                #Reset the score
                commands.Statement(f"scoreboard players set @e {score} 0",
                                   tickFunction).implement()
                #Remove the score on uninstall
                commands.Statement(f"scoreboard objectives remove {score}",
                                   uninstallFunction).implement()

    if "tick" in listeners:
        #Add a new line to the function
        commands.Statement("", tickFunction).implement()
        commands.Comment("Run tick listeners", tickFunction).implement()
        listeners["tick"].sort(key=lambda x: x.priority)
        for function in listeners["tick"]:
            commands.Statement(
                f"function {function.namespace}:{function.name}",
                tickFunction).implement()
    if "load" in listeners:
        #Add a new line to the function
        commands.Statement("", initFunction).implement()
        commands.Comment("Run listeners", initFunction).implement()
        listeners["load"].sort(key=lambda x: x.priority)
        for function in listeners["load"]:
            commands.Statement(
                f"function {function.namespace}:{function.name}",
                initFunction).implement()
    if "uninstall" in listeners:
        #Add a new line to the function
        commands.Statement("", uninstallFunction).implement()
        commands.Comment("Run listeners", uninstallFunction).implement()
        listeners["uninstall"].sort(key=lambda x: x.priority)
        for function in listeners["uninstall"]:
            commands.Statement(
                f"function {function.namespace}:{function.name}",
                uninstallFunction).implement()
    if "spawn" in listeners:
        #Add a new line to the function
        commands.Statement("", tickFunction).implement()
        commands.Comment("Run spawn listeners", tickFunction).implement()
        listeners["spawn"].sort(key=lambda x: x.priority)
        for function in listeners["spawn"]:
            commands.Statement(
                f"execute as @e[tag=!{packId}_spawned] at @s run function {function.namespace}:{function.name}",
                tickFunction).implement()

    #The "spawned" tag will be used by some other parts of the generator.
    commands.Statement(f"tag @e[tag=!{packId}_spawned] add {packId}_spawned",
                       tickFunction).implement()

    print('Adding "datapack loaded/unloaded" notification')
    #Add a new line to the function
    commands.Statement("", initFunction).implement()
    commands.Comment("Uninstall if incompatible", initFunction).implement()
    initFunction.append(
        f'execute if data storage {packId} {{isCompatible:1}} run tellraw @a [{{"text":"The pack "}},{{"text":"\\"{packName}\\" ","color":"green","hoverEvent":{{"action":"show_text","contents":[{{"text":"{packId} - {packShort}\\n{packDesc}"}}]}}}},{{"text":"has been sucessfully (re)loaded."}}]'
    )
    commands.Comment("Uninstall the pack if it is incompatible",
                     initFunction).implement()
    commands.Statement(
        f"execute if data storage {packId} {{isCompatible:0}} run function {packId}:{uninstallFunction.name}",
        initFunction).implement()

    for lib in libraries:
        uninstallFunction.append(f'function {packId}:{lib}/uninstall')
    #Add a new line to the function
    commands.Statement("", uninstallFunction).implement()
    uninstallFunction.append(
        f'tellraw @a [{{"text":"The pack "}},{{"text":"\\"{packName}\\" ","color":"green","hoverEvent":{{"action":"show_text","contents":[{{"text":"{packId} - {packShort}\\n{packDesc}"}}]}}}},{{"text":"has been sucessfully unloaded."}}]'
    )
    commands.Statement(f'datapack disable "file/{packName}"',
                       uninstallFunction).implement()
    commands.Statement("", initFunction).implement()
    commands.Comment("Start the tick function", initFunction).implement()
    commands.Statement(
        f"execute if score {packId} {packShort}_temp matches 1 run function {packId}:{tickFunction.name}",
        initFunction).implement()
    commands.Statement("", tickFunction).implement()
    commands.Comment("Start the tick function again next tick",
                     tickFunction).implement()
    commands.Statement(
        f"schedule function {packId}:{tickFunction.name} 1t replace",
        tickFunction).implement()

    os.makedirs(f".saved/data", exist_ok=True)
    print("Saving functions for use in tags")
    with open(".saved/data/functions.csv", "w+") as file:
        data = [
            "namespace,name", f"{packId},internal/load",
            f"{packId},internal/preload", f"{packId},internal/tick",
            f"{packId},uninstall"
        ]
        for i in customFunctions:
            customFunctions[i].namespace = packId
            print(
                f"commands.Function \"{customFunctions[i].namespace}:{customFunctions[i].name}\" is defined. Adding it to the data."
            )
            data.append(
                f"{customFunctions[i].namespace},{customFunctions[i].name}")

        for i in externalFunctions:
            print(
                f'External function "{i.namespace}:{i.name}" is defined. Adding it to the data.'
            )
            data.append(f"{i.namespace},{i.name}")
        file.write("\n".join(data))

    print("Generating tag files")
    tags.start(packName, packId, packDesc, useSnapshots)

    print("setting up data pack files")

    os.makedirs(f".generated/packs/{packName}/data/minecraft/tags/functions",
                exist_ok=True)
    os.makedirs(
        f'.generated/packs/{packName}/data/{packId}/functions/internal',
        exist_ok=True)
    os.makedirs(f'.generated/packs/{packName}/data/{packId}/tags/blocks',
                exist_ok=True)
    os.makedirs(f'.generated/packs/{packName}/data/{packId}/tags/entity_types',
                exist_ok=True)
    os.makedirs(f'.generated/packs/{packName}/data/{packId}/tags/fluids',
                exist_ok=True)
    os.makedirs(f'.generated/packs/{packName}/data/{packId}/tags/functions',
                exist_ok=True)
    os.makedirs(f'.generated/packs/{packName}/data/{packId}/tags/items',
                exist_ok=True)
    with open(f".generated/packs/{packName}/pack.mcmeta", "w+") as file:
        json.dump(
            {
                "pack": {
                    "pack_format": 7 if useSnapshots else 6,
                    "description": packDesc
                }
            },
            file,
            indent=4)
    with open(
            f".generated/packs/{packName}/data/minecraft/tags/functions/load.json",
            "w+") as file:
        json.dump(
            {
                "replace": False,
                "values": [f"{packId}:{preinitFunction.name}"]
            },
            file,
            indent=4)

    print("Writing preinit function to data pack")
    preinitFunction.implement(
        f".generated/packs/{packName}/data/{packId}/functions/{preinitFunction.name}.mcfunction"
    )
    print("Writing init function to data pack")
    initFunction.implement(
        f".generated/packs/{packName}/data/{packId}/functions/{initFunction.name}.mcfunction"
    )
    print("Writing uninstall function to data pack")
    uninstallFunction.implement(
        f".generated/packs/{packName}/data/{packId}/functions/{uninstallFunction.name}.mcfunction"
    )
    print("Writing tick function to data pack")
    tickFunction.implement(
        f".generated/packs/{packName}/data/{packId}/functions/{tickFunction.name}.mcfunction"
    )
    for name in customFunctions:
        print(f'Writing "{name}" function to data pack')
        os.makedirs(
            f".generated/packs/{packName}/data/{packId}/functions/{customFunctions[name].path}",
            exist_ok=True)
        customFunctions[name].implement(
            f".generated/packs/{packName}/data/{packId}/functions/{name}.mcfunction"
        )

    print("Done")
Esempio n. 13
0
 def gen_fn(fn, p):
     return c.ExecuteChain() \
            .cond('if') \
            .score_range(mar, c.ScoreRange(p.min, p.max)) \
            .run(c.Function(pair_name(fn, p)))
Esempio n. 14
0
def generateCode(code, function, path, file, parentScript):
    global listeners
    global externalFunctions
    global customFunctions
    global requiredPacks
    global packId
    global libraries

    if function == None:
        #Top-level statements: Variables and function declarations
        for line in code:
            #Listener definition
            match = re.match(
                r'(priority\=(?P<priority>[+-]?\d+)\s+)?(id="(?P<id>[^\"]+)"\s+)?on\s+(?P<name>[a-z_0-9\.\:]+)',
                line)
            if match != None:
                name = match.group("name").replace(":", "_")
                id = match.group("id")
                priority = match.group("priority")
                if not name in listeners:
                    listeners[name] = []
                version = len(listeners[name]) + 1
                function = None
                if priority == None:
                    function = commands.Function(
                        packId,
                        f"listeners/{name}/{path}{'/' if path != '' else ''}{'.'.join(file.split('.')[:-1])}/{name.replace('.', '_')}{version}",
                        f"This function is called for every {name} event with 0 priority",
                        0)
                else:
                    priority = int(priority)
                    function = commands.Function(
                        packId,
                        f"listeners/{name}/{path}{'/' if path != '' else ''}{'.'.join(file.split('.')[:-1])}/{name.replace('.', '_')}{version}",
                        f"This function is called for every {name} event with {priority} priority",
                        priority)

                function.listenerId = match.group("name")
                function.scoreId = name
                if id != None:
                    function.scoreId = id

                statements = words(
                    ";",
                    groups(line, [["{", "}"], ['"', '"', True]],
                           False,
                           requiredPair=["{", "}"])[0],
                    [['"', '"', True], ["'", "'", True], ["{", "}"],
                     ["[", "]"]], False, True)
                customFunctions[function.name] = function
                listeners[name].append(function)
                generateCode(statements, function, function.path,
                             f"{name.replace('.', '_')}-{version}.mcscript",
                             parentScript)
            else:
                #Function definition
                match = re.match(
                    r'function\s+(desc="(?P<desc>[^\"]+)"\s+)?(?P<name>[a-z_]+)\(\)',
                    line)
                if match != None:
                    name = match.group("name")
                    desc = match.group("desc")
                    function = None
                    if desc == None:
                        function = commands.Function(
                            packId,
                            f"{path}{'/' if path != '' else ''}{'.'.join(file.split('.')[:-1])}/{name.replace('.', '_')}",
                            f"The function defined with the name '{name}' in the file '{path}/{file}'",
                            0)
                    else:
                        function = commands.Function(
                            packId,
                            f"{path}{'/' if path != '' else ''}{'.'.join(file.split('.')[:-1])}/{name.replace('.', '_')}",
                            desc, 0)
                    statements = words(";",
                                       groups(line, [["{", "}"]], False)[0],
                                       [['"', '"', True], ["'", "'", True],
                                        ["{", "}"], ["[", "]"]], False, True)
                    customFunctions[function.name] = function
                    generateCode(statements, function, function.path,
                                 function.name, parentScript)
                else:
                    #External function definition
                    match = re.match(
                        r'def (?P<namespace>[a-z_]+):(?P<name>[a-z_\/]+)',
                        line)
                    if match != None:
                        externalFunctions.append(
                            commands.Function(match.group("namespace"),
                                              match.group("name"), "", 0))
                    else:
                        #Variable definition
                        match = re.match(
                            r'(?P<modifier>global|entity|constant)\s+(desc="(?P<desc>[^\"]+)"\s+)?(?P<type>(?:entity|int|float|string|bool)(?:\<\d+\>)?(?:\[\])?)\s+(?P<name>[a-zA-Z_]+)(\s*\=\s*(?P<value>.+))?',
                            line)
                        if match != None:
                            modifier = match.group("modifier")
                            t = match.group("type")
                            name = match.group("name")
                            value = match.group("value")
                            desc = match.group("desc")
                            print(f'Defining variable "{name}"')
                            commands.Variable(packId, name, modifier, t, value,
                                              desc, True)
                        else:
                            #Required pack definition
                            match = re.match(
                                r'require\s+(?P<namespace>[a-z_]+)', line)
                            if match != None:
                                requiredPacks.append(match.group("namespace"))
                            else:
                                pass
    else:
        #Lower level satements - Instructions
        for line in code:
            #Literal command
            if line[0] == "/":
                commands.LiteralCommand(line, function).implement()
            else:
                #Comment
                match = re.match(r'comment((?P<message>.+))(\)$)', line)
                if match != None:
                    message = groups(match.group("message"),
                                     [['"', '"', True]], False)[0]
                    commands.Comment(message, function).implement()
                else:
                    #Function call
                    match = re.match(
                        r'(?P<function>[a-z_0-9\.]+(:)?[a-z_0-9\.]+)(?<!\.)\(\)',
                        line)
                    if match != None:
                        f = match.group("function")
                        functionList = f.split(":")
                        if len(functionList) < 2:
                            functionList = f.split(".")
                            if len(functionList) == 1:
                                commands.CallFunction(
                                    f"{packId}:{parentScript}/{functionList[0]}",
                                    function).implement()
                            else:
                                commands.CallFunction(
                                    f"{packId}:{'/'.join(functionList)}",
                                    function).implement()
                        else:
                            namespace = functionList[0]
                            functionList = functionList[1].split(".")
                            commands.CallFunction(
                                f"{namespace}:{'/'.join(functionList)}",
                                function).implement()
                    else:
                        #Execute clause
                        match = re.match(
                            r'(?P<conditions>((if|unless|store|align|anchored|as|at|facing|positioned|rotated)(.)+?\s*)+?)\s*{(?P<code>(.|\s)*)}',
                            line)
                        if match != None:
                            conditions = []
                            conditionsWords = words(
                                " ", match.group("conditions"),
                                [['"', '"', True], ["'", "'", True],
                                 ["(", ")"]], False, True)
                            for condition in conditionsWords:
                                if condition == "":
                                    continue
                                elif condition in [
                                        "if", "unless", "store", "align",
                                        "anchored", "as", "at", "facing",
                                        "positioned", "rotated"
                                ]:
                                    conditions.append(condition)
                                elif condition[0] == "(" and condition[
                                        -1] == ")":
                                    conditions[-1] += " " + condition[1:-1]
                                else:
                                    conditions[-1] += " " + condition

                            statements = words(
                                ";", match.group("code"),
                                [['"', '"', True], ["'", "'", True],
                                 ["(", ")"], ["[", "]"], ["{", "}"]], False,
                                True)

                            if len(statements) == 1:
                                wrapper = commands.ExecuteWrapper(
                                    conditions, [], function)
                                generateCode(statements, wrapper, path, file,
                                             parentScript)
                                wrapper.implement()
                        else:
                            pass
Esempio n. 15
0
 def get_cmd(self, func):
     return c.Function(self.label.global_name)
 def make_set_func_nbt(self, func):
     tag = NBTCompound()
     tag.set('Command', FutureNBTString(c.Function(func.global_name)))
     return tag
 def allargs_hook(self, allargs):
     tr_name = self.retblock._name + '/trampoline'
     tr_nbt = NBTCompound()
     tr_nbt.set('cmd', FutureNBTString(c.Function(tr_name)))
     # Stick callback on the end of the stackframe
     allargs.append(tr_nbt)
Esempio n. 18
0
 def as_cmd(self, func):
     return c.Function(c.NSName(self.name))
Esempio n. 19
0
 def as_cmd(self):
     return c.Function(self.name)