aboutsummaryrefslogtreecommitdiff
path: root/src/smp/builtins.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/smp/builtins.py')
-rw-r--r--src/smp/builtins.py153
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