def classdef_statement_visitor( node: concat.parse.ClassdefStatementNode, ) -> ast.ClassDef: py_body = [ correct_magic_signature(statementfy(node)) for node in All( alt(visitors['word'], visitors['statement']) ).visit(node) ] py_decorators = [ to_python_decorator(word, visitors) for word in node.decorators ] py_decorators.reverse() py_bases = [] for base in node.bases: quotation = to_transpiled_quotation(base, node.location, visitors) py_base = pack_expressions([quotation, pop_stack()]) py_bases.append(py_base) py_keywords = [] for keyword_arg in node.keyword_args: py_word = visitors['word'].visit(keyword_arg[1]) stack = ast.Name(id='stack', ctx=ast.Load()) stash = ast.Name(id='stash', ctx=ast.Load()) py_word_call = ast.Call(py_word, args=[stack, stash], keywords=[]) py_keyword_value = pack_expressions([py_word_call, pop_stack()]) py_keyword = ast.keyword(keyword_arg[0], py_keyword_value) py_keywords.append(py_keyword) return ast.ClassDef( node.class_name, bases=py_bases, keywords=py_keywords, body=py_body, decorator_list=py_decorators, )
def subscription_subvisitor(node: concat.parse.SubscriptionWordNode,): words = node.children quote = concat.parse.QuoteWordNode( list(words), list(words)[0].location if words else node.location, ) py_quote = visitors['quote-word'].visit(quote) load = ast.Load() stack = ast.Name(id='stack', ctx=load) stash = ast.Name(id='stash', ctx=load) quote_call = ast.Call( func=py_quote, args=[stack, stash], keywords=[] ) append_stash = ast.Attribute(value=stash, attr='append', ctx=load) append_stash_call = ast.Call( func=append_stash, args=[pop_stack()], ctx=load ) object = pack_expressions( [quote_call, append_stash_call, pop_stack()] ) pop_stash = ast.Attribute(value=stash, attr='pop', ctx=load) pop_stash_call = ast.Call(func=pop_stash, args=[], keywords=[]) index = ast.Index(value=pop_stash_call) target = ast.Subscript(value=object, slice=index, ctx=load) return target
def dict_word_visitor(node: concat.parse.DictWordNode): """Converts a DictWordNode to a Python expression. The expression looks like `push({(Quotation([...1])(stack,stash),stack.pop())[-1]:(Quotation([...2])(stack,stash),stack.pop())[-1],......})`.""" load = ast.Load() pairs = [] for key, value in node.dict_children: key_quote = to_transpiled_quotation(key, node.location, visitors) value_quote = to_transpiled_quotation( value, node.location, visitors ) stack = ast.Name(id='stack', ctx=load) stash = ast.Name(id='stash', ctx=load) key_quote_call = ast.Call( func=key_quote, args=[stack, stash], keywords=[] ) value_quote_call = ast.Call( func=value_quote, args=[stack, stash], keywords=[] ) py_key = pack_expressions([key_quote_call, pop_stack()]) py_value = pack_expressions([value_quote_call, pop_stack()]) pairs.append((py_key, py_value)) dictionary = ast.Dict( keys=[*dict(pairs)], values=[*dict(pairs).values()] ) push_func = ast.Name(id='push', ctx=load) py_node = ast.Call(func=push_func, args=[dictionary], keywords=[]) py_node.lineno, py_node.col_offset = node.location return py_node
def pushed_subscription_word_visitor( node: concat.parse.SubscriptionWordNode, ) -> ast.expr: quotation = concat.parse.QuoteWordNode(node.children, node.location) py_index = ast.Index(pop_stack()) subscription = ast.Subscript(pop_stack(-2), py_index, ast.Load()) py_quotation = cast(ast.expr, visitors['quote-word'].visit(quotation)) py_node = pack_expressions( [call_concat_function(py_quotation), subscription] ) py_node.lineno, py_node.col_offset = node.location return py_node
def iterable_word_visitor( node: concat.parse.IterableWordNode, kind: Type[ast.expr], **kwargs: ast.AST ) -> ast.expr: """Converts a IterableWordNode to a Python expression. Lambda abstraction is used so that the inside elements of the list are not evaluated immediately, even when the list is in a push word.""" load = ast.Load() elements = [] for words in node.element_words: location = list(words)[0].location if words else node.location quote = concat.parse.QuoteWordNode(list(words), location) py_quote = visitors['quote-word'].visit(quote) stack = ast.Name(id='stack', ctx=load) stash = ast.Name(id='stash', ctx=load) quote_call = ast.Call( func=py_quote, args=[stack, stash], keywords=[] ) subtuple = ast.Tuple(elts=[quote_call, pop_stack()], ctx=load) index = ast.Index(value=ast.Num(n=-1)) last = ast.Subscript(value=subtuple, slice=index, ctx=load) elements.append(last) iterable = kind(elts=elements, **kwargs) py_node = abstract(append_to_stack(iterable)) py_node.lineno, py_node.col_offset = node.location return py_node
def subscription_word_visitor( node: concat.parse.SubscriptionWordNode, ) -> ast.expr: """Converts a SubscriptionWordNode to a Python expression. The Python expression looks like `lambda stack,stash:(...(stack,stash), stack.pop(-2)[stack.pop()])[-1](stack,stash)`. NOTE: The result of the subscript is called by default.""" quotation = concat.parse.QuoteWordNode(node.children, node.location) py_index = ast.Index(pop_stack()) subscription = ast.Subscript(pop_stack(-2), py_index, ast.Load()) py_quotation = cast(ast.expr, visitors['quote-word'].visit(quotation)) py_node = abstract( call_concat_function( pack_expressions( [call_concat_function(py_quotation), subscription] ) ) ) py_node.lineno, py_node.col_offset = node.location return py_node