Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/createContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ const createEmptyRuntime = () => ({
envStepsTotal: 0,
breakpointSteps: [],
changepointSteps: [],
streamLineage: new Map<string, string[]>(),
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
streamsPointSteps: []
});

const createEmptyDebugger = () => ({
Expand Down Expand Up @@ -140,6 +142,8 @@ export const createEmptyContext = <T>(
runtime: createEmptyRuntime(),
numberOfOuterEnvironments: 1,
prelude: null,
pendingStreamFnStack: [],
streamLineage: new Map<string, string[]>(),
debugger: createEmptyDebugger(),
nativeStorage: createNativeStorage(),
executionMethod: 'auto',
Expand Down
1 change: 1 addition & 0 deletions src/cse-machine/closure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const closureToJS = (value: Closure, context: Context) => {
nodes: [...context.runtime.nodes],
breakpointSteps: [...context.runtime.breakpointSteps],
changepointSteps: [...context.runtime.changepointSteps],
streamsPointSteps: [...context.runtime.streamsPointSteps],
debuggerOn: false,
},
};
Expand Down
29 changes: 28 additions & 1 deletion src/cse-machine/interpreter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* This interpreter implements an explicit-control evaluator.
* This interpreter implements an explicit-control evaluator.
*
* Heavily adapted from https://github.com/source-academy/JSpike/
* and the legacy interpreter
Expand Down Expand Up @@ -60,6 +60,7 @@ import {
declareIdentifier,
defineVariable,
envChanging,
envChangingStreams,
getVariable,
handleArrayCreation,
handleRuntimeError,
Expand Down Expand Up @@ -359,6 +360,25 @@ export function* generateCSEMachineStateStream(
context.runtime.changepointSteps.push(steps + 1);
}

if (!isPrelude && envChangingStreams(command, context)) {
// same as !isPrelude && envChanging(command) check above
// but this checks if next instruction on control is a pair() function
// Usage: streams visualiser
context.runtime.streamsPointSteps.push(steps + 1)
}
const evalResult = context.runtime.stash?.peek();
const mostRecentControlHeight = context.pendingStreamFnStack[context.pendingStreamFnStack.length -1]?.[1]

if(Array.isArray(evalResult) && evalResult.length == 2 && mostRecentControlHeight != undefined && context.runtime.control?.size() == parseInt(mostRecentControlHeight) - 1) {
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
const mostRecentNullaryFnId = context.pendingStreamFnStack.pop()?.[0]
if (mostRecentNullaryFnId != undefined){
if (!context.streamLineage.get(mostRecentNullaryFnId)) {
context.streamLineage.set(mostRecentNullaryFnId, [])
}
context.streamLineage.get(mostRecentNullaryFnId)?.push((evalResult as any).id)
}
}
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated

control.pop();
if (isNode(command)) {
context.runtime.nodes.shift();
Expand Down Expand Up @@ -834,6 +854,13 @@ const cmdEvaluators: CommandEvaluators = {
context.runtime.environments.unshift(func.environment);
}

// Streams Visualisation:
// If CALL0, push the nullary fn to pendingStreamFnStack
// (to map which nullary fn produces which pairs; for nested nullary fn)
if (func.node.params.length === 0) {
context.pendingStreamFnStack.push([func.id, context.runtime.control !== null ? context.runtime.control.size().toString() : "0"])
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
}

// Handle special case if function is simple
if (isSimpleFunction(func.node)) {
// Closures convert ArrowExpressionStatements to BlockStatements
Expand Down
11 changes: 11 additions & 0 deletions src/cse-machine/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,17 @@ export const envChanging = (command: ControlItem): boolean => {
}
};

export const envChangingStreams = (command: ControlItem, context: Context): boolean => {
if (isInstr(command)) {
const evalResult = context.runtime.stash?.peek();
const mostRecentControlHeight = context.pendingStreamFnStack[context.pendingStreamFnStack.length - 1]?.[1]
if (Array.isArray(evalResult) && evalResult.length == 2 && mostRecentControlHeight != undefined && context.runtime.control?.size() == parseInt(mostRecentControlHeight) - 1) {
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
return true
}
}
return false
}

// TODO: This type guard does not seem to be doing what it thinks its doing
/**
* To determine if the function is simple.
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,14 @@ export interface Context<T = any> {
envStepsTotal: number;
breakpointSteps: number[];
changepointSteps: number[];
streamsPointSteps: number[]
};

// STREAM VISUALISATION
streamLineage: Map<string, string[]>

pendingStreamFnStack: (string[] | undefined)[]
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated
Comment thread
DaRealTristan marked this conversation as resolved.
Outdated

numberOfOuterEnvironments: number;

prelude: string | null;
Expand Down
1 change: 1 addition & 0 deletions src/utils/testing/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export function mockRuntimeContext(): Context {
envStepsTotal: 0,
breakpointSteps: [],
changepointSteps: [],
streamsPointSteps: []
};
return context;
}
Expand Down
Loading