forked from HoloTech/customcmd-plugin
feat: Data and client framework
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
from parsimonious.grammar import Grammar
|
||||
from parsimonious.nodes import NodeVisitor
|
||||
|
||||
from . import logger
|
||||
from .terms import (
|
||||
constant_term,
|
||||
define_equal,
|
||||
define_walrus,
|
||||
define_term,
|
||||
binop,
|
||||
compare,
|
||||
cmdarg_term,
|
||||
command_shell,
|
||||
get_var,
|
||||
ternary_term,
|
||||
run_function,
|
||||
cascade_term,
|
||||
)
|
||||
|
||||
|
||||
class Execuitor(NodeVisitor):
|
||||
"""
|
||||
NodeVisitor that visits each node in a parsed command component,
|
||||
and builds a forward-directional ExecTerm from them.
|
||||
"""
|
||||
|
||||
def lift_child_log(self, node, visited_children):
|
||||
print(f"NODE: {node} WITH {visited_children}")
|
||||
return self.lift_child(node, visited_children)
|
||||
|
||||
visit_basicterm = lift_child_log
|
||||
|
||||
def visit_parenthised(self, node, visited_children):
|
||||
print(f"PARENTH: {visited_children}")
|
||||
_, child, _ = visited_children[0]
|
||||
return child
|
||||
|
||||
def visit_command(self, node, visited_children):
|
||||
print(f"COMMAND: {visited_children}")
|
||||
_, component, _ = visited_children
|
||||
return command_shell(node.text, component)
|
||||
|
||||
def visit_bool(self, node, boolterm):
|
||||
(value,) = boolterm[0]
|
||||
if value.text.lower() == "true":
|
||||
return constant_term(node.text, True)
|
||||
elif value.text.lower() == "false":
|
||||
return constant_term(node.text, False)
|
||||
else:
|
||||
raise ValueError(f"Unrecognised bool {value.text}")
|
||||
|
||||
def visit_test(self, node, testterm):
|
||||
(expr,) = testterm
|
||||
term1, op, term2 = expr
|
||||
return compare(node.text, term1, op.text, term2)
|
||||
|
||||
def generic_visit(self, node, visited_children):
|
||||
"""If we don't have a rule for this node return it as raw text, but evaluatable"""
|
||||
print(f"GENERIC: {node} WITH {visited_children}")
|
||||
return visited_children or node
|
||||
|
||||
def visit_quoted(self, node, visited_children):
|
||||
return constant_term(node.text, node.text[1:-1])
|
||||
|
||||
def visit_keyword(self, node, visited_children):
|
||||
return node.text
|
||||
|
||||
def visit_word(self, node, visited_children):
|
||||
return node.text
|
||||
|
||||
def visit_equals(self, node, defineterms):
|
||||
var, _, _, _, term = defineterms
|
||||
return define_equal(node.text, str(var), term)
|
||||
|
||||
def visit_defines(self, node, defineterms):
|
||||
var, _, _, _, term = defineterms
|
||||
return define_walrus(node.text, str(var), term)
|
||||
|
||||
def visit_definesterm(self, node, defineterms):
|
||||
var, _, _, _, term = defineterms
|
||||
return define_term(node.text, str(var), term)
|
||||
|
||||
def visit_numeric(self, node, numeric_term):
|
||||
return constant_term(node.text, int(node.text))
|
||||
|
||||
def visit_cmdarg(self, node, visited_children):
|
||||
_, argspec = visited_children
|
||||
return cmdarg_term(
|
||||
node.text, int(argspec.text.strip("$*")), argspec.text.endswith("*")
|
||||
)
|
||||
|
||||
def visit_ternary(self, node, visited_children):
|
||||
print(f"TERNARY: {visited_children}")
|
||||
cond, _, arg1, _, arg2 = visited_children
|
||||
return ternary_term(node.text, cond, arg1, arg2)
|
||||
|
||||
def visit_term(self, node, visited_children):
|
||||
print(f"TERM: {visited_children}")
|
||||
_, value, _ = visited_children
|
||||
(child,) = value
|
||||
return child
|
||||
|
||||
def visit_component(self, node, visited_children):
|
||||
print(f"COMPONENT: {visited_children}")
|
||||
_, value, _ = visited_children
|
||||
(child,) = value
|
||||
return child
|
||||
|
||||
def visit_var(self, node, varterm):
|
||||
root, remaining = varterm
|
||||
(root,) = root
|
||||
terms = (root, *(attr for _, attr in remaining))
|
||||
return get_var(node.text, *terms)
|
||||
|
||||
def visit_function(self, node, visited_children):
|
||||
print(f"FUNCTION: {node.text}, {visited_children}")
|
||||
func, remaining = visited_children
|
||||
args = (term for _, term in remaining)
|
||||
return run_function(node.text, func, *args)
|
||||
|
||||
def visit_cascade(self, node, visited_children):
|
||||
print(f"CASCADE: {visited_children}")
|
||||
term, remaining = visited_children
|
||||
terms = (term, *(bterm for _, bterm in remaining))
|
||||
return cascade_term(node.text, *terms)
|
||||
|
||||
def visit_binop(self, node, binopterm):
|
||||
(expr,) = binopterm
|
||||
term1, remaining = expr
|
||||
op = remaining[0][0]
|
||||
terms = (term1, *(bterm for _, bterm in remaining))
|
||||
return binop(node.text, op.text, *terms)
|
||||
Reference in New Issue
Block a user