Skip to content

Commit

Permalink
Add add decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
WingedSeal committed Sep 14, 2023
1 parent abcafeb commit 07ffd76
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 13 deletions.
12 changes: 11 additions & 1 deletion src/jmc/compile/datapack.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ class DataPack:
"private_functions", "private_function_count",
"_scoreboards", "loads", "ticks", "namespace",
"used_command", "lexer", "defined_file_pos",
"after_ticks", "after_loads", "version")
"after_ticks", "after_loads", "version",
"after_func")
private_name = "__private__"
load_name = "__load__"
tick_name = "__tick__"
Expand Down Expand Up @@ -188,6 +189,10 @@ def __init__(self, namespace: str, pack_format: int,
"""Output list of commands at the end of load"""
self.after_ticks: list[str] = []
"""Output list of commands at the end of tick"""
self.after_func: dict[str, list[str]] = defaultdict(list)
"""Output list of commands at the end of any function"""
self.after_func_token: dict[str, tuple[Token, Tokenizer]] = {}
"""Output list of token responsible for adding after_func"""
self.namespace = namespace
"""Datapack's namespace"""

Expand Down Expand Up @@ -432,6 +437,11 @@ def build(self) -> None:
self.after_ticks)
else:
self.functions[self.tick_name] = Function(self.after_ticks)
for _func_path, _commands in self.after_func.items():
if _func_path not in self.functions:
raise JMCValueError(
f"Function '{_func_path}' was not defined", self.after_func_token[_func_path][0], self.after_func_token[_func_path][1])
self.functions[_func_path].extend(_commands)
for name, functions in self.private_functions.items():
for path, func in functions.items():
self.functions[f"{self.private_name}/{name}/{path}"] = func
Expand Down
68 changes: 58 additions & 10 deletions src/jmc/compile/decorator_parse.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
from .tokenizer import Token
from .command.utils import ArgType
from .datapack import Function
from .exception import JMCMissingValueError
from .header import Header
from .tokenizer import Token, Tokenizer
from .command.utils import Arg, ArgType, verify_args
from .datapack import DataPack, Function


class JMCDecorator:
is_save_to_datapack: bool
"""Whether to save the function to datapack"""
arg_type: dict[str, ArgType]
"""Dictionary containing all parameter and it's ArgType (Set by decorator)"""
tokenizer: Tokenizer
"""Tokenizer"""
call_string: str
"""String that will be used in to call the function (Set by decorator)"""
raw_args: dict[str, Arg]
"""Dictionary containing parameter and given argument as Arg object"""
args: dict[str, str]
"""Dictionary containing parameter and parsed argument in form of string"""
defaults: dict[str, str]
"""Defaults value of each parameter as string (Set by decorator)"""
datapack: DataPack
"""Datapack"""

def __init__(self, arg_token: Token | None) -> None:
def __init__(self, tokenizer: Tokenizer, datapack: DataPack,
arg_token: Token | None) -> None:
self.arg_token = arg_token
pass
self.tokenizer = tokenizer
self.datapack = datapack
if arg_token:
args_Args = verify_args(self.arg_type,
self.call_string, arg_token, tokenizer)
self.raw_args = {}
self.args = {}

def modify(self, func: Function) -> None:
for key, arg in args_Args.items():
if arg is None:
if key not in self.defaults:
raise JMCMissingValueError(key, arg_token, tokenizer)
self.args[key] = self.defaults[key]
continue
self.raw_args[key] = arg
self.args[key] = arg.token.string

def modify(self, func: Function, func_name: str) -> None:
raise NotImplementedError(
"'modify' method of JMCDecorator not implemented")

Expand All @@ -22,7 +52,7 @@ def modify(self, func: Function) -> None:


def dec_property(call_string: str,
arg_type: dict[str, ArgType] | None = None, is_save_to_datapack: bool = True):
arg_type: dict[str, ArgType] | None = None, defaults: dict[str, str] | None = None, is_save_to_datapack: bool = True):

def decorator(cls: type[JMCDecorator]) -> type[JMCDecorator]:
"""
Expand All @@ -33,13 +63,31 @@ def decorator(cls: type[JMCDecorator]) -> type[JMCDecorator]:
"""
cls.is_save_to_datapack = is_save_to_datapack
cls.arg_type = arg_type if arg_type is not None else {}
cls.defaults = defaults if defaults is not None else {}
cls.call_string = call_string
DECORATORS[call_string] = cls
return cls
return decorator


@dec_property("add",
arg_type={})
arg_type={
"from": ArgType._FUNC_CALL
})
class Add(JMCDecorator):
def modify(self, func: Function) -> None:
print(self.arg_token)
def modify(self, func: Function, func_path: str) -> None:
if self.args["from"] == self.datapack.tick_name:
self.datapack.after_ticks.append(
f"function {self.datapack.namespace}:{func_path}")
return
if self.args["from"] == self.datapack.load_name:
self.datapack.after_loads.append(
f"function {self.datapack.namespace}:{func_path}")
return

self.datapack.after_func[self.args["from"]].append(
f"function {self.datapack.namespace}:{func_path}")
if self.arg_token is None:
return
self.datapack.after_func_token[self.args["from"]
] = self.arg_token, self.tokenizer
2 changes: 1 addition & 1 deletion src/jmc/compile/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class Header(SingleTon):
"""Python function to run before building datapack"""
finished_compiled_time: float
nometa: bool
"Whether hand pack.mcmeta to user"
"""Whether hand pack.mcmeta to user"""

def __init__(self) -> None:
self.__clear(self)
Expand Down
7 changes: 6 additions & 1 deletion src/jmc/compile/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,12 @@ def parse_decorated_function(self, tokenizer: Tokenizer,
file_path_str,
prefix,
is_save_to_datapack=False)
jmc_decorator(args).modify(jmc_function)
jmc_decorator(
tokenizer,
self.datapack,
args).modify(
jmc_function,
func_path)
self.datapack.functions[func_path] = jmc_function

def parse_func(self, tokenizer: Tokenizer,
Expand Down

0 comments on commit 07ffd76

Please sign in to comment.