Skip to content

Commit 0c4b0d1

Browse files
committed
@rulespace package
1 parent 7c9a027 commit 0c4b0d1

8 files changed

+541
-144
lines changed

agreval.js

+169-123
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
// import * as evaluator from './compiled/agreval_module.mjs';
2-
import { compileToConstructor, compileToModuleSrc, deltaSource, instance2dot, metaInstance } from 'rulespace';
2+
import { assertTrue, MutableMaps, Sets } from '@rulespace/common';
3+
import { compileToConstructor, compileToModuleSrc, instance2dot, computeMeta } from '@rulespace/rulespace';
34
import { SchemeParser, Sym, Pair } from './sexp-reader.js';
4-
import { assertTrue, MutableMaps, Sets } from 'common';
55

66
import { specification } from './agreval-rsp.js';
77

8+
export { lattice_conc, lattice_prim } from './lattice-rsp.js';
9+
export { kalloc_conc, kalloc_0cfa } from './kalloc-rsp.js';
10+
export { specification as semantics_scheme };
11+
export { computeMeta };
12+
13+
export { instance2dot };
814

915
function param2tuples(lam)
1016
{
@@ -190,7 +196,6 @@ function* filterPred(tuples, pred)
190196

191197
export function create_agreval(configSrc)
192198
{
193-
194199
const evaluatorCtr = compileToConstructor(specification + configSrc);
195200

196201
return function agreval(src, options = {})
@@ -220,102 +225,145 @@ export function create_agreval(configSrc)
220225
debug(evaluator);
221226
}
222227

223-
return evaluator;
228+
return new Evaluator(evaluator);
224229
}
225230
}
226231

227-
function* result(evaluator)
232+
class Evaluator
228233
{
229-
for (const t of filterPred(evaluator.tuples(), 'evaluate'))
234+
constructor(evaluator)
230235
{
231-
yield t.t1;
236+
this.evaluator = evaluator;
232237
}
233-
}
234238

235-
function initialState(evaluator)
236-
{
237-
return [...filterPred(evaluator.tuples(), 'initial_state')][0].t0;
238-
}
239+
computeFlowGraph()
240+
{
241+
const evaluator = this.evaluator;
242+
const todo = [this.initialState()];
243+
const states = new Set();
244+
const transitions = [];
245+
while (todo.length > 0)
246+
{
247+
const current = todo.pop();
248+
if (states.has(current))
249+
{
250+
continue;
251+
}
252+
states.add(current);
253+
for (const succ of this.successorStates(current))
254+
{
255+
transitions.push([current, succ]);
256+
todo.push(succ);
257+
}
258+
}
259+
return {states:[...states], transitions};
260+
}
239261

240-
function successorStates(evaluator, state)
241-
{
242-
const result = [];
243-
for (const t of filterPred(evaluator.tuples(), 'step'))
262+
*result()
244263
{
245-
if (t.t0 === state)
264+
const evaluator = this.evaluator;
265+
for (const t of filterPred(evaluator.tuples(), 'evaluate'))
246266
{
247-
result.push(t.t1);
267+
yield t.t1;
248268
}
249269
}
250-
return result;
251-
}
252270

253-
function astTuple(evaluator, tag)
254-
{
255-
for (const t of evaluator.tuples())
271+
initialState()
256272
{
257-
if (t.constructor.name.startsWith('$'))
273+
const evaluator = this.evaluator;
274+
return [...filterPred(evaluator.tuples(), 'initial_state')][0].t0;
275+
}
276+
277+
successorStates(state)
278+
{
279+
const evaluator = this.evaluator;
280+
const result = [];
281+
for (const t of filterPred(evaluator.tuples(), 'step'))
258282
{
259-
if (t.t0 === tag)
283+
if (t.t0 === state)
260284
{
261-
return t;
285+
result.push(t.t1);
262286
}
263287
}
288+
return result;
264289
}
265-
throw new Error(`tuple with tag ${tag} not found`);
266-
}
267-
268-
function expToString(evaluator, tag)
269-
{
270-
function helper(tag)
290+
291+
astTuple(tag)
271292
{
272-
const t = astTuple(tag);
273-
switch (t.constructor.name)
293+
const evaluator = this.evaluator;
294+
for (const t of evaluator.tuples())
274295
{
275-
case '$id': return t.t1;
276-
case '$lit': return t.t1;
277-
case '$let': return `(let ((${helper(t.t1)} ${helper(t.t2)})) ${helper(t.t3)})`;
278-
case '$letrec': return `(letrec ((${helper(t.t1)} ${helper(t.t2)})) ${helper(t.t3)})`;
279-
case '$lam': return `(lambda ... ${helper(t.t1)})`;
280-
case '$if': return `(if ${helper(t.t1)} ${helper(t.t2)} ${helper(t.t3)})`;
281-
case '$set': return `(set! ${helper(t.t1)} ${helper(t.t2)})`;
282-
case '$cons': return `(cons ${helper(t.t1)} ${helper(t.t2)})`;
283-
case '$car': return `(car ${helper(t.t1)})`;
284-
case '$cdr': return `(cdr ${helper(t.t1)})`;
285-
case '$setcar': return `(set-car! ${helper(t.t1)} ${helper(t.t2)})`;
286-
case '$setcdr': return `(set-cdr! ${helper(t.t1)} ${helper(t.t2)})`;
287-
case '$app':
296+
if (t.constructor.name.startsWith('$'))
297+
{
298+
if (t.t0 === tag)
288299
{
289-
const randTuples = [];
290-
for (const t_rand of filterPred(evaluator.tuples(), 'rand'))
300+
return t;
301+
}
302+
}
303+
}
304+
throw new Error(`tuple with tag ${tag} not found`);
305+
}
306+
307+
expToString(tag)
308+
{
309+
const evaluator = this.evaluator;
310+
const self = this;
311+
function helper(tag)
312+
{
313+
const t = self.astTuple(tag);
314+
switch (t.constructor.name)
315+
{
316+
case '$id': return t.t1;
317+
case '$lit': return t.t1;
318+
case '$let': return `(let ((${helper(t.t1)} ${helper(t.t2)})) ${helper(t.t3)})`;
319+
case '$letrec': return `(letrec ((${helper(t.t1)} ${helper(t.t2)})) ${helper(t.t3)})`;
320+
case '$lam': return `(lambda ... ${helper(t.t1)})`;
321+
case '$if': return `(if ${helper(t.t1)} ${helper(t.t2)} ${helper(t.t3)})`;
322+
case '$set': return `(set! ${helper(t.t1)} ${helper(t.t2)})`;
323+
case '$cons': return `(cons ${helper(t.t1)} ${helper(t.t2)})`;
324+
case '$car': return `(car ${helper(t.t1)})`;
325+
case '$cdr': return `(cdr ${helper(t.t1)})`;
326+
case '$setcar': return `(set-car! ${helper(t.t1)} ${helper(t.t2)})`;
327+
case '$setcdr': return `(set-cdr! ${helper(t.t1)} ${helper(t.t2)})`;
328+
case '$app':
291329
{
292-
if (t_rand.t1 === t.t0)
330+
const randTuples = [];
331+
for (const t_rand of filterPred(evaluator.tuples(), 'rand'))
293332
{
294-
randTuples.push(t_rand);
333+
if (t_rand.t1 === t.t0)
334+
{
335+
randTuples.push(t_rand);
336+
}
295337
}
338+
randTuples.sort((ta, tb) => ta.t2 - tb.t2);
339+
const rands = randTuples.map(t => t.t0);
340+
return `(${helper(t.t1)} ${rands.map(helper).join(' ')})`;
296341
}
297-
randTuples.sort((ta, tb) => ta.t2 - tb.t2);
298-
const rands = randTuples.map(t => t.t0);
299-
return `(${helper(t.t1)} ${rands.map(helper).join(' ')})`;
300-
}
301-
default: throw new Error(t.constructor.name);
342+
default: throw new Error(t.constructor.name);
343+
}
302344
}
345+
346+
return helper(tag);
303347
}
304348

305-
return helper(tag);
306-
}
307-
308-
function evaluate(evaluator, exp, state)
309-
{
310-
const result = [];
311-
for (const t of filterPred(evaluator.tuples(), 'greval'))
349+
evaluate(exp, state)
312350
{
313-
if (t.t0 === exp && t.t1 === state)
351+
const evaluator = this.evaluator;
352+
const result = [];
353+
for (const t of filterPred(evaluator.tuples(), 'greval'))
314354
{
315-
result.push(t.t2);
355+
if (t.t0 === exp && t.t1 === state)
356+
{
357+
result.push(t.t2);
358+
}
316359
}
360+
return result;
361+
}
362+
363+
meta()
364+
{
365+
return computeMeta(this.evaluator);
317366
}
318-
return result;
319367
}
320368

321369
function debug(evaluator)
@@ -425,70 +473,68 @@ function debug(evaluator)
425473
// })
426474
// }
427475

428-
function dotFlowGraph(evaluator, nodeToString)
429-
{
430-
const todo = [initialState(evaluator)];
431-
const nodes = [];
432-
const transitions = new Map();
433-
while (todo.length > 0)
434-
{
435-
const current = todo.pop();
436-
let index = nodes.indexOf(current);
437-
if (index > -1)
438-
{
439-
continue;
440-
}
441-
nodes.push(current);
442-
for (const succ of evaluator.successorStates(current))
443-
{
444-
MutableMaps.putPushArray(transitions, current, succ);
445-
todo.push(succ);
446-
}
447-
}
448-
const dotNodes = nodes.map((node, i) => `${i} [label="${nodeToString(node)}"];`);
449-
const dotTransitions = [];
450-
for (const [source, dests] of transitions)
451-
{
452-
const tagSource = nodes.indexOf(source);
453-
for (const dest of dests)
454-
{
455-
dotTransitions.push(`${tagSource} -> ${nodes.indexOf(dest)}`);
456-
}
457-
}
476+
// function dotFlowGraph(evaluator, nodeToString)
477+
// {
478+
// const todo = [initialState(evaluator)];
479+
// const nodes = [];
480+
// const transitions = new Map();
481+
// while (todo.length > 0)
482+
// {
483+
// const current = todo.pop();
484+
// let index = nodes.indexOf(current);
485+
// if (index > -1)
486+
// {
487+
// continue;
488+
// }
489+
// nodes.push(current);
490+
// for (const succ of successorStates(evaluator, current))
491+
// {
492+
// MutableMaps.putPushArray(transitions, current, succ);
493+
// todo.push(succ);
494+
// }
495+
// }
496+
// const dotNodes = nodes.map((node, i) => `${i} [label="${nodeToString(node)}"];`);
497+
// const dotTransitions = [];
498+
// for (const [source, dests] of transitions)
499+
// {
500+
// const tagSource = nodes.indexOf(source);
501+
// for (const dest of dests)
502+
// {
503+
// dotTransitions.push(`${tagSource} -> ${nodes.indexOf(dest)}`);
504+
// }
505+
// }
458506

459-
return `
460-
digraph G {
461-
node [style=filled,fontname="Roboto Condensed"];
507+
// return `
508+
// digraph G {
509+
// node [style=filled,fontname="Roboto Condensed"];
462510

463-
${dotNodes.join('\n')}
511+
// ${dotNodes.join('\n')}
464512

465-
${dotTransitions.join('\n')}
513+
// ${dotTransitions.join('\n')}
466514

467-
}
468-
`;
469-
}
515+
// }
516+
// `;
517+
// }
470518

471-
function dotProvenanceGraph()
472-
{
473-
return instance2dot(evaluator);
474-
}
475519

476-
import { lattice_conc as lattice } from './lattice-rsp.js';
477-
import { kalloc_0cfa as kalloc } from './kalloc-rsp.js';
520+
// export function dotProvenanceGraph()
521+
// {
522+
// return instance2dot(evaluator);
523+
// }
524+
525+
// import { lattice_conc as lattice } from './lattice-rsp.js';
526+
// import { kalloc_conc as kalloc } from './kalloc-rsp.js';
527+
528+
// const agreval = create_agreval(lattice + kalloc);
529+
// const start = Date.now();
530+
// const evaluator = agreval(`
478531

479-
const agreval = create_agreval(lattice + kalloc);
480-
const start = Date.now();
481-
const evaluator = agreval(`
532+
// (+ 1 2)
482533

483-
(let ((x 1))
484-
(let ((y 2))
485-
(let ((u "piano"))
486-
(let ((z (+ x y)))
487-
z))))
488534

489-
`, {debug:false});
490-
console.log(`${Date.now() - start} ms`);
491-
console.log([...result(evaluator)]);
492-
// console.log(dotFlowGraph(evaluator, t => `${evaluator.expToString(t.t0)} | ${t.t1} | ${evaluator.evaluate(t.t0, t)}`));
493-
console.log(dotProvenanceGraph());
535+
// `, {debug:false});
536+
// console.log(`${Date.now() - start} ms`);
537+
// console.log([...result(evaluator)]);
538+
// // console.log(dotFlowGraph(evaluator, t => `${evaluator.expToString(t.t0)} | ${t.t1} | ${evaluator.evaluate(t.t0, t)}`));
539+
// console.log(dotProvenanceGraph());
494540

compile_agreval.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { specification as analysis_specification } from './agreval-rsp.js';
2-
import { compileToModuleSrc } from 'rulespace';
31
import fs from 'fs';
2+
import { compileToModuleSrc } from '@rulespace/rulespace';
3+
import { specification as analysis_specification } from './agreval-rsp.js';
44

55
import { lattice_conc as lattice } from './lattice-rsp.js';
66
import { kalloc_conc as kalloc } from './kalloc-rsp.js';

greval.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import { assertTrue } from '@rulespace/common';
2+
import { compileToConstructor, instance2dot } from '@rulespace/rulespace';
13
import { specification } from './greval-rsp.js';
2-
import { compileToConstructor, instance2dot } from 'rulespace';
34
import { SchemeParser, Sym, Pair } from './sexp-reader.js';
4-
import { assertTrue } from 'common';
55

66
const evaluatorCtr = compileToConstructor(specification, {debug:false});
77

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './agreval.js';

0 commit comments

Comments
 (0)