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 { Attenuation, runRewrites } from './rewrite.js';
import { queueTask } from './task.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))); valueHandle = t.replace(ds, valueHandle, fromBoxState(BoxState(value)));
} }
setValue(t, 0); setValue(t, 0);
t.assert(ds, fromObserve(Observe($SetBox, t.ref({ t.assert(ds, fromObserve(Observe({
message(t: Turn, [newValue]: [number]): void { label: $SetBox,
// console.log(`Box ${t.actor.id}: got ${newValue}`); observer: t.ref({
if (newValue % REPORT_EVERY === 0) { message(t: Turn, [newValue]: [number]): void {
const endTime = Date.now(); // console.log(`Box ${t.actor.id}: got ${newValue}`);
const delta = (endTime - startTime) / 1000.0; if (newValue % REPORT_EVERY === 0) {
const count = newValue - prevValue; const endTime = Date.now();
prevValue = newValue; const delta = (endTime - startTime) / 1000.0;
startTime = endTime; const count = newValue - prevValue;
console.log(`Box ${t.actor.id}: got ${newValue} (${count / delta} Hz)`); 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) { export default function (t: Turn, ds: Ref) {
console.log('Spawning Client'); console.log('Spawning Client');
let count = 0; let count = 0;
t.assert(ds, fromObserve(Observe($BoxState, t.ref({ t.assert(ds, fromObserve(Observe({
assert(t: Turn, [currentValue]: [number]): void { label: $BoxState,
// console.log(`Client ${t.actor.id}: got ${currentValue}`); observer: t.ref({
t.message(ds, fromSetBox(SetBox(currentValue + 1))); 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();
} }
// 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 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 { export function asBoxState(v: _val): BoxState {
let result = toBoxState(v); 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 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 { export function asObserve(v: _val): Observe {
let result = toObserve(v); 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 function Handle(value: number): Handle {return value;}
export namespace Event { export namespace Event {
export function Assert(value: Assert): Event {return {"_variant": "Assert", value};}; export function Assert(value: Assert): Event {return {"_variant": "Assert", "value": value};};
export function Retract(value: Retract): Event {return {"_variant": "Retract", value};}; export function Retract(value: Retract): Event {return {"_variant": "Retract", "value": value};};
export function Message(value: Message): Event {return {"_variant": "Message", value};}; export function Message(value: Message): Event {return {"_variant": "Message", "value": value};};
export function Sync(value: Sync): Event {return {"_variant": "Sync", value};}; export function Sync(value: Sync): Event {return {"_variant": "Sync", "value": value};};
} }
export function Oid(value: number): Oid {return value;} export function Oid(value: number): Oid {return value;}
export function Turn(value: Array<TurnEvent>): Turn {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 { export function asAssertion(v: _val): Assertion {
let result = toAssertion(v); 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 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 function Attenuation(value: Array<Caveat>): Attenuation {return value;}
export namespace Caveat { export namespace Caveat {
export function Rewrite(value: Rewrite): Caveat {return {"_variant": "Rewrite", value};}; export function Rewrite(value: Rewrite): Caveat {return {"_variant": "Rewrite", "value": value};};
export function Alts(value: Alts): Caveat {return {"_variant": "Alts", 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 namespace ConstructorSpec {
export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", value};}; export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", "value": value};};
export function CArr(value: CArr): ConstructorSpec {return {"_variant": "CArr", value};}; export function CArr(value: CArr): ConstructorSpec {return {"_variant": "CArr", "value": value};};
export function CDict(value: CDict): ConstructorSpec {return {"_variant": "CDict", 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 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 namespace Pattern {
export function PDiscard(value: PDiscard): Pattern {return {"_variant": "PDiscard", value};}; export function PDiscard(value: PDiscard): Pattern {return {"_variant": "PDiscard", "value": value};};
export function PBind(value: PBind): Pattern {return {"_variant": "PBind", value};}; export function PBind(value: PBind): Pattern {return {"_variant": "PBind", "value": value};};
export function PAnd(value: PAnd): Pattern {return {"_variant": "PAnd", value};}; export function PAnd(value: PAnd): Pattern {return {"_variant": "PAnd", "value": value};};
export function PNot(value: PNot): Pattern {return {"_variant": "PNot", value};}; export function PNot(value: PNot): Pattern {return {"_variant": "PNot", "value": value};};
export function Lit(value: Lit): Pattern {return {"_variant": "Lit", value};}; export function Lit(value: Lit): Pattern {return {"_variant": "Lit", "value": value};};
export function PCompound(value: PCompound): Pattern {return {"_variant": "PCompound", value};}; export function PCompound(value: PCompound): Pattern {return {"_variant": "PCompound", "value": value};};
} }
export function PDiscard(): PDiscard {return null;} 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 function PCompoundMembers(value: _.KeyedDictionary<_val, Pattern, _ptr>): PCompoundMembers {return value;}
export namespace Template { export namespace Template {
export function TRef(value: TRef): Template {return {"_variant": "TRef", value};}; export function TRef(value: TRef): Template {return {"_variant": "TRef", "value": value};};
export function Lit(value: Lit): Template {return {"_variant": "Lit", value};}; export function Lit(value: Lit): Template {return {"_variant": "Lit", "value": value};};
export function TCompound(value: TCompound): Template {return {"_variant": "TCompound", 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;} 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 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 { export function asInstance(v: _val): Instance {
let result = toInstance(v); let result = toInstance(v);

View File

@ -58,24 +58,34 @@ Turn.for(new Actor(), async (t: Turn) => {
const ds_for_box = attenuate( const ds_for_box = attenuate(
ds, ds,
rfilter( rfilter(
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($BoxState, 1)), new Dictionary())), Pattern.PCompound(PCompound({
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($Observe, 2)), ctor: ConstructorSpec.CRec(CRec({ label: $BoxState, arity: 1 })),
new Dictionary<Ref, Pattern>([ members: new Dictionary()
[0, Pattern.Lit(Lit($SetBox))]]))))); })),
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( const ds_for_client = attenuate(
ds_unproxied, ds_unproxied,
rfilter( rfilter(
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($SetBox, 1)), new Dictionary())), Pattern.PCompound(PCompound({
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($Observe, 2)), ctor: ConstructorSpec.CRec(CRec({ label: $SetBox, arity: 1 })),
new Dictionary<Ref, Pattern>([ members: new Dictionary()
[0, Pattern.Lit(Lit($BoxState))]]))))); })),
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 boxpath = path.join(__dirname, 'box.js');
const clientpath = path.join(__dirname, 'client.js'); const clientpath = path.join(__dirname, 'client.js');
spawnModule(t, boxpath, [ds_for_box, 500000, 25000]); // spawnModule(t, boxpath, [ds_for_box, 500000, 25000]);
// spawnWorker(t, boxpath, [ds_for_box, 50000, 2500]); spawnWorker(t, boxpath, [ds_for_box, 50000, 2500]);
spawnModule(t, clientpath, ds_for_client); spawnModule(t, clientpath, ds_for_client);
// spawnWorker(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 { 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 { retract(_turn: Turn, handle: Handle): void {
@ -240,7 +243,7 @@ export class Relay {
this.pendingTurn = []; this.pendingTurn = [];
}); });
} }
this.pendingTurn.push(IO.TurnEvent(remoteOid, m)); this.pendingTurn.push(IO.TurnEvent({ oid: remoteOid, event: m }));
} }
lookupLocal(localOid: IO.Oid): Ref { 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'); const _a = Symbol.for('a');
export function rfilter(... patterns: Pattern[]): Caveat { 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)); 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, // debug: true,
}).then(gatekeeper => import(moduleName).then(m => t.freshen(t => { }).then(gatekeeper => import(moduleName).then(m => t.freshen(t => {
t.assert(shutdownRef, true); t.assert(shutdownRef, true);
t.assert(gatekeeper, fromResolve(Resolve(asSturdyRef(cap), t.ref({ t.assert(gatekeeper, fromResolve(Resolve({
assert(t, ds) { sturdyref: asSturdyRef(cap),
m.default(t, ds); observer: t.ref({
} assert(t, ds) {
})))); m.default(t, ds);
}
})
})));
}))); })));
}); });
}); });

View File

@ -7,14 +7,20 @@ import { Ref } from 'actor.js';
async function main() { 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({
RW.Pattern.PBind(RW.PBind( pattern: RW.Pattern.PBind(RW.PBind({
Symbol.for('a'), name: Symbol.for('a'),
RW.Pattern.PCompound(RW.PCompound( pattern: RW.Pattern.PCompound(RW.PCompound({
RW.ConstructorSpec.CRec(RW.CRec(Symbol.for('says'), 2)), ctor: RW.ConstructorSpec.CRec(RW.CRec({
new Dictionary<Ref, RW.Pattern>([ label: Symbol.for('says'),
[0, RW.Pattern.Lit(RW.Lit('Tony'))]]))))), arity: 2
RW.Template.TRef(RW.TRef(Symbol.for('a')))))); })),
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(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)));
console.log('should be true:', await validate(m2, 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> { 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> { export async function attenuate(r: S.SturdyRef, ... a: S.Attenuation): Promise<S.SturdyRef> {
return S.SturdyRef( return S.SturdyRef({
r.oid, oid: r.oid,
[... r.caveatChain, a], caveatChain: [... r.caveatChain, a],
await mac(r.sig, sturdyEncode(S.fromAttenuation(a))) sig: await mac(r.sig, sturdyEncode(S.fromAttenuation(a)))
); });
} }
export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> { export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> {