import type es from 'estree'; import type { EnvTree } from './createContext'; import type Heap from './cse-machine/heap'; import type { Control, Stash } from './cse-machine/interpreter'; import type { SourceError } from './errors/base'; import type { Chapter, LanguageOptions, Variant } from './langs'; import type { LoadedBundle, ModuleContext } from './modules/moduleTypes'; /** * Defines functions that act as built-ins, but might rely on * different implementations. e.g display() in a web application. */ export interface CustomBuiltIns { rawDisplay: (value: Value, str: string, externalContext: any) => Value; prompt: (value: Value, str: string, externalContext: any) => string | null; alert: (value: Value, str: string, externalContext: any) => void; visualiseList: (list: any, externalContext: any) => void; } /** * Interface that custom Source objects can implement to override the default * `toString` behaviour */ export interface ReplResult { /** * @internal */ toReplString: () => string; } export type ExecutionMethod = 'native' | 'auto' | 'cse-machine'; export interface NativeStorage { builtins: Map; previousProgramsIdentifiers: Set; operators: Map Value>; maxExecTime: number; evaller: null | ((program: string) => Value); loadedModules: Record; loadedModuleTypes: Record>; } export interface Context { /** The source version used */ chapter: Chapter; /** The external symbols that exist in the Context. */ externalSymbols: string[]; /** All the errors gathered */ errors: SourceError[]; /** Runtime Specific state */ runtime: { break: boolean; debuggerOn: boolean; isRunning: boolean; environmentTree: EnvTree; environments: Environment[]; nodes: Node[]; control: Control | null; stash: Stash | null; objectCount: number; envStepsTotal: number; breakpointSteps: number[]; changepointSteps: number[]; }; streamLineage: Map; pendingStreamFnStack: [string, number][]; numberOfOuterEnvironments: number; prelude: string | null; /** the state of the debugger */ debugger: { /** External observers watching this context */ status: boolean; state: { it: IterableIterator; }; }; /** * Used for storing external properties. * For e.g, this can be used to store some application-related * context for use in your own built-in functions (like `display(a)`) */ externalContext?: T; /** * Used for storing the native context and other values */ nativeStorage: NativeStorage; /** * Describes the language processor to be used for evaluation */ executionMethod: ExecutionMethod; /** * Describes the strategy / paradigm to be used for evaluation * Examples: concurrent */ variant: Variant; /** * Describes the custom language option to be used for evaluation */ languageOptions: LanguageOptions; /** * Contains the evaluated code that has not yet been typechecked. */ unTypecheckedCode: string[]; typeEnvironment: TypeEnvironment; /** * Storage container for module specific information and state */ moduleContexts: { [name: string]: ModuleContext; }; /** * Programs previously executed in this context */ previousPrograms: es.Program[]; /** * Whether the evaluation timeout should be increased */ shouldIncreaseEvaluationTimeout: boolean; } export interface BlockFrame { type: string; loc?: es.SourceLocation | null; enclosingLoc?: es.SourceLocation | null; children: (DefinitionNode | BlockFrame)[]; } export interface DefinitionNode { name: string; type: string; loc?: es.SourceLocation | null; } export interface Frame { [name: string]: any; } export type Value = any; export type AllowedDeclarations = 'const' | 'let'; export interface Environment { readonly id: string; name: string; tail: Environment | null; callExpression?: es.CallExpression; head: Frame; heap: Heap; thisContext?: Value; } /** * Represents an evaluation that resulted in an error */ export interface Error { status: 'error'; context: Context; } /** * Represents an evaluation that finished successfully */ export interface Finished { status: 'finished'; context: Context; value: Value; } /** * Represents an evaluation that has been suspended. Only possible when the `cse-machine` * is being used. */ export interface SuspendedCseEval { status: 'suspended-cse-eval'; context: Context; } /** * Represents the result of an evaluation */ export type Result = Finished | Error | SuspendedCseEval; /** * StatementSequence: A sequence of statements not surrounded by braces. * It is *not* a block, and thus does not trigger environment creation when evaluated. * * The current ESTree specification does not have this node type, so we define it here. */ export interface StatementSequence extends es.BaseStatement { type: 'StatementSequence'; body: Array; innerComments?: Array | undefined; } /** * js-slang's custom Node type - this should be used wherever es.Node is used. */ export type Node = { isEnvDependent?: boolean; } & (es.Node | StatementSequence | es.MaybeNamedClassDeclaration | es.MaybeNamedFunctionDeclaration); export interface Directive extends es.ExpressionStatement { type: 'ExpressionStatement'; expression: es.Literal; directive: string; } export type { Address as SVMAddress, Argument as SVMArgument, SVMFunction, Instruction as SVMInstruction, Offset as SVMOffset, Program as SVMProgram, } from './vm/svml-compiler'; export type ContiguousArrayElementExpression = Exclude; export type ContiguousArrayElements = ContiguousArrayElementExpression[]; export type PrimitiveType = 'boolean' | 'null' | 'number' | 'string' | 'undefined'; export type TSAllowedTypes = 'any' | 'void'; export declare const disallowedTypes: readonly ["bigint", "never", "object", "symbol", "unknown"]; export type TSDisallowedTypes = (typeof disallowedTypes)[number]; export type TSBasicType = PrimitiveType | TSAllowedTypes | TSDisallowedTypes; export type NodeWithInferredType = InferredType & T; export type FuncDeclWithInferredTypeAnnotation = NodeWithInferredType & TypedFuncDecl; export type InferredType = Untypable | Typed | NotYetTyped; export interface TypedFuncDecl { functionInferredType?: Type; } export interface Untypable { typability?: 'Untypable'; inferredType?: Type; } export interface NotYetTyped { typability?: 'NotYetTyped'; inferredType?: Type; } export interface Typed { typability?: 'Typed'; inferredType?: Type; } export type Constraint = 'none' | 'addable'; export type Type = Primitive | Variable | FunctionType | List | Pair | SArray | UnionType | LiteralType; export interface Primitive { kind: 'primitive'; name: PrimitiveType | TSAllowedTypes; value?: string | number | boolean; } export interface Variable { kind: 'variable'; name: string; constraint: Constraint; typeArgs?: Type[]; } export interface FunctionType { kind: 'function'; parameterTypes: Type[]; returnType: Type; } export interface List { kind: 'list'; elementType: Type; typeAsPair?: Pair; } export interface Pair { kind: 'pair'; headType: Type; tailType: Type; } export interface SArray { kind: 'array'; elementType: Type; } export interface UnionType { kind: 'union'; types: Type[]; } export interface LiteralType { kind: 'literal'; value: string | number | boolean; } export type BindableType = Type | ForAll | PredicateType; export interface ForAll { kind: 'forall'; polyType: Type; typeParams?: Variable[]; } export interface PredicateType { kind: 'predicate'; ifTrueType: Type | ForAll; } export type PredicateTest = { node: NodeWithInferredType; ifTrueType: Type | ForAll; argVarName: string; }; /** * Each element in the TypeEnvironment array represents a different scope * (e.g. first element is the global scope, last element is the closest). * Within each scope, variable types/declaration kinds, as well as type aliases, are stored. */ export type TypeEnvironment = { typeMap: Map; declKindMap: Map; typeAliasMap: Map; }[]; /** * Utility type for selecting extracting the specific Node type when provided * the type string. */ export type NodeTypeToNode = Extract;