diff --git a/.husky/.gitignore b/.husky/.gitignore
index c9cdc63b0..31354ec13 100644
--- a/.husky/.gitignore
+++ b/.husky/.gitignore
@@ -1 +1 @@
-_
\ No newline at end of file
+_
diff --git a/docs/_config.yml b/docs/_config.yml
index 2f7efbeab..fff4ab923 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -1 +1 @@
-theme: jekyll-theme-minimal
\ No newline at end of file
+theme: jekyll-theme-minimal
diff --git a/docs/jsdoc/templates/template/publish.js b/docs/jsdoc/templates/template/publish.js
index 0c4276037..b340d6ed9 100644
--- a/docs/jsdoc/templates/template/publish.js
+++ b/docs/jsdoc/templates/template/publish.js
@@ -1,268 +1,271 @@
// changed from default template by MH on 1/7/2019, see "MH" below
// changed from previous template by JC on 29/3/2020, see "JC" below
-const doop = require('jsdoc/util/doop');
-const env = require('jsdoc/env');
-const fs = require('jsdoc/fs');
-const helper = require('jsdoc/util/templateHelper');
-const logger = require('jsdoc/util/logger');
-const path = require('jsdoc/path');
-const taffy = require('taffydb').taffy;
-const template = require('jsdoc/template');
-const util = require('util');
-
-const htmlsafe = helper.htmlsafe;
-const linkto = helper.linkto;
-const resolveAuthorLinks = helper.resolveAuthorLinks;
-const hasOwnProp = Object.prototype.hasOwnProperty;
-
-let data;
-let view;
-
-let outdir = path.normalize(env.opts.destination);
+const doop = require('jsdoc/util/doop')
+const env = require('jsdoc/env')
+const fs = require('jsdoc/fs')
+const helper = require('jsdoc/util/templateHelper')
+const logger = require('jsdoc/util/logger')
+const path = require('jsdoc/path')
+const taffy = require('taffydb').taffy
+const template = require('jsdoc/template')
+const util = require('util')
+
+const htmlsafe = helper.htmlsafe
+const linkto = helper.linkto
+const resolveAuthorLinks = helper.resolveAuthorLinks
+const hasOwnProp = Object.prototype.hasOwnProperty
+
+let data
+let view
+
+let outdir = path.normalize(env.opts.destination)
function find(spec) {
- return helper.find(data, spec);
+ return helper.find(data, spec)
}
function tutoriallink(tutorial) {
- return helper.toTutorial(tutorial, null, {
- tag: 'em',
- classname: 'disabled',
- prefix: 'Tutorial: '
- });
+ return helper.toTutorial(tutorial, null, {
+ tag: 'em',
+ classname: 'disabled',
+ prefix: 'Tutorial: '
+ })
}
function getAncestorLinks(doclet) {
- return helper.getAncestorLinks(data, doclet);
+ return helper.getAncestorLinks(data, doclet)
}
function hashToLink(doclet, hash) {
- let url;
+ let url
- if ( !/^(#.+)/.test(hash) ) {
- return hash;
- }
+ if (!/^(#.+)/.test(hash)) {
+ return hash
+ }
- url = helper.createLink(doclet);
- url = url.replace(/(#.+|$)/, hash);
+ url = helper.createLink(doclet)
+ url = url.replace(/(#.+|$)/, hash)
- return `${hash}`;
+ return `${hash}`
}
-function needsSignature({kind, type, meta}) {
- let needsSig = false;
-
- // function and class definitions always get a signature
- if (kind === 'function' || kind === 'class') {
- needsSig = true;
- }
- // typedefs that contain functions get a signature, too
- else if (kind === 'typedef' && type && type.names &&
- type.names.length) {
- for (let i = 0, l = type.names.length; i < l; i++) {
- if (type.names[i].toLowerCase() === 'function') {
- needsSig = true;
- break;
- }
- }
- }
- // and namespaces that are functions get a signature (but finding them is a
- // bit messy)
- else if (kind === 'namespace' && meta && meta.code &&
- meta.code.type && meta.code.type.match(/[Ff]unction/)) {
- needsSig = true;
+function needsSignature({ kind, type, meta }) {
+ let needsSig = false
+
+ // function and class definitions always get a signature
+ if (kind === 'function' || kind === 'class') {
+ needsSig = true
+ }
+ // typedefs that contain functions get a signature, too
+ else if (kind === 'typedef' && type && type.names && type.names.length) {
+ for (let i = 0, l = type.names.length; i < l; i++) {
+ if (type.names[i].toLowerCase() === 'function') {
+ needsSig = true
+ break
+ }
}
-
- return needsSig;
+ }
+ // and namespaces that are functions get a signature (but finding them is a
+ // bit messy)
+ else if (
+ kind === 'namespace' &&
+ meta &&
+ meta.code &&
+ meta.code.type &&
+ meta.code.type.match(/[Ff]unction/)
+ ) {
+ needsSig = true
+ }
+
+ return needsSig
}
-function getSignatureAttributes({optional, nullable}) {
- const attributes = [];
+function getSignatureAttributes({ optional, nullable }) {
+ const attributes = []
- if (optional) {
- attributes.push('opt');
- }
+ if (optional) {
+ attributes.push('opt')
+ }
- if (nullable === true) {
- attributes.push('nullable');
- }
- else if (nullable === false) {
- attributes.push('non-null');
- }
+ if (nullable === true) {
+ attributes.push('nullable')
+ } else if (nullable === false) {
+ attributes.push('non-null')
+ }
- return attributes;
+ return attributes
}
function updateItemName(item) {
- const attributes = getSignatureAttributes(item);
- let itemName = item.name || '';
-
- if (item.variable) {
- itemName = `…${itemName}`;
- }
-
- if (attributes && attributes.length) {
- itemName = util.format( '%s%s', itemName,
- attributes.join(', ') );
- }
-
- return itemName;
+ const attributes = getSignatureAttributes(item)
+ let itemName = item.name || ''
+
+ if (item.variable) {
+ itemName = `…${itemName}`
+ }
+
+ if (attributes && attributes.length) {
+ itemName = util.format(
+ '%s%s',
+ itemName,
+ attributes.join(', ')
+ )
+ }
+
+ return itemName
}
function addParamAttributes(params) {
- return params.filter(({name}) => name && !name.includes('.')).map(updateItemName);
+ return params.filter(({ name }) => name && !name.includes('.')).map(updateItemName)
}
function buildItemTypeStrings(item) {
- const types = [];
+ const types = []
- if (item && item.type && item.type.names) {
- item.type.names.forEach(name => {
- types.push( linkto(name, htmlsafe(name)) );
- });
- }
+ if (item && item.type && item.type.names) {
+ item.type.names.forEach(name => {
+ types.push(linkto(name, htmlsafe(name)))
+ })
+ }
- return types;
+ return types
}
function buildAttribsString(attribs) {
- let attribsString = '';
+ let attribsString = ''
- if (attribs && attribs.length) {
- attribsString = htmlsafe( util.format('(%s) ', attribs.join(', ')) );
- }
+ if (attribs && attribs.length) {
+ attribsString = htmlsafe(util.format('(%s) ', attribs.join(', ')))
+ }
- return attribsString;
+ return attribsString
}
function addNonParamAttributes(items) {
- let types = [];
+ let types = []
- items.forEach(item => {
- types = types.concat( buildItemTypeStrings(item) );
- });
+ items.forEach(item => {
+ types = types.concat(buildItemTypeStrings(item))
+ })
- return types;
+ return types
}
function addSignatureParams(f) {
- const params = f.params ? addParamAttributes(f.params) : [];
+ const params = f.params ? addParamAttributes(f.params) : []
- f.signature = util.format( '%s(%s)', (f.signature || ''), params.join(', ') );
+ f.signature = util.format('%s(%s)', f.signature || '', params.join(', '))
}
function addSignatureReturns(f) {
- const attribs = [];
- let attribsString = '';
- let returnTypes = [];
- let returnTypesString = '';
- const source = f.yields || f.returns;
-
- // jam all the return-type attributes into an array. this could create odd results (for example,
- // if there are both nullable and non-nullable return types), but let's assume that most people
- // who use multiple @return tags aren't using Closure Compiler type annotations, and vice-versa.
- if (source) {
- source.forEach(item => {
- helper.getAttribs(item).forEach(attrib => {
- if (!attribs.includes(attrib)) {
- attribs.push(attrib);
- }
- });
- });
-
- attribsString = buildAttribsString(attribs);
- }
+ const attribs = []
+ let attribsString = ''
+ let returnTypes = []
+ let returnTypesString = ''
+ const source = f.yields || f.returns
+
+ // jam all the return-type attributes into an array. this could create odd results (for example,
+ // if there are both nullable and non-nullable return types), but let's assume that most people
+ // who use multiple @return tags aren't using Closure Compiler type annotations, and vice-versa.
+ if (source) {
+ source.forEach(item => {
+ helper.getAttribs(item).forEach(attrib => {
+ if (!attribs.includes(attrib)) {
+ attribs.push(attrib)
+ }
+ })
+ })
- if (source) {
- returnTypes = addNonParamAttributes(source);
- }
- if (returnTypes.length) {
- returnTypesString = util.format( ' → %s{%s}', attribsString, returnTypes.join('|') );
- }
+ attribsString = buildAttribsString(attribs)
+ }
- f.signature = `${f.signature || ''}${returnTypesString}`;
+ if (source) {
+ returnTypes = addNonParamAttributes(source)
+ }
+ if (returnTypes.length) {
+ returnTypesString = util.format(' → %s{%s}', attribsString, returnTypes.join('|'))
+ }
+
+ f.signature = `${f.signature || ''}${returnTypesString}`
}
function addSignatureTypes(f) {
- const types = f.type ? buildItemTypeStrings(f) : [];
+ const types = f.type ? buildItemTypeStrings(f) : []
- f.signature = `${f.signature || ''}${types.length ? ` :${types.join('|')}` : ''}`;
+ f.signature = `${f.signature || ''}${types.length ? ` :${types.join('|')}` : ''}`
}
function addAttribs(f) {
- const attribs = helper.getAttribs(f);
- const attribsString = buildAttribsString(attribs);
+ const attribs = helper.getAttribs(f)
+ const attribsString = buildAttribsString(attribs)
- f.attribs = util.format('%s', attribsString);
+ f.attribs = util.format('%s', attribsString)
}
function shortenPaths(files, commonPrefix) {
- Object.keys(files).forEach(file => {
- files[file].shortened = files[file].resolved.replace(commonPrefix, '')
- // always use forward slashes
- .replace(/\\/g, '/');
- });
-
- return files;
+ Object.keys(files).forEach(file => {
+ files[file].shortened = files[file].resolved
+ .replace(commonPrefix, '')
+ // always use forward slashes
+ .replace(/\\/g, '/')
+ })
+
+ return files
}
-function getPathFromDoclet({meta}) {
- if (!meta) {
- return null;
- }
+function getPathFromDoclet({ meta }) {
+ if (!meta) {
+ return null
+ }
- return meta.path && meta.path !== 'null' ?
- path.join(meta.path, meta.filename) :
- meta.filename;
+ return meta.path && meta.path !== 'null' ? path.join(meta.path, meta.filename) : meta.filename
}
function generate(title, docs, filename, resolveLinks) {
- let docData;
- let html;
- let outpath;
+ let docData
+ let html
+ let outpath
- resolveLinks = resolveLinks !== false;
+ resolveLinks = resolveLinks !== false
- docData = {
- env: env,
- title: title,
- // remove tags from header, also see layout.tmpl
- header: title.replace(/]*>/,"").replace(/<\/a>/,""),
- docs: docs
- };
+ docData = {
+ env: env,
+ title: title,
+ // remove tags from header, also see layout.tmpl
+ header: title.replace(/]*>/, '').replace(/<\/a>/, ''),
+ docs: docs
+ }
- outpath = path.join(outdir, filename);
- html = view.render('container.tmpl', docData);
+ outpath = path.join(outdir, filename)
+ html = view.render('container.tmpl', docData)
- if (resolveLinks) {
- html = helper.resolveLinks(html); // turn {@link foo} into foo
- }
+ if (resolveLinks) {
+ html = helper.resolveLinks(html) // turn {@link foo} into foo
+ }
- fs.writeFileSync(outpath, html, 'utf8');
+ fs.writeFileSync(outpath, html, 'utf8')
}
function generateSourceFiles(sourceFiles, encoding = 'utf8') {
- Object.keys(sourceFiles).forEach(file => {
- let source;
- // links are keyed to the shortened path in each doclet's `meta.shortpath` property
- const sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened);
-
- helper.registerLink(sourceFiles[file].shortened, sourceOutfile);
-
- try {
- source = {
- kind: 'source',
- code: helper.htmlsafe( fs.readFileSync(sourceFiles[file].resolved, encoding) )
- };
- }
- catch (e) {
- logger.error('Error while generating source file %s: %s', file, e.message);
- }
+ Object.keys(sourceFiles).forEach(file => {
+ let source
+ // links are keyed to the shortened path in each doclet's `meta.shortpath` property
+ const sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened)
+
+ helper.registerLink(sourceFiles[file].shortened, sourceOutfile)
+
+ try {
+ source = {
+ kind: 'source',
+ code: helper.htmlsafe(fs.readFileSync(sourceFiles[file].resolved, encoding))
+ }
+ } catch (e) {
+ logger.error('Error while generating source file %s: %s', file, e.message)
+ }
- generate(`Source: ${sourceFiles[file].shortened}`, [source], sourceOutfile,
- false);
- });
+ generate(`Source: ${sourceFiles[file].shortened}`, [source], sourceOutfile, false)
+ })
}
/**
@@ -277,71 +280,70 @@ function generateSourceFiles(sourceFiles, encoding = 'utf8') {
* @param {Array.} modules - The array of module doclets to search.
*/
function attachModuleSymbols(doclets, modules) {
- const symbols = {};
-
- // build a lookup table
- doclets.forEach(symbol => {
- symbols[symbol.longname] = symbols[symbol.longname] || [];
- symbols[symbol.longname].push(symbol);
- });
-
- modules.forEach(module => {
- if (symbols[module.longname]) {
- module.modules = symbols[module.longname]
- // Only show symbols that have a description. Make an exception for classes, because
- // we want to show the constructor-signature heading no matter what.
- .filter(({description, kind}) => description || kind === 'class')
- .map(symbol => {
- symbol = doop(symbol);
-
- if (symbol.kind === 'class' || symbol.kind === 'function') {
- symbol.name = `${symbol.name.replace('module:', '(require("')}"))`;
- }
-
- return symbol;
- });
- }
- });
+ const symbols = {}
+
+ // build a lookup table
+ doclets.forEach(symbol => {
+ symbols[symbol.longname] = symbols[symbol.longname] || []
+ symbols[symbol.longname].push(symbol)
+ })
+
+ modules.forEach(module => {
+ if (symbols[module.longname]) {
+ module.modules = symbols[module.longname]
+ // Only show symbols that have a description. Make an exception for classes, because
+ // we want to show the constructor-signature heading no matter what.
+ .filter(({ description, kind }) => description || kind === 'class')
+ .map(symbol => {
+ symbol = doop(symbol)
+
+ if (symbol.kind === 'class' || symbol.kind === 'function') {
+ symbol.name = `${symbol.name.replace('module:', '(require("')}"))`
+ }
+
+ return symbol
+ })
+ }
+ })
}
function buildMemberNav(items, itemHeading, itemsSeen, linktoFn) {
- let nav = '';
-
- if (items.length) {
- let itemsNav = '';
-
- items.forEach(item => {
- let displayName;
-
- if ( !hasOwnProp.call(item, 'longname') ) {
- itemsNav += `${linktoFn('', item.name)}`;
- }
- else if ( !hasOwnProp.call(itemsSeen, item.longname) ) {
- if (env.conf.templates.default.useLongnameInNav) {
- displayName = item.longname;
- } else {
- displayName = item.name;
- }
- itemsNav += `${linktoFn(item.longname, displayName.replace(/\b(module|event):/g, ''))}`;
-
- itemsSeen[item.longname] = true;
- }
- });
-
- if (itemsNav !== '') {
- nav += `${itemHeading}
`;
+ let nav = ''
+
+ if (items.length) {
+ let itemsNav = ''
+
+ items.forEach(item => {
+ let displayName
+
+ if (!hasOwnProp.call(item, 'longname')) {
+ itemsNav += `${linktoFn('', item.name)}`
+ } else if (!hasOwnProp.call(itemsSeen, item.longname)) {
+ if (env.conf.templates.default.useLongnameInNav) {
+ displayName = item.longname
+ } else {
+ displayName = item.name
}
+ itemsNav += `${linktoFn(item.longname, displayName.replace(/\b(module|event):/g, ''))}`
+
+ itemsSeen[item.longname] = true
+ }
+ })
+
+ if (itemsNav !== '') {
+ nav += `${itemHeading}
`
}
+ }
- return nav;
+ return nav
}
function linktoTutorial(longName, name) {
- return tutoriallink(name);
+ return tutoriallink(name)
}
function linktoExternal(longName, name) {
- return linkto(longName, name.replace(/(^"|"$)/g, ''));
+ return linkto(longName, name.replace(/(^"|"$)/g, ''))
}
/**
@@ -359,47 +361,46 @@ function linktoExternal(longName, name) {
* @return {string} The HTML for the navigation sidebar.
*/
function buildNav(members) {
- let globalNav;
- let nav = ''; // '';
- const seen = {};
- const seenTutorials = {};
-
- nav += buildMemberNav(members.modules, 'Modules', {}, linkto);
- nav += buildMemberNav(members.externals, 'Externals', seen, linktoExternal);
- nav += buildMemberNav(members.namespaces, 'Namespaces', seen, linkto);
-// nav += buildMemberNav(members.classes, 'Classes', seen, linkto);
- nav += buildMemberNav(members.interfaces, 'Interfaces', seen, linkto);
- nav += buildMemberNav(members.events, 'Events', seen, linkto);
- nav += buildMemberNav(members.mixins, 'Mixins', seen, linkto);
- nav += buildMemberNav(members.tutorials, 'Tutorials', seenTutorials, linktoTutorial);
-
- if (members.globals.length) {
- globalNav = '';
-
- members.globals.forEach(({kind, longname, name}) => {
- if ( kind !== 'typedef' && !hasOwnProp.call(seen, longname) ) {
- globalNav += `${linkto(longname, name)}`;
- }
- seen[longname] = true;
- });
-
- if (!globalNav) {
- // turn the heading into a link so you can actually get to the global page
- // MH: 9/7/19: use the basename of the folder as heading
- // MH: 13/7/19: we turn "_" into " §", in order to have nice headings
- // JC: 29/3/20: restrict above transformation to first "_"
- const symbolReplacedName = path.basename(outdir).replace(/_/, " §");
- // JC: 29/3/20: change all remaining "_" to " "
- const displayName = symbolReplacedName.replace(/_/g, " ");
- const link = `${displayName}`;
- nav += `${linkto('global', 'Predeclared in '+ link)}
`;
- }
- else {
- nav += `Predeclared names
`;
- }
+ let globalNav
+ let nav = '' // '';
+ const seen = {}
+ const seenTutorials = {}
+
+ nav += buildMemberNav(members.modules, 'Modules', {}, linkto)
+ nav += buildMemberNav(members.externals, 'Externals', seen, linktoExternal)
+ nav += buildMemberNav(members.namespaces, 'Namespaces', seen, linkto)
+ // nav += buildMemberNav(members.classes, 'Classes', seen, linkto);
+ nav += buildMemberNav(members.interfaces, 'Interfaces', seen, linkto)
+ nav += buildMemberNav(members.events, 'Events', seen, linkto)
+ nav += buildMemberNav(members.mixins, 'Mixins', seen, linkto)
+ nav += buildMemberNav(members.tutorials, 'Tutorials', seenTutorials, linktoTutorial)
+
+ if (members.globals.length) {
+ globalNav = ''
+
+ members.globals.forEach(({ kind, longname, name }) => {
+ if (kind !== 'typedef' && !hasOwnProp.call(seen, longname)) {
+ globalNav += `${linkto(longname, name)}`
+ }
+ seen[longname] = true
+ })
+
+ if (!globalNav) {
+ // turn the heading into a link so you can actually get to the global page
+ // MH: 9/7/19: use the basename of the folder as heading
+ // MH: 13/7/19: we turn "_" into " §", in order to have nice headings
+ // JC: 29/3/20: restrict above transformation to first "_"
+ const symbolReplacedName = path.basename(outdir).replace(/_/, ' §')
+ // JC: 29/3/20: change all remaining "_" to " "
+ const displayName = symbolReplacedName.replace(/_/g, ' ')
+ const link = `${displayName}`
+ nav += `${linkto('global', 'Predeclared in ' + link)}
`
+ } else {
+ nav += `Predeclared names
`
}
+ }
- return nav;
+ return nav
}
/**
@@ -408,315 +409,319 @@ function buildNav(members) {
@param {Tutorial} tutorials
*/
exports.publish = (taffyData, opts, tutorials) => {
- let classes;
- let conf;
- let externals;
- let files;
- let fromDir;
- let globalUrl;
- let indexUrl;
- let interfaces;
- let members;
- let mixins;
- let modules;
- let namespaces;
- let outputSourceFiles;
- let packageInfo;
- let packages;
- const sourceFilePaths = [];
- let sourceFiles = {};
- let staticFileFilter;
- let staticFilePaths;
- let staticFiles;
- let staticFileScanner;
- let templatePath;
-
- data = taffyData;
-
- conf = env.conf.templates || {};
- conf.default = conf.default || {};
-
- templatePath = path.normalize(opts.template);
- view = new template.Template( path.join(templatePath, 'tmpl') );
-
- // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
- // doesn't try to hand them out later
- indexUrl = helper.getUniqueFilename('index');
- // don't call registerLink() on this one! 'index' is also a valid longname
-
- globalUrl = helper.getUniqueFilename('global');
- helper.registerLink('global', globalUrl);
-
- // set up templating
- view.layout = conf.default.layoutFile ?
- path.getResourcePath(path.dirname(conf.default.layoutFile),
- path.basename(conf.default.layoutFile) ) :
- 'layout.tmpl';
-
- // set up tutorials for helper
- helper.setTutorials(tutorials);
-
- data = helper.prune(data);
- data.sort('longname, version, since');
- helper.addEventListeners(data);
-
- data().each(doclet => {
- let sourcePath;
-
- doclet.attribs = '';
-
- if (doclet.examples) {
- doclet.examples = doclet.examples.map(example => {
- let caption;
- let code;
-
- if (example.match(/^\s*([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) {
- caption = RegExp.$1;
- code = RegExp.$3;
- }
-
- return {
- caption: caption || '',
- code: code || example
- };
- });
- }
- if (doclet.see) {
- doclet.see.forEach((seeItem, i) => {
- doclet.see[i] = hashToLink(doclet, seeItem);
- });
+ let classes
+ let conf
+ let externals
+ let files
+ let fromDir
+ let globalUrl
+ let indexUrl
+ let interfaces
+ let members
+ let mixins
+ let modules
+ let namespaces
+ let outputSourceFiles
+ let packageInfo
+ let packages
+ const sourceFilePaths = []
+ let sourceFiles = {}
+ let staticFileFilter
+ let staticFilePaths
+ let staticFiles
+ let staticFileScanner
+ let templatePath
+
+ data = taffyData
+
+ conf = env.conf.templates || {}
+ conf.default = conf.default || {}
+
+ templatePath = path.normalize(opts.template)
+ view = new template.Template(path.join(templatePath, 'tmpl'))
+
+ // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
+ // doesn't try to hand them out later
+ indexUrl = helper.getUniqueFilename('index')
+ // don't call registerLink() on this one! 'index' is also a valid longname
+
+ globalUrl = helper.getUniqueFilename('global')
+ helper.registerLink('global', globalUrl)
+
+ // set up templating
+ view.layout = conf.default.layoutFile
+ ? path.getResourcePath(
+ path.dirname(conf.default.layoutFile),
+ path.basename(conf.default.layoutFile)
+ )
+ : 'layout.tmpl'
+
+ // set up tutorials for helper
+ helper.setTutorials(tutorials)
+
+ data = helper.prune(data)
+ data.sort('longname, version, since')
+ helper.addEventListeners(data)
+
+ data().each(doclet => {
+ let sourcePath
+
+ doclet.attribs = ''
+
+ if (doclet.examples) {
+ doclet.examples = doclet.examples.map(example => {
+ let caption
+ let code
+
+ if (example.match(/^\s*([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) {
+ caption = RegExp.$1
+ code = RegExp.$3
}
- // build a list of source files
- if (doclet.meta) {
- sourcePath = getPathFromDoclet(doclet);
- sourceFiles[sourcePath] = {
- resolved: sourcePath,
- shortened: null
- };
- if (!sourceFilePaths.includes(sourcePath)) {
- sourceFilePaths.push(sourcePath);
- }
+ return {
+ caption: caption || '',
+ code: code || example
}
- });
-
- // update outdir if necessary, then create outdir
- packageInfo = ( find({kind: 'package'}) || [] )[0];
- if (packageInfo && packageInfo.name) {
- outdir = path.join( outdir, packageInfo.name, (packageInfo.version || '') );
+ })
}
- fs.mkPath(outdir);
-
- // copy the template's static files to outdir
- fromDir = path.join(templatePath, 'static');
- staticFiles = fs.ls(fromDir, 3);
-
- staticFiles.forEach(fileName => {
- const toDir = fs.toDir( fileName.replace(fromDir, outdir) );
-
- fs.mkPath(toDir);
- fs.copyFileSync(fileName, toDir);
- });
-
- // copy user-specified static files to outdir
- if (conf.default.staticFiles) {
- // The canonical property name is `include`. We accept `paths` for backwards compatibility
- // with a bug in JSDoc 3.2.x.
- staticFilePaths = conf.default.staticFiles.include ||
- conf.default.staticFiles.paths ||
- [];
- staticFileFilter = new (require('jsdoc/src/filter').Filter)(conf.default.staticFiles);
- staticFileScanner = new (require('jsdoc/src/scanner').Scanner)();
-
- staticFilePaths.forEach(filePath => {
- let extraStaticFiles;
-
- filePath = path.resolve(env.pwd, filePath);
- extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter);
-
- extraStaticFiles.forEach(fileName => {
- const sourcePath = fs.toDir(filePath);
- const toDir = fs.toDir( fileName.replace(sourcePath, outdir) );
-
- fs.mkPath(toDir);
- fs.copyFileSync(fileName, toDir);
- });
- });
+ if (doclet.see) {
+ doclet.see.forEach((seeItem, i) => {
+ doclet.see[i] = hashToLink(doclet, seeItem)
+ })
}
- if (sourceFilePaths.length) {
- sourceFiles = shortenPaths( sourceFiles, path.commonPrefix(sourceFilePaths) );
+ // build a list of source files
+ if (doclet.meta) {
+ sourcePath = getPathFromDoclet(doclet)
+ sourceFiles[sourcePath] = {
+ resolved: sourcePath,
+ shortened: null
+ }
+ if (!sourceFilePaths.includes(sourcePath)) {
+ sourceFilePaths.push(sourcePath)
+ }
}
- data().each(doclet => {
- let docletPath;
- const url = helper.createLink(doclet);
-
- helper.registerLink(doclet.longname, url);
-
- // add a shortened version of the full path
- if (doclet.meta) {
- docletPath = getPathFromDoclet(doclet);
- docletPath = sourceFiles[docletPath].shortened;
- if (docletPath) {
- doclet.meta.shortpath = docletPath;
- }
- }
- });
+ })
+
+ // update outdir if necessary, then create outdir
+ packageInfo = (find({ kind: 'package' }) || [])[0]
+ if (packageInfo && packageInfo.name) {
+ outdir = path.join(outdir, packageInfo.name, packageInfo.version || '')
+ }
+ fs.mkPath(outdir)
+
+ // copy the template's static files to outdir
+ fromDir = path.join(templatePath, 'static')
+ staticFiles = fs.ls(fromDir, 3)
+
+ staticFiles.forEach(fileName => {
+ const toDir = fs.toDir(fileName.replace(fromDir, outdir))
+
+ fs.mkPath(toDir)
+ fs.copyFileSync(fileName, toDir)
+ })
+
+ // copy user-specified static files to outdir
+ if (conf.default.staticFiles) {
+ // The canonical property name is `include`. We accept `paths` for backwards compatibility
+ // with a bug in JSDoc 3.2.x.
+ staticFilePaths = conf.default.staticFiles.include || conf.default.staticFiles.paths || []
+ staticFileFilter = new (require('jsdoc/src/filter').Filter)(conf.default.staticFiles)
+ staticFileScanner = new (require('jsdoc/src/scanner').Scanner)()
+
+ staticFilePaths.forEach(filePath => {
+ let extraStaticFiles
+
+ filePath = path.resolve(env.pwd, filePath)
+ extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter)
+
+ extraStaticFiles.forEach(fileName => {
+ const sourcePath = fs.toDir(filePath)
+ const toDir = fs.toDir(fileName.replace(sourcePath, outdir))
+
+ fs.mkPath(toDir)
+ fs.copyFileSync(fileName, toDir)
+ })
+ })
+ }
+
+ if (sourceFilePaths.length) {
+ sourceFiles = shortenPaths(sourceFiles, path.commonPrefix(sourceFilePaths))
+ }
+ data().each(doclet => {
+ let docletPath
+ const url = helper.createLink(doclet)
+
+ helper.registerLink(doclet.longname, url)
+
+ // add a shortened version of the full path
+ if (doclet.meta) {
+ docletPath = getPathFromDoclet(doclet)
+ docletPath = sourceFiles[docletPath].shortened
+ if (docletPath) {
+ doclet.meta.shortpath = docletPath
+ }
+ }
+ })
- data().each(doclet => {
- const url = helper.longnameToUrl[doclet.longname];
+ data().each(doclet => {
+ const url = helper.longnameToUrl[doclet.longname]
- if (url.includes('#')) {
- doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop();
- }
- else {
- doclet.id = doclet.name;
- }
+ if (url.includes('#')) {
+ doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop()
+ } else {
+ doclet.id = doclet.name
+ }
- if ( needsSignature(doclet) ) {
- addSignatureParams(doclet);
- addSignatureReturns(doclet);
- addAttribs(doclet);
- }
- });
+ if (needsSignature(doclet)) {
+ addSignatureParams(doclet)
+ addSignatureReturns(doclet)
+ addAttribs(doclet)
+ }
+ })
- // do this after the urls have all been generated
- data().each(doclet => {
- doclet.ancestors = getAncestorLinks(doclet);
+ // do this after the urls have all been generated
+ data().each(doclet => {
+ doclet.ancestors = getAncestorLinks(doclet)
- if (doclet.kind === 'member') {
- addSignatureTypes(doclet);
- addAttribs(doclet);
- }
+ if (doclet.kind === 'member') {
+ addSignatureTypes(doclet)
+ addAttribs(doclet)
+ }
- if (doclet.kind === 'constant') {
- addSignatureTypes(doclet);
- addAttribs(doclet);
- doclet.kind = 'member';
+ if (doclet.kind === 'constant') {
+ addSignatureTypes(doclet)
+ addAttribs(doclet)
+ doclet.kind = 'member'
+ }
+ })
+
+ members = helper.getMembers(data)
+ members.tutorials = tutorials.children
+
+ // output pretty-printed source files by default
+ outputSourceFiles = conf.default && conf.default.outputSourceFiles !== false
+
+ // add template helpers
+ view.find = find
+ view.linkto = linkto
+ view.resolveAuthorLinks = resolveAuthorLinks
+ view.tutoriallink = tutoriallink
+ view.htmlsafe = htmlsafe
+ view.outputSourceFiles = outputSourceFiles
+
+ // once for all
+ view.nav = buildNav(members)
+ attachModuleSymbols(find({ longname: { left: 'module:' } }), members.modules)
+
+ // generate the pretty-printed source files first so other pages can link to them
+ if (outputSourceFiles) {
+ generateSourceFiles(sourceFiles, opts.encoding)
+ }
+
+ // MH: 9/7/19: use the basename of the folder as heading
+ let baseName = path.basename(outdir)
+ // MH: 13/7/19: turn "_" into " §", in order to have nice headings
+ // JC: 29/3/20: restrict above transformation to first "_"
+ const symbolReplacedName = baseName.replace(/_/, ' §')
+ // JC: 29/3/20: change all remaining "_" to " ", then capitalize each word
+ const spacedName = symbolReplacedName.replace(/_/g, ' ')
+ // Arsalan: 21/4/20: capitalize the first letter of each word, including those separated by a hyphen
+ const displayName = spacedName.replace(/(^|[\s-])\S/g, firstLetter => firstLetter.toUpperCase())
+
+ const link = `${displayName}`
+
+ // MH: 23/4/2020: added else to conditional to allow for empty libs
+ if (members.globals.length) {
+ generate('Predeclared in ' + link, [{ kind: 'globalobj' }], globalUrl)
+ } else {
+ generate('No names predeclared in ' + link, [{ kind: 'globalobj' }], globalUrl)
+ }
+
+ // index page displays information from package.json and lists files
+ files = find({ kind: 'file' })
+ packages = find({ kind: 'package' })
+
+ generate(
+ displayName, // MH: 1/7/2019: This was:
+ // generate('Home',
+ packages
+ .concat([
+ {
+ kind: 'mainpage',
+ readme: opts.readme,
+ longname: opts.mainpagetitle ? opts.mainpagetitle : 'Main Page'
}
- });
-
- members = helper.getMembers(data);
- members.tutorials = tutorials.children;
-
- // output pretty-printed source files by default
- outputSourceFiles = conf.default && conf.default.outputSourceFiles !== false;
-
- // add template helpers
- view.find = find;
- view.linkto = linkto;
- view.resolveAuthorLinks = resolveAuthorLinks;
- view.tutoriallink = tutoriallink;
- view.htmlsafe = htmlsafe;
- view.outputSourceFiles = outputSourceFiles;
-
- // once for all
- view.nav = buildNav(members);
- attachModuleSymbols( find({ longname: {left: 'module:'} }), members.modules );
-
- // generate the pretty-printed source files first so other pages can link to them
- if (outputSourceFiles) {
- generateSourceFiles(sourceFiles, opts.encoding);
+ ])
+ .concat(files),
+ indexUrl
+ )
+
+ // set up the lists that we'll use to generate pages
+ classes = taffy(members.classes)
+ modules = taffy(members.modules)
+ namespaces = taffy(members.namespaces)
+ mixins = taffy(members.mixins)
+ externals = taffy(members.externals)
+ interfaces = taffy(members.interfaces)
+
+ Object.keys(helper.longnameToUrl).forEach(longname => {
+ const myClasses = helper.find(classes, { longname: longname })
+ const myExternals = helper.find(externals, { longname: longname })
+ const myInterfaces = helper.find(interfaces, { longname: longname })
+ const myMixins = helper.find(mixins, { longname: longname })
+ const myModules = helper.find(modules, { longname: longname })
+ const myNamespaces = helper.find(namespaces, { longname: longname })
+
+ if (myModules.length) {
+ generate(`Module: ${myModules[0].name}`, myModules, helper.longnameToUrl[longname])
}
- // MH: 9/7/19: use the basename of the folder as heading
- let baseName = path.basename(outdir);
- // MH: 13/7/19: turn "_" into " §", in order to have nice headings
- // JC: 29/3/20: restrict above transformation to first "_"
- const symbolReplacedName = baseName.replace(/_/, " §");
- // JC: 29/3/20: change all remaining "_" to " ", then capitalize each word
- const spacedName = symbolReplacedName.replace(/_/g, " ");
- // Arsalan: 21/4/20: capitalize the first letter of each word, including those separated by a hyphen
- const displayName = spacedName.replace(/(^|[\s-])\S/g, firstLetter => firstLetter.toUpperCase());
-
- const link = `${displayName}`;
-
- // MH: 23/4/2020: added else to conditional to allow for empty libs
- if (members.globals.length) {
- generate('Predeclared in '+ link, [{kind: 'globalobj'}], globalUrl);
- } else {
- generate('No names predeclared in ' + link, [{kind: 'globalobj'}], globalUrl);
+ if (myClasses.length) {
+ generate(`Class: ${myClasses[0].name}`, myClasses, helper.longnameToUrl[longname])
}
- // index page displays information from package.json and lists files
- files = find({kind: 'file'});
- packages = find({kind: 'package'});
-
- generate(displayName, // MH: 1/7/2019: This was:
- // generate('Home',
- packages.concat(
- [{
- kind: 'mainpage',
- readme: opts.readme,
- longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'
- }]
- ).concat(files), indexUrl);
-
- // set up the lists that we'll use to generate pages
- classes = taffy(members.classes);
- modules = taffy(members.modules);
- namespaces = taffy(members.namespaces);
- mixins = taffy(members.mixins);
- externals = taffy(members.externals);
- interfaces = taffy(members.interfaces);
-
- Object.keys(helper.longnameToUrl).forEach(longname => {
- const myClasses = helper.find(classes, {longname: longname});
- const myExternals = helper.find(externals, {longname: longname});
- const myInterfaces = helper.find(interfaces, {longname: longname});
- const myMixins = helper.find(mixins, {longname: longname});
- const myModules = helper.find(modules, {longname: longname});
- const myNamespaces = helper.find(namespaces, {longname: longname});
-
- if (myModules.length) {
- generate(`Module: ${myModules[0].name}`, myModules, helper.longnameToUrl[longname]);
- }
+ if (myNamespaces.length) {
+ generate(`Namespace: ${myNamespaces[0].name}`, myNamespaces, helper.longnameToUrl[longname])
+ }
- if (myClasses.length) {
- generate(`Class: ${myClasses[0].name}`, myClasses, helper.longnameToUrl[longname]);
- }
+ if (myMixins.length) {
+ generate(`Mixin: ${myMixins[0].name}`, myMixins, helper.longnameToUrl[longname])
+ }
- if (myNamespaces.length) {
- generate(`Namespace: ${myNamespaces[0].name}`, myNamespaces, helper.longnameToUrl[longname]);
- }
+ if (myExternals.length) {
+ generate(`External: ${myExternals[0].name}`, myExternals, helper.longnameToUrl[longname])
+ }
- if (myMixins.length) {
- generate(`Mixin: ${myMixins[0].name}`, myMixins, helper.longnameToUrl[longname]);
- }
+ if (myInterfaces.length) {
+ generate(`Interface: ${myInterfaces[0].name}`, myInterfaces, helper.longnameToUrl[longname])
+ }
+ })
+
+ // TODO: move the tutorial functions to templateHelper.js
+ function generateTutorial(title, tutorial, filename) {
+ const tutorialData = {
+ title: title,
+ header: tutorial.title,
+ content: tutorial.parse(),
+ children: tutorial.children
+ }
+ const tutorialPath = path.join(outdir, filename)
+ let html = view.render('tutorial.tmpl', tutorialData)
- if (myExternals.length) {
- generate(`External: ${myExternals[0].name}`, myExternals, helper.longnameToUrl[longname]);
- }
+ // yes, you can use {@link} in tutorials too!
+ html = helper.resolveLinks(html) // turn {@link foo} into foo
- if (myInterfaces.length) {
- generate(`Interface: ${myInterfaces[0].name}`, myInterfaces, helper.longnameToUrl[longname]);
- }
- });
-
- // TODO: move the tutorial functions to templateHelper.js
- function generateTutorial(title, tutorial, filename) {
- const tutorialData = {
- title: title,
- header: tutorial.title,
- content: tutorial.parse(),
- children: tutorial.children
- };
- const tutorialPath = path.join(outdir, filename);
- let html = view.render('tutorial.tmpl', tutorialData);
-
- // yes, you can use {@link} in tutorials too!
- html = helper.resolveLinks(html); // turn {@link foo} into foo
-
- fs.writeFileSync(tutorialPath, html, 'utf8');
- }
+ fs.writeFileSync(tutorialPath, html, 'utf8')
+ }
- // tutorials can have only one parent so there is no risk for loops
- function saveChildren({children}) {
- children.forEach(child => {
- generateTutorial(`Tutorial: ${child.title}`, child, helper.tutorialToUrl(child.name));
- saveChildren(child);
- });
- }
+ // tutorials can have only one parent so there is no risk for loops
+ function saveChildren({ children }) {
+ children.forEach(child => {
+ generateTutorial(`Tutorial: ${child.title}`, child, helper.tutorialToUrl(child.name))
+ saveChildren(child)
+ })
+ }
- saveChildren(tutorials);
-};
+ saveChildren(tutorials)
+}
diff --git a/docs/lib/array.js b/docs/lib/array.js
index c9cd723a3..3c0920cfd 100644
--- a/docs/lib/array.js
+++ b/docs/lib/array.js
@@ -1,7 +1,7 @@
/**
* **primitive**; returns
* the current length of array x, which is 1 plus the
- * highest index that has been used so far in an array assignment on
+ * highest index that has been used so far in an array assignment on
* x. Here literal array expressions are counted too: The
* array [10, 20, 30] has a length of 3.
* Time: Θ(1), space: Θ(1)
@@ -11,11 +11,10 @@
function array_length(x) {}
/**
- * **primitive**; returns true if x
+ * **primitive**; returns true if x
* is an array, and false if it is not.
* Time: Θ(1), space: Θ(1)
* @param {value} x - given value
* @returns {boolean} whether x is an array
*/
function is_array(x) {}
-
diff --git a/docs/lib/concurrency.js b/docs/lib/concurrency.js
index 75fa7c269..46c057a5b 100644
--- a/docs/lib/concurrency.js
+++ b/docs/lib/concurrency.js
@@ -1,6 +1,6 @@
/**
* Setup multiple threads for concurrent execution. For each
- * function f_i,
+ * function f_i,
* setup a thread t_i that executes the body of
* f_i. Any parameters of f_i refer
* to undefined during execution.
diff --git a/docs/lib/continuation.js b/docs/lib/continuation.js
index e357eea1d..39c794fcd 100755
--- a/docs/lib/continuation.js
+++ b/docs/lib/continuation.js
@@ -1,8 +1,7 @@
/**
* Generate a continuation cont,
- * and call f(cont).
+ * and call f(cont).
* @param {function} f - A function of the form (cont) => ...
* @returns the return value of f if cont is not consumed
*/
function call_cc(f) {}
-
diff --git a/docs/lib/empty.js b/docs/lib/empty.js
index 2e3c9c1b0..1c2d1be97 100755
--- a/docs/lib/empty.js
+++ b/docs/lib/empty.js
@@ -1,4 +1,3 @@
/**
* there are no predeclared names here
*/
-
diff --git a/docs/lib/ev3.js b/docs/lib/ev3.js
index 5d632ee36..81dbd77c7 100644
--- a/docs/lib/ev3.js
+++ b/docs/lib/ev3.js
@@ -5,8 +5,7 @@
* @returns {boolean} true if the peripheral is connected, false otherwise
* @alias ev3_connected
*/
-var connected = function(obj) {
-};
+var connected = function (obj) {}
/**
* Gets the motor connected to port A.
@@ -14,8 +13,7 @@ var connected = function(obj) {
* @returns {peripheral} The motor connected to port A
* @alias ev3_motorA
*/
-var motorA = function() {
-};
+var motorA = function () {}
/**
* Gets the motor connected to port B.
@@ -23,8 +21,7 @@ var motorA = function() {
* @returns {peripheral} The motor connected to port B
* @alias ev3_motorB
*/
-var motorB = function() {
-};
+var motorB = function () {}
/**
* Gets the motor connected to port C.
@@ -32,8 +29,7 @@ var motorB = function() {
* @returns {peripheral} The motor connected to port C
* @alias ev3_motorC
*/
-var motorC = function() {
-};
+var motorC = function () {}
/**
* Gets the motor connected to port D.
@@ -41,9 +37,7 @@ var motorC = function() {
* @returns {peripheral} The motor connected to port D
* @alias ev3_motorD
*/
-var motorD = function() {
-};
-
+var motorD = function () {}
/**
* Causes the motor to rotate for a specified duration at the specified speed.
@@ -55,8 +49,7 @@ var motorD = function() {
* @param {number} speed - The speed to run at, in tacho counts per second
* @alias ev3_runForTime
*/
-var runForTime = function(motor, time, speed) {
-};
+var runForTime = function (motor, time, speed) {}
/**
* Causes the motor to rotate to the given absolute position (as reported by
@@ -69,8 +62,7 @@ var runForTime = function(motor, time, speed) {
* @param {number} speed - The speed to run at, in tacho counts per second
* @alias ev3_runToAbsolutePosition
*/
-var runToAbsolutePosition = function(motor, position, speed) {
-};
+var runToAbsolutePosition = function (motor, position, speed) {}
/**
* Causes the motor to rotate until the position reaches {@link ev3_motorGetPosition}()
@@ -83,8 +75,7 @@ var runToAbsolutePosition = function(motor, position, speed) {
* @param {number} speed - The speed to run at, in tacho counts per second
* @alias ev3_runToRelativePosition
*/
-var runToRelativePosition = function(motor, position, speed) {
-};
+var runToRelativePosition = function (motor, position, speed) {}
/**
* Gets the motor's current position, in pulses of the rotary encoder.
@@ -93,8 +84,7 @@ var runToRelativePosition = function(motor, position, speed) {
* @returns {number} The current position.
* @alias ev3_motorGetPosition
*/
-var motorGetPosition = function(motor) {
-}
+var motorGetPosition = function (motor) {}
/**
* Gets the motor's current speed, in tacho counts per second.
@@ -103,8 +93,7 @@ var motorGetPosition = function(motor) {
* @returns {number} The current speed.
* @alias ev3_motorGetSpeed
*/
-var motorGetSpeed = function(motor) {
-}
+var motorGetSpeed = function (motor) {}
/**
* Sets the speed the motor will run at the next time {@link ev3_motorStart}
@@ -114,8 +103,7 @@ var motorGetSpeed = function(motor) {
* @param {number} speed - The speed to run at, in tacho counts per second
* @alias ev3_motorSetSpeed
*/
-var motorSetSpeed = function(motor, speed) {
-}
+var motorSetSpeed = function (motor, speed) {}
/**
* Causes the motor to start with the previously set speed and stop action
@@ -124,8 +112,7 @@ var motorSetSpeed = function(motor, speed) {
* @param {peripheral} motor - The motor
* @alias ev3_motorStart
*/
-var motorStart = function(motor) {
-};
+var motorStart = function (motor) {}
/**
* Causes the motor to stop using the previously set stop action.
@@ -133,8 +120,7 @@ var motorStart = function(motor) {
* @param {peripheral} motor - The motor
* @alias ev3_motorStop
*/
-var motorStop = function(motor) {
-};
+var motorStop = function (motor) {}
/**
* Sets the stop action of the motor.
@@ -149,8 +135,7 @@ var motorStop = function(motor) {
* @param {string} stopAction - The stop action to use.
* @alias ev3_motorSetStopAction
*/
-var motorSetStopAction = function(motor, stopAction) {
-}
+var motorSetStopAction = function (motor, stopAction) {}
/**
* Gets the colour sensor connected any of ports 1, 2, 3 or 4.
@@ -158,8 +143,7 @@ var motorSetStopAction = function(motor, stopAction) {
* @returns {peripheral} The colour sensor.
* @alias ev3_colorSensor
*/
-var colorSensor = function() {
-};
+var colorSensor = function () {}
/**
* Gets the amount of red seen by the colour sensor.
@@ -168,8 +152,7 @@ var colorSensor = function() {
* @returns {number} The amount of red, in sensor-specific units.
* @alias ev3_colorSensorRed
*/
-var colorSensorRed = function(colorSensor) {
-}
+var colorSensorRed = function (colorSensor) {}
/**
* Gets the amount of green seen by the colour sensor.
@@ -178,8 +161,7 @@ var colorSensorRed = function(colorSensor) {
* @returns {number} The amount of green, in sensor-specific units.
* @alias ev3_colorSensorGreen
*/
-var colorSensorGreen = function(colorSensor) {
-}
+var colorSensorGreen = function (colorSensor) {}
/**
* Gets the amount of blue seen by the colour sensor.
@@ -188,8 +170,7 @@ var colorSensorGreen = function(colorSensor) {
* @returns {number} The amount of blue, in sensor-specific units.
* @alias ev3_colorSensorBlue
*/
-var colorSensorBlue = function(colorSensor) {
-}
+var colorSensorBlue = function (colorSensor) {}
/**
* Gets the colour as seen by the colour sensor.
@@ -208,8 +189,7 @@ var colorSensorBlue = function(colorSensor) {
* @returns {number} A number representing the colour observed by the device.
* @alias ev3_colorSensorGetColor
*/
-var colorSensorGetColor = function(colorSensor) {
-}
+var colorSensorGetColor = function (colorSensor) {}
/**
* Gets the reflected light intensity seen by the colour sensor.
@@ -218,8 +198,7 @@ var colorSensorGetColor = function(colorSensor) {
* @returns {number} The reflected light intensity, as a percentage from 0 to 100.
* @alias ev3_reflectedLightIntensity
*/
-var reflectedLightIntensity = function(colorSensor) {
-};
+var reflectedLightIntensity = function (colorSensor) {}
/**
* Gets the ambient light intensity seen by the colour sensor.
@@ -228,8 +207,7 @@ var reflectedLightIntensity = function(colorSensor) {
* @returns {number} The ambient light intensity, as a percentage from 0 to 100.
* @alias ev3_ambientLightIntensity
*/
-var ambientLightIntensity = function(colorSensor) {
-};
+var ambientLightIntensity = function (colorSensor) {}
/**
* Gets the touch sensor connected to port 1.
@@ -237,8 +215,7 @@ var ambientLightIntensity = function(colorSensor) {
* @returns {peripheral} The touch sensor.
* @alias ev3_touchSensor1
*/
-var touchSensor1 = function() {
-};
+var touchSensor1 = function () {}
/**
* Gets the touch sensor connected to port 2.
@@ -246,8 +223,7 @@ var touchSensor1 = function() {
* @returns {peripheral} The touch sensor.
* @alias ev3_touchSensor2
*/
-var touchSensor2 = function() {
-};
+var touchSensor2 = function () {}
/**
* Gets the touch sensor connected to port 3.
@@ -255,8 +231,7 @@ var touchSensor2 = function() {
* @returns {peripheral} The touch sensor.
* @alias ev3_touchSensor3
*/
-var touchSensor3 = function() {
-};
+var touchSensor3 = function () {}
/**
* Gets the touch sensor connected to port 4.
@@ -264,8 +239,7 @@ var touchSensor3 = function() {
* @returns {peripheral} The touch sensor.
* @alias ev3_touchSensor4
*/
-var touchSensor4 = function() {
-};
+var touchSensor4 = function () {}
/**
* Gets whether the touch sensor is pressed.
@@ -274,8 +248,7 @@ var touchSensor4 = function() {
* @returns {boolean} true when the touch sensor is pressed, false otherwise.
* @alias ev3_touchSensorPressed
*/
-var touchSensorPressed = function(touchSensor) {
-};
+var touchSensorPressed = function (touchSensor) {}
/**
* Gets the ultrasonic sensor connected any of ports 1, 2, 3 or 4.
@@ -283,8 +256,7 @@ var touchSensorPressed = function(touchSensor) {
* @returns {peripheral} The ultrasonic sensor.
* @alias ev3_ultrasonicSensor
*/
-var ultrasonicSensor = function() {
-};
+var ultrasonicSensor = function () {}
/**
* Gets the distance read by the ultrasonic sensor in centimeters.
@@ -293,8 +265,7 @@ var ultrasonicSensor = function() {
* @returns {number} The distance, in centimeters.
* @alias ev3_ultrasonicSensorDistance
*/
-var ultrasonicSensorDistance = function(ultrasonicSensor) {
-};
+var ultrasonicSensorDistance = function (ultrasonicSensor) {}
/**
* Gets the gyro sensor connected any of ports 1, 2, 3 or 4.
@@ -302,8 +273,7 @@ var ultrasonicSensorDistance = function(ultrasonicSensor) {
* @returns {peripheral} The gyro sensor.
* @alias ev3_gyroSensor
*/
-var gyroSensor = function() {
-};
+var gyroSensor = function () {}
/**
* Gets the rate of rotation detected by the gyro sensor.
@@ -312,8 +282,7 @@ var gyroSensor = function() {
* @returns {number} The rate of rotation, in degrees per second.
* @alias ev3_gyroSensorRate
*/
-var gyroSensorRate = function(gyroSensor) {
-};
+var gyroSensorRate = function (gyroSensor) {}
/**
* Gets the absolute angle detected by the gyro sensor, measured from when
@@ -323,9 +292,7 @@ var gyroSensorRate = function(gyroSensor) {
* @returns {number} The angle, in degrees.
* @alias ev3_gyroSensorAngle
*/
-var gyroSensorAngle = function(gyroSensor) {
-};
-
+var gyroSensorAngle = function (gyroSensor) {}
/**
* Pauses for a period of time.
@@ -333,8 +300,7 @@ var gyroSensorAngle = function(gyroSensor) {
* @param {number} time - The time to wait, in milliseconds.
* @alias ev3_pause
*/
-var pause = function(time) {
-};
+var pause = function (time) {}
/**
* Returns a hello world message.
@@ -342,7 +308,7 @@ var pause = function(time) {
* @returns {string} A hello world message.
* @alias ev3_hello
*/
-var hello = function() {};
+var hello = function () {}
/**
* Waits for one of the buttons on the EV3's control face to be pressed, then
@@ -358,7 +324,7 @@ var hello = function() {};
* @returns {number} A number corresponding to the button that was pressed
* @alias ev3_waitForButtonPress
*/
-var waitForButtonPress = function() {};
+var waitForButtonPress = function () {}
/**
* Makes the robot speak the given words through its speaker. Returns after the
@@ -367,7 +333,7 @@ var waitForButtonPress = function() {};
* @param {string} words - The words to speak.
* @alias ev3_speak
*/
-var speak = function(words) {};
+var speak = function (words) {}
/**
* Causes the robot to emit a sequence of beeps. Returns after the beeps are
@@ -381,7 +347,7 @@ var speak = function(words) {};
* @param {Array} beeps - The beep sequence.
* @alias ev3_playSequence
*/
-var playSequence = function(beeps) {};
+var playSequence = function (beeps) {}
/**
* Gets the left green LED.
@@ -393,7 +359,7 @@ var playSequence = function(beeps) {};
* @returns {peripheral} The left green LED
* @alias ev3_ledLeftGreen
*/
-var ledLeftGreen = function() {};
+var ledLeftGreen = function () {}
/**
* Gets the left red LED.
@@ -405,7 +371,7 @@ var ledLeftGreen = function() {};
* @returns {peripheral} The left red LED
* @alias ev3_ledLeftRed
*/
-var ledLeftRed = function() {};
+var ledLeftRed = function () {}
/**
* Gets the right green LED.
@@ -417,7 +383,7 @@ var ledLeftRed = function() {};
* @returns {peripheral} The right green LED
* @alias ev3_ledRightGreen
*/
-var ledRightGreen = function() {};
+var ledRightGreen = function () {}
/**
* Gets the right red LED.
@@ -429,7 +395,7 @@ var ledRightGreen = function() {};
* @returns {peripheral} The right red LED
* @alias ev3_ledRightRed
*/
-var ledRightRed = function() {};
+var ledRightRed = function () {}
/**
* Gets the brightness of the given LED.
@@ -440,7 +406,7 @@ var ledRightRed = function() {};
* @returns {number} The brightness of the given LED
* @alias ev3_ledGetBrightness
*/
-var ledGetBrightness = function (led) {};
+var ledGetBrightness = function (led) {}
/**
* Sets the brightness of the given LED.
@@ -451,4 +417,4 @@ var ledGetBrightness = function (led) {};
* @param {number} brightness - The desired brightness
* @alias ev3_ledSetBrightness
*/
-var ledSetBrightness = function (led, brightness) {};
+var ledSetBrightness = function (led, brightness) {}
diff --git a/docs/lib/list.js b/docs/lib/list.js
index 68be4f23c..dfeac7993 100644
--- a/docs/lib/list.js
+++ b/docs/lib/list.js
@@ -8,7 +8,7 @@
* @returns {pair} pair with x as head and y as tail.
*/
function pair(x, y) {}
-
+
/**
* **primitive**; returns true if x is a
* pair and false otherwise; time: Theta(1)Theta(1).
@@ -23,7 +23,7 @@ function is_pair(x) {}
* @returns {value} head of p
*/
function head(p) {}
-
+
/**
* **primitive**; returns tail (second component of given pair p; time: Theta(1)Theta(1).
* @param {pair} p - given pair
@@ -38,13 +38,13 @@ function tail(p) {}
* @returns {boolean} whether x is null
*/
function is_null(x) {}
-
+
/**
* **primitive**; returns true if
* xs is a list as defined in the textbook, and
- * false otherwise. Iterative process;
+ * false otherwise. Iterative process;
* time: Theta(n), space: Theta(1), where n
- * is the length of the
+ * is the length of the
* chain of tail operations that can be applied to xs.
* is_list recurses down the list and checks that it ends with the empty list null
* @param {value} xs - given candidate
@@ -58,7 +58,7 @@ function is_list(xs) {}
* @param {value} value1,value2,...,value_n - given values
* @returns {list} list containing all values
*/
-function list(value1, value2, ...values ) {}
+function list(value1, value2, ...values) {}
/**
* visualizes the arguments in a separate drawing
@@ -68,14 +68,14 @@ function list(value1, value2, ...values ) {}
* @param {value} value1,value2,...,value_n - given values
* @returns {value} given x
*/
- function draw_data(value1, value2, ...values ) {}
+function draw_data(value1, value2, ...values) {}
/**
* Returns true if both
* have the same structure with respect to pair,
- * and identical values at corresponding leave positions (places that are not
+ * and identical values at corresponding leave positions (places that are not
* themselves pairs), and false otherwise. For the "identical",
- * the values need to have the same type, otherwise the result is
+ * the values need to have the same type, otherwise the result is
* false. If corresponding leaves are boolean values, these values
* need to be the same. If both are undefined or both are
* null, the result is true. Otherwise they are compared
@@ -89,61 +89,56 @@ function list(value1, value2, ...values ) {}
* @returns {boolean} whether x is structurally equal to y
*/
function equal(xs, ys) {
- return is_pair(xs)
- ? (is_pair(ys) &&
- equal(head(xs), head(ys)) &&
- equal(tail(xs), tail(ys)))
- : is_null(xs)
- ? is_null(ys)
- : is_number(xs)
- ? (is_number(ys) && xs === ys)
+ return is_pair(xs)
+ ? is_pair(ys) && equal(head(xs), head(ys)) && equal(tail(xs), tail(ys))
+ : is_null(xs)
+ ? is_null(ys)
+ : is_number(xs)
+ ? is_number(ys) && xs === ys
: is_boolean(xs)
- ? (is_boolean(ys) && ((xs && ys) || (!xs && !ys)))
- : is_string(xs)
- ? (is_string(ys) && xs === ys)
- : is_undefined(xs)
- ? is_undefined(ys)
- : // we know now that xs is a function
- (is_function(ys) && xs === ys);
+ ? is_boolean(ys) && ((xs && ys) || (!xs && !ys))
+ : is_string(xs)
+ ? is_string(ys) && xs === ys
+ : is_undefined(xs)
+ ? is_undefined(ys)
+ : // we know now that xs is a function
+ is_function(ys) && xs === ys
}
/**
* Returns the length of the list
- * xs.
+ * xs.
* Iterative process; time: Theta(n), space:
* Theta(1), where n is the length of xs.
* @param {list} xs - given list
* @returns {number} length of xs
*/
function length(xs) {
- return $length(xs, 0);
+ return $length(xs, 0)
}
function $length(xs, acc) {
- return is_null(xs) ? acc : $length(tail(xs), acc + 1);
+ return is_null(xs) ? acc : $length(tail(xs), acc + 1)
}
/**
* Returns a list that results from list
- * xs by element-wise application of unary function f.
+ * xs by element-wise application of unary function f.
* Iterative process; time: Theta(n) (apart from f),
* space: Theta(n) (apart from f), where n is the length of xs.
* f is applied element-by-element:
* map(f, list(1, 2)) results in list(f(1), f(2)).
- * @param {function} f - unary
+ * @param {function} f - unary
* @param {list} xs - given list
* @returns {list} result of mapping
*/
function map(f, xs) {
- return $map(f, xs, null);
+ return $map(f, xs, null)
}
function $map(f, xs, acc) {
- return is_null(xs)
- ? reverse(acc)
- : $map(f, tail(xs), pair(f(head(xs)), acc));
+ return is_null(xs) ? reverse(acc) : $map(f, tail(xs), pair(f(head(xs)), acc))
}
-
-/**
+/**
* Makes a list with n
* elements by applying the unary function f
* to the numbers 0 to n - 1, assumed to be a nonnegative integer.
@@ -153,10 +148,10 @@ function $map(f, xs, acc) {
* @returns {list} resulting list
*/
function build_list(fun, n) {
- return $build_list(n - 1, fun, null);
+ return $build_list(n - 1, fun, null)
}
function $build_list(i, fun, already_built) {
- return i < 0 ? already_built : $build_list(i - 1, fun, pair(fun(i), already_built));
+ return i < 0 ? already_built : $build_list(i - 1, fun, pair(fun(i), already_built))
}
/**
@@ -167,21 +162,20 @@ function $build_list(i, fun, already_built) {
* f is applied element-by-element:
* for_each(fun, list(1, 2)) results in the calls
* fun(1) and fun(2).
- * @param {function} f - unary
+ * @param {function} f - unary
* @param {list} xs - given list
* @returns {boolean} true
*/
function for_each(fun, xs) {
if (is_null(xs)) {
- return true;
+ return true
} else {
- fun(head(xs));
- return for_each(fun, tail(xs));
+ fun(head(xs))
+ return for_each(fun, tail(xs))
}
}
-
/**
* Returns a string that represents
* list xs using the text-based box-and-pointer notation
@@ -193,18 +187,16 @@ function for_each(fun, xs) {
* @returns {string} xs converted to string
*/
function list_to_string(xs) {
- return $list_to_string(xs, x => x);
+ return $list_to_string(xs, x => x)
}
function $list_to_string(xs, cont) {
- return is_null(xs)
- ? cont("null")
- : is_pair(xs)
- ? $list_to_string(
- head(xs),
- x => $list_to_string(
- tail(xs),
- y => cont("[" + x + "," + y + "]")))
- : cont(stringify(xs));
+ return is_null(xs)
+ ? cont('null')
+ : is_pair(xs)
+ ? $list_to_string(head(xs), x =>
+ $list_to_string(tail(xs), y => cont('[' + x + ',' + y + ']'))
+ )
+ : cont(stringify(xs))
}
/**
@@ -217,16 +209,14 @@ function $list_to_string(xs, cont) {
* @returns {list} xs in reverse
*/
function reverse(xs) {
- return $reverse(xs, null);
+ return $reverse(xs, null)
}
function $reverse(original, reversed) {
- return is_null(original)
- ? reversed
- : $reverse(tail(original), pair(head(original), reversed));
+ return is_null(original) ? reversed : $reverse(tail(original), pair(head(original), reversed))
}
/**
- * Returns a list that results from
+ * Returns a list that results from
* appending the list ys to the list xs.
* Iterative process; time: Theta(n), space:
* Theta(n), where n is the length of xs.
@@ -238,12 +228,10 @@ function $reverse(original, reversed) {
* @returns {list} result of appending xs and ys
*/
function append(xs, ys) {
- return $append(xs, ys, xs => xs);
+ return $append(xs, ys, xs => xs)
}
function $append(xs, ys, cont) {
- return is_null(xs)
- ? cont(ys)
- : $append(tail(xs), ys, zs => cont(pair(head(xs), zs)));
+ return is_null(xs) ? cont(ys) : $append(tail(xs), ys, zs => cont(pair(head(xs), zs)))
}
/**
@@ -258,11 +246,7 @@ function $append(xs, ys, cont) {
* @returns {list} postfix sublist that starts with v
*/
function member(v, xs) {
- return is_null(xs)
- ? null
- : (v === head(xs))
- ? xs
- : member(v, tail(xs));
+ return is_null(xs) ? null : v === head(xs) ? xs : member(v, tail(xs))
}
/** Returns a list that results from
@@ -277,14 +261,14 @@ function member(v, xs) {
* @returns {list} xs with first occurrence of v removed
*/
function remove(v, xs) {
- return $remove(v, xs, null);
+ return $remove(v, xs, null)
}
function $remove(v, xs, acc) {
return is_null(xs)
- ? append(reverse(acc), xs)
- : v === head(xs)
- ? append(reverse(acc), tail(xs))
- : $remove(v, tail(xs), pair(head(xs), acc));
+ ? append(reverse(acc), xs)
+ : v === head(xs)
+ ? append(reverse(acc), tail(xs))
+ : $remove(v, tail(xs), pair(head(xs), acc))
}
/**
@@ -292,7 +276,7 @@ function $remove(v, xs, acc) {
* xs by removing all items from xs that
* are identical (===) to v.
* Returns the original
- * list if there is no occurrence.
+ * list if there is no occurrence.
* Iterative process;
* time: Theta(n), space: Theta(n), where n
* is the length of xs.
@@ -301,14 +285,14 @@ function $remove(v, xs, acc) {
* @returns {list} xs with all occurrences of v removed
*/
function remove_all(v, xs) {
- return $remove_all(v, xs, null);
+ return $remove_all(v, xs, null)
}
function $remove_all(v, xs, acc) {
return is_null(xs)
- ? append(reverse(acc), xs)
- : v === head(xs)
- ? $remove_all(v, tail(xs), acc)
- : $remove_all(v, tail(xs), pair(head(xs), acc));
+ ? append(reverse(acc), xs)
+ : v === head(xs)
+ ? $remove_all(v, tail(xs), acc)
+ : $remove_all(v, tail(xs), pair(head(xs), acc))
}
/**
@@ -324,14 +308,14 @@ function $remove_all(v, xs, acc) {
* @returns {list} list with those elements of xs for which pred holds.
*/
function filter(pred, xs) {
- return $filter(pred, xs, null);
+ return $filter(pred, xs, null)
}
function $filter(pred, xs, acc) {
return is_null(xs)
? reverse(acc)
: pred(head(xs))
- ? $filter(pred, tail(xs), pair(head(xs), acc))
- : $filter(pred, tail(xs), acc);
+ ? $filter(pred, tail(xs), pair(head(xs), acc))
+ : $filter(pred, tail(xs), acc)
}
/**
@@ -346,17 +330,15 @@ function $filter(pred, xs, acc) {
* @returns {list} list from start to end
*/
function enum_list(start, end) {
- return $enum_list(start, end, null);
+ return $enum_list(start, end, null)
}
function $enum_list(start, end, acc) {
- return start > end
- ? reverse(acc)
- : $enum_list(start + 1, end, pair(start, acc));
+ return start > end ? reverse(acc) : $enum_list(start + 1, end, pair(start, acc))
}
-/**
+/**
* Returns the element
- * of list xs at position n,
+ * of list xs at position n,
* where the first element has index 0.
* Iterative process;
* time: Theta(n), space: Theta(1),
@@ -366,16 +348,14 @@ function $enum_list(start, end, acc) {
* @returns {value} item in xs at position n
*/
function list_ref(xs, n) {
- return n === 0
- ? head(xs)
- : list_ref(tail(xs), n - 1);
+ return n === 0 ? head(xs) : list_ref(tail(xs), n - 1)
}
/** Applies binary
* function f to the elements of xs from
* right-to-left order, first applying f to the last element
* and the value initial, resulting in r1,
- * then to the
+ * then to the
* second-last element and r1, resulting in
* r2,
* etc, and finally
@@ -392,15 +372,12 @@ function list_ref(xs, n) {
* @returns {value} result of accumulating xs using f starting with initial
*/
function accumulate(f, initial, xs) {
- return $accumulate(f, initial, xs, x => x);
+ return $accumulate(f, initial, xs, x => x)
}
function $accumulate(f, initial, xs, cont) {
- return is_null(xs)
- ? cont(initial)
- : $accumulate(f, initial, tail(xs), x => cont(f(head(xs), x)));
+ return is_null(xs) ? cont(initial) : $accumulate(f, initial, tail(xs), x => cont(f(head(xs), x)))
}
-
/**
* Optional second argument.
* Similar to display, but formats well-formed lists nicely if detected;
diff --git a/docs/lib/math.js b/docs/lib/math.js
index 068ec86fd..5696f4bdb 100644
--- a/docs/lib/math.js
+++ b/docs/lib/math.js
@@ -1,30 +1,28 @@
/**
- *
+ *
* The Number value for e, Euler's number,
* which is approximately 2.718281828459045.
* @const {number}
- *
+ *
*/
-const math_E = 2.718281828459045;
-
+const math_E = 2.718281828459045
/**
- *
- * The Number value for the natural logarithm of 10,
+ *
+ * The Number value for the natural logarithm of 10,
* which is approximately 2.302585092994046.
* @const {number}
- *
+ *
*/
-const math_LN10 = 2.302585092994046;
+const math_LN10 = 2.302585092994046
-
-/**
- * The Number value for the natural logarithm of 2,
+/**
+ * The Number value for the natural logarithm of 2,
* which is approximately 0.6931471805599453.
* @const {number}
- *
+ *
*/
-const math_LN2 = 0.6931471805599453;
+const math_LN2 = 0.6931471805599453
/**
* The Number value for the base-10 logarithm of e,
@@ -35,7 +33,7 @@ the base of the natural logarithms; this value is approximately 0.43429448190325
*
* @const {number}
*/
-const math_LOG10E = 1 / math_LN10;
+const math_LOG10E = 1 / math_LN10
/**
* The Number value for the base-2 logarithm of eℝ, the base of the natural logarithms;
@@ -46,7 +44,7 @@ this value is approximately 1.4426950408889634.
*
* @const {number}
*/
-const math_LOG2E = 1 / math_LN2;
+const math_LOG2E = 1 / math_LN2
/**
* The Number value for π, the ratio of the circumference of a circle to its diameter,
@@ -55,149 +53,139 @@ which is approximately 3.1415926535897932.
*
* @const {number}
*/
-const math_PI = 3.1415926535897932;
+const math_PI = 3.1415926535897932
-/**
+/**
* The Number value for the square root of 2, which is approximately 1.4142135623730951.
- *
+ *
* @const {number}
*/
-const math_SQRT2 = 1.4142135623730951;
+const math_SQRT2 = 1.4142135623730951
-/**
+/**
* The Number value for the square root of 0.5, which is approximately 0.7071067811865476.
- *
+ *
* NOTE:
* The value of math_SQRT1_2 is approximately the reciprocal of the value of math_SQRT2.
* @const {number}
*/
-const math_SQRT1_2 = 1 / math_SQRT2;
+const math_SQRT1_2 = 1 / math_SQRT2
/**
*
* computes the absolute value of x; the result has the same magnitude as x but has positive sign.
- *
+ *
* @param {number} x - given number
* @returns {number} absolute value of x
-*/
-function math_abs( x ) {}
+ */
+function math_abs(x) {}
/**
- * computes the arc cosine of x.
+ * computes the arc cosine of x.
* The result is expressed in radians and ranges from +0 to +π.
- *
+ *
* @param {number} x - given number
* @returns {number} arc cosine of x
*/
-function math_acos( x ) {}
+function math_acos(x) {}
-
/**
*
* computes the inverse hyperbolic cosine of x.
- *
+ *
* @param {number} x - given number
* @returns {number} inverse hyperbolic cosine of x.
*/
-function math_acosh( x ) {}
+function math_acosh(x) {}
-
/**
*
* computes the arc sine of x. The result is expressed in radians and ranges from -π / 2 to +π / 2.
- *
+ *
* @param {number} x - given number
* @returns {number} arc sine of x.
*/
-function math_asin( x ) {}
+function math_asin(x) {}
-
/**
*
- * computes the inverse hyperbolic
+ * computes the inverse hyperbolic
* sine of x. The result is expressed in radians and ranges from -π / 2 to +π / 2.
- *
+ *
* @param {number} x - given number
* @returns {number} inverse hyperbolic sine of x
*/
-function math_asinh( x ) {}
+function math_asinh(x) {}
-
/**
*
* computes the arc tangent of x. The result is expressed in radians and ranges from -π / 2 to +π / 2.
- *
+ *
* @param {number} x - given number
* @returns {number} arc tangent of x
*/
-function math_atan( x ) {}
+function math_atan(x) {}
-
/**
*
* computes the inverse hyperbolic tangent of x.
- *
+ *
* @param {number} x - given number
* @returns {number} inverse hyperbolic tangent of x.
*/
-function math_atanh( x ) {}
+function math_atanh(x) {}
-
/**
*
* computes the arc tangent of the quotient y / x of the arguments y and x, where the signs of y and x are used to determine the quadrant of the result. Note that it is intentional and traditional for the two-argument arc tangent function that the argument named y be first and the argument named x be second. The result is expressed in radians and ranges from -π to +π.
- *
+ *
* @param {number} y - given first number
* @param {number} x - given second number
* @returns {number} arc tangent of y / x.
*/
-function math_atan2( y, x ) {}
+function math_atan2(y, x) {}
-
/**
*
* computes the cube root of x.
- *
+ *
* @param {number} x - given number
* @returns {number} cube root of x.
*/
-function math_cbrt( x ) {}
+function math_cbrt(x) {}
-
/**
* computes the smallest (closest to -∞) Number value that is not less than x and is an integer. If x is already an integer, the result is x.
* The value of math_ceil(x) is the same as the value of -math_floor(-x).
* @param {number} x - given number
* @returns {number} "ceiling" of the number
*/
-function math_ceil( x ) {}
+function math_ceil(x) {}
-
/**
* When math_clz32 is called with one argument x, the following steps are taken:
- *
+ *
* Let n be ToUint32(x).
* Let p be the number of leading zero bits in the 32-bit binary representation of n.
* Return p.
*
* NOTE:
- *
If n is 0, p will be 32. If the most significant bit of the 32-bit binary encoding of n is 1,
+ *
If n is 0, p will be 32. If the most significant bit of the 32-bit binary encoding of n is 1,
* p will be 0.
- *
+ *
* @param {number} n - given number
* @returns {number} p - leading zero bits
*/
-function math_clz32( x ) {}
-
+function math_clz32(x) {}
/**
*
- * Computes the cosine of x.
+ * Computes the cosine of x.
* The argument is expressed in radians.
* @param {number} x - given number
* @returns {number} - cosine of x
*/
-function math_cos( x ) {}
+function math_cos(x) {}
/**
*
@@ -207,47 +195,43 @@ function math_cos( x ) {}
* @param { number } x - given number
* @returns {number} hyperbolic cosine of x
*/
-function math_cosh( x ) {}
+function math_cosh(x) {}
-
/**
- * computes the exponential function of x
+ * computes the exponential function of x
* (e raised to the power of x, where e is the base of the natural logarithms).
- *
+ *
* @param { number } x - given number
* @returns {number} e to the power of x
*/
-function math_exp( x ) {}
+function math_exp(x) {}
-
/**
- * computes subtracting 1 from the
- * exponential function of x (e raised to the power of x, where e is the base of
- * the natural logarithms). The result is computed in a way that is accurate even
+ * computes subtracting 1 from the
+ * exponential function of x (e raised to the power of x, where e is the base of
+ * the natural logarithms). The result is computed in a way that is accurate even
* when the value of x is close to 0.
* @param {number} x - given number
* @returns {number} -1 plus e to the power of x
*/
-function math_expm1( x ) {}
+function math_expm1(x) {}
-
/**
- * computes the greatest (closest to +∞) Number value that is not greater than x
- * and is an integer.
+ * computes the greatest (closest to +∞) Number value that is not greater than x
+ * and is an integer.
*
If x is already an integer, the result is x.
- *
+ *
* NOTE:
* The value of math_floor(x) is the same as the value of -math_ceil(-x).
* @param {number} x - given number
* @return {number} floor of x
*/
-function math_floor( x ) {}
+function math_floor(x) {}
-
/**
*
* When math_fround is called with argument x, the following steps are taken:
- *
+ *
* - If
x is NaN, return NaN.
* - If
x is one of +0, -0, +∞, -∞, return x.
* - Let x32 be the result of converting
x to a value in IEEE 754-2008 binary32 format using roundTiesToEven mode.
@@ -256,19 +240,19 @@ function math_floor( x ) {}
* @param {number} x - given number
* @returns {number} fround of x
*/
-function math_fround( x ) {}
+function math_fround(x) {}
/**
- *
+ *
* computes the square root
* of the sum of squares of its arguments.
- *
+ *
*
If no arguments are passed, the result is +0.
* @param {number} value1,value2,... - given numbers
* @returns {number} square root of sum of squares of arguments
*/
-function math_hypot ( value1, value2, ...values ) {}
-
+function math_hypot(value1, value2, ...values) {}
+
/**
*
* When math_imul is called with arguments x and y,
@@ -282,178 +266,167 @@ function math_hypot ( value1, value2, ...values ) {}
* @param {number} x - given second number
* @returns {number} - x imul y
*/
-function math_imul( x, y ) {}
+function math_imul(x, y) {}
-
/**
*
* Computes the natural logarithm of x.
- *
+ *
* @param {number} x - given number
* @returns {number} - natural logarithm of x
*/
-function math_log ( x ) {}
+function math_log(x) {}
-
/**
* computes the natural logarithm of 1 + x. The result is computed in a way that is accurate even when the value of x is close to zero.
* @param {number} x - given number
* @returns {number} math_log(1 + x)
*/
-function math_log1p( x ) {}
+function math_log1p(x) {}
-
/**
*
* computes the base 10 logarithm of x.
* @param {number} x - given number
* @returns {number} base 10 logarithm of x
*/
-function math_log10( x ) {}
+function math_log10(x) {}
-
/**
*
* computes the base 2 logarithm of x.
- *
+ *
* @param {number} x - given number
* @returns {number} base 2 logarithm of x
*/
-function math_log2( x ) {}
+function math_log2(x) {}
-
/**
*
* Given zero or more numbers, returns the largest of them.
- *
+ *
*
If no arguments are given, the result is -∞.
*
If any value is NaN, the result is NaN.
- * The comparison of values to determine the largest value is done using the
+ * The comparison of values to determine the largest value is done using the
* Abstract Relational Comparison algorithm except that +0 is considered to be larger than -0.
* @param {number} value1,value2,... - given numbers
* @returns {number} largest of them
*/
-function math_max( value1, value2, ...values ) {}
-
+function math_max(value1, value2, ...values) {}
+
/**
*
* Given zero or more arguments, returns the smallest of them.
- *
+ *
*
If no arguments are given, the result is +∞.
*
If any value is NaN, the result is NaN.
- * The comparison of values to determine the smallest value is done using the
+ * The comparison of values to determine the smallest value is done using the
* Abstract Relational Comparison algorithm except that +0 is considered to be larger than -0.
* @param {number} value1,value2,... - given numbers
* @returns {number} smallest of them
*/
-function math_min( value1, value2, ...values ) {}
-
+function math_min(value1, value2, ...values) {}
+
/**
*
- * Computes the result of raising base to
+ * Computes the result of raising base to
* the power of exponent.
- *
+ *
* @param {number} base - the given base
* @param {number} exponent - the given exponent
* @returns {number} base to the power of exponent
**/
-function math_pow( base, exponent ) {}
+function math_pow(base, exponent) {}
- /**
- * Returns a number value with positive sign, greater than or equal to 0 but less than 1,
- * chosen randomly or pseudo randomly with approximately uniform distribution over that
+/**
+ * Returns a number value with positive sign, greater than or equal to 0 but less than 1,
+ * chosen randomly or pseudo randomly with approximately uniform distribution over that
* range, using an implementation-dependent algorithm or strategy. This function takes no arguments.
- *
- * Each math_random function created for distinct realms must produce a distinct sequence
+ *
+ * Each math_random function created for distinct realms must produce a distinct sequence
* of values from successive calls.
* @returns {number} random number greater than or equal to 0 but less than 1
*/
-function math_random ( ) {}
-
+function math_random() {}
+
/**
*
- * Returns the number value that is closest to x and is an integer.
- *
If two integers are equally close to x, then the result is the Number value
+ * Returns the number value that is closest to x and is an integer.
+ *
If two integers are equally close to x, then the result is the Number value
* that is closer to +∞. If x is already an integer, the result is x.
- *
+ *
* NOTE 1:
* math_round(3.5) returns 4, but math_round(-3.5) returns -3.
* @param {number} x - the given number
* @returns {number} closest integer to x
*/
-function math_round( x ) {}
+function math_round(x) {}
-
/**
*
* Computes the sign of x, indicating whether x is positive, negative, or zero.
- *
+ *
* @param {number} x - the given number
* @returns {number} the sign (-1, 0 or +1)
*/
-function math_sign( x ) {}
-
+function math_sign(x) {}
+
/**
*
- * Computes the sine of x.
+ * Computes the sine of x.
* The argument is expressed in radians.
* @param {number} x - the given number
* @returns {number} the sine of x
*/
-function math_sin( x ) {}
+function math_sin(x) {}
-
/**
*
* Computes the hyperbolic sine of x.
* NOTE:
* The value of sinh(x) is the same as (exp(x) - exp(-x)) / 2.
- *
+ *
* @param {number} x - the given number
* @returns {number} the hyperbolic sine of x
*/
-function math_sinh( x ) {}
+function math_sinh(x) {}
-
/**
*
* Computes the square root of x.
- *
+ *
* @param {number} x - the given number
* @returns {number} the square root of x
*/
-function math_sqrt( x ) {}
+function math_sqrt(x) {}
-
/**
*
* Computes the tangent of x. The argument is expressed in radians.
- *
+ *
* @param {number} x - the given number
* @returns {number} the tangent of x
*/
-function math_tan( x ) {}
+function math_tan(x) {}
-
/**
*
* Computes the hyperbolic tangent of x.
- *
+ *
* NOTE:
* The value of math_tanh(x) is the same as
* (exp(x) - exp(-x))/(exp(x) + exp(-x)).
- *
+ *
* @param {number} x - the given number
* @returns {number} the hyperbolic tangent of x
*/
-function math_tanh( x ) {}
+function math_tanh(x) {}
-
/**
*
* Computes the integral part of the number x,
- * removing any fractional digits.
+ * removing any fractional digits.
* @param {number} x - the given number
* @returns {number} the integral part of x
*/
-function math_trunc( x ) {}
+function math_trunc(x) {}
diff --git a/docs/lib/mce.js b/docs/lib/mce.js
index cedc31a97..6c28f88f9 100644
--- a/docs/lib/mce.js
+++ b/docs/lib/mce.js
@@ -1,8 +1,8 @@
/**
* returns the parse tree that results from parsing
* the string str as a Source program. The format
- * of the parse tree is described in chapter 4 of
- * the textbook
+ * of the parse tree is described in chapter 4 of
+ * the textbook
* in Structure and
* Interpretation of Computer Programs, JavaScript Adaptation (SICP).
* @param {string} x - given program as a string
@@ -28,4 +28,3 @@ function tokenize(str) {}
* @returns {whatever} whatever f returns
*/
function apply_in_underlying_javascript(f, xs) {}
-
diff --git a/docs/lib/misc.js b/docs/lib/misc.js
index d18c29377..73f8c1f56 100644
--- a/docs/lib/misc.js
+++ b/docs/lib/misc.js
@@ -4,16 +4,14 @@
* @param {value} v to be checked
* @returns {boolean} indicating whether the value is a number
*/
-function is_number(v) {
-}
+function is_number(v) {}
/**
* checks whether a given value is a boolean
* @param {value} v to be checked
* @returns {boolean} indicating whether the value is a boolean
*/
-function is_boolean(v) {
-}
+function is_boolean(v) {}
/**
* checks whether a given value is a string.
@@ -21,24 +19,21 @@ function is_boolean(v) {
* @param {value} v to be checked
* @returns {boolean} indicating whether the value is a string
*/
-function is_string(v) {
-}
+function is_string(v) {}
/**
* checks whether a given value is a function
* @param {value} v to be checked
* @returns {boolean} indicating whether the value is a function
*/
-function is_function(v) {
-}
+function is_function(v) {}
/**
* checks whether a given value is the special value undefined
* @param {value} v to be checked
* @returns {boolean} indicating whether the value is undefined
*/
-function is_undefined(v) {
-}
+function is_undefined(v) {}
/**
* Returns number of milliseconds elapsed since January 1, 1970 00:00:00 UTC.
@@ -68,7 +63,7 @@ function parse_int(s, i) {}
* See also textbook explanation in section 4.1.1.
* @const {undefined}
*/
-const undefined = (() => {})();
+const undefined = (() => {})()
/**
* The name NaN refers to the special number value NaN ("not a number"). Note that
@@ -76,14 +71,14 @@ const undefined = (() => {})();
* See ECMAScript Specification, Section 4.3.24
* @const {number}
*/
-const NaN = 0 / 0;
+const NaN = 0 / 0
/**
* The name Infinity refers to the special number value Infinity.
* See ECMAScript Specification, Section 4.3.23
* @const {number}
*/
-const Infinity = 1 / 0;
+const Infinity = 1 / 0
/**
* Pops up a window that displays the string s, provides
@@ -95,8 +90,7 @@ const Infinity = 1 / 0;
* @param {string} s to be displayed in popup
* @returns {string} entered text
*/
-function prompt(s) {
-}
+function prompt(s) {}
/**
* Optional second argument. If present,
@@ -112,8 +106,7 @@ function prompt(s) {
* @param {string} s to be displayed, preceding v, optional argument
* @returns {value} v, the first argument value
*/
-function display(v, s) {
-}
+function display(v, s) {}
/**
* Optional second argument.
@@ -131,8 +124,7 @@ function display(v, s) {
* @param {value} v to be displayed
* @param {string} s to be displayed, preceding v
*/
-function error(v, s) {
-}
+function error(v, s) {}
/**
* returns a string that represents the value v, using a
@@ -143,8 +135,7 @@ function error(v, s) {
* @param {value} v the argument value
* @returns {string} string representation of v
*/
-function stringify(v) {
-}
+function stringify(v) {}
/**
* Takes a string s as first argument and a nonnegative integer
@@ -165,5 +156,4 @@ function char_at(s, i) {}
* @param {function} f - given function
* @returns {number} number of parameters f expects
*/
- function arity(f) {
- }
+function arity(f) {}
diff --git a/docs/lib/parsetreetypes.js b/docs/lib/parsetreetypes.js
index acedfabc0..3d08a2827 100644
--- a/docs/lib/parsetreetypes.js
+++ b/docs/lib/parsetreetypes.js
@@ -4,7 +4,7 @@
// that is generated by the parse function in Source 4.
// Program
-type Program = Pair<"sequence", Pair, null>>;
+type Program = Pair<'sequence', Pair, null>>
// Statement
type Statement =
@@ -18,37 +18,40 @@ type Statement =
| BreakStatement
| ContinueStatement
| Block
- | Expression;
+ | Expression
-type ConstantDeclaration = Pair<"constant_declaration",
- Pair>>;
-type FunctionDeclaration = Pair<"function_declaration",
- Pair>>>;
-type ReturnStatement = Pair<"return_statement", Pair>;
-type WhileLoop = Pair<"while_loop", Pair>>;
-type ForLoop = Pair<"for_loop", Pair>>>>;
-type BreakStatement = Pair<"break_statement", null>;
-type ContinueStatement = Pair<"continue_statement", null>;
+type ConstantDeclaration = Pair<'constant_declaration', Pair>>
+type FunctionDeclaration = Pair<
+ 'function_declaration',
+ Pair>>
+>
+type ReturnStatement = Pair<'return_statement', Pair>
+type WhileLoop = Pair<'while_loop', Pair>>
+type ForLoop = Pair<
+ 'for_loop',
+ Pair>>>
+>
+type BreakStatement = Pair<'break_statement', null>
+type ContinueStatement = Pair<'continue_statement', null>
// Parameters
-type Parameters = List;
+type Parameters = List
// If-Statement
-type ConditionalStatement = Pair<"conditional_statement", Pair>>>;
+type ConditionalStatement = Pair<
+ 'conditional_statement',
+ Pair>>
+>
// Block
-type Block = Pair<"block", Pair>;
+type Block = Pair<'block', Pair>
// Let
-type VariableDeclaration = Pair<"variable_declaration",
- Pair>>;
+type VariableDeclaration = Pair<'variable_declaration', Pair>>
// Assignment
-type Assignment = Pair<"assignment", Pair>>;
-type ObjectAssignment = Pair<"object_assignment",
- Pair>>;
+type Assignment = Pair<'assignment', Pair>>
+type ObjectAssignment = Pair<'object_assignment', Pair>>
// Expression
type Expression =
@@ -63,29 +66,34 @@ type Expression =
| Assignment
| ObjectAssignment
| ObjectAccess
- | ArrayExpression;
+ | ArrayExpression
-type Literal = Pair<"literal", Pair>;
-type Name = Pair<"name", Pair>;
- type LogicalComposition = Pair<"logical_composition", Pair>>>;
-type BinaryOperatorCombination = Pair<"binary_operator_combination",
- Pair>>>;
-type UnaryOperatorCombination = Pair<"unary_operator_combination",
- Pair>>;
-type Application = Pair<"application", Pair, null>>>;
-type LambdaExpression = Pair<"lambda_expression", Pair>>;
-type ConditionalExpression = Pair<"conditional_expression", Pair>>>;
-type ObjectAccess = Pair<"object_access", Pair>>;
-type ArrayExpression = Pair<"array_expression", Pair, null>>;
+type Literal = Pair<'literal', Pair>
+type Name = Pair<'name', Pair>
+type LogicalComposition = Pair<
+ 'logical_composition',
+ Pair>>
+>
+type BinaryOperatorCombination = Pair<
+ 'binary_operator_combination',
+ Pair>>
+>
+type UnaryOperatorCombination = Pair<
+ 'unary_operator_combination',
+ Pair>
+>
+type Application = Pair<'application', Pair, null>>>
+type LambdaExpression = Pair<'lambda_expression', Pair>>
+type ConditionalExpression = Pair<
+ 'conditional_expression',
+ Pair>>
+>
+type ObjectAccess = Pair<'object_access', Pair>>
+type ArrayExpression = Pair<'array_expression', Pair, null>>
// Operators
-type LogicalOperator = "&&" | "||";
-type BinaryOperator = "+" | "-" | "*" | "/" | "%" | "==="
- | "!==" | "<" | ">" | "<=" | ">=";
-type UnaryOperator = "!" | "-unary";
+type LogicalOperator = '&&' | '||'
+type BinaryOperator = '+' | '-' | '*' | '/' | '%' | '===' | '!==' | '<' | '>' | '<=' | '>='
+type UnaryOperator = '!' | '-unary'
// \end{lstlisting} // \texttt{parsetreetypes.js END}
diff --git a/docs/lib/stream.js b/docs/lib/stream.js
index c627f4318..25e45d6e1 100644
--- a/docs/lib/stream.js
+++ b/docs/lib/stream.js
@@ -6,30 +6,31 @@
/**
* assumes that the tail (second component) of the
* pair {x} is a nullary function, and returns the result of
- * applying that function. Throws an exception if the argument
+ * applying that function. Throws an exception if the argument
* is not a pair, or if the tail is not a function.
- * Laziness: Yes: {stream_tail} only forces the direct tail
- * stream, but not the rest of the stream, i.e. not the tail
+ * Laziness: Yes: {stream_tail} only forces the direct tail
+ * stream, but not the rest of the stream, i.e. not the tail
* of the tail, etc.
* @param {Stream} xs - given stream
* @returns {Stream} result stream (if stream discipline is used)
*/
function stream_tail(xs) {
- if (is_pair(xs)) {
- const the_tail = tail(xs);
- if (is_function(the_tail)) {
- return the_tail();
- } else {
- error(the_tail,
- 'stream_tail(xs) expects a function as ' +
- 'the tail of the argument pair xs, ' +
- 'but encountered ');
- }
+ if (is_pair(xs)) {
+ const the_tail = tail(xs)
+ if (is_function(the_tail)) {
+ return the_tail()
} else {
- error(xs, 'stream_tail(xs) expects a pair as ' +
- 'argument xs, but encountered ');
+ error(
+ the_tail,
+ 'stream_tail(xs) expects a function as ' +
+ 'the tail of the argument pair xs, ' +
+ 'but encountered '
+ )
}
+ } else {
+ error(xs, 'stream_tail(xs) expects a pair as ' + 'argument xs, but encountered ')
+ }
}
/**
@@ -43,51 +44,43 @@ function stream_tail(xs) {
*/
function is_stream(xs) {
- return is_null(xs) ||
- (is_pair(xs) &&
- is_function(tail(xs)) &&
- arity(tail(xs)) === 0 &&
- is_stream(stream_tail(xs)));
+ return (
+ is_null(xs) ||
+ (is_pair(xs) && is_function(tail(xs)) && arity(tail(xs)) === 0 && is_stream(stream_tail(xs)))
+ )
}
/**
* Given list xs, returns a stream of same length with
* the same elements as xs in the same order.
- * Laziness: Yes: list_to_stream
- * goes down the list only when forced.
+ * Laziness: Yes: list_to_stream
+ * goes down the list only when forced.
* @param {list} xs - given list
* @returns {stream} stream containing all elements of xs
*/
function list_to_stream(xs) {
- return is_null(xs)
- ? null
- : pair(head(xs),
- () => list_to_stream(tail(xs)));
+ return is_null(xs) ? null : pair(head(xs), () => list_to_stream(tail(xs)))
}
/**
* Given stream xs, returns a list of same length with
* the same elements as xs in the same order.
- * Laziness: No: stream_to_list needs to force the whole
+ * Laziness: No: stream_to_list needs to force the whole
* stream.
* @param {stream} xs - stream
* @returns {list} containing all elements of xs
*/
function stream_to_list(xs) {
- return is_null(xs)
- ? null
- : pair(head(xs), stream_to_list(stream_tail(xs)));
+ return is_null(xs) ? null : pair(head(xs), stream_to_list(stream_tail(xs)))
}
-
-
/**
* Given n values, returns a stream of length n.
* The elements of the stream are the given values in the given order.
* Lazy? No: A
- * complete list is generated,
+ * complete list is generated,
* and then a stream using list_to_stream is generated from it.
* @param {value} value1,value2,...,value_n - given values
* @returns {stream} stream containing all values
@@ -103,40 +96,35 @@ function stream() {
/**
* Returns the length of the stream
- * xs.
+ * xs.
* Iterative process.
- * Lazy? No: The function needs to explore the whole stream
+ * Lazy? No: The function needs to explore the whole stream
* @param {stream} xs - given stream
* @returns {number} length of xs
*/
function stream_length(xs) {
- return is_null(xs)
- ? 0
- : 1 + stream_length(stream_tail(xs));
+ return is_null(xs) ? 0 : 1 + stream_length(stream_tail(xs))
}
/**
* Returns a stream that results from stream
- * xs by element-wise application
- * of unary function f.
+ * xs by element-wise application
+ * of unary function f.
* f is applied element-by-element:
* stream_map(f, stream(1,2)) results in
* the same as stream(f(1),f(2)).
* Lazy? Yes: The argument stream is only explored as forced by
* the result stream.
- * @param {function} f - unary
+ * @param {function} f - unary
* @param {stream} xs - given stream
* @returns {stream} result of mapping
*/
function stream_map(f, s) {
- return is_null(s)
- ? null
- : pair(f(head(s)),
- () => stream_map(f, stream_tail(s)));
+ return is_null(s) ? null : pair(f(head(s)), () => stream_map(f, stream_tail(s)))
}
-/**
+/**
* Makes a stream with n
* elements by applying the unary function f
* to the numbers 0 to n - 1, assumed to be a nonnegative integer.
@@ -148,16 +136,12 @@ function stream_map(f, s) {
*/
function build_stream(fun, n) {
- function build(i) {
- return i >= n
- ? null
- : pair(fun(i),
- () => build(i + 1));
- }
- return build(0);
+ function build(i) {
+ return i >= n ? null : pair(fun(i), () => build(i + 1))
+ }
+ return build(0)
}
-
/**
* Applies unary function f to every
* element of the stream xs.
@@ -165,20 +149,20 @@ function build_stream(fun, n) {
* f is applied element-by-element:
* stream_for_each(f, stream(1, 2)) results in the calls
* f(1) and f(2).
- * Lazy? No: stream_for_each
+ * Lazy? No: stream_for_each
* forces the exploration of the entire stream
- * @param {function} f - unary
+ * @param {function} f - unary
* @param {stream} xs - given stream
* @returns {boolean} true
*/
function stream_for_each(fun, xs) {
- if (is_null(xs)) {
- return true;
- } else {
- fun(head(xs));
- return stream_for_each(fun, stream_tail(xs));
- }
+ if (is_null(xs)) {
+ return true
+ } else {
+ fun(head(xs))
+ return stream_for_each(fun, stream_tail(xs))
+ }
}
/**
@@ -186,24 +170,26 @@ function stream_for_each(fun, xs) {
* order. Iterative process.
* The process is iterative, but consumes space Omega(n)
* because of the result stream.
- * Lazy? No: stream_reverse
+ * Lazy? No: stream_reverse
* forces the exploration of the entire stream
* @param {stream} xs - given stream
* @returns {stream} xs in reverse
*/
function stream_reverse(xs) {
- function rev(original, reversed) {
- return is_null(original)
- ? reversed
- : rev(stream_tail(original),
- pair(head(original), () => reversed));
- }
- return rev(xs, null);
+ function rev(original, reversed) {
+ return is_null(original)
+ ? reversed
+ : rev(
+ stream_tail(original),
+ pair(head(original), () => reversed)
+ )
+ }
+ return rev(xs, null)
}
/**
- * Returns a stream that results from
+ * Returns a stream that results from
* appending the stream ys to the stream xs.
* In the result, null at the end of the first argument stream
* is replaced by the second argument, regardless what the second
@@ -215,10 +201,7 @@ function stream_reverse(xs) {
*/
function stream_append(xs, ys) {
- return is_null(xs)
- ? ys
- : pair(head(xs),
- () => stream_append(stream_tail(xs), ys));
+ return is_null(xs) ? ys : pair(head(xs), () => stream_append(stream_tail(xs), ys))
}
/**
@@ -227,8 +210,8 @@ function stream_append(xs, ys) {
* v (using ===); returns null if the
* element does not occur in the stream.
* Iterative process.
- * Lazy? Sort-of: stream_member
- * forces the stream only until the element
+ * Lazy? Sort-of: stream_member
+ * forces the stream only until the element
* is found.
* @param {value} v - given value
* @param {stream} xs - given stream
@@ -236,18 +219,14 @@ function stream_append(xs, ys) {
*/
function stream_member(x, s) {
- return is_null(s)
- ? null
- : head(s) === x
- ? s
- : stream_member(x, stream_tail(s));
+ return is_null(s) ? null : head(s) === x ? s : stream_member(x, stream_tail(s))
}
/** Returns a stream that results from
* xs by removing the first item from xs that
* is identical (===) to v.
* Returns the original
- * stream if there is no occurrence.
+ * stream if there is no occurrence.
* Lazy? Yes: the result stream forces the construction of each next element
* @param {value} v - given value
* @param {stream} xs - given stream
@@ -255,12 +234,11 @@ function stream_member(x, s) {
*/
function stream_remove(v, xs) {
- return is_null(xs)
- ? null
- : v === head(xs)
- ? stream_tail(xs)
- : pair(head(xs),
- () => stream_remove(v, stream_tail(xs)));
+ return is_null(xs)
+ ? null
+ : v === head(xs)
+ ? stream_tail(xs)
+ : pair(head(xs), () => stream_remove(v, stream_tail(xs)))
}
/**
@@ -268,21 +246,21 @@ function stream_remove(v, xs) {
* xs by removing all items from xs that
* are identical (===) to v.
* Returns the original
- * stream if there is no occurrence.
+ * stream if there is no occurrence.
* Recursive process.
- * Lazy? Yes: the result stream forces the construction of each next
- * element
+ * Lazy? Yes: the result stream forces the construction of each next
+ * element
* @param {value} v - given value
* @param {stream} xs - given stream
* @returns {stream} xs with all occurrences of v removed
*/
function stream_remove_all(v, xs) {
- return is_null(xs)
- ? null
- : v === head(xs)
- ? stream_remove_all(v, stream_tail(xs))
- : pair(head(xs), () => stream_remove_all(v, stream_tail(xs)));
+ return is_null(xs)
+ ? null
+ : v === head(xs)
+ ? stream_remove_all(v, stream_tail(xs))
+ : pair(head(xs), () => stream_remove_all(v, stream_tail(xs)))
}
/**
@@ -301,12 +279,11 @@ function stream_remove_all(v, xs) {
*/
function stream_filter(p, s) {
- return is_null(s)
- ? null
- : p(head(s))
- ? pair(head(s),
- () => stream_filter(p, stream_tail(s)))
- : stream_filter(p, stream_tail(s));
+ return is_null(s)
+ ? null
+ : p(head(s))
+ ? pair(head(s), () => stream_filter(p, stream_tail(s)))
+ : stream_filter(p, stream_tail(s))
}
/**
@@ -321,14 +298,11 @@ function stream_filter(p, s) {
*/
function enum_stream(start, end) {
- return start > end
- ? null
- : pair(start,
- () => enum_stream(start + 1, end));
+ return start > end ? null : pair(start, () => enum_stream(start + 1, end))
}
/**
- * Returns infinite stream if integers starting
+ * Returns infinite stream if integers starting
* at given number n using a step size of 1.
* Lazy? Yes: The result stream forces the construction of
* each next element
@@ -337,8 +311,7 @@ function enum_stream(start, end) {
*/
function integers_from(n) {
- return pair(n,
- () => integers_from(n + 1));
+ return pair(n, () => integers_from(n + 1))
}
/**
@@ -353,20 +326,15 @@ function integers_from(n) {
*/
function eval_stream(s, n) {
- function es(s, n) {
- return n === 1
- ? list(head(s))
- : pair(head(s),
- es(stream_tail(s), n - 1));
- }
- return n === 0
- ? null
- : es(s, n);
+ function es(s, n) {
+ return n === 1 ? list(head(s)) : pair(head(s), es(stream_tail(s), n - 1))
+ }
+ return n === 0 ? null : es(s, n)
}
-/**
+/**
* Returns the element
- * of stream xs at position n,
+ * of stream xs at position n,
* where the first element has index 0.
* Iterative process.
* Lazy? Sort-of: stream_ref only forces the computation of
@@ -378,9 +346,7 @@ function eval_stream(s, n) {
*/
function stream_ref(s, n) {
- return n === 0
- ? head(s)
- : stream_ref(stream_tail(s), n - 1);
+ return n === 0 ? head(s) : stream_ref(stream_tail(s), n - 1)
}
// \end{lstlisting} // \texttt{stream.js END}
diff --git a/package.json b/package.json
index 6a83ea103..51084069a 100644
--- a/package.json
+++ b/package.json
@@ -61,7 +61,9 @@
"prepare": "husky install"
},
"devDependencies": {
+ "@babel/core": "^7.26.10",
"@babel/preset-env": "^7.23.2",
+ "@types/babel__core": "^7",
"@types/jest": "^29.0.0",
"@types/lodash": "^4.14.202",
"@types/node": "^20.0.0",
diff --git a/scripts/autocomplete.mjs b/scripts/autocomplete.mjs
index 34de8e977..36b923b4b 100644
--- a/scripts/autocomplete.mjs
+++ b/scripts/autocomplete.mjs
@@ -1,36 +1,36 @@
// @ts-check
-import fs from 'fs/promises';
-import pathlib from 'path';
-import { JSDOM } from 'jsdom';
+import fs from 'fs/promises'
+import pathlib from 'path'
+import { JSDOM } from 'jsdom'
-const CONST_DECL = "const";
-const FUNC_DECL = "func";
+const CONST_DECL = 'const'
+const FUNC_DECL = 'func'
-const BASE_DIR = "docs/source"
-const SRC_FILENAME = "global.html"
-const OUT_DIR = "src/editors/ace/docTooltip"
+const BASE_DIR = 'docs/source'
+const SRC_FILENAME = 'global.html'
+const OUT_DIR = 'src/editors/ace/docTooltip'
const TARGETS = [
- "source_1",
- "source_1_wasm",
- "source_1_typed",
- "source_2",
- "source_2_typed",
- "source_3",
- "source_3_concurrent",
- "source_3_typed",
- "source_4",
- "source_4_typed",
- "source_4_explicit-control",
- "External libraries"
+ 'source_1',
+ 'source_1_wasm',
+ 'source_1_typed',
+ 'source_2',
+ 'source_2_typed',
+ 'source_3',
+ 'source_3_concurrent',
+ 'source_3_typed',
+ 'source_4',
+ 'source_4_typed',
+ 'source_4_explicit-control',
+ 'External libraries'
]
function newTitleNode(title, document) {
- const node = document.createElement('h4');
- const text = document.createTextNode(title);
- node.appendChild(text);
- return node;
+ const node = document.createElement('h4')
+ const text = document.createTextNode(title)
+ node.appendChild(text)
+ return node
}
function buildDescriptionHtml(div) {
@@ -38,63 +38,63 @@ function buildDescriptionHtml(div) {
}
function processConstant(namespace, element, document) {
- const header = element.getElementsByTagName('h4')[0];
- const rawName = header.textContent;
+ const header = element.getElementsByTagName('h4')[0]
+ const rawName = header.textContent
const fields = rawName.split(' ').slice(1)
- let title = fields.join('');
- const name = header.getAttribute('id');
+ let title = fields.join('')
+ const name = header.getAttribute('id')
if (!title) {
- title = name;
+ title = name
}
- const titleNode = newTitleNode(title, document);
- const descriptionNode = element.getElementsByClassName('description')[0];
+ const titleNode = newTitleNode(title, document)
+ const descriptionNode = element.getElementsByClassName('description')[0]
- const descriptionDiv = document.createElement('div');
- descriptionDiv.appendChild(titleNode);
- descriptionDiv.appendChild(descriptionNode);
- const html = buildDescriptionHtml(descriptionDiv);
+ const descriptionDiv = document.createElement('div')
+ descriptionDiv.appendChild(titleNode)
+ descriptionDiv.appendChild(descriptionNode)
+ const html = buildDescriptionHtml(descriptionDiv)
namespace[name] = { title, description: html, meta: CONST_DECL }
}
function processFunction(namespace, element, document) {
- const header = element.getElementsByTagName('h4')[0];
- const title = header.textContent;
- const name = header.getAttribute('id');
+ const header = element.getElementsByTagName('h4')[0]
+ const title = header.textContent
+ const name = header.getAttribute('id')
- const titleNode = newTitleNode(title, document);
- const descriptionNode = element.getElementsByClassName('description')[0];
+ const titleNode = newTitleNode(title, document)
+ const descriptionNode = element.getElementsByClassName('description')[0]
- const descriptionDiv = document.createElement('div');
- descriptionDiv.appendChild(titleNode);
- descriptionDiv.appendChild(descriptionNode);
- const html = buildDescriptionHtml(descriptionDiv);
+ const descriptionDiv = document.createElement('div')
+ descriptionDiv.appendChild(titleNode)
+ descriptionDiv.appendChild(descriptionNode)
+ const html = buildDescriptionHtml(descriptionDiv)
- namespace[name] = { title, description: html, meta: FUNC_DECL };
+ namespace[name] = { title, description: html, meta: FUNC_DECL }
}
async function processDirGlobals(target) {
- const inFile = pathlib.join(BASE_DIR, target, SRC_FILENAME);
- let document;
+ const inFile = pathlib.join(BASE_DIR, target, SRC_FILENAME)
+ let document
try {
- const contents = await fs.readFile(inFile);
- document = new JSDOM(contents.toString()).window.document;
+ const contents = await fs.readFile(inFile)
+ document = new JSDOM(contents.toString()).window.document
} catch (err) {
- console.error(inFile, "failed", err);
- return err;
+ console.error(inFile, 'failed', err)
+ return err
}
- const names = {};
+ const names = {}
- const constants = document.getElementsByClassName("constant-entry");
- Array.prototype.forEach.call(constants, ele => processConstant(names, ele, document));
+ const constants = document.getElementsByClassName('constant-entry')
+ Array.prototype.forEach.call(constants, ele => processConstant(names, ele, document))
const functions = document.getElementsByClassName('function-entry')
- Array.prototype.forEach.call(functions, ele => processFunction(names, ele, document));
+ Array.prototype.forEach.call(functions, ele => processFunction(names, ele, document))
- const outFile = pathlib.join(OUT_DIR, target + '.json');
+ const outFile = pathlib.join(OUT_DIR, target + '.json')
await fs.writeFile(outFile, JSON.stringify(names, null, 2), 'utf-8')
return undefined
}
@@ -108,7 +108,7 @@ export default async function autocomplete() {
console.error(`
Error: path to jsdoc html is invalid.
Ensure that this script is run from the project root and documentation has been generated\
- `);
+ `)
} else {
console.error(error)
}
@@ -116,11 +116,10 @@ export default async function autocomplete() {
}
await fs.mkdir(OUT_DIR, { recursive: true })
-
+
// Exit with error code if the there was some error
const errors = await Promise.all(TARGETS.map(processDirGlobals))
if (errors.find(each => each !== undefined)) process.exit(1)
console.log('Finished processing autocomplete documentation')
}
-
diff --git a/scripts/docs.mjs b/scripts/docs.mjs
index 70f0faef0..22ad7ac84 100644
--- a/scripts/docs.mjs
+++ b/scripts/docs.mjs
@@ -8,222 +8,178 @@ import process from 'process'
import autocomplete from './autocomplete.mjs'
const configs = {
- "landing": {
- "readme": "README_top.md",
- "dst": "",
- "libs": [
- "empty.js"
- ]
+ landing: {
+ readme: 'README_top.md',
+ dst: '',
+ libs: ['empty.js']
},
- "Source §1": {
- "readme": "README_1.md",
- "dst": "source_1/",
- "libs": [
- "misc.js",
- "math.js"
- ]
+ 'Source §1': {
+ readme: 'README_1.md',
+ dst: 'source_1/',
+ libs: ['misc.js', 'math.js']
},
- "Source §1 Typed": {
- "readme": "README_1_TYPED.md",
- "dst": "source_1_typed/",
- "libs": [
- "misc.js",
- "math.js"
- ]
+ 'Source §1 Typed': {
+ readme: 'README_1_TYPED.md',
+ dst: 'source_1_typed/',
+ libs: ['misc.js', 'math.js']
},
- "Source §1 WebAssembly": {
- "readme": "README_1_WASM.md",
- "dst": "source_1_wasm/",
- "libs": [
- "empty.js"
- ]
+ 'Source §1 WebAssembly': {
+ readme: 'README_1_WASM.md',
+ dst: 'source_1_wasm/',
+ libs: ['empty.js']
},
- "Source §2": {
- "readme": "README_2.md",
- "dst": "source_2/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js"
- ]
+ 'Source §2': {
+ readme: 'README_2.md',
+ dst: 'source_2/',
+ libs: ['auxiliary.js', 'misc.js', 'math.js', 'list.js']
},
- "Source §2 Typed": {
- "readme": "README_2_TYPED.md",
- "dst": "source_2_typed/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js"
- ]
+ 'Source §2 Typed': {
+ readme: 'README_2_TYPED.md',
+ dst: 'source_2_typed/',
+ libs: ['auxiliary.js', 'misc.js', 'math.js', 'list.js']
},
- "Source §3": {
- "readme": "README_3.md",
- "dst": "source_3/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js",
- "stream.js",
- "array.js",
- "pairmutator.js"
+ 'Source §3': {
+ readme: 'README_3.md',
+ dst: 'source_3/',
+ libs: [
+ 'auxiliary.js',
+ 'misc.js',
+ 'math.js',
+ 'list.js',
+ 'stream.js',
+ 'array.js',
+ 'pairmutator.js'
]
},
- "Source §3 Concurrent": {
- "readme": "README_3_CONCURRENT.md",
- "dst": "source_3_concurrent/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js",
- "stream.js",
- "array.js",
- "pairmutator.js",
- "concurrency.js"
+ 'Source §3 Concurrent': {
+ readme: 'README_3_CONCURRENT.md',
+ dst: 'source_3_concurrent/',
+ libs: [
+ 'auxiliary.js',
+ 'misc.js',
+ 'math.js',
+ 'list.js',
+ 'stream.js',
+ 'array.js',
+ 'pairmutator.js',
+ 'concurrency.js'
]
},
- "Source §3 Typed": {
- "readme": "README_3_TYPED.md",
- "dst": "source_3_typed/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js",
- "stream.js",
- "array.js",
- "pairmutator.js"
+ 'Source §3 Typed': {
+ readme: 'README_3_TYPED.md',
+ dst: 'source_3_typed/',
+ libs: [
+ 'auxiliary.js',
+ 'misc.js',
+ 'math.js',
+ 'list.js',
+ 'stream.js',
+ 'array.js',
+ 'pairmutator.js'
]
},
- "Source §4": {
- "readme": "README_4.md",
- "dst": "source_4/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js",
- "stream.js",
- "array.js",
- "pairmutator.js",
- "mce.js"
+ 'Source §4': {
+ readme: 'README_4.md',
+ dst: 'source_4/',
+ libs: [
+ 'auxiliary.js',
+ 'misc.js',
+ 'math.js',
+ 'list.js',
+ 'stream.js',
+ 'array.js',
+ 'pairmutator.js',
+ 'mce.js'
]
},
- "Source §4 Explicit-Control": {
- "readme": "README_4_EXPLICIT-CONTROL.md",
- "dst": "source_4_explicit-control/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js",
- "stream.js",
- "array.js",
- "pairmutator.js",
- "mce.js",
- "continuation.js"
+ 'Source §4 Explicit-Control': {
+ readme: 'README_4_EXPLICIT-CONTROL.md',
+ dst: 'source_4_explicit-control/',
+ libs: [
+ 'auxiliary.js',
+ 'misc.js',
+ 'math.js',
+ 'list.js',
+ 'stream.js',
+ 'array.js',
+ 'pairmutator.js',
+ 'mce.js',
+ 'continuation.js'
]
},
- "Source §4 Typed": {
- "readme": "README_4_TYPED.md",
- "dst": "source_4_typed/",
- "libs": [
- "auxiliary.js",
- "misc.js",
- "math.js",
- "list.js",
- "stream.js",
- "array.js",
- "pairmutator.js",
- "mce.js"
+ 'Source §4 Typed': {
+ readme: 'README_4_TYPED.md',
+ dst: 'source_4_typed/',
+ libs: [
+ 'auxiliary.js',
+ 'misc.js',
+ 'math.js',
+ 'list.js',
+ 'stream.js',
+ 'array.js',
+ 'pairmutator.js',
+ 'mce.js'
]
},
- "AUXILLARY": {
- "readme": "README_AUXILIARY.md",
- "dst": "AUXILIARY/",
- "libs": [
- "auxiliary.js"
- ]
+ AUXILLARY: {
+ readme: 'README_AUXILIARY.md',
+ dst: 'AUXILIARY/',
+ libs: ['auxiliary.js']
},
- "MISC": {
- "readme": "README_MISC.md",
- "dst": "MISC/",
- "libs": [
- "misc.js"
- ]
+ MISC: {
+ readme: 'README_MISC.md',
+ dst: 'MISC/',
+ libs: ['misc.js']
},
- "MATH": {
- "readme": "README_MATH.md",
- "dst": "MATH/",
- "libs": [
- "math.js"
- ]
+ MATH: {
+ readme: 'README_MATH.md',
+ dst: 'MATH/',
+ libs: ['math.js']
},
- "LIST": {
- "readme": "README_LISTS.md",
- "dst": "LISTS/",
- "libs": [
- "list.js"
- ]
+ LIST: {
+ readme: 'README_LISTS.md',
+ dst: 'LISTS/',
+ libs: ['list.js']
},
- "STREAMS": {
- "readme": "README_STREAMS.md",
- "dst": "STREAMS/",
- "libs": [
- "stream.js"
- ]
+ STREAMS: {
+ readme: 'README_STREAMS.md',
+ dst: 'STREAMS/',
+ libs: ['stream.js']
},
- "ARRAYS": {
- "readme": "README_ARRAYS.md",
- "dst": "ARRAYS/",
- "libs": [
- "array.js"
- ]
+ ARRAYS: {
+ readme: 'README_ARRAYS.md',
+ dst: 'ARRAYS/',
+ libs: ['array.js']
},
- "PAIRMUTATIONS": {
- "readme": "README_PAIRMUTATORS.md",
- "dst": "PAIRMUTATORS/",
- "libs": [
- "pairmutator.js"
- ]
+ PAIRMUTATIONS: {
+ readme: 'README_PAIRMUTATORS.md',
+ dst: 'PAIRMUTATORS/',
+ libs: ['pairmutator.js']
},
- "CONCURRENCY": {
- "readme": "README_CONCURRENCY.md",
- "dst": "CONCURRENCY/",
- "libs": [
- "concurrency.js"
- ]
+ CONCURRENCY: {
+ readme: 'README_CONCURRENCY.md',
+ dst: 'CONCURRENCY/',
+ libs: ['concurrency.js']
},
- "MCE": {
- "readme": "README_MCE.md",
- "dst": "MCE/",
- "libs": [
- "mce.js"
- ]
+ MCE: {
+ readme: 'README_MCE.md',
+ dst: 'MCE/',
+ libs: ['mce.js']
},
- "CONTINUATION": {
- "readme": "README_CONTINUATION.md",
- "dst": "CONTINUATION/",
- "libs": [
- "continuation.js"
- ]
+ CONTINUATION: {
+ readme: 'README_CONTINUATION.md',
+ dst: 'CONTINUATION/',
+ libs: ['continuation.js']
},
- "EV3": {
- "readme": "EV3_README.md",
- "dst": "EV3/",
- "libs": [
- "ev3.js"
- ]
+ EV3: {
+ readme: 'EV3_README.md',
+ dst: 'EV3/',
+ libs: ['ev3.js']
},
- "EXTERNAL": {
- "readme": "README_EXTERNAL.md",
- "dst": "External libraries",
- "libs": [
- "ev3.js"
- ]
+ EXTERNAL: {
+ readme: 'README_EXTERNAL.md',
+ dst: 'External libraries',
+ libs: ['ev3.js']
}
}
@@ -231,9 +187,9 @@ const config_file = 'docs/jsdoc/conf.json'
const readmes = 'docs/md'
const libraries = 'docs/lib'
const out_dir = 'docs/source'
-const jsdoc = "node_modules/jsdoc/jsdoc.js"
-const template_location = "docs/jsdoc/templates/template"
-const specs_dir = "docs/specs"
+const jsdoc = 'node_modules/jsdoc/jsdoc.js'
+const template_location = 'docs/jsdoc/templates/template'
+const specs_dir = 'docs/specs'
async function run() {
await fs.mkdir(out_dir, { recursive: true })
@@ -243,10 +199,14 @@ async function run() {
// for each configuration
const proc = fork(jsdoc, [
'-r',
- '-t', template_location,
- '-c', config_file,
- '-R', pathlib.join(readmes, config.readme),
- '-d', pathlib.join(out_dir, config.dst),
+ '-t',
+ template_location,
+ '-c',
+ config_file,
+ '-R',
+ pathlib.join(readmes, config.readme),
+ '-d',
+ pathlib.join(out_dir, config.dst),
...config.libs.map(each => pathlib.join(libraries, each))
])
@@ -280,19 +240,21 @@ async function prepare({ silent }) {
await run()
// Copy images in images directory to out_dir
- await fs.readdir('docs/images')
- .then(images => Promise.all(images.map(async img => {
- const srcPath = pathlib.join('docs/images', img)
- const dstPath = pathlib.join(out_dir, img)
- await fs.copyFile(srcPath, dstPath)
- console.debug(`Copied ${srcPath} to ${dstPath}`)
- })))
+ await fs.readdir('docs/images').then(images =>
+ Promise.all(
+ images.map(async img => {
+ const srcPath = pathlib.join('docs/images', img)
+ const dstPath = pathlib.join(out_dir, img)
+ await fs.copyFile(srcPath, dstPath)
+ console.debug(`Copied ${srcPath} to ${dstPath}`)
+ })
+ )
+ )
- const makeProc = spawn('make', { cwd: specs_dir, stdio: [
- 'ignore',
- silent ? 'ignore' : 'inherit',
- 'inherit'
- ]})
+ const makeProc = spawn('make', {
+ cwd: specs_dir,
+ stdio: ['ignore', silent ? 'ignore' : 'inherit', 'inherit']
+ })
const makeretcode = await new Promise(resolve => {
makeProc.on('exit', resolve)
@@ -306,16 +268,18 @@ async function prepare({ silent }) {
console.log('Finished running make')
// Copy pdf files that make produced to out_dir
- await fs.readdir(specs_dir)
- .then(files => Promise.all(files
- .filter(file => pathlib.extname(file) === '.pdf')
- .map(async file => {
- const srcPath = pathlib.join(specs_dir, file)
- const dstPath = pathlib.join(out_dir, file)
- await fs.copyFile(srcPath, dstPath)
- console.debug(`Copied ${srcPath} to ${dstPath}`)
- })
- ))
+ await fs.readdir(specs_dir).then(files =>
+ Promise.all(
+ files
+ .filter(file => pathlib.extname(file) === '.pdf')
+ .map(async file => {
+ const srcPath = pathlib.join(specs_dir, file)
+ const dstPath = pathlib.join(out_dir, file)
+ await fs.copyFile(srcPath, dstPath)
+ console.debug(`Copied ${srcPath} to ${dstPath}`)
+ })
+ )
+ )
}
async function clean() {
@@ -336,7 +300,8 @@ async function checkGitRoot() {
}
resolve(stdout.trim())
- })})
+ })
+ })
const procDir = pathlib.relative(gitRoot, '')
if (procDir !== '') {
@@ -347,22 +312,15 @@ async function checkGitRoot() {
await new Command()
.hook('preAction', checkGitRoot)
- .addCommand(
- new Command('run')
- .description('Run JSDOC and build documentation')
- .action(run),
- { isDefault: true }
- )
+ .addCommand(new Command('run').description('Run JSDOC and build documentation').action(run), {
+ isDefault: true
+ })
.addCommand(
new Command('prepare')
.option('--silent', 'Run make without outputting to stdout')
.action(prepare)
)
- .addCommand(
- new Command('clean')
- .description('Clear the output directory')
- .action(clean)
- )
+ .addCommand(new Command('clean').description('Clear the output directory').action(clean))
.addCommand(
new Command('autocomplete')
.description('Update autocomplete documentation')
@@ -370,8 +328,7 @@ await new Command()
)
.addCommand(
new Command('docs')
- .description('Execute the \'run\' command and then the \'autocomplete\' command')
+ .description("Execute the 'run' command and then the 'autocomplete' command")
.action(() => run().then(autocomplete))
)
.parseAsync()
-
\ No newline at end of file
diff --git a/src/cse-machine/__tests__/__snapshots__/cse-machine-errors.ts.snap b/src/cse-machine/__tests__/__snapshots__/cse-machine-errors.ts.snap
index 5d412190e..a0dd4a136 100644
--- a/src/cse-machine/__tests__/__snapshots__/cse-machine-errors.ts.snap
+++ b/src/cse-machine/__tests__/__snapshots__/cse-machine-errors.ts.snap
@@ -1,5 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`Array access should have an array as object: expectParsedError 1`] = `
+Object {
+ "alertResult": Array [],
+ "code": "1[3];",
+ "displayResult": Array [],
+ "numErrors": 1,
+ "parsedErrors": "Line 1: Expected array, got number.",
+ "result": undefined,
+ "resultStatus": "error",
+ "visualiseListResult": Array [],
+}
+`;
+
exports[`Builtins don't create additional errors when it's not their fault: expectParsedError 1`] = `
Object {
"alertResult": Array [],
@@ -969,6 +982,20 @@ test();",
}
`;
+exports[`Spread should have array as the argument: expectParsedError 1`] = `
+Object {
+ "alertResult": Array [],
+ "code": "const f = x => x;
+f(...1);",
+ "displayResult": Array [],
+ "numErrors": 1,
+ "parsedErrors": "Line 2: Expected array, got number.",
+ "result": undefined,
+ "resultStatus": "error",
+ "visualiseListResult": Array [],
+}
+`;
+
exports[`Type error with * , error line at , not : expectParsedError 1`] = `
Object {
"alertResult": Array [],
diff --git a/src/cse-machine/__tests__/cse-machine-errors.ts b/src/cse-machine/__tests__/cse-machine-errors.ts
index 9fa1bdc78..3b30703c9 100644
--- a/src/cse-machine/__tests__/cse-machine-errors.ts
+++ b/src/cse-machine/__tests__/cse-machine-errors.ts
@@ -60,6 +60,27 @@ test('Undefined variable error message differs from verbose version', () => {
)
})
+const arrayaccessnotarray = stripIndent`
+1[3];
+`
+
+test('Array access should have an array as object', () => {
+ return expectParsedError(arrayaccessnotarray, optionEC4).toMatchInlineSnapshot(
+ `"Line 1: Expected array, got number."`
+ )
+})
+
+const spreadelementnotarray = stripIndent`
+const f = x => x;
+f(...1);
+`
+
+test('Spread should have array as the argument', () => {
+ return expectParsedError(spreadelementnotarray, optionEC4).toMatchInlineSnapshot(
+ `"Line 2: Expected array, got number."`
+ )
+})
+
const assignToBuiltin = stripIndent`
map = 5;
`
diff --git a/src/cse-machine/interpreter.ts b/src/cse-machine/interpreter.ts
index 4615697c2..e8726d220 100644
--- a/src/cse-machine/interpreter.ts
+++ b/src/cse-machine/interpreter.ts
@@ -7,7 +7,7 @@
/* tslint:disable:max-classes-per-file */
import * as es from 'estree'
-import { isArray, reverse } from 'lodash'
+import { isArray } from 'lodash'
import { IOptions } from '..'
import { UNKNOWN_LOCATION } from '../constants'
@@ -329,7 +329,7 @@ function evaluateImports(program: es.Program, context: Context) {
* @returns The corresponding promise.
*/
export function CSEResultPromise(context: Context, value: Value): Promise {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
if (value instanceof CSEBreak) {
resolve({ status: 'suspended-cse-eval', context })
} else if (value instanceof CseError) {
@@ -560,12 +560,7 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
return
},
- WhileStatement: function (
- command: es.WhileStatement,
- context: Context,
- control: Control,
- stash: Stash
- ) {
+ WhileStatement: function (command: es.WhileStatement, context: Context, control: Control) {
if (hasBreakStatement(command.body as es.BlockStatement)) {
control.push(instr.breakMarkerInstr(command))
}
@@ -641,12 +636,7 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
}
},
- IfStatement: function (
- command: es.IfStatement,
- context: Context,
- control: Control,
- stash: Stash
- ) {
+ IfStatement: function (command: es.IfStatement, context: Context, control: Control) {
control.push(...reduceConditional(command))
},
@@ -714,21 +704,11 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
}
},
- ContinueStatement: function (
- command: es.ContinueStatement,
- context: Context,
- control: Control,
- stash: Stash
- ) {
+ ContinueStatement: function (command: es.ContinueStatement, context: Context, control: Control) {
control.push(instr.contInstr(command))
},
- BreakStatement: function (
- command: es.BreakStatement,
- context: Context,
- control: Control,
- stash: Stash
- ) {
+ BreakStatement: function (command: es.BreakStatement, context: Context, control: Control) {
control.push(instr.breakInstr(command))
},
@@ -767,21 +747,15 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
ArrayExpression: function (command: es.ArrayExpression, context: Context, control: Control) {
const elems = command.elements as ContiguousArrayElements
- reverse(elems)
const len = elems.length
control.push(instr.arrLitInstr(len, command))
- for (const elem of elems) {
- control.push(elem)
+ for (let i = len - 1; i >= 0; i--) {
+ control.push(elems[i])
}
},
- MemberExpression: function (
- command: es.MemberExpression,
- context: Context,
- control: Control,
- stash: Stash
- ) {
+ MemberExpression: function (command: es.MemberExpression, context: Context, control: Control) {
control.push(instr.arrAccInstr(command))
control.push(command.property)
control.push(command.object)
@@ -790,8 +764,7 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
ConditionalExpression: function (
command: es.ConditionalExpression,
context: Context,
- control: Control,
- stash: Stash
+ control: Control
) {
control.push(...reduceConditional(command))
},
@@ -854,7 +827,7 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
* Instructions
*/
- [InstrType.RESET]: function (command: Instr, context: Context, control: Control, stash: Stash) {
+ [InstrType.RESET]: function (command: Instr, context: Context, control: Control) {
// Keep pushing reset instructions until marker is found.
const cmdNext: ControlItem | undefined = control.pop()
if (cmdNext && (!isInstr(cmdNext) || cmdNext.instrType !== InstrType.MARKER)) {
@@ -1265,7 +1238,25 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
) {
const index = stash.pop()
const array = stash.pop()
- stash.push(array[index])
+
+ //Check if the index is legal
+ const indexRangeError = rttc.checkoutofRange(command.srcNode, index, context.chapter)
+ if (indexRangeError) {
+ handleRuntimeError(context, indexRangeError)
+ }
+
+ // Check if left-hand side is array
+ const lhsArrayCheckError = rttc.checkArray(command.srcNode, array, context.chapter)
+ if (lhsArrayCheckError) {
+ handleRuntimeError(context, lhsArrayCheckError)
+ }
+
+ // Check if index is out-of-bounds with array, in which case, returns undefined as per spec
+ if (index >= array.length) {
+ stash.push(undefined)
+ } else {
+ stash.push(array[index])
+ }
},
[InstrType.ARRAY_ASSIGNMENT]: function (
@@ -1281,12 +1272,7 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
stash.push(value)
},
- [InstrType.CONTINUE]: function (
- command: Instr,
- context: Context,
- control: Control,
- stash: Stash
- ) {
+ [InstrType.CONTINUE]: function (command: Instr, context: Context, control: Control) {
const next = control.pop() as ControlItem
if (isInstr(next) && next.instrType == InstrType.CONTINUE_MARKER) {
// Encountered continue mark, stop popping
@@ -1301,7 +1287,7 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
[InstrType.CONTINUE_MARKER]: function () {},
- [InstrType.BREAK]: function (command: Instr, context: Context, control: Control, stash: Stash) {
+ [InstrType.BREAK]: function (command: Instr, context: Context, control: Control) {
const next = control.pop() as ControlItem
if (isInstr(next) && next.instrType == InstrType.BREAK_MARKER) {
// Encountered break mark, stop popping
@@ -1324,6 +1310,12 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
) {
const array = stash.pop()
+ // Check if right-hand side is array
+ const rhsArrayCheckError = rttc.checkArray(command.srcNode, array, context.chapter)
+ if (rhsArrayCheckError) {
+ handleRuntimeError(context, rhsArrayCheckError)
+ }
+
// spread array
for (let i = 0; i < array.length; i++) {
stash.push(array[i])
diff --git a/src/utils/rttc.ts b/src/utils/rttc.ts
index 118177514..5803113f2 100644
--- a/src/utils/rttc.ts
+++ b/src/utils/rttc.ts
@@ -119,6 +119,13 @@ export const checkIfStatement = (node: Node, test: Value, chapter: Chapter = Cha
: new TypeError(node, ' as condition', 'boolean', typeOf(test), chapter)
}
+const MAX_SOURCE_ARRAY_INDEX = 4294967295
+export const checkoutofRange = (node: Node, index: Value, chapter: Chapter = Chapter.SOURCE_4) => {
+ return index >= 0 && index <= MAX_SOURCE_ARRAY_INDEX // as per Source 3 spec
+ ? undefined
+ : new TypeError(node, ' in reasonable range', 'index', 'out of range', chapter)
+}
+
export const checkMemberAccess = (node: Node, obj: Value, prop: Value) => {
if (isObject(obj)) {
return isString(prop) ? undefined : new TypeError(node, ' as prop', 'string', typeOf(prop))
@@ -136,3 +143,9 @@ export const checkMemberAccess = (node: Node, obj: Value, prop: Value) => {
export const isIdentifier = (node: any): node is es.Identifier => {
return (node as es.Identifier).name !== undefined
}
+
+export const checkArray = (node: Node, maybeArray: Value, chapter: Chapter = Chapter.SOURCE_4) => {
+ return isArray(maybeArray)
+ ? undefined
+ : new TypeError(node, '', 'array', typeOf(maybeArray), chapter)
+}
diff --git a/yarn.lock b/yarn.lock
index 2bbef2041..112755624 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -32,6 +32,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/code-frame@npm:^7.26.2":
+ version: 7.26.2
+ resolution: "@babel/code-frame@npm:7.26.2"
+ dependencies:
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ js-tokens: "npm:^4.0.0"
+ picocolors: "npm:^1.0.0"
+ checksum: 10c0/7d79621a6849183c415486af99b1a20b84737e8c11cd55b6544f688c51ce1fd710e6d869c3dd21232023da272a79b91efb3e83b5bc2dc65c1187c5fcd1b72ea8
+ languageName: node
+ linkType: hard
+
"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.2, @babel/compat-data@npm:^7.23.5":
version: 7.23.5
resolution: "@babel/compat-data@npm:7.23.5"
@@ -39,6 +50,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/compat-data@npm:^7.26.5":
+ version: 7.26.8
+ resolution: "@babel/compat-data@npm:7.26.8"
+ checksum: 10c0/66408a0388c3457fff1c2f6c3a061278dd7b3d2f0455ea29bb7b187fa52c60ae8b4054b3c0a184e21e45f0eaac63cf390737bc7504d1f4a088a6e7f652c068ca
+ languageName: node
+ linkType: hard
+
"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3":
version: 7.23.9
resolution: "@babel/core@npm:7.23.9"
@@ -62,6 +80,29 @@ __metadata:
languageName: node
linkType: hard
+"@babel/core@npm:^7.26.10":
+ version: 7.26.10
+ resolution: "@babel/core@npm:7.26.10"
+ dependencies:
+ "@ampproject/remapping": "npm:^2.2.0"
+ "@babel/code-frame": "npm:^7.26.2"
+ "@babel/generator": "npm:^7.26.10"
+ "@babel/helper-compilation-targets": "npm:^7.26.5"
+ "@babel/helper-module-transforms": "npm:^7.26.0"
+ "@babel/helpers": "npm:^7.26.10"
+ "@babel/parser": "npm:^7.26.10"
+ "@babel/template": "npm:^7.26.9"
+ "@babel/traverse": "npm:^7.26.10"
+ "@babel/types": "npm:^7.26.10"
+ convert-source-map: "npm:^2.0.0"
+ debug: "npm:^4.1.0"
+ gensync: "npm:^1.0.0-beta.2"
+ json5: "npm:^2.2.3"
+ semver: "npm:^6.3.1"
+ checksum: 10c0/e046e0e988ab53841b512ee9d263ca409f6c46e2a999fe53024688b92db394346fa3aeae5ea0866331f62133982eee05a675d22922a4603c3f603aa09a581d62
+ languageName: node
+ linkType: hard
+
"@babel/generator@npm:^7.23.6, @babel/generator@npm:^7.7.2":
version: 7.23.6
resolution: "@babel/generator@npm:7.23.6"
@@ -74,6 +115,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/generator@npm:^7.26.10":
+ version: 7.26.10
+ resolution: "@babel/generator@npm:7.26.10"
+ dependencies:
+ "@babel/parser": "npm:^7.26.10"
+ "@babel/types": "npm:^7.26.10"
+ "@jridgewell/gen-mapping": "npm:^0.3.5"
+ "@jridgewell/trace-mapping": "npm:^0.3.25"
+ jsesc: "npm:^3.0.2"
+ checksum: 10c0/88b3b3ea80592fc89349c4e1a145e1386e4042866d2507298adf452bf972f68d13bf699a845e6ab8c028bd52c2247013eb1221b86e1db5c9779faacba9c4b10e
+ languageName: node
+ linkType: hard
+
"@babel/helper-annotate-as-pure@npm:^7.22.5":
version: 7.22.5
resolution: "@babel/helper-annotate-as-pure@npm:7.22.5"
@@ -105,6 +159,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-compilation-targets@npm:^7.26.5":
+ version: 7.26.5
+ resolution: "@babel/helper-compilation-targets@npm:7.26.5"
+ dependencies:
+ "@babel/compat-data": "npm:^7.26.5"
+ "@babel/helper-validator-option": "npm:^7.25.9"
+ browserslist: "npm:^4.24.0"
+ lru-cache: "npm:^5.1.1"
+ semver: "npm:^6.3.1"
+ checksum: 10c0/9da5c77e5722f1a2fcb3e893049a01d414124522bbf51323bb1a0c9dcd326f15279836450fc36f83c9e8a846f3c40e88be032ed939c5a9840922bed6073edfb4
+ languageName: node
+ linkType: hard
+
"@babel/helper-create-class-features-plugin@npm:^7.22.11, @babel/helper-create-class-features-plugin@npm:^7.22.5":
version: 7.22.15
resolution: "@babel/helper-create-class-features-plugin@npm:7.22.15"
@@ -196,6 +263,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-module-imports@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-module-imports@npm:7.25.9"
+ dependencies:
+ "@babel/traverse": "npm:^7.25.9"
+ "@babel/types": "npm:^7.25.9"
+ checksum: 10c0/078d3c2b45d1f97ffe6bb47f61961be4785d2342a4156d8b42c92ee4e1b7b9e365655dd6cb25329e8fe1a675c91eeac7e3d04f0c518b67e417e29d6e27b6aa70
+ languageName: node
+ linkType: hard
+
"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.23.0, @babel/helper-module-transforms@npm:^7.23.3":
version: 7.23.3
resolution: "@babel/helper-module-transforms@npm:7.23.3"
@@ -211,6 +288,19 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-module-transforms@npm:^7.26.0":
+ version: 7.26.0
+ resolution: "@babel/helper-module-transforms@npm:7.26.0"
+ dependencies:
+ "@babel/helper-module-imports": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ "@babel/traverse": "npm:^7.25.9"
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: 10c0/ee111b68a5933481d76633dad9cdab30c41df4479f0e5e1cc4756dc9447c1afd2c9473b5ba006362e35b17f4ebddd5fca090233bef8dfc84dca9d9127e56ec3a
+ languageName: node
+ linkType: hard
+
"@babel/helper-optimise-call-expression@npm:^7.22.5":
version: 7.22.5
resolution: "@babel/helper-optimise-call-expression@npm:7.22.5"
@@ -301,6 +391,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-validator-option@npm:^7.25.9":
+ version: 7.25.9
+ resolution: "@babel/helper-validator-option@npm:7.25.9"
+ checksum: 10c0/27fb195d14c7dcb07f14e58fe77c44eea19a6a40a74472ec05c441478fa0bb49fa1c32b2d64be7a38870ee48ef6601bdebe98d512f0253aea0b39756c4014f3e
+ languageName: node
+ linkType: hard
+
"@babel/helper-wrap-function@npm:^7.22.20":
version: 7.22.20
resolution: "@babel/helper-wrap-function@npm:7.22.20"
@@ -323,6 +420,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helpers@npm:^7.26.10":
+ version: 7.26.10
+ resolution: "@babel/helpers@npm:7.26.10"
+ dependencies:
+ "@babel/template": "npm:^7.26.9"
+ "@babel/types": "npm:^7.26.10"
+ checksum: 10c0/f99e1836bcffce96db43158518bb4a24cf266820021f6461092a776cba2dc01d9fc8b1b90979d7643c5c2ab7facc438149064463a52dd528b21c6ab32509784f
+ languageName: node
+ linkType: hard
+
"@babel/highlight@npm:^7.23.4":
version: 7.23.4
resolution: "@babel/highlight@npm:7.23.4"
@@ -343,6 +450,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/parser@npm:^7.26.10, @babel/parser@npm:^7.26.9":
+ version: 7.26.10
+ resolution: "@babel/parser@npm:7.26.10"
+ dependencies:
+ "@babel/types": "npm:^7.26.10"
+ bin:
+ parser: ./bin/babel-parser.js
+ checksum: 10c0/c47f5c0f63cd12a663e9dc94a635f9efbb5059d98086a92286d7764357c66bceba18ccbe79333e01e9be3bfb8caba34b3aaebfd8e62c3d5921c8cf907267be75
+ languageName: node
+ linkType: hard
+
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.22.15":
version: 7.22.15
resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.22.15"
@@ -1318,6 +1436,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/template@npm:^7.26.9":
+ version: 7.26.9
+ resolution: "@babel/template@npm:7.26.9"
+ dependencies:
+ "@babel/code-frame": "npm:^7.26.2"
+ "@babel/parser": "npm:^7.26.9"
+ "@babel/types": "npm:^7.26.9"
+ checksum: 10c0/019b1c4129cc01ad63e17529089c2c559c74709d225f595eee017af227fee11ae8a97a6ab19ae6768b8aa22d8d75dcb60a00b28f52e9fa78140672d928bc1ae9
+ languageName: node
+ linkType: hard
+
"@babel/traverse@npm:^7.23.9":
version: 7.23.9
resolution: "@babel/traverse@npm:7.23.9"
@@ -1336,6 +1465,21 @@ __metadata:
languageName: node
linkType: hard
+"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.10":
+ version: 7.26.10
+ resolution: "@babel/traverse@npm:7.26.10"
+ dependencies:
+ "@babel/code-frame": "npm:^7.26.2"
+ "@babel/generator": "npm:^7.26.10"
+ "@babel/parser": "npm:^7.26.10"
+ "@babel/template": "npm:^7.26.9"
+ "@babel/types": "npm:^7.26.10"
+ debug: "npm:^4.3.1"
+ globals: "npm:^11.1.0"
+ checksum: 10c0/4e86bb4e3c30a6162bb91df86329df79d96566c3e2d9ccba04f108c30473a3a4fd360d9990531493d90f6a12004f10f616bf9b9229ca30c816b708615e9de2ac
+ languageName: node
+ linkType: hard
+
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.6, @babel/types@npm:^7.23.9, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
version: 7.26.9
resolution: "@babel/types@npm:7.26.9"
@@ -1346,6 +1490,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.26.9":
+ version: 7.26.10
+ resolution: "@babel/types@npm:7.26.10"
+ dependencies:
+ "@babel/helper-string-parser": "npm:^7.25.9"
+ "@babel/helper-validator-identifier": "npm:^7.25.9"
+ checksum: 10c0/7a7f83f568bfc3dfabfaf9ae3a97ab5c061726c0afa7dcd94226d4f84a81559da368ed79671e3a8039d16f12476cf110381a377ebdea07587925f69628200dac
+ languageName: node
+ linkType: hard
+
"@bcoe/v8-coverage@npm:^0.2.3":
version: 0.2.3
resolution: "@bcoe/v8-coverage@npm:0.2.3"
@@ -1720,6 +1874,17 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/gen-mapping@npm:^0.3.5":
+ version: 0.3.8
+ resolution: "@jridgewell/gen-mapping@npm:0.3.8"
+ dependencies:
+ "@jridgewell/set-array": "npm:^1.2.1"
+ "@jridgewell/sourcemap-codec": "npm:^1.4.10"
+ "@jridgewell/trace-mapping": "npm:^0.3.24"
+ checksum: 10c0/c668feaf86c501d7c804904a61c23c67447b2137b813b9ce03eca82cb9d65ac7006d766c218685d76e3d72828279b6ee26c347aa1119dab23fbaf36aed51585a
+ languageName: node
+ linkType: hard
+
"@jridgewell/resolve-uri@npm:^3.1.0":
version: 3.1.2
resolution: "@jridgewell/resolve-uri@npm:3.1.2"
@@ -1734,6 +1899,13 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/set-array@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "@jridgewell/set-array@npm:1.2.1"
+ checksum: 10c0/2a5aa7b4b5c3464c895c802d8ae3f3d2b92fcbe84ad12f8d0bfbb1f5ad006717e7577ee1fd2eac00c088abe486c7adb27976f45d2941ff6b0b92b2c3302c60f4
+ languageName: node
+ linkType: hard
+
"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14":
version: 1.4.15
resolution: "@jridgewell/sourcemap-codec@npm:1.4.15"
@@ -1751,6 +1923,16 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
+ version: 0.3.25
+ resolution: "@jridgewell/trace-mapping@npm:0.3.25"
+ dependencies:
+ "@jridgewell/resolve-uri": "npm:^3.1.0"
+ "@jridgewell/sourcemap-codec": "npm:^1.4.14"
+ checksum: 10c0/3d1ce6ebc69df9682a5a8896b414c6537e428a1d68b02fcc8363b04284a8ca0df04d0ee3013132252ab14f2527bc13bea6526a912ecb5658f0e39fd2860b4df4
+ languageName: node
+ linkType: hard
+
"@nodelib/fs.scandir@npm:2.1.5":
version: 2.1.5
resolution: "@nodelib/fs.scandir@npm:2.1.5"
@@ -1860,7 +2042,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/babel__core@npm:^7.1.14":
+"@types/babel__core@npm:^7, @types/babel__core@npm:^7.1.14":
version: 7.20.5
resolution: "@types/babel__core@npm:7.20.5"
dependencies:
@@ -2703,6 +2885,20 @@ __metadata:
languageName: node
linkType: hard
+"browserslist@npm:^4.24.0":
+ version: 4.24.4
+ resolution: "browserslist@npm:4.24.4"
+ dependencies:
+ caniuse-lite: "npm:^1.0.30001688"
+ electron-to-chromium: "npm:^1.5.73"
+ node-releases: "npm:^2.0.19"
+ update-browserslist-db: "npm:^1.1.1"
+ bin:
+ browserslist: cli.js
+ checksum: 10c0/db7ebc1733cf471e0b490b4f47e3e2ea2947ce417192c9246644e92c667dd56a71406cc58f62ca7587caf828364892e9952904a02b7aead752bc65b62a37cfe9
+ languageName: node
+ linkType: hard
+
"bs-logger@npm:0.x":
version: 0.2.6
resolution: "bs-logger@npm:0.2.6"
@@ -2789,6 +2985,13 @@ __metadata:
languageName: node
linkType: hard
+"caniuse-lite@npm:^1.0.30001688":
+ version: 1.0.30001706
+ resolution: "caniuse-lite@npm:1.0.30001706"
+ checksum: 10c0/b502d0a509611fd5b009e1123d482e983696984b6b749c3f485fd8d02cc58376c59cf0bb15f22fa2d337da104970edd27dd525d4663cebc728e26ac4adedff0d
+ languageName: node
+ linkType: hard
+
"caseless@npm:~0.12.0":
version: 0.12.0
resolution: "caseless@npm:0.12.0"
@@ -3231,6 +3434,13 @@ __metadata:
languageName: node
linkType: hard
+"electron-to-chromium@npm:^1.5.73":
+ version: 1.5.122
+ resolution: "electron-to-chromium@npm:1.5.122"
+ checksum: 10c0/e6bcb82e0c91687c9d93753393d438eb4d744c4d75e5d4e247c742ac45ca14611b3c5d5df138fd6671648a2868d5c7b429bef829fe2b3b990a8b7b1d9a8c01e6
+ languageName: node
+ linkType: hard
+
"emittery@npm:^0.13.1":
version: 0.13.1
resolution: "emittery@npm:0.13.1"
@@ -3415,6 +3625,13 @@ __metadata:
languageName: node
linkType: hard
+"escalade@npm:^3.2.0":
+ version: 3.2.0
+ resolution: "escalade@npm:3.2.0"
+ checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65
+ languageName: node
+ linkType: hard
+
"escape-string-regexp@npm:^1.0.5":
version: 1.0.5
resolution: "escape-string-regexp@npm:1.0.5"
@@ -5128,11 +5345,13 @@ __metadata:
version: 0.0.0-use.local
resolution: "js-slang@workspace:."
dependencies:
+ "@babel/core": "npm:^7.26.10"
"@babel/parser": "npm:^7.19.4"
"@babel/preset-env": "npm:^7.23.2"
"@commander-js/extra-typings": "npm:^12.0.1"
"@joeychenofficial/alt-ergo-modified": "npm:^2.4.0"
"@ts-morph/bootstrap": "npm:^0.18.0"
+ "@types/babel__core": "npm:^7"
"@types/estree": "npm:^1.0.5"
"@types/jest": "npm:^29.0.0"
"@types/lodash": "npm:^4.14.202"
@@ -5334,6 +5553,15 @@ __metadata:
languageName: node
linkType: hard
+"jsesc@npm:^3.0.2":
+ version: 3.1.0
+ resolution: "jsesc@npm:3.1.0"
+ bin:
+ jsesc: bin/jsesc
+ checksum: 10c0/531779df5ec94f47e462da26b4cbf05eb88a83d9f08aac2ba04206508fc598527a153d08bd462bae82fc78b3eaa1a908e1a4a79f886e9238641c4cdefaf118b1
+ languageName: node
+ linkType: hard
+
"jsesc@npm:~0.5.0":
version: 0.5.0
resolution: "jsesc@npm:0.5.0"
@@ -5870,6 +6098,13 @@ __metadata:
languageName: node
linkType: hard
+"node-releases@npm:^2.0.19":
+ version: 2.0.19
+ resolution: "node-releases@npm:2.0.19"
+ checksum: 10c0/52a0dbd25ccf545892670d1551690fe0facb6a471e15f2cfa1b20142a5b255b3aa254af5f59d6ecb69c2bec7390bc643c43aa63b13bf5e64b6075952e716b1aa
+ languageName: node
+ linkType: hard
+
"nopt@npm:^8.0.0":
version: 8.1.0
resolution: "nopt@npm:8.1.0"
@@ -6170,6 +6405,13 @@ __metadata:
languageName: node
linkType: hard
+"picocolors@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "picocolors@npm:1.1.1"
+ checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
+ languageName: node
+ linkType: hard
+
"picomatch@npm:^2.0.4, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1":
version: 2.3.1
resolution: "picomatch@npm:2.3.1"
@@ -7328,6 +7570,20 @@ __metadata:
languageName: node
linkType: hard
+"update-browserslist-db@npm:^1.1.1":
+ version: 1.1.3
+ resolution: "update-browserslist-db@npm:1.1.3"
+ dependencies:
+ escalade: "npm:^3.2.0"
+ picocolors: "npm:^1.1.1"
+ peerDependencies:
+ browserslist: ">= 4.21.0"
+ bin:
+ update-browserslist-db: cli.js
+ checksum: 10c0/682e8ecbf9de474a626f6462aa85927936cdd256fe584c6df2508b0df9f7362c44c957e9970df55dfe44d3623807d26316ea2c7d26b80bb76a16c56c37233c32
+ languageName: node
+ linkType: hard
+
"uri-js@npm:^4.2.2":
version: 4.4.1
resolution: "uri-js@npm:4.4.1"