def apply(self, element) -> Element: has_head = Util.has_head_element(element) if has_head: new_form_element = element.parent.wrap(element.prev, element.end, Form) new_form = new_form_element.code new_form.prepend( Identifier("@" + element.text + element.end.text, element.range)) # @[] head BEGIN_MACRO('[') begin ... end END_MACRO(']') else: new_form_element = element.parent.wrap(element, element.end, Form) new_form = new_form_element.code new_form.prepend( Identifier(element.text + element.end.text, element.range)) # @[] BEGIN_MACRO('[') begin head ... end END_MACRO(']') begin_element = element.next last_element = new_form.last new_form.remove(element) # remove BEGIN_MACRO('[') new_form.remove(new_form.last) # remove END_MACRO(']') if begin_element is last_element: # if we have something like a[] or a{} or so... return new_form_element.next else: # return Util.join_all_args(new_form_element, begin_element, "head-prefixed parenthesized form", 2 if has_head else 1) Util.explode_list_of_args(begin_element) return new_form_element.next
def identifier_in(arg: Union[Code, Element, str], collection_of_str): if isinstance(arg, str): name, syntactic_extra, semantic_extra = Identifier.split_name(arg) for itm in collection_of_str: equal_to_name, equal_to_semantic_extra = Identifier.split_name(itm) if _identifier_eq(name, semantic_extra, equal_to_name, equal_to_semantic_extra ): return True return False else: if arg is None: return False code = get_code(arg) return any(is_identifier(code, name) for name in collection_of_str)
def identifier_in(arg: Union[Code, Element, str], collection_of_str): if isinstance(arg, str): name, syntactic_extra, semantic_extra = Identifier.split_name(arg) for itm in collection_of_str: equal_to_name, equal_to_semantic_extra = Identifier.split_name(itm) if _identifier_eq(name, semantic_extra, equal_to_name, equal_to_semantic_extra): return True return False else: if arg is None: return False code = get_code(arg) return any(is_identifier(code, name) for name in collection_of_str)
def apply(self, element): form = element.parent if is_identifier(element, '=') and \ not ( form.first.next is element or is_token(form.first.next, Tokens.PUNCTUATION, ',')): return form.wrap(form.first, element.prev, PreSeq) if element.next is not None: first_indent = element.next while first_indent is not None and not is_token( first_indent, Tokens.INDENT): first_indent = first_indent.next if first_indent is not None: if is_token(first_indent.prev, Tokens.PUNCTUATION, ':'): form.wrap(element.next, form.last, PreForm) else: form.replace(first_indent, Tokens.ARGBREAK()) form.wrap(element.next, form.last, PreSeq) form.remove(element) if isinstance(form, PreForm): form.prepend(Identifier("=")) else: new_form = form.wrap(form.first, form.last, Form).code new_form.prepend(element) return None
def apply(self, element): form = element.parent new_form_element = form.wrap(element.prev, element, Form) new_form = new_form_element.code new_form.remove(element) new_form.prepend(Identifier(element.value, element.range)) return new_form_element.next
def apply(self, element) -> Element: assert is_token(element.next, Tokens.COMMENT) if element.next.next is element.end: parent = element.parent next_element = element.end.next parent.remove(element.next) parent.remove(element) parent.remove(element.end) return next_element else: parent = element.parent """:type : Node""" new_form_element = parent.wrap(element, element.end, Form) new_form = new_form_element.code new_form.prepend(Identifier("debug-values", element.range)) # str BEGIN_MACRO('#') seq of STRING tokens, interspersed with Identifiers and BEGIN_MACRO / END_MACRO pairs END_MACRO new_form.remove(element) # remove BEGIN_MACRO('#') new_form.remove(element.end) # remove END_MACRO elm = new_form[1] # first element while elm is not None: if is_token(elm, Tokens.BEGIN_MACRO): elm = elm.end.next elif is_token(elm, Tokens.COMMENT): nxt = elm.next new_form.remove(elm) elm = nxt else: elm = elm.next return new_form_element.next
def apply(self, element): # p < n form = element.parent ops = [element] p = element.prev n = element.next args = [p, n] form.remove(p) # < n form.remove(n) # < new_form = Form(Identifier(self.head_symbol_name)) new_form_element = form.replace(element, new_form) # (head_symbol) while True: # while we find + e e1 = new_form_element.next if e1 is None: break e2 = e1.next if e2 is None: break if is_identifier( e1.code ) and e1.code.name in self.sym_vals: # if e1 is the same symbol as e, then it is the same operator form.remove(e1) form.remove(e2) ops.append(e1) args.append(e2) else: break for op in ops: new_form.append(op) new_form.append(Seq(*args)) return new_form_element.next
def apply(self, element) -> Element: new_form_element = element.parent.wrap(element, element.end, Form) new_form = new_form_element.code new_form.prepend(Identifier("quote", element.range)) new_form.remove(element) # remove BEGIN_MACRO ' new_form.remove(new_form.last) # remove END_MACRO ' return new_form_element.next
def arrange(self, node: Code): if not isinstance(node, Node): return element = None if self.direction == ReadDirection.LEFT_TO_RIGHT: element = node.first elif self.direction == ReadDirection.RIGHT_TO_LEFT: element = node.last while element is not None: nxt = element.next if self.direction == ReadDirection.LEFT_TO_RIGHT else element.prev for r in self.rules: if r.applies(element): #region Debug Printing if G.Options.PRINT_ARRANGEMENT_OUTPUTS: node.insert(element, Identifier("⋅")) out = " Arrangement: " + r.name + "\n" out += indent_string("BEFORE:", 12) + "\n" out += indent_string(lisp_printer(node), 20) print(out) node.remove(element.next) #endregion nxt = r.apply(element) # region Debug Printing if G.Options.PRINT_ARRANGEMENT_OUTPUTS: if nxt is None: node.insert(node.last, Identifier("⋅")) else: node.insert(nxt, Identifier("⋅")) out = indent_string("After:", 12) + "\n" out += indent_string(lisp_printer(node), 20) print(out) if nxt is None: node.remove(node.last) else: node.remove(nxt.next) # endregion break element = nxt
def is_identifier(code_or_element: Union[Code, Element], name: str = None) -> bool: if code_or_element is None: return False code = get_code(code_or_element) if name is None: return isinstance(code, Identifier) else: if not isinstance(code, Identifier): return False name, semantic_extra = Identifier.split_name(name) return _identifier_eq(code.name, code.semantic_name, name, semantic_extra)
def is_identifier( code_or_element: Union[Code, Element], name:str=None ) -> bool: if code_or_element is None: return False code = get_code(code_or_element) if name is None: return isinstance(code, Identifier) else: if not isinstance(code, Identifier): return False name, semantic_extra = Identifier.split_name(name) return _identifier_eq(code.name, code.semantic_name, name, semantic_extra)
def apply(self, element): form = element.parent p = element.prev n = element.next nn = n.next form.remove(p) form.remove(n) form.remove(nn) head = Identifier(element.code.name + n.code.name) head.range.update(element.code.range) head.range.update(n.code.range) new_form = Form(head, p, nn) new_form_element = form.replace(element, new_form) return new_form_element.next
def apply(self, element) -> Element: if element.next is element.end: parent = element.parent parent.remove(element.end) element.code = Literal( "", self.string_literal_type, StreamRange(element.range.position_after, element.range.position_after)) return element.next assert is_token(element.next, Tokens.STRING) if element.next.next is element.end: parent = element.parent string_token = element.next parent.remove(element) parent.remove(element.end) string_token.code = Literal(string_token.value, self.string_literal_type, string_token.range) return string_token.next else: # FIXME: allow for interpolation new_form_element = element.parent.wrap(element, element.end, Form) new_form = new_form_element.code new_form.prepend(Identifier("str", element.range)) # str BEGIN_MACRO('“') seq of STRING tokens, interspersed with Identifiers and BEGIN_MACRO / END_MACRO pairs END_MACRO new_form.remove(element) # remove BEGIN_MACRO('“') new_form.remove(element.end) # remove END_MACRO elm = new_form[1] # first element while elm is not None: if is_token(elm, Tokens.STRING): elm.code = Literal(elm.value, self.string_literal_type, elm.range) if is_token(elm, Tokens.BEGIN_MACRO): elm = elm.end.next else: elm = elm.next return new_form_element.next
def apply(self, element) -> Element: if Constituent.is_int(element.value): new_element = element.parent.replace( element, Literal(int(element.value), self.int_literal_type, element.range)) elif Constituent.is_float(element.value): new_element = element.parent.replace( element, Literal(float(element.value), self.float_literal_type, element.range)) else: identifier_name = element.value if identifier_name != "-": identifier_name = identifier_name.replace("-", "_") new_element = element.parent.replace( element, Identifier(identifier_name, element.range)) # if element.value in self.stalling_identifiers: # return element return new_element.next
def _single_indented_segment_apply(self, begin_token) -> Element: # BEGIN = INDENT END new_form_element = begin_token.parent.wrap(begin_token, begin_token.end, Form) # (BEGIN = INDENT END) new_form = new_form_element.code indent = begin_token.indents[0] assignment_symbol_elm = indent.prev has_colon = begin_token.find_punctuation(':', indent) is not None if has_colon: raise ArrangementError(has_colon.range, "Unexpected `:` in assignment segment.") new_form.wrap(begin_token.next, assignment_symbol_elm.prev, PreSeq) # (BEGIN ⟅,⟆ = INDENT END) new_form.remove(new_form.first) # (⟅,⟆ = INDENT END) new_form.remove(new_form.last) # (⟅,⟆ = INDENT ) new_form.remove(assignment_symbol_elm) # (⟅,⟆ INDENT ) new_form.prepend(Identifier("=")) # (= ⟅,⟆ INDENT ) if is_identifier(assignment_symbol_elm, '='): first_begin_after_indentation = indent.next # remove BEGIN/END pairs of non-indented, non-colon-having segments Util.explode_list_of_args(first_begin_after_indentation) rvalue_elm = new_form.wrap(indent.next, new_form.last, PreSeq) # (= ⟅,⟆ INDENT ⟅,⟆ ) new_form.remove(indent) # (= ⟅,⟆ ⟅,⟆ ) return new_form_element.next
def gensym(self): self.set(gensym_count=self.gensym_count + 1) return Identifier("GENSYM_" + str(self.gensym_count))