Attenuator, for experimenting with client/server
This commit is contained in:
parent
4b7fd6ce88
commit
1b120512a8
|
@ -1,4 +1,4 @@
|
|||
import { Dictionary, IdentitySet, Record, Tuple, Value, is, IdentityMap } from 'preserves';
|
||||
import { IdentitySet, Value } from 'preserves';
|
||||
import { Attenuation, runRewrites } from './rewrite.js';
|
||||
import { queueTask } from './task.js';
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ export const PDiscard = Record.makeConstructor<{}, never>()(
|
|||
_PDiscard, []);
|
||||
|
||||
export const _PBind = Symbol.for('bind');
|
||||
export const PBind = Record.makeConstructor<{name: string, pattern: Pattern}, never>()(
|
||||
export const PBind = Record.makeConstructor<{name: symbol, pattern: Pattern}, never>()(
|
||||
_PBind, ['name', 'pattern']);
|
||||
|
||||
export const _PAnd = Symbol.for('and');
|
||||
|
@ -49,14 +49,14 @@ export const PCompound =
|
|||
|
||||
export type Pattern =
|
||||
| Record<typeof _PDiscard, [], never>
|
||||
| Record<typeof _PBind, [string, Pattern], never>
|
||||
| Record<typeof _PBind, [symbol, Pattern], never>
|
||||
| Record<typeof _PAnd, [Pattern[]], never>
|
||||
| Record<typeof _PNot, [Pattern], never>
|
||||
| Record<typeof _Lit, [Value<never>], never>
|
||||
| Record<typeof _PCompound, [ConstructorSpec, Dictionary<Pattern, never>], never>;
|
||||
|
||||
export const _TRef = Symbol.for('ref');
|
||||
export const TRef = Record.makeConstructor<{name: string}, never>()(
|
||||
export const TRef = Record.makeConstructor<{name: symbol}, never>()(
|
||||
_TRef, ['name']);
|
||||
|
||||
export const _TCompound = Symbol.for('compound');
|
||||
|
@ -65,7 +65,7 @@ export const TCompound =
|
|||
_TCompound, ['ctor', 'members']);
|
||||
|
||||
export type Template =
|
||||
| Record<typeof _TRef, [string], never>
|
||||
| Record<typeof _TRef, [symbol], never>
|
||||
| Record<typeof _Lit, [Value<never>], never>
|
||||
| Record<typeof _TCompound, [ConstructorSpec, Dictionary<Template, never>], never>;
|
||||
|
||||
|
@ -78,7 +78,7 @@ export function match(p: Pattern, v: Assertion): Bindings | null {
|
|||
return true;
|
||||
case _PBind:
|
||||
if (walk(PBind._.pattern(p), v)) {
|
||||
bindings[PBind._.name(p)] = v;
|
||||
bindings[PBind._.name(p).asPreservesText()] = v;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -138,8 +138,9 @@ export function instantiate(t: Template, b: Bindings): Assertion {
|
|||
function walk(t: Template): Assertion {
|
||||
switch (t.label) {
|
||||
case _TRef: {
|
||||
const v = b[TRef._.name(t)];
|
||||
if (v === void 0) throw new Error(`Unbound reference: ${TRef._.name(t)}`);
|
||||
const n = TRef._.name(t).asPreservesText()
|
||||
const v = b[n];
|
||||
if (v === void 0) throw new Error(`Unbound reference: ${n}`);
|
||||
return v;
|
||||
}
|
||||
case _Lit:
|
||||
|
@ -207,8 +208,10 @@ export function runRewrites(a: Attenuation | undefined, v: Assertion): Assertion
|
|||
return v;
|
||||
}
|
||||
|
||||
const _a = Symbol.for('a');
|
||||
|
||||
export function rfilter(... patterns: Pattern[]): RewriteStage {
|
||||
return patterns.map(p => ({ pattern: PBind('a', p), template: TRef('a') }));
|
||||
return patterns.map(p => ({ pattern: PBind(_a, p), template: TRef(_a) }));
|
||||
}
|
||||
|
||||
export function attenuate(ref: Ref, ... a: Attenuation): Ref {
|
||||
|
|
|
@ -6,11 +6,11 @@ import { Bytes, Dictionary } from 'preserves';
|
|||
async function main() {
|
||||
const m1 = await mint('hello world', new Bytes(KEY_LENGTH));
|
||||
console.log(m1.asPreservesText());
|
||||
const m2 = await attenuate(m1, Rewrite(RW.PBind('a',
|
||||
const m2 = await attenuate(m1, Rewrite(RW.PBind(Symbol.for('a'),
|
||||
RW.PCompound(RW.CRec(Symbol.for('says'), 2),
|
||||
new Dictionary<RW.Pattern, never>([
|
||||
[0, RW.Lit('Tony')]]))),
|
||||
RW.TRef('a')));
|
||||
RW.TRef(Symbol.for('a'))));
|
||||
console.log(m2.asPreservesText());
|
||||
console.log('should be true:', await validate(m1, new Bytes(KEY_LENGTH)));
|
||||
console.log('should be true:', await validate(m2, new Bytes(KEY_LENGTH)));
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { Bytes, Reader } from 'preserves';
|
||||
import { attenuate, Caveat, sturdyDecode, sturdyEncode, SturdyRef } from '../sturdy.js';
|
||||
|
||||
const [ base, pat ] = process.argv.slice(2);
|
||||
const baseCap = sturdyDecode(Bytes.fromHex(base ?? '')) as SturdyRef;
|
||||
const cs = new Reader(pat).next() as Array<Caveat>;
|
||||
attenuate(baseCap, ... cs).then(derived => {
|
||||
console.log(derived.asPreservesText());
|
||||
console.log(sturdyEncode(derived).toHex());
|
||||
});
|
Loading…
Reference in New Issue