diff --git a/.appveyor.yml b/.appveyor.yml index ffd608d195..8a6b0e4a6b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -5,12 +5,8 @@ branches: install: - ps: >- ## Download Rebol v276 - - $url = "http://static.red-lang.org/build/rebview.exe" - - $output = "c:\projects\red\rebview.exe" - - (New-Object System.Net.WebClient).DownloadFile($url, $output) + + curl -o c:\projects\red\rebview.exe https://static.red-lang.org/build/rebview.exe build_script: - cmd: >- c:\projects\red\rebview.exe -qws tests\run-all.r --batch diff --git a/.editorconfig b/.github/.editorconfig similarity index 100% rename from .editorconfig rename to .github/.editorconfig diff --git a/.github/.gitattributes-sample b/.github/.gitattributes-sample new file mode 100644 index 0000000000..a4b096dac4 --- /dev/null +++ b/.github/.gitattributes-sample @@ -0,0 +1,40 @@ +# Auto detect +# Handle line endings automatically for files detected as +# text and leave all files detected as binary untouched. +# This will handle all files NOT defined below. +* text=auto + +# Overwrite the default settings for some known files: + +*.bas text +*.bat text eol=crlf +*.cmd text eol=crlf +*.def text +*.dex binary +*.dll binary +*.dylib binary +*.icns binary +*.ico binary +*.java text +*.lib binary +*.md text +*.plist text +*.r text +*.red text +*.reds text +*.sample text +*.sh text eol=lf +*.so binary +*.tests text +*.xlsm binary +*.xlsx binary +*.xml text +*.yml text + +# Image files + +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary diff --git a/.gitignore-sample b/.github/.gitignore-sample similarity index 100% rename from .gitignore-sample rename to .github/.gitignore-sample diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d51bcfc4df..200c85de92 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -26,7 +26,8 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. -**Platform version (please complete the following information)** -``` -Run `about` command from Red console and paste the output here. -``` +**Platform version** +Please specify the operating system, Red version, and build date with Git commit. + +* This can be done all at once by running `about/debug` command from Red console and pasting its output here. +* `About/debug/cc` automatically copies the output to the clipboard. diff --git a/.github/workflows/RPi.yml b/.github/workflows/RPi.yml new file mode 100644 index 0000000000..8acba938ba --- /dev/null +++ b/.github/workflows/RPi.yml @@ -0,0 +1,148 @@ +name: RPi + +on: push + +jobs: + Build-RPi-Tests: + runs-on: ubuntu-latest + name: Build RPi Tests + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Build Red Tests + uses: ./CI/Linux-32 + with: + command: rebol -qws tests/build-arm-tests.r -t RPi + + - name: Build Red/System Tests + uses: ./CI/Linux-32 + with: + command: rebol -qws system/tests/build-arm-tests.r -t RPi + + - uses: actions/upload-artifact@v3 + with: + name: rpi-tests-bin + path: quick-test/runnable/arm-tests/red + retention-days: 3 + + - uses: actions/upload-artifact@v3 + with: + name: rpi-rs-bin + path: quick-test/runnable/arm-tests/system + retention-days: 3 + + Run-RPi-RS-Tests: + + runs-on: [self-hosted, linux, arm] + needs: Build-RPi-Tests + + steps: + - name: Clean working directory + run: | + echo "Cleaning up previous run" + rm -rf ${{ github.workspace }}/* + + - name: Retrieve tests + uses: actions/download-artifact@v3 + with: + name: rpi-rs-bin + + - name: Run tests + run: | + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/. + chmod +x run-all.sh + ./run-all.sh + + # upload log file if any test failed + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: RPi-RS-Tests-log + path: quick-test.log + + Run-RPi-Tests: + + runs-on: [self-hosted, linux, arm] + needs: Run-RPi-RS-Tests + + steps: + - name: Clean working directory + run: | + echo "Cleaning up previous run" + rm -rf ${{ github.workspace }}/* + + - name: Retrieve tests + uses: actions/download-artifact@v3 + with: + name: rpi-tests-bin + + - name: Run tests + run: | + chmod +x run-all.sh + ./run-all.sh + + # upload log file if any test failed + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: RPi-Tests-log + path: quick-test.log + + + Run-RS-Tests-Armbian: + + runs-on: [self-hosted, Linux, ARM64] + needs: Build-RPi-Tests + + steps: + - name: Clean working directory + run: | + echo "Cleaning up previous run" + rm -rf ${{ github.workspace }}/* + + - name: Retrieve tests + uses: actions/download-artifact@v3 + with: + name: rpi-rs-bin + + - name: Run tests + run: | + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/. + chmod +x run-all.sh + ./run-all.sh + + # upload log file if any test failed + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: RS-Tests-Armbian-log + path: quick-test.log + + Run-Red-Tests-Armbian: + + runs-on: [self-hosted, Linux, ARM64] + needs: Run-RS-Tests-Armbian + + steps: + - name: Clean working directory + run: | + echo "Cleaning up previous run" + rm -rf ${{ github.workspace }}/* + + - name: Retrieve tests + uses: actions/download-artifact@v3 + with: + name: rpi-tests-bin + + - name: Run tests + run: | + chmod +x run-all.sh + ./run-all.sh + + # upload log file if any test failed + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: Red-Tests-Armbian-log + path: quick-test.log \ No newline at end of file diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml new file mode 100644 index 0000000000..de465bc615 --- /dev/null +++ b/.github/workflows/linux.yml @@ -0,0 +1,40 @@ +name: Linux-x86 + +on: push + +jobs: + Linux-Red-Tests: + runs-on: ubuntu-latest + name: Run Linux-x86 Tests + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Build Tests + uses: ./CI/Linux-gtk + with: + command: /sbin/start-stop-daemon --start --quiet --background --exec /usr/bin/Xvfb && sleep 3 && rebol -qws tests/run-all.r --batch + + # upload log file if any test failed + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: Linux-Red-Tests-log + path: quick-test/quick-test.log + + Linux-RS-Tests: + runs-on: ubuntu-latest + name: Run Linux-RS Tests + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Build Tests + uses: ./CI/Linux-32 + with: + command: rebol -qws system/tests/run-all.r --batch + + # upload log file if any test failed + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: Linux-RS-Tests-log + path: quick-test/quick-test.log \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e0f1c770d0..7d6748d928 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,30 +8,70 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: setup red repo run: | $url = "http://static.red-lang.org/build/rebview.exe" $output = "$Env:GITHUB_WORKSPACE\rebview.exe" (New-Object System.Net.WebClient).DownloadFile($url, $output) - - name: run view test + - name: run core test + run: rebview.exe -qws tests\run-core-tests.r --batch + shell: cmd + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: core-test-log + path: quick-test/quick-test.log + + Core-Release: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v3 + - name: setup red repo run: | - rebview.exe -qws tests\run-core-tests.r --batch - rebview.exe -qws system\tests\run-all.r --batch + $url = "http://static.red-lang.org/build/rebview.exe" + $output = "$Env:GITHUB_WORKSPACE\rebview.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + - name: run core test + run: rebview.exe -qws tests\run-core-tests.r --batch --release shell: cmd - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v3 if: failure() with: name: core-test-log path: quick-test/quick-test.log + Core-Debug: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v3 + - name: setup red repo + run: | + $url = "http://static.red-lang.org/build/rebview.exe" + $output = "$Env:GITHUB_WORKSPACE\rebview.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + - name: run core test + run: rebview.exe -qws tests\run-core-tests.r --batch --debug + shell: cmd + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: core-debug-test-log + path: quick-test/quick-test.log + View: runs-on: windows-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: setup red repo run: | $url = "http://static.red-lang.org/build/rebview.exe" @@ -41,7 +81,7 @@ jobs: run: rebview.exe -qws tests\run-view-tests.r --batch shell: cmd - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v3 if: failure() with: name: view-test-log @@ -52,7 +92,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: setup red repo run: | $url = "http://static.red-lang.org/build/rebview.exe" @@ -62,7 +102,7 @@ jobs: run: rebview.exe -qws tests\run-regression-tests.r --batch shell: cmd - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v3 if: failure() with: name: regression-test-log @@ -73,20 +113,60 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: setup red repo run: | $url = "http://static.red-lang.org/build/rebview.exe" $output = "$Env:GITHUB_WORKSPACE\rebview.exe" (New-Object System.Net.WebClient).DownloadFile($url, $output) - - name: run view test - run: | - rebview.exe -qws tests\run-all.r --each - rebview.exe -qws system\tests\run-all.r --each + - name: run each test + run: rebview.exe -qws tests\run-core-tests.r --ci-each shell: cmd - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v3 if: failure() with: name: each-test-log path: quick-test/quick-test.log + + Each-Mode-Debug: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v3 + - name: setup red repo + run: | + $url = "http://static.red-lang.org/build/rebview.exe" + $output = "$Env:GITHUB_WORKSPACE\rebview.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + - name: run each test + run: rebview.exe -qws tests\run-core-tests.r --ci-each --debug + shell: cmd + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: each-debug-test-log + path: quick-test/quick-test.log + + Red-System-Test: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v3 + - name: setup red repo + run: | + $url = "http://static.red-lang.org/build/rebview.exe" + $output = "$Env:GITHUB_WORKSPACE\rebview.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + - name: run Red/System test + run: rebview.exe -qws system\tests\run-all.r --batch + shell: cmd + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: rs-test-log + path: quick-test/quick-test.log \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5fc69d2da2..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,160 +0,0 @@ -# Only use continuous integration on the master branch -branches: - only: - - master - - -notifications: - email: - # Send notifications on every build failure to comitter and author. - # Never send notifications for sucessful builds. - on_success: never - webhooks: - urls: - # Gitter - - secure: "FWx+7+aWMapJfqykkpcBSiaNylWkSXRiXt28pXlbg5LHHgMz5Fh44BwdSB3RnD/lFqLWw+0w0XfvTjqEcqkn0x3nb9UKN/LJfh+QJGEv6wfjg2X+zlLuLVmFgRurWeHk3dDS1Y8SN4jdcondXmRP+KHKrwx5v/18LDYSHMWjO0Y=" - on_success: change # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: false # default: false - - -# Disables Travis CI's Ruby-specific defaults. -language: c - - -env: - global: - - STATUS=1 - # STATUS_URL - - secure: "OGj4ljDpWyvhS8pBDJxFt5Xm7J+dX6tOJpMvQRBb2Q+2QPAniHwNCbQbJj02vTFR5eGAzmgFuv8ovKdPtOwSgKVeS0cxr3PCGBdV8GGEq1LjAP96YQshYIvW5najvwuhcE0jM4MujIiYxa+X+ftjcBstsN1h3ItskrvyZv5/4BM=" - - -matrix: -# allow_failures: # Enable to disregard ARM build failures -# - env: OS=arm # Enable to disregard ARM build failures - include: - - - ### Linux ############################################################ - - os: linux - dist: trusty - sudo: required - env: OS=linux - script: # Run i386 tests - - > - docker run -v ${PWD}:/red -w /red - i386/debian:red rebol -qws tests/run-all.r --batch - - mv quick-test/quick-test.log quick-test/quick-test-red.log - - > - docker run -v ${PWD}:/red -w /red - i386/debian:red rebol -qws system/tests/run-all.r --batch - - - ### ARMel ############################################################ - - os: linux - dist: trusty - sudo: required - env: OS=armel - script: # Run ARMv5el tests - - > - docker run -v ${PWD}:/red - -w /red/quick-test/runnable/arm-tests/red/ - --entrypoint /red/quick-test/runnable/arm-tests/red/run-all.sh - balenalib/armv5e-debian:latest - - > - docker run -v ${PWD}:/red - -e LD_LIBRARY_PATH='$LD_LIBRARY_PATH:/red/quick-test/runnable/arm-tests/system/' - -w /red/quick-test/runnable/arm-tests/system/ - --entrypoint /red/quick-test/runnable/arm-tests/system/run-all.sh - balenalib/armv5e-debian:latest - - - ### ARMhf ############################################################ - - os: linux - dist: trusty - sudo: required - env: OS=armhf - script: # Run ARMv7hf tests - - > - docker run -v ${PWD}:/red - -w /red/quick-test/runnable/arm-tests/red/ - --entrypoint /red/quick-test/runnable/arm-tests/red/run-all.sh - balenalib/raspberry-pi2-debian:latest - - > - docker run -v ${PWD}:/red - -e LD_LIBRARY_PATH='$LD_LIBRARY_PATH:/red/quick-test/runnable/arm-tests/system/' - -w /red/quick-test/runnable/arm-tests/system/ - --entrypoint /red/quick-test/runnable/arm-tests/system/run-all.sh - balenalib/raspberry-pi2-debian:latest - - - ### macOS ############################################################ - - os: osx - env: OS=macos - script: # Run macOS tests - - rebol -qws tests/run-all.r --batch - - mv quick-test/quick-test.log quick-test/quick-test-red.log - - rebol -qws system/tests/run-all.r --batch - - -###### all ############################################################## -install: - # Linux: hook up qemu, build 32bit image including curl and rebol - - > - if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then - docker run --rm --privileged - multiarch/qemu-user-static:register && - printf - 'FROM i386/debian:latest\n - RUN apt-get update && - apt-get install -y curl libcurl4 && - curl -o /bin/rebol https://static.red-lang.org/tmp/rebol && - chmod +x /bin/rebol\n - ' > Dockerfile && - docker build -t i386/debian:red . ; - fi - # ARMel: build tests on i386 - - > - if [[ ${OS} == "armel" ]]; then - docker run -v ${PWD}:/red -w /red - i386/debian:red rebol -qws tests/build-arm-tests.r '-t Linux-ARM' && - docker run -v ${PWD}:/red -w /red - i386/debian:red rebol -qws system/tests/build-arm-tests.r '-t Linux-ARM' && - docker pull balenalib/armv5e-debian:latest ; - fi - # ARMhf: build tests on i386 - - > - if [[ ${OS} == "armhf" ]]; then - docker run -v ${PWD}:/red -w /red - i386/debian:red rebol -qws tests/build-arm-tests.r '-t RPi' && - docker run -v ${PWD}:/red -w /red - i386/debian:red rebol -qws system/tests/build-arm-tests.r '-t RPi' && - docker pull balenalib/raspberry-pi2-debian:latest ; - fi - # macOS: install rebol - - > - if [[ ${OS} == "macos" ]]; then - sudo curl -o /usr/local/bin/rebol - https://static.red-lang.org/tmp/rebol-osx && - sudo chmod +x /usr/local/bin/rebol ; - fi - - -# If tests fail, change status code and save test logs into Travis logs -after_failure: - - > - STATUS=0 ; - if [[ ${OS} == "armel" ]] || [[ ${OS} == "armhf" ]]; then - cat quick-test/runnable/arm-tests/red/quick-test.log ; - printf '\n\n\n\n' ; - cat quick-test/runnable/arm-tests/system/quick-test.log ; - else - cat quick-test/quick-test-red.log ; - printf '\n\n\n\n' ; - cat quick-test/quick-test.log ; - fi - - -# Notify build status -after_script: - - curl ${STATUS_URL}/${OS}/${STATUS} diff --git a/CI/Linux-32/Dockerfile b/CI/Linux-32/Dockerfile new file mode 100644 index 0000000000..422df992b9 --- /dev/null +++ b/CI/Linux-32/Dockerfile @@ -0,0 +1,4 @@ +FROM i386/ubuntu:18.04 +COPY entrypoint.sh /entrypoint.sh +RUN apt-get update && apt-get -y install curl && curl -o /bin/rebol https://static.red-lang.org/tmp/rebol && chmod +x /bin/rebol +ENTRYPOINT ["/entrypoint.sh"] diff --git a/CI/Linux-32/action.yml b/CI/Linux-32/action.yml new file mode 100644 index 0000000000..1eb6de1521 --- /dev/null +++ b/CI/Linux-32/action.yml @@ -0,0 +1,12 @@ +name: Run on x86 +description: Run a shell command in an Ubuntu 18.04 x86 container +inputs: + command: + description: 'Command to run' + required: true + default: 'lsb_release -a' +runs: + using: 'docker' + image: 'Dockerfile' + args: + - ${{ inputs.command }} diff --git a/CI/Linux-32/entrypoint.sh b/CI/Linux-32/entrypoint.sh new file mode 100755 index 0000000000..24b63767e9 --- /dev/null +++ b/CI/Linux-32/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh -l +set -x +exec bash -x -c "$1" diff --git a/CI/Linux-gtk/Dockerfile b/CI/Linux-gtk/Dockerfile new file mode 100644 index 0000000000..cc1315bc2b --- /dev/null +++ b/CI/Linux-gtk/Dockerfile @@ -0,0 +1,5 @@ +FROM i386/ubuntu:18.04 +COPY entrypoint.sh /entrypoint.sh +ENV DISPLAY :0 +RUN apt-get update && apt-get -y install curl libcurl4 libgtk-3-0 xvfb && curl -o /bin/rebol https://static.red-lang.org/tmp/rebol && chmod +x /bin/rebol +ENTRYPOINT ["/entrypoint.sh"] diff --git a/CI/Linux-gtk/action.yml b/CI/Linux-gtk/action.yml new file mode 100644 index 0000000000..1eb6de1521 --- /dev/null +++ b/CI/Linux-gtk/action.yml @@ -0,0 +1,12 @@ +name: Run on x86 +description: Run a shell command in an Ubuntu 18.04 x86 container +inputs: + command: + description: 'Command to run' + required: true + default: 'lsb_release -a' +runs: + using: 'docker' + image: 'Dockerfile' + args: + - ${{ inputs.command }} diff --git a/CI/Linux-gtk/entrypoint.sh b/CI/Linux-gtk/entrypoint.sh new file mode 100755 index 0000000000..24b63767e9 --- /dev/null +++ b/CI/Linux-gtk/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh -l +set -x +exec bash -x -c "$1" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 3db9ae9f60..8bbb57f341 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,7 +2,7 @@ ## 1. Purpose -We strive to provide a friendly, safe, and welcoming environment for all, generate positive experiences, and make the world a better place. +We strive to provide a friendly, safe, and welcoming environment for all, generate positive experiences and make the world a better place. ## 2. Goal of this Document @@ -33,7 +33,7 @@ The following behaviors are considered harassment and are unacceptable within ou * Inappropriate photography or recording. * Inappropriate physical contact. You should have someone's consent before touching them. * Unwelcome sexual attention, including sexualized comments or jokes, inappropriate touching, and sexual advances. - * Deliberate intimidation, stalking or following (online or in person). + * Deliberate intimidation, stalking or following (online or in-person). * Advocating for, or encouraging, any of the above behavior. * Sustained disruption of community events, including talks and presentations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 67ee5a4385..447e3bdcfc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ There are many ways to contribute to Red in addition to making [donations](http: There are seven different ways to contribute to the Red project: * Make fixes and enhancements to the Red and Red/System core and runtimes -* Write and maintain Red mezzanine functions, modules, objects and schemes +* Write and maintain Red mezzanine functions, modules, objects, and schemes * Write and maintain documentation and documentation systems * Write and maintain Red and Red/System tests * Use Red and Red/System and submit meaningful bug reports @@ -15,18 +15,19 @@ No matter how small, your contribution will be valued and appreciated providing (A simple way for you to confirm both 1 & 2 will be introduced in due course.) 3. A lot of care and attention has been given to the design of both the Red and Red-System languages. Before starting work on anything to change or extend either language, please submit a proposal for your change by raising an issue on the Red project GitHub repository. (It could save you a lot of unnecessary work.) 4. All code submissions should include a reasonable set of tests written with [quick test](http://static.red-lang.org/red-system-quick-test.html). -5. All commit messages submitted to Red repository should be prefixed according to the following conventions: +5. All commit messages submitted to the Red repository should be prefixed according to the following conventions: * `FEAT:` new feature. * `FIX:` ticket or bug fix. If it's a ticket, then the form is: `FIX: issue # ()`. * `TESTS:` new or modified test(s), or testing framework related. * `DOCS:` related to the part of the documentation that is in [red/docs](https://github.com/red/docs) repository. + * `CI:` related to the Continuous Integration build or config scripts in the repo. ### Coding Standards All contributions should adhere to the following coding standards 1. All source code should be UTF-8 encoded. -2. All indents should be made using tabs not spaces and be 4 characters wide. -3. Functions specifications that don't include the datatypes of the arguments and locals should be kept concise. The specification should be on same line as function name, unless it doesn't fit on a line of around 90 characters. If the specification cannot fit on one line, the arguments and locals should be on different lines. If necessary put refinements on a separate line. +2. All indents should be made using tabs, not spaces, and be 4 characters wide. +3. Functions specifications that don't include the datatypes of the arguments and locals should be kept concise. The specification should be on the same line as the function name unless it doesn't fit on a line of around 90 characters. If the specification cannot fit on one line, the arguments and locals should be on different lines. If necessary put refinements on a separate line. 4. Function specifications that include datatypes should follow a vertical layout. 5. End-of-line comments are preferred over between line comments. They should be preceded with ";—-" starting at position 57. ``` @@ -70,10 +71,10 @@ Every code-based contribution should be accompanied by a meaningful set of tests The following approach to writing tests should be used: 1. A separate test file should be used for each functional unit included in your code that you submit. -2. The test must run successfully on Windows, Linux and OS X. +2. The test must run successfully on Windows, Linux, and OS X. 3. Tests should be written for the compiler in preference to the interpreter. 4. Tests should be grouped by functionality. -5. Each test should be independent from all other tests. The results of a test should not be dependent upon the results of any other test. (It should be possible to remove any test from a file and the other tests should still all pass). +5. Each test should be independent of all other tests. The results of a test should not be dependent upon the results of any other test. (It should be possible to remove any test from a file and the other tests should still all pass). 6. Each test should have a unique "name" so that it can be quickly found by searching the test file. 7. The project coding standards should be followed. 8. For short tests both the test header and the assert should be written on a single line. @@ -129,8 +130,8 @@ Contributions to the Red and Red/System core and runtimes should: 3. As much as possible, reflect the coding style of the existing core and runtimes. 4. Follow the existing core and runtime naming conventions and file locations. -### Red mezzanine functions, modules, objects and schemes -In the Red project, mezzanine code refers to functions, modules, objects and schemes written in Red that are included in the Red binary. +### Red mezzanine functions, modules, objects, and schemes +In the Red project, mezzanine code refers to functions, modules, objects, and schemes written in Red that are included in the Red binary. The process for code to be included as Red mezzanine is as follows: @@ -141,7 +142,7 @@ The process for code to be included as Red mezzanine is as follows: At the current stage of Red's development, mezzanine code is not yet being accepted so please do not submit proposals until they are. ### Documentation and documentation systems -At the moment, the content and format of Red documentation has still to be decided, as has the mechanism for automatically generating API documentation from the source. Please contact the Red team if you would like to volunteer. A reliable way to contact the Red team is via the [Red Group](https://groups.google.com/forum/?hl=en#!forum/red-lang). +At the moment, the content and format of Red documentation have still to be decided, as has the mechanism for automatically generating API documentation from the source. Please contact the Red team if you would like to volunteer. A reliable way to contact the Red team is via the [Red Group](https://groups.google.com/forum/?hl=en#!forum/red-lang). ### Red and Red/System tests Writing additional tests is both an easy way to contribute to Red and a good way to learn the finer details of Red and Red/System. All you need to do is find the test file for a feature that you would like to help with and add some tests. Nothing could be easier. diff --git a/README.md b/README.md index d998674db9..9e98338f42 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,109 @@ [![Join the chat at https://gitter.im/red/red](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/red/red?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Windows build](https://bs.red-lang.org/windows.svg)](https://ci.appveyor.com/project/red/red/branch/master) [![Windows build 2](https://github.com/red/red/workflows/Windows/badge.svg)](https://github.com/red/red/actions?query=workflow%3AWindows) -[![macOS build](https://bs.red-lang.org/macos.svg)](https://travis-ci.org/red/red) -[![Linux build](https://bs.red-lang.org/linux.svg)](https://travis-ci.org/red/red) -[![ARMel build](https://bs.red-lang.org/armel.svg)](https://travis-ci.org/red/red) -[![ARMhf build](https://bs.red-lang.org/armhf.svg)](https://travis-ci.org/red/red) +[![Linux build 2](https://github.com/red/red/workflows/Linux-x86/badge.svg)](https://github.com/red/red/actions?query=workflow%3ALinux-x86) +[![ARMhf build 2](https://github.com/red/red/workflows/RPi/badge.svg)](https://github.com/red/red/actions?query=workflow%3ARPi) -Red Programming Language ------------------------- +# Red Programming Language -**Red** is a new programming language strongly inspired by [Rebol](http://rebol.com), but with a broader field of usage thanks to its native-code compiler, from system programming to high-level scripting, while providing modern support for concurrency and multi-core CPUs. +

+ +

-Red has its own complete cross-platform toolchain, featuring two compilers, an interpreter and a linker, not depending on any third-party library, except for a Rebol2 interpreter, required during the bootstrap phase. Once complete, Red will be [self-hosted](http://en.wikipedia.org/wiki/Self-hosting). -The Red software stack also contains another language, **Red/System**, which is a low-level dialect of Red. It is a limited C-level language with a Red look'n feel, required to build Red's runtime library and be the target language of Red's compiler. More information at [red-lang.org](http://www.red-lang.org). +**Red** is a programming language strongly inspired by [Rebol](http://rebol.com), but with a broader field of usage thanks to its native-code compiler, from system programming to high-level scripting, while providing modern support for concurrency and multi-core CPUs. -Making a Red "Hello World" ------------------------- -The Red toolchain comes as a single **one-megabyte** executable file that you can download from [here](http://www.red-lang.org/p/download.html) for the big-3 platforms. +Red tackles the software building complexity using a DSL-oriented approach (we call them _dialects_) . The following dialects are built-in: -1. Put the downloaded **red** binary in the working folder. +* [Red/System](https://static.red-lang.org/red-system-specs-light.html): a C-level system programming language compiled to native code +* [Parse](http://www.red-lang.org/2013/11/041-introducing-parse.html): a powerful PEG parser +* [VID](https://github.com/red/docs/blob/master/en/vid.adoc): a simple GUI layout creation dialect +* [Draw](https://github.com/red/docs/blob/master/en/draw.adoc): a vector 2D drawing dialect +* [Rich-text](https://github.com/red/docs/blob/master/en/rtd.adoc): a rich-text description dialect + + +Red has its own complete cross-platform toolchain, featuring an encapper, a native compiler, an interpreter, and a linker, not depending on any third-party library, except for a Rebol2 interpreter, required during the alpha stage. Once 1.0 is reached, Red will be [self-hosted](http://en.wikipedia.org/wiki/Self-hosting). Currently, Red is still at alpha stage and 32-bit only. + +Red's main features are: + +* Human-friendly [syntax](https://pointillistic.com/ren/) +* [Homoiconic](http://en.wikipedia.org/wiki/Homoiconicity) (Red is its own meta-language and own [data-format](http://www.rebol.com/rebolsteps.html)) +* Functional, imperative, [reactive](http://www.red-lang.org/2016/06/061-reactive-programming.html) and symbolic programming +* Prototype-based object support +* Multi-typing +* Powerful pattern-matching [Macros](http://www.red-lang.org/2016/12/entering-world-of-macros.html) system +* Rich set of built-in datatypes (50+) +* Both statically and JIT-compiled(*) to native code +* Cross-compilation [done](https://github.com/red/red/blob/master/usage.txt) [right](https://github.com/red/red/blob/master/system/config.r) +* Produces executables of less than 1MB, with no dependencies +* Concurrency and parallelism strong support (actors, parallel collections)(*) +* Low-level system programming abilities through the built-in Red/System [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) +* Powerful [PEG parser DSL](http://www.red-lang.org/2013/11/041-introducing-parse.html) built-in +* Fast and compacting Garbage Collector +* Instrumentation built-in for the interpreter, [lexer](https://github.com/red/docs/blob/master/en/lexer.adoc#instrumenting-the-lexer) and parser. +* Cross-platform native [GUI system](http://www.red-lang.org/2016/03/060-red-gui-system.html), with a [UI layout DSL](http://doc.red-lang.org/gui/VID.html) and a [drawing DSL](http://doc.red-lang.org/gui/Draw.html) +* Bridging [to the JVM](https://github.com/red/red/blob/master/bridges/java/hello.red) +* High-level scripting and [REPL](http://en.wikipedia.org/wiki/Read-eval-print_loop) GUI and CLI consoles included +* Visual Studio Code [plugin](https://marketplace.visualstudio.com/items?itemName=red-auto.red), with many helpful features +* Highly [embeddable](http://www.red-lang.org/2017/03/062-libred-and-macros.html) +* Low memory footprint +* Single-file (~1MB) contains whole toolchain, full standard library and REPL (**) +* No install, no setup +* Fun guaranteed! + +(*) Not implemented yet. +(**) Temporarily split in two binaries + +More information at [red-lang.org](https://www.red-lang.org). + +# Running the Red REPL + +[Download](https://www.red-lang.org/p/download.html) a GUI or CLI console binary suitable for your operating system, rename it at your convenience, then run it from shell or by double-clicking on it (Windows). You should see the following output: + + ---== Red 0.6.4 ==-- + Type HELP for starting information. + + >> + +A simple Hello World would look like: + + >> print "Hello World!" + Hello World! + +If you are on the GUI console, a GUI Hello World (prompt omitted): + + view [text "Hello World!"] + +

+ +

+ +A more [sophisticated example](https://github.com/red/code/blob/master/Showcase/last-commits2.red) that retrieves the last commits from this repo and displays their log messages in a scrollable list: + + view [ + text-list data collect [ + foreach event load https://api.github.com/repos/red/red/commits [ + keep event/commit/message + ] + ] + ] + +

+ +

+ + +You can now head to see and try some showcasing scripts [here](https://github.com/red/code/tree/master/Showcase) and [there](https://github.com/red/code/tree/master/Scripts). You can run those examples from the console directly using Github's "raw" link. E.g.: + + >> do https://raw.githubusercontent.com/red/code/master/Showcase/calculator.red + +Note: If you are using the Wine emulator, it has some [issues](https://github.com/red/red/issues/1618) with the GUI-Console. Install the `Consolas` font to fix the problem. + + +# Generating a standalone executable + +The Red toolchain comes as a single executable file that you can [download](https://www.red-lang.org/p/download.html) for the big-3 platforms (32-bit only for now). Rename the file to `redc` (or `redc.exe` under Windows). + +1. Put the downloaded **redc** binary in the working folder. 2. In a code or text editor, write the following Hello World program: @@ -31,35 +115,29 @@ The Red toolchain comes as a single **one-megabyte** executable file that you ca 3. Save it under the name: **hello.red** -4. From a terminal (works from DOS too), run it with: - - $ red hello.red +6. Generate a compiled executable from that program: (first run will pre-compile libRedRT library) -5. You should see the _Hello World!_ output. - -6. Want to generate a compiled executable from that program? - - $ red -c hello.red + $ redc -c hello.red $ ./hello 7. Want to generate a compiled executable from that program with no dependencies? - $ red -r hello.red + $ redc -r hello.red $ ./hello 8. Want to cross-compile to another supported platform? - $ red -t Windows hello.red - $ red -t Darwin hello.red - $ red -t Linux-ARM hello.red + $ redc -t Windows hello.red + $ redc -t Darwin hello.red + $ redc -t Linux-ARM hello.red -**The command-line syntax is:** +**The full command-line syntax is:** - red [command] [options] [file] + redc [command] [options] [file] -`[file]` any Red or Red/System source file. If no file and no option is provided, the graphical interactive console will be launched. If a file with no option is provided, the file will be simply run by the interpreter (it is expected to be a Red script with no Red/System code). +`[file]` any Red or Red/System source file. -Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Windows, the default is to run in GUI mode. To run it in the command line mode, invoke the red binary with the option `--cli`. +* The -c, -r and -u options are mutually exclusive. `[options]` @@ -72,7 +150,7 @@ Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Win -dlib, --dynamic-lib : Generate a shared library from the source file. - -e, --encap : Compile in encap mode, so code is interpreted + -e, --encap : Compile in encap mode, so code is interpreted at runtime. Avoids compiler issues. Required for some dynamic code. @@ -105,25 +183,22 @@ Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Win --no-compress : Omit Redbin format compression. - --catch : Stay in the REPL after the script finishes. - - --cli : Run the command-line REPL instead of the - graphical console. - --no-runtime : Do not include runtime during Red/System source compilation. + --no-view : Do not include VIEW module in the CLI console + and the libRedRT. + --red-only : Stop just after Red-level compilation. Use higher verbose level to see compiler output. (internal debugging purpose) - --show-func-map : Output an address/name map of Red/System + --show-func-map : Output an address/name map of Red/System functions, for debugging purposes. - `[command]` - build libRed [stdcall] : Builds libRed library and unpacks the + build libRed [stdcall] : Builds libRed library and unpacks the libRed/ folder locally. clear [] : Delete all temporary files from current @@ -134,55 +209,32 @@ Cross-compilation targets: MSDOS : Windows, x86, console (+ GUI) applications Windows : Windows, x86, GUI applications WindowsXP : Windows, x86, GUI applications, no touch API - Linux : GNU/Linux, x86 + Linux : GNU/Linux, x86, console (+ GUI) applications + Linux-GTK : GNU/Linux, x86, GUI only applications + Linux-musl : GNU/Linux, x86, musl libc Linux-ARM : GNU/Linux, ARMv5, armel (soft-float) RPi : GNU/Linux, ARMv7, armhf (hard-float) + RPi-GTK : GNU/Linux, ARMv7, armhf (hard-float), GUI only applications Darwin : macOS Intel, console-only applications macOS : macOS Intel, applications bundles Syllable : Syllable OS, x86 FreeBSD : FreeBSD, x86 + NetBSD : NetBSD, x86 Android : Android, ARMv5 Android-x86 : Android, x86 -_Note_: Running the Red toolchain binary from a $PATH currently requires a wrapping shell script (see relevant tickets: [#543](https://github.com/red/red/issues/543) and [#1547](https://github.com/red/red/issues/1547)). - -Running the Red REPL ------------------------ - -1. Just run the `red` binary with no option to access the [REPL](http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop). - - ---== Red 0.6.3 ==-- - Type HELP for starting information. - - >> - -1. You can use it to test rapidly some Red code: - - >> 1 + 2 - == 3 - - >> inc: func [n][n + 1] - == func [n][n + 1] - - >> inc 123 - == 124 - - -Notes: +_Note_: The toolchain executable (`redc.exe`) relies on Rebol encapper which does not support being run from a location specified in `PATH` environment variable and you get `PROGRAM ERROR: Invalid encapsulated data` error. If you are on Windows try using PowerShell instead of CMD. You can also provide the full path to the executable, put a copy of it in your working folder or wrap a shell script (see relevant tickets: [#543](https://github.com/red/red/issues/543) and [#1547](https://github.com/red/red/issues/1547)). -- On Windows, the REPL runs by default in GUI mode. To run it in the command line, invoke the red binary as `red --cli`. -- Wine has some [issues](https://github.com/red/red/issues/1618) with the GUI-Console. Install the `Consolas` font to fix the problem. +# Running Red from the sources (for contributors) -Running Red from the sources (for contributors) ------------------------- The compiler and linker are currently written in Rebol. Please follow the instructions for installing the compiler toolchain in order to run it from sources: 1. Clone this git repository or download an archive (`ZIP` button above or from [tagged packages](https://github.com/red/red/tags)). 1. Download a Rebol interpreter suitable for your OS: [Windows](http://www.rebol.com/downloads/v278/rebol-core-278-3-1.exe), [Linux](http://www.maxvessi.net/rebsite/Linux/) (or [Linux](http://www.rebol.com/downloads/v278/rebol-core-278-4-2.tar.gz)), [Mac OS X](http://www.rebol.com/downloads/v278/rebol-core-278-2-5.tar.gz), [FreeBSD](http://www.rebol.com/downloads/v278/rebol-core-278-7-2.tar.gz), [OpenBSD](http://www.rebol.com/downloads/v278/rebol-core-278-9-4.tar.gz), [Solaris](http://www.rebol.com/downloads/v276/rebol-core-276-10-1.gz). -1. Extract the `rebol` binary, put it in root folder, that's all! +1. Extract the `rebol` binary, put it in the root folder, that's all! 1. Let's test it: run `./rebol`, you'll see a `>>` prompt appear. Windows users need to double-click on the `rebol.exe` file to run it. @@ -192,11 +244,7 @@ The compiler and linker are currently written in Rebol. Please follow the instru The compilation process should finish with a `...output file size` message. The resulting binary is in the working folder. Windows users need to open a DOS console and run `hello.exe` from there. -To see the intermediary Red/System code generated by the compiler, use: - - >> do/args %red.r "-v 2 %tests/hello.red" - -You can also compile the Red console from source: +You can compile the Red console from source: >> do/args %red.r "-r %environment/console/CLI/console.red" @@ -207,22 +255,22 @@ To compile the Windows GUI console from source: Note: the `-c` argument is not necessary when launching the Red toolchain from sources, as the default action is to compile the input script (the toolchain in binary form default action is to run the input script through the interpreter). The `-r` argument is needed when compiling the Red console to make additional runtime functions available. -Note: The red git repository does not include a .gitignore file. If you run the automated tests a number of files will be created that are not stored in the repository. Installing and renaming a copy of [.gitignore-sample](https://github.com/red/red/blob/master/.gitignore-sample) file will ignore these generated files. +Note: The red git repository does not include a `.gitignore` file. If you run the automated tests, several files will be created that are not stored in the repository. Installing and renaming a copy of [`.git/.gitignore-sample`](https://github.com/red/red/blob/master/.gitignore-sample) file will ignore these generated files. + +# Contributing -Contributing -------------------------- If you want to contribute code to the Red project be sure to read the [guidelines](https://github.com/red/red/wiki/%5BDOC%5D-Contributor-Guidelines) first. -It is usually a good idea to inform the Red team about what changes you are going to make in order to ensure that someone is not already working on the same thing. You can reach us through the [mailing-list](https://groups.google.com/forum/?hl=en#!forum/red-lang) or our [chat room](https://gitter.im/red/red). +It is usually a good idea to inform the Red team about what changes you are going to make in order to ensure that someone is not already working on the same thing. You can reach us through our [chat room](https://gitter.im/red/red). Satisfied with the results of your change and want to issue a pull request on Github? -Make sure the changes pass all the existing tests, add relevant tests to the test-suite and please test on as many platforms as you can. You can run all the tests using (from Rebol console, at repository root): +Make sure the changes pass all the existing tests, add relevant tests to the test-suite, and please test on as many platforms as you can. You can run all the tests using (from Rebol console, at repository root): - >> do %run-all.r + >> do %run-all-tests.r + +# Git integration with console built from sources -Git integration with console built from sources -------------------------- If you want git version included in your Red console built from sources, use this command: ```Red call/show "" ;-- patch call bug on Windows @@ -231,10 +279,10 @@ do/args %red.r "-r %environment/console/CLI/console.red" ;-- build Console write %build/git.r "none^/" ;-- restore git repo status ``` -Anti-virus false positive -------------------------- -Some anti-virus programs are a bit too sensitive and can wrongly report an alert on some binaries generated by Red, if that happens to you, please fill a ticket [here](https://github.com/red/red/issues), so we can report the false positive. +# Anti-virus false positive + +Some anti-virus programs are a bit too sensitive and can wrongly report an alert on some binaries generated by Red (see [here](https://github.com/red/red/wiki/%5BNOTE%5D-Anti-virus-false-positives) for the details). If that happens to you, please report it to your anti-virus vendor as a false positive. + +# License -License -------------------------- Both Red and Red/System are published under [BSD](http://www.opensource.org/licenses/bsd-3-clause) license, runtime is under [BSL](http://www.boost.org/users/license.html) license. BSL is a bit more permissive license than BSD, more suitable for the runtime parts. diff --git a/bridges/java/bridge.red b/bridges/java/bridge.red index f6f9635b45..4bff715d92 100644 --- a/bridges/java/bridge.red +++ b/bridges/java/bridge.red @@ -14,7 +14,7 @@ Red [ #define node! int-ptr! ;-- required for Red datatypes definitions #include %../../system/bridges/java/JNI.reds - #include %../../runtime/datatypes/structures.reds + #include %../../runtime/structures.reds env: as JNI-env! 0 jni: as JNI! 0 diff --git a/build/README.md b/build/README.md index 350e3354d8..09f95ad6b9 100644 --- a/build/README.md +++ b/build/README.md @@ -1,7 +1,7 @@ Building Red binaries ------------------------ -_Note: This is **not** required to build or run red from sources. It is for a feature used by the red team. Check the [main readme](/README.md#running-red-from-the-sources) if you want to build red from sources_ +_Note: This is **not** required to build or run red from sources. It is for a feature used by the red team. Check the [main readme](/README.md#running-red-from-the-sources-for-contributors) if you want to build red from sources_ _Prerequisite_ diff --git a/build/git-version.r b/build/git-version.r index 412ee28361..8c91e2329c 100644 --- a/build/git-version.r +++ b/build/git-version.r @@ -24,6 +24,8 @@ context [ ] set 'git-version has [temp] [ + if all [system/version/4 = 3 not find get-env "PATH" "git"][return none] + attempt [ temp: parse git "describe --long" "-" compose/deep [ diff --git a/build/git.r b/build/git.r deleted file mode 100644 index c86c3f3551..0000000000 --- a/build/git.r +++ /dev/null @@ -1 +0,0 @@ -none \ No newline at end of file diff --git a/build/includes.r b/build/includes.r index 20d72188f7..7c81773b5c 100644 --- a/build/includes.r +++ b/build/includes.r @@ -8,24 +8,26 @@ REBOL [ ] change-dir %.. -do %system/utils/encap-fs.r +do %utils/encap-fs.r write %build/bin/sources.r set-cache [ - %version.r - %usage.txt - %boot.red - %compiler.r - %lexer.r %build/ [ %git.r ] + %encapper/ [ + %version.r + %usage.txt + %boot.red + %compiler.r + %lexer.r + %modules.r + ] %environment/ [ %actions.red %colors.red ;%css-colors.red %datatypes.red %functions.red - %lexer.red %natives.red %networking.red %operators.red @@ -33,13 +35,15 @@ write %build/bin/sources.r set-cache [ %routines.red %scalars.red %system.red + %tools.red %codecs/ [ - %bmp.red - %gif.red - %jpeg.red - %png.red - %csv.red - %json.red + %BMP.red + %GIF.red + %JPEG.red + %PNG.red + %CSV.red + %JSON.red + %redbin.red ] %console/ [ %auto-complete.red @@ -76,6 +80,7 @@ write %build/bin/sources.r set-cache [ %case-folding.reds %clipboard.reds %collector.reds + %common.reds %compress.reds %crush.reds %crypto.reds @@ -84,7 +89,10 @@ write %build/bin/sources.r set-cache [ %deflate.reds %dtoa.reds %hashtable.reds + %image-utils.reds %interpreter.reds + %lexer.reds + %lexer-transitions.reds %macros.reds %natives.reds %ownership.reds @@ -96,20 +104,22 @@ write %build/bin/sources.r set-cache [ %simple-io.reds %sort.reds %stack.reds + %structures.reds %threads.reds %tokenizer.reds %tools.reds %unicode.reds %utils.reds + %vector2d.reds %datatypes/ [ %action.reds %block.reds %bitset.reds %binary.reds %char.reds - %common.reds %context.reds %datatype.reds + %date.reds %email.reds %error.reds %event.reds @@ -118,6 +128,7 @@ write %build/bin/sources.r set-cache [ %function.reds %get-path.reds %get-word.reds + %handle.reds %hash.reds %image.reds %integer.reds @@ -126,6 +137,7 @@ write %build/bin/sources.r set-cache [ %lit-word.reds %logic.reds %map.reds + %money.reds %native.reds %none.reds %op.reds @@ -136,13 +148,13 @@ write %build/bin/sources.r set-cache [ %percent.reds %point.reds %port.reds + %ref.reds %refinement.reds %routine.reds %series.reds %set-path.reds %set-word.reds %string.reds - %structures.reds %symbol.reds %tag.reds %time.reds @@ -152,19 +164,20 @@ write %build/bin/sources.r set-cache [ %url.reds %vector.reds %word.reds - %handle.reds - %date.reds ] %platform/ [ %android.reds %darwin.reds %freebsd.reds + %netbsd.reds %linux.reds %POSIX.reds %syllable.reds %win32.reds %COM.reds + %image-wic.reds %image-gdiplus.reds + %image-gdk.reds %image-quartz.reds %win32-ansi.reds %win32-print.reds @@ -186,10 +199,12 @@ write %build/bin/sources.r set-cache [ %base.reds %button.reds %camera.reds + %calendar.reds %classes.reds %comdlgs.reds %direct2d.reds - %draw-d2d.reds + %matrix2d.reds + %draw-gdi.reds %draw.reds %events.reds %font.reds @@ -220,6 +235,26 @@ write %build/bin/sources.r set-cache [ %tab-panel.reds %text-box.reds ] + %gtk3/ [ + %camera.reds + %camera-dev.reds + %color.reds + %comdlgs.reds + %css.reds + %draw.reds + %events.reds + %font.reds + %gtk.reds + %gui.reds + %handlers.reds + %menu.reds + %para.reds + %rules.red + %tab-panel.reds + %text-box.reds + %text-list.reds + %v4l2.reds + ] %test/ [ %draw.reds %events.reds @@ -265,6 +300,7 @@ write %build/bin/sources.r set-cache [ %darwin.reds %debug.reds %freebsd.reds + %netbsd.reds %libc.reds %lib-names.reds %lib-natives.reds diff --git a/build/precap.r b/build/precap.r index 2877014b00..9729cb75cf 100644 --- a/build/precap.r +++ b/build/precap.r @@ -9,7 +9,7 @@ REBOL [ ] #include %encap-paths.r -#include %../system/utils/encap-fs.r +#include %../utils/encap-fs.r do #include-string %bin/sources.r build-date: #include %timestamp.r diff --git a/docs/conversion-matrix.xlsx b/docs/conversion-matrix.xlsx index 90e1c9637b..be47df3360 100644 Binary files a/docs/conversion-matrix.xlsx and b/docs/conversion-matrix.xlsx differ diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv new file mode 100644 index 0000000000..405d1248cd --- /dev/null +++ b/docs/lexer/lexer-FSM.csv @@ -0,0 +1,63 @@ +;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_H;C_E_LOW;C_E_UP;C_ALPHAL;C_ALPHAU;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_EQUAL;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_C0;C_BIN;C_WORD;C_ILLEGAL;C_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD_1ST;S_WORD_1ST;S_WORD;S_WORD;S_WORD;S_WORD;S_HEX;S_WORD;S_HEX;S_SLASH_1ST;T_ERROR;S_LESSER;S_WORD;S_EQUAL;S_FILE_1ST;T_ERROR;S_LINE_CMT;S_REF;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;S_WORD;S_START;T_ERROR;S_WORD;T_ERROR;T_EOF +S_LINE_CMT;S_LINE_CMT;T_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_CMT +S_LINE_STR;S_LINE_STR;T_ERROR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR +S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;S_HERDOC_ST;T_WORD;S_FILE_STR;S_FILE;S_FILE;S_PERCENT;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_HDPER_ST;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE +S_FILE_STR;S_FILE_STR;T_ERROR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR +S_HDPER_ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;S_HERDOC_ST;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_HDPER_ST;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;T_ERROR;T_WORD +S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR +S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_CL;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR +S_HDPER_CL;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_ERROR;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;S_HDPER_CL;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING +S_SLASH_1ST;T_WORD;T_WORD;S_SLASH;S_SLASH;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_SLASH;S_WORDSET;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH_N;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_WORD;T_WORD;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_WORD;S_SLASH;S_SLASH;T_ERROR;T_WORD +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_ERROR;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SLASH_N;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH_N;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;T_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_SHARP;T_ERROR;T_ERROR;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_ERROR +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR +S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_HEX_END2;S_DECEXP;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;S_DECIMAL;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;S_EMAIL;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECEXP;T_FLOAT;T_FLOAT;S_DECEXP;S_DECEXP;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;S_EMAIL;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_HEX_END2;T_ERROR;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_ERROR;T_FLOAT_SP;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP +S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;S_DATE;T_DATE;T_ERROR;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE +S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;S_TIME;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;S_EMAIL;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;S_MONEY_DEC;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY +S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;T_HEX;S_WORD;S_WORD;T_ERROR;T_HEX +S_HEX_END2;T_HEX;T_HEX;T_ERROR;T_ERROR;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PATH;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX;S_EMAIL;T_ERROR;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_HEX +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG_STR2;S_WORDSET;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_LESSER;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_TAG;T_WORD;S_TAG;S_TAG;T_ERROR;T_WORD +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_MONEY;S_WORD;S_WORD;T_ERROR;T_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH_1ST;T_ERROR;S_LESSER;S_WORD;S_EQUAL;S_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY_1ST;S_WORD;S_WORD;S_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;T_ERROR;T_WORD +S_PERCENT;T_WORD;T_WORD;T_ERROR;T_ERROR;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;S_PERCENT;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_WORD +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;S_URL;T_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_URL;S_URL;S_URL;T_ERROR;T_URL +S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL +S_REF;T_REF;T_REF;S_REF;S_REF;T_REF;T_REF;T_REF;T_REF;T_REF;T_REF;T_REF;T_ERROR;T_ERROR;S_REF;S_REF;S_REF;S_REF;S_REF;S_REF;S_REF;S_REF;S_REF;T_ERROR;T_REF;T_ERROR;T_ERROR;S_REF;T_ERROR;T_REF;T_ERROR;S_REF;T_ERROR;S_REF;S_REF;T_ERROR;T_REF;S_REF;S_REF;T_ERROR;T_REF +S_EQUAL;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_W1ST;S_PATH_W1ST;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_REF;S_PATH_WORD;S_MONEY_1ST;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_PATH_NUM;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_W1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;S_MONEY_1ST;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD +S_PATH_SHARP;T_ERROR;T_ERROR;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR +S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_MONEY_1ST;S_WORD;S_WORD;T_ERROR;T_WORD;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx new file mode 100644 index 0000000000..eb53d097d9 Binary files /dev/null and b/docs/lexer/lexer-FSM.xlsx differ diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt new file mode 100644 index 0000000000..5180cc254c --- /dev/null +++ b/docs/lexer/lexer-states.txt @@ -0,0 +1,493 @@ + +=== Lexical Scanner FSM === + +--- FSM states --- + +S_START +S_LINE_CMT +S_LINE_STR +S_SKIP_STR +S_M_STRING +S_SKIP_MSTR +S_FILE_1ST +S_FILE +S_FILE_STR +S_HDPER_ST +S_HERDOC_ST +S_HDPER_C0 +S_HDPER_CL +S_SLASH_1ST +S_SLASH +S_SLASH_N +S_SHARP +S_BINARY +S_LINE_CMT2 +S_CHAR +S_SKIP_CHAR +S_CONSTRUCT +S_ISSUE +S_NUMBER +S_DOTNUM +S_DECIMAL +S_DECEXP +S_DECX +S_DEC_SPECIAL +S_TUPLE +S_DATE +S_TIME_1ST +S_TIME +S_PAIR_1ST +S_PAIR +S_MONEY_1ST +S_MONEY +S_MONEY_DEC +S_HEX +S_HEX_END +S_HEX_END2 +S_LESSER +S_TAG +S_TAG_STR +S_TAG_STR2 +S_SIGN +S_DOTWORD +S_DOTDEC +S_WORD_1ST +S_WORD +S_WORDSET +S_PERCENT +S_URL +S_EMAIL +S_REF +S_EQUAL +S_PATH +S_PATH_NUM +S_PATH_W1ST +S_PATH_WORD +S_PATH_SHARP +S_PATH_SIGN +T_EOF +T_ERROR +T_BLK_OP +T_BLK_CL +T_PAR_OP +T_PAR_CL +T_MSTR_OP +T_MSTR_CL +T_MAP_OP +T_PATH +T_CONS_MK +T_CMT +T_STRING +T_WORD +T_ISSUE +T_INTEGER +T_REFINE +T_CHAR +T_FILE +T_BINARY +T_PERCENT +T_FLOAT +T_FLOAT_SP +T_TUPLE +T_DATE +T_PAIR +T_TIME +T_MONEY +T_TAG +T_URL +T_EMAIL +T_HEX +T_RAWSTRING +T_REF + +--- Lexical classes --- + +C_BLANK : space, tab, cr +C_LINE : lf +C_DIGIT : 1-9 +C_ZERO : 0 +C_BLOCK_OP : [ +C_BLOCK_CL : ] +C_PAREN_OP : [ +C_PAREN_CL : ] +C_STRING_OP : { +C_STRING_CL : } +C_DBL_QUOTE : " +C_SHARP : # +C_QUOTE : ' +C_COLON : : +C_X : x, X +C_T : T +C_H : h +C_E_LOW : e +C_E_UP : E +C_ALPHAL : a-d,f +C_ALPHAU : A-D,F +C_SLASH : / +C_BSLASH : \ +C_LESSER : < +C_GREATER : > +C_EQUAL : = +C_PERCENT : % +C_COMMA : , +C_SEMICOL : ; +C_AT : @ +C_DOT : . +C_MONEY : $ +C_PLUS : + +C_MINUS : - +C_CARET : ^ +C_C0 : 0x01-0x08, 0x0B-0x0C, 0x0E-0x1F +C_BIN : 0x7F-0xBF +C_WORD : all the rest +C_ILLEGAL : 0xC0-0xC1, 0xF5-0xFF +C_EOF : NUL + +--- Character groups --- + +ws: space | tab | cr | lf +dbl-quote: " + +delimit0: # | ' | < | % | ^ +delimit7: ws | ] | ) | } | : | < | > | , +delimit5: ws | [ | ] | ( | ) | } | ; | @ | EOF +delimit14: ws | [ | ] | ( | ) | { | " | ; | < | EOF +delimit4: ws | [ | ] | ( | ) | } | ; | " | \ | EOF +delimit1: ws | [ | ] | ( | ) | { | } | " | ; | @ | EOF +delimit6: ws | [ | ] | ( | ) | { | } | ; | @ | : | EOF +delimit8: ws | [ | ] | ( | ) | { | } | " | ; | < | EOF +delimit20: ws | [ | ] | ( | ) | { | } | " | ; | \ | EOF +delimit23: ws | [ | ] | ( | ) | { | } | " | ; | @ | # | EOF +delimit12: ws | [ | ] | ( | ) | { | } | " | ; | \ | # | EOF +delimit15: ws | [ | ] | ( | ) | { | } | " | : | ; | # | EOF +delimit24: ws | [ | ] | ( | ) | { | } | " | ; | / | \ | EOF +delimit9: ws | [ | ] | ( | ) | { | } | " | ; | < | / | EOF +delimit22: ws | [ | ] | ( | ) | { | } | " | ; | < | \ | EOF +delimit16: ws | [ | ] | ( | ) | { | } | " | ; | < | \ | # | EOF +delimit10: ws | [ | ] | ( | ) | { | } | " | ; | < | / | : | EOF +delimit17: ws | [ | ] | ( | ) | { | } | " | ; | < | \ | / | EOF +delimit19: ws | [ | ] | { | } | ; | / | \ | % | , | $ | ^ | EOF +delimit21: ws | [ | ] | ( | ) | { | } | " | : | ; | / | \ | EOF +delimit2: ws | [ | ] | ( | ) | { | } | " | ; | < | # | : | / | EOF +delimit11: ws | [ | ] | ( | ) | { | } | " | ; | < | / | \ | 0-9 | EOF +delimit18: ws | [ | ] | ( | ) | { | } | : | ; | < | > | = | , | @ | / | EOF +delimit3: ws | [ | ] | ( | ) | { | } | " | % | ; | < | # | @ | / | \ | ^ | , | : | $ | EOF + + +hexa: C_ZERO | C_DIGIT | C_ALPHAX +alphaU: A, B, C, D, F +s-word: C_X | T | h | e | C_ALPHAL | > | = | C_BIN | C_WORD +word1st: C_X | T | h | e | E | C_ALPHAL | C_ALPHAU | < | > | = | . | + | - | C_BIN | C_WORD +word1st!=: C_X | T | h | e | E | C_ALPHAL | C_ALPHAU | < | > | . | + | - | C_BIN | C_WORD +p-word1st: C_X | T | h | e | E | C_ALPHAL | C_ALPHAU | > | = | . | C_BIN | C_WORD +p-word: 0-9 | ' | C_X | T | h | e | E | C_ALPHAL | C_ALPHAU | < | > | = | . | + | - | ^ | C_BIN | C_WORD + +--- FSM transitions --- + +S_START->ws->S_START + +S_START->";"->S_LINE_CMT->not(lf)->S_LINE_CMT + \->lf->T_CMT + +S_START->"["->T_BLK_OP +S_START->"]"->T_BLK_CL +S_START->"("->T_PAR_OP +S_START->")"->T_PAR_CL +S_START->"{"->T_MSTR_OP +S_START->"{"->T_MSTR_OP +S_START->"}"->T_ERROR + +S_START->dbl-quote->S_LINE_STR->not("^"|dbl-quote)->S_LINE_STR + \->"^"->S_SKIP_STR->*->S_LINE_STR + \->dbl-quote->T_STRING + +S_M_STRING->not("^"|"{"|"}")->S_M_STRING + \->"^"->S_SKIP_MSTR->not(EOF)->S_M_STRING + \ \->EOF->T_ERROR + \->"{"->T_MSTR_OP + \->"}"->T_MSTR_CL + +S_START->"/"->S_SLASH_1ST->not(delimit1)->S_SLASH->not(delimit1|":"|"/")->S_SLASH + \ \->delimit1|"/"->T_REFINE + \ \->":"->T_ERROR + \->delimit23->T_WORD + \->"/"->S_SLASH_N->"/"->S_SLASH_N + \->delimit23->T_WORD + \->not(delimit23|"/")->S_WORD + +S_START->"%"->S_FILE_1ST->not(delimit5)->S_FILE->not(delimit6)->S_FILE + \ \->delimit6->T_FILE + \ + \->dbl-quote->S_FILE_STR->not(dbl-quote)->S_FILE_STR + \ \->dbl-quote->T_FILE + \ + \->"%"->S_HDPER_ST->"%"->S_HDPER_ST + \ \->"{"->S_HERDOC_ST + \ \->delimit4->T_WORD + \ \->EOF->T_ERROR + \ \->else->S_FILE + \ + \->"{"->S_HERDOC_ST->"}"->S_HDPER_C0->"%"|"}"->S_HDPER_CL->"%"->S_HDPER_CL + \ \ \ \ + \ \ \ \->delimit14->T_RAWSTRING + \ \ \ \->else->T_ERROR + \ \ \->else->S_HERDOC_ST + \ \->else->S_HERDOC_ST + \ + \->":"->S_PERCENT + \->delimit5->T_WORD + + +S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws|"/"|"="|"+"->S_BINARY + \ \->";"->S_LINE_CMT2->not(lf|EOF)->S_LINE_CMT2 + \ \ \->lf->S_BINARY + \ \ \->EOF->T_ERROR + \ \ + \ \->"}"->T_BINARY + \ + \->dbl-quote->S_CHAR->not("^"|dbl-quote|EOF)->S_CHAR + \ \->"^"->S_SKIP_CHAR->*->S_CHAR + \ \->dbl-quote->T_CHAR + \ \->EOF->T_ERROR + \ + \->"("->T_MAP_OP + \ + \->"["->S_CONSTRUCT->not("]"|EOF)->S_CONSTRUCT + \ \->"]"->T_CONS_MK + \ \->EOF->T_ERROR + \ + \->not(delimit7)->S_ISSUE->not(delimit1|"/"|":")->S_ISSUE + \ \->delimit1->T_ISSUE + \ \->"/"|":"->T_ERROR + \->delimit7->T_ERROR + + +S_START->digit->S_NUMBER->digit|"'"->S_NUMBER + \->delimit8->T_INTEGER + \->"."|","->S_DOTNUM->digit->S_DECIMAL->digit|"-"->S_DECIMAL + \ \ \->"e"|"E"->S_DECEXP->digit|"+"|"-"->S_DECEXP + \ \ \ \->delimit10->T_FLOAT + \ \ \ \->else->T_ERROR + \ \ \ + \ \ \->"."->S_TUPLE->digit|"."->S_TUPLE + \ \ \ \->delimit10->T_TUPLE + \ \ \ \->else->T_ERROR + \ \ \ + \ \ \->"%"->T_PERCENT + \ \ \->"x"|"X"->S_PAIR_1ST + \ \ \->delimit10->T_FLOAT + \ \ \->else->T_ERROR + \ \ + \ \->"#"->S_DEC_SPECIAL->not(delimit11)->S_DEC_SPECIAL + \ \ \->delimit11->T_FLOAT_SP + \ \ + \ \->"%"->T_PERCENT + \ \->"x"|"X"->S_PAIR_1ST + \ \->"e"|"E"->S_DECEXP + \ \->delimit9->T_FLOAT + \ \->else->T_ERROR + \ + \->"/"|"T"|"-"->S_DATE->not(delimit8|"%"|"@"|"^")->S_DATE + \ \->delimit8->T_DATE + \ \->"%"|"@"|"^"->T_ERROR + \ + \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME + \ \->else->T_ERROR \->delimit9->T_TIME + \ \->else->T_ERROR + \ + \->"x"|"X"->S_PAIR_1ST->digit|sign->S_PAIR->digit|"."|"e"|"E"->S_PAIR + \ \->"@"->S_EMAIL \->"@"->S_EMAIL + \ \->else->T_ERROR \->delimit10->T_PAIR + \ \->else->T_ERROR + \ + \->"%"->T_PERCENT + \->"#"->S_SHARP + \->"@"->S_EMAIL + \->"e"->S_DECEXP + \->"E"->S_DECX->digit->S_DECX + \ \->"+"|"-"->S_DECEXP + \ \->alphaU|"E"->S_HEX + \ \->"h"->S_HEX_END2 + \ \->"%"->T_PERCENT + \ \->"@"->S_EMAIL + \ \->"."->S_TUPLE + \ \->delimit10->T_FLOAT + \ \->else->T_ERROR + \ + \->alphaU->S_HEX + \->"h"->S_HEX_END2 + \->else->T_ERROR + + +S_START->"."->S_DOTWORD->digit->S_DOTDEC->digit|"e"|"E"|"+"|"-"->S_DOTDEC + \ \->"%"->T_PERCENT + \ \->"@"->S_EMAIL + \ \->delimit10->T_FLOAT + \ \->else->T_ERROR + \ + \->delimit12->T_WORD + \->":"->S_WORDSET + \->"@"->S_EMAIL + \->"/"->T_PATH + \->","|"%"|"$"->T_ERROR + \->not(delimit12|":"|"@"|"/"|","|"%"|"$")->S_WORD + + +S_START->"<"->S_LESSER + \->delimit15->T_WORD + \->"<"->S_LESSER + \->">"|"="->S_WORD + \->else->S_TAG + \->dbl-quote->S_TAG_STR->not(dbl-quote)->S_TAG_STR + \ \->dbl-quote->S_TAG + \ + \->"'"->S_TAG_STR2->not("'")->S_TAG_STR2 + \ \->"'"->S_TAG + \ + \->">"->T_TAG + \->EOF->T_ERROR + \->else->S_TAG + + +S_START->"+"|"-"->S_SIGN->digit->S_NUMBER + \->"$"->S_MONEY + \"."->S_DOTWORD + \->"'"|"<"|"%"|"^"->T_ERROR + \->delimit12->T_WORD + \->else->S_WORD + + +S_START->"="->S_EQUAL->p-word->S_WORD + \->":"->S_WORDSET + \->delimit24->T_WORD + \->else->T_ERROR + + +S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit|"'"->S_MONEY + \->else->T_ERROR \->"."|","->S_MONEY_DEC->digit|"'"->S_MONEY_DEC + \ \->delimit2->T_MONEY + \ \->else->T_ERROR + \ + \->delimit2->T_MONEY + \->else->T_ERROR + + +S_START->alphaU|"E"->S_HEX->alphaU|digit|"E"->S_HEX + \->delimit12->T_WORD + \->":"->S_WORDSET + \->"@"->S_EMAIL + \->"/"->T_PATH + \->"$"->S_MONEY + \->"h"->S_HEX_END + \->","|"%"->T_ERROR + \->else->S_WORD + +S_START->"'"|":"->S_WORD_1ST->"%"->S_PERCENT + \ \->":"->T_ERROR + \ \->delimit3->T_WORD + \ \->else->T_ERROR + \->"/"->S_SLASH_1ST + \->"="->S_EQUAL + \->word1st!=->S_WORD + \->else->T_ERROR + +S_START->s-word->S_WORD->delimit16->T_WORD + \->":"->S_WORDSET->else->S_URL->delimit22->T_URL + \ \ \->">"|"^"->T_ERROR + \ \ \->else->S_URL + \ \->delimit16->T_WORD + \ \->"<"->T_ERROR + \ + \->"@"->S_EMAIL->else->S_EMAIL + \ \->delimit17->T_EMAIL + \ \->"@"|">"|"="|","|"^"|"$"|":"|"'"|"#"->T_ERROR + \ + \->"/"->T_PATH + \->"$"->S_MONEY_1ST + \->","|"%"->T_ERROR + \->else->S_WORD + +S_START->"@"->S_REF->delimit8->T_REF + \->"#"|"'"|"\"|">"|"="|","|"@"|"$"|"^"->T_ERROR + \->else->S_REF + + +S_PATH->delimit19->T_ERROR +S_PATH->"("->T_PAR_OP +S_PATH->")"->T_PAR_CL +S_PATH->dbl-quote->S_LINE_STR + +S_PATH->"#"->S_PATH_SHARP->dbl-quote->S_CHAR + \->delimit18->T_ERROR + \->else->S_ISSUE->delimit1->T_ISSUE + \->else->S_ISSUE + + +S_PATH->digit->S_PATH_NUM->digit|"'"->S_PATH_NUM + \->delimit9->T_INTEGER + \->"%"->T_PERCENT + \->"."->S_DOTNUM + \->"x"|"X"->S_PAIR_1ST + \->"e"|"E"->S_DECEXP + \->else->T_ERROR + +S_PATH->"<"->S_LESSER + +S_PATH->"+"|"-"->S_PATH_SIGN->digit->S_PATH_NUM + \->"$"->S_MONEY_1ST + \->delimit20->T_WORD + \->delimit0->T_ERROR + \->else->S_WORD + +S_PATH->"$"->S_MONEY_1ST +S_PATH->"@"->S_REF + +S_PATH->"'"|":"->S_PATH_W1ST->word1st->S_PATH_WORD + \->else->T_ERROR + +S_PATH->p-word1st->S_PATH_WORD->p-word->S_PATH_WORD + \->delimit21->T_WORD + \->"@"->S_EMAIL + \->","|"#"|"%"|"$"->T_ERROR + + +=== Binary16 classes === + +C_BIN_ILLEGAL : all the rest ;-- 0 +C_BIN_BLANK : space, tab, cr, lf ;-- 1 +C_BIN_HEXA : 0-9, a-f, A-F ;-- 2 +C_BIN_CMT : ; ;-- 3 + +=== Float FSM === + +C_FL_ILLEGAL : all the rest ;-- 0 +C_FL_SIGN : +, - ;-- 1 +C_FL_DIGIT : 0-9 ;-- 2 +C_FL_EXP : e, E ;-- 3 +C_FL_DOT : ., ;-- 4 +C_FL_QUOTE : ' ;-- 5 + +S_FL_START ;-- 0 +S_FL_NUM ;-- 1 +S_FL_DEC ;-- 2 +S_FL_EXP ;-- 3 +S_FL_EXPS ;-- 4 +S_FL_EXPD ;-- 5 +T_FL_FLOAT ;-- 6 +T_FL_ERROR ;-- 7 + + +S_FL_START->"+"|"-"->S_FL_START + +S_FL_START->"."|","->S_FL_DEC + \->digit->S_FL_NUM->digit|"'"->S_FL_NUM + \->"."|","->S_FL_DEC + \->"e"|"E"->S_FL_EXP + +S_FL_DEC->digit|"'"->S_FL_DEC + \->"e"|"E"->S_FL_EXP + +S_FL_EXP->"+"|"-"->S_FL_EXPS->digit->S_FL_EXPD + \->digit->S_FL_EXPD + +S_FL_EXPD->digit->S_FL_EXPD \ No newline at end of file diff --git a/docs/comparison-matrix.red b/docs/old/comparison-matrix.red similarity index 100% rename from docs/comparison-matrix.red rename to docs/old/comparison-matrix.red diff --git a/docs/emit-block.r b/docs/old/emit-block.r similarity index 100% rename from docs/emit-block.r rename to docs/old/emit-block.r diff --git a/docs/emit-reds-api-html.r b/docs/old/emit-reds-api-html.r similarity index 100% rename from docs/emit-reds-api-html.r rename to docs/old/emit-reds-api-html.r diff --git a/docs/emit-reds-api-md2.r b/docs/old/emit-reds-api-md2.r similarity index 100% rename from docs/emit-reds-api-md2.r rename to docs/old/emit-reds-api-md2.r diff --git a/docs/generate-reds-api.r b/docs/old/generate-reds-api.r similarity index 100% rename from docs/generate-reds-api.r rename to docs/old/generate-reds-api.r diff --git a/docs/make-to-matrix-html.r b/docs/old/make-to-matrix-html.r similarity index 100% rename from docs/make-to-matrix-html.r rename to docs/old/make-to-matrix-html.r diff --git a/docs/to-matrix-template.html b/docs/old/to-matrix-template.html similarity index 100% rename from docs/to-matrix-template.html rename to docs/old/to-matrix-template.html diff --git a/docs/to-matrix.html b/docs/old/to-matrix.html similarity index 100% rename from docs/to-matrix.html rename to docs/old/to-matrix.html diff --git a/docs/to-matrix.red b/docs/old/to-matrix.red similarity index 100% rename from docs/to-matrix.red rename to docs/old/to-matrix.red diff --git a/docs/dark.css b/docs/red-system/dark.css similarity index 100% rename from docs/dark.css rename to docs/red-system/dark.css diff --git a/docs/light.css b/docs/red-system/light.css similarity index 100% rename from docs/light.css rename to docs/red-system/light.css diff --git a/docs/makedoc2.r b/docs/red-system/makedoc2.r similarity index 100% rename from docs/makedoc2.r rename to docs/red-system/makedoc2.r diff --git a/docs/red-system-quick-test.txt b/docs/red-system/red-system-quick-test.txt similarity index 100% rename from docs/red-system-quick-test.txt rename to docs/red-system/red-system-quick-test.txt diff --git a/docs/red-system-specs.txt b/docs/red-system/red-system-specs.txt similarity index 95% rename from docs/red-system-specs.txt rename to docs/red-system/red-system-specs.txt index 4faf4f21ac..f64c5b1709 100644 --- a/docs/red-system-specs.txt +++ b/docs/red-system/red-system-specs.txt @@ -1,8 +1,8 @@ Red/System Language Specification Author: Nenad Rakocevic - Date: 05/09/2019 - Revision: 56 + Date: 08/09/2022 + Revision: 60 Status: reference document Home: red-lang.org @@ -128,7 +128,7 @@ Variables can hold any value of the available datatypes. This can be the real va bar: "hello" \note Multiple assignments -Multiple assignments, like a: b: 123, are not currently supported in Red/System. Such a feature will be added in the future at some point, probably on the rewrite of Red/System in Red. +Multiple assignments, like a: b: 123, are currently partially supported in Red/System through "assignment grouping". It is acting like a macro expansion where the pattern a: b: 123 would be expanded to a: 123 b: 123. It will duplicate whatever value is assigned to each variable, so special care is needed when using it. /note @@ -495,7 +495,11 @@ will output Struct! datatype is roughly equivalent to C struct type. It is a record of one or several values, each value having its own datatype. A struct variable holds the memory address of a struct value. -Implementation note: Struct! values members are padded in memory in order to preserve optimal alignment for each target (for example, it is aligned to 4 bytes for IA32 target). Size? function will return the size of the struct! value in memory including the padding bytes. +Implementation notes: + +* Struct! values members are padded in memory in order to preserve optimal alignment for each target (for example, it is aligned to 4 bytes for IA32 target). Size? function will return the size of the struct! value in memory including the padding bytes. + +* Structs declared as values do not hold any pointer as their content is inlined, so their memory location is fixed and cannot be changed by the user. +++Declaration @@ -508,12 +512,12 @@ Declaring a struct! value is achieved by using the DECLARE STRUCT! sequence foll : a valid identifier : integer! | byte! | logic! | float! | float32! | c-string! | - pointer! [integer! | byte! | float! | float64! | float32!] | + pointer! [integer! | byte! | float! | float64! | float32! | pointer!] | struct! [] | struct! [] value | function! [] -The returned value of DECLARE STRUCT! is the memory address of the newly created struct! value. +The returned value of DECLARE STRUCT! is the memory address of the newly created struct! value on the heap. Struct values declared as local variables in functions have their memory slots pre-reserved. -Note: Struct members are all initialized to 0 when a new literal struct! is declared. +Note: Struct members are all initialized to zero when a new literal struct! is declared. +++Usage @@ -537,7 +541,11 @@ It is possible to nest struct values (and not just pointers to struct values) by In this case, the nested struct c storage space is reserved when allocating the space for the parent struct s2. The size of struct s2 is 20 bytes, while the size of s is 12 bytes. -Struct pointers and struct values can be arbitrarily nested and mixed together. +Struct pointers and struct values can be arbitrarily nested and mixed together. But the assignment rules differ whether it is a struct pointer or a struct value: + +* A struct! variable addressed by pointer can be changed to point to a different location, even if it was referring to a memory location reserved using `declare`. + +* A struct! variable addressed by value (contains `value` keyword) copies data on assignment from the argument location. +++Accessing members @@ -613,7 +621,7 @@ Aliasing syntax: : the name to use as alias : a valid identifier - : integer! | byte! | pointer! [integer! | byte!] | logic! | + : integer! | byte! | pointer! [integer! | byte! | float! | float32! | pointer!] | logic! | float! | float32! | c-string! | struct! [] | struct! [] value | function! [] @@ -663,7 +671,7 @@ New pointers value can be created using the following syntax: declare pointer! [] - : integer! | byte! | float! | float32! + : integer! | byte! | float! | float32! | pointer! \note Possible syntactic sugar The & symbol used in previous revisions of this document has been removed due to the new limited pointer! datatype usage. It could be reintroduced again in the future if required. @@ -675,6 +683,7 @@ Examples: foo: declare pointer! [integer!] ;-- equivalent to C's: int *foo; bar: declare pointer! [byte!] ;-- equivalent to C's: char *bar; baz: declare pointer! [float!] ;-- equivalent to C's: double *baz; + qux: declare pointer! [pointer!] ;-- equivalent to C's: void **qux; \note Pointer value initialization Do not assume any default value for a pointer value until it is initialized properly. In the current implementation, global pointer variables are set to null by default while local pointer variables default value is undefined. This might change in the future to adopt a default value more suitable for debugging (like 0BADBAD0h or similar hex trick). @@ -865,6 +874,27 @@ Currently literal arrays allow write access, but there is no bound checking as i /note ++++Binary arrays + +Binary arrays are a type of literal array made out of bytes only. + +Syntax + + : #{...hex bytes...} + + : a pointer of [pointer! [byte!] type. + +The array is statically allocated and can be accessed using pointer path notation or pointer arithmetic. The size in bytes of a binary array can be retrieved using size? keyword. + +Examples: + + table: #{0042FA0100CAFE00AA} + probe size? table ;-- outputs 9 + probe table/2 ;-- outputs "B" + probe as integer! table/2 ;-- outputs 66 + +Note: whitespaces and comments are accepted inside binary arrays. + +++Null value A special null value is available to use for pointer! and other pointer-like (pass-by-reference) types (struct!, c-string!) and pseudo-type function!. Null does not have a specific type, but can be used to replace any other pointer-like value. So, null cannot be used as initializing value for a global variable or a local variable that does not have an explicit type specification. @@ -939,6 +969,8 @@ It is possible to get a pointer on an existing variable for the following dataty * float32! +* pointer! + Syntax : @@ -964,6 +996,9 @@ This expression will return a pointer value which type depends on the variable t float32! pointer! [float32!] + +pointer! +pointer! [pointer!] @@ -1212,9 +1247,8 @@ The grammar rules are specified in + "]" - ::= "ANY" "[" + "]" - ::= "EITHER" "[" + "]" "[" + "]" - ::= | | + ::= "ANY" "[" + "]" + ::= | ::= "(" ")" ::= | | | "null" @@ -1227,8 +1261,6 @@ The grammar rules are specified in 0][print "ok"] ---Evaluation order rule @@ -1294,18 +1324,20 @@ The specification block is a Red/System dialect (DSL), so the words inside such : function's name : special attributes : function's argument indentifier - : integer! | byte! | logic! | pointer! [integer! | byte!] | + : integer! | byte! | logic! | + pointer! [integer! | byte! | float! | float32! | pointer!] | float! | float32! | c-string! | struct! [] | - struct! [] value + struct! [] value | | value : local variable : function's body code + : struct alias Doc-strings are just optional documentation that can be processed by any external tool, they have no runtime effect. \note Func vs Function Currently, function is a synonym for func in Red/System. In future, however, the behaviour of function in Red/System may be changed to match the behaviour of function in Red (i.e. all set-words are assumed locals). -Until this change has been decided, it may be wise to use the func keyword instead of function in Red/System code, particularly in cases where its use would be affected by such a change. +Until this change has been decided, it may be wise to use the func keyword instead of function in Red/System code, particularly in cases where its usage would be affected by such a change. /note @@ -1331,7 +1363,22 @@ Until this change has been decided, it may be wise to use the func keywor c: 100 a * c / b ] - + +Grouping of arguments or local variables by type is also possible. + +Example + + percent?: func [ + a b [integer!] + return: [integer!] + /local + c d [integer!] + ][ + c: 20 + d: c + 80 + a * d / b + ] + \note Arguments passing In the current implementation, pointer!, integer!, byte!, float!, float32! and logic! arguments are passed by value, while c-string! and struct! arguments are passed by reference. Adding the `value` keyword after a struct! type specification, allows it to be passed by value (works also for returned value). @@ -1709,6 +1756,42 @@ Immediately quits the function and returns a value. ] "ok" ;-- return "ok" if a <> 0 ] + +---Subroutines + +Subroutines are reusable code parts in a function's body that can be called from within the function where they are defined only. + +Syntax + + : [] + + : subroutine's name (local variable). + : subroutine's code (regular R/S code). + +A subroutine name is a local variable that needs to be defined as of type subroutine!, else a compilation error will occur. Once defined, a subroutine can be called by invoking its name from anywhere in the function code (but after its own definition). A subroutine returns its last value to the caller. + +Example: + + foo: func [ + a [integer!] + return: [integer!] + /local + do-error [subroutine!] + ][ + do-error: [print "Wrong number!" return err] + switch a [ + 0 [err: 10 do-error] + 5 [err: 20 do-error] + 10 [err: 30 do-error] + ] + print "Correct!" + ] + +\note + +The subroutine! type is currently a pseudo-type, not a first-class type, so it cannot be passed as argument or returned from a function. + +/note ===Scoping @@ -2147,7 +2230,7 @@ An alternative way to write it (allowed because all code paths return a value of ] prin ["a is " msg lf] - + ---loop Loop over a block of code, decrementing a counter down to zero. LOOP does not return any value, so it cannot be used in an expression. @@ -2766,9 +2849,12 @@ Reserves a storage space on stack (in stack slots unit) and returns a pointer th Syntax : system/stack/allocate + : system/stack/allocate/zero : variable of type: pointer! [integer!] : expression returning an integer + +The /zero option forces the allocated stack region to be zero-filled. \note Stack slots unit Stack slots unit are system-dependent, on IA-32 and ARM, a slot is equal to 4 bytes. @@ -3038,6 +3124,38 @@ where: : an integer! value +---fpu/status + +Retrieve the FPU exception bits status. + +Syntax + + system/fpu/status + + return: a value of type integer!. + +The resulting status bits layout depends on the architecture: + +IA-32: + P|U|O|Z|D|I + + P: Precision + U: Underflow + O: Overflow + Z: Zero Divide + D: Denormalized operand + I: Invalid Operation + +ARM: + ID|0|IX|UF|OF|DZ|IO + + ID: Input Denormal + IX: Inexact (Precision) + UF: Underflow + OF: Overflow + DZ: Division by Zero + IO: Invalid Operation + ---fpu/control-word Set or retrieve the full FPU control register. @@ -3886,7 +4004,11 @@ A valid Red/System source file will need this header: There is no minimum or maximum number of entries that a valid header can contain, so an empty block will also be valid (but bad practice). -Implementation note: Header values types are the ones provided by REBOL during the bootstrapping phase only. Once the Red layer will be implemented, the allowed datatypes will be Red ones. +\note Implementation note +Header values types are the ones provided by REBOL during the bootstrapping phase only. Once the Red layer will be +implemented, the allowed datatypes will be Red ones. + +/note The attribute that you can specify are not limited, you can add whatever you want/need. Anyway, some attribute names are used by convention: @@ -4102,7 +4224,7 @@ will output: ---Logic! -*Add logic! support for OR, XOR, AND operators (if it provides any advantage over ANY/ALL). +*Add logic! support for OR, XOR, AND operators (if it provides any advantage over ANY/ALL). ---Integer! @@ -4167,6 +4289,34 @@ will output: ===Document History +*08/09/2022 - revision 60 + +*>Adds pointer! to pointer! mentions. + + +*05/09/2022 - revision 59 + +*>Improves struct by value description. + + +*23/02/2022 - revision 58 + +*>Removes EITHER from expression rules, as the current compiler can't handle it properly. + + +*14/08/2020 - revision 57 + +*>Adds subroutines description. + +*>Adds binary! arrays description. + +*>Adds multiple assignments and variable grouping mentions. + +*>Adds system/stack/allocate/zero description. + +*>Adds system/fpu/status description. + + *05/09/2019 - revision 56 *>Fixes issues #3301, #3303, #3305. diff --git a/docs/template.html b/docs/red-system/template.html similarity index 100% rename from docs/template.html rename to docs/red-system/template.html diff --git a/boot.red b/encapper/boot.red similarity index 82% rename from boot.red rename to encapper/boot.red index eceb214486..33b9551e5d 100644 --- a/boot.red +++ b/encapper/boot.red @@ -18,26 +18,25 @@ Red [ #include %environment/routines.red #include %environment/scalars.red #include %environment/colors.red + + #register-intrinsics #include %environment/functions.red #include %environment/system.red - #include %environment/lexer.red #include %environment/operators.red - #register-intrinsics - - #include %environment/codecs/png.red - #include %environment/codecs/jpeg.red - #include %environment/codecs/bmp.red - #include %environment/codecs/gif.red - #include %environment/codecs/json.red - #include %environment/codecs/csv.red + #include %environment/codecs/PNG.red + #include %environment/codecs/JPEG.red + #include %environment/codecs/BMP.red + #include %environment/codecs/GIF.red + #include %environment/codecs/redbin.red #include %environment/reactivity.red ;-- requires SET intrinsic #include %environment/networking.red #include %utils/preprocessor.r + #include %environment/tools.red ;-- temporary code -- - #if not find [Windows macOS] config/OS [ + #if not find [Windows macOS Linux] config/OS [ unset [event! image!] image?: func ["Returns true if the value is this type" value [any-type!]][false] ] diff --git a/compiler.r b/encapper/compiler.r similarity index 90% rename from compiler.r rename to encapper/compiler.r index bac332791b..b8f82e6186 100644 --- a/compiler.r +++ b/encapper/compiler.r @@ -36,10 +36,11 @@ red: context [ rebol-gctx: bind? 'rebol expr-stack: make block! 8 current-call: none + currencies: none ;-- extra user-defined currency codes from script's header unless value? 'Red [red: none] ;-- for %preprocessor to load - lexer: do bind load-cache %lexer.r 'self + lexer: do bind load-cache %encapper/lexer.r 'self extracts: do bind load-cache %utils/extractor.r 'self redbin: do bind load-cache %utils/redbin.r 'self preprocessor: do-cache file: %utils/preprocessor.r @@ -60,6 +61,7 @@ red: context [ sym-table: make block! 1000 literals: make block! 1000 declarations: make block! 1000 + boot-extras: make block! 100 bodies: make block! 1000 ssa-names: make block! 10 ;-- unique names lookup table (SSA form) types-cache: make hash! 100 ;-- store compiled typesets [types array name...] @@ -69,6 +71,7 @@ red: context [ s-counter: 0 ;-- series suffix counter depth: 0 ;-- expression nesting level counter max-depth: 0 + root-slots: 0 ;-- extra root block slots counter booting?: none ;-- YES: compiling boot script nl: newline set 'float! 'float ;-- type names not defined in Rebol @@ -101,10 +104,7 @@ red: context [ iterators: [loop until while repeat foreach forall forever remove-each] - standard-modules: [ - ;-- Name ------ Entry file -------------- OS availability ----- - View %modules/view/view.red [Windows macOS] - ] + standard-modules: load-cache %encapper/modules.r func-constructors: [ 'func | 'function | 'does | 'has | 'routine | 'make 'function! @@ -140,7 +140,7 @@ red: context [ either word? err [ join uppercase/part mold err 1 " error" ][reform err] - "^/*** in file:" to-local-file script-name + "^/*** in file:" any [attempt [to-local-file script-name] "??"] ;either locals [join "^/*** in function: " func-name][""] ] if pc [ @@ -241,6 +241,33 @@ red: context [ clear next mark ;-- remove code at "upper" level ] + insert-head-last: func [body [block!] /local mark][ + mark: tail output + do body + insert mark/-1 mark + clear mark + ] + + to-nibbles: func [src [string!] /local out][ + out: make string! 11 + foreach [high low] src [ + append out to char! add + shift/left (to integer! high - #"0") 4 + to integer! low - #"0" + ] + out + ] + + to-currency-code: func [code [string!] /local pos][ + code: to word! code + case [ + pos: find extracts/currencies code [index? pos] + all [currencies pos: find currencies code][(index? pos) + length? extracts/currencies] + code = '... [0] + 'else [throw-error ["unknown money! currency" code ", add it to the Currencies: header."]] + ] + ] + any-function?: func [value [word!]][ find [native! action! op! function! routine!] value ] @@ -281,6 +308,8 @@ red: context [ unicode-char?: func [value][value/1 = #"'"] float-special?: func [value][value/1 = #"."] tuple-value?: func [value][value/1 = #"~"] + money-value?: func [value][value/1 = #"$"] + ref-value?: func [value][value/1 = #"@"] percent-value?: func [value][#"%" = last value] date-special?: func [value][all [block? value value/1 = #!date!]] @@ -334,7 +363,7 @@ red: context [ bind-function: func [body [block!] shadow [object!] /local self* rule pos][ bind body shadow if 1 < length? obj-stack [ - self*: in do obj-stack 'self ;-- rebing SELF to the wrapping object + self*: in do obj-stack 'self ;-- rebind SELF to the wrapping object parse body rule: [ any [pos: 'self (pos/1: self*) | into rule | skip] @@ -359,6 +388,25 @@ red: context [ throw-error ["Should not happen: not found context for word: " mold name] ] + emit-word-ref: func [name [any-word!] /no-prefix /local obj idx ctx][ + case [ + rebol-gctx = obj: bind? name [ + emit either no-prefix [decorate-symbol name][prefix-exec name] + ] + all [ctx: select objects obj attempt [idx: get-word-index/with name ctx]][ + emit 'word/push-local + emit either parent-object? obj ['octx][ctx] ;-- optional parametrized context reference (octx) + emit idx + ] + ctx: select shadow-funcs obj [ + emit 'word/push-local + emit ctx + emit get-word-index name ;@@ replace that + ] + 'else [throw-error ["Should not happen: undefined context for word:" name]] + ] + ] + emit-push-from: func [ name [any-word!] original [any-word!] type [word!] actions [block!] /local ctx obj idx @@ -382,7 +430,7 @@ red: context [ ] emit-push-word: func [name [any-word!] original [any-word!] /local type ctx obj][ - type: to word! form type? name + type: to word! form type? :name name: to word! :name either all [ @@ -414,7 +462,7 @@ red: context [ ] emit decorate-symbol/no-alias name ][ - if new: select-ssa name [name: new] ;@@ add a check for function! type + if all [new: select-ssa name not find-function new new][name: new] emit case [ ;-- global word all [ literal @@ -434,7 +482,7 @@ red: context [ ] get-path-word: func [ - original [any-word!] blk [block!] get? [logic!] + original [any-word!] blk [block!] get? [logic!] first? [logic!] /local name new obj ctx idx ][ name: to word! original @@ -446,11 +494,11 @@ red: context [ either get? [ append blk decorate-symbol/no-alias name ;-- local word, point to value slot ][ - append blk [as cell!] - append/only blk prefix-exec name ;-- force global word + append blk [as cell! get-root] + append blk redbin/emit-word/root name select objects obj none ] ][ - if new: select-ssa name [name: new] ;@@ add a check for function! type + if all [new: select-ssa name not find-function new new][name: new] either get? [ either all [ rebol-gctx <> obj @@ -458,17 +506,17 @@ red: context [ attempt [idx: get-word-index/with name ctx] ][ repend blk [ - 'word/get-in + 'word/push-local either parent-object? obj ['octx][ctx] ;-- optional parametrized context reference (octx) idx ] ][ - append/only blk '_context/get + unless first? [append/only blk '_context/get] append/only blk prefix-exec name ] ][ - append blk [as cell!] - append/only blk prefix-exec name + append blk [as cell! get-root] + append blk redbin/emit-word/root name none none ] ] @@ -531,8 +579,8 @@ red: context [ ] ][ append body [ - RED_THROWN_BREAK [break] - RED_THROWN_CONTINUE [continue] + RED_THROWN_BREAK [system/thrown: 0 break] + RED_THROWN_CONTINUE [system/thrown: 0 continue] ] ] ] @@ -574,7 +622,12 @@ red: context [ ] emit-native: func [name [word!] /with options [block!] /local wrap? pos body][ - if wrap?: to logic! find [parse do] name [emit 'switch] + if wrap?: to logic! find [parse do] name [ + emit [ + assert system/thrown = 0 + switch + ] + ] emit join natives-prefix to word! join name #"*" emit 'true ;-- request run-time type-checking pos: either with [ @@ -584,7 +637,12 @@ red: context [ -2 ] insert-lf pos - pick [1 0] wrap? - if wrap? [emit build-exception-handler] + if wrap? [ + emit build-exception-handler + emit [ + system/thrown: 0 + ] + ] ] emit-exit-function: does [ @@ -652,6 +710,7 @@ red: context [ foreach type spec [ unless block? type [ + if type = 'red/cell! [type: 'any-type!] ;-- coming from routines type: either word: in extracts/scalars type [get word][reduce [type]] foreach word type [ @@ -693,9 +752,9 @@ red: context [ find spec to lit-word! name ][ type: case [ - block? pos/2 [pos/2] - all [string? pos/3 block? pos/3][pos/3] - 'else [[default!]] + all [block? pos/2 not empty? pos/2] [pos/2] + all [string? pos/3 block? pos/3] [pos/3] + 'else [[default!]] ] make-typeset type find/reverse pos refinement! spec to logic! native ][ @@ -794,7 +853,7 @@ red: context [ ] decorate-symbol: func [name [word!] /no-alias /local pos][ - if all [not no-alias pos: find/case/skip aliases name 2][name: pos/2] + if all [not no-alias not local-word? name pos: find/case/skip aliases name 2][name: pos/2] to word! join "~" clean-lf-flag name ] @@ -820,7 +879,7 @@ red: context [ reduce [var set-var] ] - add-symbol: func [name [word!] /with original /local sym id alias][ + add-symbol: func [name [word!] /only /with original /local sym id alias][ unless find/case symbols name [ if find symbols name [ if find/case/skip aliases name 2 [exit] @@ -829,18 +888,15 @@ red: context [ ] sym: decorate-symbol name id: 1 + ((length? symbols) / 2) - repend symbols [name reduce [sym id]] + unless only [repend symbols [name reduce [sym id]]] repend sym-table [ to set-word! sym 'word/load mold any [original name] ] + root-slots: root-slots + 1 new-line skip tail sym-table -3 on ] ] - get-symbol-id: func [name [word!]][ - second select symbols name - ] - add-global: func [name [word!]][ unless any [ local-word? name @@ -1056,7 +1112,7 @@ red: context [ ] path: none ][ - bind path/1 'rebol ;-- force binding to global context + path/1: bind path/1 'rebol ;-- force binding to global context ] ] path @@ -1077,6 +1133,7 @@ red: context [ any [ word! (return no) | lit-word! (return yes) + | get-word! (return yes) | /local (return no) | skip ] @@ -1146,6 +1203,19 @@ red: context [ entry ] ] + + decode-attributes: func [spec [block!] /local do-error flags][ + do-error: [throw-error ["invalid function spec block:" mold pos]] + flags: 0 + foreach attrib spec/1 [ + unless word? attrib [do-error] + flags: switch attrib [ ;-- keep those flags synced with %runtime/definitions.reds + trace [flags or to-integer #{00000400}] + no-trace [flags or to-integer #{00000200}] + ] + ] + flags + ] check-invalid-exit: func [name [word!]][ if empty? locals-stack [ @@ -1174,6 +1244,7 @@ red: context [ ][ pos/1: none ] + true ] check-func-name: func [name [word!] /local new pos][ @@ -1261,15 +1332,18 @@ red: context [ ] ] - check-spec: func [spec [block!] /local symbols word pos stop locals return?][ + check-spec: func [spec [block!] /local symbols word pos stop locals return? loc? flags][ symbols: make block! length? spec locals: 0 + flags: 0 + loc?: no unless parse spec [ opt string! + opt [pos: block! (flags: decode-attributes pos) opt string!] any [ - pos: /local (append symbols 'local) [ - some [ + pos: /local (loc?: yes append symbols 'local) [ + any [ pos: word! ( unless find symbols word: to word! pos/1 [ append symbols word @@ -1278,10 +1352,6 @@ red: context [ ) pos: opt block! pos: opt string! ] - | ( - remove pos - clear back tail symbols - ) ] | set-word! ( if any [return? pos/1 <> return-def][stop: [end skip]] @@ -1289,7 +1359,7 @@ red: context [ ) stop pos: block! opt string! | [ [word! | lit-word! | get-word!] opt block! opt string! - | refinement! opt string! + | refinement! opt string! (if loc? [stop: [end skip]]) stop ] (append symbols to word! pos/1) ] ][ @@ -1308,7 +1378,34 @@ red: context [ throw-error ["duplicate word definition:" s/1] ] ] - reduce [symbols locals] + reduce [symbols locals flags] + ] + + make-attributs: func [spec [block!] /prolog locals /epilog /local flags trace? no-trace? out][ + unless all [ + any [ + block? flags: spec/1 + block? flags: spec/2 + ] + any [ + trace?: find flags 'trace + no-trace?: find flags 'no-trace + ] + ][return ()] + + out: copy [] + either prolog [ + insert find/tail locals 'saved 'prev + append out [ + prev: interpreter/tracing? + ] + if trace? [append out [interpreter/tracing?: interpreter/trace?]] + if no-trace? [append out [interpreter/tracing?: no]] + ][ + append out [interpreter/tracing?: prev] + ] + new-line back back tail out yes + out ] make-refs-table: func [spec [block!] /local mark pos arity arg-rule list ref args][ @@ -1377,7 +1474,7 @@ red: context [ invalid-spec: [throw-error ["invalid argument function to make op!:" mold copy/part at pos 4 2]] name: to word! pos/1 - if find functions name [exit] ;-- mainly intended for 'make (hardcoded) + if find functions name [return none] ;-- mainly intended for 'make (hardcoded) switch type: pos/3 [ native! [nat?: yes if find intrinsics name [type: 'intrinsic!]] @@ -1414,7 +1511,7 @@ red: context [ emit-path: func [ path [path! set-path!] set? [logic!] alt? [logic!] - /local pos words item blk get? mark + /local idx pos words item blk get? mark ][ either set? [ emit-open-frame 'eval-set-path @@ -1429,155 +1526,29 @@ red: context [ ][ emit-open-frame 'eval-path ] - pos: tail output + if all [1 <> length? obj-stack path/1 = last obj-stack][remove path] ;-- remove temp object prefix inserted by object-access? (mind #4567!) - if path/1 = last obj-stack [remove path] ;-- remove temp object prefix inserted by object-access? - - if set? [ - emit [object/path-parent/header: TYPE_NONE] - insert-lf -2 - ] - emit either integer? last path [ - pick [set-int-path* eval-int-path*] set? + idx: either empty? ctx-stack [ + redbin/emit-block path ][ - pick [set-path* eval-path*] set? + redbin/emit-block/with path last ctx-stack ] - insert-lf -1 - mark: tail output - path: back tail path - while [not head? path: back path][ - emit pick [eval-int-path eval-path] integer? path/1 - ] ;-- path should be at head again + emit 'eval-path* - words: clear [] - blk: [] + words: reduce [to word! form set? 'get-root idx] + blk: make block! 20 ;-- requires by get-path-word, returned as result forall path [ - append words either integer? item: path/1 [item][ - get?: to logic! any [head? path get-word? item] - get-path-word item clear blk get? - ] - ] - emit words - - new-line/all mark no - new-line pos yes - emit-close-frame - ] - - emit-eval-path: func [/set][ - emit 'actions/eval-path* - emit either set ['true]['false] - insert-lf -2 - ] - - emit-path-func: func [body [block!] octx [word!] cnt [integer!] /local pos f-name rule arity name][ - pos: body - body: copy pos - clear pos - - if all [1 = length? body body/1 = 'stack/reset][clear body] - rewrite-locals body - - name: either pos: find body 'pos [ - either body = [ - stack/push pos - stack/reset - ][ - clear body - 2 + append words either integer? item: path/1 [ + reduce ['integer/push item] ][ - insert body [ - pos: stack/arguments - ] - 4 - ] - ][2] - if #"~" <> first form name: pick body name [ - name: [words/_anon] - ] - - if all [not empty? body 'stack/unwind = last body][ - change/only back tail body 'stack/unwind-last - new-line back tail body yes - ] - unless any [empty? body 1 = length? body][ - arity: 0 - parse body rule: [ - some [ - 'stack/push 'pos pos: '+ ( - arity: arity + 1 - either arity = 1 [pos: remove/part pos 2][pos/2: arity - 1] - ) :pos - | into rule - | skip - ] - ] - redirect-to declarations [ - f-name: decorate-func to word! join "~path" cnt - emit reduce [to set-word! f-name 'func [octx [node!] /local pos] body] - insert-lf -4 - ] - emit compose [ - stack/defer-call (name) as-integer (to get-word! f-name) (arity) (octx) + get?: to logic! any [head? path get-word? item] + get-path-word item clear blk get? head? path ] - f-name ] - ] - - emit-dynamic-path: func [ - body [block!] - /local path idx mark saved cnt frame? octx blk-idx - ][ - octx: pick [octx null] to logic! all [ - not empty? locals-stack - container-obj? - ] - path: first paths-stack - blk-idx: redbin/emit-block path - - if frame?: all [ - not emit-path-func body octx cnt: get-counter - not empty? expr-stack - find [ switch case] last expr-stack - ][ - emit-open-frame 'dyn-path ;-- wrap it in a stack frame in this case - ] - emit-get-word path/1 path/1 + new-line/all words no + emit reduce [words] insert-lf -2 - saved: output - - forall path [ - emit [either stack/func?] - insert-lf -2 - idx: (index? path) - 1 - emit compose/deep [[stack/push-call as red-path! get-root (blk-idx) (idx) 0 (octx)]] - - either tail? next path [ - emit [[stack/adjust]] - ][ - mark: tail output - unless head? path [ - emit [ - stack/top: stack/top - 1 - copy-cell stack/top stack/top - 1 - ] - ] - emit-open-frame 'eval-path - emit [stack/push stack/arguments - 1] - insert-lf -4 - emit append to path! to word! form type? path/2 'push - emit prefix-exec path/2 - insert-lf -2 - emit-eval-path no - emit 'stack/unwind-part - insert-lf -1 - change/only/part mark mark: copy mark tail output - output: mark - ] - ] - remove paths-stack - output: saved - if frame? [emit-close-frame] + emit-close-frame ] get-return-type: func [spec [block!] /local type][ ;-- for routine spec blocks @@ -1588,7 +1559,31 @@ red: context [ ] ] - emit-routine: func [name [word!] spec [block!] /local type cnt offset alter][ + emit-routine: func [name [word!] spec [block!] /local type cnt offset alter idx pos][ + idx: 0 + if block? spec/1 [spec: next spec] + forall spec [ + if any [spec/1 = /local set-word? spec/1][break] ;-- avoid processing local variable + if block? spec/1 [ + type: spec/1/1 + if type <> 'red-value! [ ;-- any-type! => red-value! => no check + if pos: find/match form type "red-" [type: to word! pos] + type: reduce [type] + emit make-typeset type none back spec yes ;-- inject type-checking calls for arguments + emit idx + either idx > 0 [ + emit reduce ['stack/arguments '+ idx] + insert-lf -9 + ][ + emit 'stack/arguments + insert-lf -7 + ] + ] + idx: idx + 1 + ] + ] + spec: head spec + declare-variable/init 'r_arg to paren! [as red-value! 0] emit [r_arg: stack/arguments] insert-lf -2 @@ -1669,7 +1664,7 @@ red: context [ comp-literal: func [ /inactive /with val - /local value char? special? percent? map? tuple? dt-special? name w make-block type idx zone + /local value char? special? percent? map? tuple? money? ref? dt-special? name w make-block type idx zone ][ make-block: [ value: to block! value @@ -1691,6 +1686,8 @@ red: context [ special?: float-special? value percent?: percent-value? value tuple?: tuple-value? value + money?: money-value? value + ref?: ref-value? value ] ] scalar? :value @@ -1732,8 +1729,22 @@ red: context [ emit to integer! copy/part skip bin -8 -4 insert-lf -5 ] + money? [ + emit 'money/push + value: to string! next value + emit pick [true false] value/4 = #"-" + emit to-currency-code copy/part value 3 + emit to-nibbles copy skip value 4 + ] + ref? [ + idx: redbin/emit-string/root next value ;-- issue! is an any-string! in Rebol2 + emit 'ref/push + emit compose [as red-string! get-root (idx)] + insert-lf -5 + ] find [refinement! issue!] type?/word :value [ - add-symbol w: to word! form value + w: to word! form value + either issue? :value [add-symbol/only w][add-symbol w] type: to word! form type? :value either all [not issue? :value local-word? w][ @@ -1798,11 +1809,11 @@ red: context [ insert-lf -3 ] path! set-path! [ - idx: do make-block case [ inactive [ - either get-word? pc/1/1 [ + either get-word? pc/1/1 [ ;-- R2 doesn't have get-path! emit 'get-path/push + pc/1/1: to word! pc/1/1 ][ emit to path! reduce [to word! form type? pc/1 'push] if path? pc/1 [emit [as red-path!]] @@ -1817,6 +1828,7 @@ red: context [ if path? pc/1 [emit [as red-path!]] ] ] + idx: do make-block emit reduce ['get-root idx] insert-lf -3 ] @@ -1890,7 +1902,7 @@ red: context [ /locals words ctx spec name id func? obj original body pos entry symbol body? ctx2 new blk list path on-set-info values w defer mark blk-idx - event pos2 loc-s loc-d shadow-path saved-pc saved set? rebind? evt-var + event pos2 loc-s loc-d shadow-path saved-pc saved set? evt-var ][ saved-pc: pc either set-path? original: pc/-1 [ @@ -1969,12 +1981,13 @@ red: context [ words: third obj/1 unless find [context object object!] pc/1 [ - unless new: is-object? pc/2 [ + if all [not new: is-object? pc/2 not passive][ comp-call 'make select functions 'make ;-- fallback to runtime creation return none ] - ctx2: select objects new ;-- multiple inheritance case + if all [passive not new][new: proto/1] + ctx2: select objects new proto/1 ;-- multiple inheritance case spec: union spec next first new insert proto new @@ -1988,7 +2001,7 @@ red: context [ ] ctx: add-context spec - blk-idx: redbin/emit-context/root ctx spec no yes + blk-idx: redbin/emit-context/root ctx spec no yes 'object redirect-to literals [ ;-- store spec and body blocks emit compose [ @@ -2044,18 +2057,18 @@ red: context [ ] ] if body? [bind body obj] - + if passive [return []] unless all [empty? locals-stack not iterator-pending?][ ;-- in a function or iteration block emit compose [ - (to set-word! ctx) _context/clone get-root (blk-idx) ;-- rebuild context + (to set-word! ctx) _context/clone-words get-root (blk-idx) CONTEXT_OBJECT ;-- rebuild context ] insert-lf -3 ] if proto [ if body? [inherit-functions obj last proto] - emit reduce ['object/duplicate select objects last proto ctx 'true] + emit reduce ['object/clone-series select objects last proto ctx 'true] insert-lf -4 ] if all [not body? not passive][ @@ -2098,8 +2111,7 @@ red: context [ ] pos: none - rebind?: to word! form to logic! proto - defer: reduce ['object/init-push ctx id rebind?] ;-- deferred emission + defer: reduce ['object/init-push ctx id] ;-- deferred emission new-line defer yes ;-- events definitions processing @@ -2155,7 +2167,7 @@ red: context [ comp-object: :comp-context - comp-construct: has [only? with? obj][ + comp-construct: has [only? with? body? obj defer mark][ only?: with?: no if all [ @@ -2164,23 +2176,44 @@ red: context [ ][ throw-error "Invalid CONSTRUCT refinement" ] - either with? [ - unless obj: is-object? pc/3 [--not-implemented--] - also - comp-context/passive/extend only? obj - pc: next pc + body?: block? pc/2 + if all [ + find [set-word! set-path!] type?/word pc/-1 + any [all [body? not with?] all [with? obj: is-object? pc/3]] ][ - comp-context/passive only? - ] ;-- return object deferred block + either with? [ + comp-context/passive/extend only? obj + ][ + comp-context/passive only? + ] + ] + pc: next pc + mark: tail output + emit-open-frame 'construct + comp-expression + if with? [comp-expression] + emit-native/with 'construct reduce [pick [1 -1] with? pick [0 -1] only?] + emit-close-frame + defer: copy mark + clear mark + defer ;-- return object deferred block ] - comp-try: has [all? mark body call handlers][ - call: pick [try-all try] to logic! all?: path? pc/-1 + comp-try: has [path all? keep? mark body call handlers][ + all?: keep?: no + if path? path: pc/-1 [ + all?: to logic! find path 'all + keep?: to logic! find path 'keep + ] + call: pick [try-all try] all? emit-open-frame 'body either block? pc/1 [ emit-open-frame call - emit [catch RED_THROWN_ERROR] + emit [ + assert system/thrown = 0 + catch RED_THROWN_ERROR + ] insert-lf -2 body: comp-sub-block 'try if body/1 = 'stack/reset [remove body] @@ -2219,7 +2252,7 @@ red: context [ emit 'switch insert-lf -1 ] - emit-native/with 'try reduce [pick [0 -1] all?] + emit-native/with 'try reduce [pick [0 -1] all? pick [0 -1] keep?] new-line back tail output no unless all? [emit build-exception-handler] emit-close-frame @@ -2325,7 +2358,10 @@ red: context [ comp-expression/close-path ;@@ optimize case for literal counter emit-argument-type-check 0 'loop 'stack/arguments - emit compose [(set-name) integer/get*] + emit compose [ + natives/coerce-counter* + (set-name) integer/get* + ] insert-lf -2 emit compose/deep [ either (name) <= 0 [(set-last-none)] @@ -2377,72 +2413,41 @@ red: context [ emit-close-frame ] - comp-repeat: has [name word cnt set-cnt lim set-lim action][ - unless any-word? word: pc/1 [ + comp-repeat: has [name][ + unless any-word? name: pc/1 [ pc: back pc throw-error "REPEAT expects a word as first argument" ] - emit-open-frame 'repeat - - add-symbol word - add-global word - name: decorate-symbol word - action: either local-word? word [ - 'natives/repeat-set ;-- set the value slot on stack - ][ - '_context/set-integer ;-- set the word value in global context - ] - - depth: depth + 1 - if depth > max-depth [max-depth: depth] - - emit-stack-reset - + add-symbol name + add-global name pc: next pc - comp-expression/close-path ;-- compile 2nd argument - emit-argument-type-check 1 'repeat 'stack/arguments - - set [cnt set-cnt] declare-variable join "r" depth ;-- integer counter - set [lim set-lim] declare-variable join "rlim" depth ;-- counter limit - emit reduce either local-word? word [ ;@@ only integer! argument supported - [ - set-lim 'natives/repeat-init* name - set-cnt 0 - ] - ][ - [ - set-lim 'integer/get* - '_context/set-integer name lim - set-cnt 0 - ] - ] - insert-lf -2 - insert-lf -5 - insert-lf -7 - emit-stack-reset emit-open-frame 'repeat - emit compose/deep [ - while [ - ;-- set word 1 + get word - ;-- TBD: set word next get word - (set-cnt) (cnt) + 1 - ;-- (get word) < value - ;-- TBD: not tail? get word - (cnt) <= (lim) - ] + comp-expression ;-- fetch the upper limit for the counter + emit 'natives/coerce-counter* ;-- eventually convert float to integer + insert-lf -1 + emit-argument-type-check 1 'repeat 'stack/arguments + + emit-open-frame 'set + emit-push-word name name ;-- push the word + emit [ + integer/push 0 + word/set ;-- initialize the counter word to 0 ] - new-line last output on - new-line skip tail last output -3 on - + emit-close-frame + + emit [loop integer/get stack/arguments] + insert-lf -3 push-call 'repeat comp-sub-block 'repeat-body pop-call - insert last output reduce [action name cnt] - new-line last output on - emit-close-frame - emit-close-frame - depth: depth - 1 + insert-head-last [ ;-- inject code at loop's head to pre-increment counter + emit [ ;-- forces a newline marker + natives/inc-counter as red-word! ;-- increments the counter + ] + emit-word-ref name + ] + emit-close-frame/last ] comp-forever: does [ @@ -2515,17 +2520,19 @@ red: context [ emit make-typeset [series!] none functions/forall/3 yes emit [0 stack/arguments - 2] ;-- index of first argument insert-lf -9 - emit copy/deep [ ;-- copy/deep required for R/S lines injection - while [natives/forall-loop] - ] + + emit-open-frame 'forall + emit [loop natives/get-series-length as red-series! stack/arguments - 2] + insert-lf -7 push-call 'forall comp-sub-block 'forall-body ;-- compile body pop-call append last output [ ;-- inject at tail of body block - natives/forall-next ;-- move series to next position + if natives/forall-next? [break] ;-- move series to next position ] emit [ + stack/unwind natives/forall-end ;-- reset series stack/unwind ] @@ -2601,7 +2608,7 @@ red: context [ throw-error "CONTINUE used with no loop" ] if 'forall = last loops [ - emit 'natives/forall-next ;-- move series to next position + emit 'natives/forall-next? ;-- move series to next position insert-lf -1 ] emit [stack/unroll-loop yes continue] @@ -2611,11 +2618,12 @@ red: context [ comp-func-body: func [ name [word!] spec [block!] body [block!] symbols [block!] locals-nb [integer!] - /local init locals blk args? + /local init locals blk args? tracing ][ push-locals copy symbols ;-- prepare compiled spec block forall symbols [symbols/1: decorate-symbol/no-alias symbols/1] locals: append copy [/local ctx saved] symbols + set/any 'tracing make-attributs/prolog spec locals blk: either container-obj? [head insert copy locals [octx [node!]]][locals] emit reduce [to set-word! decorate-func/strict name 'func blk] insert-lf -3 @@ -2630,6 +2638,7 @@ red: context [ ctx: TO_CTX(to paren! last ctx-stack) saved: ctx/values ctx/values: as node! stack/arguments + (get/any 'tracing) ] new-line skip tail init -4 on args?: yes @@ -2667,7 +2676,8 @@ red: context [ ;-- Function's epilog -- append last output compose [ stack/unwind-last ;-- closing body stack frame, and propagating last value - ctx/values: saved ;-- restore context values pointer + ctx/values: saved ;-- restore context values pointer + (make-attributs/epilog spec) ] new-line skip tail last output -4 yes @@ -2691,7 +2701,7 @@ red: context [ throw-error ["duplicate word definition in function:" pc/1] ] ] - ;-- Remove local words that are duplicates of lit/get-word arguments + ;-- Check if local words are duplicates of lit/get-word arguments if loc: find spec /local [ pos: loc while [not tail? pos][ @@ -2702,7 +2712,7 @@ red: context [ find/part spec to get-word! pos/1 loc ] ][ - remove pos + throw-error ["duplicate word definition in function:" pos/1] ][ pos: next pos ] @@ -2750,9 +2760,14 @@ red: context [ ] ] unless empty? words [ + remove find words 'local ;-- #4998 pos: tail spec - unless find spec /local [append spec /local] - append spec words + either parse spec [thru /local any word! loc: to end][ + insert loc words + ][ + append spec /local + append spec words + ] new-line pos yes new-line/all next pos no ] @@ -2763,7 +2778,7 @@ red: context [ /local name word spec body symbols locals-nb spec-idx body-idx ctx pos octx src-name original global? path obj fpath shadow defer ctx-idx body-code - alter entry mark + alter entry mark flags ][ unless all [block? pc/2 any [does block? pc/3]][ ;-- fallback if no literal spec & body blocks word: pc/1 @@ -2783,7 +2798,10 @@ red: context [ case [ set-path? original [ path: original - either set [obj fpath] object-access? path [ + either all [ + set [obj fpath] object-access? path + obj + ][ do reduce [join to set-path! fpath last path 'function!] ;-- update shadow object info obj: find objects obj name: to word! rejoin [any [obj/-1 obj/2] #"~" last path] @@ -2810,20 +2828,22 @@ red: context [ ] pc: next pc - set [spec body] pc + spec: pc/1 ;-- #5030 + body: pc/2 + case [ collect [collect-words spec body] does [body: spec spec: make block! 1 pc: back pc] has [spec: head insert copy spec /local] ] - set [symbols locals-nb] check-spec spec + set [symbols locals-nb flags] check-spec spec add-function name spec if pos: find spec return-def [register-user-type/store name pos/2] push-locals symbols ;-- store spec and body blocks ctx: push-context copy symbols - ctx-idx: redbin/emit-context/root ctx symbols yes no + ctx-idx: redbin/emit-context/root ctx symbols yes no 'function spec-idx: redbin/emit-block spec redirect-to literals [ emit compose [ @@ -2854,7 +2874,7 @@ red: context [ defer: compose [ _function/push get-root (spec-idx) (body-code) (ctx) as integer! (to get-word! decorate-func/strict name) - (octx) + (octx) (flags) ] new-line defer yes new-line skip tail defer -4 no @@ -2946,7 +2966,7 @@ red: context [ either obj/5 [ ctx: either empty? locals-stack [obj/2]['octx] emit reduce ['object/push ctx obj/5/5 obj/3 obj/5/1 obj/5/2 obj/5/3 obj/5/4] ;-- event(s) case - insert-lf -7 + insert-lf -8 ][ emit reduce ['object/init-push obj/2 obj/3] insert-lf -3 @@ -3210,8 +3230,8 @@ red: context [ root? [logic!] /set? /local - path value emit? get? entry alter saved after dynamic? ctx mark obj? - fpath symbol obj self? true-blk defer obj-field? parent fire index breaks + path value emit? get? entry alter saved after dynamic? ctx mark obj? new t? p + fpath symbol obj self? true-blk defer obj-field? parent fire index breaks ][ path: copy pc/1 emit?: yes @@ -3233,7 +3253,7 @@ red: context [ unless set? [emit [stack/mark-native words/_body]] ;@@ not clean... emit compose [ - interpreter/eval-path stack/top - 1 null null (to word! form set?) no (to word! form root?) no + interpreter/eval-path stack/top - 1 null null null (to word! form set?) no (to word! form root?) no ] unless set? [emit [stack/unwind-last]] @@ -3328,7 +3348,21 @@ red: context [ word? last path ;-- not allow get-words to pass (#1141) any [self? (length? path) = length? fpath] ;-- allow only object-path/field forms ][ - ctx: second obj: find objects obj + either self? [ + p: path + until [ ;-- process nested objects + t?: tail? next p: next p + obj: find objects obj + if all [not t? object? new: select obj/1 p/1][ + obj: new + if t? [obj: find objects obj] + ] + t? + ] + ][ + obj: find objects obj + ] + ctx: second obj unless index: get-word-index/with last path ctx [ throw-error ["word" last path "not defined in" path] ] @@ -3360,14 +3394,24 @@ red: context [ object/fire-on-set* ] to logic! local-word? first back back tail path - parent: either 2 < length? path [ ;-- extract word from parent context - breaks: [-12 -9 -6 -1] - set [obj fpath] object-access? copy/part path (length? path) - 1 - ctx: second obj: find objects obj - ['word/from ctx get-word-index/with pick tail path -2 ctx] - ][ - breaks: [-10 -7 -4 -1] ;-- word is in global context - [decorate-symbol path/1] + parent: case [ + 2 < length? path [ ;-- extract word from parent context + breaks: [-12 -9 -6 -1] + set [obj fpath] object-access? copy/part path (length? path) - 1 + ctx: second obj: find objects obj + ['word/from ctx get-word-index/with pick tail path -2 ctx] + ] + self? [ ;-- self/field + breaks: [-10 -7 -4 -1] + set [obj fpath] object-access? copy/part path 1 + ctx: second obj: find objects obj + fire: 'object/loc-ctx-fire-on-set* + [ctx] + ] + 'else [ + breaks: [-10 -7 -4 -1] ;-- word is in global context + [decorate-symbol path/1] + ] ] repend any [mark last output] compose [ fire @@ -3468,6 +3512,10 @@ red: context [ either all [not thru spec/1 = 'intrinsic!][ switch any [all [path? call call/1] call] keywords ][ + if all [path? call (length? call) <> length? unique call][ + pc: back pc + throw-error ["duplicate or invalid refinement usage:" call] + ] compact?: spec/1 <> 'function! ;-- do not push refinements on stack refs: make block! 1 ;-- refinements storage in compact mode cnt: 0 @@ -3478,7 +3526,7 @@ red: context [ emit reduce [ ;-- special case for path-generated wrapper functions 'stack/mark-func decorate-exec-ctx decorate-symbol name - get-func-ctx original ctx-name + ctx-name ] insert-lf -3 ][ @@ -3525,7 +3573,8 @@ red: context [ either path? call [ ;-- call with refinements? ctx: copy spec/4 ;-- get a new context block foreach ref next call [ - option: to refinement! either integer? ref [form ref][ref] + unless word? ref [throw-error ["incompatible type" ref "in" call]] + option: to refinement! ref unless pos: find/skip spec/4 option 3 [ throw-error [call/1 "has no refinement called" ref] @@ -3713,6 +3762,7 @@ red: context [ all [ any [word? pc/1 all [path? pc/1 not get-word? pc/1/1]] do take-frame + any [not find [object context construct] pc/1 check-redefined name original] defer: dispatch-ctx-keywords/with original pc/1 ][] 'else [ @@ -3831,6 +3881,7 @@ red: context [ pc: back pc throw-error ["undefined word" pc/1] ][ + add-symbol to word! first back pc do emit-word ] ] @@ -4235,36 +4286,6 @@ red: context [ ] true ] - #load [ ;-- temporary directive - change/part/only pc to do pc/2 pc/3 3 - comp-expression ;-- continue expression fetching - true - ] - #version [ - change pc form load-cache %version.r - comp-expression - true - ] - #git [ - change/only pc load-cache %build/git.r - comp-expression - true - ] - #build-date [ ;-- UTC date - change pc use [date][ - date: now - date: date - date/zone - date/zone: none - date - ] - comp-expression - true - ] - #build-config [ - change/only pc load find mold job #"[" - comp-expression - true - ] #register-intrinsics [ ;-- internal boot-level directive if booting? [ pc: next pc @@ -4298,15 +4319,6 @@ red: context [ unless no-infix [ if check-infix-operators root [ - if all [any [root close-path] paths < length? paths-stack][ - emit-dynamic-path out - push-call - loop length? paths-stack [ - emit-dynamic-path make block! 0 - ] - pop-call - if tail? pc [emit-dyn-check] - ] if all [root 'stack/reset <> last output][ emit-stack-reset ;-- clear stack from last root expression result ] @@ -4517,7 +4529,7 @@ red: context [ insert/part tail prolog p 2 p: remove/part p 2 ) :p - | p: #include (pc: p comp-include/only p) + | p: #include (pc: p comp-include/only p) :p | p: [block! | paren!] :p into rule | skip ] @@ -4574,10 +4586,11 @@ red: context [ output: make block! 10000 comp-init - pc: next preprocessor/expand/clean load-source/hidden %boot.red job ;-- compile Red's boot script + pc: next preprocessor/expand/clean load-source/hidden %encapper/boot.red job ;-- compile Red's boot script unless job/red-help? [clear-docstrings pc] booting?: yes comp-block + append output boot-extras booting?: no mods: tail output @@ -4673,8 +4686,8 @@ red: context [ unless empty? sys-global [ process-calls/global sys-global ;-- lazy #call processing ] - slots: redbin/index + 3000 - if job/dev-mode? [slots: slots + 100'000] ;-- Cannot know how many slot will be needed by the app + slots: redbin/index + 3000 + root-slots + if job/dev-mode? [slots: slots + 100'000] ;-- Cannot know how many slots will be needed by the app change/only find out slots pos: third last out @@ -4694,6 +4707,7 @@ red: context [ ***-root-size: with red [ + stk-bottom: system/stack/top ;-- reset stk-bottom set by libRedRT to allow GC to mark all pointers on stack root-base: redbin/boot-load system/boot-data yes exec: context