• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / js-slang / 11929582114

20 Nov 2024 08:33AM UTC coverage: 81.654% (+0.04%) from 81.61%
11929582114

Pull #1728

github

web-flow
Merge c3f0269a5 into 665233634
Pull Request #1728: Implement the CSET machine, along with macros

3654 of 4864 branches covered (75.12%)

Branch coverage included in aggregate %.

491 of 596 new or added lines in 11 files covered. (82.38%)

1 existing line in 1 file now uncovered.

11474 of 13663 relevant lines covered (83.98%)

143610.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.4
/src/createContext.ts
1
// Variable determining chapter of Source is contained in this file.
2

3
import * as scheme_libs from './alt-langs/scheme/scm-slang/src/stdlib/source-scheme-library'
79✔
4
import {
79✔
5
  scheme1Prelude,
6
  scheme2Prelude,
7
  scheme3Prelude,
8
  scheme4Prelude,
9
  schemeFullPrelude
10
} from './stdlib/scheme.prelude'
11
import { GLOBAL, JSSLANG_PROPERTIES } from './constants'
79✔
12
import { call_with_current_continuation } from './cse-machine/continuations'
79✔
13
import Heap from './cse-machine/heap'
79✔
14
import * as gpu_lib from './gpu/lib'
79✔
15
import { AsyncScheduler } from './schedulers'
79✔
16
import { lazyListPrelude } from './stdlib/lazyList.prelude'
79✔
17
import * as list from './stdlib/list'
79✔
18
import { list_to_vector } from './stdlib/list'
79✔
19
import { listPrelude } from './stdlib/list.prelude'
79✔
20
import { localImportPrelude } from './stdlib/localImport.prelude'
79✔
21
import * as misc from './stdlib/misc'
79✔
22
import { nonDetPrelude } from './stdlib/non-det.prelude'
79✔
23
import * as parser from './stdlib/parser'
79✔
24
import * as pylib from './stdlib/pylib'
79✔
25
import * as stream from './stdlib/stream'
79✔
26
import { streamPrelude } from './stdlib/stream.prelude'
79✔
27
import { createTypeEnvironment, tForAll, tVar } from './typeChecker/utils'
79✔
28
import {
79✔
29
  Chapter,
30
  Context,
31
  CustomBuiltIns,
32
  Environment,
33
  NativeStorage,
34
  Value,
35
  Variant
36
} from './types'
37
import { makeWrapper } from './utils/makeWrapper'
79✔
38
import * as operators from './utils/operators'
79✔
39
import { stringify } from './utils/stringify'
79✔
40
import { schemeVisualise } from './alt-langs/scheme/scheme-mapper'
79✔
41
import { cset_apply, cset_eval } from './cse-machine/scheme-macros'
79✔
42
import { Transformers } from './cse-machine/interpreter'
79✔
43

44
export class LazyBuiltIn {
79✔
45
  func: (...arg0: any) => any
46
  evaluateArgs: boolean
47
  constructor(func: (...arg0: any) => any, evaluateArgs: boolean) {
48
    this.func = func
3,151✔
49
    this.evaluateArgs = evaluateArgs
3,151✔
50
  }
51
}
52

53
export class EnvTree {
79✔
54
  private _root: EnvTreeNode | null = null
5,036✔
55
  private map = new Map<Environment, EnvTreeNode>()
5,036✔
56

57
  get root(): EnvTreeNode | null {
58
    return this._root
3✔
59
  }
60

61
  public insert(environment: Environment): void {
62
    const tailEnvironment = environment.tail
628,155✔
63
    if (tailEnvironment === null) {
628,155✔
64
      if (this._root === null) {
4,021✔
65
        this._root = new EnvTreeNode(environment, null)
4,021✔
66
        this.map.set(environment, this._root)
4,021✔
67
      }
68
    } else {
69
      const parentNode = this.map.get(tailEnvironment)
624,134✔
70
      if (parentNode) {
624,134✔
71
        const childNode = new EnvTreeNode(environment, parentNode)
624,134✔
72
        parentNode.addChild(childNode)
624,134✔
73
        this.map.set(environment, childNode)
624,134✔
74
      }
75
    }
76
  }
77

78
  public getTreeNode(environment: Environment): EnvTreeNode | undefined {
79
    return this.map.get(environment)
5✔
80
  }
81
}
82

83
export class EnvTreeNode {
79✔
84
  private _children: EnvTreeNode[] = []
628,156✔
85

86
  constructor(readonly environment: Environment, public parent: EnvTreeNode | null) {}
628,156✔
87

88
  get children(): EnvTreeNode[] {
89
    return this._children
3✔
90
  }
91

92
  public resetChildren(newChildren: EnvTreeNode[]): void {
93
    this.clearChildren()
1✔
94
    this.addChildren(newChildren)
1✔
95
    newChildren.forEach(c => (c.parent = this))
3✔
96
  }
97

98
  private clearChildren(): void {
99
    this._children = []
1✔
100
  }
101

102
  private addChildren(newChildren: EnvTreeNode[]): void {
103
    this._children.push(...newChildren)
1✔
104
  }
105

106
  public addChild(newChild: EnvTreeNode): EnvTreeNode {
107
    this._children.push(newChild)
624,135✔
108
    return newChild
624,135✔
109
  }
110
}
111

112
const createEmptyRuntime = () => ({
4,019✔
113
  break: false,
114
  debuggerOn: true,
115
  isRunning: false,
116
  environmentTree: new EnvTree(),
117
  environments: [],
118
  value: undefined,
119
  nodes: [],
120
  control: null,
121
  stash: null,
122
  transformers: new Transformers(),
123
  objectCount: 0,
124
  envSteps: -1,
125
  envStepsTotal: 0,
126
  breakpointSteps: [],
127
  changepointSteps: []
128
})
129

130
const createEmptyDebugger = () => ({
4,019✔
131
  observers: { callbacks: Array<() => void>() },
132
  status: false,
133
  state: {
134
    it: (function* (): any {
135
      return
×
136
    })(),
137
    scheduler: new AsyncScheduler()
138
  }
139
})
140

141
export const createGlobalEnvironment = (): Environment => ({
4,021✔
142
  tail: null,
143
  name: 'global',
144
  head: {},
145
  heap: new Heap(),
146
  id: '-1'
147
})
148

149
const createNativeStorage = (): NativeStorage => ({
4,019✔
150
  builtins: new Map(),
151
  previousProgramsIdentifiers: new Set(),
152
  operators: new Map(Object.entries(operators)),
153
  gpu: new Map(Object.entries(gpu_lib)),
154
  maxExecTime: JSSLANG_PROPERTIES.maxExecTime,
155
  evaller: null,
156
  loadedModules: {}
157
})
158

159
export const createEmptyContext = <T>(
79✔
160
  chapter: Chapter,
161
  variant: Variant = Variant.DEFAULT,
×
162
  externalSymbols: string[],
163
  externalContext?: T
164
): Context<T> => {
165
  return {
4,019✔
166
    chapter,
167
    externalSymbols,
168
    errors: [],
169
    externalContext,
170
    runtime: createEmptyRuntime(),
171
    numberOfOuterEnvironments: 1,
172
    prelude: null,
173
    debugger: createEmptyDebugger(),
174
    nativeStorage: createNativeStorage(),
175
    executionMethod: 'auto',
176
    variant,
177
    moduleContexts: {},
178
    unTypecheckedCode: [],
179
    typeEnvironment: createTypeEnvironment(chapter),
180
    previousPrograms: [],
181
    shouldIncreaseEvaluationTimeout: false
182
  }
183
}
184

185
export const ensureGlobalEnvironmentExist = (context: Context) => {
79✔
186
  if (!context.runtime) {
8,038!
187
    context.runtime = createEmptyRuntime()
×
188
  }
189
  if (!context.runtime.environments) {
8,038!
190
    context.runtime.environments = []
×
191
  }
192
  if (!context.runtime.environmentTree) {
8,038!
193
    context.runtime.environmentTree = new EnvTree()
×
194
  }
195
  if (context.runtime.environments.length === 0) {
8,038✔
196
    const globalEnvironment = createGlobalEnvironment()
4,019✔
197
    context.runtime.environments.push(globalEnvironment)
4,019✔
198
    context.runtime.environmentTree.insert(globalEnvironment)
4,019✔
199
  }
200
}
201

202
export const defineSymbol = (context: Context, name: string, value: Value) => {
79✔
203
  const globalEnvironment = context.runtime.environments[0]
286,276✔
204
  Object.defineProperty(globalEnvironment.head, name, {
286,276✔
205
    value,
206
    writable: false,
207
    enumerable: true
208
  })
209
  context.nativeStorage.builtins.set(name, value)
286,276✔
210
  const typeEnv = context.typeEnvironment[0]
286,276✔
211
  // if the global type env doesn't already have the imported symbol,
212
  // we set it to a type var T that can typecheck with anything.
213
  if (!typeEnv.declKindMap.has(name)) {
286,276✔
214
    typeEnv.typeMap.set(name, tForAll(tVar('T1')))
39,675✔
215
    typeEnv.declKindMap.set(name, 'const')
39,675✔
216
  }
217
}
218

219
export function defineBuiltin(
220
  context: Context,
221
  name: string, // enforce minArgsNeeded
222
  value: Value,
223
  minArgsNeeded: number
224
): void
225
export function defineBuiltin(
226
  context: Context,
227
  name: string,
228
  value: Value,
229
  minArgsNeeded?: number
230
): void
231
// Defines a builtin in the given context
232
// If the builtin is a function, wrap it such that its toString hides the implementation
233
export function defineBuiltin(
79✔
234
  context: Context,
235
  name: string,
236
  value: Value,
237
  minArgsNeeded: undefined | number = undefined
251,366✔
238
) {
239
  function extractName(name: string): string {
240
    return name.split('(')[0].trim()
243,307✔
241
  }
242

243
  function extractParameters(name: string): string[] {
244
    // if the function has no () in its name, it has no parameters
245
    if (!name.includes('(')) {
243,307✔
246
      return []
10✔
247
    }
248
    return name
243,297✔
249
      .split('(')[1]
250
      .split(')')[0]
251
      .split(',')
252
      .map(s => s.trim())
300,158✔
253
  }
254

255
  if (typeof value === 'function') {
286,276✔
256
    const funName = extractName(name)
242,155✔
257
    const funParameters = extractParameters(name)
242,155✔
258
    const repr = `function ${name} {\n\t[implementation hidden]\n}`
242,155✔
259
    value.toString = () => repr
242,155✔
260
    value.minArgsNeeded = minArgsNeeded
242,155✔
261
    value.funName = funName
242,155✔
262
    value.funParameters = funParameters
242,155✔
263

264
    defineSymbol(context, funName, value)
242,155✔
265
  } else if (value instanceof LazyBuiltIn) {
44,121✔
266
    const wrapped = (...args: any) => value.func(...args)
39,655✔
267
    const funName = extractName(name)
1,152✔
268
    const funParameters = extractParameters(name)
1,152✔
269
    const repr = `function ${name} {\n\t[implementation hidden]\n}`
1,152✔
270
    wrapped.toString = () => repr
1,152✔
271
    wrapped.funName = funName
1,152✔
272
    wrapped.funParameters = funParameters
1,152✔
273
    makeWrapper(value.func, wrapped)
1,152✔
274
    defineSymbol(context, funName, new LazyBuiltIn(wrapped, value.evaluateArgs))
1,152✔
275
  } else {
276
    defineSymbol(context, name, value)
42,969✔
277
  }
278
}
279

280
export const importExternalSymbols = (context: Context, externalSymbols: string[]) => {
79✔
281
  ensureGlobalEnvironmentExist(context)
4,019✔
282

283
  externalSymbols.forEach(symbol => {
4,019✔
284
    defineSymbol(context, symbol, GLOBAL[symbol])
×
285
  })
286
}
287

288
/**
289
 * Imports builtins from standard and external libraries.
290
 */
291
export const importBuiltins = (context: Context, externalBuiltIns: CustomBuiltIns) => {
79✔
292
  ensureGlobalEnvironmentExist(context)
4,019✔
293
  const rawDisplay = (v: Value, ...s: string[]) =>
4,019✔
294
    externalBuiltIns.rawDisplay(v, s[0], context.externalContext)
376✔
295
  const display = (v: Value, ...s: string[]) => {
4,019✔
296
    if (s.length === 1 && s[0] !== undefined && typeof s[0] !== 'string') {
375✔
297
      throw new TypeError('display expects the second argument to be a string')
1✔
298
    }
299
    return rawDisplay(stringify(v), s[0]), v
374✔
300
  }
301
  const displayList = (v: Value, ...s: string[]) => {
4,019✔
302
    if (s.length === 1 && s[0] !== undefined && typeof s[0] !== 'string') {
38✔
303
      throw new TypeError('display_list expects the second argument to be a string')
2✔
304
    }
305
    return list.rawDisplayList(display, v, s[0])
36✔
306
  }
307
  const prompt = (v: Value) => {
4,019✔
308
    const start = Date.now()
×
309
    const promptResult = externalBuiltIns.prompt(v, '', context.externalContext)
×
310
    context.nativeStorage.maxExecTime += Date.now() - start
×
311
    return promptResult
×
312
  }
313
  const alert = (v: Value) => {
4,019✔
314
    const start = Date.now()
×
315
    externalBuiltIns.alert(v, '', context.externalContext)
×
316
    context.nativeStorage.maxExecTime += Date.now() - start
×
317
  }
318
  const visualiseList = (...v: Value) => {
4,019✔
319
    externalBuiltIns.visualiseList(v, context.externalContext)
6✔
320
    return v[0]
6✔
321
  }
322

323
  if (context.chapter >= 1) {
4,019✔
324
    defineBuiltin(context, 'get_time()', misc.get_time)
3,852✔
325
    defineBuiltin(context, 'display(val, prepend = undefined)', display, 1)
3,852✔
326
    defineBuiltin(context, 'raw_display(str, prepend = undefined)', rawDisplay, 1)
3,852✔
327
    defineBuiltin(context, 'stringify(val, indent = 2, maxLineLength = 80)', stringify, 1)
3,852✔
328
    defineBuiltin(context, 'error(str, prepend = undefined)', misc.error_message, 1)
3,852✔
329
    defineBuiltin(context, 'prompt(str)', prompt)
3,852✔
330
    defineBuiltin(context, 'is_number(val)', misc.is_number)
3,852✔
331
    defineBuiltin(context, 'is_string(val)', misc.is_string)
3,852✔
332
    defineBuiltin(context, 'is_function(val)', misc.is_function)
3,852✔
333
    defineBuiltin(context, 'is_boolean(val)', misc.is_boolean)
3,852✔
334
    defineBuiltin(context, 'is_undefined(val)', misc.is_undefined)
3,852✔
335
    defineBuiltin(context, 'parse_int(str, radix)', misc.parse_int)
3,852✔
336
    defineBuiltin(context, 'char_at(str, index)', misc.char_at)
3,852✔
337
    defineBuiltin(context, 'arity(f)', misc.arity)
3,852✔
338
    defineBuiltin(context, 'undefined', undefined)
3,852✔
339
    defineBuiltin(context, 'NaN', NaN)
3,852✔
340
    defineBuiltin(context, 'Infinity', Infinity)
3,852✔
341
    // Define all Math libraries
342
    const mathLibraryNames = Object.getOwnPropertyNames(Math)
3,852✔
343
    // Short param names for stringified version of math functions
344
    const parameterNames = [...'abcdefghijklmnopqrstuvwxyz']
3,852✔
345
    for (const name of mathLibraryNames) {
3,852✔
346
      const value = Math[name]
165,636✔
347
      if (typeof value === 'function') {
165,636✔
348
        let paramString: string
349
        let minArgsNeeded = undefined
134,820✔
350
        if (name === 'max' || name === 'min') {
134,820✔
351
          paramString = '...values'
7,704✔
352
          minArgsNeeded = 0
7,704✔
353
        } else {
354
          paramString = parameterNames.slice(0, value.length).join(', ')
127,116✔
355
        }
356
        defineBuiltin(context, `math_${name}(${paramString})`, value, minArgsNeeded)
134,820✔
357
      } else {
358
        defineBuiltin(context, `math_${name}`, value)
30,816✔
359
      }
360
    }
361
  }
362

363
  if (context.chapter >= 2) {
4,019✔
364
    // List library
365

366
    if (context.variant === Variant.LAZY) {
2,343✔
367
      defineBuiltin(context, 'pair(left, right)', new LazyBuiltIn(list.pair, false))
94✔
368
      defineBuiltin(context, 'list(...values)', new LazyBuiltIn(list.list, false), 0)
94✔
369
      defineBuiltin(context, 'is_pair(val)', new LazyBuiltIn(list.is_pair, true))
94✔
370
      defineBuiltin(context, 'head(xs)', new LazyBuiltIn(list.head, true))
94✔
371
      defineBuiltin(context, 'tail(xs)', new LazyBuiltIn(list.tail, true))
94✔
372
      defineBuiltin(context, 'is_null(val)', new LazyBuiltIn(list.is_null, true))
94✔
373
      defineBuiltin(context, 'draw_data(...xs)', new LazyBuiltIn(visualiseList, true), 1)
94✔
374
      defineBuiltin(context, 'is_list(val)', new LazyBuiltIn(list.is_list, true))
94✔
375
    } else {
376
      defineBuiltin(context, 'pair(left, right)', list.pair)
2,249✔
377
      defineBuiltin(context, 'is_pair(val)', list.is_pair)
2,249✔
378
      defineBuiltin(context, 'head(xs)', list.head)
2,249✔
379
      defineBuiltin(context, 'tail(xs)', list.tail)
2,249✔
380
      defineBuiltin(context, 'is_null(val)', list.is_null)
2,249✔
381
      defineBuiltin(context, 'list(...values)', list.list, 0)
2,249✔
382
      defineBuiltin(context, 'draw_data(...xs)', visualiseList, 1)
2,249✔
383
      defineBuiltin(context, 'display_list(val, prepend = undefined)', displayList, 0)
2,249✔
384
      defineBuiltin(context, 'is_list(val)', list.is_list)
2,249✔
385
    }
386
  }
387

388
  if (context.chapter >= 3) {
4,019✔
389
    defineBuiltin(context, 'set_head(xs, val)', list.set_head)
1,933✔
390
    defineBuiltin(context, 'set_tail(xs, val)', list.set_tail)
1,933✔
391
    defineBuiltin(context, 'array_length(arr)', misc.array_length)
1,933✔
392
    defineBuiltin(context, 'is_array(val)', misc.is_array)
1,933✔
393

394
    // Stream library
395
    defineBuiltin(context, 'stream(...values)', stream.stream, 0)
1,933✔
396
  }
397

398
  if (context.chapter >= 4) {
4,019✔
399
    defineBuiltin(context, 'parse(program_string)', (str: string) =>
1,287✔
400
      parser.parse(str, createContext(context.chapter))
133✔
401
    )
402
    defineBuiltin(context, 'tokenize(program_string)', (str: string) =>
1,287✔
403
      parser.tokenize(str, createContext(context.chapter))
3✔
404
    )
405
    defineBuiltin(
1,287✔
406
      context,
407
      'apply_in_underlying_javascript(fun, args)',
408
      // tslint:disable-next-line:ban-types
409
      (fun: Function, args: Value) => fun.apply(fun, list_to_vector(args))
6✔
410
    )
411

412
    if (context.variant === Variant.GPU) {
1,287✔
413
      defineBuiltin(context, '__clearKernelCache()', gpu_lib.__clearKernelCache)
32✔
414
      defineBuiltin(
32✔
415
        context,
416
        '__createKernelSource(shape, extern, localNames, output, fun, kernelId)',
417
        gpu_lib.__createKernelSource
418
      )
419
    }
420

421
    // Continuations for explicit-control variant
422
    if (context.chapter >= 4) {
1,287✔
423
      defineBuiltin(
1,287✔
424
        context,
425
        'call_cc(f)',
426
        context.variant === Variant.EXPLICIT_CONTROL
1,287✔
427
          ? call_with_current_continuation
428
          : (f: any) => {
429
              throw new Error('call_cc is only available in Explicit-Control variant')
×
430
            }
431
      )
432
    }
433
  }
434

435
  if (context.chapter === Chapter.LIBRARY_PARSER) {
4,019✔
436
    defineBuiltin(context, 'is_object(val)', misc.is_object)
354✔
437
    defineBuiltin(context, 'is_NaN(val)', misc.is_NaN)
354✔
438
    defineBuiltin(context, 'has_own_property(obj, prop)', misc.has_own_property)
354✔
439
    defineBuiltin(context, 'alert(val)', alert)
354✔
440
    // tslint:disable-next-line:ban-types
441
    defineBuiltin(context, 'timed(fun)', (f: Function) =>
354✔
442
      misc.timed(context, f, context.externalContext, externalBuiltIns.rawDisplay)
×
443
    )
444
  }
445

446
  if (context.variant === Variant.LAZY) {
4,019✔
447
    defineBuiltin(context, 'wrapLazyCallee(f)', new LazyBuiltIn(operators.wrapLazyCallee, true))
100✔
448
    defineBuiltin(context, 'makeLazyFunction(f)', new LazyBuiltIn(operators.makeLazyFunction, true))
100✔
449
    defineBuiltin(context, 'forceIt(val)', new LazyBuiltIn(operators.forceIt, true))
100✔
450
    defineBuiltin(context, 'delayIt(xs)', new LazyBuiltIn(operators.delayIt, true))
100✔
451
  }
452

453
  if (context.chapter <= +Chapter.SCHEME_1 && context.chapter >= +Chapter.FULL_SCHEME) {
4,019✔
454
    switch (context.chapter) {
75!
455
      case Chapter.FULL_SCHEME:
456
        // Introduction to eval
457
        // eval metaprocedure
458
        defineBuiltin(context, '$scheme_ZXZhbA$61$$61$(xs)', cset_eval)
56✔
459

460
      case Chapter.SCHEME_4:
461
        // Introduction to call/cc
462
        defineBuiltin(context, 'call$47$cc(f)', call_with_current_continuation)
62✔
463

464
      case Chapter.SCHEME_3:
465
        // Introduction to mutable values, streams
466

467
        // Scheme pair mutation
468
        defineBuiltin(context, 'set$45$car$33$(pair, val)', scheme_libs.set$45$car$33$)
63✔
469
        defineBuiltin(context, 'set$45$cdr$33$(pair, val)', scheme_libs.set$45$cdr$33$)
63✔
470

471
        // Scheme list mutation
472
        defineBuiltin(context, 'list$45$set$33$(xs, n, val)', scheme_libs.list$45$set$33$)
63✔
473
        //defineBuiltin(context, 'filter$33$(pred, xs)', scheme_libs.filterB);
474

475
        // Scheme promises
476
        defineBuiltin(context, 'make$45$promise(thunk)', scheme_libs.make$45$promise)
63✔
477
        defineBuiltin(context, 'promise$63$(p)', scheme_libs.promise$63$)
63✔
478
        defineBuiltin(context, 'force(p)', scheme_libs.force)
63✔
479

480
        // Scheme vectors
481
        defineBuiltin(context, 'vector(...vals)', scheme_libs.vector, 0)
63✔
482
        defineBuiltin(context, 'make$45$vector(n, val)', scheme_libs.make$45$vector, 1)
63✔
483

484
        defineBuiltin(context, 'vector$63$(v)', scheme_libs.vector$63$)
63✔
485

486
        defineBuiltin(context, 'vector$45$length(v)', scheme_libs.vector$45$length)
63✔
487
        defineBuiltin(context, 'vector$45$empty$63$(v)', scheme_libs.vector$45$empty$63$)
63✔
488

489
        defineBuiltin(context, 'vector$45$ref(v, k)', scheme_libs.vector$45$ref)
63✔
490

491
        defineBuiltin(context, 'vector$45$set$33$(v, k, val)', scheme_libs.vector$45$set$33$)
63✔
492
        defineBuiltin(
63✔
493
          context,
494
          'vector$45$fill$33$(v, val, start, end)',
495
          scheme_libs.vector$45$fill$33$,
496
          2
497
        )
498
        defineBuiltin(context, 'list$45$$62$vector(xs)', scheme_libs.list$45$$62$vector)
63✔
499

500
      case Chapter.SCHEME_2:
501
        // Scheme pairs
502
        defineBuiltin(context, 'cons(left, right)', scheme_libs.cons)
64✔
503
        defineBuiltin(context, 'xcons(right, left)', scheme_libs.xcons)
64✔
504
        defineBuiltin(context, 'pair$63$(val)', scheme_libs.pair$63$)
64✔
505
        defineBuiltin(context, 'not$45$pair$63$(val)', scheme_libs.not$45$pair$63$)
64✔
506
        defineBuiltin(context, 'car(xs)', scheme_libs.car)
64✔
507
        defineBuiltin(context, 'cdr(xs)', scheme_libs.cdr)
64✔
508

509
        // Scheme lists
510
        defineBuiltin(context, 'list(...vals)', scheme_libs.list, 0)
64✔
511
        defineBuiltin(context, 'list$42$(...vals)', scheme_libs.list$42$, 1)
64✔
512
        defineBuiltin(context, 'cons$42$(...vals)', scheme_libs.cons$42$, 1)
64✔
513
        defineBuiltin(context, 'circular$45$list(...vals)', scheme_libs.circular$45$list, 0)
64✔
514
        defineBuiltin(context, 'make$45$list(n, val)', scheme_libs.make$45$list, 1)
64✔
515

516
        defineBuiltin(context, 'circular$45$list$63$(val)', scheme_libs.circular$45$list$63$)
64✔
517
        defineBuiltin(context, 'proper$45$list$63$(val)', scheme_libs.proper$45$list$63$)
64✔
518
        defineBuiltin(context, 'dotted$45$list$63$(val)', scheme_libs.dotted$45$list$63$)
64✔
519
        defineBuiltin(context, 'null$63$(val)', scheme_libs.null$63$)
64✔
520
        defineBuiltin(context, 'null$45$list$63$(val)', scheme_libs.null$45$list$63$)
64✔
521
        defineBuiltin(context, 'list$63$(val)', scheme_libs.list$63$)
64✔
522

523
        defineBuiltin(context, 'list$45$tabulate(n, f)', scheme_libs.list$45$tabulate)
64✔
524
        defineBuiltin(context, 'list$45$tail(xs, n)', scheme_libs.list$45$tail)
64✔
525
        defineBuiltin(context, 'list$45$ref(xs, k)', scheme_libs.list$45$ref)
64✔
526
        defineBuiltin(context, 'last(xs)', scheme_libs.last)
64✔
527
        defineBuiltin(context, 'last$45$pair(xs)', scheme_libs.last$45$pair)
64✔
528

529
        defineBuiltin(context, 'first(xs)', scheme_libs.first)
64✔
530
        defineBuiltin(context, 'second(xs)', scheme_libs.second)
64✔
531
        defineBuiltin(context, 'third(xs)', scheme_libs.third)
64✔
532
        defineBuiltin(context, 'fourth(xs)', scheme_libs.fourth)
64✔
533
        defineBuiltin(context, 'fifth(xs)', scheme_libs.fifth)
64✔
534
        defineBuiltin(context, 'sixth(xs)', scheme_libs.sixth)
64✔
535
        defineBuiltin(context, 'seventh(xs)', scheme_libs.seventh)
64✔
536
        defineBuiltin(context, 'eighth(xs)', scheme_libs.eighth)
64✔
537
        defineBuiltin(context, 'ninth(xs)', scheme_libs.ninth)
64✔
538
        defineBuiltin(context, 'tenth(xs)', scheme_libs.tenth)
64✔
539

540
        // some of these functions will be represented
541
        // using the preludes
542
        // defineBuiltin(context, 'filter(pred, xs)', scheme_libs.filter)
543
        defineBuiltin(context, 'r7rs$45$map(f, ...xss)', scheme_libs.map, 2)
64✔
544
        defineBuiltin(context, 'r7rs$45$fold(f, init, ...xss)', scheme_libs.fold, 3)
64✔
545
        defineBuiltin(
64✔
546
          context,
547
          'r7rs$45$fold$45$right(f, init, ...xss)',
548
          scheme_libs.fold$45$right,
549
          3
550
        )
551
        defineBuiltin(context, 'r7rs$45$fold$45$left(f, init, ...xss)', scheme_libs.fold$45$left, 3)
64✔
552
        //defineBuiltin(context, 'reduce(f, ridentity, xs)', scheme_libs.reduce)
553
        //defineBuiltin(context, 'reduce$45$right(f, ridentity, xs)', scheme_libs.reduce$45$right)
554
        //defineBuiltin(context, 'reduce$45$left(f, ridentity, xs)', scheme_libs.reduce$45$left)
555

556
        defineBuiltin(context, 'any(xs)', scheme_libs.any)
64✔
557
        defineBuiltin(context, 'list$45$copy(xs)', scheme_libs.list$45$copy)
64✔
558
        defineBuiltin(context, 'length(xs)', scheme_libs.length)
64✔
559
        defineBuiltin(context, 'length$43$(xs)', scheme_libs.length$43$)
64✔
560
        defineBuiltin(context, 'r7rs$45$append(...xss)', scheme_libs.append, 0)
64✔
561
        defineBuiltin(context, 'concatenate(xss)', scheme_libs.concatenate)
64✔
562
        defineBuiltin(context, 'reverse(xs)', scheme_libs.reverse)
64✔
563
        defineBuiltin(context, 'take(xs, n)', scheme_libs.take)
64✔
564
        defineBuiltin(context, 'take$45$right(xs, n)', scheme_libs.take$45$right)
64✔
565
        defineBuiltin(context, 'drop(xs, n)', scheme_libs.drop)
64✔
566
        defineBuiltin(context, 'drop$45$right(xs, n)', scheme_libs.drop$45$right)
64✔
567

568
        defineBuiltin(context, 'list$61$(eq$45$pred, ...xss)', scheme_libs.list$61$, 1)
64✔
569

570
        /*
571
        defineBuiltin(context, 'memq(item, xs)', scheme_libs.memq)
572
        defineBuiltin(context, 'memv(item, xs)', scheme_libs.memv)
573
        defineBuiltin(context, 'member(item, xs)', scheme_libs.member)
574
        defineBuiltin(context, 'assq(item, xs)', scheme_libs.assq)
575
        defineBuiltin(context, 'assv(item, xs)', scheme_libs.assv)
576
        defineBuiltin(context, 'assoc(item, xs)', scheme_libs.assoc)
577
        */
578

579
        // Scheme cxrs
580

581
        defineBuiltin(context, 'caar(xs)', scheme_libs.caar)
64✔
582
        defineBuiltin(context, 'cadr(xs)', scheme_libs.cadr)
64✔
583
        defineBuiltin(context, 'cdar(xs)', scheme_libs.cdar)
64✔
584
        defineBuiltin(context, 'cddr(xs)', scheme_libs.cddr)
64✔
585
        defineBuiltin(context, 'caaar(xs)', scheme_libs.caaar)
64✔
586
        defineBuiltin(context, 'caadr(xs)', scheme_libs.caadr)
64✔
587
        defineBuiltin(context, 'cadar(xs)', scheme_libs.cadar)
64✔
588
        defineBuiltin(context, 'caddr(xs)', scheme_libs.caddr)
64✔
589
        defineBuiltin(context, 'cdaar(xs)', scheme_libs.cdaar)
64✔
590
        defineBuiltin(context, 'cdadr(xs)', scheme_libs.cdadr)
64✔
591
        defineBuiltin(context, 'cddar(xs)', scheme_libs.cddar)
64✔
592
        defineBuiltin(context, 'cdddr(xs)', scheme_libs.cdddr)
64✔
593
        defineBuiltin(context, 'caaaar(xs)', scheme_libs.caaaar)
64✔
594
        defineBuiltin(context, 'caaadr(xs)', scheme_libs.caaadr)
64✔
595
        defineBuiltin(context, 'caadar(xs)', scheme_libs.caadar)
64✔
596
        defineBuiltin(context, 'caaddr(xs)', scheme_libs.caaddr)
64✔
597
        defineBuiltin(context, 'cadaar(xs)', scheme_libs.cadaar)
64✔
598
        defineBuiltin(context, 'cadadr(xs)', scheme_libs.cadadr)
64✔
599
        defineBuiltin(context, 'caddar(xs)', scheme_libs.caddar)
64✔
600
        defineBuiltin(context, 'cadddr(xs)', scheme_libs.cadddr)
64✔
601
        defineBuiltin(context, 'cdaaar(xs)', scheme_libs.cdaaar)
64✔
602
        defineBuiltin(context, 'cdaadr(xs)', scheme_libs.cdaadr)
64✔
603
        defineBuiltin(context, 'cdadar(xs)', scheme_libs.cdadar)
64✔
604
        defineBuiltin(context, 'cdaddr(xs)', scheme_libs.cdaddr)
64✔
605
        defineBuiltin(context, 'cddaar(xs)', scheme_libs.cddaar)
64✔
606
        defineBuiltin(context, 'cddadr(xs)', scheme_libs.cddadr)
64✔
607
        defineBuiltin(context, 'cdddar(xs)', scheme_libs.cdddar)
64✔
608
        defineBuiltin(context, 'cddddr(xs)', scheme_libs.cddddr)
64✔
609

610
        // Scheme symbols
611

612
        defineBuiltin(context, 'symbol$63$(val)', scheme_libs.symbol$63$)
64✔
613
        defineBuiltin(context, 'symbol$61$$63$(sym1, sym2)', scheme_libs.symbol$61$$63$)
64✔
614
        //defineBuiltin(context, 'symbol$45$$62$string(str)', scheme_libs.symbol$45$$62$string)
615
        defineBuiltin(context, 'string$45$$62$symbol(sym)', scheme_libs.string$45$$62$symbol)
64✔
616

617
        // Scheme strings
618
        defineBuiltin(context, 'string$45$$62$list(str)', scheme_libs.string$45$$62$list)
64✔
619
        defineBuiltin(context, 'list$45$$62$string(xs)', scheme_libs.list$45$$62$string)
64✔
620

621
        // Scheme apply is needed here to help in the definition of the Scheme Prelude.
622
        defineBuiltin(context, 'apply(f, ...args)', cset_apply, 2)
64✔
623

624
      case Chapter.SCHEME_1:
625
        // Display
626
        defineBuiltin(
75✔
627
          context,
628
          'display(val, prepend = undefined)',
NEW
629
          (val: any, ...str: string[]) => display(schemeVisualise(val), ...str),
×
630
          1
631
        )
632
        defineBuiltin(context, 'newline()', () => display(''))
75✔
633

634
        // I/O
635
        defineBuiltin(context, 'read(str)', () => prompt(''))
75✔
636

637
        // Error
638
        defineBuiltin(context, 'error(str, prepend = undefined)', misc.error_message, 1)
75✔
639

640
        // Scheme truthy and falsy value evaluator
641
        defineBuiltin(context, 'truthy(val)', scheme_libs.truthy)
75✔
642

643
        // Scheme conversion from vector to list, defined here as
644
        // it is used to support variadic functions
645
        defineBuiltin(context, 'vector$45$$62$list(v)', scheme_libs.vector$45$$62$list)
75✔
646

647
        // Scheme function to build numbers
648
        defineBuiltin(context, 'make_number(n)', scheme_libs.make_number)
75✔
649

650
        // Scheme equality predicates
651

652
        defineBuiltin(context, 'eq$63$(...vals)', scheme_libs.eq$63$)
75✔
653
        defineBuiltin(context, 'eqv$63$(...vals)', scheme_libs.eqv$63$)
75✔
654
        defineBuiltin(context, 'equal$63$(...vals)', scheme_libs.equal$63$)
75✔
655

656
        // Scheme basic arithmetic
657
        defineBuiltin(context, '$43$(...vals)', scheme_libs.$43$, 0)
75✔
658
        defineBuiltin(context, '$42$(...vals)', scheme_libs.$42$, 0)
75✔
659
        defineBuiltin(context, '$45$(...vals)', scheme_libs.$45$, 1)
75✔
660
        defineBuiltin(context, '$47$(...vals)', scheme_libs.$47$, 1)
75✔
661

662
        // Scheme comparison
663
        defineBuiltin(context, '$61$(...vals)', scheme_libs.$61$, 2)
75✔
664
        defineBuiltin(context, '$60$(...vals)', scheme_libs.$60$, 2)
75✔
665
        defineBuiltin(context, '$62$(...vals)', scheme_libs.$62$, 2)
75✔
666
        defineBuiltin(context, '$60$$61$(...vals)', scheme_libs.$60$$61$, 2)
75✔
667
        defineBuiltin(context, '$62$$61$(...vals)', scheme_libs.$62$$61$, 2)
75✔
668

669
        // Scheme math functions
670
        defineBuiltin(context, 'number$63$(val)', scheme_libs.number$63$)
75✔
671
        defineBuiltin(context, 'complex$63$(val)', scheme_libs.complex$63$)
75✔
672
        defineBuiltin(context, 'real$63$(val)', scheme_libs.real$63$)
75✔
673
        defineBuiltin(context, 'rational$63$(val)', scheme_libs.rational$63$)
75✔
674
        defineBuiltin(context, 'integer$63$(val)', scheme_libs.integer$63$)
75✔
675
        defineBuiltin(context, 'exact$63$(val)', scheme_libs.exact$63$)
75✔
676
        defineBuiltin(context, 'inexact$63$(val)', scheme_libs.inexact$63$)
75✔
677
        //defineBuiltin(context, 'exact$45$integer$63$(val)', scheme_libs.exact_integerQ)
678
        defineBuiltin(context, 'zero$63$(val)', scheme_libs.zero$63$)
75✔
679
        defineBuiltin(context, 'infinity$63$(val)', scheme_libs.infinity$63$)
75✔
680
        defineBuiltin(context, 'nan$63$(val)', scheme_libs.nan$63$)
75✔
681
        defineBuiltin(context, 'negative$63$(val)', scheme_libs.negative$63$)
75✔
682
        defineBuiltin(context, 'odd$63$(val)', scheme_libs.odd$63$)
75✔
683
        defineBuiltin(context, 'even$63$(val)', scheme_libs.even$63$)
75✔
684
        defineBuiltin(context, 'max(...vals)', scheme_libs.max, 0)
75✔
685
        defineBuiltin(context, 'min(...vals)', scheme_libs.min, 0)
75✔
686
        defineBuiltin(context, 'abs(val)', scheme_libs.abs)
75✔
687

688
        defineBuiltin(context, 'numerator(val)', scheme_libs.numerator)
75✔
689
        defineBuiltin(context, 'denominator(val)', scheme_libs.denominator)
75✔
690

691
        defineBuiltin(context, 'quotient(n, d)', scheme_libs.quotient)
75✔
692
        defineBuiltin(context, 'modulo(n, d)', scheme_libs.modulo)
75✔
693
        defineBuiltin(context, 'remainder(n, d)', scheme_libs.remainder)
75✔
694
        defineBuiltin(context, 'gcd(...vals)', scheme_libs.gcd, 0)
75✔
695
        defineBuiltin(context, 'lcm(...vals)', scheme_libs.lcm, 0)
75✔
696
        defineBuiltin(context, 'square(val)', scheme_libs.square)
75✔
697
        defineBuiltin(context, 'floor(val)', scheme_libs.floor)
75✔
698
        defineBuiltin(context, 'ceiling(val)', scheme_libs.ceiling)
75✔
699
        defineBuiltin(context, 'truncate(val)', scheme_libs.truncate)
75✔
700
        defineBuiltin(context, 'round(val)', scheme_libs.round)
75✔
701
        defineBuiltin(context, 'sqrt(val)', scheme_libs.sqrt)
75✔
702
        defineBuiltin(context, 'expt(base, exp)', scheme_libs.expt)
75✔
703
        defineBuiltin(context, 'exp(val)', scheme_libs.exp)
75✔
704
        defineBuiltin(context, 'log(val)', scheme_libs.log)
75✔
705
        defineBuiltin(context, 'sqrt(val)', scheme_libs.sqrt)
75✔
706
        defineBuiltin(context, 'sin(val)', scheme_libs.sin)
75✔
707
        defineBuiltin(context, 'cos(val)', scheme_libs.cos)
75✔
708
        defineBuiltin(context, 'tan(val)', scheme_libs.tan)
75✔
709
        defineBuiltin(context, 'asin(val)', scheme_libs.asin)
75✔
710
        defineBuiltin(context, 'acos(val)', scheme_libs.acos)
75✔
711
        defineBuiltin(context, 'atan(n, m)', scheme_libs.atan, 1)
75✔
712

713
        defineBuiltin(context, 'make$45$rectangular(real, imag)', scheme_libs.make$45$rectangular)
75✔
714
        defineBuiltin(context, 'make$45$polar(mag, ang)', scheme_libs.make$45$polar)
75✔
715
        defineBuiltin(context, 'real$45$part(val)', scheme_libs.real$45$part)
75✔
716
        defineBuiltin(context, 'imag$45$part(val)', scheme_libs.imag$45$part)
75✔
717
        defineBuiltin(context, 'magnitude(val)', scheme_libs.magnitude)
75✔
718
        defineBuiltin(context, 'angle(val)', scheme_libs.angle)
75✔
719

720
        defineBuiltin(context, 'math$45$pi', scheme_libs.PI)
75✔
721
        defineBuiltin(context, 'math$45$e', scheme_libs.E)
75✔
722

723
        defineBuiltin(context, 'number$45$$62$string(val)', scheme_libs.number$45$$62$string)
75✔
724

725
        // special values for scm-slang
726

727
        // Scheme booleans
728
        defineBuiltin(context, 'boolean$63$(val)', scheme_libs.boolean$63$)
75✔
729
        defineBuiltin(context, 'boolean$61$$63$(x, y)', scheme_libs.boolean$61$$63$)
75✔
730
        defineBuiltin(context, 'and(...vals)', scheme_libs.and, 0)
75✔
731
        defineBuiltin(context, 'or(...vals)', scheme_libs.or, 0)
75✔
732
        defineBuiltin(context, 'not(val)', scheme_libs.not)
75✔
733

734
        // Scheme strings
735

736
        defineBuiltin(context, 'string$63$(val)', scheme_libs.string$63$)
75✔
737
        defineBuiltin(context, 'make$45$string(n, char)', scheme_libs.make$45$string, 1)
75✔
738
        defineBuiltin(context, 'string(...vals)', scheme_libs.string, 0)
75✔
739
        defineBuiltin(context, 'string$45$length(str)', scheme_libs.string$45$length)
75✔
740
        defineBuiltin(context, 'string$45$ref(str, k)', scheme_libs.string$45$ref)
75✔
741
        defineBuiltin(context, 'string$61$$63$(str1, str2)', scheme_libs.string$61$$63$)
75✔
742
        defineBuiltin(context, 'string$60$$63$(str1, str2)', scheme_libs.string$60$$63$)
75✔
743
        defineBuiltin(context, 'string$62$$63$(str1, str2)', scheme_libs.string$62$$63$)
75✔
744
        defineBuiltin(context, 'string$60$$61$$63$(str1, str2)', scheme_libs.string$60$$61$$63$)
75✔
745
        defineBuiltin(context, 'string$62$$61$$63$(str1, str2)', scheme_libs.string$62$$61$$63$)
75✔
746
        defineBuiltin(context, 'substring(str, start, end)', scheme_libs.substring, 2)
75✔
747
        defineBuiltin(context, 'string$45$append(...vals)', scheme_libs.string$45$append, 0)
75✔
748
        defineBuiltin(context, 'string$45$copy(str)', scheme_libs.string$45$copy)
75✔
749
        defineBuiltin(context, 'string$45$map(f, str)', scheme_libs.string$45$map)
75✔
750
        defineBuiltin(context, 'string$45$for$45$each(f, str)', scheme_libs.string$45$for$45$each)
75✔
751
        defineBuiltin(context, 'string$45$$62$number(str)', scheme_libs.string$45$$62$number)
75✔
752

753
        // Scheme procedures
754
        defineBuiltin(context, 'procedure$63$(val)', scheme_libs.procedure$63$)
75✔
755
        defineBuiltin(context, 'compose(...fns)', scheme_libs.compose, 0)
75✔
756

757
        // Special values
758
        defineBuiltin(context, 'undefined', undefined)
75✔
759
        break
75✔
760
      default:
761
      //should be unreachable
762
    }
763
  }
764

765
  if (context.chapter <= Chapter.PYTHON_1 && context.chapter >= Chapter.PYTHON_1) {
4,019✔
766
    if (context.chapter == Chapter.PYTHON_1) {
62✔
767
      // Display
768
      defineBuiltin(context, 'get_time()', misc.get_time)
62✔
769
      defineBuiltin(context, 'print(val)', display, 1)
62✔
770
      defineBuiltin(context, 'raw_print(str)', rawDisplay, 1)
62✔
771
      defineBuiltin(context, 'str(val)', (val: any) => stringify(val, 2, 80), 1)
62✔
772
      defineBuiltin(context, 'error(str)', misc.error_message, 1)
62✔
773
      defineBuiltin(context, 'prompt(str)', prompt)
62✔
774
      defineBuiltin(context, 'is_float(val)', pylib.is_float)
62✔
775
      defineBuiltin(context, 'is_int(val)', pylib.is_int)
62✔
776
      defineBuiltin(context, 'is_string(val)', misc.is_string)
62✔
777
      defineBuiltin(context, 'is_function(val)', misc.is_function)
62✔
778
      defineBuiltin(context, 'is_boolean(val)', misc.is_boolean)
62✔
779
      defineBuiltin(context, 'is_None(val)', list.is_null)
62✔
780
      defineBuiltin(context, 'parse_int(str, radix)', misc.parse_int)
62✔
781
      defineBuiltin(context, 'char_at(str, index)', misc.char_at)
62✔
782
      defineBuiltin(context, 'arity(f)', misc.arity)
62✔
783
      defineBuiltin(context, 'None', null)
62✔
784

785
      // Binary operators
786
      defineBuiltin(context, '__py_adder(x, y)', pylib.__py_adder)
62✔
787
      defineBuiltin(context, '__py_minuser(x, y)', pylib.__py_minuser)
62✔
788
      defineBuiltin(context, '__py_multiplier(x, y)', pylib.__py_multiplier)
62✔
789
      defineBuiltin(context, '__py_divider(x, y)', pylib.__py_divider)
62✔
790
      defineBuiltin(context, '__py_modder(x, y)', pylib.__py_modder)
62✔
791
      defineBuiltin(context, '__py_powerer(x, y)', pylib.__py_powerer)
62✔
792
      defineBuiltin(context, '__py_floorer(x, y)', pylib.__py_floorer)
62✔
793

794
      // Unary operator +
795
      defineBuiltin(context, '__py_unary_plus(x)', pylib.__py_unary_plus)
62✔
796

797
      // Math Library
798
      defineBuiltin(context, 'math_abs(x)', pylib.math_abs)
62✔
799
      defineBuiltin(context, 'math_acos(x)', pylib.math_acos)
62✔
800
      defineBuiltin(context, 'math_acosh(x)', pylib.math_acosh)
62✔
801
      defineBuiltin(context, 'math_asin(x)', pylib.math_asin)
62✔
802
      defineBuiltin(context, 'math_asinh(x)', pylib.math_asinh)
62✔
803
      defineBuiltin(context, 'math_atan(x)', pylib.math_atan)
62✔
804
      defineBuiltin(context, 'math_atan2(x)', pylib.math_atan2)
62✔
805
      defineBuiltin(context, 'math_atanh(x)', pylib.math_atanh)
62✔
806
      defineBuiltin(context, 'math_cbrt(x)', pylib.math_cbrt)
62✔
807
      defineBuiltin(context, 'math_ceil(x)', pylib.math_ceil)
62✔
808
      defineBuiltin(context, 'math_clz32(x)', pylib.math_clz32)
62✔
809
      defineBuiltin(context, 'math_cos(x)', pylib.math_cos)
62✔
810
      defineBuiltin(context, 'math_cosh(x)', pylib.math_cosh)
62✔
811
      defineBuiltin(context, 'math_exp(x)', pylib.math_exp)
62✔
812
      defineBuiltin(context, 'math_expm1(x)', pylib.math_expm1)
62✔
813
      defineBuiltin(context, 'math_floor(x)', pylib.math_floor)
62✔
814
      defineBuiltin(context, 'math_fround(x)', pylib.math_fround)
62✔
815
      defineBuiltin(context, 'math_hypot(...values)', pylib.math_hypot)
62✔
816
      defineBuiltin(context, 'math_imul(x, y)', pylib.math_imul)
62✔
817
      defineBuiltin(context, 'math_log(x)', pylib.math_log)
62✔
818
      defineBuiltin(context, 'math_log1p(x)', pylib.math_log1p)
62✔
819
      defineBuiltin(context, 'math_log2(x)', pylib.math_log2)
62✔
820
      defineBuiltin(context, 'math_log10(x)', pylib.math_log10)
62✔
821
      defineBuiltin(context, 'math_max(...values)', pylib.math_max)
62✔
822
      defineBuiltin(context, 'math_min(...values)', pylib.math_min)
62✔
823
      defineBuiltin(context, 'math_pow(base, exponent)', pylib.math_pow)
62✔
824
      defineBuiltin(context, 'math_random()', pylib.math_random)
62✔
825
      defineBuiltin(context, 'math_round(x)', pylib.math_round)
62✔
826
      defineBuiltin(context, 'math_sign(x)', pylib.math_sign)
62✔
827
      defineBuiltin(context, 'math_sin(x)', pylib.math_sin)
62✔
828
      defineBuiltin(context, 'math_sinh(x)', pylib.math_sinh)
62✔
829
      defineBuiltin(context, 'math_sqrt(x)', pylib.math_sqrt)
62✔
830
      defineBuiltin(context, 'math_tan(x)', pylib.math_tan)
62✔
831
      defineBuiltin(context, 'math_tanh(x)', pylib.math_tanh)
62✔
832
      defineBuiltin(context, 'math_trunc(x)', pylib.math_trunc)
62✔
833

834
      // Math constants
835
      defineBuiltin(context, 'math_e', Math.E)
62✔
836
      defineBuiltin(context, 'math_inf', Infinity)
62✔
837
      defineBuiltin(context, 'math_nan', NaN)
62✔
838
      defineBuiltin(context, 'math_pi', Math.PI)
62✔
839
      defineBuiltin(context, 'math_tau', Math.PI * 2)
62✔
840
    }
841
  }
842
}
843

844
function importPrelude(context: Context) {
845
  let prelude = ''
4,019✔
846
  if (context.chapter >= 2) {
4,019✔
847
    prelude += context.variant === Variant.LAZY ? lazyListPrelude : listPrelude
2,343✔
848
    prelude += localImportPrelude
2,343✔
849
  }
850
  if (context.chapter >= 3) {
4,019✔
851
    prelude += streamPrelude
1,933✔
852
  }
853

854
  if (context.variant === Variant.NON_DET) {
4,019✔
855
    prelude += nonDetPrelude
249✔
856
  }
857

858
  if (context.chapter <= +Chapter.SCHEME_1 && context.chapter >= +Chapter.FULL_SCHEME) {
4,019✔
859
    // Scheme preludes
860
    // scheme 1 is the "highest" scheme chapter, so we can just check if it's less than or equal to scheme 1
861
    if (context.chapter <= +Chapter.SCHEME_1) {
75✔
862
      prelude += scheme1Prelude
75✔
863
    }
864
    if (context.chapter <= +Chapter.SCHEME_2) {
75✔
865
      prelude += scheme2Prelude
64✔
866
    }
867
    if (context.chapter <= +Chapter.SCHEME_3) {
75✔
868
      prelude += scheme3Prelude
63✔
869
    }
870
    if (context.chapter <= +Chapter.SCHEME_4) {
75✔
871
      prelude += scheme4Prelude
62✔
872
    }
873
    if (context.chapter <= +Chapter.FULL_SCHEME) {
75✔
874
      prelude += schemeFullPrelude
56✔
875
    }
876
  }
877
  if (prelude !== '') {
4,019✔
878
    context.prelude = prelude
2,418✔
879
  }
880
}
881

882
const defaultBuiltIns: CustomBuiltIns = {
79✔
883
  rawDisplay: misc.rawDisplay,
884
  // See issue #5
885
  prompt: misc.rawDisplay,
886
  // See issue #11
887
  alert: misc.rawDisplay,
888
  visualiseList: (_v: Value) => {
889
    throw new Error('List visualizer is not enabled')
×
890
  }
891
}
892

893
const createContext = <T>(
79✔
894
  chapter: Chapter = Chapter.SOURCE_1,
1,017✔
895
  variant: Variant = Variant.DEFAULT,
1,303✔
896
  externalSymbols: string[] = [],
2,512✔
897
  externalContext?: T,
898
  externalBuiltIns: CustomBuiltIns = defaultBuiltIns
2,512✔
899
): Context => {
900
  if (chapter === Chapter.FULL_JS || chapter === Chapter.FULL_TS) {
4,142✔
901
    // fullJS will include all builtins and preludes of source 4
902
    return {
123✔
903
      ...createContext(
904
        Chapter.SOURCE_4,
905
        variant,
906
        externalSymbols,
907
        externalContext,
908
        externalBuiltIns
909
      ),
910
      chapter
911
    } as Context
912
  }
913
  const context = createEmptyContext(chapter, variant, externalSymbols, externalContext)
4,019✔
914

915
  importBuiltins(context, externalBuiltIns)
4,019✔
916
  importPrelude(context)
4,019✔
917
  importExternalSymbols(context, externalSymbols)
4,019✔
918

919
  return context
4,019✔
920
}
921

922
export default createContext
79✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc