[wadler] Cons has a list of documents in it
I think I want to start thinking about "leftmost" and "rightmost" and it's just easier and faster if cons has an actual list in it instead of dotted pairs.
This commit is contained in:
parent
d5ccd5b147
commit
9d55588a35
3 changed files with 38 additions and 28 deletions
|
|
@ -558,8 +558,8 @@ class Harness:
|
||||||
self.format_document(lines, doc.resolve(), indent)
|
self.format_document(lines, doc.resolve(), indent)
|
||||||
|
|
||||||
case wadler.Cons():
|
case wadler.Cons():
|
||||||
self.format_document(lines, doc.left, indent)
|
for child in doc.docs:
|
||||||
self.format_document(lines, doc.right, indent)
|
self.format_document(lines, child, indent)
|
||||||
|
|
||||||
case wadler.Marker():
|
case wadler.Marker():
|
||||||
append("Marker")
|
append("Marker")
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,7 @@ from . import runtime
|
||||||
|
|
||||||
@dataclasses.dataclass(frozen=True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
class Cons:
|
class Cons:
|
||||||
left: "Document"
|
docs: list["Document"]
|
||||||
right: "Document"
|
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(frozen=True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
|
|
@ -73,14 +72,19 @@ Document = None | Text | Literal | NewLine | ForceBreak | Cons | Indent | Group
|
||||||
|
|
||||||
|
|
||||||
def cons(*documents: Document) -> Document:
|
def cons(*documents: Document) -> Document:
|
||||||
result = None
|
if len(documents) == 0:
|
||||||
for doc in documents:
|
return None
|
||||||
if result is None:
|
|
||||||
result = doc
|
|
||||||
elif doc is not None:
|
|
||||||
result = Cons(result, doc)
|
|
||||||
|
|
||||||
return result
|
result = []
|
||||||
|
for document in documents:
|
||||||
|
if isinstance(document, Cons):
|
||||||
|
result.extend(document.docs)
|
||||||
|
elif document is not None:
|
||||||
|
result.append(document)
|
||||||
|
|
||||||
|
if len(result) == 0:
|
||||||
|
return None
|
||||||
|
return Cons(result)
|
||||||
|
|
||||||
|
|
||||||
def group(document: Document) -> Document:
|
def group(document: Document) -> Document:
|
||||||
|
|
@ -174,9 +178,8 @@ def layout_document(doc: Document, width: int, indent: str) -> DocumentLayout:
|
||||||
# line and yes, whatever you were asking about has fit.
|
# line and yes, whatever you were asking about has fit.
|
||||||
return not chunk.flat
|
return not chunk.flat
|
||||||
|
|
||||||
case Cons(left, right):
|
case Cons(docs):
|
||||||
stack.append(chunk.with_document(right))
|
stack.extend(chunk.with_document(doc) for doc in reversed(docs))
|
||||||
stack.append(chunk.with_document(left))
|
|
||||||
|
|
||||||
case Lazy():
|
case Lazy():
|
||||||
stack.append(chunk.with_document(chunk.doc.resolve()))
|
stack.append(chunk.with_document(chunk.doc.resolve()))
|
||||||
|
|
@ -236,9 +239,8 @@ def layout_document(doc: Document, width: int, indent: str) -> DocumentLayout:
|
||||||
output.append("\n" + (chunk.indent * indent))
|
output.append("\n" + (chunk.indent * indent))
|
||||||
column = chunk.indent * len(indent)
|
column = chunk.indent * len(indent)
|
||||||
|
|
||||||
case Cons(left, right):
|
case Cons(docs):
|
||||||
chunks.append(chunk.with_document(right))
|
chunks.extend(chunk.with_document(doc) for doc in reversed(docs))
|
||||||
chunks.append(chunk.with_document(left))
|
|
||||||
|
|
||||||
case Indent(amount, doc):
|
case Indent(amount, doc):
|
||||||
chunks.append(chunk.with_document(doc, and_indent=amount))
|
chunks.append(chunk.with_document(doc, and_indent=amount))
|
||||||
|
|
@ -264,20 +266,25 @@ def layout_document(doc: Document, width: int, indent: str) -> DocumentLayout:
|
||||||
|
|
||||||
def resolve_document(doc: Document) -> Document:
|
def resolve_document(doc: Document) -> Document:
|
||||||
match doc:
|
match doc:
|
||||||
case Cons(left, right):
|
case Cons(docs):
|
||||||
lr = resolve_document(left)
|
docs = [resolve_document(d) for d in docs]
|
||||||
rr = resolve_document(right)
|
return cons(*docs)
|
||||||
if lr is not left or rr is not right:
|
|
||||||
return cons(lr, rr)
|
|
||||||
else:
|
|
||||||
return doc
|
|
||||||
|
|
||||||
case Lazy(_):
|
case Lazy(_):
|
||||||
return resolve_document(doc.resolve())
|
return resolve_document(doc.resolve())
|
||||||
|
|
||||||
case _:
|
case Group(doc):
|
||||||
|
return group(resolve_document(doc))
|
||||||
|
|
||||||
|
case Marker(child, meta):
|
||||||
|
return Marker(resolve_document(child), meta)
|
||||||
|
|
||||||
|
case Text() | Literal() | NewLine() | ForceBreak() | Indent() | None:
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
case _:
|
||||||
|
typing.assert_never(doc)
|
||||||
|
|
||||||
|
|
||||||
def child_to_name(child: runtime.Tree | runtime.TokenValue) -> str:
|
def child_to_name(child: runtime.Tree | runtime.TokenValue) -> str:
|
||||||
if isinstance(child, runtime.Tree):
|
if isinstance(child, runtime.Tree):
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@ from parser.parser import (
|
||||||
alt,
|
alt,
|
||||||
indent,
|
indent,
|
||||||
seq,
|
seq,
|
||||||
Rule,
|
|
||||||
Assoc,
|
|
||||||
sp,
|
sp,
|
||||||
nl,
|
nl,
|
||||||
br,
|
br,
|
||||||
|
|
@ -129,9 +127,14 @@ def flatten_document(doc: wadler.Document, src: str) -> list:
|
||||||
case wadler.Lazy():
|
case wadler.Lazy():
|
||||||
return flatten_document(doc.resolve(), src)
|
return flatten_document(doc.resolve(), src)
|
||||||
case wadler.Cons():
|
case wadler.Cons():
|
||||||
return flatten_document(doc.left, src) + flatten_document(doc.right, src)
|
result = []
|
||||||
|
for d in doc.docs:
|
||||||
|
result += flatten_document(d, src)
|
||||||
|
return result
|
||||||
case None:
|
case None:
|
||||||
return []
|
return []
|
||||||
|
case wadler.Marker():
|
||||||
|
return [f"<marker {repr(doc.meta)}>", flatten_document(doc.child, src)]
|
||||||
case _:
|
case _:
|
||||||
typing.assert_never(doc)
|
typing.assert_never(doc)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue