Named arguments

This commit is contained in:
Tony Garnock-Jones 2021-03-23 19:18:26 +01:00
parent 1bd65cd283
commit be81529c5d
14 changed files with 145 additions and 105 deletions

View File

@ -1,4 +1,4 @@
import { DecodeError, IdentitySet, Value } from '@preserves/core';
import { IdentitySet, Value } from '@preserves/core';
import { Attenuation, runRewrites } from './rewrite.js';
import { queueTask } from './task.js';

View File

@ -15,19 +15,22 @@ export default function (t: Turn, arg: Assertion) {
valueHandle = t.replace(ds, valueHandle, fromBoxState(BoxState(value)));
}
setValue(t, 0);
t.assert(ds, fromObserve(Observe($SetBox, t.ref({
message(t: Turn, [newValue]: [number]): void {
// console.log(`Box ${t.actor.id}: got ${newValue}`);
if (newValue % REPORT_EVERY === 0) {
const endTime = Date.now();
const delta = (endTime - startTime) / 1000.0;
const count = newValue - prevValue;
prevValue = newValue;
startTime = endTime;
console.log(`Box ${t.actor.id}: got ${newValue} (${count / delta} Hz)`);
t.assert(ds, fromObserve(Observe({
label: $SetBox,
observer: t.ref({
message(t: Turn, [newValue]: [number]): void {
// console.log(`Box ${t.actor.id}: got ${newValue}`);
if (newValue % REPORT_EVERY === 0) {
const endTime = Date.now();
const delta = (endTime - startTime) / 1000.0;
const count = newValue - prevValue;
prevValue = newValue;
startTime = endTime;
console.log(`Box ${t.actor.id}: got ${newValue} (${count / delta} Hz)`);
}
if (newValue === LIMIT) t.quit();
setValue(t, newValue);
}
if (newValue === LIMIT) t.quit();
setValue(t, newValue);
}
}))));
})
})));
}

View File

@ -5,23 +5,29 @@ import { Assertion, Ref, Turn } from "./actor.js";
export default function (t: Turn, ds: Ref) {
console.log('Spawning Client');
let count = 0;
t.assert(ds, fromObserve(Observe($BoxState, t.ref({
assert(t: Turn, [currentValue]: [number]): void {
// console.log(`Client ${t.actor.id}: got ${currentValue}`);
t.message(ds, fromSetBox(SetBox(currentValue + 1)));
}
}))));
t.assert(ds, fromObserve(Observe($BoxState, t.ref({
assert(_t: Turn, _assertion: Assertion): void {
count++;
// console.log('inc to', count, _assertion);
},
retract(t: Turn) {
if (--count === 0) {
console.log(`Client ${t.actor.id}: detected box termination`);
t.quit();
t.assert(ds, fromObserve(Observe({
label: $BoxState,
observer: t.ref({
assert(t: Turn, [currentValue]: [number]): void {
// console.log(`Client ${t.actor.id}: got ${currentValue}`);
t.message(ds, fromSetBox(SetBox(currentValue + 1)));
}
// console.log('dec to', count);
},
}))));
})
})));
t.assert(ds, fromObserve(Observe({
label: $BoxState,
observer: t.ref({
assert(_t: Turn, _assertion: Assertion): void {
count++;
// console.log('inc to', count, _assertion);
},
retract(t: Turn) {
if (--count === 0) {
console.log(`Client ${t.actor.id}: detected box termination`);
t.quit();
}
// console.log('dec to', count);
},
})
})));
}

View File

@ -15,9 +15,9 @@ export type SetBox = {"value": number};
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
export function BoxState(value: number): BoxState {return {value};}
export function BoxState(value: number): BoxState {return {"value": value};}
export function SetBox(value: number): SetBox {return {value};}
export function SetBox(value: number): SetBox {return {"value": value};}
export function asBoxState(v: _val): BoxState {
let result = toBoxState(v);

View File

@ -12,7 +12,7 @@ export type Observe = {"label": symbol, "observer": _ptr};
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
export function Observe(label: symbol, observer: _ptr): Observe {return {label, observer};}
export function Observe({label, observer}: {label: symbol, observer: _ptr}): Observe {return {"label": label, "observer": observer};}
export function asObserve(v: _val): Observe {
let result = toObserve(v);

View File

@ -47,25 +47,25 @@ export function Assertion(value: _val): Assertion {return value;}
export function Handle(value: number): Handle {return value;}
export namespace Event {
export function Assert(value: Assert): Event {return {"_variant": "Assert", value};};
export function Retract(value: Retract): Event {return {"_variant": "Retract", value};};
export function Message(value: Message): Event {return {"_variant": "Message", value};};
export function Sync(value: Sync): Event {return {"_variant": "Sync", value};};
export function Assert(value: Assert): Event {return {"_variant": "Assert", "value": value};};
export function Retract(value: Retract): Event {return {"_variant": "Retract", "value": value};};
export function Message(value: Message): Event {return {"_variant": "Message", "value": value};};
export function Sync(value: Sync): Event {return {"_variant": "Sync", "value": value};};
}
export function Oid(value: number): Oid {return value;}
export function Turn(value: Array<TurnEvent>): Turn {return value;}
export function TurnEvent(oid: Oid, event: Event): TurnEvent {return {oid, event};}
export function TurnEvent({oid, event}: {oid: Oid, event: Event}): TurnEvent {return {"oid": oid, "event": event};}
export function Assert(assertion: Assertion, handle: Handle): Assert {return {assertion, handle};}
export function Assert({assertion, handle}: {assertion: Assertion, handle: Handle}): Assert {return {"assertion": assertion, "handle": handle};}
export function Retract(handle: Handle): Retract {return {handle};}
export function Retract(handle: Handle): Retract {return {"handle": handle};}
export function Message(body: Assertion): Message {return {body};}
export function Message(body: Assertion): Message {return {"body": body};}
export function Sync(peer: _ptr): Sync {return {peer};}
export function Sync(peer: _ptr): Sync {return {"peer": peer};}
export function asAssertion(v: _val): Assertion {
let result = toAssertion(v);

View File

@ -84,65 +84,67 @@ export type TCompoundMembers = _.KeyedDictionary<_val, Template, _ptr>;
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
export function SturdyRef(oid: _val, caveatChain: Array<Attenuation>, sig: _.Bytes): SturdyRef {return {oid, caveatChain, sig};}
export function SturdyRef(
{oid, caveatChain, sig}: {oid: _val, caveatChain: Array<Attenuation>, sig: _.Bytes}
): SturdyRef {return {"oid": oid, "caveatChain": caveatChain, "sig": sig};}
export function Attenuation(value: Array<Caveat>): Attenuation {return value;}
export namespace Caveat {
export function Rewrite(value: Rewrite): Caveat {return {"_variant": "Rewrite", value};};
export function Alts(value: Alts): Caveat {return {"_variant": "Alts", value};};
export function Rewrite(value: Rewrite): Caveat {return {"_variant": "Rewrite", "value": value};};
export function Alts(value: Alts): Caveat {return {"_variant": "Alts", "value": value};};
}
export function Rewrite(pattern: Pattern, template: Template): Rewrite {return {pattern, template};}
export function Rewrite({pattern, template}: {pattern: Pattern, template: Template}): Rewrite {return {"pattern": pattern, "template": template};}
export function Alts(alternatives: Array<Rewrite>): Alts {return {alternatives};}
export function Alts(alternatives: Array<Rewrite>): Alts {return {"alternatives": alternatives};}
export function Resolve(sturdyref: SturdyRef, observer: _ptr): Resolve {return {sturdyref, observer};}
export function Resolve({sturdyref, observer}: {sturdyref: SturdyRef, observer: _ptr}): Resolve {return {"sturdyref": sturdyref, "observer": observer};}
export namespace ConstructorSpec {
export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", value};};
export function CArr(value: CArr): ConstructorSpec {return {"_variant": "CArr", value};};
export function CDict(value: CDict): ConstructorSpec {return {"_variant": "CDict", value};};
export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", "value": value};};
export function CArr(value: CArr): ConstructorSpec {return {"_variant": "CArr", "value": value};};
export function CDict(value: CDict): ConstructorSpec {return {"_variant": "CDict", "value": value};};
}
export function CRec(label: _val, arity: number): CRec {return {label, arity};}
export function CRec({label, arity}: {label: _val, arity: number}): CRec {return {"label": label, "arity": arity};}
export function CArr(arity: number): CArr {return {arity};}
export function CArr(arity: number): CArr {return {"arity": arity};}
export function CDict(): CDict {return null;}
export function Lit(value: _val): Lit {return {value};}
export function Lit(value: _val): Lit {return {"value": value};}
export namespace Pattern {
export function PDiscard(value: PDiscard): Pattern {return {"_variant": "PDiscard", value};};
export function PBind(value: PBind): Pattern {return {"_variant": "PBind", value};};
export function PAnd(value: PAnd): Pattern {return {"_variant": "PAnd", value};};
export function PNot(value: PNot): Pattern {return {"_variant": "PNot", value};};
export function Lit(value: Lit): Pattern {return {"_variant": "Lit", value};};
export function PCompound(value: PCompound): Pattern {return {"_variant": "PCompound", value};};
export function PDiscard(value: PDiscard): Pattern {return {"_variant": "PDiscard", "value": value};};
export function PBind(value: PBind): Pattern {return {"_variant": "PBind", "value": value};};
export function PAnd(value: PAnd): Pattern {return {"_variant": "PAnd", "value": value};};
export function PNot(value: PNot): Pattern {return {"_variant": "PNot", "value": value};};
export function Lit(value: Lit): Pattern {return {"_variant": "Lit", "value": value};};
export function PCompound(value: PCompound): Pattern {return {"_variant": "PCompound", "value": value};};
}
export function PDiscard(): PDiscard {return null;}
export function PBind(name: symbol, pattern: Pattern): PBind {return {name, pattern};}
export function PBind({name, pattern}: {name: symbol, pattern: Pattern}): PBind {return {"name": name, "pattern": pattern};}
export function PAnd(patterns: Array<Pattern>): PAnd {return {patterns};}
export function PAnd(patterns: Array<Pattern>): PAnd {return {"patterns": patterns};}
export function PNot(pattern: Pattern): PNot {return {pattern};}
export function PNot(pattern: Pattern): PNot {return {"pattern": pattern};}
export function PCompound(ctor: ConstructorSpec, members: PCompoundMembers): PCompound {return {ctor, members};}
export function PCompound({ctor, members}: {ctor: ConstructorSpec, members: PCompoundMembers}): PCompound {return {"ctor": ctor, "members": members};}
export function PCompoundMembers(value: _.KeyedDictionary<_val, Pattern, _ptr>): PCompoundMembers {return value;}
export namespace Template {
export function TRef(value: TRef): Template {return {"_variant": "TRef", value};};
export function Lit(value: Lit): Template {return {"_variant": "Lit", value};};
export function TCompound(value: TCompound): Template {return {"_variant": "TCompound", 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 TRef(name: symbol): TRef {return {name};}
export function TRef(name: symbol): TRef {return {"name": name};}
export function TCompound(ctor: ConstructorSpec, members: TCompoundMembers): TCompound {return {ctor, members};}
export function TCompound({ctor, members}: {ctor: ConstructorSpec, members: TCompoundMembers}): TCompound {return {"ctor": ctor, "members": members};}
export function TCompoundMembers(value: _.KeyedDictionary<_val, Template, _ptr>): TCompoundMembers {return value;}

View File

@ -11,7 +11,7 @@ export type Instance = {"name": string, "argument": _val};
export const _toPtr = () => { throw new _.DecodeError("Pointers forbidden"); };
export function Instance(name: string, argument: _val): Instance {return {name, argument};}
export function Instance({name, argument}: {name: string, argument: _val}): Instance {return {"name": name, "argument": argument};}
export function asInstance(v: _val): Instance {
let result = toInstance(v);

View File

@ -58,24 +58,34 @@ Turn.for(new Actor(), async (t: Turn) => {
const ds_for_box = attenuate(
ds,
rfilter(
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($BoxState, 1)), new Dictionary())),
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($Observe, 2)),
new Dictionary<Ref, Pattern>([
[0, Pattern.Lit(Lit($SetBox))]])))));
Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CRec(CRec({ label: $BoxState, arity: 1 })),
members: new Dictionary()
})),
Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })),
members: new Dictionary<Ref, Pattern>([
[0, Pattern.Lit(Lit($SetBox))]])
}))));
const ds_for_client = attenuate(
ds_unproxied,
rfilter(
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($SetBox, 1)), new Dictionary())),
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($Observe, 2)),
new Dictionary<Ref, Pattern>([
[0, Pattern.Lit(Lit($BoxState))]])))));
Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CRec(CRec({ label: $SetBox, arity: 1 })),
members: new Dictionary()
})),
Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })),
members: new Dictionary<Ref, Pattern>([
[0, Pattern.Lit(Lit($BoxState))]])
}))));
const boxpath = path.join(__dirname, 'box.js');
const clientpath = path.join(__dirname, 'client.js');
spawnModule(t, boxpath, [ds_for_box, 500000, 25000]);
// spawnWorker(t, boxpath, [ds_for_box, 50000, 2500]);
// spawnModule(t, boxpath, [ds_for_box, 500000, 25000]);
spawnWorker(t, boxpath, [ds_for_box, 50000, 2500]);
spawnModule(t, clientpath, ds_for_client);
// spawnWorker(t, clientpath, ds_for_client);

View File

@ -52,7 +52,10 @@ export class RelayEntity implements Entity {
}
assert(_turn: Turn, assertion: Assertion, handle: Handle): void {
this.send(IO.Event.Assert(IO.Assert(this.relay.register(assertion, handle), handle)))
this.send(IO.Event.Assert(IO.Assert({
assertion: this.relay.register(assertion, handle),
handle
})))
}
retract(_turn: Turn, handle: Handle): void {
@ -240,7 +243,7 @@ export class Relay {
this.pendingTurn = [];
});
}
this.pendingTurn.push(IO.TurnEvent(remoteOid, m));
this.pendingTurn.push(IO.TurnEvent({ oid: remoteOid, event: m }));
}
lookupLocal(localOid: IO.Oid): Ref {

View File

@ -150,7 +150,10 @@ export function runRewrites(a: Attenuation | undefined, v: Assertion): Assertion
const _a = Symbol.for('a');
export function rfilter(... patterns: Pattern[]): Caveat {
const ps = patterns.map(p => Rewrite(Pattern.PBind(PBind(_a, p)), Template.TRef(TRef(_a))));
const ps = patterns.map(p => Rewrite({
pattern: Pattern.PBind(PBind({ name: _a, pattern: p })),
template: Template.TRef(TRef(_a))
}));
return ps.length === 1 ? Caveat.Rewrite(ps[0]) : Caveat.Alts(Alts(ps));
}

View File

@ -29,11 +29,14 @@ const socket = net.createConnection({ port: 5999, host: 'localhost' }, () => {
// debug: true,
}).then(gatekeeper => import(moduleName).then(m => t.freshen(t => {
t.assert(shutdownRef, true);
t.assert(gatekeeper, fromResolve(Resolve(asSturdyRef(cap), t.ref({
assert(t, ds) {
m.default(t, ds);
}
}))));
t.assert(gatekeeper, fromResolve(Resolve({
sturdyref: asSturdyRef(cap),
observer: t.ref({
assert(t, ds) {
m.default(t, ds);
}
})
})));
})));
});
});

View File

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

View File

@ -35,15 +35,19 @@ export function sturdyDecode(bs: Bytes): SturdyValue {
}
export async function mint(oid: SturdyValue, secretKey: Bytes): Promise<S.SturdyRef> {
return S.SturdyRef(oid, [], await mac(secretKey, sturdyEncode(oid)));
return S.SturdyRef({
oid,
caveatChain: [],
sig: await mac(secretKey, sturdyEncode(oid)),
});
}
export async function attenuate(r: S.SturdyRef, ... a: S.Attenuation): Promise<S.SturdyRef> {
return S.SturdyRef(
r.oid,
[... r.caveatChain, a],
await mac(r.sig, sturdyEncode(S.fromAttenuation(a)))
);
return S.SturdyRef({
oid: r.oid,
caveatChain: [... r.caveatChain, a],
sig: await mac(r.sig, sturdyEncode(S.fromAttenuation(a)))
});
}
export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> {