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

source-academy / js-slang / 23995741899

05 Apr 2026 06:14AM UTC coverage: 77.093% (+0.002%) from 77.091%
23995741899

push

github

web-flow
Upgrade to TypeScript 6 and Prettier improvements (#1936)

* Upgrade TypeScript to v6

* Fix import source

* Fix tsconfig

* Fix preexisting type errors

* Remove scm-slang

* Bump node types

* Fix tsconfig

* Fix node types specifier

* Enable trailing commas

* Enable semicolons

* Check and commit files with changed line numbers

* Update Yarn to 4.13.0

* Remove unneeded sicp package deps

3112 of 4282 branches covered (72.68%)

Branch coverage included in aggregate %.

3761 of 5218 new or added lines in 152 files covered. (72.08%)

26 existing lines in 9 files now uncovered.

7136 of 9011 relevant lines covered (79.19%)

175254.05 hits per line

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

78.13
/src/stdlib/misc.ts
1
import Closure from '../cse-machine/closure';
2
import type { Context, Value } from '../types';
3
import { stringify } from '../utils/stringify';
4

5
/**
6
 * A function that displays to console.log by default (for a REPL).
7
 *
8
 * @param value the value to be represented and displayed.
9
 * @param externalContext a property of Context that can hold
10
 *   any information required for external use (optional).
11
 */
12
export function rawDisplay(value: Value, str: string, _externalContext: any) {
13
  console.log((str === undefined ? '' : str + ' ') + value.toString());
1!
14
  return value;
1✔
15
}
16

17
export function error_message(value: Value, ...strs: string[]) {
18
  const output = (strs[0] === undefined ? '' : strs[0] + ' ') + stringify(value);
2!
19
  throw new Error(output);
2✔
20
}
21

22
export function timed(
23
  context: Context,
24
  f: Function,
25
  externalContext: any,
26
  displayBuiltin: (value: Value, str: string, externalContext: any) => Value,
27
) {
28
  return (...args: any[]) => {
×
NEW
29
    const start = get_time();
×
NEW
30
    const result = f(...args);
×
NEW
31
    const diff = get_time() - start;
×
NEW
32
    displayBuiltin('Duration: ' + Math.round(diff) + 'ms', '', externalContext);
×
NEW
33
    return result;
×
34
  };
35
}
36

37
export function is_number(v: Value) {
38
  return typeof v === 'number';
211✔
39
}
40

41
export function is_undefined(xs: Value) {
42
  return typeof xs === 'undefined';
11✔
43
}
44

45
export function is_string(xs: Value) {
46
  return typeof xs === 'string';
36✔
47
}
48

49
export function is_boolean(xs: Value) {
50
  return typeof xs === 'boolean';
25✔
51
}
52

53
export function is_object(xs: Value) {
54
  return typeof xs === 'object' || is_function(xs);
10✔
55
}
56

57
export function is_function(xs: Value) {
58
  return typeof xs === 'function';
1,409✔
59
}
60

61
export function is_NaN(x: Value) {
62
  return is_number(x) && isNaN(x);
4✔
63
}
64

65
export function has_own_property(obj: Value, p: Value) {
66
  return obj.hasOwnProperty(p);
2✔
67
}
68

69
export function is_array(a: Value) {
70
  return a instanceof Array;
6✔
71
}
72

73
export function array_length(xs: Value[]) {
74
  return xs.length;
25✔
75
}
76

77
/**
78
 * Source version of parseInt. Both arguments are required.
79
 *
80
 * @param str String representation of the integer to be parsed. Required.
81
 * @param radix Base to parse the given `str`. Required.
82
 *
83
 * An error is thrown if `str` is not of type string, or `radix` is not an
84
 * integer within the range 2, 36 inclusive.
85
 */
86
export function parse_int(str: string, radix: number) {
87
  if (
12✔
88
    typeof str === 'string' &&
47✔
89
    typeof radix === 'number' &&
90
    Number.isInteger(radix) &&
91
    2 <= radix &&
92
    radix <= 36
93
  ) {
94
    return parseInt(str, radix);
7✔
95
  } else {
96
    throw new Error(
5✔
97
      'parse_int expects two arguments a string s, and a positive integer i between 2 and 36, inclusive.',
98
    );
99
  }
100
}
101

102
export function char_at(str: string, index: number) {
103
  if (typeof str !== 'string') {
5✔
104
    throw new Error('char_at expects the first argument to be a string.');
1✔
105
  } else if (typeof index !== 'number' || !Number.isInteger(index) || index < 0) {
4✔
106
    throw new Error('char_at expects the second argument to be a nonnegative integer.');
2✔
107
  }
108
  return str[index];
2✔
109
}
110

111
/**
112
 * arity returns the number of parameters a given function `f` expects.
113
 *
114
 * @param f Function whose arity is to be found. Required.
115
 *
116
 * An error is thrown if `f` is not a function.
117
 */
118
export function arity(f: Function) {
119
  if (f instanceof Closure) {
8!
NEW
120
    const params = f.node.params;
×
NEW
121
    const hasVarArgs = params[params.length - 1]?.type === 'RestElement';
×
NEW
122
    return hasVarArgs ? params.length - 1 : params.length;
×
123
  } else if (typeof f === 'function') {
8✔
124
    return f.length;
7✔
125
  } else {
126
    throw new Error('arity expects a function as argument');
1✔
127
  }
128
}
129

130
export function get_time() {
131
  return new Date().getTime();
19,682,157✔
132
}
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

© 2026 Coveralls, Inc