diff options
Diffstat (limited to 'src/smp/builtins.py')
-rw-r--r-- | src/smp/builtins.py | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/smp/builtins.py b/src/smp/builtins.py new file mode 100644 index 0000000..4cbb0a3 --- /dev/null +++ b/src/smp/builtins.py @@ -0,0 +1,153 @@ +import smp.exceptions +import subprocess +import datetime +import markdown +from gfm import AutolinkExtension, TaskListExtension + +def smp_builtin_define(macro_processor, macro_name, macro_value=None): + macro_name = macro_processor.process_input(macro_name) + if macro_value is not None: + macro_value = macro_processor.process_input(macro_value) + macro_processor.macros[macro_name] = macro_value + else: + macro_processor.macros[macro_name] = "" + return "" + + +def smp_builtin_undefine(macro_processor, macro_name): + if macro_name in macro_processor.macros: + del macro_processor[macro_name] + return "" + + +def smp_builtin_define_array(macro_processor, macro_name): + macro_name = macro_processor.process_input(macro_name) + macro_processor.macros[macro_name] = list() + return "" + + +def smp_builtin_ifdef(macro_processor, macro_name, iftrue, iffalse=None): + if macro_name in macro_processor.macros: + return macro_processor.process_input(iftrue) + if iffalse is not None: + return macro_processor.process_input(iffalse) + return "" + + +def smp_builtin_ifndef(macro_processor, macro_name, iftrue, iffalse=None): + if macro_name not in macro_processor.macros: + return macro_processor.process_input(iftrue) + if iffalse is not None: + return macro_processor.process_input(iffalse) + return "" + + +def smp_builtin_ifeq(macro_processor, a, b, iftrue, iffalse=None): + a = macro_processor.process_input(a) + b = macro_processor.process_input(b) + if a == b: + return macro_processor.process_input(iftrue) + if iffalse is not None: + return macro_processor.process_input(iffalse) + return "" + + +def smp_builtin_ifneq(macro_processor, a, b, iftrue, iffalse=None): + a = macro_processor.process_input(a) + b = macro_processor.process_input(b) + if a != b: + return macro_processor.process_input(iftrue) + if iffalse is not None: + return macro_processor.process_input(iffalse) + return "" + + +def smp_builtin_include(macro_processor, filename): + filename = macro_processor.process_input(filename) + with open(filename, "r") as f: + file_content = f.read() + return macro_processor.process_input(file_content) + + +def smp_builtin_include_verbatim(macro_processor, filename): + filename = macro_processor.process_input(filename) + with open(filename, "r") as f: + file_content = f.read() + return file_content + + +def smp_builtin_shell(macro_processor, cmd_args): + cmd_args = macro_processor.process_input(cmd_args) + return subprocess.check_output(cmd_args, shell=True).decode() + + +def smp_builtin_eval(macro_processor, expression): + r = eval(expression, macro_processor.py_global_env, macro_processor.macros) + return r + + +def smp_builtin_array_push(macro_processor, array_name, *values): + if array_name not in macro_processor.macros: + raise Exception(f"{array_name} is not a macro") + if not isinstance(macro_processor.macros[array_name], list): + raise Exception(f"{array_name} is not a array") + for value in values: + macro_processor.macros[array_name].append(value) + return "" + + +def smp_builtin_array_size(macro_processor, array_name): + if array_name not in macro_processor.macros: + raise Exception(f"{array_name} is not a macro") + if not isinstance(macro_processor.macros[array_name], list): + raise Exception(f"{array_name} is not a array") + return str(len(macro_processor.macros[array_name])) + + +def smp_builtin_array_each(macro_processor, array_name, template): + if array_name not in macro_processor.macros: + raise Exception(f"{array_name} is not a macro") + if not isinstance(macro_processor.macros[array_name], list): + raise Exception(f"{array_name} is not a array") + out = "" + for el in macro_processor.macros[array_name]: + if isinstance(el, str): + el = [el] + out += macro_processor.process_input(macro_processor.expand_macro(template, el)) + return out + +def smp_builtin_explode(macro_processor, array_name, delimiter, input): + if array_name not in macro_processor.macros: + raise Exception(f"{array_name} is not a macro") + if not isinstance(macro_processor.macros[array_name], list): + raise Exception(f"{array_name} is not a array") + delimiter = macro_processor.process_input(delimiter) + for el in macro_processor.process_input(input).split(delimiter): + macro_processor.macros[array_name].append(el) + return "" + +def smp_builtin_format_time(macro_processor, format, time): + timestamp = macro_processor.process_input(time) + dobj = datetime.datetime.fromisoformat(timestamp) + return dobj.strftime(format) + +def smp_builtin_html_from_markdown(macro_processor, text, extensions=list()): + # Get rid of quoting, I don't remember why, but the rust implementation does it like this. + for _ in range(2): + text = macro_processor.process_input(text) + extensions.append(AutolinkExtension()) + extensions.append(TaskListExtension(max_depth=2)) + return markdown.markdown(text, extensions=extensions) + +def smp_builtin_dumpenv(macro_processor): + out = "" + out += "━ Macros ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + for key, val in macro_processor.macros.items(): + out += f"{repr(key)}: {repr(val)}\n" + out += "━ Globals ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" + for key, val in macro_processor.py_global_env.items(): + if key == "__builtins__": + continue + out += f"{repr(key)}: {repr(val)}\n" + out += "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + return out |