From 63e417cdc3f185a808a3b533dfbc1198b5712d79 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Wed, 9 Jun 2021 15:13:50 +0200 Subject: [PATCH] TAttenuate --- schemas/sturdy.prs | 3 ++- src/gen/sturdy.ts | 59 +++++++++++++++++++++++++++++++++++------- src/runtime/rewrite.ts | 10 ++++++- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/schemas/sturdy.prs b/schemas/sturdy.prs index 630f395..f82dd4e 100644 --- a/schemas/sturdy.prs +++ b/schemas/sturdy.prs @@ -36,7 +36,8 @@ PNot = . PCompound = . PCompoundMembers = { any: Pattern ...:... }. -Template = TRef / Lit / TCompound . +Template = TAttenuate / TRef / Lit / TCompound . +TAttenuate = . TRef = . TCompound = . TCompoundMembers = { any: Template ...:... }. diff --git a/src/gen/sturdy.ts b/src/gen/sturdy.ts index 7847c2c..b4552f6 100644 --- a/src/gen/sturdy.ts +++ b/src/gen/sturdy.ts @@ -13,6 +13,7 @@ export const $Symbol = Symbol.for("Symbol"); export const $_ = Symbol.for("_"); export const $and = Symbol.for("and"); export const $arr = Symbol.for("arr"); +export const $attenuate = Symbol.for("attenuate"); export const $bind = Symbol.for("bind"); export const $compound = Symbol.for("compound"); export const $dict = Symbol.for("dict"); @@ -97,11 +98,14 @@ export type PCompound = {"ctor": ConstructorSpec, "members": PCompoundMembers}; export type PCompoundMembers = _.KeyedDictionary<_val, Pattern, _embedded>; export type Template = ( + {"_variant": "TAttenuate", "value": TAttenuate} | {"_variant": "TRef", "value": TRef} | {"_variant": "Lit", "value": Lit} | {"_variant": "TCompound", "value": TCompound} ); +export type TAttenuate = {"template": Template, "attenuation": Attenuation}; + export type TRef = {"name": symbol}; export type TCompound = {"ctor": ConstructorSpec, "members": TCompoundMembers}; @@ -181,11 +185,14 @@ export function PCompound({ctor, members}: {ctor: ConstructorSpec, members: PCom export function PCompoundMembers(value: _.KeyedDictionary<_val, Pattern, _embedded>): PCompoundMembers {return value;} export namespace Template { + export function TAttenuate(value: TAttenuate): Template {return {"_variant": "TAttenuate", "value": value};}; export function TRef(value: TRef): Template {return {"_variant": "TRef", "value": value};}; export function Lit(value: Lit): Template {return {"_variant": "Lit", "value": value};}; export function TCompound(value: TCompound): Template {return {"_variant": "TCompound", "value": value};}; } +export function TAttenuate({template, attenuation}: {template: Template, attenuation: Attenuation}): TAttenuate {return {"template": template, "attenuation": attenuation};} + export function TRef(name: symbol): TRef {return {"name": name};} export function TCompound({ctor, members}: {ctor: ConstructorSpec, members: TCompoundMembers}): TCompound {return {"ctor": ctor, "members": members};} @@ -837,18 +844,23 @@ export function asTemplate(v: _val): Template { } export function toTemplate(v: _val): undefined | Template { - let _tmp0: (TRef) | undefined; + let _tmp0: (TAttenuate) | undefined; let result: undefined | Template; - _tmp0 = toTRef(v); - if (_tmp0 !== void 0) {result = {"_variant": "TRef", "value": _tmp0};}; + _tmp0 = toTAttenuate(v); + if (_tmp0 !== void 0) {result = {"_variant": "TAttenuate", "value": _tmp0};}; if (result === void 0) { - let _tmp1: (Lit) | undefined; - _tmp1 = toLit(v); - if (_tmp1 !== void 0) {result = {"_variant": "Lit", "value": _tmp1};}; + let _tmp1: (TRef) | undefined; + _tmp1 = toTRef(v); + if (_tmp1 !== void 0) {result = {"_variant": "TRef", "value": _tmp1};}; if (result === void 0) { - let _tmp2: (TCompound) | undefined; - _tmp2 = toTCompound(v); - if (_tmp2 !== void 0) {result = {"_variant": "TCompound", "value": _tmp2};}; + let _tmp2: (Lit) | undefined; + _tmp2 = toLit(v); + if (_tmp2 !== void 0) {result = {"_variant": "Lit", "value": _tmp2};}; + if (result === void 0) { + let _tmp3: (TCompound) | undefined; + _tmp3 = toTCompound(v); + if (_tmp3 !== void 0) {result = {"_variant": "TCompound", "value": _tmp3};}; + }; }; }; return result; @@ -856,12 +868,41 @@ export function toTemplate(v: _val): undefined | Template { export function fromTemplate(_v: Template): _val { switch (_v._variant) { + case "TAttenuate": {return fromTAttenuate(_v.value);}; case "TRef": {return fromTRef(_v.value);}; case "Lit": {return fromLit(_v.value);}; case "TCompound": {return fromTCompound(_v.value);}; }; } +export function asTAttenuate(v: _val): TAttenuate { + let result = toTAttenuate(v); + if (result === void 0) throw new TypeError(`Invalid TAttenuate: ${_.stringify(v)}`); + return result; +} + +export function toTAttenuate(v: _val): undefined | TAttenuate { + let result: undefined | TAttenuate; + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { + let _tmp0: (null) | undefined; + _tmp0 = _.is(v.label, $attenuate) ? null : void 0; + if (_tmp0 !== void 0) { + let _tmp1: (Template) | undefined; + _tmp1 = toTemplate(v[0]); + if (_tmp1 !== void 0) { + let _tmp2: (Attenuation) | undefined; + _tmp2 = toAttenuation(v[1]); + if (_tmp2 !== void 0) {result = {"template": _tmp1, "attenuation": _tmp2};}; + }; + }; + }; + return result; +} + +export function fromTAttenuate(_v: TAttenuate): _val { + return _.Record($attenuate, [fromTemplate(_v["template"]), fromAttenuation(_v["attenuation"])]); +} + export function asTRef(v: _val): TRef { let result = toTRef(v); if (result === void 0) throw new TypeError(`Invalid TRef: ${_.stringify(v)}`); diff --git a/src/runtime/rewrite.ts b/src/runtime/rewrite.ts index b863b9f..b0bf278 100644 --- a/src/runtime/rewrite.ts +++ b/src/runtime/rewrite.ts @@ -1,5 +1,5 @@ import type { Assertion, Handle, Ref, Turn } from "./actor.js"; -import { Bytes, Dictionary, DoubleFloat, IdentityMap, is, isEmbedded, Record, SingleFloat, Tuple } from "@preserves/core"; +import { Bytes, Dictionary, DoubleFloat, embed, IdentityMap, is, isEmbedded, Record, SingleFloat, Tuple } from "@preserves/core"; import { Alts, @@ -112,6 +112,14 @@ export function match(p: Pattern, v: Assertion): Bindings | null { export function instantiate(t: Template, b: Bindings): Assertion { function walk(t: Template): Assertion { switch (t._variant) { + case 'TAttenuate': { + const v = walk(t.value.template); + if (!isEmbedded(v)) { + throw new Error(`Attempt to attenuate non-capability: ${v.asPreservesText()}`); + } + const r = v.embeddedValue; + return embed(attenuate(r, ... t.value.attenuation)); + } case 'TRef': { const n = t.value.name.asPreservesText() const v = b[n];