patterns: support embedded literals

This commit is contained in:
Emery Hemingway 2024-01-19 00:04:27 +02:00
parent a05cfa37eb
commit 79c621e979
2 changed files with 36 additions and 37 deletions

View File

@ -66,43 +66,42 @@ proc grab*(pr: Value): Pattern =
$(grab parsePreserves"""<foo "bar" #"00" [0 1 2.0] {maybe: #t} <_>>""") ==
"""<rec foo [<lit "bar"> <lit #"00"> <arr [<lit 0> <lit 1> <lit 2.0>]> <dict {maybe: <lit #t>}> <_>]>"""
if pr.embedded: drop()
else:
case pr.kind
of pkBoolean:
AnyAtom(orKind: AnyAtomKind.`bool`, bool: pr.bool).toPattern
of pkFloat:
AnyAtom(orKind: AnyAtomKind.`float`, float: pr.float).toPattern
of pkDouble:
AnyAtom(orKind: AnyAtomKind.`double`, double: pr.double).toPattern
of pkRegister:
AnyAtom(orKind: AnyAtomKind.`int`, int: pr.register).toPattern
of pkString:
AnyAtom(orKind: AnyAtomKind.`string`, string: pr.string).toPattern
of pkByteString:
AnyAtom(orKind: AnyAtomKind.`bytes`, bytes: pr.bytes).toPattern
of pkSymbol:
AnyAtom(orKind: AnyAtomKind.`symbol`, symbol: pr.symbol).toPattern
of pkRecord:
if (pr.isRecord("_") and pr.arity == 0) or (pr.isRecord("bind") and pr.arity == 1):
drop()
else:
DCompoundRec(
label: pr.label,
fields: map[Value, Pattern](pr.fields, grab)).toPattern
of pkSequence:
DCompoundArr(items: map(pr.sequence, grab)).toPattern
of pkSet:
raiseAssert "cannot construct a pattern over a set literal"
of pkDictionary:
var dict = DCompoundDict()
for key, val in pr.pairs: dict.entries[key] = grab val
dict.toPattern
of pkEmbedded:
# TODO: can patterns be constructed over embedded literals?
case pr.kind
of pkBoolean:
AnyAtom(orKind: AnyAtomKind.`bool`, bool: pr.bool).toPattern
of pkFloat:
AnyAtom(orKind: AnyAtomKind.`float`, float: pr.float).toPattern
of pkDouble:
AnyAtom(orKind: AnyAtomKind.`double`, double: pr.double).toPattern
of pkRegister:
AnyAtom(orKind: AnyAtomKind.`int`, int: pr.register).toPattern
of pkString:
AnyAtom(orKind: AnyAtomKind.`string`, string: pr.string).toPattern
of pkByteString:
AnyAtom(orKind: AnyAtomKind.`bytes`, bytes: pr.bytes).toPattern
of pkSymbol:
AnyAtom(orKind: AnyAtomKind.`symbol`, symbol: pr.symbol).toPattern
of pkRecord:
if (pr.isRecord("_") and pr.arity == 0) or (pr.isRecord("bind") and pr.arity == 1):
drop()
else:
raise newException(ValueError, "cannot generate a pattern for unhandled Value type")
DCompoundRec(
label: pr.label,
fields: map[Value, Pattern](pr.fields, grab)).toPattern
of pkSequence:
DCompoundArr(items: map(pr.sequence, grab)).toPattern
of pkSet:
raiseAssert "cannot construct a pattern over a set literal"
of pkDictionary:
var dict = DCompoundDict()
for key, val in pr.pairs: dict.entries[key] = grab val
dict.toPattern
of pkEmbedded:
if pr.embeddedRef.isNil: drop()
else:
AnyAtom(orKind: AnyAtomKind.`embedded`, embedded: pr.embeddedRef).toPattern
else:
raise newException(ValueError, "cannot generate a pattern for unhandled Value type")
proc grab*[T](x: T): Pattern =
## Construct a `Pattern` from value of type `T`.

View File

@ -82,8 +82,8 @@ suite "protocol":
test "later-than":
let
obsA = parsePreserves"""<Observe <rec later-than [<lit 1704113731.419243>]> #!#f>"""
obsB = parsePreserves"""<Observe <rec Observe [<rec rec [<lit later-than> <arr [<rec lit [<bind <_>>]>]>]> <_>]> #!#f>"""
obsA = parsePreserves"""<Observe <rec later-than [<lit 1704113731.419243>]> #f>"""
obsB = parsePreserves"""<Observe <rec Observe [<rec rec [<lit later-than> <arr [<rec lit [<bind <_>>]>]>]> <_>]> #f>"""
patA = """<rec later-than [<lit 1704113731.419243>]>""".parsePreserves.preservesTo(Pattern).get
patB = """<rec Observe [<rec rec [<lit later-than> <arr [<rec lit [<bind <_>>]>]>]> <_>]>""".parsePreserves.preservesTo(Pattern).get