From 90e71a606e6c1b3ec278545aeecbfe3e7d8d5f9c Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Wed, 12 Jan 2022 11:05:19 +0100 Subject: [PATCH] Experimental pattern (quasi)quoting --- syndicate/patterns.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/syndicate/patterns.py b/syndicate/patterns.py index 84cdb04..400df68 100644 --- a/syndicate/patterns.py +++ b/syndicate/patterns.py @@ -1,5 +1,6 @@ from .schema import dataspacePatterns as P from . import Symbol, Record +from preserves import preserve _dict = dict ## we're about to shadow the builtin @@ -10,6 +11,30 @@ def bind(p): CAPTURE = bind(_) +class unquote: + def __init__(self, pattern): + self.pattern = pattern + +# Simple, stupid single-level quasiquotation. +def quote(p): + if isinstance(p, unquote): + return p.pattern + if p.VARIANT == P.Pattern.DDiscard.VARIANT: + return lit(preserve(p)) + if p.VARIANT == P.Pattern.DBind.VARIANT: + return rec('bind', quote(p.value.pattern)) + if p.VARIANT == P.Pattern.DLit.VARIANT: + return lit(preserve(p)) + if p.VARIANT == P.Pattern.DCompound.VARIANT: + p = p.value + if p.VARIANT == P.DCompound.rec.VARIANT: + return rec('rec', lit(p.label), arr(*map(quote, p.fields))) + if p.VARIANT == P.DCompound.arr.VARIANT: + return rec('arr', arr(*map(quote, p.items))) + if p.VARIANT == P.DCompound.dict.VARIANT: + return rec('dict', dict(*map(lambda kv: (kv[0], quote(kv[1])), p.entries.items()))) + raise Exception(f'Unhandled case in quote: {repr(p)}') + def lit(v): if isinstance(v, list) or isinstance(v, tuple): return arr(*map(lit, v))