diff --git a/.eslintrc b/.eslintrc index 848b2c1c..cd47acb0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,17 +4,30 @@ "ecmaVersion": 2017, "sourceType": "module" }, + "ignorePatterns": ["**/scheme-numbers.js"], "rules": { "indent": ["error", 4], "import/extensions": ["error", "always"], "comma-dangle": ["error", "never"], - "no-bitwise": ["error", { "allow": ["~"] }], - "no-underscore-dangle": ["error", { "allowAfterThis": true }], + "no-bitwise": 0, + "no-underscore-dangle": 0, + "import/prefer-default-export": 0, + "no-param-reassign": 0, + "no-mixed-operators": 0, + "class-methods-use-this": 0, + "func-names": 0, + "consistent-return": 0, + "no-constant-condition": 0, + "max-len": ["error", { + "code": 120, + "ignoreComments": true + }], + "no-plusplus": 0, "no-use-before-define": [ "error", { "functions": false, - "classes": true, + "classes": false, "variables": true } ], diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 00000000..360369ee --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,22 @@ +name: Node.js CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + eslint: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18] + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: make eslint diff --git a/.github/workflows/racket.yml b/.github/workflows/racket.yml new file mode 100644 index 00000000..8637b985 --- /dev/null +++ b/.github/workflows/racket.yml @@ -0,0 +1,83 @@ +name: Racket CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + continue-on-error: ${{ matrix.experimental }} + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + racket-version: [ '8.0', '8.1', '8.2', '8.3', '8.4', + '8.5', '8.6', '8.7', 'current'] + racket-variant: [ 'CS' ] + experimental: [true] + include: + - racket-version: '6.12' + racket-variant: 'BC' + experimental: false + - racket-version: '7.0' + racket-variant: 'BC' + experimental: false + - racket-version: '7.4' + racket-variant: 'BC' + experimental: false + - racket-version: '7.5' + racket-variant: 'BC' + experimental: false + - racket-version: '7.6' + racket-variant: 'BC' + experimental: false + - racket-version: '7.7' + racket-variant: 'BC' + experimental: false + - racket-version: '7.8' + racket-variant: 'BC' + experimental: false + name: Racket ${{ matrix.racket-version }} ${{ matrix.racket-variant }} + steps: + - uses: actions/checkout@master + - name: Setup Racket + uses: Bogdanp/setup-racket@v1.4 + with: + architecture: 'x64' + version: ${{ matrix.racket-version }} + variant: ${{ matrix.racket-variant }} + - run: raco pkg install --auto -t dir racketscript-compiler/ + - run: make unit-test + - run: make integration-test + coverage: + needs: build + runs-on: ubuntu-latest + name: Racket Coverage + steps: + - uses: actions/checkout@master + - name: Setup Racket + uses: Bogdanp/setup-racket@v1.4 + with: + architecture: 'x64' + variant: 'CS' + version: 'stable' + - name: Install package and its dependencies + run: | + raco pkg install --auto cover https://github.com/vishesh/cover-codecov.git + raco pkg install --auto -t dir racketscript-compiler/ + - name: Generate coverage report + run: | + COVERAGE_MODE=1 raco cover -f codecov -b \ + racketscript-compiler/racketscript/ \ + tests/fixture.rkt + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage.json + name: codecov-racketscript + fail_ci_if_error: false + verbose: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c2631df4..00000000 --- a/.travis.yml +++ /dev/null @@ -1,53 +0,0 @@ -language: node_js - -node_js: - - "14.14" - -sudo: false - -env: - global: - - RACKET_DIR=~/racket - - RACKET_RUN_COVERAGE=7.6 - matrix: - - RACKET_VERSION=HEAD - - RACKET_VERSION=RELEASE - - RACKET_VERSION=7.8 - - RACKET_VERSION=7.7 - - RACKET_VERSION=7.6 - - RACKET_VERSION=7.5 - - RACKET_VERSION=7.4 - - RACKET_VERSION=7.0 - - RACKET_VERSION=6.12 - - RACKET_VERSION=6.9 - -matrix: - allow_failures: - - env: RACKET_VERSION=HEAD - - env: RACKET_VERSION=RELEASE - - node_js: "node" - fast_finish: true - -before_install: - - git clone https://github.com/greghendershott/travis-racket.git - - cat travis-racket/install-racket.sh | bash - - export PATH="${RACKET_DIR}/bin:${PATH}" - -install: - - make setup - - make setup-extra - - raco pkg install --auto cover-codecov - -script: - - make unit-test - - make integration-test - -after_success: - - if [ ${RACKET_RUN_COVERAGE} = ${RACKET_VERSION} ]; then - COVERAGE_MODE=1 raco cover -bf codecov -d $TRAVIS_BUILD_DIR/coverage - racketscript-compiler/racketscript/ tests/fixture.rkt; - else - echo "Skipping coverage."; - fi - -after_script: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 43abdd65..c29ef88d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,8 +67,7 @@ make build # From RacketScript codebase root ``` *Get familiar* with the various command line options provided by the -RacketScript CLI `racks` and Node. Traceur or Babel CLI often come in -handy to run ES6 modules directly. +RacketScript CLI `racks` and Node. ### Testing @@ -155,7 +154,7 @@ the information that you would otherwise provide in the issue ticket. - Make sure the test suite passes and your changes are covered. Note that for runtime changes it is not possible to get coverage report (see [Coverage](#coverage)). We use - [Travis](https://travis-ci.org/vishesh/racketscript) for continuous + [GH Actions](https://github.com/vishesh/racketscript/actions) for continuous integration. - Adhere to the [style guide](#style-guide) (you can use linters for JavaScript). @@ -205,7 +204,7 @@ to your `PATH`. #### Get familiar with the tools -Get familiar with the tools used for development such as `racks`, `traceur`, +Get familiar with the tools used for development such as `racks`, `nodejs`, `babel`, `make`, `fixture.rkt` etc. See the various targets available in `Makefile` for usage examples. diff --git a/Makefile b/Makefile index 43b812f4..b44d9fac 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,8 @@ .PHONY: build setup setup-extra clean .PHONY: test unit-test integration-test test .PHONY: coverage coverage-unit-test -.PHONY: eslint eslint-fix jshint tscheck +.PHONY: eslint eslint-fix -TSC=node_modules/typescript/bin/tsc ESLINT=node_modules/eslint/bin/eslint.js ## Compile recipes @@ -28,12 +27,12 @@ build: setup: raco pkg install --auto -t dir racketscript-compiler/ || \ - raco pkg update --link racketscript-compiler/ + raco pkg update --link racketscript-compiler/ raco pkg install --auto -t dir racketscript-extras/ || \ - raco pkg update --link racketscript-extras/ + raco pkg update --link racketscript-extras/ setup-extra: - npm install -g traceur js-beautify eslint jshint gulp + npm install -g js-beautify raco pkg install --auto cover clean: @@ -51,28 +50,18 @@ coverage: @echo " RACKETSCRIPT COVERAGE " @echo "++++++++++++++++++++++++" COVERAGE_MODE=1 raco cover -d ./coverage/all -b racketscript-compiler \ - tests/fixture.rkt + tests/fixture.rkt ## JavaScript eslint: | node_modules @echo " RACKETSCRIPT RUNTIME LINT " @echo "++++++++++++++++++++++++++++" - $(ESLINT) ./racketscript-compiler/racketscript/compiler/runtime/ || true + $(ESLINT) ./racketscript-compiler/racketscript/compiler/runtime/ eslint-fix: | node_modules $(ESLINT) --fix ./racketscript-compiler/racketscript/compiler/runtime/ -jshint: - @echo " RACKETSCRIPT RUNTIME LINT " - @echo "++++++++++++++++++++++++++++" - jshint ./racketscript-compiler/racketscript/compiler/runtime/ || true - -# Typecheck JavaScript -tscheck: node_modules - $(TSC) --noEmit --allowJs --checkJs --strict --lib es2017 --target es2017 \ - racketscript-compiler/racketscript/compiler/runtime/kernel.js - node_modules: package.json npm install diff --git a/README.md b/README.md index ca4eca3b..7e6bd3ab 100644 --- a/README.md +++ b/README.md @@ -1,147 +1,125 @@ + + # RacketScript [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](COPYING.md) -[![Build Status](https://travis-ci.org/vishesh/racketscript.svg?branch=master)](https://travis-ci.org/vishesh/racketscript) -[![Coverage Status](https://codecov.io/gh/vishesh/racketscript/coverage.svg?branch=master)](https://codecov.io/gh/vishesh/racketscript?branch=master) -[![Try Online](https://img.shields.io/badge/try_it-online!-ff9900.svg)](http://rapture.twistedplane.com:8080) - -RacketScript is an **experimental** lightweight Racket to JavaScript -compiler. The generated code is ES6, which can be translated to ES5 -using [Babel](https://babeljs.io/) -or [Traceur](https://github.com/google/traceur-compiler). RacketScript -aims to leverage both JavaScript and Racket's ecosystem, and make -interoperability between them clean and smooth. - -RacketScript takes in Racket source files, uses Racket's macro -expander to -produce -[Fully Expanded Programs](https://docs.racket-lang.org/reference/syntax-model.html#%28part._fully-expanded%29), -and then compile these fully expanded programs to -JavaScript. RacketScript doesn't support Racket features which are -expensive, for example proper tail calls and continuations. +[![Tests](https://github.com/racketscript/racketscript/actions/workflows/racket.yml/badge.svg)](https://github.com/racketscript/racketscript/actions/workflows/racket.yml) +[![ESLint](https://github.com/racketscript/racketscript/actions/workflows/node.js.yml/badge.svg)](https://github.com/racketscript/racketscript/actions/workflows/node.js.yml) +[![Coverage Status](https://codecov.io/gh/racketscript/racketscript/coverage.svg?branch=master)](https://codecov.io/gh/racketscript/racketscript?branch=master) +[![Try Online](https://img.shields.io/badge/try_it-online!-ff9900.svg)](http://play.racketscript.org) + +[![Racket](https://img.shields.io/badge/-Racket-darkred?logo=racket)](https://racket-lang.org) +[![Discourse users](https://img.shields.io/discourse/users?label=Discuss%20on%20Racket%20Discourse&logo=racket&server=https%3A%2F%2Fracket.discourse.group)](https://racket.discourse.group/) +[![Racket Discord](https://img.shields.io/discord/571040468092321801?label=Chat%20on%20Racket%20Discord&logo=racket)](https://discord.gg/6Zq8sH5) + +RacketScript is an **experimental** lightweight Racket to JavaScript (ECMAScript 6) +compiler. RacketScript aims to leverage both JavaScript and Racket's ecosystem, +and make interoperability between them clean and smooth. + +RacketScript takes in Racket source files, uses Racket's macro expander to +produce [Fully Expanded +Programs](https://docs.racket-lang.org/reference/syntax-model.html#%28part._fully-expanded%29), +and then compile these fully expanded programs to JavaScript. RacketScript +currently supports only a subset of Racket. ## Try RacketScript You can try RacketScript in your browser -at [RacketScript Playground](http://rapture.twistedplane.com:8080/). +at [RacketScript Playground](http://play.racketscript.org). + +You may alo be interested in [Rackt](https://rackt-org.github.io) - An ultrasmall (~70 loc) React wrapper written in RacketScript. ## Disclaimer -RacketScript is **work-in-progress** and is not mature and stable. -Several Racket features and libraries are not yet implemeted -(eg. number pyramid, contracts, tail calls, primitives). That said, -we encourage experimentation, user feedback, discussions, bug reports -and pull requests. +RacketScript is **work-in-progress** and is not mature and stable. Several +Racket features and libraries are not yet implemented (eg. number pyramid, +contracts, proper tail calls, continuations). There are also quite a few missing +primitive functions. That said, we encourage experimentation, user feedback, +discussions, bug reports and pull requests. ## Installation -Following system packages are required - +Following system packages are required: -- [Racket](http://www.racket-lang.org/) 6.4 or higher -- [NodeJS](https://nodejs.org/) (4.0 or higher) and NPM +- [Racket](http://www.racket-lang.org/) 6.12 or higher +- [NodeJS](https://nodejs.org/) (14.0 or higher) and NPM - Make ### Quick Install -RacketScript can be installed by running one of the following commands -in your terminal. - -For installation via `raco` +RacketScript can be installed using the Racket package manager `raco`: ```sh raco pkg install racketscript ``` -For installation via `curl` - -```sh -sh -c "$(curl -fsSL https://raw.githubusercontent.com/vishesh/racketscript/master/install.sh)" -``` - -Or, for installation via `wget` - -```sh -sh -c "$(wget https://raw.githubusercontent.com/vishesh/racketscript/master/install.sh -O -)" -``` - See [Basic Usage](#basic-usage) to get started. ### Install from Github -Once RacketScript is cloned in your machine - - -1. Fire up your terminal and goto the root directory of the - repository. -2. Execute `make setup` to install RacketScript compiler and all its - dependencies. - -Although not required, it is strongly recommeded that you install -Traceur, and Gulp as global packages. - ```sh -npm install -g traceur gulp +# Clone RacketScript +git clone git@github.com:racketscript/racketscript.git` +cd racketscript + +# Build and install +make setup ``` If you do not wish to pollute your root NPM directory, you can set a -custom global location by changing your `npmrc` (eg. `echo "prefix = +custom global location by changing your `npmrc` (eg. `echo "prefix = $HOME/.npm-packages" >> ~/.npmrc`. Then add `/prefix/path/above/bin` to your `PATH`. -RacketScript will generate Gulpfiles to compile ES6 to ES5 using -Traceur or Babel. If you wish to run ES6 modules directly, install -Traceur using NPM. Babel is recommended for writing NodeJS programs. - ## Basic Usage -RacketScript compiler is named `racks`. +RacketScript compiler is named `racks`. ```sh racks -h # show help ``` - + To compile a Racket source file: ```sh # Installs all NPM dependencies and compile file.rkt racks /path/to/file.rkt ``` - + The above command will create a output build directory named `js-build`, copy RacketScript runtime, copy other support files, install NPM dependencies, compile `file.rkt` and its dependencies. -The compiled ES6 modules typically goto one of following three +The compiled JavaScript modules typically goto one of following three folders: - "modules": The normal Racket files. - "collects": Racket collects source files. - "links": Other third party packages. - "dist": Contains sources compiled to ES6 or bundled JavaScript ready - for distribution. +for distribution. Here are few other examples that would come in handy: ```sh # To skip `npm install` step. Useful when building # for second time. -racks -n /path/to/source.rkt - -# To beautify assembled modules use `-b`. Make sure -# `js-beautify` is installed from NPM or your -# package manager. -racks -b /path/to/source.rkt +racks -n /path/to/module-name.rkt + +# Run the assembled JavaScript module. +node js-build/modules/module-name.rkt.js + +# Use `-b` to format the assembled JavaScript code use `-b`. Assumes +# `js-beautify` is available in `$PATH`. +racks -b /path/to/module-name.rkt # Override default output directory -racks -d /path/to/output/dir /path/to/source.rkt - -# Print JavaScript output to stdout -racks --js --js-beautify /path/to/source.rkt +racks -d /path/to/output/dir /path/to/module-name.rkt -# By default RacketScript uses Traceur. Run `js-build/bootstrap.js` -# to execute the compiled JavaScript program. -node js-build/bootstrap.js +# Print JavaScript output to stdout +racks --js --js-beautify /path/to/module-name.rkt ``` - + By default tail call optimization is turned off. To enable translation of self recursive tail calls to loop, pass `--enable-self-tail` flag. @@ -149,46 +127,25 @@ of self recursive tail calls to loop, pass `--enable-self-tail` flag. racks --enable-self-tail /path/to/source.rkt ``` -### Traceur - -By default RacketScript will use Traceur and produce -`dist/compiled.js`. To execute inside NodeJS, execute `bootstrap.js` -in output directory. For running in browser, either use -`traceur-browser` target, or include the Traceur runtime along with -`dist/compiled.js`. +### Browser -```sh -# Use `--target` or `-t` flag. - -# For command line. You can ignore this flag. -racks --target traceur /path/to/source.rkt +Most browsers can load RacketScript modules directly without any external +dependencies ``. -# To run the compiled JavaScript program. -node js-build/bootstrap.js - -# For targeting browser. -racks --target traceur-browser /path/to/source.rkt -``` +### Module Bundler (Webpack) -A more robust (and less portable) way, is to run the ES6 modules -generated in `modules` directly from Traceur. Goto `modules` output -directory and execute `$ traceur /path/to/source.js`. - -### Babel - -RacketScript could also use `Babel`. It will compile each assembled ES6 -module to ES5, and put it in `dist` directory, persevering original -directory structure. Replace above command with following - +For deployment, you may want to bundle all generated modules into single +JavaScript file. RacketScript can generate some boiler-plate for using +Webpack/Babel, however we recommend you to use your own configuration. ```sh # Use `--target` or `-t` flag. -racks --target babel /path/to/source.rkt -``` +racks --target webpack /path/to/source.rkt -This will compile each ES6 module generated by RacketScript, and put -in `js-build/dist` with same directory structure. The JavaScript -script file produced by Babel in `dist` can be executed directly using -Node. Babel is highly recommended if your target is NodeJS. +# Call webpack to bundle in `js-build` directory. Will produce +# single JavaScript bundle in `js-build/dist` directory. +npx webpack +``` ## Contributing to RacketScript @@ -196,7 +153,7 @@ Please read [Contribution Guidelines](CONTRIBUTING.md). ## Troubleshooting -Please read the [Troubleshooting Wiki](https://github.com/vishesh/racketscript/wiki/Troubleshooting). +Please read the [Troubleshooting Wiki](https://github.com/racketscript/racketscript/wiki/Troubleshooting). ## Related Work diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..737f7558 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,4 @@ +coverage: + status: + patch: false + informational: true diff --git a/install.sh b/install.sh deleted file mode 100755 index f8889ed8..00000000 --- a/install.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -set -e - -NODEJS_EXE=node -RACO_EXE=raco - -echo "RacketScript Installation" -echo " [https://github.com/vishesh/racketscript]" -echo "===========================================" -echo - -if ! type "$NODEJS_EXE" > /dev/null; then - echo "NodeJS (node) not found in \$PATH. [https://nodejs.org/]" - exit 1 -fi - -if ! type "$RACO_EXE" > /dev/null; then - echo "Racket not found in \$PATH [http://www.racket-lang.org/]" - exit 1 -fi - -raco pkg install -t github vishesh/racketscript/?path=racketscript-compiler#master -raco pkg install -t github vishesh/racketscript/?path=racketscript-extras#master - -echo "RacketScript installed successfully. Enjoy!" diff --git a/logo.svg b/logo.svg new file mode 100644 index 00000000..c4ea08a7 --- /dev/null +++ b/logo.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package-lock.json b/package-lock.json index 326912b0..38a9494a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,230 +1,1766 @@ { + "name": "racketscript", + "lockfileVersion": 2, "requires": true, - "lockfileVersion": 1, - "dependencies": { - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", - "dev": true + "packages": { + "": { + "devDependencies": { + "eslint": "^8.36.0", + "eslint-config-airbnb-base": "^12.0.0", + "eslint-plugin-import": "^2.7.0" + } }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "requires": { - "acorn": "^3.0.4" + "dependencies": { + "eslint-visitor-keys": "^3.3.0" }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.1.tgz", + "integrity": "sha512-BISJ6ZE4xQsuL/FmsyRaiffpq977bMlsKfGHTQrOGFErfByxIe6iZTxPf/00Zon9b9a7iUykfQwejN3s2ZW/Bw==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", + "dev": true, "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "node_modules/@eslint/js": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "engines": { + "node": ">= 8" } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "balanced-match": { + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "builtin-modules": { + "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "requires": { - "callsites": "^0.2.0" + "engines": { + "node": ">=6" } }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "optional": true } } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.5.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.0.0.tgz", + "integrity": "sha512-/XlFQGn3Mkwm642/GYBtOH3pgFX4Z7saBsqqyp96v0bEUPq24nIrZ6N72qAoD0lR2wAne4EC4YsHYkbPfaRfiA==", + "dev": true, + "dependencies": { + "eslint-restricted-globals": "^0.1.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", + "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", + "dev": true, + "dependencies": { + "debug": "^2.6.8", + "resolve": "^1.2.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "dev": true, + "dependencies": { + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", + "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "dev": true, + "dependencies": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.1.1", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "dependencies": { + "function-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "dependencies": { + "builtin-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.5" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "dependencies": { + "spdx-license-ids": "^1.0.2" + } + }, + "node_modules/spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "node_modules/spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "dependencies": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.1.tgz", + "integrity": "sha512-BISJ6ZE4xQsuL/FmsyRaiffpq977bMlsKfGHTQrOGFErfByxIe6iZTxPf/00Zon9b9a7iUykfQwejN3s2ZW/Bw==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@eslint/js": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "concat-map": { @@ -233,48 +1769,30 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" }, "dependencies": { "ms": { @@ -286,15 +1804,15 @@ } }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -310,54 +1828,102 @@ } }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "eslint": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", - "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.2", - "esquery": "^1.0.0", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.5.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } } }, "eslint-config-airbnb-base": { @@ -380,9 +1946,9 @@ }, "dependencies": { "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -401,9 +1967,9 @@ }, "dependencies": { "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -430,9 +1996,9 @@ }, "dependencies": { "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -457,59 +2023,54 @@ "dev": true }, "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" } }, "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "esutils": { @@ -518,52 +2079,40 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "reusify": "^1.0.4" } }, "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "^3.0.4" } }, "find-up": { @@ -577,21 +2126,25 @@ } }, "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "function-bind": { @@ -600,31 +2153,37 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } }, "graceful-fs": { "version": "4.1.11", @@ -632,6 +2191,12 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, "has": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", @@ -641,42 +2206,34 @@ "function-bind": "^1.0.2" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" } }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -686,7 +2243,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -699,28 +2256,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -736,22 +2271,25 @@ "builtin-modules": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, "isarray": { @@ -763,29 +2301,28 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "js-sdsl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", + "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { @@ -795,13 +2332,13 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "load-json-file": { @@ -834,70 +2371,33 @@ } } }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - }, "lodash.cond": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", "dev": true }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -916,50 +2416,29 @@ "validate-npm-package-license": "^3.0.1" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-limit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", @@ -975,6 +2454,15 @@ "p-limit": "^1.1.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -996,19 +2484,19 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-type": { @@ -1050,34 +2538,22 @@ "find-up": "^1.0.0" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "read-pkg": { @@ -1112,31 +2588,6 @@ } } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, "resolve": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", @@ -1147,66 +2598,35 @@ } }, "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { - "rx-lite": "*" + "queue-microtask": "^1.2.2" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", @@ -1214,35 +2634,20 @@ "dev": true }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", @@ -1264,46 +2669,13 @@ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", "dev": true }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -1313,29 +2685,18 @@ "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "has-flag": "^4.0.0" } }, "text-table": { @@ -1344,46 +2705,29 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, - "typescript": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz", - "integrity": "sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } }, "validate-npm-package-license": { "version": "3.0.1", @@ -1396,39 +2740,30 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "word-wrap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } diff --git a/package.json b/package.json index b078fb2c..1f8fc693 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,6 @@ { - "dependencies": { - "typescript": "^2.5.2" - }, "devDependencies": { - "eslint": "^4.18.2", + "eslint": "^8.36.0", "eslint-config-airbnb-base": "^12.0.0", "eslint-plugin-import": "^2.7.0" } diff --git a/racketscript-compiler/info.rkt b/racketscript-compiler/info.rkt index 0dc643e5..4a7c3ef9 100644 --- a/racketscript-compiler/info.rkt +++ b/racketscript-compiler/info.rkt @@ -8,7 +8,7 @@ ["racket" "6.4"] "typed-racket-lib" "typed-racket-more" - "threading" + "threading-lib" "graph-lib" "anaphoric")) @@ -19,11 +19,13 @@ (define pkg-authors '(vishesh)) (define pkg-desc "Racket to JavaScript compiler") +(define post-install-collection "") ;; Test configuration - (define test-omit-paths '("racketscript/browser.rkt" "racketscript/compiler/runtime/")) + +;; Coverage (define cover-omit-paths '("racketscript/browser.rkt" "racketscript/compiler/runtime/kernel.rkt" "racketscript/compiler/runtime/paramz.rkt" diff --git a/racketscript-compiler/racketscript/base.rkt b/racketscript-compiler/racketscript/base.rkt index 993d20c8..1e55542c 100644 --- a/racketscript-compiler/racketscript/base.rkt +++ b/racketscript-compiler/racketscript/base.rkt @@ -1,5 +1,5 @@ #lang racket/base (require "base/main.rkt") -(provide (all-from-out "base/main.rkt")) +(provide (all-from-out "base/main.rkt")) diff --git a/racketscript-compiler/racketscript/base/lang/reader.rkt b/racketscript-compiler/racketscript/base/lang/reader.rkt index 66d8b694..74f06175 100644 --- a/racketscript-compiler/racketscript/base/lang/reader.rkt +++ b/racketscript-compiler/racketscript/base/lang/reader.rkt @@ -3,5 +3,4 @@ racketscript/base #:read x-read #:read-syntax x-read-syntax - (require "../../boot/lang/reader.rkt") diff --git a/racketscript-compiler/racketscript/boot.rkt b/racketscript-compiler/racketscript/boot.rkt index 344494d0..0c1bc887 100644 --- a/racketscript-compiler/racketscript/boot.rkt +++ b/racketscript-compiler/racketscript/boot.rkt @@ -2,7 +2,7 @@ ;; really needed. (module boot '#%kernel - (#%require racket/base + (#%require (all-except racket/base #%app lambda) (for-syntax racket/base) (only "interop.rkt")) @@ -16,6 +16,8 @@ for-syntax for-template rename-out + only-in all-from-out + prefix-in begin-for-syntax quote diff --git a/racketscript-compiler/racketscript/boot/lang/private/interop.rkt b/racketscript-compiler/racketscript/boot/lang/private/interop.rkt index 5c5d87fa..79b0b225 100644 --- a/racketscript-compiler/racketscript/boot/lang/private/interop.rkt +++ b/racketscript-compiler/racketscript/boot/lang/private/interop.rkt @@ -2,8 +2,6 @@ (require racket/match racket/string - racket/syntax - syntax/readerr (only-in racketscript/compiler/util-untyped js-identifier?)) @@ -69,26 +67,30 @@ (require rackunit racketscript/interop) - (define-simple-check (check-reader str first-id? result) - (equal? (syntax->datum - (read-racketscript #f (open-input-string - (string-append - (if first-id? "s." "s*.") - str)))) - result)) + (define-simple-check (check-reader str expected) + (let ([actual (read-racketscript #f (open-input-string (substring str 2)))]) + (equal? + (if actual + (syntax->datum actual) + actual) + expected))) - (check-reader "window" #t 'window) - (check-reader "window" #f '(#%js-ffi 'var 'window)) + (check-reader "#js.window" 'window) + (check-reader "#js*.window" '(#%js-ffi 'var 'window)) - (check-reader "window.document" #t `(#%js-ffi 'ref window 'document)) - (check-reader "window.document.write" #t + (check-reader "#js.window.document" `(#%js-ffi 'ref window 'document)) + (check-reader "#js.window.document.write" `(#%js-ffi 'ref (#%js-ffi 'ref window 'document) 'write)) - (check-reader "window.document" #f + (check-reader "#js*.window.document" `(#%js-ffi 'ref (#%js-ffi 'var 'window) 'document)) - (check-reader "window.document.write" #f + (check-reader "#js*.window.document.write" `(#%js-ffi 'ref (#%js-ffi 'ref (#%js-ffi 'var 'window) 'document) - 'write))) + 'write)) + + (check-reader "#js\"body\"" `(#%js-ffi 'string "body")) + + (check-reader "#jQuery" #f)) diff --git a/racketscript-compiler/racketscript/boot/lang/reader.rkt b/racketscript-compiler/racketscript/boot/lang/reader.rkt index a28a8a43..88cce1ad 100644 --- a/racketscript-compiler/racketscript/boot/lang/reader.rkt +++ b/racketscript-compiler/racketscript/boot/lang/reader.rkt @@ -5,6 +5,7 @@ racketscript/boot #:read-syntax x-read-syntax (require (prefix-in interop: "private/interop.rkt")) + (provide x-read x-read-syntax) ;; Do or don't do renaming of fieldname diff --git a/racketscript-compiler/racketscript/compiler/absyn.rkt b/racketscript-compiler/racketscript/compiler/absyn.rkt index 45af21d1..42cfc8f5 100644 --- a/racketscript-compiler/racketscript/compiler/absyn.rkt +++ b/racketscript-compiler/racketscript/compiler/absyn.rkt @@ -1,7 +1,7 @@ #lang typed/racket/base -(require "language.rkt" - "ident.rkt") +(require "ident.rkt" + "language.rkt") (provide (all-defined-out)) diff --git a/racketscript-compiler/racketscript/compiler/assembler.rkt b/racketscript-compiler/racketscript/compiler/assembler.rkt index ac6246e5..952d497d 100644 --- a/racketscript-compiler/racketscript/compiler/assembler.rkt +++ b/racketscript-compiler/racketscript/compiler/assembler.rkt @@ -4,17 +4,15 @@ ;;; in assumed to be fresh, to enforce lexical scope rules of Racket ;;; in JavaScript -(require racket/string - racket/format - racket/match - racket/list +(require racket/format racket/function + racket/list + racket/match + racket/string "config.rkt" - "environment.rkt" + "il.rkt" "logging.rkt" - "util.rkt" - "absyn.rkt" - "il.rkt") + "util.rkt") (provide assemble assemble-module @@ -312,14 +310,6 @@ [_ #:when (single-flonum? v) (emit (~a (exact->inexact (inexact->exact v))))] [_ (emit (~a v))])] ;; TODO [(boolean? v) (emit (if v "true" "false"))] - [(regexp? v) - (define s (string-replace (cast (object-name v) String) "/" "\\/")) - (write (format "/~a/" s) out)] - [(byte-regexp? v) - (define s (string-replace (bytes->string/utf-8 - (cast (object-name v) Bytes)) - "/" "\\/")) - (write (format "/~a/" s) out)] [(void? v) (emit "null")] [else (error "Unexpected value: " v)])) diff --git a/racketscript-compiler/racketscript/compiler/case-lambda.rkt b/racketscript-compiler/racketscript/compiler/case-lambda.rkt index 1f682b8f..0cbcdd84 100644 --- a/racketscript-compiler/racketscript/compiler/case-lambda.rkt +++ b/racketscript-compiler/racketscript/compiler/case-lambda.rkt @@ -1,9 +1,8 @@ #lang racket -(require syntax/parse - syntax/stx - (for-syntax syntax/parse - racket/stxparam)) +(require (for-syntax syntax/parse) + syntax/parse + syntax/stx) (provide s-case-lambda module-replace-case-lambda) diff --git a/racketscript-compiler/racketscript/compiler/config.rkt b/racketscript-compiler/racketscript/compiler/config.rkt index e0d5c84d..ddf23215 100644 --- a/racketscript-compiler/racketscript/compiler/config.rkt +++ b/racketscript-compiler/racketscript/compiler/config.rkt @@ -1,12 +1,11 @@ #lang typed/racket/base -(require racket/match - racket/function +(require racket/function + racket/match racket/path racket/runtime-path racket/set threading - "../private/interop.rkt") (provide output-directory @@ -28,7 +27,9 @@ ignored-module-imports-in-boot ignored-undefined-identifier? - skip-arity-checks?) + skip-arity-checks? + + use-scheme-numbers?) ;;; --------------------------------------------------------------------------- (define FFI-CALL-ID '#%js-ffi) @@ -135,3 +136,9 @@ (: skip-arity-checks? (Parameter Boolean)) (define skip-arity-checks? (make-parameter #f)) + +;;; --------------------------------------------------------------------------- + +;; Compiler flag for switching between JS and Scheme number semantics. +(: use-scheme-numbers? (Parameter Boolean)) +(define use-scheme-numbers? (make-parameter #f)) diff --git a/racketscript-compiler/racketscript/compiler/directive.rkt b/racketscript-compiler/racketscript/compiler/directive.rkt new file mode 100644 index 00000000..2afe65b5 --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/directive.rkt @@ -0,0 +1,24 @@ + +#lang racket/base + +(require (for-syntax racket + syntax/parse)) + +(provide #%rs-compiler + if-scheme-numbers) + +;; #%rs-compiler is treated specially by the compiler to implement +;; compiler directives. +(define #%rs-compiler + (lambda _ + (#%app error 'racketscript "cannot use Racketscript compiler directive in Racket"))) + +(define-syntax (if-scheme-numbers stx) + (syntax-parse stx + [(_ consequent:expr alternate:expr) + #'(#%rs-compiler 'if-scheme-numbers + consequent + alternate)] + [(_ consequent:expr) + #'(#%rs-compiler 'if-scheme-numbers + consequent)])) diff --git a/racketscript-compiler/racketscript/compiler/environment.rkt b/racketscript-compiler/racketscript/compiler/environment.rkt index 8874a49a..5d519c06 100644 --- a/racketscript-compiler/racketscript/compiler/environment.rkt +++ b/racketscript-compiler/racketscript/compiler/environment.rkt @@ -2,8 +2,7 @@ (require racket/format racket/match - "config.rkt" - "util.rkt") + "config.rkt") (provide name-in-module *quoted-binding-ident-name*) diff --git a/racketscript-compiler/racketscript/compiler/expand.rkt b/racketscript-compiler/racketscript/compiler/expand.rkt index 34073770..d501351f 100644 --- a/racketscript-compiler/racketscript/compiler/expand.rkt +++ b/racketscript-compiler/racketscript/compiler/expand.rkt @@ -6,34 +6,27 @@ ;; ;; Copyright (c) 2013 Sam Tobin-Hochstadt, Jeremy Siek, Carl Friedrich Bolz -(require racket/bool - racket/dict racket/match - racket/extflonum - racket/format - racket/function +(require (for-syntax racket/base) + racket/bool + racket/dict + (only-in racket/list + append-map + last-pair + filter-map + first + add-between) racket/list + racket/match racket/path racket/pretty racket/set - racket/sequence racket/syntax racket/vector - syntax/modresolve - syntax/stx - syntax/parse syntax/id-table + syntax/parse + syntax/stx version/utils - (only-in racket/list - append-map - last-pair - filter-map - first - add-between) - - (for-syntax racket/base) - "absyn.rkt" - "case-lambda.rkt" "config.rkt" "global.rkt" "logging.rkt" @@ -141,7 +134,20 @@ [((~datum all-from-except) p ...) '()] [((~datum for-meta) 1 p ...) '()] [((~datum for-syntax) p ...) '()] - [((~datum protect) p ...) '()] + [((~datum protect) p ...) + (apply append (stx-map parse-provide #'(p ...)))] + [((~datum struct) p (f ...)) + (append + (list (SimpleProvide (syntax-e #'p)) + (SimpleProvide (syntax-e (format-id #'p "make-~a" #'p))) + (SimpleProvide (syntax-e (format-id #'p "struct:~a" #'p))) + (SimpleProvide (syntax-e (format-id #'p "~a?" #'p)))) + (stx-map ; accessors + (lambda (f) (syntax-e (format-id #'p "~a-~a" #'p f))) + #'(f ...)) + (stx-map ; mutators + (lambda (f) (syntax-e (format-id #'p "set-~a-~a!" #'p f))) + #'(f ...)))] [_ #;(error "unsupported provide form " (syntax->datum r)) '()])) (define (formals->absyn formals) @@ -274,7 +280,7 @@ (current-module-imports (set-add (current-module-imports) src-mod-path))) ;;HACK: See test/struct/import-struct.rkt. Somehow, the - ;; struct contructor has different src-id returned by + ;; struct constructor has different src-id returned by ;; identifier-binding than the actual identifier name used ;; at definition site. Implicit renaming due to macro ;; expansion? @@ -310,7 +316,7 @@ nom-src-mod-path-orig mod-src-id))])) - ;; If the moduele is renamed use the id name used at the importing + ;; If the module is renamed use the id name used at the importing ;; module rather than defining module. Since renamed, module currently ;; are #%kernel which we write ourselves in JS we prefer original name. ;; TODO: We potentially might have clashes, but its unlikely. @@ -363,14 +369,10 @@ [_ #:when (prefab-struct-key (syntax-e v)) #f] ;; TODO: No error to compile FFI [_ #:when (box? (syntax-e v)) (box (parameterize ([quoted? #t]) (to-absyn (unbox (syntax-e v)))))] - [_ #:when (exact-integer? (syntax-e v)) - (Quote (syntax-e v))] [_ #:when (boolean? (syntax-e v)) (Quote (syntax-e v))] [_ #:when (keyword? (syntax-e v)) (Quote (syntax-e v))] [(~or (~datum +inf.0) (~datum -inf.0) (~datum nan.0)) (Quote (syntax-e v))] - [_ #:when (real? (syntax-e v)) (Quote (syntax-e v))] - [_ #:when (complex? (syntax-e v)) #f] [_ #:when (char? (syntax-e v)) (Quote (syntax-e v))] [_ #:when (regexp? (syntax-e v)) @@ -458,7 +460,7 @@ (define (to-absyn/top stx) (to-absyn stx)) -(define (do-expand stx in-path) +(define (do-expand stx) ;; error checking (syntax-parse stx [((~and mod-datum (~datum module)) n:id lang:expr . rest) @@ -490,21 +492,12 @@ (read-accept-lang #t) (define full-path (path->complete-path (actual-module-path in-path))) (parameterize ([current-directory (path-only full-path)]) - (do-expand (open-read-module in-path) in-path))) + (do-expand (open-read-module in-path)))) (define (read-and-expand-module input) (read-accept-reader #t) (read-accept-lang #t) - ;; Just give it any name for now - (define full-path - (match (object-name input) - ['stdin (main-source-file)] - [v (path->complete-path v)])) - (define new-cwd (if full-path - (path-only full-path) - (current-directory))) - (parameterize ([current-directory new-cwd]) - (do-expand (read-syntax (object-name input) input) full-path))) + (do-expand (read-syntax (object-name input) input))) ;;;---------------------------------------------------------------------------- ;;; Flatten Phases in Module @@ -994,4 +987,3 @@ (check-equal? (map syntax-e (get-quoted-bindings test-mod-1)) '(internal-func)))) - diff --git a/racketscript-compiler/racketscript/compiler/ident.rkt b/racketscript-compiler/racketscript/compiler/ident.rkt index b9f13a08..10a6aa62 100644 --- a/racketscript-compiler/racketscript/compiler/ident.rkt +++ b/racketscript-compiler/racketscript/compiler/ident.rkt @@ -4,7 +4,6 @@ racket/format racket/match racket/set - racket/string typed/rackunit "config.rkt") @@ -35,14 +34,17 @@ [(false? (should-rename? ss)) ss] [(reserved-keyword? s) (~a "r" ss)] - [else + [else + (match-define (cons ch-first ch-rest) (string->list ss)) - (string-append - (normalize-symbol-atom ch-first #t ignores) (apply string-append - (map (λ ([ch : Char]) - (normalize-symbol-atom ch #f ignores)) - ch-rest)))])) + (cons (normalize-symbol-atom ch-first #t ignores) + (let loop : (Listof String) ([ss : (Listof Char) ch-rest]) + (match ss + [(list) null] + [(list* "-" ">" rst) (cons "_to_" (loop rst))] + [(list* c rst) (cons (normalize-symbol-atom c #f ignores) (loop rst))]))))])) + (module+ test (check-equal? (normalize-symbol '7am) "_7am") (check-equal? (normalize-symbol 'foobar) "foobar") diff --git a/racketscript-compiler/racketscript/compiler/il-analyze.rkt b/racketscript-compiler/racketscript/compiler/il-analyze.rkt index 6218054b..f6bb7ebe 100644 --- a/racketscript-compiler/racketscript/compiler/il-analyze.rkt +++ b/racketscript-compiler/racketscript/compiler/il-analyze.rkt @@ -1,13 +1,13 @@ #lang typed/racket/base -(require racket/match +(require racket/bool racket/list + racket/match racket/set - racket/bool "environment.rkt" + "il.rkt" "language.rkt" - "util.rkt" - "il.rkt") + "util.rkt") (provide self-tail->loop lift-returns diff --git a/racketscript-compiler/racketscript/compiler/il.rkt b/racketscript-compiler/racketscript/compiler/il.rkt index b16f6dd7..f44973a2 100644 --- a/racketscript-compiler/racketscript/compiler/il.rkt +++ b/racketscript-compiler/racketscript/compiler/il.rkt @@ -1,7 +1,7 @@ #lang typed/racket/base -(require racket/match - racket/list +(require racket/list + racket/match "absyn.rkt" "language.rkt") diff --git a/racketscript-compiler/racketscript/compiler/js-support/babel-webpack/gulpfile.js b/racketscript-compiler/racketscript/compiler/js-support/babel-webpack/gulpfile.js deleted file mode 100644 index b1acc5be..00000000 --- a/racketscript-compiler/racketscript/compiler/js-support/babel-webpack/gulpfile.js +++ /dev/null @@ -1,48 +0,0 @@ -const gulp = require('gulp'); -const babel = require('gulp-babel'); -const replace = require('gulp-replace'); -const uglify = require('gulp-uglify'); -const webpackStream = require('webpack-stream'); -const webpack = require('webpack'); -//const BabiliPlugin = require("babili-webpack-plugin"); - -const target = "~a" + ".rkt.js"; - -gulp.task('copy-hamt', function() { - return gulp.src('node_modules/hamt_plus/hamt.js') - .pipe(replace(/\/\* Export(.*\n)*/m, "\nexport {hamt}")) - .pipe(gulp.dest("runtime/third-party/")); -}); - -gulp.task('transform', gulp.series('copy-hamt', function() { - return gulp.src(['./**/*.js', - '!./node_modules/**', - '!./dist/**', - '!./*.js']) - .pipe(webpackStream({ - watch: false, - module: { - loaders: [ - { - test: /\.js$/, - exclude: /(node_modules|bower_components)/, - loader: 'babel-loader', - query: { - presets: ["env"], - } - } - ] - - }, - plugins: [new webpack.optimize.UglifyJsPlugin() - /* new BabiliPlugin() (BabaliWebpackPlugin) */], - output: { - filename: 'compiled.js' - } - })) - .pipe(gulp.dest('dist')); -})); - -gulp.task('build', gulp.series('transform', function () {})); - -gulp.task('default', gulp.series('build', function () {})); diff --git a/racketscript-compiler/racketscript/compiler/js-support/babel-webpack/package.json b/racketscript-compiler/racketscript/compiler/js-support/babel-webpack/package.json deleted file mode 100644 index 048fa186..00000000 --- a/racketscript-compiler/racketscript/compiler/js-support/babel-webpack/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "racketscript", - "version": "0.0.1", - "description": "Package JavaScript compiled from RacketScript (Racket->JS compiler)", - "main": "./dist/compiled.js", - "repository": { - "type": "git", - "url": "https://github.com/vishesh/racketscript" - }, - "keywords": [ - "racket", - "compiler" - ], - "author": "Vishesh Yadav", - "bugs": { - "url": "https://github.com/vishesh/racketscript/issues" - }, - "dependencies": { - "gulp": "^4.0.2", - "gulp-replace": "*", - "gulp-babel": "*", - "gulp-uglify": "*", - "hamt_plus": "*", - "babel-core": "*", - "babel-plugin-transform-runtime": "*", - "babel-preset-env": "*", - "webpack-stream": "*", - "babel-loader": "*" - } -} diff --git a/racketscript-compiler/racketscript/compiler/js-support/babel/gulpfile.js b/racketscript-compiler/racketscript/compiler/js-support/babel/gulpfile.js index 293b0bfa..10f44dcd 100644 --- a/racketscript-compiler/racketscript/compiler/js-support/babel/gulpfile.js +++ b/racketscript-compiler/racketscript/compiler/js-support/babel/gulpfile.js @@ -1,28 +1,21 @@ const gulp = require('gulp'); const babel = require('gulp-babel'); -const replace = require('gulp-replace'); const uglify = require('gulp-uglify'); const target = "~a" + ".rkt.js"; -gulp.task('copy-hamt', function() { - return gulp.src('node_modules/hamt_plus/hamt.js') - .pipe(replace(/\/\* Export(.*\n)*/m, "\nexport {hamt}")) - .pipe(gulp.dest("runtime/third-party/")); -}); - -gulp.task('transform', gulp.series('copy-hamt', function() { +gulp.task('transform', function() { return gulp.src(['./**/*.js', - '!./node_modules/**', - '!./dist/**', - '!./*.js']) - .pipe(babel({ - presets: ["@babel/preset-env"], - plugins: ["@babel/plugin-transform-runtime"] - })) - .pipe(uglify()) - .pipe(gulp.dest('dist')); -})); + '!./node_modules/**', + '!./dist/**', + '!./*.js']) + .pipe(babel({ + presets: ["@babel/preset-env"], + plugins: ["@babel/plugin-transform-runtime"] + })) + .pipe(uglify()) + .pipe(gulp.dest('dist')); +}); gulp.task('build', gulp.series('transform', function (done) { done(); diff --git a/racketscript-compiler/racketscript/compiler/js-support/babel/package.json b/racketscript-compiler/racketscript/compiler/js-support/babel/package.json index 033b3539..f97a2b0b 100644 --- a/racketscript-compiler/racketscript/compiler/js-support/babel/package.json +++ b/racketscript-compiler/racketscript/compiler/js-support/babel/package.json @@ -1,26 +1,10 @@ { "name": "racketscript", "version": "0.0.1", - "description": "Package JavaScript compiled from RacketScript (Racket->JS compiler)", - "main": "./dist/compiled.js", - "repository": { - "type": "git", - "url": "https://github.com/vishesh/racketscript" - }, - "keywords": [ - "racket", - "compiler" - ], - "author": "Vishesh Yadav", - "bugs": { - "url": "https://github.com/vishesh/racketscript/issues" - }, "dependencies": { "gulp": "^4.0.2", - "gulp-replace": "*", "gulp-babel": "^8.0.0", "gulp-uglify": "*", - "hamt_plus": "*", "@babel/core": "^7.9.0", "@babel/runtime": "^7.9.0", "@babel/preset-env": "^7.9.5", diff --git a/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/gulpfile.js b/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/gulpfile.js index 61840ff6..a3d452ea 100644 --- a/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/gulpfile.js +++ b/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/gulpfile.js @@ -1,21 +1,14 @@ const gulp = require('gulp'); -const replace = require('gulp-replace'); var closureCompiler = require('google-closure-compiler').gulp(); const target = "~a" + ".rkt.js"; -gulp.task('copy-hamt', function() { - return gulp.src('node_modules/hamt_plus/hamt.js') - .pipe(replace(/\/\* Export(.*\n)*/m, "\nexport {hamt}")) - .pipe(gulp.dest("runtime/third-party/")); -}); - -gulp.task('build', gulp.series('copy-hamt', function() { +gulp.task('build', function() { return gulp.src(['./**/*.js', - '!./node_modules/**', - '!./dist/**', - '!./*.js']) - .pipe(closureCompiler({ + '!./node_modules/**', + '!./dist/**', + '!./*.js']) + .pipe(closureCompiler({ compilation_level: 'SIMPLE', warning_level: 'VERBOSE', language_in: 'ECMASCRIPT6_STRICT', @@ -24,8 +17,6 @@ gulp.task('build', gulp.series('copy-hamt', function() { js_output_file: 'compiled.js' })) .pipe(gulp.dest('dist')); -})); +}); gulp.task('default', gulp.series('build', function () {})); - - diff --git a/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/package.json b/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/package.json index 80e71259..674fb8c5 100644 --- a/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/package.json +++ b/racketscript-compiler/racketscript/compiler/js-support/closure-compiler/package.json @@ -1,24 +1,8 @@ { "name": "racketscript", "version": "0.0.1", - "description": "Package JavaScript compiled from RacketScript (Racket->JS compiler)", - "main": "./dist/compiled.js", - "repository": { - "type": "git", - "url": "https://github.com/vishesh/racketscript" - }, - "keywords": [ - "racket", - "compiler" - ], - "author": "Vishesh Yadav", - "bugs": { - "url": "https://github.com/vishesh/racketscript/issues" - }, "dependencies": { - "gulp": "^4.0.2", - "gulp-replace": "*", - "hamt_plus": "*", - "google-closure-compiler": "*" + "gulp": "^4.0.2", + "google-closure-compiler": "*" } } diff --git a/racketscript-compiler/racketscript/compiler/js-support/plain/package.json b/racketscript-compiler/racketscript/compiler/js-support/plain/package.json new file mode 100644 index 00000000..4890ebeb --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/js-support/plain/package.json @@ -0,0 +1,5 @@ +{ + "name": "racketscript", + "version": "0.0.1", + "type": "module" +} diff --git a/racketscript-compiler/racketscript/compiler/js-support/traceur-browser b/racketscript-compiler/racketscript/compiler/js-support/traceur-browser deleted file mode 120000 index f71ecd0e..00000000 --- a/racketscript-compiler/racketscript/compiler/js-support/traceur-browser +++ /dev/null @@ -1 +0,0 @@ -traceur \ No newline at end of file diff --git a/racketscript-compiler/racketscript/compiler/js-support/traceur/bootstrap.js b/racketscript-compiler/racketscript/compiler/js-support/traceur/bootstrap.js deleted file mode 100644 index b504d999..00000000 --- a/racketscript-compiler/racketscript/compiler/js-support/traceur/bootstrap.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Bootstrap Rapture in NodeJS - */ - -var traceur = require('traceur'); - -traceur.require.makeDefault(function(filename) { - // don't transpile our dependencies, just our app - return filename.indexOf('node_modules') === -1; -}); - -require('./dist/compiled.js'); diff --git a/racketscript-compiler/racketscript/compiler/js-support/traceur/gulpfile.js b/racketscript-compiler/racketscript/compiler/js-support/traceur/gulpfile.js deleted file mode 100644 index ec8ccf1d..00000000 --- a/racketscript-compiler/racketscript/compiler/js-support/traceur/gulpfile.js +++ /dev/null @@ -1,25 +0,0 @@ -const gulp = require('gulp'); -const traceur = require('gulp-traceur-cmdline'); -const concat = require('gulp-concat'); -const replace = require('gulp-replace'); -const uglify = require('gulp-uglify'); - -const target = "~a" + ".rkt.js"; - -gulp.task('copy-hamt', function() { - return gulp.src('node_modules/hamt_plus/hamt.js') - .pipe(replace(/\/\* Export(.*\n)*/m, "\nexport {hamt}")) - .pipe(gulp.dest("runtime/third-party/")); -}); - -gulp.task('build', gulp.series('copy-hamt', function() { - return gulp.src('modules/' + target) - .pipe(traceur({modules: 'inline', outputLanguage: 'es6'})) - .pipe(concat('compiled.js')) - //.pipe(uglify()) - .pipe(gulp.dest('dist')); -})); - -gulp.task('default', gulp.series('build', function (done) { - done(); -})); diff --git a/racketscript-compiler/racketscript/compiler/js-support/traceur/index.html b/racketscript-compiler/racketscript/compiler/js-support/traceur/index.html deleted file mode 100644 index a5f83117..00000000 --- a/racketscript-compiler/racketscript/compiler/js-support/traceur/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - RacketScript - - - - - - - diff --git a/racketscript-compiler/racketscript/compiler/js-support/traceur/package.json b/racketscript-compiler/racketscript/compiler/js-support/traceur/package.json deleted file mode 100644 index 969541e2..00000000 --- a/racketscript-compiler/racketscript/compiler/js-support/traceur/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "racketscript", - "version": "0.0.1", - "description": "Package JavaScript compiled from RacketScript (Racket->JS compiler)", - "main": "./dist/compiled.js", - "repository": { - "type": "git", - "url": "https://github.com/vishesh/racketscript" - }, - "keywords": [ - "racket", - "compiler" - ], - "author": "Vishesh Yadav", - "bugs": { - "url": "https://github.com/vishesh/racketscript/issues" - }, - "dependencies": { - "gulp": "^4.0.2", - "gulp-concat": "*", - "gulp-traceur-cmdline": "*", - "gulp-replace": "*", - "gulp-uglify": "*", - "hamt_plus": "*", - "traceur": "*" - } -} diff --git a/racketscript-compiler/racketscript/compiler/js-support/webpack/package.json b/racketscript-compiler/racketscript/compiler/js-support/webpack/package.json new file mode 100644 index 00000000..2124bcc9 --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/js-support/webpack/package.json @@ -0,0 +1,12 @@ +{ + "name": "racketscript", + "version": "0.0.1", + "type": "module", + "dependencies": { + "util": "*" + }, + "devDependencies": { + "webpack": "^5.38.1", + "webpack-cli": "^4.7.2" + } +} diff --git a/racketscript-compiler/racketscript/compiler/js-support/webpack/webpack.config.js b/racketscript-compiler/racketscript/compiler/js-support/webpack/webpack.config.js new file mode 100644 index 00000000..e6ed2fde --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/js-support/webpack/webpack.config.js @@ -0,0 +1,14 @@ +import webpack from 'webpack'; +const target = "./modules/~a" + ".rkt.js"; + +export default { + entry: target, + output: { + filename: 'main.js', + }, + mode: "production", + target: "web", + experiments: { + topLevelAwait: true + } +}; diff --git a/racketscript-compiler/racketscript/compiler/language.rkt b/racketscript-compiler/racketscript/compiler/language.rkt index 34427142..934a1921 100644 --- a/racketscript-compiler/racketscript/compiler/language.rkt +++ b/racketscript-compiler/racketscript/compiler/language.rkt @@ -2,10 +2,8 @@ (provide define-language) -(require racket/struct - (for-syntax syntax/parse - syntax/parse/experimental/template - racket/syntax +(require (for-syntax racket/syntax + syntax/parse syntax/stx)) ;; Identifier -> Identifer diff --git a/racketscript-compiler/racketscript/compiler/logging.rkt b/racketscript-compiler/racketscript/compiler/logging.rkt index e0aa8822..c2170412 100644 --- a/racketscript-compiler/racketscript/compiler/logging.rkt +++ b/racketscript-compiler/racketscript/compiler/logging.rkt @@ -1,10 +1,10 @@ #lang racket/base -(require "config.rkt" - (for-syntax syntax/parse - racket/base - racket/syntax) - (for-meta 2 syntax/parse)) +(require (for-syntax racket/base + racket/syntax + syntax/parse) + (for-meta 2 syntax/parse) + "config.rkt") (provide log-rjs-info log-rjs-debug diff --git a/racketscript-compiler/racketscript/compiler/main.rkt b/racketscript-compiler/racketscript/compiler/main.rkt index 801a5ad1..734aed99 100644 --- a/racketscript-compiler/racketscript/compiler/main.rkt +++ b/racketscript-compiler/racketscript/compiler/main.rkt @@ -1,30 +1,27 @@ #lang racket/base -(require racket/bool +(require data/queue + racket/bool racket/cmdline racket/file racket/format - racket/match racket/list + racket/match racket/path racket/port racket/pretty - racket/runtime-path + racket/serialize racket/set racket/system - racket/serialize syntax/moddep - - data/queue threading - "absyn.rkt" - "il.rkt" - "il-analyze.rkt" "assembler.rkt" "config.rkt" "expand.rkt" "global.rkt" + "il-analyze.rkt" + "il.rkt" "logging.rkt" "moddeps.rkt" "transform.rkt" @@ -36,33 +33,27 @@ prepare-build-directory racket->js racketscript-dir - skip-gulp-build skip-npm-install enabled-optimizations - recompile-all-modules?) + recompile-all-modules? + use-scheme-numbers?) (define build-mode (make-parameter 'complete)) (define skip-npm-install (make-parameter #f)) -(define skip-gulp-build (make-parameter #f)) -(define js-output-file (make-parameter "compiled.js")) (define js-output-beautify? (make-parameter #f)) (define enabled-optimizations (make-parameter (set))) (define input-from-stdin? (make-parameter #f)) (define recompile-all-modules? (make-parameter #f)) -(define *js-bootstrap-file* "bootstrap.js") -(define *browser-index-file* "index.html") - ;; Compiler for ES6 to ES5 compilation. +;; - "plain" ;; - "babel" -;; - "traceur" ;; - "webpack" ;;TODO -(define *targets* (list "traceur" - "traceur-browser" +(define *targets* (list "plain" "babel" - "babel-webpack" + "webpack" "closure-compiler")) -(define js-target (make-parameter "traceur")) +(define js-target (make-parameter "plain")) ;; Path-String -> Path ;; Return path of support file named f @@ -122,36 +113,26 @@ (format-copy-file src (build-path dest-dir name) args)) ;; String -> Void -;; Puts a NPM and Gulp related files in output directory -;; with default-module set as the entry point module +;; Puts a NPM related files in output directory with default-module set as the +;; entry point module ;; ;; default-module is just the name of module excluding any file ;; extensions. (define (copy-build-files default-module) (copy-file+ (support-file "package.json") (output-directory)) - (format-copy-file+ (support-file "gulpfile.js") - (output-directory) - (list default-module))) + (when (equal? (js-target) "webpack") + (format-copy-file+ (support-file "webpack.config.js") + (output-directory) + (list default-module)))) ;; -> Void (define (copy-runtime-files) (copy-directory (build-path racketscript-dir "compiler" "runtime") (output-directory))) -;; -> Void -(define (copy-support-files) - (match (js-target) - ["traceur" - (copy-file+ (support-file *js-bootstrap-file*) - (output-directory))] - ["traceur-browser" - (copy-file+ (support-file *browser-index-file*) - (output-directory))] - [_ (void)])) - ;; String -> Void -;; Create output build directory tree with all NPM, Gulp. Runtime and +;; Create output build directory tree with all NPM, runtime and ;; other support files ;; ;; default-module-name: is just the name of entry point module with @@ -167,21 +148,15 @@ (make-directory* (build-path dir "modules"))) (copy-build-files default-module-name) - (copy-runtime-files) - (copy-support-files)) + (copy-runtime-files)) ;; -> Void -;; Install and build dependenciese to translate ES5 to ES5 -(define (es6->es5) +;; Install and build dependencies +(define (npm-install-build) ;; TODO: Use NPM + some build tool to do this cleanly (parameterize ([current-directory (output-directory)]) (unless (skip-npm-install) - (system "npm install")) - (unless (skip-gulp-build) - (system (~a "./" - (build-path "node_modules" - ".bin" - "gulp")))))) + (system "npm install")))) ;;;; Generate stub module @@ -247,72 +222,80 @@ (= (get-module-timestamp ts mod) (file-or-directory-modify-seconds (actual-module-path mod))))) -;; -> Void +;; -> (Setof Path) ;; For given global parameters starts build process starting -;; with entry point module and all its dependencies +;; with entry point module and all its dependencies. Returns +;; a set module paths that were compiled (typically ignored). (define (racket->js) (define added (mutable-set)) (define pending (make-queue)) - - ;; build directories to output build folder. - (define default-module-name (string-slice (~a (last-path-element - (main-source-file))) - 0 -4)) - (prepare-build-directory default-module-name) - (define (put-to-pending! mod) (unless (set-member? added mod) (set-add! added mod) (enqueue! pending mod))) - (define timestamps (load-cached-module-timestamps)) + (define default-module-name (string-slice (~a (last-path-element + (main-source-file))) + 0 -4)) + (prepare-build-directory default-module-name) (put-to-pending! (path->complete-path (main-source-file))) (for ([pm primitive-modules]) (put-to-pending! pm)) - (let loop () - (define next (and (non-empty-queue? pending) (dequeue! pending))) - (cond - [(and next (skip-module-compile? timestamps next)) - (log-rjs-info (~a "Skipping " next)) - (loop)] - [next - (current-source-file next) - (make-directory* (path-only (module-output-file next))) - (save-module-timestamp! timestamps next) - - (define expanded (quick-expand next)) - (define ast (convert expanded (override-module-path next))) - - (assemble-module (insert-arity-checks - (absyn-module->il* ast)) - #f) - - ;; Run JS beautifier - (when (js-output-beautify?) - (system (format "js-beautify -r ~a" (module-output-file next)))) - - (for ([mod (in-set (Module-imports ast))]) - (match mod - [(? symbol? _) (void)] - [_ #:when (collects-module? mod) (void) (put-to-pending! mod)] - [_ (put-to-pending! mod)])) - (loop)] - [(false? next) - (dump-module-timestamps! timestamps) - (log-rjs-info "Compiling ES6 to ES5.") - (es6->es5) - (log-rjs-info "Finished.")]))) + (define timestamps (load-cached-module-timestamps)) + (for ([(mod timestamp) timestamps]) + (when (not (skip-module-compile? timestamps mod)) + (put-to-pending! mod))) + + (define compiled-modules + (for/set ([next (in-queue pending)] + #:unless (and (skip-module-compile? timestamps next) + (log-rjs-info (~a "Skipping " next)))) + + (current-source-file next) + (make-directory* (path-only (module-output-file next))) + (save-module-timestamp! timestamps next) + + (define expanded (quick-expand next)) + (define ast (convert expanded (override-module-path next))) + (assemble-module (insert-arity-checks + (absyn-module->il* ast)) + #f) + + (when (js-output-beautify?) + (system (format "js-beautify -r ~a" (module-output-file next)))) + + (for ([mod (in-set (Module-imports ast))]) + (match mod + [(? symbol? _) (void)] + [_ #:when (collects-module? mod) (put-to-pending! mod)] + [_ (put-to-pending! mod)])) + + next)) + + (dump-module-timestamps! timestamps) + (unless (equal? (js-target) "plain") + (log-rjs-info "Running NPM [Install/Build].") + (npm-install-build)) + (log-rjs-info "Finished.") + compiled-modules) ;; String -> String (define (js-string-beautify js-str) (match-define (list in-p-out out-p-in pid in-p-err control) (process* (~a (find-executable-path "js-beautify")))) - (print js-str out-p-in) + + (display js-str out-p-in) (close-output-port out-p-in) + (control 'wait) - (port->string in-p-out)) + (define result (port->string in-p-out)) + + (close-input-port in-p-out) + (close-input-port in-p-err) + + result) (define (parse-command-line) (command-line @@ -321,7 +304,6 @@ #:once-each [("-d" "--build-dir") dir "Output directory" (output-directory (simplify-path dir))] [("-n" "--skip-npm-install") "Skip NPM install phase" (skip-npm-install #t)] - [("-g" "--skip-gulp-build") "Skip Gulp build phase" (skip-gulp-build #t)] [("-b" "--js-beautify") "Beautify JS output" (js-output-beautify? #t)] [("-r" "--force-recompile") "Re-compile all modules" (recompile-all-modules? #t)] ["--skip-arity-checks" "Skip arity checks in beginning of functions" (skip-arity-checks? #t)] @@ -333,11 +315,13 @@ (enabled-optimizations (set-add (enabled-optimizations) flatten-if-else))] ["--lift-returns" "Translate self tail calls to loops" (enabled-optimizations (set-add (enabled-optimizations) lift-returns))] + ["--scheme-numbers" "Use Scheme number semantics" + (use-scheme-numbers? #t)] #:multi - [("-t" "--target") target "ES6 to ES5 compiler [traceur|babel|traceur-browser|closure-compiler|babel-webpack]" + [("-t" "--target") target "Build target environment [plain|webpack|closure-compiler|babel]" (if (member target *targets*) (js-target target) - (error "`~a` is not a supported target."))] + (error "Unexpected target: " target))] #:once-any ["--expand" "Fully expand Racket source" (build-mode 'expand)] ["--ast" "Expand and print AST" (build-mode 'absyn)] @@ -383,25 +367,30 @@ (log-rjs-info "RacketScript root directory: ~a" racketscript-dir)) (unless (input-from-stdin?) - ;; Initialize global-export-graph so that we can import each - ;; module as an object and follow identifier's from there. - ;; For stdin builds, we have to defer this operation. + ;; Initialize global-export-graph so that we can import each module as an + ;; object and follow identifier's from there. For stdin builds, we have to + ;; defer this operation. (unless (equal? (build-mode) 'js) ;; As 'js mode prints output to stdout, we don't want to mix (log-rjs-info "Resolving module dependencies and identifiers... ")) - (global-export-graph (get-export-tree source))) + (global-export-graph (get-export-tree (list source)))) (define (expanded-module) (cond [(input-from-stdin?) - ;; HACK: Just make an stupid guess that all that we will - ;; ever use will come from standard library. Since we - ;; need stdin from playground, its fine for now. - ;; TODO: Figure out a way to compile this syntax to - ;; module code bytecode - (global-export-graph (get-export-tree (build-path racketscript-compiler-dir - "nothing.rkt"))) - (read-and-expand-module (current-input-port))] + (parameterize ([current-namespace (make-base-namespace)]) + (define expanded-mod (read-and-expand-module (current-input-port))) + (eval expanded-mod) + + ;; Prepare the module graph for each import. We don't care about, exports + ;; from here, as this module will never be imported. + (match (module->imports ''anonymous-module) + [`((0 ,mods ...) rst ...) + ;; TODO: Do we need to look at other phase imports? + (global-export-graph (get-export-tree (map resolve-module-path-index mods)))] + [_ (error "unexpected form returned by module->imports")]) + + expanded-mod)] [else (quick-expand source)])) @@ -429,6 +418,34 @@ (if (js-output-beautify?) (js-string-beautify (get-output-string output-string)) (get-output-string output-string)))] - ['complete (racket->js)]) - - (void)) + ['complete (racket->js) (void)])) + +(module+ test + (require rackunit) + + (define tests-dir (normalize-path (build-path racketscript-dir + 'up 'up + "tests"))) + + (test-case "check stale dependency compilation" + (define dep-cache-dir (build-path tests-dir "dep-cache")) + (define has-dependency (build-path dep-cache-dir + "has-dependency.rkt")) + (define dependency (normalize-path (build-path tests-dir + "dep-cache" + "private" + "dependency.rkt"))) + (parameterize ([main-source-file has-dependency] + [global-export-graph (get-export-tree (list has-dependency))] + [current-source-file has-dependency] + [recompile-all-modules? #f] + [current-output-port (open-output-nowhere)]) + (file-or-directory-modify-seconds dependency 100) + (racket->js) + ;; Change dependency's modification time to simulate + ;; an edit to the source file. + (file-or-directory-modify-seconds dependency 200) + (check-true (set-member? (racket->js) + dependency) + "stale dependency not recompiled.")) + (delete-directory/files (output-directory)))) diff --git a/racketscript-compiler/racketscript/compiler/moddeps.rkt b/racketscript-compiler/racketscript/compiler/moddeps.rkt index 5c088093..eb3b5aed 100644 --- a/racketscript-compiler/racketscript/compiler/moddeps.rkt +++ b/racketscript-compiler/racketscript/compiler/moddeps.rkt @@ -1,7 +1,7 @@ #lang racket -(require syntax/moddep - graph +(require graph + syntax/moddep threading "config.rkt" "util.rkt") @@ -71,12 +71,12 @@ [#f (result src* id*)] ['() #f])))) -;; ModulePath -> ExportTree +;; (Listof ModulePath) -> ExportTree ;; Return whole tree of exports with its source starting -;; from mod-name (ModulePath) -(define (get-export-tree mod-name) +;; with given list of modules 'mods'. +(define (get-export-tree mods) (define modules (filter-not symbol? (module-deps/tsort-inv - (get-module-deps mod-name)))) + (get-module-deps mods)))) (for/hash ([m (append (set->list primitive-modules) modules)]) (values m (get-exports/modpath m)))) @@ -129,9 +129,9 @@ (transpose _) (tsort _))) -;; Path -> (Map Path (Listof Path)) -;; Returns a adjecency map of module imports -(define (get-module-deps mod-path) +;; (Listof Path) -> (Map Path (Listof Path)) +;; Returns a adjacency map of module imports. +(define (get-module-deps mod-paths) (define graph (make-hash)) (define (build-graph mod-path) (define path (resolve-module-path mod-path #f)) @@ -150,5 +150,7 @@ (hash-update! graph path (λ (v) (cons new-mod v))) (unless (hash-ref graph new-mod #f) (build-graph new-mod))])))) - (build-graph mod-path) + (for ([path mod-paths]) + (build-graph path)) + graph) diff --git a/racketscript-compiler/racketscript/compiler/nothing.rkt b/racketscript-compiler/racketscript/compiler/nothing.rkt deleted file mode 100644 index fce67bc8..00000000 --- a/racketscript-compiler/racketscript/compiler/nothing.rkt +++ /dev/null @@ -1,3 +0,0 @@ -#lang racket - -(require "../interop.rkt") diff --git a/racketscript-compiler/racketscript/compiler/runtime/core.js b/racketscript-compiler/racketscript/compiler/runtime/core.js index 379c0f0a..abbaeb75 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core.js @@ -1,5 +1,6 @@ // Exports classes for creating basic data types and operation on them +import { PrintablePrimitive } from './core/printable_primitive.js'; import * as Box from './core/box.js'; import * as Bytes from './core/bytes.js'; import * as Char from './core/char.js'; @@ -7,17 +8,19 @@ import * as UString from './core/unicode_string.js'; import * as Regexp from './core/regexp.js'; import * as Hash from './core/hash.js'; import * as Keyword from './core/keyword.js'; -import * as Number from './core/numbers.js'; +import * as Number from './core/numbers/numbers.js'; import * as Pair from './core/pair.js'; import * as Ports from './core/ports.js'; import * as Primitive from './core/primitive.js'; +import * as PrimitiveSymbol from './core/primitive_symbol.js'; import * as Struct from './core/struct.js'; -import * as Symbol from './core/symbol.js'; import * as Values from './core/values.js'; import * as Vector from './core/vector.js'; import * as Marks from './core/marks.js'; import * as MPair from './core/mpair.js'; - +import * as Correlated from './core/correlated.js'; +import * as Linklet from './core/linklet.js'; +import * as Path from './core/path.js'; export { Bytes, @@ -26,7 +29,7 @@ export { Pair, Primitive, Struct, - Symbol, + PrimitiveSymbol, Keyword, Values, Vector, @@ -36,47 +39,34 @@ export { Ports, UString, Regexp, - MPair + MPair, + Correlated, + Linklet, + Path }; -export { - argumentsToArray, - argumentsSlice -} from './core/lib.js'; +export { argumentsToArray, argumentsSlice } from './core/lib.js'; export { racketCoreError, racketContractError, makeArgumentError, + makeResultError, makeArgumentsError, makeMismatchError, makeOutOfRangeError, isContractErr, + isErr, errMsg } from './core/errors.js'; -export { - attachProcedureArity, - attachProcedureName -} from './core/procedure.js'; +export { attachProcedureArity, attachProcedureName } from './core/procedure.js'; -export { - isEq, - isEqv, - isEqual -} from './core/equality.js'; +export { isEq, isEqv, isEqual } from './core/equality.js'; -export { - hashForEq, - hashForEqv, - hashForEqual -} from './core/hashing.js'; +export { hashForEq, hashForEqv, hashForEqual } from './core/hashing.js'; -export { - display, - write, - print -} from './core/printing.js'; +export { display, write, print } from './core/printing.js'; // ;----------------------------------------------------------------------------- @@ -85,49 +75,45 @@ export function bitwiseNot(a) { } class UnsafeUndefined extends PrintablePrimitive { - constructor () { - super(); - } - equals(v) { - return (v === this); + return v === this; } /** - * @return {!number} a 32-bit integer - */ + * @return {!number} a 32-bit integer + */ hashForEqual() { return 0; } /** - * @param {!Ports.NativeStringOutputPort} out - */ + * @param {!Ports.NativeStringOutputPort} out + */ displayNativeString(out) { out.consume('#'); } /** - * @param {!Ports.UStringOutputPort} out - */ + * @param {!Ports.UStringOutputPort} out + */ displayUString(out) { out.consume('#'); } /** - * @param {!Ports.NativeStringOutputPort} out - */ + * @param {!Ports.NativeStringOutputPort} out + */ writeNativeString(out) { out.consume('#'); } /** - * @param {!Ports.UStringOutputPort} out - */ + * @param {!Ports.UStringOutputPort} out + */ writeUString(out) { out.consume('#'); } - } -const the_unsafe_undefined = new UnsafeUndefined(); +// eslint-disable-next-line no-unused-vars +export const theUnsafeUndefined = new UnsafeUndefined(); diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/bytes.js b/racketscript-compiler/racketscript/compiler/runtime/core/bytes.js index df816575..6d2499e9 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/bytes.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/bytes.js @@ -1,10 +1,5 @@ import { hashIntArray } from './raw_hashing.js'; -// In node.js, TextDecoder is not global and needs to be imported. -const TextDecoder = (typeof window === 'undefined') - ? require('util').TextDecoder - : window.TextDecoder; // eslint-disable-line no-undef - /** * @param {*} bs * @return {!boolean} @@ -14,6 +9,51 @@ export function check(bs) { bs.constructor === Uint8Array; } +/** + * @param {!number} non-negative int length + * @param {!number} non-negative int less than 256 + * @return {!Uint8Array} + */ +export function make(len, init) { + return new Uint8Array(len).fill(init); +} + +/** + * + * @param {!Uint8Array} bs + * @param {!number} + * @return {!number} + */ +export function ref(bs, i) { + return bs[i]; +} + + +/** + * + * @param Array of {!Uint8Array} + * @return {!Uint8Array} + */ +export function append(bss) { + let size = 0; + bss.forEach((bs) => { size += bs.length; }); + const res = new Uint8Array(size); + let i = 0; + bss.forEach((bs) => { res.set(bs, i); i += bs.length; }); + return res; +} + +/** + * + * @param {!Uint8Array} bs + * @param {!number} + * @param {!number} non-negative int less than 256 + * @return {!number} + */ +export function set(bs, i, b) { + bs[i] = b; +} + /** * * @param {!Uint8Array} a @@ -87,6 +127,7 @@ export function fromIntArray(ints) { } const utf8Decoder = new TextDecoder('utf-8'); +const latin1Decoder = new TextDecoder('latin1'); /** * @param {!Uint8Array} bytes @@ -96,6 +137,14 @@ export function toString(bytes) { return utf8Decoder.decode(bytes); } +/** + * @param {!Uint8Array} bytes + * @return {!String} + */ +export function toLatin1String(bytes) { + return latin1Decoder.decode(bytes); +} + /** * Writes a string representation similar to Racket's `display` to the given port. * @@ -106,6 +155,18 @@ export function displayNativeString(out, bytes) { out.consume(toString(bytes)); } +/** + * Writes a string representation similar to Racket's `print` to the given port. + * + * @param {!Ports.NativeStringOutputPort} out + * @param {!Uint8Array} bytes + */ +export function printNativeString(out, bytes) { + out.consume('#"'); + out.consume(toString(bytes)); + out.consume('"'); +} + /** * @param {!Uint8Array} bytes * @return {!number} a 32-bit integer diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/char.js b/racketscript-compiler/racketscript/compiler/runtime/core/char.js index 134099a2..6b864f89 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/char.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/char.js @@ -183,6 +183,12 @@ export function check(char) { char.constructor === Char; } +// NOTE: +// "The Racket documentation only promises `eq?` for characters with +// scalar values in the range 0 to 255, but Chez Scheme characters +// are always `eq?` when they are `eqv?`." +// see: https://groups.google.com/g/racket-users/c/LFFV-xNq1SU/m/s6eoC35qAgAJ +// https://docs.racket-lang.org/reference/characters.html /** * @param {!Char} a * @param {!Char} b @@ -229,7 +235,7 @@ export function charUtf8Length(c) { } /** - * @param {!string} str + * @param {!string} str * @return {!boolean} */ function isSingleCodePoint(str) { @@ -257,7 +263,7 @@ export function downcase(c) { } // Unicode property testing regexps. -// We use `new RegExp` because traceur crashes on `/u` RegExp literals. +// TODO (Deprecated): We use `new RegExp` because traceur crashes on `/u` RegExp literals. const IS_ALPHABETIC = new RegExp('\\p{Alphabetic}', 'u'); const IS_LOWER_CASE = new RegExp('\\p{Lowercase}', 'u'); const IS_UPPER_CASE = new RegExp('\\p{Uppercase}', 'u'); diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/check.js b/racketscript-compiler/racketscript/compiler/runtime/core/check.js index a2cf3230..d2c417cc 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/check.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/check.js @@ -13,11 +13,12 @@ export function falsy(val, exp, msg = '') { return truthy(val === false, exp, msg); } -export function type(val, type, msg = '') { - if (val instanceof type) { +// TODO: rename the function +export function type(val, typeParam, msg = '') { + if (val instanceof typeParam) { return true; } - raise(TypeError, `${msg}(${val} : ${typeof (val)} != ${type.name})`); + raise(TypeError, `${msg}(${val} : ${typeof (val)} != ${typeParam.name})`); } export function eq(val1, val2, exp, msg) { diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/correlated.js b/racketscript-compiler/racketscript/compiler/runtime/core/correlated.js new file mode 100644 index 00000000..3e137a00 --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/core/correlated.js @@ -0,0 +1,51 @@ +import { PrintablePrimitive } from './printable_primitive.js'; +import { isEqual } from './equality.js'; +import { hashForEqual } from './hashing.js'; + +class Correlated extends PrintablePrimitive { + constructor(v) { + super(); + this.value = v; + } + + equals(v) { + return isEqual(v.value, this.value); + } + + get() { return this.value; } + + /** + * @return {!number} a 32-bit integer + */ + hashForEqual() { + return hashForEqual(this.value); + } + + /** + * @param {!Ports.NativeStringOutputPort} out + */ + displayNativeString(out) { + out.consume('#'); + } +} + +export function datumToSyntax(v) { return new Correlated(v); } + +export function syntaxP(v) { return (v instanceof Correlated); } + +// TODO: implement these stubs +/* eslint no-unused-vars: ["error", { "args": "none" }] */ +export function syntaxSource(v) { return false; } + +/* eslint no-unused-vars: ["error", { "args": "none" }] */ +export function syntaxLine(v) { return false; } + +/* eslint no-unused-vars: ["error", { "args": "none" }] */ +export function syntaxColumn(v) { return false; } + +/* eslint no-unused-vars: ["error", { "args": "none" }] */ +export function syntaxPosition(v) { return false; } + +/* eslint no-unused-vars: ["error", { "args": "none" }] */ +export function syntaxSpan(v) { return false; } + diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/equality.js b/racketscript-compiler/racketscript/compiler/runtime/core/equality.js index 6bb6b80a..81be9dd6 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/equality.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/equality.js @@ -1,6 +1,12 @@ import * as Primitive from './primitive.js'; +import * as PrimitiveSymbol from './primitive_symbol.js'; import * as Char from './char.js'; import * as Bytes from './bytes.js'; +import { + isSchemeNumber, + equals as schemeEquals, + eqv as schemeEqv +} from './numbers/scheme-numbers.js'; /** * @param {*} v1 @@ -8,6 +14,10 @@ import * as Bytes from './bytes.js'; * @return {!boolean} */ export function isEq(v1, v2) { + // Handle Symbols + if (PrimitiveSymbol.check(v1)) { + return v1.equals(v2); + } return v1 === v2; } @@ -17,12 +27,17 @@ export function isEq(v1, v2) { * @return {!boolean} */ export function isEqv(v1, v2) { - // NOTE: We are not handling special case for Symbol. - // Symbols and keywords are interned, so that's ok. + if (useSchemeEquality(v1, v2)) { + return schemeEqv(v1, v2); + } + + // Handle Symbols + if (PrimitiveSymbol.check(v1)) { + return v1.equals(v2); + } // TODO: Handle numbers correctly. - return v1 === v2 || - Char.check(v1) && Char.check(v2) && Char.eq(v1, v2); + return v1 === v2 || (Char.check(v1) && Char.check(v2) && Char.eq(v1, v2)); } /** @@ -32,6 +47,11 @@ export function isEqv(v1, v2) { */ export function isEqual(v1, v2) { if (v1 === v2) return true; + + if (useSchemeEquality(v1, v2)) { + return schemeEquals(v1, v2); + } + if (Primitive.check(v1)) return v1.equals(v2); // Bytes are not a Primitive. @@ -39,3 +59,13 @@ export function isEqual(v1, v2) { return false; } + +function useSchemeEquality(v1, v2) { + if (typeof v1 === 'number' && !Number.isInteger(v1)) { + return false; + } + if (typeof v2 === 'number' && !Number.isInteger(v2)) { + return false; + } + return isSchemeNumber(v1) && isSchemeNumber(v2); +} diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/errors.js b/racketscript-compiler/racketscript/compiler/runtime/core/errors.js index 78dca079..ae6d6524 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/errors.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/errors.js @@ -37,38 +37,38 @@ function makeError(name) { e.prototype = Object.create(Error.prototype); e.prototype.constructor = e; - return (...args) => - new (Function.prototype.bind.apply(e, [this].concat(args)))(); + return (...args) => new (Function.prototype.bind.apply(e, [this].concat(args)))(); } export const racketCoreError = makeError('RacketCoreError'); export const racketContractError = makeError('RacketContractError'); export function isContractErr(e) { - return e.name !== undefined && e.name === "RacketContractError"; + return e.name !== undefined && e.name === 'RacketContractError'; } export function isErr(e) { - return e.name !== undefined && e.name === "RacketCoreError"; + return e.name !== undefined && e.name === 'RacketCoreError'; } export function errName(e) { return e.name; } -export function errMsg(e) { return e.message; } +export function errMsg(e) { return e.message; } // this must be here to avoid circular dependency with numbers.js // copied from internet: // https://gist.github.com/jlbruno/1535691/db35b4f3af3dcbb42babc01541410f291a8e8fac function toOrdinal(i) { - var j = i % 10, - k = i % 100; - if (j == 1 && k != 11) { - return i + "st"; + const j = i % 10; + const k = i % 100; + + if (j === 1 && k !== 11) { + return `${i}st`; } - if (j == 2 && k != 12) { - return i + "nd"; + if (j === 2 && k !== 12) { + return `${i}nd`; } - if (j == 3 && k != 13) { - return i + "rd"; + if (j === 3 && k !== 13) { + return `${i}rd`; } - return i + "th"; + return `${i}th`; } // format exn message to exactly match Racket raise-argument-error @@ -84,15 +84,48 @@ export function makeArgumentError(name, expected, ...rest) { if (rest.length === 1) { printNativeString(stringOut, rest[0], true, 0); } else { - printNativeString(stringOut, rest[rest[0]+1], true, 0); + printNativeString(stringOut, rest[rest[0] + 1], true, 0); + if (rest.length > 2) { // only print if there are "other" args + stringOut.consume('\n'); + stringOut.consume(' argument position: '); + printNativeString(stringOut, toOrdinal(rest[0] + 1), true, 0); + stringOut.consume('\n'); + stringOut.consume(' other arguments...:'); + for (let i = 1; i < rest.length; i++) { + // eslint-disable-next-line no-continue + if (i === rest[0] + 1) { continue; } + stringOut.consume('\n '); + printNativeString(stringOut, rest[i], true, 0); + } + } + } + + return racketContractError(stringOut.getOutputString()); +} + +// format exn message to exactly match Racket raise-result-error +export function makeResultError(name, expected, ...rest) { + const stringOut = new MiniNativeOutputStringPort(); + // "other" args must be converted to string via `print` + // (not `write` or `display`) + stringOut.consume(`${name.toString()}: contract violation\n`); + stringOut.consume(' expected: '); + stringOut.consume(expected.toString()); + stringOut.consume('\n'); + stringOut.consume(' given: '); + if (rest.length === 1) { + printNativeString(stringOut, rest[0], true, 0); + } else { + printNativeString(stringOut, rest[rest[0] + 1], true, 0); if (rest.length > 2) { // only print if there are "other" args stringOut.consume('\n'); stringOut.consume(' argument position: '); - printNativeString(stringOut, toOrdinal(rest[0]+1), true, 0); + printNativeString(stringOut, toOrdinal(rest[0] + 1), true, 0); stringOut.consume('\n'); stringOut.consume(' other arguments...:'); for (let i = 1; i < rest.length; i++) { - if (i === rest[0]+1) { continue; } + // eslint-disable-next-line no-continue + if (i === rest[0] + 1) { continue; } stringOut.consume('\n '); printNativeString(stringOut, rest[i], true, 0); } @@ -111,11 +144,11 @@ export function makeArgumentsError(name, msg, field, ...rest) { stringOut.consume(field); stringOut.consume(': '); printNativeString(stringOut, rest[0], true, 0); - for (let i = 1; i < rest.length; i=i+2) { + for (let i = 1; i < rest.length; i += 2) { stringOut.consume('\n '); stringOut.consume(rest[i]); stringOut.consume(': '); - printNativeString(stringOut, rest[i+1], true, 0); + printNativeString(stringOut, rest[i + 1], true, 0); } return racketContractError(stringOut.getOutputString()); } @@ -124,35 +157,43 @@ export function makeArgumentsError(name, msg, field, ...rest) { export function makeMismatchError(name, msg, ...rest) { if (rest.length === 0) { return racketContractError(name.toString(), msg); - } else { - const stringOut = new MiniNativeOutputStringPort(); - stringOut.consume(`${name.toString()}: `); - stringOut.consume(msg); - for (let i = 0; i < rest.length; i++) { - // //string indicates another "msg" format str, see usage above - // console.log("make-mismatch-err"); - // console.log(rest[i].name); - if (UString.check(rest[i])) { + } + const stringOut = new MiniNativeOutputStringPort(); + stringOut.consume(`${name.toString()}: `); + stringOut.consume(msg); + for (let i = 0; i < rest.length; i++) { + // //string indicates another "msg" format str, see usage above + // console.log("make-mismatch-err"); + // console.log(rest[i].name); + if (UString.check(rest[i])) { // if (true) { - stringOut.consume(rest[i]); - } else { - printNativeString(stringOut, rest[i], true, 0); - } + stringOut.consume(rest[i]); + } else { + printNativeString(stringOut, rest[i], true, 0); } - return racketContractError(stringOut.getOutputString()); } + return racketContractError(stringOut.getOutputString()); } export function makeOutOfRangeError(name, type, v, len, i) { - if (i >= len) { - if (len > 0) { - return racketContractError(`${name}: index is out of range - index: ${i} - valid range: [0, ${len - 1}] - ${type}: `, v); - } else { - return racketContractError(`${name}: index is out of range for empty ${type} - index: ${i}`); - } + const stringOut = new MiniNativeOutputStringPort(); + // "other" args must be converted to string via `print` + // (not `write` or `display`) + if (len > 0) { + stringOut.consume(`${name.toString()}: index is out of range\n`); + stringOut.consume(' index: '); + stringOut.consume(i.toString()); + stringOut.consume('\n'); + stringOut.consume(' valid range: [0, '); + stringOut.consume((len - 1).toString()); + stringOut.consume(']\n'); + stringOut.consume(' '); + stringOut.consume(type); + stringOut.consume(': '); + printNativeString(stringOut, v, true, 0); + } else { + stringOut.consume(`${name.toString()}: index is out of range for empty ${type}\n`); } + + return racketContractError(stringOut.getOutputString()); } diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/hamt.js b/racketscript-compiler/racketscript/compiler/runtime/core/hamt.js new file mode 100644 index 00000000..b690cd8d --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/core/hamt.js @@ -0,0 +1,947 @@ +// Copyright (C) 2016-2021 Matt Bierner, RacketScript Authors +// +// Original source and copyright clause: https://github.com/mattbierner/hamt_plus + +const _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' + ? function (obj) { return typeof obj; } + : function (obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype + ? 'symbol' + : typeof obj; + }; + +/** + @fileOverview Hash Array Mapped Trie. + + Code based on: https://github.com/exclipy/pdata +*/ +const hamt = {}; // export + +/* Configuration + ***************************************************************************** */ +const SIZE = 5; + +const BUCKET_SIZE = 2 ** SIZE; + +const MASK = BUCKET_SIZE - 1; + +const MAX_INDEX_NODE = BUCKET_SIZE / 2; + +const MIN_ARRAY_NODE = BUCKET_SIZE / 4; + +/* + ***************************************************************************** */ +const nothing = {}; + +const constant = function constant(x) { + return function () { + return x; + }; +}; + +/** + Get 32 bit hash of string. + + Based on: + http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery +*/ +hamt.hash = function (str) { + const type = typeof str === 'undefined' ? 'undefined' : _typeof(str); + if (type === 'number') return str; + if (type !== 'string') str += ''; + + let hash = 0; + for (let i = 0, len = str.length; i < len; ++i) { + const c = str.charCodeAt(i); + hash = (hash << 5) - hash + c | 0; + } + return hash; +}; + +/* Bit Ops + ***************************************************************************** */ +/** + Hamming weight. + + Taken from: http://jsperf.com/hamming-weight +*/ +const popcount = function popcount(x) { + x -= x >> 1 & 0x55555555; + x = (x & 0x33333333) + (x >> 2 & 0x33333333); + x = x + (x >> 4) & 0x0f0f0f0f; + x += x >> 8; + x += x >> 16; + return x & 0x7f; +}; + +const hashFragment = function hashFragment(shift, h) { + return h >>> shift & MASK; +}; + +const toBitmap = function toBitmap(x) { + return 1 << x; +}; + +const fromBitmap = function fromBitmap(bitmap, bit) { + return popcount(bitmap & bit - 1); +}; + +/* Array Ops + ***************************************************************************** */ +/** + Set a value in an array. + + @param mutate Should the input array be mutated? + @param at Index to change. + @param v New value + @param arr Array. +*/ +const arrayUpdate = function arrayUpdate(mutate, at, v, arr) { + let out = arr; + if (!mutate) { + const len = arr.length; + out = new Array(len); + for (let i = 0; i < len; ++i) { + out[i] = arr[i]; + } + } + out[at] = v; + return out; +}; + +/** + Remove a value from an array. + + @param mutate Should the input array be mutated? + @param at Index to remove. + @param arr Array. +*/ +const arraySpliceOut = function arraySpliceOut(mutate, at, arr) { + const newLen = arr.length - 1; + let i = 0; + let g = 0; + let out = arr; + if (mutate) { + i = at; + g = at; + } else { + out = new Array(newLen); + while (i < at) { + out[g++] = arr[i++]; + } + } + ++i; + while (i <= newLen) { + out[g++] = arr[i++]; + } if (mutate) { + out.length = newLen; + } + return out; +}; + +/** + Insert a value into an array. + + @param mutate Should the input array be mutated? + @param at Index to insert at. + @param v Value to insert, + @param arr Array. +*/ +const arraySpliceIn = function arraySpliceIn(mutate, at, v, arr) { + const len = arr.length; + if (mutate) { + let _i = len; + while (_i >= at) { + arr[_i--] = arr[_i]; + }arr[at] = v; + return arr; + } + let i = 0; + let g = 0; + const out = new Array(len + 1); + while (i < at) { + out[g++] = arr[i++]; + }out[at] = v; + while (i < len) { + out[++g] = arr[i++]; + } return out; +}; + +/* Node Structures + ***************************************************************************** */ +const LEAF = 1; +const COLLISION = 2; +const INDEX = 3; +const ARRAY = 4; + +/** + Empty node. +*/ +const empty = { + __hamt_isEmpty: true +}; + +const isEmptyNode = function isEmptyNode(x) { + return x === empty || x && x.__hamt_isEmpty; +}; + +/** + Leaf holding a value. + + @member edit Edit of the node. + @member hash Hash of key. + @member key Key. + @member value Value stored. +*/ +const Leaf = function Leaf(edit, hash, key, value) { + return { + type: LEAF, + edit, + hash, + key, + value, + // eslint-disable-next-line no-use-before-define + _modify: LeafModify + }; +}; + +/** + Leaf holding multiple values with the same hash but different keys. + + @member edit Edit of the node. + @member hash Hash of key. + @member children Array of collision children node. +*/ +const Collision = function Collision(edit, hash, children) { + return { + type: COLLISION, + edit, + hash, + children, + // eslint-disable-next-line no-use-before-define + _modify: CollisionModify + }; +}; + +/** + Internal node with a sparse set of children. + + Uses a bitmap and array to pack children. + + @member edit Edit of the node. + @member mask Bitmap that encode the positions of children in the array. + @member children Array of child nodes. +*/ +const IndexedNode = function IndexedNode(edit, mask, children) { + return { + type: INDEX, + edit, + mask, + children, + // eslint-disable-next-line no-use-before-define + _modify: IndexedNodeModify + }; +}; + +/** + Internal node with many children. + + @member edit Edit of the node. + @member size Number of children. + @member children Array of child nodes. +*/ +const ArrayNode = function ArrayNode(edit, size, children) { + return { + type: ARRAY, + edit, + size, + children, + // eslint-disable-next-line no-use-before-define + _modify: ArrayNodeModify + }; +}; + +/** + Is `node` a leaf node? +*/ +const isLeaf = function isLeaf(node) { + return node === empty || node.type === LEAF || node.type === COLLISION; +}; + +/* Internal node operations. + ***************************************************************************** */ +/** + Expand an indexed node into an array node. + + @param edit Current edit. + @param frag Index of added child. + @param child Added child. + @param mask Index node mask before child added. + @param subNodes Index node children before child added. +*/ +const expand = function expand(edit, frag, child, bitmap, subNodes) { + const arr = []; + let bit = bitmap; + let count = 0; + for (let i = 0; bit; ++i) { + if (bit & 1) arr[i] = subNodes[count++]; + bit >>>= 1; + } + arr[frag] = child; + return ArrayNode(edit, count + 1, arr); +}; + +/** + Collapse an array node into a indexed node. + + @param edit Current edit. + @param count Number of elements in new array. + @param removed Index of removed element. + @param elements Array node children before remove. +*/ +const pack = function pack(edit, count, removed, elements) { + const children = new Array(count - 1); + let g = 0; + let bitmap = 0; + for (let i = 0, len = elements.length; i < len; ++i) { + if (i !== removed) { + const elem = elements[i]; + if (elem && !isEmptyNode(elem)) { + children[g++] = elem; + bitmap |= 1 << i; + } + } + } + return IndexedNode(edit, bitmap, children); +}; + +/** + Merge two leaf nodes. + + @param shift Current shift. + @param h1 Node 1 hash. + @param n1 Node 1. + @param h2 Node 2 hash. + @param n2 Node 2. +*/ +const mergeLeaves = function mergeLeaves(edit, shift, h1, n1, h2, n2) { + if (h1 === h2) return Collision(edit, h1, [n2, n1]); + + const subH1 = hashFragment(shift, h1); + const subH2 = hashFragment(shift, h2); + // eslint-disable-next-line no-nested-ternary,max-len + return IndexedNode(edit, toBitmap(subH1) | toBitmap(subH2), subH1 === subH2 ? [mergeLeaves(edit, shift + SIZE, h1, n1, h2, n2)] : subH1 < subH2 ? [n1, n2] : [n2, n1]); +}; + +/** + Update an entry in a collision list. + + @param mutate Should mutation be used? + @param edit Current edit. + @param keyEq Key compare function. + @param hash Hash of collision. + @param list Collision list. + @param f Update function. + @param k Key to update. + @param size Size ref. +*/ +const updateCollisionList = function updateCollisionList(mutate, edit, keyEq, h, list, f, k, size) { + const len = list.length; + for (let i = 0; i < len; ++i) { + const child = list[i]; + if (keyEq(k, child.key)) { + const { value } = child; + const _newValue = f(value); + if (_newValue === value) return list; + + if (_newValue === nothing) { + --size.value; + return arraySpliceOut(mutate, i, list); + } + return arrayUpdate(mutate, i, Leaf(edit, h, k, _newValue), list); + } + } + + const newValue = f(); + if (newValue === nothing) return list; + ++size.value; + return arrayUpdate(mutate, len, Leaf(edit, h, k, newValue), list); +}; + +const canEditNode = function canEditNode(edit, node) { + return edit === node.edit; +}; + +/* Editing + ***************************************************************************** */ +let LeafModify = function LeafModify(edit, keyEq, shift, f, h, k, size) { + if (keyEq(k, this.key)) { + const _v = f(this.value); + if (_v === this.value) return this; else if (_v === nothing) { + --size.value; + return empty; + } + if (canEditNode(edit, this)) { + this.value = _v; + return this; + } + return Leaf(edit, h, k, _v); + } + const v = f(); + if (v === nothing) return this; + ++size.value; + return mergeLeaves(edit, shift, this.hash, this, h, Leaf(edit, h, k, v)); +}; + +let CollisionModify = function CollisionModify(edit, keyEq, shift, f, h, k, size) { + if (h === this.hash) { + const canEdit = canEditNode(edit, this); + const list = updateCollisionList(canEdit, edit, keyEq, this.hash, this.children, f, k, size); + if (list === this.children) return this; + + return list.length > 1 ? Collision(edit, this.hash, list) : list[0]; // collapse single element collision list + } + const v = f(); + if (v === nothing) return this; + ++size.value; + return mergeLeaves(edit, shift, this.hash, this, h, Leaf(edit, h, k, v)); +}; + +let IndexedNodeModify = function IndexedNodeModify(edit, keyEq, shift, f, h, k, size) { + const { children, mask } = this; + const frag = hashFragment(shift, h); + const bit = toBitmap(frag); + const indx = fromBitmap(mask, bit); + const exists = mask & bit; + const current = exists ? children[indx] : empty; + const child = current._modify(edit, keyEq, shift + SIZE, f, h, k, size); + + if (current === child) return this; + + const canEdit = canEditNode(edit, this); + let bitmap = mask; + let newChildren; + if (exists && isEmptyNode(child)) { + // remove + bitmap &= ~bit; + if (!bitmap) return empty; + if (children.length <= 2 && isLeaf(children[indx ^ 1])) return children[indx ^ 1]; // collapse + + newChildren = arraySpliceOut(canEdit, indx, children); + } else if (!exists && !isEmptyNode(child)) { + // add + if (children.length >= MAX_INDEX_NODE) return expand(edit, frag, child, mask, children); + + bitmap |= bit; + newChildren = arraySpliceIn(canEdit, indx, child, children); + } else { + // modify + newChildren = arrayUpdate(canEdit, indx, child, children); + } + + if (canEdit) { + this.mask = bitmap; + this.children = newChildren; + return this; + } + return IndexedNode(edit, bitmap, newChildren); +}; + +let ArrayNodeModify = function ArrayNodeModify(edit, keyEq, shift, f, h, k, size) { + let count = this.size; + const { children } = this; + const frag = hashFragment(shift, h); + const child = children[frag]; + const newChild = (child || empty)._modify(edit, keyEq, shift + SIZE, f, h, k, size); + + if (child === newChild) return this; + + const canEdit = canEditNode(edit, this); + let newChildren; + if (isEmptyNode(child) && !isEmptyNode(newChild)) { + // add + ++count; + newChildren = arrayUpdate(canEdit, frag, newChild, children); + } else if (!isEmptyNode(child) && isEmptyNode(newChild)) { + // remove + --count; + if (count <= MIN_ARRAY_NODE) return pack(edit, count, frag, children); + newChildren = arrayUpdate(canEdit, frag, empty, children); + } else { + // modify + newChildren = arrayUpdate(canEdit, frag, newChild, children); + } + + if (canEdit) { + this.size = count; + this.children = newChildren; + return this; + } + return ArrayNode(edit, count, newChildren); +}; + +empty._modify = function (edit, keyEq, shift, f, h, k, size) { + const v = f(); + if (v === nothing) return empty; + ++size.value; + return Leaf(edit, h, k, v); +}; + +/* + ***************************************************************************** */ +function Map(editable, edit, config, root, size) { + this._editable = editable; + this._edit = edit; + this._config = config; + this._root = root; + this._size = size; +} + +Map.prototype.setTree = function (newRoot, newSize) { + if (this._editable) { + this._root = newRoot; + this._size = newSize; + return this; + } + return newRoot === this._root ? this : new Map(this._editable, this._edit, this._config, newRoot, newSize); +}; + +/* Queries + ***************************************************************************** */ +/** + Lookup the value for `key` in `map` using a custom `hash`. + + Returns the value or `alt` if none. +*/ +hamt.tryGetHash = (alt, hash, key, map) => { + let node = map._root; + let shift = 0; + const { keyEq } = map._config; + while (true) { + switch (node.type) { + case LEAF: + { + return keyEq(key, node.key) ? node.value : alt; + } + case COLLISION: + { + if (hash === node.hash) { + for (let i = 0, len = node.children.length; i < len; ++i) { + const child = node.children[i]; + if (keyEq(key, child.key)) return child.value; + } + } + return alt; + } + case INDEX: + { + const frag = hashFragment(shift, hash); + const bit = toBitmap(frag); + if (node.mask & bit) { + node = node.children[fromBitmap(node.mask, bit)]; + shift += SIZE; + break; + } + return alt; + } + case ARRAY: + { + node = node.children[hashFragment(shift, hash)]; + if (node) { + shift += SIZE; + break; + } + return alt; + } + default: + return alt; + } + } +}; + +Map.prototype.tryGetHash = function (alt, hash, key) { + return hamt.tryGetHash(alt, hash, key, this); +}; + +/** + Lookup the value for `key` in `map` using internal hash function. + + @see `tryGetHash` +*/ +hamt.tryGet = (alt, key, map) => + hamt.tryGetHash(alt, map._config.hash(key), key, map); + +Map.prototype.tryGet = function (alt, key) { + return hamt.tryGet(alt, key, this); +}; + +/** + Lookup the value for `key` in `map` using a custom `hash`. + + Returns the value or `undefined` if none. +*/ +hamt.getHash = (hash, key, map) => + hamt.tryGetHash(undefined, hash, key, map); + +Map.prototype.getHash = function (hash, key) { + return hamt.getHash(hash, key, this); +}; + +/** + Lookup the value for `key` in `map` using internal hash function. + + @see `get` +*/ +hamt.get = (key, map) => + hamt.tryGetHash(undefined, map._config.hash(key), key, map); + +Map.prototype.get = function (key, alt) { + return hamt.tryGet(alt, key, this); +}; + +/** + Does an entry exist for `key` in `map`? Uses custom `hash`. +*/ +hamt.hasHash = (hash, key, map) => hamt.tryGetHash(nothing, hash, key, map) !== nothing; + + +Map.prototype.hasHash = function (hash, key) { + return hamt.hasHash(hash, key, this); +}; + +/** + Does an entry exist for `key` in `map`? Uses internal hash function. +*/ +const has = (key, map) => hamt.hasHash(map._config.hash(key), key, map); + + +Map.prototype.has = function (key) { + return has(key, this); +}; + +const defKeyCompare = function defKeyCompare(x, y) { + return x === y; +}; + +/** + Create an empty map. + + @param config Configuration. +*/ +hamt.make = function (config) { + return new Map(0, 0, { + keyEq: config && config.keyEq || defKeyCompare, + hash: config && config.hash || hamt.hash + }, empty, 0); +}; + +/** + Empty map. +*/ +hamt.empty = hamt.make(); + +/** + Does `map` contain any elements? +*/ +hamt.isEmpty = function (map) { + return map && !!isEmptyNode(map._root); +}; + +Map.prototype.isEmpty = function () { + return hamt.isEmpty(this); +}; + +/* Updates + ***************************************************************************** */ +/** + Alter the value stored for `key` in `map` using function `f` using + custom hash. + + `f` is invoked with the current value for `k` if it exists, + or no arguments if no such value exists. `modify` will always either + update or insert a value into the map. + + Returns a map with the modified value. Does not alter `map`. +*/ +hamt.modifyHash = function (f, hash, key, map) { + const size = { value: map._size }; + const newRoot = map._root._modify(map._editable ? map._edit : NaN, map._config.keyEq, 0, f, hash, key, size); + + return map.setTree(newRoot, size.value); +}; + +Map.prototype.modifyHash = function (hash, key, f) { + return hamt.modifyHash(f, hash, key, this); +}; + +/** + Alter the value stored for `key` in `map` using function `f` using + internal hash function. + + @see `modifyHash` +*/ +hamt.modify = (f, key, map) => hamt.modifyHash(f, map._config.hash(key), key, map); + +Map.prototype.modify = function (key, f) { + return hamt.modify(f, key, this); +}; + +/** + Store `value` for `key` in `map` using custom `hash`. + + Returns a map with the modified value. Does not alter `map`. +*/ +hamt.setHash = (hash, key, value, map) => hamt.modifyHash(constant(value), hash, key, map); + +Map.prototype.setHash = function (hash, key, value) { + return hamt.setHash(hash, key, value, this); +}; + +/** + Store `value` for `key` in `map` using internal hash function. + + @see `setHash` +*/ +hamt.set = (key, value, map) => hamt.setHash(map._config.hash(key), key, value, map); + +Map.prototype.set = function (key, value) { + return hamt.set(key, value, this); +}; + +/** + Remove the entry for `key` in `map`. + + Returns a map with the value removed. Does not alter `map`. +*/ +const del = constant(nothing); +hamt.removeHash = (hash, key, map) => hamt.modifyHash(del, hash, key, map); + +Map.prototype.removeHash = function (hash, key) { + return hamt.removeHash(hash, key, this); +}; + +Map.prototype.deleteHash = Map.prototype.removeHash; + +/** + Remove the entry for `key` in `map` using internal hash function. + + @see `removeHash` +*/ +hamt.remove = (key, map) => hamt.removeHash(map._config.hash(key), key, map); + +Map.prototype.remove = function (key) { + return hamt.remove(key, this); +}; + +Map.prototype.delete = Map.prototype.remove; + +/* Mutation + ***************************************************************************** */ +/** + Mark `map` as mutable. + */ +hamt.beginMutation = map => new Map(map._editable + 1, map._edit + 1, map._config, map._root, map._size); + +Map.prototype.beginMutation = function () { + return hamt.beginMutation(this); +}; + +/** + Mark `map` as immutable. + */ +hamt.endMutation = function (map) { + map._editable = map._editable && map._editable - 1; + return map; +}; + +Map.prototype.endMutation = function () { + return hamt.endMutation(this); +}; + +/** + Mutate `map` within the context of `f`. + @param f + @param map HAMT +*/ +hamt.mutate = function (f, map) { + const transient = hamt.beginMutation(map); + f(transient); + return hamt.endMutation(transient); +}; + +Map.prototype.mutate = function (f) { + return hamt.mutate(f, this); +}; + +/* Traversal + ***************************************************************************** */ +/** + Apply a continuation. +*/ +const appk = function appk(k) { + // eslint-disable-next-line no-use-before-define + return k && lazyVisitChildren(k[0], k[1], k[2], k[3], k[4]); +}; + +/** + Recursively visit all values stored in an array of nodes lazily. +*/ +const lazyVisitChildren = function lazyVisitChildren(len, children, i, f, k) { + while (i < len) { + const child = children[i++]; + // eslint-disable-next-line no-use-before-define + if (child && !isEmptyNode(child)) return lazyVisit(child, f, [len, children, i, f, k]); + } + return appk(k); +}; + +/** + Recursively visit all values stored in `node` lazily. +*/ +const lazyVisit = function lazyVisit(node, f, k) { + switch (node.type) { + case LEAF: + return { + value: f(node), + rest: k + }; + + case COLLISION: + case ARRAY: + case INDEX: + return lazyVisitChildren(node.children.length, node.children, 0, f, k); + + default: + return appk(k); + } +}; + +const DONE = { + done: true +}; + +/** + Javascript iterator over a map. +*/ +function MapIterator(v) { + this.v = v; +} + +MapIterator.prototype.next = function () { + if (!this.v) return DONE; + const v0 = this.v; + this.v = appk(v0.rest); + return v0; +}; + +MapIterator.prototype[Symbol.iterator] = function () { + return this; +}; + +/** + Lazily visit each value in map with function `f`. +*/ +const visit = function visit(map, f) { + return new MapIterator(lazyVisit(map._root, f)); +}; + +/** + Get a Javascsript iterator of `map`. + + Iterates over `[key, value]` arrays. +*/ +hamt.entries = map => visit(map, x => [x.key, x.value]); + +Map.prototype.entries = function () { + return hamt.entries(this); +}; + +Map.prototype[Symbol.iterator] = Map.prototype.entries; + +/** + Get array of all keys in `map`. + + Order is not guaranteed. +*/ +hamt.keys = map => visit(map, x => x.key); + +Map.prototype.keys = function () { + return hamt.keys(this); +}; + +/** + Get array of all values in `map`. + + Order is not guaranteed, duplicates are preserved. +*/ +hamt.values = map => visit(map, x => x.value); + +Map.prototype.values = function () { + return hamt.values(this); +}; + +/* Fold + ***************************************************************************** */ +/** + Visit every entry in the map, aggregating data. + + Order of nodes is not guaranteed. + + @param f Function mapping accumulated value, value, and key to new value. + @param z Starting value. + @param m HAMT +*/ +hamt.fold = function (f, z, m) { + const root = m._root; + if (root.type === LEAF) return f(z, root.value, root.key); + + const toVisit = [root.children]; + let children = toVisit.pop(); + while (children) { + for (let i = 0, len = children.length; i < len;) { + const child = children[i++]; + if (child && child.type) { + if (child.type === LEAF) z = f(z, child.value, child.key); else toVisit.push(child.children); + } + } + + children = toVisit.pop(); + } + return z; +}; + +Map.prototype.fold = function (f, z) { + return hamt.fold(f, z, this); +}; + +/** + Visit every entry in the map, aggregating data. + + Order of nodes is not guaranteed. + + @param f Function invoked with value and key + @param map HAMT +*/ +hamt.forEach = (f, map) => hamt.fold((_, value, key) => f(value, key, map), null, map); + +Map.prototype.forEach = function (f) { + return hamt.forEach(f, this); +}; + +/* Aggregate + ***************************************************************************** */ +/** + Get the number of entries in `map`. +*/ +hamt.count = map => map._size; + +Map.prototype.count = function () { + return hamt.count(this); +}; + +Object.defineProperty(Map.prototype, 'size', { + get: Map.prototype.count +}); + +export { hamt }; +// # sourceMappingURL=hamt.js.map diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/hash.js b/racketscript-compiler/racketscript/compiler/runtime/core/hash.js index b9e259a5..ee17615c 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/hash.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/hash.js @@ -81,9 +81,8 @@ class Hash extends PrintablePrimitive { const result = this._h.get(k); if (result !== undefined) { return result; - } else { - return typeof fail === 'function' ? fail() : fail; } + return typeof fail === 'function' ? fail() : fail; } hasKey(k) { return this._h.has(k); } @@ -126,14 +125,14 @@ class Hash extends PrintablePrimitive { // iteration operations, eg hash-iterate-first/next iterateFirst() { - if (this._h.size == 0) return false; + if (this._h.size === 0) return false; // must save iterator since next() is stateful this._iterator = this._h.entries(); return this._iterator.next(); } - iterateNext(i) { - if (this._iterator == undefined) { + iterateNext() { + if (this._iterator === undefined) { return false; } const j = this._iterator.next(); @@ -274,6 +273,6 @@ export function isEqHash(h) { return check(h) && h._type === 'eq'; } -export function isWeakHash(h) { +export function isWeakHash() { return false; // TODO: implement weak hashes } diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/keyword.js b/racketscript-compiler/racketscript/compiler/runtime/core/keyword.js index 95d27781..b04c8248 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/keyword.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/keyword.js @@ -22,9 +22,8 @@ class Keyword extends PrintablePrimitive { lt(v) { if (v === this) { return false; - } else { - return this.v < v.v; } + return this.v < v.v; } } diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/lib.js b/racketscript-compiler/racketscript/compiler/runtime/core/lib.js index f58c4094..6395d097 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/lib.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/lib.js @@ -1,4 +1,4 @@ -export { hamt } from '../third-party/hamt.js'; +export { hamt } from './hamt.js'; /* --------------------------------------------------------------------------*/ /* Other Helpers */ diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/linklet.js b/racketscript-compiler/racketscript/compiler/runtime/core/linklet.js new file mode 100644 index 00000000..b058f327 --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/core/linklet.js @@ -0,0 +1,36 @@ +import { PrintablePrimitive } from './printable_primitive.js'; + +// eslint-disable-next-line no-unused-vars +class Linklet extends PrintablePrimitive {} + +class LinkletInstance extends PrintablePrimitive { + constructor(name, data, mode, m) { + super(); + this.name = name; + this.data = data; + this.mode = mode; + this.m = m; + } +} + +export function makeInstance(name, _data, _mode, ...args) { + const m = new Map(); + const data = _data || false; + const mode = _mode || false; + for (let i = 0; i < args.length; i += 2) { + m.set(args[i], args[i + 1]); + } + return new LinkletInstance(name, data, mode, m); +} + + +export function instanceName(i) { return i.name; } +export function instanceData(i) { return i.data; } +export function instanceVariableValue(i, s) { return i.m.get(s); } +export function instanceVariableNames(i) { return i.keys(); } +export function instanceSetVariableValue(i, s, v) { + return i.m.set(s, v); +} +export function instanceUnsetVariable(i, s) { return i.m.remove(s); } +export function instanceDescribeVariable() { } + diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/marks.js b/racketscript-compiler/racketscript/compiler/runtime/core/marks.js index 124f240d..6177189d 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/marks.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/marks.js @@ -1,14 +1,13 @@ // Continuation Marks import * as Pair from './pair.js'; -import * as Symbol from './symbol.js'; +import * as PrimitiveSymbol from './primitive_symbol.js'; import { racketCoreError } from './errors.js'; import { hashForEq as HASH } from './hashing.js'; let __frames; const __prompts = new Map(); -const __async_callback_wrappers = []; -const __defaultContinuationPromptTag - = makeContinuationPromptTag(Symbol.make('default')); +const __asyncCallbackWrappers = []; +const __defaultContinuationPromptTag = makeContinuationPromptTag(PrimitiveSymbol.make('default')); /* --------------------------------------------------------------------------*/ @@ -19,7 +18,7 @@ export function init() { } export function registerAsynCallbackWrapper(w) { - __async_callback_wrappers.push(w); + __asyncCallbackWrappers.push(w); } export function defaultContinuationPromptTag() { @@ -46,11 +45,11 @@ export function AbortCurrentContinuation(promptTag, handlerArgs) { this.promptTag = promptTag; this.handlerArgs = handlerArgs; - this.stack = (new Error()).stack; + this.stack = new Error().stack; if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } else { - this.stack = (new Error()).stack; + this.stack = new Error().stack; } } AbortCurrentContinuation.prototype = Object.create(Error.prototype); @@ -82,8 +81,7 @@ function getPromptFrame(promptTag) { return promptTag; } const result = __prompts.get(promptTag); - return (result && result[result.length - 1]) - || undefined; + return (result && result[result.length - 1]) || undefined; } export function makeContinuationPromptTag(sym) { @@ -100,8 +98,7 @@ export function callWithContinuationPrompt(proc, promptTag, handler, ...args) { savePrompt(promptTag); return proc(...args); } catch (e) { - if (e instanceof AbortCurrentContinuation && - e.promptTag === promptTag) { + if (e instanceof AbortCurrentContinuation && e.promptTag === promptTag) { return handler(...e.handlerArgs); } throw e; @@ -120,7 +117,9 @@ export function updateFrame(newFrames, oldFrames) { if (__frames !== oldFrames) { throw new Error("current frame doesn't match with old frame"); } - return __frames = newFrames; + + __frames = newFrames; + return __frames; } export function enterFrame() { @@ -137,8 +136,10 @@ export function getContinuationMarks(promptTag) { promptTag = promptTag || __defaultContinuationPromptTag; let frames = __frames; const promptFrame = getPromptFrame(promptTag); - if (promptFrame === undefined && - promptTag !== __defaultContinuationPromptTag) { + if ( + promptFrame === undefined && + promptTag !== __defaultContinuationPromptTag + ) { throw racketCoreError('No corresponding tag in continuation!'); } @@ -160,7 +161,7 @@ export function getMarks(framesArr, key, promptTag) { const result = []; for (let ii = 0; ii < framesArr.length; ++ii) { - // FIXME: for-of requires polyfill + // FIXME: for-of requires polyfill const fr = framesArr[ii]; if (keyHash in fr) { if (fr === promptFrame) { @@ -176,20 +177,22 @@ export function getMarks(framesArr, key, promptTag) { // and parameterization and check if that if this needs export function getFirstMark(frames, key, noneV) { const keyHash = HASH(key); - return Pair.listFind(frames, (fr) => { - if (keyHash in fr) { - return fr[keyHash]; - } - }) || noneV; + return ( + Pair.listFind(frames, (fr) => { + if (keyHash in fr) { + return fr[keyHash]; + } + }) || noneV + ); } export function wrapWithContext(fn) { - return (function (currentFrames) { + return (function () { const state = {}; - __async_callback_wrappers.forEach(w => w.onCreate(state)); + __asyncCallbackWrappers.forEach(w => w.onCreate(state)); return function (...args) { init(); - __async_callback_wrappers.forEach(w => w.onInvoke(state)); + __asyncCallbackWrappers.forEach(w => w.onInvoke(state)); try { return fn(...args); } finally { diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/mpair.js b/racketscript-compiler/racketscript/compiler/runtime/core/mpair.js index b7b82e9a..beb4f95a 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/mpair.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/mpair.js @@ -1,7 +1,7 @@ import { PrintablePrimitive } from './printable_primitive.js'; import { displayNativeString, writeNativeString } from './print_native_string.js'; import { isEqual } from './equality.js'; -import { EMPTY, isEmpty, isList } from './pair.js'; +import { isEmpty, isList } from './pair.js'; class MPair extends PrintablePrimitive { /** @private */ diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/numbers.js b/racketscript-compiler/racketscript/compiler/runtime/core/numbers/js-numbers.js similarity index 78% rename from racketscript-compiler/racketscript/compiler/runtime/core/numbers.js rename to racketscript-compiler/racketscript/compiler/runtime/core/numbers/js-numbers.js index 4032ea5a..15aa54e7 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/numbers.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/numbers/js-numbers.js @@ -1,4 +1,4 @@ -import { racketCoreError } from './errors.js'; +import { racketCoreError } from '../errors.js'; /* Arithmetic */ @@ -72,3 +72,21 @@ export function equals(...operands) { export function check(v) { return typeof v === 'number'; } + +/* Bitwise operators */ + +export function bitwiseOr(...operands) { + return [].reduce.call(operands, (a, b) => a | b, 0); +} + +export function bitwiseXor(...operands) { + return [].reduce.call(operands, (a, b) => a ^ b, 0); +} + +export function bitwiseAnd(...operands) { + return [].reduce.call(operands, (a, b) => a & b, -1); +} + +export function bitwiseNot(v) { + return ~v; +} diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/numbers/numbers.js b/racketscript-compiler/racketscript/compiler/runtime/core/numbers/numbers.js new file mode 100644 index 00000000..d3764dbb --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/core/numbers/numbers.js @@ -0,0 +1,7 @@ +import * as Scheme from './scheme-numbers.js'; +import * as JS from './js-numbers.js'; + +export { + Scheme, + JS +}; diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/numbers/scheme-numbers.js b/racketscript-compiler/racketscript/compiler/runtime/core/numbers/scheme-numbers.js new file mode 100644 index 00000000..80b2db0b --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/core/numbers/scheme-numbers.js @@ -0,0 +1,4470 @@ +// Taken from https://github.com/dyoo/js-numbers/blob/master/src/js-numbers.js +// and originally written by Danny Yoo (dyoo@cs.wpi.edu) +// The original license is provided below. Modifications to the original +// source are made under the Racketscript license. +// +// +// // Licensing +// --------- +// +// This software is covered under the following copyright: +// +// /* +// * Copyright (c) 2010 Danny Yoo +// * All Rights Reserved. +// * +// * Permission is hereby granted, free of charge, to any person obtaining +// * a copy of this software and associated documentation files (the +// * "Software"), to deal in the Software without restriction, including +// * without limitation the rights to use, copy, modify, merge, publish, +// * distribute, sublicense, and/or sell copies of the Software, and to +// * permit persons to whom the Software is furnished to do so, subject to +// * the following conditions: +// * +// * The above copyright notice and this permission notice shall be +// * included in all copies or substantial portions of the Software. +// * +// * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +// * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +// * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +// * +// * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, +// * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER +// * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF +// * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT +// * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// * +// * In addition, the following condition applies: +// * +// * All redistributions must retain an intact copy of this copyright notice +// * and disclaimer. +// */ +// +// +// +// +// +// ====================================================================== +// +// js-numbers uses code from the jsbn library. The LICENSE to it is: +// +// Licensing +// --------- +// +// This software is covered under the following copyright: +// +// /* +// * Copyright (c) 2003-2005 Tom Wu +// * All Rights Reserved. +// * +// * Permission is hereby granted, free of charge, to any person obtaining +// * a copy of this software and associated documentation files (the +// * "Software"), to deal in the Software without restriction, including +// * without limitation the rights to use, copy, modify, merge, publish, +// * distribute, sublicense, and/or sell copies of the Software, and to +// * permit persons to whom the Software is furnished to do so, subject to +// * the following conditions: +// * +// * The above copyright notice and this permission notice shall be +// * included in all copies or substantial portions of the Software. +// * +// * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +// * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +// * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +// * +// * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, +// * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER +// * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF +// * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT +// * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// * +// * In addition, the following condition applies: +// * +// * All redistributions must retain an intact copy of this copyright notice +// * and disclaimer. +// */ +// +// Address all questions regarding this license to: +// +// Tom Wu +// tjw@cs.Stanford.EDU + + +// Scheme numbers. + +// The numeric tower has the following levels: +// integers +// rationals +// floats +// complex numbers +// +// with the representations: +// integers: fixnum or BigInteger [level=0] +// rationals: Rational [level=1] +// floats: FloatPoint [level=2] +// complex numbers: Complex [level=3] + +// We try to stick with the unboxed fixnum representation for +// integers, since that's what scheme programs commonly deal with, and +// we want that common type to be lightweight. + + +// A boxed-scheme-number is either BigInteger, Rational, FloatPoint, or Complex. +// An integer-scheme-number is either fixnum or BigInteger. + +// Abbreviation +var Numbers = {}; + +// makeNumericBinop: (fixnum fixnum -> any) (scheme-number scheme-number -> any) -> (scheme-number scheme-number) X +// Creates a binary function that works either on fixnums or boxnums. +// Applies the appropriate binary function, ensuring that both scheme numbers are +// lifted to the same level. +var makeNumericBinop = function(onFixnums, onBoxednums, options) { + options = options || {}; + return function(x, y) { + if (options.isXSpecialCase && options.isXSpecialCase(x)) + return options.onXSpecialCase(x, y); + if (options.isYSpecialCase && options.isYSpecialCase(y)) + return options.onYSpecialCase(x, y); + if (typeof(x) === 'number' && + typeof(y) === 'number') { + return onFixnums(x, y); + } + if (typeof(x) === 'number') { + x = liftFixnumInteger(x, y); + } + if (typeof(y) === 'number') { + y = liftFixnumInteger(y, x); + } + if (x.level < y.level) x = x.liftTo(y); + if (y.level < x.level) y = y.liftTo(x); + return onBoxednums(x, y); + }; +} + +// fromFixnum: fixnum -> scheme-number +var fromFixnum = function(x) { + if (isNaN(x) || (!isFinite(x))) { + return FloatPoint.makeInstance(x); + } + var nf = Math.floor(x); + if (nf === x) { + if (isOverflow(nf)) { + return makeBignum(expandExponent(x + '')); + } else { + return nf; + } + } else { + return FloatPoint.makeInstance(x); + } +}; +var expandExponent = function(s) { + var match = s.match(scientificPattern), + mantissaChunks, exponent; + if (match) { + mantissaChunks = match[1].match(/^([^.]*)(.*)$/); + exponent = Number(match[2]); + if (mantissaChunks[2].length === 0) { + return mantissaChunks[1] + zfill(exponent); + } + if (exponent >= mantissaChunks[2].length - 1) { + return (mantissaChunks[1] + + mantissaChunks[2].substring(1) + + zfill(exponent - (mantissaChunks[2].length - 1))); + } else { + return (mantissaChunks[1] + + mantissaChunks[2].substring(1, 1 + exponent)); + } + } else { + return s; + } +}; +// zfill: integer -> string +// builds a string of "0"'s of length n. +var zfill = function(n) { + var buffer = []; + buffer.length = n; + for (var i = 0; i < n; i++) { + buffer[i] = '0'; + } + return buffer.join(''); +}; + +// liftFixnumInteger: fixnum-integer boxed-scheme-number -> boxed-scheme-number +// Lifts up fixnum integers to a boxed type. +var liftFixnumInteger = function(x, other) { + switch (other.level) { + case 0: // BigInteger + return makeBignum(x); + case 1: // Rational + return new Rational(x, 1); + case 2: // FloatPoint + return new FloatPoint(x); + case 3: // Complex + return new Complex(x, 0); + default: + throwRuntimeError("IMPOSSIBLE: cannot lift fixnum integer to " + other.toString(), x, other); + } +}; + +// throwRuntimeError: string (scheme-number | undefined) (scheme-number | undefined) -> void +// Throws a runtime error with the given message string. +var throwRuntimeError = function(msg, x, y) { + Numbers['onThrowRuntimeError'](msg, x, y); +}; + +// onThrowRuntimeError: string (scheme-number | undefined) (scheme-number | undefined) -> void +// By default, will throw a new Error with the given message. +// Override Numbers['onThrowRuntimeError'] if you need to do something special. +var onThrowRuntimeError = function(msg, x, y) { + throw new Error(msg); +}; + +// isSchemeNumber: any -> boolean +// Returns true if the thing is a scheme number. +var isSchemeNumber = function(thing) { + return (typeof(thing) === 'number' || + (thing instanceof Rational || + thing instanceof FloatPoint || + thing instanceof Complex || + thing instanceof BigInteger)); +}; + +// isRational: scheme-number -> boolean +var isRational = function(n) { + return (typeof(n) === 'number' || + (isSchemeNumber(n) && n.isRational())); +}; +// isReal: scheme-number -> boolean +var isReal = function(n) { + return (typeof(n) === 'number' || + (isSchemeNumber(n) && n.isReal())); +}; +// isExact: scheme-number -> boolean +var isExact = function(n) { + return (typeof(n) === 'number' || + (isSchemeNumber(n) && n.isExact())); +}; +// isExact: scheme-number -> boolean +var isInexact = function(n) { + if (typeof(n) === 'number') { + return false; + } else { + return (isSchemeNumber(n) && n.isInexact()); + } +}; +// isInteger: scheme-number -> boolean +var isInteger = function(n) { + return (typeof(n) === 'number' || + (isSchemeNumber(n) && n.isInteger())); +}; +// isExactInteger: scheme-number -> boolean +var isExactInteger = function(n) { + return (typeof(n) === 'number' || + (isSchemeNumber(n) && + n.isInteger() && + n.isExact())); +} + +// toFixnum: scheme-number -> javascript-number +var toFixnum = function(n) { + if (typeof(n) === 'number') + return n; + return n.toFixnum(); +}; +// toExact: scheme-number -> scheme-number +var toExact = function(n) { + if (typeof(n) === 'number') + return n; + return n.toExact(); +}; + +// toExact: scheme-number -> scheme-number +var toInexact = function(n) { + if (typeof(n) === 'number') + return FloatPoint.makeInstance(n); + return n.toInexact(); +}; + +////////////////////////////////////////////////////////////////////// + +// Takes a two argument function and makes it multi-arity. +// Can provide an alternative function for when called with +// a single argument or no arguments. +function makeMultiArityArithmetic(multiArg, singleArg=false, noArg=false) { + function quickReduce(array) { + let result = array[0]; + for (let i = 1; i < array.length; i++) { + result = multiArg(result, array[i]); + } + return result; + } + + if (noArg && singleArg) { + return function(...operands) { + if (operands.length === 0) { + return noArg(); + } else if (operands.length === 1) { + return singleArg(operands[0]); + } + return quickReduce(operands); + } + } + + if (singleArg) { + return function(...operands) { + if (operands.length === 1) { + return singleArg(operands[0]); + } + quickReduce(operands); + } + } + + if (!singleArge && !noArg) { + return function(...operands) { + quickReduce(operands); + } + } + + throwRuntimeError("singleArg must be provided if noArg is provided."); +} + +// multiAdd: multi-arity version of add. +var multiAdd = makeMultiArityArithmetic(add, (value) => value, () => 0); + +// add: scheme-number scheme-number -> scheme-number +var add = function(x, y) { + var sum; + if (typeof(x) === 'number' && typeof(y) === 'number') { + sum = x + y; + if (isOverflow(sum)) { + return (makeBignum(x)).add(makeBignum(y)); + } + } + if (x instanceof FloatPoint && y instanceof FloatPoint) { + return x.add(y); + } + return addSlow(x, y); +}; +var addSlow = makeNumericBinop( + function(x, y) { + var sum = x + y; + if (isOverflow(sum)) { + return (makeBignum(x)).add(makeBignum(y)); + } else { + return sum; + } + }, + function(x, y) { + return x.add(y); + }, { + isXSpecialCase: function(x) { + return isExactInteger(x) && _integerIsZero(x) + }, + onXSpecialCase: function(x, y) { + return y; + }, + isYSpecialCase: function(y) { + return isExactInteger(y) && _integerIsZero(y) + }, + onYSpecialCase: function(x, y) { + return x; + } + }); + +// multiSub: multi-arity version of subtract. +var multiSub = makeMultiArityArithmetic(subtract, (value) => subtract(0, value)); + +// subtract: scheme-number scheme-number -> scheme-number +var subtract = makeNumericBinop( + function(x, y) { + var diff = x - y; + if (isOverflow(diff)) { + return (makeBignum(x)).subtract(makeBignum(y)); + } else { + return diff; + } + }, + function(x, y) { + return x.subtract(y); + }, { + isXSpecialCase: function(x) { + return isExactInteger(x) && _integerIsZero(x) + }, + onXSpecialCase: function(x, y) { + return negate(y); + }, + isYSpecialCase: function(y) { + return isExactInteger(y) && _integerIsZero(y) + }, + onYSpecialCase: function(x, y) { + return x; + } + }); + +// mul: multi-arity version of multiply. +var multiMultiply = makeMultiArityArithmetic(multiply, (value) => value, () => 1); + +// mulitply: scheme-number scheme-number -> scheme-number +var multiply = function(x, y) { + var prod; + if (typeof(x) === 'number' && typeof(y) === 'number') { + prod = x * y; + if (isOverflow(prod)) { + return (makeBignum(x)).multiply(makeBignum(y)); + } else { + return prod; + } + } + if (x instanceof FloatPoint && y instanceof FloatPoint) { + return x.multiply(y); + } + return multiplySlow(x, y); +}; +var multiplySlow = makeNumericBinop( + function(x, y) { + var prod = x * y; + if (isOverflow(prod)) { + return (makeBignum(x)).multiply(makeBignum(y)); + } else { + return prod; + } + }, + function(x, y) { + return x.multiply(y); + }, { + isXSpecialCase: function(x) { + return (isExactInteger(x) && + (_integerIsZero(x) || _integerIsOne(x) || _integerIsNegativeOne(x))) + }, + onXSpecialCase: function(x, y) { + if (_integerIsZero(x)) + return 0; + if (_integerIsOne(x)) + return y; + if (_integerIsNegativeOne(x)) + return negate(y); + }, + isYSpecialCase: function(y) { + return (isExactInteger(y) && + (_integerIsZero(y) || _integerIsOne(y) || _integerIsNegativeOne(y))) + }, + onYSpecialCase: function(x, y) { + if (_integerIsZero(y)) + return 0; + if (_integerIsOne(y)) + return x; + if (_integerIsNegativeOne(y)) + return negate(x); + } + }); + +// div: multi-arity version of divide. +var multiDivide = makeMultiArityArithmetic(divide, (value) => divide(1, value)); + +// divide: scheme-number scheme-number -> scheme-number +var divide = makeNumericBinop( + function(x, y) { + if (_integerIsZero(y)) + throwRuntimeError("/: division by zero", x, y); + var div = x / y; + if (isOverflow(div)) { + return (makeBignum(x)).divide(makeBignum(y)); + } else if (Math.floor(div) !== div) { + return Rational.makeInstance(x, y); + } else { + return div; + } + }, + function(x, y) { + return x.divide(y); + }, { + isXSpecialCase: function(x) { + return (eqv(x, 0)); + }, + onXSpecialCase: function(x, y) { + if (eqv(y, 0)) { + throwRuntimeError("/: division by zero", x, y); + } + return 0; + }, + isYSpecialCase: function(y) { + return (eqv(y, 0)); + }, + onYSpecialCase: function(x, y) { + throwRuntimeError("/: division by zero", x, y); + } + }); + +// Makes a multi-arity comparison function. +function makeMultiArityComparison(compare) { + return function(...operands) { + if (operands.length === 1) { + return true; + } + for (let i = 1; i < operands.length; i++) { + if (!compare(operands[i - 1], operands[i])) { + return false; + } + } + return true; + } +} + + + +// equals: scheme-number scheme-number -> boolean +var equals = makeNumericBinop( + function(x, y) { + return x === y; + }, + function(x, y) { + return x.equals(y); + }); + +// eqv: scheme-number scheme-number -> boolean +var eqv = function(x, y) { + if (x === y) + return true; + if (typeof(x) === 'number' && typeof(y) === 'number') + return x === y; + if (x === NEGATIVE_ZERO || y === NEGATIVE_ZERO) + return x === y; + if (x instanceof Complex || y instanceof Complex) { + return (eqv(realPart(x), realPart(y)) && + eqv(imaginaryPart(x), imaginaryPart(y))); + } + var ex = isExact(x), + ey = isExact(y); + return (((ex && ey) || (!ex && !ey)) && equals(x, y)); +}; +// approxEqual: scheme-number scheme-number scheme-number -> boolean +var approxEquals = function(x, y, delta) { + return lessThan(abs(subtract(x, y)), + delta); +}; +// greaterThanOrEqual: scheme-number scheme-number -> boolean +var greaterThanOrEqual = makeNumericBinop( + function(x, y) { + return x >= y; + }, + function(x, y) { + if (!(isReal(x) && isReal(y))) + throwRuntimeError( + ">=: couldn't be applied to complex number", x, y); + return x.greaterThanOrEqual(y); + }); + +// lessThanOrEqual: scheme-number scheme-number -> boolean +var lessThanOrEqual = makeNumericBinop( + function(x, y) { + return x <= y; + }, + function(x, y) { + if (!(isReal(x) && isReal(y))) + throwRuntimeError("<=: couldn't be applied to complex number", x, y); + return x.lessThanOrEqual(y); + }); + +// greaterThan: scheme-number scheme-number -> boolean +var greaterThan = makeNumericBinop( + function(x, y) { + return x > y; + }, + function(x, y) { + if (!(isReal(x) && isReal(y))) + throwRuntimeError(">: couldn't be applied to complex number", x, y); + return x.greaterThan(y); + }); + +// lessThan: scheme-number scheme-number -> boolean +var lessThan = makeNumericBinop( + function(x, y) { + return x < y; + }, + function(x, y) { + if (!(isReal(x) && isReal(y))) + throwRuntimeError("<: couldn't be applied to complex number", x, y); + return x.lessThan(y); + }); + +// expt: scheme-number scheme-number -> scheme-number +var expt = (function() { + var _expt = makeNumericBinop( + function(x, y) { + var pow = Math.pow(x, y); + if (isOverflow(pow)) { + return (makeBignum(x)).expt(makeBignum(y)); + } else { + return pow; + } + }, + function(x, y) { + if (equals(y, 0)) { + return add(y, 1); + } else { + return x.expt(y); + } + }); + return function(x, y) { + if (equals(y, 0)) + return add(y, 1); + if (isReal(y) && lessThan(y, 0)) { + return _expt(divide(1, x), negate(y)); + } + return _expt(x, y); + }; +})(); + +// exp: scheme-number -> scheme-number +var exp = function(n) { + if (eqv(n, 0)) { + return 1; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.exp(n)); + } + return n.exp(); +}; + +// modulo: scheme-number scheme-number -> scheme-number +var modulo = function(m, n) { + if (!isInteger(m)) { + throwRuntimeError('modulo: the first argument ' + + m + " is not an integer.", m, n); + } + if (!isInteger(n)) { + throwRuntimeError('modulo: the second argument ' + + n + " is not an integer.", m, n); + } + var result; + if (typeof(m) === 'number') { + result = m % n; + if (n < 0) { + if (result <= 0) + return result; + else + return result + n; + } else { + if (result < 0) + return result + n; + else + return result; + } + } + result = _integerModulo(floor(m), floor(n)); + // The sign of the result should match the sign of n. + if (lessThan(n, 0)) { + if (lessThanOrEqual(result, 0)) { + return result; + } + return add(result, n); + } else { + if (lessThan(result, 0)) { + return add(result, n); + } + return result; + } +}; + +// numerator: scheme-number -> scheme-number +var numerator = function(n) { + if (typeof(n) === 'number') + return n; + return n.numerator(); +}; + +// denominator: scheme-number -> scheme-number +var denominator = function(n) { + if (typeof(n) === 'number') + return 1; + return n.denominator(); +}; +// sqrt: scheme-number -> scheme-number +var sqrt = function(n) { + if (typeof(n) === 'number') { + if (n >= 0) { + var result = Math.sqrt(n); + if (Math.floor(result) === result) { + return result; + } else { + return FloatPoint.makeInstance(result); + } + } else { + return (Complex.makeInstance(0, sqrt(-n))); + } + } + return n.sqrt(); +}; +// abs: scheme-number -> scheme-number +var abs = function(n) { + if (typeof(n) === 'number') { + return Math.abs(n); + } + return n.abs(); +}; +// floor: scheme-number -> scheme-number +var floor = function(n) { + if (typeof(n) === 'number') + return n; + return n.floor(); +}; +// ceiling: scheme-number -> scheme-number +var ceiling = function(n) { + if (typeof(n) === 'number') { + return Math.ceil(n); + } + return n.ceiling(); +}; +// conjugate: scheme-number -> scheme-number +var conjugate = function(n) { + if (typeof(n) === 'number') + return n; + return n.conjugate(); +}; +// magnitude: scheme-number -> scheme-number +var magnitude = function(n) { + if (typeof(n) === 'number') + return Math.abs(n); + return n.magnitude(); +}; + +// log: scheme-number -> scheme-number +var log = function(n) { + if (eqv(n, 1)) { + return 0; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.log(n)); + } + return n.log(); +}; +// angle: scheme-number -> scheme-number +var angle = function(n) { + if (typeof(n) === 'number') { + if (n > 0) + return 0; + else + return FloatPoint.pi; + } + return n.angle(); +}; +// tan: scheme-number -> scheme-number +var tan = function(n) { + if (eqv(n, 0)) { + return 0; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.tan(n)); + } + return n.tan(); +}; +// atan: scheme-number -> scheme-number +var atan = function(n) { + if (eqv(n, 0)) { + return 0; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.atan(n)); + } + return n.atan(); +}; + +var atan2 = function(y, x) { + if (typeof(y) == 'number' && typeof(x) == 'number') { + return FloatPoint.makeInstance(Math.atan2(y, x)) + } + y = toInexact(y); + x = toInexact(x); + return FloatPoint.makeInstance(Math.atan2(y.n, x.n)) +} +// cos: scheme-number -> scheme-number +var cos = function(n) { + if (eqv(n, 0)) { + return 1; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.cos(n)); + } + return n.cos(); +}; +// sin: scheme-number -> scheme-number +var sin = function(n) { + if (eqv(n, 0)) { + return 0; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.sin(n)); + } + return n.sin(); +}; +// acos: scheme-number -> scheme-number +var acos = function(n) { + if (eqv(n, 1)) { + return 0; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.acos(n)); + } + return n.acos(); +}; +// asin: scheme-number -> scheme-number +var asin = function(n) { + if (eqv(n, 0)) { + return 0; + } + if (typeof(n) === 'number') { + return FloatPoint.makeInstance(Math.asin(n)); + } + return n.asin(); +}; +// imaginaryPart: scheme-number -> scheme-number +var imaginaryPart = function(n) { + if (typeof(n) === 'number') { + return 0; + } + return n.imaginaryPart(); +}; +// realPart: scheme-number -> scheme-number +var realPart = function(n) { + if (typeof(n) === 'number') { + return n; + } + return n.realPart(); +}; +// round: scheme-number -> scheme-number +var round = function(n) { + if (typeof(n) === 'number') { + return n; + } + return n.round(); +}; + +// sqr: scheme-number -> scheme-number +var sqr = function(x) { + return multiply(x, x); +}; + +// integerSqrt: scheme-number -> scheme-number +var integerSqrt = function(x) { + if (!isInteger(x)) { + throwRuntimeError('integer-sqrt: the argument ' + x.toString() + + " is not an integer.", x); + } + if (typeof(x) === 'number') { + if (x < 0) { + return Complex.makeInstance(0, + Math.floor(Math.sqrt(-x))) + } else { + return Math.floor(Math.sqrt(x)); + } + } + return x.integerSqrt(); +}; + +// gcd: scheme-number [scheme-number ...] -> scheme-number +var gcd = function(first, rest) { + if (!isInteger(first)) { + throwRuntimeError('gcd: the argument ' + first.toString() + + " is not an integer.", first); + } + var a = abs(first), + t, b; + for (var i = 0; i < rest.length; i++) { + b = abs(rest[i]); + if (!isInteger(b)) { + throwRuntimeError('gcd: the argument ' + b.toString() + + " is not an integer.", b); + } + while (!_integerIsZero(b)) { + t = a; + a = b; + b = _integerModulo(t, b); + } + } + return a; +}; +// lcm: scheme-number [scheme-number ...] -> scheme-number +var lcm = function(first, rest) { + if (!isInteger(first)) { + throwRuntimeError('lcm: the argument ' + first.toString() + + " is not an integer.", first); + } + var result = abs(first); + if (_integerIsZero(result)) { + return 0; + } + for (var i = 0; i < rest.length; i++) { + if (!isInteger(rest[i])) { + throwRuntimeError('lcm: the argument ' + rest[i].toString() + + " is not an integer.", rest[i]); + } + var divisor = _integerGcd(result, rest[i]); + if (_integerIsZero(divisor)) { + return 0; + } + result = divide(multiply(result, rest[i]), divisor); + } + return result; +}; + +var quotient = function(x, y) { + if (!isInteger(x)) { + throwRuntimeError('quotient: the first argument ' + x.toString() + + " is not an integer.", x); + } + if (!isInteger(y)) { + throwRuntimeError('quotient: the second argument ' + y.toString() + + " is not an integer.", y); + } + return _integerQuotient(x, y); +}; + +var remainder = function(x, y) { + if (!isInteger(x)) { + throwRuntimeError('remainder: the first argument ' + x.toString() + + " is not an integer.", x); + } + if (!isInteger(y)) { + throwRuntimeError('remainder: the second argument ' + y.toString() + + " is not an integer.", y); + } + return _integerRemainder(x, y); +}; + +// Implementation of the hyperbolic functions +// http://en.wikipedia.org/wiki/Hyperbolic_cosine +var cosh = function(x) { + if (eqv(x, 0)) { + return FloatPoint.makeInstance(1.0); + } + return divide(add(exp(x), exp(negate(x))), + 2); +}; +var sinh = function(x) { + return divide(subtract(exp(x), exp(negate(x))), + 2); +}; + +var makeComplexPolar = function(r, theta) { + // special case: if theta is zero, just return + // the scalar. + if (eqv(theta, 0)) { + return r; + } + return Complex.makeInstance(multiply(r, cos(theta)), + multiply(r, sin(theta))); +}; + +var bitwiseAnd = function(...nums) { + var jsNums = getJSExactIntegers(...nums); + return jsNums.reduce((x, y) => (x & y)); +} + +var bitwiseOr = function(...nums) { + var jsNums = getJSExactIntegers(...nums); + return jsNums.reduce((x, y) => (x | y)); +} + +var bitwiseXor = function(...nums) { + var jsNums = getJSExactIntegers(...nums); + return jsNums.reduce((x, y) => (x ^ y)); +} + +var bitwiseNot = function(n) { + var jsNum = getJSExactIntegers(n)[0]; + return ~jsNum; +} + +var arithmeticShift = function(n, m) { + [n, m] = getJSExactIntegers(n, m); + if (m < 0) { + return n >> -m; + } else { + return n << m; + } +} + +////////////////////////////////////////////////////////////////////// +// Helpers + +// IsFinite: scheme-number -> boolean +// Returns true if the scheme number is finite or not. +var isSchemeNumberFinite = function(n) { + if (typeof(n) === 'number') { + return isFinite(n); + } else { + return n.isFinite(); + } +}; +// isOverflow: javascript-number -> boolean +// Returns true if we consider the number an overflow. +var MIN_FIXNUM = -(9e15); +var MAX_FIXNUM = (9e15); +var isOverflow = function(n) { + return (n < MIN_FIXNUM || MAX_FIXNUM < n); +}; + +// negate: scheme-number -> scheme-number +// multiplies a number times -1. +var negate = function(n) { + if (typeof(n) === 'number') { + return -n; + } + return n.negate(); +}; + +// halve: scheme-number -> scheme-number +// Divide a number by 2. +var halve = function(n) { + return divide(n, 2); +}; + +// timesI: scheme-number scheme-number +// multiplies a number times i. +var timesI = function(x) { + return multiply(x, plusI); +}; + +// fastExpt: computes n^k by squaring. +// n^k = (n^2)^(k/2) +// Assumes k is non-negative integer. +var fastExpt = function(n, k) { + var acc = 1; + while (true) { + if (_integerIsZero(k)) { + return acc; + } + if (equals(modulo(k, 2), 0)) { + n = multiply(n, n); + k = divide(k, 2); + } else { + acc = multiply(acc, n); + k = subtract(k, 1); + } + } +}; + +// getJSExactIntegers: scheme-number [scheme-number ...] -> [js-number] +// Get's the underlying JS numbers from one or more scheme exact integers +// and returns them in an array. +var getJSExactIntegers = function(...nums) { + // Only defined for exact integers. + nums.map((x) => { + if (!isExactInteger(x)) { + throwRuntimeError("Expected exact integer(s).") + } + }) + + // Get the JS value. + return nums.map((x) => { + if (typeof(x) === 'number') { + return x; + } else { + return x.n; + } + }) +} + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +// Integer operations +// Integers are either represented as fixnums or as BigIntegers. +// makeIntegerBinop: (fixnum fixnum -> X) (BigInteger BigInteger -> X) -> X +// Helper to collect the common logic for coersing integer fixnums or bignums to a +// common type before doing an operation. +var makeIntegerBinop = function(onFixnums, onBignums, options) { + options = options || {}; + return (function(m, n) { + if (m instanceof Rational) { + m = numerator(m); + } else if (m instanceof Complex) { + m = realPart(m); + } + if (n instanceof Rational) { + n = numerator(n); + } else if (n instanceof Complex) { + n = realPart(n); + } + if (typeof(m) === 'number' && typeof(n) === 'number') { + var result = onFixnums(m, n); + if (!isOverflow(result) || + (options.ignoreOverflow)) { + return result; + } + } + if (m instanceof FloatPoint || n instanceof FloatPoint) { + if (options.doNotCoerseToFloating) { + return onFixnums(toFixnum(m), toFixnum(n)); + } else { + return FloatPoint.makeInstance( + onFixnums(toFixnum(m), toFixnum(n))); + } + } + if (typeof(m) === 'number') { + m = makeBignum(m); + } + if (typeof(n) === 'number') { + n = makeBignum(n); + } + return onBignums(m, n); + }); +}; + +var makeIntegerUnOp = function(onFixnums, onBignums, options) { + options = options || {}; + return (function(m) { + if (m instanceof Rational) { + m = numerator(m); + } else if (m instanceof Complex) { + m = realPart(m); + } + if (typeof(m) === 'number') { + var result = onFixnums(m); + if (!isOverflow(result) || + (options.ignoreOverflow)) { + return result; + } + } + if (m instanceof FloatPoint) { + return onFixnums(toFixnum(m)); + } + if (typeof(m) === 'number') { + m = makeBignum(m); + } + return onBignums(m); + }); +}; + +// _integerModulo: integer-scheme-number integer-scheme-number -> integer-scheme-number +var _integerModulo = makeIntegerBinop( + function(m, n) { + return m % n; + }, + function(m, n) { + return bnMod.call(m, n); + }); + +// _integerGcd: integer-scheme-number integer-scheme-number -> integer-scheme-number +var _integerGcd = makeIntegerBinop( + function(a, b) { + var t; + while (b !== 0) { + t = a; + a = b; + b = t % b; + } + return a; + }, + function(m, n) { + return bnGCD.call(m, n); + }); + +// _integerIsZero: integer-scheme-number -> boolean +// Returns true if the number is zero. +var _integerIsZero = makeIntegerUnOp( + function(n) { + return n === 0; + }, + function(n) { + return bnEquals.call(n, BigInteger.ZERO); + } +); + +// _integerIsOne: integer-scheme-number -> boolean +var _integerIsOne = makeIntegerUnOp( + function(n) { + return n === 1; + }, + function(n) { + return bnEquals.call(n, BigInteger.ONE); + }); + +// _integerIsNegativeOne: integer-scheme-number -> boolean +var _integerIsNegativeOne = makeIntegerUnOp( + function(n) { + return n === -1; + }, + function(n) { + return bnEquals.call(n, BigInteger.NEGATIVE_ONE); + }); + +// _integerAdd: integer-scheme-number integer-scheme-number -> integer-scheme-number +var _integerAdd = makeIntegerBinop( + function(m, n) { + return m + n; + }, + function(m, n) { + return bnAdd.call(m, n); + }); +// _integerSubtract: integer-scheme-number integer-scheme-number -> integer-scheme-number +var _integerSubtract = makeIntegerBinop( + function(m, n) { + return m - n; + }, + function(m, n) { + return bnSubtract.call(m, n); + }); +// _integerMultiply: integer-scheme-number integer-scheme-number -> integer-scheme-number +var _integerMultiply = makeIntegerBinop( + function(m, n) { + return m * n; + }, + function(m, n) { + return bnMultiply.call(m, n); + }); +//_integerQuotient: integer-scheme-number integer-scheme-number -> integer-scheme-number +var _integerQuotient = makeIntegerBinop( + function(m, n) { + return ((m - (m % n)) / n); + }, + function(m, n) { + return bnDivide.call(m, n); + }); +var _integerRemainder = makeIntegerBinop( + function(m, n) { + return m % n; + }, + function(m, n) { + return bnRemainder.call(m, n); + }); + +// _integerDivideToFixnum: integer-scheme-number integer-scheme-number -> fixnum +var _integerDivideToFixnum = makeIntegerBinop( + function(m, n) { + return m / n; + }, + function(m, n) { + return toFixnum(m) / toFixnum(n); + }, { + ignoreOverflow: true, + doNotCoerseToFloating: true + }); + +// _integerEquals: integer-scheme-number integer-scheme-number -> boolean +var _integerEquals = makeIntegerBinop( + function(m, n) { + return m === n; + }, + function(m, n) { + return bnEquals.call(m, n); + }, { + doNotCoerseToFloating: true + }); +// _integerGreaterThan: integer-scheme-number integer-scheme-number -> boolean +var _integerGreaterThan = makeIntegerBinop( + function(m, n) { + return m > n; + }, + function(m, n) { + return bnCompareTo.call(m, n) > 0; + }, { + doNotCoerseToFloating: true + }); +// _integerLessThan: integer-scheme-number integer-scheme-number -> boolean +var _integerLessThan = makeIntegerBinop( + function(m, n) { + return m < n; + }, + function(m, n) { + return bnCompareTo.call(m, n) < 0; + }, { + doNotCoerseToFloating: true + }); +// _integerGreaterThanOrEqual: integer-scheme-number integer-scheme-number -> boolean +var _integerGreaterThanOrEqual = makeIntegerBinop( + function(m, n) { + return m >= n; + }, + function(m, n) { + return bnCompareTo.call(m, n) >= 0; + }, { + doNotCoerseToFloating: true + }); +// _integerLessThanOrEqual: integer-scheme-number integer-scheme-number -> boolean +var _integerLessThanOrEqual = makeIntegerBinop( + function(m, n) { + return m <= n; + }, + function(m, n) { + return bnCompareTo.call(m, n) <= 0; + }, { + doNotCoerseToFloating: true + }); + +////////////////////////////////////////////////////////////////////// +// The boxed number types are expected to implement the following +// interface. +// +// toString: -> string +// level: number +// liftTo: scheme-number -> scheme-number +// isFinite: -> boolean +// isInteger: -> boolean +// Produce true if this number can be coersed into an integer. +// isRational: -> boolean +// Produce true if the number is rational. +// isReal: -> boolean +// Produce true if the number is real. +// isExact: -> boolean +// Produce true if the number is exact +// toExact: -> scheme-number +// Produce an exact number. +// toFixnum: -> javascript-number +// Produce a javascript number. +// greaterThan: scheme-number -> boolean +// Compare against instance of the same type. +// greaterThanOrEqual: scheme-number -> boolean +// Compare against instance of the same type. +// lessThan: scheme-number -> boolean +// Compare against instance of the same type. +// lessThanOrEqual: scheme-number -> boolean +// Compare against instance of the same type. +// add: scheme-number -> scheme-number +// Add with an instance of the same type. +// subtract: scheme-number -> scheme-number +// Subtract with an instance of the same type. +// multiply: scheme-number -> scheme-number +// Multiply with an instance of the same type. +// divide: scheme-number -> scheme-number +// Divide with an instance of the same type. +// numerator: -> scheme-number +// Return the numerator. +// denominator: -> scheme-number +// Return the denominator. +// integerSqrt: -> scheme-number +// Produce the integer square root. +// sqrt: -> scheme-number +// Produce the square root. +// abs: -> scheme-number +// Produce the absolute value. +// floor: -> scheme-number +// Produce the floor. +// ceiling: -> scheme-number +// Produce the ceiling. +// conjugate: -> scheme-number +// Produce the conjugate. +// magnitude: -> scheme-number +// Produce the magnitude. +// log: -> scheme-number +// Produce the log. +// angle: -> scheme-number +// Produce the angle. +// atan: -> scheme-number +// Produce the arc tangent. +// cos: -> scheme-number +// Produce the cosine. +// sin: -> scheme-number +// Produce the sine. +// expt: scheme-number -> scheme-number +// Produce the power to the input. +// exp: -> scheme-number +// Produce e raised to the given power. +// acos: -> scheme-number +// Produce the arc cosine. +// asin: -> scheme-number +// Produce the arc sine. +// imaginaryPart: -> scheme-number +// Produce the imaginary part +// realPart: -> scheme-number +// Produce the real part. +// round: -> scheme-number +// Round to the nearest integer. +// equals: scheme-number -> boolean +// Produce true if the given number of the same type is equal. + +////////////////////////////////////////////////////////////////////// +// Rationals + +var Rational = function(n, d) { + this.n = n; + this.d = d; +}; + +Rational.prototype.toString = function() { + if (_integerIsOne(this.d)) { + return this.n.toString() + ""; + } else { + return this.n.toString() + "/" + this.d.toString(); + } +}; + +Rational.prototype.level = 1; + +Rational.prototype.liftTo = function(target) { + if (target.level === 2) + return new FloatPoint( + _integerDivideToFixnum(this.n, this.d)); + if (target.level === 3) + return new Complex(this, 0); + return throwRuntimeError("invalid level of Number", this, target); +}; +Rational.prototype.isFinite = function() { + return true; +}; +Rational.prototype.equals = function(other) { + return (other instanceof Rational && + _integerEquals(this.n, other.n) && + _integerEquals(this.d, other.d)); +}; + +Rational.prototype.isInteger = function() { + return _integerIsOne(this.d); +}; +Rational.prototype.isRational = function() { + return true; +}; +Rational.prototype.isReal = function() { + return true; +}; + +Rational.prototype.add = function(other) { + return Rational.makeInstance(_integerAdd(_integerMultiply(this.n, other.d), + _integerMultiply(this.d, other.n)), + _integerMultiply(this.d, other.d)); +}; +Rational.prototype.subtract = function(other) { + return Rational.makeInstance(_integerSubtract(_integerMultiply(this.n, other.d), + _integerMultiply(this.d, other.n)), + _integerMultiply(this.d, other.d)); +}; +Rational.prototype.negate = function() { + return Rational.makeInstance(-this.n, this.d) +}; +Rational.prototype.multiply = function(other) { + return Rational.makeInstance(_integerMultiply(this.n, other.n), + _integerMultiply(this.d, other.d)); +}; +Rational.prototype.divide = function(other) { + if (_integerIsZero(this.d) || _integerIsZero(other.n)) { + throwRuntimeError("/: division by zero", this, other); + } + return Rational.makeInstance(_integerMultiply(this.n, other.d), + _integerMultiply(this.d, other.n)); +}; + +Rational.prototype.toExact = function() { + return this; +}; +Rational.prototype.toInexact = function() { + return FloatPoint.makeInstance(this.toFixnum()); +}; + +Rational.prototype.isExact = function() { + return true; +}; +Rational.prototype.isInexact = function() { + return false; +}; + +Rational.prototype.toFixnum = function() { + return _integerDivideToFixnum(this.n, this.d); +}; +Rational.prototype.numerator = function() { + return this.n; +}; +Rational.prototype.denominator = function() { + return this.d; +}; +Rational.prototype.greaterThan = function(other) { + return _integerGreaterThan(_integerMultiply(this.n, other.d), + _integerMultiply(this.d, other.n)); +}; +Rational.prototype.greaterThanOrEqual = function(other) { + return _integerGreaterThanOrEqual(_integerMultiply(this.n, other.d), + _integerMultiply(this.d, other.n)); +}; +Rational.prototype.lessThan = function(other) { + return _integerLessThan(_integerMultiply(this.n, other.d), + _integerMultiply(this.d, other.n)); +}; +Rational.prototype.lessThanOrEqual = function(other) { + return _integerLessThanOrEqual(_integerMultiply(this.n, other.d), + _integerMultiply(this.d, other.n)); +}; + +Rational.prototype.integerSqrt = function() { + var result = sqrt(this); + if (isRational(result)) { + return toExact(floor(result)); + } else if (isReal(result)) { + return toExact(floor(result)); + } else { + return Complex.makeInstance(toExact(floor(realPart(result))), + toExact(floor(imaginaryPart(result)))); + } +}; + + +Rational.prototype.sqrt = function() { + if (_integerGreaterThanOrEqual(this.n, 0)) { + var newN = sqrt(this.n); + var newD = sqrt(this.d); + if (equals(floor(newN), newN) && + equals(floor(newD), newD)) { + return Rational.makeInstance(newN, newD); + } else { + return FloatPoint.makeInstance(_integerDivideToFixnum(newN, newD)); + } + } else { + var newN = sqrt(negate(this.n)); + var newD = sqrt(this.d); + if (equals(floor(newN), newN) && + equals(floor(newD), newD)) { + return Complex.makeInstance( + 0, + Rational.makeInstance(newN, newD)); + } else { + return Complex.makeInstance( + 0, + FloatPoint.makeInstance(_integerDivideToFixnum(newN, newD))); + } + } +}; + +Rational.prototype.abs = function() { + return Rational.makeInstance(abs(this.n), + this.d); +}; + + +Rational.prototype.floor = function() { + var quotient = _integerQuotient(this.n, this.d); + if (_integerLessThan(this.n, 0)) { + return subtract(quotient, 1); + } else { + return quotient; + } +}; + + +Rational.prototype.ceiling = function() { + var quotient = _integerQuotient(this.n, this.d); + if (_integerLessThan(this.n, 0)) { + return quotient; + } else { + return add(quotient, 1); + } +}; + +Rational.prototype.conjugate = function() { + return this; +}; + +Rational.prototype.magnitude = Rational.prototype.abs; + +Rational.prototype.log = function() { + return FloatPoint.makeInstance(Math.log(this.n / this.d)); +}; + +Rational.prototype.angle = function() { + if (_integerIsZero(this.n)) + return 0; + if (_integerGreaterThan(this.n, 0)) + return 0; + else + return FloatPoint.pi; +}; + +Rational.prototype.tan = function() { + return FloatPoint.makeInstance(Math.tan(_integerDivideToFixnum(this.n, this.d))); +}; + +Rational.prototype.atan = function() { + return FloatPoint.makeInstance(Math.atan(_integerDivideToFixnum(this.n, this.d))); +}; + +Rational.prototype.cos = function() { + return FloatPoint.makeInstance(Math.cos(_integerDivideToFixnum(this.n, this.d))); +}; + +Rational.prototype.sin = function() { + return FloatPoint.makeInstance(Math.sin(_integerDivideToFixnum(this.n, this.d))); +}; + +Rational.prototype.expt = function(a) { + if (isExactInteger(a) && greaterThanOrEqual(a, 0)) { + return fastExpt(this, a); + } + return FloatPoint.makeInstance(Math.pow(_integerDivideToFixnum(this.n, this.d), + _integerDivideToFixnum(a.n, a.d))); +}; + +Rational.prototype.exp = function() { + return FloatPoint.makeInstance(Math.exp(_integerDivideToFixnum(this.n, this.d))); +}; + +Rational.prototype.acos = function() { + return FloatPoint.makeInstance(Math.acos(_integerDivideToFixnum(this.n, this.d))); +}; + +Rational.prototype.asin = function() { + return FloatPoint.makeInstance(Math.asin(_integerDivideToFixnum(this.n, this.d))); +}; + +Rational.prototype.imaginaryPart = function() { + return 0; +}; + +Rational.prototype.realPart = function() { + return this; +}; + + +Rational.prototype.round = function() { + // FIXME: not correct when values are bignums + if (equals(this.d, 2)) { + // Round to even if it's a n/2 + var v = _integerDivideToFixnum(this.n, this.d); + var fl = Math.floor(v); + var ce = Math.ceil(v); + if (_integerIsZero(fl % 2)) { + return fl; + } else { + return ce; + } + } else { + return Math.round(this.n / this.d); + } +}; + + +Rational.makeInstance = function(n, d) { + if (n === undefined) + throwRuntimeError("n undefined", n, d); + + if (d === undefined) { + d = 1; + } + + if (_integerLessThan(d, 0)) { + n = negate(n); + d = negate(d); + } + + var divisor = _integerGcd(abs(n), abs(d)); + n = _integerQuotient(n, divisor); + d = _integerQuotient(d, divisor); + + // Optimization: if we can get around construction the rational + // in favor of just returning n, do it: + if (_integerIsOne(d) || _integerIsZero(n)) { + return n; + } + + return new Rational(n, d); +}; + + + +// Floating Point numbers +var FloatPoint = function(n) { + this.n = n; +}; +FloatPoint = FloatPoint; + + +var NaN = new FloatPoint(Number.NaN); +var inf = new FloatPoint(Number.POSITIVE_INFINITY); +var neginf = new FloatPoint(Number.NEGATIVE_INFINITY); + +// We use these two constants to represent the floating-point coersion +// of bignums that can't be represented with fidelity. +var TOO_POSITIVE_TO_REPRESENT = new FloatPoint(Number.POSITIVE_INFINITY); +var TOO_NEGATIVE_TO_REPRESENT = new FloatPoint(Number.NEGATIVE_INFINITY); + +// Negative zero is a distinguished value representing -0.0. +// There should only be one instance for -0.0. +var NEGATIVE_ZERO = new FloatPoint(-0.0); +var INEXACT_ZERO = new FloatPoint(0.0); + +FloatPoint.pi = new FloatPoint(Math.PI); +FloatPoint.e = new FloatPoint(Math.E); +FloatPoint.nan = NaN; +FloatPoint.inf = inf; +FloatPoint.neginf = neginf; + +FloatPoint.makeInstance = function(n) { + if (isNaN(n)) { + return FloatPoint.nan; + } else if (n === Number.POSITIVE_INFINITY) { + return FloatPoint.inf; + } else if (n === Number.NEGATIVE_INFINITY) { + return FloatPoint.neginf; + } else if (n === 0) { + if ((1 / n) === -Infinity) { + return NEGATIVE_ZERO; + } else { + return INEXACT_ZERO; + } + } + return new FloatPoint(n); +}; + + +FloatPoint.prototype.isExact = function() { + return false; +}; + +FloatPoint.prototype.isInexact = function() { + return true; +}; + + +FloatPoint.prototype.isFinite = function() { + return (isFinite(this.n) || + this === TOO_POSITIVE_TO_REPRESENT || + this === TOO_NEGATIVE_TO_REPRESENT); +}; + + +FloatPoint.prototype.toExact = function() { + // The precision of ieee is about 16 decimal digits, which we use here. + if (!isFinite(this.n) || isNaN(this.n)) { + throwRuntimeError("toExact: no exact representation for " + this, this); + } + + var stringRep = this.n.toString(); + var match = stringRep.match(/^(.*)\.(.*)$/); + if (match) { + var intPart = parseInt(match[1]); + var fracPart = parseInt(match[2]); + var tenToDecimalPlaces = Math.pow(10, match[2].length); + return Rational.makeInstance(Math.round(this.n * tenToDecimalPlaces), + tenToDecimalPlaces); + } else { + return this.n; + } +}; + +FloatPoint.prototype.toInexact = function() { + return this; +}; + +FloatPoint.prototype.isInexact = function() { + return true; +}; + + +FloatPoint.prototype.level = 2; + + +FloatPoint.prototype.liftTo = function(target) { + if (target.level === 3) + return new Complex(this, 0); + return throwRuntimeError("invalid level of Number", this, target); +}; + +FloatPoint.prototype.toString = function() { + if (isNaN(this.n)) + return "+nan.0"; + if (this.n === Number.POSITIVE_INFINITY) + return "+inf.0"; + if (this.n === Number.NEGATIVE_INFINITY) + return "-inf.0"; + if (this === NEGATIVE_ZERO) + return "-0.0"; + var partialResult = this.n.toString(); + if (!partialResult.match('\\.')) { + return partialResult + ".0"; + } else { + return partialResult; + } +}; + + +FloatPoint.prototype.equals = function(other, aUnionFind) { + return ((other instanceof FloatPoint) && + ((this.n === other.n))); +}; + + + +FloatPoint.prototype.isRational = function() { + return this.isFinite(); +}; + +FloatPoint.prototype.isInteger = function() { + return this.isFinite() && this.n === Math.floor(this.n); +}; + +FloatPoint.prototype.isReal = function() { + return true; +}; + + +// sign: Number -> {-1, 0, 1} +var sign = function(n) { + if (lessThan(n, 0)) { + return -1; + } else if (greaterThan(n, 0)) { + return 1; + } else if (n === NEGATIVE_ZERO) { + return -1; + } else { + return 0; + } +}; + + +FloatPoint.prototype.add = function(other) { + if (this.isFinite() && other.isFinite()) { + return FloatPoint.makeInstance(this.n + other.n); + } else { + if (isNaN(this.n) || isNaN(other.n)) { + return NaN; + } else if (this.isFinite() && !other.isFinite()) { + return other; + } else if (!this.isFinite() && other.isFinite()) { + return this; + } else { + return ((sign(this) * sign(other) === 1) ? + this : NaN); + }; + } +}; + +FloatPoint.prototype.subtract = function(other) { + if (this.isFinite() && other.isFinite()) { + return FloatPoint.makeInstance(this.n - other.n); + } else if (isNaN(this.n) || isNaN(other.n)) { + return NaN; + } else if (!this.isFinite() && !other.isFinite()) { + if (sign(this) === sign(other)) { + return NaN; + } else { + return this; + } + } else if (this.isFinite()) { + return multiply(other, -1); + } else { // other.isFinite() + return this; + } +}; + + +FloatPoint.prototype.negate = function() { + return FloatPoint.makeInstance(-this.n); +}; + +FloatPoint.prototype.multiply = function(other) { + return FloatPoint.makeInstance(this.n * other.n); +}; + +FloatPoint.prototype.divide = function(other) { + return FloatPoint.makeInstance(this.n / other.n); +}; + + +FloatPoint.prototype.toFixnum = function() { + return this.n; +}; + +FloatPoint.prototype.numerator = function() { + var stringRep = this.n.toString(); + var match = stringRep.match(/^(.*)\.(.*)$/); + if (match) { + var afterDecimal = parseInt(match[2]); + var factorToInt = Math.pow(10, match[2].length); + var extraFactor = _integerGcd(factorToInt, afterDecimal); + var multFactor = factorToInt / extraFactor; + return FloatPoint.makeInstance(Math.round(this.n * multFactor)); + } else { + return this; + } +}; + +FloatPoint.prototype.denominator = function() { + var stringRep = this.n.toString(); + var match = stringRep.match(/^(.*)\.(.*)$/); + if (match) { + var afterDecimal = parseInt(match[2]); + var factorToInt = Math.pow(10, match[2].length); + var extraFactor = _integerGcd(factorToInt, afterDecimal); + return FloatPoint.makeInstance(Math.round(factorToInt / extraFactor)); + } else { + return FloatPoint.makeInstance(1); + } +}; + + +FloatPoint.prototype.floor = function() { + return FloatPoint.makeInstance(Math.floor(this.n)); +}; + +FloatPoint.prototype.ceiling = function() { + return FloatPoint.makeInstance(Math.ceil(this.n)); +}; + + +FloatPoint.prototype.greaterThan = function(other) { + return this.n > other.n; +}; + +FloatPoint.prototype.greaterThanOrEqual = function(other) { + return this.n >= other.n; +}; + +FloatPoint.prototype.lessThan = function(other) { + return this.n < other.n; +}; + +FloatPoint.prototype.lessThanOrEqual = function(other) { + return this.n <= other.n; +}; + + +FloatPoint.prototype.integerSqrt = function() { + if (this === NEGATIVE_ZERO) { + return this; + } + if (isInteger(this)) { + if (this.n >= 0) { + return FloatPoint.makeInstance(Math.floor(Math.sqrt(this.n))); + } else { + return Complex.makeInstance( + INEXACT_ZERO, + FloatPoint.makeInstance(Math.floor(Math.sqrt(-this.n)))); + } + } else { + throwRuntimeError("integerSqrt: can only be applied to an integer", this); + } +}; + +FloatPoint.prototype.sqrt = function() { + if (this.n < 0) { + var result = Complex.makeInstance( + 0, + FloatPoint.makeInstance(Math.sqrt(-this.n))); + return result; + } else { + return FloatPoint.makeInstance(Math.sqrt(this.n)); + } +}; + +FloatPoint.prototype.abs = function() { + return FloatPoint.makeInstance(Math.abs(this.n)); +}; + + + +FloatPoint.prototype.log = function() { + if (this.n < 0) + return (new Complex(this, 0)).log(); + else + return FloatPoint.makeInstance(Math.log(this.n)); +}; + +FloatPoint.prototype.angle = function() { + if (0 === this.n) + return 0; + if (this.n > 0) + return 0; + else + return FloatPoint.pi; +}; + +FloatPoint.prototype.tan = function() { + return FloatPoint.makeInstance(Math.tan(this.n)); +}; + +FloatPoint.prototype.atan = function() { + return FloatPoint.makeInstance(Math.atan(this.n)); +}; + +FloatPoint.prototype.cos = function() { + return FloatPoint.makeInstance(Math.cos(this.n)); +}; + +FloatPoint.prototype.sin = function() { + return FloatPoint.makeInstance(Math.sin(this.n)); +}; + +FloatPoint.prototype.expt = function(a) { + if (this.n === 1) { + if (a.isFinite()) { + return this; + } else if (isNaN(a.n)) { + return this; + } else { + return this; + } + } else { + return FloatPoint.makeInstance(Math.pow(this.n, a.n)); + } +}; + +FloatPoint.prototype.exp = function() { + return FloatPoint.makeInstance(Math.exp(this.n)); +}; + +FloatPoint.prototype.acos = function() { + return FloatPoint.makeInstance(Math.acos(this.n)); +}; + +FloatPoint.prototype.asin = function() { + return FloatPoint.makeInstance(Math.asin(this.n)); +}; + +FloatPoint.prototype.imaginaryPart = function() { + return 0; +}; + +FloatPoint.prototype.realPart = function() { + return this; +}; + + +FloatPoint.prototype.round = function() { + if (isFinite(this.n)) { + if (this === NEGATIVE_ZERO) { + return this; + } + if (Math.abs(Math.floor(this.n) - this.n) === 0.5) { + if (Math.floor(this.n) % 2 === 0) + return FloatPoint.makeInstance(Math.floor(this.n)); + return FloatPoint.makeInstance(Math.ceil(this.n)); + } else { + return FloatPoint.makeInstance(Math.round(this.n)); + } + } else { + return this; + } +}; + + +FloatPoint.prototype.conjugate = function() { + return this; +}; + +FloatPoint.prototype.magnitude = FloatPoint.prototype.abs; + + + +////////////////////////////////////////////////////////////////////// +// Complex numbers +////////////////////////////////////////////////////////////////////// + +var Complex = function(r, i) { + this.r = r; + this.i = i; +}; + +// Constructs a complex number from two basic number r and i. r and i can +// either be plt.type.Rational or plt.type.FloatPoint. +Complex.makeInstance = function(r, i) { + if (i === undefined) { + i = 0; + } + if (isExact(i) && isInteger(i) && _integerIsZero(i)) { + return r; + } + if (isInexact(r) || isInexact(i)) { + r = toInexact(r); + i = toInexact(i); + } + return new Complex(r, i); +}; + +Complex.prototype.toString = function() { + var realPart = this.r.toString(), + imagPart = this.i.toString(); + if (imagPart[0] === '-' || imagPart[0] === '+') { + return realPart + imagPart + 'i'; + } else { + return realPart + "+" + imagPart + 'i'; + } +}; + + +Complex.prototype.isFinite = function() { + return isSchemeNumberFinite(this.r) && isSchemeNumberFinite(this.i); +}; + + +Complex.prototype.isRational = function() { + return isRational(this.r) && eqv(this.i, 0); +}; + +Complex.prototype.isInteger = function() { + return (isInteger(this.r) && + eqv(this.i, 0)); +}; + +Complex.prototype.toExact = function() { + return Complex.makeInstance(toExact(this.r), toExact(this.i)); +}; + +Complex.prototype.toInexact = function() { + return Complex.makeInstance(toInexact(this.r), + toInexact(this.i)); +}; + + +Complex.prototype.isExact = function() { + return isExact(this.r) && isExact(this.i); +}; + + +Complex.prototype.isInexact = function() { + return isInexact(this.r) || isInexact(this.i); +}; + + +Complex.prototype.level = 3; + + +Complex.prototype.liftTo = function(target) { + throwRuntimeError("Don't know how to lift Complex number", this, target); +}; + +Complex.prototype.equals = function(other) { + var result = ((other instanceof Complex) && + (equals(this.r, other.r)) && + (equals(this.i, other.i))); + return result; +}; + + + +Complex.prototype.greaterThan = function(other) { + if (!this.isReal() || !other.isReal()) { + throwRuntimeError(">: expects argument of type real number", this, other); + } + return greaterThan(this.r, other.r); +}; + +Complex.prototype.greaterThanOrEqual = function(other) { + if (!this.isReal() || !other.isReal()) { + throwRuntimeError(">=: expects argument of type real number", this, other); + } + return greaterThanOrEqual(this.r, other.r); +}; + +Complex.prototype.lessThan = function(other) { + if (!this.isReal() || !other.isReal()) { + throwRuntimeError("<: expects argument of type real number", this, other); + } + return lessThan(this.r, other.r); +}; + +Complex.prototype.lessThanOrEqual = function(other) { + if (!this.isReal() || !other.isReal()) { + throwRuntimeError("<=: expects argument of type real number", this, other); + } + return lessThanOrEqual(this.r, other.r); +}; + + +Complex.prototype.abs = function() { + if (!equals(this.i, 0).valueOf()) + throwRuntimeError("abs: expects argument of type real number", this); + return abs(this.r); +}; + +Complex.prototype.toFixnum = function() { + if (!equals(this.i, 0).valueOf()) + throwRuntimeError("toFixnum: expects argument of type real number", this); + return toFixnum(this.r); +}; + +Complex.prototype.numerator = function() { + if (!this.isReal()) + throwRuntimeError("numerator: can only be applied to real number", this); + return numerator(this.n); +}; + + +Complex.prototype.denominator = function() { + if (!this.isReal()) + throwRuntimeError("floor: can only be applied to real number", this); + return denominator(this.n); +}; + +Complex.prototype.add = function(other) { + return Complex.makeInstance( + add(this.r, other.r), + add(this.i, other.i)); +}; + +Complex.prototype.subtract = function(other) { + return Complex.makeInstance( + subtract(this.r, other.r), + subtract(this.i, other.i)); +}; + +Complex.prototype.negate = function() { + return Complex.makeInstance(negate(this.r), + negate(this.i)); +}; + + +Complex.prototype.multiply = function(other) { + // If the other value is real, just do primitive division + if (other.isReal()) { + return Complex.makeInstance( + multiply(this.r, other.r), + multiply(this.i, other.r)); + } + var r = subtract( + multiply(this.r, other.r), + multiply(this.i, other.i)); + var i = add( + multiply(this.r, other.i), + multiply(this.i, other.r)); + return Complex.makeInstance(r, i); +}; + + + + + +Complex.prototype.divide = function(other) { + var a, b, c, d, r, x, y; + // If the other value is real, just do primitive division + if (other.isReal()) { + return Complex.makeInstance( + divide(this.r, other.r), + divide(this.i, other.r)); + } + + if (this.isInexact() || other.isInexact()) { + // http://portal.acm.org/citation.cfm?id=1039814 + // We currently use Smith's method, though we should + // probably switch over to Priest's method. + a = this.r; + b = this.i; + c = other.r; + d = other.i; + if (lessThanOrEqual(abs(d), abs(c))) { + r = divide(d, c); + x = divide(add(a, multiply(b, r)), + add(c, multiply(d, r))); + y = divide(subtract(b, multiply(a, r)), + add(c, multiply(d, r))); + } else { + r = divide(c, d); + x = divide(add(multiply(a, r), b), + add(multiply(c, r), d)); + y = divide(subtract(multiply(b, r), a), + add(multiply(c, r), d)); + } + return Complex.makeInstance(x, y); + } else { + var con = conjugate(other); + var up = multiply(this, con); + + // Down is guaranteed to be real by this point. + var down = realPart(multiply(other, con)); + + var result = Complex.makeInstance( + divide(realPart(up), down), + divide(imaginaryPart(up), down)); + return result; + } +}; + +Complex.prototype.conjugate = function() { + var result = Complex.makeInstance( + this.r, + subtract(0, this.i)); + + return result; +}; + +Complex.prototype.magnitude = function() { + var sum = add( + multiply(this.r, this.r), + multiply(this.i, this.i)); + return sqrt(sum); +}; + +Complex.prototype.isReal = function() { + return eqv(this.i, 0); +}; + +Complex.prototype.integerSqrt = function() { + if (isInteger(this)) { + return integerSqrt(this.r); + } else { + throwRuntimeError("integerSqrt: can only be applied to an integer", this); + } +}; + +Complex.prototype.sqrt = function() { + if (this.isReal()) + return sqrt(this.r); + // http://en.wikipedia.org/wiki/Square_root#Square_roots_of_negative_and_complex_numbers + var r_plus_x = add(this.magnitude(), this.r); + + var r = sqrt(halve(r_plus_x)); + + var i = divide(this.i, sqrt(multiply(r_plus_x, 2))); + + + return Complex.makeInstance(r, i); +}; + +Complex.prototype.log = function() { + var m = this.magnitude(); + var theta = this.angle(); + var result = add( + log(m), + timesI(theta)); + return result; +}; + +Complex.prototype.angle = function() { + if (this.isReal()) { + return angle(this.r); + } + if (equals(0, this.r)) { + var tmp = halve(FloatPoint.pi); + return greaterThan(this.i, 0) ? + tmp : negate(tmp); + } else { + var tmp = atan(divide(abs(this.i), abs(this.r))); + if (greaterThan(this.r, 0)) { + return greaterThan(this.i, 0) ? + tmp : negate(tmp); + } else { + return greaterThan(this.i, 0) ? + subtract(FloatPoint.pi, tmp) : subtract(tmp, FloatPoint.pi); + } + } +}; + +var plusI = Complex.makeInstance(0, 1); +var minusI = Complex.makeInstance(0, -1); + + +Complex.prototype.tan = function() { + return divide(this.sin(), this.cos()); +}; + +Complex.prototype.atan = function() { + if (equals(this, plusI) || + equals(this, minusI)) { + return neginf; + } + return multiply( + plusI, + multiply( + FloatPoint.makeInstance(0.5), + log(divide( + add(plusI, this), + add( + plusI, + subtract(0, this)))))); +}; + +Complex.prototype.cos = function() { + if (this.isReal()) + return cos(this.r); + var iz = timesI(this); + var iz_negate = negate(iz); + + return halve(add(exp(iz), exp(iz_negate))); +}; + +Complex.prototype.sin = function() { + if (this.isReal()) + return sin(this.r); + var iz = timesI(this); + var iz_negate = negate(iz); + var z2 = Complex.makeInstance(0, 2); + var exp_negate = subtract(exp(iz), exp(iz_negate)); + var result = divide(exp_negate, z2); + return result; +}; + + +Complex.prototype.expt = function(y) { + if (isExactInteger(y) && greaterThanOrEqual(y, 0)) { + return fastExpt(this, y); + } + var expo = multiply(y, this.log()); + return exp(expo); +}; + +Complex.prototype.exp = function() { + var r = exp(this.r); + var cos_a = cos(this.i); + var sin_a = sin(this.i); + + return multiply( + r, + add(cos_a, timesI(sin_a))); +}; + +Complex.prototype.acos = function() { + if (this.isReal()) + return acos(this.r); + var pi_half = halve(FloatPoint.pi); + var iz = timesI(this); + var root = sqrt(subtract(1, sqr(this))); + var l = timesI(log(add(iz, root))); + return add(pi_half, l); +}; + +Complex.prototype.asin = function() { + if (this.isReal()) + return asin(this.r); + + var oneNegateThisSq = + subtract(1, sqr(this)); + var sqrtOneNegateThisSq = sqrt(oneNegateThisSq); + return multiply(2, atan(divide(this, + add(1, sqrtOneNegateThisSq)))); +}; + +Complex.prototype.ceiling = function() { + if (!this.isReal()) + throwRuntimeError("ceiling: can only be applied to real number", this); + return ceiling(this.r); +}; + +Complex.prototype.floor = function() { + if (!this.isReal()) + throwRuntimeError("floor: can only be applied to real number", this); + return floor(this.r); +}; + +Complex.prototype.imaginaryPart = function() { + return this.i; +}; + +Complex.prototype.realPart = function() { + return this.r; +}; + +Complex.prototype.round = function() { + if (!this.isReal()) + throwRuntimeError("round: can only be applied to real number", this); + return round(this.r); +}; + + + +var rationalRegexp = new RegExp("^([+-]?\\d+)/(\\d+)$"); +var complexRegexp = new RegExp("^([+-]?[\\d\\w/\\.]*)([+-])([\\d\\w/\\.]*)i$"); +var digitRegexp = new RegExp("^[+-]?\\d+$"); +var flonumRegexp = new RegExp("^([+-]?\\d*)\\.(\\d*)$"); +var scientificPattern = new RegExp("^([+-]?\\d*\\.?\\d*)[Ee](\\+?\\d+)$"); + +// fromString: string -> (scheme-number | false) +var fromString = function(x) { + x = x.toString(); // TODO: This can be done better. + + var aMatch = x.match(rationalRegexp); + if (aMatch) { + return Rational.makeInstance(fromString(aMatch[1]), + fromString(aMatch[2])); + } + + var cMatch = x.match(complexRegexp); + if (cMatch) { + return Complex.makeInstance(fromString(cMatch[1] || "0"), + fromString(cMatch[2] + (cMatch[3] || "1"))); + } + + // Floating point tests + if (x === '+nan.0' || x === '-nan.0') + return FloatPoint.nan; + if (x === '+inf.0') + return FloatPoint.inf; + if (x === '-inf.0') + return FloatPoint.neginf; + if (x === "-0.0") { + return NEGATIVE_ZERO; + } + if (x.match(flonumRegexp) || x.match(scientificPattern)) { + return FloatPoint.makeInstance(Number(x)); + } + + // Finally, integer tests. + if (x.match(digitRegexp)) { + var n = Number(x); + if (isOverflow(n)) { + return makeBignum(x); + } else { + return n; + } + } else { + return false; + } +}; + + + + + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +// The code below comes from Tom Wu's BigInteger implementation: + +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary & 0xffffff) == 0xefcafe); + +// (public) Constructor +function BigInteger(a, b, c) { + if (a != null) + if ("number" == typeof a) this.fromNumber(a, b, c); + else if (b == null && "string" != typeof a) this.fromString(a, 256); + else this.fromString(a, b); +} + +// return new, unset BigInteger +function nbi() { + return new BigInteger(null); +} + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, + xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, + xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; +} +if (j_lm && (typeof(navigator) !== 'undefined' && navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} else if (j_lm && (typeof(navigator) !== 'undefined' && navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1 << dbits) - 1); +BigInteger.prototype.DV = (1 << dbits); + +var BI_FP = 52; +BigInteger.prototype.FV = Math.pow(2, BI_FP); +BigInteger.prototype.F1 = BI_FP - dbits; +BigInteger.prototype.F2 = 2 * dbits - BI_FP; + +// Digit conversions +var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; +var BI_RC = []; +var rr, vv; +rr = "0".charCodeAt(0); +for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; +rr = "a".charCodeAt(0); +for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; +rr = "A".charCodeAt(0); +for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + +function int2char(n) { + return BI_RM.charAt(n); +} + +function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return (c == null) ? -1 : c; +} + +// (protected) copy this to r +function bnpCopyTo(r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x < 0) ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; +} + +// (protected) set from string and radix +function bnpFromString(s, b) { + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { + this.fromRadix(s, b); + return; + } + this.t = 0; + this.s = 0; + var i = s.length, + mi = false, + sh = 0; + while (--i >= 0) { + var x = (k == 8) ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if (sh == 0) + this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = (x >> (this.DB - sh)); + } else + this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); +} + +// (protected) clamp off excess high words +function bnpClamp() { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if (this.s < 0) return "-" + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, + d, m = false, + r = [], + i = this.t; + var p = this.DB - (i * this.DB) % k; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { + m = true; + r.push(int2char(d)); + } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { + p += this.DB; + --i; + } + } + if (d > 0) m = true; + if (m) r.push(int2char(d)); + } + } + return m ? r.join("") : "0"; +} + +// (public) -this +function bnNegate() { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; +} + +// (public) |this| +function bnAbs() { + return (this.s < 0) ? this.negate() : this; +} + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + if (this.s < 0) { + r = a.t - i; + } else { + r = i - a.t; + } + if (r != 0) return r; + while (--i >= 0) + if ((r = this[i] - a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, + t; + if ((t = x >>> 16) != 0) { + x = t; + r += 16; + } + if ((t = x >> 8) != 0) { + x = t; + r += 8; + } + if ((t = x >> 4) != 0) { + x = t; + r += 4; + } + if ((t = x >> 2) != 0) { + x = t; + r += 2; + } + if ((t = x >> 1) != 0) { + x = t; + r += 1; + } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if (this.t <= 0) return 0; + return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), + c = (this.s << bs) & this.DM, + i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; + } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); +} + +// (protected) r = this - a +function bnpSubTo(a, r) { + var i = 0, + c = 0, + m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a, r) { + var x = this.abs(), + y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2 * x.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); +} + + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), + ts = this.s, + ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, + d2 = (1 << this.F1) / yt, + e = 1 << this.F2; + var i = r.t, + j = i - ys, + t = (q == null) ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { + this.m = m; +} + +function cConvert(x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} + +function cRevert(x) { + return x; +} + +function cReduce(x) { + x.divRemTo(this.m, null, x); +} + +function cMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); +} + +function cSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); +} + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y > 0) ? this.DV - y : -y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while (x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV; + x[++j]++; + } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); +} + +// r = "xy/R mod m"; x,y != r +function montMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); +} + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { + return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; +} + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), + r2 = nbi(), + g = z.convert(this), + i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { + var t = r; + r = r2; + r2 = t; + } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); + else z = new Montgomery(m); + return this.exp(e, z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// Copyright (c) 2005-2009 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Extended JavaScript BN functions, required for RSA private ops. + +// Version 1.1: new BigInteger("0", 10) returns "proper" zero + +// (public) +function bnClone() { + var r = nbi(); + this.copyTo(r); + return r; +} + +// (public) return value as integer +function bnIntValue() { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; +} + +// (public) return value as byte +function bnByteValue() { + return (this.t == 0) ? this.s : (this[0] << 24) >> 24; +} + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { + return (this.t == 0) ? this.s : (this[0] << 16) >> 16; +} + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { + return Math.floor(Math.LN2 * this.DB / Math.log(r)); +} + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), + y = nbi(), + z = nbi(), + r = ""; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; +} + +// (protected) convert from radix string +function bnpFromRadix(s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), + mi = false, + j = 0, + w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); +} + +// (protected) alternate constructor +function bnpFromNumber(a, b, c) { + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } else { + // new BigInteger(int,RNG) + var x = [], + t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= ((1 << t) - 1); + else x[0] = 0; + this.fromString(x, 256); + } +} + +// (public) convert to bigendian byte array +function bnToByteArray() { + var i = this.t, + r = []; + r[0] = this.s; + var p = this.DB - (i * this.DB) % 8, + d, k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { + p += this.DB; + --i; + } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; +} + +function bnEquals(a) { + return (this.compareTo(a) == 0); +} + +function bnMin(a) { + return (this.compareTo(a) < 0) ? this : a; +} + +function bnMax(a) { + return (this.compareTo(a) > 0) ? this : a; +} + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a, op, r) { + var i, f, m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); +} + +// (public) this & a +function op_and(x, y) { + return x & y; +} + +function bnAnd(a) { + var r = nbi(); + this.bitwiseTo(a, op_and, r); + return r; +} + +// (public) this | a +function op_or(x, y) { + return x | y; +} + +function bnOr(a) { + var r = nbi(); + this.bitwiseTo(a, op_or, r); + return r; +} + +// (public) this ^ a +function op_xor(x, y) { + return x ^ y; +} + +function bnXor(a) { + var r = nbi(); + this.bitwiseTo(a, op_xor, r); + return r; +} + +// (public) this & ~a +function op_andnot(x, y) { + return x & ~y; +} + +function bnAndNot(a) { + var r = nbi(); + this.bitwiseTo(a, op_andnot, r); + return r; +} + +// (public) ~this +function bnNot() { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +} + +// (public) this << n +function bnShiftLeft(n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); + else this.lShiftTo(n, r); + return r; +} + +// (public) this >> n +function bnShiftRight(n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); + else this.rShiftTo(n, r); + return r; +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { + x >>= 16; + r += 16; + } + if ((x & 0xff) == 0) { + x >>= 8; + r += 8; + } + if ((x & 0xf) == 0) { + x >>= 4; + r += 4; + } + if ((x & 3) == 0) { + x >>= 2; + r += 2; + } + if ((x & 1) == 0) ++r; + return r; +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while (x != 0) { + x &= x - 1; + ++r; + } + return r; +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, + x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return (this.s != 0); + return ((this[j] & (1 << (n % this.DB))) != 0); +} + +// (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); +} + +// (public) this + a +function bnAdd(a) { + var r = nbi(); + this.addTo(a, r); + return r; +} + +// (public) this - a +function bnSubtract(a) { + var r = nbi(); + this.subTo(a, r); + return r; +} + +// (public) this * a +function bnMultiply(a) { + var r = nbi(); + this.multiplyTo(a, r); + return r; +} + +// (public) this / a +function bnDivide(a) { + var r = nbi(); + this.divRemTo(a, r, null); + return r; +} + +// (public) this % a +function bnRemainder(a) { + var r = nbi(); + this.divRemTo(a, null, r); + return r; +} + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = nbi(), + r = nbi(); + this.divRemTo(a, q, r); + return [q, r]; +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +} + +// A "null" reducer +function NullExp() {} + +function nNop(x) { + return x; +} + +function nMulTo(x, y, r) { + x.multiplyTo(y, r); +} + +function nSqrTo(x, r) { + x.squareTo(r); +} + +NullExp.prototype.convert = nNop; +NullExp.prototype.revert = nNop; +NullExp.prototype.mulTo = nMulTo; +NullExp.prototype.sqrTo = nSqrTo; + +// (public) this^e +function bnPow(e) { + return this.exp(e, new NullExp()); +} + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a, n, r) { + --n; + var i = r.t = this.t + a.t - n; + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} + +function barrettConvert(x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } +} + +function barrettRevert(x) { + return x; +} + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { + x.t = this.m.t + 1; + x.clamp(); + } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); +} + +// r = x*y mod m; x,y != r +function barrettMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); +} + +Barrett.prototype.convert = barrettConvert; +Barrett.prototype.revert = barrettRevert; +Barrett.prototype.reduce = barrettReduce; +Barrett.prototype.mulTo = barrettMulTo; +Barrett.prototype.sqrTo = barrettSqrTo; + +// (public) this^e % m (HAC 14.85) +function bnModPow(e, m) { + var i = e.bitLength(), + k, r = nbv(1), + z; + if (i <= 0) return r; + else if (i < 18) k = 1; + else if (i < 48) k = 3; + else if (i < 144) k = 4; + else if (i < 768) k = 5; + else k = 6; + if (i < 8) + z = new Classic(m); + else if (m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = [], + n = 3, + k1 = k - 1, + km = (1 << k) - 1; + g[1] = z.convert(this); + if (k > 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, + w, is1 = true, + r2 = nbi(), + t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { + w >>= 1; + --n; + } + if ((i -= n) < 0) { + i += this.DB; + --j; + } + if (is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } else { + while (n > 1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n > 0) z.sqrTo(r, r2); + else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); + t = r; + r = r2; + r2 = t; + if (--i < 0) { + i = this.DB - 1; + --j; + } + } + } + return z.revert(r); +} + +// (public) gcd(this,a) (HAC 14.54) +function bnGCD(a) { + var x = (this.s < 0) ? this.negate() : this.clone(); + var y = (a.s < 0) ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(), + g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if (n <= 0) return 0; + var d = this.DV % n, + r = (this.s < 0) ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else + for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven(); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), + v = this.clone(); + var a = nbv(1), + b = nbv(0), + c = nbv(0), + d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a); + b.subTo(m, b); + } + a.rShiftTo(1, a); + } else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c); + d.subTo(m, d); + } + c.rShiftTo(1, c); + } else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if (d.compareTo(m) >= 0) return d.subtract(m); + if (d.signum() < 0) d.addTo(m, d); + else return d; + if (d.signum() < 0) return d.add(m); + else return d; +} + +var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509]; +var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], + j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) + if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +} + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + a.fromInt(lowprimes[i]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; +} + + + +// protected +BigInteger.prototype.chunkSize = bnpChunkSize; +BigInteger.prototype.toRadix = bnpToRadix; +BigInteger.prototype.fromRadix = bnpFromRadix; +BigInteger.prototype.fromNumber = bnpFromNumber; +BigInteger.prototype.bitwiseTo = bnpBitwiseTo; +BigInteger.prototype.changeBit = bnpChangeBit; +BigInteger.prototype.addTo = bnpAddTo; +BigInteger.prototype.dMultiply = bnpDMultiply; +BigInteger.prototype.dAddOffset = bnpDAddOffset; +BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; +BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; +BigInteger.prototype.modInt = bnpModInt; +BigInteger.prototype.millerRabin = bnpMillerRabin; + +// public +BigInteger.prototype.clone = bnClone; +BigInteger.prototype.intValue = bnIntValue; +BigInteger.prototype.byteValue = bnByteValue; +BigInteger.prototype.shortValue = bnShortValue; +BigInteger.prototype.signum = bnSigNum; +BigInteger.prototype.toByteArray = bnToByteArray; +BigInteger.prototype.equals = bnEquals; +BigInteger.prototype.min = bnMin; +BigInteger.prototype.max = bnMax; +BigInteger.prototype.and = bnAnd; +BigInteger.prototype.or = bnOr; +BigInteger.prototype.xor = bnXor; +BigInteger.prototype.andNot = bnAndNot; +BigInteger.prototype.not = bnNot; +BigInteger.prototype.shiftLeft = bnShiftLeft; +BigInteger.prototype.shiftRight = bnShiftRight; +BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; +BigInteger.prototype.bitCount = bnBitCount; +BigInteger.prototype.testBit = bnTestBit; +BigInteger.prototype.setBit = bnSetBit; +BigInteger.prototype.clearBit = bnClearBit; +BigInteger.prototype.flipBit = bnFlipBit; +BigInteger.prototype.add = bnAdd; +BigInteger.prototype.subtract = bnSubtract; +BigInteger.prototype.multiply = bnMultiply; +BigInteger.prototype.divide = bnDivide; +BigInteger.prototype.remainder = bnRemainder; +BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; +BigInteger.prototype.modPow = bnModPow; +BigInteger.prototype.modInverse = bnModInverse; +BigInteger.prototype.pow = bnPow; +BigInteger.prototype.gcd = bnGCD; +BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + +// BigInteger interfaces not implemented in jsbn: + +// BigInteger(int signum, byte[] magnitude) +// double doubleValue() +// float floatValue() +// int hashCode() +// long longValue() +// static BigInteger valueOf(long val) + + + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// +// END OF copy-and-paste of jsbn. + + + +BigInteger.NEGATIVE_ONE = BigInteger.ONE.negate(); + + +// Other methods we need to add for compatibilty with js-numbers numeric tower. + +// add is implemented above. +// subtract is implemented above. +// multiply is implemented above. +// equals is implemented above. +// abs is implemented above. +// negate is defined above. + +// makeBignum: string -> BigInteger +var makeBignum = function(s) { + if (typeof(s) === 'number') { + s = s + ''; + } + s = expandExponent(s); + return new BigInteger(s, 10); +}; + +var zerostring = function(n) { + var buf = []; + for (var i = 0; i < n; i++) { + buf.push('0'); + } + return buf.join(''); +}; + + +BigInteger.prototype.level = 0; +BigInteger.prototype.liftTo = function(target) { + if (target.level === 1) { + return new Rational(this, 1); + } + if (target.level === 2) { + var fixrep = this.toFixnum(); + if (fixrep === Number.POSITIVE_INFINITY) + return TOO_POSITIVE_TO_REPRESENT; + if (fixrep === Number.NEGATIVE_INFINITY) + return TOO_NEGATIVE_TO_REPRESENT; + return new FloatPoint(fixrep); + } + if (target.level === 3) { + return new Complex(this, 0); + } + return throwRuntimeError("invalid level for BigInteger lift", this, target); +}; + +BigInteger.prototype.isFinite = function() { + return true; +}; + +BigInteger.prototype.isInteger = function() { + return true; +}; + +BigInteger.prototype.isRational = function() { + return true; +}; + +BigInteger.prototype.isReal = function() { + return true; +}; + +BigInteger.prototype.isExact = function() { + return true; +}; + +BigInteger.prototype.isInexact = function() { + return false; +}; + +BigInteger.prototype.toExact = function() { + return this; +}; + +BigInteger.prototype.toInexact = function() { + return FloatPoint.makeInstance(this.toFixnum()); +}; + +BigInteger.prototype.toFixnum = function() { + var result = 0, + str = this.toString(), + i; + if (str[0] === '-') { + for (i = 1; i < str.length; i++) { + result = result * 10 + Number(str[i]); + } + return -result; + } else { + for (i = 0; i < str.length; i++) { + result = result * 10 + Number(str[i]); + } + return result; + } +}; + + +BigInteger.prototype.greaterThan = function(other) { + return this.compareTo(other) > 0; +}; + +BigInteger.prototype.greaterThanOrEqual = function(other) { + return this.compareTo(other) >= 0; +}; + +BigInteger.prototype.lessThan = function(other) { + return this.compareTo(other) < 0; +}; + +BigInteger.prototype.lessThanOrEqual = function(other) { + return this.compareTo(other) <= 0; +}; + +// divide: scheme-number -> scheme-number +// WARNING NOTE: we override the old version of divide. +BigInteger.prototype.divide = function(other) { + var quotientAndRemainder = bnDivideAndRemainder.call(this, other); + if (quotientAndRemainder[1].compareTo(BigInteger.ZERO) === 0) { + return quotientAndRemainder[0]; + } else { + var result = add(quotientAndRemainder[0], + Rational.makeInstance(quotientAndRemainder[1], other)); + return result; + } +}; + +BigInteger.prototype.numerator = function() { + return this; +}; + +BigInteger.prototype.denominator = function() { + return 1; +}; + + +(function() { + // Classic implementation of Newton-Ralphson square-root search, + // adapted for integer-sqrt. + // http://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number + var searchIter = function(n, guess) { + while (!(lessThanOrEqual(sqr(guess), n) && + lessThan(n, sqr(add(guess, 1))))) { + guess = floor(divide(add(guess, + floor(divide(n, guess))), + 2)); + } + return guess; + }; + + // integerSqrt: -> scheme-number + BigInteger.prototype.integerSqrt = function() { + var n; + if (sign(this) >= 0) { + return searchIter(this, this); + } else { + n = this.negate(); + return Complex.makeInstance(0, searchIter(n, n)); + } + }; +})(); + + +(function() { + // Get an approximation using integerSqrt, and then start another + // Newton-Ralphson search if necessary. + BigInteger.prototype.sqrt = function() { + var approx = this.integerSqrt(), + fix; + if (eqv(sqr(approx), this)) { + return approx; + } + fix = toFixnum(this); + if (isFinite(fix)) { + if (fix >= 0) { + return FloatPoint.makeInstance(Math.sqrt(fix)); + } else { + return Complex.makeInstance( + 0, + FloatPoint.makeInstance(Math.sqrt(-fix))); + } + } else { + return approx; + } + }; +})(); + + + + + +// sqrt: -> scheme-number +// http://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number +// Produce the square root. + +// floor: -> scheme-number +// Produce the floor. +BigInteger.prototype.floor = function() { + return this; +} + +// ceiling: -> scheme-number +// Produce the ceiling. +BigInteger.prototype.ceiling = function() { + return this; +} + +// conjugate: -> scheme-number +// Produce the conjugate. + +// magnitude: -> scheme-number +// Produce the magnitude. + +// log: -> scheme-number +// Produce the log. + +// angle: -> scheme-number +// Produce the angle. + +// atan: -> scheme-number +// Produce the arc tangent. + +// cos: -> scheme-number +// Produce the cosine. + +// sin: -> scheme-number +// Produce the sine. + + +// expt: scheme-number -> scheme-number +// Produce the power to the input. +BigInteger.prototype.expt = function(n) { + return bnPow.call(this, n); +}; + + + +// exp: -> scheme-number +// Produce e raised to the given power. + +// acos: -> scheme-number +// Produce the arc cosine. + +// asin: -> scheme-number +// Produce the arc sine. + +BigInteger.prototype.imaginaryPart = function() { + return 0; +} +BigInteger.prototype.realPart = function() { + return this; +} + +// round: -> scheme-number +// Round to the nearest integer. + + + + + +////////////////////////////////////////////////////////////////////// +// toRepeatingDecimal: jsnum jsnum {limit: number}? -> [string, string, string] +// +// Given the numerator and denominator parts of a rational, +// produces the repeating-decimal representation, where the first +// part are the digits before the decimal, the second are the +// non-repeating digits after the decimal, and the third are the +// remaining repeating decimals. +// +// An optional limit on the decimal expansion can be provided, in which +// case the search cuts off if we go past the limit. +// If this happens, the third argument returned becomes '...' to indicate +// that the search was prematurely cut off. +var toRepeatingDecimal = (function() { + var getResidue = function(r, d, limit) { + var digits = []; + var seenRemainders = {}; + seenRemainders[r] = true; + while (true) { + if (limit-- <= 0) { + return [digits.join(''), '...'] + } + + var nextDigit = quotient( + multiply(r, 10), d); + var nextRemainder = remainder( + multiply(r, 10), + d); + digits.push(nextDigit.toString()); + if (seenRemainders[nextRemainder]) { + r = nextRemainder; + break; + } else { + seenRemainders[nextRemainder] = true; + r = nextRemainder; + } + } + + var firstRepeatingRemainder = r; + var repeatingDigits = []; + while (true) { + var nextDigit = quotient(multiply(r, 10), d); + var nextRemainder = remainder( + multiply(r, 10), + d); + repeatingDigits.push(nextDigit.toString()); + if (equals(nextRemainder, firstRepeatingRemainder)) { + break; + } else { + r = nextRemainder; + } + }; + + var digitString = digits.join(''); + var repeatingDigitString = repeatingDigits.join(''); + + while (digitString.length >= repeatingDigitString.length && + (digitString.substring( + digitString.length - repeatingDigitString.length) === + repeatingDigitString)) { + digitString = digitString.substring( + 0, digitString.length - repeatingDigitString.length); + } + + return [digitString, repeatingDigitString]; + + }; + + return function(n, d, options) { + // default limit on decimal expansion; can be overridden + var limit = 512; + if (options && typeof(options.limit) !== 'undefined') { + limit = options.limit; + } + if (!isInteger(n)) { + throwRuntimeError('toRepeatingDecimal: n ' + n.toString() + + " is not an integer."); + } + if (!isInteger(d)) { + throwRuntimeError('toRepeatingDecimal: d ' + d.toString() + + " is not an integer."); + } + if (equals(d, 0)) { + throwRuntimeError('toRepeatingDecimal: d equals 0'); + } + if (lessThan(d, 0)) { + throwRuntimeError('toRepeatingDecimal: d < 0'); + } + var sign = (lessThan(n, 0) ? "-" : ""); + n = abs(n); + var beforeDecimalPoint = sign + quotient(n, d); + var afterDecimals = getResidue(remainder(n, d), d, limit); + return [beforeDecimalPoint].concat(afterDecimals); + }; +})(); +////////////////////////////////////////////////////////////////////// + + + + +// External interface of js-numbers: + +const makeRational = Rational.makeInstance; +const makeFloat = FloatPoint.makeInstance; +const makeComplex = Complex.makeInstance; +const pi = FloatPoint.pi; +const e = FloatPoint.e; +const nan = FloatPoint.nan; +const negative_inf = FloatPoint.neginf; +// const inf = FloatPoint.inf; +const negative_one = -1; +const one = 1; +const zero = 0; + +export { + fromFixnum, + fromString, + makeBignum, + makeRational, + makeFloat, + makeComplex, + makeComplexPolar, + // pi, + e, + nan, + negative_inf, + inf, + negative_one, // Rational.NEGATIVE_ONE, + zero, // Rational.ZERO, + one, // Rational.ONE, + plusI as i, + minusI as negative_i, + NEGATIVE_ZERO as negative_zero, + onThrowRuntimeError, + isSchemeNumber, + isRational, + isReal, + isExact, + isInexact, + isInteger, + toFixnum, + toExact, + toInexact, + add, + subtract, + multiply, + divide, + equals, + eqv, + approxEquals, + greaterThanOrEqual, + lessThanOrEqual, + greaterThan, + lessThan, + expt, + exp, + modulo, + numerator, + denominator, + integerSqrt, + sqrt, + abs, + quotient, + remainder, + floor, + ceiling, + conjugate, + magnitude, + log, + angle, + tan, + atan, + atan2, + cos, + sin, + acos, + asin, + cosh, + sinh, + imaginaryPart, + realPart, + round, + sqr, + gcd, + lcm, + toRepeatingDecimal, + BigInteger, + Rational, + FloatPoint, + Complex, + MIN_FIXNUM, + MAX_FIXNUM, + bitwiseAnd, + bitwiseOr, + bitwiseXor, + bitwiseNot, + arithmeticShift +}; diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/path.js b/racketscript-compiler/racketscript/compiler/runtime/core/path.js new file mode 100644 index 00000000..22406aaa --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/core/path.js @@ -0,0 +1,12 @@ +import { PrintablePrimitive } from './printable_primitive.js'; + +class Path extends PrintablePrimitive { + constructor(s) { + super(); + this.s = s; + } +} + +export function fromString(s) { return new Path(s); } +export function check(s) { return (s instanceof Path); } + diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/ports.js b/racketscript-compiler/racketscript/compiler/runtime/core/ports.js index eed975d0..d4e0eb8f 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/ports.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/ports.js @@ -10,6 +10,18 @@ class Port extends PrintablePrimitive { isInputPort() { return false; } + + isStringPort() { + return false; + } +} + + +/** @abstract */ +class InputPort extends PrintablePrimitive { + isInputPort() { + return true; + } } /** @@ -43,6 +55,10 @@ export function isOutputPort(v) { return check(v) && v.isOutputPort(); } +export function isStringPort(v) { + return check(v) && v.isStringPort(); +} + // Only consumes output via the given `consumeFn` when encountering a newline, // othewise buffers the output. // Writes *native* strings to the output. @@ -81,7 +97,10 @@ class NewlineFlushingOutputPort extends OutputPort { } } +// eslint-disable-next-line no-console export const standardOutputPort = new NewlineFlushingOutputPort(str => console.log(str), 'stdout'); +export const standardInputPort = new InputPort(); +// eslint-disable-next-line no-console export const standardErrorPort = new NewlineFlushingOutputPort(str => console.log(str), 'stderr'); /** @@ -119,6 +138,9 @@ export class NativeOutputStringPort extends OutputPort { return 'js-string'; } + isStringPort() { + return true; + } isUStringPort() { return false; @@ -155,6 +177,10 @@ class OutputStringPort extends OutputPort { return 'string'; } + isStringPort() { + return true; + } + isUStringPort() { return true; } diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/primitive_symbol.js b/racketscript-compiler/racketscript/compiler/runtime/core/primitive_symbol.js new file mode 100644 index 00000000..266e36ef --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/core/primitive_symbol.js @@ -0,0 +1,81 @@ +import { PrintablePrimitive } from './printable_primitive.js'; +import { hashString } from './raw_hashing.js'; + +let counter = 0; + +class PrimitiveSymbol extends PrintablePrimitive { + constructor(name) { + super(); + + if (name) { + // interned + this.name = name; + this.sym = Symbol.for(name); + } else { + // uninterned + this.sym = Symbol(`_${counter++}`); + } + } + + get isInterned() { + return Boolean(this.name); + } + + get value() { + return this.sym; + } + + equals(s) { + if (s.sym) { + return s.value === this.value; + } + return s === this.value; + } + + lt(s) { + if (s === this) { + return false; + } + return this.toString() < s.toString(); + } + + hashForEqual() { + return hashString(this.toString()); + } + + /* String printing */ + + [Symbol.toPrimitive](hint) { + if (hint === 'number') { + return 0; + } + return this.toString(); + } + + displayNativeString(out) { + if (this.isInterned) { + out.consume(Symbol.keyFor(this.sym)); + } else { + out.consume(this.sym.toString()); + } + } +} + +export function make(v) { + return new PrimitiveSymbol(v ? v.toString() : ''); +} + +export function makeUninterned() { + return new PrimitiveSymbol(); +} + +export function check(v) { + return v instanceof PrimitiveSymbol; +} + +export function isInterned(v) { + if (check(v)) { + return v.isInterned; + } + return false; +} diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/print_native_string.js b/racketscript-compiler/racketscript/compiler/runtime/core/print_native_string.js index 66e4a97c..b33740fe 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/print_native_string.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/print_native_string.js @@ -18,11 +18,11 @@ export function displayNativeString(out, v) { } else if (Bytes.check(v)) { Bytes.displayNativeString(out, v); } else if (Procedure.check(v)) { - if (v.__rjs_struct_object) { - v.__rjs_struct_object.displayNativeString(out); - } else { + if (v.__rjs_struct_object) { + v.__rjs_struct_object.displayNativeString(out); + } else { Procedure.displayNativeString(out, v); - } + } } else /* if (typeof v === 'number' || typeof v === 'string') */ { out.consume(v.toString()); } @@ -52,6 +52,8 @@ export function writeNativeString(out, v) { export function printNativeString(out, v, printAsExpression, quoteDepth) { if (printAsExpression && quoteDepth !== 1 && Primitive.check(v)) { v.printNativeString(out); + } else if (Bytes.check(v)) { + Bytes.printNativeString(out, v); } else { writeNativeString(out, v); } diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/print_ustring.js b/racketscript-compiler/racketscript/compiler/runtime/core/print_ustring.js index d2d8f2e7..d6de619e 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/print_ustring.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/print_ustring.js @@ -25,11 +25,11 @@ export function displayUString(out, v) { } else if (Bytes.check(v)) { out.consume(UString.makeMutable(Bytes.toString(v))); } else if (Procedure.check(v)) { - if (v.__rjs_struct_object) { - v.__rjs_struct_object.displayUString(out); - } else { + if (v.__rjs_struct_object) { + v.__rjs_struct_object.displayUString(out); + } else { out.consume(UString.makeMutable(Procedure.toString(v))); - } + } } else /* if (typeof v === 'number' || typeof v === 'string') */ { out.consume(UString.makeMutable(v.toString())); } diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/printing.js b/racketscript-compiler/racketscript/compiler/runtime/core/printing.js index 61e8b415..d20dddfb 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/printing.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/printing.js @@ -1,7 +1,5 @@ -import * as Primitive from './primitive.js'; import { displayNativeString, writeNativeString, printNativeString } from './print_native_string.js'; import { displayUString, writeUString, printUString } from './print_ustring.js'; -import * as Ports from './ports.js'; // TODO: All of these functions can be migrated to kernel.rkt after fprintf is. diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/procedure.js b/racketscript-compiler/racketscript/compiler/runtime/core/procedure.js index 61e98e80..11eafd13 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/procedure.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/procedure.js @@ -34,9 +34,13 @@ export function check(v) { * @return {!String} A string representation similar to Racket's `display`. */ export function toString(f) { - return f.__rjs_name ? - `#` : - (f.name ? `#` : '#'); + const notRjsName = f.name + ? `#` + : '#'; + + return f.__rjs_name + ? `#` + : notRjsName; } /** diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/raw_hashing.js b/racketscript-compiler/racketscript/compiler/runtime/core/raw_hashing.js index 279a7b3c..eb5adb5f 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/raw_hashing.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/raw_hashing.js @@ -14,14 +14,21 @@ */ export function hash(o) { if (o === null) return 0; + if (o && o.sym) return hashString(`sym_${o.toString()}`); switch (typeof o) { - case 'number': return hashNumber(o); - case 'string': return hashString(o); - case 'boolean': return o ? 1 : -1; - case 'undefined': return 0; + case 'number': + return hashNumber(o); + case 'string': + return hashString(o); + case 'boolean': + return o ? 1 : -1; + case 'undefined': + return 0; case 'object': - case 'function': return hashObjectIdentity(o); - default: return hashString(o.toString()); + case 'function': + return hashObjectIdentity(o); + default: + return hashString(o.toString()); } } @@ -37,9 +44,9 @@ export function hashString(s) { let h = 0; const n = s.length; for (let i = 0; i < n; ++i) { - // Benchmarks of various ways to do this: - // https://run.perf.zone/view/String-Hashing-Performance-1504040177726 - h = ~~(((h << 5) - h) + s.charCodeAt(i)); + // Benchmarks of various ways to do this: + // https://run.perf.zone/view/String-Hashing-Performance-1504040177726 + h = ~~((h << 5) - h + s.charCodeAt(i)); } return h; } @@ -66,8 +73,8 @@ export function hashNumber(n) { // This slightly increases the potential number of collisions // with large numbers and floats, but increases the performance by 20%. if (~~n === n) { - // If `n` is -0, the above check will pass. - // `~~` is here only to convert the potential -0 to 0. + // If `n` is -0, the above check will pass. + // `~~` is here only to convert the potential -0 to 0. return ~~n; } kBufAsF64[0] = n; @@ -114,7 +121,7 @@ export function hashIntArray(a) { let h = 0; const n = a.length; for (let i = 0; i < n; ++i) { - h = ~~(((h << 5) - h) + a[i]); + h = ~~((h << 5) - h + a[i]); } return h; } @@ -134,7 +141,7 @@ export function hashArray(a, valueToIntFn) { let h = 0; const n = a.length; for (let i = 0; i < n; ++i) { - h = ~~(((h << 5) - h) + valueToIntFn(a[i])); + h = ~~((h << 5) - h + valueToIntFn(a[i])); } return h; } diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/regexp.js b/racketscript-compiler/racketscript/compiler/runtime/core/regexp.js index cebcadc0..d1f04e96 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/regexp.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/regexp.js @@ -23,9 +23,11 @@ export function fromString(str) { /** * @param {!(RegExp|Uint8Array|UString.UString)} pattern * @param {!(Uint8Array|UString.UString)} input + * @param {!Int} start-pos + * @param {!Int|#f} end-pos * @return {!Pair.Pair|false} A list of bytes or strings, depending on the input. */ -export function match(pattern, input) { +export function match(pattern, input, start, _end) { // TODO: Contract-checking should happen in kernel.rkt. const isRegexpPattern = check(pattern); const isBytesPattern = !isRegexpPattern && Bytes.check(pattern); @@ -49,7 +51,9 @@ export function match(pattern, input) { ? UString.fromBytesUtf8(/** @type {!Uint8Array} */(pattern)) : pattern; - const result = stringInput.toString().match(stringOrRegExpPattern); + const end = ((typeof _end) === 'number') ? _end : stringInput.length; + + const result = stringInput.toString().slice(start, end).match(stringOrRegExpPattern); if (result === null) { return false; diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/struct.js b/racketscript-compiler/racketscript/compiler/runtime/core/struct.js index 8353f971..c7b50011 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/struct.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/struct.js @@ -5,8 +5,6 @@ import * as Pair from './pair.js'; import { PrintablePrimitive } from './printable_primitive.js'; import { displayNativeString, writeNativeString, printNativeString } from './print_native_string.js'; import { isEqual } from './equality.js'; -import { hashArray } from './raw_hashing.js'; -import { hashForEqual } from './hashing.js'; import * as Values from './values.js'; // This module implements Racket structs via three classes which @@ -58,11 +56,11 @@ class Struct extends PrintablePrimitive { this._desc._options.name; if (guardLambda) { const guardFields = fields.concat(finalCallerName); - let new_fields = guardLambda(...guardFields); - if (Values.check(new_fields)) { - fields = new_fields.getAll(); + const newFields = guardLambda(...guardFields); + if (Values.check(newFields)) { + fields = newFields.getAll(); } else { - fields = [new_fields]; + fields = [newFields]; } } @@ -79,8 +77,8 @@ class Struct extends PrintablePrimitive { } // Auto fields - const autoV = this._desc._options.autoV; /* Initial value for auto fields */ - for (let i = 0; i < this._desc._options.autoFieldCount; i++) { + const { autoV, autoFieldCount } = this._desc._options; /* Initial value for auto fields */ + for (let i = 0; i < autoFieldCount; i++) { this._fields.push(autoV); } } @@ -149,10 +147,11 @@ class Struct extends PrintablePrimitive { } // check for prop:equal+hash must come before transparent check + // eslint-disable-next-line no-use-before-define const p = this._desc._options.props.get(propEqualHash); if (p !== undefined) { const eqhashfn = p.car(); - return eqhashfn(this, v, null); // TODO: prop:equal+hash rec arg? + return eqhashfn(this, v, (a, b) => a.equals(b)); // TODO: handle cycles } if (this._desc._options.inspector) { @@ -223,6 +222,7 @@ class StructTypeDescriptor extends PrintablePrimitive { prop.hd.attachToStructTypeDescriptor(this, prop.tl); } } + // eslint-disable-next-line no-use-before-define this._propProcedure = this._findProperty(propProcedure); // Value for auto fields @@ -232,6 +232,11 @@ class StructTypeDescriptor extends PrintablePrimitive { // those of super types this._totalInitFields = options.initFieldCount; if (options.superType) { + C.falsy( + options.superType._isSealed(), + racketCoreError, + 'make-struct-type: cannot make a subtype of a sealed type' + ); this._totalInitFields += options.superType._totalInitFields; } @@ -295,7 +300,6 @@ class StructTypeDescriptor extends PrintablePrimitive { } maybeStructObject(s) { - let structObject; if (s instanceof Struct) { return s; } else if (s instanceof Function && @@ -402,6 +406,18 @@ class StructTypeDescriptor extends PrintablePrimitive { isFieldImmutable(n) { return this._options.immutables.has(n); } + + _isSealed() { + for (let desc = this; desc; desc = desc.getSuperType()) { + for (const [prop, val] of desc._options.props) { + if (prop._isSealedProperty()) { + return val; + } + } + } + + return false; // should be undefined, testing for now + } } /** ************************************************************************** */ @@ -438,10 +454,11 @@ class StructTypeProperty extends PrintablePrimitive { getPropertyPredicate() { return (v) => { + let desc; if (v instanceof StructTypeDescriptor) { - var desc = v; + desc = v; } else if (v instanceof Struct) { - var desc = v._desc; + desc = v._desc; } else { return false; } @@ -452,10 +469,11 @@ class StructTypeProperty extends PrintablePrimitive { getPropertyAccessor() { return (v) => { /* property acccessor */ + let desc; if (v instanceof StructTypeDescriptor) { - var desc = v; + desc = v; } else if (v instanceof Struct) { - var desc = v._desc; + desc = v._desc; } else { C.raise(racketCoreError, 'invalid argument to accessor'); } @@ -483,6 +501,10 @@ class StructTypeProperty extends PrintablePrimitive { prop.attachToStructTypeDescriptor(desc, proc(newV)); }); } + + _isSealedProperty() { + return this._name === 'prop:sealed'; + } } /** ************************************************************************** */ @@ -533,16 +555,19 @@ export function isStructInstance(v) { } export function check(v, desc) { - return isStructInstance(v) && v._desc == desc; + return isStructInstance(v) && v._desc === desc; } /** ************************************************************************** */ // Properties +// TODO: find out why changing let to const and moving them to the top breaks tests +// eslint-disable-next-line import/no-mutable-exports export let propProcedure = makeStructTypeProperty({ name: 'prop:procedure' }).getAt(0); +// eslint-disable-next-line import/no-mutable-exports export let propEqualHash = makeStructTypeProperty({ name: 'prop:equal+hash' }).getAt(0); diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/symbol.js b/racketscript-compiler/racketscript/compiler/runtime/core/symbol.js deleted file mode 100644 index 0e17b41b..00000000 --- a/racketscript-compiler/racketscript/compiler/runtime/core/symbol.js +++ /dev/null @@ -1,54 +0,0 @@ -import { PrintablePrimitive } from './printable_primitive.js'; -import { internedMake } from './lib.js'; - -class Symbol extends PrintablePrimitive { - constructor(v) { - super(); - this.v = v; - this._cachedHashCode = null; - } - - /** - * @param {!Ports.NativeStringOutputPort} out - */ - displayNativeString(out) { - out.consume(this.v); - } - - equals(v) { - // Symbols are interned by default, and two symbols - // with same name can't be unequal. - // Eg. (define x (gensym)) ;;=> 'g60 - // (equal? x 'g60) ;;=> #f - // TODO: does this handle uninterned symbols? - return v === this; - } - - lt(v) { - if (v === this) { - return false; - } else { - return this.v < v.v; - } - } - - /** - * @return {!number} - */ - hashForEqual() { - if (this._cachedHashCode === null) { - this._cachedHashCode = super.hashForEqual(); - } - return this._cachedHashCode; - } -} - - -export const make = internedMake(v => new Symbol(v.toString())); - -// TODO: is it correct to convert toString()? -export const makeUninterned = v => new Symbol(v.toString()); - -export function check(v) { - return (v instanceof Symbol); -} diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/unicode_string.js b/racketscript-compiler/racketscript/compiler/runtime/core/unicode_string.js index 79066e2d..b49cc9b0 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/unicode_string.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/unicode_string.js @@ -5,11 +5,6 @@ import { MiniNativeOutputStringPort } from './mini_native_output_string_port.js' import { internedMake } from './lib.js'; import { hashIntArray } from './raw_hashing.js'; -// In node.js, TextEncoder is not global and needs to be imported. -const TextEncoder = (typeof window === 'undefined') - ? require('util').TextEncoder - : window.TextEncoder; // eslint-disable-line no-undef - /** * A sequence of {Char.Char}s. * @@ -232,21 +227,20 @@ export class UString extends Primitive /* implements Printable */ { * @return {!boolean} */ isValidInteger(radix) { - const chars = this.chars; - const startFrom = chars[0].codepoint === /* '-' */ 45 ? 1 : 0; + const startFrom = this.chars[0].codepoint === /* '-' */ 45 ? 1 : 0; if (radix > 10) { const maxLowercase = /* 'a' - 11 */ 86 + radix; const maxUppercase = maxLowercase - 32; - for (let i = startFrom; i < chars.length; ++i) { - let cp = chars[i].codepoint; + for (let i = startFrom; i < this.chars.length; ++i) { + const cp = this.chars[i].codepoint; if (cp < /* '0' */ 48 || cp > maxLowercase || cp > maxUppercase && cp < /* 'a' */ 97 || cp > /* '9' */ 57 && cp < /* 'A' */ 65) return false; } } else { const max = /* '0' - 1 */ 47 + radix; - for (let i = startFrom; i < chars.length; ++i) { - let cp = chars[i].codepoint; + for (let i = startFrom; i < this.chars.length; ++i) { + const cp = this.chars[i].codepoint; if (cp < /* '0' */ 48 || cp > max) return false; } } @@ -486,6 +480,14 @@ export function toBytesUtf8(str) { return utf8Encoder.encode(str.toString()); } +/** + * @param {!(UString|String)} str + * @return {!Char.Char[]} chars + */ +export function toArray(str) { + return str.chars; +} + /** * @param {!Uint8Array} bytes * @return {!MutableUString} @@ -494,6 +496,14 @@ export function fromBytesUtf8(bytes) { return makeMutable(Bytes.toString(bytes)); } +/** + * @param {!Uint8Array} bytes + * @return {!MutableUString} + */ +export function fromBytesLatin1(bytes) { + return makeMutable(Bytes.toString(bytes)); +} + /** * @param {!UString[]} strs * @return {!MutableUString} diff --git a/racketscript-compiler/racketscript/compiler/runtime/core/vector.js b/racketscript-compiler/racketscript/compiler/runtime/core/vector.js index 59f95511..2834539d 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/core/vector.js +++ b/racketscript-compiler/racketscript/compiler/runtime/core/vector.js @@ -61,6 +61,14 @@ class Vector extends PrintablePrimitive { this.items[n] = v; } + copy(destStart, src, srcStart, srcEnd) { + for (let i = srcStart, j = destStart; + i < srcEnd && i < src.items.length && j < this.items.length; + i++, j++) { + this.items[j] = src.items[i]; + } + } + length() { return this.items.length; } @@ -77,7 +85,7 @@ class Vector extends PrintablePrimitive { const items1 = this.items; const items2 = v.items; - if (items1.length != items2.length) { + if (items1.length !== items2.length) { return false; } @@ -106,7 +114,6 @@ export function copy(vec, mutable) { return new Vector(vec.items, mutable); } - export function makeInit(size, init) { const r = new Array(size); r.fill(init); diff --git a/racketscript-compiler/racketscript/compiler/runtime/flfxnum.rkt b/racketscript-compiler/racketscript/compiler/runtime/flfxnum.rkt index 27154566..88e193fa 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/flfxnum.rkt +++ b/racketscript-compiler/racketscript/compiler/runtime/flfxnum.rkt @@ -1,3 +1,115 @@ #lang racketscript/boot -(require racketscript/interop) +(require racketscript/interop + racketscript/compiler/directive + "kernel.rkt" + "lib.rkt" + (for-syntax syntax/parse)) + +(define+provide fl* (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.multiply + #js.Core.Number.JS.mul ) 0)) +(define+provide fl/ (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.divide + #js.Core.Number.JS.div ) 1)) +(define+provide fl+ (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.add + #js.Core.Number.JS.add ) 0)) +(define+provide fl- (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.subtract + #js.Core.Number.JS.sub ) 1)) +(define+provide fl< (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.lessThan + #js.Core.Number.JS.lt ) 1)) +(define+provide fl> (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.greaterThan + #js.Core.Number.JS.gt ) 1)) +(define+provide fl<= (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.lessThanOrEqual + #js.Core.Number.JS.lte ) 1)) +(define+provide fl>= (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.greaterThanOrEqual + #js.Core.Number.JS.gte ) 1)) +(define+provide fl= (#js.Core.attachProcedureArity (if-scheme-numbers #js.Core.Number.Scheme.approxEquals + #js.Core.Number.JS.equals ) 1)) + +(define+provide flabs (if-scheme-numbers #js.Core.Number.Scheme.abs + #js.Math.abs)) +(define+provide flmin (if-scheme-numbers min + #js.Math.min)) +(define+provide flmax (if-scheme-numbers max + #js.Math.max)) +(define+provide flround (if-scheme-numbers round + #js.Math.round)) +(define+provide flfloor (if-scheme-numbers floor + #js.Math.floor)) +(define+provide flceiling (if-scheme-numbers ceiling + #js.Math.ceil)) +(define+provide fltruncate (if-scheme-numbers truncate + #js.Math.trunc)) + +(define+provide flsin (if-scheme-numbers sin + #js.Math.sin)) +(define+provide flcos (if-scheme-numbers cos + #js.Math.cos)) +(define+provide fltan (if-scheme-numbers tan + #js.Math.tan)) +(define+provide flasin (if-scheme-numbers asin + #js.Math.asin)) +(define+provide flacos (if-scheme-numbers acos + #js.Math.acos)) +(define+provide flatan (if-scheme-numbers atan + #js.Math.atan)) +(define+provide fllog (if-scheme-numbers log + #js.Math.log)) +(define+provide flexp (if-scheme-numbers exp + #js.Math.exp)) +(define+provide flsqrt (if-scheme-numbers sqrt + #js.Math.sqrt)) +(define+provide flexpt (if-scheme-numbers expt + #js.Math.pow)) + +(define-binop bitwise-or \|) + +(define-syntax (define-fx-binop+provide stx) + (syntax-parse stx + [(_ opname:id op:id) + #'(begin + (define+provide (opname a b) + (bitwise-or (binop op a b) 0)))])) + +(define-fx-binop+provide fx+ +) +(define-fx-binop+provide fx- -) +(define-fx-binop+provide fx* *) +(define-fx-binop+provide fxquotient /) +(define-fx-binop+provide fxremainder %) + +(define+provide (fxmodulo a b) + (define remainder (binop % a b)) + (#js.Math.floor (if (binop >= remainder 0) + remainder + (binop + remainder b)))) + +(define+provide (fxabs a) + (#js.Math.abs a)) + + +(define+provide (fx= a b) + (binop === a b)) +(define+provide (fx< a b) + (binop < a b)) +(define+provide (fx<= a b) + (binop <= a b)) +(define+provide (fx> a b) + (binop > a b)) +(define+provide (fx>= a b) + (binop >= a b)) +(define+provide (fxmin a b) + (if ($/binop < a b) a b)) +(define+provide (fxmax a b) + (if ($/binop > a b) b a)) + + +(define-fx-binop+provide fxrshift >>) +(define-fx-binop+provide fxlshift <<) +(define-fx-binop+provide fxand &&) +(define-fx-binop+provide fxior \|\|) +(define-fx-binop+provide fxxor ^) +(define+provide fxnot #js.Core.bitwiseNot) + +(define+provide flvector #js.Array.from) ; just create regular array +(define+provide flvector? #js.Array.isArray) +(define+provide fxvector #js.Array.from) ; just create regular array +(define+provide fxvector? #js.Array.isArray) diff --git a/racketscript-compiler/racketscript/compiler/runtime/kernel.js b/racketscript-compiler/racketscript/compiler/runtime/kernel.js index 7b0913f4..f1f029d6 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/kernel.js +++ b/racketscript-compiler/racketscript/compiler/runtime/kernel.js @@ -7,10 +7,11 @@ import * as Paramz from './paramz.js'; export function isImmutable(v) { if (Core.Primitive.check(v)) { return v.isImmutable(); - } else if (Core.Bytes.check(v) || typeof v === 'string') { + } + if (Core.Bytes.check(v) || typeof v === 'string') { return true; - } else if (typeof v === 'number' || typeof v === 'boolean' || - typeof v === 'undefined' || v === null) { + } + if (typeof v === 'number' || typeof v === 'boolean' || typeof v === 'undefined' || v === null) { return false; } throw Core.racketCoreError('isImmutable not implemented for', v); @@ -33,20 +34,32 @@ export function fprintf(isPrintAsExpression, out, form, ...args) { let lastMatch = ''; const matches = formStr.match(regex); - const numExpected = matches ? - matches.filter(m => !NO_ARG_FORM_RE.test(m)).length : 0; + const numExpected = matches + ? matches.filter(m => !NO_ARG_FORM_RE.test(m)).length + : 0; if (numExpected !== args.length) { - throw Core.racketContractError(`fprintf: format string requires ${numExpected} arguments, ` + - `given ${args.length}; arguments were:`, out, form, ...args); + throw Core.racketContractError( + `fprintf: format string requires ${numExpected} arguments, ` + + `given ${args.length}; arguments were:`, + out, + form, + ...args + ); } // eslint-disable-next-line no-cond-assign while ((reExecResult = regex.exec(formStr)) !== null) { - Core.display(out, formStr.slice(prevIndex + lastMatch.length, reExecResult.index)); + Core.display( + out, + formStr.slice(prevIndex + lastMatch.length, reExecResult.index) + ); prevIndex = reExecResult.index; lastMatch = reExecResult[0]; // eslint-disable-line prefer-destructuring if (/^~\s/.test(lastMatch)) continue; // eslint-disable-line no-continue - switch (lastMatch.charAt(1)) { // eslint-disable-line default-case + // eslint-disable-next-line default-case + switch ( + lastMatch.charAt(1) + ) { case '~': Core.display(out, '~'); continue; // eslint-disable-line no-continue @@ -76,17 +89,17 @@ export function fprintf(isPrintAsExpression, out, form, ...args) { break; case 'b': case 'B': - // TODO: raise exn:fail:contract if the number is not exact. + // TODO: raise exn:fail:contract if the number is not exact. Core.display(out, v.toString(2)); break; case 'o': case 'O': - // TODO: raise exn:fail:contract if the number is not exact. + // TODO: raise exn:fail:contract if the number is not exact. Core.display(out, v.toString(8)); break; case 'x': case 'X': - // TODO: raise exn:fail:contract if the number is not exact. + // TODO: raise exn:fail:contract if the number is not exact. Core.display(out, v.toString(16)); break; default: @@ -119,11 +132,11 @@ export function listToString(charsList) { // Errors /** - * @param {Core.Symbol|Core.UString|String} firstArg + * @param {Core.PrimitiveSymbol|Core.UString|String} firstArg * @param {*[]} rest */ export function error(firstArg, ...rest) { - if (Core.Symbol.check(firstArg)) { + if (Core.PrimitiveSymbol.check(firstArg)) { if (rest.length === 0) { throw Core.racketCoreError(firstArg.toString()); } else { @@ -153,7 +166,7 @@ export function doraise(e) { } /** - * @param {Core.Symbol} name + * @param {Core.PrimitiveSymbol} name * @param {Core.UString|String} expected * @param {*[]} rest */ @@ -162,10 +175,12 @@ export function doraise(e) { // (raise-argument-error name expected arg) // (raise-argument-error name expected bad-pos arg ...) export function argerror(name, expected, ...rest) { - var theerr; - if (Core.Symbol.check(name) + let theerr; + if ( + Core.PrimitiveSymbol.check(name) && (Core.UString.check(expected) || typeof expected === 'string') - && rest.length >= 1) { + && rest.length >= 1 + ) { theerr = Core.makeArgumentError(name, expected, ...rest); } else { theerr = Core.racketContractError('raise-argument-error: invalid arguments'); @@ -175,7 +190,31 @@ export function argerror(name, expected, ...rest) { } /** - * @param {Core.Symbol} name + * @param {Core.PrimitiveSymbol} name + * @param {Core.UString|String} expected + * @param {*[]} rest + */ +// analogous to Racket raise-result-error +// usage: +// (raise-result-error name expected arg) +// (raise-result-error name expected bad-pos arg ...) +export function resulterror(name, expected, ...rest) { + let theerr; + if ( + Core.PrimitiveSymbol.check(name) + && (Core.UString.check(expected) || typeof expected === 'string') + && rest.length >= 1 + ) { + theerr = Core.makeResultError(name, expected, ...rest); + } else { + theerr = Core.racketContractError('raise-result-error: invalid result'); + } + + doraise(theerr); +} + +/** + * @param {Core.PrimitiveSymbol} name * @param {Core.UString|String} msg * @param {Core.UString|String} field * @param {*[]} rest @@ -183,11 +222,13 @@ export function argerror(name, expected, ...rest) { // analogous to Racket raise-arguments-error, // so rest must be at least 1 and must be odd bc each field must have matching v export function argserror(name, msg, field, ...rest) { - var theerr; - if (Core.Symbol.check(name) + let theerr; + if ( + Core.PrimitiveSymbol.check(name) && (Core.UString.check(msg) || typeof msg === 'string') && (Core.UString.check(field) || typeof field === 'string') - && rest.length >= 1 && rest.length % 2 === 1) { + && rest.length >= 1 && rest.length % 2 === 1 + ) { theerr = Core.makeArgumentsError(name, msg, field, ...rest); } else { theerr = Core.racketContractError('raise-arguments-error: invalid arguments'); @@ -197,7 +238,7 @@ export function argserror(name, msg, field, ...rest) { } /** - * @param {Core.Symbol} name + * @param {Core.PrimitiveSymbol} name * @param {Core.UString|String} msg * @param {*[]} rest */ @@ -205,9 +246,11 @@ export function argserror(name, msg, field, ...rest) { // usage: raise-mismatch-error name, (~seq msg v ...) ... // so ...rst might have additional msg, v ... export function mismatcherror(name, msg, ...rest) { - var theerr; - if (Core.Symbol.check(name) - && (Core.UString.check(msg) || typeof msg === 'string')) { + let theerr; + if ( + Core.PrimitiveSymbol.check(name) + && (Core.UString.check(msg) || typeof msg === 'string') + ) { theerr = Core.makeMismatchError(name, msg, ...rest); } else { theerr = Core.racketContractError('error: invalid arguments'); @@ -216,71 +259,96 @@ export function mismatcherror(name, msg, ...rest) { doraise(theerr); } +/** + * @param {String} name + * @param {String} type + * @param {*} v + * @param {!number} length + * @param {!number} index + */ +// analogous to Racket raise-range-error +// usage: raise-range-error name, type, v len, i +export function outofrangeerror(name, type, v, len, i) { + let theerr; + if ( + typeof name === 'string' + && typeof type === 'string' + && typeof len === 'number' + && typeof i === 'number' + ) { + theerr = Core.makeOutOfRangeError(name, type, v, len, i); + } else { + theerr = Core.racketContractError('error: invalid arguments'); + } + + doraise(theerr); +} + /* --------------------------------------------------------------------------*/ // Not Implemented/Unorganized/Dummies export function random(...args) { switch (args.length) { - case 0: return Math.random(); + case 0: + return Math.random(); case 1: if (args[0] > 0) { return Math.floor(Math.random() * args[0]); } error('random: argument should be positive'); + break; case 2: if (args[0] > 0 && args[1] > args[0]) { return Math.floor(args[0] + Math.random() * (args[1] - args[0])); } error('random: invalid arguments'); + break; default: error('random: invalid number of arguments'); + break; } } // TODO: add optional equal? pred export function memv(v, lst) { - while (Core.Pair.isEmpty(lst) == false) { + while (Core.Pair.isEmpty(lst) === false) { if (Core.isEqv(v, lst.hd)) { return lst; } lst = lst.tl; - continue; } return false; } export function memq(v, lst) { - while (Core.Pair.isEmpty(lst) == false) { + while (Core.Pair.isEmpty(lst) === false) { if (Core.isEq(v, lst.hd)) { return lst; } lst = lst.tl; - continue; } return false; } export function memf(f, lst) { - while (Core.Pair.isEmpty(lst) == false) { + while (Core.Pair.isEmpty(lst) === false) { if (f(lst.hd)) { return lst; } lst = lst.tl; - continue; } return false; } export function findf(f, lst) { - while (Core.Pair.isEmpty(lst) == false) { + while (Core.Pair.isEmpty(lst) === false) { if (f(lst.hd)) { return lst.hd; } lst = lst.tl; - continue; } return false; } diff --git a/racketscript-compiler/racketscript/compiler/runtime/kernel.rkt b/racketscript-compiler/racketscript/compiler/runtime/kernel.rkt index c9bd18cb..daa66c5f 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/kernel.rkt +++ b/racketscript-compiler/racketscript/compiler/runtime/kernel.rkt @@ -1,8 +1,8 @@ #lang racketscript/boot -(require racketscript/interop - racket/stxparam - (for-syntax syntax/parse) +(require (for-syntax syntax/parse) + racketscript/interop + racketscript/compiler/directive "lib.rkt") ;; ---------------------------------------------------------------------------- @@ -24,7 +24,7 @@ (#js.Values.make vals))) 0) "values")) - + (define+provide (call-with-values generator receiver) (let ([vals (generator)]) @@ -43,7 +43,7 @@ ;; ---------------------------------------------------------------------------- ;; Void -(define+provide (void) *null*) +(define+provide (void . _) *null*) (define+provide (void? v) (or (binop === v *null*) (binop === v *undefined*))) @@ -51,106 +51,330 @@ ;; ---------------------------------------------------------------------------- ;; Numbers -(define+provide number? #js.Core.Number.check) -(define+provide real? #js.Core.Number.check) -(define+provide integer? #js.Number.isInteger) +(define+provide number? (if-scheme-numbers #js.Core.Number.Scheme.isSchemeNumber + #js.Core.Number.JS.check)) +(define+provide real? (if-scheme-numbers #js.Core.Number.Scheme.isReal + #js.Core.Number.JS.check)) +(define+provide integer? (if-scheme-numbers #js.Core.Number.Scheme.isInteger + #js.Number.isInteger)) + +(define-syntax (define+provide/scheme-numbers stx) + (syntax-parse stx + [(_ identifier:id binding:expr) + #`(define+provide identifier + (if-scheme-numbers binding + (lambda _ + (#js.Core.racketCoreError "Not supported with JS number semantics"))))] + [(_ (identifier:id args:expr ...) body:expr ...) + #'(define+provide/scheme-numbers identifier + (λ (args ...) body ...))])) + +(define-syntax (define-checked+provide/scheme-numbers stx) + (syntax-parse stx + [(_ (identifier:id [arg:expr pred:expr] ...) body:expr) + #`(define-checked+provide (identifier [arg pred] ...) + (if-scheme-numbers body + (lambda _ + (#js.Core.racketCoreError "Not supported with JS number semantics"))))])) + +(define+provide/scheme-numbers complex? number?) (define-checked+provide (zero? [v number?]) - (binop === v 0)) + (if-scheme-numbers (#js.Core.Number.Scheme.equals #js.Core.Number.Scheme.zero v) + (binop === v 0))) (define-checked+provide (positive? [v real?]) - (binop > v 0)) + (if-scheme-numbers (#js.Core.Number.Scheme.greaterThan v #js.Core.Number.Scheme.zero) + (binop > v 0))) (define-checked+provide (negative? [v real?]) - (binop < v 0)) + (if-scheme-numbers (#js.Core.Number.Scheme.lessThan v #js.Core.Number.Scheme.zero) + (binop < v 0))) (define-checked+provide (add1 [v number?]) - (binop + v 1)) + (if-scheme-numbers (#js.Core.Number.Scheme.add v #js.Core.Number.Scheme.one) + (binop + v 1))) (define-checked+provide (sub1 [v number?]) - (binop - v 1)) + (if-scheme-numbers (#js.Core.Number.Scheme.subtract v #js.Core.Number.Scheme.one) + (binop - v 1))) (define-checked+provide (quotient [dividend integer?] [divisor integer?]) - (binop \| (binop / dividend divisor) 0)) + (if-scheme-numbers (#js.Core.Number.Scheme.quotient dividend divisor) + (binop \| (binop / dividend divisor) 0))) (define-checked+provide (even? [v integer?]) - (binop === (binop % v 2) 0)) + (if-scheme-numbers (#js.Core.Number.Scheme.equals (#js.Core.Number.Scheme.modulo v 2) 0) + (binop === (binop % v 2) 0))) (define-checked+provide (odd? [v integer?]) - (not (binop === (binop % v 2) 0))) + (not (even? v))) (define+provide (exact-nonnegative-integer? v) - (and (#js.Number.isInteger v) (binop >= v 0))) + (if-scheme-numbers (and (integer? v) + (#js.Core.Number.Scheme.greaterThanOrEqual v 0) + (exact? v)) + (and (#js.Number.isInteger v) (binop >= v 0)))) (define+provide (exact-integer? v) - (#js.Number.isInteger v)) + (if-scheme-numbers (and (integer? v) + (exact? v)) + (#js.Number.isInteger v))) (define+provide (exact? v) - (#js.Number.isInteger v)) - -(define+provide (single-flonum-available?) #f) - -(define+provide * (#js.Core.attachProcedureArity #js.Core.Number.mul 0)) -(define+provide / (#js.Core.attachProcedureArity #js.Core.Number.div 1)) -(define+provide + (#js.Core.attachProcedureArity #js.Core.Number.add 0)) -(define+provide - (#js.Core.attachProcedureArity #js.Core.Number.sub 1)) -(define+provide < (#js.Core.attachProcedureArity #js.Core.Number.lt 1)) -(define+provide > (#js.Core.attachProcedureArity #js.Core.Number.gt 1)) -(define+provide <= (#js.Core.attachProcedureArity #js.Core.Number.lte 1)) -(define+provide >= (#js.Core.attachProcedureArity #js.Core.Number.gte 1)) -(define+provide = (#js.Core.attachProcedureArity #js.Core.Number.equals 1)) + (if-scheme-numbers (#js.Core.Number.Scheme.isExact v) + (#js.Number.isInteger v))) + +(define+provide (inexact? v) (not (exact? v))) + +;; single-flonum not implemented +(define+provide (single-flonum-available?) (if-scheme-numbers #f + #f)) +(define+provide (single-flonum?) (if-scheme-numbers #f + #f)) +(define+provide (real->single-flonum v) (if-scheme-numbers v + v)) + +(define+provide * + (if-scheme-numbers (#js.Core.attachProcedureArity (λ nums + (cond + [(null? nums) + 1] + [(null? (cdr nums)) + (car nums)] + [else + (#js.Core.Number.Scheme.multiply (car nums) (apply * (cdr nums)))])) + 0) + (#js.Core.attachProcedureArity #js.Core.Number.JS.mul 0))) +(define+provide / + (if-scheme-numbers (#js.Core.attachProcedureArity (λ nums + (cond + [(null? (cdr nums)) + (#js.Core.Number.Scheme.divide 1 (car nums))] + [else + (foldl (λ (x y) + (#js.Core.Number.Scheme.divide y x)) + (car nums) + (cdr nums))])) + 1) + (#js.Core.attachProcedureArity #js.Core.Number.JS.div 1))) +(define+provide + + (if-scheme-numbers (#js.Core.attachProcedureArity (λ nums + (cond + [(null? nums) + 0] + [(null? (cdr nums)) + (car nums)] + [else + (#js.Core.Number.Scheme.add (car nums) (apply + (cdr nums)))])) + 0) + (#js.Core.attachProcedureArity #js.Core.Number.JS.add 0))) +(define+provide - + (if-scheme-numbers (#js.Core.attachProcedureArity (λ nums + (cond + [(null? (cdr nums)) + (#js.Core.Number.Scheme.subtract 0 (car nums))] + [else + (foldl (λ (n acc) + (#js.Core.Number.Scheme.subtract acc n)) + (car nums) + (cdr nums))])) + 1) + (#js.Core.attachProcedureArity #js.Core.Number.JS.sub 1))) + +(define-syntax-rule (make-js-comparison op jsop) + (λ nums + (cond + [(null? nums) + #t] + [(null? (cdr nums)) + #t] + [else + (and (jsop (car nums) (car (cdr nums))) + (apply op (cdr nums)))]))) + +(define+provide < + (if-scheme-numbers (#js.Core.attachProcedureArity (make-js-comparison < #js.Core.Number.Scheme.lessThan) 1) + (#js.Core.attachProcedureArity #js.Core.Number.JS.lt 1))) +(define+provide > + (if-scheme-numbers (#js.Core.attachProcedureArity (make-js-comparison > #js.Core.Number.Scheme.greaterThan) 1) + (#js.Core.attachProcedureArity #js.Core.Number.JS.gt 1))) +(define+provide <= + (if-scheme-numbers (#js.Core.attachProcedureArity (make-js-comparison <= #js.Core.Number.Scheme.lessThanOrEqual) 1) + (#js.Core.attachProcedureArity #js.Core.Number.JS.lte 1))) +(define+provide >= + (if-scheme-numbers (#js.Core.attachProcedureArity (make-js-comparison >= #js.Core.Number.Scheme.greaterThanOrEqual) 1) + (#js.Core.attachProcedureArity #js.Core.Number.JS.gte 1))) +(define+provide = + (if-scheme-numbers (#js.Core.attachProcedureArity (make-js-comparison = #js.Core.Number.Scheme.equals) 1) + (#js.Core.attachProcedureArity #js.Core.Number.JS.equals 1))) (define-checked+provide (floor [v real?]) - (#js.Math.floor v)) + (if-scheme-numbers (#js.Core.Number.Scheme.floor v) + (#js.Math.floor v))) (define-checked+provide (abs [v real?]) - (#js.Math.abs v)) -(define-checked+provide (sin [v real?]) - (#js.Math.sin v)) -(define-checked+provide (cos [v real?]) - (#js.Math.cos v)) -(define-checked+provide (tan [v real?]) - (#js.Math.tan v)) -(define-checked+provide (atan [v real?]) - (#js.Math.atan v)) + (if-scheme-numbers (#js.Core.Number.Scheme.abs v) + (#js.Math.abs v))) +(define-checked+provide (sin [v number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.sin v) + (#js.Math.sin v))) +(define-checked+provide (cos [v number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.cos v) + (#js.Math.cos v))) +(define-checked+provide (tan [v number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.tan v) + (#js.Math.tan v))) +(define-checked+provide (asin [v number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.asin v) + (#js.Math.asin v))) +(define-checked+provide (acos [v number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.acos v) + (#js.Math.acos v))) +(define+provide atan + (if-scheme-numbers (case-lambda + [(x) (#js.Core.Number.Scheme.atan x)] + [(x y) (#js.Core.Number.Scheme.atan2 x y)]) + (case-lambda + [(v) (#js.Math.atan v)] + [(x y) (#js.Math.atan2 x y)]))) (define-checked+provide (ceiling [v real?]) - (#js.Math.ceil v)) + (if-scheme-numbers (#js.Core.Number.Scheme.ceiling v) + (#js.Math.ceil v))) (define-checked+provide (round [v real?]) - (#js.Math.round v)) + (if-scheme-numbers (#js.Core.Number.Scheme.round v) + (#js.Math.round v))) (define-checked+provide (min [a real?] [b real?]) - (#js.Math.min a b)) + (if-scheme-numbers (cond + [(not (and (number? a) + (number? b))) + #js.Core.Number.Scheme.nan] + [(#js.Core.Number.Scheme.lessThan a b) a] + [else b]) + (#js.Math.min a b))) (define-checked+provide (max [a real?] [b real?]) - (#js.Math.max a b)) - -(define-checked+provide (log [v real?]) - (#js.Math.log v)) + (if-scheme-numbers (cond + [(not (and (number? a) + (number? b))) + #js.Core.Number.Scheme.nan] + [(#js.Core.Number.Scheme.greaterThan a b) a] + [else b]) + (#js.Math.max a b))) + +(define-checked+provide (log [v number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.log v) + (#js.Math.log v))) + +(define-checked+provide (exp [w number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.exp w) + (#js.Math.exp w))) (define-checked+provide (expt [w number?] [z number?]) - (#js.Math.pow w z)) + (if-scheme-numbers (#js.Core.Number.Scheme.expt w z) + (#js.Math.pow w z))) (define-checked+provide (sqrt [v number?]) - (#js.Math.sqrt v)) + (if-scheme-numbers (#js.Core.Number.Scheme.sqrt v) + (#js.Math.sqrt v))) (define-checked+provide (sqr [v number?]) - (* v v)) + (if-scheme-numbers (#js.Core.Number.Scheme.sqr v) + (* v v))) + +(define-checked+provide (truncate [v number?]) + (if-scheme-numbers (cond + [(negative? v) + (- (floor v) 1)] + [else (floor v)]) + (#js.Math.trunc v))) (define-checked+provide (remainder [a integer?] [b integer?]) - (binop % a b)) + (if-scheme-numbers (#js.Core.Number.Scheme.remainder a b) + (binop % a b))) (define-checked+provide (number->string [n number?]) (#js.Core.UString.makeMutable (#js.n.toString))) ;; TODO: only works for numbers < 32 bits (define-checked+provide (arithmetic-shift [n integer?] [m integer?]) - (if (negative? n) - (binop >> n m) - (binop << n m))) + (if-scheme-numbers (#js.Core.Number.Scheme.arithmeticShift n m) + (if (negative? m) + (binop >> n (- m)) + (binop << n m)))) ;;TODO: Support bignums -(define+provide (inexact->exact x) x) -(define+provide (exact->inexact x) x) - +(define+provide (inexact->exact v) (if-scheme-numbers (#js.Core.Number.Scheme.toExact v) + v)) +(define+provide (exact->inexact v) (if-scheme-numbers (#js.Core.Number.Scheme.toInexact v) + v)) + +;; complex Numbers +(define-checked+provide (make-rectangular [x real?] [y real?]) + (if-scheme-numbers (#js.Core.Number.Scheme.makeComplex x y) + (#js.Core.Pair.make x y))) + + +(define-checked+provide (make-polar [m real?] [a real?]) + (if-scheme-numbers (#js.Core.Number.Scheme.makeComplexPolar m a) + (error "Complex numbers not supported with JS numerber semantics"))) + +(define-checked+provide (real-part [z (if-scheme-numbers number? pair?)]) + (if-scheme-numbers (#js.Core.Number.Scheme.realPart z) + (#js.z.hd z))) +(define-checked+provide (imag-part [z (if-scheme-numbers number? pair?)]) + (if-scheme-numbers (#js.Core.Number.Scheme.imaginaryPart z) + (#js.z.tl z))) +(define-checked+provide/scheme-numbers (magnitude [x number?]) + (#js.Core.Number.Scheme.magnitude x)) + +(define-checked+provide/scheme-numbers (conjugate [x number?]) + (#js.Core.Number.Scheme.conjugate x)) + +(define-checked+provide/scheme-numbers (angle [x number?]) + (#js.Core.Number.Scheme.angle x)) + +(define+provide rational? (if-scheme-numbers #js.Core.Number.Scheme.isRational + #js.Number.isInteger)) +(define-checked+provide (numerator [x number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.numerator x) + x)) +(define-checked+provide (denominator [x number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.denominator x) + 1)) + +;; bitwise operators + +(define+provide bitwise-and + (if-scheme-numbers (#js.Core.attachProcedureName + (#js.Core.attachProcedureArity #js.Core.Number.Scheme.bitwiseAnd 1) + "bitwise-and") + (#js.Core.attachProcedureName + (#js.Core.attachProcedureArity #js.Core.Number.JS.bitwiseAnd 1) + "bitwise-and"))) + +(define+provide bitwise-ior + (if-scheme-numbers (#js.Core.attachProcedureName + (#js.Core.attachProcedureArity #js.Core.Number.Scheme.bitwiseOr 1) + "bitwise-ior") + (#js.Core.attachProcedureName + (#js.Core.attachProcedureArity #js.Core.Number.JS.bitwiseOr 1) + "bitwise-ior"))) + +(define+provide bitwise-xor + (if-scheme-numbers (#js.Core.attachProcedureName + (#js.Core.attachProcedureArity #js.Core.Number.Scheme.bitwiseXor 1) + "bitwise-xor") + (#js.Core.attachProcedureName + (#js.Core.attachProcedureArity #js.Core.Number.JS.bitwiseXor 1) + "bitwise-xor"))) + +(define-checked+provide (bitwise-not [v number?]) + (if-scheme-numbers (#js.Core.Number.Scheme.bitwiseNot v) + (#js.Core.Number.JS.bitwiseNot v))) + +(define+provide (bitwise-bit-set? n m) + (not (zero? (bitwise-and n (arithmetic-shift 1 m))))) ;; ---------------------------------------------------------------------------- ;; Booleans @@ -183,8 +407,14 @@ #js.v.hd.tl) (define-checked+provide (cddr [v (check/pair-of? #t pair?)]) #js.v.tl.tl) +(define-checked+provide (cdddr [v (check/pair-of? #t (check/pair-of? #t pair?))]) + #js.v.tl.tl.tl) (define-checked+provide (caddr [v (check/pair-of? #t (check/pair-of? #t pair?))]) #js.v.tl.tl.hd) +(define-checked+provide (cadddr [v (check/pair-of? #t (check/pair-of? #t (check/pair-of? #t pair?)))]) + #js.v.tl.tl.tl.hd) +(define-checked+provide (cddddr [v (check/pair-of? #t (check/pair-of? #t (check/pair-of? #t pair?)))]) + #js.v.tl.tl.tl.tl) (define+provide null #js.Core.Pair.EMPTY) (define+provide list @@ -323,7 +553,10 @@ ;; v is optional (define-checked+provide (make-vector [size integer?] [v #t]) - (#js.Core.Vector.makeInit size (or v 0))) + (#js.Core.Vector.makeInit size + (if (eq? v *undefined*) + 0 + v))) (define+provide vector? #js.Core.Vector.check) @@ -339,13 +572,26 @@ (define-checked+provide (vector->list [vec vector?]) (#js.Core.Pair.listFromArray #js.vec.items)) +(define-checked+provide (list->vector [lst list?]) + (#js.Core.Vector.make (#js.Core.Pair.listToArray lst) #t)) + (define-checked+provide (vector->immutable-vector [vec vector?]) (#js.Core.Vector.copy vec #f)) +(define-checked+provide (vector-copy [vec vector?]) + (#js.Core.Vector.copy vec #t)) ; a vector copy is always mutable + +(define-checked+provide (vector-copy! [dest vector?] + [dest-start integer?] + [src vector?] + [src-start integer?] + [src-end integer?]) + (#js.dest.copy dest-start src src-start src-end)) + ;; -------------------------------------------------------------------------- ;; Hashes -(define-syntax-rule (make-hash-contructor make) +(define-syntax-rule (make-hash-constructor make) (v-λ () #:unchecked (define kv* arguments) (when (binop !== (binop % #js.kv*.length 2) 0) @@ -355,9 +601,9 @@ (#js.items.push (array ($ kv* i) ($ kv* (+ i 1))))) (make items #f)))) -(define+provide hash (make-hash-contructor #js.Core.Hash.makeEqual)) -(define+provide hasheqv (make-hash-contructor #js.Core.Hash.makeEqv)) -(define+provide hasheq (make-hash-contructor #js.Core.Hash.makeEq)) +(define+provide hash (make-hash-constructor #js.Core.Hash.makeEqual)) +(define+provide hasheqv (make-hash-constructor #js.Core.Hash.makeEqv)) +(define+provide hasheq (make-hash-constructor #js.Core.Hash.makeEq)) (define+provide make-hash (v-λ (assocs) #:unchecked @@ -417,7 +663,7 @@ (if (#js.h.isImmutable) (#js.h.set k v) (raise (#js.Core.makeArgumentError - "hash-set" "(and hash? immutable?)" 0 h k v)))) + "hash-set" "(and/c hash? immutable?)" 0 h k v)))) (define+provide (hash-remove h k) (if (#js.h.isImmutable) @@ -480,6 +726,8 @@ (define+provide (hash-union h1 h2) (#js.h1.union h2)) +(define+provide (hash-strong? h) #t) + ;; -------------------------------------------------------------------------- ;; Higher Order Functions @@ -747,7 +995,7 @@ (apply fprintf out form args) (get-output-string out))) -(define+provide symbol? #js.Core.Symbol.check) +(define+provide symbol? #js.Core.PrimitiveSymbol.check) (define+provide keyword? #js.Core.Keyword.check) (define+provide (make-string k [c #\nul]) @@ -755,6 +1003,8 @@ (define+provide (list->string lst) (#js.Kernel.listToString lst)) +(define+provide (string->list [str string?]) + (#js.Core.Pair.listFromArray (#js.Core.UString.toArray str))) (define+provide (string->immutable-string [s string?]) (#js.Core.UString.stringToImmutableString s)) @@ -763,33 +1013,44 @@ (#js.Core.UString.makeMutable (#js.v.toString))) (define-checked+provide (string->symbol [s string?]) - (#js.Core.Symbol.make s)) + (#js.Core.PrimitiveSymbol.make s)) (define-checked+provide (string->uninterned-symbol [s string?]) - (#js.Core.Symbol.makeUninterned s)) + (#js.Core.PrimitiveSymbol.makeUninterned s)) ;; TODO: implement unreadable symbols (define-checked+provide (string->unreadable-symbol [s string?]) - (#js.Core.Symbol.make s)) + (#js.Core.PrimitiveSymbol.make s)) ; Does not support prefixed forms such as "#b101". (define+provide (string->number s [radix 10]) (define (integer-in lo hi) (v-λ (v) #:unchecked - (and (exact-integer? v) (>= v lo) (<= v hi)))) + (and (exact-integer? v) + (>= v 2) + (<= v 16)))) + (check/raise string? s 0) (check/raise (integer-in 2 16) radix 1) - (let ([result (#js*.parseInt s radix)]) - (if (or (#js*.isNaN result) - ; Work around parseInt permissiveness. - (not (#js.s.isValidInteger radix))) - #f - result))) + + (define (js-string->number) + (let ([result (#js*.parseInt s radix)]) + (if (or (#js*.isNaN result) + ; Work around parseInt permissiveness. + (not (#js.s.isValidInteger radix))) + #f + result))) + + (if-scheme-numbers + (let ([scheme-number (#js.Core.Number.Scheme.fromString s)]) + (if (and scheme-number + (= radix 10)) + scheme-number + (js-string->number))) + (js-string->number))) (define-checked+provide (symbol-interned? [sym symbol?]) - ;;NOTE: We simply check if given symbol is equal to an - ;; interned symbol. - (binop === sym (#js.Core.Symbol.make #js.sym.v))) + (#js.Core.PrimitiveSymbol.isInterned sym)) (define+provide (symbol=? s v) (#js.s.equals v)) @@ -921,6 +1182,21 @@ (define+provide (set-box! b v) (#js.b.set v)) +(define+provide box? #js.Core.Box.check) + +;; FIXME below here +(define+provide (box-cas! loc old new) + ;; doesn't handle threads + (and (eq? old (unbox loc)) (set-box! loc new) #t)) + +(define+provide box-immutable #js.Core.Box.make) + +(define+provide make-weak-box #js.Core.Box.make) +(define+provide (weak-box-value v) (#js.v.get)) + +(define+provide (set-box*! b v) (#js.b.set v)) +(define+provide (unbox* v) (#js.v.get)) + ;; -------------------------------------------------------------------------- ;; Properties @@ -944,16 +1220,25 @@ (define-property+provide prop:incomplete-arity) (define-property+provide prop:method-arity-error) (define-property+provide prop:exn:srclocs) +(define-property+provide prop:authentic) +(define-property+provide prop:serialize) +(define-property+provide prop:custom-write) +(define-property+provide prop:sealed) +(define-property+provide prop:object-name) (define+provide prop:procedure #js.Core.Struct.propProcedure) (define+provide prop:equal+hash #js.Core.Struct.propEqualHash) +(define+provide (equal-hash-code v) 0) +(define+provide (equal-secondary-hash-code v) 1) + ;; -------------------------------------------------------------------------- ;; Errors (define+provide error #js.Kernel.error) (define+provide raise-argument-error #js.Kernel.argerror) (define+provide raise-arguments-error #js.Kernel.argserror) +(define+provide raise-result-error #js.Kernel.resulterror) (define+provide raise-mismatch-error #js.Kernel.mismatcherror) ;; -------------------------------------------------------------------------- @@ -962,12 +1247,37 @@ (define+provide (bytes? bs) (#js.Core.Bytes.check bs)) +;; init val `b` is optional +(define+provide (make-bytes len [b 0]) + (#js.Core.Bytes.make len b)) + +(define-checked+provide (bytes-ref [bs bytes?] [i integer?]) + (if (or (< i 0) (> i #js.bs.length)) + (raise + (#js.Core.makeOutOfRangeError "bytes-ref" "byte string" bs #js.bs.length i)) + (#js.Core.Bytes.ref bs i))) + +(define-checked+provide (bytes-set! [bs bytes?] [i integer?] [b integer?]) + (if (or (< i 0) (> i #js.bs.length)) + (raise + (#js.Core.makeOutOfRangeError "bytes-set!" "byte string" bs #js.bs.length i)) + (#js.Core.Bytes.set bs i b))) + +(define+provide bytes-append + (v-λ bss #:unchecked (#js.Core.Bytes.append bss))) + (define-checked+provide (bytes->string/utf-8 [bs bytes?]) (#js.Core.UString.fromBytesUtf8 bs)) +(define-checked+provide (bytes->string/latin-1 [bs bytes?]) + (#js.Core.UString.fromBytesLatin1 bs)) + (define-checked+provide (string->bytes/utf-8 [str string?]) (#js.Core.UString.toBytesUtf8 str)) +(define+provide (string->bytes/locale str [err-byte #t] [start 0] [end 0]) + (#js.Core.UString.toBytesUtf8 str)) + (define-checked+provide (bytes=? [bstr1 bytes?] [bstr2 bytes?]) (#js.Core.Bytes.eq bstr1 bstr2)) @@ -977,6 +1287,9 @@ (define-checked+provide (bytes>? [bstr1 bytes?] [bstr2 bytes?]) (#js.Core.Bytes.gt bstr1 bstr2)) +(define-checked+provide (bytes-length [bs bytes?]) + #js.bs.length) + ;; -------------------------------------------------------------------------- ;; Continuation Marks @@ -1020,6 +1333,9 @@ (define+provide current-output-port (make-parameter #js.Core.Ports.standardOutputPort)) +(define+provide current-input-port + (make-parameter #js.Core.Ports.standardInputPort)) + (define+provide current-error-port (make-parameter #js.Core.Ports.standardErrorPort)) @@ -1078,6 +1394,8 @@ ;; Not implemented/Unorganized/Dummies (define+provide current-inspector (v-λ () #:unchecked #t)) +(define+provide current-code-inspector (v-λ () #:unchecked #t)) +(define+provide (make-inspector . _) #f) (define+provide (check-method) #f) (define+provide random #js.Kernel.random) @@ -1093,8 +1411,6 @@ (v-λ (x n) "str" #;(#js.x.toString))) -(define+provide (procedure-arity-mask fn) (procedure-arity fn)) -(define+provide (bitwise-bit-set? mask n) #t) (define+provide (procedure-extract-target f) #f) ;; -------------------------------------------------------------------------- @@ -1120,8 +1436,13 @@ (define+provide byte-pregexp byte-regexp) -(define+provide (regexp-match pattern input) - (#js.Core.Regexp.match pattern input)) +(define+provide (regexp-match pattern input [start-pos 0] [end-pos #f]) + (#js.Core.Regexp.match pattern input start-pos end-pos)) + +(define+provide (regexp-match? pattern input [start-pos 0] [end-pos #f]) + (if (#js.Core.Regexp.match pattern input start-pos end-pos) + #t + #f)) ;; -------------------------------------------------------------------------- ;; Procedures @@ -1169,6 +1490,14 @@ (kernel:arity-at-least? v))) v))) +(define+provide (procedure-arity-mask fn) + (let ([ar (procedure-arity fn)]) + (cond + [(integer? ar) + (arithmetic-shift 1 ar)] + [(kernel:arity-at-least? ar) + (arithmetic-shift -1 (kernel:arity-at-least-value ar))]))) + (define+provide (checked-procedure-check-and-extract type v proc v1 v2) (cond [(and (#js.Core.Struct.check v type) @@ -1186,12 +1515,15 @@ (v-λ (sym) #:unchecked (let ([s (or (and sym #js.sym.v) "")]) (set! __count (binop + __count 1)) - (#js.Core.Symbol.makeUninterned (binop + s __count))))) + (#js.Core.PrimitiveSymbol.makeUninterned (binop + s __count))))) (define+provide (eval-jit-enabled) #f) (define+provide (variable-reference-constant? x) #f) (define+provide (variable-reference-from-unsafe? x) #f) +(define+provide (variable-reference->module-source x) #f) +(define+provide (variable-reference->resolved-module-path x) #f) +(define+provide (module-name-fixup x) #f) (define+provide (inspector? p) #t) @@ -1200,11 +1532,58 @@ (define __count 1000) -(define+provide system-type - (v-λ (system-type mod) #:unchecked - 'javascript)) +(define+provide (system-type [mode 'os]) + (case mode + [(os) 'unix] + [(vm) 'javascript] + [(gc) 'javascript] + [(fs-change) (#js.Core.Vector.make (array #false #false #false #false) #false)] + [else #false]) + ) + +;; path stubs +(define+provide (find-system-path kind) "") +(define+provide build-path ; multi-arity + (v-λ (base) #:unchecked base)) ;; TODO: manually implement weak references? or ES6 WeakMap? see pr#106 (define+provide make-weak-hash make-hash) (define+provide make-weak-hasheqv make-hasheqv) (define+provide make-weak-hasheq make-hasheq) + + +(define+provide (current-environment-variables) null) +(define+provide (environment-variables-ref e n) #f) +(define+provide (environment-variables-set! e n v [fail #f]) (void)) + +(define+provide (prefab-struct-key v) #f) + +(define+provide path? #js.Core.Path.check) + +(define+provide (version) "99.0") ;; fake + +(define+provide string->path #js.Core.Path.fromString) + +;; -------------------------------------------------------------------------- + +(define+provide (dynamic-wind f g h) + (f) (g) (h)) + +(define+provide (datum-intern-literal v) v) + +;; semaphore stubs +(define+provide (make-semaphore x) x) +(define+provide (semaphore-peek-evt x) x) +(define+provide call-with-semaphore + (v-λ (s f) #:unchecked #f)) + +;; ---------------------------------------------------------------------------- +;; Syntax + +;; TODO: implement these stubs + +(define+provide syntax-source #js.Core.Correlated.syntaxSource) +(define+provide syntax-line #js.Core.Correlated.syntaxLine) +(define+provide syntax-column #js.Core.Correlated.syntaxColumn) +(define+provide syntax-position #js.Core.Correlated.syntaxPosition) +(define+provide syntax-span #js.Core.Correlated.syntaxSpan) diff --git a/racketscript-compiler/racketscript/compiler/runtime/lib.rkt b/racketscript-compiler/racketscript/compiler/runtime/lib.rkt index 640ff82e..9978615d 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/lib.rkt +++ b/racketscript-compiler/racketscript/compiler/runtime/lib.rkt @@ -1,12 +1,11 @@ #lang racketscript/boot -(require racketscript/interop - racket/stxparam - syntax/parse/define - (for-syntax racket/base - racket/list +(require (for-syntax racket/base racket/format - syntax/parse)) + racket/list + syntax/parse) + racket/stxparam + racketscript/interop) (provide throw new @@ -43,7 +42,9 @@ check/not check/pair-of? define-checked - define-checked+provide) + define-checked+provide + define-nyi + define-nyi+provide) ;; ---------------------------------------------------------------------------- @@ -277,3 +278,13 @@ [(_ (name:id e ...) body ...) #`(begin (define-checked (name e ...) body ...) (provide name))])) + + +(define-syntax (define-nyi stx) + (syntax-parse stx + [(_ n:id) + #'(define name (lambda _ (throw (#js.Core.racketCoreError 'name " is not yet implemented"))))])) + + +(define-syntax-rule (define-nyi+provide id) + (begin (define-nyi id) (provide id))) diff --git a/racketscript-compiler/racketscript/compiler/runtime/linklet-primitive.rkt b/racketscript-compiler/racketscript/compiler/runtime/linklet-primitive.rkt index 27154566..c474c9ac 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/linklet-primitive.rkt +++ b/racketscript-compiler/racketscript/compiler/runtime/linklet-primitive.rkt @@ -1,3 +1,40 @@ #lang racketscript/boot -(require racketscript/interop) +(require racketscript/interop "lib.rkt" "syntax.rkt") + +(define+provide (variable-reference-from-unsafe? v) #false) +(define+provide (variable-reference-constant? v) #false) +(define+provide make-instance #js.Core.Linklet.makeInstance) +(define+provide instance-data #js.Core.Linklet.instanceData) +(define+provide instance-name #js.Core.Linklet.instanceName) +(define+provide instance-variable-value #js.Core.Linklet.instanceVariableValue) +(define+provide instance-variable-names #js.Core.Linklet.instanceVariableNames) +(define+provide instance-set-variable-value! #js.Core.Linklet.instanceSetVariableValue) +(define+provide instance-unset-variable! #js.Core.Linklet.instanceUnsetVariable) +(define+provide instance-describe-variable! #js.Core.Linklet.instanceDescribeVariable) +(define+provide (linklet-virtual-machine-bytes) #"racketscript") + +(define-syntax-rule (bounce ids ...) + (#js.Core.Hash.makeEqual + (array (array 'ids ids) ...) + #false)) + +;; one big table with everything +(define+provide (primitive-table v) + (bounce syntax? syntax-e datum->syntax syntax->datum + syntax-property syntax-property-symbol-keys + syntax-source syntax-line syntax-column syntax-span + syntax-position + variable-reference-constant? + variable-reference-from-unsafe? + make-instance + instance-describe-variable! + instance-unset-variable! + instance-set-variable-value! + instance-variable-names + instance-variable-value + instance-data + instance-name + linklet-virtual-machine-bytes + primitive-table)) + diff --git a/racketscript-compiler/racketscript/compiler/runtime/paramz.js b/racketscript-compiler/racketscript/compiler/runtime/paramz.js index 459b9868..9f319669 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/paramz.js +++ b/racketscript-compiler/racketscript/compiler/runtime/paramz.js @@ -1,12 +1,6 @@ -import * as Core from './core.js'; +import { Marks, Box } from './core.js'; import { hamt } from './core/lib.js'; -/* --------------------------------------------------------------------------*/ -// All exports go in exports - -const Marks = Core.Marks; -const Box = Core.Box; - /* --------------------------------------------------------------------------*/ // Parameterization data structure is a HAMT Map keyed by parameter // and the value is stored in a box. The parameter is function object @@ -26,6 +20,7 @@ const Box = Core.Box; // ffi's "=>$" form. export const ParameterizationKey = {}; /* a unique reference that can act as key */ +export const BreakEnabledKey = {}; /* a unique reference that can act as key */ export const ExceptionHandlerKey = {}; /* a unique reference that can act as key */ let __top; diff --git a/racketscript-compiler/racketscript/compiler/runtime/paramz.rkt b/racketscript-compiler/racketscript/compiler/runtime/paramz.rkt index b0f554cc..ec0789ef 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/paramz.rkt +++ b/racketscript-compiler/racketscript/compiler/runtime/paramz.rkt @@ -6,6 +6,9 @@ (define Paramz ($/require/* "./paramz.js")) (define+provide parameterization-key #js.Paramz.ParameterizationKey) +(define+provide break-enabled-key #js.Paramz.BreakEnabledKey) +(define+provide cache-configuration #js.Paramz.BreakEnabledKey) (define+provide extend-parameterization #js.Paramz.extendParameterization) (define+provide exception-handler-key #js.Paramz.ExceptionHandlerKey) (define+provide (check-for-break) ($/undefined)) +(define+provide (reparameterize v) v) diff --git a/racketscript-compiler/racketscript/compiler/runtime/runtime.rkt b/racketscript-compiler/racketscript/compiler/runtime/runtime.rkt index 2c247752..c6aa4b85 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/runtime.rkt +++ b/racketscript-compiler/racketscript/compiler/runtime/runtime.rkt @@ -4,6 +4,7 @@ "lib.rkt") ;; TODO: why does this need to be here and in kernel.rkt? +;; Because the compiler hangs if it isn't here. (define+provide values (v-λ vals (if (binop === #js.vals.length 1) diff --git a/racketscript-compiler/racketscript/compiler/runtime/syntax.rkt b/racketscript-compiler/racketscript/compiler/runtime/syntax.rkt new file mode 100644 index 00000000..b1f12cc6 --- /dev/null +++ b/racketscript-compiler/racketscript/compiler/runtime/syntax.rkt @@ -0,0 +1,32 @@ +#lang racketscript/boot + +(require (for-syntax syntax/parse) + racket/stxparam + racketscript/interop + "lib.rkt") + +(provide (rename-out [-syntax? syntax?] + [-datum->syntax datum->syntax] + (-syntax->datum syntax->datum) + [-syntax-e syntax-e] + (-syntax-source syntax-source) + (-syntax-line syntax-line) + (-syntax-column syntax-column) + (-syntax-position syntax-position) + (-syntax-span syntax-span) + (-syntax-property syntax-property) + (-syntax-property-symbol-keys syntax-property-symbol-keys))) + +(define (-syntax? v) (#js.Core.Correlated.syntaxP v)) +(define (-datum->syntax v) (#js.Core.Correlated.datumToSyntax v)) +(define (-syntax-e v) (#js.v.get)) +(define (-syntax->datum v) (#js.v.get)) +(define (-syntax-source v) #f) +(define (-syntax-line v) #f) +(define (-syntax-column v) #f) +(define (-syntax-position v) #f) +(define (-syntax-span v) #f) +(define (-syntax-property s k [val #f]) + (if val s #f)) + +(define (-syntax-property-symbol-keys v) #js.Core.Pair.EMPTY) diff --git a/racketscript-compiler/racketscript/compiler/runtime/unsafe.rkt b/racketscript-compiler/racketscript/compiler/runtime/unsafe.rkt index d7528e1a..db8cc125 100644 --- a/racketscript-compiler/racketscript/compiler/runtime/unsafe.rkt +++ b/racketscript-compiler/racketscript/compiler/runtime/unsafe.rkt @@ -1,12 +1,12 @@ #lang racketscript/boot -(require racketscript/interop - (for-syntax syntax/parse) +(require (for-syntax syntax/parse) + racketscript/interop + racketscript/compiler/directive "lib.rkt") (define Core ($/require/* "./core.js")) - ;;----------------------------------------------------------------------------- ;; Unsafe Numeric Operations @@ -51,6 +51,21 @@ (define+provide (unsafe-fxmax a b) (if ($/binop > a b) b a)) +;; TODO: is this correct? +(define+provide (unsafe-fl= a b) + (binop === a b)) +(define+provide (unsafe-fl< a b) + (binop < a b)) +(define+provide (unsafe-fl<= a b) + (binop <= a b)) +(define+provide (unsafe-fl> a b) + (binop > a b)) +(define+provide (unsafe-fl>= a b) + (binop >= a b)) +(define+provide (unsafe-flmin a b) + (if ($/binop < a b) a b)) +(define+provide (unsafe-flmax a b) + (if ($/binop > a b) b a)) (define-unsafe-fx-binop+provide unsafe-fxrshift >>) (define-unsafe-fx-binop+provide unsafe-fxlshift <<) @@ -92,6 +107,15 @@ (define+provide (unsafe-vector-length v) (#js.v.length)) +(define+provide (unsafe-vector*-ref v k) + (#js.v.ref k)) + +(define+provide (unsafe-vector*-set! v k val) + (#js.v.set k val)) + +(define+provide (unsafe-vector*-length v) + (#js.v.length)) + ;;----------------------------------------------------------------------------- ;; Hash (define+provide (unsafe-immutable-hash-iterate-first h) @@ -130,4 +154,19 @@ (define+provide (unsafe-mutable-hash-iterate-pair h i) (#js.h.iteratePair i)) -(define+provide unsafe-undefined #js.Core.the_unsafe_undefined) +(define+provide unsafe-undefined #js.Core.theUnsafeUndefined) + +;; stubs +(define+provide unsafe-make-place-local #js.Core.Box.make) +(define+provide (unsafe-place-local-set! b v) (#js.b.set v)) +(define+provide (unsafe-place-local-ref b) (#js.b.get)) + +(define+provide (variable-reference-from-unsafe? v) #f) + +(define+provide (unsafe-root-continuation-prompt-tag) + (#js.Core.Marks.defaultContinuationPromptTag)) + +;; strings +(define+provide (unsafe-string-length s) + #js.s.length) + diff --git a/racketscript-compiler/racketscript/compiler/stx-utils.rkt b/racketscript-compiler/racketscript/compiler/stx-utils.rkt index 75d710c8..b6b34bd0 100644 --- a/racketscript-compiler/racketscript/compiler/stx-utils.rkt +++ b/racketscript-compiler/racketscript/compiler/stx-utils.rkt @@ -1,5 +1,7 @@ #lang racket/base -(require racket/match syntax/stx) +(require racket/match + syntax/stx) + (provide (all-defined-out)) (define (stx-foldl f b . lsts) diff --git a/racketscript-compiler/racketscript/compiler/transform.rkt b/racketscript-compiler/racketscript/compiler/transform.rkt index d8ce4ab3..e0552e3e 100644 --- a/racketscript-compiler/racketscript/compiler/transform.rkt +++ b/racketscript-compiler/racketscript/compiler/transform.rkt @@ -3,25 +3,19 @@ ;;; Generate IL code from abstract syntax. Each binding name ;;; in assumed to be fresh, to enforce lexical scope rules of Racket -(require racket/match - racket/function - racket/bool - racket/list +(require racket/bool racket/format - racket/path + racket/list + racket/match racket/set - racket/syntax - typed/racket/unsafe threading - anaphoric + "absyn.rkt" "config.rkt" - "global.rkt" - "logging.rkt" - "util.rkt" "environment.rkt" - "absyn.rkt" + "il-analyze.rkt" "il.rkt" - "il-analyze.rkt") + "logging.rkt" + "util.rkt") (require/typed racket/syntax [format-symbol (-> String Any * Symbol)]) @@ -321,6 +315,17 @@ (ILAssign id v))) (ILValue (void)))] + [(PlainApp (ImportedIdent '#%rs-compiler _ _) args) + (match args + [(list (Quote 'if-scheme-numbers) consequent alternate) + (if (use-scheme-numbers?) + (absyn-expr->il consequent #f) + (absyn-expr->il alternate #f))] + [(list (Quote 'if-scheme-numbers) consequent) + (if (use-scheme-numbers?) + (absyn-expr->il consequent #f) + (values '() (ILValue (void))))] + [else (error 'absyn-expr->il "unknown RS compiler directive" args)])] [(PlainApp (ImportedIdent '#%js-ffi _ _) args) (match args [(list (Quote 'var) (Quote var)) @@ -427,16 +432,18 @@ (define (il-app/binop v arg*) (define v-il (let-values ([(_ v) (absyn-expr->il v #f)]) v)) - (cond - [(and (equal? v (ImportedIdent '- '#%kernel #t)) - (length=? arg* 1)) - (ILApp v-il arg*)] - [(and (equal? v (ImportedIdent '/ '#%kernel #t)) - (length=? arg* 1)) - (ILBinaryOp '/ (cons (ILValue 1) arg*))] - [(and (ImportedIdent? v) (member v binops) (>= (length arg* ) 2)) - (ILBinaryOp (ImportedIdent-id v) arg*)] - [else (ILApp v-il arg*)])) + (if (use-scheme-numbers?) + (ILApp v-il arg*) + (cond + [(and (equal? v (ImportedIdent '- '#%kernel #t)) + (length=? arg* 1)) + (ILApp v-il arg*)] + [(and (equal? v (ImportedIdent '/ '#%kernel #t)) + (length=? arg* 1)) + (ILBinaryOp '/ (cons (ILValue 1) arg*))] + [(and (ImportedIdent? v) (member v binops) (>= (length arg* ) 2)) + (ILBinaryOp (ImportedIdent-id v) arg*)] + [else (ILApp v-il arg*)]))) ;; If some arguements produce statement, it may have side effects ;; and hence lambda expression should be computed first. @@ -533,13 +540,19 @@ ;; Probably a macro-introduced binding. ;; TODO: If its unimplemented primitive, we reach here. For ;; primitive modules, filter unimplemented bindings. - (define mod-obj-name (hash-ref (module-object-name-map) src)) + (define mod-obj-name (hash-ref (module-object-name-map) src + (lambda () + (log-rjs-warning "missing unreachable binding ~s ~s" id* src) + src))) (values '() (ILRef (ILRef (assert mod-obj-name symbol?) *quoted-binding-ident-name*) id*))] [else - (define mod-obj-name (hash-ref (module-object-name-map) src)) + (define mod-obj-name (hash-ref (module-object-name-map) src + (lambda () + (log-rjs-warning "missing reachable binding ~s ~s" id* src) + src))) (values '() (ILRef (assert mod-obj-name symbol?) id*))])] [(WithContinuationMark key _ (and (WithContinuationMark key _ _) wcm)) @@ -582,7 +595,7 @@ (list old-context-id new-context-id)))))) (values stms result-id)] [(VarRef _) (values '() (absyn-value->il '#%variable-reference))] - + [_ (error (~a "unsupported expr " expr))])) @@ -606,25 +619,33 @@ (cons (ILVarDec result-id v) binding-stms))])) - (: absyn-value->il (-> Any ILExpr)) (define (absyn-value->il d) + ;; Order here matters. For example, a list is always a cons + ;; but a cons is not always a list. (cond [(Quote? d) (absyn-value->il (Quote-datum d))] [(string? d) (ILApp (name-in-module 'core 'UString.make) (list (ILValue d)))] [(symbol? d) - (ILApp (name-in-module 'core 'Symbol.make) + (ILApp (name-in-module 'core 'PrimitiveSymbol.make) (list (ILValue (symbol->string d))))] + [(and (complex? d) + (not (real? d))) + (if (use-scheme-numbers?) + (ILApp (name-in-module 'core 'Number.Scheme.makeComplex) + (list (absyn-value->il (real-part d)) + (absyn-value->il (imag-part d)))) + (error (~a "Complex numbers not supported with JS number semantics: " d)))] [(keyword? d) (ILApp (name-in-module 'core 'Keyword.make) (list (ILValue (keyword->string d))))] + [(empty? d) + (name-in-module 'core 'Pair.EMPTY)] [(list? d) (ILApp (name-in-module 'core 'Pair.makeList) (map absyn-value->il d))] - [(empty? d) - (name-in-module 'core 'Pair.EMPTY)] [(cons? d) (ILApp (name-in-module 'core 'Pair.make) (list (absyn-value->il (car d)) @@ -658,13 +679,19 @@ [(char? d) (ILApp (name-in-module 'core 'Char.charFromCodepoint) (list (absyn-value->il (char->integer d))))] - [(or (integer? d) + [(or (regexp? d) (byte-regexp? d)) + (define v (object-name d)) ; string or bytes + (ILApp (name-in-module 'core 'Regexp.fromString) + (list (ILValue (if (bytes? v) (bytes->string/utf-8 v) v))))] + [(or (exact-integer? d) (boolean? d) - (regexp? d) - (byte-regexp? d) - (void? d) - (real? d)) + (void? d)) (ILValue d)] + [(real? d) + (if (use-scheme-numbers?) + (ILApp (name-in-module 'core 'Number.Scheme.makeFloat) + (list (ILValue d))) + (ILValue d))] [else (error (~a "unsupported value" d))])) (: expand-normal-case-lambda (-> (Listof PlainLambda) @@ -894,7 +921,7 @@ (: ~sym (-> Symbol ILExpr)) (define (~sym s) (ILApp - (name-in-module 'core 'Symbol.make) (list (ILValue (symbol->string s))))) + (name-in-module 'core 'PrimitiveSymbol.make) (list (ILValue (symbol->string s))))) (: ~cons (-> ILExpr ILExpr ILExpr)) (define (~cons a b) @@ -1002,7 +1029,9 @@ (list (ILVarDec 'if_res1 (~sym 'yes))) (list (ILVarDec 'if_res1 (~sym 'false)))) (ILVarDec 'a 'if_res1) - (ILVarDec 'b (ILBinaryOp '+ (list (~val 1) (~val 2))))) + (ILVarDec 'b (if (use-scheme-numbers?) + (ILApp (ILRef 'kernel '+) (list (ILValue 1) (ILValue 2))) + (ILBinaryOp '+ (list (~val 1) (~val 2)))))) (ILApp 'list '(a b)))) ;; -------------------------------------------------------------------------- @@ -1016,14 +1045,19 @@ (ILApp (ILRef 'kernel '/) '())) (check-ilexpr (PlainApp (kident '+) (list (Quote 1) (Quote 2))) '() - (ILBinaryOp '+ (list (ILValue 1) (ILValue 2)))) + (if (use-scheme-numbers?) + (ILApp (ILRef 'kernel '+) (list (ILValue 1) (ILValue 2))) + (ILBinaryOp '+ (list (ILValue 1) (ILValue 2))))) (check-ilexpr (PlainApp (kident '-) (list (Quote 1) (Quote 2) (Quote 3))) '() - (ILBinaryOp '- - (list - (ILValue 1) (ILValue 2) (ILValue 3))))) + (if (use-scheme-numbers?) + (ILApp (ILRef 'kernel '-) + (list (ILValue 1) (ILValue 2) (ILValue 3))) + (ILBinaryOp '- + (list + (ILValue 1) (ILValue 2) (ILValue 3)))))) ;; -------------------------------------------------------------------------- diff --git a/racketscript-compiler/racketscript/compiler/util-untyped.rkt b/racketscript-compiler/racketscript/compiler/util-untyped.rkt index a27b7291..1695c32c 100644 --- a/racketscript-compiler/racketscript/compiler/util-untyped.rkt +++ b/racketscript-compiler/racketscript/compiler/util-untyped.rkt @@ -1,14 +1,15 @@ #lang racket -(require "logging.rkt") - (provide links-module? improper->proper *jsident-pattern* js-identifier?) +(require (for-syntax syntax/parse) + setup/dirs + setup/link) -;; Path-String Path-String -> Boolean +;; Path Path -> Boolean ;; Returns true if path has base as prefix (define (subpath? base path) (define base* (explode-path base)) @@ -20,75 +21,22 @@ [p path*]) (equal? b p))])) -;; Module-Path -> (Maybe (list Symbol Path)) -;; Is mod-path belongs to a module listed in links file. If yes -;; return the link name in links.rktd file and path to root of -;; of that links module. +;; Module-Path -> (Maybe (list String Path)) +;; If `mod-path` belongs to a module listed in (find-links-file), +;; return a list containing: +;; - the link name, +;; - and path to root of the module +;; e.g., '("racketscript-compiler" +;; #) +;; else return false. (define (links-module? mod-path) - (define (match-link? dir link) - (match link - [(list 'root path) #:when (absolute-path? path) - ;; Links.rktd may have point to root package which is not at current - ;; subdir. Eg. /usr/local/.../links.rktl may point to a package in - ;; home directory. - (subpath? (~a (simplify-path path)) - (~a mod-path))] - [(list name path) - (subpath? (~a (simplify-path (build-path dir path))) - (~a mod-path))] - [(list name path re) #f])) - - ;; Path LinkEntry -> (list Symbol Path) - ;; Returns (list link-name pkg-root-dir) - ;; WHERE: LinkEntry is an entry in links.rktd file - (define (link->result link-fpath link) - ;; HACK: If the link path is relative path, then we pick - ;; the last component - (define (fix-relative-path p) - (if (relative-path? p) - (~a (let-values ([(base last dir?) (split-path p)]) last)) - p)) - (match link - [(list 'root path) #:when (absolute-path? path) - (list (~a (let-values ([(base last dir?) (split-path path)]) last)) - (string->path path))] - [(list name path) - (list (if (symbol? name) - (fix-relative-path path) - name) - (simplify-path (build-path (path-only link-fpath) - path)))] - [_ (error 'link->result "unsupported form")])) - - ;; Path -> (list Symbol Path) - ;; Iterate through each entry in links.rktd file pointed - ;; by link-fpath and find the entry with module mod-path - (define (find-link link-fpath) - (log-rjs-debug "Processing library collection links at: ~a" link-fpath) - (define links-dir (path-only link-fpath)) - (cond - [(file-exists? link-fpath) - (call-with-input-file link-fpath - (λ (p-links-in) - (let loop ([links (read p-links-in)]) - (match links - ['() #f] - [(cons hd tl) (if (match-link? links-dir hd) - (link->result link-fpath hd) - (loop tl))]))))] - [else - (log-rjs-warning "Library collection link file ~a does not exist!" link-fpath) - #f])) - - ;; Iterate through each links.rktd file, to find - ;; the out - (let loop ([links (current-library-collection-links)]) - (match links - ['() #f] - [(cons #f tl) (loop tl)] - [(cons hd tl) (or (find-link hd) - (loop tl))]))) - + (define links-file (find-links-file)) + (for*/or ([links-file (current-library-collection-links)] + #:when links-file + [link-path (links #:file links-file #:root? #t)]) + (and (subpath? link-path mod-path) + (let-values ([(base link-name dir?) (split-path link-path)]) + (list (~a link-name) link-path))))) (define (improper->proper l) (match l diff --git a/racketscript-compiler/racketscript/compiler/util.rkt b/racketscript-compiler/racketscript/compiler/util.rkt index 30651c41..fc6cbd63 100644 --- a/racketscript-compiler/racketscript/compiler/util.rkt +++ b/racketscript-compiler/racketscript/compiler/util.rkt @@ -9,11 +9,9 @@ racket/path racket/sequence racket/set - racket/string typed/rackunit "config.rkt" - "ident.rkt" - "util-untyped.rkt") + "ident.rkt") (require/typed racket/string [string-prefix? (-> String String Boolean)]) @@ -209,7 +207,9 @@ mod)) (: module-output-file (-> (U Path Symbol) Path)) +;; NOTE: returns simplified path, which is required by fns like find-relative-path (define (module-output-file mod) + (simple-form-path (match (module-kind mod) [(list 'primitive mod-path) ;; Eg. #%kernel, #%utils ... @@ -233,9 +233,10 @@ (path->complete-path output-path)] [(list 'general mod-path) (let* ([main (assert (main-source-file) path?)] - [rel-path (find-relative-path (path-parent main) mod-path)]) + [rel-path (find-relative-path (simple-form-path (path-parent main)) + (simple-form-path mod-path))]) (path->complete-path - (build-path (output-directory) "modules" (~a rel-path ".js"))))])) + (build-path (output-directory) "modules" (~a rel-path ".js"))))]))) (: module->relative-import (-> Path Path)) (define (module->relative-import mod-path) diff --git a/racketscript-compiler/racketscript/interop.rkt b/racketscript-compiler/racketscript/interop.rkt index 14e95c3f..8796e7c8 100644 --- a/racketscript-compiler/racketscript/interop.rkt +++ b/racketscript-compiler/racketscript/interop.rkt @@ -12,31 +12,34 @@ $/:= $/throw $/undefined + $/defined? $/null + $/null? $/typeof $/instanceof $/arguments $/binop + $/+ $/str $/this =>$ js-string - racket-string + js-string->string + js-array->list assoc->object (rename-out [*in-js-array in-js-array] [*in-js-object in-js-object]) for/js-array - for/js-object) + js-array? + for/js-object + js-object?) -(require syntax/parse/define - (for-syntax syntax/parse +(require (for-syntax racket/base racket/string - racket/base - racket/sequence syntax/stx - threading - (for-template "private/interop.rkt") - "private/interop.rkt")) + threading) + "private/interop.rkt" + syntax/parse/define) (begin-for-syntax (require (only-in "compiler/util-untyped.rkt" js-identifier?)) @@ -100,10 +103,20 @@ (syntax-parse stx [_ #`(#%js-ffi 'undefined)])) +;; shorthand for testing if something is undefined +(define-syntax ($/defined? stx) + (syntax-parse stx + [(_ x) #'($/binop !== x $/undefined)])) + (define-syntax ($/null stx) (syntax-parse stx [_ #`(#%js-ffi 'null)])) +;; shorthand for testing null +(define-syntax ($/null? stx) + (syntax-parse stx + [(_ x) #'($/binop === x $/null)])) + (define-syntax ($/this stx) (syntax-parse stx [_ #`(#%js-ffi 'this)])) @@ -188,12 +201,20 @@ [(_ oper:id operand0:expr operand1:expr) #'(#%js-ffi 'operator 'oper operand0 operand1)])) +(define-syntax ($/+ stx) + (syntax-parse stx + [(_ e) #'e] + [(_ e . rst) #'($/binop + e ($/+ . rst))])) + (define (js-string e) ($$ e.toString)) -(define (racket-string e) +(define (js-string->string e) (($ ($ '$rjs_core) 'UString 'makeImmutable) e)) +(define (js-array->list e) + (($ ($ '$rjs_core) 'Pair 'listFromArray) e)) + (define-syntax-parser $/str [(_ v:str) #'(#%js-ffi 'string v)] [(_ e:expr) #'(js-string e)]) @@ -208,7 +229,7 @@ (define key (let ([k (car p)]) (cond - [(string? k) k] + [(or ($/typeof k "string") (string? k)) k] ; allow both js and racket string keys [(symbol? k) (symbol->string k)] [else (error 'assoc->object "invalid key value")]))) ($/:= ($ result key) (car (cdr p))) @@ -252,7 +273,7 @@ ($ arr 'length i)) (define (js-array? v) - ($/instanceof v ($ 'Array))) + (($ ($ 'Array) 'isArray) v)) (define (in-js-array arr) (check-array arr) @@ -300,7 +321,11 @@ (for/list ([(k v) (*in-js-object obj)]) (values k v))) (define (js-object? v) - ($/typeof v "object")) + ($/binop && + ($/binop && + ($/typeof v "object") + ($/binop !== v $/null)) + (not (($ ($ '$rjs_core) 'Primitive 'check) v)))) (define (check-object v) (unless (js-object? v) @@ -380,8 +405,69 @@ (check-interop #'($ window 'document "write") #'(#%js-ffi 'index (#%js-ffi 'ref window 'document) "write")) - ;; Check '$>' + ;; Check `$$` + (check-interop #'($$ 'window.document write) + #'((#%js-ffi 'ref 'window 'document) write)) + + (check-interop #'($$ window.parent location) + #'((#%js-ffi 'ref window 'parent) location)) + + (check-interop #'($$ 'window document write) + #'((#%js-ffi 'var 'window) document write)) + + ;; Check $/new + (check-interop #'($/new (Img "foo.jpeg")) #'(#%js-ffi 'new (Img "foo.jpeg"))) + + ;; Check $/throw + (check-interop #'($/throw '42) #'(#%js-ffi 'throw '42)) + + ;; Check $/undefined + (check-interop #'($/undefined) #'(#%js-ffi 'undefined)) + ;; Check $/null + (check-interop #'($/null) #'(#%js-ffi 'null)) + + ;; Check $/this + (check-interop #'($/this) #'(#%js-ffi 'this)) + + ;; Check $/arguments + (check-interop #'($/arguments) #'(#%js-ffi 'arguments)) + + ;; Check $/:= + (check-interop #'($/:= ($ window 'document 'width) '42) + #'(#%js-ffi 'assign (#%js-ffi 'ref (#%js-ffi 'ref window 'document) 'width) '42)) + + ;; Check $/array + (check-interop #'($/array 42 'foobar ($/new ($/this))) + #'(#%js-ffi 'array 42 'foobar (#%js-ffi 'new (#%js-ffi 'this)))) + + ;; Check $/require + (check-interop #'($/require "foo.rkt") #'(#%js-ffi 'require "foo.rkt")) + (check-interop #'($/require "bar.rkt" *) #'(#%js-ffi 'require '* "bar.rkt")) + + ;; Check $/require/* + (check-interop #'($/require/* "foo.rkt") #'(#%js-ffi 'require '* "foo.rkt")) + + ;; Check $/typeof + (check-interop #'($/typeof '42) #'(#%js-ffi 'typeof '42)) + (check-interop #'($/typeof '42 "function") + #'(#%js-ffi 'operator '=== (#%js-ffi 'typeof '42) (#%js-ffi 'string "function"))) + + ;; Check $/instanceof + (check-interop #'($/instanceof '42 'Object) #'(#%js-ffi 'instanceof '42 'Object)) + + ;; Check $/binop + (check-interop #'($/binop * '33 '67) #'(#%js-ffi 'operator '* '33 '67)) + + ;; Check $/+ + (check-interop #'($/+ '5) #'5) + (check-interop #'($/+ '5 '6 '7) #'(#%js-ffi 'operator '+ '5 (#%js-ffi 'operator '+ '6 '7))) + + ;; Check $/str + (check-interop #'($/str "foobar") #'(#%js-ffi 'string "foobar")) + (check-interop #'($/str (make-string)) #'(js-string (make-string))) + + ;; Check '$>' (check-interop #'($> foo bar (baz 'a 'b)) #'((#%js-ffi 'ref (#%js-ffi 'ref foo 'bar) 'baz) 'a 'b)) diff --git a/racketscript-compiler/racketscript/lang/reader.rkt b/racketscript-compiler/racketscript/lang/reader.rkt new file mode 100644 index 00000000..bfa2e428 --- /dev/null +++ b/racketscript-compiler/racketscript/lang/reader.rkt @@ -0,0 +1,6 @@ +#lang s-exp syntax/module-reader +racketscript + +#:read x-read +#:read-syntax x-read-syntax +(require "../boot/lang/reader.rkt") diff --git a/racketscript-compiler/racketscript/private/interop.rkt b/racketscript-compiler/racketscript/private/interop.rkt index 2ae15788..224f6d9f 100644 --- a/racketscript-compiler/racketscript/private/interop.rkt +++ b/racketscript-compiler/racketscript/private/interop.rkt @@ -15,6 +15,12 @@ ;; + 'object ;; + 'array ;; + 'require + ;; + 'this + ;; + 'typeof + ;; + 'instanceof + ;; + 'string + ;; + 'arguments + ;; + 'operator (define-values (#%js-ffi) (lambda _ (#%app error 'racketscript "can't make JS ffi calls in Racket")))) diff --git a/racketscript-doc/info.rkt b/racketscript-doc/info.rkt new file mode 100644 index 00000000..29b33ea6 --- /dev/null +++ b/racketscript-doc/info.rkt @@ -0,0 +1,14 @@ +#lang info + +(define collection 'multi) + +(define deps '("base")) + +(define build-deps + '("racket-doc" + "scribble-lib" + "scribble-enhanced" + "racketscript-compiler")) + +(define pkg-desc "Documentation for the RacketScript compiler") +(define pkg-authors '(vishesh stchang)) diff --git a/racketscript-doc/racketscript/info.rkt b/racketscript-doc/racketscript/info.rkt new file mode 100644 index 00000000..0a05d090 --- /dev/null +++ b/racketscript-doc/racketscript/info.rkt @@ -0,0 +1,3 @@ +#lang info +(define scribblings + '(["scribblings/racketscript.scrbl" (multi-page)])) diff --git a/racketscript-doc/racketscript/scribblings/ffi.scrbl b/racketscript-doc/racketscript/scribblings/ffi.scrbl new file mode 100644 index 00000000..438d4f8b --- /dev/null +++ b/racketscript-doc/racketscript/scribblings/ffi.scrbl @@ -0,0 +1,232 @@ +#lang scribble/manual + +@(require (only-in scribble-enhanced + [defform enhanced:defform] + [defform* enhanced:defform*]) + (for-label racket/base + racket/contract/base + racketscript/interop)) + +@title[#:tag "rs-js-ffi"]{The RacketScript-JavaScript FFI} + +@defmodule[racketscript/interop #:use-sources (racketscript/interop)] + +RacketScript supports direct interoperability with most JavaScript +features. This section explains how to invoke plain JavaScript in a +RacketScript program. + +@section[#:tag "js-ffi"]{RacketScript's JavaScript FFI Primitive} + +RacketScript's @racket[#%js-ffi] form compiles directly to various +JavaScript features. The first argument is a symbol that indicates the +kind of JavaScript code to be generated and the rest are the arguments +for that kind of operation. + +@bold{NOTE}: Users most likely @bold{should not} be using this +form. Instead, use the API described in the @secref{mainapi} section, +which will expand to the appropriate call to @racket[#%js-ffi]. + + +@enhanced:defform*[((#%js-ffi 'var) + (#%js-ffi 'ref obj prop-id) + (#%js-ffi 'index obj prop-expr) + (#%js-ffi 'assign x e) + (#%js-ffi 'new expr) + (#%js-ffi 'throw exn) + (#%js-ffi 'undefined) + (#%js-ffi 'null) + (#%js-ffi 'this) + (#%js-ffi 'arguments) + (#%js-ffi 'object [fld v] ...) + (#%js-ffi 'array args ...) + (#%js-ffi 'typeof obj) + (#%js-ffi 'instanceof obj type) + (#%js-ffi 'string str) + (#%js-ffi 'require mod) + (#%js-ffi 'operator 'op operand ...)) +]{} + +Summary of JavaScript operations supported by @racket[#%js-ffi]: + +@itemlist[@item{@racket['var]: Use to access variable in the JavaScript namespace} + @item{@racket['ref]: JavaScript object property reference, i.e., dot notation} + @item{@racket['index]: JavaScript index operation, i.e., bracket notation} + @item{@racket['assign]: JavaScript assignment} + @item{@racket['new]: JavaScript object constructor} + @item{@racket['throw]: Throw JavaScript exception} + @item{@racket['undefined]: JS @tt{undefined} value} + @item{@racket['null]: JS @tt{null} object value} + @item{@racket['this]: JS @tt{this} object self reference} + @item{@racket['arguments]: implicit JS @tt{arguments} variable containing function args} + @item{@racket['object]: JS object literals, i.e, curly brace notation} + @item{@racket['array]: JS array literals, i.e, bracket notation} + @item{@racket['typeof]: JS @tt{typeof} operation} + @item{@racket['instanceof]: JS @tt{instanceof} operation} + @item{@racket['string]: JS strings (incompatible with Racket/RacketScript strings, see @racket[$/str])} + @item{@racket['require]: JS @tt{import}, use to import JS libraries} + @item{@racket['operator]: Use to call JS functions requiring infix notation} + ] + +@section[#:tag "mainapi"]{RacketScript's JavaScript FFI API} + +@defform*[(($ jsid) + ($ expr sym) + ($ expr expr) + ($ expr expr ...)) + #:grammar + ([jsid (code:line valid JS identifier (alphanumeric underscore and dollar chars))]) + #:contracts + ([sym symbol?])]{ + +Syntax for accessing Javascript variables and properties. + + @itemlist[@item{Using the @racket[$] operator with a single identifier references a JavaScript variable. + + @bold{Example}: @racket[($ JSON)] + + @bold{Note}: the identifier be a @bold{valid JavaScript identifier} (underscore, dollar, and alphanumeric characters only), and not Racket or RacketScript one. + + Equivalent to @racket[(#%js-ffi 'var jsid)].} + + @item{Supplying a second argument that is a symbol corresponds to accessing a JavaScript object property using dot notation, where the symbol name is the property name. + + @bold{Example}: If handling a web request named @racket[req], getting the body of the request could be written @racket[($ req 'body)] which compiles to @tt{req.body} in JavaScript. + + Equivalent to @racket[(#%js-ffi 'ref req 'body)]. + + @bold{Note}: The above assumes that @racket[req] is a RacketScript variable. If the variable is in the JavaScript namespace only, then an additional @racket[$] is needed to first access the variable (see first @racket[$] case above). + + @bold{Example}: @racket[($ ($ JSON) 'parse)] compiles to the JavaScript @tt{JSON.parse} function. + + Equivalent to @racket[(#%js-ffi 'ref (#%js-ffi 'var JSON) 'parse)].} + + @item{A second argument that is an arbitrary expression is treated as JavaScript bracket notation. + + @bold{Example}: @racket[($ req "body")] compiles to @tt{req["body"]} in JavaScript. + + + Equivalent to @racket[(#%js-ffi 'index req "body")].} + @item{Supplying more than two arguments corresponds to a series of bracket lookups.}]} + +@defform[($$ dot-chain e ...) + #:grammar + ([dot-chain (code:line symbol or identifier consisting of multiple dot-separated names)])]{ +Shorthand for multiple @racket[$]s. Allows more direct use of dot notation in RacketScript. E.g., @racket[($$ window.document.write)] corresponds to @tt{window.document.write} in JavaScript.} + + +@defform[($/new constructor-expr)]{JavaScript object construction. Equivalent to @racket[(#%js-ffi 'new constructor-expr)].} +@defform[($/throw exn)]{Throw a JavaScript exception. Equivalent to @racket[(#%js-ffi 'throw exn)].} +@defform[#:id $/undefined $/undefined]{The JavaScript @tt{undefined} value. Equivalent to @racket[(#%js-ffi 'undefined)]} +@defform[#:id $/null $/null]{The JavaScript @tt{null} object. Equivalent to @racket[(#%js-ffi 'null)].} +@defform[#:id $/this $/this]{The JavaScript @tt{this} keyword. Equivalent to @racket[(#%js-ffi 'this)].} +@defform[#:id $/arguments $/arguments]{The JavaScript @tt{arguments} object containing the arguments passed to a function. Equivalent to @racket[(#%js-ffi 'arguments)].} + +@defform[($/obj [fld v] ...) + #:grammar ([fld identifier])]{JavaScript object literal notation, i.e., brace notation, where @tt{fld} are identifiers representing the object's properties, and @tt{v ...} are values assigned to those properties. Equivalent to @racket[(#%js-ffi 'object fld ... v ...)]} + +@defform[($/:= e v)]{JavaScript assignment statement. Equivalent to @racket[(#%js-ffi 'assign e v)]. @racket[e] should be a symbol, or a @racket[#%js-ffi] @racket['var], @racket['ref], or @racket['index] call.} + +@defform[($/array e ...)]{JavaScript array literal notation, where @racket[($/array 1 2 3)] compiles to @tt{[1,2,3]}. Equivalent to @racket[(#%js-ffi 'array e ...)]} + +@defform*[#:literals (*) + (($/require mod) + ($/require mod *)) + #:contracts + ([mod string?])]{ + JavaScript import statement. + + Often used with @racket[define], e.g., @racket[(define express ($/require "express"))] compiles to: + + @tt{import * as express from "express";} + + Equivalent to @racket[(#%js-ffi 'require mod)] or @racket[(#%js-ffi 'require '* mod)]} + + +@defform[($/require/* mod) + #:contracts + ([mod string?])]{ + JavaScript import all statement. + + Shorthand for @racket[($/require mod *)]} + +@defform[($> e call ...) + #:grammar + ([call id + (meth arg ...)])]{ + JavaScript chaincall. + + For example: + + @tt{($> (#js.res.status 400) (send #js"Bad Request"))} + + is compiles to @tt{res.status(400).send("Bad Request")} + + Equivalent to nested @racket[#%js-ffi] calls (with @racket['var], @racket['ref], or @racket['index]). +} + +@defform*[(($/typeof e) + ($/typeof e type)) + #:contracts + ([type (and/c string? + (or/c "undefined" "object" "boolean" "number" "string" "function"))])]{ +JavaScript @tt{typeof} operator. + +The first form returns a string representing the typeof the given JavaScript value. Equivalent to @racket[(#%js-ffi 'typeof e)]. + +The second form is shorthand for checking the type of a value. For example, @racket[($/typeof 11 "number")] is compiles to + +@tt{typeof 11 === "number";} + +Equivalent to @racket[($/binop === (#%js-ffi 'typeof e) ($/str v))] +} + +@defform[($/instanceof e type) #:grammar ([e (code:line JavaScript Object)])]{Returns a boolean indicating whether JavaScript object @racket[e] is an instance of @racket[type]. + + Equivalent to @racket[(#%js-ffi 'instanceof e type)]} + + +@defform[($/binop op operand1 operand2)]{JavaScript infix binary function call. + +Equivalent to @racket[(#%js-ffi 'operator 'op operand1 operand2)]} + +@defform[($/+ operand ...)]{Multi-argument infix calls to JavaScript @tt{+} (can be used as either concat or addition). + Equivalent to multiple nested calls to @racket[$/binop].} + +@defproc[(js-string->string [jsstr JSstring]) string?]{Converts a JS string to a RacketScript string.} + +@defproc[(js-string [str string?]) JSstring]{Converts a RacketScript string to a JS string.} + +@defform[($/str s)]{Converts a Racket string to a JS string, or vice versa, using @racket[js-string->string] or @racket[js-string].} + +@section[#:tag "reader"]{Reader Extensions} + +@tt{#lang racketscript/base} includes reader extensions that +make it easier to interoperate with JavaScript. Specifically, +RacketScript's reader recognizes three delimiters: + +@itemlist[@item{@verbatim|{#js}| + + Used to access JavaScript object properties via dot notation. + + @bold{Example}: @verbatim|{#js.req.body}| where @racket[req] is a RacketScript variable. + + Equivalent to a series of @racket[#%js-ffi] @racket['ref] calls.} + + @item{@verbatim|{#js*}| + + Used to access JavaScript object properties via dot notation. The difference with @racket{#js} is that @racket{#js*} wraps the first identifier in a @racket[#%js-ffi] @racket['var] form, i.e., it is used to access properties of @bold{JavaScript} variables rather than RacketScript variables. + + + @bold{Example}: @verbatim|{#js*.JSON.parse}| where @racket[JSON] is a JavaScript variable. + + Equivalent to a series of @racket[#%js-ffi] @racket['ref] calls where the first id is wrapped in a @racket[#%js-ffi] @racket['var].} + + @item{@verbatim|{#js"some js string"}| + + Used to create JS strings. + + @bold{Note}: JS strings are not compatible with Racket/RacketScript strings. Use @racket[$/str] and other related API functions to convert between the two when needed. + + @bold{Example}: @verbatim|{(#js*.console.warn #js"Error!")}| + + Equivalent to a @racket[#%js-ffi] call with @racket['string].}] diff --git a/racketscript-doc/racketscript/scribblings/racketscript.scrbl b/racketscript-doc/racketscript/scribblings/racketscript.scrbl new file mode 100644 index 00000000..591709b8 --- /dev/null +++ b/racketscript-doc/racketscript/scribblings/racketscript.scrbl @@ -0,0 +1,19 @@ +#lang scribble/manual + +@title[#:style '(toc)]{The RacketScript Language and Compiler} + +@defmodule[racketscript/base #:lang #:use-sources (racketscript/interop)] + +@(author + (author+email "Vishesh Yadav" "vishesh3y@gmail.com" #:obfuscate? #t) + (author+email "Stephen Chang" "stchang@racket-lang.org" #:obfuscate? #t)) + +RacketScript is an experimental Racket to JavaScript (ES6) +compiler. It allows programmers to use both JavaScript's and Racket's +ecosystem and aims to make this interoperability as smooth as +possible. + +@local-table-of-contents[] + +@include-section{start.scrbl} +@include-section{ffi.scrbl} diff --git a/racketscript-doc/racketscript/scribblings/start.scrbl b/racketscript-doc/racketscript/scribblings/start.scrbl new file mode 100644 index 00000000..1fd5a3fc --- /dev/null +++ b/racketscript-doc/racketscript/scribblings/start.scrbl @@ -0,0 +1,8 @@ +#lang scribble/manual + +@title[#:tag "start"]{Getting Started} + } + +@section[#:tag "install"]{Installation} + +@section[#:tag "use"]{Use} diff --git a/racketscript-extras/racketscript/htdp/image.rkt b/racketscript-extras/racketscript/htdp/image.rkt index 28a22692..e5db9547 100644 --- a/racketscript-extras/racketscript/htdp/image.rkt +++ b/racketscript-extras/racketscript/htdp/image.rkt @@ -45,10 +45,12 @@ flip-horizontal bitmap/data + bitmap/url freeze print-image color + (rename-out [color make-color]) (struct-out posn)) ;;----------------------------------------------------------------------------- @@ -122,18 +124,6 @@ (define (image-height i) #js.i.height) (define (image-width i) #js.i.width) -(define-proto EmptyScene - (λ (width height borders?) - #:with-this this - (set-object! this - [type "empty-scene"] - [width width] - [height height] - [borders? borders?])) - [render (λ (ctx x y) - ;; TODO: borders? - (void))]) - (define-proto Text (λ (text size color face family style weight underline?) #:with-this this @@ -278,8 +268,10 @@ (#js.ctx.lineTo (posn-x pt) (posn-y pt)) (loop (cdr points)))))))]) -(define (empty-scene width height) - (new (EmptyScene width height #f))) +(define (empty-scene width height [color "white"]) + (overlay + (rectangle width height "solid" color) + (rectangle width height "outline" "black"))) (define (text txt size color) (new (Text txt @@ -461,6 +453,7 @@ (λ (data) #:with-this this (define image (new #js*.Image)) + (:= #js.image.crossOrigin #js"anonymous") (:= #js.image.src (js-string data)) (set-object! this [image image] @@ -674,6 +667,9 @@ (define (bitmap/data data) (new (Bitmap data))) +(define (bitmap/url url) + (new (Bitmap url))) + (define (frame img) (color-frame "black" img)) diff --git a/racketscript-extras/racketscript/htdp/private/color.rkt b/racketscript-extras/racketscript/htdp/private/color.rkt index 04aa28d0..2bec772b 100644 --- a/racketscript-extras/racketscript/htdp/private/color.rkt +++ b/racketscript-extras/racketscript/htdp/private/color.rkt @@ -66,6 +66,7 @@ ["darksalmon" (-color 233 150 122)] ["gold" (-color 255 215 0)] ["yellow" (-color 255 255 0)] + ["medium yellow" (-color 255 255 0)] ["olive" (-color 128 128 0)] ["burlywood" (-color 222 184 135)] ["tan" (-color 210 180 140)] @@ -206,4 +207,5 @@ ["darkgray" (-color 169 169 169)] ["dim gray" (-color 105 105 105)] ["dimgray" (-color 105 105 105)] - ["black" (-color 0 0 0)])) + ["black" (-color 0 0 0)] + ["transparent" (-color 0 0 0 0)])) diff --git a/racketscript-extras/racketscript/htdp/universe.rkt b/racketscript-extras/racketscript/htdp/universe.rkt index 89f13ab8..8bbc9280 100644 --- a/racketscript-extras/racketscript/htdp/universe.rkt +++ b/racketscript-extras/racketscript/htdp/universe.rkt @@ -11,8 +11,10 @@ to-draw stop-when big-bang + name - key=?) + key=? + mouse=?) (define *default-frames-per-second* 70) @@ -63,7 +65,7 @@ (:= #js.canvas.width #js.img.width) (:= #js.canvas.height #js.img.height) - ;; We are reassiging using change-world so that change world + ;; We are reassigning using change-world so that change world ;; callbacks gets invoked at start of big-bang (#js.this.change-world #js.this.world) @@ -92,6 +94,8 @@ (λ () #:with-this this (:= #js.this.-stopped #f) + ; always draw first, in case no on-tick handler provided + (#js.this.queue-event ($/obj [type #js"to-draw"])) (#js.this.process-events))] [stop (λ () @@ -148,9 +152,10 @@ (define changed? (cond - [handler (#js.handler.invoke #js.this.world evt)] + ; raw evt must be checked 1st; bc handler will be undefined [(equal? #js.evt.type #js"raw") (#js.evt.invoke #js.this.world evt)] + [handler (#js.handler.invoke #js.this.world evt)] [else (#js.console.warn "ignoring unknown/unregistered event type: " evt)])) (loop (or world-changed? changed?))] @@ -220,7 +225,7 @@ (λ (evt) (define posn (canvas-posn-δ canvas evt)) (#js.bb.queue-event ($/obj [type #js"on-mouse"] - [evt r-evt-name] + [evt (js-string->string r-evt-name)] [x ($ posn 'x)] [y ($ posn 'y)])))) @@ -365,7 +370,7 @@ k)) (let ([key-table-code ($ key-table code)]) (if (void? key-table-code) - (racket-string code) + (js-string->string code) key-table-code))) (define (canvas-posn-δ canvas evt) @@ -376,3 +381,19 @@ (define (key=? k1 k2) (equal? k1 k2)) +(define (mouse=? m1 m2) + (equal? m1 m2)) + +(define (name name) + (λ (bb) + ($/obj + [name #js"name"] + [register + (λ () + #:with-this this + (:= #js.this.old-title #js*.document.title) + (:= #js*.document.title (js-string name)))] + [deregister + (λ () + #:with-this this + (:= #js*.document.title #js.this.old-title))]))) \ No newline at end of file diff --git a/racketscript/info.rkt b/racketscript/info.rkt index e4f50c17..2f812dad 100644 --- a/racketscript/info.rkt +++ b/racketscript/info.rkt @@ -5,11 +5,13 @@ (define deps '("base" "racketscript-compiler" - "racketscript-extras")) + "racketscript-extras" + "racketscript-doc")) (define build-deps '()) (define implies '("racketscript-compiler" - "racketscript-extras")) + "racketscript-extras" + "racketscript-doc")) diff --git a/tests/basic/__complex.rkt b/tests/basic/__complex.rkt new file mode 100644 index 00000000..a5e5e0c9 --- /dev/null +++ b/tests/basic/__complex.rkt @@ -0,0 +1,52 @@ +#lang racket + +;; TODO: Make able to test with JS +;; number semantics. +(begin (+ 1.0-3i 2.0+1i) + (+ 1.0-3i 2.0) + (+ 1.0-3i 2) + (+ 1.0-3i 1.0+3i) + (+ 1.0-3i 1.0+3i 2 5.0) + (/ 1-3i 1+3i 2 5) + (* 1.0-3i 1.0+3i 2 5.0) + (- 1.0-3i 1.0+3i 2 5.0) + (add1 1.0-3i) + (sub1 1.0-3i) + (number? 1.0+1i) + (complex? 1.0+1i) + (real? 1.0+1i) + (rational? 1.0+1i) + (integer? 1.0+1i) + (zero? 0+0i) + (zero? 0-0i) + (zero? 1+0i) + (exact? 2+1i) + (exact? 2.0+1i) + (inexact? 2+3i) + (inexact? 2.0+3i) + (exact->inexact 2+3i) + (= 1.0-3i 1.0+3i 2 5.0) + (= 1.0-3i 1.0-3i 1.0-3i 1.0-3i ) + (sqrt -1) + (sqrt 100+100i) + (expt 2+3i 4) + (exp 2+3i) + (log 2+3i) + (sin 0+0i) + (cos 0+0i) + (tan 0+0i) + (asin (sin 1+1i)) + (acos (cos 1+1i)) + (atan 0+0i) + (make-rectangular 3 5) + (make-polar 3 5) + (real-part 3-5i) + (imag-part 3-5i) + (magnitude 3-5i) + (angle 3-5i) + (number->string 3-5i) + (string->number "3-5i") + (conjugate 3-5i) + (sinh 3-5i) + (cosh 3-5i) + (tanh 0+0i)) diff --git a/tests/basic/arithmatic.rkt b/tests/basic/arithmatic.rkt index e9377a5e..53d88d15 100644 --- a/tests/basic/arithmatic.rkt +++ b/tests/basic/arithmatic.rkt @@ -53,3 +53,13 @@ (displayln (+)) (displayln (*)) + +;; test bitwise operations +(displayln (bitwise-and 5 3)) ;; 1 +(displayln (bitwise-and 5 3 -1983)) ;; 1 +(displayln (bitwise-ior 5 3)) ;; 7 +(displayln (bitwise-ior 5 3 10)) ;; 15 +(displayln (bitwise-xor 5 3)) ;; 6 +(displayln (bitwise-xor 5 3 10)) ;; 12 +(displayln (bitwise-not 5)) ;; -6 +(displayln (bitwise-not -3)) ;; 2 diff --git a/tests/basic/bytes.rkt b/tests/basic/bytes.rkt index 92d3668e..056cd69e 100644 --- a/tests/basic/bytes.rkt +++ b/tests/basic/bytes.rkt @@ -1,4 +1,7 @@ #lang racket + +(require "../test-utils.rkt") + (displayln (bytes->string/utf-8 #"Hello World")) (displayln (string->bytes/utf-8 "Hello World")) (displayln (bytes=? #"abc" #"abc")) @@ -21,3 +24,18 @@ (bytes>? #"aa" #"a") (bytes>? #"a" #"aa") (bytes>? #"aa" #"aa") + +(make-bytes 5 65) +;; TODO: 0 byte doesnt print the same as Racket +(bytes->string/utf-8 (make-bytes 5 0)) +(bytes->string/utf-8 (make-bytes 5)) +(make-bytes 0) +(make-bytes 0 0) + +(bytes-ref (make-bytes 5 65) 1) + +(define bs (make-bytes 5 65)) +(bytes-set! bs 0 66) +(bytes-ref bs 0) +(err/rt-test (bytes-ref bs 6)) ;; out of range +(err/rt-test (bytes-set! bs 6 66)) ;; out of range diff --git a/tests/basic/char.rkt b/tests/basic/char.rkt index c007ba21..ab6019a7 100644 --- a/tests/basic/char.rkt +++ b/tests/basic/char.rkt @@ -88,7 +88,7 @@ (displayln "char-numeric?") (println (char-numeric? #\5)) ; Nd -(run-if-version "6.10" +(run-if-version "7.0.0.1" (println (char-numeric? #\Ⅻ)) ; Nl (println (char-numeric? #\㊲))) ; No ;; TODO: the following should return #t but returns #f diff --git a/tests/basic/for.rkt b/tests/basic/for.rkt index 976b8541..60cdd486 100644 --- a/tests/basic/for.rkt +++ b/tests/basic/for.rkt @@ -5,3 +5,11 @@ (displayln v))) (fn (list 1 2 3 4)) + +;; string sequences +;; needs unsafe-string-length +(for ([c "string"]) + (displayln c)) + +(for ([c (string->list "string")]) + (displayln c)) diff --git a/tests/basic/list.rkt b/tests/basic/list.rkt index 744c9a62..bbb34afa 100644 --- a/tests/basic/list.rkt +++ b/tests/basic/list.rkt @@ -37,3 +37,12 @@ ;; anything larger will blow the stack (build-list 1000 add1) + +(remove 1 '(1 2 3)) +(remove 4 '(1 2 3)) +(remove 1 '()) +(remove 4 '(1 2 3 4) equal?) +(remove 5 '(1 2 3 4) <) + +(list->vector '()) +(list->vector '(1 2 3 4)) diff --git a/tests/basic/math.rkt b/tests/basic/math.rkt new file mode 100644 index 00000000..78d01275 --- /dev/null +++ b/tests/basic/math.rkt @@ -0,0 +1,9 @@ +#lang racket/base +(require racket/math) + +(displayln (atan 0 -1)) ; pi +(displayln pi) +(displayln (sin pi)) +(displayln (acos 0)) +(displayln (asin 0)) +(displayln (atan 0)) diff --git a/tests/basic/protect-out.rkt b/tests/basic/protect-out.rkt new file mode 100644 index 00000000..2f9ae07e --- /dev/null +++ b/tests/basic/protect-out.rkt @@ -0,0 +1,4 @@ +#lang racket/base +(define (f x) x) +(define-for-syntax (f1 x) x) +(provide (protect-out f (for-meta 1 f1))) diff --git a/tests/basic/require-provide.rkt b/tests/basic/require-provide.rkt index baff121c..0e73cfe3 100644 --- a/tests/basic/require-provide.rkt +++ b/tests/basic/require-provide.rkt @@ -11,3 +11,6 @@ (define (sub a b) (- a b)) +;; require protected id, see pr#284 +(require "protect-out.rkt") +(displayln (f 10)) diff --git a/tests/basic/string.rkt b/tests/basic/string.rkt index 816f6eee..01c19d60 100644 --- a/tests/basic/string.rkt +++ b/tests/basic/string.rkt @@ -25,6 +25,8 @@ (displayln (immutable? (string->immutable-string (string #\i #\🎂 #\c)))) (displayln (list->string '(#\a #\🎂 #\c))) +(displayln (string->list "abc")) +(displayln (string->list "")) (displayln (immutable? (list->string '(#\a #\🎂 #\c)))) (displayln (string-length (list->string '(#\a #\🎂 #\c)))) diff --git a/tests/basic/vector.rkt b/tests/basic/vector.rkt index fdc96af4..b145e398 100644 --- a/tests/basic/vector.rkt +++ b/tests/basic/vector.rkt @@ -21,3 +21,13 @@ (displayln "equal") (displayln (equal? #(1 2 3) #(1 2 3))) (displayln (equal? #(1 2 3) #(2 2 3))) + +(displayln "make-vector") +(displayln (make-vector 5)) +(displayln (make-vector 5 3)) +(displayln (make-vector 5 #f)) +(displayln (make-vector 0)) + +(define vec2 (vector 4 5 6)) +(vector-copy! vec 1 vec2 0 3) +(displayln vec) diff --git a/tests/dep-cache/has-dependency.rkt b/tests/dep-cache/has-dependency.rkt new file mode 100644 index 00000000..52b46b6d --- /dev/null +++ b/tests/dep-cache/has-dependency.rkt @@ -0,0 +1,10 @@ +#lang racket + +;; Tests dependecy caching by compiling once, then swapping +;; the names of ./private/dependency.rkt and ./private/depndency-changed.rkt, +;; then compiling again. If dependency caching isn't working properly, there +;; will be an error on the second compilation. + +(require "./private/dependency.rkt") + +(println (format "~a" (add 5))) diff --git a/tests/dep-cache/private/dependency.rkt b/tests/dep-cache/private/dependency.rkt new file mode 100644 index 00000000..ca92c738 --- /dev/null +++ b/tests/dep-cache/private/dependency.rkt @@ -0,0 +1,6 @@ +#lang racket + +(provide add) + +(define (add n) + (+ n 2)) diff --git a/tests/ffi/chaining.rkt b/tests/ffi/chaining.rkt index 40a7a5eb..9cefd2ae 100644 --- a/tests/ffi/chaining.rkt +++ b/tests/ffi/chaining.rkt @@ -1,26 +1,23 @@ -#lang racket/base +#lang racketscript/base -(require racketscript/ffi) - - -(define console ($ 'global 'console)) +(require racketscript/interop) (define (fun x) (if (zero? x) - ($/obj [name "Vishesh"] - [location "Boston"]) + ($/obj [name #js"Vishesh"] + [location #js"Boston"]) ($/obj [onfoo (λ (n) - ($$ console.log "Called foo: " n) + (#js*.console.log #js"Called foo: " n) (fun n))] [onbar (λ (n) - ($$ console.log "Called bar " n) + (#js*.console.log #js"Called bar: " n) (fun n))]))) - -($ ($> (fun 10) - (onfoo 10) - (onbar 20) - (onfoo 30) - (onbar 40) - (onbar 50) - (onfoo 0)) - 'name) +(#js*.console.log + ($ ($> (fun 10) + (onfoo 10) + (onbar 20) + (onfoo 30) + (onbar 40) + (onbar 50) + (onfoo 0)) + 'name)) diff --git a/tests/ffi/chaining.rkt.expected b/tests/ffi/chaining.rkt.expected new file mode 100644 index 00000000..d827332c --- /dev/null +++ b/tests/ffi/chaining.rkt.expected @@ -0,0 +1,7 @@ +Called foo: 10 +Called bar: 20 +Called foo: 30 +Called bar: 40 +Called bar: 50 +Called foo: 0 +Vishesh diff --git a/tests/ffi/context2d/simple.rkt b/tests/ffi/context2d/simple.rkt index 74fd7078..5d5a245b 100644 --- a/tests/ffi/context2d/simple.rkt +++ b/tests/ffi/context2d/simple.rkt @@ -1,13 +1,13 @@ -#lang racket +#lang racketscript/base -(require racketscript/ffi) +(require racketscript/interop) (define document ($$ 'window.document)) (define (onload) - (define canvas ($ document 'getElementById <$> "main_canvas")) - (define ctx ($ canvas 'getContext <$> "2d")) - ($ ctx 'fillStyle <:=> "blue") + (define canvas ($$ document.getElementById #js"main_canvas")) + (define ctx ($$ canvas.getContext #js"2d")) + ($/:= #js.ctx.fillStyle #js"blue") ($$ ctx.fillRect 10 20 200 100) ($$ ctx.strokeStyle "#fa00ff") ($$ ctx.lineWidth 5) diff --git a/tests/ffi/for-array.rkt b/tests/ffi/for-array.rkt index 6d03360b..5322bc77 100644 --- a/tests/ffi/for-array.rkt +++ b/tests/ffi/for-array.rkt @@ -1,4 +1,4 @@ -#lang racketscript/base +#lang racketscript (require racketscript/interop) diff --git a/tests/ffi/for-array.rkt.expected b/tests/ffi/for-array.rkt.expected new file mode 100644 index 00000000..bf1b6473 --- /dev/null +++ b/tests/ffi/for-array.rkt.expected @@ -0,0 +1,4 @@ +[ + 0, 1, 4, 9, 16, + 25, 36, 49, 64, 81 +] diff --git a/tests/ffi/for-object.rkt.expected b/tests/ffi/for-object.rkt.expected new file mode 100644 index 00000000..a4f82510 --- /dev/null +++ b/tests/ffi/for-object.rkt.expected @@ -0,0 +1,12 @@ +{ + '0': 0, + '2': 1, + '4': 4, + '6': 9, + '8': 16, + '10': 25, + '12': 36, + '14': 49, + '16': 64, + '18': 81 +} diff --git a/tests/ffi/in-js-array.rkt.expected b/tests/ffi/in-js-array.rkt.expected new file mode 100644 index 00000000..dc484a37 --- /dev/null +++ b/tests/ffi/in-js-array.rkt.expected @@ -0,0 +1,12 @@ +1 +2 +3 +4 +5 +6 +1 +2 +3 +4 +5 +6 diff --git a/tests/ffi/in-js-object.rkt.expected b/tests/ffi/in-js-object.rkt.expected new file mode 100644 index 00000000..d5636319 --- /dev/null +++ b/tests/ffi/in-js-object.rkt.expected @@ -0,0 +1,4 @@ +(name John) +(city San Jose) +(occupation Driver) +#hash((occupation . Driver) (city . San Jose) (name . John)) diff --git a/tests/ffi/pr226.rkt b/tests/ffi/pr226.rkt new file mode 100644 index 00000000..c22f3e31 --- /dev/null +++ b/tests/ffi/pr226.rkt @@ -0,0 +1,52 @@ +#lang racketscript/base + +(require racketscript/interop + racket/string + (for-syntax racket/base syntax/parse racket/syntax)) + +(define-syntax define-js-checker + (syntax-parser + [(_ name #:checks-js thing) + #:with thing-pred? (format-id #'thing "js-~a?" #'thing) + #'(define-syntax name + (syntax-parser + [(_ e) #'(name e "")] + [(_ e label) + #'(let ([x e]) + (when (non-empty-string? label) + (printf "~a " label)) + (printf "~v is a js ~a?: ~a\n" x 'thing (thing-pred? x)))]))])) + +(define-js-checker check-js-obj #:checks-js object) +(define-js-checker check-js-array #:checks-js array) + +(define-syntax check-js-objs+arrays + (syntax-parser + [(_) #'(begin)] + [(_ e #:label str . rst) + #'(begin + (let ([x e]) + (check-js-obj x str) + (check-js-array x str)) + (check-js-objs+arrays . rst))] + [(_ e . rst) ; no label + #'(begin + (let ([x e]) + (check-js-obj x) + (check-js-array x)) + (check-js-objs+arrays . rst))])) + +(check-js-objs+arrays {$/obj} + [$/array 1 2 3] #:label "raw js array" + (make-hash) + (vector 1 2 3) + #"ABC" #:label "racket bytestring" ; Uint8Array TypedArray is not Array + #\D #:label "racket char" + "a racket string" + #js"a js string" + '() + '(1 2 3) + 1 + #f + $/null) + diff --git a/tests/ffi/pr226.rkt.expected b/tests/ffi/pr226.rkt.expected new file mode 100644 index 00000000..cc9f3913 --- /dev/null +++ b/tests/ffi/pr226.rkt.expected @@ -0,0 +1,26 @@ +[object Object] is a js object?: #t +[object Object] is a js array?: #f +raw js array 1,2,3 is a js object?: #t +raw js array 1,2,3 is a js array?: #t +'#hash() is a js object?: #f +'#hash() is a js array?: #f +'#(1 2 3) is a js object?: #f +'#(1 2 3) is a js array?: #f +racket bytestring #"ABC" is a js object?: #t +racket bytestring #"ABC" is a js array?: #f +racket char #\D is a js object?: #f +racket char #\D is a js array?: #f +"a racket string" is a js object?: #f +"a racket string" is a js array?: #f +a js string is a js object?: #f +a js string is a js array?: #f +'() is a js object?: #f +'() is a js array?: #f +'(1 2 3) is a js object?: #f +'(1 2 3) is a js array?: #f +1 is a js object?: #f +1 is a js array?: #f +#f is a js object?: #f +#f is a js array?: #f +# is a js object?: #f +# is a js array?: #f diff --git a/tests/fixture.rkt b/tests/fixture.rkt index f2d0857e..62540626 100755 --- a/tests/fixture.rkt +++ b/tests/fixture.rkt @@ -8,7 +8,8 @@ racketscript/compiler/util racketscript/compiler/global racketscript/compiler/moddeps - racketscript/compiler/il-analyze) + racketscript/compiler/il-analyze + (for-syntax syntax/parse)) ;; Print Racket and JS output of test programs to stdout ;; Also show check failure @@ -18,6 +19,11 @@ ;; tests. (define clean-output-before-test (make-parameter #f)) +;; Find path to NodeJS excecutable. +(define nodejs-executable-path (make-parameter (or (find-executable-path "node") + (find-executable-path "nodejs") + (error "NodeJS executable not found in PATH!")))) + ;; Turning if false would ignore all standard output ;; produced by compiler (define racketscript-stdout? (make-parameter #f)) @@ -27,6 +33,9 @@ (define coverage-mode? (let ([mod (getenv "COVERAGE_MODE")]) (and mod (equal? (string->number mod) 1)))) +;; For running tests that don't need Racket, e.g. ffi tests +(define js-only? (make-parameter #f)) + (define (displayln* v) (if coverage-mode? (displayln "") @@ -74,15 +83,23 @@ ;; Path-String -> (list String String) ;; Runs module in file fpath in Racket interpreter and return ;; stdout and stderr produced +;; TODO: Handle error if we are unable to start process. (define (run-in-nodejs fpath) (match-define (list in-p-out out-p-in pid in-p-err control) - (process* (build-path (output-directory) "node_modules" ".bin" "traceur") + (process* (nodejs-executable-path) (module-output-file (if (absolute-path? fpath) (string->path fpath) (build-path (current-directory) fpath))))) (control 'wait) - (list (port->string in-p-out) - (port->string in-p-err))) + (define result (list (port->string in-p-out) + (port->string in-p-err))) + + (close-output-port out-p-in) + (close-input-port in-p-out) + (close-input-port in-p-err) + + result) + ;; String String -> Boolean ;; Compare the outputs produced @@ -92,7 +109,7 @@ ;; Path-String -> ExportTree (define get-cached-export-tree (memoized-λ (test-fpath) - (get-export-tree test-fpath))) + (get-export-tree (list test-fpath)))) ;; Path-String -> Void ;; Compile test-case in `fpath` to JavaScript @@ -113,13 +130,19 @@ (when (verbose?) ((error-display-handler) "racket->js failed" e)) #f)]) - (racket->js) - (if (false? coverage-mode?) - (list (log-and-return 'racket (run-in-racket fpath)) - (log-and-return 'nodejs (run-in-nodejs fpath))) - (list (list "" "") - (list "" "")))))) - + (racket->js)) + (cond [coverage-mode? (list (list "" "") (list "" ""))] + [(js-only?) + (define expected-file (path-add-extension fpath ".expected" ".")) + (define expected + (if (file-exists? expected-file) + (file->string expected-file) + "")) + (list (list expected "") + (log-and-return 'nodejs (run-in-nodejs fpath)))] + [else + (list (log-and-return 'racket (run-in-racket fpath)) + (log-and-return 'nodejs (run-in-nodejs fpath)))]))) ;; Path-String -> Void ;; Rackunit check for RacketScript. Executes module at file fpath ;; in Racket and NodeJS and compare their outputs @@ -144,18 +167,15 @@ ;; 2. Always skip-npm-install to save time ;; [3. Always remove old compiled module outputs)] (define (setup) - (when (clean-output-before-test) - (delete-directory/files (output-directory))) + (skip-npm-install #t) - (prepare-build-directory "") ;; We don't care about bootstrap file - (unless (skip-npm-install) - (parameterize ([current-directory (output-directory)]) - (system "npm install") - (skip-npm-install #t)))) + (when (clean-output-before-test) + (delete-directory/files (output-directory)))) -;; (Listof Glob-Pattern) -> Void +;; (Listof Glob-Pattern) -> Boolean ;; If tc-search-patterns is simply a path to directory, run all test -;; cases in that directory otherwise use glob pattern +;; cases in that directory otherwise use glob pattern. +;; Returns #t or #f depending on test results (define (run-tests tc-search-patterns) ;; First clean the compiled modules always, to avoid cases where ;; compilation fails but it anyway proceeds with last module output @@ -184,9 +204,9 @@ (for/list ([pat tc-search-patterns]) ; test all rkt files in dir, unless given single file (if (string-suffix? pat ".rkt") - (glob pat) + (glob pat) (glob (~a pat "/*.rkt")))))))) - + (define failed-tests '()) ;; Handler when exception is raised by check failures. Gather @@ -205,8 +225,7 @@ (λ (test-thunk) (with-handlers ([exn:test:check? (λ (e) (displayln* "✘") - ((current-check-handler) e) - #f)]) + ((current-check-handler) e))]) (test-thunk) (displayln* "✔"))))) @@ -218,12 +237,7 @@ (flush-output) (parameterize ([current-test-name test]) - (check-racketscript test)) - - ;; Disable Gulp build as soon as we have run it once, as all we - ;; need is HAMT built in runtime.1 - (unless (skip-gulp-build) - (skip-gulp-build #t))) + (check-racketscript test))) (unless (empty? failed-tests) (displayln (format "\nFailed tests (~a/~a) => " @@ -235,50 +249,84 @@ (unless (set-empty? skipped-tests) (displayln (format "\nSkipped tests [~a] => " (set-count skipped-tests))) (for ([t (sort (set->list skipped-tests) string RacketScript Fixtures Runner <-\n") - (when coverage-mode? (displayln "Running in coverage mode.")) - - (unless coverage-mode? - (parameterize ([enabled-optimizations (set)]) - (displayln "---------------------------------") - (displayln "::: Optimizations on ::: none :::") - (displayln "---------------------------------") - (run-tests (filter-not - (λ (s) (string-contains? s "optimize")) - tc-search-patterns)))) - - ;; (displayln "") - ;; (parameterize ([enabled-optimizations (set self-tail->loop)]) - ;; (displayln "--------------------------------") - ;; (displayln "::: Optimizations on ::: TCO :::") - ;; (displayln "--------------------------------") - ;; (run-tests tc-search-patterns)) - - ;; (displayln "") - ;; (parameterize ([enabled-optimizations (set flatten-if-else)]) - ;; (displayln "--------------------------------------------") - ;; (displayln "::: Optimizations on ::: Flatten If-Else :::") - ;; (displayln "-------------------------------------------") - ;; (run-tests tc-search-patterns)) - - (displayln "") - (parameterize ([enabled-optimizations (set flatten-if-else - self-tail->loop)]) - (displayln "--------------------------------") - (displayln "::: Optimizations on ::: All :::") - (displayln "-------------------------------") - (run-tests tc-search-patterns))) - -(skip-npm-install #f) ;; For setup we need to install packages + (displayln (format " □ ~a" t)))) + + (empty? failed-tests)) + +(define-syntax (define-test-case stx) + (syntax-parse stx + [(_ test-name:id + (~optional test-desc:string) + ([param:id value] ...)) + #:do [(define test-name-length (syntax-span #'test-name))] + #`(define test-name + (lambda (paths) + (setup) + (define passed #t) + (define (set-passed! new-value) + (set! passed (and passed new-value))) + + (parameterize ([param value] ...) + (displayln 'test-name) + (displayln (make-string #,test-name-length #\-)) + (displayln test-desc) + (displayln "") + (set-passed! (run-tests paths))) + + (displayln "") + passed))])) + +(define-syntax (run-test-suite stx) + (syntax-parse stx + [(_ test-case ...+ (~seq #:with paths)) + #'(and + (test-case paths) ...)] + [(_ test-case ...+) + #'(and + (test-case) ...)])) + +(define-syntax (fixture-run stx) + (define common + #'(begin + (displayln "") + (displayln "-> RacketScript Fixtures Runner <-\n") + (when coverage-mode? (displayln "Running in coverage mode.")))) + (syntax-parse stx + [(_ test ...+) + #`(begin + #,common + (unless (andmap (lambda (x) x) + (list test ...)) + (exit 1)))])) + +(define-test-case Baseline + "Racket programs without optimization" + ([enabled-optimizations (set)])) + +(define-test-case Optimized + "Racket programs with all optimizations applied" + ([enabled-optimizations (set flatten-if-else + self-tail->loop)])) + +(define-test-case Scheme-Numbers + "Racket programs using scheme number semantics" + ([enabled-optimizations (set)] + [use-scheme-numbers? #t])) + +(define-test-case FFI-Baseline + "FFI tests without optimization" + ([js-only? #t])) + +(define-test-case FFI-Optimized + "FFI tests with all optimizations applied" + ([js-only? #t] + [enabled-optimizations (set flatten-if-else + self-tail->loop)])) + (module+ main - ;; For setup we keep this on by default, and later turned off + (define quick? (make-parameter #f)) + ;; For setup we keep this on by default, and later turned off (define tc-search-pattern (command-line #:program "racketscript-fixture" @@ -288,15 +336,22 @@ (clean-output-before-test #t)] [("-o" "--compiler-out") "Show RacketScript output" (racketscript-stdout? #t)] - [("-n" "--skip-npm") "Skip NPM install on setup" - (skip-npm-install #t)] [("-v" "--verbose") "Show exceptions when running tests." (racketscript-stdout? #t) (verbose? #t)] + [("--js-only") "Compare js output against .expected file." + (js-only? #t)] + [("--quick") "Only run tests with all optimizations applied." + (quick? #t)] #:args (p . ps*) (cons p ps*))) - (run tc-search-pattern)) + (fixture-run + (run-test-suite (if (quick?) + void + Baseline) + Optimized + #:with tc-search-pattern))) (module+ test (define-runtime-path fixture-module "fixture.rkt") @@ -305,13 +360,30 @@ (define (fixture-path-patterns . paths) (for/list ([p paths]) (~a (build-path fixture-module-dir p) "/*.rkt"))) - (run (fixture-path-patterns "racket-core" - "test-the-test" - "basic" - "struct" - "hash" - "wcm" - "modules" - "optimize" - "experimental"))) - + (define basic-tests + (fixture-path-patterns + "racket-core" + "test-the-test" + "basic" + "struct" + "hash" + "wcm" + "modules" + "experimental")) + + + (fixture-run + + (run-test-suite (if coverage-mode? + void + Baseline) + Scheme-Numbers + #:with basic-tests) + + (run-test-suite Optimized + #:with (append basic-tests + (fixture-path-patterns "optimize"))) + + (run-test-suite FFI-Baseline + FFI-Optimized + #:with (fixture-path-patterns "ffi")))) diff --git a/tests/hash/eq-basic.rkt b/tests/hash/eq-basic.rkt index 43438139..ba703171 100644 --- a/tests/hash/eq-basic.rkt +++ b/tests/hash/eq-basic.rkt @@ -88,8 +88,17 @@ (equal? (hash-ref (hash-set h1 p1 (list (posn 0 0) 'origin)) p1) (list (posn 0 0) 'origin)) -;; check eqv-ness -;; hasheqv should return 1, hasheq should return 2 -(hash-ref (hasheq (integer->char 955) 1) +;; check eq-ness +;; hasheq should return 1 +;; Racket documentation promises `eq?` for characters with +;; scalar values in the range 0 to 255 +(hash-ref (hasheq (integer->char 255) 1) + (integer->char 255) + 2) +;; for chars > 255, eq behavior is actually undefined?? +;; eg, the following test returns 2 for < racket 8, but 1 for racket 8+ (chez) +;; so skip the test +;; see: https://groups.google.com/g/racket-users/c/LFFV-xNq1SU/m/s6eoC35qAgAJ +#;(hash-ref (hasheq (integer->char 955) 1) (integer->char 955) 2) diff --git a/tests/hash/eqv-basic.rkt b/tests/hash/eqv-basic.rkt index 6d23233a..79be5251 100644 --- a/tests/hash/eqv-basic.rkt +++ b/tests/hash/eqv-basic.rkt @@ -89,7 +89,10 @@ (list (posn 0 0) 'origin)) ;; check eqv-ness -;; hasheqv should return 1, hasheq should return 2 +;; hasheqv should return 1 +(hash-ref (hasheqv (integer->char 255) 1) + (integer->char 255) + 2) (hash-ref (hasheqv (integer->char 955) 1) (integer->char 955) 2) diff --git a/tests/racket-core/hash.rkt b/tests/racket-core/hash.rkt index 4429df72..49bcd32f 100644 --- a/tests/racket-core/hash.rkt +++ b/tests/racket-core/hash.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require "testing.rkt" "../test-utils.rkt" (for-syntax racket/base) #;racket/hash) +(require "../test-utils.rkt" (for-syntax racket/base)) ;; ---------------------------------------- ;; Hash-key sorting: @@ -82,8 +82,9 @@ #"apple" 'a #"banana" 'b #"coconut" 'c u/apple 'a u/banana 'b u/coconut 'c ;; TODO: properly implement unreadable symbols + 'apple 'banana 'coconut 'coconut+ ; apple 'a banana 'b coconut 'c - 'apple 'a 'banana 'b 'coconut 'c 'coconut+ '+ + ;'apple 'a 'banana 'b 'coconut 'c 'coconut+ '+ '#:apple 'a '#:banana 'b '#:coconut 'c null 'one (void) 'one @@ -593,14 +594,43 @@ (err/rt-test (hash-set! (hash) 1 2) exn:fail:contract? "expected.*not.*immutable") (err/rt-test (hash-ref (hash) 1)) (run-if-version "7.4.0.3" (err/rt-test (hash-ref-key (hash) 1))) -(err/rt-test (hash-set (make-hash) 1 2)) -(err/rt-test (hash-remove (make-hash) 1)) -(err/rt-test (hash-set! (hash) 1 2)) -(err/rt-test (hash-remove! (hash) 1)) -(run-if-version "6.5.0.8" (err/rt-test (hash-keys-subset? (hash) (hasheqv)))) -(run-if-version "6.5.0.8" (err/rt-test (hash-keys-subset? (hash) (hasheq)))) -(run-if-version "6.5.0.8" (err/rt-test (hash-keys-subset? (hasheqv) (hasheq)))) -(run-if-version "6.5.0.8" (err/rt-test (hash-keys-subset? (hasheq) (hasheqv)))) + +(run-if-version "8.1.0.1" ; racket cs changed err msgs, see pr#3838 + ;; also, hash-set err changed to use and/c instead of and in 8.0 + (err/rt-test (hash-set (make-hash) 1 2) exn:fail:contract? "hash\\? immutable") + (err/rt-test (hash-remove (make-hash) 1)) + (err/rt-test (hash-set! (hash) 1 2)) + (err/rt-test (hash-remove! (hash) 1))) + +(err/rt-test (hash-set (make-hash) 1 2) exn:fail:contract? "hash\\? immutable") +(err/rt-test (hash-set (make-hash) 1 2) exn:fail:contract? "hash does not contain key") +(err/rt-test (hash-remove (make-hash) 1) exn:fail:contract? "hash does not contain key") +(err/rt-test (hash-set! (hash) 1 2) exn:fail:contract? "hash does not contain key") +(err/rt-test (hash-remove! (hash) 1) exn:fail:contract? "hash does not contain key") + + +(run-if-version "6.5.0.8" + (err/rt-test (hash-keys-subset? (hash) (hasheqv)) + exn:fail:contract? + "hash tables do not use same key comparison.*hash.*hasheqv") + (err/rt-test (hash-keys-subset? (hash) (hasheq)) + exn:fail:contract? + "hash tables do not use same key comparison.*hash.*hasheqv") + (err/rt-test (hash-keys-subset? (hasheqv) (hasheq)) + exn:fail:contract? + "hash tables do not use same key comparison.*hash.*hasheqv") + (err/rt-test (hash-keys-subset? (hasheq) (hasheqv)) + exn:fail:contract? + "hash tables do not use same key comparison.*hash.*hasheqv") + (run-if-version "8.1.0.1" ; see commit f2933d5ab8 + (err/rt-test (hash-keys-subset? (hash) (hasheqv))) + (err/rt-test (hash-keys-subset? (hash) (hasheq))) + (err/rt-test (hash-keys-subset? (hasheqv) (hasheq))) + (err/rt-test (hash-keys-subset? (hasheq) (hasheqv))))) + +(run-if-version "8.1" + (hash-strong? (hash)) + (hash-strong? (make-hash))) ;; ---------------------------------------- ;; diff --git a/tests/racket-core/list.rkt b/tests/racket-core/list.rkt index 56b63b21..a93745da 100644 --- a/tests/racket-core/list.rkt +++ b/tests/racket-core/list.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require "testing.rkt" "../test-utils.rkt" racket/list) +(require "../test-utils.rkt" racket/list) (test (list 1 2 3 4) foldl cons '() (list 4 3 2 1)) (test (list 1 2 3 4) foldr cons '() (list 1 2 3 4)) @@ -40,7 +40,9 @@ (err/rt-test (memf cons '((1) (2) (3)))) (err/rt-test (memf string? '((1) (2) (3) . 4)) exn:application:mismatch?) -(err/rt-test (assf add1 '(0 1 2)) exn:application:mismatch?) +;; bug in racket cs, see commit e2cbd9bd739db0a38 +(run-if-version "8.1" (err/rt-test (assf add1 '(0 1 2)) exn:application:mismatch?)) +(err/rt-test (assf add1 '(0 1 2)) exn:application:mismatch? "non-pair found in list: 0") (test '(0 x) assf number? '((a 1) (0 x) (1 w) (2 r) (c 17))) (test '("ok" . 10) assf string? '((a 0) (0 a) (1 w) ("ok" . 10) (2 .7) c)) (err/rt-test (assf cons '((1) (2) (3)))) diff --git a/tests/racket-core/rx.rkt b/tests/racket-core/rx.rkt index 4f40ae7f..24db82f2 100644 --- a/tests/racket-core/rx.rkt +++ b/tests/racket-core/rx.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require "testing.rkt" "../test-utils.rkt") +(require "../test-utils.rkt") ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -21,27 +21,26 @@ ;; bytes-string inputs => byte results (test result regexp-match (bytes->string/utf-8 pattern) input)] [else ; pattern == rx literal - ;; TODO: result is always strings for now - ;; bc js cannot differentiate between literal regexps and byte-regexps (test result regexp-match pattern (bytes->string/utf-8 input))]) - ;; (test result regexp-match (bytes-append #"(?:" pattern #")") input) - ;; (test result regexp-match (bytes-append #"(?:(?:" pattern #"))") input) - ;; (test (and result (cons (car result) result)) - ;; regexp-match (bytes-append #"(?:(" pattern #"))") input) - ;; (test result regexp-match (bytes-append #"(?:)" pattern #"") input) - ;; (test result regexp-match (bytes-append #"(?<=)" pattern #"") input) - ;; (test result regexp-match (bytes-append #"(?:^|(?<=.))" pattern #"") input) - ;; (test result regexp-match (bytes-append #"" pattern #"(?=)") input) - ;; (test result regexp-match (bytes-append #"" pattern #"(?:$|(?=.))") input) - ;; (test (and result (cons (car result) result)) - ;; regexp-match (byte-pregexp (bytes-append #"(?=(" pattern #"))\\1")) input) + (test result regexp-match (bytes-append #"(?:" pattern #")") input) + (test result regexp-match (bytes-append #"(?:(?:" pattern #"))") input) + (test (and result (cons (car result) result)) + regexp-match (bytes-append #"(?:(" pattern #"))") input) + (test result regexp-match (bytes-append #"(?:)" pattern #"") input) + (test result regexp-match (bytes-append #"(?<=)" pattern #"") input) + (test result regexp-match (bytes-append #"(?:^|(?<=.))" pattern #"") input) + (test result regexp-match (bytes-append #"" pattern #"(?=)") input) + (test result regexp-match (bytes-append #"" pattern #"(?:$|(?=.))") input) + (test (and result (cons (car result) result)) + regexp-match (byte-pregexp (bytes-append #"(?=(" pattern #"))\\1")) input) + ;; invalid JS Regexp: "Invalid group" ;; (test result regexp-match (bytes-append #"(?>" pattern #")") input) ) ;; For when adding "x"s to the beginning and end shouldn't change the result: (define (test-regexp-x result pattern input) (test-regexp result pattern input) -; (test-regexp result pattern (bytes-append #"xxx" input #"xxx")) + (test-regexp result pattern (bytes-append #"xxx" input #"xxx")) ) (test-regexp-x '(#"a") #"a" #"abc") @@ -147,10 +146,11 @@ (test-regexp '(#"d") #"q?[ad]" #"d") (test-regexp #f #"q?[ad]" #"c") -;; (test '(#"a") regexp-match #rx#"^[^\0]" #"aaa\0") -;; (test #f regexp-match #rx#"^[^\0]" #"\0aaa\0") -;; (test '(#"aaa") regexp-match #rx#"^[^\0]*" #"aaa\0") +(test '(#"a") regexp-match #rx#"^[^\0]" #"aaa\0") +(test #f regexp-match #rx#"^[^\0]" #"\0aaa\0") +(test '(#"aaa") regexp-match #rx#"^[^\0]*" #"aaa\0") +;; this is testing err msg, but they will be different since we use js Regexp ;; (map (lambda (t) ;; (err/rt-test (byte-pregexp t)) ;; (err/rt-test (pregexp t))) @@ -270,161 +270,165 @@ ;; sigmas lambdas)) ;; sigmas)) -;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; Most of the following tests are derived from "testinput" in -;; ;; CL-PPCRE, which probably is from Perl originally. -;; ;; The tests have been modified to avoid various incompatibilities. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Most of the following tests are derived from "testinput" in +;; CL-PPCRE, which probably is from Perl originally. +;; The tests have been modified to avoid various incompatibilities. -;; (define (make-reluctant-port bstr) -;; ;; Handing out a single character at a time stresses -;; ;; the regexp matcher's lazy reading of a port: -;; (define pos 0) -;; (define len (bytes-length bstr)) -;; (make-input-port -;; 'reluctant-bytes -;; (lambda (s) -;; (if (pos . >= . len) -;; eof -;; (begin -;; (bytes-set! s 0 (bytes-ref bstr pos)) -;; (set! pos (add1 pos)) -;; 1))) -;; (lambda (s skip evt) -;; (if ((+ pos skip) . >= . len) -;; eof -;; (begin -;; (bytes-set! s 0 (bytes-ref bstr (+ pos skip))) -;; 1))) -;; void)) +(define (make-reluctant-port bstr) + ;; Handing out a single character at a time stresses + ;; the regexp matcher's lazy reading of a port: + (define pos 0) + (define len (bytes-length bstr)) + (make-input-port + 'reluctant-bytes + (lambda (s) + (if (pos . >= . len) + eof + (begin + (bytes-set! s 0 (bytes-ref bstr pos)) + (set! pos (add1 pos)) + 1))) + (lambda (s skip evt) + (if ((+ pos skip) . >= . len) + eof + (begin + (bytes-set! s 0 (bytes-ref bstr (+ pos skip))) + 1))) + void)) -;; (map (lambda (t) -;; (if (pair? t) -;; (begin -;; (test (caddr t) regexp-match (byte-pregexp (car t)) (cadr t)) -;; (test (caddr t) regexp-match (byte-pregexp (car t)) (bytes-append #"xxxxxxxxxx" (cadr t)) 10) -;; (test (caddr t) regexp-match (byte-pregexp (car t)) (bytes-append (cadr t) #"xxxxxxxxxx") 0 (bytes-length (cadr t))) -;; (test (caddr t) regexp-match (byte-pregexp (car t)) (open-input-bytes (cadr t))) -;; (test (caddr t) regexp-match (byte-pregexp (car t)) (make-reluctant-port (cadr t))) -;; (test (and (caddr t) -;; (map (lambda (v) -;; (and v (bytes->string/latin-1 v))) -;; (caddr t))) -;; regexp-match -;; (pregexp (bytes->string/latin-1 (car t))) -;; (bytes->string/latin-1 (cadr t))) -;; (test (and (caddr t) -;; (map (lambda (v) -;; (and v (string->bytes/utf-8 (bytes->string/latin-1 v)))) -;; (caddr t))) -;; regexp-match -;; (pregexp (bytes->string/latin-1 (car t))) -;; (open-input-string (bytes->string/latin-1 (cadr t))))) -;; (begin -;; (err/rt-test (byte-pregexp t)) -;; (err/rt-test (pregexp (bytes->string/latin-1 t)))))) -;; '(#"}" +(map (lambda (t) + (if (pair? t) + (begin + (test (caddr t) regexp-match (byte-pregexp (car t)) (cadr t)) + (test (caddr t) regexp-match (byte-pregexp (car t)) (bytes-append #"xxxxxxxxxx" (cadr t)) 10) + (test (caddr t) regexp-match (byte-pregexp (car t)) (bytes-append (cadr t) #"xxxxxxxxxx") 0 (bytes-length (cadr t))) + ;; (test (caddr t) regexp-match (byte-pregexp (car t)) (open-input-bytes (cadr t))) + ;; (test (caddr t) regexp-match (byte-pregexp (car t)) (make-reluctant-port (cadr t))) + ;; (test (and (caddr t) + ;; (map (lambda (v) + ;; (and v (bytes->string/latin-1 v))) + ;; (caddr t))) + ;; regexp-match + ;; (pregexp (bytes->string/latin-1 (car t))) + ;; (bytes->string/latin-1 (cadr t))) + ;; (test (and (caddr t) + ;; (map (lambda (v) + ;; (and v (string->bytes/utf-8 (bytes->string/latin-1 v)))) + ;; (caddr t))) + ;; regexp-match + ;; (pregexp (bytes->string/latin-1 (car t))) + ;; (open-input-string (bytes->string/latin-1 (cadr t)))) + ) + ;; err cases, dont test these + (begin + (err/rt-test (byte-pregexp t)) + (err/rt-test (pregexp (bytes->string/latin-1 t))) + ))) + '(;#"}" ;; #"]" ;; #"[a[:alph:]b]" -;; (#"the quick brown fox" #"the quick brown fox" (#"the quick brown fox")) -;; (#"the quick brown fox" #"The quick brown FOX" #f) -;; (#"the quick brown fox" #"What do you know about the quick brown fox?" (#"the quick brown fox")) -;; (#"the quick brown fox" #"What do you know about THE QUICK BROWN FOX?" #f) + (#"the quick brown fox" #"the quick brown fox" (#"the quick brown fox")) + (#"the quick brown fox" #"The quick brown FOX" #f) + (#"the quick brown fox" #"What do you know about the quick brown fox?" (#"the quick brown fox")) + (#"the quick brown fox" #"What do you know about THE QUICK BROWN FOX?" #f) +;; SyntaxError: Invalid regular expression: /(?i:The quick brown fox)/: Invalid group ;; (#"(?i:The quick brown fox)" #"the quick brown fox" (#"the quick brown fox")) ;; (#"(?i:The quick brown fox)" #"The quick brown FOX" (#"The quick brown FOX")) ;; (#"(?i:The quick brown fox)" #"What do you know about the quick brown fox?" (#"the quick brown fox")) ;; (#"(?i:The quick brown fox)" #"What do you know about THE QUICK BROWN FOX?" (#"THE QUICK BROWN FOX")) -;; (#"abcd\t\n\r\f\a\e\071\x3b\\$\\\\\\?caxyz" #"abcd\t\n\r\f\a\e9;$\\?caxyz" (#"abcd\t\n\r\f\a\e9;$\\?caxyz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabbxyyyypqAzz" (#"abxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabbxyyyypqAzz" (#"abxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabxyzpqrrrabbxyyyypqAzz" (#"aabxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabxyzpqrrrabbxyyyypqAzz" (#"aaabxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabxyzpqrrrabbxyyyypqAzz" (#"aaaabxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abcxyzpqrrrabbxyyyypqAzz" (#"abcxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabcxyzpqrrrabbxyyyypqAzz" (#"aabcxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypAzz" (#"aaabcxyzpqrrrabbxyyyypAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqAzz" (#"aaabcxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqqqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzpqrrrabbxyyyypqAzz" (#"aaaabcxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzzpqrrrabbxyyyypqAzz" (#"abxyzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabxyzzzpqrrrabbxyyyypqAzz" (#"aabxyzzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabxyzzzzpqrrrabbxyyyypqAzz" (#"aaabxyzzzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabxyzzzzpqrrrabbxyyyypqAzz" (#"aaaabxyzzzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abcxyzzpqrrrabbxyyyypqAzz" (#"abcxyzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabcxyzzzpqrrrabbxyyyypqAzz" (#"aabcxyzzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzzzzpqrrrabbxyyyypqAzz" (#"aaabcxyzzzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbxyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbbxyyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypABzz" (#"aaabcxyzpqrrrabbxyyyypABzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypABBzz" (#"aaabcxyzpqrrrabbxyyyypABBzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">>>aaabxyzpqrrrabbxyyyypqAzz" (#"aaabxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">aaaabxyzpqrrrabbxyyyypqAzz" (#"aaaabxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">>>>abcxyzpqrrrabbxyyyypqAzz" (#"abcxyzpqrrrabbxyyyypqAzz")) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrabbxyyyypqAzz" #f) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrrabbxyyyypqAzz" #f) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabxyyyypqAzz" #f) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz" #f) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyypqAzz" #f) -;; (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz" #f) -;; (#"^(abc){1,2}zz" #"abczz" (#"abczz" #"abc")) -;; (#"^(abc){1,2}zz" #"abcabczz" (#"abcabczz" #"abc")) -;; (#"^(abc){1,2}zz" #"zz" #f) -;; (#"^(abc){1,2}zz" #"abcabcabczz" #f) -;; (#"^(abc){1,2}zz" #">>abczz" #f) -;; (#"^(b+?|a){1,2}?c" #"bc" (#"bc" #"b")) -;; (#"^(b+?|a){1,2}?c" #"bbc" (#"bbc" #"b")) -;; (#"^(b+?|a){1,2}?c" #"bbbc" (#"bbbc" #"bb")) -;; (#"^(b+?|a){1,2}?c" #"bac" (#"bac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"bbac" (#"bbac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"aac" (#"aac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"abbbbbbbbbbbc" (#"abbbbbbbbbbbc" #"bbbbbbbbbbb")) -;; (#"^(b+?|a){1,2}?c" #"bbbbbbbbbbbac" (#"bbbbbbbbbbbac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"aaac" #f) -;; (#"^(b+?|a){1,2}?c" #"abbbbbbbbbbbac" #f) -;; (#"^(b+|a){1,2}c" #"bc" (#"bc" #"b")) -;; (#"^(b+|a){1,2}c" #"bbc" (#"bbc" #"bb")) -;; (#"^(b+|a){1,2}c" #"bbbc" (#"bbbc" #"bbb")) -;; (#"^(b+|a){1,2}c" #"bac" (#"bac" #"a")) -;; (#"^(b+|a){1,2}c" #"bbac" (#"bbac" #"a")) -;; (#"^(b+|a){1,2}c" #"aac" (#"aac" #"a")) -;; (#"^(b+|a){1,2}c" #"abbbbbbbbbbbc" (#"abbbbbbbbbbbc" #"bbbbbbbbbbb")) -;; (#"^(b+|a){1,2}c" #"bbbbbbbbbbbac" (#"bbbbbbbbbbbac" #"a")) -;; (#"^(b+|a){1,2}c" #"aaac" #f) -;; (#"^(b+|a){1,2}c" #"abbbbbbbbbbbac" #f) -;; (#"^(b+|a){1,2}?bc" #"bbc" (#"bbc" #"b")) + (#"abcd\t\n\r\f\a\e\071\x3b\\$\\\\\\?caxyz" #"abcd\t\n\r\f\a\e9;$\\?caxyz" (#"abcd\t\n\r\f\a\e9;$\\?caxyz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabbxyyyypqAzz" (#"abxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabbxyyyypqAzz" (#"abxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabxyzpqrrrabbxyyyypqAzz" (#"aabxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabxyzpqrrrabbxyyyypqAzz" (#"aaabxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabxyzpqrrrabbxyyyypqAzz" (#"aaaabxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abcxyzpqrrrabbxyyyypqAzz" (#"abcxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabcxyzpqrrrabbxyyyypqAzz" (#"aabcxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypAzz" (#"aaabcxyzpqrrrabbxyyyypAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqAzz" (#"aaabcxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqqAzz" (#"aaabcxyzpqrrrabbxyyyypqqqqqqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzpqrrrabbxyyyypqAzz" (#"aaaabcxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzzpqrrrabbxyyyypqAzz" (#"abxyzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabxyzzzpqrrrabbxyyyypqAzz" (#"aabxyzzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabxyzzzzpqrrrabbxyyyypqAzz" (#"aaabxyzzzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabxyzzzzpqrrrabbxyyyypqAzz" (#"aaaabxyzzzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abcxyzzpqrrrabbxyyyypqAzz" (#"abcxyzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aabcxyzzzpqrrrabbxyyyypqAzz" (#"aabcxyzzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzzzzpqrrrabbxyyyypqAzz" (#"aaabcxyzzzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbxyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyyypqAzz" (#"aaaabcxyzzzzpqrrrabbbxyyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypABzz" (#"aaabcxyzpqrrrabbxyyyypABzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypABBzz" (#"aaabcxyzpqrrrabbxyyyypABBzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">>>aaabxyzpqrrrabbxyyyypqAzz" (#"aaabxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">aaaabxyzpqrrrabbxyyyypqAzz" (#"aaaabxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #">>>>abcxyzpqrrrabbxyyyypqAzz" (#"abcxyzpqrrrabbxyyyypqAzz")) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrabbxyyyypqAzz" #f) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrrabbxyyyypqAzz" #f) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"abxyzpqrrrabxyyyypqAzz" #f) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz" #f) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaaabcxyzzzzpqrrrabbbxyyypqAzz" #f) + (#"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" #"aaabcxyzpqrrrabbxyyyypqqqqqqqAzz" #f) + (#"^(abc){1,2}zz" #"abczz" (#"abczz" #"abc")) + (#"^(abc){1,2}zz" #"abcabczz" (#"abcabczz" #"abc")) + (#"^(abc){1,2}zz" #"zz" #f) + (#"^(abc){1,2}zz" #"abcabcabczz" #f) + (#"^(abc){1,2}zz" #">>abczz" #f) + (#"^(b+?|a){1,2}?c" #"bc" (#"bc" #"b")) + (#"^(b+?|a){1,2}?c" #"bbc" (#"bbc" #"b")) + (#"^(b+?|a){1,2}?c" #"bbbc" (#"bbbc" #"bb")) + (#"^(b+?|a){1,2}?c" #"bac" (#"bac" #"a")) + (#"^(b+?|a){1,2}?c" #"bbac" (#"bbac" #"a")) + (#"^(b+?|a){1,2}?c" #"aac" (#"aac" #"a")) + (#"^(b+?|a){1,2}?c" #"abbbbbbbbbbbc" (#"abbbbbbbbbbbc" #"bbbbbbbbbbb")) + (#"^(b+?|a){1,2}?c" #"bbbbbbbbbbbac" (#"bbbbbbbbbbbac" #"a")) + (#"^(b+?|a){1,2}?c" #"aaac" #f) + (#"^(b+?|a){1,2}?c" #"abbbbbbbbbbbac" #f) + (#"^(b+|a){1,2}c" #"bc" (#"bc" #"b")) + (#"^(b+|a){1,2}c" #"bbc" (#"bbc" #"bb")) + (#"^(b+|a){1,2}c" #"bbbc" (#"bbbc" #"bbb")) + (#"^(b+|a){1,2}c" #"bac" (#"bac" #"a")) + (#"^(b+|a){1,2}c" #"bbac" (#"bbac" #"a")) + (#"^(b+|a){1,2}c" #"aac" (#"aac" #"a")) + (#"^(b+|a){1,2}c" #"abbbbbbbbbbbc" (#"abbbbbbbbbbbc" #"bbbbbbbbbbb")) + (#"^(b+|a){1,2}c" #"bbbbbbbbbbbac" (#"bbbbbbbbbbbac" #"a")) + (#"^(b+|a){1,2}c" #"aaac" #f) + (#"^(b+|a){1,2}c" #"abbbbbbbbbbbac" #f) + (#"^(b+|a){1,2}?bc" #"bbc" (#"bbc" #"b")) ;; #"^(b*|ba){1,2}?bc" -;; (#"(.)c|ad" #"ad" (#"ad" #f)) -;; (#"(a)c|ad" #"ad" (#"ad" #f)) -;; (#"(?<=(a))c|d" #"ad" (#"d" #f)) -;; (#"(?=(a))ac|ad" #"ad" (#"ad" #f)) -;; (#"^[ab\\]cde]" #"athing" (#"a")) -;; (#"^[ab\\]cde]" #"bthing" (#"b")) -;; (#"^[ab\\]cde]" #"]thing" (#"]")) -;; (#"^[ab\\]cde]" #"cthing" (#"c")) -;; (#"^[ab\\]cde]" #"dthing" (#"d")) -;; (#"^[ab\\]cde]" #"ething" (#"e")) -;; (#"^[ab\\]cde]" #"fthing" #f) -;; (#"^[ab\\]cde]" #"[thing" #f) -;; (#"^[ab\\]cde]" #"\\\\thing" #f) + (#"(.)c|ad" #"ad" (#"ad" #f)) + (#"(a)c|ad" #"ad" (#"ad" #f)) + (#"(?<=(a))c|d" #"ad" (#"d" #f)) + (#"(?=(a))ac|ad" #"ad" (#"ad" #f)) + (#"^[ab\\]cde]" #"athing" (#"a")) + (#"^[ab\\]cde]" #"bthing" (#"b")) + (#"^[ab\\]cde]" #"]thing" (#"]")) + (#"^[ab\\]cde]" #"cthing" (#"c")) + (#"^[ab\\]cde]" #"dthing" (#"d")) + (#"^[ab\\]cde]" #"ething" (#"e")) + (#"^[ab\\]cde]" #"fthing" #f) + (#"^[ab\\]cde]" #"[thing" #f) + (#"^[ab\\]cde]" #"\\\\thing" #f) ;; (#"^[]cde]" #"]thing" (#"]")) ;; (#"^[]cde]" #"cthing" (#"c")) ;; (#"^[]cde]" #"dthing" (#"d")) ;; (#"^[]cde]" #"ething" (#"e")) -;; (#"^[]cde]" #"athing" #f) -;; (#"^[]cde]" #"fthing" #f) -;; (#"^[^ab\\]cde]" #"fthing" (#"f")) -;; (#"^[^ab\\]cde]" #"[thing" (#"[")) -;; (#"^[^ab\\]cde]" #"\\\\thing" (#"\\")) -;; (#"^[^ab\\]cde]" #"athing" #f) -;; (#"^[^ab\\]cde]" #"bthing" #f) -;; (#"^[^ab\\]cde]" #"]thing" #f) -;; (#"^[^ab\\]cde]" #"cthing" #f) -;; (#"^[^ab\\]cde]" #"dthing" #f) -;; (#"^[^ab\\]cde]" #"ething" #f) + (#"^[]cde]" #"athing" #f) + (#"^[]cde]" #"fthing" #f) + (#"^[^ab\\]cde]" #"fthing" (#"f")) + (#"^[^ab\\]cde]" #"[thing" (#"[")) + (#"^[^ab\\]cde]" #"\\\\thing" (#"\\")) + (#"^[^ab\\]cde]" #"athing" #f) + (#"^[^ab\\]cde]" #"bthing" #f) + (#"^[^ab\\]cde]" #"]thing" #f) + (#"^[^ab\\]cde]" #"cthing" #f) + (#"^[^ab\\]cde]" #"dthing" #f) + (#"^[^ab\\]cde]" #"ething" #f) ;; (#"^[^]cde]" #"athing" (#"a")) ;; (#"^[^]cde]" #"fthing" (#"f")) ;; (#"^[^]cde]" #"]thing" #f) @@ -433,42 +437,43 @@ ;; (#"^[^]cde]" #"ething" #f) ;; (#"^\\\201" #"\201" (#"\201")) ;; (#"^\377" #"\377" (#"\377")) -;; (#"^[0-9]+$" #"0" (#"0")) -;; (#"^[0-9]+$" #"1" (#"1")) -;; (#"^[0-9]+$" #"2" (#"2")) -;; (#"^[0-9]+$" #"3" (#"3")) -;; (#"^[0-9]+$" #"4" (#"4")) -;; (#"^[0-9]+$" #"5" (#"5")) -;; (#"^[0-9]+$" #"6" (#"6")) -;; (#"^[0-9]+$" #"7" (#"7")) -;; (#"^[0-9]+$" #"8" (#"8")) -;; (#"^[0-9]+$" #"9" (#"9")) -;; (#"^[0-9]+$" #"10" (#"10")) -;; (#"^[0-9]+$" #"100" (#"100")) -;; (#"^[0-9]+$" #"abc" #f) -;; (#"^.*nter" #"enter" (#"enter")) -;; (#"^.*nter" #"inter" (#"inter")) -;; (#"^.*nter" #"uponter" (#"uponter")) -;; (#"^xxx[0-9]+$" #"xxx0" (#"xxx0")) -;; (#"^xxx[0-9]+$" #"xxx1234" (#"xxx1234")) -;; (#"^xxx[0-9]+$" #"xxx" #f) -;; (#"^.+[0-9][0-9][0-9]$" #"x123" (#"x123")) -;; (#"^.+[0-9][0-9][0-9]$" #"xx123" (#"xx123")) -;; (#"^.+[0-9][0-9][0-9]$" #"123456" (#"123456")) -;; (#"^.+[0-9][0-9][0-9]$" #"123" #f) -;; (#"^.+[0-9][0-9][0-9]$" #"x1234" (#"x1234")) -;; (#"^.+?[0-9][0-9][0-9]$" #"x123" (#"x123")) -;; (#"^.+?[0-9][0-9][0-9]$" #"xx123" (#"xx123")) -;; (#"^.+?[0-9][0-9][0-9]$" #"123456" (#"123456")) -;; (#"^.+?[0-9][0-9][0-9]$" #"123" #f) -;; (#"^.+?[0-9][0-9][0-9]$" #"x1234" (#"x1234")) -;; (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz.ixr.zzz.ac.uk" (#"abc!pqr=apquxz.ixr.zzz.ac.uk" #"abc" #"pqr")) -;; (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"!pqr=apquxz.ixr.zzz.ac.uk" #f) -;; (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!=apquxz.ixr.zzz.ac.uk" #f) -;; (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz:ixr.zzz.ac.uk" #f) -;; (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz.ixr.zzz.ac.ukk" #f) -;; (#":" #"Well, we need a colon: somewhere" (#":")) -;; (#":" #"Fail if we don't" #f) + (#"^[0-9]+$" #"0" (#"0")) + (#"^[0-9]+$" #"1" (#"1")) + (#"^[0-9]+$" #"2" (#"2")) + (#"^[0-9]+$" #"3" (#"3")) + (#"^[0-9]+$" #"4" (#"4")) + (#"^[0-9]+$" #"5" (#"5")) + (#"^[0-9]+$" #"6" (#"6")) + (#"^[0-9]+$" #"7" (#"7")) + (#"^[0-9]+$" #"8" (#"8")) + (#"^[0-9]+$" #"9" (#"9")) + (#"^[0-9]+$" #"10" (#"10")) + (#"^[0-9]+$" #"100" (#"100")) + (#"^[0-9]+$" #"abc" #f) + (#"^.*nter" #"enter" (#"enter")) + (#"^.*nter" #"inter" (#"inter")) + (#"^.*nter" #"uponter" (#"uponter")) + (#"^xxx[0-9]+$" #"xxx0" (#"xxx0")) + (#"^xxx[0-9]+$" #"xxx1234" (#"xxx1234")) + (#"^xxx[0-9]+$" #"xxx" #f) + (#"^.+[0-9][0-9][0-9]$" #"x123" (#"x123")) + (#"^.+[0-9][0-9][0-9]$" #"xx123" (#"xx123")) + (#"^.+[0-9][0-9][0-9]$" #"123456" (#"123456")) + (#"^.+[0-9][0-9][0-9]$" #"123" #f) + (#"^.+[0-9][0-9][0-9]$" #"x1234" (#"x1234")) + (#"^.+?[0-9][0-9][0-9]$" #"x123" (#"x123")) + (#"^.+?[0-9][0-9][0-9]$" #"xx123" (#"xx123")) + (#"^.+?[0-9][0-9][0-9]$" #"123456" (#"123456")) + (#"^.+?[0-9][0-9][0-9]$" #"123" #f) + (#"^.+?[0-9][0-9][0-9]$" #"x1234" (#"x1234")) + (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz.ixr.zzz.ac.uk" (#"abc!pqr=apquxz.ixr.zzz.ac.uk" #"abc" #"pqr")) + (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"!pqr=apquxz.ixr.zzz.ac.uk" #f) + (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!=apquxz.ixr.zzz.ac.uk" #f) + (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz:ixr.zzz.ac.uk" #f) + (#"^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" #"abc!pqr=apquxz.ixr.zzz.ac.ukk" #f) + (#":" #"Well, we need a colon: somewhere" (#":")) + (#":" #"Fail if we don't" #f) +;; SyntaxError: Invalid regular expression: /(?i:([\da-f:]+)$)/: Invalid group ;; (#"(?i:([\\da-f:]+)$)" #"0abc" (#"0abc" #"0abc")) ;; (#"(?i:([\\da-f:]+)$)" #"abc" (#"abc" #"abc")) ;; (#"(?i:([\\da-f:]+)$)" #"fed" (#"fed" #"fed")) @@ -481,130 +486,131 @@ ;; (#"(?i:([\\da-f:]+)$)" #"gzzz" #f) ;; (#"(?i:([\\da-f:]+)$)" #"fed\\x20" (#"20" #"20")) ;; (#"(?i:([\\da-f:]+)$)" #"Any old rubbish" #f) -;; (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #".1.2.3" (#".1.2.3" #"1" #"2" #"3")) -;; (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"A.12.123.0" (#"A.12.123.0" #"12" #"123" #"0")) -;; (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #".1.2.3333" #f) -;; (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"1.2.3" #f) -;; (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"1234.2.3" #f) -;; (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1 IN SOA non-sp1 non-sp2(" (#"1 IN SOA non-sp1 non-sp2(" #"1" #"non-sp1" #"non-sp2")) -;; (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1 IN SOA non-sp1 non-sp2 (" (#"1 IN SOA non-sp1 non-sp2 (" #"1" #"non-sp1" #"non-sp2")) -;; (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1IN SOA non-sp1 non-sp2(" #f) -;; (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"a." (#"a." #f)) -;; (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"Z." (#"Z." #f)) -;; (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"2." (#"2." #f)) -;; (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"ab-c.pq-r." (#"ab-c.pq-r." #".pq-r")) -;; (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"sxk.zzz.ac.uk." (#"sxk.zzz.ac.uk." #".uk")) -;; (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"x-.y-." (#"x-.y-." #".y-")) -;; (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"-abc.peq." #f) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a" (#"*.a" #f #f #f)) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.b0-a" (#"*.b0-a" #"0-a" #f #f)) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c3-b.c" (#"*.c3-b.c" #"3-b" #".c" #f)) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c-a.b-c" (#"*.c-a.b-c" #"-a" #".b-c" #"-c")) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.0" #f) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a-" #f) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a-b.c-" #f) -;; (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c-a.0-c" #f) -;; (#"^(?=ab(de))(abd)(e)" #"abde" (#"abde" #"de" #"abd" #"e")) -;; (#"^(?!(ab)de|x)(abd)(f)" #"abdf" (#"abdf" #f #"abd" #"f")) -;; (#"^(?=(ab(cd)))(ab)" #"abcd" (#"ab" #"abcd" #"cd" #"ab")) + (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #".1.2.3" (#".1.2.3" #"1" #"2" #"3")) + (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"A.12.123.0" (#"A.12.123.0" #"12" #"123" #"0")) + (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #".1.2.3333" #f) + (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"1.2.3" #f) + (#"^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" #"1234.2.3" #f) + (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1 IN SOA non-sp1 non-sp2(" (#"1 IN SOA non-sp1 non-sp2(" #"1" #"non-sp1" #"non-sp2")) + (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1 IN SOA non-sp1 non-sp2 (" (#"1 IN SOA non-sp1 non-sp2 (" #"1" #"non-sp1" #"non-sp2")) + (#"^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" #"1IN SOA non-sp1 non-sp2(" #f) + (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"a." (#"a." #f)) + (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"Z." (#"Z." #f)) + (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"2." (#"2." #f)) + (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"ab-c.pq-r." (#"ab-c.pq-r." #".pq-r")) + (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"sxk.zzz.ac.uk." (#"sxk.zzz.ac.uk." #".uk")) + (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"x-.y-." (#"x-.y-." #".y-")) + (#"^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-Z\\d\\-]*)*\\.$" #"-abc.peq." #f) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a" (#"*.a" #f #f #f)) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.b0-a" (#"*.b0-a" #"0-a" #f #f)) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c3-b.c" (#"*.c3-b.c" #"3-b" #".c" #f)) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c-a.b-c" (#"*.c-a.b-c" #"-a" #".b-c" #"-c")) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.0" #f) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a-" #f) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.a-b.c-" #f) + (#"^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" #"*.c-a.0-c" #f) + (#"^(?=ab(de))(abd)(e)" #"abde" (#"abde" #"de" #"abd" #"e")) + (#"^(?!(ab)de|x)(abd)(f)" #"abdf" (#"abdf" #f #"abd" #"f")) + (#"^(?=(ab(cd)))(ab)" #"abcd" (#"ab" #"abcd" #"cd" #"ab")) +;; SyntaxError: Invalid regular expression: /(?i:^[\da-f](\.[\da-f])*$)/: Invalid group ;; (#"(?i:^[\\da-f](\\.[\\da-f])*$)" #"a.b.c.d" (#"a.b.c.d" #".d")) ;; (#"(?i:^[\\da-f](\\.[\\da-f])*$)" #"A.B.C.D" (#"A.B.C.D" #".D")) ;; (#"(?i:^[\\da-f](\\.[\\da-f])*$)" #"a.b.c.1.2.3.C" (#"a.b.c.1.2.3.C" #".C")) -;; (#"^\\\".*\\\"\\s*(;.*)?$" #"\"1234\"" (#"\"1234\"" #f)) -;; (#"^\\\".*\\\"\\s*(;.*)?$" #"\"abcd\" ;" (#"\"abcd\" ;" #";")) -;; (#"^\\\".*\\\"\\s*(;.*)?$" #"\"\" ; rhubarb" (#"\"\" ; rhubarb" #"; rhubarb")) -;; (#"^\\\".*\\\"\\s*(;.*)?$" #"\"1234\" : things" #f) -;; (#"^$" #"\\" #f) -;; (#"^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$" #"abcdefhijklm" (#"abcdefhijklm" #"abc" #"bc" #"c" #"def" #"ef" #"f" #"hij" #"ij" #"j" #"klm" #"lm" #"m")) -;; (#"^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$" #"abcdefhijklm" (#"abcdefhijklm" #"bc" #"c" #"ef" #"f" #"ij" #"j" #"lm" #"m")) -;; ; (#"^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]" #"a+ Z0+\\x08\\n\\x1d\\x12" #f) -;; (#"^[.^$|()*+?{,}]+" #".^\\$(*+)|{?,?}" (#".^")) -;; (#"^a*\\w" #"z" (#"z")) -;; (#"^a*\\w" #"az" (#"az")) -;; (#"^a*\\w" #"aaaz" (#"aaaz")) -;; (#"^a*\\w" #"a" (#"a")) -;; (#"^a*\\w" #"aa" (#"aa")) -;; (#"^a*\\w" #"aaaa" (#"aaaa")) -;; (#"^a*\\w" #"a+" (#"a")) -;; (#"^a*\\w" #"aa+" (#"aa")) -;; (#"^a*?\\w" #"z" (#"z")) -;; (#"^a*?\\w" #"az" (#"a")) -;; (#"^a*?\\w" #"aaaz" (#"a")) -;; (#"^a*?\\w" #"a" (#"a")) -;; (#"^a*?\\w" #"aa" (#"a")) -;; (#"^a*?\\w" #"aaaa" (#"a")) -;; (#"^a*?\\w" #"a+" (#"a")) -;; (#"^a*?\\w" #"aa+" (#"a")) -;; (#"^a+\\w" #"az" (#"az")) -;; (#"^a+\\w" #"aaaz" (#"aaaz")) -;; (#"^a+\\w" #"aa" (#"aa")) -;; (#"^a+\\w" #"aaaa" (#"aaaa")) -;; (#"^a+\\w" #"aa+" (#"aa")) -;; (#"^a+?\\w" #"az" (#"az")) -;; (#"^a+?\\w" #"aaaz" (#"aa")) -;; (#"^a+?\\w" #"aa" (#"aa")) -;; (#"^a+?\\w" #"aaaa" (#"aa")) -;; (#"^a+?\\w" #"aa+" (#"aa")) -;; (#"^\\d{8}\\w{2,}" #"1234567890" (#"1234567890")) -;; (#"^\\d{8}\\w{2,}" #"12345678ab" (#"12345678ab")) -;; (#"^\\d{8}\\w{2,}" #"12345678__" (#"12345678__")) -;; (#"^\\d{8}\\w{2,}" #"1234567" #f) -;; (#"^[aeiou\\d]{4,5}$" #"uoie" (#"uoie")) -;; (#"^[aeiou\\d]{4,5}$" #"1234" (#"1234")) -;; (#"^[aeiou\\d]{4,5}$" #"12345" (#"12345")) -;; (#"^[aeiou\\d]{4,5}$" #"aaaaa" (#"aaaaa")) -;; (#"^[aeiou\\d]{4,5}$" #"123456" #f) -;; (#"^[aeiou\\d]{4,5}?" #"uoie" (#"uoie")) -;; (#"^[aeiou\\d]{4,5}?" #"1234" (#"1234")) -;; (#"^[aeiou\\d]{4,5}?" #"12345" (#"1234")) -;; (#"^[aeiou\\d]{4,5}?" #"aaaaa" (#"aaaa")) -;; (#"^[aeiou\\d]{4,5}?" #"123456" (#"1234")) -;; (#"^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\12$" #"abcdefghijkcda2" #f) -;; (#"^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\12$" #"abcdefghijkkkkcda2" #f) -;; (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"cataract cataract23" (#"cataract cataract23" #"cataract" #"aract" #"ract" #"" #"3")) -;; (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"catatonic catatonic23" (#"catatonic catatonic23" #"catatonic" #"atonic" #"tonic" #"" #"3")) -;; (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"caterpillar caterpillar23" (#"caterpillar caterpillar23" #"caterpillar" #"erpillar" #f #"" #"3")) -;; (#"^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]" #"From abcd Mon Sep 01 12:33:02 1997" (#"From abcd Mon Sep 01 12:33" #"abcd")) -;; (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd Mon Sep 01 12:33:02 1997" (#"From abcd Mon Sep 01 12:33" #"Sep ")) -;; (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd Mon Sep 1 12:33:02 1997" (#"From abcd Mon Sep 1 12:33" #"Sep ")) -;; (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd Sep 01 12:33:02 1997" #f) -;; (#"\\w+(?=\t)" #"the quick brown\\t fox" #f) -;; (#"foo(?!bar)(.*)" #"foobar is foolish see?" (#"foolish see?" #"lish see?")) -;; (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"foobar crowbar etc" (#"rowbar etc" #" etc")) -;; (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"barrel" (#"barrel" #"rel")) -;; (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"2barrel" (#"2barrel" #"rel")) -;; (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"A barrel" (#"A barrel" #"rel")) -;; (#"^(\\D*)(?=\\d)(?!123)" #"abc456" (#"abc" #"abc")) -;; (#"^(\\D*)(?=\\d)(?!123)" #"abc123" #f) -;; (#"^(a)\\1{2,3}(.)" #"aaab" (#"aaab" #"a" #"b")) -;; (#"^(a)\\1{2,3}(.)" #"aaaab" (#"aaaab" #"a" #"b")) -;; (#"^(a)\\1{2,3}(.)" #"aaaaab" (#"aaaaa" #"a" #"a")) -;; (#"^(a)\\1{2,3}(.)" #"aaaaaab" (#"aaaaa" #"a" #"a")) -;; (#"(?!^)abc" #"the abc" (#"abc")) -;; (#"(?!^)abc" #"abc" #f) -;; (#"(?=^)abc" #"abc" (#"abc")) -;; (#"(?=^)abc" #"the abc" #f) -;; (#"^[ab]{1,3}(ab*|b)" #"aabbbbb" (#"aabb" #"b")) -;; (#"^[ab]{1,3}?(ab*|b)" #"aabbbbb" (#"aabbbbb" #"abbbbb")) -;; (#"^[ab]{1,3}?(ab*?|b)" #"aabbbbb" (#"aa" #"a")) -;; (#"^[ab]{1,3}(ab*?|b)" #"aabbbbb" (#"aabb" #"b")) -;; #| -;; (#"abc\\0def\\00pqr\\000xyz\\0000AB" #"abc\\0def\\00pqr\\000xyz\\0000AB" #f) -;; (#"abc\\0def\\00pqr\\000xyz\\0000AB" #"abc456 abc\\0def\\00pqr\\000xyz\\0000ABCDE" #f) -;; (#"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #f) -;; (#"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #"abc456 abc\\x0def\\x00pqr\\x000xyz\\x0000ABCDE" #f) -;; (#"^[\\000-\\037]" #"\\0A" #f) -;; (#"^[\\000-\\037]" #"\\01B" #f) -;; (#"^[\\000-\\037]" #"\\037C" #f) -;; (#"\\0*" #"\\0\\0\\0\\0" #f) -;; (#"A\\x0{2,3}Z" #"The A\\x0\\x0Z" #f) -;; (#"A\\x0{2,3}Z" #"An A\\0\\x0\\0Z" #f) -;; (#"A\\x0{2,3}Z" #"A\\0Z" #f) -;; (#"A\\x0{2,3}Z" #"A\\0\\x0\\0\\x0Z" #f) -;; |# -;; (#"^(cow|)\\1(bell)" #"cowcowbell" (#"cowcowbell" #"cow" #"bell")) -;; (#"^(cow|)\\1(bell)" #"bell" (#"bell" #"" #"bell")) -;; (#"^(cow|)\\1(bell)" #"cowbell" #f) + (#"^\\\".*\\\"\\s*(;.*)?$" #"\"1234\"" (#"\"1234\"" #f)) + (#"^\\\".*\\\"\\s*(;.*)?$" #"\"abcd\" ;" (#"\"abcd\" ;" #";")) + (#"^\\\".*\\\"\\s*(;.*)?$" #"\"\" ; rhubarb" (#"\"\" ; rhubarb" #"; rhubarb")) + (#"^\\\".*\\\"\\s*(;.*)?$" #"\"1234\" : things" #f) + (#"^$" #"\\" #f) + (#"^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$" #"abcdefhijklm" (#"abcdefhijklm" #"abc" #"bc" #"c" #"def" #"ef" #"f" #"hij" #"ij" #"j" #"klm" #"lm" #"m")) + (#"^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$" #"abcdefhijklm" (#"abcdefhijklm" #"bc" #"c" #"ef" #"f" #"ij" #"j" #"lm" #"m")) +; (#"^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]" #"a+ Z0+\\x08\\n\\x1d\\x12" #f) + (#"^[.^$|()*+?{,}]+" #".^\\$(*+)|{?,?}" (#".^")) + (#"^a*\\w" #"z" (#"z")) + (#"^a*\\w" #"az" (#"az")) + (#"^a*\\w" #"aaaz" (#"aaaz")) + (#"^a*\\w" #"a" (#"a")) + (#"^a*\\w" #"aa" (#"aa")) + (#"^a*\\w" #"aaaa" (#"aaaa")) + (#"^a*\\w" #"a+" (#"a")) + (#"^a*\\w" #"aa+" (#"aa")) + (#"^a*?\\w" #"z" (#"z")) + (#"^a*?\\w" #"az" (#"a")) + (#"^a*?\\w" #"aaaz" (#"a")) + (#"^a*?\\w" #"a" (#"a")) + (#"^a*?\\w" #"aa" (#"a")) + (#"^a*?\\w" #"aaaa" (#"a")) + (#"^a*?\\w" #"a+" (#"a")) + (#"^a*?\\w" #"aa+" (#"a")) + (#"^a+\\w" #"az" (#"az")) + (#"^a+\\w" #"aaaz" (#"aaaz")) + (#"^a+\\w" #"aa" (#"aa")) + (#"^a+\\w" #"aaaa" (#"aaaa")) + (#"^a+\\w" #"aa+" (#"aa")) + (#"^a+?\\w" #"az" (#"az")) + (#"^a+?\\w" #"aaaz" (#"aa")) + (#"^a+?\\w" #"aa" (#"aa")) + (#"^a+?\\w" #"aaaa" (#"aa")) + (#"^a+?\\w" #"aa+" (#"aa")) + (#"^\\d{8}\\w{2,}" #"1234567890" (#"1234567890")) + (#"^\\d{8}\\w{2,}" #"12345678ab" (#"12345678ab")) + (#"^\\d{8}\\w{2,}" #"12345678__" (#"12345678__")) + (#"^\\d{8}\\w{2,}" #"1234567" #f) + (#"^[aeiou\\d]{4,5}$" #"uoie" (#"uoie")) + (#"^[aeiou\\d]{4,5}$" #"1234" (#"1234")) + (#"^[aeiou\\d]{4,5}$" #"12345" (#"12345")) + (#"^[aeiou\\d]{4,5}$" #"aaaaa" (#"aaaaa")) + (#"^[aeiou\\d]{4,5}$" #"123456" #f) + (#"^[aeiou\\d]{4,5}?" #"uoie" (#"uoie")) + (#"^[aeiou\\d]{4,5}?" #"1234" (#"1234")) + (#"^[aeiou\\d]{4,5}?" #"12345" (#"1234")) + (#"^[aeiou\\d]{4,5}?" #"aaaaa" (#"aaaa")) + (#"^[aeiou\\d]{4,5}?" #"123456" (#"1234")) + (#"^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\12$" #"abcdefghijkcda2" #f) + (#"^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\12$" #"abcdefghijkkkkcda2" #f) + (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"cataract cataract23" (#"cataract cataract23" #"cataract" #"aract" #"ract" #"" #"3")) + (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"catatonic catatonic23" (#"catatonic catatonic23" #"catatonic" #"atonic" #"tonic" #"" #"3")) + (#"(cat(a(ract|tonic)|erpillar)) \\1()2(3)" #"caterpillar caterpillar23" (#"caterpillar caterpillar23" #"caterpillar" #"erpillar" #f #"" #"3")) + (#"^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]" #"From abcd Mon Sep 01 12:33:02 1997" (#"From abcd Mon Sep 01 12:33" #"abcd")) + (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd Mon Sep 01 12:33:02 1997" (#"From abcd Mon Sep 01 12:33" #"Sep ")) + (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd Mon Sep 1 12:33:02 1997" (#"From abcd Mon Sep 1 12:33" #"Sep ")) + (#"^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" #"From abcd Sep 01 12:33:02 1997" #f) + (#"\\w+(?=\t)" #"the quick brown\\t fox" #f) + (#"foo(?!bar)(.*)" #"foobar is foolish see?" (#"foolish see?" #"lish see?")) + (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"foobar crowbar etc" (#"rowbar etc" #" etc")) + (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"barrel" (#"barrel" #"rel")) + (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"2barrel" (#"2barrel" #"rel")) + (#"(?:(?!foo)...|^.{0,2})bar(.*)" #"A barrel" (#"A barrel" #"rel")) + (#"^(\\D*)(?=\\d)(?!123)" #"abc456" (#"abc" #"abc")) + (#"^(\\D*)(?=\\d)(?!123)" #"abc123" #f) + (#"^(a)\\1{2,3}(.)" #"aaab" (#"aaab" #"a" #"b")) + (#"^(a)\\1{2,3}(.)" #"aaaab" (#"aaaab" #"a" #"b")) + (#"^(a)\\1{2,3}(.)" #"aaaaab" (#"aaaaa" #"a" #"a")) + (#"^(a)\\1{2,3}(.)" #"aaaaaab" (#"aaaaa" #"a" #"a")) + (#"(?!^)abc" #"the abc" (#"abc")) + (#"(?!^)abc" #"abc" #f) + (#"(?=^)abc" #"abc" (#"abc")) + (#"(?=^)abc" #"the abc" #f) + (#"^[ab]{1,3}(ab*|b)" #"aabbbbb" (#"aabb" #"b")) + (#"^[ab]{1,3}?(ab*|b)" #"aabbbbb" (#"aabbbbb" #"abbbbb")) + (#"^[ab]{1,3}?(ab*?|b)" #"aabbbbb" (#"aa" #"a")) + (#"^[ab]{1,3}(ab*?|b)" #"aabbbbb" (#"aabb" #"b")) +#| + (#"abc\\0def\\00pqr\\000xyz\\0000AB" #"abc\\0def\\00pqr\\000xyz\\0000AB" #f) + (#"abc\\0def\\00pqr\\000xyz\\0000AB" #"abc456 abc\\0def\\00pqr\\000xyz\\0000ABCDE" #f) + (#"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #f) + (#"abc\\x0def\\x00pqr\\x000xyz\\x0000AB" #"abc456 abc\\x0def\\x00pqr\\x000xyz\\x0000ABCDE" #f) + (#"^[\\000-\\037]" #"\\0A" #f) + (#"^[\\000-\\037]" #"\\01B" #f) + (#"^[\\000-\\037]" #"\\037C" #f) + (#"\\0*" #"\\0\\0\\0\\0" #f) + (#"A\\x0{2,3}Z" #"The A\\x0\\x0Z" #f) + (#"A\\x0{2,3}Z" #"An A\\0\\x0\\0Z" #f) + (#"A\\x0{2,3}Z" #"A\\0Z" #f) + (#"A\\x0{2,3}Z" #"A\\0\\x0\\0\\x0Z" #f) +|# + (#"^(cow|)\\1(bell)" #"cowcowbell" (#"cowcowbell" #"cow" #"bell")) + (#"^(cow|)\\1(bell)" #"bell" (#"bell" #"" #"bell")) + (#"^(cow|)\\1(bell)" #"cowbell" #f) ;; #| ;; (#"^\\s" #"\\040abc" #f) ;; (#"^\\s" #"\\x0cabc" #f) @@ -613,242 +619,244 @@ ;; (#"^\\s" #"\\tabc" #f) ;; (#"^\\s" #"abc" #f) ;; |# -;; (#"^(a|x)\\1*b" #"ab" (#"ab" #"a")) -;; (#"^(a|x)\\1*b" #"aaaab" (#"aaaab" #"a")) -;; (#"^(a|x)\\1*b" #"acb" #f) -;; (#"^(a|x)\\1+b" #"aab" (#"aab" #"a")) -;; (#"^(a|x)\\1+b" #"aaaab" (#"aaaab" #"a")) -;; (#"^(a|x)\\1+b" #"ab" #f) -;; (#"^(a|)\\1?b" #"ab" (#"ab" #"a")) -;; (#"^(a|)\\1?b" #"aab" (#"aab" #"a")) -;; (#"^(a|)\\1?b" #"b" (#"b" #"")) -;; (#"^(a|)\\1?b" #"acb" #f) + (#"^(a|x)\\1*b" #"ab" (#"ab" #"a")) + (#"^(a|x)\\1*b" #"aaaab" (#"aaaab" #"a")) + (#"^(a|x)\\1*b" #"acb" #f) + (#"^(a|x)\\1+b" #"aab" (#"aab" #"a")) + (#"^(a|x)\\1+b" #"aaaab" (#"aaaab" #"a")) + (#"^(a|x)\\1+b" #"ab" #f) + (#"^(a|)\\1?b" #"ab" (#"ab" #"a")) + (#"^(a|)\\1?b" #"aab" (#"aab" #"a")) + (#"^(a|)\\1?b" #"b" (#"b" #"")) + (#"^(a|)\\1?b" #"acb" #f) ;; #"^(a|)\\1{2}b" ;; #"^(a|)\\1{2,3}b" -;; (#"ab{1,3}bc" #"abbbbc" (#"abbbbc")) -;; (#"ab{1,3}bc" #"abbbc" (#"abbbc")) -;; (#"ab{1,3}bc" #"abbc" (#"abbc")) -;; (#"ab{1,3}bc" #"abc" #f) -;; (#"ab{1,3}bc" #"abbbbbc" #f) -;; (#"([^.]*)\\.([^:]*):[T ]+(.*)" #"track1.title:TBlah blah blah" (#"track1.title:TBlah blah blah" #"track1" #"title" #"Blah blah blah")) + (#"ab{1,3}bc" #"abbbbc" (#"abbbbc")) + (#"ab{1,3}bc" #"abbbc" (#"abbbc")) + (#"ab{1,3}bc" #"abbc" (#"abbc")) + (#"ab{1,3}bc" #"abc" #f) + (#"ab{1,3}bc" #"abbbbbc" #f) + (#"([^.]*)\\.([^:]*):[T ]+(.*)" #"track1.title:TBlah blah blah" (#"track1.title:TBlah blah blah" #"track1" #"title" #"Blah blah blah")) +;; SyntaxError: Invalid regular expression: /(?i:([^.]*)\.([^:]*):[T ]+(.*))/: Invalid group ;; (#"(?i:([^.]*)\\.([^:]*):[T ]+(.*))" #"track1.title:TBlah blah blah" (#"track1.title:TBlah blah blah" #"track1" #"title" #"Blah blah blah")) ;; (#"(?i:([^.]*)\\.([^:]*):[t ]+(.*))" #"track1.title:TBlah blah blah" (#"track1.title:TBlah blah blah" #"track1" #"title" #"Blah blah blah")) -;; (#"^[W-c]+$" #"WXY_^abc" (#"WXY_^abc")) -;; (#"^[W-c]+$" #"wxy" #f) -;; (#"(?i:^[W-c]+$)" #"WXY_^abc" (#"WXY_^abc")) -;; (#"(?i:^[W-c]+$)" #"wxy_^ABC" (#"wxy_^ABC")) -;; (#"(?i:^[\x3f-\x5F]+$)" #"WXY_^abc" (#"WXY_^abc")) -;; (#"(?i:^[\x3f-\x5F]+$)" #"wxy_^ABC" (#"wxy_^ABC")) -;; (#"(?:b)|(?::+)" #"b::c" (#"b")) -;; (#"(?:b)|(?::+)" #"c::b" (#"::")) -;; (#"[-az]+" #"az-" (#"az-")) -;; (#"[-az]+" #"b" #f) -;; (#"[az-]+" #"za-" (#"za-")) -;; (#"[az-]+" #"b" #f) -;; (#"[a\\-z]+" #"a-z" (#"a-z")) -;; (#"[a\\-z]+" #"b" #f) -;; (#"[a-z]+" #"abcdxyz" (#"abcdxyz")) -;; (#"[\\d-]+" #"12-34" (#"12-34")) -;; (#"[\\d-]+" #"aaa" #f) + (#"^[W-c]+$" #"WXY_^abc" (#"WXY_^abc")) + (#"^[W-c]+$" #"wxy" #f) + ;; (#"(?i:^[W-c]+$)" #"WXY_^abc" (#"WXY_^abc")) + ;; (#"(?i:^[W-c]+$)" #"wxy_^ABC" (#"wxy_^ABC")) + ;; (#"(?i:^[\x3f-\x5F]+$)" #"WXY_^abc" (#"WXY_^abc")) + ;; (#"(?i:^[\x3f-\x5F]+$)" #"wxy_^ABC" (#"wxy_^ABC")) + (#"(?:b)|(?::+)" #"b::c" (#"b")) + (#"(?:b)|(?::+)" #"c::b" (#"::")) + (#"[-az]+" #"az-" (#"az-")) + (#"[-az]+" #"b" #f) + (#"[az-]+" #"za-" (#"za-")) + (#"[az-]+" #"b" #f) + (#"[a\\-z]+" #"a-z" (#"a-z")) + (#"[a\\-z]+" #"b" #f) + (#"[a-z]+" #"abcdxyz" (#"abcdxyz")) + (#"[\\d-]+" #"12-34" (#"12-34")) + (#"[\\d-]+" #"aaa" #f) ;; #"[\\d-z]" -;; (#"[\\dz-]+" #"12-34z" (#"12-34z")) -;; (#"[\\dz-]+" #"aaa" #f) -;; (#"\\\x5c" #"\\\\" (#"\\")) -;; (#"\x20Z" #"the Zoo" (#" Z")) -;; (#"\x20Z" #"Zulu" #f) + (#"[\\dz-]+" #"12-34z" (#"12-34z")) + (#"[\\dz-]+" #"aaa" #f) + (#"\\\x5c" #"\\\\" (#"\\")) + (#"\x20Z" #"the Zoo" (#" Z")) + (#"\x20Z" #"Zulu" #f) ;; (#"(?i:(abc)\\1)" #"abcabc" (#"abcabc" #"abc")) ;; (#"(?i:(abc)\\1)" #"ABCabc" (#"ABCabc" #"ABC")) ;; (#"(?i:(abc)\\1)" #"abcABC" (#"abcABC" #"abc")) -;; (#"ab\\{3cd" #"ab{3cd" (#"ab{3cd")) + (#"ab\\{3cd" #"ab{3cd" (#"ab{3cd")) ;; #"ab{3cd" -;; (#"ab\\{3,cd" #"ab{3,cd" (#"ab{3,cd")) + (#"ab\\{3,cd" #"ab{3,cd" (#"ab{3,cd")) ;; #"ab{3,cd" -;; (#"ab\\{3,4a\\}cd" #"ab{3,4a}cd" (#"ab{3,4a}cd")) + (#"ab\\{3,4a\\}cd" #"ab{3,4a}cd" (#"ab{3,4a}cd")) ;; #"ab{3,4a}cd" -;; (#"\\{4,5a\\}bc" #"{4,5a}bc" (#"{4,5a}bc")) + (#"\\{4,5a\\}bc" #"{4,5a}bc" (#"{4,5a}bc")) ;; #"{4,5a}bc" -;; (#"(abc)\123" #"abc\x53" (#"abcS" #"abc")) + (#"(abc)\123" #"abc\x53" (#"abcS" #"abc")) ;; (#"(abc)\223" #"abc\x93" (#"abc\x93" #"abc")) ;; (#"(abc)\323" #"abc\xd3" (#"abc\xd3" #"abc")) -;; (#"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\123" #"abcdefghijkllS" (#"abcdefghijkllS" #"a" #"b" #"c" #"d" #"e" #"f" #"g" #"h" #"i" #"j" #"k" #"l")) + (#"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\\12\123" #"abcdefghijkllS" (#"abcdefghijkllS" #"a" #"b" #"c" #"d" #"e" #"f" #"g" #"h" #"i" #"j" #"k" #"l")) ;; #"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\12\123" -;; (#"a{0}bc" #"bc" (#"bc")) -;; (#"(a|(bc)){0,0}?xyz" #"xyz" (#"xyz" #f #f)) + (#"a{0}bc" #"bc" (#"bc")) + (#"(a|(bc)){0,0}?xyz" #"xyz" (#"xyz" #f #f)) ;; (#"abc[\\10]de" #"abc\010de" #f) ;; (#"abc[\\1]de" #"abc\1de" #f) ;; (#"(abc)[\\1]de" #"abc\1de" #f) ;; "^([^a])([^\\b])([^c]*)([^d]{3,4})" -;; (#"[^a]" #"Abc" (#"A")) + (#"[^a]" #"Abc" (#"A")) ;; (#"(?i:[^a])" #"Abc " (#"b")) -;; (#"[^a]+" #"AAAaAbc" (#"AAA")) + (#"[^a]+" #"AAAaAbc" (#"AAA")) ;; (#"(?i:[^a]+)" #"AAAaAbc " (#"bc ")) -;; (#"[^k]$" #"abc" (#"c")) -;; (#"[^k]$" #"abk " (#" ")) -;; (#"[^k]{2,3}$" #"abc" (#"abc")) -;; (#"[^k]{2,3}$" #"kbc" (#"bc")) -;; (#"[^k]{2,3}$" #"kabc " (#"bc ")) -;; (#"[^k]{2,3}$" #"abk" #f) -;; (#"[^k]{2,3}$" #"akb" #f) -;; (#"[^k]{2,3}$" #"akk " #f) -;; (#"^\\d{8,}\\@.+[^k]$" #"12345678\\@a.b.c.d" #f) -;; (#"^\\d{8,}\\@.+[^k]$" #"123456789\\@x.y.z" #f) -;; (#"^\\d{8,}\\@.+[^k]$" #"12345678\\@x.y.uk" #f) -;; (#"^\\d{8,}\\@.+[^k]$" #"1234567\\@a.b.c.d " #f) -;; (#"(a)\\1{8,}" #"aaaaaaaaa" (#"aaaaaaaaa" #"a")) -;; (#"(a)\\1{8,}" #"aaaaaaaaaa" (#"aaaaaaaaaa" #"a")) -;; (#"(a)\\1{8,}" #"aaaaaaa " #f) -;; (#"[^a]" #"aaaabcd" (#"b")) -;; (#"[^a]" #"aaAabcd " (#"A")) + (#"[^k]$" #"abc" (#"c")) + (#"[^k]$" #"abk " (#" ")) + (#"[^k]{2,3}$" #"abc" (#"abc")) + (#"[^k]{2,3}$" #"kbc" (#"bc")) + (#"[^k]{2,3}$" #"kabc " (#"bc ")) + (#"[^k]{2,3}$" #"abk" #f) + (#"[^k]{2,3}$" #"akb" #f) + (#"[^k]{2,3}$" #"akk " #f) + (#"^\\d{8,}\\@.+[^k]$" #"12345678\\@a.b.c.d" #f) + (#"^\\d{8,}\\@.+[^k]$" #"123456789\\@x.y.z" #f) + (#"^\\d{8,}\\@.+[^k]$" #"12345678\\@x.y.uk" #f) + (#"^\\d{8,}\\@.+[^k]$" #"1234567\\@a.b.c.d " #f) + (#"(a)\\1{8,}" #"aaaaaaaaa" (#"aaaaaaaaa" #"a")) + (#"(a)\\1{8,}" #"aaaaaaaaaa" (#"aaaaaaaaaa" #"a")) + (#"(a)\\1{8,}" #"aaaaaaa " #f) + (#"[^a]" #"aaaabcd" (#"b")) + (#"[^a]" #"aaAabcd " (#"A")) ;; (#"(?i:[^a])" #"aaaabcd" (#"b")) ;; (#"(?i:[^a])" #"aaAabcd " (#"b")) -;; (#"[^az]" #"aaaabcd" (#"b")) -;; (#"[^az]" #"aaAabcd " (#"A")) + (#"[^az]" #"aaaabcd" (#"b")) + (#"[^az]" #"aaAabcd " (#"A")) ;; (#"(?i:[^az])" #"aaaabcd" (#"b")) ;; (#"(?i:[^az])" #"aaAabcd " (#"b")) -;; (#"P[^*]TAIRE[^*]{1,6}?LL" #"xxxxxxxxxxxPSTAIREISLLxxxxxxxxx" (#"PSTAIREISLL")) -;; (#"P[^*]TAIRE[^*]{1,}?LL" #"xxxxxxxxxxxPSTAIREISLLxxxxxxxxx" (#"PSTAIREISLL")) -;; (#"(\\.\\d\\d[1-9]?)\\d+" #"1.230003938" (#".230003938" #".23")) -;; (#"(\\.\\d\\d[1-9]?)\\d+" #"1.875000282 " (#".875000282" #".875")) -;; (#"(\\.\\d\\d[1-9]?)\\d+" #"1.235 " (#".235" #".23")) -;; (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.230003938 " (#".23" #".23" #"")) -;; (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.875000282" (#".875" #".875" #"5")) -;; (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.235 " #f) -;; (#"a(?:)b" #"ab " (#"ab")) + (#"P[^*]TAIRE[^*]{1,6}?LL" #"xxxxxxxxxxxPSTAIREISLLxxxxxxxxx" (#"PSTAIREISLL")) + (#"P[^*]TAIRE[^*]{1,}?LL" #"xxxxxxxxxxxPSTAIREISLLxxxxxxxxx" (#"PSTAIREISLL")) + (#"(\\.\\d\\d[1-9]?)\\d+" #"1.230003938" (#".230003938" #".23")) + (#"(\\.\\d\\d[1-9]?)\\d+" #"1.875000282 " (#".875000282" #".875")) + (#"(\\.\\d\\d[1-9]?)\\d+" #"1.235 " (#".235" #".23")) + (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.230003938 " (#".23" #".23" #"")) + (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.875000282" (#".875" #".875" #"5")) + (#"(\\.\\d\\d((?=0)|\\d(?=\\d)))" #"1.235 " #f) + (#"a(?:)b" #"ab " (#"ab")) ;; (#"(?i:\\b(foo)\\s+(\\w+))" #"Food is on the foo table" (#"foo table" #"foo" #"table")) -;; (#"foo(.*)bar" #"The food is under the bar in the barn." (#"food is under the bar in the bar" #"d is under the bar in the ")) -;; (#"foo(.*?)bar" #"The food is under the bar in the barn." (#"food is under the bar" #"d is under the ")) -;; (#"(.*)(\\d*)" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 53147" #"")) -;; (#"(.*)(\\d+)" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 5314" #"7")) -;; (#"(.*?)(\\d*)" #"I have 2 numbers: 53147" (#"" #"" #"")) -;; (#"(.*?)(\\d+)" #"I have 2 numbers: 53147" (#"I have 2" #"I have " #"2")) -;; (#"(.*)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 5314" #"7")) -;; (#"(.*?)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147")) -;; (#"(.*)\\b(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147")) -;; (#"(.*\\D)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147")) -;; (#"^\\D*(?!123)" #"ABC123" (#"AB")) -;; (#"^(\\D*)(?=\\d)(?!123)" #"ABC445" (#"ABC" #"ABC")) -;; (#"^(\\D*)(?=\\d)(?!123)" #"ABC123" #f) + (#"foo(.*)bar" #"The food is under the bar in the barn." (#"food is under the bar in the bar" #"d is under the bar in the ")) + (#"foo(.*?)bar" #"The food is under the bar in the barn." (#"food is under the bar" #"d is under the ")) + (#"(.*)(\\d*)" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 53147" #"")) + (#"(.*)(\\d+)" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 5314" #"7")) + (#"(.*?)(\\d*)" #"I have 2 numbers: 53147" (#"" #"" #"")) + (#"(.*?)(\\d+)" #"I have 2 numbers: 53147" (#"I have 2" #"I have " #"2")) + (#"(.*)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: 5314" #"7")) + (#"(.*?)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147")) + (#"(.*)\\b(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147")) + (#"(.*\\D)(\\d+)$" #"I have 2 numbers: 53147" (#"I have 2 numbers: 53147" #"I have 2 numbers: " #"53147")) + (#"^\\D*(?!123)" #"ABC123" (#"AB")) + (#"^(\\D*)(?=\\d)(?!123)" #"ABC445" (#"ABC" #"ABC")) + (#"^(\\D*)(?=\\d)(?!123)" #"ABC123" #f) ;; #"^[W-]46]" -;; (#"^[W-]46\\]" #"W46]789 " (#"W46]")) -;; (#"^[W-]46\\]" #"-46]789" (#"-46]")) -;; (#"^[W-]46\\]" #"Wall" #f) -;; (#"^[W-]46\\]" #"Zebra" #f) -;; (#"^[W-]46\\]" #"42" #f) -;; (#"^[W-]46\\]" #"[abcd] " #f) -;; (#"^[W-]46\\]" #"]abcd[" #f) -;; (#"^[W-\\]46]" #"W46]789 " (#"W")) -;; (#"^[W-\\]46]" #"Wall" (#"W")) -;; (#"^[W-\\]46]" #"Zebra" (#"Z")) -;; (#"^[W-\\]46]" #"Xylophone " (#"X")) -;; (#"^[W-\\]46]" #"42" (#"4")) -;; (#"^[W-\\]46]" #"[abcd] " (#"[")) -;; (#"^[W-\\]46]" #"]abcd[" (#"]")) -;; (#"^[W-\\]46]" #"\\\\backslash " (#"\\")) -;; (#"^[W-\\]46]" #"-46]789" #f) -;; (#"^[W-\\]46]" #"well" #f) -;; (#"\\d\\d\\/\\d\\d\\/\\d\\d\\d\\d" #"01/01/2000" (#"01/01/2000")) -;; (#"word (?:[a-zA-Z0-9]+ ){0,10}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark otherword" #f) -;; (#"word (?:[a-zA-Z0-9]+ ){0,10}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark" #f) -;; (#"word (?:[a-zA-Z0-9]+ ){0,300}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope" #f) -;; (#"^(a){0,0}" #"bcd" (#"" #f)) -;; (#"^(a){0,0}" #"abc" (#"" #f)) -;; (#"^(a){0,0}" #"aab " (#"" #f)) -;; (#"^(a){0,1}" #"bcd" (#"" #f)) -;; (#"^(a){0,1}" #"abc" (#"a" #"a")) -;; (#"^(a){0,1}" #"aab " (#"a" #"a")) -;; (#"^(a){0,2}" #"bcd" (#"" #f)) -;; (#"^(a){0,2}" #"abc" (#"a" #"a")) -;; (#"^(a){0,2}" #"aab " (#"aa" #"a")) -;; (#"^(a){0,3}" #"bcd" (#"" #f)) -;; (#"^(a){0,3}" #"abc" (#"a" #"a")) -;; (#"^(a){0,3}" #"aab" (#"aa" #"a")) -;; (#"^(a){0,3}" #"aaa " (#"aaa" #"a")) -;; (#"^(a){0,}" #"bcd" (#"" #f)) -;; (#"^(a){0,}" #"abc" (#"a" #"a")) -;; (#"^(a){0,}" #"aab" (#"aa" #"a")) -;; (#"^(a){0,}" #"aaa" (#"aaa" #"a")) -;; (#"^(a){0,}" #"aaaaaaaa " (#"aaaaaaaa" #"a")) -;; (#"^(a){1,1}" #"bcd" #f) -;; (#"^(a){1,1}" #"abc" (#"a" #"a")) -;; (#"^(a){1,1}" #"aab " (#"a" #"a")) -;; (#"^(a){1,2}" #"bcd" #f) -;; (#"^(a){1,2}" #"abc" (#"a" #"a")) -;; (#"^(a){1,2}" #"aab " (#"aa" #"a")) -;; (#"^(a){1,3}" #"bcd" #f) -;; (#"^(a){1,3}" #"abc" (#"a" #"a")) -;; (#"^(a){1,3}" #"aab" (#"aa" #"a")) -;; (#"^(a){1,3}" #"aaa " (#"aaa" #"a")) -;; (#"^(a){1,}" #"bcd" #f) -;; (#"^(a){1,}" #"abc" (#"a" #"a")) -;; (#"^(a){1,}" #"aab" (#"aa" #"a")) -;; (#"^(a){1,}" #"aaa" (#"aaa" #"a")) -;; (#"^(a){1,}" #"aaaaaaaa " (#"aaaaaaaa" #"a")) -;; (#"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" #"123456654321" (#"123456654321")) -;; (#"^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d" #"123456654321 " (#"123456654321")) -;; (#"^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]" #"123456654321" (#"123456654321")) -;; (#"^[abc]{12}" #"abcabcabcabc" (#"abcabcabcabc")) -;; (#"^[a-c]{12}" #"abcabcabcabc" (#"abcabcabcabc")) -;; (#"^(a|b|c){12}" #"abcabcabcabc " (#"abcabcabcabc" #"c")) -;; (#"^[abcdefghijklmnopqrstuvwxy0123456789]" #"n" (#"n")) -;; (#"^[abcdefghijklmnopqrstuvwxy0123456789]" #"z " #f) -;; (#"abcde{0,0}" #"abcd" (#"abcd")) -;; (#"abcde{0,0}" #"abce " #f) -;; (#"ab[cd]{0,0}e" #"abe" (#"abe")) -;; (#"ab[cd]{0,0}e" #"abcde " #f) -;; (#"ab(c){0,0}d" #"abd" (#"abd" #f)) -;; (#"ab(c){0,0}d" #"abcd " #f) -;; (#"a(b*)" #"a" (#"a" #"")) -;; (#"a(b*)" #"ab" (#"ab" #"b")) -;; (#"a(b*)" #"abbbb" (#"abbbb" #"bbbb")) -;; (#"a(b*)" #"bbbbb " #f) -;; (#"ab\\d{0}e" #"abe" (#"abe")) -;; (#"ab\\d{0}e" #"ab1e " #f) -;; (#"\"([^\\\\\"]+|\\\\.)*\"" #"the \\\"quick\\\" brown fox" #f) -;; (#"\"([^\\\\\"]+|\\\\.)*\"" #"\\\"the \\\\\\\"quick\\\\\\\" brown fox\\\" " #f) + (#"^[W-]46\\]" #"W46]789 " (#"W46]")) + (#"^[W-]46\\]" #"-46]789" (#"-46]")) + (#"^[W-]46\\]" #"Wall" #f) + (#"^[W-]46\\]" #"Zebra" #f) + (#"^[W-]46\\]" #"42" #f) + (#"^[W-]46\\]" #"[abcd] " #f) + (#"^[W-]46\\]" #"]abcd[" #f) + (#"^[W-\\]46]" #"W46]789 " (#"W")) + (#"^[W-\\]46]" #"Wall" (#"W")) + (#"^[W-\\]46]" #"Zebra" (#"Z")) + (#"^[W-\\]46]" #"Xylophone " (#"X")) + (#"^[W-\\]46]" #"42" (#"4")) + (#"^[W-\\]46]" #"[abcd] " (#"[")) + (#"^[W-\\]46]" #"]abcd[" (#"]")) + (#"^[W-\\]46]" #"\\\\backslash " (#"\\")) + (#"^[W-\\]46]" #"-46]789" #f) + (#"^[W-\\]46]" #"well" #f) + (#"\\d\\d\\/\\d\\d\\/\\d\\d\\d\\d" #"01/01/2000" (#"01/01/2000")) + (#"word (?:[a-zA-Z0-9]+ ){0,10}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark otherword" #f) + (#"word (?:[a-zA-Z0-9]+ ){0,10}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark" #f) + (#"word (?:[a-zA-Z0-9]+ ){0,300}otherword" #"rd cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope" #f) + (#"^(a){0,0}" #"bcd" (#"" #f)) + (#"^(a){0,0}" #"abc" (#"" #f)) + (#"^(a){0,0}" #"aab " (#"" #f)) + (#"^(a){0,1}" #"bcd" (#"" #f)) + (#"^(a){0,1}" #"abc" (#"a" #"a")) + (#"^(a){0,1}" #"aab " (#"a" #"a")) + (#"^(a){0,2}" #"bcd" (#"" #f)) + (#"^(a){0,2}" #"abc" (#"a" #"a")) + (#"^(a){0,2}" #"aab " (#"aa" #"a")) + (#"^(a){0,3}" #"bcd" (#"" #f)) + (#"^(a){0,3}" #"abc" (#"a" #"a")) + (#"^(a){0,3}" #"aab" (#"aa" #"a")) + (#"^(a){0,3}" #"aaa " (#"aaa" #"a")) + (#"^(a){0,}" #"bcd" (#"" #f)) + (#"^(a){0,}" #"abc" (#"a" #"a")) + (#"^(a){0,}" #"aab" (#"aa" #"a")) + (#"^(a){0,}" #"aaa" (#"aaa" #"a")) + (#"^(a){0,}" #"aaaaaaaa " (#"aaaaaaaa" #"a")) + (#"^(a){1,1}" #"bcd" #f) + (#"^(a){1,1}" #"abc" (#"a" #"a")) + (#"^(a){1,1}" #"aab " (#"a" #"a")) + (#"^(a){1,2}" #"bcd" #f) + (#"^(a){1,2}" #"abc" (#"a" #"a")) + (#"^(a){1,2}" #"aab " (#"aa" #"a")) + (#"^(a){1,3}" #"bcd" #f) + (#"^(a){1,3}" #"abc" (#"a" #"a")) + (#"^(a){1,3}" #"aab" (#"aa" #"a")) + (#"^(a){1,3}" #"aaa " (#"aaa" #"a")) + (#"^(a){1,}" #"bcd" #f) + (#"^(a){1,}" #"abc" (#"a" #"a")) + (#"^(a){1,}" #"aab" (#"aa" #"a")) + (#"^(a){1,}" #"aaa" (#"aaa" #"a")) + (#"^(a){1,}" #"aaaaaaaa " (#"aaaaaaaa" #"a")) + (#"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" #"123456654321" (#"123456654321")) + (#"^\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d" #"123456654321 " (#"123456654321")) + (#"^[\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d][\\d]" #"123456654321" (#"123456654321")) + (#"^[abc]{12}" #"abcabcabcabc" (#"abcabcabcabc")) + (#"^[a-c]{12}" #"abcabcabcabc" (#"abcabcabcabc")) + (#"^(a|b|c){12}" #"abcabcabcabc " (#"abcabcabcabc" #"c")) + (#"^[abcdefghijklmnopqrstuvwxy0123456789]" #"n" (#"n")) + (#"^[abcdefghijklmnopqrstuvwxy0123456789]" #"z " #f) + (#"abcde{0,0}" #"abcd" (#"abcd")) + (#"abcde{0,0}" #"abce " #f) + (#"ab[cd]{0,0}e" #"abe" (#"abe")) + (#"ab[cd]{0,0}e" #"abcde " #f) + (#"ab(c){0,0}d" #"abd" (#"abd" #f)) + (#"ab(c){0,0}d" #"abcd " #f) + (#"a(b*)" #"a" (#"a" #"")) + (#"a(b*)" #"ab" (#"ab" #"b")) + (#"a(b*)" #"abbbb" (#"abbbb" #"bbbb")) + (#"a(b*)" #"bbbbb " #f) + (#"ab\\d{0}e" #"abe" (#"abe")) + (#"ab\\d{0}e" #"ab1e " #f) + (#"\"([^\\\\\"]+|\\\\.)*\"" #"the \\\"quick\\\" brown fox" #f) + (#"\"([^\\\\\"]+|\\\\.)*\"" #"\\\"the \\\\\\\"quick\\\\\\\" brown fox\\\" " #f) ;; (#"(?i:]{0,})>]{0,})>([\\d]{0,}\\.)(.*)((
([\\w\\W\\s\\d][^<>]{0,})|[\\s]{0,}))<\\/a><\\/TD>]{0,})>([\\w\\W\\s\\d][^<>]{0,})<\\/TD>]{0,})>([\\w\\W\\s\\d][^<>]{0,})<\\/TD><\\/TR>)" #"R BGCOLOR='#DBE9E9'>43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide" #f) -;; (#"^(b+?|a){1,2}?c" #"bac" (#"bac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"bbac" (#"bbac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"bbbac" (#"bbbac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"bbbbac" (#"bbbbac" #"a")) -;; (#"^(b+?|a){1,2}?c" #"bbbbbac " (#"bbbbbac" #"a")) -;; (#"^(b+|a){1,2}?c" #"bac" (#"bac" #"a")) -;; (#"^(b+|a){1,2}?c" #"bbac" (#"bbac" #"a")) -;; (#"^(b+|a){1,2}?c" #"bbbac" (#"bbbac" #"a")) -;; (#"^(b+|a){1,2}?c" #"bbbbac" (#"bbbbac" #"a")) -;; (#"^(b+|a){1,2}?c" #"bbbbbac " (#"bbbbbac" #"a")) -;; (#"\x0\\{ab\\}" #"\0{ab}" (#"\0{ab}")) -;; (#"(A|B)*?CD" #"CD " (#"CD" #f)) -;; (#"(A|B)*CD" #"CD " (#"CD" #f)) + (#"^(b+?|a){1,2}?c" #"bac" (#"bac" #"a")) + (#"^(b+?|a){1,2}?c" #"bbac" (#"bbac" #"a")) + (#"^(b+?|a){1,2}?c" #"bbbac" (#"bbbac" #"a")) + (#"^(b+?|a){1,2}?c" #"bbbbac" (#"bbbbac" #"a")) + (#"^(b+?|a){1,2}?c" #"bbbbbac " (#"bbbbbac" #"a")) + (#"^(b+|a){1,2}?c" #"bac" (#"bac" #"a")) + (#"^(b+|a){1,2}?c" #"bbac" (#"bbac" #"a")) + (#"^(b+|a){1,2}?c" #"bbbac" (#"bbbac" #"a")) + (#"^(b+|a){1,2}?c" #"bbbbac" (#"bbbbac" #"a")) + (#"^(b+|a){1,2}?c" #"bbbbbac " (#"bbbbbac" #"a")) + (#"\x0\\{ab\\}" #"\0{ab}" (#"\0{ab}")) + (#"(A|B)*?CD" #"CD " (#"CD" #f)) + (#"(A|B)*CD" #"CD " (#"CD" #f)) ;; (#"(AB)*?\\1" #"ABABAB" (#"ABAB" #"AB")) ;; (#"(AB)*\\1" #"ABABAB" (#"ABABAB" #"AB")) ;; #"((a{0,5}){0,5}){0,5}[c]" ;; #"((a{0,5}){0,5})*[c]" ;; #"((a{0,5}){0,5})*[c]" ;; #"(\\b)*a" -;; (#"(a)*b" #"ab" (#"ab" #"a")) + (#"(a)*b" #"ab" (#"ab" #"a")) ;; #"(a|)*b" ;; #"(a|)*b" ;; #"(a|)*b" ;; (#"^(?:(a)|(b))*\\1\\2$" #"abab" (#"abab" #"a" #"b")) -;; (#"abc[^x]def" #"abcxabcydef" (#"abcydef")) + (#"abc[^x]def" #"abcxabcydef" (#"abcydef")) ;; (#"^(a|\\1x)*$" #"aax" (#"aax" #"ax")) ;; (#"^(a|\\1x)*$" #"aaxa" (#"aaxa" #"a")) -;; (#"" #"@{['']}" (#"")) + (#"" #"@{['']}" (#"")) ;; (#"^(?:(a)|(b))*$" #"ab" (#"ab" #"a" #"b")) -;; (#"[\0]" #"a" #f) -;; (#"[\0]" #"\0" (#"\0")) -;; (#"[\1]" #"a" #f) -;; (#"[\1]" #"\1" (#"\1")) + (#"[\0]" #"a" #f) + (#"[\0]" #"\0" (#"\0")) + (#"[\1]" #"a" #f) + (#"[\1]" #"\1" (#"\1")) ;; (#"\\10()()()()()()()()()()" #"a" #f) -;; (#"a(?<=)b" #"ab" (#"ab")) ;; << added "=" to pattern -;; (#"(?<=qq)b*" #"aqbbbqqbb" (#"bb")) ;; << added -;; (#"(?<=q?q)b*" #"aqbbbqqbb" (#"bbb")) ;; << added -;; (#"()" #"a" (#"" #"")) + (#"a(?<=)b" #"ab" (#"ab")) ;; << added "=" to pattern + (#"(?<=qq)b*" #"aqbbbqqbb" (#"bb")) ;; << added + (#"(?<=q?q)b*" #"aqbbbqqbb" (#"bbb")) ;; << added + (#"()" #"a" (#"" #"")) ;; #"[\\x]" ;; #"[\\x]" ;; #"((a)*)*" -;; (#"()a\\1" #"a" (#"a" #"")) + (#"()a\\1" #"a" (#"a" #"")) ;; (#"a\\1()" #"a" #f) +;; SyntaxError: Invalid regular expression: /a(?i:a)a/: Invalid group ;; (#"a(?i:a)a" #"aaa" (#"aaa")) ;; (#"a(?i:a)a" #"aAa" (#"aAa")) ;; (#"a(?i:a)a" #"aAA" #f) @@ -870,33 +878,33 @@ ;; #"[\\d-f]" ;; #"[\\d-f]" ;; #"[\\d-f]" -;; (#"[-b\\d]" #"b" (#"b")) -;; (#"[-b\\d]" #"c" #f) -;; (#"[-b\\d]" #"d" #f) -;; (#"[-b\\d]" #"-" (#"-")) -;; (#"[-b\\d]" #"1" (#"1")) -;; (#"[\\df-]" #"d" #f) -;; (#"[\\df-]" #"e" #f) -;; (#"[\\df-]" #"f" (#"f")) -;; (#"[\\df-]" #"-" (#"-")) -;; (#"[\\df-]" #"1" (#"1")) -;; (#"[-a-c]" #"-" (#"-")) -;; (#"[-a-c]" #"a" (#"a")) -;; (#"[-a-c]" #"b" (#"b")) -;; (#"[-a-c]" #"d" #f) -;; (#"[a-c-]" #"-" (#"-")) -;; (#"[a-c-]" #"a" (#"a")) -;; (#"[a-c-]" #"b" (#"b")) -;; (#"[a-c-]" #"d" #f) -;; (#"[-]" #"a" #f) -;; (#"[-]" #"-" (#"-")) -;; (#"[--]" #"a" #f) -;; (#"[--]" #"-" (#"-")) + (#"[-b\\d]" #"b" (#"b")) + (#"[-b\\d]" #"c" #f) + (#"[-b\\d]" #"d" #f) + (#"[-b\\d]" #"-" (#"-")) + (#"[-b\\d]" #"1" (#"1")) + (#"[\\df-]" #"d" #f) + (#"[\\df-]" #"e" #f) + (#"[\\df-]" #"f" (#"f")) + (#"[\\df-]" #"-" (#"-")) + (#"[\\df-]" #"1" (#"1")) + (#"[-a-c]" #"-" (#"-")) + (#"[-a-c]" #"a" (#"a")) + (#"[-a-c]" #"b" (#"b")) + (#"[-a-c]" #"d" #f) + (#"[a-c-]" #"-" (#"-")) + (#"[a-c-]" #"a" (#"a")) + (#"[a-c-]" #"b" (#"b")) + (#"[a-c-]" #"d" #f) + (#"[-]" #"a" #f) + (#"[-]" #"-" (#"-")) + (#"[--]" #"a" #f) + (#"[--]" #"-" (#"-")) ;; #"[---]" ;; #"[--b]" -;; (#"[-b-]" #"-" (#"-")) -;; (#"[-b-]" #"a" #f) -;; (#"[-b-]" #"c" #f) + (#"[-b-]" #"-" (#"-")) + (#"[-b-]" #"a" #f) + (#"[-b-]" #"c" #f) ;; #"a{" ;; (#"a{}" #"aaa" (#"")) ;; #"a{3" @@ -918,11 +926,11 @@ ;; #"^a{ 1}$" ;; #"{}" ;; #"{}" -;; (#"|" #"x" (#"")) -;; (#"|x" #"x" (#"")) -;; (#"x|" #"x" (#"x")) -;; (#"\0000" #"\0000" (#"\0\x30")) -;; (#"a(?<=)b" #"ab" (#"ab")) + (#"|" #"x" (#"")) + (#"|x" #"x" (#"")) + (#"x|" #"x" (#"x")) + (#"\0000" #"\0000" (#"\0\x30")) + (#"a(?<=)b" #"ab" (#"ab")) ;; (#"a(?i:b)" #"ab" (#"ab")) ;; (#"a(?i:b)" #"aB" (#"aB")) ;; (#"a(?i:b)" #"Ab" #f) @@ -937,35 +945,37 @@ ;; #"a(?<=(a))*\\1" ;; #"a(?<=(a))*?\\1" ;; #"(?=(a)\\1)*aa" -;; (#"^((a|b){2,5}){2}$" #"aaabbbbb" (#"aaabbbbb" #"bbb" #"b")) + (#"^((a|b){2,5}){2}$" #"aaabbbbb" (#"aaabbbbb" #"bbb" #"b")) ;; #"^(b*|ba){1,2}bc" -;; (#"^a{4,5}(?:c|a)c$" #"aaac" #f) -;; (#"^a{4,5}(?:c|a)c$" #"aaaac" #f) + (#"^a{4,5}(?:c|a)c$" #"aaac" #f) + (#"^a{4,5}(?:c|a)c$" #"aaaac" #f) ;; #"^(a|){4,5}(?:c|a)c$" +;; SyntaxError: Invalid regular expression: /(?m:^).abc$/: Invalid group ;; (#"(?m:^).abc$" #"exabc" #f) ;; (#"(?m:^)abc" #"c" #f) -;; (#"^abc" #"c" #f) -;; (#"(?(\.\d\d[1-9]?))\d+/: Invalid group ;; (#"(?>(\\.\\d\\d[1-9]?))\\d+" #"1.230003938" (#".230003938" #".23")) ;; (#"(?>(\\.\\d\\d[1-9]?))\\d+" #"1.875000282" (#".875000282" #".875")) ;; (#"(?>(\\.\\d\\d[1-9]?))\\d+" #"1.235 " #f) ;; (#"^((?>\\w+)|(?>\\s+))*$" #"now is the time for all good men to come to the aid of the party" (#"now is the time for all good men to come to the aid of the party" #"party")) ;; (#"^((?>\\w+)|(?>\\s+))*$" #"this is not a line with only words and spaces!" #f) -;; (#"(\\d+)(\\w)" #"12345a" (#"12345a" #"12345" #"a")) -;; (#"(\\d+)(\\w)" #"12345+ " (#"12345" #"1234" #"5")) + (#"(\\d+)(\\w)" #"12345a" (#"12345a" #"12345" #"a")) + (#"(\\d+)(\\w)" #"12345+ " (#"12345" #"1234" #"5")) ;; (#"((?>\\d+))(\\w)" #"12345a" (#"12345a" #"12345" #"a")) ;; (#"((?>\\d+))(\\w)" #"12345+ " #f) ;; (#"(?>a+)b" #"aaab" (#"aaab")) @@ -1041,10 +1051,10 @@ ;; #"(?>a*)*" ;; #"((?>a*))*" ;; #"((?>a*?))*" -;; (#"(?<=(foo))bar\\1" #"foobarfoo" (#"barfoo" #"foo")) -;; (#"(?<=(foo))bar\\1" #"foobarfootling " (#"barfoo" #"foo")) -;; (#"(?<=(foo))bar\\1" #"foobar" #f) -;; (#"(?<=(foo))bar\\1" #"barfoo " #f) + (#"(?<=(foo))bar\\1" #"foobarfoo" (#"barfoo" #"foo")) + (#"(?<=(foo))bar\\1" #"foobarfootling " (#"barfoo" #"foo")) + (#"(?<=(foo))bar\\1" #"foobar" #f) + (#"(?<=(foo))bar\\1" #"barfoo " #f) ;; (#"(?i:saturday|sunday)" #"saturday" (#"saturday")) ;; (#"(?i:saturday|sunday)" #"sunday" (#"sunday")) ;; (#"(?i:saturday|sunday)" #"Saturday" (#"Saturday")) @@ -1076,201 +1086,204 @@ ;; (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"Zambesi" (#"Z" #"Z")) ;; (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"aCD " #f) ;; (#"^(ab|a(?i:[b-c](?m-i:d))|(?m-i:x(?i:y))|(?i:z))" #"XY " #f) -;; (#"(?<=(?