UNPKG

js-slang

Version:

Javascript-based implementations of Source, written in Typescript

767 lines 42.6 kB
"use strict"; // Variable determining chapter of Source is contained in this file. Object.defineProperty(exports, "__esModule", { value: true }); exports.importBuiltins = exports.importExternalSymbols = exports.defineBuiltin = exports.defineSymbol = exports.ensureGlobalEnvironmentExist = exports.createEmptyContext = exports.createGlobalEnvironment = exports.EnvTreeNode = exports.EnvTree = exports.LazyBuiltIn = void 0; const scheme_libs = require("./alt-langs/scheme/scm-slang/src/stdlib/source-scheme-library"); const scheme_prelude_1 = require("./stdlib/scheme.prelude"); const constants_1 = require("./constants"); const continuations_1 = require("./cse-machine/continuations"); const heap_1 = require("./cse-machine/heap"); const gpu_lib = require("./gpu/lib"); const schedulers_1 = require("./schedulers"); const lazyList_prelude_1 = require("./stdlib/lazyList.prelude"); const list = require("./stdlib/list"); const list_1 = require("./stdlib/list"); const list_prelude_1 = require("./stdlib/list.prelude"); const localImport_prelude_1 = require("./stdlib/localImport.prelude"); const misc = require("./stdlib/misc"); const non_det_prelude_1 = require("./stdlib/non-det.prelude"); const parser = require("./stdlib/parser"); const pylib = require("./stdlib/pylib"); const stream = require("./stdlib/stream"); const stream_prelude_1 = require("./stdlib/stream.prelude"); const utils_1 = require("./typeChecker/utils"); const types_1 = require("./types"); const makeWrapper_1 = require("./utils/makeWrapper"); const operators = require("./utils/operators"); const stringify_1 = require("./utils/stringify"); const scheme_mapper_1 = require("./alt-langs/scheme/scheme-mapper"); class LazyBuiltIn { constructor(func, evaluateArgs) { this.func = func; this.evaluateArgs = evaluateArgs; } } exports.LazyBuiltIn = LazyBuiltIn; class EnvTree { constructor() { this._root = null; this.map = new Map(); } get root() { return this._root; } insert(environment) { const tailEnvironment = environment.tail; if (tailEnvironment === null) { if (this._root === null) { this._root = new EnvTreeNode(environment, null); this.map.set(environment, this._root); } } else { const parentNode = this.map.get(tailEnvironment); if (parentNode) { const childNode = new EnvTreeNode(environment, parentNode); parentNode.addChild(childNode); this.map.set(environment, childNode); } } } getTreeNode(environment) { return this.map.get(environment); } } exports.EnvTree = EnvTree; class EnvTreeNode { constructor(environment, parent) { this.environment = environment; this.parent = parent; this._children = []; } get children() { return this._children; } resetChildren(newChildren) { this.clearChildren(); this.addChildren(newChildren); newChildren.forEach(c => (c.parent = this)); } clearChildren() { this._children = []; } addChildren(newChildren) { this._children.push(...newChildren); } addChild(newChild) { this._children.push(newChild); return newChild; } } exports.EnvTreeNode = EnvTreeNode; const createEmptyRuntime = () => ({ break: false, debuggerOn: true, isRunning: false, environmentTree: new EnvTree(), environments: [], value: undefined, nodes: [], control: null, stash: null, objectCount: 0, envSteps: -1, envStepsTotal: 0, breakpointSteps: [], changepointSteps: [] }); const createEmptyDebugger = () => ({ observers: { callbacks: Array() }, status: false, state: { it: (function* () { return; })(), scheduler: new schedulers_1.AsyncScheduler() } }); const createGlobalEnvironment = () => ({ tail: null, name: 'global', head: {}, heap: new heap_1.default(), id: '-1' }); exports.createGlobalEnvironment = createGlobalEnvironment; const createNativeStorage = () => ({ builtins: new Map(), previousProgramsIdentifiers: new Set(), operators: new Map(Object.entries(operators)), gpu: new Map(Object.entries(gpu_lib)), maxExecTime: constants_1.JSSLANG_PROPERTIES.maxExecTime, evaller: null, loadedModules: {} }); const createEmptyContext = (chapter, variant = types_1.Variant.DEFAULT, externalSymbols, externalContext) => { return { chapter, externalSymbols, errors: [], externalContext, runtime: createEmptyRuntime(), numberOfOuterEnvironments: 1, prelude: null, debugger: createEmptyDebugger(), nativeStorage: createNativeStorage(), executionMethod: 'auto', variant, moduleContexts: {}, unTypecheckedCode: [], typeEnvironment: (0, utils_1.createTypeEnvironment)(chapter), previousPrograms: [], shouldIncreaseEvaluationTimeout: false }; }; exports.createEmptyContext = createEmptyContext; const ensureGlobalEnvironmentExist = (context) => { if (!context.runtime) { context.runtime = createEmptyRuntime(); } if (!context.runtime.environments) { context.runtime.environments = []; } if (!context.runtime.environmentTree) { context.runtime.environmentTree = new EnvTree(); } if (context.runtime.environments.length === 0) { const globalEnvironment = (0, exports.createGlobalEnvironment)(); context.runtime.environments.push(globalEnvironment); context.runtime.environmentTree.insert(globalEnvironment); } }; exports.ensureGlobalEnvironmentExist = ensureGlobalEnvironmentExist; const defineSymbol = (context, name, value) => { const globalEnvironment = context.runtime.environments[0]; Object.defineProperty(globalEnvironment.head, name, { value, writable: false, enumerable: true }); context.nativeStorage.builtins.set(name, value); const typeEnv = context.typeEnvironment[0]; // if the global type env doesn't already have the imported symbol, // we set it to a type var T that can typecheck with anything. if (!typeEnv.declKindMap.has(name)) { typeEnv.typeMap.set(name, (0, utils_1.tForAll)((0, utils_1.tVar)('T1'))); typeEnv.declKindMap.set(name, 'const'); } }; exports.defineSymbol = defineSymbol; // Defines a builtin in the given context // If the builtin is a function, wrap it such that its toString hides the implementation function defineBuiltin(context, name, value, minArgsNeeded = undefined) { function extractName(name) { return name.split('(')[0].trim(); } function extractParameters(name) { // if the function has no () in its name, it has no parameters if (!name.includes('(')) { return []; } return name .split('(')[1] .split(')')[0] .split(',') .map(s => s.trim()); } if (typeof value === 'function') { const funName = extractName(name); const funParameters = extractParameters(name); const repr = `function ${name} {\n\t[implementation hidden]\n}`; value.toString = () => repr; value.minArgsNeeded = minArgsNeeded; value.funName = funName; value.funParameters = funParameters; (0, exports.defineSymbol)(context, funName, value); } else if (value instanceof LazyBuiltIn) { const wrapped = (...args) => value.func(...args); const funName = extractName(name); const funParameters = extractParameters(name); const repr = `function ${name} {\n\t[implementation hidden]\n}`; wrapped.toString = () => repr; wrapped.funName = funName; wrapped.funParameters = funParameters; (0, makeWrapper_1.makeWrapper)(value.func, wrapped); (0, exports.defineSymbol)(context, funName, new LazyBuiltIn(wrapped, value.evaluateArgs)); } else { (0, exports.defineSymbol)(context, name, value); } } exports.defineBuiltin = defineBuiltin; const importExternalSymbols = (context, externalSymbols) => { (0, exports.ensureGlobalEnvironmentExist)(context); externalSymbols.forEach(symbol => { (0, exports.defineSymbol)(context, symbol, constants_1.GLOBAL[symbol]); }); }; exports.importExternalSymbols = importExternalSymbols; /** * Imports builtins from standard and external libraries. */ const importBuiltins = (context, externalBuiltIns) => { (0, exports.ensureGlobalEnvironmentExist)(context); const rawDisplay = (v, ...s) => externalBuiltIns.rawDisplay(v, s[0], context.externalContext); const display = (v, ...s) => { if (s.length === 1 && s[0] !== undefined && typeof s[0] !== 'string') { throw new TypeError('display expects the second argument to be a string'); } return rawDisplay((0, stringify_1.stringify)(v), s[0]), v; }; const displayList = (v, ...s) => { if (s.length === 1 && s[0] !== undefined && typeof s[0] !== 'string') { throw new TypeError('display_list expects the second argument to be a string'); } return list.rawDisplayList(display, v, s[0]); }; const prompt = (v) => { const start = Date.now(); const promptResult = externalBuiltIns.prompt(v, '', context.externalContext); context.nativeStorage.maxExecTime += Date.now() - start; return promptResult; }; const alert = (v) => { const start = Date.now(); externalBuiltIns.alert(v, '', context.externalContext); context.nativeStorage.maxExecTime += Date.now() - start; }; const visualiseList = (...v) => { externalBuiltIns.visualiseList(v, context.externalContext); return v[0]; }; if (context.chapter >= 1) { defineBuiltin(context, 'get_time()', misc.get_time); defineBuiltin(context, 'display(val, prepend = undefined)', display, 1); defineBuiltin(context, 'raw_display(str, prepend = undefined)', rawDisplay, 1); defineBuiltin(context, 'stringify(val, indent = 2, maxLineLength = 80)', stringify_1.stringify, 1); defineBuiltin(context, 'error(str, prepend = undefined)', misc.error_message, 1); defineBuiltin(context, 'prompt(str)', prompt); defineBuiltin(context, 'is_number(val)', misc.is_number); defineBuiltin(context, 'is_string(val)', misc.is_string); defineBuiltin(context, 'is_function(val)', misc.is_function); defineBuiltin(context, 'is_boolean(val)', misc.is_boolean); defineBuiltin(context, 'is_undefined(val)', misc.is_undefined); defineBuiltin(context, 'parse_int(str, radix)', misc.parse_int); defineBuiltin(context, 'char_at(str, index)', misc.char_at); defineBuiltin(context, 'arity(f)', misc.arity); defineBuiltin(context, 'undefined', undefined); defineBuiltin(context, 'NaN', NaN); defineBuiltin(context, 'Infinity', Infinity); // Define all Math libraries const mathLibraryNames = Object.getOwnPropertyNames(Math); // Short param names for stringified version of math functions const parameterNames = [...'abcdefghijklmnopqrstuvwxyz']; for (const name of mathLibraryNames) { const value = Math[name]; if (typeof value === 'function') { let paramString; let minArgsNeeded = undefined; if (name === 'max' || name === 'min') { paramString = '...values'; minArgsNeeded = 0; } else { paramString = parameterNames.slice(0, value.length).join(', '); } defineBuiltin(context, `math_${name}(${paramString})`, value, minArgsNeeded); } else { defineBuiltin(context, `math_${name}`, value); } } } if (context.chapter >= 2) { // List library if (context.variant === types_1.Variant.LAZY) { defineBuiltin(context, 'pair(left, right)', new LazyBuiltIn(list.pair, false)); defineBuiltin(context, 'list(...values)', new LazyBuiltIn(list.list, false), 0); defineBuiltin(context, 'is_pair(val)', new LazyBuiltIn(list.is_pair, true)); defineBuiltin(context, 'head(xs)', new LazyBuiltIn(list.head, true)); defineBuiltin(context, 'tail(xs)', new LazyBuiltIn(list.tail, true)); defineBuiltin(context, 'is_null(val)', new LazyBuiltIn(list.is_null, true)); defineBuiltin(context, 'draw_data(...xs)', new LazyBuiltIn(visualiseList, true), 1); defineBuiltin(context, 'is_list(val)', new LazyBuiltIn(list.is_list, true)); } else { defineBuiltin(context, 'pair(left, right)', list.pair); defineBuiltin(context, 'is_pair(val)', list.is_pair); defineBuiltin(context, 'head(xs)', list.head); defineBuiltin(context, 'tail(xs)', list.tail); defineBuiltin(context, 'is_null(val)', list.is_null); defineBuiltin(context, 'list(...values)', list.list, 0); defineBuiltin(context, 'draw_data(...xs)', visualiseList, 1); defineBuiltin(context, 'display_list(val, prepend = undefined)', displayList, 0); defineBuiltin(context, 'is_list(val)', list.is_list); } } if (context.chapter >= 3) { defineBuiltin(context, 'set_head(xs, val)', list.set_head); defineBuiltin(context, 'set_tail(xs, val)', list.set_tail); defineBuiltin(context, 'array_length(arr)', misc.array_length); defineBuiltin(context, 'is_array(val)', misc.is_array); // Stream library defineBuiltin(context, 'stream(...values)', stream.stream, 0); } if (context.chapter >= 4) { defineBuiltin(context, 'parse(program_string)', (str) => parser.parse(str, createContext(context.chapter))); defineBuiltin(context, 'tokenize(program_string)', (str) => parser.tokenize(str, createContext(context.chapter))); defineBuiltin(context, 'apply_in_underlying_javascript(fun, args)', // tslint:disable-next-line:ban-types (fun, args) => fun.apply(fun, (0, list_1.list_to_vector)(args))); if (context.variant === types_1.Variant.GPU) { defineBuiltin(context, '__clearKernelCache()', gpu_lib.__clearKernelCache); defineBuiltin(context, '__createKernelSource(shape, extern, localNames, output, fun, kernelId)', gpu_lib.__createKernelSource); } // Continuations for explicit-control variant if (context.chapter >= 4) { defineBuiltin(context, 'call_cc(f)', context.variant === types_1.Variant.EXPLICIT_CONTROL ? continuations_1.call_with_current_continuation : (f) => { throw new Error('call_cc is only available in Explicit-Control variant'); }); } } if (context.chapter === types_1.Chapter.LIBRARY_PARSER) { defineBuiltin(context, 'is_object(val)', misc.is_object); defineBuiltin(context, 'is_NaN(val)', misc.is_NaN); defineBuiltin(context, 'has_own_property(obj, prop)', misc.has_own_property); defineBuiltin(context, 'alert(val)', alert); // tslint:disable-next-line:ban-types defineBuiltin(context, 'timed(fun)', (f) => misc.timed(context, f, context.externalContext, externalBuiltIns.rawDisplay)); } if (context.variant === types_1.Variant.LAZY) { defineBuiltin(context, 'wrapLazyCallee(f)', new LazyBuiltIn(operators.wrapLazyCallee, true)); defineBuiltin(context, 'makeLazyFunction(f)', new LazyBuiltIn(operators.makeLazyFunction, true)); defineBuiltin(context, 'forceIt(val)', new LazyBuiltIn(operators.forceIt, true)); defineBuiltin(context, 'delayIt(xs)', new LazyBuiltIn(operators.delayIt, true)); } if (context.chapter <= +types_1.Chapter.SCHEME_1 && context.chapter >= +types_1.Chapter.FULL_SCHEME) { switch (context.chapter) { case types_1.Chapter.FULL_SCHEME: case types_1.Chapter.SCHEME_4: // Introduction to call/cc defineBuiltin(context, 'call$47$cc(f)', continuations_1.call_with_current_continuation); // Introduction to eval // Scheme apply // ^ is needed in Schemes 2 and 3 to apply to call functions with rest parameters, // so we move it there. case types_1.Chapter.SCHEME_3: // Introduction to mutable values, streams // Scheme pair mutation defineBuiltin(context, 'set$45$car$33$(pair, val)', scheme_libs.set$45$car$33$); defineBuiltin(context, 'set$45$cdr$33$(pair, val)', scheme_libs.set$45$cdr$33$); // Scheme list mutation defineBuiltin(context, 'list$45$set$33$(xs, n, val)', scheme_libs.list$45$set$33$); //defineBuiltin(context, 'filter$33$(pred, xs)', scheme_libs.filterB); // Scheme promises defineBuiltin(context, 'make$45$promise(thunk)', scheme_libs.make$45$promise); defineBuiltin(context, 'promise$63$(p)', scheme_libs.promise$63$); defineBuiltin(context, 'force(p)', scheme_libs.force); // Scheme vectors defineBuiltin(context, 'vector(...vals)', scheme_libs.vector, 0); defineBuiltin(context, 'make$45$vector(n, val)', scheme_libs.make$45$vector, 1); defineBuiltin(context, 'vector$63$(v)', scheme_libs.vector$63$); defineBuiltin(context, 'vector$45$length(v)', scheme_libs.vector$45$length); defineBuiltin(context, 'vector$45$empty$63$(v)', scheme_libs.vector$45$empty$63$); defineBuiltin(context, 'vector$45$ref(v, k)', scheme_libs.vector$45$ref); defineBuiltin(context, 'vector$45$set$33$(v, k, val)', scheme_libs.vector$45$set$33$); defineBuiltin(context, 'vector$45$fill$33$(v, val, start, end)', scheme_libs.vector$45$fill$33$, 2); defineBuiltin(context, 'list$45$$62$vector(xs)', scheme_libs.list$45$$62$vector); case types_1.Chapter.SCHEME_2: // Splicing builtin resolvers // defineBuiltin(context, '$36$make$45$splice(expr)', scheme_libs.make_splice) // defineBuiltin(context, '$36$resolve$45$splice(xs)', scheme_libs.resolve_splice) // Scheme pairs defineBuiltin(context, 'cons(left, right)', scheme_libs.cons); defineBuiltin(context, 'xcons(right, left)', scheme_libs.xcons); defineBuiltin(context, 'pair$63$(val)', scheme_libs.pair$63$); defineBuiltin(context, 'not$45$pair$63$(val)', scheme_libs.not$45$pair$63$); defineBuiltin(context, 'car(xs)', scheme_libs.car); defineBuiltin(context, 'cdr(xs)', scheme_libs.cdr); // Scheme lists defineBuiltin(context, 'list(...vals)', scheme_libs.list, 0); defineBuiltin(context, 'list$42$(...vals)', scheme_libs.list$42$, 1); defineBuiltin(context, 'cons$42$(...vals)', scheme_libs.cons$42$, 1); defineBuiltin(context, 'circular$45$list(...vals)', scheme_libs.circular$45$list, 0); defineBuiltin(context, 'make$45$list(n, val)', scheme_libs.make$45$list, 1); defineBuiltin(context, 'circular$45$list$63$(val)', scheme_libs.circular$45$list$63$); defineBuiltin(context, 'proper$45$list$63$(val)', scheme_libs.proper$45$list$63$); defineBuiltin(context, 'dotted$45$list$63$(val)', scheme_libs.dotted$45$list$63$); defineBuiltin(context, 'null$63$(val)', scheme_libs.null$63$); defineBuiltin(context, 'null$45$list$63$(val)', scheme_libs.null$45$list$63$); defineBuiltin(context, 'list$63$(val)', scheme_libs.list$63$); defineBuiltin(context, 'list$45$tabulate(n, f)', scheme_libs.list$45$tabulate); defineBuiltin(context, 'list$45$tail(xs, n)', scheme_libs.list$45$tail); defineBuiltin(context, 'list$45$ref(xs, k)', scheme_libs.list$45$ref); defineBuiltin(context, 'last(xs)', scheme_libs.last); defineBuiltin(context, 'last$45$pair(xs)', scheme_libs.last$45$pair); defineBuiltin(context, 'first(xs)', scheme_libs.first); defineBuiltin(context, 'second(xs)', scheme_libs.second); defineBuiltin(context, 'third(xs)', scheme_libs.third); defineBuiltin(context, 'fourth(xs)', scheme_libs.fourth); defineBuiltin(context, 'fifth(xs)', scheme_libs.fifth); defineBuiltin(context, 'sixth(xs)', scheme_libs.sixth); defineBuiltin(context, 'seventh(xs)', scheme_libs.seventh); defineBuiltin(context, 'eighth(xs)', scheme_libs.eighth); defineBuiltin(context, 'ninth(xs)', scheme_libs.ninth); defineBuiltin(context, 'tenth(xs)', scheme_libs.tenth); // some of these functions will be represented // using the preludes // defineBuiltin(context, 'filter(pred, xs)', scheme_libs.filter) defineBuiltin(context, 'r7rs$45$map(f, ...xss)', scheme_libs.map, 2); defineBuiltin(context, 'r7rs$45$fold(f, init, ...xss)', scheme_libs.fold, 3); defineBuiltin(context, 'r7rs$45$fold$45$right(f, init, ...xss)', scheme_libs.fold$45$right, 3); defineBuiltin(context, 'r7rs$45$fold$45$left(f, init, ...xss)', scheme_libs.fold$45$left, 3); //defineBuiltin(context, 'reduce(f, ridentity, xs)', scheme_libs.reduce) //defineBuiltin(context, 'reduce$45$right(f, ridentity, xs)', scheme_libs.reduce$45$right) //defineBuiltin(context, 'reduce$45$left(f, ridentity, xs)', scheme_libs.reduce$45$left) defineBuiltin(context, 'any(xs)', scheme_libs.any); defineBuiltin(context, 'list$45$copy(xs)', scheme_libs.list$45$copy); defineBuiltin(context, 'length(xs)', scheme_libs.length); defineBuiltin(context, 'length$43$(xs)', scheme_libs.length$43$); defineBuiltin(context, 'r7rs$45$append(...xss)', scheme_libs.append, 0); defineBuiltin(context, 'concatenate(xss)', scheme_libs.concatenate); defineBuiltin(context, 'reverse(xs)', scheme_libs.reverse); defineBuiltin(context, 'take(xs, n)', scheme_libs.take); defineBuiltin(context, 'take$45$right(xs, n)', scheme_libs.take$45$right); defineBuiltin(context, 'drop(xs, n)', scheme_libs.drop); defineBuiltin(context, 'drop$45$right(xs, n)', scheme_libs.drop$45$right); defineBuiltin(context, 'list$61$(eq$45$pred, ...xss)', scheme_libs.list$61$, 1); /* defineBuiltin(context, 'memq(item, xs)', scheme_libs.memq) defineBuiltin(context, 'memv(item, xs)', scheme_libs.memv) defineBuiltin(context, 'member(item, xs)', scheme_libs.member) defineBuiltin(context, 'assq(item, xs)', scheme_libs.assq) defineBuiltin(context, 'assv(item, xs)', scheme_libs.assv) defineBuiltin(context, 'assoc(item, xs)', scheme_libs.assoc) */ // Scheme cxrs defineBuiltin(context, 'caar(xs)', scheme_libs.caar); defineBuiltin(context, 'cadr(xs)', scheme_libs.cadr); defineBuiltin(context, 'cdar(xs)', scheme_libs.cdar); defineBuiltin(context, 'cddr(xs)', scheme_libs.cddr); defineBuiltin(context, 'caaar(xs)', scheme_libs.caaar); defineBuiltin(context, 'caadr(xs)', scheme_libs.caadr); defineBuiltin(context, 'cadar(xs)', scheme_libs.cadar); defineBuiltin(context, 'caddr(xs)', scheme_libs.caddr); defineBuiltin(context, 'cdaar(xs)', scheme_libs.cdaar); defineBuiltin(context, 'cdadr(xs)', scheme_libs.cdadr); defineBuiltin(context, 'cddar(xs)', scheme_libs.cddar); defineBuiltin(context, 'cdddr(xs)', scheme_libs.cdddr); defineBuiltin(context, 'caaaar(xs)', scheme_libs.caaaar); defineBuiltin(context, 'caaadr(xs)', scheme_libs.caaadr); defineBuiltin(context, 'caadar(xs)', scheme_libs.caadar); defineBuiltin(context, 'caaddr(xs)', scheme_libs.caaddr); defineBuiltin(context, 'cadaar(xs)', scheme_libs.cadaar); defineBuiltin(context, 'cadadr(xs)', scheme_libs.cadadr); defineBuiltin(context, 'caddar(xs)', scheme_libs.caddar); defineBuiltin(context, 'cadddr(xs)', scheme_libs.cadddr); defineBuiltin(context, 'cdaaar(xs)', scheme_libs.cdaaar); defineBuiltin(context, 'cdaadr(xs)', scheme_libs.cdaadr); defineBuiltin(context, 'cdadar(xs)', scheme_libs.cdadar); defineBuiltin(context, 'cdaddr(xs)', scheme_libs.cdaddr); defineBuiltin(context, 'cddaar(xs)', scheme_libs.cddaar); defineBuiltin(context, 'cddadr(xs)', scheme_libs.cddadr); defineBuiltin(context, 'cdddar(xs)', scheme_libs.cdddar); defineBuiltin(context, 'cddddr(xs)', scheme_libs.cddddr); // Scheme symbols defineBuiltin(context, 'symbol$63$(val)', scheme_libs.symbol$63$); defineBuiltin(context, 'symbol$61$$63$(sym1, sym2)', scheme_libs.symbol$61$$63$); //defineBuiltin(context, 'symbol$45$$62$string(str)', scheme_libs.symbol$45$$62$string) defineBuiltin(context, 'string$45$$62$symbol(sym)', scheme_libs.string$45$$62$symbol); // Scheme strings defineBuiltin(context, 'string$45$$62$list(str)', scheme_libs.string$45$$62$list); defineBuiltin(context, 'list$45$$62$string(xs)', scheme_libs.list$45$$62$string); // Scheme apply is needed here to help in the definition of the Scheme Prelude. defineBuiltin(context, 'apply(f, ...args)', scheme_libs.apply, 2); case types_1.Chapter.SCHEME_1: // Display defineBuiltin(context, 'display(val)', (val) => display((0, scheme_mapper_1.schemeVisualise)(val))); defineBuiltin(context, 'newline()', () => display('')); // I/O defineBuiltin(context, 'read(str)', () => prompt('')); // Error defineBuiltin(context, 'error(str, prepend = undefined)', misc.error_message, 1); // Scheme truthy and falsy value evaluator defineBuiltin(context, 'truthy(val)', scheme_libs.truthy); // Scheme conversion from vector to list, defined here as // it is used to support variadic functions defineBuiltin(context, 'vector$45$$62$list(v)', scheme_libs.vector$45$$62$list); // Scheme function to build numbers defineBuiltin(context, 'make_number(n)', scheme_libs.make_number); // Scheme equality predicates defineBuiltin(context, 'eq$63$(...vals)', scheme_libs.eq$63$); defineBuiltin(context, 'eqv$63$(...vals)', scheme_libs.eqv$63$); defineBuiltin(context, 'equal$63$(...vals)', scheme_libs.equal$63$); // Scheme basic arithmetic defineBuiltin(context, '$43$(...vals)', scheme_libs.$43$, 0); defineBuiltin(context, '$42$(...vals)', scheme_libs.$42$, 0); defineBuiltin(context, '$45$(...vals)', scheme_libs.$45$, 1); defineBuiltin(context, '$47$(...vals)', scheme_libs.$47$, 1); // Scheme comparison defineBuiltin(context, '$61$(...vals)', scheme_libs.$61$, 2); defineBuiltin(context, '$60$(...vals)', scheme_libs.$60$, 2); defineBuiltin(context, '$62$(...vals)', scheme_libs.$62$, 2); defineBuiltin(context, '$60$$61$(...vals)', scheme_libs.$60$$61$, 2); defineBuiltin(context, '$62$$61$(...vals)', scheme_libs.$62$$61$, 2); // Scheme math functions defineBuiltin(context, 'number$63$(val)', scheme_libs.number$63$); defineBuiltin(context, 'complex$63$(val)', scheme_libs.complex$63$); defineBuiltin(context, 'real$63$(val)', scheme_libs.real$63$); defineBuiltin(context, 'rational$63$(val)', scheme_libs.rational$63$); defineBuiltin(context, 'integer$63$(val)', scheme_libs.integer$63$); defineBuiltin(context, 'exact$63$(val)', scheme_libs.exact$63$); defineBuiltin(context, 'inexact$63$(val)', scheme_libs.inexact$63$); //defineBuiltin(context, 'exact$45$integer$63$(val)', scheme_libs.exact_integerQ) defineBuiltin(context, 'zero$63$(val)', scheme_libs.zero$63$); defineBuiltin(context, 'infinity$63$(val)', scheme_libs.infinity$63$); defineBuiltin(context, 'nan$63$(val)', scheme_libs.nan$63$); defineBuiltin(context, 'negative$63$(val)', scheme_libs.negative$63$); defineBuiltin(context, 'odd$63$(val)', scheme_libs.odd$63$); defineBuiltin(context, 'even$63$(val)', scheme_libs.even$63$); defineBuiltin(context, 'max(...vals)', scheme_libs.max, 0); defineBuiltin(context, 'min(...vals)', scheme_libs.min, 0); defineBuiltin(context, 'abs(val)', scheme_libs.abs); defineBuiltin(context, 'numerator(val)', scheme_libs.numerator); defineBuiltin(context, 'denominator(val)', scheme_libs.denominator); defineBuiltin(context, 'quotient(n, d)', scheme_libs.quotient); defineBuiltin(context, 'modulo(n, d)', scheme_libs.modulo); defineBuiltin(context, 'remainder(n, d)', scheme_libs.remainder); defineBuiltin(context, 'gcd(...vals)', scheme_libs.gcd, 0); defineBuiltin(context, 'lcm(...vals)', scheme_libs.lcm, 0); defineBuiltin(context, 'square(val)', scheme_libs.square); defineBuiltin(context, 'floor(val)', scheme_libs.floor); defineBuiltin(context, 'ceiling(val)', scheme_libs.ceiling); defineBuiltin(context, 'truncate(val)', scheme_libs.truncate); defineBuiltin(context, 'round(val)', scheme_libs.round); defineBuiltin(context, 'sqrt(val)', scheme_libs.sqrt); defineBuiltin(context, 'expt(base, exp)', scheme_libs.expt); defineBuiltin(context, 'exp(val)', scheme_libs.exp); defineBuiltin(context, 'log(val)', scheme_libs.log); defineBuiltin(context, 'sqrt(val)', scheme_libs.sqrt); defineBuiltin(context, 'sin(val)', scheme_libs.sin); defineBuiltin(context, 'cos(val)', scheme_libs.cos); defineBuiltin(context, 'tan(val)', scheme_libs.tan); defineBuiltin(context, 'asin(val)', scheme_libs.asin); defineBuiltin(context, 'acos(val)', scheme_libs.acos); defineBuiltin(context, 'atan(n, m)', scheme_libs.atan, 1); defineBuiltin(context, 'make$45$rectangular(real, imag)', scheme_libs.make$45$rectangular); defineBuiltin(context, 'make$45$polar(mag, ang)', scheme_libs.make$45$polar); defineBuiltin(context, 'real$45$part(val)', scheme_libs.real$45$part); defineBuiltin(context, 'imag$45$part(val)', scheme_libs.imag$45$part); defineBuiltin(context, 'magnitude(val)', scheme_libs.magnitude); defineBuiltin(context, 'angle(val)', scheme_libs.angle); defineBuiltin(context, 'math$45$pi', scheme_libs.PI); defineBuiltin(context, 'math$45$e', scheme_libs.E); defineBuiltin(context, 'number$45$$62$string(val)', scheme_libs.number$45$$62$string); // special values for scm-slang // Scheme booleans defineBuiltin(context, 'boolean$63$(val)', scheme_libs.boolean$63$); defineBuiltin(context, 'boolean$61$$63$(x, y)', scheme_libs.boolean$61$$63$); defineBuiltin(context, 'and(...vals)', scheme_libs.and, 0); defineBuiltin(context, 'or(...vals)', scheme_libs.or, 0); defineBuiltin(context, 'not(val)', scheme_libs.not); // Scheme strings defineBuiltin(context, 'string$63$(val)', scheme_libs.string$63$); defineBuiltin(context, 'make$45$string(n, char)', scheme_libs.make$45$string, 1); defineBuiltin(context, 'string(...vals)', scheme_libs.string, 0); defineBuiltin(context, 'string$45$length(str)', scheme_libs.string$45$length); defineBuiltin(context, 'string$45$ref(str, k)', scheme_libs.string$45$ref); defineBuiltin(context, 'string$61$$63$(str1, str2)', scheme_libs.string$61$$63$); defineBuiltin(context, 'string$60$$63$(str1, str2)', scheme_libs.string$60$$63$); defineBuiltin(context, 'string$62$$63$(str1, str2)', scheme_libs.string$62$$63$); defineBuiltin(context, 'string$60$$61$$63$(str1, str2)', scheme_libs.string$60$$61$$63$); defineBuiltin(context, 'string$62$$61$$63$(str1, str2)', scheme_libs.string$62$$61$$63$); defineBuiltin(context, 'substring(str, start, end)', scheme_libs.substring, 2); defineBuiltin(context, 'string$45$append(...vals)', scheme_libs.string$45$append, 0); defineBuiltin(context, 'string$45$copy(str)', scheme_libs.string$45$copy); defineBuiltin(context, 'string$45$map(f, str)', scheme_libs.string$45$map); defineBuiltin(context, 'string$45$for$45$each(f, str)', scheme_libs.string$45$for$45$each); defineBuiltin(context, 'string$45$$62$number(str)', scheme_libs.string$45$$62$number); // Scheme procedures defineBuiltin(context, 'procedure$63$(val)', scheme_libs.procedure$63$); defineBuiltin(context, 'compose(...fns)', scheme_libs.compose, 0); // Special values defineBuiltin(context, 'undefined', undefined); break; default: //should be unreachable } } if (context.chapter <= types_1.Chapter.PYTHON_1 && context.chapter >= types_1.Chapter.PYTHON_1) { if (context.chapter == types_1.Chapter.PYTHON_1) { // Display defineBuiltin(context, 'get_time()', misc.get_time); defineBuiltin(context, 'print(val)', display, 1); defineBuiltin(context, 'raw_print(str)', rawDisplay, 1); defineBuiltin(context, 'str(val)', (val) => (0, stringify_1.stringify)(val, 2, 80), 1); defineBuiltin(context, 'error(str)', misc.error_message, 1); defineBuiltin(context, 'prompt(str)', prompt); defineBuiltin(context, 'is_float(val)', pylib.is_float); defineBuiltin(context, 'is_int(val)', pylib.is_int); defineBuiltin(context, 'is_string(val)', misc.is_string); defineBuiltin(context, 'is_function(val)', misc.is_function); defineBuiltin(context, 'is_boolean(val)', misc.is_boolean); defineBuiltin(context, 'is_None(val)', list.is_null); defineBuiltin(context, 'parse_int(str, radix)', misc.parse_int); defineBuiltin(context, 'char_at(str, index)', misc.char_at); defineBuiltin(context, 'arity(f)', misc.arity); defineBuiltin(context, 'None', null); // Binary operators defineBuiltin(context, '__py_adder(x, y)', pylib.__py_adder); defineBuiltin(context, '__py_minuser(x, y)', pylib.__py_minuser); defineBuiltin(context, '__py_multiplier(x, y)', pylib.__py_multiplier); defineBuiltin(context, '__py_divider(x, y)', pylib.__py_divider); defineBuiltin(context, '__py_modder(x, y)', pylib.__py_modder); defineBuiltin(context, '__py_powerer(x, y)', pylib.__py_powerer); defineBuiltin(context, '__py_floorer(x, y)', pylib.__py_floorer); // Unary operator + defineBuiltin(context, '__py_unary_plus(x)', pylib.__py_unary_plus); // Math Library defineBuiltin(context, 'math_abs(x)', pylib.math_abs); defineBuiltin(context, 'math_acos(x)', pylib.math_acos); defineBuiltin(context, 'math_acosh(x)', pylib.math_acosh); defineBuiltin(context, 'math_asin(x)', pylib.math_asin); defineBuiltin(context, 'math_asinh(x)', pylib.math_asinh); defineBuiltin(context, 'math_atan(x)', pylib.math_atan); defineBuiltin(context, 'math_atan2(x)', pylib.math_atan2); defineBuiltin(context, 'math_atanh(x)', pylib.math_atanh); defineBuiltin(context, 'math_cbrt(x)', pylib.math_cbrt); defineBuiltin(context, 'math_ceil(x)', pylib.math_ceil); defineBuiltin(context, 'math_clz32(x)', pylib.math_clz32); defineBuiltin(context, 'math_cos(x)', pylib.math_cos); defineBuiltin(context, 'math_cosh(x)', pylib.math_cosh); defineBuiltin(context, 'math_exp(x)', pylib.math_exp); defineBuiltin(context, 'math_expm1(x)', pylib.math_expm1); defineBuiltin(context, 'math_floor(x)', pylib.math_floor); defineBuiltin(context, 'math_fround(x)', pylib.math_fround); defineBuiltin(context, 'math_hypot(...values)', pylib.math_hypot); defineBuiltin(context, 'math_imul(x, y)', pylib.math_imul); defineBuiltin(context, 'math_log(x)', pylib.math_log); defineBuiltin(context, 'math_log1p(x)', pylib.math_log1p); defineBuiltin(context, 'math_log2(x)', pylib.math_log2); defineBuiltin(context, 'math_log10(x)', pylib.math_log10); defineBuiltin(context, 'math_max(...values)', pylib.math_max); defineBuiltin(context, 'math_min(...values)', pylib.math_min); defineBuiltin(context, 'math_pow(base, exponent)', pylib.math_pow); defineBuiltin(context, 'math_random()', pylib.math_random); defineBuiltin(context, 'math_round(x)', pylib.math_round); defineBuiltin(context, 'math_sign(x)', pylib.math_sign); defineBuiltin(context, 'math_sin(x)', pylib.math_sin); defineBuiltin(context, 'math_sinh(x)', pylib.math_sinh); defineBuiltin(context, 'math_sqrt(x)', pylib.math_sqrt); defineBuiltin(context, 'math_tan(x)', pylib.math_tan); defineBuiltin(context, 'math_tanh(x)', pylib.math_tanh); defineBuiltin(context, 'math_trunc(x)', pylib.math_trunc); // Math constants defineBuiltin(context, 'math_e', Math.E); defineBuiltin(context, 'math_inf', Infinity); defineBuiltin(context, 'math_nan', NaN); defineBuiltin(context, 'math_pi', Math.PI); defineBuiltin(context, 'math_tau', Math.PI * 2); } } }; exports.importBuiltins = importBuiltins; function importPrelude(context) { let prelude = ''; if (context.chapter >= 2) { prelude += context.variant === types_1.Variant.LAZY ? lazyList_prelude_1.lazyListPrelude : list_prelude_1.listPrelude; prelude += localImport_prelude_1.localImportPrelude; } if (context.chapter >= 3) { prelude += stream_prelude_1.streamPrelude; } if (context.variant === types_1.Variant.NON_DET) { prelude += non_det_prelude_1.nonDetPrelude; } if (context.chapter <= +types_1.Chapter.SCHEME_1 && context.chapter >= +types_1.Chapter.FULL_SCHEME) { // Scheme preludes // scheme 1 is the "highest" scheme chapter, so we can just check if it's less than or equal to scheme 1 if (context.chapter <= +types_1.Chapter.SCHEME_1) { prelude += scheme_prelude_1.scheme1Prelude; } if (context.chapter <= +types_1.Chapter.SCHEME_2) { prelude += scheme_prelude_1.scheme2Prelude; } if (context.chapter <= +types_1.Chapter.SCHEME_3) { prelude += scheme_prelude_1.scheme3Prelude; } if (context.chapter <= +types_1.Chapter.SCHEME_4) { prelude += scheme_prelude_1.scheme4Prelude; } if (context.chapter <= +types_1.Chapter.FULL_SCHEME) { prelude += scheme_prelude_1.schemeFullPrelude; } } if (prelude !== '') { context.prelude = prelude; } } const defaultBuiltIns = { rawDisplay: misc.rawDisplay, // See issue #5 prompt: misc.rawDisplay, // See issue #11 alert: misc.rawDisplay, visualiseList: (_v) => { throw new Error('List visualizer is not enabled'); } }; const createContext = (chapter = types_1.Chapter.SOURCE_1, variant = types_1.Variant.DEFAULT, externalSymbols = [], externalContext, externalBuiltIns = defaultBuiltIns) => { if (chapter === types_1.Chapter.FULL_JS || chapter === types_1.Chapter.FULL_TS) { // fullJS will include all builtins and preludes of source 4 return { ...createContext(types_1.Chapter.SOURCE_4, variant, externalSymbols, externalContext, externalBuiltIns), chapter }; } const context = (0, exports.createEmptyContext)(chapter, variant, externalSymbols, externalContext); (0, exports.importBuiltins)(context, externalBuiltIns); importPrelude(context); (0, exports.importExternalSymbols)(context, externalSymbols); return context; }; exports.default = createContext; //# sourceMappingURL=createContext.js.map