No names in patterns

This commit is contained in:
Tony Garnock-Jones 2021-07-13 18:27:58 +02:00
parent 9bb081292b
commit 381471225b
4 changed files with 35 additions and 43 deletions

View File

@ -1,4 +1,5 @@
version 1 . version 1 .
embeddedType Actor.Ref .
; Each Attenuation is a stage. The sequence of Attenuations is run RIGHT-TO-LEFT. ; Each Attenuation is a stage. The sequence of Attenuations is run RIGHT-TO-LEFT.
; That is, the newest Attenuations are at the right. ; That is, the newest Attenuations are at the right.
@ -30,7 +31,7 @@ Pattern = PDiscard / PAtom / PEmbedded / PBind / PAnd / PNot / Lit / PCompound .
PDiscard = <_>. PDiscard = <_>.
PAtom = =Boolean / =Float / =Double / =SignedInteger / =String / =ByteString / =Symbol . PAtom = =Boolean / =Float / =Double / =SignedInteger / =String / =ByteString / =Symbol .
PEmbedded = =Embedded . PEmbedded = =Embedded .
PBind = <bind @name symbol @pattern Pattern>. PBind = <bind @pattern Pattern>.
PAnd = <and @patterns [Pattern ...]>. PAnd = <and @patterns [Pattern ...]>.
PNot = <not @pattern Pattern>. PNot = <not @pattern Pattern>.
PCompound = <compound @ctor ConstructorSpec @members PCompoundMembers>. PCompound = <compound @ctor ConstructorSpec @members PCompoundMembers>.
@ -38,7 +39,6 @@ PCompoundMembers = { any: Pattern ...:... }.
Template = TAttenuate / TRef / Lit / TCompound . Template = TAttenuate / TRef / Lit / TCompound .
TAttenuate = <attenuate @template Template @attenuation Attenuation>. TAttenuate = <attenuate @template Template @attenuation Attenuation>.
TRef = <ref @name symbol>. TRef = <ref @binding int>.
TCompound = <compound @ctor ConstructorSpec @members TCompoundMembers>. TCompound = <compound @ctor ConstructorSpec @members TCompoundMembers>.
TCompoundMembers = { any: Template ...:... }. TCompoundMembers = { any: Template ...:... }.

View File

@ -7,18 +7,15 @@ async function main() {
const m1 = await mint('hello world', new Bytes(KEY_LENGTH)); const m1 = await mint('hello world', new Bytes(KEY_LENGTH));
console.log(m1); console.log(m1);
const m2 = await attenuate(m1, Caveat.Rewrite(Rewrite({ const m2 = await attenuate(m1, Caveat.Rewrite(Rewrite({
pattern: RW.Pattern.PBind(RW.PBind({ pattern: RW.Pattern.PBind(RW.PBind(RW.Pattern.PCompound(RW.PCompound({
name: Symbol.for('a'),
pattern: RW.Pattern.PCompound(RW.PCompound({
ctor: RW.ConstructorSpec.CRec(RW.CRec({ ctor: RW.ConstructorSpec.CRec(RW.CRec({
label: Symbol.for('says'), label: Symbol.for('says'),
arity: 2 arity: 2
})), })),
members: new Dictionary<RW._embedded, RW.Pattern>([ members: new Dictionary<RW._embedded, RW.Pattern>([
[0, RW.Pattern.Lit(RW.Lit('Tony'))]]) [0, RW.Pattern.Lit(RW.Lit('Tony'))]])
})) })))),
})), template: RW.Template.TRef(RW.TRef(0))
template: RW.Template.TRef(RW.TRef(Symbol.for('a')))
}))); })));
console.log(m2); console.log(m2);
console.log('should be true:', await validate(m1, new Bytes(KEY_LENGTH))); console.log('should be true:', await validate(m1, new Bytes(KEY_LENGTH)));

View File

@ -1,4 +1,5 @@
import * as _ from "@preserves/core"; import * as _ from "@preserves/core";
import * as _i_Actor from "../runtime/actor";
export const $0 = 0; export const $0 = 0;
export const $1 = 1; export const $1 = 1;
@ -24,7 +25,7 @@ export const $rec = Symbol.for("rec");
export const $ref = Symbol.for("ref"); export const $ref = Symbol.for("ref");
export const $rewrite = Symbol.for("rewrite"); export const $rewrite = Symbol.for("rewrite");
export type _embedded = any; export type _embedded = _i_Actor.Ref;
export type _val = _.Value<_embedded>; export type _val = _.Value<_embedded>;
@ -87,7 +88,7 @@ export type PAtom = (
export type PEmbedded = null; export type PEmbedded = null;
export type PBind = {"name": symbol, "pattern": Pattern}; export type PBind = {"pattern": Pattern};
export type PAnd = {"patterns": Array<Pattern>}; export type PAnd = {"patterns": Array<Pattern>};
@ -106,7 +107,7 @@ export type Template = (
export type TAttenuate = {"template": Template, "attenuation": Attenuation}; export type TAttenuate = {"template": Template, "attenuation": Attenuation};
export type TRef = {"name": symbol}; export type TRef = {"binding": number};
export type TCompound = {"ctor": ConstructorSpec, "members": TCompoundMembers}; export type TCompound = {"ctor": ConstructorSpec, "members": TCompoundMembers};
@ -174,7 +175,7 @@ export namespace PAtom {
export function PEmbedded(): PEmbedded {return null;} export function PEmbedded(): PEmbedded {return null;}
export function PBind({name, pattern}: {name: symbol, pattern: Pattern}): PBind {return {"name": name, "pattern": pattern};} export function PBind(pattern: Pattern): PBind {return {"pattern": pattern};}
export function PAnd(patterns: Array<Pattern>): PAnd {return {"patterns": patterns};} export function PAnd(patterns: Array<Pattern>): PAnd {return {"patterns": patterns};}
@ -193,7 +194,7 @@ export namespace Template {
export function TAttenuate({template, attenuation}: {template: Template, attenuation: Attenuation}): TAttenuate {return {"template": template, "attenuation": attenuation};} 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 TRef(binding: number): TRef {return {"binding": binding};}
export function TCompound({ctor, members}: {ctor: ConstructorSpec, members: TCompoundMembers}): TCompound {return {"ctor": ctor, "members": members};} export function TCompound({ctor, members}: {ctor: ConstructorSpec, members: TCompoundMembers}): TCompound {return {"ctor": ctor, "members": members};}
@ -706,19 +707,15 @@ export function toPBind(v: _val): undefined | PBind {
let _tmp0: (null) | undefined; let _tmp0: (null) | undefined;
_tmp0 = _.is(v.label, $bind) ? null : void 0; _tmp0 = _.is(v.label, $bind) ? null : void 0;
if (_tmp0 !== void 0) { if (_tmp0 !== void 0) {
let _tmp1: (symbol) | undefined; let _tmp1: (Pattern) | undefined;
_tmp1 = typeof v[0] === 'symbol' ? v[0] : void 0; _tmp1 = toPattern(v[0]);
if (_tmp1 !== void 0) { if (_tmp1 !== void 0) {result = {"pattern": _tmp1};};
let _tmp2: (Pattern) | undefined;
_tmp2 = toPattern(v[1]);
if (_tmp2 !== void 0) {result = {"name": _tmp1, "pattern": _tmp2};};
};
}; };
}; };
return result; return result;
} }
export function fromPBind(_v: PBind): _val {return _.Record($bind, [_v["name"], fromPattern(_v["pattern"])]);} export function fromPBind(_v: PBind): _val {return _.Record($bind, [fromPattern(_v["pattern"])]);}
export function asPAnd(v: _val): PAnd { export function asPAnd(v: _val): PAnd {
let result = toPAnd(v); let result = toPAnd(v);
@ -915,15 +912,15 @@ export function toTRef(v: _val): undefined | TRef {
let _tmp0: (null) | undefined; let _tmp0: (null) | undefined;
_tmp0 = _.is(v.label, $ref) ? null : void 0; _tmp0 = _.is(v.label, $ref) ? null : void 0;
if (_tmp0 !== void 0) { if (_tmp0 !== void 0) {
let _tmp1: (symbol) | undefined; let _tmp1: (number) | undefined;
_tmp1 = typeof v[0] === 'symbol' ? v[0] : void 0; _tmp1 = typeof v[0] === 'number' ? v[0] : void 0;
if (_tmp1 !== void 0) {result = {"name": _tmp1};}; if (_tmp1 !== void 0) {result = {"binding": _tmp1};};
}; };
}; };
return result; return result;
} }
export function fromTRef(_v: TRef): _val {return _.Record($ref, [_v["name"]]);} export function fromTRef(_v: TRef): _val {return _.Record($ref, [_v["binding"]]);}
export function asTCompound(v: _val): TCompound { export function asTCompound(v: _val): TCompound {
let result = toTCompound(v); let result = toTCompound(v);

View File

@ -27,10 +27,10 @@ import {
} from '../gen/sturdy.js'; } from '../gen/sturdy.js';
export * from '../gen/sturdy.js'; export * from '../gen/sturdy.js';
export type Bindings = { [name: string]: Assertion }; export type Bindings = Array<Assertion>;
export function match(p: Pattern, v: Assertion): Bindings | null { export function match(p: Pattern, v: Assertion): Bindings | null {
let bindings: Bindings = {}; let bindings: Bindings = [];
function walk(p: Pattern, v: Assertion): boolean { function walk(p: Pattern, v: Assertion): boolean {
switch (p._variant) { switch (p._variant) {
@ -50,7 +50,7 @@ export function match(p: Pattern, v: Assertion): Bindings | null {
return isEmbedded(v); return isEmbedded(v);
case 'PBind': case 'PBind':
if (walk(p.value.pattern, v)) { if (walk(p.value.pattern, v)) {
bindings[p.value.name.asPreservesText()] = v; bindings.push(v);
return true; return true;
} }
return false; return false;
@ -61,7 +61,7 @@ export function match(p: Pattern, v: Assertion): Bindings | null {
return true; return true;
case 'PNot': { case 'PNot': {
const savedBindings = bindings; const savedBindings = bindings;
bindings = {}; bindings = [];
const result = !walk(p.value.pattern, v) const result = !walk(p.value.pattern, v)
bindings = savedBindings; bindings = savedBindings;
return result; return result;
@ -121,7 +121,7 @@ export function instantiate(t: Template, b: Bindings): Assertion {
return embed(attenuate(r, ... t.value.attenuation)); return embed(attenuate(r, ... t.value.attenuation));
} }
case 'TRef': { case 'TRef': {
const n = t.value.name.asPreservesText() const n = t.value.binding;
const v = b[n]; const v = b[n];
if (v === void 0) throw new Error(`Unbound reference: ${n}`); if (v === void 0) throw new Error(`Unbound reference: ${n}`);
return v; return v;
@ -193,12 +193,10 @@ export function runRewrites(a: Attenuation | undefined, v: Assertion): Assertion
return v; return v;
} }
const _a = Symbol.for('a');
export function rfilter(... patterns: Pattern[]): Caveat { export function rfilter(... patterns: Pattern[]): Caveat {
const ps = patterns.map(p => Rewrite({ const ps = patterns.map(p => Rewrite({
pattern: Pattern.PBind(PBind({ name: _a, pattern: p })), pattern: Pattern.PBind(PBind(p)),
template: Template.TRef(TRef(_a)) template: Template.TRef(TRef(0))
})); }));
return ps.length === 1 ? Caveat.Rewrite(ps[0]) : Caveat.Alts(Alts(ps)); return ps.length === 1 ? Caveat.Rewrite(ps[0]) : Caveat.Alts(Alts(ps));
} }
@ -271,8 +269,8 @@ export function pAnd(... ps: Pattern[]): Pattern {
return Pattern.PAnd(PAnd(ps)); return Pattern.PAnd(PAnd(ps));
} }
export function pBind(name: symbol, pattern: Pattern): Pattern { export function pBind(pattern: Pattern): Pattern {
return Pattern.PBind(PBind({ name, pattern })); return Pattern.PBind(PBind(pattern));
} }
export function pEmbedded(): Pattern { export function pEmbedded(): Pattern {