diff options
166 files changed, 11050 insertions, 8791 deletions
diff --git a/.editorconfig b/.editorconfig index 705b1f022..70cc78f0b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,38 +6,38 @@ root = true [*] -indent_style = tab -indent_size = 8 -tab_width = 8 -end_of_line = lf charset = utf-8 +end_of_line = lf +indent_size = 8 +indent_style = tab insert_final_newline = true +tab_width = 8 [{Makefile,Makefile.*,makefile,*.mk}] trim_trailing_whitespace = true #max_line_length = 80 [*.{c,cc,C,cxx,cpp,h,hh,H,hxx,hpp,inc,y}] -indent_style = space indent_size = 2 +indent_style = space trim_trailing_whitespace = true #max_line_length = 120 [{*.rb,Rakefile,rakefile,*.rake,*.gemspec,*.gembox}] -indent_style = space indent_size = 2 +indent_style = space trim_trailing_whitespace = true #max_line_length = 120 [*.bat] -end_of_line = crlf charset = latin1 +end_of_line = crlf #max_line_length = 80 [*.{yaml,yml}] -indent_style = space indent_size = 2 +indent_style = space [*.md] -indent_style = space indent_size = 2 +indent_style = space diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..3dab080a9 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,4 @@ +# Extend the tab with 8 whitespace +6fc5dc986a5ffc1a74c63ad0617ea1dcc10d3cdd +# reformatted doc/opcode.md +61e8a540869c57ebddac53cf9d243db407d57fff diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml index 671046203..a1023acbd 100644 --- a/.github/linters/.markdown-lint.yml +++ b/.github/linters/.markdown-lint.yml @@ -1,13 +1,26 @@ +# https://github.com/DavidAnson/markdownlint#rules--aliases +# markdownlint -c .github/linters/.markdown-lint.yml . + +# MD001 heading-increment/header-increment - Heading levels should only increment by one level at a time MD001: false -MD003: false -MD005: false -MD007: false + +# MD010 no-hard-tabs - Hard tabs MD010: false -MD011: false + +# MD013 line-length - Line length MD013: false + +# MD014 commands-show-output - Dollar signs used before commands without showing output MD014: false + +# MD024 no-duplicate-heading/no-duplicate-header - Multiple headings with the same content MD024: false + +# MD025 single-title/single-h1 - Multiple top-level headings in the same document MD025: false + +# MD026 no-trailing-punctuation - Trailing punctuation in heading MD026: false + +# MD040 fenced-code-language - Fenced code blocks should have a language specified MD040: false -MD046: false diff --git a/.github/linters/.yaml-lint.yml b/.github/linters/.yaml-lint.yml index 88f3b4eb9..be4c88798 100644 --- a/.github/linters/.yaml-lint.yml +++ b/.github/linters/.yaml-lint.yml @@ -1,5 +1,6 @@ --- - +# https://yamllint.readthedocs.io/en/stable/ +# yamllint --strict -c .github/linters/.yaml-lint.yml . extends: default rules: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 93e759c3e..07a24d994 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: gcc steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Ruby version run: ruby -v - name: Compiler version @@ -25,7 +25,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: clang steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Ruby version run: ruby -v - name: Compiler version @@ -40,7 +40,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: gcc steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Ruby version run: ruby -v - name: Compiler version @@ -55,7 +55,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: clang steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Ruby version run: ruby -v - name: Compiler version @@ -70,7 +70,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: clang steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Ruby version run: ruby -v - name: Compiler version @@ -85,7 +85,7 @@ jobs: MRUBY_CONFIG: ci/gcc-clang CC: gcc steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Ruby version run: ruby -v - name: Compiler version @@ -105,8 +105,8 @@ jobs: package-dir: C:\cygwin-package cache-version: v1 steps: - - uses: actions/checkout@v2 - - uses: actions/[email protected] + - uses: actions/[email protected] + - uses: actions/[email protected] with: path: ${{ env.package-dir }} key: ${{ runner.os }}-cygwin-${{ env.cache-version }} @@ -145,7 +145,7 @@ jobs: env: MRUBY_CONFIG: ci/msvc steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Ruby version run: ruby -v - name: Build and test diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 75f80a558..184ca54c3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/[email protected] with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f949c5bbc..51c50faf9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,29 +4,29 @@ on: [pull_request] jobs: misspell: - name: Check Spelling + name: Check spelling with misspell runs-on: ubuntu-latest steps: - name: Check Out - uses: actions/checkout@v2 + uses: actions/[email protected] - name: Install - run: | - wget -O - -q https://git.io/misspell | sh -s -- -b . + run: wget -O - -q https://git.io/misspell | sh -s -- -b . - name: Misspell - run: | - git ls-files --empty-directory | xargs ./misspell -error - merge-conflict: - name: Merge Conflict + run: git ls-files --empty-directory | xargs ./misspell -error + pre-commit: + name: Run pre-commit runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/[email protected] - name: Check merge conflict run: | - grep "^<<<<<<< HEAD" $(git ls-files | xargs) && exit 1 || true - trailing-whitespace: - name: Trailing whitespace - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Check for trailing whitespace - run: "! git grep -EIn $'[ \t]+$'" + python -m pip install --upgrade pip + pip install pre-commit + - name: Set PY + run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV + - uses: actions/cache@v1 + with: + path: ~/.cache/pre-commit + key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} + - name: Run pre-commit + run: pre-commit run --all-files diff --git a/.github/workflows/oss-fuzz.yml b/.github/workflows/oss-fuzz.yml index e693b913d..739e4afad 100644 --- a/.github/workflows/oss-fuzz.yml +++ b/.github/workflows/oss-fuzz.yml @@ -16,7 +16,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/[email protected] + uses: actions/[email protected] if: failure() with: name: artifacts diff --git a/.github/workflows/linter.yml b/.github/workflows/super-linter.yml index 306060c3f..df453bdce 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/super-linter.yml @@ -1,4 +1,4 @@ -name: Lint Code Base +name: Super Linter on: push: @@ -12,14 +12,12 @@ jobs: name: Lint Code Base runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: github/super-linter@v3 + - uses: actions/[email protected] + - uses: github/[email protected] env: ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true # VALIDATE_BASH_EXEC: true # VALIDATE_EDITORCONFIG: true - VALIDATE_MARKDOWN: true # VALIDATE_SHELL_SHFMT: true - VALIDATE_YAML: true GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 46abd0675..f260b5138 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,15 +10,19 @@ repos: - id: identity - id: check-hooks-apply - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.0.1 hooks: - id: check-added-large-files - id: check-case-conflict - id: check-executables-have-shebangs exclude: ^test/t/lang\.rb$ - id: check-merge-conflict + - id: check-vcs-permalinks - id: check-yaml + - id: detect-private-key - id: end-of-file-fixer + - id: file-contents-sorter + files: ^codespell\.txt$ - id: fix-byte-order-marker - id: mixed-line-ending - id: trailing-whitespace @@ -27,16 +31,28 @@ repos: # hooks: # - id: forbid-tabs # - id: remove-tabs + - repo: https://github.com/codespell-project/codespell + rev: v2.1.0 + hooks: + - id: codespell + name: Run codespell + description: Check spelling with codespell + entry: codespell --ignore-words=codespell.txt - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.27.1 + rev: v0.29.0 hooks: - id: markdownlint name: Run markdownlint + description: Checks the style of Markdown files entry: markdownlint -c .github/linters/.markdown-lint.yml . + types: [markdown] + files: \.(md|mdown|markdown)$ - repo: https://github.com/adrienverge/yamllint - rev: v1.26.1 + rev: v1.26.3 hooks: - id: yamllint - name: Check YAML files with yamllint - entry: yamllint --strict -c .github/linters/.yaml-lint.yml . + name: Run yamllint + description: Check YAML files with yamllint + entry: yamllint --strict -c .github/linters/.yaml-lint.yml types: [yaml] + files: \.(yaml|yml)$ @@ -1,16 +1,16 @@ # Authors of mruby (mruby developers) -## The List of Contributors sorted by number of commits (as of 2021-04-12 ff2ffe3) +## The List of Contributors sorted by number of commits (as of 2021-10-16 36bca25) - 7340 Yukihiro "Matz" Matsumoto (@matz)* - 576 KOBAYASHI Shuji (@shuujii) + 7818 Yukihiro "Matz" Matsumoto (@matz)* + 586 KOBAYASHI Shuji (@shuujii) 376 Daniel Bovensiepen (@bovi) - 344 Takeshi Watanabe (@take-cheeze)* + 346 Takeshi Watanabe (@take-cheeze)* 334 Masaki Muranaka (@monaka) + 311 dearblue (@dearblue)* 298 Tomoyuki Sahara (@tsahara)* - 276 dearblue (@dearblue)* 234 Jun Hiroe (@suzukaze) - 217 Cremno (@cremno)* + 219 Cremno (@cremno)* 208 Yuki Kurihara (@ksss)+ 148 Yasuhiro Matsumoto (@mattn)* 113 Carson McDonald (@carsonmcdonald) @@ -25,6 +25,7 @@ 59 Kurebayashi, Takahiro (@crimsonwoods)* 56 h2so5 (@h2so5) 52 Ralph Desir (@Mav7)* + 47 John Bampton (@jbampton) 45 Rory O'Connell (@RoryO)* 43 Yuichiro Kaneko (@yui-knk)+ 42 fleuria (@flaneur2020) @@ -35,22 +36,21 @@ 31 MATSUMOTO Ryosuke (@matsumotory)* 30 Nobuyoshi Nakada (@nobu) 28 Masayoshi Takahashi (@takahashim)+ - 26 John Bampton (@jbampton) 24 Julian Aron Prenner (@furunkel)* 24 Ryan Scott (@ryan-scott-dev)* 22 Clayton Smith (@clayton-shopify) 22 Zachary Scott (@zzak)* + 22 mirichi (@mirichi) 21 Jared Breeden (@jbreeden)* - 20 mirichi (@mirichi) + 20 Uchio Kondo (@udzura)* 19 Bouke van der Bijl (@bouk) 19 Felix Jones (@felixjones)* 19 Hidetaka Takano (@TJ-Hidetaka-Takano) - 19 Uchio Kondo (@udzura)* 19 go kikuta (@gkta)* 18 Corey Powell (@IceDragon200) 18 Jon Maken (@jonforums)+ 18 Mitchell Blank Jr (@mitchblank)* - 16 Ryan Lopopolo (@lopopolo) + 17 Ryan Lopopolo (@lopopolo) 16 bggd (@bggd) 16 kano4 (@kano4) 14 Blaž Hrastnik (@archseer)* @@ -107,6 +107,7 @@ 5 Yurie Yamane (@yurie)+ 5 dreamedge (@dreamedge) 5 nkshigeru (@nkshigeru) + 4 Dante Catalfamo (@dantecatalfamo) 4 Goro Kikuchi (@gorogit) 4 Herwin Weststrate (@herwinw) 4 Jon Moss (@maclover7) @@ -122,7 +123,7 @@ 4 kurodash (@kurodash)* 4 masahino (@masahino) 4 wanabe (@wanabe)* - 4 xuejianqing (@zhihuikeji) + 4 xuejianqing (@joans321) 3 Anton Davydov (@davydovanton) 3 Carlo Prelz (@asfluido)* 3 David Turnbull (@AE9RB) @@ -131,8 +132,8 @@ 3 J. Mutua (@katmutua)+ 3 Jan Berdajs (@mrbrdo) 3 Joseph McCullough (@joequery) + 3 Mark McCurry (@fundamental) 3 Nobuhiro Iwamatsu (@iwamatsu) - 3 Mark McCurry (@fundamental) 3 Per Lundberg (@perlun)* 3 Rob Fors (@robfors)* 3 Rodrigo Malizia (@rmalizia44)+ @@ -238,6 +239,7 @@ 1 Megumi Tomita (@tomykaira)+ 1 Mitchell Hashimoto (@mitchellh) 1 Mitsutaka Mimura (@takkanm) + 1 Nathan Ladd (@ntl) 1 Nicholas (@knf) 1 Nozomi SATO (@nozomiS) 1 Okumura Takahiro (@hfm) @@ -255,6 +257,7 @@ 1 Sayed Abdelhaleem (@visualsayed) 1 Shugo Maeda (@shugo) 1 Sorah Fukumori (@sorah) + 1 Stuart Hinson (@stuarth) 1 Takuma Kume (@takumakume)+ 1 Thomas Schmidt (@digitaltom) 1 Timo Schilling (@timoschilling) @@ -286,6 +289,12 @@ `*` - Entries unified according to names and addresses `+` - Entries with names different from commits +## Contributors without named commits + + Yuichi Osawa (Mitsubishi Electric Micro-Computer Application Software) + Shota Nakano (Manycolors) + Bjorn De Meyer + ## Corporate contributors Ministry of Economy, Trade and Industry, Japan @@ -297,9 +306,3 @@ Specified non-profit organization mruby Forum Mitsubishi Electric Micro-Computer Application Software Co.,Ltd. Manycolors, Inc. - -## Contributors without named commits - - Yuichi Osawa (Mitsubishi Electric Micro-Computer Application Software) - Shota Nakano (Manycolors) - Bjorn De Meyer diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ebc9c2239..516be1e3c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ things in mind before submitting your pull request: * Work on the latest possible state of **mruby/master** * Create a branch which is dedicated to your change -* Test your changes before creating a pull request (```rake test```) +* Test your changes before creating a pull request (`rake test`) * If possible write a test case which confirms your change * Don't mix several features or bug-fixes in one pull request * Create a meaningful commit message @@ -18,15 +18,15 @@ things in mind before submitting your pull request: * Use mrbgem to provide non ISO features (classes, modules and methods) unless you have a special reason to implement them in the core -## Pre-commit +## pre-commit -A framework for managing and maintaining multi-language pre-commit hooks. -Pre-commit can be [installed](https://pre-commit.com/#installation) with `pip`, `curl`, `brew` or `conda`. +A framework for managing and maintaining multi-language `pre-commit` hooks. +`pre-commit` can be [installed](https://pre-commit.com/#installation) with `pip`, `curl`, `brew` or `conda`. -You need to first install pre-commit and then install the pre-commit hooks with `pre-commit install`. -Now pre-commit will run automatically on git commit! +You need to first install `pre-commit` and then install the `pre-commit` hooks with `pre-commit install`. +Now `pre-commit` will run automatically on git commit! -It's usually a good idea to run the hooks against all the files when adding new hooks (usually pre-commit will only run on the changed files during git hooks). +It's usually a good idea to run the hooks against all the files when adding new hooks (usually `pre-commit` will only run on the changed files during git hooks). Use `pre-commit run --all-files` to check all files. To run a single hook use `pre-commit run --all-files <hook_id>` @@ -37,6 +37,22 @@ To update use `pre-commit autoupdate` * [Usage](https://pre-commit.com/#usage) * [pre-commit-autoupdate](https://pre-commit.com/#pre-commit-autoupdate) +## Spell Checking + +We are running [misspell](https://github.com/client9/misspell) which is mainly written in +[Golang](https://golang.org/) to check spelling with [GitHub Actions](.github/workflows/lint.yml). +Correct commonly misspelled English words quickly with `misspell`. You can run `misspell` locally +against all files with: + +```bash +find . -type f | xargs ./misspell -error +``` + +Notable `misspell` help options or flags are: + +* `-i` string: ignore the following corrections, comma separated +* `-w`: Overwrite file with corrections (default is just to display) + ## Coding conventions How to style your C and Ruby code which you want to submit. @@ -67,13 +83,13 @@ on-demand. #### Insert a break after the function return value: - ```C - int - main(void) - { - ... - } - ``` +```c +int +main(void) +{ + ... +} +``` ### Ruby code diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..2f0ae5b28 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +## Reporting a Vulnerability + +If you have any security concern, contact <[email protected]>. + +## Scope + +We consider following issues as vulnerabilities: + +* Remote code execution +* Crash caused by a valid Ruby script + +We *don't* consider following issues as vulnerabilities: + +* Runtime C undefined behavior (including integer overflow) +* Crash caused by misused API +* Crash caused by tweaked compiled binary @@ -1,17 +1,14 @@ -Thing to Do in the future -=== +# Thing to Do in the future # After mruby 3.0 -* replace `fp_fmt.c` by `float_format` (<https://github.com/dhylands/format-float.git>) * multi-precision integer -* WORD_BOXING: Pack some floats in `mrb_value` * NAN_BOXING: Allow `MRB_INT64` along with NaN boxing -* keyword arguments à la Ruby3.0 (using `OP_SENDVK`) -* parser and code generator independent from `mrb_state` (mmruby?) +* keyword arguments à la Ruby3.0 (update `OP_SEND`) +* parser and code generator independent from `mrb_state` (picoruby?) +* variable sized AST node # Things to do (Things that are not done yet) * `begin ... end while cond` to behave as CRuby * special variables ($1,$2..) -* super in aliased methods diff --git a/benchmark/build_config_cc.rb b/benchmark/build_config_cc.rb deleted file mode 100644 index 56d725bc7..000000000 --- a/benchmark/build_config_cc.rb +++ /dev/null @@ -1,13 +0,0 @@ -MRuby::Build.new do |conf| - toolchain :gcc -end - -MRuby::Build.new('gcc') do |conf| - toolchain :gcc - conf.gembox 'default' -end - -MRuby::Build.new('clang') do |conf| - toolchain :clang - conf.gembox 'default' -end diff --git a/build_config/IntelGalileo.rb b/build_config/IntelGalileo.rb index d28986e36..f1f39e5dc 100644 --- a/build_config/IntelGalileo.rb +++ b/build_config/IntelGalileo.rb @@ -74,7 +74,7 @@ MRuby::CrossBuild.new("Galileo") do |conf| conf.gem :core => "mruby-fiber" conf.gem :core => "mruby-toplevel-ext" - #lightweigh regular expression + #lightweight regular expression conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master" #Arduino API diff --git a/build_config/android_arm64-v8a.rb b/build_config/android_arm64_v8a.rb index 7fab2f063..7fab2f063 100644 --- a/build_config/android_arm64-v8a.rb +++ b/build_config/android_arm64_v8a.rb diff --git a/build_config/boxing.rb b/build_config/boxing.rb index 4b07c22e1..d861bd537 100644 --- a/build_config/boxing.rb +++ b/build_config/boxing.rb @@ -3,8 +3,6 @@ bits = [64, 32] ints = [64, 32] boxings.product(bits, ints) do |boxing, bit, int| - next if boxing == "nan" && int == 64 - MRuby::Build.new("boxing-#{boxing}-m#{bit}-i#{int}") do |conf| conf.toolchain :gcc conf.gembox 'default' diff --git a/build_config/ci/gcc-clang.rb b/build_config/ci/gcc-clang.rb index aa4a1a87d..eeaab5d0f 100644 --- a/build_config/ci/gcc-clang.rb +++ b/build_config/ci/gcc-clang.rb @@ -6,7 +6,7 @@ MRuby::Build.new('full-debug') do |conf| # include all core GEMs conf.gembox 'full-core' - conf.cc.defines += %w(MRB_GC_STRESS MRB_USE_DEBUG_HOOK) + conf.cc.defines += %w(MRB_GC_STRESS MRB_USE_DEBUG_HOOK MRB_UTF8_STRING) conf.enable_test end @@ -18,7 +18,7 @@ MRuby::Build.new do |conf| conf.gembox 'full-core' conf.gem :core => 'mruby-bin-debugger' conf.compilers.each do |c| - c.defines += %w(MRB_GC_FIXED_ARENA) + c.defines += %w(MRB_GC_FIXED_ARENA MRB_UTF8_STRING) end conf.enable_bintest conf.enable_test @@ -28,9 +28,9 @@ MRuby::Build.new('cxx_abi') do |conf| conf.toolchain conf.gembox 'full-core' - conf.cc.flags += %w(-fpermissive) + conf.cc.flags += %w(-fpermissive -std=gnu++03) conf.compilers.each do |c| - c.defines += %w(MRB_GC_FIXED_ARENA) + c.defines += %w(MRB_GC_FIXED_ARENA MRB_UTF8_STRING) end conf.enable_test diff --git a/build_config/cross-mingw-winetest.rb b/build_config/cross-mingw-winetest.rb new file mode 100644 index 000000000..fad06b265 --- /dev/null +++ b/build_config/cross-mingw-winetest.rb @@ -0,0 +1,91 @@ + +# Cross-compile using MinGW and test using Wine. +# +# Steps: +# +# 1. Install MinGW; 64-bit target seems to work best. +# +# 2. Install Wine. +# +# 3. Run command: +# +# wine cmd /c echo "Hello world"' +# +# This will confirm that Wine works and will trigger standard +# Wine setup, which is slow. +# +# 4. Confirm that drive 'z:' is mapped to your root filesystem. +# (This is supposed to be a default but it helps to +# double-check.) To confirm, run: +# +# wine cmd /c dir 'z:\\' +# +# This should give you a DOS-style equivalent of 'ls /'. If not, +# you'll need to fix that with winecfg or by adding a symlink to +# '~/.wine/dosdevices'. +# +# 5. You will likely need to tweak the settings below to work with +# your configuration unless it is exactly like one of the platforms +# I've tested on (Ubuntu 20.04 or macOS using brew.) +# +# 6. Run the build command: +# +# MRUBY_CONFIG=build_config/cross-mingw-winetest.rb rake test +# +# If all goes well, you should now have Windows executables and a +# set of passing tests. +# +# +# Caveats: +# +# 1. This works by using a helper script that rewrites test output +# to make it look *nix-like and then handing it back to the test +# cases. Some of the existing tests were (slightly) modified to +# make this easier but only for the 'full-core' gembox. Other +# gems' bintests may or may not work with the helper script and +# may or may not be fixable by extending the script. +# +# 2. MinGW and Wine are both complex and not very consistent so you +# will likely need to do some fiddling to get things to work. +# +# 3. This script assumes you are running it on a *nix-style OS. +# +# 4. I recommend building 64-bit targets only. Building a 32-bit +# Windows binary with i686-w64-mingw32 seems to work (at least, +# it did for me) but the resulting executable failed a number of +# unit tests due to small errors in some floating point +# operations. It's unclear if this indicates more serious problems. +# + + +MRuby::CrossBuild.new("cross-mingw-winetest") do |conf| + conf.toolchain :gcc + + conf.host_target = "x86_64-w64-mingw32" + + # Ubuntu 20 + conf.cc.command = "#{conf.host_target}-gcc-posix" + + # macOS+Wine from brew + #conf.cc.command = "#{conf.host_target}-gcc" + + conf.linker.command = conf.cc.command + conf.archiver.command = "#{conf.host_target}-gcc-ar" + conf.exts.executable = ".exe" + + # By default, we compile as static as possible to remove runtime + # MinGW dependencies; they are probably fixable but it gets + # complicated. + conf.cc.flags = ['-static'] + conf.linker.flags += ['-static'] + + conf.test_runner do |t| + thisdir = File.absolute_path( File.dirname(__FILE__) ) + t.command = File.join(thisdir, * %w{ helpers wine_runner.rb}) + end + + conf.gembox "full-core" + + conf.enable_bintest + conf.enable_test +end diff --git a/build_config/default.rb b/build_config/default.rb index 894f1055b..f5e2cbb71 100644 --- a/build_config/default.rb +++ b/build_config/default.rb @@ -42,7 +42,7 @@ MRuby::Build.new do |conf| # linker.library_paths = [] # linker.option_library = '-l%s' # linker.option_library_path = '-L%s' - # linker.link_options = "%{flags} -o "%{outfile}" %{objs} %{libs}" + # linker.link_options = %Q[%{flags} -o "%{outfile}" %{objs} %{libs}] # end # Archiver settings diff --git a/build_config/dreamcast_shelf.rb b/build_config/dreamcast_shelf.rb index ee9b260a5..092fde0d0 100644 --- a/build_config/dreamcast_shelf.rb +++ b/build_config/dreamcast_shelf.rb @@ -74,7 +74,6 @@ MRuby::CrossBuild.new("dreamcast") do |conf| conf.gem :core => "mruby-array-ext" conf.gem :core => "mruby-binding" - conf.gem :core => "mruby-binding-core" conf.gem :core => "mruby-catch" conf.gem :core => "mruby-class-ext" conf.gem :core => "mruby-cmath" @@ -90,7 +89,6 @@ MRuby::CrossBuild.new("dreamcast") do |conf| conf.gem :core => "mruby-exit" conf.gem :core => "mruby-fiber" conf.gem :core => "mruby-hash-ext" - conf.gem :core => "mruby-inline-struct" # conf.gem :core => "mruby-io" conf.gem :core => "mruby-kernel-ext" conf.gem :core => "mruby-math" diff --git a/build_config/helpers/wine_runner.rb b/build_config/helpers/wine_runner.rb new file mode 100755 index 000000000..9a7eb46b0 --- /dev/null +++ b/build_config/helpers/wine_runner.rb @@ -0,0 +1,71 @@ +#!/usr/bin/env ruby + +# Wrapper for running tests for cross-compiled Windows builds in Wine. + +require 'open3' + +DOSROOT = 'z:' + +# Rewrite test output to replace DOS-isms with Unix-isms. +def clean(output, stderr = false) + ends_with_newline = !!(output =~ /\n$/) + executable = ARGV[0].gsub(/\.exe\z/i, '') + + # Fix line-ends + output = output.gsub(/\r\n/, "\n") + + # Strip out Wine messages + + + results = output.split(/\n/).map do |line| + # Fix file paths + if line =~ /#{DOSROOT}\\/i + line.gsub!(/#{DOSROOT}([^:]*)/i) { |path| + path.gsub!(/^#{DOSROOT}/i, '') + path.gsub!(%r{\\}, '/') + path + } + end + + # strip '.exe' off the end of the executable's name if needed + line.gsub!(/(#{Regexp.escape executable})\.exe/i, '\1') + + line + end + + result_text = results.join("\n") + result_text += "\n" if ends_with_newline + return result_text +end + + +def main + if ARGV.empty? || ARGV[0] =~ /^- (-?) (\?|help|h) $/x + puts "#{$0} <command-line>" + exit 0 + end + + # For simplicity, just read all of stdin into memory and pass that + # as an argument when invoking wine. (Skipped if STDIN was not + # redirected.) + if !STDIN.tty? + input = STDIN.read + else + input = "" + end + + # Disable all Wine messages so they don't interfere with the output + ENV['WINEDEBUG'] = 'err-all,warn-all,fixme-all,trace-all' + + # Run the program in wine and capture the output + output, errormsg, status = Open3.capture3('wine', *ARGV, :stdin_data => input) + + # Clean and print the results. + STDOUT.write clean(output) + STDERR.write clean(errormsg) + + exit(status.exitstatus) +end + + +main() diff --git a/build_config/no-float.rb b/build_config/host-nofloat.rb index 977bf4e12..977bf4e12 100644 --- a/build_config/no-float.rb +++ b/build_config/host-nofloat.rb diff --git a/build_config/serenity.rb b/build_config/serenity.rb new file mode 100644 index 000000000..6704d2673 --- /dev/null +++ b/build_config/serenity.rb @@ -0,0 +1,26 @@ +# Cross compiling configuration for SerenityOS +# Graphical Unix-like operating system for x86 computers. +# https://github.com/SerenityOS/serenity +# +# Should be built using the SerenityOS Ports system +# https://github.com/SerenityOS/serenity/tree/master/Ports +# +# As of 2021/08/20, SERENITY_ARCH is defined in the SerenityOS Ports +# build script to always be either "i686" or "x86_64" + +MRuby::CrossBuild.new('serenity') do |conf| + conf.toolchain :gcc + + conf.archiver.command = "#{ENV['SERENITY_ARCH']}-pc-serenity-ar" + conf.linker.command = "#{ENV['SERENITY_ARCH']}-pc-serenity-g++" + + conf.cxx.command = "#{ENV['SERENITY_ARCH']}-pc-serenity-g++" + conf.cxx.defines << (ENV['SERENITY_ARCH'].include?('64') ? 'MRB_64BIT' : 'MRB_32BIT') + + conf.cc.command = "#{ENV['SERENITY_ARCH']}-pc-serenity-gcc" + conf.cc.defines << (ENV['SERENITY_ARCH'].include?('64') ? 'MRB_64BIT' : 'MRB_32BIT') + + conf.gembox 'full-core' + + conf.test_runner.command = 'env' +end diff --git a/codespell.txt b/codespell.txt new file mode 100644 index 000000000..dcc0ddb43 --- /dev/null +++ b/codespell.txt @@ -0,0 +1,17 @@ +ans +ba +creat +delet +disabl +filetest +fo +hel +hist +ist +methid +nd +quitt +remore +runn +sting +upto diff --git a/doc/guides/compile.md b/doc/guides/compile.md index 7156b2b68..2923a2676 100644 --- a/doc/guides/compile.md +++ b/doc/guides/compile.md @@ -138,18 +138,18 @@ C Compiler has header searcher to detect installed library. If you need an include path of header file use `search_header_path`: ```ruby -# Searches ```iconv.h```. +# Searches `iconv.h`. # If found it will return include path of the header file. -# Otherwise it will return nil . +# Otherwise it will return nil. fail 'iconv.h not found' unless conf.cc.search_header_path 'iconv.h' ``` If you need a full file name of header file use `search_header`: ```ruby -# Searches ```iconv.h```. +# Searches `iconv.h`. # If found it will return full path of the header file. -# Otherwise it will return nil . +# Otherwise it will return nil. iconv_h = conf.cc.search_header 'iconv.h' print "iconv.h found: #{iconv_h}\n" ``` @@ -333,9 +333,9 @@ conf.enable_debug When debugging mode is enabled * Macro `MRB_DEBUG` would be defined. - * Which means `mrb_assert()` macro is enabled. + * Which means `mrb_assert()` macro is enabled. * Debug information of irep would be generated by `mrbc`. - * Because `-g` flag would be added to `mrbc` runner. + * Because `-g` flag would be added to `mrbc` runner. * You can have better backtrace of mruby scripts with this. ## Cross-Compilation @@ -379,23 +379,25 @@ end During the build process the directory `build` will be created in the root directory. The structure of this directory will look like this: - +- build - | - +- host - | - +- LEGAL <- License description - | - +- bin <- Binaries (mirb, mrbc and mruby) - | - +- lib <- Libraries (libmruby.a and libmruby_core.a) - | - +- mrbc <- Minimal mrbc place - | - +- mrbgems <- Compilation result from mrbgems - | - +- mrblib <- Compilation result from mrblib - | - +- src <- Compilation result from C sources +``` ++- build + | + +- host + | + +- LEGAL <- License description + | + +- bin <- Binaries (mirb, mrbc and mruby) + | + +- lib <- Libraries (libmruby.a and libmruby_core.a) + | + +- mrbc <- Minimal mrbc place + | + +- mrbgems <- Compilation result from mrbgems + | + +- mrblib <- Compilation result from mrblib + | + +- src <- Compilation result from C sources +``` The compilation workflow will look like this: @@ -425,31 +427,33 @@ The compilation workflow will look like this: In case of a cross-compilation to `i386` the `build` directory structure looks like this: - +- build - | - +- host - | | - | +- bin <- Native Binaries - | | - | +- lib <- Native Libraries - | | - | +- mrbgems - | | - | +- src - | - +- i386 - | - +- bin <- Cross-compiled Binaries - | - +- include <- Header Directory - | - +- lib <- Cross-compiled Libraries - | - +- mrbgems - | - +- mrblib - | - +- src +``` ++- build + | + +- host + | | + | +- bin <- Native Binaries + | | + | +- lib <- Native Libraries + | | + | +- mrbgems + | | + | +- src + | + +- i386 + | + +- bin <- Cross-compiled Binaries + | + +- include <- Header Directory + | + +- lib <- Cross-compiled Libraries + | + +- mrbgems + | + +- mrblib + | + +- src +``` An extra directory is created for the target platform. In case you compile for `i386` a directory called `i386` is created under the diff --git a/doc/guides/mrbconf.md b/doc/guides/mrbconf.md index b5bc8c85c..e71346ae6 100644 --- a/doc/guides/mrbconf.md +++ b/doc/guides/mrbconf.md @@ -151,17 +151,18 @@ largest value of required alignment. ## Reduce heap memory configuration -`MRB_USE_LINK_TIME_RO_DATA_P` +`MRB_USE_ETEXT_RO_DATA_P` -* Only available on ELF platforms. -* If you specify the address of a read-only section when creating a symbol or string, that string will be used as it is. -* Heap memory can be saved. -* Uses `__ehdr_start` and `__init_array_start`. -* It must be `__ehdr_start < data_addr < __init_array_start`. +* Use `etext` and `edata` section addresses defined by the linker to detect read-only data. +* Those addresses are widely available, but not portable, nor standardized. +* This macro is defined by default on User-mode Linux. + +`MRB_NO_DEFAULT_RO_DATA_P` + +* Define this macro when the default `mrb_ro_data_p()` does not work for any reason. `MRB_USE_CUSTOM_RO_DATA_P` -* Takes precedence over `MRB_USE_LINK_TIME_RO_DATA_P`. * Please try if `MRB_USE_LINK_TIME_RO_DATA_P` is not available. * The `mrb_ro_data_p()` function is implemented by the user in an arbitrary file. * The prototype declaration is `mrb_bool mrb_ro_data_p(const char *ptr)`. diff --git a/doc/guides/mrbgems.md b/doc/guides/mrbgems.md index d4160ebc8..03f8829e1 100644 --- a/doc/guides/mrbgems.md +++ b/doc/guides/mrbgems.md @@ -55,8 +55,8 @@ conf.gem mgem: 'mruby-redis', checksum_hash: '3446d19fc4a3f9697b5ddbf2a904f301c4 If there are missing dependencies, mrbgem dependencies solver will reference mrbgem from the core or mgem-list. -To pull all gems from remote GIT repository on build, call ```rake -p```, -or ```rake --pull-gems```. +To pull all gems from remote GIT repository on build, call `rake -p`, +or `rake --pull-gems`. NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. @@ -111,21 +111,21 @@ contains every gem found in the `mrbgems` directory. The maximal GEM structure looks like this: ``` -+- GEM_NAME <- Name of GEM - | - +- README.md <- Readme for GEM - | - +- mrbgem.rake <- GEM Specification - | - +- include/ <- Header for Ruby extension (will exported) - | - +- mrblib/ <- Source for Ruby extension - | - +- src/ <- Source for C extension - | - +- tools/ <- Source for Executable (in C) - | - +- test/ <- Test code (Ruby) ++- GEM_NAME <- Name of GEM + | + +- README.md <- Readme for GEM + | + +- mrbgem.rake <- GEM Specification + | + +- include/ <- Header for Ruby extension (will exported) + | + +- mrblib/ <- Source for Ruby extension + | + +- src/ <- Source for C extension + | + +- tools/ <- Source for Executable (in C) + | + +- test/ <- Test code (Ruby) ``` The folder `mrblib` contains pure Ruby files to extend mruby. The folder `src` @@ -200,8 +200,8 @@ Version requirement supports following operators: * '>=': is equal or greater * '<=': is equal or lesser * '~>': is equal or greater and is lesser than the next major version - * example 1: '~> 2.2.2' means '>= 2.2.2' and '< 2.3.0' - * example 2: '~> 2.2' means '>= 2.2.0' and '< 3.0.0' + * example 1: '~> 2.2.2' means '>= 2.2.2' and '< 2.3.0' + * example 2: '~> 2.2' means '>= 2.2.0' and '< 3.0.0' When more than one version requirements is passed, the dependency must satisfy all of it. @@ -215,7 +215,7 @@ use `MRuby::Build#gem` in the build configuration to override default gem. If you have conflicting GEMs use the following method: * `spec.add_conflict(gem, *requirements)` - * The `requirements` argument is same as in `add_dependency` method. + * The `requirements` argument is same as in `add_dependency` method. like following code: @@ -256,7 +256,7 @@ By default, `/...absolute path.../{GEM_NAME}/include` will be exported. So it is recommended not to put GEM's local header files on include/. These exports are retroactive. -For example: when B depends to C and A depends to B, A will get include paths exported by C. +For example: when B depends on C and A depends on B, A will get include paths exported by C. Exported include_paths are automatically appended to GEM local include_paths by rake. You can use `spec.export_include_paths` accessor if you want more complex build. @@ -273,7 +273,7 @@ mrbgems expects that you have implemented a C method called by the name of your GEM. If you call your GEM `c_extension_example`, your initialisation method could look like this: -```C +```c void mrb_c_extension_example_gem_init(mrb_state* mrb) { struct RClass *class_cextension = mrb_define_module(mrb, "CExtension"); @@ -288,7 +288,7 @@ mrbgems expects that you have implemented a C method called by the name of your GEM. If you call your GEM `c_extension_example`, your finalizer method could look like this: -```C +```c void mrb_c_extension_example_gem_final(mrb_state* mrb) { free(someone); @@ -297,19 +297,21 @@ mrb_c_extension_example_gem_final(mrb_state* mrb) { ### Example - +- c_extension_example/ - | - +- README.md (Optional) - | - +- src/ - | | - | +- example.c <- C extension source - | - +- test/ - | | - | +- example.rb <- Test code for C extension - | - +- mrbgem.rake <- GEM specification +``` ++- c_extension_example/ + | + +- README.md (Optional) + | + +- src/ + | | + | +- example.c <- C extension source + | + +- test/ + | | + | +- example.rb <- Test code for C extension + | + +- mrbgem.rake <- GEM specification +``` ## Ruby Extension @@ -323,19 +325,21 @@ none ### Example - +- ruby_extension_example/ - | - +- README.md (Optional) - | - +- mrblib/ - | | - | +- example.rb <- Ruby extension source - | - +- test/ - | | - | +- example.rb <- Test code for Ruby extension - | - +- mrbgem.rake <- GEM specification +``` ++- ruby_extension_example/ + | + +- README.md (Optional) + | + +- mrblib/ + | | + | +- example.rb <- Ruby extension source + | + +- test/ + | | + | +- example.rb <- Test code for Ruby extension + | + +- mrbgem.rake <- GEM specification +``` ## C and Ruby Extension @@ -353,23 +357,25 @@ See C and Ruby example. ### Example - +- c_and_ruby_extension_example/ - | - +- README.md (Optional) - | - +- mrblib/ - | | - | +- example.rb <- Ruby extension source - | - +- src/ - | | - | +- example.c <- C extension source - | - +- test/ - | | - | +- example.rb <- Test code for C and Ruby extension - | - +- mrbgem.rake <- GEM specification +``` ++- c_and_ruby_extension_example/ + | + +- README.md (Optional) + | + +- mrblib/ + | | + | +- example.rb <- Ruby extension source + | + +- src/ + | | + | +- example.c <- C extension source + | + +- test/ + | | + | +- example.rb <- Test code for C and Ruby extension + | + +- mrbgem.rake <- GEM specification +``` ## Binary gems @@ -389,23 +395,23 @@ binary gems, to separate normal gems and binary gems. ### Example ``` - +- mruby-bin-example/ ++- mruby-bin-example/ | - +- README.md (Optional) + +- README.md (Optional) | +- bintest/ - | | - | +- example.rb <- Test code for binary gem + | | + | +- example.rb <- Test code for binary gem | - +- mrbgem.rake <- Gem specification + +- mrbgem.rake <- Gem specification | - +- mrblib/ <- Source for Ruby extension (Optional) + +- mrblib/ <- Source for Ruby extension (Optional) | - +- src/ <- Source for C extension (Optional) + +- src/ <- Source for C extension (Optional) | +- tools/ - | - +- example/ <- Executable name directory - | - +- example.c <- Source for Executable (includes main) + | + +- example/ <- Executable name directory + | + +- example.c <- Source for Executable (includes main) ``` diff --git a/doc/guides/symbol.md b/doc/guides/symbol.md index e9e72a6d3..8f90ce59f 100644 --- a/doc/guides/symbol.md +++ b/doc/guides/symbol.md @@ -4,7 +4,7 @@ Symbols in `mruby` C source code is represented by `mrb_sym` which is alias of `uint32_t`. Lower 30 bits are used for symbols so that higher 2 bits can be used as flags, e.g. `struct mt_elem` in `class.c`. -```C +```c struct mt_elem { union mt_ptr ptr; size_t func_p:1; @@ -57,13 +57,13 @@ To save RAM, `mruby` can use compile-time allocation of some symbols. You can use following macros to get preallocated symbols by including `mruby/presym.h` header. - * `MRB_SYM(xor)` //=> xor (Word characters) - * `MRB_SYM_B(xor)` //=> xor! (Method with Bang) - * `MRB_SYM_Q(xor)` //=> xor? (Method with Question mark) - * `MRB_SYM_E(xor)` //=> xor= (Method with Equal) - * `MRB_CVSYM(xor)` //=> @@xor (Class Variable) - * `MRB_IVSYM(xor)` //=> @xor (Instance Variable) - * `MRB_OPSYM(xor)` //=> ^ (Operator) +* `MRB_SYM(xor)` //=> xor (Word characters) +* `MRB_SYM_B(xor)` //=> xor! (Method with Bang) +* `MRB_SYM_Q(xor)` //=> xor? (Method with Question mark) +* `MRB_SYM_E(xor)` //=> xor= (Method with Equal) +* `MRB_CVSYM(xor)` //=> @@xor (Class Variable) +* `MRB_IVSYM(xor)` //=> @xor (Instance Variable) +* `MRB_OPSYM(xor)` //=> ^ (Operator) For `MRB_OPSYM()`, specify the names corresponding to operators (see `MRuby::Presym::OPERATORS` in `lib/mruby/presym.rb` for the names that diff --git a/doc/limitations.md b/doc/limitations.md index d903d528c..b0caecc8f 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -13,28 +13,6 @@ This document is collecting these limitations. This document does not contain a complete list of limitations. Please help to improve it by submitting your findings. -## `Array` passed to `puts` - -Passing an Array to `puts` results in different output. - -```ruby -puts [1,2,3] -``` - -#### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] - -``` -1 -2 -3 -``` - -#### mruby [3.0.0 (2021-03-05)] - -``` -[1, 2, 3] -``` - ## `Kernel.raise` in rescue clause `Kernel.raise` without arguments does not raise the current exception within @@ -54,7 +32,7 @@ end #### mruby [3.0.0 (2021-03-05)] -No exception is raised. Instead, you have to do: +`RuntimeError` is raised instead of `ZeroDivisionError`. To re-raise the exception, you have to do: ```ruby begin @@ -77,7 +55,7 @@ To reduce memory consumption `Array` does not support instance variables. ```ruby class Liste < Array def initialize(str = nil) - @feld = str + @field = str end end @@ -241,27 +219,6 @@ trace (most recent call last): -e:1: undefined method 'binding' (NoMethodError) ``` -## Keyword arguments - -mruby keyword arguments behave slightly different from CRuby 2.5 -to make the behavior simpler and less confusing. - -#### Ruby [ruby 2.5.1p57 (2018-03-29 revision 63029)] - -``` -$ ruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)' -[[{"a"=>1}], {:b=>2}] -``` - -#### mruby [3.0.0 (2021-03-05)] - -``` -$ ./bin/mruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)' -trace (most recent call last): - [0] -e:1 --e:1: keyword argument hash with non symbol keys (ArgumentError) -``` - ## `nil?` redefinition in conditional expressions Redefinition of `nil?` is ignored in conditional expressions. diff --git a/doc/mruby3.md b/doc/mruby3.0.md index d5218428e..09d2c4af9 100644 --- a/doc/mruby3.md +++ b/doc/mruby3.0.md @@ -1,5 +1,4 @@ -User visible changes in `mruby3` -=== +# User visible changes in `mruby3.0` # Build System @@ -43,7 +42,7 @@ We have ported some new syntax from CRuby. ## Renamed for consistency Some configuration macro names are changed for consistency (use `MRB_USE_XXX` -or `MRB_NO_XXX`). + or `MRB_NO_XXX`). | mruby2 | mruby3 | |--------------------------------|---------------------------| @@ -61,7 +60,7 @@ or `MRB_NO_XXX`). | `DISABLE_MIRB_UNDERSCORE` | `MRB_NO_MIRB_UNDERSCORE` | * `MRB_USE_FLOAT32` is changed from `MRB_USE_FLOAT` to make sure `float` here - means using single precision float, and not the opposite of `MRB_NO_FLOAT`. + means using single precision float, and not the opposite of `MRB_NO_FLOAT`. * `MRB_USE_METHOD_T_STRUCT` uses `struct` version of `mrb_method_t`. More portable but consumes more memory. Turned on by default on 32bit platforms. * `MRB_` prefix is added to those without. @@ -76,13 +75,13 @@ to be default `mrb_value` representation. Now the default is ## `MRB_WORD_BOXING` Pack `mrb_value` in an `intptr_t` integer. Consumes less -memory compared to `MRB_NO_BOXING` especially on 32-bit -platforms. `Fixnum` size is 31 bits, so some integer values +memory compared to `MRB_NO_BOXING` especially on 32 bit +platforms. `Fixnum` size is 31 bits so some integer values does not fit in `Fixnum` integers. ## `MRB_NAN_BOXING` -Pack `mrb_value` in a floating-point number. Nothing +Pack `mrb_value` in a floating pointer number. Nothing changed from previous versions. ## `MRB_USE_MALLOC_TRIM` @@ -117,7 +116,7 @@ Instructions that access pool[i]/syms[i] where i>255. * `OP_STRING16` * `OP_LOADSYM16` -Instructions that load a 32-bit integer. +Instructions that load a 32 bit integer. * `OP_LOADI32` @@ -152,7 +151,7 @@ No more operand extension Jump addresses used to be specified by absolute offset from the start of `iseq`. Now they are relative offset from the address of the next instruction. -## `Random` now use `xoshiro128++` +## `Random` now use `xoshiro128++`. For better and faster random number generation. @@ -160,4 +159,4 @@ For better and faster random number generation. Preallocated symbols are interned at compile-time. They can be accessed via symbols macros (e.g. `MRB_SYM()`). -See [Symbols](./guides/symbol.md). +See [Symbols](https://github.com/mruby/mruby/blob/master/doc/guides/symbol.md). diff --git a/doc/mruby3.1.md b/doc/mruby3.1.md new file mode 100644 index 000000000..abe2946d1 --- /dev/null +++ b/doc/mruby3.1.md @@ -0,0 +1,146 @@ +# User visible changes in `mruby3.1` from `mruby3.0` + +# Build System + +## `build_config` directory + +Several configurations for new platforms are added: + +* `cross-mingw-winetest.rb` +* `cross-mingw.rb` +* `nintendo_switch.rb` +* `serenity.rb` + +Some new configurations for added for convenience. + +* `minimal`: minimal configuration +* `host-f32`: compiles with `mrb_float` as 32 bit `float` +* `host-nofloat`: compiles with no float configuration + +And `android_arm64-v8a.rb` was renamed to `android_arm64_v8a.rb` for consistency. + +# Configuration Options Changed + +Some configuration macros are available: + +* `MRB_WORDBOX_NO_FLOAT_TRUNCATE`: by default, float values are packed in the word if possible, but define this macro to allocate float values in the heap. +* `MRB_USE_RO_DATA_P_ETEXT`: define this macro if `_etext` is available on your platform. +* `MRB_NO_DEFAULT_RO_DATA_P`: define this macro to avoid using predefined `mrb_ro_data_p()` function + +# Language Changes + +## Keyword Arguments + +CRuby3.0 compatible keyword arguments are introduced. +Keyword arguments are basically separated from ordinal arguments + +## New Methods + +* `Array#product` +* `Random.bytes` +* `Random#bytes` + +# Internal Changes + +## Reintroduced Instructions + +`mruby3.0` removed `OP_EXT1`, `OP_EXT2`, `OP_EXT3` for operand extension. But the operand size limitations was too tight for real-world application. +`mruby3.1` reintroduces those extension instructions. + +## Removed Instructions + +`mruby3.1` removed following instructions. + +* `OP_LOADL16` +* `OP_LOADSYM16` +* `OP_STRING16` +* `OP_LAMBDA16` +* `OP_BLOCK16` +* `OP_METHOD16` +* `OP_EXEC16` + +Those instructions are no longer needed by reintroduction of extension instructions. + +* `OP_SENDV` +* `OP_SENDVB` + +Those instructions for method calls with variable number of arguments are no longer needed. They are covered by `OP_SEND` instruction with `n=15`. + +## New Instructions + +`mruby3.1` introduces following new instructions. + +* `OP_GETIDX`: takes 2 operands `a[b]` +* `OP_SETIDX`: takes 3 operands `a[b]=c` +* `OP_SSEND`: takes 3 operands `a=self.b(c...)`; see `OP_SEND` +* `OP_SSENDB`: takes 3 operands `a=self.b(c...){...}`; see `OP_SEND` + +### `OP_GETIDX` and `OP_SETIDX` + +Execute `obj[int]` and `obj[int] = value` respectively, where `obj` is `string|array|hash`. + +### `OP_SSEND` and `OP_SSENDB` + +They are similar to `OP_SEND` and `OP_SENDB` respectively. They initialize the `R[a]` by `self` first so that we can skip one `OP_LOADSELF` instruction for each call. + +## Changed Instructions + +### `OP_SEND` and `OP_SENDB` + +Method calling instructions are unified. Now `OP_SEND` and `OP_SENDB` (method call with a block) can support both splat arguments and keyword arguments as well. + +The brief description of the instructions: + +|`OP_SEND` | BBB | `R[a] = R[a].call(Syms[b],R[a+1..n],R[a+n+1],R[a+n+2]..nk) c=n|nk<<4` | +|`OP_SENDB` | BBB | `R[a] = R[a].call(Syms[b],R[a+1..n],R[a+n+1..nk],R[a+n+2..nk],&R[a+n+2*nk+2]) c=n|nk<<4` | + +Operand C specifies the number of arguments. Lower 4 bits (`n`) represents the number of ordinal arguments, and higher 4 bits (`nk`) represents the number of keyword arguments. +When `n == 15`, the method takes arguments packed in an array. When `nk == 15`, the method takes keyword arguments are packed in a hash. + +### `OP_ARYPUSH` + +Now takes 2 operands and pushes multiple entries to an array. + +## Boxing Updated + +### Word Boxing + +`MRB_WORD_BOXING` now packs floating point numbers in the word, if the size of `mrb_float` is equal or smaller than the size of `mrb_int` by default. +If the size of `mrb_float` and `mrb_int` are same, the last 2 bits in the `mrb_float` are trimmed and used as flags. If you need full precision, you need to define `MRB_WORDBOX_NO_FLOAT_TRUNCATE` as described above. + +### NaN Boxing + +Previous NaN boxing packs values in NaN representation, but pointer retrievals are far more frequent than floating point number references. So we add constant offset to NaN representation to clear higher bits of pointer representation. This representation is called "Favor Pointer" NaN Boxing. + +Also, previous NaN boxing limit the size of `mrb_int` to 4 bytes (32 bits) to fit in NaN values. Now we allocates integer values in the heap, if the value does not fit in the 32 bit range, just like we did in Word Boxing. + +## Constant Folding + +The code generator was updated to reduce the number of instructions, e.g. + +``` +a = 2 * 5 +``` + +will be interpreted as + +``` +a = 10 +``` + +In addition, we have improved peephole optimizations, for example: + +``` +GETIV R4 :@foo +MOVE R1 R4 +``` + +to + +``` +GETIV R1 :@foo +``` + +## `String#hash` now use `FNV1a` algorithm + +For better and faster hash values. diff --git a/doc/opcode.md b/doc/opcode.md index 3ad09919c..113e390e8 100644 --- a/doc/opcode.md +++ b/doc/opcode.md @@ -22,114 +22,107 @@ sign) of operands. ## table.1 Instruction Table -| Instruction Name | Operand type | Semantics | -|------------------|--------------|--------------------------------------------------------| -| OP_NOP | - | no operation | -| OP_MOVE | BB | R(a) = R(b) | -| OP_LOADL | BB | R(a) = Pool(b) | -| OP_LOADL16 | BS | R(a) = Pool(b) | -| OP_LOADI | BB | R(a) = mrb_int(b) | -| OP_LOADINEG | BB | R(a) = mrb_int(-b) | -| OP_LOADI__1 | B | R(a) = mrb_int(-1) | -| OP_LOADI_0 | B | R(a) = mrb_int(0) | -| OP_LOADI_1 | B | R(a) = mrb_int(1) | -| OP_LOADI_2 | B | R(a) = mrb_int(2) | -| OP_LOADI_3 | B | R(a) = mrb_int(3) | -| OP_LOADI_4 | B | R(a) = mrb_int(4) | -| OP_LOADI_5 | B | R(a) = mrb_int(5) | -| OP_LOADI_6 | B | R(a) = mrb_int(6) | -| OP_LOADI_7 | B | R(a) = mrb_int(7) | -| OP_LOADI16 | BS | R(a) = mrb_int(b) | -| OP_LOADI32 | BSS | R(a) = mrb_int((b<<16)+c) | -| OP_LOADSYM | BB | R(a) = Syms(b) | -| OP_LOADSYM16 | BS | R(a) = Syms(b) | -| OP_LOADNIL | B | R(a) = nil | -| OP_LOADSELF | B | R(a) = self | -| OP_LOADT | B | R(a) = true | -| OP_LOADF | B | R(a) = false | -| OP_GETGV | BB | R(a) = getglobal(Syms(b)) | -| OP_SETGV | BB | setglobal(Syms(b), R(a)) | -| OP_GETSV | BB | R(a) = Special[Syms(b)] | -| OP_SETSV | BB | Special[Syms(b)] = R(a) | -| OP_GETIV | BB | R(a) = ivget(Syms(b)) | -| OP_SETIV | BB | ivset(Syms(b),R(a)) | -| OP_GETCV | BB | R(a) = cvget(Syms(b)) | -| OP_SETCV | BB | cvset(Syms(b),R(a)) | -| OP_GETCONST | BB | R(a) = constget(Syms(b)) | -| OP_SETCONST | BB | constset(Syms(b),R(a)) | -| OP_GETMCNST | BB | R(a) = R(a)::Syms(b) | -| OP_SETMCNST | BB | R(a+1)::Syms(b) = R(a) | -| OP_GETUPVAR | BBB | R(a) = uvget(b,c) | -| OP_SETUPVAR | BBB | uvset(b,c,R(a)) | -| OP_JMP | S | pc+=a | -| OP_JMPIF | BS | if R(a) pc+=b | -| OP_JMPNOT | BS | if !R(a) pc+=b | -| OP_JMPNIL | BS | if R(a)==nil pc+=b | -| OP_JMPUW | S | unwind_and_jump_to(a) | -| OP_EXCEPT | B | R(a) = exc | -| OP_RESCUE | BB | R(b) = R(a).isa?(R(b)) | -| OP_RAISEIF | B | raise(R(a)) if R(a) | -| OP_SENDV | BB | R(a) = call(R(a),Syms(b),*R(a+1)) | -| OP_SENDVB | BB | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) | -| OP_SEND | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) | -| OP_SENDB | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) | -| OP_SENDVK | BB | R(a) = call(R(a),Syms(b),*R(a+1),**(a+2),&R(a+3)) | -| OP_CALL | - | R(0) = self.call(frame.argc, frame.argv) | -| OP_SUPER | BB | R(a) = super(R(a+1),... ,R(a+b+1)) | -| OP_ARGARY | BS | R(a) = argument array (16=5:1:5:1:4) | -| OP_ENTER | W | arg setup according to flags (23=5:5:1:5:5:1:1) | -| OP_KEY_P | BB | R(a) = kdict.key?(Syms(b)) | -| OP_KEYEND | - | raise unless kdict.empty? | -| OP_KARG | BB | R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) | -| OP_RETURN | B | return R(a) (normal) | -| OP_RETURN_BLK | B | return R(a) (in-block return) | -| OP_BREAK | B | break R(a) | -| OP_BLKPUSH | BS | R(a) = block (16=5:1:5:1:4) | -| OP_ADD | B | R(a) = R(a)+R(a+1) | -| OP_ADDI | BB | R(a) = R(a)+mrb_int(b) | -| OP_SUB | B | R(a) = R(a)-R(a+1) | -| OP_SUBI | BB | R(a) = R(a)-mrb_int(b) | -| OP_MUL | B | R(a) = R(a)*R(a+1) | -| OP_DIV | B | R(a) = R(a)/R(a+1) | -| OP_EQ | B | R(a) = R(a)==R(a+1) | -| OP_LT | B | R(a) = R(a)<R(a+1) | -| OP_LE | B | R(a) = R(a)<=R(a+1) | -| OP_GT | B | R(a) = R(a)>R(a+1) | -| OP_GE | B | R(a) = R(a)>=R(a+1) | -| OP_ARRAY | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b)) | -| OP_ARRAY2 | BBB | R(a) = ary_new(R(b),R(b+1)..R(b+c)) | -| OP_ARYCAT | B | ary_cat(R(a),R(a+1)) | -| OP_ARYPUSH | B | ary_push(R(a),R(a+1)) | -| OP_ARYDUP | B | R(a) = ary_dup(R(a)) | -| OP_AREF | BBB | R(a) = R(b)[c] | -| OP_ASET | BBB | R(a)[c] = R(b) | -| OP_APOST | BBB | *R(a),R(a+1)..R(a+c) = R(a)[b..] | -| OP_INTERN | B | R(a) = intern(R(a)) | -| OP_STRING | BB | R(a) = str_dup(Lit(b)) | -| OP_STRING16 | BS | R(a) = str_dup(Lit(b)) | -| OP_STRCAT | B | str_cat(R(a),R(a+1)) | -| OP_HASH | BB | R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) | -| OP_HASHADD | BB | R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) | -| OP_HASHCAT | B | R(a) = hash_cat(R(a),R(a+1)) | -| OP_LAMBDA | BB | R(a) = lambda(SEQ[b],OP_L_LAMBDA) | -| OP_LAMBDA16 | BS | R(a) = lambda(SEQ[b],OP_L_LAMBDA) | -| OP_BLOCK | BB | R(a) = lambda(SEQ[b],OP_L_BLOCK) | -| OP_BLOCK16 | BS | R(a) = lambda(SEQ[b],OP_L_BLOCK) | -| OP_METHOD | BB | R(a) = lambda(SEQ[b],OP_L_METHOD) | -| OP_METHOD16 | BS | R(a) = lambda(SEQ[b],OP_L_METHOD) | -| OP_RANGE_INC | B | R(a) = range_new(R(a),R(a+1),FALSE) | -| OP_RANGE_EXC | B | R(a) = range_new(R(a),R(a+1),TRUE) | -| OP_OCLASS | B | R(a) = ::Object | -| OP_CLASS | BB | R(a) = newclass(R(a),Syms(b),R(a+1)) | -| OP_MODULE | BB | R(a) = newmodule(R(a),Syms(b)) | -| OP_EXEC | BB | R(a) = blockexec(R(a),SEQ[b]) | -| OP_EXEC16 | BS | R(a) = blockexec(R(a),SEQ[b]) | -| OP_DEF | BB | R(a).newmethod(Syms(b),R(a+1)) | -| OP_ALIAS | BB | alias_method(target_class,Syms(a),Syms(b)) | -| OP_UNDEF | B | undef_method(target_class,Syms(a)) | -| OP_SCLASS | B | R(a) = R(a).singleton_class | -| OP_TCLASS | B | R(a) = target_class | -| OP_DEBUG | BBB | print a,b,c | -| OP_ERR | B | raise(LocalJumpError, Lit(a)) | -| OP_STOP | - | stop VM | -|------------------|--------------|--------------------------------------------------------| +| Instruction Name | Operand type | Semantics | +|------------------|--------------|----------------------------------------------------------| +| `OP_NOP` | `-` | `no operation` | +| `OP_MOVE` | `BB` | `R(a) = R(b)` | +| `OP_LOADL` | `BB` | `R(a) = Pool(b)` | +| `OP_LOADI` | `BB` | `R(a) = mrb_int(b)` | +| `OP_LOADINEG` | `BB` | `R(a) = mrb_int(-b)` | +| `OP_LOADI__1` | `B` | `R(a) = mrb_int(-1)` | +| `OP_LOADI_0` | `B` | `R(a) = mrb_int(0)` | +| `OP_LOADI_1` | `B` | `R(a) = mrb_int(1)` | +| `OP_LOADI_2` | `B` | `R(a) = mrb_int(2)` | +| `OP_LOADI_3` | `B` | `R(a) = mrb_int(3)` | +| `OP_LOADI_4` | `B` | `R(a) = mrb_int(4)` | +| `OP_LOADI_5` | `B` | `R(a) = mrb_int(5)` | +| `OP_LOADI_6` | `B` | `R(a) = mrb_int(6)` | +| `OP_LOADI_7` | `B` | `R(a) = mrb_int(7)` | +| `OP_LOADI16` | `BS` | `R(a) = mrb_int(b)` | +| `OP_LOADI32` | `BSS` | `R(a) = mrb_int((b<<16)+c)` | +| `OP_LOADSYM` | `BB` | `R(a) = Syms(b)` | +| `OP_LOADNIL` | `B` | `R(a) = nil` | +| `OP_LOADSELF` | `B` | `R(a) = self` | +| `OP_LOADT` | `B` | `R(a) = true` | +| `OP_LOADF` | `B` | `R(a) = false` | +| `OP_GETGV` | `BB` | `R(a) = getglobal(Syms(b))` | +| `OP_SETGV` | `BB` | `setglobal(Syms(b), R(a))` | +| `OP_GETSV` | `BB` | `R(a) = Special[Syms(b)]` | +| `OP_SETSV` | `BB` | `Special[Syms(b)] = R(a)` | +| `OP_GETIV` | `BB` | `R(a) = ivget(Syms(b))` | +| `OP_SETIV` | `BB` | `ivset(Syms(b),R(a))` | +| `OP_GETCV` | `BB` | `R(a) = cvget(Syms(b))` | +| `OP_SETCV` | `BB` | `cvset(Syms(b),R(a))` | +| `OP_GETCONST` | `BB` | `R(a) = constget(Syms(b))` | +| `OP_SETCONST` | `BB` | `constset(Syms(b),R(a))` | +| `OP_GETMCNST` | `BB` | `R(a) = R(a)::Syms(b)` | +| `OP_SETMCNST` | `BB` | `R(a+1)::Syms(b) = R(a)` | +| `OP_GETUPVAR` | `BBB` | `R(a) = uvget(b,c)` | +| `OP_SETUPVAR` | `BBB` | `uvset(b,c,R(a))` | +| `OP_JMP` | `S` | `pc+=a` | +| `OP_JMPIF` | `BS` | `if R(a) pc+=b` | +| `OP_JMPNOT` | `BS` | `if !R(a) pc+=b` | +| `OP_JMPNIL` | `BS` | `if R(a)==nil pc+=b` | +| `OP_JMPUW` | `S` | `unwind_and_jump_to(a)` | +| `OP_EXCEPT` | `B` | `R(a) = exc` | +| `OP_RESCUE` | `BB` | `R(b) = R(a).isa?(R(b))` | +| `OP_RAISEIF` | `B` | `raise(R(a)) if R(a)` | +| `OP_SEND` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))` | +| `OP_SENDB` | `BBB` | `R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1))` | +| `OP_CALL` | `-` | `R(0) = self.call(frame.argc, frame.argv)` | +| `OP_SUPER` | `BB` | `R(a) = super(R(a+1),... ,R(a+b+1))` | +| `OP_ARGARY` | `BS` | `R(a) = argument array (16=m5:r1:m5:d1:lv4)` | +| `OP_ENTER` | `W` | `arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1)` | +| `OP_KEY_P` | `BB` | `R(a) = kdict.key?(Syms(b))` | +| `OP_KEYEND` | `-` | `raise unless kdict.empty?` | +| `OP_KARG` | `BB` | `R(a) = kdict[Syms(b)]; kdict.delete(Syms(b))` | +| `OP_RETURN` | `B` | `return R(a) (normal)` | +| `OP_RETURN_BLK` | `B` | `return R(a) (in-block return)` | +| `OP_BREAK` | `B` | `break R(a)` | +| `OP_BLKPUSH` | `BS` | `R(a) = block (16=m5:r1:m5:d1:lv4)` | +| `OP_ADD` | `B` | `R(a) = R(a)+R(a+1)` | +| `OP_ADDI` | `BB` | `R(a) = R(a)+mrb_int(b)` | +| `OP_SUB` | `B` | `R(a) = R(a)-R(a+1)` | +| `OP_SUBI` | `BB` | `R(a) = R(a)-mrb_int(b)` | +| `OP_MUL` | `B` | `R(a) = R(a)*R(a+1)` | +| `OP_DIV` | `B` | `R(a) = R(a)/R(a+1)` | +| `OP_EQ` | `B` | `R(a) = R(a)==R(a+1)` | +| `OP_LT` | `B` | `R(a) = R(a)<R(a+1)` | +| `OP_LE` | `B` | `R(a) = R(a)<=R(a+1)` | +| `OP_GT` | `B` | `R(a) = R(a)>R(a+1)` | +| `OP_GE` | `B` | `R(a) = R(a)>=R(a+1)` | +| `OP_ARRAY` | `BB` | `R(a) = ary_new(R(a),R(a+1)..R(a+b))` | +| `OP_ARRAY2` | `BBB` | `R(a) = ary_new(R(b),R(b+1)..R(b+c))` | +| `OP_ARYCAT` | `B` | `ary_cat(R(a),R(a+1))` | +| `OP_ARYPUSH` | `BB` | `ary_push(R(a),R(a+1)..R(a+b))` | +| `OP_ARYDUP` | `B` | `R(a) = ary_dup(R(a))` | +| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` | +| `OP_ASET` | `BBB` | `R(a)[c] = R(b)` | +| `OP_APOST` | `BBB` | `*R(a),R(a+1)..R(a+c) = R(a)[b..]` | +| `OP_INTERN` | `B` | `R(a) = intern(R(a))` | +| `OP_STRING` | `BB` | `R(a) = str_dup(Pool(b))` | +| `OP_STRCAT` | `B` | `str_cat(R(a),R(a+1))` | +| `OP_HASH` | `BB` | `R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1))` | +| `OP_HASHADD` | `BB` | `hash_push(R(a),R(a+1)..R(a+b*2))` | +| `OP_HASHCAT` | `B` | `R(a) = hash_cat(R(a),R(a+1))` | +| `OP_LAMBDA` | `BB` | `R(a) = lambda(Irep(b),OP_L_LAMBDA)` | +| `OP_BLOCK` | `BB` | `R(a) = lambda(Irep(b),OP_L_BLOCK)` | +| `OP_METHOD` | `BB` | `R(a) = lambda(Irep(b),OP_L_METHOD)` | +| `OP_RANGE_INC` | `B` | `R(a) = range_new(R(a),R(a+1),FALSE)` | +| `OP_RANGE_EXC` | `B` | `R(a) = range_new(R(a),R(a+1),TRUE)` | +| `OP_OCLASS` | `B` | `R(a) = ::Object` | +| `OP_CLASS` | `BB` | `R(a) = newclass(R(a),Syms(b),R(a+1))` | +| `OP_MODULE` | `BB` | `R(a) = newmodule(R(a),Syms(b))` | +| `OP_EXEC` | `BB` | `R(a) = blockexec(R(a),Irep[b])` | +| `OP_DEF` | `BB` | `R(a).newmethod(Syms(b),R(a+1)); R(a) = Syms(b)` | +| `OP_ALIAS` | `BB` | `alias_method(target_class,Syms(a),Syms(b))` | +| `OP_UNDEF` | `B` | `undef_method(target_class,Syms(a))` | +| `OP_SCLASS` | `B` | `R(a) = R(a).singleton_class` | +| `OP_TCLASS` | `B` | `R(a) = target_class` | +| `OP_DEBUG` | `BBB` | `print a,b,c` | +| `OP_ERR` | `B` | `raise(LocalJumpError, Pool(a))` | +| `OP_EXT1` | `-` | `make 1st operand 16bit` | +| `OP_EXT2` | `-` | `make 2nd operand 16bit` | +| `OP_EXT3` | `-` | `make 1st and 2nd operands 16bit` | +| `OP_STOP` | `-` | `stop VM` | +|------------------|--------------|----------------------------------------------------------| diff --git a/examples/mrbgems/c_and_ruby_extension_example/src/example.c b/examples/mrbgems/c_and_ruby_extension_example/src/example.c index 1fdb1078d..f1d7971c2 100644 --- a/examples/mrbgems/c_and_ruby_extension_example/src/example.c +++ b/examples/mrbgems/c_and_ruby_extension_example/src/example.c @@ -5,9 +5,8 @@ static mrb_value mrb_c_method(mrb_state *mrb, mrb_value self) { - mrb_value self_str = mrb_str_to_str(mrb, self); - - printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self_str)); + mrb_ensure_string_type(mrb, self); + printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self)); return self; } diff --git a/examples/mrbgems/c_extension_example/src/example.c b/examples/mrbgems/c_extension_example/src/example.c index 727c7c698..fe872c933 100644 --- a/examples/mrbgems/c_extension_example/src/example.c +++ b/examples/mrbgems/c_extension_example/src/example.c @@ -5,9 +5,8 @@ static mrb_value mrb_c_method(mrb_state *mrb, mrb_value self) { - mrb_value self_str = mrb_str_to_str(mrb, self); - - printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self_str)); + mrb_ensure_string_type(mrb, self); + printf("%s: A C Extension\n", mrb_str_to_cstr(mrb, self)); return self; } diff --git a/include/mrbconf.h b/include/mrbconf.h index d4da81bfc..e11a55e8c 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -7,9 +7,6 @@ #ifndef MRUBYCONF_H #define MRUBYCONF_H -#include <limits.h> -#include <stdint.h> - /* architecture selection: */ /* specify -DMRB_32BIT or -DMRB_64BIT to override */ #if !defined(MRB_32BIT) && !defined(MRB_64BIT) @@ -82,6 +79,9 @@ # define MRB_WORD_BOXING #endif +/* if defined mruby allocates Float objects in the heap to keep full precision if needed */ +//#define MRB_WORDBOX_NO_FLOAT_TRUNCATE + /* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64; Default for 32-bit CPU mode. */ //#define MRB_INT32 @@ -113,11 +113,17 @@ /* number of object per heap page */ //#define MRB_HEAP_PAGE_SIZE 1024 -/* if __ehdr_start is available, mruby can reduce memory used by symbols */ -//#define MRB_USE_LINK_TIME_RO_DATA_P +/* define if your platform does not support etext, edata */ +//#define MRB_NO_DEFAULT_RO_DATA_P + +/* define if your platform supports etext, edata */ +//#define MRB_USE_RO_DATA_P_ETEXT +/* use MRB_USE_ETEXT_RO_DATA_P by default on Linux */ +#if (defined(__linux__) && !defined(__KERNEL__)) +#define MRB_USE_ETEXT_RO_DATA_P +#endif -/* if MRB_USE_LINK_TIME_RO_DATA_P does not work, - you can try mrb_ro_data_p() that you have implemented yourself in any file; +/* you can provide and use mrb_ro_data_p() for your platform. prototype is `mrb_bool mrb_ro_data_p(const char *ptr)` */ //#define MRB_USE_CUSTOM_RO_DATA_P @@ -181,14 +187,6 @@ # include <stdio.h> #endif -#ifndef FALSE -# define FALSE 0 -#endif - -#ifndef TRUE -# define TRUE 1 -#endif - /* ** mruby tuning profiles **/ diff --git a/include/mruby.h b/include/mruby.h index d421dc58c..21b96817a 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -44,6 +44,9 @@ #include <limits.h> #ifdef __cplusplus +#ifndef UINTPTR_MAX +#error Must be placed `#include <mruby.h>` before `#include <stdint.h>` +#endif #ifndef SIZE_MAX #ifdef __SIZE_MAX__ #define SIZE_MAX __SIZE_MAX__ @@ -66,14 +69,18 @@ #define mrb_assert_int_fit(t1,n,t2,max) ((void)0) #endif -#if (defined __cplusplus && __cplusplus >= 201103L) || \ +#if (defined __cplusplus && __cplusplus >= 201703L) +# define mrb_static_assert(...) static_assert(__VA_ARGS__) +# define mrb_static_assert1(exp) static_assert(exp) +# define mrb_static_assert2(exp, str) static_assert(exp, str) +#elif (defined __cplusplus && __cplusplus >= 201103L) || \ (defined _MSC_VER) || \ (defined __GXX_EXPERIMENTAL_CXX0X__) /* for old G++/Clang++ */ -# define mrb_static_assert(exp, str) static_assert(exp, str) +# define mrb_static_assert2(exp, str) static_assert(exp, str) #elif defined __STDC_VERSION__ && \ ((__STDC_VERSION__ >= 201112L) || \ (defined __GNUC__ && __GNUC__ * 100 + __GNUC_MINOR__ >= 406)) -# define mrb_static_assert(exp, str) _Static_assert(exp, str) +# define mrb_static_assert2(exp, str) _Static_assert(exp, str) #else # /* alternative implementation of static_assert() */ # define _mrb_static_assert_cat0(a, b) a##b @@ -83,10 +90,24 @@ # else # define _mrb_static_assert_id(prefix) _mrb_static_assert_cat(prefix, __LINE__) # endif -# define mrb_static_assert(exp, str) \ +# define mrb_static_assert2(exp, str) \ struct _mrb_static_assert_id(_mrb_static_assert_) { char x[(exp) ? 1 : -1]; } #endif -#define mrb_static_assert1(exp) mrb_static_assert(exp, #exp) + +#ifndef mrb_static_assert +# define mrb_static_assert1(exp) mrb_static_assert2(exp, #exp) +# define mrb_static_assert_expand(...) __VA_ARGS__ /* for MSVC behaviour - https://stackoverflow.com/q/5530505 */ +# define mrb_static_assert_selector(a, b, name, ...) name +/** + * The `mrb_static_assert()` macro function takes one or two arguments. + * + * !!!c + * mrb_static_assert(expect_condition); + * mrb_static_assert(expect_condition, error_message); + */ +# define mrb_static_assert(...) \ + mrb_static_assert_expand(mrb_static_assert_selector(__VA_ARGS__, mrb_static_assert2, mrb_static_assert1, _)(__VA_ARGS__)) +#endif #include "mrbconf.h" @@ -96,6 +117,7 @@ #include <mruby/version.h> #ifndef MRB_NO_FLOAT +#include <math.h> #include <float.h> #ifndef FLT_EPSILON #define FLT_EPSILON (1.19209290e-07f) @@ -149,9 +171,10 @@ typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud); #endif typedef struct { + uint8_t n:4; /* (15=*) c=n|nk<<4 */ + uint8_t nk:4; /* (15=*) */ + uint8_t cci; /* called from C function */ mrb_sym mid; - int16_t argc; - int16_t acc; const struct RProc *proc; mrb_value *stack; const mrb_code *pc; /* current address on iseq of this proc */ @@ -265,7 +288,9 @@ typedef struct mrb_state { #endif mrb_sym symidx; - struct symbol_name *symtbl; /* symbol table */ + const char **symtbl; + uint8_t *symlink; + uint8_t *symflags; mrb_sym symhash[256]; size_t symcapa; #ifndef MRB_USE_ALL_SYMBOLS @@ -886,19 +911,20 @@ MRB_API struct RClass* mrb_define_module_under_id(mrb_state *mrb, struct RClass * | char | Ruby type | C types | Notes | * |:----:|----------------|-------------------|----------------------------------------------------| * | `o` | {Object} | {mrb_value} | Could be used to retrieve any type of argument | - * | `C` | {Class}/{Module} | {mrb_value} | | + * | `C` | {Class}/{Module} | {mrb_value} | when `!` follows, the value may be `nil` | * | `S` | {String} | {mrb_value} | when `!` follows, the value may be `nil` | * | `A` | {Array} | {mrb_value} | when `!` follows, the value may be `nil` | * | `H` | {Hash} | {mrb_value} | when `!` follows, the value may be `nil` | * | `s` | {String} | const char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` | * | `z` | {String} | const char * | `NULL` terminated string; `z!` gives `NULL` for `nil` | * | `a` | {Array} | const {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` | + * | `c` | {Class}/{Module} | strcut RClass * | `c!` gives `NULL` for `nil` | * | `f` | {Integer}/{Float} | {mrb_float} | | * | `i` | {Integer}/{Float} | {mrb_int} | | * | `b` | boolean | {mrb_bool} | | * | `n` | {String}/{Symbol} | {mrb_sym} | | * | `d` | data | void *, {mrb_data_type} const | 2nd argument will be used to check data type so it won't be modified; when `!` follows, the value may be `nil` | - * | `I` | inline struct | void * | | + * | `I` | inline struct | void *, struct RClass | `I!` gives `NULL` for `nil` | * | `&` | block | {mrb_value} | &! raises exception if no block given. | * | `*` | rest arguments | const {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array; `*!` avoid copy of the stack. | * | <code>\|</code> | optional | | After this spec following specs would be optional. | @@ -906,6 +932,13 @@ MRB_API struct RClass* mrb_define_module_under_id(mrb_state *mrb, struct RClass * | `:` | keyword args | {mrb_kwargs} const | Get keyword arguments. @see mrb_kwargs | * * @see mrb_get_args + * + * Immediately after format specifiers it can add format modifiers: + * + * | char | Notes | + * |:----:|-----------------------------------------------------------------------------------------| + * | `!` | Switch to the alternate mode; The behaviour changes depending on the format specifier | + * | `+` | Request a not frozen object; However, except nil value | */ typedef const char *mrb_args_format; @@ -1004,6 +1037,11 @@ MRB_API const mrb_value *mrb_get_argv(mrb_state *mrb); */ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb); +/** + * Check if a block argument is given from mrb_state. + */ +MRB_API mrb_bool mrb_block_given_p(mrb_state *mrb); + /* `strlen` for character string literals (use with caution or `strlen` instead) Adjacent string literals are concatenated in C/C++ in translation phase 6. If `lit` is not one, the compiler will report a syntax error: @@ -1126,6 +1164,17 @@ MRB_API void *mrb_malloc_simple(mrb_state*, size_t); /* return NULL if no memor MRB_API struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*); MRB_API void mrb_free(mrb_state*, void*); +/** + * Allocates a Ruby object that matches the constant literal defined in + * `enum mrb_vtype` and returns a pointer to the corresponding C type. + * + * @param mrb The current mruby state + * @param tt The constant literal of `enum mrb_vtype` + * @param klass A Class object + * @return Reference to the newly created object + */ +#define MRB_OBJ_ALLOC(mrb, tt, klass) ((MRB_VTYPE_TYPEOF(tt)*)mrb_obj_alloc(mrb, tt, klass)) + MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len); /** @@ -1219,10 +1268,8 @@ MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name); MRB_API mrb_bool mrb_obj_eq(mrb_state *mrb, mrb_value a, mrb_value b); MRB_API mrb_bool mrb_obj_equal(mrb_state *mrb, mrb_value a, mrb_value b); MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2); -MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base); -MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val); #ifndef MRB_NO_FLOAT -MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val); +MRB_API mrb_value mrb_to_float(mrb_state *mrb, mrb_value val); #endif MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); @@ -1339,10 +1386,23 @@ MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj); /* mrb_gc_unregister() removes the object from GC root. */ MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj); -MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val); -#define mrb_int(mrb, val) mrb_integer(mrb_to_int(mrb, val)) +/* type conversion/check functions */ +MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self); +MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self); +MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash); +MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); +MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str); +MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); +/* obsolete: use mrb_ensure_string_type() instead */ +#define mrb_string_type(mrb, str) mrb_ensure_string_type(mrb,str) +#define mrb_to_str(mrb, str) mrb_ensure_string_type(mrb,str) +/* obsolete: use mrb_obj_as_string() instead */ +#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str) +MRB_API mrb_value mrb_to_integer(mrb_state *mrb, mrb_value val); +#define mrb_to_int(mrb, val) mrb_to_integer(mrb, val) +#define mrb_as_int(mrb, val) mrb_integer(mrb_to_integer(mrb, val)) + /* string type checking (contrary to the name, it doesn't convert) */ -MRB_API mrb_value mrb_to_str(mrb_state *mrb, mrb_value val); MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o) @@ -1361,6 +1421,8 @@ MRB_API mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid); MRB_API mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c); MRB_API mrb_bool mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func); +/* obsolete function(s); will be removed */ +#define mrb_int(mrb, val) mrb_as_int(mrb, val) /** * Resume a Fiber diff --git a/include/mruby/array.h b/include/mruby/array.h index 16f78f773..8bb652472 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -14,15 +14,17 @@ */ MRB_BEGIN_DECL - typedef struct mrb_shared_array { int refcnt; mrb_ssize len; mrb_value *ptr; } mrb_shared_array; -#if defined(MRB_32BIT) && defined(MRB_NO_BOXING) && !defined(MRB_USE_FLOAT32) +#if defined(MRB_32BIT) && defined(MRB_NO_BOXING) && !defined(MRB_USE_FLOAT32) && !defined(MRB_ARY_NO_EMBED) # define MRB_ARY_NO_EMBED +#endif + +#ifdef MRB_ARY_NO_EMBED # define MRB_ARY_EMBED_LEN_MAX 0 #else # define MRB_ARY_EMBED_LEN_MAX ((mrb_int)(sizeof(void*)*3/sizeof(mrb_value))) @@ -177,20 +179,6 @@ MRB_API void mrb_ary_push(mrb_state *mrb, mrb_value array, mrb_value value); MRB_API mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary); /* - * Returns a reference to an element of the array on the given index. - * - * Equivalent to: - * - * ary[n] - * - * @param mrb The mruby state reference. - * @param ary The target array. - * @param n The array index being referenced - * @return The referenced value. - */ -MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n); - -/* * Sets a value on an array at the given index * * Equivalent to: @@ -200,7 +188,7 @@ MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n); * @param mrb The mruby state reference. * @param ary The target array. * @param n The array index being referenced. - * @param val The value being setted. + * @param val The value being set. */ MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val); @@ -216,8 +204,6 @@ MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val * @param other The array to replace it with. */ MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other); -MRB_API mrb_value mrb_ensure_array_type(mrb_state *mrb, mrb_value self); -MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self); /* * Unshift an element into the array @@ -243,6 +229,7 @@ MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item * @param offset The element position (negative counts from the tail). */ MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset); +#define mrb_ary_ref(mrb, ary, n) mrb_ary_entry(ary, n) /* * Replace subsequence of an array. diff --git a/include/mruby/boxing_nan.h b/include/mruby/boxing_nan.h index 05f1d953c..77b6204a3 100644 --- a/include/mruby/boxing_nan.h +++ b/include/mruby/boxing_nan.h @@ -15,116 +15,145 @@ # error ---->> MRB_NAN_BOXING and MRB_NO_FLOAT conflict <<---- #endif -#ifdef MRB_INT64 -# error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<---- -#endif - -#define MRB_FIXNUM_SHIFT 0 -#define MRB_SYMBOL_SHIFT 0 #define MRB_FIXNUM_MIN INT32_MIN #define MRB_FIXNUM_MAX INT32_MAX +enum mrb_nanbox_tt_inline { + MRB_NANBOX_TT_POINTER = 0, + MRB_NANBOX_TT_INTEGER = 1, + MRB_NANBOX_TT_SYMBOL = 2, + MRB_NANBOX_TT_MISC = 3, +}; + /* value representation by nan-boxing: - * float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF - * object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP - * int : 1111111111110001 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII - * sym : 1111111111110001 0100000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS - * In order to get enough bit size to save TT, all pointers are shifted 2 bits - * in the right direction. Also, TTTTTT is the mrb_vtype + 1; + * float : SEEEEEEE EEEEFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF + * +/-inf: S1111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000 + * nan : 01111111 11111000 00000000 00000000 00000000 00000000 00000000 00000000 + * int : 01111111 11111001 00000000 00000000 IIIIIIII IIIIIIII IIIIIIII IIIIIIII + * sym : 01111111 11111110 00000000 00000000 SSSSSSSS SSSSSSSS SSSSSSSS SSSSSSSS + * misc : 01111111 11111111 00000000 00000000 00000000 00000000 00TTTTTT 0000MMMM + * object: 01111111 11111100 PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPP00 + * ptr : 01111111 11111100 PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPP01 + * Stored as O = R + 0x8004000000000000, retrieved as R = O - 0x8004000000000000. + * This makes pointers have all zeros in the top 32 bits. + * Small-ints and strs have 1 as LSB to make sure they don't look like pointers + * to the garbage collector. */ typedef struct mrb_value { uint64_t u; } mrb_value; -union mrb_value_ { - mrb_float f; - uint64_t u; -#ifdef MRB_64BIT - void *p; -# define BOXNAN_IMMEDIATE_VALUE uint32_t i -#else -# define BOXNAN_IMMEDIATE_VALUE union { uint32_t i; void *p; } -#endif - struct { - MRB_ENDIAN_LOHI( - uint32_t ttt; - ,BOXNAN_IMMEDIATE_VALUE; - ) - }; - mrb_value value; -}; +static inline mrb_float +mrb_nan_boxing_value_float(mrb_value v) +{ + union { + mrb_float f; + uint64_t u; + } x; + x.u = v.u - 0x8004000000000000; + return x.f; +} + +#define SET_FLOAT_VALUE(mrb,r,f) do { \ + union { \ + mrb_float f; \ + uint64_t u; \ + } float_uint_union; \ + if ((f) != (f)) { /* NaN */ \ + float_uint_union.u = 0x7ff8000000000000UL; \ + } \ + else { \ + float_uint_union.f = (f); \ + } \ + r.u = float_uint_union.u + 0x8004000000000000; \ +} while(0) -mrb_static_assert1(sizeof(mrb_value) == sizeof(union mrb_value_)); +#define mrb_float_p(o) (((uint64_t)((o).u)&0xfffc000000000000) != 0) -static inline union mrb_value_ -mrb_val_union(mrb_value v) +struct RInteger { + MRB_OBJECT_HEADER; + mrb_int i; +}; + +MRB_INLINE enum mrb_vtype +mrb_type(mrb_value o) { - union mrb_value_ x; - x.value = v; - return x; + if (mrb_float_p(o)) return MRB_TT_FLOAT; + + int64_t u = o.u; + switch ((enum mrb_nanbox_tt_inline)((u >> 48) & 3)) { + case MRB_NANBOX_TT_POINTER: { + if (u == 0) return MRB_TT_FALSE; + if (u & 1) return MRB_TT_CPTR; + return ((struct RBasic*)(uintptr_t)u)->tt; + } + case MRB_NANBOX_TT_INTEGER: + return MRB_TT_INTEGER; + case MRB_NANBOX_TT_SYMBOL: + return MRB_TT_SYMBOL; + case MRB_NANBOX_TT_MISC: + return (enum mrb_vtype)((o.u >> 8) & 0x1f); + default: + /* never happen */ + return MRB_TT_FLOAT; + } } -#define mrb_tt(o) ((enum mrb_vtype)((mrb_val_union(o).ttt & 0xfc000)>>14)-1) -#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < mrb_val_union(o).ttt ? mrb_tt(o) : MRB_TT_FLOAT) -#define mrb_float(o) mrb_val_union(o).f -#define mrb_fixnum(o) ((mrb_int)mrb_val_union(o).i) -#define mrb_integer(o) mrb_fixnum(o) -#define mrb_symbol(o) ((mrb_sym)mrb_val_union(o).i) - -#ifdef MRB_64BIT -#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)(mrb_val_union(o).p)))<<2)) -#define mrb_cptr(o) (((struct RCptr*)mrb_ptr(o))->p) -#define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff) +#define NANBOX_SET_MISC_VALUE(r,t,i) NANBOX_SET_VALUE(r, MRB_NANBOX_TT_MISC, ((t)<<8) | i) + +#define mrb_float(o) mrb_nan_boxing_value_float(o) +#ifdef MRB_INT64 +/* +#ifdef MRB_32BIT +#define mrb_fixnum(o) ((mrb_int)((intptr_t)0xffffffffffff&((o).u))|(((o).u & 0x800000000000)?0xffff000000000000:0)) #else -#define mrb_ptr(o) ((void*)mrb_val_union(o).i) -#define mrb_cptr(o) mrb_ptr(o) -#define BOXNAN_SHIFT_LONG_POINTER(v) 0 +#define mrb_fixnum(o) ((mrb_int)(int32_t)((o).u)) #endif +*/ -#define BOXNAN_SET_VALUE(o, tt, attr, v) do { \ - union mrb_value_ mrb_value_union_variable; \ - mrb_value_union_variable.attr = (v);\ - mrb_value_union_variable.ttt = 0xfff00000 | (((tt)+1)<<14);\ - o = mrb_value_union_variable.value;\ -} while (0) +#define mrb_fixnum(o) ((mrb_int)(int32_t)((o).u)) -#ifdef MRB_64BIT -#define BOXNAN_SET_OBJ_VALUE(o, tt, v) do {\ - union mrb_value_ mrb_value_union_variable;\ - mrb_value_union_variable.p = (void*)((uintptr_t)(v)>>2);\ - mrb_value_union_variable.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\ - o = mrb_value_union_variable.value;\ -} while (0) +static inline mrb_int +mrb_nan_boxing_value_int(mrb_value v) +{ + uint64_t u = v.u; + if (((u>>48)&3)==MRB_NANBOX_TT_POINTER) { + struct RInteger *p = (struct RInteger*)(uintptr_t)u; + return p->i; + } + return mrb_fixnum(v); +} +#define mrb_integer(o) mrb_nan_boxing_value_int(o) #else -#define BOXNAN_SET_OBJ_VALUE(o, tt, v) BOXNAN_SET_VALUE(o, tt, i, (uint32_t)v) +#define mrb_fixnum(o) ((mrb_int)(((uintptr_t)0xffffffff)&((o).u))) +#define mrb_integer(o) mrb_fixnum(o) #endif +#define mrb_symbol(o) ((mrb_sym)((uintptr_t)0xffffffff)&((o).u)) +#define mrb_ptr(o) ((void*)(uintptr_t)(o).u) +#define mrb_cptr(o) ((void*)(uintptr_t)(0xfffffffffffe&(o).u)) -#define SET_FLOAT_VALUE(mrb,r,v) do { \ - union mrb_value_ mrb_value_union_variable; \ - if ((v) != (v)) { /* NaN */ \ - mrb_value_union_variable.ttt = 0x7ff80000; \ - mrb_value_union_variable.i = 0; \ - } \ - else { \ - mrb_value_union_variable.f = (v); \ - } \ - r = mrb_value_union_variable.value; \ -} while(0) +#define NANBOX_SET_VALUE(o, tt, v) do { \ + (o).u = ((uint64_t)tt<<48) | ((uint64_t)(v)); \ +} while (0) -#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 0) -#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, i, 1) -#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, i, 1) -#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, i, 1) -#define SET_INT_VALUE(mrb, r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n)) -#define SET_FIXNUM_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_INTEGER, i, (uint32_t)(n)) -#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, i, (uint32_t)(v)) -#define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v)) -#ifdef MRB_64BIT -MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*); -#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_nan_boxing_cptr_value(mrb, v)) +#define SET_NIL_VALUE(r) NANBOX_SET_MISC_VALUE(r, MRB_TT_FALSE, 0) +#define SET_FALSE_VALUE(r) NANBOX_SET_MISC_VALUE(r, MRB_TT_FALSE, 1) +#define SET_TRUE_VALUE(r) NANBOX_SET_MISC_VALUE(r, MRB_TT_TRUE, 1) +#define SET_BOOL_VALUE(r,b) NANBOX_SET_MISC_VALUE(r, (b) ? MRB_TT_TRUE : MRB_TT_FALSE, 1) +#ifdef MRB_INT64 +MRB_API mrb_value mrb_boxing_int_value(struct mrb_state*, mrb_int); +#define SET_INT_VALUE(mrb, r, n) ((r) = mrb_boxing_int_value(mrb, n)) #else -#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, p, v) +#define SET_INT_VALUE(mrb, r, n) SET_FIXNUM_VALUE(r, n) #endif -#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, i, 0) +#define SET_FIXNUM_VALUE(r,n) NANBOX_SET_VALUE(r, MRB_NANBOX_TT_INTEGER, (uint32_t)(n)) +#define SET_SYM_VALUE(r,v) NANBOX_SET_VALUE(r, MRB_NANBOX_TT_SYMBOL, (uint32_t)(v)) +#define SET_OBJ_VALUE(r,v) do {(r).u = (uint64_t)(uintptr_t)v;} while (0) +#define SET_CPTR_VALUE(mrb,r,v) do {(r).u = ((uint64_t)(uintptr_t)v) | 1;} while (0) +#define SET_UNDEF_VALUE(r) NANBOX_SET_MISC_VALUE(r, MRB_TT_UNDEF, 4) + +#define mrb_nil_p(o) (mrb_type(o) == MRB_TT_FALSE && ((o).u & 3) == 0) +#define mrb_false_p(o) (mrb_type(o) == MRB_TT_FALSE && ((o).u & 2) == 0) +#define mrb_fixnum_p(o) (!mrb_float_p(o) && ((o.u>>48)&3)==MRB_NANBOX_TT_INTEGER) #endif /* MRUBY_BOXING_NAN_H */ diff --git a/include/mruby/boxing_word.h b/include/mruby/boxing_word.h index beab8681e..ab1aef36e 100644 --- a/include/mruby/boxing_word.h +++ b/include/mruby/boxing_word.h @@ -7,7 +7,11 @@ #ifndef MRUBY_BOXING_WORD_H #define MRUBY_BOXING_WORD_H -#ifndef MRB_NO_FLOAT +#if defined(MRB_32BIT) && !defined(MRB_USE_FLOAT32) && !defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) +# define MRB_WORDBOX_NO_FLOAT_TRUNCATE +#endif + +#if !defined(MRB_NO_FLOAT) && defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) struct RFloat { MRB_OBJECT_HEADER; mrb_float f; @@ -29,9 +33,9 @@ enum mrb_special_consts { #if defined(MRB_64BIT) && defined(MRB_INT32) #define MRB_FIXNUM_SHIFT 0 #else -#define MRB_FIXNUM_SHIFT BOXWORD_FIXNUM_SHIFT +#define MRB_FIXNUM_SHIFT WORDBOX_FIXNUM_SHIFT #endif -#define MRB_SYMBOL_SHIFT BOXWORD_SYMBOL_SHIFT +#define MRB_SYMBOL_SHIFT WORDBOX_SYMBOL_SHIFT #if defined(MRB_64BIT) && defined(MRB_INT64) # define MRB_FIXNUM_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT) @@ -41,36 +45,69 @@ enum mrb_special_consts { # define MRB_FIXNUM_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT) #endif -#define BOXWORD_FIXNUM_BIT_POS 1 -#define BOXWORD_SYMBOL_BIT_POS 2 -#define BOXWORD_FIXNUM_SHIFT BOXWORD_FIXNUM_BIT_POS -#ifdef MRB_64BIT -#define BOXWORD_SYMBOL_SHIFT 0 +#define WORDBOX_FIXNUM_BIT_POS 1 +#define WORDBOX_FIXNUM_SHIFT WORDBOX_FIXNUM_BIT_POS +#define WORDBOX_FIXNUM_FLAG (1 << (WORDBOX_FIXNUM_BIT_POS - 1)) +#define WORDBOX_FIXNUM_MASK ((1 << WORDBOX_FIXNUM_BIT_POS) - 1) + +#if defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) +/* floats are allocated in heaps */ +#define WORDBOX_SYMBOL_BIT_POS 2 +#define WORDBOX_SYMBOL_SHIFT WORDBOX_SYMBOL_BIT_POS +#define WORDBOX_SYMBOL_FLAG (1 << (WORDBOX_SYMBOL_BIT_POS - 1)) +#define WORDBOX_SYMBOL_MASK ((1 << WORDBOX_SYMBOL_BIT_POS) - 1) #else -#define BOXWORD_SYMBOL_SHIFT BOXWORD_SYMBOL_BIT_POS +#define WORDBOX_FLOAT_FLAG 2 +#define WORDBOX_FLOAT_MASK 3 +#if defined(MRB_64BIT) +#define WORDBOX_SYMBOL_SHIFT 32 +#else /* MRB_32BIT */ +#define WORDBOX_SYMBOL_SHIFT 5 #endif -#define BOXWORD_FIXNUM_FLAG (1 << (BOXWORD_FIXNUM_BIT_POS - 1)) -#define BOXWORD_SYMBOL_FLAG (1 << (BOXWORD_SYMBOL_BIT_POS - 1)) -#define BOXWORD_FIXNUM_MASK ((1 << BOXWORD_FIXNUM_BIT_POS) - 1) -#define BOXWORD_SYMBOL_MASK ((1 << BOXWORD_SYMBOL_BIT_POS) - 1) -#define BOXWORD_IMMEDIATE_MASK 0x07 - -#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \ - ((o).w = (((uintptr_t)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG) -#define BOXWORD_SHIFT_VALUE_P(o,n) \ - (((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG) -#define BOXWORD_OBJ_TYPE_P(o,n) \ +#define WORDBOX_SYMBOL_FLAG 0x1c +#define WORDBOX_SYMBOL_MASK 0x1f +#endif + +#define WORDBOX_IMMEDIATE_MASK 0x07 + +#define WORDBOX_SET_SHIFT_VALUE(o,n,v) \ + ((o).w = (((uintptr_t)(v)) << WORDBOX_##n##_SHIFT) | WORDBOX_##n##_FLAG) +#define WORDBOX_SHIFT_VALUE_P(o,n) \ + (((o).w & WORDBOX_##n##_MASK) == WORDBOX_##n##_FLAG) +#define WORDBOX_OBJ_TYPE_P(o,n) \ (!mrb_immediate_p(o) && mrb_val_union(o).bp->tt == MRB_TT_##n) /* * mrb_value representation: * + * 64bit word with inline float: + * nil : ...0000 0000 (all bits are 0) + * false : ...0000 0100 (mrb_fixnum(v) != 0) + * true : ...0000 1100 + * undef : ...0001 0100 + * symbol: ...0001 1100 (use only upper 32-bit as symbol value with MRB_64BIT) + * fixnum: ...IIII III1 + * float : ...FFFF FF10 (51 bit significands; require MRB_64BIT) + * object: ...PPPP P000 + * + * 32bit word with inline float: + * nil : ...0000 0000 (all bits are 0) + * false : ...0000 0100 (mrb_fixnum(v) != 0) + * true : ...0000 1100 + * undef : ...0001 0100 + * symbol: ...SSS1 1100 (use only upper 32-bit as symbol value with MRB_64BIT) + * symbol: ...SSS1 0100 (symbol occupies 20bits) + * fixnum: ...IIII III1 + * float : ...FFFF FF10 (22 bit significands; require MRB_64BIT) + * object: ...PPPP P000 + * + * and word boxing without inline float: * nil : ...0000 0000 (all bits are 0) * false : ...0000 0100 (mrb_fixnum(v) != 0) * true : ...0000 1100 * undef : ...0001 0100 * fixnum: ...IIII III1 - * symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU) + * symbol: ...SSSS SS10 * object: ...PPPP P000 (any bits are 1) */ typedef struct mrb_value { @@ -79,26 +116,21 @@ typedef struct mrb_value { union mrb_value_ { void *p; -#ifdef MRB_64BIT - /* use struct to avoid bit shift. */ - struct { - MRB_ENDIAN_LOHI( - mrb_sym sym; - ,uint32_t flag; - ) - } sym; -#endif struct RBasic *bp; #ifndef MRB_NO_FLOAT +#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE + mrb_float f; +#else struct RFloat *fp; #endif +#endif struct RInteger *ip; struct RCptr *vp; uintptr_t w; mrb_value value; }; -mrb_static_assert1(sizeof(mrb_value) == sizeof(union mrb_value_)); +mrb_static_assert(sizeof(mrb_value) == sizeof(union mrb_value_)); static inline union mrb_value_ mrb_val_union(mrb_value v) @@ -112,61 +144,62 @@ MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*); #ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float); #endif -MRB_API mrb_value mrb_word_boxing_int_value(struct mrb_state*, mrb_int); +MRB_API mrb_value mrb_boxing_int_value(struct mrb_state*, mrb_int); -#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil) +#define mrb_immediate_p(o) ((o).w & WORDBOX_IMMEDIATE_MASK || (o).w == MRB_Qnil) #define mrb_ptr(o) mrb_val_union(o).p #define mrb_cptr(o) mrb_val_union(o).vp->p #ifndef MRB_NO_FLOAT -#define mrb_float(o) mrb_val_union(o).fp->f +#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE +MRB_API mrb_float mrb_word_boxing_value_float(mrb_value v); +#define mrb_float(o) mrb_word_boxing_value_float(o) +#else +#define mrb_float(o) mrb_val_union(o).fp->f +#endif #endif -#define mrb_fixnum(o) (mrb_int)(((intptr_t)(o).w) >> BOXWORD_FIXNUM_SHIFT) +#define mrb_fixnum(o) (mrb_int)(((intptr_t)(o).w) >> WORDBOX_FIXNUM_SHIFT) MRB_INLINE mrb_int mrb_integer_func(mrb_value o) { if (mrb_immediate_p(o)) return mrb_fixnum(o); return mrb_val_union(o).ip->i; } #define mrb_integer(o) mrb_integer_func(o) -#ifdef MRB_64BIT -#define mrb_symbol(o) mrb_val_union(o).sym.sym -#else -#define mrb_symbol(o) (mrb_sym)(((o).w) >> BOXWORD_SYMBOL_SHIFT) -#endif +#define mrb_symbol(o) (mrb_sym)(((o).w) >> WORDBOX_SYMBOL_SHIFT) #define mrb_bool(o) (((o).w & ~(uintptr_t)MRB_Qfalse) != 0) -#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM) -#define mrb_integer_p(o) (BOXWORD_SHIFT_VALUE_P(o, FIXNUM)||BOXWORD_OBJ_TYPE_P(o, INTEGER)) -#ifdef MRB_64BIT -#define mrb_symbol_p(o) (mrb_val_union(o).sym.flag == BOXWORD_SYMBOL_FLAG) -#else -#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL) -#endif +#define mrb_fixnum_p(o) WORDBOX_SHIFT_VALUE_P(o, FIXNUM) +#define mrb_integer_p(o) (WORDBOX_SHIFT_VALUE_P(o, FIXNUM)||WORDBOX_OBJ_TYPE_P(o, INTEGER)) +#define mrb_symbol_p(o) WORDBOX_SHIFT_VALUE_P(o, SYMBOL) #define mrb_undef_p(o) ((o).w == MRB_Qundef) #define mrb_nil_p(o) ((o).w == MRB_Qnil) #define mrb_false_p(o) ((o).w == MRB_Qfalse) #define mrb_true_p(o) ((o).w == MRB_Qtrue) #ifndef MRB_NO_FLOAT -#define mrb_float_p(o) BOXWORD_OBJ_TYPE_P(o, FLOAT) +#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE +#define mrb_float_p(o) WORDBOX_SHIFT_VALUE_P(o, FLOAT) +#else +#define mrb_float_p(o) WORDBOX_OBJ_TYPE_P(o, FLOAT) +#endif #endif -#define mrb_array_p(o) BOXWORD_OBJ_TYPE_P(o, ARRAY) -#define mrb_string_p(o) BOXWORD_OBJ_TYPE_P(o, STRING) -#define mrb_hash_p(o) BOXWORD_OBJ_TYPE_P(o, HASH) -#define mrb_cptr_p(o) BOXWORD_OBJ_TYPE_P(o, CPTR) -#define mrb_exception_p(o) BOXWORD_OBJ_TYPE_P(o, EXCEPTION) -#define mrb_free_p(o) BOXWORD_OBJ_TYPE_P(o, FREE) -#define mrb_object_p(o) BOXWORD_OBJ_TYPE_P(o, OBJECT) -#define mrb_class_p(o) BOXWORD_OBJ_TYPE_P(o, CLASS) -#define mrb_module_p(o) BOXWORD_OBJ_TYPE_P(o, MODULE) -#define mrb_iclass_p(o) BOXWORD_OBJ_TYPE_P(o, ICLASS) -#define mrb_sclass_p(o) BOXWORD_OBJ_TYPE_P(o, SCLASS) -#define mrb_proc_p(o) BOXWORD_OBJ_TYPE_P(o, PROC) -#define mrb_range_p(o) BOXWORD_OBJ_TYPE_P(o, RANGE) -#define mrb_env_p(o) BOXWORD_OBJ_TYPE_P(o, ENV) -#define mrb_data_p(o) BOXWORD_OBJ_TYPE_P(o, DATA) -#define mrb_fiber_p(o) BOXWORD_OBJ_TYPE_P(o, FIBER) -#define mrb_istruct_p(o) BOXWORD_OBJ_TYPE_P(o, ISTRUCT) -#define mrb_break_p(o) BOXWORD_OBJ_TYPE_P(o, BREAK) +#define mrb_array_p(o) WORDBOX_OBJ_TYPE_P(o, ARRAY) +#define mrb_string_p(o) WORDBOX_OBJ_TYPE_P(o, STRING) +#define mrb_hash_p(o) WORDBOX_OBJ_TYPE_P(o, HASH) +#define mrb_cptr_p(o) WORDBOX_OBJ_TYPE_P(o, CPTR) +#define mrb_exception_p(o) WORDBOX_OBJ_TYPE_P(o, EXCEPTION) +#define mrb_free_p(o) WORDBOX_OBJ_TYPE_P(o, FREE) +#define mrb_object_p(o) WORDBOX_OBJ_TYPE_P(o, OBJECT) +#define mrb_class_p(o) WORDBOX_OBJ_TYPE_P(o, CLASS) +#define mrb_module_p(o) WORDBOX_OBJ_TYPE_P(o, MODULE) +#define mrb_iclass_p(o) WORDBOX_OBJ_TYPE_P(o, ICLASS) +#define mrb_sclass_p(o) WORDBOX_OBJ_TYPE_P(o, SCLASS) +#define mrb_proc_p(o) WORDBOX_OBJ_TYPE_P(o, PROC) +#define mrb_range_p(o) WORDBOX_OBJ_TYPE_P(o, RANGE) +#define mrb_env_p(o) WORDBOX_OBJ_TYPE_P(o, ENV) +#define mrb_data_p(o) WORDBOX_OBJ_TYPE_P(o, DATA) +#define mrb_fiber_p(o) WORDBOX_OBJ_TYPE_P(o, FIBER) +#define mrb_istruct_p(o) WORDBOX_OBJ_TYPE_P(o, ISTRUCT) +#define mrb_break_p(o) WORDBOX_OBJ_TYPE_P(o, BREAK) #ifndef MRB_NO_FLOAT #define SET_FLOAT_VALUE(mrb,r,v) ((r) = mrb_word_boxing_float_value(mrb, v)) @@ -177,18 +210,9 @@ mrb_integer_func(mrb_value o) { #define SET_FALSE_VALUE(r) ((r).w = MRB_Qfalse) #define SET_TRUE_VALUE(r) ((r).w = MRB_Qtrue) #define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r)) -#define SET_INT_VALUE(mrb,r,n) ((r) = mrb_word_boxing_int_value(mrb, n)) -#define SET_FIXNUM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n) -#ifdef MRB_64BIT -#define SET_SYM_VALUE(r,v) do {\ - union mrb_value_ mrb_value_union_variable;\ - mrb_value_union_variable.sym.sym = v;\ - mrb_value_union_variable.sym.flag = BOXWORD_SYMBOL_FLAG;\ - (r) = mrb_value_union_variable.value;\ -} while (0) -#else -#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n) -#endif +#define SET_INT_VALUE(mrb,r,n) ((r) = mrb_boxing_int_value(mrb, n)) +#define SET_FIXNUM_VALUE(r,n) WORDBOX_SET_SHIFT_VALUE(r, FIXNUM, n) +#define SET_SYM_VALUE(r,n) WORDBOX_SET_SHIFT_VALUE(r, SYMBOL, n) #define SET_OBJ_VALUE(r,v) ((r).w = (uintptr_t)(v)) MRB_INLINE enum mrb_vtype @@ -199,6 +223,9 @@ mrb_type(mrb_value o) mrb_fixnum_p(o) ? MRB_TT_INTEGER : mrb_symbol_p(o) ? MRB_TT_SYMBOL : mrb_undef_p(o) ? MRB_TT_UNDEF : +#ifndef MRB_NO_FLOAT + mrb_float_p(o) ? MRB_TT_FLOAT : +#endif mrb_val_union(o).bp->tt; } diff --git a/include/mruby/compile.h b/include/mruby/compile.h index 8159cd696..6732625c1 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -16,8 +16,6 @@ MRB_BEGIN_DECL #include <mruby.h> -struct mrb_jmpbuf; - struct mrb_parser_state; /* load context */ typedef struct mrbc_context { @@ -165,7 +163,6 @@ struct mrb_parser_state { uint16_t filename_table_length; uint16_t current_filename_index; - struct mrb_jmpbuf* jmp; mrb_ast_node *nvars; }; diff --git a/include/mruby/debug.h b/include/mruby/debug.h index 2062a9308..7319ccb3f 100644 --- a/include/mruby/debug.h +++ b/include/mruby/debug.h @@ -16,7 +16,8 @@ MRB_BEGIN_DECL typedef enum mrb_debug_line_type { mrb_debug_line_ary = 0, - mrb_debug_line_flat_map = 1 + mrb_debug_line_flat_map, + mrb_debug_line_packed_map } mrb_debug_line_type; typedef struct mrb_irep_debug_info_line { @@ -31,8 +32,9 @@ typedef struct mrb_irep_debug_info_file { mrb_debug_line_type line_type; union { void *ptr; - mrb_irep_debug_info_line *flat_map; uint16_t *ary; + mrb_irep_debug_info_line *flat_map; + uint8_t *packed_map; } lines; } mrb_irep_debug_info_file; diff --git a/include/mruby/dump.h b/include/mruby/dump.h index 3c48866d9..fea0ac2b1 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -54,7 +54,7 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t); /* Binary Format Version Major:Minor */ /* Major: Incompatible to prior versions */ /* Minor: Upper-compatible to prior versions */ -#define RITE_BINARY_MAJOR_VER "02" +#define RITE_BINARY_MAJOR_VER "03" #define RITE_BINARY_MINOR_VER "00" #define RITE_BINARY_FORMAT_VER RITE_BINARY_MAJOR_VER RITE_BINARY_MINOR_VER #define RITE_COMPILER_NAME "MATZ" diff --git a/include/mruby/error.h b/include/mruby/error.h index 20ca38586..80c21434f 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -17,9 +17,11 @@ MRB_BEGIN_DECL struct RException { MRB_OBJECT_HEADER; struct iv_tbl *iv; + struct RString *mesg; }; #define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v)) +#define MRB_EXC_MESG_STRING_FLAG 0x100 MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg); MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str); diff --git a/include/mruby/hash.h b/include/mruby/hash.h index 749ea3869..1b37a12d4 100644 --- a/include/mruby/hash.h +++ b/include/mruby/hash.h @@ -37,8 +37,6 @@ struct RHash { size_t mrb_hash_memsize(mrb_value obj); MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa); -MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash); -MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); /* * Initializes a new hash. diff --git a/include/mruby/irep.h b/include/mruby/irep.h index 6a3b4bd10..2a0e261d1 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -122,7 +122,8 @@ struct mrb_insn_data { uint8_t insn; uint16_t a; uint16_t b; - uint16_t c; + uint8_t c; + const mrb_code *addr; }; struct mrb_insn_data mrb_decode_insn(const mrb_code *pc); diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index fc6cacfda..4b14588ac 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -30,21 +30,19 @@ MRB_BEGIN_DECL #endif #endif -#ifndef MRB_NO_FLOAT -MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val); -#endif -MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base); -/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */ -#ifndef MRB_NO_FLOAT -MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); -MRB_API int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float f); -MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x); -#endif - MRB_API mrb_value mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y); MRB_API mrb_value mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y); MRB_API mrb_value mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y); +MRB_API mrb_value mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base); +MRB_API char *mrb_int_to_cstr(char *buf, size_t len, mrb_int n, mrb_int base); + +/* internal function(s) */ +mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); + +/* obsolete function(s); will be removed */ +#define mrb_fixnum_to_str(mrb, x, base) mrb_integer_to_str(mrb, x, base) + #ifndef __has_builtin #define __has_builtin(x) 0 #endif @@ -135,8 +133,6 @@ mrb_int_mul_overflow(mrb_int a, mrb_int b, mrb_int *c) #endif #ifndef MRB_NO_FLOAT -# include <stdint.h> -# include <float.h> # define MRB_FLT_RADIX FLT_RADIX @@ -162,6 +158,19 @@ mrb_int_mul_overflow(mrb_int a, mrb_int b, mrb_int *c) # define MRB_FLT_MAX DBL_MAX # define MRB_FLT_MAX_10_EXP DBL_MAX_10_EXP # endif /* MRB_USE_FLOAT32 */ + +MRB_API mrb_value mrb_float_to_integer(mrb_state *mrb, mrb_value val); +MRB_API mrb_float mrb_as_float(mrb_state *mrb, mrb_value x); + +/* internal functions */ +mrb_float mrb_div_float(mrb_float x, mrb_float y); +mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); +int mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, char sign); + +/* obsolete functions; will be removed */ +#define mrb_flo_to_fixnum(mrb, val) mrb_float_to_integer(mrb, val) +#define mrb_to_flo(mrb, x) mrb_as_float(mrb, x) + #endif /* MRB_NO_FLOAT */ MRB_END_DECL diff --git a/include/mruby/opcode.h b/include/mruby/opcode.h index 987c5ad8f..249598161 100644 --- a/include/mruby/opcode.h +++ b/include/mruby/opcode.h @@ -40,4 +40,34 @@ enum mrb_insn { #define FETCH_S() do {a=READ_S();} while (0) #define FETCH_W() do {a=READ_W();} while (0) +/* with OP_EXT1 (1st 16bit) */ +#define FETCH_Z_1() FETCH_Z() +#define FETCH_B_1() FETCH_S() +#define FETCH_BB_1() do {a=READ_S(); b=READ_B();} while (0) +#define FETCH_BBB_1() do {a=READ_S(); b=READ_B(); c=READ_B();} while (0) +#define FETCH_BS_1() do {a=READ_S(); b=READ_S();} while (0) +#define FETCH_BSS_1() do {a=READ_S(); b=READ_S();c=READ_S();} while (0) +#define FETCH_S_1() FETCH_S() +#define FETCH_W_1() FETCH_W() + +/* with OP_EXT2 (2nd 16bit) */ +#define FETCH_Z_2() FETCH_Z() +#define FETCH_B_2() FETCH_B() +#define FETCH_BB_2() do {a=READ_B(); b=READ_S();} while (0) +#define FETCH_BBB_2() do {a=READ_B(); b=READ_S(); c=READ_B();} while (0) +#define FETCH_BS_2() FETCH_BS() +#define FETCH_BSS_2() FETCH_BSS() +#define FETCH_S_2() FETCH_S() +#define FETCH_W_2() FETCH_W() + +/* with OP_EXT3 (1st & 2nd 16bit) */ +#define FETCH_Z_3() FETCH_Z() +#define FETCH_B_3() FETCH_B() +#define FETCH_BB_3() do {a=READ_S(); b=READ_S();} while (0) +#define FETCH_BBB_3() do {a=READ_S(); b=READ_S(); c=READ_B();} while (0) +#define FETCH_BS_3() do {a=READ_S(); b=READ_S();} while (0) +#define FETCH_BSS_3() FETCH_BSS_1() +#define FETCH_S_3() FETCH_S() +#define FETCH_W_3() FETCH_W() + #endif /* MRUBY_OPCODE_H */ diff --git a/include/mruby/ops.h b/include/mruby/ops.h index d5d8fb077..f62d8cdfa 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -13,110 +13,108 @@ operation code operands semantics ------------------------------------------------------------------------*/ OPCODE(NOP, Z) /* no operation */ -OPCODE(MOVE, BB) /* R(a) = R(b) */ -OPCODE(LOADL, BB) /* R(a) = Pool(b) */ -OPCODE(LOADL16, BS) /* R(a) = Pool(b) */ -OPCODE(LOADI, BB) /* R(a) = mrb_int(b) */ -OPCODE(LOADINEG, BB) /* R(a) = mrb_int(-b) */ -OPCODE(LOADI__1, B) /* R(a) = mrb_int(-1) */ -OPCODE(LOADI_0, B) /* R(a) = mrb_int(0) */ -OPCODE(LOADI_1, B) /* R(a) = mrb_int(1) */ -OPCODE(LOADI_2, B) /* R(a) = mrb_int(2) */ -OPCODE(LOADI_3, B) /* R(a) = mrb_int(3) */ -OPCODE(LOADI_4, B) /* R(a) = mrb_int(4) */ -OPCODE(LOADI_5, B) /* R(a) = mrb_int(5) */ -OPCODE(LOADI_6, B) /* R(a) = mrb_int(6) */ -OPCODE(LOADI_7, B) /* R(a) = mrb_int(7) */ -OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */ -OPCODE(LOADI32, BSS) /* R(a) = mrb_int((b<<16)+c) */ -OPCODE(LOADSYM, BB) /* R(a) = Syms(b) */ -OPCODE(LOADSYM16, BS) /* R(a) = Syms(b) */ -OPCODE(LOADNIL, B) /* R(a) = nil */ -OPCODE(LOADSELF, B) /* R(a) = self */ -OPCODE(LOADT, B) /* R(a) = true */ -OPCODE(LOADF, B) /* R(a) = false */ -OPCODE(GETGV, BB) /* R(a) = getglobal(Syms(b)) */ -OPCODE(SETGV, BB) /* setglobal(Syms(b), R(a)) */ -OPCODE(GETSV, BB) /* R(a) = Special[Syms(b)] */ -OPCODE(SETSV, BB) /* Special[Syms(b)] = R(a) */ -OPCODE(GETIV, BB) /* R(a) = ivget(Syms(b)) */ -OPCODE(SETIV, BB) /* ivset(Syms(b),R(a)) */ -OPCODE(GETCV, BB) /* R(a) = cvget(Syms(b)) */ -OPCODE(SETCV, BB) /* cvset(Syms(b),R(a)) */ -OPCODE(GETCONST, BB) /* R(a) = constget(Syms(b)) */ -OPCODE(SETCONST, BB) /* constset(Syms(b),R(a)) */ -OPCODE(GETMCNST, BB) /* R(a) = R(a)::Syms(b) */ -OPCODE(SETMCNST, BB) /* R(a+1)::Syms(b) = R(a) */ -OPCODE(GETUPVAR, BBB) /* R(a) = uvget(b,c) */ -OPCODE(SETUPVAR, BBB) /* uvset(b,c,R(a)) */ +OPCODE(MOVE, BB) /* R[a] = R[b] */ +OPCODE(LOADL, BB) /* R[a] = Pool[b] */ +OPCODE(LOADI, BB) /* R[a] = mrb_int(b) */ +OPCODE(LOADINEG, BB) /* R[a] = mrb_int(-b) */ +OPCODE(LOADI__1, B) /* R[a] = mrb_int(-1) */ +OPCODE(LOADI_0, B) /* R[a] = mrb_int(0) */ +OPCODE(LOADI_1, B) /* R[a] = mrb_int(1) */ +OPCODE(LOADI_2, B) /* R[a] = mrb_int(2) */ +OPCODE(LOADI_3, B) /* R[a] = mrb_int(3) */ +OPCODE(LOADI_4, B) /* R[a] = mrb_int(4) */ +OPCODE(LOADI_5, B) /* R[a] = mrb_int(5) */ +OPCODE(LOADI_6, B) /* R[a] = mrb_int(6) */ +OPCODE(LOADI_7, B) /* R[a] = mrb_int(7) */ +OPCODE(LOADI16, BS) /* R[a] = mrb_int(b) */ +OPCODE(LOADI32, BSS) /* R[a] = mrb_int((b<<16)+c) */ +OPCODE(LOADSYM, BB) /* R[a] = Syms[b] */ +OPCODE(LOADNIL, B) /* R[a] = nil */ +OPCODE(LOADSELF, B) /* R[a] = self */ +OPCODE(LOADT, B) /* R[a] = true */ +OPCODE(LOADF, B) /* R[a] = false */ +OPCODE(GETGV, BB) /* R[a] = getglobal(Syms[b]) */ +OPCODE(SETGV, BB) /* setglobal(Syms[b], R[a]) */ +OPCODE(GETSV, BB) /* R[a] = Special[Syms[b]] */ +OPCODE(SETSV, BB) /* Special[Syms[b]] = R[a] */ +OPCODE(GETIV, BB) /* R[a] = ivget(Syms[b]) */ +OPCODE(SETIV, BB) /* ivset(Syms[b],R[a]) */ +OPCODE(GETCV, BB) /* R[a] = cvget(Syms[b]) */ +OPCODE(SETCV, BB) /* cvset(Syms[b],R[a]) */ +OPCODE(GETCONST, BB) /* R[a] = constget(Syms[b]) */ +OPCODE(SETCONST, BB) /* constset(Syms[b],R[a]) */ +OPCODE(GETMCNST, BB) /* R[a] = R[a]::Syms[b] */ +OPCODE(SETMCNST, BB) /* R[a+1]::Syms[b] = R[a] */ +OPCODE(GETUPVAR, BBB) /* R[a] = uvget(b,c) */ +OPCODE(SETUPVAR, BBB) /* uvset(b,c,R[a]) */ +OPCODE(GETIDX, B) /* R[a] = R[a][R[a+1]] */ +OPCODE(SETIDX, B) /* R[a][R[a+1]] = R[a+2] */ OPCODE(JMP, S) /* pc+=a */ -OPCODE(JMPIF, BS) /* if R(a) pc+=b */ -OPCODE(JMPNOT, BS) /* if !R(a) pc+=b */ -OPCODE(JMPNIL, BS) /* if R(a)==nil pc+=b */ +OPCODE(JMPIF, BS) /* if R[a] pc+=b */ +OPCODE(JMPNOT, BS) /* if !R[a] pc+=b */ +OPCODE(JMPNIL, BS) /* if R[a]==nil pc+=b */ OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */ -OPCODE(EXCEPT, B) /* R(a) = exc */ -OPCODE(RESCUE, BB) /* R(b) = R(a).isa?(R(b)) */ -OPCODE(RAISEIF, B) /* raise(R(a)) if R(a) */ -OPCODE(SENDV, BB) /* R(a) = call(R(a),Syms(b),*R(a+1)) */ -OPCODE(SENDVB, BB) /* R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) */ -OPCODE(SEND, BBB) /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) */ -OPCODE(SENDB, BBB) /* R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) */ -OPCODE(SENDVK, BB) /* R(a) = call(R(a),Syms(b),*R(a+1),**(a+2),&R(a+3)) # todo */ -OPCODE(CALL, Z) /* R(0) = self.call(frame.argc, frame.argv) */ -OPCODE(SUPER, BB) /* R(a) = super(R(a+1),... ,R(a+b+1)) */ -OPCODE(ARGARY, BS) /* R(a) = argument array (16=m5:r1:m5:d1:lv4) */ +OPCODE(EXCEPT, B) /* R[a] = exc */ +OPCODE(RESCUE, BB) /* R[b] = R[a].isa?(R[b]) */ +OPCODE(RAISEIF, B) /* raise(R[a]) if R[a] */ +OPCODE(SSEND, BBB) /* R[a] = self.send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..) (c=n|k<<4) */ +OPCODE(SSENDB, BBB) /* R[a] = self.send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..,&R[a+n+2k+1]) */ +OPCODE(SEND, BBB) /* R[a] = R[a].send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..) (c=n|k<<4) */ +OPCODE(SENDB, BBB) /* R[a] = R[a].send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..,&R[a+n+2k+1]) */ +OPCODE(CALL, Z) /* R[0] = self.call(frame.argc, frame.argv) */ +OPCODE(SUPER, BB) /* R[a] = super(R[a+1],... ,R[a+b+1]) */ +OPCODE(ARGARY, BS) /* R[a] = argument array (16=m5:r1:m5:d1:lv4) */ OPCODE(ENTER, W) /* arg setup according to flags (23=m5:o5:r1:m5:k5:d1:b1) */ -OPCODE(KEY_P, BB) /* R(a) = kdict.key?(Syms(b)) */ +OPCODE(KEY_P, BB) /* R[a] = kdict.key?(Syms[b]) */ OPCODE(KEYEND, Z) /* raise unless kdict.empty? */ -OPCODE(KARG, BB) /* R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) */ -OPCODE(RETURN, B) /* return R(a) (normal) */ -OPCODE(RETURN_BLK, B) /* return R(a) (in-block return) */ -OPCODE(BREAK, B) /* break R(a) */ -OPCODE(BLKPUSH, BS) /* R(a) = block (16=m5:r1:m5:d1:lv4) */ -OPCODE(ADD, B) /* R(a) = R(a)+R(a+1) */ -OPCODE(ADDI, BB) /* R(a) = R(a)+mrb_int(b) */ -OPCODE(SUB, B) /* R(a) = R(a)-R(a+1) */ -OPCODE(SUBI, BB) /* R(a) = R(a)-mrb_int(b) */ -OPCODE(MUL, B) /* R(a) = R(a)*R(a+1) */ -OPCODE(DIV, B) /* R(a) = R(a)/R(a+1) */ -OPCODE(EQ, B) /* R(a) = R(a)==R(a+1) */ -OPCODE(LT, B) /* R(a) = R(a)<R(a+1) */ -OPCODE(LE, B) /* R(a) = R(a)<=R(a+1) */ -OPCODE(GT, B) /* R(a) = R(a)>R(a+1) */ -OPCODE(GE, B) /* R(a) = R(a)>=R(a+1) */ -OPCODE(ARRAY, BB) /* R(a) = ary_new(R(a),R(a+1)..R(a+b)) */ -OPCODE(ARRAY2, BBB) /* R(a) = ary_new(R(b),R(b+1)..R(b+c)) */ -OPCODE(ARYCAT, B) /* ary_cat(R(a),R(a+1)) */ -OPCODE(ARYPUSH, B) /* ary_push(R(a),R(a+1)) */ -OPCODE(ARYDUP, B) /* R(a) = ary_dup(R(a)) */ -OPCODE(AREF, BBB) /* R(a) = R(b)[c] */ -OPCODE(ASET, BBB) /* R(a)[c] = R(b) */ -OPCODE(APOST, BBB) /* *R(a),R(a+1)..R(a+c) = R(a)[b..] */ -OPCODE(INTERN, B) /* R(a) = intern(R(a)) */ -OPCODE(STRING, BB) /* R(a) = str_dup(Lit(b)) */ -OPCODE(STRING16, BS) /* R(a) = str_dup(Lit(b)) */ -OPCODE(STRCAT, B) /* str_cat(R(a),R(a+1)) */ -OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) */ -OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) */ -OPCODE(HASHCAT, B) /* R(a) = hash_cat(R(a),R(a+1)) */ -OPCODE(LAMBDA, BB) /* R(a) = lambda(SEQ[b],L_LAMBDA) */ -OPCODE(LAMBDA16, BS) /* R(a) = lambda(SEQ[b],L_LAMBDA) */ -OPCODE(BLOCK, BB) /* R(a) = lambda(SEQ[b],L_BLOCK) */ -OPCODE(BLOCK16, BS) /* R(a) = lambda(SEQ[b],L_BLOCK) */ -OPCODE(METHOD, BB) /* R(a) = lambda(SEQ[b],L_METHOD) */ -OPCODE(METHOD16, BS) /* R(a) = lambda(SEQ[b],L_METHOD) */ -OPCODE(RANGE_INC, B) /* R(a) = range_new(R(a),R(a+1),FALSE) */ -OPCODE(RANGE_EXC, B) /* R(a) = range_new(R(a),R(a+1),TRUE) */ -OPCODE(OCLASS, B) /* R(a) = ::Object */ -OPCODE(CLASS, BB) /* R(a) = newclass(R(a),Syms(b),R(a+1)) */ -OPCODE(MODULE, BB) /* R(a) = newmodule(R(a),Syms(b)) */ -OPCODE(EXEC, BB) /* R(a) = blockexec(R(a),SEQ[b]) */ -OPCODE(EXEC16, BS) /* R(a) = blockexec(R(a),SEQ[b]) */ -OPCODE(DEF, BB) /* R(a).newmethod(Syms(b),R(a+1)) */ -OPCODE(ALIAS, BB) /* alias_method(target_class,Syms(a),Syms(b)) */ -OPCODE(UNDEF, B) /* undef_method(target_class,Syms(a)) */ -OPCODE(SCLASS, B) /* R(a) = R(a).singleton_class */ -OPCODE(TCLASS, B) /* R(a) = target_class */ +OPCODE(KARG, BB) /* R[a] = kdict[Syms[b]]; kdict.delete(Syms[b]) */ +OPCODE(RETURN, B) /* return R[a] (normal) */ +OPCODE(RETURN_BLK, B) /* return R[a] (in-block return) */ +OPCODE(BREAK, B) /* break R[a] */ +OPCODE(BLKPUSH, BS) /* R[a] = block (16=m5:r1:m5:d1:lv4) */ +OPCODE(ADD, B) /* R[a] = R[a]+R[a+1] */ +OPCODE(ADDI, BB) /* R[a] = R[a]+mrb_int(b) */ +OPCODE(SUB, B) /* R[a] = R[a]-R[a+1] */ +OPCODE(SUBI, BB) /* R[a] = R[a]-mrb_int(b) */ +OPCODE(MUL, B) /* R[a] = R[a]*R[a+1] */ +OPCODE(DIV, B) /* R[a] = R[a]/R[a+1] */ +OPCODE(EQ, B) /* R[a] = R[a]==R[a+1] */ +OPCODE(LT, B) /* R[a] = R[a]<R[a+1] */ +OPCODE(LE, B) /* R[a] = R[a]<=R[a+1] */ +OPCODE(GT, B) /* R[a] = R[a]>R[a+1] */ +OPCODE(GE, B) /* R[a] = R[a]>=R[a+1] */ +OPCODE(ARRAY, BB) /* R[a] = ary_new(R[a],R[a+1]..R[a+b]) */ +OPCODE(ARRAY2, BBB) /* R[a] = ary_new(R[b],R[b+1]..R[b+c]) */ +OPCODE(ARYCAT, B) /* ary_cat(R[a],R[a+1]) */ +OPCODE(ARYPUSH, BB) /* ary_push(R[a],R[a+1]..R[a+b]) */ +OPCODE(ARYDUP, B) /* R[a] = ary_dup(R[a]) */ +OPCODE(AREF, BBB) /* R[a] = R[b][c] */ +OPCODE(ASET, BBB) /* R[a][c] = R[b] */ +OPCODE(APOST, BBB) /* *R[a],R[a+1]..R[a+c] = R[a][b..] */ +OPCODE(INTERN, B) /* R[a] = intern(R[a]) */ +OPCODE(SYMBOL, BB) /* R[a] = intern(Pool[b]) */ +OPCODE(STRING, BB) /* R[a] = str_dup(Pool[b]) */ +OPCODE(STRCAT, B) /* str_cat(R[a],R[a+1]) */ +OPCODE(HASH, BB) /* R[a] = hash_new(R[a],R[a+1]..R[a+b*2-1]) */ +OPCODE(HASHADD, BB) /* hash_push(R[a],R[a+1]..R[a+b*2]) */ +OPCODE(HASHCAT, B) /* R[a] = hash_cat(R[a],R[a+1]) */ +OPCODE(LAMBDA, BB) /* R[a] = lambda(Irep[b],L_LAMBDA) */ +OPCODE(BLOCK, BB) /* R[a] = lambda(Irep[b],L_BLOCK) */ +OPCODE(METHOD, BB) /* R[a] = lambda(Irep[b],L_METHOD) */ +OPCODE(RANGE_INC, B) /* R[a] = range_new(R[a],R[a+1],FALSE) */ +OPCODE(RANGE_EXC, B) /* R[a] = range_new(R[a],R[a+1],TRUE) */ +OPCODE(OCLASS, B) /* R[a] = ::Object */ +OPCODE(CLASS, BB) /* R[a] = newclass(R[a],Syms[b],R[a+1]) */ +OPCODE(MODULE, BB) /* R[a] = newmodule(R[a],Syms[b]) */ +OPCODE(EXEC, BB) /* R[a] = blockexec(R[a],Irep[b]) */ +OPCODE(DEF, BB) /* R[a].newmethod(Syms[b],R[a+1]); R[a] = Syms[b] */ +OPCODE(ALIAS, BB) /* alias_method(target_class,Syms[a],Syms[b]) */ +OPCODE(UNDEF, B) /* undef_method(target_class,Syms[a]) */ +OPCODE(SCLASS, B) /* R[a] = R[a].singleton_class */ +OPCODE(TCLASS, B) /* R[a] = target_class */ OPCODE(DEBUG, BBB) /* print a,b,c */ -OPCODE(ERR, B) /* raise(LocalJumpError, Lit(a)) */ +OPCODE(ERR, B) /* raise(LocalJumpError, Pool[a]) */ +OPCODE(EXT1, Z) /* make 1st operand (a) 16bit */ +OPCODE(EXT2, Z) /* make 2nd operand (b) 16bit */ +OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */ OPCODE(STOP, Z) /* stop VM */ diff --git a/include/mruby/string.h b/include/mruby/string.h index 4410accd5..b296832af 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -324,20 +324,6 @@ MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len); */ MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); -/** - * Returns a Ruby string type. - * - * - * @param mrb The current mruby state. - * @param str Ruby string. - * @return [mrb_value] A Ruby string. - */ -MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str); -MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); -/* obsolete: use mrb_ensure_string_type() instead */ -MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str); - - MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa); #define mrb_str_buf_new(mrb, capa) mrb_str_new_capa(mrb, (capa)) @@ -369,17 +355,10 @@ MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str); */ MRB_API mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self); -MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck); -MRB_API mrb_value mrb_cstr_to_inum(mrb_state *mrb, const char *s, mrb_int base, mrb_bool badcheck); +MRB_API mrb_value mrb_str_to_integer(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck); +/* obsolete: use mrb_str_to_integer() */ +#define mrb_str_to_inum(mrb, str, base, badcheck) mrb_str_to_integer(mrb, str, base, badcheck) MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck); -MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck); - -/** - * Returns a converted string type. - * For type checking, non converting `mrb_to_str` is recommended. - * obsolete: use `mrb_obj_as_string()` instead. - */ -#define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str) /** * Returns true if the strings match and false if the strings don't match. diff --git a/include/mruby/value.h b/include/mruby/value.h index 39c01509d..ad439334b 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -31,7 +31,30 @@ typedef uint32_t mrb_sym; * Not to be confused with Ruby's boolean classes, which can be * obtained using mrb_false_value() and mrb_true_value() */ +#if defined(__cplusplus) || (defined(__bool_true_false_are_defined) && __bool_true_false_are_defined) +typedef bool mrb_bool; + +# ifndef FALSE +# define FALSE false +# endif +# ifndef TRUE +# define TRUE true +# endif +#else +# if __STDC_VERSION__ >= 199901L +typedef _Bool mrb_bool; +# else typedef uint8_t mrb_bool; +# endif + +# ifndef FALSE +# define FALSE 0 +# endif +# ifndef TRUE +# define TRUE 1 +# endif +#endif + struct mrb_state; #if defined _MSC_VER && _MSC_VER < 1800 @@ -77,6 +100,7 @@ struct mrb_state; # define MRB_ENDIAN_LOHI(a,b) b a #endif +MRB_API mrb_int mrb_int_read(const char *p, const char *e, char **endp); #ifndef MRB_NO_FLOAT MRB_API double mrb_float_read(const char*, char**); #ifdef MRB_USE_FLOAT32 @@ -87,13 +111,11 @@ MRB_API double mrb_float_read(const char*, char**); #endif #if defined _MSC_VER && _MSC_VER < 1900 -# include <stdarg.h> MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg); MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...); # define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg) # define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__) # if _MSC_VER < 1800 && !defined MRB_NO_FLOAT -# include <float.h> # define isfinite(n) _finite(n) # define isnan _isnan # define isinf(n) (!_finite(n) && !_isnan(n)) @@ -104,36 +126,49 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; # endif #endif +#define MRB_VTYPE_FOREACH(f) \ + /* mrb_vtype */ /* c type */ /* ruby class */ \ + f(MRB_TT_FALSE, void, "false") \ + f(MRB_TT_TRUE, void, "true") \ + f(MRB_TT_SYMBOL, void, "Symbol") \ + f(MRB_TT_UNDEF, void, "undefined") \ + f(MRB_TT_FREE, void, "free") \ + f(MRB_TT_FLOAT, struct RFloat, "Float") \ + f(MRB_TT_INTEGER, struct RInteger, "Integer") \ + f(MRB_TT_CPTR, struct RCptr, "cptr") \ + f(MRB_TT_OBJECT, struct RObject, "Object") \ + f(MRB_TT_CLASS, struct RClass, "Class") \ + f(MRB_TT_MODULE, struct RClass, "Module") \ + f(MRB_TT_ICLASS, struct RClass, "iClass") \ + f(MRB_TT_SCLASS, struct RClass, "SClass") \ + f(MRB_TT_PROC, struct RProc, "Proc") \ + f(MRB_TT_ARRAY, struct RArray, "Array") \ + f(MRB_TT_HASH, struct RHash, "Hash") \ + f(MRB_TT_STRING, struct RString, "String") \ + f(MRB_TT_RANGE, struct RRange, "Range") \ + f(MRB_TT_EXCEPTION, struct RException, "Exception") \ + f(MRB_TT_ENV, struct REnv, "env") \ + f(MRB_TT_DATA, struct RData, "Data") \ + f(MRB_TT_FIBER, struct RFiber, "Fiber") \ + f(MRB_TT_STRUCT, struct RArray, "Struct") \ + f(MRB_TT_ISTRUCT, struct RIStruct, "istruct") \ + f(MRB_TT_BREAK, struct RBreak, "break") \ + f(MRB_TT_COMPLEX, struct RComplex, "Complex") \ + f(MRB_TT_RATIONAL, struct RRational, "Rational") + enum mrb_vtype { - MRB_TT_FALSE = 0, - MRB_TT_TRUE, - MRB_TT_SYMBOL, - MRB_TT_UNDEF, - MRB_TT_FREE, - MRB_TT_FLOAT, - MRB_TT_INTEGER, - MRB_TT_CPTR, - MRB_TT_OBJECT, - MRB_TT_CLASS, - MRB_TT_MODULE, - MRB_TT_ICLASS, - MRB_TT_SCLASS, - MRB_TT_PROC, - MRB_TT_ARRAY, - MRB_TT_HASH, - MRB_TT_STRING, - MRB_TT_RANGE, - MRB_TT_EXCEPTION, - MRB_TT_ENV, - MRB_TT_DATA, - MRB_TT_FIBER, - MRB_TT_ISTRUCT, - MRB_TT_BREAK, - MRB_TT_COMPLEX, - MRB_TT_RATIONAL, +#define MRB_VTYPE_DEFINE(tt, type, name) tt, + MRB_VTYPE_FOREACH(MRB_VTYPE_DEFINE) +#undef MRB_VTYPE_DEFINE MRB_TT_MAXDEFINE }; +#define MRB_VTYPE_TYPEOF(tt) MRB_TYPEOF_##tt + +#define MRB_VTYPE_TYPEDEF(tt, type, name) typedef type MRB_VTYPE_TYPEOF(tt); +MRB_VTYPE_FOREACH(MRB_VTYPE_TYPEDEF) +#undef MRB_VTYPE_TYPEDEF + /* for compatibility */ #define MRB_TT_FIXNUM MRB_TT_INTEGER @@ -374,26 +409,29 @@ mrb_undef_value(void) return v; } -#if defined(MRB_USE_ETEXT_EDATA) && !defined(MRB_USE_LINK_TIME_RO_DATA_P) -# ifdef __GNUC__ -# warning MRB_USE_ETEXT_EDATA is deprecated. Define MRB_USE_LINK_TIME_RO_DATA_P instead. -# endif -# define MRB_USE_LINK_TIME_RO_DATA_P -#endif - #if defined(MRB_USE_CUSTOM_RO_DATA_P) /* If you define `MRB_USE_CUSTOM_RO_DATA_P`, you must implement `mrb_ro_data_p()`. */ mrb_bool mrb_ro_data_p(const char *p); -#elif defined(MRB_USE_LINK_TIME_RO_DATA_P) -extern char __ehdr_start[]; -extern char __init_array_start[]; - +#elif !defined(MRB_NO_DEFAULT_RO_DATA_P) +#if defined(MRB_USE_ETEXT_RO_DATA_P) +#define MRB_LINK_TIME_RO_DATA_P +extern char etext, edata; static inline mrb_bool mrb_ro_data_p(const char *p) { - return __ehdr_start < p && p < __init_array_start; + return &etext < p && p < &edata; } -#else +#elif defined(__APPLE__) +#define MRB_LINK_TIME_RO_DATA_P +#include <mach-o/getsect.h> +static inline mrb_bool +mrb_ro_data_p(const char *p) +{ + return (char*)get_etext() < p && p < (char*)get_edata(); +} +#endif /* Linux or macOS */ +#endif /* MRB_NO_DEFAULT_RO_DATA_P */ +#ifndef MRB_LINK_TIME_RO_DATA_P # define mrb_ro_data_p(p) FALSE #endif diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index 67267ab46..66005a6df 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -541,6 +541,23 @@ EOS end end + def run_bintest + puts ">>> Bintest #{name} <<<" + targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir } + targets << filename(".") if File.directory? "./bintest" + mrbc = @gems["mruby-bin-mrbc"] ? exefile("#{@build_dir}/bin/mrbc") : mrbcfile + + emulator = @test_runner.command + emulator = @test_runner.shellquote(emulator) if emulator + + env = { + "BUILD_DIR" => @build_dir, + "MRBCFILE" => mrbc, + "EMULATOR" => @test_runner.emulator, + } + sh env, "ruby test/bintest.rb#{verbose_flag} #{targets.join ' '}" + end + protected def create_mrbc_build; end diff --git a/lib/mruby/build/command.rb b/lib/mruby/build/command.rb index c93d08ea7..31a595ef0 100644 --- a/lib/mruby/build/command.rb +++ b/lib/mruby/build/command.rb @@ -363,6 +363,11 @@ module MRuby @flags = [] end + def emulator + return "" unless @command + return [@command, *@flags].map{|c| shellquote(c)}.join(' ') + end + def run(testbinfile) puts "TEST for " + @build.name _run runner_options, { :flags => [flags, verbose_flag].flatten.join(' '), :infile => testbinfile } diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index 716f21286..fa0bb3a49 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -253,7 +253,7 @@ module MRuby f.puts %Q[#include <mruby.h>] else f.puts %Q[#include <stdlib.h>] - unless build.presym_enabled? + unless cdump? f.puts %Q[#include <mruby.h>] f.puts %Q[#include <mruby/proc.h>] end diff --git a/lib/mruby/presym.rb b/lib/mruby/presym.rb index 6a68cf65c..016c2b20e 100644 --- a/lib/mruby/presym.rb +++ b/lib/mruby/presym.rb @@ -99,7 +99,7 @@ module MRuby end def list_path - @list_pat ||= "#{@build.build_dir}/presym".freeze + @list_path ||= "#{@build.build_dir}/presym".freeze end def header_dir; diff --git a/lib/mruby/source.rb b/lib/mruby/source.rb index a305c7b04..ce9e558dc 100644 --- a/lib/mruby/source.rb +++ b/lib/mruby/source.rb @@ -2,7 +2,7 @@ require "pathname" module MRuby module Source - # MRuby's source root directory + # mruby's source root directory ROOT = Pathname.new(File.expand_path('../../../',__FILE__)) # Reads a constant defined at version.h @@ -1,2 +1,2 @@ -#! /usr/bin/env ruby +#!/usr/bin/env ruby exec "rake", *ARGV diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb index ecd09aa6e..f7576cbf7 100644 --- a/mrbgems/mruby-array-ext/mrblib/array.rb +++ b/mrbgems/mruby-array-ext/mrblib/array.rb @@ -150,7 +150,7 @@ class Array # [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ] # def &(elem) - raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array + raise TypeError, "cannot convert #{elem.class} into Array" unless elem.class == Array hash = {} array = [] @@ -204,7 +204,7 @@ class Array # a.intersect?(b) #=> true # a.intersect?(c) #=> false def intersect?(ary) - raise TypeError, "can't convert #{ary.class} into Array" unless ary.class == Array + raise TypeError, "cannot convert #{ary.class} into Array" unless ary.class == Array hash = {} if self.length > ary.length @@ -294,41 +294,6 @@ class Array end end - ## - # call-seq: - # ary.compact -> new_ary - # - # Returns a copy of +self+ with all +nil+ elements removed. - # - # [ "a", nil, "b", nil, "c", nil ].compact - # #=> [ "a", "b", "c" ] - # - def compact - result = self.dup - result.compact! - result - end - - ## - # call-seq: - # ary.compact! -> ary or nil - # - # Removes +nil+ elements from the array. - # Returns +nil+ if no changes were made, otherwise returns - # <i>ary</i>. - # - # [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ] - # [ "a", "b", "c" ].compact! #=> nil - # - def compact! - result = self.select { |e| !e.nil? } - if result.size == self.size - nil - else - self.replace(result) - end - end - # for efficiency def reverse_each(&block) return to_enum :reverse_each unless block @@ -421,7 +386,6 @@ class Array end beg = len = 0 - ary = [] if block if arg0.nil? && arg1.nil? && arg2.nil? # ary.fill { |index| block } -> ary @@ -485,57 +449,6 @@ class Array ## # call-seq: - # ary.rotate(count=1) -> new_ary - # - # Returns a new array by rotating +self+ so that the element at +count+ is - # the first element of the new array. - # - # If +count+ is negative then it rotates in the opposite direction, starting - # from the end of +self+ where +-1+ is the last element. - # - # a = [ "a", "b", "c", "d" ] - # a.rotate #=> ["b", "c", "d", "a"] - # a #=> ["a", "b", "c", "d"] - # a.rotate(2) #=> ["c", "d", "a", "b"] - # a.rotate(-3) #=> ["b", "c", "d", "a"] - - def rotate(count=1) - ary = [] - len = self.length - - if len > 0 - idx = (count < 0) ? (len - (~count % len) - 1) : (count % len) # rotate count - len.times do - ary << self[idx] - idx += 1 - idx = 0 if idx > len-1 - end - end - ary - end - - ## - # call-seq: - # ary.rotate!(count=1) -> ary - # - # Rotates +self+ in place so that the element at +count+ comes first, and - # returns +self+. - # - # If +count+ is negative then it rotates in the opposite direction, starting - # from the end of the array where +-1+ is the last element. - # - # a = [ "a", "b", "c", "d" ] - # a.rotate! #=> ["b", "c", "d", "a"] - # a #=> ["b", "c", "d", "a"] - # a.rotate!(2) #=> ["d", "a", "b", "c"] - # a.rotate!(-3) #=> ["a", "b", "c", "d"] - - def rotate!(count=1) - self.replace(self.rotate(count)) - end - - ## - # call-seq: # ary.delete_if { |item| block } -> ary # ary.delete_if -> Enumerator # @@ -746,7 +659,6 @@ class Array return to_enum :keep_if unless block idx = 0 - len = self.size while idx < self.size do if block.call(self[idx]) idx += 1 @@ -961,7 +873,7 @@ class Array # ary.to_h -> Hash # ary.to_h{|item| ... } -> Hash # - # Returns the result of interpreting <i>aray</i> as an array of + # Returns the result of interpreting <i>array</i> as an array of # <tt>[key, value]</tt> pairs. If a block is given, it should # return <tt>[key, value]</tt> pairs to construct a hash. # @@ -984,4 +896,51 @@ class Array alias append push alias prepend unshift alias filter! select! + + ## + # call-seq: + # ary.product(*arys) -> array + # ary.product(*arys) { |item| ... } -> self + def product(*arys, &block) + size = arys.size + i = size + while i > 0 + i -= 1 + unless arys[i].kind_of?(Array) + raise TypeError, "no implicit conversion into Array" + end + end + + i = size + total = self.size + total *= arys[i -= 1].size while i > 0 + + if block + result = self + list = ->(*, e) { block.call e } + class << list; alias []= call; end + else + result = [nil] * total + list = result + end + + i = 0 + while i < total + group = [nil] * (size + 1) + j = size + n = i + while j > 0 + j -= 1 + a = arys[j] + b = a.size + group[j + 1] = a[n % b] + n /= b + end + group[0] = self[n] + list[i] = group + i += 1 + end + + result + end end diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index 8df9d7f30..d97778642 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -95,6 +95,12 @@ mrb_ary_at(mrb_state *mrb, mrb_value ary) } static mrb_value +ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) +{ + return mrb_ary_entry(ary, n); +} + +static mrb_value mrb_ary_values_at(mrb_state *mrb, mrb_value self) { mrb_int argc; @@ -102,10 +108,9 @@ mrb_ary_values_at(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "*", &argv, &argc); - return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, mrb_ary_ref); + return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, ary_ref); } - /* * call-seq: * ary.slice!(index) -> obj or nil @@ -183,6 +188,168 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) return ary; } +/* + * call-seq: + * ary.compact -> new_ary + * + * Returns a copy of +self+ with all +nil+ elements removed. + * + * [ "a", nil, "b", nil, "c", nil ].compact + * #=> [ "a", "b", "c" ] + */ + +static mrb_value +mrb_ary_compact(mrb_state *mrb, mrb_value self) +{ + mrb_value ary = mrb_ary_new(mrb); + mrb_int len = RARRAY_LEN(self); + mrb_value *p = RARRAY_PTR(self); + + for (mrb_int i = 0; i < len; ++i) { + if (!mrb_nil_p(p[i])) { + mrb_ary_push(mrb, ary, p[i]); + } + } + return ary; +} + +/* + * call-seq: + * ary.compact! -> ary or nil + * + * Removes +nil+ elements from the array. + * Returns +nil+ if no changes were made, otherwise returns + * <i>ary</i>. + * + * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ] + * [ "a", "b", "c" ].compact! #=> nil + */ +static mrb_value +mrb_ary_compact_bang(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int i, j = 0; + mrb_int len = ARY_LEN(a); + mrb_value *p = ARY_PTR(a); + + mrb_ary_modify(mrb, a); + for (i = 0; i < len; ++i) { + if (!mrb_nil_p(p[i])) { + if (i != j) p[j] = p[i]; + j++; + } + } + if (i == j) return mrb_nil_value(); + if (j < len) ARY_SET_LEN(RARRAY(self), j); + return self; +} + + +/* + * call-seq: + * ary.rotate(count=1) -> new_ary + * + * Returns a new array by rotating +self+ so that the element at +count+ is + * the first element of the new array. + * + * If +count+ is negative then it rotates in the opposite direction, starting + * from the end of +self+ where +-1+ is the last element. + * + * a = [ "a", "b", "c", "d" ] + * a.rotate #=> ["b", "c", "d", "a"] + * a #=> ["a", "b", "c", "d"] + * a.rotate(2) #=> ["c", "d", "a", "b"] + * a.rotate(-3) #=> ["b", "c", "d", "a"] + */ +static mrb_value +mrb_ary_rotate(mrb_state *mrb, mrb_value self) +{ + mrb_value ary = mrb_ary_new(mrb); + mrb_int len = RARRAY_LEN(self); + mrb_value *p = RARRAY_PTR(self); + mrb_int count=1, idx; + + mrb_get_args(mrb, "|i", &count); + if (len <= 0) return ary; + if (count < 0) { + idx = len - (~count % len) - 1; + } + else { + idx = count % len; + } + for (mrb_int i = 0; i<len; i++) { + mrb_ary_push(mrb, ary, p[idx++]); + if (idx == len) idx = 0; + } + return ary; +} + +static void +rev(mrb_value *p, mrb_int beg, mrb_int end) +{ + for (mrb_int i=beg,j=end-1; i<j; i++,j--) { + mrb_value v = p[i]; + p[i] = p[j]; + p[j] = v; + } +} + +/* + * call-seq: + * ary.rotate!(count=1) -> ary + * + * Rotates +self+ in place so that the element at +count+ comes first, and + * returns +self+. + * + * If +count+ is negative then it rotates in the opposite direction, starting + * from the end of the array where +-1+ is the last element. + * + * a = [ "a", "b", "c", "d" ] + * a.rotate! #=> ["b", "c", "d", "a"] + * a #=> ["b", "c", "d", "a"] + * a.rotate!(2) #=> ["d", "a", "b", "c"] + * a.rotate!(-3) #=> ["a", "b", "c", "d"] + */ +static mrb_value +mrb_ary_rotate_bang(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int len = ARY_LEN(a); + mrb_value *p = ARY_PTR(a); + mrb_int count=1, idx; + + mrb_get_args(mrb, "|i", &count); + mrb_ary_modify(mrb, a); + if (len == 0 || count == 0) return self; + if (count == 1) { + mrb_value v = p[0]; + for (mrb_int i=1; i<len; i++) { + p[i-1] = p[i]; + } + p[len-1] = v; + return self; + } + if (count < 0) { + idx = len - (~count % len) - 1; + } + else { + idx = count % len; + } + /* e.g. [1,2,3,4,5].rotate!(2) -> [3,4,5,1,2] */ + /* first, reverse the whole array */ + /* [1,2,3,4,5] -> [5,4,3,2,1] */ + rev(p, 0, len); + /* then, re-reverse part before idx */ + /* [5,4,3,2,1] -> [3,4,5,2,1] */ + /* ^idx ~~~~~ */ + rev(p, 0, len-idx); + /* finally, re-reverse part after idx */ + /* [3,4,5,2,1] -> [3,4,5,1,2] */ + /* ^idx ~~~ */ + rev(p, len-idx, len); + return self; +} + void mrb_mruby_array_ext_gem_init(mrb_state* mrb) { @@ -192,7 +359,11 @@ mrb_mruby_array_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, a, "at", mrb_ary_at, MRB_ARGS_REQ(1)); mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1)); mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY()); - mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, a, "compact", mrb_ary_compact, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "compact!", mrb_ary_compact_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "rotate", mrb_ary_rotate, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, a, "rotate!", mrb_ary_rotate_bang, MRB_ARGS_OPT(1)); } void diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb index 3f73ad8b9..879980c7e 100644 --- a/mrbgems/mruby-array-ext/test/array.rb +++ b/mrbgems/mruby-array-ext/test/array.rb @@ -421,3 +421,25 @@ assert('Array#transpose') do assert_raise(TypeError) { [1].transpose } assert_raise(IndexError) { [[1], [2,3,4]].transpose } end + +assert "Array#product" do + assert_equal [[1], [2], [3]], [1, 2, 3].product + assert_equal [], [1, 2, 3].product([]) + assert_equal [], [1, 2, 3].product([4, 5, 6], []) + + expect = [[1, 5, 8], [1, 5, 9], [1, 6, 8], [1, 6, 9], [1, 7, 8], [1, 7, 9], + [2, 5, 8], [2, 5, 9], [2, 6, 8], [2, 6, 9], [2, 7, 8], [2, 7, 9], + [3, 5, 8], [3, 5, 9], [3, 6, 8], [3, 6, 9], [3, 7, 8], [3, 7, 9], + [4, 5, 8], [4, 5, 9], [4, 6, 8], [4, 6, 9], [4, 7, 8], [4, 7, 9]] + assert_equal expect, [1, 2, 3, 4].product([5, 6, 7], [8, 9]) + + expect = [[1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 6, 7], [1, 6, 8], [1, 6, 9], + [2, 4, 7], [2, 4, 8], [2, 4, 9], [2, 5, 7], [2, 5, 8], [2, 5, 9], [2, 6, 7], [2, 6, 8], [2, 6, 9], + [3, 4, 7], [3, 4, 8], [3, 4, 9], [3, 5, 7], [3, 5, 8], [3, 5, 9], [3, 6, 7], [3, 6, 8], [3, 6, 9]] + + assert_equal expect, [1, 2, 3].product([4, 5, 6], [7, 8, 9]) + base = [1, 2, 3] + x = [] + assert_equal base, base.product([4, 5, 6], [7, 8, 9]) { |e| x << e } + assert_equal expect, x +end diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index 4d139aa76..55c6cd125 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -14,30 +14,49 @@ #include <mruby/variable.h> #include "mrdberror.h" #include "apibreak.h" +#include "apistring.h" #define MAX_BREAKPOINTNO (MAX_BREAKPOINT * 1024) #define MRB_DEBUG_BP_FILE_OK (0x0001) #define MRB_DEBUG_BP_LINENO_OK (0x0002) +uint32_t mrb_packed_int_decode(uint8_t *p, uint8_t **newpos); + static uint16_t check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno) { uint32_t count = info_file->line_entry_count; uint16_t l_idx; - if (info_file->line_type == mrb_debug_line_ary) { + switch (info_file->line_type) { + case mrb_debug_line_ary: for (l_idx = 0; l_idx < count; ++l_idx) { if (lineno == info_file->lines.ary[l_idx]) { return lineno; } } - } - else { + break; + + case mrb_debug_line_flat_map: for (l_idx = 0; l_idx < count; ++l_idx) { if (lineno == info_file->lines.flat_map[l_idx].line) { return lineno; } } + break; + + case mrb_debug_line_packed_map: + { + uint8_t *p = info_file->lines.packed_map; + uint8_t *pend = p + count; + uint32_t line = 0; + while (p < pend) { + mrb_packed_int_decode(p, &p); + line += mrb_packed_int_decode(p, &p); + if (line == lineno) return lineno; + } + } + break; } return 0; @@ -173,7 +192,6 @@ mrb_debug_set_break_line(mrb_state *mrb, mrb_debug_context *dbg, const char *fil int32_t index; char* set_file; uint16_t result; - size_t len; if ((mrb == NULL)||(dbg == NULL)||(file == NULL)) { return MRB_DEBUG_INVALID_ARGUMENT; @@ -187,7 +205,7 @@ mrb_debug_set_break_line(mrb_state *mrb, mrb_debug_context *dbg, const char *fil return MRB_DEBUG_BREAK_NO_OVER; } - /* file and lineno check (line type mrb_debug_line_ary only.) */ + /* file and lineno check. */ result = check_file_lineno(mrb, dbg->root_irep, file, lineno); if (result == 0) { return MRB_DEBUG_BREAK_INVALID_FILE; @@ -196,8 +214,7 @@ mrb_debug_set_break_line(mrb_state *mrb, mrb_debug_context *dbg, const char *fil return MRB_DEBUG_BREAK_INVALID_LINENO; } - len = strlen(file) + 1; - set_file = (char*)mrb_malloc(mrb, len); + set_file = mrdb_strdup(mrb, file); index = dbg->bpnum; dbg->bp[index].bpno = dbg->next_bpno; @@ -207,8 +224,6 @@ mrb_debug_set_break_line(mrb_state *mrb, mrb_debug_context *dbg, const char *fil dbg->bp[index].point.linepoint.lineno = lineno; dbg->bpnum++; - strncpy(set_file, file, len); - dbg->bp[index].point.linepoint.file = set_file; return dbg->bp[index].bpno; @@ -220,7 +235,6 @@ mrb_debug_set_break_method(mrb_state *mrb, mrb_debug_context *dbg, const char *c int32_t index; char* set_class; char* set_method; - size_t len; if ((mrb == NULL) || (dbg == NULL) || (method_name == NULL)) { return MRB_DEBUG_INVALID_ARGUMENT; @@ -235,18 +249,16 @@ mrb_debug_set_break_method(mrb_state *mrb, mrb_debug_context *dbg, const char *c } if (class_name != NULL) { - len = strlen(class_name) + 1; - set_class = (char*)mrb_malloc(mrb, len); - strncpy(set_class, class_name, len); + set_class = mrdb_strdup(mrb, class_name); } else { set_class = NULL; } - len = strlen(method_name) + 1; - set_method = (char*)mrb_malloc(mrb, len); - - strncpy(set_method, method_name, len); + set_method = mrdb_strdup(mrb, method_name); + if (set_method == NULL) { + mrb_free(mrb, set_class); + } index = dbg->bpnum; dbg->bp[index].bpno = dbg->next_bpno; @@ -332,10 +344,10 @@ mrb_debug_delete_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) for(i = index ; i < dbg->bpnum; i++) { if ((i + 1) == dbg->bpnum) { - memset(&dbg->bp[i], 0, sizeof(mrb_debug_breakpoint)); + dbg->bp[i] = (mrb_debug_breakpoint){0}; } else { - memcpy(&dbg->bp[i], &dbg->bp[i + 1], sizeof(mrb_debug_breakpoint)); + dbg->bp[i] = dbg->bp[i + 1]; } } diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c index 66ddfa783..27db02b48 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c @@ -3,12 +3,12 @@ */ #include <ctype.h> -#include <stdlib.h> #include <string.h> #include "mrdb.h" #include "mrdberror.h" #include "apilist.h" +#include "apistring.h" #include <mruby/compile.h> #include <mruby/irep.h> #include <mruby/debug.h> @@ -65,7 +65,6 @@ dirname(mrb_state *mrb, const char *path) { size_t len; const char *p; - char *dir; if (path == NULL) { return NULL; @@ -74,11 +73,7 @@ dirname(mrb_state *mrb, const char *path) p = strrchr(path, '/'); len = p != NULL ? (size_t)(p - path) : strlen(path); - dir = (char*)mrb_malloc(mrb, len + 1); - strncpy(dir, path, len); - dir[len] = '\0'; - - return dir; + return mrdb_strndup(mrb, path, len); } static source_file* @@ -97,8 +92,11 @@ source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename) } file->lineno = 1; - file->path = (char*)mrb_malloc(mrb, strlen(filename) + 1); - strcpy(file->path, filename); + file->path = mrdb_strdup(mrb, filename); + if (file->path == NULL) { + source_file_free(mrb, file); + return NULL; + } return file; } diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c new file mode 100644 index 000000000..a7b320ade --- /dev/null +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c @@ -0,0 +1,34 @@ +/* +** apistring.c +** +*/ + +#include <string.h> +#include "apistring.h" + +static size_t +mrb_debug_strnlen(const char *s, size_t maxlen) +{ + const char *p = (const char*)memchr(s, '\0', maxlen); + return p != NULL ? (size_t)(p - s) : maxlen; +} + +char* +mrdb_strndup(mrb_state *mrb, const char *s, size_t size) +{ + size_t l = mrb_debug_strnlen(s, size); + char *d = (char*)mrb_malloc_simple(mrb, l + 1); + if (d != NULL) { + memcpy(d, s, l); + d[l] = '\0'; + } + return d; +} + +char* +mrdb_strdup(mrb_state *mrb, const char *s) +{ + size_t z = strlen(s) + 1; + char *d = (char*)mrb_malloc_simple(mrb, z); + return d != NULL ? (char*)memcpy(d, s, z) : NULL; +} diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h b/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h new file mode 100644 index 000000000..33737e7fd --- /dev/null +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h @@ -0,0 +1,14 @@ +/* + * apistring.h + */ + +#ifndef APISTRING_H_ +#define APISTRING_H_ + +#include "mruby.h" + +/* both functions return a null pointer on failure */ +char *mrdb_strndup(mrb_state *mrb, const char *s, size_t size); +char *mrdb_strdup(mrb_state *mrb, const char *s); + +#endif /* APISTRING_H_ */ diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c index a05ff9415..0714f3f21 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c @@ -8,6 +8,7 @@ #include <string.h> #include "apilist.h" +#include "apistring.h" #include <mruby/compile.h> typedef struct help_msg { @@ -140,7 +141,8 @@ static listcmd_parser_state* listcmd_parser_state_new(mrb_state *mrb) { listcmd_parser_state *st = (listcmd_parser_state*)mrb_malloc(mrb, sizeof(listcmd_parser_state)); - memset(st, 0, sizeof(listcmd_parser_state)); + static const listcmd_parser_state st_zero = {0}; + *st = st_zero; return st; } @@ -232,10 +234,7 @@ parse_filename(mrb_state *mrb, char **sp, listcmd_parser_state *st) len = strlen(*sp); } - if (len > 0) { - st->filename = (char*)mrb_malloc(mrb, len + 1); - strncpy(st->filename, *sp, len); - st->filename[len] = '\0'; + if (len > 0 && (st->filename = mrdb_strndup(mrb, *sp, len)) != NULL) { *sp += len; return TRUE; } diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index 009cd955c..ee2ae0aca 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -186,9 +186,9 @@ static mrb_debug_context* mrb_debug_context_new(mrb_state *mrb) { mrb_debug_context *dbg = (mrb_debug_context*)mrb_malloc(mrb, sizeof(mrb_debug_context)); + static const mrb_debug_context dbg_zero = {0}; - memset(dbg, 0, sizeof(mrb_debug_context)); - + *dbg = dbg_zero; dbg->xm = DBG_INIT; dbg->xphase = DBG_PHASE_BEFORE_RUN; dbg->next_bpno = 1; @@ -225,9 +225,9 @@ static mrdb_state* mrdb_state_new(mrb_state *mrb) { mrdb_state *mrdb = (mrdb_state*)mrb_malloc(mrb, sizeof(mrdb_state)); + static const mrdb_state mrdb_zero = {0}; - memset(mrdb, 0, sizeof(mrdb_state)); - + *mrdb = mrdb_zero; mrdb->dbg = mrb_debug_context_get(mrb); mrdb->command = (char*)mrb_malloc(mrb, MAX_COMMAND_LINE+1); mrdb->print_no = 1; @@ -574,7 +574,7 @@ mrb_code_fetch_hook(mrb_state *mrb, const mrb_irep *irep, const mrb_code *pc, mr switch (dbg->xm) { case DBG_STEP: - if (!file || (dbg->prvfile == file && dbg->prvline == line)) { + if (*pc != OP_JMP && (!file || (dbg->prvfile == file && dbg->prvline == line))) { return; } dbg->method_bpno = 0; diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 464df1c24..db92d7266 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -134,7 +134,7 @@ p(mrb_state *mrb, mrb_value obj, int prompt) } /* Guess if the user might want to enter more - * or if he wants an evaluation of his code now */ + * or if they wants an evaluation of their code now */ static mrb_bool is_code_block_open(struct mrb_parser_state *parser) { diff --git a/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb b/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb index f4d9208b3..90bbd123f 100644 --- a/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb +++ b/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb @@ -7,7 +7,7 @@ assert('Compiling multiple files without new line in last line. #2361') do b.write('module B; end') b.flush result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} #{b.path} 2>&1` - assert_equal "#{cmd('mrbc')}:#{a.path}:Syntax OK", result.chomp + assert_equal "#{cmd_bin('mrbc')}:#{a.path}:Syntax OK", result.chomp assert_equal 0, $?.exitstatus end @@ -16,7 +16,7 @@ assert('parsing function with void argument') do a.write('f ()') a.flush result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} 2>&1` - assert_equal "#{cmd('mrbc')}:#{a.path}:Syntax OK", result.chomp + assert_equal "#{cmd_bin('mrbc')}:#{a.path}:Syntax OK", result.chomp assert_equal 0, $?.exitstatus end diff --git a/mrbgems/mruby-bin-mruby/bintest/mruby.rb b/mrbgems/mruby-bin-mruby/bintest/mruby.rb index bc25f18c1..a626a13cd 100644 --- a/mrbgems/mruby-bin-mruby/bintest/mruby.rb +++ b/mrbgems/mruby-bin-mruby/bintest/mruby.rb @@ -2,7 +2,7 @@ require 'tempfile' require 'open3' def assert_mruby(exp_out, exp_err, exp_success, args) - out, err, stat = Open3.capture3(cmd("mruby"), *args) + out, err, stat = Open3.capture3( *(cmd_list("mruby") + args)) assert "assert_mruby" do assert_operator(exp_out, :===, out, "standard output") assert_operator(exp_err, :===, err, "standard error") @@ -87,7 +87,7 @@ assert('mruby -e option (no code specified)') do end assert('mruby -h option') do - assert_mruby(/\AUsage: #{Regexp.escape cmd("mruby")} .*/m, "", true, %w[-h]) + assert_mruby(/\AUsage: #{Regexp.escape cmd_bin("mruby")} .*/m, "", true, %w[-h]) end assert('mruby -r option') do diff --git a/mrbgems/mruby-binding-core/src/binding-core.c b/mrbgems/mruby-binding-core/src/binding-core.c index 1454f5945..5e104e720 100644 --- a/mrbgems/mruby-binding-core/src/binding-core.c +++ b/mrbgems/mruby-binding-core/src/binding-core.c @@ -24,16 +24,16 @@ binding_extract_pc(mrb_state *mrb, mrb_value binding) } } -static const struct RProc * -binding_extract_proc(mrb_state *mrb, mrb_value binding) +const struct RProc * +mrb_binding_extract_proc(mrb_state *mrb, mrb_value binding) { mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); mrb_check_type(mrb, obj, MRB_TT_PROC); return mrb_proc_ptr(obj); } -static struct REnv * -binding_extract_env(mrb_state *mrb, mrb_value binding) +struct REnv * +mrb_binding_extract_env(mrb_state *mrb, mrb_value binding) { mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(env)); if (mrb_nil_p(obj)) { @@ -108,8 +108,8 @@ binding_local_variable_defined_p(mrb_state *mrb, mrb_value self) mrb_sym varname; mrb_get_args(mrb, "n", &varname); - const struct RProc *proc = binding_extract_proc(mrb, self); - struct REnv *env = binding_extract_env(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); if (e) { return mrb_true_value(); @@ -129,8 +129,8 @@ binding_local_variable_get(mrb_state *mrb, mrb_value self) mrb_sym varname; mrb_get_args(mrb, "n", &varname); - const struct RProc *proc = binding_extract_proc(mrb, self); - struct REnv *env = binding_extract_env(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); if (!e) { mrb_raisef(mrb, E_NAME_ERROR, "local variable %!n is not defined", varname); @@ -146,11 +146,14 @@ binding_local_variable_set(mrb_state *mrb, mrb_value self) mrb_value obj; mrb_get_args(mrb, "no", &varname, &obj); - const struct RProc *proc = binding_extract_proc(mrb, self); - struct REnv *env = binding_extract_env(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); if (e) { *e = obj; + if (!mrb_immediate_p(obj)) { + mrb_field_write_barrier(mrb, (struct RBasic*)env, (struct RBasic*)mrb_obj_ptr(obj)); + } } else { mrb_proc_merge_lvar(mrb, (mrb_irep*)proc->body.irep, env, 1, &varname, &obj); @@ -184,7 +187,7 @@ binding_source_location(mrb_state *mrb, mrb_value self) } mrb_value srcloc; - const struct RProc *proc = binding_extract_proc(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); if (!proc || MRB_PROC_CFUNC_P(proc) || !proc->upper || MRB_PROC_CFUNC_P(proc->upper)) { srcloc = mrb_nil_value(); @@ -217,7 +220,7 @@ binding_source_location(mrb_state *mrb, mrb_value self) mrb_value mrb_binding_alloc(mrb_state *mrb) { - struct RObject *obj = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb_class_get_id(mrb, MRB_SYM(Binding))); + struct RObject *obj = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb_class_get_id(mrb, MRB_SYM(Binding))); return mrb_obj_value(obj); } @@ -231,7 +234,7 @@ mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv * static const mrb_code iseq_dummy[] = { OP_RETURN, 0 }; - struct RProc *lvspace = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + struct RProc *lvspace = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class); mrb_irep *irep = mrb_add_irep(mrb); irep->flags = MRB_ISEQ_NO_FREE; irep->iseq = iseq_dummy; @@ -246,7 +249,7 @@ mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv * lvspace->flags |= MRB_PROC_ENVSET; } - *envp = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL); + *envp = MRB_OBJ_ALLOC(mrb, MRB_TT_ENV, NULL); (*envp)->stack = (mrb_value*)mrb_calloc(mrb, 1, sizeof(mrb_value)); (*envp)->stack[0] = lvspace->e.env ? lvspace->e.env->stack[0] : mrb_nil_value(); (*envp)->cxt = lvspace->e.env ? lvspace->e.env->cxt : mrb->c; diff --git a/mrbgems/mruby-binding/mrblib/binding.rb b/mrbgems/mruby-binding/mrblib/binding.rb deleted file mode 100644 index b07480db1..000000000 --- a/mrbgems/mruby-binding/mrblib/binding.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Binding - def eval(expr, *args) - Kernel.eval(expr, self, *args) - end -end diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c new file mode 100644 index 000000000..eb44f0e90 --- /dev/null +++ b/mrbgems/mruby-binding/src/binding.c @@ -0,0 +1,170 @@ +#include <mruby.h> +#include <mruby/array.h> +#include <mruby/class.h> +#include <mruby/compile.h> +#include <mruby/error.h> +#include <mruby/proc.h> +#include <mruby/presym.h> +#include <mruby/string.h> + +mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); +void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); +mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p); +const struct RProc *mrb_binding_extract_proc(mrb_state *mrb, mrb_value binding); +struct REnv *mrb_binding_extract_env(mrb_state *mrb, mrb_value binding); +typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sym, void *user); +void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user); + +static void +binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char *file) +{ + if (!p) { + mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state (out of memory)"); + } + + if (0 < p->nerr) { + mrb_value str; + + if (file) { + str = mrb_format(mrb, "file %s line %d: %s", + file, + p->error_buffer[0].lineno, + p->error_buffer[0].message); + } + else { + str = mrb_format(mrb, "line %d: %s", + p->error_buffer[0].lineno, + p->error_buffer[0].message); + } + mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); + } +} + +#define LV_BUFFERS 8 + +struct expand_lvspace { + mrb_irep *irep; + struct REnv *env; + size_t numvar; + mrb_sym syms[LV_BUFFERS]; +}; + +static mrb_bool +expand_lvspace(mrb_state *mrb, mrb_sym sym, void *user) +{ + struct expand_lvspace *p = (struct expand_lvspace*)user; + mrb_int symlen; + const char *symname = mrb_sym_name_len(mrb, sym, &symlen); + + if (symname && symlen > 0) { + if (symname[0] != '&' && symname[0] != '*') { + p->syms[p->numvar++] = sym; + if (p->numvar >= LV_BUFFERS) { + mrb_proc_merge_lvar(mrb, p->irep, p->env, p->numvar, p->syms, NULL); + p->numvar = 0; + } + } + } + + return TRUE; +} + +struct binding_eval_prepare_body { + mrb_value binding; + const char *file; + const char *expr; + mrb_int exprlen; + mrbc_context *mrbc; + struct mrb_parser_state *pstate; +}; + +static mrb_value +binding_eval_prepare_body(mrb_state *mrb, void *opaque) +{ + struct binding_eval_prepare_body *p = (struct binding_eval_prepare_body*)opaque; + + const struct RProc *proc = mrb_binding_extract_proc(mrb, p->binding); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + + p->mrbc = mrbc_context_new(mrb); + mrbc_filename(mrb, p->mrbc, p->file ? p->file : "(eval)"); + p->mrbc->upper = proc; + p->mrbc->capture_errors = TRUE; + p->pstate = mrb_parse_nstring(mrb, p->expr, p->exprlen, p->mrbc); + binding_eval_error_check(mrb, p->pstate, p->file); + + struct expand_lvspace args = { + (mrb_irep*)proc->body.irep, + mrb_binding_extract_env(mrb, p->binding), + 0, + { 0 } + }; + mrb_parser_foreach_top_variable(mrb, p->pstate, expand_lvspace, &args); + if (args.numvar > 0) { + mrb_proc_merge_lvar(mrb, args.irep, args.env, args.numvar, args.syms, NULL); + } + + return mrb_nil_value(); +} + +static void +binding_eval_prepare(mrb_state *mrb, mrb_value binding) +{ + struct binding_eval_prepare_body d = { binding, NULL, NULL, 0, NULL, NULL }; + mrb_int argc; + mrb_value *argv; + mrb_get_args(mrb, "s|z*!", &d.expr, &d.exprlen, &d.file, &argv, &argc); + + /* `eval` should take (string[, file, line]) */ + if (argc > 3) mrb_argnum_error(mrb, argc, 1, 3); + mrb_bool error; + mrb_value ret = mrb_protect_error(mrb, binding_eval_prepare_body, &d, &error); + if (d.pstate) mrb_parser_free(d.pstate); + if (d.mrbc) mrbc_context_free(mrb, d.mrbc); + if (error) mrb_exc_raise(mrb, ret); +} + +static mrb_value +mrb_binding_eval(mrb_state *mrb, mrb_value binding) +{ + binding_eval_prepare(mrb, binding); + + struct RClass *c = mrb->kernel_module; + mrb_method_t m = mrb_method_search_vm(mrb, &c, MRB_SYM(eval)); + mrb_callinfo *ci = mrb->c->ci; + int argc = ci->n; + mrb_value *argv = ci->stack + 1; + struct RProc *proc; + + if (argc < 15) { + argv[0] = mrb_ary_new_from_values(mrb, argc, argv); + argv[1] = argv[argc]; /* copy block */ + ci->n = 15; + } + if (MRB_METHOD_UNDEF_P(m)) { + mrb_method_missing(mrb, MRB_SYM(eval), binding, argv[0]); + } + + mrb_ary_splice(mrb, argv[0], 1, 0, binding); /* insert binding as 2nd argument */ + if (MRB_METHOD_FUNC_P(m)) { + proc = mrb_proc_new_cfunc(mrb, MRB_METHOD_FUNC(m)); + MRB_PROC_SET_TARGET_CLASS(proc, c); + } + else { + proc = MRB_METHOD_PROC(m); + } + ci->u.target_class = c; + return mrb_exec_irep(mrb, binding, proc); +} + +void +mrb_mruby_binding_gem_init(mrb_state *mrb) +{ + struct RClass *binding = mrb_class_get_id(mrb, MRB_SYM(Binding)); + mrb_define_method(mrb, binding, "eval", mrb_binding_eval, MRB_ARGS_ANY()); +} + +void +mrb_mruby_binding_gem_final(mrb_state *mrb) +{ +} diff --git a/mrbgems/mruby-binding/test/binding.rb b/mrbgems/mruby-binding/test/binding.rb index 7dd3fd1dd..bfae84c59 100644 --- a/mrbgems/mruby-binding/test/binding.rb +++ b/mrbgems/mruby-binding/test/binding.rb @@ -43,13 +43,6 @@ assert("Binding#local_variable_get") do } end -assert("Binding#source_location") do - skip unless -> {}.source_location - - bind, source_location = binding, [__FILE__, __LINE__] - assert_equal source_location, bind.source_location -end - assert "Kernel#binding and .eval from C" do bind = binding_in_c assert_equal 5, bind.eval("2 + 3") @@ -68,3 +61,10 @@ assert "Binding#eval with Binding.new via Method" do assert_true true end + +assert "access local variables into procs" do + bx = binding + block = bx.eval("a = 1; proc { a }") + bx.eval("a = 2") + assert_equal 2, block.call +end diff --git a/mrbgems/mruby-catch/src/catch.c b/mrbgems/mruby-catch/src/catch.c index d54c49dfe..048a44738 100644 --- a/mrbgems/mruby-catch/src/catch.c +++ b/mrbgems/mruby-catch/src/catch.c @@ -92,7 +92,7 @@ mrb_f_throw(mrb_state *mrb, mrb_value self) const mrb_callinfo *ci = find_catcher(mrb, tag); if (ci) { - struct RBreak *b = (struct RBreak *)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL); + struct RBreak *b = MRB_OBJ_ALLOC(mrb, MRB_TT_BREAK, NULL); mrb_break_value_set(b, obj); mrb_break_proc_set(b, ci[2].proc); /* Back to the closure in `catch` method */ mrb_exc_raise(mrb, mrb_obj_value(b)); diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index 39c16fc48..290ddf4b3 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -49,7 +49,7 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "*&!", &argv, &argc, &blk); c = mrb_class_ptr(self); - if (mrb->c->ci->acc < 0) { + if (mrb->c->ci->cci > 0) { return mrb_yield_with_class(mrb, blk, argc, argv, self, c); } mrb_vm_ci_target_class_set(mrb->c->ci, c); diff --git a/mrbgems/mruby-cmath/src/cmath.c b/mrbgems/mruby-cmath/src/cmath.c index 03b181840..8b0c4d04a 100644 --- a/mrbgems/mruby-cmath/src/cmath.c +++ b/mrbgems/mruby-cmath/src/cmath.c @@ -15,7 +15,6 @@ # error CMath conflicts with 'MRB_NO_FLOAT' configuration #endif -#include <math.h> #include <complex.h> mrb_value mrb_complex_new(mrb_state *mrb, mrb_float real, mrb_float imag); diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 12f7c3b3f..7edcd2029 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -4,10 +4,6 @@ ** See Copyright Notice in mruby.h */ -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> #include <mruby.h> #include <mruby/compile.h> #include <mruby/proc.h> @@ -20,9 +16,11 @@ #include <mruby/opcode.h> #include <mruby/re.h> #include <mruby/throw.h> +#include <ctype.h> +#include <string.h> #ifndef MRB_CODEGEN_LEVEL_MAX -#define MRB_CODEGEN_LEVEL_MAX 1024 +#define MRB_CODEGEN_LEVEL_MAX 256 #endif #define MAXARG_S (1<<16) @@ -40,15 +38,16 @@ enum looptype { struct loopinfo { enum looptype type; - uint32_t pc0, pc1, pc2, pc3; - int acc; + uint32_t pc0; /* `next` destination */ + uint32_t pc1; /* `redo` destination */ + uint32_t pc2; /* `break` destination */ + int reg; /* destination register */ struct loopinfo *prev; }; typedef struct scope { mrb_state *mrb; mrb_pool *mpool; - struct mrb_jmpbuf jmp; struct scope *prev; @@ -58,7 +57,7 @@ typedef struct scope { uint32_t pc; uint32_t lastpc; uint32_t lastlabel; - int ainfo:15; + size_t ainfo:15; mrb_bool mscope:1; struct loopinfo *loop; @@ -147,7 +146,7 @@ codegen_error(codegen_scope *s, const char *message) fprintf(stderr, "%s\n", message); } #endif - MRB_THROW(&s->jmp); + MRB_THROW(s->mrb->jmp); } static void* @@ -237,7 +236,9 @@ genop_1(codegen_scope *s, mrb_code i, uint16_t a) { s->lastpc = s->pc; if (a > 0xff) { - codegen_error(s, "too big operand"); + gen_B(s, OP_EXT1); + gen_B(s, i); + gen_S(s, a); } else { gen_B(s, i); @@ -249,30 +250,24 @@ static void genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) { s->lastpc = s->pc; - if (a > 0xff || b > 0xff) { - codegen_error(s, "too big operand"); - } - else { + if (a > 0xff && b > 0xff) { + gen_B(s, OP_EXT3); gen_B(s, i); - gen_B(s, (uint8_t)a); - gen_B(s, (uint8_t)b); - } -} - -/* similar to `genop_2` but generate `genop_2S` with `i+1` */ -/* works for OP_LOADL, OP_LOADSYM, OP_STRING */ -static void -genop_bs(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) -{ - s->lastpc = s->pc; - if (a > 0xff || b > 0xffff) { - codegen_error(s, "too big operand"); + gen_S(s, a); + gen_S(s, b); } - if (b > 0xff) { - gen_B(s, i+1); + else if (b > 0xff) { + gen_B(s, OP_EXT2); + gen_B(s, i); gen_B(s, (uint8_t)a); gen_S(s, b); } + else if (a > 0xff) { + gen_B(s, OP_EXT1); + gen_B(s, i); + gen_S(s, a); + gen_B(s, (uint8_t)b); + } else { gen_B(s, i); gen_B(s, (uint8_t)a); @@ -331,6 +326,8 @@ struct mrb_insn_data mrb_decode_insn(const mrb_code *pc) { struct mrb_insn_data data = { 0 }; + if (pc == 0) return data; + data.addr = pc; mrb_code insn = READ_B(); uint16_t a = 0; uint16_t b = 0; @@ -341,6 +338,32 @@ mrb_decode_insn(const mrb_code *pc) #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x (); break; #include "mruby/ops.h" #undef OPCODE + } + switch (insn) { + case OP_EXT1: + insn = READ_B(); + switch (insn) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); break; +#include "mruby/ops.h" +#undef OPCODE + } + break; + case OP_EXT2: + insn = READ_B(); + switch (insn) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); break; +#include "mruby/ops.h" +#undef OPCODE + } + break; + case OP_EXT3: + insn = READ_B(); + switch (insn) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); break; +#include "mruby/ops.h" +#undef OPCODE + } + break; default: break; } @@ -351,13 +374,101 @@ mrb_decode_insn(const mrb_code *pc) return data; } +#undef OPCODE +#define Z 1 +#define S 3 +#define W 4 +#define OPCODE(_,x) x, +/* instruction sizes */ +static uint8_t mrb_insn_size[] = { +#define B 2 +#define BB 3 +#define BBB 4 +#define BS 4 +#define BSS 6 +#include "mruby/ops.h" +#undef B +#undef BB +#undef BBB +#undef BS +#undef BSS +}; +/* EXT1 instruction sizes */ +static uint8_t mrb_insn_size1[] = { +#define B 3 +#define BB 4 +#define BBB 5 +#define BS 5 +#define BSS 7 +#include "mruby/ops.h" +#undef B +#undef BS +#undef BSS +}; +/* EXT2 instruction sizes */ +static uint8_t mrb_insn_size2[] = { +#define B 2 +#define BS 4 +#define BSS 6 +#include "mruby/ops.h" +#undef B +#undef BB +#undef BBB +#undef BS +#undef BSS +}; +/* EXT3 instruction sizes */ +#define B 3 +#define BB 5 +#define BBB 6 +#define BS 5 +#define BSS 7 +static uint8_t mrb_insn_size3[] = { +#include "mruby/ops.h" +}; +#undef B +#undef BB +#undef BBB +#undef BS +#undef BSS +#undef OPCODE + +static const mrb_code* +mrb_prev_pc(codegen_scope *s, const mrb_code *pc) +{ + const mrb_code *prev_pc = NULL; + const mrb_code *i = s->iseq; + + while (i<pc) { + uint8_t insn = i[0]; + prev_pc = i; + switch (insn) { + case OP_EXT1: + i += mrb_insn_size1[i[1]] + 1; + break; + case OP_EXT2: + i += mrb_insn_size2[i[1]] + 1; + break; + case OP_EXT3: + i += mrb_insn_size3[i[1]] + 1; + break; + default: + i += mrb_insn_size[insn]; + break; + } + } + return prev_pc; +} + +#define pc_addr(s) &((s)->iseq[(s)->pc]) +#define addr_pc(s, addr) (uint32_t)((addr) - s->iseq) +#define rewind_pc(s) s->pc = s->lastpc + static struct mrb_insn_data mrb_last_insn(codegen_scope *s) { - if (s->pc == s->lastpc) { - struct mrb_insn_data data; - - data.insn = OP_NOP; + if (s->pc == 0) { + struct mrb_insn_data data = { OP_NOP, 0 }; return data; } return mrb_decode_insn(&s->iseq[s->lastpc]); @@ -376,17 +487,15 @@ gen_jmpdst(codegen_scope *s, uint32_t pc) { if (pc == JMPLINK_START) { - gen_S(s, 0); + pc = 0; } - else { - uint32_t pos2 = s->pc+2; - int32_t off = pc - pos2; + uint32_t pos2 = s->pc+2; + int32_t off = pc - pos2; - if (off > INT16_MAX || INT16_MIN > off) { - codegen_error(s, "too big jump offset"); - } - gen_S(s, (uint16_t)off); + if (off > INT16_MAX || INT16_MIN > off) { + codegen_error(s, "too big jump offset"); } + gen_S(s, (uint16_t)off); } static uint32_t @@ -394,8 +503,7 @@ genjmp(codegen_scope *s, mrb_code i, uint32_t pc) { uint32_t pos; - s->lastpc = s->pc; - gen_B(s, i); + genop_0(s, i); pos = s->pc; gen_jmpdst(s, pc); return pos; @@ -411,36 +519,64 @@ genjmp2(codegen_scope *s, mrb_code i, uint16_t a, uint32_t pc, int val) if (!no_peephole(s) && !val) { struct mrb_insn_data data = mrb_last_insn(s); - if (data.insn == OP_MOVE && data.a == a) { - s->pc = s->lastpc; - a = data.b; + switch (data.insn) { + case OP_MOVE: + if (data.a == a && data.a > s->nlocals) { + rewind_pc(s); + a = data.b; + } + break; + case OP_LOADNIL: + case OP_LOADF: + if (data.a == a || data.a > s->nlocals) { + s->pc = addr_pc(s, data.addr); + if (i == OP_JMPNOT || (i == OP_JMPNIL && data.insn == OP_LOADNIL)) { + return genjmp(s, OP_JMP, pc); + } + else { /* OP_JMPIF */ + return JMPLINK_START; + } + } + break; + case OP_LOADT: case OP_LOADI: case OP_LOADINEG: case OP_LOADI__1: + case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: + case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: + if (data.a == a || data.a > s->nlocals) { + s->pc = addr_pc(s, data.addr); + if (i == OP_JMPIF) { + return genjmp(s, OP_JMP, pc); + } + else { /* OP_JMPNOT and OP_JMPNIL */ + return JMPLINK_START; + } + } + break; } } - s->lastpc = s->pc; if (a > 0xff) { - codegen_error(s, "too big operand"); - pos = 0; + gen_B(s, OP_EXT1); + genop_0(s, i); + gen_S(s, a); } else { - gen_B(s, i); + genop_0(s, i); gen_B(s, (uint8_t)a); - pos = s->pc; - gen_jmpdst(s, pc); } + pos = s->pc; + gen_jmpdst(s, pc); return pos; } #define genjmp2_0(s,i,a,val) genjmp2(s,i,a,JMPLINK_START,val) +static mrb_bool get_int_operand(codegen_scope *s, struct mrb_insn_data *data, mrb_int *ns); +static void gen_int(codegen_scope *s, uint16_t dst, mrb_int i); + static void gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) { - if (no_peephole(s)) { - normal: - genop_2(s, OP_MOVE, dst, src); - return; - } + if (nopeep || no_peephole(s)) goto normal; else { struct mrb_insn_data data = mrb_last_insn(s); @@ -454,25 +590,104 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) case OP_LOADI__1: case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: - if (nopeep || data.a != src || data.a < s->nlocals) goto normal; - s->pc = s->lastpc; + if (data.a != src || data.a < s->nlocals) goto normal; + rewind_pc(s); genop_1(s, data.insn, dst); - break; + return; + case OP_HASH: case OP_ARRAY: + if (data.b != 0) goto normal; + /* fall through */ case OP_LOADI: case OP_LOADINEG: case OP_LOADL: case OP_LOADSYM: - case OP_LOADL16: case OP_LOADSYM16: case OP_GETGV: case OP_GETSV: case OP_GETIV: case OP_GETCV: - case OP_GETCONST: case OP_STRING: case OP_STRING16: + case OP_GETCONST: case OP_STRING: case OP_LAMBDA: case OP_BLOCK: case OP_METHOD: case OP_BLKPUSH: - case OP_LAMBDA16: case OP_BLOCK16: case OP_METHOD16: - if (nopeep || data.a != src || data.a < s->nlocals) goto normal; - s->pc = s->lastpc; + if (data.a != src || data.a < s->nlocals) goto normal; + rewind_pc(s); genop_2(s, data.insn, dst, data.b); - break; + return; + case OP_LOADI16: + if (data.a != src || data.a < s->nlocals) goto normal; + rewind_pc(s); + genop_2S(s, data.insn, dst, data.b); + return; + case OP_LOADI32: + if (data.a != src || data.a < s->nlocals) goto normal; + else { + uint32_t i = (uint32_t)data.b<<16|data.c; + rewind_pc(s); + genop_2SS(s, data.insn, dst, i); + } + return; + case OP_AREF: + case OP_GETUPVAR: + if (data.a != src || data.a < s->nlocals) goto normal; + rewind_pc(s); + genop_3(s, data.insn, dst, data.b, data.c); + return; + case OP_ADDI: case OP_SUBI: + if (addr_pc(s, data.addr) == s->lastlabel || data.a != src || data.a < s->nlocals) goto normal; + else { + struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr)); + if (data0.insn != OP_MOVE || data0.a != data.a || data0.b != dst) goto normal; + s->pc = addr_pc(s, data0.addr); + if (addr_pc(s, data0.addr) != s->lastlabel) { + /* constant folding */ + data0 = mrb_decode_insn(mrb_prev_pc(s, data0.addr)); + mrb_int n; + if (data0.a == dst && get_int_operand(s, &data0, &n)) { + if ((data.insn == OP_ADDI && !mrb_int_add_overflow(n, data.b, &n)) || + (data.insn == OP_SUBI && !mrb_int_sub_overflow(n, data.b, &n))) { + s->pc = addr_pc(s, data0.addr); + gen_int(s, dst, n); + return; + } + } + } + } + genop_2(s, data.insn, dst, data.b); + return; default: - goto normal; + break; } } + normal: + genop_2(s, OP_MOVE, dst, src); + return; +} + +static int search_upvar(codegen_scope *s, mrb_sym id, int *idx); + +static void +gen_getupvar(codegen_scope *s, uint16_t dst, mrb_sym id) +{ + int idx; + int lv = search_upvar(s, id, &idx); + + if (!no_peephole(s)) { + struct mrb_insn_data data = mrb_last_insn(s); + if (data.insn == OP_SETUPVAR && data.a == dst && data.b == idx && data.c == lv) { + /* skip GETUPVAR right after SETUPVAR */ + return; + } + } + genop_3(s, OP_GETUPVAR, dst, idx, lv); +} + +static void +gen_setupvar(codegen_scope *s, uint16_t dst, mrb_sym id) +{ + int idx; + int lv = search_upvar(s, id, &idx); + + if (!no_peephole(s)) { + struct mrb_insn_data data = mrb_last_insn(s); + if (data.insn == OP_MOVE && data.a == dst) { + dst = data.b; + rewind_pc(s); + } + } + genop_3(s, OP_SETUPVAR, dst, idx, lv); } static void @@ -485,7 +700,7 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src) struct mrb_insn_data data = mrb_last_insn(s); if (data.insn == OP_MOVE && src == data.a) { - s->pc = s->lastpc; + rewind_pc(s); genop_1(s, op, data.b); } else if (data.insn != OP_RETURN) { @@ -494,6 +709,55 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src) } } +static mrb_bool +get_int_operand(codegen_scope *s, struct mrb_insn_data *data, mrb_int *n) +{ + switch (data->insn) { + case OP_LOADI__1: + *n = -1; + return TRUE; + + case OP_LOADINEG: + *n = -data->b; + return TRUE; + + case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: + case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: + *n = data->insn - OP_LOADI_0; + return TRUE; + + case OP_LOADI: + case OP_LOADI16: + *n = data->b; + return TRUE; + + case OP_LOADI32: + *n = (mrb_int)((uint32_t)data->b<<16)+data->c; + return TRUE; + + case OP_LOADL: + { + mrb_pool_value *pv = &s->pool[data->b]; + + if (pv->tt == IREP_TT_INT32) { + *n = (mrb_int)pv->u.i32; + } +#ifdef MRB_INT64 + else if (pv->tt == IREP_TT_INT64) { + *n = (mrb_int)pv->u.i64; + } +#endif + else { + return FALSE; + } + } + return TRUE; + + default: + return FALSE; + } +} + static void gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) { @@ -504,31 +768,123 @@ gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) } else { struct mrb_insn_data data = mrb_last_insn(s); + mrb_int n; - switch (data.insn) { - case OP_LOADI__1: - if (op == OP_ADD) op = OP_SUB; - else op = OP_ADD; - data.b = 1; - goto replace; - case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: - case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: - data.b = data.insn - OP_LOADI_0; - /* fall through */ - case OP_LOADI: - replace: - if (data.b >= 128) goto normal; - s->pc = s->lastpc; + if (!get_int_operand(s, &data, &n)) { + /* not integer immediate */ + goto normal; + } + struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr)); + mrb_int n0; + if (addr_pc(s, data.addr) == s->lastlabel || !get_int_operand(s, &data0, &n0)) { + /* OP_ADDI/OP_SUBI takes upto 16bits */ + if (n > INT16_MAX) goto normal; + rewind_pc(s); if (op == OP_ADD) { - genop_2(s, OP_ADDI, dst, (uint8_t)data.b); + genop_2(s, OP_ADDI, dst, (uint16_t)n); } else { - genop_2(s, OP_SUBI, dst, (uint8_t)data.b); + genop_2(s, OP_SUBI, dst, (uint16_t)n); } - break; - default: + return; + } + if (op == OP_ADD) { + if (mrb_int_add_overflow(n0, n, &n)) goto normal; + } + else { /* OP_SUB */ + if (mrb_int_sub_overflow(n0, n, &n)) goto normal; + } + s->pc = addr_pc(s, data0.addr); + gen_int(s, dst, n); + } +} + +static void +gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst) +{ + if (no_peephole(s)) { + normal: + genop_1(s, op, dst); + return; + } + else { + struct mrb_insn_data data = mrb_last_insn(s); + mrb_int n, n0; + if (addr_pc(s, data.addr) == s->lastlabel || !get_int_operand(s, &data, &n)) { + /* not integer immediate */ + goto normal; + } + struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr)); + if (!get_int_operand(s, &data0, &n0) || n == 0) { goto normal; } + if (op == OP_MUL) { + if (mrb_int_mul_overflow(n0, n, &n)) goto normal; + } + else { /* OP_DIV */ + if (n0 == MRB_INT_MIN && n == -1) goto normal; + n = n0 / n; + } + s->pc = addr_pc(s, data0.addr); + gen_int(s, dst, n); + } +} + +mrb_bool mrb_num_shift(mrb_state *mrb, mrb_int val, mrb_int width, mrb_int *num); + +static mrb_bool +gen_binop(codegen_scope *s, mrb_sym op, uint16_t dst) +{ + if (no_peephole(s)) return FALSE; + else if (op == MRB_OPSYM_2(s->mrb, aref)) { + genop_1(s, OP_GETIDX, dst); + return TRUE; + } + else { + struct mrb_insn_data data = mrb_last_insn(s); + mrb_int n, n0; + if (addr_pc(s, data.addr) == s->lastlabel || !get_int_operand(s, &data, &n)) { + /* not integer immediate */ + return FALSE; + } + struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr)); + if (!get_int_operand(s, &data0, &n0)) { + return FALSE; + } + if (op == MRB_OPSYM_2(s->mrb, lshift)) { + if (!mrb_num_shift(s->mrb, n0, n, &n)) return FALSE; + } + else if (op == MRB_OPSYM_2(s->mrb, rshift)) { + if (n == MRB_INT_MIN) return FALSE; + if (!mrb_num_shift(s->mrb, n0, -n, &n)) return FALSE; + } + else if (op == MRB_OPSYM_2(s->mrb, mod) && n != 0) { + if (n0 == MRB_INT_MIN && n == -1) { + n = 0; + } + else { + mrb_int n1 = n0 % n; + if ((n0 < 0) != (n < 0) && n1 != 0) { + n1 += n; + } + n = n1; + } + } + else if (op == MRB_OPSYM_2(s->mrb, and)) { + n = n0 & n; + } + else if (op == MRB_OPSYM_2(s->mrb, or)) { + n = n0 | n; + } + else if (op == MRB_OPSYM_2(s->mrb, xor)) { + n = n0 ^ n; + } + else { + return FALSE; + } + s->pc = addr_pc(s, data0.addr); + gen_int(s, dst, n); + return TRUE; } } @@ -751,6 +1107,66 @@ new_sym(codegen_scope *s, mrb_sym sym) return s->irep->slen++; } +static void +gen_setxv(codegen_scope *s, uint8_t op, uint16_t dst, mrb_sym sym, int val) +{ + int idx = new_sym(s, sym); + if (!val && !no_peephole(s)) { + struct mrb_insn_data data = mrb_last_insn(s); + if (data.insn == OP_MOVE && data.a == dst) { + dst = data.b; + rewind_pc(s); + } + } + genop_2(s, op, dst, idx); +} + +static void +gen_int(codegen_scope *s, uint16_t dst, mrb_int i) +{ + if (i < 0) { + if (i == -1) genop_1(s, OP_LOADI__1, dst); + else if (i >= -0xff) genop_2(s, OP_LOADINEG, dst, (uint16_t)-i); + else if (i >= INT16_MIN) genop_2S(s, OP_LOADI16, dst, (uint16_t)i); + else if (i >= INT32_MIN) genop_2SS(s, OP_LOADI32, dst, (uint32_t)i); + else goto int_lit; + } + else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, dst); + else if (i <= 0xff) genop_2(s, OP_LOADI, dst, (uint16_t)i); + else if (i <= INT16_MAX) genop_2S(s, OP_LOADI16, dst, (uint16_t)i); + else if (i <= INT32_MAX) genop_2SS(s, OP_LOADI32, dst, (uint32_t)i); + else { + int_lit: + genop_2(s, OP_LOADL, dst, new_lit(s, mrb_int_value(s->mrb, i))); + } +} + +static mrb_bool +gen_uniop(codegen_scope *s, mrb_sym sym, uint16_t dst) +{ + if (no_peephole(s)) return FALSE; + struct mrb_insn_data data = mrb_last_insn(s); + mrb_int n; + + if (!get_int_operand(s, &data, &n)) return FALSE; + if (sym == MRB_OPSYM_2(s->mrb, plus)) { + /* unary plus does nothing */ + } + else if (sym == MRB_OPSYM_2(s->mrb, minus)) { + if (n == MRB_INT_MIN) return FALSE; + n = -n; + } + else if (sym == MRB_OPSYM_2(s->mrb, neg)) { + n = ~n; + } + else { + return FALSE; + } + s->pc = addr_pc(s, data.addr); + gen_int(s, dst, n); + return TRUE; +} + static int node_len(node *tree) { @@ -807,10 +1223,12 @@ search_upvar(codegen_scope *s, mrb_sym id, int *idx) int i; const mrb_sym *v = ir->lv; - for (i=1; n > 1; n--, v++, i++) { - if (*v == id) { - *idx = i; - return lv - 1; + if (v) { + for (i=1; n > 1; n--, v++, i++) { + if (*v == id) { + *idx = i; + return lv - 1; + } } } if (MRB_PROC_SCOPE_P(u)) break; @@ -848,7 +1266,7 @@ for_body(codegen_scope *s, node *tree) } /* construct loop */ lp = loop_push(s, LOOP_FOR); - lp->pc2 = new_label(s); + lp->pc1 = new_label(s); /* loop body */ codegen(s, tree->cdr->cdr->car, VAL); @@ -883,8 +1301,8 @@ lambda_body(codegen_scope *s, node *tree, int blk) } else { mrb_aspec a; - int ma, oa, ra, pa, ka, kd, ba; - int pos, i; + int ma, oa, ra, pa, ka, kd, ba, i; + uint32_t pos; node *opt; node *margs, *pargs; node *tail; @@ -945,8 +1363,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) gen_move(s, idx, cursp(), 0); } else { - int lv = search_upvar(s, id, &idx); - genop_3(s, OP_GETUPVAR, cursp(), idx, lv); + gen_getupvar(s, cursp(), id); } i++; opt = opt->cdr; @@ -984,8 +1401,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) gen_move(s, idx, cursp(), 0); } else { - int lv = search_upvar(s, kwd_sym, &idx); - genop_3(s, OP_GETUPVAR, cursp(), idx, lv); + gen_getupvar(s, cursp(), kwd_sym); } jmp_def_set = genjmp_0(s, OP_JMP); dispatch(s, jmpif_key_p); @@ -1091,80 +1507,149 @@ attrsym(codegen_scope *s, mrb_sym a) return mrb_intern(s->mrb, name2, len+1); } -#define CALL_MAXARGS 127 +#define CALL_MAXARGS 15 +#define GEN_LIT_ARY_MAX 64 +#define GEN_VAL_STACK_MAX 99 static int -gen_values(codegen_scope *s, node *t, int val, int extra) +gen_values(codegen_scope *s, node *t, int val, int extra, int limit) { int n = 0; - int is_splat; + int first = 1; + int slimit = GEN_VAL_STACK_MAX; + + if (limit == 0) limit = GEN_LIT_ARY_MAX; + if (cursp() >= slimit) slimit = INT16_MAX; + + if (!val) { + while (t) { + codegen(s, t->car, NOVAL); + n++; + t = t->cdr; + } + return n; + } while (t) { - is_splat = nint(t->car->car) == NODE_SPLAT; /* splat mode */ - if ( - n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */ - || is_splat) { - if (val) { - if (is_splat && n == 0 && nint(t->car->cdr->car) == NODE_ARRAY) { - codegen(s, t->car->cdr, VAL); - pop(); + int is_splat = nint(t->car->car) == NODE_SPLAT; + + if (is_splat || n+extra >= limit-1 || cursp() >= slimit) { /* flush stack */ + pop_n(n); + if (first) { + if (n == 0) { + genop_1(s, OP_LOADNIL, cursp()); } else { - pop_n(n); - if (n == 0 && is_splat) { - genop_1(s, OP_LOADNIL, cursp()); - } - else { - genop_2(s, OP_ARRAY, cursp(), n); - } - push(); - codegen(s, t->car, VAL); - pop(); pop(); - if (is_splat) { - genop_1(s, OP_ARYCAT, cursp()); - } - else { - genop_1(s, OP_ARYPUSH, cursp()); - } - } - t = t->cdr; - while (t) { - push(); - codegen(s, t->car, VAL); - pop(); pop(); - if (nint(t->car->car) == NODE_SPLAT) { - genop_1(s, OP_ARYCAT, cursp()); - } - else { - genop_1(s, OP_ARYPUSH, cursp()); - } - t = t->cdr; + genop_2(s, OP_ARRAY, cursp(), n); } + push(); + first = 0; + limit = GEN_LIT_ARY_MAX; } - else { - while (t) { - codegen(s, t->car, NOVAL); - t = t->cdr; - } + else if (n > 0) { + pop(); + genop_2(s, OP_ARYPUSH, cursp(), n); + push(); } - return -1; + n = 0; } - /* normal (no splat) mode */ codegen(s, t->car, val); - n++; + if (is_splat) { + pop(); pop(); + genop_1(s, OP_ARYCAT, cursp()); + push(); + } + else { + n++; + } t = t->cdr; } + if (!first) { + pop(); + if (n > 0) { + pop_n(n); + genop_2(s, OP_ARYPUSH, cursp(), n); + } + return -1; /* variable length */ + } return n; } +static int +gen_hash(codegen_scope *s, node *tree, int val, int limit) +{ + int slimit = GEN_VAL_STACK_MAX; + if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX; + int len = 0; + mrb_bool update = FALSE; + + while (tree) { + if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) { + if (len > 0) { + pop_n(len*2); + if (!update) { + genop_2(s, OP_HASH, cursp(), len); + } + else { + pop(); + genop_2(s, OP_HASHADD, cursp(), len); + } + push(); + } + codegen(s, tree->car->cdr, val); + if (len > 0 || update) { + pop(); pop(); + genop_1(s, OP_HASHCAT, cursp()); + push(); + } + update = TRUE; + len = 0; + } + else { + codegen(s, tree->car->car, val); + codegen(s, tree->car->cdr, val); + len++; + } + tree = tree->cdr; + if (val && cursp() >= slimit) { + pop_n(len*2); + if (!update) { + genop_2(s, OP_HASH, cursp(), len); + } + else { + pop(); + genop_2(s, OP_HASHADD, cursp(), len); + } + push(); + update = TRUE; + len = 0; + } + } + if (update) { + if (len > 0) { + pop_n(len*2+1); + genop_2(s, OP_HASHADD, cursp(), len); + push(); + } + return -1; /* variable length */ + } + if (update) return -1; + return len; +} + static void gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) { mrb_sym sym = name ? name : nsym(tree->cdr->car); - int skip = 0; - int n = 0, noop = 0, sendv = 0, blk = 0; + int skip = 0, n = 0, nk = 0, noop = 0, noself = 0, blk = 0, sp_save = cursp(); - codegen(s, tree->car, VAL); /* receiver */ + if (!tree->car) { + noself = noop = 1; + push(); + } + else { + codegen(s, tree->car, VAL); /* receiver */ + } if (safe) { int recv = cursp()-1; gen_move(s, cursp(), recv, 1); @@ -1172,74 +1657,92 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) } tree = tree->cdr->cdr->car; if (tree) { - n = gen_values(s, tree->car, VAL, sp?1:0); - if (n < 0) { - n = noop = sendv = 1; - push(); + if (tree->car) { /* positional arguments */ + n = gen_values(s, tree->car, VAL, sp?1:0, 14); + if (n < 0) { /* variable length */ + noop = 1; /* not operator */ + n = 15; + push(); + } + } + if (tree->cdr->car) { /* keyword arguments */ + noop = 1; + nk = gen_hash(s, tree->cdr->car->cdr, VAL, 14); + if (nk < 0) nk = 15; } } - if (sp) { /* last argument pushed (attr=) */ - if (sendv) { + if (sp) { /* last argument pushed (attr=, []=) */ + /* pack keyword arguments */ + if (nk > 0 && nk < 15) { + pop_n(nk*2); + genop_2(s, OP_HASH, cursp(), nk); + push(); + } + if (n == CALL_MAXARGS) { + if (nk > 0) { + pop(); pop(); + genop_2(s, OP_ARYPUSH, cursp(), 1); + push(); + } gen_move(s, cursp(), sp, 0); pop(); - genop_1(s, OP_ARYPUSH, cursp()); + genop_2(s, OP_ARYPUSH, cursp(), 1); push(); } else { gen_move(s, cursp(), sp, 0); push(); + if (nk > 0) n++; n++; } + nk = 0; } - if (tree && tree->cdr) { - noop = 1; - codegen(s, tree->cdr, VAL); + if (tree && tree->cdr && tree->cdr->cdr) { + codegen(s, tree->cdr->cdr, VAL); pop(); + noop = 1; blk = 1; } push();pop(); - pop_n(n+1); - { - mrb_int symlen; - const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen); - - if (!noop && symlen == 1 && symname[0] == '+' && n == 1) { - gen_addsub(s, OP_ADD, cursp()); - } - else if (!noop && symlen == 1 && symname[0] == '-' && n == 1) { - gen_addsub(s, OP_SUB, cursp()); - } - else if (!noop && symlen == 1 && symname[0] == '*' && n == 1) { - genop_1(s, OP_MUL, cursp()); - } - else if (!noop && symlen == 1 && symname[0] == '/' && n == 1) { - genop_1(s, OP_DIV, cursp()); - } - else if (!noop && symlen == 1 && symname[0] == '<' && n == 1) { - genop_1(s, OP_LT, cursp()); - } - else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1) { - genop_1(s, OP_LE, cursp()); - } - else if (!noop && symlen == 1 && symname[0] == '>' && n == 1) { - genop_1(s, OP_GT, cursp()); - } - else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1) { - genop_1(s, OP_GE, cursp()); - } - else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1) { - genop_1(s, OP_EQ, cursp()); - } - else { - int idx = new_sym(s, sym); - - if (sendv) { - genop_2(s, blk ? OP_SENDVB : OP_SENDV, cursp(), idx); - } - else { - genop_3(s, blk ? OP_SENDB : OP_SEND, cursp(), idx, n); - } - } + s->sp = sp_save; + if (!noop && sym == MRB_OPSYM_2(s->mrb, add) && n == 1) { + gen_addsub(s, OP_ADD, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, sub) && n == 1) { + gen_addsub(s, OP_SUB, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, mul) && n == 1) { + gen_muldiv(s, OP_MUL, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, div) && n == 1) { + gen_muldiv(s, OP_DIV, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, lt) && n == 1) { + genop_1(s, OP_LT, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, le) && n == 1) { + genop_1(s, OP_LE, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, gt) && n == 1) { + genop_1(s, OP_GT, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, ge) && n == 1) { + genop_1(s, OP_GE, cursp()); + } + else if (!noop && sym == MRB_OPSYM_2(s->mrb, eq) && n == 1) { + genop_1(s, OP_EQ, cursp()); + } + else if (!noop && n == 0 && gen_uniop(s, sym, cursp())) { + /* constant folding succeeded */ + } + else if (!noop && n == 1 && gen_binop(s, sym, cursp())) { + /* constant folding succeeded */ + } + else if (noself ){ + genop_3(s, blk ? OP_SSENDB : OP_SSEND, cursp(), new_sym(s, sym), n|(nk<<4)); + } + else { + genop_3(s, blk ? OP_SENDB : OP_SEND, cursp(), new_sym(s, sym), n|(nk<<4)); } if (safe) { dispatch(s, skip); @@ -1258,8 +1761,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) tree = tree->cdr; switch (type) { case NODE_GVAR: - idx = new_sym(s, nsym(tree)); - genop_2(s, OP_SETGV, sp, idx); + gen_setxv(s, OP_SETGV, sp, nsym(tree), val); break; case NODE_ARG: case NODE_LVAR: @@ -1271,8 +1773,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) break; } else { /* upvar */ - int lv = search_upvar(s, nsym(tree), &idx); - genop_3(s, OP_SETUPVAR, sp, idx, lv); + gen_setupvar(s, sp, nsym(tree)); } break; case NODE_NVAR: @@ -1280,16 +1781,13 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) codegen_error(s, "Can't assign to numbered parameter"); break; case NODE_IVAR: - idx = new_sym(s, nsym(tree)); - genop_2(s, OP_SETIV, sp, idx); + gen_setxv(s, OP_SETIV, sp, nsym(tree), val); break; case NODE_CVAR: - idx = new_sym(s, nsym(tree)); - genop_2(s, OP_SETCV, sp, idx); + gen_setxv(s, OP_SETCV, sp, nsym(tree), val); break; case NODE_CONST: - idx = new_sym(s, nsym(tree)); - genop_2(s, OP_SETCONST, sp, idx); + gen_setxv(s, OP_SETCONST, sp, nsym(tree), val); break; case NODE_COLON2: gen_move(s, cursp(), sp, 0); @@ -1320,9 +1818,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) break; default: -#ifndef MRB_NO_STDIO - fprintf(stderr, "unknown lhs %d\n", type); -#endif + codegen_error(s, "unknown lhs"); break; } if (val) push(); @@ -1383,6 +1879,16 @@ static void gen_intern(codegen_scope *s) { pop(); + if (!no_peephole(s)) { + struct mrb_insn_data data = mrb_last_insn(s); + + if (data.insn == OP_STRING && data.a == cursp()) { + rewind_pc(s); + genop_2(s, OP_SYMBOL, data.a, data.b); + push(); + return; + } + } genop_1(s, OP_INTERN, cursp()); push(); } @@ -1391,7 +1897,7 @@ static void gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) { if (val) { - int i = 0, j = 0; + int i = 0, j = 0, gen = 0; while (tree) { switch (nint(tree->car->car)) { @@ -1419,6 +1925,19 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) push(); j--; } + if (i > GEN_LIT_ARY_MAX) { + pop_n(i); + if (gen) { + pop(); + genop_2(s, OP_ARYPUSH, cursp(), i); + } + else { + genop_2(s, OP_ARRAY, cursp(), i); + gen = 1; + } + push(); + i = 0; + } tree = tree->cdr; } if (j > 0) { @@ -1427,7 +1946,13 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) gen_intern(s); } pop_n(i); - genop_2(s, OP_ARRAY, cursp(), i); + if (gen) { + pop(); + genop_2(s, OP_ARYPUSH, cursp(), i); + } + else { + genop_2(s, OP_ARRAY, cursp(), i); + } push(); } else { @@ -1450,45 +1975,48 @@ raise_error(codegen_scope *s, const char *msg) } static mrb_int -readint_mrb_int(codegen_scope *s, const char *p, int base, mrb_bool neg, mrb_bool *overflow) +readint(codegen_scope *s, const char *p, int base, mrb_bool neg, mrb_bool *overflow) { const char *e = p + strlen(p); mrb_int result = 0; - int n; - mrb_assert(base >= 2 && base <= 36); + mrb_assert(base >= 2 && base <= 16); if (*p == '+') p++; while (p < e) { + int n; char c = *p; - c = tolower((unsigned char)c); - for (n=0; n<base; n++) { - if (mrb_digitmap[n] == c) { - break; - } - } - if (n == base) { + switch (c) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + n = c - '0'; break; + case '8': case '9': + n = c - '0'; break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + n = c - 'a' + 10; break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + n = c - 'A' + 10; break; + default: codegen_error(s, "malformed readint input"); - } - - if (neg) { - if ((MRB_INT_MIN + n)/base > result) { - *overflow = TRUE; - return 0; - } - result *= base; - result -= n; - } - else { - if ((MRB_INT_MAX - n)/base < result) { - *overflow = TRUE; - return 0; - } - result *= base; - result += n; - } + *overflow = TRUE; + /* not reached */ + return result; + } + if (mrb_int_mul_overflow(result, base, &result)) { + overflow: + *overflow = TRUE; + return 0; + } + mrb_uint tmp = ((mrb_uint)result)+n; + if (neg && tmp == (mrb_uint)MRB_INT_MAX+1) { + *overflow = FALSE; + return MRB_INT_MIN; + } + if (tmp > MRB_INT_MAX) goto overflow; + result = (mrb_int)tmp; p++; } *overflow = FALSE; + if (neg) return -result; return result; } @@ -1506,6 +2034,49 @@ gen_retval(codegen_scope *s, node *tree) } } +static mrb_bool +true_always(node *tree) +{ + switch (nint(tree->car)) { + case NODE_TRUE: + case NODE_INT: + case NODE_STR: + case NODE_SYM: + return TRUE; + default: + return FALSE; + } +} + +static mrb_bool +false_always(node *tree) +{ + switch (nint(tree->car)) { + case NODE_FALSE: + case NODE_NIL: + return TRUE; + default: + return FALSE; + } +} + +static void +gen_blkmove(codegen_scope *s, int ainfo, int lv) +{ + int m1 = (ainfo>>7)&0x3f; + int r = (ainfo>>6)&0x1; + int m2 = (ainfo>>1)&0x1f; + int kd = (ainfo)&0x1; + int off = m1+r+m2+kd+1; + if (lv == 0) { + gen_move(s, cursp(), off, 0); + } + else { + genop_3(s, OP_GETUPVAR, cursp(), off, lv); + } + push(); +} + static void codegen(codegen_scope *s, node *tree, int val) { @@ -1673,7 +2244,7 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { int idx = lambda_body(s, tree, 1); - genop_bs(s, OP_LAMBDA, cursp(), idx); + genop_2(s, OP_LAMBDA, cursp(), idx); push(); } break; @@ -1682,41 +2253,37 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { int idx = lambda_body(s, tree, 1); - genop_bs(s, OP_BLOCK, cursp(), idx); + genop_2(s, OP_BLOCK, cursp(), idx); push(); } break; case NODE_IF: { - int pos1, pos2, nil_p = FALSE; + uint32_t pos1, pos2; + mrb_bool nil_p = FALSE; node *elsepart = tree->cdr->cdr->car; if (!tree->car) { codegen(s, elsepart, val); goto exit; } - switch (nint(tree->car->car)) { - case NODE_TRUE: - case NODE_INT: - case NODE_STR: + if (true_always(tree->car)) { codegen(s, tree->cdr->car, val); goto exit; - case NODE_FALSE: - case NODE_NIL: + } + if (false_always(tree->car)) { codegen(s, elsepart, val); goto exit; - case NODE_CALL: - { - node *n = tree->car->cdr; - mrb_sym mid = nsym(n->cdr->car); - mrb_sym mnil = MRB_SYM_Q_2(s->mrb, nil); - if (mid == mnil && n->cdr->cdr->car == NULL) { - nil_p = TRUE; - codegen(s, n->car, VAL); - } + } + if (nint(tree->car->car) == NODE_CALL) { + node *n = tree->car->cdr; + mrb_sym mid = nsym(n->cdr->car); + mrb_sym sym_nil_p = MRB_SYM_Q_2(s->mrb, nil); + if (mid == sym_nil_p && n->cdr->cdr->car == NULL) { + nil_p = TRUE; + codegen(s, n->car, VAL); } - break; } if (!nil_p) { codegen(s, tree->car, VAL); @@ -1764,8 +2331,16 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_AND: { - int pos; + uint32_t pos; + if (true_always(tree->car)) { + codegen(s, tree->cdr, val); + goto exit; + } + if (false_always(tree->car)) { + codegen(s, tree->car, val); + goto exit; + } codegen(s, tree->car, VAL); pop(); pos = genjmp2_0(s, OP_JMPNOT, cursp(), val); @@ -1776,8 +2351,16 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_OR: { - int pos; + uint32_t pos; + if (true_always(tree->car)) { + codegen(s, tree->car, val); + goto exit; + } + if (false_always(tree->car)) { + codegen(s, tree->cdr, val); + goto exit; + } codegen(s, tree->car, VAL); pop(); pos = genjmp2_0(s, OP_JMPIF, cursp(), val); @@ -1787,35 +2370,44 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_WHILE: - { - struct loopinfo *lp = loop_push(s, LOOP_NORMAL); - - lp->pc0 = new_label(s); - lp->pc1 = genjmp_0(s, OP_JMP); - lp->pc2 = new_label(s); - codegen(s, tree->cdr, NOVAL); - dispatch(s, lp->pc1); - codegen(s, tree->car, VAL); - pop(); - genjmp2(s, OP_JMPIF, cursp(), lp->pc2, NOVAL); - - loop_pop(s, val); - } - break; - case NODE_UNTIL: { + if (true_always(tree->car)) { + if (nt == NODE_UNTIL) { + if (val) { + genop_1(s, OP_LOADNIL, cursp()); + push(); + } + goto exit; + } + } + else if (false_always(tree->car)) { + if (nt == NODE_WHILE) { + if (val) { + genop_1(s, OP_LOADNIL, cursp()); + push(); + } + goto exit; + } + } + + uint32_t pos = JMPLINK_START; struct loopinfo *lp = loop_push(s, LOOP_NORMAL); + if (!val) lp->reg = -1; lp->pc0 = new_label(s); - lp->pc1 = genjmp_0(s, OP_JMP); - lp->pc2 = new_label(s); - codegen(s, tree->cdr, NOVAL); - dispatch(s, lp->pc1); codegen(s, tree->car, VAL); pop(); - genjmp2(s, OP_JMPNOT, cursp(), lp->pc2, NOVAL); - + if (nt == NODE_WHILE) { + pos = genjmp2_0(s, OP_JMPNOT, cursp(), NOVAL); + } + else { + pos = genjmp2_0(s, OP_JMPIF, cursp(), NOVAL); + } + lp->pc1 = new_label(s); + codegen(s, tree->cdr, NOVAL); + genjmp(s, OP_JMP, lp->pc0); + dispatch(s, pos); loop_pop(s, val); } break; @@ -1948,15 +2540,12 @@ codegen(codegen_scope *s, node *tree, int val) { int n; - n = gen_values(s, tree, val, 0); - if (n >= 0) { - if (val) { + n = gen_values(s, tree, val, 0, 0); + if (val) { + if (n >= 0) { pop_n(n); genop_2(s, OP_ARRAY, cursp(), n); - push(); } - } - else if (val) { push(); } } @@ -1965,62 +2554,10 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_HASH: case NODE_KW_HASH: { - int len = 0; - mrb_bool update = FALSE; - - while (tree) { - if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) { - if (len > 0) { - pop_n(len*2); - if (!update) { - genop_2(s, OP_HASH, cursp(), len); - } - else { - pop(); - genop_2(s, OP_HASHADD, cursp(), len); - } - push(); - } - codegen(s, tree->car->cdr, VAL); - if (len > 0 || update) { - pop(); pop(); - genop_1(s, OP_HASHCAT, cursp()); - push(); - } - update = TRUE; - len = 0; - } - else { - codegen(s, tree->car->car, val); - codegen(s, tree->car->cdr, val); - len++; - } - tree = tree->cdr; - if (val && cursp() > 127) { - pop_n(len*2); - if (!update) { - genop_2(s, OP_HASH, cursp(), len); - } - else { - pop(); - genop_2(s, OP_HASHADD, cursp(), len); - } - push(); - update = TRUE; - len = 0; - } - } - if (val) { - pop_n(len*2); - if (!update) { - genop_2(s, OP_HASH, cursp(), len); - } - else { - pop(); - if (len > 0) { - genop_2(s, OP_HASHADD, cursp(), len); - } - } + int nk = gen_hash(s, tree, val, GEN_LIT_ARY_MAX); + if (val && nk >= 0) { + pop_n(nk*2); + genop_2(s, OP_HASH, cursp(), nk); push(); } } @@ -2156,7 +2693,7 @@ codegen(codegen_scope *s, node *tree, int val) idx = new_sym(s, nsym(n->cdr->car)); base = cursp()-1; if (n->cdr->cdr->car) { - nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1); + nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1, 14); if (nargs >= 0) { callargs = nargs; } @@ -2181,7 +2718,7 @@ codegen(codegen_scope *s, node *tree, int val) if (len == 2 && ((name[0] == '|' && name[1] == '|') || (name[0] == '&' && name[1] == '&'))) { - int pos; + uint32_t pos; pop(); if (val) { @@ -2201,7 +2738,7 @@ codegen(codegen_scope *s, node *tree, int val) if (nint(tree->car->car) == NODE_CALL) { if (callargs == CALL_MAXARGS) { pop(); - genop_1(s, OP_ARYPUSH, cursp()); + genop_2(s, OP_ARYPUSH, cursp(), 1); } else { pop_n(callargs); @@ -2258,7 +2795,7 @@ codegen(codegen_scope *s, node *tree, int val) } if (callargs == CALL_MAXARGS) { pop(); - genop_1(s, OP_ARYPUSH, cursp()); + genop_2(s, OP_ARYPUSH, cursp(), 1); } else { pop_n(callargs); @@ -2275,37 +2812,48 @@ codegen(codegen_scope *s, node *tree, int val) { codegen_scope *s2 = s; int lv = 0; - int n = 0, noop = 0, sendv = 0; + int n = 0, nk = 0, st = 0; - push(); /* room for receiver */ + push(); while (!s2->mscope) { lv++; s2 = s2->prev; if (!s2) break; } - genop_2S(s, OP_ARGARY, cursp(), (lv & 0xf)); - push(); push(); /* ARGARY pushes two values */ - pop(); pop(); if (tree) { node *args = tree->car; if (args) { - n = gen_values(s, args, VAL, 0); + st = n = gen_values(s, args, VAL, 0, 14); if (n < 0) { - n = noop = sendv = 1; + st = 1; n = 15; push(); } } - } - if (tree && tree->cdr) { - codegen(s, tree->cdr, VAL); - pop(); + /* keyword arguments */ + if (s2 && (s2->ainfo & 0x1) && tree->cdr->car) { + nk = gen_hash(s, tree->cdr->car->cdr, VAL, 14); + if (nk < 0) {st++; nk = 15;} + else st += nk; + n |= 15<<4; + } + /* block arguments */ + if (tree->cdr->cdr) { + codegen(s, tree->cdr->cdr, VAL); + } + else if (!s2) {/* super at top-level */ + push(); /* no need to push block */ + } + else { + gen_blkmove(s, s2->ainfo, lv); + } + st++; } else { - genop_1(s, OP_LOADNIL, cursp()); - push(); pop(); + if (!s2) push(); + else gen_blkmove(s, s2->ainfo, lv); + st++; } - pop_n(n+1); - if (sendv) n = CALL_MAXARGS; + pop_n(st+1); genop_2(s, OP_SUPER, cursp(), n); if (val) push(); } @@ -2314,7 +2862,10 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_ZSUPER: { codegen_scope *s2 = s; - int lv = 0, ainfo = 0; + int lv = 0; + size_t ainfo = 0; + int n = CALL_MAXARGS; + int sp = cursp(); push(); /* room for receiver */ while (!s2->mscope) { @@ -2325,14 +2876,33 @@ codegen(codegen_scope *s, node *tree, int val) if (s2 && s2->ainfo > 0) { ainfo = s2->ainfo; } - genop_2S(s, OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)); - push(); push(); pop(); /* ARGARY pushes two values */ - if (tree && tree->cdr) { - codegen(s, tree->cdr, VAL); - pop(); + if (ainfo > 0) { + genop_2S(s, OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)); + push(); push(); push(); /* ARGARY pushes 3 values at most */ + pop(); pop(); pop(); + /* keyword arguments */ + if (ainfo & 0x1) { + n |= CALL_MAXARGS<<4; + push(); + } + /* block argument */ + if (tree && tree->cdr && tree->cdr->cdr) { + push(); + codegen(s, tree->cdr->cdr, VAL); + } } - pop(); pop(); - genop_2(s, OP_SUPER, cursp(), CALL_MAXARGS); + else { + /* block argument */ + if (tree && tree->cdr && tree->cdr->cdr) { + codegen(s, tree->cdr->cdr, VAL); + } + else { + gen_blkmove(s, 0, lv); + } + n = 0; + } + s->sp = sp; + genop_2(s, OP_SUPER, cursp(), n); if (val) push(); } break; @@ -2365,12 +2935,12 @@ codegen(codegen_scope *s, node *tree, int val) if (!s2) break; } if (s2) { - ainfo = s2->ainfo; + ainfo = (int)s2->ainfo; } if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)"); push(); if (tree) { - n = gen_values(s, tree, VAL, 0); + n = gen_values(s, tree, VAL, 0, 14); if (n < 0) { n = sendv = 1; push(); @@ -2416,7 +2986,7 @@ codegen(codegen_scope *s, node *tree, int val) raise_error(s, "unexpected redo"); } else { - genjmp(s, OP_JMPUW, s->loop->pc2); + genjmp(s, OP_JMPUW, s->loop->pc1); } if (val) push(); break; @@ -2447,8 +3017,7 @@ codegen(codegen_scope *s, node *tree, int val) gen_move(s, cursp(), idx, val); } else { - int lv = search_upvar(s, nsym(tree), &idx); - genop_3(s, OP_GETUPVAR, cursp(), idx, lv); + gen_getupvar(s, cursp(), nsym(tree)); } push(); } @@ -2538,29 +3107,13 @@ codegen(codegen_scope *s, node *tree, int val) mrb_int i; mrb_bool overflow; - i = readint_mrb_int(s, p, base, FALSE, &overflow); + i = readint(s, p, base, FALSE, &overflow); if (overflow) { int off = new_litbn(s, p, base, FALSE); - genop_bs(s, OP_LOADL, cursp(), off); + genop_2(s, OP_LOADL, cursp(), off); } else { - if (i < 0) { - if (i == -1) genop_1(s, OP_LOADI__1, cursp()); - else if (i >= -0xff) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); - else if (i >= INT16_MIN) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); - else if (i >= INT32_MIN) genop_2SS(s, OP_LOADI32, cursp(), (uint32_t)i); - else goto lit_int; - } - else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp()); - else if (i <= 0xff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i); - else if (i <= INT16_MAX) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); - else if (i <= INT32_MAX) genop_2SS(s, OP_LOADI32, cursp(), (uint32_t)i); - else { - int off; - lit_int: - off = new_lit(s, mrb_int_value(s->mrb, i)); - genop_bs(s, OP_LOADL, cursp(), off); - } + gen_int(s, cursp(), i); } push(); } @@ -2573,7 +3126,7 @@ codegen(codegen_scope *s, node *tree, int val) mrb_float f = mrb_float_read(p, NULL); int off = new_lit(s, mrb_float_value(s->mrb, f)); - genop_bs(s, OP_LOADL, cursp(), off); + genop_2(s, OP_LOADL, cursp(), off); push(); } break; @@ -2590,7 +3143,7 @@ codegen(codegen_scope *s, node *tree, int val) mrb_float f = mrb_float_read(p, NULL); int off = new_lit(s, mrb_float_value(s->mrb, -f)); - genop_bs(s, OP_LOADL, cursp(), off); + genop_2(s, OP_LOADL, cursp(), off); push(); } break; @@ -2603,26 +3156,13 @@ codegen(codegen_scope *s, node *tree, int val) mrb_int i; mrb_bool overflow; - i = readint_mrb_int(s, p, base, TRUE, &overflow); + i = readint(s, p, base, TRUE, &overflow); if (overflow) { int off = new_litbn(s, p, base, TRUE); - genop_bs(s, OP_LOADL, cursp(), off); + genop_2(s, OP_LOADL, cursp(), off); } else { - if (i == -1) genop_1(s, OP_LOADI__1, cursp()); - else if (i >= -0xff) { - genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); - } - else if (i >= INT16_MIN) { - genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); - } - else if (i >= INT32_MIN) { - genop_2SS(s, OP_LOADI32, cursp(), (uint32_t)i); - } - else { - int off = new_lit(s, mrb_int_value(s->mrb, i)); - genop_bs(s, OP_LOADL, cursp(), off); - } + gen_int(s, cursp(), i); } push(); } @@ -2630,10 +3170,13 @@ codegen(codegen_scope *s, node *tree, int val) default: if (val) { - int sym = new_sym(s, MRB_OPSYM_2(s->mrb, minus)); codegen(s, tree, VAL); pop(); - genop_3(s, OP_SEND, cursp(), sym, 0); + push_n(2);pop_n(2); /* space for receiver&block */ + mrb_sym minus = MRB_OPSYM_2(s->mrb, minus); + if (!gen_uniop(s, minus, cursp())) { + genop_3(s, OP_SEND, cursp(), new_sym(s, minus), 0); + } push(); } else { @@ -2652,7 +3195,7 @@ codegen(codegen_scope *s, node *tree, int val) int off = new_lit(s, mrb_str_new(s->mrb, p, len)); mrb_gc_arena_restore(s->mrb, ai); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); push(); } break; @@ -2739,7 +3282,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_1(s, OP_LOADSELF, cursp()); push(); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); push(); push(); pop_n(3); sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */ @@ -2762,12 +3305,12 @@ codegen(codegen_scope *s, node *tree, int val) genop_1(s, OP_OCLASS, cursp()); genop_2(s, OP_GETMCNST, cursp(), sym); push(); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); push(); if (p2 || p3) { if (p2) { /* opt */ off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); } else { genop_1(s, OP_LOADNIL, cursp()); @@ -2776,7 +3319,7 @@ codegen(codegen_scope *s, node *tree, int val) argc++; if (p3) { /* enc */ off = new_lit(s, mrb_str_new(s->mrb, p3, 1)); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); push(); argc++; } @@ -2816,7 +3359,7 @@ codegen(codegen_scope *s, node *tree, int val) p = (char*)n->car; off = new_lit(s, mrb_str_new_cstr(s->mrb, p)); codegen(s, tree->car, VAL); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); pop(); genop_1(s, OP_STRCAT, cursp()); push(); @@ -2824,14 +3367,14 @@ codegen(codegen_scope *s, node *tree, int val) if (n->cdr->car) { /* opt */ char *p2 = (char*)n->cdr->car; off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); push(); argc++; } if (n->cdr->cdr) { /* enc */ char *p2 = (char*)n->cdr->cdr; off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); - genop_bs(s, OP_STRING, cursp(), off); + genop_2(s, OP_STRING, cursp(), off); push(); argc++; } @@ -2858,7 +3401,7 @@ codegen(codegen_scope *s, node *tree, int val) if (val) { int sym = new_sym(s, nsym(tree)); - genop_bs(s, OP_LOADSYM, cursp(), sym); + genop_2(s, OP_LOADSYM, cursp(), sym); push(); } break; @@ -2959,7 +3502,7 @@ codegen(codegen_scope *s, node *tree, int val) } else { idx = scope_body(s, body, val); - genop_bs(s, OP_EXEC, cursp(), idx); + genop_2(s, OP_EXEC, cursp(), idx); } if (val) { push(); @@ -2991,7 +3534,7 @@ codegen(codegen_scope *s, node *tree, int val) } else { idx = scope_body(s, tree->cdr->car, val); - genop_bs(s, OP_EXEC, cursp(), idx); + genop_2(s, OP_EXEC, cursp(), idx); } if (val) { push(); @@ -3012,7 +3555,7 @@ codegen(codegen_scope *s, node *tree, int val) } else { idx = scope_body(s, tree->cdr->car, val); - genop_bs(s, OP_EXEC, cursp(), idx); + genop_2(s, OP_EXEC, cursp(), idx); } if (val) { push(); @@ -3027,14 +3570,11 @@ codegen(codegen_scope *s, node *tree, int val) genop_1(s, OP_TCLASS, cursp()); push(); - genop_bs(s, OP_METHOD, cursp(), idx); + genop_2(s, OP_METHOD, cursp(), idx); push(); pop(); pop(); genop_2(s, OP_DEF, cursp(), sym); - if (val) { - genop_bs(s, OP_LOADSYM, cursp(), sym); - push(); - } + if (val) push(); } break; @@ -3048,13 +3588,10 @@ codegen(codegen_scope *s, node *tree, int val) pop(); genop_1(s, OP_SCLASS, cursp()); push(); - genop_bs(s, OP_METHOD, cursp(), idx); + genop_2(s, OP_METHOD, cursp(), idx); pop(); genop_2(s, OP_DEF, cursp(), sym); - if (val) { - genop_bs(s, OP_LOADSYM, cursp(), sym); - push(); - } + if (val) push(); } break; @@ -3111,7 +3648,7 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *nlv) s->mpool = pool; if (!prev) return s; s->prev = prev; - s->ainfo = -1; + s->ainfo = 0; s->mscope = 0; scope_add_irep(s); @@ -3214,9 +3751,9 @@ loop_push(codegen_scope *s, enum looptype t) struct loopinfo *p = (struct loopinfo *)codegen_palloc(s, sizeof(struct loopinfo)); p->type = t; - p->pc0 = p->pc1 = p->pc2 = p->pc3 = JMPLINK_START; + p->pc0 = p->pc1 = p->pc2 = JMPLINK_START; p->prev = s->loop; - p->acc = cursp(); + p->reg = cursp(); s->loop = p; return p; @@ -3232,11 +3769,16 @@ loop_break(codegen_scope *s, node *tree) else { struct loopinfo *loop; - if (tree) { - gen_retval(s, tree); - } loop = s->loop; + if (tree) { + if (loop->reg < 0) { + codegen(s, tree, NOVAL); + } + else { + gen_retval(s, tree); + } + } while (loop) { if (loop->type == LOOP_BEGIN) { loop = loop->prev; @@ -3256,11 +3798,16 @@ loop_break(codegen_scope *s, node *tree) if (loop->type == LOOP_NORMAL) { int tmp; - if (tree) { - gen_move(s, loop->acc, cursp(), 0); + if (loop->reg >= 0) { + if (tree) { + gen_move(s, loop->reg, cursp(), 0); + } + else { + genop_1(s, OP_LOADNIL, loop->reg); + } } - tmp = genjmp(s, OP_JMPUW, loop->pc3); - loop->pc3 = tmp; + tmp = genjmp(s, OP_JMPUW, loop->pc2); + loop->pc2 = tmp; } else { if (!tree) { @@ -3277,7 +3824,7 @@ loop_pop(codegen_scope *s, int val) if (val) { genop_1(s, OP_LOADNIL, cursp()); } - dispatch_linked(s, s->loop->pc3); + dispatch_linked(s, s->loop->pc2); s->loop = s->loop->prev; if (val) push(); } @@ -3308,16 +3855,18 @@ static struct RProc* generate_code(mrb_state *mrb, parser_state *p, int val) { codegen_scope *scope = scope_new(mrb, 0, 0); - struct RProc *proc; struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf jmpbuf; + struct RProc *proc; + + mrb->jmp = &jmpbuf; scope->mrb = mrb; scope->parser = p; scope->filename_sym = p->filename_sym; scope->filename_index = p->current_filename_index; - MRB_TRY(&scope->jmp) { - mrb->jmp = &scope->jmp; + MRB_TRY(mrb->jmp) { /* prepare irep */ codegen(scope, p->tree, val); proc = mrb_proc_new(mrb, scope->irep); @@ -3330,13 +3879,13 @@ generate_code(mrb_state *mrb, parser_state *p, int val) mrb->jmp = prev_jmp; return proc; } - MRB_CATCH(&scope->jmp) { + MRB_CATCH(mrb->jmp) { mrb_irep_decref(mrb, scope->irep); mrb_pool_close(scope->mpool); mrb->jmp = prev_jmp; return NULL; } - MRB_END_EXC(&scope->jmp); + MRB_END_EXC(mrb->jmp); } MRB_API struct RProc* @@ -3360,26 +3909,3 @@ mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep) mrb_irep_remove_lv(mrb, (mrb_irep*)irep->reps[i]); } } - -#undef OPCODE -#define Z 1 -#define S 3 -#define W 4 -/* instruction sizes */ -uint8_t mrb_insn_size[] = { -#define B 2 -#define BB 3 -#define BBB 4 -#define BS 4 -#define BSS 6 -#define SB 4 -#define OPCODE(_,x) x, -#include "mruby/ops.h" -#undef OPCODE -#undef B -#undef BB -#undef BS -#undef BSS -#undef SB -#undef BBB -}; diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 2c2bff714..ed4265a16 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -13,7 +13,6 @@ #include <ctype.h> #include <errno.h> -#include <stdlib.h> #include <string.h> #include <mruby.h> #include <mruby/compile.h> @@ -34,7 +33,6 @@ typedef struct mrb_parser_heredoc_info parser_heredoc_info; static int yyparse(parser_state *p); static int yylex(void *lval, parser_state *p); static void yyerror(parser_state *p, const char *s); -static void yywarn(parser_state *p, const char *s); static void yywarning(parser_state *p, const char *s); static void backref_error(parser_state *p, node *n); static void void_expr_error(parser_state *p, node *n); @@ -106,7 +104,7 @@ parser_palloc(parser_state *p, size_t size) void *m = mrb_pool_alloc(p->pool, size); if (!m) { - MRB_THROW(p->jmp); + MRB_THROW(p->mrb->jmp); } return m; } @@ -286,9 +284,10 @@ local_var_p(parser_state *p, mrb_sym sym) const mrb_sym *v = ir->lv; int i; - if (!v) break; - for (i=0; i+1 < ir->nlocals; i++) { - if (v[i] == sym) return TRUE; + if (v) { + for (i=0; i+1 < ir->nlocals; i++) { + if (v[i] == sym) return TRUE; + } } if (MRB_PROC_SCOPE_P(u)) break; u = u->upper; @@ -500,13 +499,18 @@ new_call(parser_state *p, node *a, mrb_sym b, node *c, int pass) static node* new_fcall(parser_state *p, mrb_sym b, node *c) { - node *n = new_self(p); - NODE_LINENO(n, c); - n = list4((node*)NODE_FCALL, n, nsym(b), c); + node *n = list4((node*)NODE_FCALL, 0, nsym(b), c); NODE_LINENO(n, c); return n; } +/* (a b . c) */ +static node* +new_callargs(parser_state *p, node *a, node *b, node *c) +{ + return cons(a, cons(b, c)); +} + /* (:super . c) */ static node* new_super(parser_state *p, node *c) @@ -518,7 +522,7 @@ new_super(parser_state *p, node *c) static node* new_zsuper(parser_state *p) { - return list1((node*)NODE_ZSUPER); + return cons((node*)NODE_ZSUPER, 0); } /* (:yield . c) */ @@ -527,7 +531,12 @@ new_yield(parser_state *p, node *c) { if (c) { if (c->cdr) { - yyerror(p, "both block arg and actual block given"); + if (c->cdr->cdr) { + yyerror(p, "both block arg and actual block given"); + } + if (c->cdr->car) { + return cons((node*)NODE_YIELD, push(c->car, c->cdr->car)); + } } return cons((node*)NODE_YIELD, c->car); } @@ -961,13 +970,14 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b) static node* new_imaginary(parser_state *p, node *imaginary) { - return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), + new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1); } static node* new_rational(parser_state *p, node *rational) { - return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), list1(list1(rational)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), 1); } /* (:int . i) */ @@ -1190,17 +1200,17 @@ call_uni_op(parser_state *p, node *recv, const char *m) static node* call_bin_op(parser_state *p, node *recv, const char *m, node *arg1) { - return new_call(p, recv, intern_cstr(m), list1(list1(arg1)), 1); + return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1); } static void args_with_block(parser_state *p, node *a, node *b) { if (b) { - if (a->cdr) { + if (a->cdr && a->cdr->cdr) { yyerror(p, "both block arg and actual block given"); } - a->cdr = b; + a->cdr->cdr = b; } } @@ -1227,19 +1237,16 @@ call_with_block(parser_state *p, node *a, node *b) switch (typen(a->car)) { case NODE_SUPER: case NODE_ZSUPER: - if (!a->cdr) a->cdr = cons(0, b); - else { - args_with_block(p, a->cdr, b); - } + if (!a->cdr) a->cdr = new_callargs(p, 0, 0, b); + else args_with_block(p, a->cdr, b); break; case NODE_CALL: case NODE_FCALL: case NODE_SCALL: - n = a->cdr->cdr->cdr; - if (!n->car) n->car = cons(0, b); - else { - args_with_block(p, n->car, b); - } + /* (NODE_CALL recv mid (args kw . blk)) */ + n = a->cdr->cdr->cdr; /* (args kw . blk) */ + if (!n->car) n->car = new_callargs(p, 0, 0, b); + else args_with_block(p, n->car, b); break; default: break; @@ -1247,7 +1254,7 @@ call_with_block(parser_state *p, node *a, node *b) } static node* -negate_lit(parser_state *p, node *n) +new_negate(parser_state *p, node *n) { return cons((node*)NODE_NEGATE, n); } @@ -1261,10 +1268,11 @@ cond(node *n) static node* ret_args(parser_state *p, node *n) { - if (n->cdr) { + if (n->cdr->cdr) { yyerror(p, "block argument should not be given"); return NULL; } + if (!n->car) return NULL; if (!n->car->cdr) return n->car->car; return new_array(p, n->car); } @@ -1293,6 +1301,24 @@ var_reference(parser_state *p, node *lhs) return lhs; } +static node* +label_reference(parser_state *p, mrb_sym sym) +{ + const char *name = mrb_sym_name(p->mrb, sym); + node *n; + + if (local_var_p(p, sym)) { + n = new_lvar(p, sym); + } + else if (ISUPPER(name[0])) { + n = new_const(p, sym); + } + else { + n = new_fcall(p, sym, 0); + } + return n; +} + typedef enum mrb_string_type string_type; static node* @@ -1623,7 +1649,7 @@ bodystmt : compstmt NODE_LINENO($$, $1); } else if ($3) { - yywarn(p, "else without rescue is useless"); + yywarning(p, "else without rescue is useless"); $$ = push($1, $3); } else { @@ -1754,6 +1780,44 @@ command_asgn : lhs '=' command_rhs { $$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5); } + | defn_head f_opt_arglist_paren '=' command + { + $$ = $1; + endless_method_name(p, $1); + void_expr_error(p, $4); + defn_setup(p, $$, $2, $4); + nvars_unnest(p); + p->in_def--; + } + | defn_head f_opt_arglist_paren '=' command modifier_rescue arg + { + $$ = $1; + endless_method_name(p, $1); + void_expr_error(p, $4); + void_expr_error(p, $6); + defn_setup(p, $$, $2, new_mod_rescue(p, $4, $6)); + nvars_unnest(p); + p->in_def--; + } + | defs_head f_opt_arglist_paren '=' command + { + $$ = $1; + void_expr_error(p, $4); + defs_setup(p, $$, $2, $4); + nvars_unnest(p); + p->in_def--; + p->in_single--; + } + | defs_head f_opt_arglist_paren '=' command modifier_rescue arg + { + $$ = $1; + void_expr_error(p, $4); + void_expr_error(p, $6); + defs_setup(p, $$, $2, new_mod_rescue(p, $4, $6)); + nvars_unnest(p); + p->in_def--; + p->in_single--; + } | backref tOP_ASGN command_rhs { backref_error(p, $1); @@ -2253,11 +2317,11 @@ arg : lhs '=' arg_rhs } | tUMINUS_NUM tINTEGER tPOW arg { - $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@"); + $$ = new_negate(p, call_bin_op(p, $2, "**", $4)); } | tUMINUS_NUM tFLOAT tPOW arg { - $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@"); + $$ = new_negate(p, call_bin_op(p, $2, "**", $4)); } | tUPLUS arg { @@ -2265,7 +2329,7 @@ arg : lhs '=' arg_rhs } | tUMINUS arg { - $$ = call_uni_op(p, $2, "-@"); + $$ = new_negate(p, $2); } | arg '|' arg { @@ -2370,7 +2434,7 @@ arg : lhs '=' arg_rhs nvars_unnest(p); p->in_def--; } - | defs_head f_arglist_paren '=' arg + | defs_head f_opt_arglist_paren '=' arg { $$ = $1; void_expr_error(p, $4); @@ -2379,7 +2443,7 @@ arg : lhs '=' arg_rhs p->in_def--; p->in_single--; } - | defs_head f_arglist_paren '=' arg modifier_rescue arg + | defs_head f_opt_arglist_paren '=' arg modifier_rescue arg { $$ = $1; void_expr_error(p, $4); @@ -2403,7 +2467,7 @@ aref_args : none } | args comma assocs trailer { - $$ = push($1, new_kw_hash(p, $3)); + $$ = push($1, new_hash(p, $3)); } | assocs trailer { @@ -2430,39 +2494,23 @@ paren_args : '(' opt_call_args ')' } | '(' args comma tBDOT3 rparen { -#if 1 - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - $$ = cons(push($2, new_splat(p, new_lvar(p, r))), - new_block_arg(p, new_lvar(p, b))); -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); - $$ = cons(list2(push($2, new_splat(p, new_lvar(p, r))), - new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), - new_block_arg(p, new_lvar(p, b))); -#endif + $$ = new_callargs(p, push($2, new_splat(p, new_lvar(p, r))), + new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))), + new_block_arg(p, new_lvar(p, b))); } | '(' tBDOT3 rparen { -#if 1 - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - if (local_var_p(p, r) && local_var_p(p, b)) { - $$ = cons(list1(new_splat(p, new_lvar(p, r))), - new_block_arg(p, new_lvar(p, b))); - } -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) { - $$ = cons(list2(new_splat(p, new_lvar(p, r)), - new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), - new_block_arg(p, new_lvar(p, b))); + $$ = new_callargs(p, list1(new_splat(p, new_lvar(p, r))), + new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))), + new_block_arg(p, new_lvar(p, b))); } -#endif else { yyerror(p, "unexpected argument forwarding ..."); $$ = 0; @@ -2478,17 +2526,17 @@ opt_call_args : none | call_args opt_terms | args comma { - $$ = cons($1,0); + $$ = new_callargs(p,$1,0,0); NODE_LINENO($$, $1); } | args comma assocs comma { - $$ = cons(push($1, new_kw_hash(p, $3)), 0); + $$ = new_callargs(p,$1,new_kw_hash(p,$3),0); NODE_LINENO($$, $1); } | assocs comma { - $$ = cons(list1(new_kw_hash(p, $1)), 0); + $$ = new_callargs(p,0,new_kw_hash(p,$1),0); NODE_LINENO($$, $1); } ; @@ -2496,27 +2544,27 @@ opt_call_args : none call_args : command { void_expr_error(p, $1); - $$ = cons(list1($1), 0); + $$ = new_callargs(p, list1($1), 0, 0); NODE_LINENO($$, $1); } | args opt_block_arg { - $$ = cons($1, $2); + $$ = new_callargs(p, $1, 0, $2); NODE_LINENO($$, $1); } | assocs opt_block_arg { - $$ = cons(list1(new_kw_hash(p, $1)), $2); + $$ = new_callargs(p, 0, new_kw_hash(p, $1), $2); NODE_LINENO($$, $1); } | args comma assocs opt_block_arg { - $$ = cons(push($1, new_kw_hash(p, $3)), $4); + $$ = new_callargs(p, $1, new_kw_hash(p, $3), $4); NODE_LINENO($$, $1); } | block_arg { - $$ = cons(0, $1); + $$ = new_callargs(p, 0, 0, $1); NODE_LINENO($$, $1); } ; @@ -2548,20 +2596,19 @@ opt_block_arg : comma block_arg } ; -comma : ',' - | ',' opt_nl heredoc_bodies +comma : ',' opt_nl ; args : arg { void_expr_error(p, $1); - $$ = cons($1, 0); + $$ = list1($1); NODE_LINENO($$, $1); } | tSTAR arg { void_expr_error(p, $2); - $$ = cons(new_splat(p, $2), 0); + $$ = list1(new_splat(p, $2)); NODE_LINENO($$, $2); } | args comma arg @@ -2673,7 +2720,7 @@ primary : literal } | operation brace_block { - $$ = new_fcall(p, $1, cons(0, $2)); + $$ = new_fcall(p, $1, new_callargs(p, 0, 0, $2)); } | method_call | method_call brace_block @@ -3268,7 +3315,14 @@ string_fragment : tCHAR } | tSTRING_BEG string_rep tSTRING { - $$ = new_dstr(p, push($2, $3)); + node *n = $2; + if (intn($3->cdr->cdr) > 0) { + n = push(n, $3); + } + else { + cons_free($3); + } + $$ = new_dstr(p, n); } ; @@ -3310,7 +3364,14 @@ xstring : tXSTRING_BEG tXSTRING } | tXSTRING_BEG string_rep tXSTRING { - $$ = new_dxstr(p, push($2, $3)); + node *n = $2; + if (intn($3->cdr->cdr) > 0) { + n = push(n, $3); + } + else { + cons_free($3); + } + $$ = new_dxstr(p, n); } ; @@ -3373,7 +3434,14 @@ words : tWORDS_BEG tSTRING } | tWORDS_BEG string_rep tSTRING { - $$ = new_words(p, push($2, $3)); + node *n = $2; + if (intn($3->cdr->cdr) > 0) { + n = push(n, $3); + } + else { + cons_free($3); + } + $$ = new_words(p, n); } ; @@ -3385,8 +3453,15 @@ symbol : basic_symbol } | tSYMBEG tSTRING_BEG string_rep tSTRING { + node *n = $3; p->lstate = EXPR_ENDARG; - $$ = new_dsym(p, new_dstr(p, push($3, $4))); + if (intn($4->cdr->cdr) > 0) { + n = push(n, $4); + } + else { + cons_free($4); + } + $$ = new_dsym(p, new_dstr(p, n)); } ; @@ -3416,7 +3491,11 @@ symbols : tSYMBOLS_BEG tSTRING } | tSYMBOLS_BEG string_rep tSTRING { - $$ = new_symbols(p, push($2, $3)); + node *n = $2; + if (intn($3->cdr->cdr) > 0) { + n = push(n, $3); + } + $$ = new_symbols(p, n); } ; @@ -3424,11 +3503,11 @@ numeric : tINTEGER | tFLOAT | tUMINUS_NUM tINTEGER %prec tLOWEST { - $$ = negate_lit(p, $2); + $$ = new_negate(p, $2); } | tUMINUS_NUM tFLOAT %prec tLOWEST { - $$ = negate_lit(p, $2); + $$ = new_negate(p, $2); } ; @@ -3501,12 +3580,7 @@ var_ref : variable } | keyword__ENCODING__ { -#ifdef MRB_UTF8_STRING - const char *enc = "UTF-8"; -#else - const char *enc = "ASCII-8BIT"; -#endif - $$ = new_str(p, enc, strlen(enc)); + $$ = new_fcall(p, MRB_SYM_2(p->mrb, __ENCODING__), 0); } ; @@ -3547,39 +3621,21 @@ f_arglist_paren : '(' f_args rparen } | '(' f_arg ',' tBDOT3 rparen { -#if 1 - /* til real keyword args implemented */ - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - local_add_f(p, r); - $$ = new_args(p, $2, 0, r, 0, - new_args_tail(p, 0, 0, b)); -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); - local_add_f(p, r); local_add_f(p, k); + local_add_f(p, r); $$ = new_args(p, $2, 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); -#endif } | '(' tBDOT3 rparen { -#if 1 - /* til real keyword args implemented */ - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - local_add_f(p, r); - $$ = new_args(p, 0, 0, r, 0, - new_args_tail(p, 0, 0, b)); -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); - local_add_f(p, r); local_add_f(p, k); + local_add_f(p, r); $$ = new_args(p, 0, 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); -#endif } ; @@ -3938,22 +3994,22 @@ assocs : assoc } ; -label_tag : tLABEL_TAG - | tLABEL_TAG heredoc_bodies - ; - assoc : arg tASSOC arg { void_expr_error(p, $1); void_expr_error(p, $3); $$ = cons($1, $3); } - | tIDENTIFIER label_tag arg + | tIDENTIFIER tLABEL_TAG arg { void_expr_error(p, $3); $$ = cons(new_sym(p, $1), $3); } - | string_fragment label_tag arg + | tIDENTIFIER tLABEL_TAG + { + $$ = cons(new_sym(p, $1), label_reference(p, $1)); + } + | string_fragment tLABEL_TAG arg { void_expr_error(p, $3); if (typen($1->car) == NODE_DSTR) { @@ -4012,7 +4068,7 @@ opt_terms : /* none */ ; opt_nl : /* none */ - | nl + | opt_nl nl ; rparen : opt_terms ')' @@ -4025,7 +4081,6 @@ trailer : /* none */ term : ';' {yyerrok;} | nl - | heredoc_body ; nl : '\n' @@ -4033,6 +4088,7 @@ nl : '\n' p->lineno += $<num>1; p->column = 0; } + | heredoc_body ; terms : term @@ -4087,7 +4143,7 @@ yyerror_c(parser_state *p, const char *msg, char c) } static void -yywarn(parser_state *p, const char *s) +yywarning(parser_state *p, const char *s) { char* c; size_t n; @@ -4115,12 +4171,6 @@ yywarn(parser_state *p, const char *s) } static void -yywarning(parser_state *p, const char *s) -{ - yywarn(p, s); -} - -static void yywarning_s(parser_state *p, const char *msg, const char *s) { char buf[256]; @@ -6225,10 +6275,10 @@ parser_yylex(parser_state *p) if (last_state == EXPR_FNAME) goto gvar; tokfix(p); { - unsigned long n = strtoul(tok(p), NULL, 10); - if (n > INT_MAX) { - yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX)); - return 0; + mrb_int n = mrb_int_read(tok(p), NULL, NULL); + if (n > INT32_MAX) { + yywarning(p, "capture group index too big; always nil"); + return keyword_nil; } pylval.nd = new_nth_ref(p, (int)n); } @@ -6513,6 +6563,7 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt) int i = 0; if (!cxt) return; + if (!p->tree) return; if (intn(p->tree->car) != NODE_SCOPE) return; n0 = n = p->tree->cdr->car; while (n) { @@ -6533,53 +6584,39 @@ MRB_API void mrb_parser_parse(parser_state *p, mrbc_context *c) { struct mrb_jmpbuf buf1; - p->jmp = &buf1; + struct mrb_jmpbuf *prev = p->mrb->jmp; + p->mrb->jmp = &buf1; - MRB_TRY(p->jmp) { + MRB_TRY(p->mrb->jmp) { int n = 1; p->cmd_start = TRUE; p->in_def = p->in_single = 0; p->nerr = p->nwarn = 0; p->lex_strterm = NULL; - parser_init_cxt(p, c); - if (p->mrb->jmp) { - n = yyparse(p); - } - else { - struct mrb_jmpbuf buf2; - - p->mrb->jmp = &buf2; - MRB_TRY(p->mrb->jmp) { - n = yyparse(p); - } - MRB_CATCH(p->mrb->jmp) { - p->nerr++; - } - MRB_END_EXC(p->mrb->jmp); - p->mrb->jmp = 0; - } + n = yyparse(p); if (n != 0 || p->nerr > 0) { p->tree = 0; + p->mrb->jmp = prev; return; } - if (!p->tree) { - p->tree = new_nil(p); - } parser_update_cxt(p, c); if (c && c->dump_result) { mrb_parser_dump(p->mrb, p->tree, 0); } } - MRB_CATCH(p->jmp) { - yyerror(p, "memory allocation error"); + MRB_CATCH(p->mrb->jmp) { p->nerr++; - p->tree = 0; - return; + if (p->mrb->exc == NULL) { + yyerror(p, "memory allocation error"); + p->nerr++; + p->tree = 0; + } } MRB_END_EXC(p->jmp); + p->mrb->jmp = prev; } MRB_API parser_state* @@ -6964,8 +7001,13 @@ dump_args(mrb_state *mrb, node *n, int offset) } n = n->cdr; if (n->car) { + mrb_sym rest = sym(n->car); + dump_prefix(n, offset+1); - printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car))); + if (rest == MRB_OPSYM(mul)) + printf("rest=*\n"); + else + printf("rest=*%s\n", mrb_sym_name(mrb, rest)); } n = n->cdr; if (n->car) { @@ -7242,9 +7284,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) printf("args:\n"); dump_recur(mrb, tree->car, offset+2); if (tree->cdr) { - dump_prefix(tree, offset+1); - printf("block:\n"); - mrb_parser_dump(mrb, tree->cdr, offset+2); + if (tree->cdr->car) { + dump_prefix(tree, offset+1); + printf("kwargs:\n"); + mrb_parser_dump(mrb, tree->cdr->car, offset+2); + } + if (tree->cdr->cdr) { + dump_prefix(tree, offset+1); + printf("block:\n"); + mrb_parser_dump(mrb, tree->cdr->cdr, offset+2); + } } } break; @@ -7385,7 +7434,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_ZSUPER: - printf("NODE_ZSUPER\n"); + printf("NODE_ZSUPER:\n"); + if (tree) { + dump_prefix(tree, offset+1); + printf("args:\n"); + dump_recur(mrb, tree->car, offset+2); + if (tree->cdr) { + dump_prefix(tree, offset+1); + printf("block:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + } + } break; case NODE_RETURN: @@ -7711,7 +7770,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_KW_REST_ARGS: - printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree))); + if (tree) + printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree))); + else + printf("NODE_KW_REST_ARGS\n"); break; default: @@ -7720,3 +7782,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } #endif } + +typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sym, void *user); +void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user); + +void +mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user) +{ + const mrb_ast_node *n = p->tree; + if ((intptr_t)n->car == NODE_SCOPE) { + n = n->cdr->car; + for (; n; n = n->cdr) { + mrb_sym sym = sym(n->car); + if (sym && !func(mrb, sym, user)) break; + } + } +} diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c index 137e4d4cf..ef956207c 100644 --- a/mrbgems/mruby-compiler/core/y.tab.c +++ b/mrbgems/mruby-compiler/core/y.tab.c @@ -76,7 +76,6 @@ #include <ctype.h> #include <errno.h> -#include <stdlib.h> #include <string.h> #include <mruby.h> #include <mruby/compile.h> @@ -97,7 +96,6 @@ typedef struct mrb_parser_heredoc_info parser_heredoc_info; static int yyparse(parser_state *p); static int yylex(void *lval, parser_state *p); static void yyerror(parser_state *p, const char *s); -static void yywarn(parser_state *p, const char *s); static void yywarning(parser_state *p, const char *s); static void backref_error(parser_state *p, node *n); static void void_expr_error(parser_state *p, node *n); @@ -169,7 +167,7 @@ parser_palloc(parser_state *p, size_t size) void *m = mrb_pool_alloc(p->pool, size); if (!m) { - MRB_THROW(p->jmp); + MRB_THROW(p->mrb->jmp); } return m; } @@ -349,9 +347,10 @@ local_var_p(parser_state *p, mrb_sym sym) const mrb_sym *v = ir->lv; int i; - if (!v) break; - for (i=0; i+1 < ir->nlocals; i++) { - if (v[i] == sym) return TRUE; + if (v) { + for (i=0; i+1 < ir->nlocals; i++) { + if (v[i] == sym) return TRUE; + } } if (MRB_PROC_SCOPE_P(u)) break; u = u->upper; @@ -563,13 +562,18 @@ new_call(parser_state *p, node *a, mrb_sym b, node *c, int pass) static node* new_fcall(parser_state *p, mrb_sym b, node *c) { - node *n = new_self(p); - NODE_LINENO(n, c); - n = list4((node*)NODE_FCALL, n, nsym(b), c); + node *n = list4((node*)NODE_FCALL, 0, nsym(b), c); NODE_LINENO(n, c); return n; } +/* (a b . c) */ +static node* +new_callargs(parser_state *p, node *a, node *b, node *c) +{ + return cons(a, cons(b, c)); +} + /* (:super . c) */ static node* new_super(parser_state *p, node *c) @@ -581,7 +585,7 @@ new_super(parser_state *p, node *c) static node* new_zsuper(parser_state *p) { - return list1((node*)NODE_ZSUPER); + return cons((node*)NODE_ZSUPER, 0); } /* (:yield . c) */ @@ -590,7 +594,12 @@ new_yield(parser_state *p, node *c) { if (c) { if (c->cdr) { - yyerror(p, "both block arg and actual block given"); + if (c->cdr->cdr) { + yyerror(p, "both block arg and actual block given"); + } + if (c->cdr->car) { + return cons((node*)NODE_YIELD, push(c->car, c->cdr->car)); + } } return cons((node*)NODE_YIELD, c->car); } @@ -1024,13 +1033,14 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b) static node* new_imaginary(parser_state *p, node *imaginary) { - return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Complex), + new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1); } static node* new_rational(parser_state *p, node *rational) { - return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), list1(list1(rational)), 1); + return new_call(p, new_const(p, MRB_SYM_2(p->mrb, Kernel)), MRB_SYM_2(p->mrb, Rational), new_callargs(p, list1(rational), 0, 0), 1); } /* (:int . i) */ @@ -1253,17 +1263,17 @@ call_uni_op(parser_state *p, node *recv, const char *m) static node* call_bin_op(parser_state *p, node *recv, const char *m, node *arg1) { - return new_call(p, recv, intern_cstr(m), list1(list1(arg1)), 1); + return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1); } static void args_with_block(parser_state *p, node *a, node *b) { if (b) { - if (a->cdr) { + if (a->cdr && a->cdr->cdr) { yyerror(p, "both block arg and actual block given"); } - a->cdr = b; + a->cdr->cdr = b; } } @@ -1290,19 +1300,16 @@ call_with_block(parser_state *p, node *a, node *b) switch (typen(a->car)) { case NODE_SUPER: case NODE_ZSUPER: - if (!a->cdr) a->cdr = cons(0, b); - else { - args_with_block(p, a->cdr, b); - } + if (!a->cdr) a->cdr = new_callargs(p, 0, 0, b); + else args_with_block(p, a->cdr, b); break; case NODE_CALL: case NODE_FCALL: case NODE_SCALL: - n = a->cdr->cdr->cdr; - if (!n->car) n->car = cons(0, b); - else { - args_with_block(p, n->car, b); - } + /* (NODE_CALL recv mid (args kw . blk)) */ + n = a->cdr->cdr->cdr; /* (args kw . blk) */ + if (!n->car) n->car = new_callargs(p, 0, 0, b); + else args_with_block(p, n->car, b); break; default: break; @@ -1310,7 +1317,7 @@ call_with_block(parser_state *p, node *a, node *b) } static node* -negate_lit(parser_state *p, node *n) +new_negate(parser_state *p, node *n) { return cons((node*)NODE_NEGATE, n); } @@ -1324,10 +1331,11 @@ cond(node *n) static node* ret_args(parser_state *p, node *n) { - if (n->cdr) { + if (n->cdr->cdr) { yyerror(p, "block argument should not be given"); return NULL; } + if (!n->car) return NULL; if (!n->car->cdr) return n->car->car; return new_array(p, n->car); } @@ -1356,6 +1364,24 @@ var_reference(parser_state *p, node *lhs) return lhs; } +static node* +label_reference(parser_state *p, mrb_sym sym) +{ + const char *name = mrb_sym_name(p->mrb, sym); + node *n; + + if (local_var_p(p, sym)) { + n = new_lvar(p, sym); + } + else if (ISUPPER(name[0])) { + n = new_const(p, sym); + } + else { + n = new_fcall(p, sym, 0); + } + return n; +} + typedef enum mrb_string_type string_type; static node* @@ -1448,7 +1474,7 @@ heredoc_end(parser_state *p) /* xxx ----------------------------- */ -#line 1452 "mrbgems/mruby-compiler/core/y.tab.c" +#line 1478 "mrbgems/mruby-compiler/core/y.tab.c" # ifndef YY_CAST # ifdef __cplusplus @@ -1620,7 +1646,7 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 1394 "mrbgems/mruby-compiler/core/parse.y" +#line 1420 "mrbgems/mruby-compiler/core/parse.y" node *nd; mrb_sym id; @@ -1628,7 +1654,7 @@ union YYSTYPE stack_type stack; const struct vtable *vars; -#line 1632 "mrbgems/mruby-compiler/core/y.tab.c" +#line 1658 "mrbgems/mruby-compiler/core/y.tab.c" }; typedef union YYSTYPE YYSTYPE; @@ -1946,16 +1972,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 12611 +#define YYLAST 12926 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 149 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 177 +#define YYNNTS 176 /* YYNRULES -- Number of rules. */ -#define YYNRULES 607 +#define YYNRULES 609 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 1063 +#define YYNSTATES 1072 #define YYUNDEFTOK 2 #define YYMAXUTOK 377 @@ -2014,67 +2040,67 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 1565, 1565, 1565, 1576, 1582, 1586, 1591, 1595, 1601, - 1603, 1602, 1616, 1643, 1649, 1653, 1658, 1662, 1668, 1668, - 1672, 1676, 1680, 1684, 1688, 1692, 1696, 1701, 1702, 1706, - 1710, 1714, 1718, 1725, 1728, 1732, 1736, 1740, 1744, 1748, - 1753, 1757, 1764, 1765, 1769, 1773, 1774, 1778, 1782, 1786, - 1790, 1794, 1804, 1803, 1818, 1827, 1828, 1831, 1832, 1839, - 1838, 1853, 1857, 1862, 1866, 1871, 1875, 1880, 1884, 1888, - 1892, 1896, 1902, 1906, 1912, 1913, 1919, 1923, 1927, 1931, - 1935, 1939, 1943, 1947, 1951, 1955, 1961, 1962, 1968, 1972, - 1978, 1982, 1988, 1992, 1996, 2000, 2004, 2008, 2014, 2020, - 2027, 2031, 2035, 2039, 2043, 2047, 2053, 2059, 2064, 2070, - 2074, 2077, 2081, 2085, 2092, 2093, 2094, 2095, 2100, 2107, - 2108, 2111, 2115, 2115, 2121, 2122, 2123, 2124, 2125, 2126, - 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, - 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, - 2147, 2148, 2149, 2150, 2153, 2153, 2153, 2154, 2154, 2155, - 2155, 2155, 2156, 2156, 2156, 2156, 2157, 2157, 2157, 2158, - 2158, 2158, 2159, 2159, 2159, 2159, 2160, 2160, 2160, 2160, - 2161, 2161, 2161, 2161, 2162, 2162, 2162, 2162, 2163, 2163, - 2163, 2163, 2164, 2164, 2167, 2171, 2175, 2179, 2183, 2187, - 2191, 2196, 2201, 2206, 2210, 2214, 2218, 2222, 2226, 2230, - 2234, 2238, 2242, 2246, 2250, 2254, 2258, 2262, 2266, 2270, - 2274, 2278, 2282, 2286, 2290, 2294, 2298, 2302, 2306, 2310, - 2314, 2318, 2322, 2326, 2330, 2334, 2338, 2342, 2346, 2350, - 2354, 2363, 2373, 2382, 2392, 2398, 2399, 2404, 2408, 2415, - 2419, 2427, 2431, 2447, 2473, 2474, 2477, 2478, 2479, 2484, - 2489, 2496, 2502, 2507, 2512, 2517, 2524, 2524, 2535, 2541, - 2545, 2551, 2552, 2555, 2561, 2567, 2572, 2579, 2584, 2589, - 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603, 2607, 2612, - 2611, 2623, 2627, 2622, 2632, 2632, 2636, 2640, 2644, 2648, - 2653, 2658, 2662, 2666, 2670, 2674, 2678, 2679, 2685, 2691, - 2684, 2703, 2711, 2719, 2719, 2719, 2726, 2726, 2726, 2733, - 2739, 2744, 2746, 2743, 2755, 2753, 2771, 2776, 2769, 2793, - 2791, 2807, 2817, 2828, 2832, 2836, 2840, 2846, 2853, 2854, - 2855, 2858, 2859, 2862, 2863, 2871, 2872, 2878, 2882, 2885, - 2889, 2893, 2897, 2902, 2906, 2910, 2914, 2920, 2919, 2929, - 2933, 2937, 2941, 2947, 2952, 2957, 2961, 2965, 2969, 2973, - 2977, 2981, 2985, 2989, 2993, 2997, 3001, 3005, 3009, 3013, - 3019, 3024, 3031, 3031, 3035, 3040, 3047, 3051, 3057, 3058, - 3061, 3066, 3069, 3073, 3079, 3083, 3090, 3089, 3104, 3114, - 3118, 3123, 3130, 3134, 3138, 3142, 3146, 3150, 3154, 3158, - 3162, 3169, 3168, 3183, 3182, 3198, 3206, 3215, 3218, 3225, - 3228, 3232, 3233, 3236, 3240, 3243, 3247, 3250, 3251, 3252, - 3253, 3256, 3257, 3263, 3264, 3265, 3269, 3275, 3276, 3282, - 3287, 3286, 3297, 3301, 3307, 3311, 3317, 3321, 3327, 3330, - 3331, 3334, 3340, 3346, 3347, 3350, 3357, 3356, 3370, 3374, - 3381, 3386, 3393, 3399, 3400, 3401, 3402, 3403, 3407, 3413, - 3417, 3423, 3424, 3425, 3429, 3435, 3439, 3443, 3447, 3451, - 3457, 3461, 3467, 3471, 3475, 3479, 3483, 3487, 3495, 3502, - 3513, 3514, 3518, 3522, 3521, 3538, 3539, 3542, 3548, 3566, - 3586, 3587, 3593, 3599, 3605, 3612, 3617, 3624, 3628, 3634, - 3638, 3644, 3645, 3648, 3652, 3658, 3662, 3666, 3670, 3676, - 3681, 3686, 3690, 3694, 3698, 3702, 3706, 3710, 3714, 3718, - 3722, 3726, 3730, 3734, 3738, 3743, 3749, 3754, 3759, 3764, - 3769, 3776, 3780, 3787, 3792, 3791, 3803, 3807, 3813, 3821, - 3829, 3837, 3841, 3847, 3851, 3857, 3858, 3861, 3866, 3873, - 3874, 3877, 3883, 3887, 3893, 3898, 3898, 3923, 3924, 3930, - 3935, 3941, 3942, 3945, 3951, 3956, 3966, 3973, 3974, 3975, - 3978, 3979, 3980, 3981, 3984, 3985, 3986, 3989, 3990, 3993, - 3997, 4003, 4004, 4010, 4011, 4014, 4015, 4018, 4021, 4022, - 4023, 4026, 4027, 4028, 4031, 4038, 4039, 4043 + 0, 1591, 1591, 1591, 1602, 1608, 1612, 1617, 1621, 1627, + 1629, 1628, 1642, 1669, 1675, 1679, 1684, 1688, 1694, 1694, + 1698, 1702, 1706, 1710, 1714, 1718, 1722, 1727, 1728, 1732, + 1736, 1740, 1744, 1751, 1754, 1758, 1762, 1766, 1770, 1774, + 1779, 1783, 1792, 1802, 1811, 1821, 1828, 1829, 1833, 1837, + 1838, 1842, 1846, 1850, 1854, 1858, 1868, 1867, 1882, 1891, + 1892, 1895, 1896, 1903, 1902, 1917, 1921, 1926, 1930, 1935, + 1939, 1944, 1948, 1952, 1956, 1960, 1966, 1970, 1976, 1977, + 1983, 1987, 1991, 1995, 1999, 2003, 2007, 2011, 2015, 2019, + 2025, 2026, 2032, 2036, 2042, 2046, 2052, 2056, 2060, 2064, + 2068, 2072, 2078, 2084, 2091, 2095, 2099, 2103, 2107, 2111, + 2117, 2123, 2128, 2134, 2138, 2141, 2145, 2149, 2156, 2157, + 2158, 2159, 2164, 2171, 2172, 2175, 2179, 2179, 2185, 2186, + 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, + 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, + 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2217, 2217, + 2217, 2218, 2218, 2219, 2219, 2219, 2220, 2220, 2220, 2220, + 2221, 2221, 2221, 2222, 2222, 2222, 2223, 2223, 2223, 2223, + 2224, 2224, 2224, 2224, 2225, 2225, 2225, 2225, 2226, 2226, + 2226, 2226, 2227, 2227, 2227, 2227, 2228, 2228, 2231, 2235, + 2239, 2243, 2247, 2251, 2255, 2260, 2265, 2270, 2274, 2278, + 2282, 2286, 2290, 2294, 2298, 2302, 2306, 2310, 2314, 2318, + 2322, 2326, 2330, 2334, 2338, 2342, 2346, 2350, 2354, 2358, + 2362, 2366, 2370, 2374, 2378, 2382, 2386, 2390, 2394, 2398, + 2402, 2406, 2410, 2414, 2418, 2427, 2437, 2446, 2456, 2462, + 2463, 2468, 2472, 2479, 2483, 2491, 2495, 2504, 2521, 2522, + 2525, 2526, 2527, 2532, 2537, 2544, 2550, 2555, 2560, 2565, + 2572, 2572, 2583, 2589, 2593, 2599, 2602, 2608, 2614, 2619, + 2626, 2631, 2636, 2643, 2644, 2645, 2646, 2647, 2648, 2649, + 2650, 2654, 2659, 2658, 2670, 2674, 2669, 2679, 2679, 2683, + 2687, 2691, 2695, 2700, 2705, 2709, 2713, 2717, 2721, 2725, + 2726, 2732, 2738, 2731, 2750, 2758, 2766, 2766, 2766, 2773, + 2773, 2773, 2780, 2786, 2791, 2793, 2790, 2802, 2800, 2818, + 2823, 2816, 2840, 2838, 2854, 2864, 2875, 2879, 2883, 2887, + 2893, 2900, 2901, 2902, 2905, 2906, 2909, 2910, 2918, 2919, + 2925, 2929, 2932, 2936, 2940, 2944, 2949, 2953, 2957, 2961, + 2967, 2966, 2976, 2980, 2984, 2988, 2994, 2999, 3004, 3008, + 3012, 3016, 3020, 3024, 3028, 3032, 3036, 3040, 3044, 3048, + 3052, 3056, 3060, 3066, 3071, 3078, 3078, 3082, 3087, 3094, + 3098, 3104, 3105, 3108, 3113, 3116, 3120, 3126, 3130, 3137, + 3136, 3151, 3161, 3165, 3170, 3177, 3181, 3185, 3189, 3193, + 3197, 3201, 3205, 3209, 3216, 3215, 3230, 3229, 3245, 3253, + 3262, 3265, 3272, 3275, 3279, 3280, 3283, 3287, 3290, 3294, + 3297, 3298, 3299, 3300, 3303, 3304, 3310, 3311, 3312, 3316, + 3329, 3330, 3336, 3341, 3340, 3351, 3355, 3361, 3365, 3378, + 3382, 3388, 3391, 3392, 3395, 3401, 3407, 3408, 3411, 3418, + 3417, 3431, 3435, 3449, 3454, 3468, 3474, 3475, 3476, 3477, + 3478, 3482, 3488, 3492, 3502, 3503, 3504, 3508, 3514, 3518, + 3522, 3526, 3530, 3536, 3540, 3546, 3550, 3554, 3558, 3562, + 3566, 3574, 3581, 3587, 3588, 3592, 3596, 3595, 3612, 3613, + 3616, 3622, 3631, 3642, 3643, 3649, 3655, 3661, 3668, 3673, + 3680, 3684, 3690, 3694, 3700, 3701, 3704, 3708, 3714, 3718, + 3722, 3726, 3732, 3737, 3742, 3746, 3750, 3754, 3758, 3762, + 3766, 3770, 3774, 3778, 3782, 3786, 3790, 3794, 3799, 3805, + 3810, 3815, 3820, 3825, 3832, 3836, 3843, 3848, 3847, 3859, + 3863, 3869, 3877, 3885, 3893, 3897, 3903, 3907, 3913, 3914, + 3917, 3922, 3929, 3930, 3933, 3939, 3943, 3949, 3954, 3954, + 3979, 3980, 3986, 3991, 3997, 4003, 4008, 4012, 4022, 4029, + 4030, 4031, 4034, 4035, 4036, 4037, 4040, 4041, 4042, 4045, + 4046, 4049, 4053, 4059, 4060, 4066, 4067, 4070, 4071, 4074, + 4077, 4078, 4079, 4082, 4083, 4086, 4091, 4094, 4095, 4099 }; #endif @@ -2141,9 +2167,9 @@ static const char *const yytname[] = "f_arg_item", "@32", "f_arg", "f_opt_asgn", "f_opt", "f_block_opt", "f_block_optarg", "f_optarg", "restarg_mark", "f_rest_arg", "blkarg_mark", "f_block_arg", "opt_f_block_arg", "singleton", "$@33", - "assoc_list", "assocs", "label_tag", "assoc", "operation", "operation2", - "operation3", "dot_or_colon", "call_op", "call_op2", "opt_terms", - "opt_nl", "rparen", "trailer", "term", "nl", "terms", "none", YY_NULLPTR + "assoc_list", "assocs", "assoc", "operation", "operation2", "operation3", + "dot_or_colon", "call_op", "call_op2", "opt_terms", "opt_nl", "rparen", + "trailer", "term", "nl", "terms", "none", YY_NULLPTR }; #endif @@ -2170,12 +2196,12 @@ static const yytype_int16 yytoknum[] = }; # endif -#define YYPACT_NINF (-848) +#define YYPACT_NINF (-862) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-608) +#define YYTABLE_NINF (-610) #define yytable_value_is_error(Yyn) \ ((Yyn) == YYTABLE_NINF) @@ -2184,113 +2210,114 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - -848, 137, 2991, -848, 7860, 9984, 10326, 6168, -848, 9630, - 9630, -848, -848, 10098, 7350, 5903, 8096, 8096, -848, -848, - 8096, 3648, 3240, -848, -848, -848, -848, 97, 7350, -848, - 49, -848, -848, -848, 6310, 3104, -848, -848, 6452, -848, - -848, -848, -848, -848, -848, -848, 51, 9748, 9748, 9748, - 9748, 168, 5162, 891, 8568, 8922, 7632, -848, 7068, 1196, - 473, 810, 1387, 1396, -848, 273, 9866, 9748, -848, 1021, - -848, 1343, -848, 279, 1637, 1722, -848, -848, 130, 112, - -848, 121, 10212, -848, 152, 12292, 671, 677, 36, 82, - -848, 321, -848, -848, -848, -848, -848, -848, -848, -848, - -848, 46, 187, -848, 200, 71, -848, -848, -848, -848, - -848, 181, 181, 207, 689, 917, -848, 9630, 283, 5281, - 352, 1722, 1722, -848, 174, -848, 806, -848, -848, 71, - -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, - -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, - -848, -848, -848, -848, -848, -848, -848, -848, 24, 103, - 146, 166, -848, -848, -848, -848, -848, -848, 179, 182, - 197, 225, -848, 228, -848, -848, -848, -848, -848, -848, - -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, - -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, - -848, -848, -848, -848, -848, -848, -848, -848, -848, 233, - 4340, 341, 279, 680, 277, 12416, 843, 52, 309, 76, - 680, 9630, 9630, 883, 348, -848, -848, 1109, 381, 98, - 107, -848, -848, -848, -848, -848, -848, -848, -848, -848, - 7209, -848, -848, 278, -848, -848, -848, -848, -848, -848, - 1021, -848, 338, -848, 402, -848, -848, 1021, 3376, 9748, - 9748, 9748, 9748, -848, 12354, -848, -848, 292, 379, 292, - -848, -848, -848, 8214, -848, -848, -848, 8096, -848, -848, - -848, 5903, 9630, -848, -848, 317, 5400, -848, 1118, 368, - 12478, 12478, 203, 7978, 5162, 343, 1021, 1343, 1021, 380, - -848, 7978, 1021, 359, 1352, 1352, -848, 12354, 364, 1352, - -848, 461, 10440, 383, 1158, 1213, 1216, 1732, -848, -848, - -848, -848, 1421, -848, -848, -848, -848, -848, -848, 518, - 1507, -848, -848, 499, -848, 880, -848, 1513, -848, 1528, - 430, 441, -848, -848, -848, -848, 5665, 9630, 9630, 9630, - 9630, 7978, 9630, 9630, 155, -848, -848, -848, -848, -848, - -848, -848, -848, -848, -848, -848, -848, 1378, 431, 444, - 4340, 9748, -848, 409, 524, 446, -848, 1021, -848, -848, - -848, 475, 9748, -848, 480, 556, 481, 576, -848, -848, - 511, 4340, -848, -848, 9040, -848, 5162, 7746, 492, 9040, - 9748, 9748, 9748, 9748, 9748, 9748, 9748, 9748, 9748, 9748, - 9748, 9748, 9748, 9748, 588, 9748, 9748, 9748, 9748, 9748, - 9748, 9748, 9748, 9748, 9748, 9748, 9748, 1200, -848, 8096, - -848, 2511, -848, -848, 11750, -848, -848, -848, -848, 9866, - 9866, -848, 542, -848, 279, -848, 1218, -848, -848, -848, - -848, -848, -848, 2629, 8096, 10718, 4340, 9630, -848, -848, - -848, 627, 630, 218, -848, 4486, 629, 9748, 10804, 8096, - 10890, 9748, 9748, 4778, 106, 106, 122, 10976, 8096, 11062, - -848, 583, -848, 5400, 402, -848, -848, 9158, 645, -848, - 518, 9748, 12416, 12416, 12416, 9748, 374, -848, 8332, -848, - 9748, -848, 8686, 6022, 520, 1021, 292, 292, -848, -848, - 1016, 526, -848, -848, 7350, 4897, 534, 10804, 10890, 9748, - 1343, 1021, -848, -848, 5784, 541, 1343, -848, -848, 8804, - -848, 1021, 8922, -848, -848, -848, 1218, 121, 10440, -848, - 10440, 11148, 8096, 11234, 2150, -848, -848, -848, 1539, 5400, - 518, -848, -848, -848, -848, -848, -848, -848, 9748, 9748, - -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, - 1672, 1021, 1021, 545, 9748, 661, 12416, 78, -848, -848, - -848, 47, -848, -848, 2150, -848, 12416, 2150, -848, -848, - 1545, -848, -848, 9748, 673, 38, 9748, -848, 12008, 292, - -848, 1021, 10440, 549, -848, -848, -848, 648, 572, 1998, - -848, -848, 1267, 219, 2194, 2194, 2194, 2194, 2128, 2128, - 2694, 2786, 2194, 2194, 12478, 12478, 465, 465, -848, 368, - 11946, 2128, 2128, 1923, 1923, 1531, 674, 674, 368, 368, - 368, 3784, 6808, 4056, 6926, -848, 181, -848, 554, 292, - 258, -848, 507, -848, -848, 3512, -848, -848, 2370, 38, - 38, -848, 2848, -848, -848, -848, -848, -848, 1021, 9630, - 4340, 1033, 515, -848, 181, 557, 181, 685, 1016, 7491, - -848, 9276, 683, -848, 425, -848, 6570, 6689, 563, 295, - 296, 683, -848, -848, -848, -848, 66, 115, 567, 126, - 128, 9630, 7350, 571, 706, 12416, 80, -848, 518, 12416, - 12416, 518, 9748, 12354, -848, 292, 12416, -848, -848, -848, - -848, 8450, 8686, -848, -848, -848, 585, -848, -848, 170, - 1343, 1021, 1352, 492, -848, 1033, 515, 586, 1058, 1092, - 581, 89, -848, 591, -848, 368, 368, -848, 1286, 1021, - 592, -848, -848, 1886, 11822, -848, 676, -848, 446, -848, - -848, -848, 593, 595, 596, -848, 612, 676, 596, 11884, - -848, -848, 2150, 4340, -848, -848, 12079, 9394, -848, -848, - 10440, 7978, 9866, 9748, 11320, 8096, 11406, 55, 9866, 9866, - -848, 542, 509, 8332, 9866, 9866, -848, 542, 82, 130, - 4340, 5400, 38, -848, 1021, 740, -848, -848, -848, -848, - 12008, -848, 665, -848, 5043, 745, -848, 9630, 750, -848, - 9748, 9748, 298, 9748, 9748, 753, 5546, 5546, 140, 106, - -848, -848, -848, 9512, 4632, 518, 12416, -848, 6022, 292, - -848, -848, -848, 1095, 615, 625, 4340, 5400, -848, -848, - -848, 631, -848, 1803, 1021, 9748, -848, 2150, -848, 1545, - -848, 1545, -848, 1545, -848, -848, 9748, -848, 581, 581, - 10554, -848, 635, 446, 638, 10554, -848, 643, 649, -848, - 757, 9748, 12150, -848, -848, 12416, 3920, 4192, 651, 305, - 449, 9748, 9748, -848, -848, -848, -848, -848, 9866, -848, - -848, -848, -848, -848, -848, -848, 789, 684, 5400, 4340, - -848, -848, 10668, 680, -848, -848, 5546, -848, -848, 680, - -848, 9748, -848, 797, 825, -848, 12416, 365, -848, 8686, - -848, 1320, 826, 710, 1836, 1836, 1295, -848, 12416, 596, - 704, 596, 596, 12416, 724, 727, 801, 1322, 78, -848, - -848, 1742, -848, 1322, 2150, -848, 1545, -848, -848, 12221, - 464, 12416, 12416, -848, -848, -848, -848, 718, 844, 805, - -848, 1335, 1213, 1216, 4340, -848, 4486, -848, -848, 5546, - -848, -848, -848, -848, 12, -848, -848, -848, -848, 721, - 721, 1836, 726, -848, 1545, -848, -848, -848, -848, -848, - -848, 11492, -848, 446, 78, -848, -848, 731, 735, 739, - -848, 742, 739, -848, -848, 1218, 11578, 8096, 11664, 630, - 425, 851, 1320, -848, 1836, 721, 1836, 596, 741, 744, - -848, 2150, -848, 1545, -848, 1545, -848, 1545, -848, -848, - 1033, 515, 748, 746, 804, -848, -848, -848, -848, 721, - -848, 739, 751, 739, 739, 1095, -848, 1545, -848, -848, - -848, 739, -848 + -862, 113, 3344, -862, 8328, 10452, 10794, 6636, -862, 10098, + 10098, -862, -862, 10566, 7818, 6252, 8564, 8564, -862, -862, + 8564, 3997, 3582, -862, -862, -862, -862, 10, 7818, -862, + 20, -862, -862, -862, 6778, 3179, -862, -862, 6920, -862, + -862, -862, -862, -862, -862, -862, 292, 10216, 10216, 10216, + 10216, 114, 5511, 1275, 9036, 9390, 8100, -862, 7536, 628, + 100, 502, 965, 992, -862, 487, 10334, 10216, -862, 756, + -862, 1407, -862, 364, 1613, 1613, -862, -862, 155, 65, + -862, 67, 10680, -862, 115, 12651, 82, 154, 137, 88, + -862, 103, -862, -862, -862, -862, -862, -862, -862, -862, + -862, 81, 142, -862, 277, 97, -862, -862, -862, -862, + -862, 107, 107, 10, 618, 1033, -862, 10098, 148, 5630, + 567, 1261, 1261, -862, 145, -862, 206, -862, -862, 97, + -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, + -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, + -862, -862, -862, -862, -862, -862, -862, -862, 54, 106, + 110, 158, -862, -862, -862, -862, -862, -862, 173, 192, + 216, 219, -862, 238, -862, -862, -862, -862, -862, -862, + -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, + -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, + -862, -862, -862, -862, -862, -862, -862, -862, -862, 280, + 4689, 224, 364, 1613, 1613, 810, 160, 12775, 377, 320, + 193, 331, 810, 10098, 10098, 644, 235, -862, -862, 645, + 275, 86, 116, -862, -862, -862, -862, -862, -862, -862, + -862, -862, 7677, -862, -862, 162, -862, -862, -862, -862, + -862, -862, 756, -862, 557, -862, 287, -862, -862, 756, + 3725, 10216, 10216, 10216, 10216, -862, 12713, -862, -862, 180, + 258, 180, -862, -862, -862, 8682, -862, -862, -862, 8564, + -862, -862, -862, 6252, 6490, -862, 186, 5749, -862, 678, + 225, 2722, 2722, 288, 8446, 5511, 198, 756, 1407, 756, + 267, -862, 8446, 756, 251, 1367, 1367, -862, 12713, 256, + 1367, -862, 342, 10908, 257, 768, 926, 1070, 1707, -862, + -862, -862, -862, 1192, -862, -862, -862, -862, -862, -862, + 570, 1262, -862, -862, 326, -862, 663, -862, 1270, -862, + 1280, 313, 324, -862, -862, -862, -862, 6014, 10098, 10098, + 10098, 10098, 8446, 10098, 10098, 63, -862, -862, -862, -862, + -862, -862, -862, -862, -862, -862, -862, -862, 2066, 318, + 337, 4689, 10216, -862, 308, 409, 336, -862, 756, -862, + -862, -862, 339, 10216, -862, 341, 453, 367, 462, -862, + -862, 399, 4689, -862, -862, 9508, -862, 5511, 8214, 380, + 9508, 10216, 10216, 10216, 10216, 10216, 10216, 10216, 10216, 10216, + 10216, 10216, 10216, 10216, 10216, 479, 10216, 10216, 10216, 10216, + 10216, 10216, 10216, 10216, 10216, 10216, 10216, 10216, 11186, -862, + 8564, -862, 11272, -862, -862, 12476, -862, -862, -862, -862, + 10334, 10334, -862, 438, -862, 364, -862, 1071, -862, -862, + -862, -862, -862, -862, 11358, 8564, 11444, 4689, 10098, -862, + -862, -862, 532, 550, 382, 456, 460, -862, 4835, 578, + 10216, 11530, 8564, 11616, 10216, 10216, 5127, 73, 73, 124, + 11702, 8564, 11788, -862, 535, -862, 5749, 287, -862, -862, + 9626, 585, -862, 10216, 12775, 12775, 12775, 10216, -862, -862, + 8800, -862, 10216, -862, 9154, 6371, 470, 756, 180, 180, + -862, -862, 1006, 472, -862, -862, -862, 7818, 5246, 464, + 11530, 11616, 10216, 1407, 756, -862, -862, 6133, 489, 1407, + -862, -862, 9272, -862, 756, 9390, -862, -862, -862, 1071, + 67, 10908, -862, 10908, 11874, 8564, 11960, 1470, -862, -862, + -862, 1285, 5749, 570, -862, -862, -862, -862, -862, -862, + -862, 10216, 10216, -862, -862, -862, -862, -862, -862, -862, + -862, -862, -862, 1586, 756, 756, 500, 10334, 633, 12775, + 92, -862, -862, -862, 47, -862, -862, 1470, -862, 12775, + 1470, -862, -862, 1815, -862, -862, 10334, 638, 56, 10216, + -862, 2992, 180, -862, 756, 10908, 526, -862, -862, -862, + 626, 553, 1418, -862, -862, 1092, 407, 3503, 3503, 3503, + 3503, 1726, 1726, 12793, 2453, 3503, 3503, 2722, 2722, 918, + 918, -862, 225, 12775, 1726, 1726, 1345, 1345, 1622, 314, + 314, 225, 225, 225, 4133, 7276, 4405, 7394, -862, 107, + -862, 538, 180, 343, -862, 413, -862, -862, 3861, -862, + -862, 1934, 56, 56, -862, 2201, -862, -862, -862, -862, + -862, 756, 10098, 4689, 1091, 634, -862, 107, 543, 107, + 683, 1006, 7959, -862, 9744, 682, -862, 10216, 10216, 619, + -862, 7038, 7157, 562, 458, 465, 682, -862, -862, -862, + -862, 62, 112, 568, 130, 134, 10098, 7818, 576, 701, + 12775, 774, -862, 12775, 12775, 493, 10216, 12713, -862, 180, + 12775, -862, -862, -862, -862, 8918, 9154, -862, -862, -862, + 582, -862, -862, 55, 1407, 756, 1367, 380, -862, 1091, + 634, 581, 1159, 1160, -862, 72, -862, 593, -862, 225, + 225, -862, 1007, 756, 606, -862, -862, 2252, 708, 2789, + -862, 703, -862, 336, -862, -862, -862, 624, 625, 627, + -862, 635, 703, 627, 744, 2908, -862, -862, 1470, 4689, + -862, -862, 3393, 9862, -862, -862, 10908, 8446, 10334, 10216, + 12046, 8564, 12132, 217, 10334, 10334, -862, 438, 433, 8800, + 10334, 10334, -862, 438, 88, 155, 4689, 5749, 56, -862, + 756, 778, -862, -862, -862, -862, 2992, -862, 704, -862, + 5392, 787, -862, 10098, 789, -862, 10216, 10216, 476, 10216, + 10216, 795, 5895, 5895, 135, 73, -862, -862, -862, 9980, + 4981, 12775, -862, 6371, 180, -862, -862, -862, 1173, 667, + 1415, 4689, 5749, -862, -862, -862, 671, -862, 1596, 756, + 10216, 10216, -862, 1470, -862, 1815, -862, 1815, -862, 1815, + -862, -862, 10216, 10216, -862, -862, -862, 11022, -862, 681, + 336, 688, 11022, -862, 692, 696, -862, 828, 10216, 12509, + -862, -862, 12775, 4269, 4541, 705, 517, 528, 10216, 10216, + -862, -862, -862, -862, -862, 10334, -862, -862, -862, -862, + -862, -862, -862, 829, 711, 5749, 4689, -862, -862, 11136, + 810, -862, -862, 5895, -862, -862, 810, -862, 10216, -862, + 836, 840, -862, 12775, 244, -862, 9154, -862, 1385, 842, + 723, 1676, 1676, 1081, -862, 12775, 12775, 627, 721, 627, + 627, 12775, 12775, 740, 741, 821, 1093, 92, -862, -862, + 1793, -862, 1093, 1470, -862, 1815, -862, -862, 12580, 575, + 12775, 12775, -862, -862, -862, -862, 742, 864, 827, -862, + 1136, 926, 1070, 4689, -862, 4835, -862, -862, 5895, -862, + -862, -862, -862, 746, -862, -862, -862, -862, 752, 752, + 1676, 755, -862, 1815, -862, -862, -862, -862, -862, -862, + 12218, -862, 336, 92, -862, -862, 761, 763, 769, -862, + 779, 769, -862, -862, 1071, 12304, 8564, 12390, 550, 619, + 868, 1385, 493, 1676, 752, 1676, 627, 766, 782, -862, + 1470, -862, 1815, -862, 1815, -862, 1815, -862, -862, 1091, + 634, 745, 853, 995, -862, -862, -862, -862, 752, -862, + 769, 788, 769, 769, 1173, -862, 1815, -862, -862, -862, + 769, -862 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -2298,159 +2325,160 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_int16 yydefact[] = { - 2, 0, 0, 1, 0, 0, 0, 0, 289, 0, - 0, 313, 316, 0, 0, 593, 333, 334, 335, 336, - 301, 266, 266, 484, 483, 485, 486, 595, 0, 10, - 0, 488, 487, 489, 475, 579, 477, 476, 479, 478, - 471, 472, 433, 434, 490, 491, 287, 0, 0, 0, - 0, 0, 0, 291, 607, 607, 84, 308, 0, 0, - 0, 0, 0, 0, 448, 0, 0, 0, 3, 593, - 6, 9, 27, 33, 535, 535, 45, 56, 55, 0, - 72, 0, 76, 86, 0, 50, 244, 0, 57, 306, - 280, 281, 431, 282, 283, 284, 429, 428, 460, 430, - 427, 482, 0, 285, 286, 266, 5, 8, 333, 334, - 301, 607, 409, 0, 109, 110, 287, 0, 0, 0, - 0, 535, 535, 112, 492, 337, 0, 482, 286, 0, - 329, 164, 174, 165, 161, 190, 191, 192, 193, 172, - 187, 180, 170, 169, 185, 168, 167, 163, 188, 162, - 175, 179, 181, 173, 166, 182, 189, 184, 183, 176, - 186, 171, 160, 178, 177, 159, 157, 158, 154, 155, - 156, 114, 116, 115, 149, 150, 127, 128, 129, 136, - 133, 135, 130, 131, 151, 152, 137, 138, 142, 145, - 146, 132, 134, 124, 125, 126, 139, 140, 141, 143, - 144, 147, 148, 153, 565, 51, 117, 118, 564, 0, - 0, 0, 54, 0, 0, 50, 0, 482, 0, 286, - 0, 0, 0, 108, 0, 348, 347, 0, 0, 482, - 286, 183, 176, 186, 171, 154, 155, 156, 114, 115, - 0, 119, 121, 20, 120, 451, 456, 455, 601, 604, - 593, 603, 0, 453, 0, 605, 602, 594, 577, 0, - 0, 0, 0, 261, 273, 70, 265, 607, 431, 607, - 569, 71, 69, 607, 255, 302, 68, 0, 254, 408, - 67, 593, 0, 596, 18, 0, 0, 217, 0, 218, - 205, 208, 298, 0, 0, 0, 593, 15, 593, 74, - 14, 0, 593, 0, 598, 598, 245, 0, 0, 598, - 567, 0, 0, 82, 0, 92, 99, 535, 465, 464, - 466, 467, 0, 463, 462, 435, 440, 439, 442, 0, - 0, 437, 444, 0, 446, 0, 458, 0, 469, 0, - 473, 474, 49, 232, 233, 4, 594, 0, 0, 0, - 0, 0, 0, 0, 542, 538, 537, 536, 539, 540, - 544, 556, 511, 512, 560, 559, 555, 535, 0, 500, - 0, 504, 509, 607, 514, 607, 534, 0, 541, 543, - 546, 520, 0, 553, 520, 558, 520, 0, 518, 496, - 500, 0, 396, 398, 0, 88, 0, 80, 77, 0, + 2, 0, 0, 1, 0, 0, 0, 0, 292, 0, + 0, 316, 319, 0, 0, 595, 336, 337, 338, 339, + 304, 270, 270, 487, 486, 488, 489, 597, 0, 10, + 0, 491, 490, 492, 478, 581, 480, 479, 482, 481, + 474, 475, 436, 437, 493, 494, 290, 0, 0, 0, + 0, 0, 0, 294, 609, 609, 88, 311, 0, 0, + 0, 0, 0, 0, 451, 0, 0, 0, 3, 595, + 6, 9, 27, 33, 538, 538, 49, 60, 59, 0, + 76, 0, 80, 90, 0, 54, 248, 0, 61, 309, + 283, 284, 434, 285, 286, 287, 432, 431, 463, 433, + 430, 485, 0, 288, 289, 270, 5, 8, 336, 337, + 304, 609, 412, 0, 113, 114, 290, 0, 0, 0, + 0, 538, 538, 116, 495, 340, 0, 485, 289, 0, + 332, 168, 178, 169, 165, 194, 195, 196, 197, 176, + 191, 184, 174, 173, 189, 172, 171, 167, 192, 166, + 179, 183, 185, 177, 170, 186, 193, 188, 187, 180, + 190, 175, 164, 182, 181, 163, 161, 162, 158, 159, + 160, 118, 120, 119, 153, 154, 131, 132, 133, 140, + 137, 139, 134, 135, 155, 156, 141, 142, 146, 149, + 150, 136, 138, 128, 129, 130, 143, 144, 145, 147, + 148, 151, 152, 157, 568, 55, 121, 122, 567, 0, + 0, 0, 58, 538, 538, 0, 0, 54, 0, 485, + 0, 289, 0, 0, 0, 112, 0, 351, 350, 0, + 0, 485, 289, 187, 180, 190, 175, 158, 159, 160, + 118, 119, 0, 123, 125, 20, 124, 454, 459, 458, + 603, 605, 595, 606, 0, 456, 0, 607, 604, 596, + 579, 0, 0, 0, 0, 265, 276, 74, 269, 609, + 434, 609, 572, 75, 73, 609, 259, 305, 72, 0, + 258, 411, 71, 595, 0, 18, 0, 0, 221, 0, + 222, 209, 212, 301, 0, 0, 0, 595, 15, 595, + 78, 14, 0, 595, 0, 600, 600, 249, 0, 0, + 600, 570, 0, 0, 86, 0, 96, 103, 538, 468, + 467, 469, 470, 0, 466, 465, 438, 443, 442, 445, + 0, 0, 440, 447, 0, 449, 0, 461, 0, 472, + 0, 476, 477, 53, 236, 237, 4, 596, 0, 0, + 0, 0, 0, 0, 0, 545, 541, 540, 539, 542, + 543, 547, 559, 514, 515, 563, 562, 558, 538, 0, + 503, 0, 507, 512, 609, 517, 609, 537, 0, 544, + 546, 549, 523, 0, 556, 523, 561, 523, 0, 521, + 499, 0, 0, 399, 401, 0, 92, 0, 84, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 204, 207, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 590, 607, - 589, 0, 592, 591, 0, 413, 411, 307, 432, 0, - 0, 402, 61, 305, 326, 109, 110, 111, 473, 474, - 500, 493, 324, 0, 607, 0, 0, 0, 588, 587, - 52, 0, 607, 298, 339, 0, 338, 0, 0, 607, - 0, 0, 0, 0, 0, 0, 298, 0, 607, 0, - 321, 0, 122, 0, 0, 452, 454, 0, 0, 606, - 571, 0, 274, 576, 268, 0, 271, 262, 0, 270, - 0, 263, 0, 593, 0, 593, 607, 607, 256, 267, - 593, 0, 304, 48, 0, 0, 0, 0, 0, 0, - 17, 593, 296, 13, 594, 73, 292, 295, 299, 600, - 246, 599, 600, 248, 300, 568, 98, 90, 0, 85, - 0, 0, 607, 0, 535, 309, 393, 468, 0, 0, - 443, 449, 436, 438, 445, 447, 459, 470, 0, 0, - 7, 21, 22, 23, 24, 25, 46, 47, 502, 548, - 0, 593, 593, 520, 0, 0, 503, 0, 516, 563, - 513, 0, 517, 501, 0, 527, 549, 0, 530, 557, - 0, 532, 561, 0, 0, 607, 0, 28, 30, 0, - 31, 593, 0, 78, 89, 44, 34, 42, 0, 249, - 194, 29, 0, 286, 222, 227, 228, 229, 224, 226, - 236, 237, 230, 231, 203, 206, 234, 235, 32, 214, - 595, 223, 225, 219, 220, 221, 209, 210, 211, 212, - 213, 580, 585, 581, 586, 407, 266, 405, 0, 607, - 580, 582, 581, 583, 406, 266, 580, 581, 266, 607, - 607, 35, 249, 195, 41, 202, 59, 62, 0, 0, - 0, 109, 110, 113, 0, 0, 607, 0, 593, 0, - 290, 607, 607, 419, 607, 340, 584, 297, 0, 580, - 581, 607, 342, 314, 341, 317, 584, 297, 0, 580, - 581, 0, 0, 0, 0, 273, 0, 320, 572, 574, - 573, 0, 0, 275, 269, 607, 575, 570, 253, 251, - 257, 258, 260, 303, 597, 19, 0, 26, 201, 75, - 16, 593, 598, 91, 83, 95, 97, 0, 94, 96, - 595, 0, 461, 0, 450, 215, 216, 542, 356, 593, - 349, 499, 497, 0, 240, 331, 0, 510, 607, 562, - 519, 547, 520, 520, 520, 554, 520, 542, 520, 242, - 332, 384, 382, 0, 381, 380, 279, 0, 87, 81, - 0, 0, 0, 0, 0, 607, 0, 0, 0, 0, - 404, 65, 410, 258, 0, 0, 403, 63, 399, 58, - 0, 0, 607, 327, 0, 0, 410, 330, 566, 53, - 420, 421, 607, 422, 0, 607, 345, 0, 0, 343, - 0, 0, 410, 0, 0, 0, 0, 0, 410, 0, - 123, 457, 319, 0, 0, 272, 276, 264, 593, 607, - 11, 293, 247, 93, 0, 386, 0, 0, 310, 441, - 357, 354, 545, 0, 593, 0, 515, 0, 523, 0, - 525, 0, 531, 0, 528, 533, 0, 379, 595, 595, - 506, 507, 607, 607, 364, 0, 551, 364, 364, 362, - 0, 0, 277, 79, 43, 250, 580, 581, 0, 580, - 581, 0, 0, 40, 199, 39, 200, 66, 0, 37, - 197, 38, 198, 64, 400, 401, 0, 0, 0, 0, - 494, 325, 0, 0, 424, 346, 0, 12, 426, 0, - 311, 0, 312, 0, 0, 322, 275, 607, 252, 259, - 392, 0, 0, 0, 0, 0, 352, 498, 241, 520, - 520, 520, 520, 243, 0, 0, 0, 505, 0, 360, - 361, 364, 372, 550, 0, 375, 0, 377, 397, 278, - 410, 239, 238, 36, 196, 414, 412, 0, 0, 0, - 423, 0, 100, 107, 0, 425, 0, 315, 318, 0, - 416, 417, 415, 390, 595, 388, 391, 395, 394, 358, - 355, 0, 350, 524, 0, 521, 526, 529, 385, 383, - 298, 0, 508, 607, 0, 363, 370, 364, 364, 364, - 552, 364, 364, 60, 328, 106, 0, 607, 0, 607, - 607, 0, 0, 387, 0, 353, 0, 520, 584, 297, - 359, 0, 367, 0, 369, 0, 376, 0, 373, 378, - 103, 105, 0, 580, 581, 418, 344, 323, 389, 351, - 522, 364, 364, 364, 364, 101, 368, 0, 365, 371, - 374, 364, 366 + 0, 208, 211, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 592, + 609, 591, 0, 594, 593, 0, 416, 414, 310, 435, + 0, 0, 405, 65, 308, 329, 113, 114, 115, 476, + 477, 503, 496, 327, 0, 609, 0, 0, 0, 590, + 589, 56, 0, 609, 301, 0, 0, 342, 0, 341, + 0, 0, 609, 0, 0, 0, 0, 0, 0, 301, + 0, 609, 0, 324, 0, 126, 0, 0, 455, 457, + 0, 0, 608, 576, 277, 578, 272, 0, 597, 266, + 0, 274, 0, 267, 0, 595, 0, 595, 609, 609, + 260, 271, 595, 0, 307, 52, 598, 0, 0, 0, + 0, 0, 0, 17, 595, 299, 13, 596, 77, 295, + 298, 302, 602, 250, 601, 602, 252, 303, 571, 102, + 94, 0, 89, 0, 0, 609, 0, 538, 312, 396, + 471, 0, 0, 446, 452, 439, 441, 448, 450, 462, + 473, 0, 0, 7, 21, 22, 23, 24, 25, 50, + 51, 505, 551, 0, 595, 595, 523, 0, 0, 506, + 0, 519, 566, 516, 0, 520, 504, 0, 530, 552, + 0, 533, 560, 0, 535, 564, 0, 0, 609, 0, + 28, 30, 0, 31, 595, 0, 82, 93, 48, 34, + 46, 0, 253, 198, 29, 0, 289, 226, 231, 232, + 233, 228, 230, 240, 241, 234, 235, 207, 210, 238, + 239, 32, 218, 597, 227, 229, 223, 224, 225, 213, + 214, 215, 216, 217, 582, 587, 583, 588, 410, 270, + 408, 0, 609, 582, 584, 583, 585, 409, 270, 582, + 583, 270, 609, 609, 35, 253, 199, 45, 206, 63, + 66, 0, 0, 0, 113, 114, 117, 0, 0, 609, + 0, 595, 0, 293, 609, 609, 422, 0, 0, 609, + 343, 586, 300, 0, 582, 583, 609, 345, 317, 344, + 320, 586, 300, 0, 582, 583, 0, 0, 0, 0, + 276, 0, 323, 575, 574, 275, 0, 278, 273, 609, + 577, 573, 257, 255, 261, 262, 264, 306, 599, 19, + 0, 26, 205, 79, 16, 595, 600, 95, 87, 99, + 101, 0, 98, 100, 597, 0, 464, 0, 453, 219, + 220, 545, 359, 595, 352, 502, 500, 0, 41, 244, + 334, 0, 513, 609, 565, 522, 550, 523, 523, 523, + 557, 523, 545, 523, 43, 246, 335, 387, 385, 0, + 384, 383, 282, 0, 91, 85, 0, 0, 0, 0, + 0, 609, 0, 0, 0, 0, 407, 69, 413, 262, + 0, 0, 406, 67, 402, 62, 0, 0, 609, 330, + 0, 0, 413, 333, 569, 57, 423, 424, 609, 425, + 0, 609, 348, 0, 0, 346, 0, 0, 413, 0, + 0, 0, 0, 0, 413, 0, 127, 460, 322, 0, + 0, 279, 268, 595, 609, 11, 296, 251, 97, 0, + 389, 0, 0, 313, 444, 360, 357, 548, 0, 595, + 0, 0, 518, 0, 526, 0, 528, 0, 534, 0, + 531, 536, 0, 0, 382, 597, 597, 509, 510, 609, + 609, 367, 0, 554, 367, 367, 365, 0, 0, 280, + 83, 47, 254, 582, 583, 0, 582, 583, 0, 0, + 40, 203, 39, 204, 70, 0, 37, 201, 38, 202, + 68, 403, 404, 0, 0, 0, 0, 497, 328, 0, + 0, 427, 349, 0, 12, 429, 0, 314, 0, 315, + 0, 0, 325, 278, 609, 256, 263, 395, 0, 0, + 0, 0, 0, 355, 501, 42, 245, 523, 523, 523, + 523, 44, 247, 0, 0, 0, 508, 0, 363, 364, + 367, 375, 553, 0, 378, 0, 380, 400, 281, 413, + 243, 242, 36, 200, 417, 415, 0, 0, 0, 426, + 0, 104, 111, 0, 428, 0, 318, 321, 0, 419, + 420, 418, 393, 597, 391, 394, 398, 397, 361, 358, + 0, 353, 527, 0, 524, 529, 532, 388, 386, 301, + 0, 511, 609, 0, 366, 373, 367, 367, 367, 555, + 367, 367, 64, 331, 110, 0, 609, 0, 609, 609, + 0, 0, 390, 0, 356, 0, 523, 586, 300, 362, + 0, 370, 0, 372, 0, 379, 0, 376, 381, 107, + 109, 0, 582, 583, 421, 347, 326, 392, 354, 525, + 367, 367, 367, 367, 105, 371, 0, 368, 374, 377, + 367, 369 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -848, -848, -848, 382, -848, 28, -848, -255, 267, -848, - 120, -848, -31, -208, 229, 64, 100, -848, 83, -46, - -848, -605, -848, 30, 886, -183, -19, -66, -274, -472, - -45, 1894, -87, 898, 20, 14, -848, -848, 15, -848, - 1140, -848, 707, 65, -55, -403, 72, 26, -848, -298, - -233, 280, 375, -340, 129, -848, -848, -848, -848, -848, - -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, - -848, 8, -216, -467, -115, -563, -848, -848, -848, 136, - 91, -848, -565, -848, -848, -424, -848, -110, -848, -848, - 114, -848, -848, -848, -86, -848, -848, -469, -848, -104, - -848, -848, -848, -848, -848, -15, 21, -178, -848, -848, - -848, -848, -405, -273, -848, 669, -848, -848, -848, 16, - -848, -848, -848, 1698, 2055, 921, 1364, -848, -848, -848, - 405, 74, -668, 354, -16, -848, -848, -848, 73, -20, - -195, -246, -815, -685, -526, -848, 135, -735, -520, -847, - -11, -505, -848, -439, -848, 262, -318, -848, -848, -848, - 45, 667, -422, 609, -265, -848, -848, -53, -848, 34, - -18, 366, -264, 601, -21, -62, -2 + -862, -862, -862, 419, -862, 28, -862, -277, 32, -862, + 74, -862, -195, -390, 422, 1715, 1901, -862, 1, -58, + -862, -635, -862, 14, 927, -207, -30, -53, -275, -506, + -12, 985, -38, 933, 13, -21, -862, -862, 19, -862, + 1204, -862, 149, 41, -202, -374, 66, 5, -862, -392, + -262, -131, 161, -361, 35, -862, -862, -862, -862, -862, + -862, -862, -862, -862, -862, -862, -862, -862, -862, -862, + -862, 8, -179, -442, -88, -590, -862, -862, -862, 164, + 85, -862, -558, -862, -862, -218, -862, -86, -862, -862, + 141, -862, -862, -862, -85, -862, -862, -472, -862, -77, + -862, -862, -862, -862, -862, 38, 71, -210, -862, -862, + -862, -862, -862, -245, -862, 698, -862, -862, -862, 31, + -862, -862, -862, 2358, 2761, 946, 2172, -862, -862, 0, + 590, -6, 76, 397, 24, -862, -862, -862, 329, -445, + -14, -229, -842, -706, -60, -862, 227, -711, -525, -861, + -3, -517, -862, 75, -862, 202, -308, -862, -862, -862, + 102, -438, 612, -157, -862, -862, -82, -862, 34, -26, + 344, -249, -180, -281, -67, -2 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 1, 2, 68, 69, 70, 285, 461, 462, 296, - 297, 514, 72, 606, 73, 74, 75, 679, 213, 76, - 77, 667, 802, 78, 79, 298, 80, 81, 82, 539, - 83, 214, 123, 124, 241, 242, 243, 702, 644, 207, - 85, 303, 610, 645, 275, 504, 505, 276, 277, 266, - 497, 532, 649, 600, 86, 210, 301, 731, 302, 317, - 741, 221, 826, 222, 827, 701, 979, 670, 668, 909, - 456, 288, 465, 693, 818, 819, 228, 749, 934, 1005, - 952, 868, 773, 774, 869, 844, 984, 985, 545, 848, - 393, 595, 88, 89, 443, 660, 659, 488, 982, 682, - 812, 913, 917, 90, 91, 92, 330, 331, 549, 93, - 94, 95, 550, 251, 252, 253, 483, 96, 97, 98, - 324, 99, 100, 217, 218, 103, 219, 452, 669, 368, - 450, 370, 371, 372, 871, 872, 373, 374, 375, 760, - 585, 377, 378, 379, 380, 570, 381, 382, 383, 876, - 877, 384, 385, 386, 387, 388, 578, 209, 457, 308, - 507, 491, 270, 129, 674, 647, 460, 455, 434, 511, - 845, 512, 530, 255, 256, 257, 300 + -1, 1, 2, 68, 69, 70, 286, 462, 463, 297, + 298, 517, 72, 609, 73, 213, 214, 682, 215, 76, + 77, 670, 808, 78, 79, 299, 80, 81, 82, 542, + 83, 216, 123, 124, 243, 244, 245, 707, 647, 207, + 85, 304, 613, 648, 277, 506, 507, 278, 279, 268, + 499, 535, 652, 603, 86, 210, 302, 735, 303, 318, + 745, 223, 832, 224, 833, 706, 988, 673, 671, 916, + 457, 289, 468, 698, 824, 825, 230, 753, 941, 1014, + 961, 875, 779, 780, 876, 849, 993, 994, 548, 853, + 394, 598, 88, 89, 444, 663, 662, 491, 991, 685, + 818, 920, 924, 90, 91, 92, 331, 332, 552, 93, + 94, 95, 553, 253, 254, 255, 486, 96, 97, 98, + 325, 99, 100, 219, 220, 103, 221, 453, 672, 369, + 370, 371, 372, 373, 878, 879, 374, 375, 376, 377, + 588, 378, 379, 380, 381, 573, 382, 383, 384, 883, + 884, 385, 386, 387, 388, 389, 581, 209, 458, 309, + 509, 272, 129, 677, 650, 461, 456, 435, 513, 850, + 514, 533, 257, 258, 259, 301 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -2458,549 +2486,572 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 106, 268, 268, 437, 473, 268, 283, 346, 695, 282, - 87, 313, 87, 126, 126, 704, 398, 216, 216, 278, - 342, 227, 206, 216, 216, 216, 648, 205, 216, 206, - 244, 447, 107, 299, 431, 433, 501, 875, 538, 268, - 268, 533, 284, 206, 244, 535, 263, 263, 280, 254, - 263, 675, 306, 310, 376, 376, 551, 582, 761, 611, - 87, 269, 269, 851, 314, 269, 688, 765, 734, 121, - 121, 546, 389, 206, 216, 698, 438, 121, 323, 762, - 717, 333, 335, 337, 339, 708, 274, 279, 265, 271, - 314, -103, 272, 220, 800, 801, 464, 435, 250, 305, - 309, 376, 376, 345, 870, 122, 122, 1010, 435, 278, - 717, 521, 891, 122, -484, 575, 986, 771, 846, 815, - 121, 572, 71, -100, 71, 216, 432, 87, 825, 756, - 779, 442, -107, 692, 125, 125, 594, 3, -480, 737, - -105, 428, 125, -481, -480, 763, 121, -106, 766, 391, - 364, -102, 553, -104, 1022, 553, 122, 553, 392, 553, - 249, 553, 646, 470, 772, -101, 655, -100, 472, 658, - 441, -484, -108, -100, 479, 365, 274, 279, 892, 362, - 363, 364, 122, 430, 1010, 125, 897, 286, -92, 588, - 676, 591, 903, -483, 441, 245, 391, -107, 246, 247, - 714, 677, 847, 646, 714, 655, 365, 986, -95, 436, - -580, 125, 568, 601, 676, 273, 875, 551, 87, 875, - 436, 245, 496, 292, 246, 247, 248, 761, 249, 216, - 216, 661, 664, 394, 524, 518, -485, 908, 212, 212, - -92, 281, 531, 531, 212, 249, 537, 531, 762, -99, - -483, 992, 248, 676, 249, 206, -486, -97, 268, -581, - 323, 543, 268, 395, -98, 499, 538, 499, -94, -488, - -96, 508, -487, 399, 501, 299, 569, 744, 676, 439, - 870, 216, -93, 870, 484, 216, 870, -489, 870, 216, - 216, -73, 440, -485, 87, 519, 875, 376, 740, 451, - 717, 87, 87, 263, 474, 475, 835, 263, 883, 87, - 519, 440, -87, -486, 763, -475, 352, 353, -479, 295, - 314, -107, 269, 458, -106, 273, -488, 761, 538, -487, - 523, 340, 341, 878, 445, 761, 870, 765, 446, -106, - -107, 811, -99, 548, -489, -98, 444, 376, 597, 509, - 794, 281, 603, 607, 87, 216, 216, 216, 216, 87, - 216, 216, 925, 870, 980, 870, 673, 870, 605, 870, - 553, 579, -475, 579, 560, -479, 121, 299, 87, -102, - 459, 42, 888, 814, 43, 487, 295, 823, 824, 870, - 921, 267, 267, 607, 607, 267, 463, 794, 467, 87, - -94, 471, 216, 476, 87, 314, 480, 612, 605, 605, - 448, 449, 122, 520, 268, 805, -102, -104, 940, -101, - 482, 526, 487, 714, 714, 761, -102, 508, 59, 304, - 561, 562, 563, 564, 496, 744, 490, 216, 551, 268, - 856, 125, 817, 814, 944, 945, 653, 612, 612, 653, - 212, 212, 508, 485, 268, 515, 246, 247, 981, 263, - 683, 121, 216, 268, 87, 216, 71, 508, 842, 415, - 653, 565, 733, 87, 537, 283, 508, 216, 711, 369, - 390, 87, 837, 268, 263, 653, 216, 268, 522, -595, - 834, 87, -595, -595, 653, 714, 654, 122, 761, 263, - 528, -72, 573, 534, 499, 499, 538, 717, 263, 761, - 510, 513, 1008, 106, 268, 1011, 536, 268, 880, 646, - 654, 655, 249, 87, 376, 540, 125, 268, 725, 206, - 244, 558, 87, 653, 332, 654, 537, 326, 327, 720, - 508, 795, 559, 715, 654, 906, 314, 498, 314, 502, - 216, 577, 574, 516, 949, 950, 898, 87, 653, 786, - 554, 295, 744, 326, 327, -495, 415, 858, 860, 862, - -104, 864, 263, 865, 732, 580, 212, 212, 212, 212, - 893, 566, 567, 654, 529, -101, 899, 901, 581, 328, - 329, 932, 1052, 775, 422, 423, 424, 425, 426, 795, - 796, 898, 121, 798, 121, -297, 837, 589, 654, 283, - 314, 105, 787, 105, 1042, 328, 329, 584, 105, 105, - -297, 796, 587, 590, 105, 105, 105, 592, -104, 105, - -101, 714, 593, 245, 604, 71, 246, 247, 122, 628, - 122, 666, 680, 681, 730, 685, 547, 499, 506, -96, - 758, -93, 267, 278, 968, -297, 278, 775, 775, -581, - 707, 105, -297, 295, 525, 719, 121, 125, 527, 125, - 531, 724, 791, 727, 278, 105, 755, 216, 87, 813, - 816, 797, 816, -87, 799, 1030, 678, 753, 770, 816, - 963, 780, 781, 782, 206, 792, 464, 974, 806, 809, - 807, 814, 122, 976, 822, 750, 268, 268, 828, 216, - 831, 790, 904, 499, 537, -577, 830, 206, 244, 283, - 274, 832, 764, 274, 840, 768, 105, 843, 105, 249, - 849, 125, 684, 568, 853, 857, 607, 859, 861, 790, - 691, 274, 607, 895, 993, 995, 996, 997, 607, 607, - 703, 605, 804, 676, 863, 911, 579, 605, 912, 916, - 930, -337, -102, 605, 605, 920, 839, 427, 922, 599, - 268, 931, 958, 935, 599, 415, -337, 948, 268, -475, - 951, 87, 428, 508, 829, 954, 721, 722, 314, 87, - 612, 956, 960, 216, -475, 245, 612, 216, 246, 247, - 775, 653, 612, 612, 965, 424, 425, 426, 87, 87, - 914, -337, 977, 918, 466, 263, 743, 429, -337, 105, - -104, 466, 87, 966, 430, 216, 248, -577, 249, -475, - 105, 105, 1050, -577, 87, 87, -475, 499, 839, 759, - 978, 987, 87, 759, 121, 873, 994, 283, 283, 988, - 998, 654, 607, 999, 87, 87, 1000, 1013, 489, 1014, - 1015, -102, 706, 1024, -102, -102, 1047, 605, 1026, 718, - 579, 579, 334, 1031, 326, 327, 723, 1033, 947, 777, - 122, 1035, 105, 953, 1037, -580, 105, 729, -581, 1055, - 105, 105, -102, 1057, -102, 105, 453, 726, 212, 225, - 919, 884, 105, 105, 130, 1046, 612, 874, 867, 125, - 105, 428, 1048, 905, 268, 1045, 87, 87, 1018, -104, - 971, 486, -104, -104, 87, 816, 328, 329, 208, 793, - 212, 757, 1002, 468, 121, 500, 0, 751, 752, 121, - 1007, 0, 555, -578, 326, 327, 454, 489, 428, 0, - -104, 0, -104, 430, 0, 105, 105, 105, 105, 105, - 105, 105, 105, 283, 0, 0, 1023, 778, 955, 957, - 122, 0, 0, -287, 0, 122, 121, 0, 583, 105, - 0, 0, 87, 469, 87, 0, 833, 87, -287, 0, - 430, 0, 939, 0, 941, 502, 328, 329, 942, 125, - 105, 579, 268, 105, 125, 105, -294, -479, 105, -294, - -294, 0, 122, 0, 0, 508, 0, 683, 816, 0, - 0, 1003, -479, -287, 873, 216, 0, 873, 0, 873, - -287, 0, 0, 653, 879, 0, -294, -294, 105, -294, - 0, 125, 1006, 0, 808, 0, 212, 263, 105, 105, - 0, 0, 0, 352, 353, -578, 599, -479, 0, -584, - 0, -578, 0, 105, -479, 105, 105, 0, 907, 989, - 990, 0, 0, 0, 105, 694, 694, 873, 105, 0, - 0, 915, 105, 654, -580, 0, 0, 105, 0, 1009, - 0, 1012, 105, 923, 924, 0, 0, 841, 1032, 1034, - 1036, 927, 1038, 1039, 873, 0, 873, 0, 873, 0, - 873, 0, 0, 0, 933, 852, 0, 0, -581, 929, - 0, -410, 0, -584, 105, 489, 1025, 0, 0, 1027, - 873, 245, 489, 105, 246, 247, 245, 0, -584, 246, - 247, 0, 1056, 1058, 1059, 1060, 663, 665, -580, 215, - 215, 105, 1062, 0, 0, 215, 264, 264, 105, 0, - 264, 1049, 248, -580, 249, 0, 1051, 248, 1053, 249, - 0, -584, 1054, -584, 0, 967, 0, -580, 663, 665, - -584, 0, -581, 975, 0, -410, 0, 287, 289, 290, - 291, 0, 1061, 0, 264, 307, -580, -581, -580, 477, - -410, 0, -580, 0, 928, -580, 343, 344, 517, 0, - 759, 0, 0, 879, 428, 0, 879, 0, 879, 0, - 937, 0, 0, 428, 0, 0, 728, 0, 0, 0, - -581, 0, -581, -410, 0, -410, -581, 0, 0, -581, - 0, 1019, -410, 1020, 0, 0, 1021, 0, 541, 478, - 0, 641, 642, 0, 0, 643, 430, 215, 469, 325, - 326, 327, 0, 428, 0, 430, 879, 0, 0, 803, - 174, 175, 176, 177, 178, 179, 180, 181, 105, 105, - 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, - 0, 0, 0, 879, 0, 879, 0, 879, 542, 879, - 188, 189, 190, -482, 0, 430, -286, 466, -298, 0, - 105, 0, 328, 329, 0, 0, 0, 0, -482, 879, - 0, -286, 0, -298, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 0, 201, 202, 747, 0, 355, - 356, 357, 358, 203, 273, 0, 747, 0, 355, 356, - 357, 358, 0, -482, 0, 359, -286, 784, -298, 0, - -482, 215, 215, -286, 359, -298, 104, 0, 104, 128, - 128, 983, 428, 355, 356, 357, 358, 230, 0, 0, - 0, 0, 105, 347, 348, 349, 350, 351, 0, 359, - 105, 105, 0, 0, 105, 0, 0, 105, 105, 492, - 493, 494, 343, 105, 105, 910, 0, 785, 0, 105, - 105, 0, 1001, 264, 430, 0, 104, 264, 0, 0, - 316, 215, 215, 105, 0, 1016, 105, 428, 850, 354, - 694, 355, 356, 357, 358, 105, 105, 991, 0, 0, - 428, 0, 0, 105, 0, 0, 316, 359, 0, 0, - 336, 326, 327, 0, 0, 105, 105, 0, 0, 338, - 326, 327, 454, 571, 0, 0, 0, 245, 0, 430, - 246, 247, 360, 0, 0, 1017, 0, 0, 361, 362, - 363, 364, 430, 104, 547, 326, 327, 215, 215, 215, - 215, 0, 215, 215, 496, 894, 896, 0, 248, 0, - 249, 900, 902, 328, 329, 0, 365, 105, 0, 366, - 0, 576, 328, 329, 466, 0, 0, 105, 105, 0, - 466, 0, 586, 0, 0, 105, 0, 894, 896, 0, - 900, 902, 0, 0, 598, 0, 0, 328, 329, 609, - 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, - 624, 625, 626, 627, 0, 629, 630, 631, 632, 633, - 634, 635, 636, 637, 638, 639, 640, 0, 0, 264, - 552, 326, 327, 0, 104, 0, 556, 326, 327, 662, - 662, 0, 0, 105, 0, 105, 0, 0, 105, 0, - 0, 557, 326, 327, 264, 0, 767, 215, 355, 356, - 357, 358, 742, 326, 327, 964, 0, 662, 0, 264, - 0, 662, 662, 0, 359, 0, 0, 0, 264, 412, - 413, 0, 0, 328, 329, 0, 105, 705, 964, 328, - 329, 709, 415, 0, 0, 710, 0, 0, 713, 360, - 716, 0, 307, 291, 328, 329, 362, 363, 364, 0, - 104, 0, 0, 0, 0, 328, 329, 104, 104, 662, - 422, 423, 424, 425, 426, 104, 0, 0, 0, 713, - 0, 0, 307, 365, 0, 0, 316, 0, 0, 0, - 0, 0, 264, 0, 0, 0, 0, 0, 354, 0, - 355, 356, 357, 358, 0, 0, 0, 0, 745, 746, - 101, 0, 101, 127, 127, 127, 359, 0, 0, 0, - 104, 229, 0, 0, 754, 104, 0, 0, 0, 0, - 0, 0, 0, 747, 0, 355, 356, 357, 358, 0, - 0, 360, 0, 769, 104, 0, 776, 361, 362, 363, - 364, 359, 0, 0, 0, 0, 0, 0, 0, 0, - 101, 0, 0, 0, 315, 104, 0, 0, -607, 0, - 104, 316, 0, 613, 0, 365, 360, 0, 366, 0, - 0, 0, 748, 354, 0, 355, 356, 357, 358, 0, - 315, 367, 0, 354, 0, 355, 356, 357, 358, 0, - 0, 359, 0, 354, 0, 355, 356, 357, 358, 0, - 0, 359, 0, 613, 613, 0, 0, 0, 0, 215, - 0, 359, 0, 0, 0, 0, 360, 101, 0, 0, - 104, 810, 361, 362, 363, 364, 360, 0, 0, 104, - 0, 0, 361, 362, 363, 364, 360, 104, 0, 0, - 0, 215, 361, 362, 363, 364, 0, 104, 0, 0, - 365, 0, 836, 366, 747, 0, 355, 356, 357, 358, - 365, 713, 307, 366, 0, 0, 367, 0, 0, 0, - 365, 0, 359, 366, 0, 0, 544, 0, 0, 104, - 0, 0, 0, 0, 1004, 0, 0, 747, 104, 355, - 356, 357, 358, 0, 0, 0, 84, 360, 84, 0, - 0, 0, 316, 936, 316, 359, 0, 226, 101, 0, - 0, 0, 0, 104, 0, 0, 0, 882, 0, 0, - 0, 0, 662, 885, 0, 264, 0, 0, 662, 662, - 360, 0, 0, 713, 662, 662, 0, 354, 0, 355, - 356, 357, 358, 0, 0, 0, 84, 0, 0, 0, - 0, 0, 0, 0, 0, 359, 0, 215, 0, 0, - 662, 662, 0, 662, 662, 0, 316, 0, 0, 0, - 0, 854, 0, 926, 0, 0, 0, 0, 291, 0, - 360, 0, 0, 0, 101, 0, 361, 362, 363, 364, - 0, 101, 101, 0, 0, 938, 0, 0, 0, 101, - 0, 0, 0, 0, 0, 0, 943, 0, 0, 0, - 315, 412, 413, 84, 365, 0, 0, 366, 0, 0, - 0, 959, 0, 0, 415, 0, 0, 0, 0, 0, - 0, 961, 962, 0, 104, 0, 0, 0, 662, 0, - 0, 0, 783, 0, 101, 0, 0, 0, 0, 101, - 0, 421, 422, 423, 424, 425, 426, 102, 0, 102, - 0, 662, 0, 0, 0, 0, 0, 0, 101, 307, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 0, 0, 0, 0, 412, 413, 0, 101, - 0, 0, 0, 0, 101, 315, 0, 0, 0, 415, - 0, 0, 0, 0, 84, 0, 0, 102, 0, 0, + 106, 284, 347, 516, 438, 432, 434, 285, 343, 503, + 87, 222, 87, 126, 126, 709, 252, 218, 218, 280, + 205, 229, 300, 218, 218, 218, 206, 282, 218, 399, + 265, 265, 107, 206, 265, 469, 700, 738, 541, 614, + 125, 125, 469, 476, 314, 246, 856, 206, 125, 256, + 664, 667, 307, 311, 270, 270, 651, 536, 270, 246, + 87, 538, 276, 281, 315, 770, 721, 882, 585, 392, + 767, 324, 390, 390, 218, 391, 71, 206, 71, 492, + 448, 678, 267, 273, 296, 554, 274, -107, 524, 549, + 315, 125, 270, 270, 578, 821, 995, 721, 693, 785, + 697, 851, 1019, 346, 806, 807, 831, 703, 718, 280, + 443, -104, 718, 3, 436, 597, 392, 125, 271, 271, + 571, 556, 271, 436, 556, 218, 556, 87, 556, 439, + 556, 334, 336, 338, 340, 777, 473, -109, 500, 575, + 504, -111, 765, 761, -487, 765, 442, 482, 765, -110, + 365, 296, 276, 281, 283, -106, 306, 310, 287, -108, + -105, 333, 904, 42, 327, 328, 43, 492, 910, 293, + 442, 741, -340, -483, 532, 366, -77, 269, 269, 1019, + 680, 269, 778, 393, 572, 852, 395, -340, 247, 995, + 604, 248, 249, 363, 364, 365, -486, -91, 586, 446, + -488, -487, -104, 447, -99, 608, -582, 521, 392, 396, + 59, 390, 390, 465, 466, 305, 329, 330, 87, 250, + 366, 251, -340, -96, 477, 478, 437, 433, -96, -340, + 527, 218, 218, 546, 440, 437, 400, 1001, 534, 534, + 767, 275, 429, 534, 428, 608, 608, 503, -489, 882, + 915, 275, 882, -486, -101, 324, -583, -488, -103, 429, + 540, 206, 820, -491, 490, 300, -102, 501, 541, 501, + 452, 649, -98, 510, 898, 658, -100, -97, 661, 464, + 890, 470, -490, 218, 431, 474, 487, 218, 721, 265, + 479, 218, 218, 265, 430, 87, 454, 699, 699, 679, + 483, 431, 87, 87, 485, -489, -492, 490, 748, -478, + 87, 429, 765, 270, 649, 502, 658, 270, 744, 519, + -491, 315, 498, 817, 518, 679, 416, 296, -482, 882, + 541, 526, 247, 718, 718, 248, 249, 600, 770, -490, + 899, 556, 610, 525, 989, 511, 455, 492, 125, 564, + 565, 566, 567, 431, 492, 87, 218, 218, 218, 218, + 87, 218, 218, -492, 679, 251, -478, 300, 523, 441, + 459, 591, 582, 594, 582, 563, 529, 725, 726, 87, + 522, 271, 610, 610, -484, -482, 606, 557, -76, 679, + 327, 328, 531, 932, 551, 537, 811, 539, -111, 543, + 87, 353, 354, 218, 900, 87, 315, 718, 615, -110, + 906, 908, -483, -112, 561, 416, 676, 895, 765, -103, + 765, 71, 765, 475, 765, 562, 568, 460, 510, 296, + -102, 212, 212, 125, 516, 800, 508, 212, 218, 577, + 269, -104, 329, 330, 265, 425, 426, 427, 615, 615, + 580, 656, -111, 510, 656, 862, 802, 842, -498, 804, + 583, 686, 990, 218, -106, 87, 218, 471, 270, 265, + 510, 783, 715, 657, 522, 656, 87, 802, 584, 510, + 218, 587, 429, 590, 87, -98, 265, 847, 737, 218, + 540, 809, 656, 270, 87, 265, 729, 657, 721, 441, + 689, 656, 887, -110, 592, 801, 501, 501, 696, 593, + 270, 541, 516, 595, 657, 972, 106, 472, 708, 270, + 596, 799, 607, 657, 431, 905, 87, 766, -111, 913, + 631, 469, 840, 792, -108, 87, 206, 669, 270, 445, + 656, 724, 270, 510, 718, 341, 342, 683, 246, 315, + 829, 315, 540, 218, -105, -100, 602, 830, 765, 265, + 87, 602, 657, 684, 335, 656, 327, 328, 928, 516, + 270, 958, 959, 270, 939, -97, 125, 687, 125, -106, + 839, 688, 842, 270, 747, 218, -108, 657, 504, 666, + 668, 758, 71, 608, 690, 576, 781, -105, 550, 608, + 712, 734, 719, 731, 218, 608, 608, 793, 247, 800, + 774, 248, 249, 315, 105, 723, 105, 728, 329, 330, + 801, 105, 105, 666, 668, 449, 450, 105, 105, 105, + 917, -91, 105, 649, 736, 658, 823, 820, -106, 977, + 125, 251, 757, 528, -579, 212, 212, 530, 760, -108, + 501, 711, 1051, 776, 797, 699, 280, 953, 954, 280, + 781, 781, 768, 803, 105, 771, 805, 905, 786, 534, + 787, 732, 488, 810, 788, 248, 249, 280, 105, 798, + 218, 87, 819, 822, 812, 247, 836, 822, 248, 249, + 796, 326, 327, 328, 822, 815, -105, 766, 813, 276, + 820, 206, 276, 828, 1039, 512, 515, 835, -478, 834, + 608, 451, 451, 936, 218, 837, 838, 501, 796, 911, + 276, 845, 848, -478, -300, 558, 206, 327, 328, 105, + 610, 105, 854, 540, -290, 480, 610, 902, 246, -300, + 469, 983, 610, 610, 329, 330, 469, 985, 858, -290, + 429, 516, 860, 864, 866, 868, -579, 870, -478, 871, + 571, 582, -579, 270, 270, -478, 863, 865, 520, 867, + 212, 212, 212, 212, -300, 569, 570, 869, -583, 329, + 330, -300, 764, 429, -290, 481, 764, 87, 872, 510, + 467, -290, 431, 918, 315, 87, 615, 919, 766, 218, + 754, 923, 615, 218, 927, 265, 781, 766, 615, 615, + 929, 656, 937, 942, 87, 87, 921, 769, 472, 925, + 773, 125, 105, 957, 926, 431, 467, 844, 87, 270, + 960, 218, 768, 657, 963, 105, 105, 270, 965, 914, + 87, 87, 501, 967, 974, 602, 969, 610, 87, 722, + 975, 986, 922, 885, 877, 987, 727, 996, 544, 87, + 87, 891, 997, 1003, 930, 931, 1007, 1008, 733, -106, + 679, 247, 934, 429, 248, 249, 1009, 582, 582, 1023, + 681, 1022, 1024, 1056, 940, 956, 1064, 105, 1031, 247, + 962, 105, 248, 249, 1033, 105, 105, 1035, 1027, 105, + 766, 844, 250, 1040, 251, 1042, 105, 105, 545, 763, + -582, 1044, 125, 615, 105, 431, 498, 125, 755, 756, + 250, 1046, 251, 87, 87, 247, -583, 980, 248, 249, + 1066, 87, 822, 1002, 1004, 1005, 1006, 730, 948, 130, + 227, 1055, 874, 901, 903, 1057, 912, 976, 784, 907, + 909, 1054, 489, 208, 125, 984, 250, 1016, 251, 105, + 105, 105, 105, 105, 105, 105, 105, 1032, -106, 964, + 966, -106, -106, 766, 270, 901, 903, 762, 907, 909, + 886, 1011, 0, 105, 766, 0, 0, 84, 0, 84, + 0, 87, 0, 87, 0, 0, 87, 0, 228, -106, + 0, -106, 0, 0, 105, 881, 0, 105, 0, 105, + 582, -108, 105, 0, 0, 1028, -485, 1029, 0, 416, + 1030, 0, 1059, 0, 510, 814, 686, 822, 337, 327, + 328, -485, 0, 877, 218, 1017, 877, 84, 1020, 877, + 265, 877, 105, 353, 354, 1015, 656, 423, 424, 425, + 426, 427, 105, 105, 973, 339, 327, 328, 751, -580, + 356, 357, 358, 359, 270, 0, -485, 105, 657, 105, + 105, 0, 0, -485, 0, 0, 360, 973, 0, 846, + 105, 329, 330, 0, 105, 0, 0, 0, 105, 877, + 947, 0, 949, 105, 212, 0, 950, 857, 105, 0, + 0, 1041, 1043, 1045, 84, 1047, 1048, 880, 329, 330, + -108, 0, 0, -108, -108, 1061, 877, -586, 877, 0, + 877, 247, 877, -482, 248, 249, 0, 0, 212, 0, + 105, 0, 751, 0, 356, 357, 358, 359, -482, 105, + 0, -108, 877, -108, 0, 1065, 1067, 1068, 1069, 855, + 360, 0, 250, 0, 251, 1071, 0, 105, 0, 764, + -289, -301, 886, 0, 105, 886, 0, 886, 998, 999, + 0, -580, 0, -482, 0, -289, -301, -580, 0, 0, + -482, -586, 790, 1010, 0, -582, -583, 935, 0, 105, + 1018, 0, 1021, 0, 0, 84, -586, 429, 429, -413, + 0, 0, 0, 944, 0, 0, 0, 0, 105, 0, + -289, -301, 0, 217, 217, 886, 0, -289, -301, 217, + 266, 266, 0, 1000, 266, 0, 1025, 1034, 0, -586, + 1036, -586, 791, 455, 0, -582, 0, 0, -586, 431, + 431, 429, 886, 0, 886, 212, 886, 0, 886, -582, + -583, 288, 290, 291, 292, 550, 327, 328, 266, 308, + 0, 0, 1058, -413, -582, -583, 0, 1060, 886, 1062, + 344, 345, 84, 1063, 0, 0, 1026, 0, -413, 84, + 84, 0, 0, 431, 105, 105, 1012, 84, 0, 880, + 0, 0, 880, 1070, 880, 0, 0, -582, -583, -582, + -583, 0, 0, -582, -583, 0, -582, -583, 329, 330, + 0, -413, 355, -413, 356, 357, 358, 359, 105, 0, + -413, 217, 0, 0, 0, 555, 327, 328, 0, 0, + 360, 0, 84, 559, 327, 328, 0, 84, 0, 0, + 0, 0, 880, 560, 327, 328, 0, 0, 746, 327, + 328, 0, 0, 0, 0, 361, 84, 0, 0, 0, + 0, 362, 363, 364, 365, 0, 0, 0, 0, 880, + 0, 880, 0, 880, 0, 880, 0, 84, 329, 330, + 0, 0, 84, 0, 0, 611, 329, 330, 0, 366, + -297, 105, 367, -297, -297, 880, 329, 330, 0, 105, + 105, 329, 330, 105, 0, 368, 105, 105, 0, 0, + 0, 0, 105, 105, 0, 0, 0, 0, 105, 105, + -297, -297, 0, -297, 0, 611, 611, 217, 217, 0, + 0, 0, 105, 413, 414, 105, 992, 0, 356, 357, + 358, 359, 84, 0, 105, 105, 416, 348, 349, 350, + 351, 352, 105, 84, 360, 0, 0, 0, 0, 0, + 0, 84, 789, 105, 105, 494, 495, 496, 344, 0, + 0, 84, 0, 422, 423, 424, 425, 426, 427, 266, + 0, 0, 247, 266, 0, 248, 249, 217, 217, 0, + 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 0, 84, 0, 0, 413, 414, 0, 498, + 0, 0, 84, 250, 0, 251, 0, 105, 0, 416, + 0, 355, 0, 356, 357, 358, 359, 105, 105, 0, + 247, 0, 0, 248, 249, 105, 0, 84, 0, 360, + 417, 0, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 217, 217, 217, 217, 0, 217, 217, 0, + -276, 938, 0, 251, 361, 0, 0, 0, 0, 0, + 362, 363, 364, 365, 0, 0, 579, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 589, 0, 0, + 0, 0, 0, 0, 0, 105, 0, 105, 366, 601, + 105, 367, 0, 0, 612, 617, 618, 619, 620, 621, + 622, 623, 624, 625, 626, 627, 628, 629, 630, 0, + 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, + 642, 643, 0, 0, 266, 0, 0, 751, 105, 356, + 357, 358, 359, 0, 665, 665, 0, 751, 0, 356, + 357, 358, 359, 0, 0, 360, 0, 0, 84, 266, + 0, 0, 217, 0, 355, 360, 356, 357, 358, 359, + 0, 0, 0, 0, 665, 0, 266, 0, 665, 665, + 361, 0, 360, 0, 0, 266, 752, 0, 0, 0, + 361, 0, 0, 0, 710, 0, 943, 713, 0, 0, + 0, 714, 0, 0, 717, 0, 720, 361, 308, 292, + 413, 414, 0, 362, 363, 364, 365, 74, 0, 74, + 121, 121, 0, 416, 0, 0, 665, 751, 121, 356, + 357, 358, 359, 0, -609, 0, 717, 0, 0, 308, + 0, 366, 0, 0, 367, 360, 0, 0, 0, 266, + 0, 423, 424, 425, 426, 427, 0, 368, 355, 0, + 356, 357, 358, 359, 84, 749, 750, 74, 0, 0, + 361, 121, 84, 611, 0, 0, 360, 0, 0, 611, + 0, 759, 0, 0, 0, 611, 611, 0, 0, 0, + 0, 84, 84, 0, 0, 0, 0, 121, 0, 0, + 775, 361, 0, 782, 0, 84, 0, 362, 363, 364, + 365, 0, 0, 0, 413, 414, 0, 84, 84, 0, + 0, 0, 0, 0, 0, 84, 0, 416, 0, 0, + 0, 0, 0, 0, 74, 366, 84, 84, 367, 0, + 0, 0, 0, 0, 355, 0, 356, 357, 358, 359, + 0, 547, 420, 421, 422, 423, 424, 425, 426, 427, + 0, 0, 360, 0, 0, 0, 772, 0, 356, 357, + 358, 359, 0, 0, 0, 0, 217, 0, 0, 0, + 0, 0, 0, 0, 360, 0, 0, 361, 816, 0, + 611, 759, 775, 362, 363, 364, 365, 0, 0, 0, + 84, 84, 0, 75, 979, 75, 122, 122, 84, 361, + 217, 0, 0, 0, 122, 0, 363, 364, 365, 0, + 841, 366, 0, 0, 367, 74, 0, 0, 0, 717, + 308, 0, 0, 0, -609, 1013, 0, 0, 0, 0, + 0, 0, 0, 366, 0, 0, 0, -609, -609, -609, + -609, -609, -609, 75, -609, 0, 0, 122, 0, 0, + -609, -609, 0, 0, 0, 0, 0, 0, 84, 0, + 84, -609, -609, 84, -609, -609, -609, -609, -609, 0, + 0, 0, 0, 122, 0, 0, 0, 889, 0, 0, + 0, 0, 665, 892, 0, 266, 0, 0, 665, 665, + 0, 0, 74, 717, 665, 665, 0, 0, 0, 74, + 74, 0, 0, 0, 0, 0, 0, 74, 0, 0, + 75, 0, 0, 0, -609, 0, 0, 217, 121, 0, + 665, 665, 0, 665, 665, 0, 0, 0, 0, -609, + 0, 0, 0, 933, 0, 0, 0, 292, 0, -609, + 0, 0, -609, -609, 0, 0, 0, 0, 0, 0, + 0, 0, 74, 0, 945, 946, 0, 74, 0, 0, + 0, 0, -609, -609, 0, 0, 951, 952, 275, -609, + -609, -609, -609, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 968, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 970, 971, 0, 0, 0, 74, 0, 665, + 0, 75, 74, 121, 0, 74, 0, 355, 0, 356, + 357, 358, 359, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 665, 0, 0, 360, 0, 0, 0, 0, + 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 574, 0, 0, 0, 74, 74, 0, 0, 0, + 361, 0, 0, 0, 0, 0, 362, 363, 364, 365, + 0, 0, 74, 0, 104, 0, 104, 128, 128, 0, + 0, 0, 0, 74, 0, 232, 0, 0, 75, 0, + 0, 74, 0, 0, 366, 75, 75, 367, 0, 0, + 0, 74, 0, 75, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 104, 0, 0, 0, 317, 0, + 266, 0, 0, 74, 0, 0, 0, 0, 0, 0, + 0, 0, 74, 0, 0, 789, 0, 0, 75, 0, + 0, 0, 0, 75, 317, 0, 121, 0, 121, 0, + 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, + 0, 0, 75, 401, 402, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 0, 0, 0, 0, 413, + 414, 104, 0, 75, 0, 0, 0, 0, 75, 122, + 0, 75, 416, 355, 0, 356, 357, 358, 359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 0, 0, 0, 0, 0, 104, 0, 0, - -273, 0, 0, 0, 316, 104, 613, 0, 0, 0, - 0, 0, 613, 0, 101, 0, 0, 264, 613, 613, - 0, 0, 0, 101, 104, 104, 0, 0, 0, 0, - 0, 101, 0, 0, 102, 0, 0, 0, 104, 0, - 84, 101, 0, 0, 0, 0, 0, 84, 84, 0, - 104, 104, 0, 0, 0, 84, 0, 0, 104, 0, - 0, 354, 0, 355, 356, 357, 358, 0, 0, 0, - 104, 104, 0, 101, 0, 0, 412, 413, 0, 359, - 0, 0, 101, 0, 0, 0, 0, 0, 0, 415, - 0, 0, 0, 0, 128, 0, 315, 0, 315, 128, - 84, 0, 0, 0, 360, 84, 0, 101, 0, 0, - 361, 362, 363, 364, 419, 420, 421, 422, 423, 424, - 425, 426, 613, 0, 84, 102, -608, -608, -608, -608, - 404, 405, 104, 104, -608, -608, 973, 0, 365, 0, - 104, 366, 412, 413, 0, 84, 0, 0, 0, 0, - 84, 0, 0, 608, 0, 415, 0, 0, 0, 0, - 315, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 417, 418, - 419, 420, 421, 422, 423, 424, 425, 426, 0, 0, - 0, 0, 0, 608, 608, 0, 0, 0, 104, 0, - 104, 102, 0, 104, 0, 0, 0, 0, 102, 102, - 84, 0, 0, 0, 0, 0, 102, 0, 0, 84, - 0, 0, 0, 0, 0, 0, 0, 84, 101, 0, - -607, 0, 0, 0, 0, 0, 0, 84, 0, 0, - 0, 0, 0, -607, -607, -607, -607, -607, -607, 0, - -607, 0, 0, 0, 0, 0, -607, -607, 0, 0, - 0, 102, 0, 0, 0, 0, 102, -607, -607, 84, - -607, -607, -607, -607, -607, 0, 0, 0, 84, 0, - 0, 0, 0, 0, 0, 102, 0, 0, 0, 0, + 121, 360, 0, 417, 0, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 0, 0, 859, 0, 0, + 0, 75, 75, 0, 0, 0, 361, 0, 0, 0, + 0, 0, 362, 363, 364, 365, 0, 0, 75, 0, + 101, 0, 101, 127, 127, 127, 0, 0, 0, 75, + 0, 231, 0, 0, 0, 0, 0, 75, 0, 0, + 366, 0, 104, 367, 0, 0, 0, 75, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 84, 0, 0, 102, 0, 0, 0, - 0, 102, 0, 0, 102, 0, 0, 0, 0, 0, - -607, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 101, 0, 0, 0, -607, 0, 0, 315, 101, - 0, 0, 0, 0, 0, -607, 0, 0, -607, -607, - 0, 0, 0, 0, 102, 102, 0, 0, 101, 101, - 0, 0, 0, 0, 0, 0, 0, 0, -607, -607, - 0, 102, 101, 0, 273, -607, -607, -607, -607, 0, - 102, 0, 0, 0, 101, 101, 0, 0, 102, 0, - 0, 0, 101, 0, 0, 0, 0, 0, 102, 0, - 0, 0, 0, 0, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 650, 651, 84, 0, 652, 0, 127, 0, - 102, 0, 0, 127, 0, 0, 0, 0, 0, 102, - 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, - 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, - 187, 0, 0, 0, 102, 0, 101, 101, 0, 0, - 972, 188, 189, 190, 101, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 316, 0, 0, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 0, 201, 202, 0, 0, - 0, 0, 0, 0, 203, 273, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, - 0, 0, 101, 0, 101, 84, 608, 101, 0, 0, - 671, 642, 608, 0, 672, 0, 0, 0, 608, 608, - 0, 0, 0, 0, 84, 84, 0, 0, 0, 174, - 175, 176, 177, 178, 179, 180, 181, 0, 84, 182, - 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, - 84, 84, 0, 0, 0, 102, 0, 0, 84, 188, - 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, - 84, 84, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 0, 201, 202, 400, 401, 402, 403, - 404, 405, 203, 273, 408, 409, 0, 0, 0, 0, - 0, 0, 412, 413, 0, 0, 0, 0, 0, 0, - 0, 0, 608, 0, 0, 415, 0, 0, 0, 0, - 0, 0, 84, 84, 0, 0, 970, 0, 0, 0, - 84, 0, 0, 0, 0, 0, 0, 0, 417, 418, - 419, 420, 421, 422, 423, 424, 425, 426, 102, 0, - 0, 0, 0, 0, 0, 0, 102, 102, 0, 0, - 0, 0, 0, 102, 0, 0, 0, 0, 0, 102, - 102, 0, 0, 0, 0, 102, 102, 0, 400, 401, - 402, 403, 404, 405, 406, 0, 408, 409, 84, 102, - 84, 0, 0, 84, 412, 413, 0, 0, 0, 0, - 0, 102, 102, 0, 0, 0, 0, 415, 0, 102, - 0, 0, 783, 0, 0, 0, 0, 0, 0, 0, - 0, 102, 102, 0, 0, 0, 0, 0, 0, 0, - 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 0, 0, 0, 0, 412, 413, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 415, - 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 102, 102, 0, 0, 0, 0, 0, - 416, 102, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -607, 4, 0, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, - 15, 0, 16, 17, 18, 19, 0, 0, 0, 0, - 0, 20, 21, 22, 23, 24, 25, 26, 0, 102, - 27, 102, 0, 0, 102, 0, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, - 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, - 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, - 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, - 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, - 0, 61, 62, 63, -288, 64, -607, 0, 0, -607, - -607, 0, 0, 0, 0, 0, 0, -288, -288, -288, - -288, -288, -288, 0, -288, 65, 66, 67, 0, 0, - 0, -288, -288, -288, 0, 0, 0, -607, 0, -607, - 0, -288, -288, 0, -288, -288, -288, -288, -288, 0, + 316, 0, 122, 0, 122, 0, 0, 0, 0, 0, + 0, 0, 0, 75, 0, 0, 0, 0, 0, 104, + 0, 0, 0, 0, 0, 0, 104, 104, 0, 0, + 0, 0, 0, 0, 104, 0, 0, 101, 0, 0, + 0, 0, 0, 0, 0, 317, 0, 0, 0, 0, + 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, + 0, 121, 74, 74, 0, 0, 122, 0, 0, 74, + 0, 0, 0, 0, 0, 74, 74, 0, 0, 104, + 0, 74, 74, 0, 104, 401, 402, 403, 404, 405, + 406, 407, 0, 409, 410, 74, 0, 0, 0, 0, + 0, 413, 414, 104, 0, 0, 0, 74, 74, 0, + 0, 0, 0, 0, 416, 74, 0, 0, 0, 0, + 0, 0, 0, 0, 104, 0, 74, 74, 101, 104, + 317, 0, 616, 0, 75, 0, 0, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 0, 0, 0, + 0, 0, 121, 0, 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -288, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -288, -288, -288, -288, - -288, -288, -288, -288, -288, -288, -288, -288, 0, 0, - 0, 0, -288, -288, -288, 0, 0, -288, 0, 0, - 0, 0, 0, -288, 0, -288, 0, 0, 0, -288, - 0, 0, 0, 0, 0, 0, 0, -288, 0, -288, - 0, 0, -288, -288, 0, 0, -288, -288, -288, -288, - -288, -288, -288, -288, -288, -288, -288, -288, 0, 0, - -409, 0, 0, -288, -288, -288, -288, 0, 0, -288, - -288, -288, -288, -409, -409, -409, -409, -409, -409, 0, - -409, 0, 0, 0, 0, 0, -409, -409, -409, 0, - 0, 0, 0, 0, 0, 0, 0, -409, -409, 0, - -409, -409, -409, -409, -409, 0, 0, 0, 0, 0, + 0, 0, 616, 616, 0, 0, 0, 0, 0, 0, + 74, 0, 0, 0, 0, 0, 0, 0, 0, 104, + 74, 74, 0, 0, 121, 0, 0, 0, 74, 0, + 104, 0, 0, 0, 0, 101, 0, 0, 104, 0, + 0, 0, 101, 101, 0, 0, 0, 0, 104, 0, + 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 316, 0, 0, 0, 0, 0, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 122, 75, 75, + 104, 0, 0, 0, 0, 75, 0, 0, 74, 104, + 74, 75, 75, 74, 0, 101, 0, 75, 75, 0, + 101, 0, 0, 317, 0, 317, 0, 0, 0, 0, + 0, 75, 0, 0, 104, 0, 0, 0, 0, 101, + 0, 0, 0, 75, 75, 0, 0, 0, 0, 0, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 75, 75, 0, 101, 316, 0, 0, 0, + 0, 0, 0, 102, 0, 102, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 317, 122, 0, + 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, -610, -610, 75, 0, 0, 0, + 413, 414, 0, 102, 0, 101, 75, 75, 0, 0, + 122, 0, 0, 416, 75, 0, 101, 0, 0, 0, + 0, 0, 0, 861, 101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 101, 104, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, 0, 0, 0, 0, + 0, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 0, 0, 0, 101, 413, 414, 0, + 102, 0, 0, 0, 75, 101, 75, 0, 0, 75, + 416, 0, 0, 0, 0, 0, 0, 0, 0, 316, + 0, 316, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 417, 0, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -409, -409, -409, -409, -409, -409, -409, -409, - -409, -409, -409, -409, 0, 0, 0, 0, -409, -409, - -409, 0, 0, -409, 0, 0, 0, 0, 0, -409, - 0, -409, 0, 0, 0, -409, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -409, 0, 0, -409, -409, - 0, 0, -409, 0, -409, -409, -409, -409, -409, -409, - -409, -409, -409, -409, 0, 0, -475, 0, -409, -409, - -409, -409, -409, 0, 273, -409, -409, -409, -409, -475, - -475, -475, -475, -475, -475, 0, -475, 0, 0, 0, - 0, 0, 0, -475, -475, 0, 0, 0, 0, 0, - 0, 0, 0, -475, -475, 0, -475, -475, -475, -475, - -475, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -475, -475, - -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, - 0, 0, 0, 0, -475, -475, -475, 0, -475, -475, - 0, 0, 0, 0, 0, -475, 0, -475, 0, 0, - 0, -475, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -475, 0, 0, -475, -475, 0, -475, -475, 0, - -475, -475, -475, -475, -475, -475, -475, -475, -475, -475, - 0, 0, -607, 0, 0, -475, -475, -475, -475, 0, - 0, -475, -475, -475, -475, -607, -607, -607, -607, -607, - -607, 0, -607, 0, 0, 0, 0, 0, -607, -607, - -607, 0, 0, 0, 0, 0, 0, 0, 0, -607, - -607, 0, -607, -607, -607, -607, -607, 0, 0, 0, + 0, 104, 873, 0, 0, 0, 0, 0, 317, 104, + 616, 0, 0, 316, 0, 0, 616, 0, 0, 0, + 0, 102, 616, 616, 0, 0, 0, 0, 104, 104, + 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 104, 0, 0, 0, 413, 414, 0, 0, + 0, 0, 0, 0, 104, 104, 0, 0, 0, 416, + 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 104, 104, 0, 0, 0, 0, 0, + 417, 101, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 0, 0, 0, 0, 0, 0, 102, 128, + 0, 0, 0, 0, 128, 102, 102, 0, 0, 0, + 0, 0, 0, 102, 401, 402, 403, 404, 405, 406, + 407, 408, 409, 410, 411, 412, 0, 616, 0, 0, + 413, 414, 0, 0, 0, 0, 0, 104, 104, 0, + 0, 982, 0, 416, 0, 104, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 102, 0, + 0, 0, 0, 102, 417, 0, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, 0, 0, 0, 0, + 0, 0, 102, 0, -276, 0, 0, 101, 0, 0, + 0, 0, 0, 0, 316, 101, 0, 0, 0, 0, + 0, 0, 0, 102, 0, 104, 0, 104, 102, 0, + 104, 102, 0, 0, 101, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 101, -291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 101, -291, -291, -291, -291, -291, -291, 101, -291, + 0, 102, 102, 0, 0, 0, -291, -291, -291, 101, + 101, 0, 0, 0, 0, 0, -291, -291, 102, -291, + -291, -291, -291, -291, 0, 0, 0, 0, 0, 102, + 0, 0, 0, 0, 0, 127, -291, 102, 0, 0, + 127, 0, 0, 0, 0, 0, 0, 102, 0, 0, + 0, -291, -291, -291, -291, -291, -291, -291, -291, -291, + -291, -291, -291, 0, 0, 0, 0, -291, -291, -291, + 0, 0, -291, 101, 101, 0, 0, 981, -291, 102, + -291, 101, 0, 0, -291, 0, 0, 0, 102, 0, + 0, 0, -291, 0, -291, 0, 0, -291, -291, 0, + 0, -291, -291, -291, -291, -291, -291, -291, -291, -291, + -291, -291, -291, 102, 0, 0, 0, 0, -291, -291, + -291, -291, 0, 0, -291, -291, -291, -291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -607, -607, -607, -607, -607, -607, - -607, -607, -607, -607, -607, -607, 0, 0, 0, 0, - -607, -607, -607, 0, 0, -607, 0, 0, 0, 0, - 0, -607, 0, -607, 0, 0, 0, -607, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -607, 0, 0, - -607, -607, 0, 0, -607, 0, -607, -607, -607, -607, - -607, -607, -607, -607, -607, -607, 0, 0, -607, 0, - -607, -607, -607, -607, -607, 0, 273, -607, -607, -607, - -607, -607, -607, -607, -607, -607, -607, 0, -607, 0, - 0, 0, 0, 0, 0, -607, -607, 0, 0, 0, - 0, 0, 0, 0, 0, -607, -607, 0, -607, -607, - -607, -607, -607, 0, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 101, -609, 4, 101, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, + 0, 0, 0, 15, 0, 16, 17, 18, 19, 0, + 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, + 26, 0, 0, 27, 0, 0, 0, 0, 0, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, + 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, + 0, 0, 0, 0, 102, 51, 0, 0, 52, 53, + 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, + 58, 59, 60, 0, 61, 62, 63, 0, 64, -609, + 0, 0, -609, -609, 0, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 0, 65, 66, + 67, 413, 414, 0, 0, 0, 0, 0, 0, 0, + -609, 0, -609, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 417, 0, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 0, 0, 0, + 0, 0, 0, 0, 0, -277, 0, 0, 0, 0, + 102, 0, 0, 0, 0, 0, 0, 0, 102, 102, + 0, 0, 0, 0, 0, 102, 0, 0, 0, 0, + 0, 102, 102, 0, 0, 0, 0, 102, 102, 0, + 0, 0, 0, 0, 0, -610, -610, -610, -610, 405, + 406, 102, -412, -610, -610, 0, 0, 0, 0, 0, + 0, 413, 414, 102, 102, -412, -412, -412, -412, -412, + -412, 102, -412, 0, 416, 0, 0, 0, -412, -412, + -412, 0, 102, 102, 0, 0, 0, 0, 0, -412, + -412, 0, -412, -412, -412, -412, -412, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, - -607, -607, 0, 0, 0, 0, -607, -607, -607, 0, - 0, -607, 0, 0, 0, 0, 0, -607, 0, -607, - 0, 0, 0, -607, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -607, 0, 0, -607, -607, 0, 0, - -607, 0, -607, -607, -607, -607, -607, -607, -607, -607, - -607, -607, 0, 0, -584, 0, 0, -607, -607, -607, - -607, 0, 273, -607, -607, -607, -607, -584, -584, -584, - 0, -584, -584, 0, -584, 0, 0, 0, 0, 0, - -584, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -584, -584, 0, -584, -584, -584, -584, -584, 0, + 0, 0, 0, 0, -412, -412, -412, -412, -412, -412, + -412, -412, -412, -412, -412, -412, 102, 0, 0, 0, + -412, -412, -412, 0, 0, -412, 102, 102, 0, 0, + 0, -412, 0, -412, 102, 0, 0, -412, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -412, 0, 0, + -412, -412, 0, 0, -412, 0, -412, -412, -412, -412, + -412, -412, -412, -412, -412, -412, 0, 0, 0, 0, + -412, -412, -412, -412, -412, -478, 275, -412, -412, -412, + -412, 0, 0, 0, 0, 0, 0, 0, -478, -478, + -478, -478, -478, -478, 102, -478, 102, 0, 0, 102, + 0, 0, -478, -478, 0, 0, 0, 0, 0, 0, + 0, 0, -478, -478, 0, -478, -478, -478, -478, -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 493, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -478, -478, -478, + -478, -478, -478, -478, -478, -478, -478, -478, -478, 0, + 0, 0, 0, -478, -478, -478, 0, -478, -478, 0, + 0, 0, 0, 0, -478, 0, -478, 0, 0, 0, + -478, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -478, 0, 0, -478, -478, 0, -478, -478, 0, -478, + -478, -478, -478, -478, -478, -478, -478, -478, -478, 0, + 0, -609, 0, 0, -478, -478, -478, -478, 0, 0, + -478, -478, -478, -478, -609, -609, -609, -609, -609, -609, + 0, -609, 0, 0, 0, 0, 0, -609, -609, -609, + 0, 0, 0, 0, 0, 0, 0, 0, -609, -609, + 0, -609, -609, -609, -609, -609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -584, -584, -584, -584, - -584, -584, -584, -584, -584, -584, -584, -584, 0, 0, - 0, 0, -584, -584, -584, 0, 788, -584, 0, 0, - 0, 0, 0, 0, 0, -584, 0, 0, 0, -584, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -584, - 0, 0, -584, -584, 0, -103, -584, 0, -584, -584, - -584, -584, -584, -584, -584, -584, -584, -584, 0, 0, - -584, 0, -584, -584, -584, 0, -95, 0, 0, -584, - -584, -584, -584, -584, -584, -584, 0, -584, -584, 0, - -584, 0, 0, 0, 0, 0, -584, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -584, -584, 0, - -584, -584, -584, -584, -584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -609, -609, -609, -609, -609, -609, -609, + -609, -609, -609, -609, -609, 0, 0, 0, 0, -609, + -609, -609, 0, 0, -609, 0, 0, 0, 0, 0, + -609, 0, -609, 0, 0, 0, -609, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -609, 0, 0, -609, + -609, 0, 0, -609, 0, -609, -609, -609, -609, -609, + -609, -609, -609, -609, -609, 0, 0, -609, 0, -609, + -609, -609, -609, -609, 0, 275, -609, -609, -609, -609, + -609, -609, -609, -609, -609, -609, 0, -609, 0, 0, + 0, 0, 0, 0, -609, -609, 0, 0, 0, 0, + 0, 0, 0, 0, -609, -609, 0, -609, -609, -609, + -609, -609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -584, -584, -584, -584, -584, -584, -584, -584, - -584, -584, -584, -584, 0, 0, 0, 0, -584, -584, - -584, 0, 788, -584, 0, 0, 0, 0, 0, 0, - 0, -584, 0, 0, 0, -584, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -584, 0, 0, -584, -584, - 0, -103, -584, 0, -584, -584, -584, -584, -584, -584, - -584, -584, -584, -584, 0, 0, -297, 0, -584, -584, - -584, 0, -584, 0, 0, -584, -584, -584, -584, -297, - -297, -297, 0, -297, -297, 0, -297, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -609, + -609, -609, -609, -609, -609, -609, -609, -609, -609, -609, + -609, 0, 0, 0, 0, -609, -609, -609, 0, 0, + -609, 0, 0, 0, 0, 0, -609, 0, -609, 0, + 0, 0, -609, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -609, 0, 0, -609, -609, 0, 0, -609, + 0, -609, -609, -609, -609, -609, -609, -609, -609, -609, + -609, 0, 0, -586, 0, 0, -609, -609, -609, -609, + 0, 275, -609, -609, -609, -609, -586, -586, -586, 0, + -586, -586, 0, -586, 0, 0, 0, 0, 0, -586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -297, -297, 0, -297, -297, -297, -297, - -297, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -586, -586, 0, -586, -586, -586, -586, -586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -297, -297, - -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, - 0, 0, 0, 0, -297, -297, -297, 0, 789, -297, - 0, 0, 0, 0, 0, 0, 0, -297, 0, 0, - 0, -297, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -297, 0, 0, -297, -297, 0, -105, -297, 0, - -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, - 0, 0, -297, 0, 0, -297, -297, 0, -97, 0, - 0, -297, -297, -297, -297, -297, -297, -297, 0, -297, - -297, 0, -297, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -297, - -297, 0, -297, -297, -297, -297, -297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -586, -586, -586, -586, -586, + -586, -586, -586, -586, -586, -586, -586, 0, 0, 0, + 0, -586, -586, -586, 0, 794, -586, 0, 0, 0, + 0, 0, 0, 0, -586, 0, 0, 0, -586, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -586, 0, + 0, -586, -586, 0, -107, -586, 0, -586, -586, -586, + -586, -586, -586, -586, -586, -586, -586, 0, 0, -586, + 0, -586, -586, -586, 0, -99, 0, 0, -586, -586, + -586, -586, -586, -586, -586, 0, -586, -586, 0, -586, + 0, 0, 0, 0, 0, -586, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -586, -586, 0, -586, + -586, -586, -586, -586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -297, -297, -297, -297, -297, -297, - -297, -297, -297, -297, -297, -297, 0, 0, 0, 0, - -297, -297, -297, 0, 789, -297, 0, 0, 0, 0, - 0, 0, 0, -297, 0, 0, 0, -297, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -297, 0, 0, - -297, -297, 0, -105, -297, 0, -297, -297, -297, -297, - -297, -297, -297, -297, -297, -297, 0, 0, 0, 0, - 0, -297, -297, 0, -297, 0, 0, -297, -297, -297, - -297, 293, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, -607, -607, -607, 0, 0, -607, 15, - 0, 16, 17, 18, 19, 0, 0, 0, 0, 0, - 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, - 0, 0, 0, 0, 0, 28, 0, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, - 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, - 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, - 0, 51, 0, 0, 52, 53, 0, 54, 55, 0, - 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, - 61, 62, 63, 0, 64, -607, 0, 0, -607, -607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 65, 66, 67, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -607, 293, -607, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, - 0, -607, 0, -607, -607, 15, 0, 16, 17, 18, - 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, - 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, - 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, + 0, -586, -586, -586, -586, -586, -586, -586, -586, -586, + -586, -586, -586, 0, 0, 0, 0, -586, -586, -586, + 0, 794, -586, 0, 0, 0, 0, 0, 0, 0, + -586, 0, 0, 0, -586, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -586, 0, 0, -586, -586, 0, + -107, -586, 0, -586, -586, -586, -586, -586, -586, -586, + -586, -586, -586, 0, 0, -300, 0, -586, -586, -586, + 0, -586, 0, 0, -586, -586, -586, -586, -300, -300, + -300, 0, -300, -300, 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, - 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, - 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, - 64, -607, 0, 0, -607, -607, 0, 0, 0, 0, + 0, 0, -300, -300, 0, -300, -300, -300, -300, -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 65, 66, 67, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -607, 293, -607, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 0, 0, -607, 0, 0, - -607, 15, -607, 16, 17, 18, 19, 0, 0, 0, - 0, 0, 20, 21, 22, 23, 24, 25, 26, 0, - 0, 27, 0, 0, 0, 0, 0, 28, 0, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, - 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, - 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, - 0, 0, 0, 51, 0, 0, 52, 53, 0, 54, - 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, - 60, 0, 61, 62, 63, 0, 64, -607, 0, 0, - -607, -607, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 65, 66, 67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -607, 293, - -607, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 0, 0, -607, 0, 0, -607, 15, 0, 16, - 17, 18, 19, 0, 0, 0, 0, 0, 20, 21, - 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, - 0, 0, 0, 28, 0, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, - 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 49, 50, 0, 0, 0, 0, 0, 51, - 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, - 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, - 63, 0, 64, -607, 0, 0, -607, -607, 4, 0, + 0, 0, 0, 0, 0, 0, 0, -300, -300, -300, + -300, -300, -300, -300, -300, -300, -300, -300, -300, 0, + 0, 0, 0, -300, -300, -300, 0, 795, -300, 0, + 0, 0, 0, 0, 0, 0, -300, 0, 0, 0, + -300, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -300, 0, 0, -300, -300, 0, -109, -300, 0, -300, + -300, -300, -300, -300, -300, -300, -300, -300, -300, 0, + 0, -300, 0, 0, -300, -300, 0, -101, 0, 0, + -300, -300, -300, -300, -300, -300, -300, 0, -300, -300, + 0, -300, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -300, -300, + 0, -300, -300, -300, -300, -300, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -300, -300, -300, -300, -300, -300, -300, + -300, -300, -300, -300, -300, 0, 0, 0, 0, -300, + -300, -300, 0, 795, -300, 0, 0, 0, 0, 0, + 0, 0, -300, 0, 0, 0, -300, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -300, 0, 0, -300, + -300, 0, -109, -300, 0, -300, -300, -300, -300, -300, + -300, -300, -300, -300, -300, 0, 0, 0, 0, 0, + -300, -300, 0, -300, 0, 0, -300, -300, -300, -300, + 294, 0, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, -609, -609, -609, 0, 0, -609, 15, 0, + 16, 17, 18, 19, 0, 0, 0, 0, 0, 20, + 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, + 0, 0, 0, 0, 28, 0, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, + 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, + 51, 0, 0, 52, 53, 0, 54, 55, 0, 56, + 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, + 62, 63, 0, 64, -609, 0, 0, -609, -609, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 65, 66, 67, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -609, 294, -609, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, + -609, 0, -609, -609, 15, 0, 16, 17, 18, 19, + 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, + 25, 26, 0, 0, 27, 0, 0, 0, 0, 0, + 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, + 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, + 50, 0, 0, 0, 0, 0, 51, 0, 0, 52, + 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, + 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, + -609, 0, 0, -609, -609, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, + 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -609, 294, -609, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 0, 0, -609, 0, 0, -609, + 15, -609, 16, 17, 18, 19, 0, 0, 0, 0, + 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, + 27, 0, 0, 0, 0, 0, 28, 0, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, + 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, + 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, + 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, + 0, 61, 62, 63, 0, 64, -609, 0, 0, -609, + -609, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 65, 66, 67, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -609, 294, -609, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 0, 0, 65, 66, 67, 0, 15, 0, 16, 17, - 18, 19, 0, 0, -607, 0, -607, 20, 21, 22, + 0, 0, -609, 0, 0, -609, 15, 0, 16, 17, + 18, 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, - 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, - 0, 64, -607, 0, 0, -607, -607, 0, 0, 0, + 0, 64, -609, 0, 0, -609, -609, 4, 0, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, + 0, 65, 66, 67, 0, 15, 0, 16, 17, 18, + 19, 0, 0, -609, 0, -609, 20, 21, 22, 23, + 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, + 0, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, + 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 65, 66, 67, 0, 0, -607, 0, 0, 0, - 0, 0, 0, -607, 293, -607, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 0, -607, -607, 0, - 0, 0, 15, 0, 16, 17, 18, 19, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, - 0, 0, 27, 0, 0, 0, 0, 0, 28, 0, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, - 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, - 0, 0, 0, 0, 51, 0, 0, 52, 53, 0, - 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, - 59, 60, 0, 61, 62, 63, 0, 64, -607, 0, - 0, -607, -607, 293, 0, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 0, 0, 65, 66, 67, - 0, 15, 0, 16, 17, 18, 19, 0, 0, -607, - 0, -607, 20, 21, 22, 23, 24, 25, 26, 0, + 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, + 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, + 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, + 64, -609, 0, 0, -609, -609, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 65, 66, 67, 0, 0, -609, 0, 0, 0, 0, + 0, 0, -609, 294, -609, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 0, -609, -609, 0, 0, + 0, 15, 0, 16, 17, 18, 19, 0, 0, 0, + 0, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, - 0, 0, 0, 51, 0, 0, 294, 53, 0, 54, + 0, 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, - 60, 0, 61, 62, 63, 0, 64, -607, 0, 0, - -607, -607, 293, 0, 5, 6, 7, 8, 9, 10, + 60, 0, 61, 62, 63, 0, 64, -609, 0, 0, + -609, -609, 294, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 65, 66, 67, 0, - 15, 0, 16, 17, 18, 19, 0, -607, -607, 0, - -607, 20, 21, 22, 23, 24, 25, 26, 0, 0, + 15, 0, 16, 17, 18, 19, 0, 0, -609, 0, + -609, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, - 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, + 0, 0, 51, 0, 0, 295, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, - 0, 61, 62, 63, 0, 64, -607, 0, 0, -607, - -607, 293, 0, 5, 6, 7, 8, 9, 10, 11, + 0, 61, 62, 63, 0, 64, -609, 0, 0, -609, + -609, 294, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 65, 66, 67, 0, 15, - 0, 16, 17, 18, 19, 0, -607, -607, 0, -607, + 0, 16, 17, 18, 19, 0, -609, -609, 0, -609, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, @@ -3009,258 +3060,270 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, - 61, 62, 63, 0, 64, -607, 0, 0, -607, -607, + 61, 62, 63, 0, 64, -609, 0, 0, -609, -609, + 294, 0, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 0, 0, 65, 66, 67, 0, 15, 0, + 16, 17, 18, 19, 0, -609, -609, 0, -609, 20, + 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, + 0, 0, 0, 0, 28, 0, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, + 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, + 51, 0, 0, 52, 53, 0, 54, 55, 0, 56, + 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, + 62, 63, 0, 64, -609, 0, 0, -609, -609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 65, 66, 67, 0, 0, -607, - 0, 0, 0, 0, 0, 0, -607, 293, -607, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, - 0, -607, 0, 0, 0, 15, 0, 16, 17, 18, - 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, - 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, - 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, - 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, - 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, - 64, -607, 0, 0, -607, -607, 0, 0, 5, 6, + 0, 0, 0, 65, 66, 67, 0, 0, -609, 0, + 0, 0, 0, 0, 0, -609, 294, -609, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, - 65, 66, 67, 0, 15, 0, 16, 17, 18, 19, - 0, 0, -607, 0, -607, 20, 21, 22, 23, 24, + -609, 0, 0, 0, 15, 0, 16, 17, 18, 19, + 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, 0, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, - 245, 0, 0, 246, 247, 0, 0, 5, 6, 7, + -609, 0, 0, -609, -609, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 65, 66, 67, 0, 15, 0, 16, 17, 18, 19, 0, - 0, 248, 0, 249, 20, 21, 22, 23, 24, 25, + 0, -609, 0, -609, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, 0, 28, - 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, - 58, 59, 60, 0, 61, 62, 63, 0, 64, 245, - 0, 0, 246, 247, 0, 0, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 0, 0, 0, 65, 66, + 58, 59, 60, 0, 61, 62, 63, 0, 64, 247, + 0, 0, 248, 249, 0, 0, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 0, 0, 65, 66, 67, 0, 15, 0, 16, 17, 18, 19, 0, 0, - 248, 0, 249, 20, 21, 22, 23, 24, 25, 26, - 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, - 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 250, 0, 251, 20, 21, 22, 23, 24, 25, 26, + 0, 0, 27, 0, 0, 0, 0, 0, 28, 0, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, - 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, - 54, 55, 0, 0, 0, 0, 0, 57, 0, 58, - 59, 60, 0, 61, 62, 63, 0, 64, 245, 0, - 0, 246, 247, 0, 0, 5, 6, 7, 8, 9, + 0, 0, 0, 0, 51, 0, 0, 52, 53, 0, + 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, + 59, 60, 0, 61, 62, 63, 0, 64, 247, 0, + 0, 248, 249, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 65, 66, 67, - 0, 15, 0, 108, 109, 18, 19, 0, 0, 248, - 0, 249, 110, 111, 112, 23, 24, 25, 26, 0, - 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 0, 16, 17, 18, 19, 0, 0, 250, + 0, 251, 20, 21, 22, 23, 24, 25, 26, 0, + 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, 55, 0, 0, 0, 0, 0, 57, 0, 58, 59, - 60, 0, 61, 62, 63, 0, 64, 245, 0, 0, - 246, 247, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 65, 262, 67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, - 249, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 0, 0, 0, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 0, 0, - 0, 0, 0, 165, 166, 167, 168, 169, 170, 171, - 172, 36, 37, 173, 39, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, - 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, - 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 188, 189, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 61, 62, 63, 0, 64, 247, 0, 0, + 248, 249, 0, 0, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 0, 0, 0, 65, 66, 67, 0, + 15, 0, 108, 109, 18, 19, 0, 0, 250, 0, + 251, 110, 111, 112, 23, 24, 25, 26, 0, 0, + 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, + 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, + 0, 0, 211, 0, 0, 119, 53, 0, 54, 55, + 0, 0, 0, 0, 0, 57, 0, 58, 59, 60, + 0, 61, 62, 63, 0, 64, 247, 0, 0, 248, + 249, 0, 0, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 0, 0, 0, 65, 264, 67, 0, 15, + 0, 16, 17, 18, 19, 0, 0, 250, 0, 251, + 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, + 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, + 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, + 0, 211, 0, 0, 119, 53, 0, 54, 55, 0, + 0, 0, 0, 0, 57, 0, 58, 59, 60, 0, + 61, 62, 63, 0, 64, 247, 0, 0, 248, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 0, 201, 202, 0, 0, 0, 0, 0, - 0, 203, 204, -577, -577, -577, -577, -577, -577, -577, - -577, -577, 0, 0, 0, 0, 0, 0, 0, -577, - 0, -577, -577, -577, -577, 0, -577, 0, 0, 0, - -577, -577, -577, -577, -577, -577, -577, 0, 0, -577, - 0, 0, 0, 0, 0, 0, 0, 0, -577, -577, - -577, -577, -577, -577, -577, -577, -577, 0, -577, -577, - -577, 0, 0, -577, 0, 0, -577, -577, 0, -577, - -577, -577, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -577, -577, 0, 0, 0, 0, - 0, -577, 0, 0, -577, -577, 0, -577, -577, 0, - -577, 0, -577, -577, -577, 0, -577, -577, -577, 0, - -577, -577, -577, 0, -577, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 65, 66, 67, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 251, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 0, 0, 0, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 0, 0, 0, 0, + 0, 165, 166, 167, 168, 169, 170, 171, 172, 36, + 37, 173, 39, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, + 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -577, -577, -577, 0, -577, 0, - 0, 0, 0, 0, -577, -578, -578, -578, -578, -578, - -578, -578, -578, -578, 0, 0, 0, 0, 0, 0, - 0, -578, 0, -578, -578, -578, -578, 0, -578, 0, - 0, 0, -578, -578, -578, -578, -578, -578, -578, 0, - 0, -578, 0, 0, 0, 0, 0, 0, 0, 0, - -578, -578, -578, -578, -578, -578, -578, -578, -578, 0, - -578, -578, -578, 0, 0, -578, 0, 0, -578, -578, - 0, -578, -578, -578, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -578, -578, 0, 0, - 0, 0, 0, -578, 0, 0, -578, -578, 0, -578, - -578, 0, -578, 0, -578, -578, -578, 0, -578, -578, - -578, 0, -578, -578, -578, 0, -578, 0, 0, 0, - 0, 0, 0, -580, -580, -580, -580, -580, -580, -580, - -580, -580, 0, 0, 0, 0, -578, -578, -578, -580, - -578, -580, -580, -580, -580, 0, -578, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 0, 201, 202, 0, 0, 0, 0, 0, 0, 203, + 204, -579, -579, -579, -579, -579, -579, -579, -579, -579, + 0, 0, 0, 0, 0, 0, 0, -579, 0, -579, + -579, -579, -579, 0, -579, 0, 0, 0, -579, -579, + -579, -579, -579, -579, -579, 0, 0, -579, 0, 0, + 0, 0, 0, 0, 0, 0, -579, -579, -579, -579, + -579, -579, -579, -579, -579, 0, -579, -579, -579, 0, + 0, -579, 0, 0, -579, -579, 0, -579, -579, -579, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -579, -579, 0, 0, 0, 0, 0, -579, + 0, 0, -579, -579, 0, -579, -579, 0, -579, 0, + -579, -579, -579, 0, -579, -579, -579, 0, -579, -579, + -579, 0, -579, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -579, -579, -579, 0, -579, 0, 0, 0, + 0, 0, -579, -580, -580, -580, -580, -580, -580, -580, + -580, -580, 0, 0, 0, 0, 0, 0, 0, -580, + 0, -580, -580, -580, -580, 0, -580, 0, 0, 0, -580, -580, -580, -580, -580, -580, -580, 0, 0, -580, 0, 0, 0, 0, 0, 0, 0, 0, -580, -580, -580, -580, -580, -580, -580, -580, -580, 0, -580, -580, -580, 0, 0, -580, 0, 0, -580, -580, 0, -580, -580, -580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -580, -580, 0, 0, 0, 0, - 0, -580, 820, 0, -580, -580, 0, -580, -580, 0, + 0, -580, 0, 0, -580, -580, 0, -580, -580, 0, -580, 0, -580, -580, -580, 0, -580, -580, -580, 0, -580, -580, -580, 0, -580, 0, 0, 0, 0, 0, - 0, -103, -581, -581, -581, -581, -581, -581, -581, -581, - -581, 0, 0, 0, -580, -580, -580, 0, -581, 0, - -581, -581, -581, -581, -580, 0, 0, 0, 0, -581, - -581, -581, -581, -581, -581, -581, 0, 0, -581, 0, - 0, 0, 0, 0, 0, 0, 0, -581, -581, -581, - -581, -581, -581, -581, -581, -581, 0, -581, -581, -581, - 0, 0, -581, 0, 0, -581, -581, 0, -581, -581, - -581, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -581, -581, 0, 0, 0, 0, 0, - -581, 821, 0, -581, -581, 0, -581, -581, 0, -581, - 0, -581, -581, -581, 0, -581, -581, -581, 0, -581, - -581, -581, 0, -581, 0, 0, 0, 0, 0, 0, - -105, -582, -582, -582, -582, -582, -582, -582, -582, -582, - 0, 0, 0, -581, -581, -581, 0, -582, 0, -582, - -582, -582, -582, -581, 0, 0, 0, 0, -582, -582, + 0, -582, -582, -582, -582, -582, -582, -582, -582, -582, + 0, 0, 0, 0, -580, -580, -580, -582, -580, -582, + -582, -582, -582, 0, -580, 0, 0, 0, -582, -582, -582, -582, -582, -582, -582, 0, 0, -582, 0, 0, 0, 0, 0, 0, 0, 0, -582, -582, -582, -582, -582, -582, -582, -582, -582, 0, -582, -582, -582, 0, 0, -582, 0, 0, -582, -582, 0, -582, -582, -582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -582, -582, 0, 0, 0, 0, 0, -582, - 0, 0, -582, -582, 0, -582, -582, 0, -582, 0, + 826, 0, -582, -582, 0, -582, -582, 0, -582, 0, -582, -582, -582, 0, -582, -582, -582, 0, -582, -582, - -582, 0, -582, 0, 0, 0, 0, 0, 0, -583, - -583, -583, -583, -583, -583, -583, -583, -583, 0, 0, - 0, 0, -582, -582, -582, -583, 0, -583, -583, -583, - -583, 0, -582, 0, 0, 0, -583, -583, -583, -583, - -583, -583, -583, 0, 0, -583, 0, 0, 0, 0, - 0, 0, 0, 0, -583, -583, -583, -583, -583, -583, - -583, -583, -583, 0, -583, -583, -583, 0, 0, -583, - 0, 0, -583, -583, 0, -583, -583, -583, 0, 0, + -582, 0, -582, 0, 0, 0, 0, 0, 0, -107, + -583, -583, -583, -583, -583, -583, -583, -583, -583, 0, + 0, 0, -582, -582, -582, 0, -583, 0, -583, -583, + -583, -583, -582, 0, 0, 0, 0, -583, -583, -583, + -583, -583, -583, -583, 0, 0, -583, 0, 0, 0, + 0, 0, 0, 0, 0, -583, -583, -583, -583, -583, + -583, -583, -583, -583, 0, -583, -583, -583, 0, 0, + -583, 0, 0, -583, -583, 0, -583, -583, -583, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -583, -583, 0, 0, 0, 0, 0, -583, 827, + 0, -583, -583, 0, -583, -583, 0, -583, 0, -583, + -583, -583, 0, -583, -583, -583, 0, -583, -583, -583, + 0, -583, 0, 0, 0, 0, 0, 0, -109, -584, + -584, -584, -584, -584, -584, -584, -584, -584, 0, 0, + 0, -583, -583, -583, 0, -584, 0, -584, -584, -584, + -584, -583, 0, 0, 0, 0, -584, -584, -584, -584, + -584, -584, -584, 0, 0, -584, 0, 0, 0, 0, + 0, 0, 0, 0, -584, -584, -584, -584, -584, -584, + -584, -584, -584, 0, -584, -584, -584, 0, 0, -584, + 0, 0, -584, -584, 0, -584, -584, -584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -583, -583, 0, 0, 0, 0, 0, -583, 0, 0, - -583, -583, 0, -583, -583, 0, -583, 0, -583, -583, - -583, 0, -583, -583, -583, 0, -583, -583, -583, 0, - -583, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -584, -584, 0, 0, 0, 0, 0, -584, 0, 0, + -584, -584, 0, -584, -584, 0, -584, 0, -584, -584, + -584, 0, -584, -584, -584, 0, -584, -584, -584, 0, + -584, 0, 0, 0, 0, 0, 0, -585, -585, -585, + -585, -585, -585, -585, -585, -585, 0, 0, 0, 0, + -584, -584, -584, -585, 0, -585, -585, -585, -585, 0, + -584, 0, 0, 0, -585, -585, -585, -585, -585, -585, + -585, 0, 0, -585, 0, 0, 0, 0, 0, 0, + 0, 0, -585, -585, -585, -585, -585, -585, -585, -585, + -585, 0, -585, -585, -585, 0, 0, -585, 0, 0, + -585, -585, 0, -585, -585, -585, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -585, -585, + 0, 0, 0, 0, 0, -585, 0, 0, -585, -585, + 0, -585, -585, 0, -585, 0, -585, -585, -585, 0, + -585, -585, -585, 0, -585, -585, -585, 0, -585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -583, -583, -583, 0, 0, 0, 0, 0, 0, 0, - -583, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 0, 0, 0, 0, 0, 0, 0, 0, -585, -585, + -585, 0, 0, 0, 0, 0, 0, 0, -585, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 0, 0, 0, 155, 156, 157, 233, + 234, 235, 236, 162, 163, 164, 0, 0, 0, 0, + 0, 165, 166, 167, 237, 238, 239, 240, 172, 319, + 320, 241, 321, 0, 0, 0, 0, 0, 0, 322, + 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, + 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, + 0, 0, 0, 323, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 0, 201, 202, 0, 0, 0, 0, 0, 0, 203, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 0, 0, 0, 155, 156, 157, + 233, 234, 235, 236, 162, 163, 164, 0, 0, 0, + 0, 0, 165, 166, 167, 237, 238, 239, 240, 172, + 319, 320, 241, 321, 0, 0, 0, 0, 0, 0, + 322, 0, 0, 0, 0, 0, 0, 174, 175, 176, + 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, + 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 188, 189, 190, + 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 0, 201, 202, 0, 0, 0, 0, 0, 0, + 203, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 0, 0, 0, 155, 156, - 157, 231, 232, 233, 234, 162, 163, 164, 0, 0, - 0, 0, 0, 165, 166, 167, 235, 236, 237, 238, - 172, 318, 319, 239, 320, 0, 0, 0, 0, 0, - 0, 321, 0, 0, 0, 0, 0, 0, 174, 175, + 157, 233, 234, 235, 236, 162, 163, 164, 0, 0, + 0, 0, 0, 165, 166, 167, 237, 238, 239, 240, + 172, 0, 0, 241, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 189, - 190, 0, 0, 0, 0, 322, 0, 0, 0, 0, + 190, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 0, 201, 202, 0, 0, 0, 0, 0, 0, 203, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 0, 0, 0, 155, - 156, 157, 231, 232, 233, 234, 162, 163, 164, 0, - 0, 0, 0, 0, 165, 166, 167, 235, 236, 237, - 238, 172, 318, 319, 239, 320, 0, 0, 0, 0, - 0, 0, 321, 0, 0, 0, 0, 0, 0, 174, + 156, 157, 233, 234, 235, 236, 162, 163, 164, 0, + 0, 0, 0, 0, 165, 166, 167, 237, 238, 239, + 240, 172, 0, 0, 241, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, - 189, 190, 0, 0, 0, 0, 481, 0, 0, 0, + 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 0, 201, 202, 0, 0, 0, 0, - 0, 0, 203, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 0, 0, 0, - 155, 156, 157, 231, 232, 233, 234, 162, 163, 164, - 0, 0, 0, 0, 0, 165, 166, 167, 235, 236, - 237, 238, 172, 0, 0, 239, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, - 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 188, 189, 190, 0, 0, 0, 240, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 0, 201, 202, 0, 0, 0, - 0, 0, 0, 203, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 0, 0, - 0, 155, 156, 157, 231, 232, 233, 234, 162, 163, - 164, 0, 0, 0, 0, 0, 165, 166, 167, 235, - 236, 237, 238, 172, 0, 0, 239, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, - 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, - 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 188, 189, 190, 0, 0, 0, 0, 0, 0, + 0, 0, 203, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 0, 0, 0, 0, 0, 0, 0, 15, + 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, + 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, + 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, + 42, 0, 0, 43, 0, 0, 44, 45, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 0, 201, 202, 0, 0, - 0, 0, 0, 0, 203, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, - 0, 15, 0, 108, 109, 18, 19, 0, 0, 0, - 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, - 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, - 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, - 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 311, 0, 0, 119, 53, 0, 54, - 55, 0, 0, 0, 0, 0, 57, 0, 58, 59, - 60, 0, 61, 62, 63, 0, 64, 0, 0, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, - 0, 0, 0, 0, 0, 15, 120, 108, 109, 18, - 19, 0, 0, 0, 312, 0, 110, 111, 112, 23, - 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, - 0, 0, 44, 45, 0, 116, 0, 0, 0, 0, + 0, 312, 0, 0, 119, 53, 0, 54, 55, 0, + 0, 0, 0, 0, 57, 0, 58, 59, 60, 0, + 61, 62, 63, 0, 64, 0, 0, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, + 0, 0, 0, 15, 120, 108, 109, 18, 19, 0, + 0, 0, 313, 0, 110, 111, 112, 23, 24, 25, + 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, + 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, + 44, 45, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, - 119, 53, 0, 54, 55, 0, 0, 0, 0, 0, - 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, - 64, 0, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 0, 0, 0, 0, 0, 0, 15, - 120, 16, 17, 18, 19, 0, 0, 0, 602, 0, - 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, - 0, 0, 0, 0, 0, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, - 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, - 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, - 0, 51, 0, 0, 52, 53, 0, 54, 55, 0, - 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, - 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 312, 0, 0, 119, 53, + 0, 54, 55, 0, 0, 0, 0, 0, 57, 0, + 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 0, 0, 0, 65, 66, 67, 15, 0, 16, - 17, 18, 19, 0, 0, 0, 0, 0, 20, 21, + 14, 0, 0, 0, 0, 0, 0, 15, 120, 16, + 17, 18, 19, 0, 0, 0, 605, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, - 0, 0, 0, 28, 0, 30, 31, 32, 33, 34, + 0, 0, 0, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3268,126 +3331,126 @@ static const yytype_int16 yytable[] = 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 65, 66, 67, 15, 0, 16, 17, 18, 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 32, 33, 258, 35, 36, + 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, + 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, - 119, 53, 0, 54, 55, 0, 259, 0, 260, 261, + 49, 50, 0, 0, 0, 0, 0, 51, 0, 0, + 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, - 65, 262, 67, 15, 0, 16, 17, 18, 19, 0, + 65, 66, 67, 15, 0, 16, 17, 18, 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, - 0, 0, 31, 32, 33, 258, 35, 36, 37, 38, + 0, 0, 31, 32, 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 49, 503, + 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, - 0, 54, 55, 0, 259, 0, 260, 261, 57, 0, + 0, 54, 55, 0, 261, 0, 262, 263, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 0, 0, 0, 0, 65, 262, - 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, - 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, + 10, 11, 12, 13, 0, 0, 0, 0, 65, 264, + 67, 15, 0, 16, 17, 18, 19, 0, 0, 0, + 0, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, - 31, 32, 33, 258, 35, 36, 37, 38, 39, 0, + 31, 32, 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 505, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, - 55, 0, 712, 0, 260, 261, 57, 0, 58, 59, + 55, 0, 261, 0, 262, 263, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 0, 0, 0, 0, 65, 262, 67, 15, + 12, 13, 0, 0, 0, 0, 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, - 33, 258, 35, 36, 37, 38, 39, 0, 40, 41, + 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 838, 0, 0, 0, 0, + 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, 55, 0, - 712, 0, 260, 261, 57, 0, 58, 59, 60, 0, + 716, 0, 262, 263, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 0, 0, 0, 0, 65, 262, 67, 15, 0, 108, + 0, 0, 0, 0, 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, - 0, 0, 0, 0, 0, 0, 31, 32, 33, 258, + 0, 0, 0, 0, 0, 0, 31, 32, 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, - 0, 0, 119, 53, 0, 54, 55, 0, 259, 0, - 260, 0, 57, 0, 58, 59, 60, 0, 61, 62, + 0, 0, 49, 843, 0, 0, 0, 0, 0, 211, + 0, 0, 119, 53, 0, 54, 55, 0, 716, 0, + 262, 263, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, - 0, 0, 65, 262, 67, 15, 0, 108, 109, 18, + 0, 0, 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 32, 33, 258, 35, 36, + 0, 0, 0, 0, 31, 32, 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, - 119, 53, 0, 54, 55, 0, 0, 0, 260, 261, + 119, 53, 0, 54, 55, 0, 261, 0, 262, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, - 65, 262, 67, 15, 0, 108, 109, 18, 19, 0, + 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, - 0, 0, 31, 32, 33, 258, 35, 36, 37, 38, + 0, 0, 31, 32, 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, - 0, 54, 55, 0, 712, 0, 260, 0, 57, 0, + 0, 54, 55, 0, 0, 0, 262, 263, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 0, 0, 0, 0, 65, 262, + 10, 11, 12, 13, 0, 0, 0, 0, 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, - 31, 32, 33, 258, 35, 36, 37, 38, 39, 0, + 31, 32, 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, - 55, 0, 0, 0, 260, 0, 57, 0, 58, 59, + 55, 0, 716, 0, 262, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 0, 0, 0, 0, 65, 262, 67, 15, - 0, 16, 17, 18, 19, 0, 0, 0, 0, 0, - 20, 21, 22, 23, 24, 25, 26, 0, 0, 113, + 12, 13, 0, 0, 0, 0, 65, 264, 67, 15, + 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, + 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, + 33, 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, 55, 0, - 596, 0, 0, 0, 57, 0, 58, 59, 60, 0, + 0, 0, 262, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 0, 0, 0, 0, 65, 262, 67, 15, 0, 108, - 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, - 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, + 0, 0, 0, 0, 65, 264, 67, 15, 0, 16, + 17, 18, 19, 0, 0, 0, 0, 0, 20, 21, + 22, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, - 0, 0, 119, 53, 0, 54, 55, 0, 259, 0, + 0, 0, 119, 53, 0, 54, 55, 0, 599, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, - 0, 0, 65, 262, 67, 15, 0, 108, 109, 18, + 0, 0, 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, @@ -3395,11 +3458,11 @@ static const yytype_int16 yytable[] = 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, - 119, 53, 0, 54, 55, 0, 596, 0, 0, 0, + 119, 53, 0, 54, 55, 0, 261, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, - 65, 262, 67, 15, 0, 108, 109, 18, 19, 0, + 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, @@ -3407,10 +3470,10 @@ static const yytype_int16 yytable[] = 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, - 0, 54, 55, 0, 881, 0, 0, 0, 57, 0, + 0, 54, 55, 0, 599, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 0, 0, 0, 0, 65, 262, + 10, 11, 12, 13, 0, 0, 0, 0, 65, 264, 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3419,24 +3482,24 @@ static const yytype_int16 yytable[] = 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, - 55, 0, 712, 0, 0, 0, 57, 0, 58, 59, + 55, 0, 888, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 0, 0, 0, 0, 65, 262, 67, 15, - 0, 16, 17, 18, 19, 0, 0, 0, 0, 0, - 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, + 12, 13, 0, 0, 0, 0, 65, 264, 67, 15, + 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, + 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, 55, 0, - 0, 0, 0, 0, 57, 0, 58, 59, 60, 0, + 716, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 0, 0, 0, 0, 65, 66, 67, 15, 0, 108, - 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, - 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, + 0, 0, 0, 0, 65, 264, 67, 15, 0, 16, + 17, 18, 19, 0, 0, 0, 0, 0, 20, 21, + 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, @@ -3446,8 +3509,8 @@ static const yytype_int16 yytable[] = 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, - 0, 0, 65, 262, 67, 15, 0, 16, 17, 18, - 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, + 0, 0, 65, 66, 67, 15, 0, 108, 109, 18, + 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, @@ -3458,49 +3521,38 @@ static const yytype_int16 yytable[] = 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, - 65, 262, 67, 15, 0, 108, 109, 18, 19, 0, - 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, + 65, 264, 67, 15, 0, 16, 17, 18, 19, 0, + 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, - 0, 0, 31, 32, 33, 114, 35, 36, 37, 115, + 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, - 44, 45, 0, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 117, 0, 0, 118, 0, 0, 119, 53, + 44, 45, 0, 46, 47, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, + 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, 0, 54, 55, 0, 0, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, - 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 0, 0, 0, 0, 0, 0, 0, 15, 120, 108, - 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, - 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, - 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, - 0, 43, 0, 0, 44, 45, 0, 223, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, - 0, 0, 52, 53, 0, 54, 55, 0, 56, 0, - 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, - 63, 0, 64, 0, 0, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, - 0, 15, 120, 108, 109, 18, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 0, 0, 0, 0, 65, 264, + 67, 15, 0, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, + 31, 32, 33, 114, 35, 36, 37, 115, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 311, 0, 0, 396, 53, 0, 54, - 55, 0, 397, 0, 0, 0, 57, 0, 58, 59, + 117, 0, 0, 118, 0, 0, 119, 53, 0, 54, + 55, 0, 0, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 15, 120, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, - 0, 0, 0, 0, 31, 32, 33, 114, 35, 36, - 37, 115, 39, 0, 40, 41, 42, 0, 0, 43, - 0, 0, 44, 45, 0, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, + 0, 0, 44, 45, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 118, 0, 0, - 119, 53, 0, 54, 55, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, + 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 15, @@ -3511,18 +3563,18 @@ static const yytype_int16 yytable[] = 42, 0, 0, 43, 0, 0, 44, 45, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 311, 0, 0, 396, 53, 0, 54, 55, 0, - 0, 0, 0, 0, 57, 0, 58, 59, 60, 0, + 0, 312, 0, 0, 397, 53, 0, 54, 55, 0, + 398, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 15, 120, 108, 109, 18, 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, - 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, + 0, 0, 31, 32, 33, 114, 35, 36, 37, 115, 39, 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 946, 0, 0, 119, 53, + 0, 0, 0, 0, 0, 118, 0, 0, 119, 53, 0, 54, 55, 0, 0, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, 0, 64, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, @@ -3531,20 +3583,60 @@ static const yytype_int16 yytable[] = 112, 23, 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, - 0, 43, 0, 0, 44, 45, 0, 223, 0, 0, + 0, 43, 0, 0, 44, 45, 0, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 312, + 0, 0, 397, 53, 0, 54, 55, 0, 0, 0, + 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, + 63, 0, 64, 0, 0, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, + 0, 15, 120, 108, 109, 18, 19, 0, 0, 0, + 0, 0, 110, 111, 112, 23, 24, 25, 26, 0, + 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, + 40, 41, 42, 0, 0, 43, 0, 0, 44, 45, + 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 955, 0, 0, 119, 53, 0, 54, + 55, 0, 0, 0, 0, 0, 57, 0, 58, 59, + 60, 0, 61, 62, 63, 0, 64, 0, 0, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, + 0, 0, 0, 0, 0, 15, 120, 108, 109, 18, + 19, 0, 0, 0, 0, 0, 110, 111, 112, 23, + 24, 25, 26, 0, 0, 113, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, + 0, 0, 44, 45, 0, 225, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 978, 0, 0, + 119, 53, 0, 54, 55, 0, 0, 644, 645, 0, + 57, 646, 58, 59, 60, 0, 61, 62, 63, 0, + 64, 0, 0, 0, 0, 0, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, + 120, 0, 184, 185, 186, 187, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 0, 201, 202, 653, 654, 0, 0, 655, 0, 203, + 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, + 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, + 186, 187, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 969, - 0, 0, 119, 53, 0, 54, 55, 0, 0, 656, - 651, 0, 57, 657, 58, 59, 60, 0, 61, 62, - 63, 0, 64, 0, 0, 0, 0, 0, 174, 175, + 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 0, 201, 202, 674, + 645, 0, 0, 675, 0, 203, 275, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, - 0, 0, 120, 0, 184, 185, 186, 187, 0, 0, + 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 0, 201, 202, 686, 642, 0, 0, 687, - 0, 203, 273, 0, 0, 0, 0, 0, 0, 0, + 199, 200, 0, 201, 202, 659, 654, 0, 0, 660, + 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, @@ -3552,7 +3644,7 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 0, 201, - 202, 689, 651, 0, 0, 690, 0, 203, 273, 0, + 202, 691, 645, 0, 0, 692, 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, @@ -3560,8 +3652,8 @@ static const yytype_int16 yytable[] = 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 0, 201, 202, 696, 642, 0, - 0, 697, 0, 203, 273, 0, 0, 0, 0, 0, + 197, 198, 199, 200, 0, 201, 202, 694, 654, 0, + 0, 695, 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, @@ -3569,16 +3661,16 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 0, 201, 202, 699, 651, 0, 0, 700, 0, 203, - 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 201, 202, 701, 645, 0, 0, 702, 0, 203, + 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 0, 201, 202, 735, - 642, 0, 0, 736, 0, 203, 273, 0, 0, 0, + 195, 196, 197, 198, 199, 200, 0, 201, 202, 704, + 654, 0, 0, 705, 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, @@ -3586,8 +3678,8 @@ static const yytype_int16 yytable[] = 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 0, 201, 202, 738, 651, 0, 0, 739, - 0, 203, 273, 0, 0, 0, 0, 0, 0, 0, + 199, 200, 0, 201, 202, 739, 645, 0, 0, 740, + 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, @@ -3595,7 +3687,7 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 0, 201, - 202, 886, 642, 0, 0, 887, 0, 203, 273, 0, + 202, 742, 654, 0, 0, 743, 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, @@ -3603,8 +3695,8 @@ static const yytype_int16 yytable[] = 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 0, 201, 202, 889, 651, 0, - 0, 890, 0, 203, 273, 0, 0, 0, 0, 0, + 197, 198, 199, 200, 0, 201, 202, 893, 645, 0, + 0, 894, 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, @@ -3612,16 +3704,16 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 0, 201, 202, 1028, 642, 0, 0, 1029, 0, 203, - 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 201, 202, 896, 654, 0, 0, 897, 0, 203, + 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 0, 201, 202, 1040, - 642, 0, 0, 1041, 0, 203, 273, 0, 0, 0, + 195, 196, 197, 198, 199, 200, 0, 201, 202, 1037, + 645, 0, 0, 1038, 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, @@ -3629,8 +3721,8 @@ static const yytype_int16 yytable[] = 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 0, 201, 202, 1043, 651, 0, 0, 1044, - 0, 203, 273, 0, 0, 0, 0, 0, 0, 0, + 199, 200, 0, 201, 202, 1049, 645, 0, 0, 1050, + 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, @@ -3638,612 +3730,602 @@ static const yytype_int16 yytable[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 0, 201, - 202, 656, 651, 0, 0, 657, 0, 203, 273, 0, + 202, 1052, 654, 0, 0, 1053, 0, 203, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 855, 0, 0, 0, - 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 0, 201, 202, 0, 0, 0, - 0, 0, 0, 203, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 0, 0, 0, 0, - 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 415, 0, 0, 0, 0, 866, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 416, 0, 417, 418, 419, 420, - 421, 422, 423, 424, 425, 426, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 0, 0, - 0, 0, 412, 413, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 415, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 416, 0, 417, 418, - 419, 420, 421, 422, 423, 424, 425, 426, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 0, 0, 0, 0, 412, 413, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 415, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, - 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 0, 0, 249, 0, 412, 413, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 415, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 0, 0, 0, 0, 0, 0, 0, 0, - -273, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 411, 0, 0, 0, 0, 412, 413, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 416, 0, 417, 418, 419, 420, 421, 422, 423, - 424, 425, 426, 0, 0, 0, 0, 0, 0, 0, - 0, -274, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 0, 0, 0, 0, 412, 413, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 415, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 416, 0, 417, 418, 419, 420, 421, 422, - 423, 424, 425, 426, 0, 0, 0, 0, 0, 0, - 0, 0, -275, 400, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 410, 411, 0, 0, 0, 0, 412, - 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 416, 0, 417, 418, 419, 420, 421, - 422, 423, 424, 425, 426, 0, 0, 0, 0, 0, - 0, 0, 0, -276, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 0, 0, 0, 0, - 412, 413, 0, 0, 0, 414, 0, 0, 0, 0, - 0, 0, 0, 415, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 0, 201, 202, 659, 654, 0, + 0, 660, 0, 203, 275, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 0, 182, 183, 0, 0, + 0, 0, 184, 185, 186, 187, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 188, 189, 190, 0, + 0, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 0, 0, 0, 0, 413, 414, 0, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 416, 201, 202, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 416, 0, 417, 418, 419, 420, - 421, 422, 423, 424, 425, 426, 400, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 0, 0, - 0, 0, 412, 413, 0, 0, 0, 495, 0, 0, - 0, 0, 0, 0, 0, 415, 0, 0, 0, 0, + 0, 417, 0, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 0, 0, 0, 0, 0, 0, 0, + 0, -278, 401, 402, 403, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 0, 0, 0, 0, 413, 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 416, 0, 417, 418, - 419, 420, 421, 422, 423, 424, 425, 426, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 0, 0, 0, 0, 412, 413, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 415, 0, 0, + 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, - 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - -608, -608, 0, 0, 0, 0, 412, 413, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 415, + 0, 0, 417, 0, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, 0, 0, 0, 0, 0, 0, + 0, 0, -279, 401, 402, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 0, 0, 0, 0, 413, + 414, 0, 0, 0, 415, 0, 0, 0, 0, 0, + 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 417, 0, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 0, 0, 0, + 0, 413, 414, 0, 0, 0, 497, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426 + 0, 0, 0, 0, 0, 417, 0, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 401, 402, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 0, + 0, 0, 0, 413, 414, 401, 402, 403, 404, 405, + 406, 0, 0, 409, 410, 0, 416, 0, 0, 0, + 0, 413, 414, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 417, 0, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 0, + 0, 0, 0, 0, 0, 0, 0, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427 }; static const yytype_int16 yycheck[] = { - 2, 16, 17, 89, 220, 20, 27, 69, 475, 27, - 2, 56, 4, 5, 6, 484, 82, 9, 10, 21, - 66, 13, 7, 15, 16, 17, 429, 7, 20, 14, - 14, 118, 4, 52, 87, 88, 269, 772, 312, 54, - 55, 305, 28, 28, 28, 309, 16, 17, 22, 15, - 20, 454, 54, 55, 74, 75, 329, 375, 584, 399, - 52, 16, 17, 748, 56, 20, 469, 587, 540, 5, - 6, 317, 74, 58, 66, 478, 91, 13, 58, 584, - 502, 60, 61, 62, 63, 490, 21, 22, 16, 17, - 82, 25, 20, 10, 659, 660, 16, 26, 15, 54, - 55, 121, 122, 69, 772, 5, 6, 954, 26, 111, - 532, 294, 57, 13, 90, 370, 931, 79, 29, 682, - 56, 367, 2, 25, 4, 117, 90, 119, 691, 51, - 602, 105, 25, 27, 5, 6, 391, 0, 92, 542, - 25, 105, 13, 92, 92, 584, 82, 25, 587, 75, - 103, 25, 330, 25, 142, 333, 56, 335, 28, 337, - 148, 339, 427, 216, 126, 25, 431, 121, 92, 434, - 105, 147, 121, 121, 227, 128, 111, 112, 123, 101, - 102, 103, 82, 147, 1031, 56, 791, 138, 142, 384, - 455, 386, 797, 90, 129, 115, 122, 121, 118, 119, - 498, 456, 113, 468, 502, 470, 128, 1022, 142, 138, - 144, 82, 57, 396, 479, 144, 951, 490, 210, 954, - 138, 115, 142, 55, 118, 119, 146, 753, 148, 221, - 222, 439, 440, 121, 296, 288, 90, 802, 9, 10, - 142, 144, 304, 305, 15, 148, 312, 309, 753, 142, - 147, 936, 146, 518, 148, 240, 90, 142, 273, 144, - 240, 314, 277, 142, 142, 267, 540, 269, 142, 90, - 142, 273, 90, 121, 507, 294, 121, 550, 543, 92, - 948, 273, 142, 951, 250, 277, 954, 90, 956, 281, - 282, 121, 92, 147, 286, 92, 1031, 317, 544, 125, - 722, 293, 294, 273, 221, 222, 711, 277, 780, 301, - 92, 92, 142, 147, 753, 90, 37, 38, 90, 52, - 312, 121, 277, 90, 121, 144, 147, 853, 602, 147, - 296, 58, 59, 772, 51, 861, 1004, 857, 55, 121, - 121, 681, 142, 322, 147, 142, 117, 367, 394, 277, - 92, 144, 397, 399, 346, 347, 348, 349, 350, 351, - 352, 353, 829, 1031, 927, 1033, 453, 1035, 399, 1037, - 548, 373, 147, 375, 346, 147, 312, 396, 370, 121, - 147, 60, 785, 18, 63, 20, 119, 92, 92, 1057, - 92, 16, 17, 439, 440, 20, 55, 92, 121, 391, - 142, 92, 394, 55, 396, 397, 25, 399, 439, 440, - 58, 59, 312, 293, 429, 670, 121, 121, 857, 121, - 142, 301, 20, 721, 722, 951, 121, 429, 107, 54, - 347, 348, 349, 350, 142, 708, 57, 429, 711, 454, - 758, 312, 17, 18, 868, 869, 431, 439, 440, 434, - 221, 222, 454, 115, 469, 138, 118, 119, 927, 429, - 462, 397, 454, 478, 456, 457, 346, 469, 732, 101, - 455, 351, 538, 465, 540, 496, 478, 469, 496, 74, - 75, 473, 715, 498, 454, 470, 478, 502, 145, 115, - 706, 483, 118, 119, 479, 793, 431, 397, 1024, 469, - 141, 121, 367, 139, 506, 507, 780, 929, 478, 1035, - 281, 282, 951, 515, 529, 954, 55, 532, 773, 784, - 455, 786, 148, 515, 544, 142, 397, 542, 514, 514, - 514, 101, 524, 518, 61, 470, 602, 64, 65, 505, - 542, 92, 101, 498, 479, 800, 538, 267, 540, 269, - 542, 142, 121, 286, 872, 873, 92, 549, 543, 612, - 61, 294, 835, 64, 65, 121, 101, 762, 763, 764, - 121, 766, 542, 768, 529, 51, 347, 348, 349, 350, - 788, 352, 353, 518, 304, 121, 794, 795, 142, 116, - 117, 846, 1031, 595, 129, 130, 131, 132, 133, 92, - 655, 92, 538, 658, 540, 90, 839, 51, 543, 630, - 602, 2, 630, 4, 1017, 116, 117, 142, 9, 10, - 105, 676, 142, 142, 15, 16, 17, 51, 121, 20, - 121, 929, 121, 115, 142, 515, 118, 119, 538, 51, - 540, 99, 15, 13, 524, 16, 63, 649, 273, 142, - 577, 142, 277, 655, 909, 140, 658, 659, 660, 144, - 15, 52, 147, 396, 298, 145, 602, 538, 302, 540, - 732, 145, 646, 139, 676, 66, 15, 669, 670, 681, - 682, 655, 684, 142, 658, 1003, 457, 142, 15, 691, - 898, 142, 44, 121, 679, 141, 16, 913, 141, 679, - 15, 18, 602, 919, 141, 570, 721, 722, 141, 701, - 139, 646, 798, 715, 780, 26, 702, 702, 702, 740, - 655, 15, 587, 658, 139, 590, 117, 141, 119, 148, - 139, 602, 465, 57, 142, 142, 782, 142, 142, 674, - 473, 676, 788, 789, 939, 940, 941, 942, 794, 795, - 483, 782, 669, 1018, 142, 15, 758, 788, 93, 14, - 145, 90, 16, 794, 795, 15, 721, 90, 15, 394, - 785, 146, 15, 142, 399, 101, 105, 142, 793, 90, - 142, 773, 105, 785, 701, 142, 506, 507, 780, 781, - 782, 142, 141, 785, 105, 115, 788, 789, 118, 119, - 802, 786, 794, 795, 15, 131, 132, 133, 800, 801, - 812, 140, 15, 815, 213, 785, 549, 140, 147, 210, - 16, 220, 814, 139, 147, 817, 146, 138, 148, 140, - 221, 222, 1027, 144, 826, 827, 147, 839, 793, 577, - 15, 15, 834, 581, 780, 772, 142, 868, 869, 139, - 126, 786, 898, 126, 846, 847, 55, 139, 257, 15, - 55, 115, 487, 142, 118, 119, 15, 898, 142, 503, - 872, 873, 62, 142, 64, 65, 510, 142, 870, 599, - 780, 142, 273, 875, 142, 144, 277, 521, 144, 141, - 281, 282, 146, 142, 148, 286, 90, 515, 669, 13, - 817, 781, 293, 294, 6, 1020, 898, 772, 772, 780, - 301, 105, 1022, 799, 929, 1019, 908, 909, 971, 115, - 912, 252, 118, 119, 916, 927, 116, 117, 7, 649, - 701, 577, 948, 90, 870, 268, -1, 571, 572, 875, - 951, -1, 62, 26, 64, 65, 140, 346, 105, -1, - 146, -1, 148, 147, -1, 346, 347, 348, 349, 350, - 351, 352, 353, 984, -1, -1, 984, 601, 877, 878, - 870, -1, -1, 90, -1, 875, 912, -1, 377, 370, - -1, -1, 974, 140, 976, -1, 706, 979, 105, -1, - 147, -1, 857, -1, 859, 715, 116, 117, 863, 870, - 391, 1003, 1017, 394, 875, 396, 115, 90, 399, 118, - 119, -1, 912, -1, -1, 1017, -1, 1019, 1020, -1, - -1, 948, 105, 140, 951, 1017, -1, 954, -1, 956, - 147, -1, -1, 1018, 772, -1, 145, 146, 429, 148, - -1, 912, 951, -1, 678, -1, 817, 1017, 439, 440, - -1, -1, -1, 37, 38, 138, 681, 140, -1, 26, - -1, 144, -1, 454, 147, 456, 457, -1, 801, 934, - 935, -1, -1, -1, 465, 474, 475, 1004, 469, -1, - -1, 814, 473, 1018, 26, -1, -1, 478, -1, 954, - -1, 956, 483, 826, 827, -1, -1, 731, 1007, 1008, - 1009, 834, 1011, 1012, 1031, -1, 1033, -1, 1035, -1, - 1037, -1, -1, -1, 847, 749, -1, -1, 26, 839, - -1, 26, -1, 90, 515, 524, 991, -1, -1, 994, - 1057, 115, 531, 524, 118, 119, 115, -1, 105, 118, - 119, -1, 1051, 1052, 1053, 1054, 439, 440, 90, 9, - 10, 542, 1061, -1, -1, 15, 16, 17, 549, -1, - 20, 1026, 146, 105, 148, -1, 1031, 146, 1033, 148, - -1, 138, 1037, 140, -1, 908, -1, 144, 471, 472, - 147, -1, 90, 916, -1, 90, -1, 47, 48, 49, - 50, -1, 1057, -1, 54, 55, 138, 105, 140, 90, - 105, -1, 144, -1, 838, 147, 66, 67, 90, -1, - 948, -1, -1, 951, 105, -1, 954, -1, 956, -1, - 854, -1, -1, 105, -1, -1, 519, -1, -1, -1, - 138, -1, 140, 138, -1, 140, 144, -1, -1, 147, - -1, 974, 147, 976, -1, -1, 979, -1, 90, 140, - -1, 51, 52, -1, -1, 55, 147, 117, 140, 63, - 64, 65, -1, 105, -1, 147, 1004, -1, -1, 668, - 70, 71, 72, 73, 74, 75, 76, 77, 669, 670, - 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, - -1, -1, -1, 1031, -1, 1033, -1, 1035, 140, 1037, - 100, 101, 102, 90, -1, 147, 90, 706, 90, -1, - 701, -1, 116, 117, -1, -1, -1, -1, 105, 1057, - -1, 105, -1, 105, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, 135, 136, 51, -1, 53, - 54, 55, 56, 143, 144, -1, 51, -1, 53, 54, - 55, 56, -1, 140, -1, 69, 140, 90, 140, -1, - 147, 221, 222, 147, 69, 147, 2, -1, 4, 5, - 6, 51, 105, 53, 54, 55, 56, 13, -1, -1, - -1, -1, 773, 40, 41, 42, 43, 44, -1, 69, - 781, 782, -1, -1, 785, -1, -1, 788, 789, 259, - 260, 261, 262, 794, 795, 804, -1, 140, -1, 800, - 801, -1, 90, 273, 147, -1, 52, 277, -1, -1, - 56, 281, 282, 814, -1, 90, 817, 105, 142, 51, - 829, 53, 54, 55, 56, 826, 827, 142, -1, -1, - 105, -1, -1, 834, -1, -1, 82, 69, -1, -1, - 63, 64, 65, -1, -1, 846, 847, -1, -1, 63, - 64, 65, 140, 85, -1, -1, -1, 115, -1, 147, - 118, 119, 94, -1, -1, 140, -1, -1, 100, 101, - 102, 103, 147, 119, 63, 64, 65, 347, 348, 349, - 350, -1, 352, 353, 142, 788, 789, -1, 146, -1, - 148, 794, 795, 116, 117, -1, 128, 898, -1, 131, - -1, 371, 116, 117, 913, -1, -1, 908, 909, -1, - 919, -1, 382, -1, -1, 916, -1, 820, 821, -1, - 823, 824, -1, -1, 394, -1, -1, 116, 117, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, -1, 415, 416, 417, 418, 419, - 420, 421, 422, 423, 424, 425, 426, -1, -1, 429, - 63, 64, 65, -1, 210, -1, 63, 64, 65, 439, - 440, -1, -1, 974, -1, 976, -1, -1, 979, -1, - -1, 63, 64, 65, 454, -1, 51, 457, 53, 54, - 55, 56, 63, 64, 65, 898, -1, 467, -1, 469, - -1, 471, 472, -1, 69, -1, -1, -1, 478, 88, - 89, -1, -1, 116, 117, -1, 1017, 487, 921, 116, - 117, 491, 101, -1, -1, 495, -1, -1, 498, 94, - 500, -1, 502, 503, 116, 117, 101, 102, 103, -1, - 286, -1, -1, -1, -1, 116, 117, 293, 294, 519, - 129, 130, 131, 132, 133, 301, -1, -1, -1, 529, - -1, -1, 532, 128, -1, -1, 312, -1, -1, -1, - -1, -1, 542, -1, -1, -1, -1, -1, 51, -1, - 53, 54, 55, 56, -1, -1, -1, -1, 558, 559, - 2, -1, 4, 5, 6, 7, 69, -1, -1, -1, - 346, 13, -1, -1, 574, 351, -1, -1, -1, -1, - -1, -1, -1, 51, -1, 53, 54, 55, 56, -1, - -1, 94, -1, 593, 370, -1, 596, 100, 101, 102, - 103, 69, -1, -1, -1, -1, -1, -1, -1, -1, - 52, -1, -1, -1, 56, 391, -1, -1, 121, -1, - 396, 397, -1, 399, -1, 128, 94, -1, 131, -1, - -1, -1, 100, 51, -1, 53, 54, 55, 56, -1, - 82, 144, -1, 51, -1, 53, 54, 55, 56, -1, - -1, 69, -1, 51, -1, 53, 54, 55, 56, -1, - -1, 69, -1, 439, 440, -1, -1, -1, -1, 669, - -1, 69, -1, -1, -1, -1, 94, 119, -1, -1, - 456, 681, 100, 101, 102, 103, 94, -1, -1, 465, - -1, -1, 100, 101, 102, 103, 94, 473, -1, -1, - -1, 701, 100, 101, 102, 103, -1, 483, -1, -1, - 128, -1, 712, 131, 51, -1, 53, 54, 55, 56, - 128, 721, 722, 131, -1, -1, 144, -1, -1, -1, - 128, -1, 69, 131, -1, -1, 144, -1, -1, 515, - -1, -1, -1, -1, 142, -1, -1, 51, 524, 53, - 54, 55, 56, -1, -1, -1, 2, 94, 4, -1, - -1, -1, 538, 100, 540, 69, -1, 13, 210, -1, - -1, -1, -1, 549, -1, -1, -1, 777, -1, -1, - -1, -1, 782, 783, -1, 785, -1, -1, 788, 789, - 94, -1, -1, 793, 794, 795, -1, 51, -1, 53, - 54, 55, 56, -1, -1, -1, 52, -1, -1, -1, - -1, -1, -1, -1, -1, 69, -1, 817, -1, -1, - 820, 821, -1, 823, 824, -1, 602, -1, -1, -1, - -1, 85, -1, 833, -1, -1, -1, -1, 838, -1, - 94, -1, -1, -1, 286, -1, 100, 101, 102, 103, - -1, 293, 294, -1, -1, 855, -1, -1, -1, 301, - -1, -1, -1, -1, -1, -1, 866, -1, -1, -1, - 312, 88, 89, 119, 128, -1, -1, 131, -1, -1, - -1, 881, -1, -1, 101, -1, -1, -1, -1, -1, - -1, 891, 892, -1, 670, -1, -1, -1, 898, -1, - -1, -1, 44, -1, 346, -1, -1, -1, -1, 351, - -1, 128, 129, 130, 131, 132, 133, 2, -1, 4, - -1, 921, -1, -1, -1, -1, -1, -1, 370, 929, + 2, 27, 69, 284, 89, 87, 88, 28, 66, 271, + 2, 10, 4, 5, 6, 487, 15, 9, 10, 21, + 7, 13, 52, 15, 16, 17, 7, 22, 20, 82, + 16, 17, 4, 14, 20, 215, 478, 543, 313, 400, + 5, 6, 222, 222, 56, 14, 752, 28, 13, 15, + 440, 441, 54, 55, 16, 17, 430, 306, 20, 28, + 52, 310, 21, 22, 56, 590, 504, 778, 376, 75, + 587, 58, 74, 75, 66, 75, 2, 58, 4, 259, + 118, 455, 16, 17, 52, 330, 20, 25, 295, 318, + 82, 56, 54, 55, 371, 685, 938, 535, 472, 605, + 27, 29, 963, 69, 662, 663, 696, 481, 500, 111, + 105, 25, 504, 0, 26, 392, 122, 82, 16, 17, + 57, 331, 20, 26, 334, 117, 336, 119, 338, 91, + 340, 60, 61, 62, 63, 79, 218, 25, 269, 368, + 271, 25, 587, 51, 90, 590, 105, 229, 593, 25, + 103, 119, 111, 112, 144, 25, 54, 55, 138, 25, + 25, 61, 797, 60, 64, 65, 63, 347, 803, 55, + 129, 545, 90, 92, 305, 128, 121, 16, 17, 1040, + 457, 20, 126, 28, 121, 113, 121, 105, 115, 1031, + 397, 118, 119, 101, 102, 103, 90, 142, 378, 51, + 90, 147, 121, 55, 142, 400, 144, 289, 214, 142, + 107, 213, 214, 213, 214, 54, 116, 117, 210, 146, + 128, 148, 140, 142, 223, 224, 138, 90, 142, 147, + 297, 223, 224, 315, 92, 138, 121, 943, 305, 306, + 757, 144, 105, 310, 90, 440, 441, 509, 90, 960, + 808, 144, 963, 147, 142, 242, 144, 147, 142, 105, + 313, 242, 18, 90, 20, 295, 142, 269, 543, 271, + 125, 428, 142, 275, 57, 432, 142, 142, 435, 55, + 786, 121, 90, 275, 147, 92, 252, 279, 726, 275, + 55, 283, 284, 279, 140, 287, 90, 477, 478, 456, + 25, 147, 294, 295, 142, 147, 90, 20, 553, 90, + 302, 105, 757, 275, 471, 57, 473, 279, 547, 287, + 147, 313, 142, 684, 138, 482, 101, 295, 90, 1040, + 605, 297, 115, 725, 726, 118, 119, 395, 863, 147, + 123, 551, 400, 145, 934, 279, 140, 527, 313, 348, + 349, 350, 351, 147, 534, 347, 348, 349, 350, 351, + 352, 353, 354, 147, 521, 148, 147, 397, 294, 92, + 90, 385, 374, 387, 376, 347, 302, 508, 509, 371, + 92, 279, 440, 441, 92, 147, 398, 61, 121, 546, + 64, 65, 141, 835, 323, 139, 673, 55, 121, 142, + 392, 37, 38, 395, 794, 397, 398, 799, 400, 121, + 800, 801, 92, 121, 101, 101, 454, 791, 863, 142, + 865, 347, 867, 92, 869, 101, 352, 147, 430, 397, + 142, 9, 10, 398, 715, 92, 275, 15, 430, 121, + 279, 121, 116, 117, 430, 131, 132, 133, 440, 441, + 142, 432, 121, 455, 435, 763, 658, 719, 121, 661, + 51, 463, 934, 455, 121, 457, 458, 90, 430, 455, + 472, 602, 498, 432, 92, 456, 468, 679, 142, 481, + 472, 142, 105, 142, 476, 142, 472, 736, 541, 481, + 543, 671, 473, 455, 486, 481, 517, 456, 936, 92, + 468, 482, 779, 121, 51, 92, 508, 509, 476, 142, + 472, 786, 793, 51, 473, 905, 518, 140, 486, 481, + 121, 652, 142, 482, 147, 92, 518, 587, 121, 806, + 51, 711, 711, 615, 121, 527, 517, 99, 500, 117, + 521, 507, 504, 545, 936, 58, 59, 15, 517, 541, + 92, 543, 605, 545, 121, 142, 395, 92, 1003, 545, + 552, 400, 521, 13, 62, 546, 64, 65, 92, 850, + 532, 879, 880, 535, 851, 142, 541, 121, 543, 121, + 711, 121, 844, 545, 552, 577, 121, 546, 719, 440, + 441, 577, 518, 788, 16, 368, 598, 121, 63, 794, + 15, 527, 500, 139, 596, 800, 801, 633, 115, 92, + 596, 118, 119, 605, 2, 145, 4, 145, 116, 117, + 92, 9, 10, 474, 475, 58, 59, 15, 16, 17, + 810, 142, 20, 790, 532, 792, 17, 18, 121, 916, + 605, 148, 142, 299, 26, 223, 224, 303, 15, 121, + 652, 490, 1026, 15, 649, 835, 658, 875, 876, 661, + 662, 663, 587, 658, 52, 590, 661, 92, 142, 736, + 44, 522, 115, 672, 121, 118, 119, 679, 66, 141, + 672, 673, 684, 685, 141, 115, 707, 689, 118, 119, + 649, 63, 64, 65, 696, 682, 121, 757, 15, 658, + 18, 682, 661, 141, 1012, 283, 284, 706, 90, 141, + 905, 121, 122, 844, 706, 139, 15, 719, 677, 804, + 679, 139, 141, 105, 90, 62, 707, 64, 65, 117, + 788, 119, 139, 786, 90, 90, 794, 795, 707, 105, + 920, 920, 800, 801, 116, 117, 926, 926, 142, 105, + 105, 1032, 44, 767, 768, 769, 138, 771, 140, 773, + 57, 763, 144, 725, 726, 147, 142, 142, 90, 142, + 348, 349, 350, 351, 140, 353, 354, 142, 144, 116, + 117, 147, 580, 105, 140, 140, 584, 779, 44, 791, + 16, 147, 147, 15, 786, 787, 788, 93, 858, 791, + 573, 14, 794, 795, 15, 791, 808, 867, 800, 801, + 15, 792, 145, 142, 806, 807, 818, 590, 140, 821, + 593, 786, 210, 142, 823, 147, 16, 725, 820, 791, + 142, 823, 757, 792, 142, 223, 224, 799, 142, 807, + 832, 833, 844, 15, 15, 684, 141, 905, 840, 505, + 139, 15, 820, 778, 778, 15, 512, 15, 90, 851, + 852, 787, 139, 142, 832, 833, 126, 126, 524, 16, + 1027, 115, 840, 105, 118, 119, 55, 879, 880, 15, + 458, 139, 55, 15, 852, 877, 141, 275, 142, 115, + 882, 279, 118, 119, 142, 283, 284, 142, 980, 287, + 960, 799, 146, 142, 148, 142, 294, 295, 140, 580, + 144, 142, 877, 905, 302, 147, 142, 882, 574, 575, + 146, 142, 148, 915, 916, 115, 144, 919, 118, 119, + 142, 923, 934, 947, 948, 949, 950, 518, 863, 6, + 13, 1029, 778, 794, 795, 1031, 805, 915, 604, 800, + 801, 1028, 254, 7, 919, 923, 146, 960, 148, 347, + 348, 349, 350, 351, 352, 353, 354, 993, 115, 884, + 885, 118, 119, 1033, 936, 826, 827, 580, 829, 830, + 778, 957, -1, 371, 1044, -1, -1, 2, -1, 4, + -1, 983, -1, 985, -1, -1, 988, -1, 13, 146, + -1, 148, -1, -1, 392, 778, -1, 395, -1, 397, + 1012, 16, 400, -1, -1, 983, 90, 985, -1, 101, + 988, -1, 1036, -1, 1026, 681, 1028, 1029, 63, 64, + 65, 105, -1, 957, 1026, 960, 960, 52, 963, 963, + 1026, 965, 430, 37, 38, 960, 1027, 129, 130, 131, + 132, 133, 440, 441, 905, 63, 64, 65, 51, 26, + 53, 54, 55, 56, 1026, -1, 140, 455, 1027, 457, + 458, -1, -1, 147, -1, -1, 69, 928, -1, 735, + 468, 116, 117, -1, 472, -1, -1, -1, 476, 1013, + 863, -1, 865, 481, 672, -1, 869, 753, 486, -1, + -1, 1016, 1017, 1018, 119, 1020, 1021, 778, 116, 117, + 115, -1, -1, 118, 119, 1040, 1040, 26, 1042, -1, + 1044, 115, 1046, 90, 118, 119, -1, -1, 706, -1, + 518, -1, 51, -1, 53, 54, 55, 56, 105, 527, + -1, 146, 1066, 148, -1, 1060, 1061, 1062, 1063, 142, + 69, -1, 146, -1, 148, 1070, -1, 545, -1, 957, + 90, 90, 960, -1, 552, 963, -1, 965, 941, 942, + -1, 138, -1, 140, -1, 105, 105, 144, -1, -1, + 147, 90, 90, 90, -1, 26, 26, 843, -1, 577, + 963, -1, 965, -1, -1, 210, 105, 105, 105, 26, + -1, -1, -1, 859, -1, -1, -1, -1, 596, -1, + 140, 140, -1, 9, 10, 1013, -1, 147, 147, 15, + 16, 17, -1, 142, 20, -1, 90, 1000, -1, 138, + 1003, 140, 140, 140, -1, 144, -1, -1, 147, 147, + 147, 105, 1040, -1, 1042, 823, 1044, -1, 1046, 90, + 90, 47, 48, 49, 50, 63, 64, 65, 54, 55, + -1, -1, 1035, 90, 105, 105, -1, 1040, 1066, 1042, + 66, 67, 287, 1046, -1, -1, 140, -1, 105, 294, + 295, -1, -1, 147, 672, 673, 957, 302, -1, 960, + -1, -1, 963, 1066, 965, -1, -1, 138, 138, 140, + 140, -1, -1, 144, 144, -1, 147, 147, 116, 117, + -1, 138, 51, 140, 53, 54, 55, 56, 706, -1, + 147, 117, -1, -1, -1, 63, 64, 65, -1, -1, + 69, -1, 347, 63, 64, 65, -1, 352, -1, -1, + -1, -1, 1013, 63, 64, 65, -1, -1, 63, 64, + 65, -1, -1, -1, -1, 94, 371, -1, -1, -1, + -1, 100, 101, 102, 103, -1, -1, -1, -1, 1040, + -1, 1042, -1, 1044, -1, 1046, -1, 392, 116, 117, + -1, -1, 397, -1, -1, 400, 116, 117, -1, 128, + 115, 779, 131, 118, 119, 1066, 116, 117, -1, 787, + 788, 116, 117, 791, -1, 144, 794, 795, -1, -1, + -1, -1, 800, 801, -1, -1, -1, -1, 806, 807, + 145, 146, -1, 148, -1, 440, 441, 223, 224, -1, + -1, -1, 820, 88, 89, 823, 51, -1, 53, 54, + 55, 56, 457, -1, 832, 833, 101, 40, 41, 42, + 43, 44, 840, 468, 69, -1, -1, -1, -1, -1, + -1, 476, 44, 851, 852, 261, 262, 263, 264, -1, + -1, 486, -1, 128, 129, 130, 131, 132, 133, 275, + -1, -1, 115, 279, -1, 118, 119, 283, 284, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, -1, -1, -1, 88, 89, -1, 391, - -1, -1, -1, -1, 396, 397, -1, -1, -1, 101, - -1, -1, -1, -1, 210, -1, -1, 52, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 82, 83, -1, 518, -1, -1, 88, 89, -1, 142, + -1, -1, 527, 146, -1, 148, -1, 905, -1, 101, + -1, 51, -1, 53, 54, 55, 56, 915, 916, -1, + 115, -1, -1, 118, 119, 923, -1, 552, -1, 69, 122, -1, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, -1, -1, -1, -1, 773, -1, -1, - 142, -1, -1, -1, 780, 781, 782, -1, -1, -1, - -1, -1, 788, -1, 456, -1, -1, 1017, 794, 795, - -1, -1, -1, 465, 800, 801, -1, -1, -1, -1, - -1, 473, -1, -1, 119, -1, -1, -1, 814, -1, - 286, 483, -1, -1, -1, -1, -1, 293, 294, -1, - 826, 827, -1, -1, -1, 301, -1, -1, 834, -1, - -1, 51, -1, 53, 54, 55, 56, -1, -1, -1, - 846, 847, -1, 515, -1, -1, 88, 89, -1, 69, - -1, -1, 524, -1, -1, -1, -1, -1, -1, 101, - -1, -1, -1, -1, 870, -1, 538, -1, 540, 875, - 346, -1, -1, -1, 94, 351, -1, 549, -1, -1, - 100, 101, 102, 103, 126, 127, 128, 129, 130, 131, - 132, 133, 898, -1, 370, 210, 72, 73, 74, 75, - 76, 77, 908, 909, 80, 81, 912, -1, 128, -1, - 916, 131, 88, 89, -1, 391, -1, -1, -1, -1, - 396, -1, -1, 399, -1, 101, -1, -1, -1, -1, - 602, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, - -1, -1, -1, 439, 440, -1, -1, -1, 974, -1, - 976, 286, -1, 979, -1, -1, -1, -1, 293, 294, - 456, -1, -1, -1, -1, -1, 301, -1, -1, 465, - -1, -1, -1, -1, -1, -1, -1, 473, 670, -1, - 0, -1, -1, -1, -1, -1, -1, 483, -1, -1, - -1, -1, -1, 13, 14, 15, 16, 17, 18, -1, - 20, -1, -1, -1, -1, -1, 26, 27, -1, -1, - -1, 346, -1, -1, -1, -1, 351, 37, 38, 515, - 40, 41, 42, 43, 44, -1, -1, -1, 524, -1, - -1, -1, -1, -1, -1, 370, -1, -1, -1, -1, + 132, 133, 348, 349, 350, 351, -1, 353, 354, -1, + 142, 146, -1, 148, 94, -1, -1, -1, -1, -1, + 100, 101, 102, 103, -1, -1, 372, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 383, -1, -1, + -1, -1, -1, -1, -1, 983, -1, 985, 128, 395, + 988, 131, -1, -1, 400, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, -1, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, -1, -1, 430, -1, -1, 51, 1026, 53, + 54, 55, 56, -1, 440, 441, -1, 51, -1, 53, + 54, 55, 56, -1, -1, 69, -1, -1, 673, 455, + -1, -1, 458, -1, 51, 69, 53, 54, 55, 56, + -1, -1, -1, -1, 470, -1, 472, -1, 474, 475, + 94, -1, 69, -1, -1, 481, 100, -1, -1, -1, + 94, -1, -1, -1, 490, -1, 100, 493, -1, -1, + -1, 497, -1, -1, 500, -1, 502, 94, 504, 505, + 88, 89, -1, 100, 101, 102, 103, 2, -1, 4, + 5, 6, -1, 101, -1, -1, 522, 51, 13, 53, + 54, 55, 56, -1, 121, -1, 532, -1, -1, 535, + -1, 128, -1, -1, 131, 69, -1, -1, -1, 545, + -1, 129, 130, 131, 132, 133, -1, 144, 51, -1, + 53, 54, 55, 56, 779, 561, 562, 52, -1, -1, + 94, 56, 787, 788, -1, -1, 69, -1, -1, 794, + -1, 577, -1, -1, -1, 800, 801, -1, -1, -1, + -1, 806, 807, -1, -1, -1, -1, 82, -1, -1, + 596, 94, -1, 599, -1, 820, -1, 100, 101, 102, + 103, -1, -1, -1, 88, 89, -1, 832, 833, -1, + -1, -1, -1, -1, -1, 840, -1, 101, -1, -1, + -1, -1, -1, -1, 119, 128, 851, 852, 131, -1, + -1, -1, -1, -1, 51, -1, 53, 54, 55, 56, + -1, 144, 126, 127, 128, 129, 130, 131, 132, 133, + -1, -1, 69, -1, -1, -1, 51, -1, 53, 54, + 55, 56, -1, -1, -1, -1, 672, -1, -1, -1, + -1, -1, -1, -1, 69, -1, -1, 94, 684, -1, + 905, 687, 688, 100, 101, 102, 103, -1, -1, -1, + 915, 916, -1, 2, 919, 4, 5, 6, 923, 94, + 706, -1, -1, -1, 13, -1, 101, 102, 103, -1, + 716, 128, -1, -1, 131, 210, -1, -1, -1, 725, + 726, -1, -1, -1, 0, 142, -1, -1, -1, -1, + -1, -1, -1, 128, -1, -1, -1, 13, 14, 15, + 16, 17, 18, 52, 20, -1, -1, 56, -1, -1, + 26, 27, -1, -1, -1, -1, -1, -1, 983, -1, + 985, 37, 38, 988, 40, 41, 42, 43, 44, -1, + -1, -1, -1, 82, -1, -1, -1, 783, -1, -1, + -1, -1, 788, 789, -1, 791, -1, -1, 794, 795, + -1, -1, 287, 799, 800, 801, -1, -1, -1, 294, + 295, -1, -1, -1, -1, -1, -1, 302, -1, -1, + 119, -1, -1, -1, 90, -1, -1, 823, 313, -1, + 826, 827, -1, 829, 830, -1, -1, -1, -1, 105, + -1, -1, -1, 839, -1, -1, -1, 843, -1, 115, + -1, -1, 118, 119, -1, -1, -1, -1, -1, -1, + -1, -1, 347, -1, 860, 861, -1, 352, -1, -1, + -1, -1, 138, 139, -1, -1, 872, 873, 144, 145, + 146, 147, 148, -1, -1, -1, 371, -1, -1, -1, + -1, -1, 888, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 898, 899, -1, -1, -1, 392, -1, 905, + -1, 210, 397, 398, -1, 400, -1, 51, -1, 53, + 54, 55, 56, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 928, -1, -1, 69, -1, -1, -1, -1, + 936, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 85, -1, -1, -1, 440, 441, -1, -1, -1, + 94, -1, -1, -1, -1, -1, 100, 101, 102, 103, + -1, -1, 457, -1, 2, -1, 4, 5, 6, -1, + -1, -1, -1, 468, -1, 13, -1, -1, 287, -1, + -1, 476, -1, -1, 128, 294, 295, 131, -1, -1, + -1, 486, -1, 302, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 313, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 52, -1, -1, -1, 56, -1, + 1026, -1, -1, 518, -1, -1, -1, -1, -1, -1, + -1, -1, 527, -1, -1, 44, -1, -1, 347, -1, + -1, -1, -1, 352, 82, -1, 541, -1, 543, -1, + -1, -1, -1, -1, -1, -1, -1, 552, -1, -1, + -1, -1, 371, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, -1, -1, -1, -1, 88, + 89, 119, -1, 392, -1, -1, -1, -1, 397, 398, + -1, 400, 101, 51, -1, 53, 54, 55, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 549, -1, -1, 391, -1, -1, -1, - -1, 396, -1, -1, 399, -1, -1, -1, -1, -1, - 90, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 773, -1, -1, -1, 105, -1, -1, 780, 781, - -1, -1, -1, -1, -1, 115, -1, -1, 118, 119, - -1, -1, -1, -1, 439, 440, -1, -1, 800, 801, - -1, -1, -1, -1, -1, -1, -1, -1, 138, 139, - -1, 456, 814, -1, 144, 145, 146, 147, 148, -1, - 465, -1, -1, -1, 826, 827, -1, -1, 473, -1, - -1, -1, 834, -1, -1, -1, -1, -1, 483, -1, - -1, -1, -1, -1, 846, 847, -1, -1, -1, -1, + 605, 69, -1, 122, -1, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, -1, -1, 85, -1, -1, + -1, 440, 441, -1, -1, -1, 94, -1, -1, -1, + -1, -1, 100, 101, 102, 103, -1, -1, 457, -1, + 2, -1, 4, 5, 6, 7, -1, -1, -1, 468, + -1, 13, -1, -1, -1, -1, -1, 476, -1, -1, + 128, -1, 210, 131, -1, -1, -1, 486, 673, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 51, 52, 670, -1, 55, -1, 870, -1, - 515, -1, -1, 875, -1, -1, -1, -1, -1, 524, - -1, 70, 71, 72, 73, 74, 75, 76, 77, -1, - -1, 80, 81, -1, -1, -1, -1, 86, 87, 88, - 89, -1, -1, -1, 549, -1, 908, 909, -1, -1, - 912, 100, 101, 102, 916, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, -1, 135, 136, -1, -1, - -1, -1, -1, -1, 143, 144, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 773, -1, -1, - -1, -1, 974, -1, 976, 781, 782, 979, -1, -1, - 51, 52, 788, -1, 55, -1, -1, -1, 794, 795, - -1, -1, -1, -1, 800, 801, -1, -1, -1, 70, - 71, 72, 73, 74, 75, 76, 77, -1, 814, 80, - 81, -1, -1, -1, -1, 86, 87, 88, 89, -1, - 826, 827, -1, -1, -1, 670, -1, -1, 834, 100, - 101, 102, -1, -1, -1, -1, -1, -1, -1, -1, - 846, 847, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, -1, 135, 136, 72, 73, 74, 75, - 76, 77, 143, 144, 80, 81, -1, -1, -1, -1, - -1, -1, 88, 89, -1, -1, -1, -1, -1, -1, - -1, -1, 898, -1, -1, 101, -1, -1, -1, -1, - -1, -1, 908, 909, -1, -1, 912, -1, -1, -1, - 916, -1, -1, -1, -1, -1, -1, -1, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 773, -1, - -1, -1, -1, -1, -1, -1, 781, 782, -1, -1, - -1, -1, -1, 788, -1, -1, -1, -1, -1, 794, - 795, -1, -1, -1, -1, 800, 801, -1, 72, 73, - 74, 75, 76, 77, 78, -1, 80, 81, 974, 814, - 976, -1, -1, 979, 88, 89, -1, -1, -1, -1, - -1, 826, 827, -1, -1, -1, -1, 101, -1, 834, - -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, - -1, 846, 847, -1, -1, -1, -1, -1, -1, -1, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, -1, -1, -1, 88, 89, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 101, - -1, -1, -1, 898, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 908, 909, -1, -1, -1, -1, -1, - 122, 916, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 0, 1, -1, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, - 19, -1, 21, 22, 23, 24, -1, -1, -1, -1, - -1, 30, 31, 32, 33, 34, 35, 36, -1, 974, - 39, 976, -1, -1, 979, -1, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, - 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, - 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, - -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, - -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, - -1, 110, 111, 112, 0, 114, 115, -1, -1, 118, - 119, -1, -1, -1, -1, -1, -1, 13, 14, 15, - 16, 17, 18, -1, 20, 134, 135, 136, -1, -1, - -1, 27, 28, 29, -1, -1, -1, 146, -1, 148, - -1, 37, 38, -1, 40, 41, 42, 43, 44, -1, + 52, -1, -1, -1, 56, -1, -1, -1, -1, 518, + -1, -1, -1, -1, -1, -1, -1, -1, 527, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, -1, - -1, -1, 88, 89, 90, -1, -1, 93, -1, -1, - -1, -1, -1, 99, -1, 101, -1, -1, -1, 105, - -1, -1, -1, -1, -1, -1, -1, 113, -1, 115, - -1, -1, 118, 119, -1, -1, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, - 0, -1, -1, 139, 140, 141, 142, -1, -1, 145, - 146, 147, 148, 13, 14, 15, 16, 17, 18, -1, - 20, -1, -1, -1, -1, -1, 26, 27, 28, -1, - -1, -1, -1, -1, -1, -1, -1, 37, 38, -1, - 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, + 82, -1, 541, -1, 543, -1, -1, -1, -1, -1, + -1, -1, -1, 552, -1, -1, -1, -1, -1, 287, + -1, -1, -1, -1, -1, -1, 294, 295, -1, -1, + -1, -1, -1, -1, 302, -1, -1, 119, -1, -1, + -1, -1, -1, -1, -1, 313, -1, -1, -1, -1, + -1, -1, -1, -1, 779, -1, -1, -1, -1, -1, + -1, 786, 787, 788, -1, -1, 605, -1, -1, 794, + -1, -1, -1, -1, -1, 800, 801, -1, -1, 347, + -1, 806, 807, -1, 352, 72, 73, 74, 75, 76, + 77, 78, -1, 80, 81, 820, -1, -1, -1, -1, + -1, 88, 89, 371, -1, -1, -1, 832, 833, -1, + -1, -1, -1, -1, 101, 840, -1, -1, -1, -1, + -1, -1, -1, -1, 392, -1, 851, 852, 210, 397, + 398, -1, 400, -1, 673, -1, -1, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, -1, -1, -1, + -1, -1, 877, -1, -1, -1, -1, 882, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 440, 441, -1, -1, -1, -1, -1, -1, + 905, -1, -1, -1, -1, -1, -1, -1, -1, 457, + 915, 916, -1, -1, 919, -1, -1, -1, 923, -1, + 468, -1, -1, -1, -1, 287, -1, -1, 476, -1, + -1, -1, 294, 295, -1, -1, -1, -1, 486, -1, + 302, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 313, -1, -1, -1, -1, -1, -1, -1, -1, + 779, -1, -1, -1, -1, -1, -1, 786, 787, 788, + 518, -1, -1, -1, -1, 794, -1, -1, 983, 527, + 985, 800, 801, 988, -1, 347, -1, 806, 807, -1, + 352, -1, -1, 541, -1, 543, -1, -1, -1, -1, + -1, 820, -1, -1, 552, -1, -1, -1, -1, 371, + -1, -1, -1, 832, 833, -1, -1, -1, -1, -1, + -1, 840, -1, -1, -1, -1, -1, -1, -1, -1, + 392, -1, 851, 852, -1, 397, 398, -1, -1, -1, + -1, -1, -1, 2, -1, 4, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 605, 877, -1, + -1, -1, -1, 882, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 905, -1, -1, -1, + 88, 89, -1, 52, -1, 457, 915, 916, -1, -1, + 919, -1, -1, 101, 923, -1, 468, -1, -1, -1, + -1, -1, -1, 44, 476, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 486, 673, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, -1, -1, -1, -1, + -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, -1, -1, -1, 518, 88, 89, -1, + 119, -1, -1, -1, 983, 527, 985, -1, -1, 988, + 101, -1, -1, -1, -1, -1, -1, -1, -1, 541, + -1, 543, -1, -1, -1, -1, -1, -1, -1, -1, + 552, 122, -1, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, -1, -1, -1, -1, 88, 89, - 90, -1, -1, 93, -1, -1, -1, -1, -1, 99, - -1, 101, -1, -1, -1, 105, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 115, -1, -1, 118, 119, - -1, -1, 122, -1, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, -1, 0, -1, 138, 139, - 140, 141, 142, -1, 144, 145, 146, 147, 148, 13, - 14, 15, 16, 17, 18, -1, 20, -1, -1, -1, - -1, -1, -1, 27, 28, -1, -1, -1, -1, -1, - -1, -1, -1, 37, 38, -1, 40, 41, 42, 43, - 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - -1, -1, -1, -1, 88, 89, 90, -1, 92, 93, - -1, -1, -1, -1, -1, 99, -1, 101, -1, -1, - -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 115, -1, -1, 118, 119, -1, 121, 122, -1, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - -1, -1, 0, -1, -1, 139, 140, 141, 142, -1, - -1, 145, 146, 147, 148, 13, 14, 15, 16, 17, - 18, -1, 20, -1, -1, -1, -1, -1, 26, 27, - 28, -1, -1, -1, -1, -1, -1, -1, -1, 37, - 38, -1, 40, 41, 42, 43, 44, -1, -1, -1, + -1, 779, 44, -1, -1, -1, -1, -1, 786, 787, + 788, -1, -1, 605, -1, -1, 794, -1, -1, -1, + -1, 210, 800, 801, -1, -1, -1, -1, 806, 807, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 820, -1, -1, -1, 88, 89, -1, -1, + -1, -1, -1, -1, 832, 833, -1, -1, -1, 101, + -1, -1, 840, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 851, 852, -1, -1, -1, -1, -1, + 122, 673, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, -1, -1, -1, -1, -1, -1, 287, 877, + -1, -1, -1, -1, 882, 294, 295, -1, -1, -1, + -1, -1, -1, 302, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, -1, 905, -1, -1, + 88, 89, -1, -1, -1, -1, -1, 915, 916, -1, + -1, 919, -1, 101, -1, 923, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 347, -1, + -1, -1, -1, 352, 122, -1, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, -1, -1, -1, -1, + -1, -1, 371, -1, 142, -1, -1, 779, -1, -1, + -1, -1, -1, -1, 786, 787, -1, -1, -1, -1, + -1, -1, -1, 392, -1, 983, -1, 985, 397, -1, + 988, 400, -1, -1, 806, 807, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 820, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 832, 833, 13, 14, 15, 16, 17, 18, 840, 20, + -1, 440, 441, -1, -1, -1, 27, 28, 29, 851, + 852, -1, -1, -1, -1, -1, 37, 38, 457, 40, + 41, 42, 43, 44, -1, -1, -1, -1, -1, 468, + -1, -1, -1, -1, -1, 877, 57, 476, -1, -1, + 882, -1, -1, -1, -1, -1, -1, 486, -1, -1, + -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, -1, -1, -1, -1, 88, 89, 90, + -1, -1, 93, 915, 916, -1, -1, 919, 99, 518, + 101, 923, -1, -1, 105, -1, -1, -1, 527, -1, + -1, -1, 113, -1, 115, -1, -1, 118, 119, -1, + -1, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 552, -1, -1, -1, -1, 139, 140, + 141, 142, -1, -1, 145, 146, 147, 148, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 983, -1, 985, 0, 1, 988, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, + -1, -1, -1, 19, -1, 21, 22, 23, 24, -1, + -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, + 36, -1, -1, 39, -1, -1, -1, -1, -1, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, + 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, + -1, -1, -1, -1, 673, 91, -1, -1, 94, 95, + -1, 97, 98, -1, 100, -1, -1, -1, 104, -1, + 106, 107, 108, -1, 110, 111, 112, -1, 114, 115, + -1, -1, 118, 119, -1, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, -1, 134, 135, + 136, 88, 89, -1, -1, -1, -1, -1, -1, -1, + 146, -1, 148, -1, 101, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 122, -1, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, -1, -1, -1, + -1, -1, -1, -1, -1, 142, -1, -1, -1, -1, + 779, -1, -1, -1, -1, -1, -1, -1, 787, 788, + -1, -1, -1, -1, -1, 794, -1, -1, -1, -1, + -1, 800, 801, -1, -1, -1, -1, 806, 807, -1, + -1, -1, -1, -1, -1, 72, 73, 74, 75, 76, + 77, 820, 0, 80, 81, -1, -1, -1, -1, -1, + -1, 88, 89, 832, 833, 13, 14, 15, 16, 17, + 18, 840, 20, -1, 101, -1, -1, -1, 26, 27, + 28, -1, 851, 852, -1, -1, -1, -1, -1, 37, + 38, -1, 40, 41, 42, 43, 44, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, -1, -1, -1, - 88, 89, 90, -1, -1, 93, -1, -1, -1, -1, - -1, 99, -1, 101, -1, -1, -1, 105, -1, -1, + 78, 79, 80, 81, 82, 83, 905, -1, -1, -1, + 88, 89, 90, -1, -1, 93, 915, 916, -1, -1, + -1, 99, -1, 101, 923, -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, 115, -1, -1, 118, 119, -1, -1, 122, -1, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, -1, -1, 0, -1, - 138, 139, 140, 141, 142, -1, 144, 145, 146, 147, - 148, 13, 14, 15, 16, 17, 18, -1, 20, -1, - -1, -1, -1, -1, -1, 27, 28, -1, -1, -1, - -1, -1, -1, -1, -1, 37, 38, -1, 40, 41, - 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, + 128, 129, 130, 131, 132, 133, -1, -1, -1, -1, + 138, 139, 140, 141, 142, 0, 144, 145, 146, 147, + 148, -1, -1, -1, -1, -1, -1, -1, 13, 14, + 15, 16, 17, 18, 983, 20, 985, -1, -1, 988, + -1, -1, 27, 28, -1, -1, -1, -1, -1, -1, + -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, -1, -1, 88, 89, 90, -1, 92, 93, -1, + -1, -1, -1, -1, 99, -1, 101, -1, -1, -1, + 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 115, -1, -1, 118, 119, -1, 121, 122, -1, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, + -1, 0, -1, -1, 139, 140, 141, 142, -1, -1, + 145, 146, 147, 148, 13, 14, 15, 16, 17, 18, + -1, 20, -1, -1, -1, -1, -1, 26, 27, 28, + -1, -1, -1, -1, -1, -1, -1, -1, 37, 38, + -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, -1, -1, -1, 88, 89, 90, -1, - -1, 93, -1, -1, -1, -1, -1, 99, -1, 101, - -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 115, -1, -1, 118, 119, -1, -1, - 122, -1, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, -1, 0, -1, -1, 139, 140, 141, - 142, -1, 144, 145, 146, 147, 148, 13, 14, 15, - -1, 17, 18, -1, 20, -1, -1, -1, -1, -1, - 26, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 37, 38, -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, -1, -1, -1, -1, 88, + 89, 90, -1, -1, 93, -1, -1, -1, -1, -1, + 99, -1, 101, -1, -1, -1, 105, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 115, -1, -1, 118, + 119, -1, -1, 122, -1, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, -1, -1, 0, -1, 138, + 139, 140, 141, 142, -1, 144, 145, 146, 147, 148, + 13, 14, 15, 16, 17, 18, -1, 20, -1, -1, + -1, -1, -1, -1, 27, 28, -1, -1, -1, -1, + -1, -1, -1, -1, 37, 38, -1, 40, 41, 42, + 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, -1, - -1, -1, 88, 89, 90, -1, 92, 93, -1, -1, - -1, -1, -1, -1, -1, 101, -1, -1, -1, 105, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 115, - -1, -1, 118, 119, -1, 121, 122, -1, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, - 0, -1, 138, 139, 140, -1, 142, -1, -1, 145, - 146, 147, 148, 13, 14, 15, -1, 17, 18, -1, - 20, -1, -1, -1, -1, -1, 26, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 37, 38, -1, - 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, -1, -1, -1, -1, 88, 89, 90, -1, -1, + 93, -1, -1, -1, -1, -1, 99, -1, 101, -1, + -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 115, -1, -1, 118, 119, -1, -1, 122, + -1, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, -1, -1, 0, -1, -1, 139, 140, 141, 142, + -1, 144, 145, 146, 147, 148, 13, 14, 15, -1, + 17, 18, -1, 20, -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 37, 38, -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, -1, -1, -1, -1, 88, 89, - 90, -1, 92, 93, -1, -1, -1, -1, -1, -1, - -1, 101, -1, -1, -1, 105, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 115, -1, -1, 118, 119, - -1, 121, 122, -1, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, -1, 0, -1, 138, 139, - 140, -1, 142, -1, -1, 145, 146, 147, 148, 13, - 14, 15, -1, 17, 18, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 37, 38, -1, 40, 41, 42, 43, - 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, -1, -1, -1, + -1, 88, 89, 90, -1, 92, 93, -1, -1, -1, + -1, -1, -1, -1, 101, -1, -1, -1, 105, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 115, -1, + -1, 118, 119, -1, 121, 122, -1, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, -1, -1, 0, + -1, 138, 139, 140, -1, 142, -1, -1, 145, 146, + 147, 148, 13, 14, 15, -1, 17, 18, -1, 20, + -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 37, 38, -1, 40, + 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - -1, -1, -1, -1, 88, 89, 90, -1, 92, 93, - -1, -1, -1, -1, -1, -1, -1, 101, -1, -1, - -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 115, -1, -1, 118, 119, -1, 121, 122, -1, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - -1, -1, 0, -1, -1, 139, 140, -1, 142, -1, - -1, 145, 146, 147, 148, 13, 14, 15, -1, 17, - 18, -1, 20, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, - 38, -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, -1, -1, -1, -1, 88, 89, 90, + -1, 92, 93, -1, -1, -1, -1, -1, -1, -1, + 101, -1, -1, -1, 105, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 115, -1, -1, 118, 119, -1, + 121, 122, -1, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, -1, -1, 0, -1, 138, 139, 140, + -1, 142, -1, -1, 145, 146, 147, 148, 13, 14, + 15, -1, 17, 18, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, -1, -1, -1, - 88, 89, 90, -1, 92, 93, -1, -1, -1, -1, - -1, -1, -1, 101, -1, -1, -1, 105, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 115, -1, -1, - 118, 119, -1, 121, 122, -1, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, -1, -1, -1, -1, - -1, 139, 140, -1, 142, -1, -1, 145, 146, 147, - 148, 1, -1, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, -1, -1, 18, 19, - -1, 21, 22, 23, 24, -1, -1, -1, -1, -1, - 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, - -1, -1, -1, -1, -1, 45, -1, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, - 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, - 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, - -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, - 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, - 110, 111, 112, -1, 114, 115, -1, -1, 118, 119, + -1, -1, 37, 38, -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 134, 135, 136, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 146, 1, 148, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, - -1, 15, -1, 17, 18, 19, -1, 21, 22, 23, - 24, -1, -1, -1, -1, -1, 30, 31, 32, 33, - 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, - -1, 45, -1, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, - -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, - 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, - 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, - 114, 115, -1, -1, 118, 119, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, -1, -1, 88, 89, 90, -1, 92, 93, -1, + -1, -1, -1, -1, -1, -1, 101, -1, -1, -1, + 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 115, -1, -1, 118, 119, -1, 121, 122, -1, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, + -1, 0, -1, -1, 139, 140, -1, 142, -1, -1, + 145, 146, 147, 148, 13, 14, 15, -1, 17, 18, + -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 37, 38, + -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 134, 135, 136, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 146, 1, 148, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, -1, -1, 15, -1, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, - -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, - -1, 39, -1, -1, -1, -1, -1, 45, -1, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, - 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, - -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, - -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, - 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, - 108, -1, 110, 111, 112, -1, 114, 115, -1, -1, - 118, 119, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 134, 135, 136, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 146, 1, - 148, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, -1, -1, 15, -1, -1, 18, 19, -1, 21, - 22, 23, 24, -1, -1, -1, -1, -1, 30, 31, - 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, - -1, -1, -1, 45, -1, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, - -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, - -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, - -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, - 112, -1, 114, 115, -1, -1, 118, 119, 1, -1, + -1, -1, -1, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, -1, -1, -1, -1, 88, + 89, 90, -1, 92, 93, -1, -1, -1, -1, -1, + -1, -1, 101, -1, -1, -1, 105, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 115, -1, -1, 118, + 119, -1, 121, 122, -1, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, -1, -1, -1, -1, -1, + 139, 140, -1, 142, -1, -1, 145, 146, 147, 148, + 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, -1, -1, 18, 19, -1, + 21, 22, 23, 24, -1, -1, -1, -1, -1, 30, + 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, + -1, -1, -1, -1, 45, -1, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, + -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, + 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, + 91, -1, -1, 94, 95, -1, 97, 98, -1, 100, + -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, + 111, 112, -1, 114, 115, -1, -1, 118, 119, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 134, 135, 136, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 146, 1, 148, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, + 15, -1, 17, 18, 19, -1, 21, 22, 23, 24, + -1, -1, -1, -1, -1, 30, 31, 32, 33, 34, + 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, + 45, -1, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, + -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, + 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, + 95, -1, 97, 98, -1, 100, -1, -1, -1, 104, + -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, + 115, -1, -1, 118, 119, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 134, + 135, 136, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 146, 1, 148, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, -1, -1, 15, -1, -1, 18, + 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, + -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, + 39, -1, -1, -1, -1, -1, 45, -1, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, + 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, + 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, + -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, + -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, + -1, 110, 111, 112, -1, 114, 115, -1, -1, 118, + 119, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 134, 135, 136, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 146, 1, 148, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - -1, -1, 134, 135, 136, -1, 19, -1, 21, 22, - 23, 24, -1, -1, 146, -1, 148, 30, 31, 32, + -1, -1, 15, -1, -1, 18, 19, -1, 21, 22, + 23, 24, -1, -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, - -1, -1, 45, 46, 47, 48, 49, 50, 51, 52, + -1, -1, 45, -1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, - -1, 114, 115, -1, -1, 118, 119, -1, -1, -1, + -1, 114, 115, -1, -1, 118, 119, 1, -1, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, + -1, 134, 135, 136, -1, 19, -1, 21, 22, 23, + 24, -1, -1, 146, -1, 148, 30, 31, 32, 33, + 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, + -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, + -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 134, 135, 136, -1, -1, 139, -1, -1, -1, - -1, -1, -1, 146, 1, 148, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, -1, 14, 15, -1, - -1, -1, 19, -1, 21, 22, 23, 24, -1, -1, - -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, - -1, -1, 39, -1, -1, -1, -1, -1, 45, -1, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, - 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, - -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, - 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, - 107, 108, -1, 110, 111, 112, -1, 114, 115, -1, - -1, 118, 119, 1, -1, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, -1, -1, 134, 135, 136, - -1, 19, -1, 21, 22, 23, 24, -1, -1, 146, - -1, 148, 30, 31, 32, 33, 34, 35, 36, -1, + 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, + 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, + 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, + 114, 115, -1, -1, 118, 119, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 134, 135, 136, -1, -1, 139, -1, -1, -1, -1, + -1, -1, 146, 1, 148, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, -1, 14, 15, -1, -1, + -1, 19, -1, 21, 22, 23, 24, -1, -1, -1, + -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, 45, -1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, @@ -4254,7 +4336,7 @@ static const yytype_int16 yycheck[] = 108, -1, 110, 111, 112, -1, 114, 115, -1, -1, 118, 119, 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, 134, 135, 136, -1, - 19, -1, 21, 22, 23, 24, -1, 145, 146, -1, + 19, -1, 21, 22, 23, 24, -1, -1, 146, -1, 148, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, 45, -1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, @@ -4276,26 +4358,26 @@ static const yytype_int16 yycheck[] = -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, 115, -1, -1, 118, 119, + 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, -1, -1, 134, 135, 136, -1, 19, -1, + 21, 22, 23, 24, -1, 145, 146, -1, 148, 30, + 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, + -1, -1, -1, -1, 45, -1, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, + -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, + 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, + 91, -1, -1, 94, 95, -1, 97, 98, -1, 100, + -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, + 111, 112, -1, 114, 115, -1, -1, 118, 119, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 134, 135, 136, -1, -1, 139, - -1, -1, -1, -1, -1, -1, 146, 1, 148, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, - -1, 15, -1, -1, -1, 19, -1, 21, 22, 23, - 24, -1, -1, -1, -1, -1, 30, 31, 32, 33, - 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, - -1, 45, -1, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, - -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, - 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, - 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, - 114, 115, -1, -1, 118, 119, -1, -1, 3, 4, + -1, -1, -1, 134, 135, 136, -1, -1, 139, -1, + -1, -1, -1, -1, -1, 146, 1, 148, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, - 134, 135, 136, -1, 19, -1, 21, 22, 23, 24, - -1, -1, 146, -1, 148, 30, 31, 32, 33, 34, + 15, -1, -1, -1, 19, -1, 21, 22, 23, 24, + -1, -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 45, -1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, @@ -4307,7 +4389,7 @@ static const yytype_int16 yycheck[] = 135, 136, -1, 19, -1, 21, 22, 23, 24, -1, -1, 146, -1, 148, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, 45, - -1, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, @@ -4315,16 +4397,16 @@ static const yytype_int16 yycheck[] = -1, 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, 115, -1, -1, 118, 119, -1, -1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, -1, -1, -1, 134, 135, + 7, 8, 9, 10, 11, 12, -1, -1, 134, 135, 136, -1, 19, -1, 21, 22, 23, 24, -1, -1, 146, -1, 148, 30, 31, 32, 33, 34, 35, 36, - -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, - -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, + -1, -1, 39, -1, -1, -1, -1, -1, 45, -1, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, - 97, 98, -1, -1, -1, -1, -1, 104, -1, 106, + 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, 115, -1, -1, 118, 119, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, 134, 135, 136, @@ -4338,26 +4420,21 @@ static const yytype_int16 yycheck[] = -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, -1, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, 115, -1, -1, - 118, 119, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 134, 135, 136, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 146, -1, - 148, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, -1, -1, -1, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, - -1, -1, -1, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 70, 71, - 72, 73, 74, 75, 76, 77, -1, -1, 80, 81, - -1, -1, -1, -1, 86, 87, 88, 89, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 100, 101, - 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, 135, 136, -1, -1, -1, -1, -1, - -1, 143, 144, 3, 4, 5, 6, 7, 8, 9, - 10, 11, -1, -1, -1, -1, -1, -1, -1, 19, - -1, 21, 22, 23, 24, -1, 26, -1, -1, -1, + 118, 119, -1, -1, 3, 4, 5, 6, 7, 8, + 9, 10, 11, -1, -1, -1, 134, 135, 136, -1, + 19, -1, 21, 22, 23, 24, -1, -1, 146, -1, + 148, 30, 31, 32, 33, 34, 35, 36, -1, -1, + 39, -1, -1, -1, -1, -1, -1, -1, -1, 48, + 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, + 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, + 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, + -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, + -1, -1, -1, -1, -1, 104, -1, 106, 107, 108, + -1, 110, 111, 112, -1, 114, 115, -1, -1, 118, + 119, -1, -1, 3, 4, 5, 6, 7, 8, 9, + 10, 11, -1, -1, -1, 134, 135, 136, -1, 19, + -1, 21, 22, 23, 24, -1, -1, 146, -1, 148, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, @@ -4365,61 +4442,78 @@ static const yytype_int16 yycheck[] = 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, - 100, -1, 102, 103, 104, -1, 106, 107, 108, -1, - 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 104, -1, 106, 107, 108, -1, + 110, 111, 112, -1, 114, 115, -1, -1, 118, 119, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 134, 135, 136, -1, 138, -1, - -1, -1, -1, -1, 144, 3, 4, 5, 6, 7, - 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, - -1, 19, -1, 21, 22, 23, 24, -1, 26, -1, - -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, - -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, - 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, - 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, - -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, - -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, - 98, -1, 100, -1, 102, 103, 104, -1, 106, 107, - 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, - -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, - 10, 11, -1, -1, -1, -1, 134, 135, 136, 19, - 138, 21, 22, 23, 24, -1, 144, -1, -1, -1, + -1, -1, -1, -1, 134, 135, 136, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 148, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, -1, -1, -1, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, + -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 70, 71, 72, 73, + 74, 75, 76, 77, -1, -1, 80, 81, -1, -1, + -1, -1, 86, 87, 88, 89, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 100, 101, 102, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + -1, 135, 136, -1, -1, -1, -1, -1, -1, 143, + 144, 3, 4, 5, 6, 7, 8, 9, 10, 11, + -1, -1, -1, -1, -1, -1, -1, 19, -1, 21, + 22, 23, 24, -1, 26, -1, -1, -1, 30, 31, + 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, + -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, + 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, + -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, + -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, + 102, 103, 104, -1, 106, 107, 108, -1, 110, 111, + 112, -1, 114, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 134, 135, 136, -1, 138, -1, -1, -1, + -1, -1, 144, 3, 4, 5, 6, 7, 8, 9, + 10, 11, -1, -1, -1, -1, -1, -1, -1, 19, + -1, 21, 22, 23, 24, -1, 26, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, - -1, 91, 92, -1, 94, 95, -1, 97, 98, -1, + -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, 102, 103, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, - -1, 121, 3, 4, 5, 6, 7, 8, 9, 10, - 11, -1, -1, -1, 134, 135, 136, -1, 19, -1, - 21, 22, 23, 24, 144, -1, -1, -1, -1, 30, - 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, - -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, - 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, - -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, - 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, - 91, 92, -1, 94, 95, -1, 97, 98, -1, 100, - -1, 102, 103, 104, -1, 106, 107, 108, -1, 110, - 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, - 121, 3, 4, 5, 6, 7, 8, 9, 10, 11, - -1, -1, -1, 134, 135, 136, -1, 19, -1, 21, - 22, 23, 24, 144, -1, -1, -1, -1, 30, 31, + -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, + -1, -1, -1, -1, 134, 135, 136, 19, 138, 21, + 22, 23, 24, -1, 144, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, - -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, + 92, -1, 94, 95, -1, 97, 98, -1, 100, -1, 102, 103, 104, -1, 106, 107, 108, -1, 110, 111, - 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, + 112, -1, 114, -1, -1, -1, -1, -1, -1, 121, + 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, + -1, -1, 134, 135, 136, -1, 19, -1, 21, 22, + 23, 24, 144, -1, -1, -1, -1, 30, 31, 32, + 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, + -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, + 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, + 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 84, 85, -1, -1, -1, -1, -1, 91, 92, + -1, 94, 95, -1, 97, 98, -1, 100, -1, 102, + 103, 104, -1, 106, 107, 108, -1, 110, 111, 112, + -1, 114, -1, -1, -1, -1, -1, -1, 121, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, - -1, -1, 134, 135, 136, 19, -1, 21, 22, 23, - 24, -1, 144, -1, -1, -1, 30, 31, 32, 33, + -1, 134, 135, 136, -1, 19, -1, 21, 22, 23, + 24, 144, -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, @@ -4428,20 +4522,60 @@ static const yytype_int16 yycheck[] = 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, 102, 103, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, - 114, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, + 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, + 134, 135, 136, 19, -1, 21, 22, 23, 24, -1, + 144, -1, -1, -1, 30, 31, 32, 33, 34, 35, + 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, + -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, + 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, + 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, + -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, + -1, 97, 98, -1, 100, -1, 102, 103, 104, -1, + 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 134, 135, 136, -1, -1, -1, -1, -1, -1, -1, - 144, 3, 4, 5, 6, 7, 8, 9, 10, 11, + -1, -1, -1, -1, -1, -1, -1, -1, 134, 135, + 136, -1, -1, -1, -1, -1, -1, -1, 144, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, -1, -1, -1, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, + -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, -1, -1, -1, -1, -1, -1, 63, + -1, -1, -1, -1, -1, -1, 70, 71, 72, 73, + 74, 75, 76, 77, -1, -1, 80, 81, -1, -1, + -1, -1, 86, 87, 88, 89, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 100, 101, 102, -1, + -1, -1, -1, 107, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + -1, 135, 136, -1, -1, -1, -1, -1, -1, 143, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, -1, -1, -1, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, + -1, -1, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, -1, -1, -1, -1, -1, -1, + 63, -1, -1, -1, -1, -1, -1, 70, 71, 72, + 73, 74, 75, 76, 77, -1, -1, 80, 81, -1, + -1, -1, -1, 86, 87, 88, 89, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 100, 101, 102, + -1, -1, -1, -1, 107, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, -1, 135, 136, -1, -1, -1, -1, -1, -1, + 143, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, -1, -1, -1, -1, -1, - -1, 63, -1, -1, -1, -1, -1, -1, 70, 71, + 52, -1, -1, 55, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, -1, -1, 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, 101, - 102, -1, -1, -1, -1, 107, -1, -1, -1, -1, + 102, -1, -1, -1, 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, 135, 136, -1, -1, -1, -1, -1, @@ -4450,83 +4584,43 @@ static const yytype_int16 yycheck[] = 21, 22, 23, 24, 25, 26, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, -1, -1, -1, -1, - -1, -1, 63, -1, -1, -1, -1, -1, -1, 70, + 51, 52, -1, -1, 55, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, -1, -1, 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, - 101, 102, -1, -1, -1, -1, 107, -1, -1, -1, + 101, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, 135, 136, -1, -1, -1, -1, -1, -1, 143, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, -1, -1, -1, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, - 50, 51, 52, -1, -1, 55, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 70, 71, 72, 73, 74, 75, 76, 77, -1, -1, - 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 100, 101, 102, -1, -1, -1, 106, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, 135, 136, -1, -1, -1, - -1, -1, -1, 143, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, -1, -1, - -1, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, - 49, 50, 51, 52, -1, -1, 55, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 70, 71, 72, 73, 74, 75, 76, 77, -1, - -1, 80, 81, -1, -1, -1, -1, 86, 87, 88, - 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 100, 101, 102, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, -1, 135, 136, -1, -1, - -1, -1, -1, -1, 143, 3, 4, 5, 6, 7, - 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, - -1, 19, -1, 21, 22, 23, 24, -1, -1, -1, - -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, - -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, - 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, - 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, - -1, 69, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, - 98, -1, -1, -1, -1, -1, 104, -1, 106, 107, - 108, -1, 110, 111, 112, -1, 114, -1, -1, 3, - 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, - -1, -1, -1, -1, -1, 19, 134, 21, 22, 23, - 24, -1, -1, -1, 142, -1, 30, 31, 32, 33, - 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, - -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, - 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, - -1, -1, 66, 67, -1, 69, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 91, -1, -1, - 94, 95, -1, 97, 98, -1, -1, -1, -1, -1, - 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, - 114, -1, -1, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, -1, -1, -1, -1, -1, -1, 19, - 134, 21, 22, 23, 24, -1, -1, -1, 142, -1, + 10, 11, -1, -1, -1, -1, -1, -1, -1, 19, + -1, 21, 22, 23, 24, -1, -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, - -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, + -1, -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, - 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, - 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, - 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 104, -1, 106, 107, 108, -1, + 110, 111, 112, -1, 114, -1, -1, 3, 4, 5, + 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, + -1, -1, -1, 19, 134, 21, 22, 23, 24, -1, + -1, -1, 142, -1, 30, 31, 32, 33, 34, 35, + 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, + -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, + 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, + 66, 67, -1, 69, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, + -1, 97, 98, -1, -1, -1, -1, -1, 104, -1, + 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, -1, -1, -1, 134, 135, 136, 19, -1, 21, - 22, 23, 24, -1, -1, -1, -1, -1, 30, 31, + 12, -1, -1, -1, -1, -1, -1, 19, 134, 21, + 22, 23, 24, -1, -1, -1, 142, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, - -1, -1, -1, 45, -1, 47, 48, 49, 50, 51, + -1, -1, -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -4534,16 +4628,16 @@ static const yytype_int16 yycheck[] = -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, - 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, + 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, -1, 134, 135, 136, 19, -1, 21, 22, 23, 24, -1, -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, - -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, + -1, 45, -1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, - 94, 95, -1, 97, 98, -1, 100, -1, 102, 103, + 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, @@ -4591,7 +4685,7 @@ static const yytype_int16 yycheck[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, - 102, -1, 104, -1, 106, 107, 108, -1, 110, 111, + 102, 103, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, 134, 135, 136, 19, -1, 21, 22, 23, @@ -4602,7 +4696,7 @@ static const yytype_int16 yycheck[] = -1, -1, 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, - 94, 95, -1, 97, 98, -1, -1, -1, 102, 103, + 94, 95, -1, 97, 98, -1, 100, -1, 102, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, @@ -4614,7 +4708,7 @@ static const yytype_int16 yycheck[] = 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, - -1, 97, 98, -1, 100, -1, 102, -1, 104, -1, + -1, 97, 98, -1, -1, -1, 102, 103, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, 134, 135, @@ -4626,7 +4720,7 @@ static const yytype_int16 yycheck[] = -1, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, - 98, -1, -1, -1, 102, -1, 104, -1, 106, 107, + 98, -1, 100, -1, 102, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, 134, 135, 136, 19, @@ -4638,7 +4732,7 @@ static const yytype_int16 yycheck[] = 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, - 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, + -1, -1, 102, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, 134, 135, 136, 19, -1, 21, @@ -4697,7 +4791,7 @@ static const yytype_int16 yycheck[] = 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, - -1, -1, -1, -1, 104, -1, 106, 107, 108, -1, + 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, 134, 135, 136, 19, -1, 21, @@ -4729,33 +4823,22 @@ static const yytype_int16 yycheck[] = 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, - 66, 67, -1, 69, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 88, -1, -1, 91, -1, -1, 94, 95, + 66, 67, -1, 69, 70, 71, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 84, 85, + -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, -1, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, - -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, - -1, -1, -1, -1, -1, -1, -1, 19, 134, 21, - 22, 23, 24, -1, -1, -1, -1, -1, 30, 31, - 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, - -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, - 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, - -1, 63, -1, -1, 66, 67, -1, 69, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, - -1, -1, 94, 95, -1, 97, 98, -1, 100, -1, - -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, - 112, -1, 114, -1, -1, 3, 4, 5, 6, 7, - 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, - -1, 19, 134, 21, 22, 23, 24, -1, -1, -1, + -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, -1, -1, -1, -1, 134, 135, + 136, 19, -1, 21, 22, 23, 24, -1, -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, -1, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, - 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, + 88, -1, -1, 91, -1, -1, 94, 95, -1, 97, + 98, -1, -1, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, 19, 134, 21, 22, 23, @@ -4766,7 +4849,7 @@ static const yytype_int16 yycheck[] = -1, -1, 66, 67, -1, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, -1, -1, - 94, 95, -1, 97, 98, -1, -1, -1, -1, -1, + 94, 95, -1, 97, 98, -1, 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, 19, @@ -4778,7 +4861,7 @@ static const yytype_int16 yycheck[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, 98, -1, - -1, -1, -1, -1, 104, -1, 106, 107, 108, -1, + 100, -1, -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, 112, -1, 114, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1, 19, 134, 21, 22, 23, 24, -1, @@ -4800,11 +4883,51 @@ static const yytype_int16 yycheck[] = -1, 63, -1, -1, 66, 67, -1, 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, - -1, -1, 94, 95, -1, 97, 98, -1, -1, 51, - 52, -1, 104, 55, 106, 107, 108, -1, 110, 111, - 112, -1, 114, -1, -1, -1, -1, -1, 70, 71, + -1, -1, 94, 95, -1, 97, 98, -1, -1, -1, + -1, -1, 104, -1, 106, 107, 108, -1, 110, 111, + 112, -1, 114, -1, -1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, -1, -1, -1, -1, -1, -1, + -1, 19, 134, 21, 22, 23, 24, -1, -1, -1, + -1, -1, 30, 31, 32, 33, 34, 35, 36, -1, + -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, + 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, + 58, 59, 60, -1, -1, 63, -1, -1, 66, 67, + -1, 69, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 91, -1, -1, 94, 95, -1, 97, + 98, -1, -1, -1, -1, -1, 104, -1, 106, 107, + 108, -1, 110, 111, 112, -1, 114, -1, -1, 3, + 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, + -1, -1, -1, -1, -1, 19, 134, 21, 22, 23, + 24, -1, -1, -1, -1, -1, 30, 31, 32, 33, + 34, 35, 36, -1, -1, 39, -1, -1, -1, -1, + -1, -1, -1, -1, 48, 49, 50, 51, 52, 53, + 54, 55, 56, -1, 58, 59, 60, -1, -1, 63, + -1, -1, 66, 67, -1, 69, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 91, -1, -1, + 94, 95, -1, 97, 98, -1, -1, 51, 52, -1, + 104, 55, 106, 107, 108, -1, 110, 111, 112, -1, + 114, -1, -1, -1, -1, -1, 70, 71, 72, 73, + 74, 75, 76, 77, -1, -1, 80, 81, -1, -1, + 134, -1, 86, 87, 88, 89, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 100, 101, 102, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + -1, 135, 136, 51, 52, -1, -1, 55, -1, 143, + 144, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, + -1, -1, 80, 81, -1, -1, -1, -1, 86, 87, + 88, 89, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 100, 101, 102, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, -1, 135, 136, 51, + 52, -1, -1, 55, -1, 143, 144, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, -1, -1, 80, 81, - -1, -1, 134, -1, 86, 87, 88, 89, -1, -1, + -1, -1, -1, -1, 86, 87, 88, 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, 101, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -4910,39 +5033,18 @@ static const yytype_int16 yycheck[] = 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, 101, 102, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 44, -1, -1, -1, - -1, -1, -1, -1, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, -1, 135, 136, -1, -1, -1, - -1, -1, -1, 143, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, -1, -1, -1, - 88, 89, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 101, -1, -1, -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 122, -1, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, -1, - -1, -1, 88, 89, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 101, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 122, -1, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - -1, -1, -1, -1, 88, 89, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 101, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 122, -1, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, -1, 148, -1, 88, 89, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 101, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 122, -1, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, -1, -1, -1, -1, -1, -1, -1, - 142, 72, 73, 74, 75, 76, 77, 78, 79, 80, + -1, -1, -1, -1, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, -1, 135, 136, 51, 52, -1, + -1, 55, -1, 143, 144, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 70, 71, 72, 73, + 74, 75, 76, 77, -1, -1, 80, 81, -1, -1, + -1, -1, 86, 87, 88, 89, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 100, 101, 102, -1, + -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, -1, -1, -1, 88, 89, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 101, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 101, 135, 136, -1, -1, -1, -1, -1, -1, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 122, -1, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, -1, -1, -1, -1, -1, -1, @@ -4955,37 +5057,25 @@ static const yytype_int16 yycheck[] = 130, 131, 132, 133, -1, -1, -1, -1, -1, -1, -1, -1, 142, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, -1, -1, -1, 88, - 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 89, -1, -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 122, -1, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, -1, -1, -1, -1, -1, - -1, -1, -1, 142, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, -1, -1, -1, -1, - 88, 89, -1, -1, -1, 93, -1, -1, -1, -1, - -1, -1, -1, 101, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 122, -1, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, -1, -1, - -1, -1, 88, 89, -1, -1, -1, 93, -1, -1, - -1, -1, -1, -1, -1, 101, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 122, -1, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - -1, -1, -1, -1, 88, 89, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 101, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 122, -1, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, -1, -1, -1, -1, 88, 89, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 101, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 129, 130, 131, 132, 133, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, -1, -1, -1, + -1, 88, 89, -1, -1, -1, 93, -1, -1, -1, + -1, -1, -1, -1, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133 + -1, -1, -1, -1, -1, 122, -1, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, -1, -1, 88, 89, 72, 73, 74, 75, 76, + 77, -1, -1, 80, 81, -1, 101, -1, -1, -1, + -1, 88, 89, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 101, -1, -1, 122, -1, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, + -1, -1, -1, -1, -1, -1, -1, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -5002,9 +5092,9 @@ static const yytype_int16 yystos[] = 154, 159, 161, 163, 164, 165, 168, 169, 172, 173, 175, 176, 177, 179, 180, 189, 203, 220, 241, 242, 252, 253, 254, 258, 259, 260, 266, 267, 268, 270, - 271, 272, 273, 274, 275, 312, 325, 154, 21, 22, + 271, 272, 273, 274, 275, 311, 324, 154, 21, 22, 30, 31, 32, 39, 51, 55, 69, 88, 91, 94, - 134, 164, 165, 181, 182, 203, 220, 272, 275, 312, + 134, 164, 165, 181, 182, 203, 220, 272, 275, 311, 182, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 30, 31, 32, 33, 34, @@ -5013,92 +5103,93 @@ static const yytype_int16 yystos[] = 76, 77, 80, 81, 86, 87, 88, 89, 100, 101, 102, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 135, 136, 143, 144, 183, 187, 188, 274, 306, - 204, 91, 163, 167, 180, 189, 220, 272, 273, 275, - 167, 210, 212, 69, 91, 173, 180, 220, 225, 272, - 275, 33, 34, 35, 36, 48, 49, 50, 51, 55, - 106, 183, 184, 185, 268, 115, 118, 119, 146, 148, - 167, 262, 263, 264, 318, 322, 323, 324, 51, 100, - 102, 103, 135, 172, 189, 195, 198, 201, 254, 309, - 311, 195, 195, 144, 192, 193, 196, 197, 325, 192, - 196, 144, 319, 323, 184, 155, 138, 189, 220, 189, - 189, 189, 55, 1, 94, 157, 158, 159, 174, 175, - 325, 205, 207, 190, 201, 309, 325, 189, 308, 309, - 325, 91, 142, 179, 220, 272, 275, 208, 53, 54, - 56, 63, 107, 183, 269, 63, 64, 65, 116, 117, - 255, 256, 61, 255, 62, 255, 63, 255, 63, 255, - 58, 59, 168, 189, 189, 318, 324, 40, 41, 42, - 43, 44, 37, 38, 51, 53, 54, 55, 56, 69, - 94, 100, 101, 102, 103, 128, 131, 144, 278, 279, - 280, 281, 282, 285, 286, 287, 288, 290, 291, 292, - 293, 295, 296, 297, 300, 301, 302, 303, 304, 325, - 279, 280, 28, 239, 121, 142, 94, 100, 176, 121, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 88, 89, 93, 101, 122, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 90, 105, 140, - 147, 316, 90, 316, 317, 26, 138, 243, 254, 92, - 92, 192, 196, 243, 163, 51, 55, 181, 58, 59, - 279, 125, 276, 90, 140, 316, 219, 307, 90, 147, - 315, 156, 157, 55, 16, 221, 322, 121, 90, 140, - 316, 92, 92, 221, 167, 167, 55, 90, 140, 316, - 25, 107, 142, 265, 318, 115, 264, 20, 246, 322, - 57, 310, 189, 189, 189, 93, 142, 199, 200, 325, - 310, 199, 200, 85, 194, 195, 201, 309, 325, 195, - 163, 318, 320, 163, 160, 138, 157, 90, 316, 92, - 159, 174, 145, 318, 324, 320, 159, 320, 141, 200, - 321, 324, 200, 321, 139, 321, 55, 176, 177, 178, - 142, 90, 140, 316, 144, 237, 290, 63, 255, 257, - 261, 262, 63, 256, 61, 62, 63, 63, 101, 101, - 154, 167, 167, 167, 167, 159, 163, 163, 57, 121, - 294, 85, 290, 295, 121, 156, 189, 142, 305, 325, - 51, 142, 305, 322, 142, 289, 189, 142, 289, 51, - 142, 289, 51, 121, 156, 240, 100, 168, 189, 201, - 202, 174, 142, 179, 142, 161, 162, 168, 180, 189, - 191, 202, 220, 275, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 189, 189, 189, 51, 189, + 204, 91, 163, 164, 165, 167, 180, 189, 220, 272, + 273, 275, 167, 210, 212, 69, 91, 173, 180, 220, + 225, 272, 275, 33, 34, 35, 36, 48, 49, 50, + 51, 55, 106, 183, 184, 185, 268, 115, 118, 119, + 146, 148, 167, 262, 263, 264, 317, 321, 322, 323, + 51, 100, 102, 103, 135, 172, 189, 195, 198, 201, + 254, 309, 310, 195, 195, 144, 192, 193, 196, 197, + 324, 192, 196, 144, 318, 184, 155, 138, 189, 220, + 189, 189, 189, 55, 1, 94, 157, 158, 159, 174, + 175, 324, 205, 207, 190, 201, 309, 324, 189, 308, + 309, 324, 91, 142, 179, 220, 272, 275, 208, 53, + 54, 56, 63, 107, 183, 269, 63, 64, 65, 116, + 117, 255, 256, 61, 255, 62, 255, 63, 255, 63, + 255, 58, 59, 168, 189, 189, 317, 323, 40, 41, + 42, 43, 44, 37, 38, 51, 53, 54, 55, 56, + 69, 94, 100, 101, 102, 103, 128, 131, 144, 278, + 279, 280, 281, 282, 285, 286, 287, 288, 290, 291, + 292, 293, 295, 296, 297, 300, 301, 302, 303, 304, + 324, 278, 280, 28, 239, 121, 142, 94, 100, 176, + 121, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 88, 89, 93, 101, 122, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 90, 105, + 140, 147, 315, 90, 315, 316, 26, 138, 243, 254, + 92, 92, 192, 196, 243, 163, 51, 55, 181, 58, + 59, 279, 125, 276, 90, 140, 315, 219, 307, 90, + 147, 314, 156, 157, 55, 278, 278, 16, 221, 321, + 121, 90, 140, 315, 92, 92, 221, 167, 167, 55, + 90, 140, 315, 25, 107, 142, 265, 317, 115, 264, + 20, 246, 321, 57, 189, 189, 189, 93, 142, 199, + 200, 324, 57, 199, 200, 85, 194, 195, 201, 309, + 324, 195, 163, 317, 319, 163, 322, 160, 138, 157, + 90, 315, 92, 159, 174, 145, 317, 323, 319, 159, + 319, 141, 200, 320, 323, 200, 320, 139, 320, 55, + 176, 177, 178, 142, 90, 140, 315, 144, 237, 290, + 63, 255, 257, 261, 262, 63, 256, 61, 62, 63, + 63, 101, 101, 154, 167, 167, 167, 167, 159, 163, + 163, 57, 121, 294, 85, 290, 295, 121, 156, 189, + 142, 305, 324, 51, 142, 305, 321, 142, 289, 189, + 142, 289, 51, 142, 289, 51, 121, 156, 240, 100, + 168, 189, 201, 202, 174, 142, 179, 142, 161, 162, + 168, 180, 189, 191, 202, 220, 275, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, - 189, 51, 52, 55, 187, 192, 313, 314, 194, 201, - 51, 52, 55, 187, 192, 313, 51, 55, 313, 245, - 244, 162, 189, 191, 162, 191, 99, 170, 217, 277, - 216, 51, 55, 181, 313, 194, 313, 156, 163, 166, - 15, 13, 248, 325, 157, 16, 51, 55, 194, 51, - 55, 157, 27, 222, 322, 222, 51, 55, 194, 51, - 55, 214, 186, 157, 246, 189, 201, 15, 261, 189, - 189, 319, 100, 189, 198, 309, 189, 311, 320, 145, - 318, 200, 200, 320, 145, 184, 152, 139, 191, 320, - 159, 206, 309, 176, 178, 51, 55, 194, 51, 55, - 290, 209, 63, 157, 262, 189, 189, 51, 100, 226, - 295, 320, 320, 142, 189, 15, 51, 282, 287, 304, - 288, 293, 300, 302, 295, 297, 302, 51, 295, 189, - 15, 79, 126, 231, 232, 325, 189, 200, 320, 178, - 142, 44, 121, 44, 90, 140, 316, 319, 92, 92, - 192, 196, 141, 200, 92, 92, 193, 196, 193, 196, - 231, 231, 171, 322, 167, 156, 141, 15, 320, 183, - 189, 202, 249, 325, 18, 224, 325, 17, 223, 224, - 92, 92, 141, 92, 92, 224, 211, 213, 141, 167, - 184, 139, 15, 200, 221, 261, 189, 199, 85, 309, - 139, 320, 321, 141, 234, 319, 29, 113, 238, 139, - 142, 292, 320, 142, 85, 44, 305, 142, 289, 142, - 289, 142, 289, 142, 289, 289, 44, 228, 230, 233, - 281, 283, 284, 287, 295, 296, 298, 299, 302, 304, - 156, 100, 189, 178, 159, 189, 51, 55, 194, 51, - 55, 57, 123, 162, 191, 168, 191, 170, 92, 162, - 191, 162, 191, 170, 243, 239, 156, 157, 231, 218, - 322, 15, 93, 250, 325, 157, 14, 251, 325, 167, - 15, 92, 15, 157, 157, 222, 189, 157, 320, 200, - 145, 146, 156, 157, 227, 142, 100, 320, 189, 295, - 302, 295, 295, 189, 234, 234, 91, 220, 142, 305, - 305, 142, 229, 220, 142, 229, 142, 229, 15, 189, - 141, 189, 189, 162, 191, 15, 139, 157, 156, 91, - 180, 220, 272, 275, 221, 157, 221, 15, 15, 215, - 224, 246, 247, 51, 235, 236, 291, 15, 139, 295, - 295, 142, 292, 289, 142, 289, 289, 289, 126, 126, - 55, 90, 283, 287, 142, 228, 229, 299, 302, 295, - 298, 302, 295, 139, 15, 55, 90, 140, 316, 157, - 157, 157, 142, 319, 142, 295, 142, 295, 51, 55, - 305, 142, 229, 142, 229, 142, 229, 142, 229, 229, - 51, 55, 194, 51, 55, 248, 223, 15, 236, 295, - 289, 295, 302, 295, 295, 141, 229, 142, 229, 229, - 229, 295, 229 + 189, 51, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 51, 52, 55, 187, 192, 312, + 313, 194, 201, 51, 52, 55, 187, 192, 312, 51, + 55, 312, 245, 244, 162, 189, 191, 162, 191, 99, + 170, 217, 277, 216, 51, 55, 181, 312, 194, 312, + 156, 163, 166, 15, 13, 248, 324, 121, 121, 157, + 16, 51, 55, 194, 51, 55, 157, 27, 222, 321, + 222, 51, 55, 194, 51, 55, 214, 186, 157, 246, + 189, 201, 15, 189, 189, 318, 100, 189, 198, 309, + 189, 310, 319, 145, 317, 200, 200, 319, 145, 184, + 152, 139, 191, 319, 159, 206, 309, 176, 178, 51, + 55, 194, 51, 55, 290, 209, 63, 157, 262, 189, + 189, 51, 100, 226, 295, 319, 319, 142, 172, 189, + 15, 51, 282, 287, 304, 288, 293, 300, 302, 295, + 297, 302, 51, 295, 172, 189, 15, 79, 126, 231, + 232, 324, 189, 200, 319, 178, 142, 44, 121, 44, + 90, 140, 315, 318, 92, 92, 192, 196, 141, 200, + 92, 92, 193, 196, 193, 196, 231, 231, 171, 321, + 167, 156, 141, 15, 319, 183, 189, 202, 249, 324, + 18, 224, 324, 17, 223, 224, 92, 92, 141, 92, + 92, 224, 211, 213, 141, 167, 184, 139, 15, 200, + 221, 189, 199, 85, 309, 139, 319, 320, 141, 234, + 318, 29, 113, 238, 139, 142, 292, 319, 142, 85, + 44, 44, 305, 142, 289, 142, 289, 142, 289, 142, + 289, 289, 44, 44, 228, 230, 233, 281, 283, 284, + 287, 295, 296, 298, 299, 302, 304, 156, 100, 189, + 178, 159, 189, 51, 55, 194, 51, 55, 57, 123, + 162, 191, 168, 191, 170, 92, 162, 191, 162, 191, + 170, 243, 239, 156, 157, 231, 218, 321, 15, 93, + 250, 324, 157, 14, 251, 324, 167, 15, 92, 15, + 157, 157, 222, 189, 157, 319, 200, 145, 146, 156, + 157, 227, 142, 100, 319, 189, 189, 295, 302, 295, + 295, 189, 189, 234, 234, 91, 220, 142, 305, 305, + 142, 229, 220, 142, 229, 142, 229, 15, 189, 141, + 189, 189, 162, 191, 15, 139, 157, 156, 91, 180, + 220, 272, 275, 221, 157, 221, 15, 15, 215, 224, + 246, 247, 51, 235, 236, 291, 15, 139, 295, 295, + 142, 292, 289, 142, 289, 289, 289, 126, 126, 55, + 90, 283, 287, 142, 228, 229, 299, 302, 295, 298, + 302, 295, 139, 15, 55, 90, 140, 315, 157, 157, + 157, 142, 318, 142, 295, 142, 295, 51, 55, 305, + 142, 229, 142, 229, 142, 229, 142, 229, 229, 51, + 55, 194, 51, 55, 248, 223, 15, 236, 295, 289, + 295, 302, 295, 295, 141, 229, 142, 229, 229, 229, + 295, 229 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -5108,63 +5199,63 @@ static const yytype_int16 yyr1[] = 155, 154, 156, 157, 158, 158, 158, 158, 160, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 161, 161, 161, 161, 161, 161, - 161, 161, 162, 162, 162, 163, 163, 163, 163, 163, - 163, 164, 166, 165, 167, 168, 168, 169, 169, 171, - 170, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 173, 173, 174, 174, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 176, 176, 177, 177, - 178, 178, 179, 179, 179, 179, 179, 179, 179, 179, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, - 181, 182, 182, 182, 183, 183, 183, 183, 183, 184, - 184, 185, 186, 185, 187, 187, 187, 187, 187, 187, + 161, 161, 161, 161, 161, 161, 162, 162, 162, 163, + 163, 163, 163, 163, 163, 164, 166, 165, 167, 168, + 168, 169, 169, 171, 170, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 173, 173, 174, 174, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 176, 176, 177, 177, 178, 178, 179, 179, 179, 179, + 179, 179, 179, 179, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 181, 181, 182, 182, 182, 183, 183, + 183, 183, 183, 184, 184, 185, 186, 185, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 188, 188, 188, 188, 188, 188, + 187, 187, 187, 187, 187, 187, 187, 187, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 189, 189, 189, 189, 189, 189, + 188, 188, 188, 188, 188, 188, 188, 188, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 189, 189, 190, 190, 190, 190, 191, - 191, 192, 192, 192, 193, 193, 194, 194, 194, 194, - 194, 195, 195, 195, 195, 195, 197, 196, 198, 199, - 199, 200, 200, 201, 201, 201, 201, 202, 202, 202, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 204, - 203, 205, 206, 203, 207, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 208, 209, - 203, 203, 203, 210, 211, 203, 212, 213, 203, 203, - 203, 214, 215, 203, 216, 203, 217, 218, 203, 219, - 203, 203, 203, 203, 203, 203, 203, 220, 221, 221, - 221, 222, 222, 223, 223, 224, 224, 225, 225, 226, - 226, 226, 226, 226, 226, 226, 226, 227, 226, 228, - 228, 228, 228, 229, 229, 230, 230, 230, 230, 230, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 190, + 190, 190, 190, 191, 191, 192, 192, 192, 193, 193, + 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, + 197, 196, 198, 199, 199, 200, 201, 201, 201, 201, + 202, 202, 202, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 204, 203, 205, 206, 203, 207, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 208, 209, 203, 203, 203, 210, 211, 203, 212, + 213, 203, 203, 203, 214, 215, 203, 216, 203, 217, + 218, 203, 219, 203, 203, 203, 203, 203, 203, 203, + 220, 221, 221, 221, 222, 222, 223, 223, 224, 224, + 225, 225, 226, 226, 226, 226, 226, 226, 226, 226, + 227, 226, 228, 228, 228, 228, 229, 229, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, - 231, 231, 233, 232, 232, 232, 234, 234, 235, 235, - 236, 236, 237, 237, 238, 238, 240, 239, 241, 241, - 241, 241, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 244, 243, 245, 243, 246, 247, 247, 248, 248, - 249, 249, 249, 250, 250, 251, 251, 252, 252, 252, - 252, 253, 253, 254, 254, 254, 254, 255, 255, 256, - 257, 256, 256, 256, 258, 258, 259, 259, 260, 261, - 261, 262, 262, 263, 263, 264, 265, 264, 266, 266, - 267, 267, 268, 269, 269, 269, 269, 269, 269, 270, - 270, 271, 271, 271, 271, 272, 272, 272, 272, 272, - 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, - 275, 275, 276, 277, 276, 278, 278, 279, 279, 279, - 280, 280, 281, 282, 282, 283, 283, 284, 284, 285, - 285, 286, 286, 287, 287, 288, 288, 288, 288, 289, - 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, - 290, 290, 290, 290, 290, 290, 291, 291, 291, 291, - 291, 292, 292, 293, 294, 293, 295, 295, 296, 297, - 298, 299, 299, 300, 300, 301, 301, 302, 302, 303, - 303, 304, 305, 305, 306, 307, 306, 308, 308, 309, - 309, 310, 310, 311, 311, 311, 311, 312, 312, 312, - 313, 313, 313, 313, 314, 314, 314, 315, 315, 316, - 316, 317, 317, 318, 318, 319, 319, 320, 321, 321, - 321, 322, 322, 322, 323, 324, 324, 325 + 230, 230, 230, 231, 231, 233, 232, 232, 232, 234, + 234, 235, 235, 236, 236, 237, 237, 238, 238, 240, + 239, 241, 241, 241, 241, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 244, 243, 245, 243, 246, 247, + 247, 248, 248, 249, 249, 249, 250, 250, 251, 251, + 252, 252, 252, 252, 253, 253, 254, 254, 254, 254, + 255, 255, 256, 257, 256, 256, 256, 258, 258, 259, + 259, 260, 261, 261, 262, 262, 263, 263, 264, 265, + 264, 266, 266, 267, 267, 268, 269, 269, 269, 269, + 269, 269, 270, 270, 271, 271, 271, 271, 272, 272, + 272, 272, 272, 273, 273, 274, 274, 274, 274, 274, + 274, 274, 274, 275, 275, 276, 277, 276, 278, 278, + 279, 279, 279, 280, 280, 281, 282, 282, 283, 283, + 284, 284, 285, 285, 286, 286, 287, 287, 288, 288, + 288, 288, 289, 289, 290, 290, 290, 290, 290, 290, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, + 291, 291, 291, 291, 292, 292, 293, 294, 293, 295, + 295, 296, 297, 298, 299, 299, 300, 300, 301, 301, + 302, 302, 303, 303, 304, 305, 305, 306, 307, 306, + 308, 308, 309, 309, 310, 310, 310, 310, 310, 311, + 311, 311, 312, 312, 312, 312, 313, 313, 313, 314, + 314, 315, 315, 316, 316, 317, 317, 318, 318, 319, + 320, 320, 320, 321, 321, 322, 322, 323, 323, 324 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -5174,63 +5265,63 @@ static const yytype_int8 yyr2[] = 0, 5, 4, 2, 1, 1, 3, 2, 0, 4, 2, 3, 3, 3, 3, 3, 4, 1, 3, 3, 3, 3, 3, 1, 3, 3, 6, 5, 5, 5, - 5, 3, 1, 3, 1, 1, 3, 3, 3, 2, - 1, 2, 0, 5, 1, 1, 1, 1, 4, 0, - 5, 2, 3, 4, 5, 4, 5, 2, 2, 2, - 2, 2, 1, 3, 1, 3, 1, 2, 3, 5, - 2, 4, 2, 4, 1, 3, 1, 3, 2, 3, - 1, 2, 1, 4, 3, 3, 3, 3, 2, 1, - 1, 4, 3, 3, 3, 3, 2, 1, 1, 1, - 1, 2, 1, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 4, 1, 1, 1, 1, 1, 1, + 5, 4, 6, 4, 6, 3, 1, 3, 1, 1, + 3, 3, 3, 2, 1, 2, 0, 5, 1, 1, + 1, 1, 4, 0, 5, 2, 3, 4, 5, 4, + 5, 2, 2, 2, 2, 2, 1, 3, 1, 3, + 1, 2, 3, 5, 2, 4, 2, 4, 1, 3, + 1, 3, 2, 3, 1, 2, 1, 4, 3, 3, + 3, 3, 2, 1, 1, 4, 3, 3, 3, 3, + 2, 1, 1, 1, 1, 2, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 6, 5, 5, 5, - 5, 4, 3, 3, 2, 2, 3, 2, 2, 3, - 3, 3, 3, 3, 3, 4, 4, 2, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 3, 3, 3, 3, 6, 6, - 4, 6, 4, 6, 1, 1, 2, 4, 2, 1, - 3, 3, 5, 3, 1, 1, 1, 2, 2, 4, - 2, 1, 2, 2, 4, 1, 0, 2, 2, 2, - 1, 1, 3, 1, 2, 3, 4, 3, 4, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 4, 0, 0, 5, 0, 3, 3, 3, 2, 3, - 3, 1, 2, 4, 3, 2, 1, 2, 0, 0, - 5, 6, 6, 0, 0, 7, 0, 0, 7, 5, - 4, 0, 0, 9, 0, 6, 0, 0, 8, 0, - 5, 4, 4, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 1, 1, 5, 1, 2, 1, 1, 1, - 4, 6, 3, 5, 2, 4, 1, 0, 4, 4, - 2, 2, 1, 2, 0, 6, 8, 4, 6, 4, - 3, 6, 2, 4, 6, 2, 4, 2, 4, 1, - 1, 1, 0, 4, 1, 4, 1, 4, 1, 3, - 1, 1, 4, 1, 3, 3, 0, 5, 2, 4, - 5, 5, 2, 4, 4, 3, 3, 3, 2, 1, - 4, 0, 5, 0, 5, 5, 1, 1, 6, 1, - 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, - 1, 1, 2, 1, 1, 2, 3, 1, 2, 1, - 0, 4, 1, 2, 2, 3, 2, 3, 1, 1, - 2, 1, 2, 1, 2, 1, 0, 4, 2, 3, - 1, 4, 2, 1, 1, 1, 1, 1, 2, 2, - 3, 1, 1, 2, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 6, 5, 5, 5, 5, 4, 3, 3, 2, 2, + 3, 2, 2, 3, 3, 3, 3, 3, 3, 4, + 4, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, + 3, 3, 6, 6, 4, 6, 4, 6, 1, 1, + 2, 4, 2, 1, 3, 3, 5, 3, 1, 1, + 1, 2, 2, 4, 2, 1, 2, 2, 4, 1, + 0, 2, 2, 2, 1, 2, 1, 2, 3, 4, + 3, 4, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 4, 0, 0, 5, 0, 3, 3, + 3, 2, 3, 3, 1, 2, 4, 3, 2, 1, + 2, 0, 0, 5, 6, 6, 0, 0, 7, 0, + 0, 7, 5, 4, 0, 0, 9, 0, 6, 0, + 0, 8, 0, 5, 4, 4, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 5, 1, 2, + 1, 1, 1, 4, 6, 3, 5, 2, 4, 1, + 0, 4, 4, 2, 2, 1, 2, 0, 6, 8, + 4, 6, 4, 3, 6, 2, 4, 6, 2, 4, + 2, 4, 1, 1, 1, 0, 4, 1, 4, 1, + 4, 1, 3, 1, 1, 4, 1, 3, 3, 0, + 5, 2, 4, 5, 5, 2, 4, 4, 3, 3, + 3, 2, 1, 4, 0, 5, 0, 5, 5, 1, + 1, 6, 1, 1, 1, 1, 2, 1, 2, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 2, 3, + 1, 2, 1, 0, 4, 1, 2, 2, 3, 2, + 3, 1, 1, 2, 1, 2, 1, 2, 1, 0, + 4, 2, 3, 1, 4, 2, 1, 1, 1, 1, + 1, 2, 2, 3, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 4, 1, 1, 3, 5, 3, - 1, 2, 2, 2, 1, 2, 1, 1, 3, 1, - 3, 1, 1, 2, 1, 4, 2, 2, 1, 2, - 0, 6, 8, 4, 6, 4, 6, 2, 4, 6, - 2, 4, 2, 4, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 4, 1, 3, 2, 2, - 2, 1, 3, 1, 3, 1, 1, 2, 1, 1, - 1, 2, 2, 1, 1, 0, 4, 1, 2, 1, - 3, 1, 2, 3, 3, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 4, 1, 1, + 3, 5, 3, 1, 2, 2, 2, 1, 2, 1, + 1, 3, 1, 3, 1, 1, 2, 1, 4, 2, + 2, 1, 2, 0, 6, 8, 4, 6, 4, 6, + 2, 4, 6, 2, 4, 2, 4, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 4, 1, + 3, 2, 2, 2, 1, 3, 1, 3, 1, 1, + 2, 1, 1, 1, 2, 2, 1, 1, 0, 4, + 1, 2, 1, 3, 3, 3, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 0, 1, 2, 0, 1, - 1, 1, 1, 1, 1, 1, 2, 0 + 1, 1, 1, 1, 1, 0, 1, 0, 2, 2, + 0, 1, 1, 1, 1, 1, 1, 1, 2, 0 }; @@ -5932,93 +6023,93 @@ yyreduce: switch (yyn) { case 2: -#line 1565 "mrbgems/mruby-compiler/core/parse.y" +#line 1591 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; if (!p->locals) p->locals = cons(0,0); } -#line 5941 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6032 "mrbgems/mruby-compiler/core/y.tab.c" break; case 3: -#line 1570 "mrbgems/mruby-compiler/core/parse.y" +#line 1596 "mrbgems/mruby-compiler/core/parse.y" { p->tree = new_scope(p, (yyvsp[0].nd)); NODE_LINENO(p->tree, (yyvsp[0].nd)); } -#line 5950 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6041 "mrbgems/mruby-compiler/core/y.tab.c" break; case 4: -#line 1577 "mrbgems/mruby-compiler/core/parse.y" +#line 1603 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 5958 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6049 "mrbgems/mruby-compiler/core/y.tab.c" break; case 5: -#line 1583 "mrbgems/mruby-compiler/core/parse.y" +#line 1609 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 5966 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6057 "mrbgems/mruby-compiler/core/y.tab.c" break; case 6: -#line 1587 "mrbgems/mruby-compiler/core/parse.y" +#line 1613 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 5975 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6066 "mrbgems/mruby-compiler/core/y.tab.c" break; case 7: -#line 1592 "mrbgems/mruby-compiler/core/parse.y" +#line 1618 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 5983 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6074 "mrbgems/mruby-compiler/core/y.tab.c" break; case 8: -#line 1596 "mrbgems/mruby-compiler/core/parse.y" +#line 1622 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 5991 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6082 "mrbgems/mruby-compiler/core/y.tab.c" break; case 10: -#line 1603 "mrbgems/mruby-compiler/core/parse.y" +#line 1629 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); nvars_block(p); } -#line 6000 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6091 "mrbgems/mruby-compiler/core/y.tab.c" break; case 11: -#line 1608 "mrbgems/mruby-compiler/core/parse.y" +#line 1634 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "BEGIN not supported"); local_resume(p, (yyvsp[-3].nd)); nvars_unnest(p); (yyval.nd) = 0; } -#line 6011 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6102 "mrbgems/mruby-compiler/core/y.tab.c" break; case 12: -#line 1620 "mrbgems/mruby-compiler/core/parse.y" +#line 1646 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-2].nd)) { (yyval.nd) = new_rescue(p, (yyvsp[-3].nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } else if ((yyvsp[-1].nd)) { - yywarn(p, "else without rescue is useless"); + yywarning(p, "else without rescue is useless"); (yyval.nd) = push((yyvsp[-3].nd), (yyvsp[-1].nd)); } else { @@ -6033,291 +6124,345 @@ yyreduce: } } } -#line 6037 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6128 "mrbgems/mruby-compiler/core/y.tab.c" break; case 13: -#line 1644 "mrbgems/mruby-compiler/core/parse.y" +#line 1670 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6045 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6136 "mrbgems/mruby-compiler/core/y.tab.c" break; case 14: -#line 1650 "mrbgems/mruby-compiler/core/parse.y" +#line 1676 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 6053 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6144 "mrbgems/mruby-compiler/core/y.tab.c" break; case 15: -#line 1654 "mrbgems/mruby-compiler/core/parse.y" +#line 1680 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6062 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6153 "mrbgems/mruby-compiler/core/y.tab.c" break; case 16: -#line 1659 "mrbgems/mruby-compiler/core/parse.y" +#line 1685 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6070 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6161 "mrbgems/mruby-compiler/core/y.tab.c" break; case 17: -#line 1663 "mrbgems/mruby-compiler/core/parse.y" +#line 1689 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); } -#line 6078 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6169 "mrbgems/mruby-compiler/core/y.tab.c" break; case 18: -#line 1668 "mrbgems/mruby-compiler/core/parse.y" +#line 1694 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 6084 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6175 "mrbgems/mruby-compiler/core/y.tab.c" break; case 19: -#line 1669 "mrbgems/mruby-compiler/core/parse.y" +#line 1695 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_alias(p, (yyvsp[-2].id), (yyvsp[0].id)); } -#line 6092 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6183 "mrbgems/mruby-compiler/core/y.tab.c" break; case 20: -#line 1673 "mrbgems/mruby-compiler/core/parse.y" +#line 1699 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6100 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6191 "mrbgems/mruby-compiler/core/y.tab.c" break; case 21: -#line 1677 "mrbgems/mruby-compiler/core/parse.y" +#line 1703 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6108 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6199 "mrbgems/mruby-compiler/core/y.tab.c" break; case 22: -#line 1681 "mrbgems/mruby-compiler/core/parse.y" +#line 1707 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_unless(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6116 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6207 "mrbgems/mruby-compiler/core/y.tab.c" break; case 23: -#line 1685 "mrbgems/mruby-compiler/core/parse.y" +#line 1711 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_while(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6124 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6215 "mrbgems/mruby-compiler/core/y.tab.c" break; case 24: -#line 1689 "mrbgems/mruby-compiler/core/parse.y" +#line 1715 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_until(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6132 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6223 "mrbgems/mruby-compiler/core/y.tab.c" break; case 25: -#line 1693 "mrbgems/mruby-compiler/core/parse.y" +#line 1719 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6140 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6231 "mrbgems/mruby-compiler/core/y.tab.c" break; case 26: -#line 1697 "mrbgems/mruby-compiler/core/parse.y" +#line 1723 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "END not supported"); (yyval.nd) = new_postexe(p, (yyvsp[-1].nd)); } -#line 6149 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6240 "mrbgems/mruby-compiler/core/y.tab.c" break; case 28: -#line 1703 "mrbgems/mruby-compiler/core/parse.y" +#line 1729 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6157 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6248 "mrbgems/mruby-compiler/core/y.tab.c" break; case 29: -#line 1707 "mrbgems/mruby-compiler/core/parse.y" +#line 1733 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6165 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6256 "mrbgems/mruby-compiler/core/y.tab.c" break; case 30: -#line 1711 "mrbgems/mruby-compiler/core/parse.y" +#line 1737 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6173 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6264 "mrbgems/mruby-compiler/core/y.tab.c" break; case 31: -#line 1715 "mrbgems/mruby-compiler/core/parse.y" +#line 1741 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6181 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6272 "mrbgems/mruby-compiler/core/y.tab.c" break; case 32: -#line 1719 "mrbgems/mruby-compiler/core/parse.y" +#line 1745 "mrbgems/mruby-compiler/core/parse.y" { node *lhs = new_lvar(p, (yyvsp[0].id)); void_expr_error(p, (yyvsp[-2].nd)); assignable(p, lhs); (yyval.nd) = new_asgn(p, lhs, (yyvsp[-2].nd)); } -#line 6192 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6283 "mrbgems/mruby-compiler/core/y.tab.c" break; case 34: -#line 1729 "mrbgems/mruby-compiler/core/parse.y" +#line 1755 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6200 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6291 "mrbgems/mruby-compiler/core/y.tab.c" break; case 35: -#line 1733 "mrbgems/mruby-compiler/core/parse.y" +#line 1759 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6208 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6299 "mrbgems/mruby-compiler/core/y.tab.c" break; case 36: -#line 1737 "mrbgems/mruby-compiler/core/parse.y" +#line 1763 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_op(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6216 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6307 "mrbgems/mruby-compiler/core/y.tab.c" break; case 37: -#line 1741 "mrbgems/mruby-compiler/core/parse.y" +#line 1767 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6224 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6315 "mrbgems/mruby-compiler/core/y.tab.c" break; case 38: -#line 1745 "mrbgems/mruby-compiler/core/parse.y" +#line 1771 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6232 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6323 "mrbgems/mruby-compiler/core/y.tab.c" break; case 39: -#line 1749 "mrbgems/mruby-compiler/core/parse.y" +#line 1775 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = 0; } -#line 6241 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6332 "mrbgems/mruby-compiler/core/y.tab.c" break; case 40: -#line 1754 "mrbgems/mruby-compiler/core/parse.y" +#line 1780 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6249 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6340 "mrbgems/mruby-compiler/core/y.tab.c" break; case 41: -#line 1758 "mrbgems/mruby-compiler/core/parse.y" +#line 1784 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = (yyvsp[-3].nd); + endless_method_name(p, (yyvsp[-3].nd)); + void_expr_error(p, (yyvsp[0].nd)); + defn_setup(p, (yyval.nd), (yyvsp[-2].nd), (yyvsp[0].nd)); + nvars_unnest(p); + p->in_def--; + } +#line 6353 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 42: +#line 1793 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = (yyvsp[-5].nd); + endless_method_name(p, (yyvsp[-5].nd)); + void_expr_error(p, (yyvsp[-2].nd)); + void_expr_error(p, (yyvsp[0].nd)); + defn_setup(p, (yyval.nd), (yyvsp[-4].nd), new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd))); + nvars_unnest(p); + p->in_def--; + } +#line 6367 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 43: +#line 1803 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = (yyvsp[-3].nd); + void_expr_error(p, (yyvsp[0].nd)); + defs_setup(p, (yyval.nd), (yyvsp[-2].nd), (yyvsp[0].nd)); + nvars_unnest(p); + p->in_def--; + p->in_single--; + } +#line 6380 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 44: +#line 1812 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = (yyvsp[-5].nd); + void_expr_error(p, (yyvsp[-2].nd)); + void_expr_error(p, (yyvsp[0].nd)); + defs_setup(p, (yyval.nd), (yyvsp[-4].nd), new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd))); + nvars_unnest(p); + p->in_def--; + p->in_single--; + } +#line 6394 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 45: +#line 1822 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 6258 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6403 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 43: -#line 1766 "mrbgems/mruby-compiler/core/parse.y" + case 47: +#line 1830 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6266 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6411 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 46: -#line 1775 "mrbgems/mruby-compiler/core/parse.y" + case 50: +#line 1839 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6274 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6419 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 47: -#line 1779 "mrbgems/mruby-compiler/core/parse.y" + case 51: +#line 1843 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6282 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6427 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 48: -#line 1783 "mrbgems/mruby-compiler/core/parse.y" + case 52: +#line 1847 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6290 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6435 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 49: -#line 1787 "mrbgems/mruby-compiler/core/parse.y" + case 53: +#line 1851 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6298 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6443 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 51: -#line 1795 "mrbgems/mruby-compiler/core/parse.y" + case 55: +#line 1859 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_def(p, (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); p->cmdarg_stack = 0; p->in_def++; nvars_block(p); } -#line 6309 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6454 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 52: -#line 1804 "mrbgems/mruby-compiler/core/parse.y" + case 56: +#line 1868 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_FNAME; } -#line 6317 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6462 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 53: -#line 1808 "mrbgems/mruby-compiler/core/parse.y" + case 57: +#line 1872 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sdef(p, (yyvsp[-3].nd), (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); p->cmdarg_stack = 0; @@ -6326,1054 +6471,1054 @@ yyreduce: nvars_block(p); p->lstate = EXPR_ENDFN; /* force for args */ } -#line 6330 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6475 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 54: -#line 1819 "mrbgems/mruby-compiler/core/parse.y" + case 58: +#line 1883 "mrbgems/mruby-compiler/core/parse.y" { if (!(yyvsp[0].nd)) (yyval.nd) = new_nil(p); else { (yyval.nd) = (yyvsp[0].nd); } } -#line 6341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6486 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 58: -#line 1833 "mrbgems/mruby-compiler/core/parse.y" + case 62: +#line 1897 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6349 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6494 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 59: -#line 1839 "mrbgems/mruby-compiler/core/parse.y" + case 63: +#line 1903 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); } -#line 6358 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6503 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 60: -#line 1846 "mrbgems/mruby-compiler/core/parse.y" + case 64: +#line 1910 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p, (yyvsp[-2].nd), (yyvsp[-1].nd)); local_unnest(p); nvars_unnest(p); } -#line 6368 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6513 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 61: -#line 1854 "mrbgems/mruby-compiler/core/parse.y" + case 65: +#line 1918 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6376 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6521 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 62: -#line 1858 "mrbgems/mruby-compiler/core/parse.y" + case 66: +#line 1922 "mrbgems/mruby-compiler/core/parse.y" { args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_fcall(p, (yyvsp[-2].id), (yyvsp[-1].nd)); } -#line 6385 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6530 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 63: -#line 1863 "mrbgems/mruby-compiler/core/parse.y" + case 67: +#line 1927 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6393 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6538 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 64: -#line 1867 "mrbgems/mruby-compiler/core/parse.y" + case 68: +#line 1931 "mrbgems/mruby-compiler/core/parse.y" { args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num)); } -#line 6402 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6547 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 65: -#line 1872 "mrbgems/mruby-compiler/core/parse.y" + case 69: +#line 1936 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 6410 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6555 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 66: -#line 1876 "mrbgems/mruby-compiler/core/parse.y" + case 70: +#line 1940 "mrbgems/mruby-compiler/core/parse.y" { args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), tCOLON2); } -#line 6419 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6564 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 67: -#line 1881 "mrbgems/mruby-compiler/core/parse.y" + case 71: +#line 1945 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 6427 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6572 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 68: -#line 1885 "mrbgems/mruby-compiler/core/parse.y" + case 72: +#line 1949 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 6435 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6580 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 69: -#line 1889 "mrbgems/mruby-compiler/core/parse.y" + case 73: +#line 1953 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, ret_args(p, (yyvsp[0].nd))); } -#line 6443 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6588 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 70: -#line 1893 "mrbgems/mruby-compiler/core/parse.y" + case 74: +#line 1957 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, ret_args(p, (yyvsp[0].nd))); } -#line 6451 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6596 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 71: -#line 1897 "mrbgems/mruby-compiler/core/parse.y" + case 75: +#line 1961 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, ret_args(p, (yyvsp[0].nd))); } -#line 6459 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6604 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 72: -#line 1903 "mrbgems/mruby-compiler/core/parse.y" + case 76: +#line 1967 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6467 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6612 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 73: -#line 1907 "mrbgems/mruby-compiler/core/parse.y" + case 77: +#line 1971 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6475 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6620 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 75: -#line 1914 "mrbgems/mruby-compiler/core/parse.y" + case 79: +#line 1978 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6483 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6628 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 76: -#line 1920 "mrbgems/mruby-compiler/core/parse.y" + case 80: +#line 1984 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 6491 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6636 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 77: -#line 1924 "mrbgems/mruby-compiler/core/parse.y" + case 81: +#line 1988 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(push((yyvsp[-1].nd),(yyvsp[0].nd))); } -#line 6499 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6644 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 78: -#line 1928 "mrbgems/mruby-compiler/core/parse.y" + case 82: +#line 1992 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6507 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6652 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 79: -#line 1932 "mrbgems/mruby-compiler/core/parse.y" + case 83: +#line 1996 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-4].nd), (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6515 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6660 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 80: -#line 1936 "mrbgems/mruby-compiler/core/parse.y" + case 84: +#line 2000 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2((yyvsp[-1].nd), new_nil(p)); } -#line 6523 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6668 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 81: -#line 1940 "mrbgems/mruby-compiler/core/parse.y" + case 85: +#line 2004 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-3].nd), new_nil(p), (yyvsp[0].nd)); } -#line 6531 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6676 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 82: -#line 1944 "mrbgems/mruby-compiler/core/parse.y" + case 86: +#line 2008 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2(0, (yyvsp[0].nd)); } -#line 6539 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6684 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 83: -#line 1948 "mrbgems/mruby-compiler/core/parse.y" + case 87: +#line 2012 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6547 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6692 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 84: -#line 1952 "mrbgems/mruby-compiler/core/parse.y" + case 88: +#line 2016 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2(0, new_nil(p)); } -#line 6555 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6700 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 85: -#line 1956 "mrbgems/mruby-compiler/core/parse.y" + case 89: +#line 2020 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_nil(p), (yyvsp[0].nd)); } -#line 6563 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6708 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 87: -#line 1963 "mrbgems/mruby-compiler/core/parse.y" + case 91: +#line 2027 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-1].nd), NULL); } -#line 6571 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6716 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 88: -#line 1969 "mrbgems/mruby-compiler/core/parse.y" + case 92: +#line 2033 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[-1].nd)); } -#line 6579 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6724 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 89: -#line 1973 "mrbgems/mruby-compiler/core/parse.y" + case 93: +#line 2037 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[-1].nd)); } -#line 6587 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6732 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 90: -#line 1979 "mrbgems/mruby-compiler/core/parse.y" + case 94: +#line 2043 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 6595 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6740 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 91: -#line 1983 "mrbgems/mruby-compiler/core/parse.y" + case 95: +#line 2047 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 6603 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6748 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 92: -#line 1989 "mrbgems/mruby-compiler/core/parse.y" + case 96: +#line 2053 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 6611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6756 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 93: -#line 1993 "mrbgems/mruby-compiler/core/parse.y" + case 97: +#line 2057 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 6619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6764 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 94: -#line 1997 "mrbgems/mruby-compiler/core/parse.y" + case 98: +#line 2061 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6772 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 95: -#line 2001 "mrbgems/mruby-compiler/core/parse.y" + case 99: +#line 2065 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 6635 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6780 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 96: -#line 2005 "mrbgems/mruby-compiler/core/parse.y" + case 100: +#line 2069 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6643 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6788 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 97: -#line 2009 "mrbgems/mruby-compiler/core/parse.y" + case 101: +#line 2073 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 6653 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6798 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 98: -#line 2015 "mrbgems/mruby-compiler/core/parse.y" + case 102: +#line 2079 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 6663 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6808 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 99: -#line 2021 "mrbgems/mruby-compiler/core/parse.y" + case 103: +#line 2085 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 6672 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6817 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 100: -#line 2028 "mrbgems/mruby-compiler/core/parse.y" + case 104: +#line 2092 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 6680 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6825 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 101: -#line 2032 "mrbgems/mruby-compiler/core/parse.y" + case 105: +#line 2096 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 6688 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6833 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 102: -#line 2036 "mrbgems/mruby-compiler/core/parse.y" + case 106: +#line 2100 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6696 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6841 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 103: -#line 2040 "mrbgems/mruby-compiler/core/parse.y" + case 107: +#line 2104 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 6704 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6849 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 104: -#line 2044 "mrbgems/mruby-compiler/core/parse.y" + case 108: +#line 2108 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6712 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6857 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 105: -#line 2048 "mrbgems/mruby-compiler/core/parse.y" + case 109: +#line 2112 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 6722 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6867 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 106: -#line 2054 "mrbgems/mruby-compiler/core/parse.y" + case 110: +#line 2118 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 6732 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6877 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 107: -#line 2060 "mrbgems/mruby-compiler/core/parse.y" + case 111: +#line 2124 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 6741 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6886 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 108: -#line 2065 "mrbgems/mruby-compiler/core/parse.y" + case 112: +#line 2129 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 6749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6894 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 109: -#line 2071 "mrbgems/mruby-compiler/core/parse.y" + case 113: +#line 2135 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "class/module name must be CONSTANT"); } -#line 6757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6902 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 111: -#line 2078 "mrbgems/mruby-compiler/core/parse.y" + case 115: +#line 2142 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(nint(1), nsym((yyvsp[0].id))); } -#line 6765 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6910 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 112: -#line 2082 "mrbgems/mruby-compiler/core/parse.y" + case 116: +#line 2146 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(nint(0), nsym((yyvsp[0].id))); } -#line 6773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6918 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 113: -#line 2086 "mrbgems/mruby-compiler/core/parse.y" + case 117: +#line 2150 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = cons((yyvsp[-2].nd), nsym((yyvsp[0].id))); } -#line 6782 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6927 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 117: -#line 2096 "mrbgems/mruby-compiler/core/parse.y" + case 121: +#line 2160 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 6791 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6936 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 118: -#line 2101 "mrbgems/mruby-compiler/core/parse.y" + case 122: +#line 2165 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 6800 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6945 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 121: -#line 2112 "mrbgems/mruby-compiler/core/parse.y" + case 125: +#line 2176 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_undef(p, (yyvsp[0].id)); } -#line 6808 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6953 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 122: -#line 2115 "mrbgems/mruby-compiler/core/parse.y" + case 126: +#line 2179 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 6814 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6959 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 123: -#line 2116 "mrbgems/mruby-compiler/core/parse.y" + case 127: +#line 2180 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), nsym((yyvsp[0].id))); } -#line 6822 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6967 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 124: -#line 2121 "mrbgems/mruby-compiler/core/parse.y" + case 128: +#line 2185 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(or); } -#line 6828 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6973 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 125: -#line 2122 "mrbgems/mruby-compiler/core/parse.y" + case 129: +#line 2186 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(xor); } -#line 6834 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6979 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 126: -#line 2123 "mrbgems/mruby-compiler/core/parse.y" + case 130: +#line 2187 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 6840 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6985 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 127: -#line 2124 "mrbgems/mruby-compiler/core/parse.y" + case 131: +#line 2188 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(cmp); } -#line 6846 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6991 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 128: -#line 2125 "mrbgems/mruby-compiler/core/parse.y" + case 132: +#line 2189 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eq); } -#line 6852 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6997 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 129: -#line 2126 "mrbgems/mruby-compiler/core/parse.y" + case 133: +#line 2190 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eqq); } -#line 6858 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7003 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 130: -#line 2127 "mrbgems/mruby-compiler/core/parse.y" + case 134: +#line 2191 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(match); } -#line 6864 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7009 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 131: -#line 2128 "mrbgems/mruby-compiler/core/parse.y" + case 135: +#line 2192 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(nmatch); } -#line 6870 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7015 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 132: -#line 2129 "mrbgems/mruby-compiler/core/parse.y" + case 136: +#line 2193 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(gt); } -#line 6876 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7021 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 133: -#line 2130 "mrbgems/mruby-compiler/core/parse.y" + case 137: +#line 2194 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(ge); } -#line 6882 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7027 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 134: -#line 2131 "mrbgems/mruby-compiler/core/parse.y" + case 138: +#line 2195 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lt); } -#line 6888 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7033 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 135: -#line 2132 "mrbgems/mruby-compiler/core/parse.y" + case 139: +#line 2196 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(le); } -#line 6894 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7039 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 136: -#line 2133 "mrbgems/mruby-compiler/core/parse.y" + case 140: +#line 2197 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neq); } -#line 6900 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7045 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 137: -#line 2134 "mrbgems/mruby-compiler/core/parse.y" + case 141: +#line 2198 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lshift); } -#line 6906 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7051 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 138: -#line 2135 "mrbgems/mruby-compiler/core/parse.y" + case 142: +#line 2199 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(rshift); } -#line 6912 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7057 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 139: -#line 2136 "mrbgems/mruby-compiler/core/parse.y" + case 143: +#line 2200 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(add); } -#line 6918 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7063 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 140: -#line 2137 "mrbgems/mruby-compiler/core/parse.y" + case 144: +#line 2201 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(sub); } -#line 6924 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7069 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 141: -#line 2138 "mrbgems/mruby-compiler/core/parse.y" + case 145: +#line 2202 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 6930 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7075 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 142: -#line 2139 "mrbgems/mruby-compiler/core/parse.y" + case 146: +#line 2203 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 6936 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7081 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 143: -#line 2140 "mrbgems/mruby-compiler/core/parse.y" + case 147: +#line 2204 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(div); } -#line 6942 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7087 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 144: -#line 2141 "mrbgems/mruby-compiler/core/parse.y" + case 148: +#line 2205 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mod); } -#line 6948 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7093 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 145: -#line 2142 "mrbgems/mruby-compiler/core/parse.y" + case 149: +#line 2206 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 6954 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7099 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 146: -#line 2143 "mrbgems/mruby-compiler/core/parse.y" + case 150: +#line 2207 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 6960 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7105 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 147: -#line 2144 "mrbgems/mruby-compiler/core/parse.y" + case 151: +#line 2208 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(not); } -#line 6966 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7111 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 148: -#line 2145 "mrbgems/mruby-compiler/core/parse.y" + case 152: +#line 2209 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neg); } -#line 6972 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7117 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 149: -#line 2146 "mrbgems/mruby-compiler/core/parse.y" + case 153: +#line 2210 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(plus); } -#line 6978 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7123 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 150: -#line 2147 "mrbgems/mruby-compiler/core/parse.y" + case 154: +#line 2211 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(minus); } -#line 6984 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7129 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 151: -#line 2148 "mrbgems/mruby-compiler/core/parse.y" + case 155: +#line 2212 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aref); } -#line 6990 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7135 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 152: -#line 2149 "mrbgems/mruby-compiler/core/parse.y" + case 156: +#line 2213 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aset); } -#line 6996 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7141 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 153: -#line 2150 "mrbgems/mruby-compiler/core/parse.y" + case 157: +#line 2214 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(tick); } -#line 7002 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7147 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 194: -#line 2168 "mrbgems/mruby-compiler/core/parse.y" + case 198: +#line 2232 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7010 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7155 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 195: -#line 2172 "mrbgems/mruby-compiler/core/parse.y" + case 199: +#line 2236 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7018 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7163 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 196: -#line 2176 "mrbgems/mruby-compiler/core/parse.y" + case 200: +#line 2240 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-5].nd), intern_op(aref), (yyvsp[-3].nd), '.'), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7026 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7171 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 197: -#line 2180 "mrbgems/mruby-compiler/core/parse.y" + case 201: +#line 2244 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7034 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7179 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 198: -#line 2184 "mrbgems/mruby-compiler/core/parse.y" + case 202: +#line 2248 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, (yyvsp[-3].num)), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7042 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7187 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 199: -#line 2188 "mrbgems/mruby-compiler/core/parse.y" + case 203: +#line 2252 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7050 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7195 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 200: -#line 2192 "mrbgems/mruby-compiler/core/parse.y" + case 204: +#line 2256 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7059 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7204 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 201: -#line 2197 "mrbgems/mruby-compiler/core/parse.y" + case 205: +#line 2261 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7068 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7213 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 202: -#line 2202 "mrbgems/mruby-compiler/core/parse.y" + case 206: +#line 2266 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 7077 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7222 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 203: -#line 2207 "mrbgems/mruby-compiler/core/parse.y" + case 207: +#line 2271 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7085 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7230 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 204: -#line 2211 "mrbgems/mruby-compiler/core/parse.y" + case 208: +#line 2275 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7093 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7238 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 205: -#line 2215 "mrbgems/mruby-compiler/core/parse.y" + case 209: +#line 2279 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, new_nil(p), (yyvsp[0].nd)); } -#line 7101 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7246 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 206: -#line 2219 "mrbgems/mruby-compiler/core/parse.y" + case 210: +#line 2283 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7109 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7254 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 207: -#line 2223 "mrbgems/mruby-compiler/core/parse.y" + case 211: +#line 2287 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7117 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7262 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 208: -#line 2227 "mrbgems/mruby-compiler/core/parse.y" + case 212: +#line 2291 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, new_nil(p), (yyvsp[0].nd)); } -#line 7125 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7270 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 209: -#line 2231 "mrbgems/mruby-compiler/core/parse.y" + case 213: +#line 2295 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "+", (yyvsp[0].nd)); } -#line 7133 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7278 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 210: -#line 2235 "mrbgems/mruby-compiler/core/parse.y" + case 214: +#line 2299 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "-", (yyvsp[0].nd)); } -#line 7141 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7286 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 211: -#line 2239 "mrbgems/mruby-compiler/core/parse.y" + case 215: +#line 2303 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "*", (yyvsp[0].nd)); } -#line 7149 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7294 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 212: -#line 2243 "mrbgems/mruby-compiler/core/parse.y" + case 216: +#line 2307 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "/", (yyvsp[0].nd)); } -#line 7157 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7302 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 213: -#line 2247 "mrbgems/mruby-compiler/core/parse.y" + case 217: +#line 2311 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "%", (yyvsp[0].nd)); } -#line 7165 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7310 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 214: -#line 2251 "mrbgems/mruby-compiler/core/parse.y" + case 218: +#line 2315 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)); } -#line 7173 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7318 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 215: -#line 2255 "mrbgems/mruby-compiler/core/parse.y" + case 219: +#line 2319 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = call_uni_op(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)), "-@"); + (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7181 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7326 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 216: -#line 2259 "mrbgems/mruby-compiler/core/parse.y" + case 220: +#line 2323 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = call_uni_op(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)), "-@"); + (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7189 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7334 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 217: -#line 2263 "mrbgems/mruby-compiler/core/parse.y" + case 221: +#line 2327 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "+@"); } -#line 7197 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7342 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 218: -#line 2267 "mrbgems/mruby-compiler/core/parse.y" + case 222: +#line 2331 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "-@"); + (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 7205 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7350 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 219: -#line 2271 "mrbgems/mruby-compiler/core/parse.y" + case 223: +#line 2335 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "|", (yyvsp[0].nd)); } -#line 7213 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7358 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 220: -#line 2275 "mrbgems/mruby-compiler/core/parse.y" + case 224: +#line 2339 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "^", (yyvsp[0].nd)); } -#line 7221 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7366 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 221: -#line 2279 "mrbgems/mruby-compiler/core/parse.y" + case 225: +#line 2343 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "&", (yyvsp[0].nd)); } -#line 7229 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7374 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 222: -#line 2283 "mrbgems/mruby-compiler/core/parse.y" + case 226: +#line 2347 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=>", (yyvsp[0].nd)); } -#line 7237 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7382 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 223: -#line 2287 "mrbgems/mruby-compiler/core/parse.y" + case 227: +#line 2351 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">", (yyvsp[0].nd)); } -#line 7245 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7390 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 224: -#line 2291 "mrbgems/mruby-compiler/core/parse.y" + case 228: +#line 2355 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">=", (yyvsp[0].nd)); } -#line 7253 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7398 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 225: -#line 2295 "mrbgems/mruby-compiler/core/parse.y" + case 229: +#line 2359 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<", (yyvsp[0].nd)); } -#line 7261 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7406 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 226: -#line 2299 "mrbgems/mruby-compiler/core/parse.y" + case 230: +#line 2363 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=", (yyvsp[0].nd)); } -#line 7269 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7414 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 227: -#line 2303 "mrbgems/mruby-compiler/core/parse.y" + case 231: +#line 2367 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "==", (yyvsp[0].nd)); } -#line 7277 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7422 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 228: -#line 2307 "mrbgems/mruby-compiler/core/parse.y" + case 232: +#line 2371 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "===", (yyvsp[0].nd)); } -#line 7285 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7430 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 229: -#line 2311 "mrbgems/mruby-compiler/core/parse.y" + case 233: +#line 2375 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!=", (yyvsp[0].nd)); } -#line 7293 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7438 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 230: -#line 2315 "mrbgems/mruby-compiler/core/parse.y" + case 234: +#line 2379 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "=~", (yyvsp[0].nd)); } -#line 7301 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7446 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 231: -#line 2319 "mrbgems/mruby-compiler/core/parse.y" + case 235: +#line 2383 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!~", (yyvsp[0].nd)); } -#line 7309 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7454 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 232: -#line 2323 "mrbgems/mruby-compiler/core/parse.y" + case 236: +#line 2387 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 7317 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7462 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 233: -#line 2327 "mrbgems/mruby-compiler/core/parse.y" + case 237: +#line 2391 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "~"); } -#line 7325 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7470 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 234: -#line 2331 "mrbgems/mruby-compiler/core/parse.y" + case 238: +#line 2395 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<<", (yyvsp[0].nd)); } -#line 7333 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7478 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 235: -#line 2335 "mrbgems/mruby-compiler/core/parse.y" + case 239: +#line 2399 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">>", (yyvsp[0].nd)); } -#line 7341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7486 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 236: -#line 2339 "mrbgems/mruby-compiler/core/parse.y" + case 240: +#line 2403 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7349 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7494 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 237: -#line 2343 "mrbgems/mruby-compiler/core/parse.y" + case 241: +#line 2407 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7357 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7502 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 238: -#line 2347 "mrbgems/mruby-compiler/core/parse.y" + case 242: +#line 2411 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7365 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7510 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 239: -#line 2351 "mrbgems/mruby-compiler/core/parse.y" + case 243: +#line 2415 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7373 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7518 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 240: -#line 2355 "mrbgems/mruby-compiler/core/parse.y" + case 244: +#line 2419 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); endless_method_name(p, (yyvsp[-3].nd)); @@ -7382,11 +7527,11 @@ yyreduce: nvars_unnest(p); p->in_def--; } -#line 7386 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7531 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 241: -#line 2364 "mrbgems/mruby-compiler/core/parse.y" + case 245: +#line 2428 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); endless_method_name(p, (yyvsp[-5].nd)); @@ -7396,11 +7541,11 @@ yyreduce: nvars_unnest(p); p->in_def--; } -#line 7400 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7545 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 242: -#line 2374 "mrbgems/mruby-compiler/core/parse.y" + case 246: +#line 2438 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); void_expr_error(p, (yyvsp[0].nd)); @@ -7409,11 +7554,11 @@ yyreduce: p->in_def--; p->in_single--; } -#line 7413 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7558 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 243: -#line 2383 "mrbgems/mruby-compiler/core/parse.y" + case 247: +#line 2447 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); void_expr_error(p, (yyvsp[-2].nd)); @@ -7423,481 +7568,465 @@ yyreduce: p->in_def--; p->in_single--; } -#line 7427 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7572 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 244: -#line 2393 "mrbgems/mruby-compiler/core/parse.y" + case 248: +#line 2457 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7435 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7580 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 246: -#line 2400 "mrbgems/mruby-compiler/core/parse.y" + case 250: +#line 2464 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7444 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7589 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 247: -#line 2405 "mrbgems/mruby-compiler/core/parse.y" + case 251: +#line 2469 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = push((yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd))); + (yyval.nd) = push((yyvsp[-3].nd), new_hash(p, (yyvsp[-1].nd))); } -#line 7452 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7597 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 248: -#line 2409 "mrbgems/mruby-compiler/core/parse.y" + case 252: +#line 2473 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_kw_hash(p, (yyvsp[-1].nd)), 0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7461 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7606 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 249: -#line 2416 "mrbgems/mruby-compiler/core/parse.y" + case 253: +#line 2480 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7469 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7614 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 250: -#line 2420 "mrbgems/mruby-compiler/core/parse.y" + case 254: +#line 2484 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7479 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7624 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 251: -#line 2428 "mrbgems/mruby-compiler/core/parse.y" + case 255: +#line 2492 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 7487 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7632 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 252: -#line 2432 "mrbgems/mruby-compiler/core/parse.y" + case 256: +#line 2496 "mrbgems/mruby-compiler/core/parse.y" { -#if 1 - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - (yyval.nd) = cons(push((yyvsp[-3].nd), new_splat(p, new_lvar(p, r))), - new_block_arg(p, new_lvar(p, b))); -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); - (yyval.nd) = cons(list2(push((yyvsp[-3].nd), new_splat(p, new_lvar(p, r))), - new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), - new_block_arg(p, new_lvar(p, b))); -#endif + (yyval.nd) = new_callargs(p, push((yyvsp[-3].nd), new_splat(p, new_lvar(p, r))), + new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))), + new_block_arg(p, new_lvar(p, b))); } -#line 7507 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7645 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 253: -#line 2448 "mrbgems/mruby-compiler/core/parse.y" + case 257: +#line 2505 "mrbgems/mruby-compiler/core/parse.y" { -#if 1 - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - if (local_var_p(p, r) && local_var_p(p, b)) { - (yyval.nd) = cons(list1(new_splat(p, new_lvar(p, r))), - new_block_arg(p, new_lvar(p, b))); - } -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); if (local_var_p(p, r) && local_var_p(p, k) && local_var_p(p, b)) { - (yyval.nd) = cons(list2(new_splat(p, new_lvar(p, r)), - new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k))))), - new_block_arg(p, new_lvar(p, b))); + (yyval.nd) = new_callargs(p, list1(new_splat(p, new_lvar(p, r))), + new_kw_hash(p, list1(cons(new_kw_rest_args(p, 0), new_lvar(p, k)))), + new_block_arg(p, new_lvar(p, b))); } -#endif else { yyerror(p, "unexpected argument forwarding ..."); (yyval.nd) = 0; } } -#line 7535 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7664 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 258: -#line 2480 "mrbgems/mruby-compiler/core/parse.y" + case 262: +#line 2528 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = cons((yyvsp[-1].nd),0); + (yyval.nd) = new_callargs(p,(yyvsp[-1].nd),0,0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7544 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7673 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 259: -#line 2485 "mrbgems/mruby-compiler/core/parse.y" + case 263: +#line 2533 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = cons(push((yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd))), 0); + (yyval.nd) = new_callargs(p,(yyvsp[-3].nd),new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } -#line 7553 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7682 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 260: -#line 2490 "mrbgems/mruby-compiler/core/parse.y" + case 264: +#line 2538 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = cons(list1(new_kw_hash(p, (yyvsp[-1].nd))), 0); + (yyval.nd) = new_callargs(p,0,new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7562 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7691 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 261: -#line 2497 "mrbgems/mruby-compiler/core/parse.y" + case 265: +#line 2545 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); - (yyval.nd) = cons(list1((yyvsp[0].nd)), 0); + (yyval.nd) = new_callargs(p, list1((yyvsp[0].nd)), 0, 0); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7572 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7701 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 262: -#line 2503 "mrbgems/mruby-compiler/core/parse.y" + case 266: +#line 2551 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = cons((yyvsp[-1].nd), (yyvsp[0].nd)); + (yyval.nd) = new_callargs(p, (yyvsp[-1].nd), 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7581 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7710 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 263: -#line 2508 "mrbgems/mruby-compiler/core/parse.y" + case 267: +#line 2556 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = cons(list1(new_kw_hash(p, (yyvsp[-1].nd))), (yyvsp[0].nd)); + (yyval.nd) = new_callargs(p, 0, new_kw_hash(p, (yyvsp[-1].nd)), (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7590 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7719 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 264: -#line 2513 "mrbgems/mruby-compiler/core/parse.y" + case 268: +#line 2561 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = cons(push((yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd))), (yyvsp[0].nd)); + (yyval.nd) = new_callargs(p, (yyvsp[-3].nd), new_kw_hash(p, (yyvsp[-1].nd)), (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } -#line 7599 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7728 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 265: -#line 2518 "mrbgems/mruby-compiler/core/parse.y" + case 269: +#line 2566 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = cons(0, (yyvsp[0].nd)); + (yyval.nd) = new_callargs(p, 0, 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7608 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7737 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 266: -#line 2524 "mrbgems/mruby-compiler/core/parse.y" + case 270: +#line 2572 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; CMDARG_PUSH(1); } -#line 7617 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7746 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 267: -#line 2529 "mrbgems/mruby-compiler/core/parse.y" + case 271: +#line 2577 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-1].stack); (yyval.nd) = (yyvsp[0].nd); } -#line 7626 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7755 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 268: -#line 2536 "mrbgems/mruby-compiler/core/parse.y" + case 272: +#line 2584 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block_arg(p, (yyvsp[0].nd)); } -#line 7634 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7763 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 269: -#line 2542 "mrbgems/mruby-compiler/core/parse.y" + case 273: +#line 2590 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7642 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7771 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 270: -#line 2546 "mrbgems/mruby-compiler/core/parse.y" + case 274: +#line 2594 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 7650 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7779 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 273: -#line 2556 "mrbgems/mruby-compiler/core/parse.y" + case 276: +#line 2603 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); - (yyval.nd) = cons((yyvsp[0].nd), 0); + (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7660 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7789 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 274: -#line 2562 "mrbgems/mruby-compiler/core/parse.y" + case 277: +#line 2609 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); - (yyval.nd) = cons(new_splat(p, (yyvsp[0].nd)), 0); + (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7670 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7799 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 275: -#line 2568 "mrbgems/mruby-compiler/core/parse.y" + case 278: +#line 2615 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7679 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7808 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 276: -#line 2573 "mrbgems/mruby-compiler/core/parse.y" + case 279: +#line 2620 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 7688 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7817 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 277: -#line 2580 "mrbgems/mruby-compiler/core/parse.y" + case 280: +#line 2627 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7697 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7826 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 278: -#line 2585 "mrbgems/mruby-compiler/core/parse.y" + case 281: +#line 2632 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 7706 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7835 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 279: -#line 2590 "mrbgems/mruby-compiler/core/parse.y" + case 282: +#line 2637 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); } -#line 7715 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7844 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 287: -#line 2604 "mrbgems/mruby-compiler/core/parse.y" + case 290: +#line 2651 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nvar(p, (yyvsp[0].num)); } -#line 7723 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7852 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 288: -#line 2608 "mrbgems/mruby-compiler/core/parse.y" + case 291: +#line 2655 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[0].id), 0); } -#line 7731 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7860 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 289: -#line 2612 "mrbgems/mruby-compiler/core/parse.y" + case 292: +#line 2659 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 7740 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7869 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 290: -#line 2618 "mrbgems/mruby-compiler/core/parse.y" + case 293: +#line 2665 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-2].stack); (yyval.nd) = (yyvsp[-1].nd); } -#line 7749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7878 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 291: -#line 2623 "mrbgems/mruby-compiler/core/parse.y" + case 294: +#line 2670 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 7758 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7887 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 292: -#line 2627 "mrbgems/mruby-compiler/core/parse.y" + case 295: +#line 2674 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 7764 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7893 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 293: -#line 2628 "mrbgems/mruby-compiler/core/parse.y" + case 296: +#line 2675 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-3].stack); (yyval.nd) = (yyvsp[-2].nd); } -#line 7773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7902 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 294: -#line 2632 "mrbgems/mruby-compiler/core/parse.y" + case 297: +#line 2679 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 7779 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7908 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 295: -#line 2633 "mrbgems/mruby-compiler/core/parse.y" + case 298: +#line 2680 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 7787 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7916 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 296: -#line 2637 "mrbgems/mruby-compiler/core/parse.y" + case 299: +#line 2684 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 7795 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7924 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 297: -#line 2641 "mrbgems/mruby-compiler/core/parse.y" + case 300: +#line 2688 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 7803 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7932 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 298: -#line 2645 "mrbgems/mruby-compiler/core/parse.y" + case 301: +#line 2692 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 7811 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7940 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 299: -#line 2649 "mrbgems/mruby-compiler/core/parse.y" + case 302: +#line 2696 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_array(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7820 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7949 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 300: -#line 2654 "mrbgems/mruby-compiler/core/parse.y" + case 303: +#line 2701 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_hash(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7829 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7958 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 301: -#line 2659 "mrbgems/mruby-compiler/core/parse.y" + case 304: +#line 2706 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, 0); } -#line 7837 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7966 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 302: -#line 2663 "mrbgems/mruby-compiler/core/parse.y" + case 305: +#line 2710 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 7845 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7974 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 303: -#line 2667 "mrbgems/mruby-compiler/core/parse.y" + case 306: +#line 2714 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[-1].nd)), "!"); } -#line 7853 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7982 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 304: -#line 2671 "mrbgems/mruby-compiler/core/parse.y" + case 307: +#line 2718 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, new_nil(p), "!"); } -#line 7861 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7990 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 305: -#line 2675 "mrbgems/mruby-compiler/core/parse.y" + case 308: +#line 2722 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_fcall(p, (yyvsp[-1].id), cons(0, (yyvsp[0].nd))); + (yyval.nd) = new_fcall(p, (yyvsp[-1].id), new_callargs(p, 0, 0, (yyvsp[0].nd))); } -#line 7869 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7998 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 307: -#line 2680 "mrbgems/mruby-compiler/core/parse.y" + case 310: +#line 2727 "mrbgems/mruby-compiler/core/parse.y" { call_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = (yyvsp[-1].nd); } -#line 7878 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8007 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 308: -#line 2685 "mrbgems/mruby-compiler/core/parse.y" + case 311: +#line 2732 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); (yyval.num) = p->lpar_beg; p->lpar_beg = ++p->paren_nest; } -#line 7888 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8017 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 309: -#line 2691 "mrbgems/mruby-compiler/core/parse.y" + case 312: +#line 2738 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 7897 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8026 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 310: -#line 2696 "mrbgems/mruby-compiler/core/parse.y" + case 313: +#line 2743 "mrbgems/mruby-compiler/core/parse.y" { p->lpar_beg = (yyvsp[-3].num); (yyval.nd) = new_lambda(p, (yyvsp[-2].nd), (yyvsp[0].nd)); @@ -7905,149 +8034,149 @@ yyreduce: p->cmdarg_stack = (yyvsp[-1].stack); CMDARG_LEXPOP(); } -#line 7909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8038 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 311: -#line 2707 "mrbgems/mruby-compiler/core/parse.y" + case 314: +#line 2754 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-4].nd)), (yyvsp[-2].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-5].num)); } -#line 7918 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8047 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 312: -#line 2715 "mrbgems/mruby-compiler/core/parse.y" + case 315: +#line 2762 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_unless(p, cond((yyvsp[-4].nd)), (yyvsp[-2].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-5].num)); } -#line 7927 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8056 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 313: -#line 2719 "mrbgems/mruby-compiler/core/parse.y" + case 316: +#line 2766 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 7933 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8062 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 314: -#line 2719 "mrbgems/mruby-compiler/core/parse.y" + case 317: +#line 2766 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 7939 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8068 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 315: -#line 2722 "mrbgems/mruby-compiler/core/parse.y" + case 318: +#line 2769 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_while(p, cond((yyvsp[-4].nd)), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-6].num)); } -#line 7948 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8077 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 316: -#line 2726 "mrbgems/mruby-compiler/core/parse.y" + case 319: +#line 2773 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 7954 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8083 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 317: -#line 2726 "mrbgems/mruby-compiler/core/parse.y" + case 320: +#line 2773 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 7960 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8089 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 318: -#line 2729 "mrbgems/mruby-compiler/core/parse.y" + case 321: +#line 2776 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_until(p, cond((yyvsp[-4].nd)), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-6].num)); } -#line 7969 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8098 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 319: -#line 2736 "mrbgems/mruby-compiler/core/parse.y" + case 322: +#line 2783 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 7977 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8106 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 320: -#line 2740 "mrbgems/mruby-compiler/core/parse.y" + case 323: +#line 2787 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, 0, (yyvsp[-1].nd)); } -#line 7985 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8114 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 321: -#line 2744 "mrbgems/mruby-compiler/core/parse.y" + case 324: +#line 2791 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 7991 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8120 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 322: -#line 2746 "mrbgems/mruby-compiler/core/parse.y" + case 325: +#line 2793 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 7997 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8126 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 323: -#line 2749 "mrbgems/mruby-compiler/core/parse.y" + case 326: +#line 2796 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_for(p, (yyvsp[-7].nd), (yyvsp[-4].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-8].num)); } -#line 8006 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8135 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 324: -#line 2755 "mrbgems/mruby-compiler/core/parse.y" + case 327: +#line 2802 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "class definition in method body"); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8017 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8146 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 325: -#line 2763 "mrbgems/mruby-compiler/core/parse.y" + case 328: +#line 2810 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_class(p, (yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-5].num)); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8028 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8157 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 326: -#line 2771 "mrbgems/mruby-compiler/core/parse.y" + case 329: +#line 2818 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = p->in_def; p->in_def = 0; } -#line 8037 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8166 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 327: -#line 2776 "mrbgems/mruby-compiler/core/parse.y" + case 330: +#line 2823 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(local_switch(p), nint(p->in_single)); nvars_block(p); p->in_single = 0; } -#line 8047 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8176 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 328: -#line 2783 "mrbgems/mruby-compiler/core/parse.y" + case 331: +#line 2830 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sclass(p, (yyvsp[-5].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-7].num)); @@ -8056,44 +8185,44 @@ yyreduce: p->in_def = (yyvsp[-4].num); p->in_single = intn((yyvsp[-2].nd)->cdr); } -#line 8060 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8189 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 329: -#line 2793 "mrbgems/mruby-compiler/core/parse.y" + case 332: +#line 2840 "mrbgems/mruby-compiler/core/parse.y" { if (p->in_def || p->in_single) yyerror(p, "module definition in method body"); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8071 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8200 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 330: -#line 2801 "mrbgems/mruby-compiler/core/parse.y" + case 333: +#line 2848 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_module(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-4].num)); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8082 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8211 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 331: -#line 2811 "mrbgems/mruby-compiler/core/parse.y" + case 334: +#line 2858 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); defn_setup(p, (yyval.nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); nvars_unnest(p); p->in_def--; } -#line 8093 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8222 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 332: -#line 2821 "mrbgems/mruby-compiler/core/parse.y" + case 335: +#line 2868 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); defs_setup(p, (yyval.nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); @@ -8101,451 +8230,451 @@ yyreduce: p->in_def--; p->in_single--; } -#line 8105 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8234 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 333: -#line 2829 "mrbgems/mruby-compiler/core/parse.y" + case 336: +#line 2876 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, 0); } -#line 8113 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8242 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 334: -#line 2833 "mrbgems/mruby-compiler/core/parse.y" + case 337: +#line 2880 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, 0); } -#line 8121 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8250 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 335: -#line 2837 "mrbgems/mruby-compiler/core/parse.y" + case 338: +#line 2884 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_redo(p); } -#line 8129 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8258 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 336: -#line 2841 "mrbgems/mruby-compiler/core/parse.y" + case 339: +#line 2888 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_retry(p); } -#line 8137 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8266 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 337: -#line 2847 "mrbgems/mruby-compiler/core/parse.y" + case 340: +#line 2894 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 8146 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8275 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 344: -#line 2866 "mrbgems/mruby-compiler/core/parse.y" + case 347: +#line 2913 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-3].nd)), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8154 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8283 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 346: -#line 2873 "mrbgems/mruby-compiler/core/parse.y" + case 349: +#line 2920 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8162 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8291 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 347: -#line 2879 "mrbgems/mruby-compiler/core/parse.y" + case 350: +#line 2926 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(list1((yyvsp[0].nd))); } -#line 8170 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8299 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 349: -#line 2886 "mrbgems/mruby-compiler/core/parse.y" + case 352: +#line 2933 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[0].nd),0,0); } -#line 8178 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8307 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 350: -#line 2890 "mrbgems/mruby-compiler/core/parse.y" + case 353: +#line 2937 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-3].nd), new_arg(p, (yyvsp[0].id)), 0); } -#line 8186 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8315 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 351: -#line 2894 "mrbgems/mruby-compiler/core/parse.y" + case 354: +#line 2941 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-5].nd), new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8194 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8323 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 352: -#line 2898 "mrbgems/mruby-compiler/core/parse.y" + case 355: +#line 2945 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, 0); (yyval.nd) = list3((yyvsp[-2].nd), nint(-1), 0); } -#line 8203 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8332 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 353: -#line 2903 "mrbgems/mruby-compiler/core/parse.y" + case 356: +#line 2950 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-4].nd), nint(-1), (yyvsp[0].nd)); } -#line 8211 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8340 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 354: -#line 2907 "mrbgems/mruby-compiler/core/parse.y" + case 357: +#line 2954 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_arg(p, (yyvsp[0].id)), 0); } -#line 8219 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8348 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 355: -#line 2911 "mrbgems/mruby-compiler/core/parse.y" + case 358: +#line 2958 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8227 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8356 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 356: -#line 2915 "mrbgems/mruby-compiler/core/parse.y" + case 359: +#line 2962 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, 0); (yyval.nd) = list3(0, nint(-1), 0); } -#line 8236 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8365 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 357: -#line 2920 "mrbgems/mruby-compiler/core/parse.y" + case 360: +#line 2967 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, 0); } -#line 8244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8373 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 358: -#line 2924 "mrbgems/mruby-compiler/core/parse.y" + case 361: +#line 2971 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, nint(-1), (yyvsp[0].nd)); } -#line 8252 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8381 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 359: -#line 2930 "mrbgems/mruby-compiler/core/parse.y" + case 362: +#line 2977 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8260 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8389 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 360: -#line 2934 "mrbgems/mruby-compiler/core/parse.y" + case 363: +#line 2981 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 8268 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8397 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 361: -#line 2938 "mrbgems/mruby-compiler/core/parse.y" + case 364: +#line 2985 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8276 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8405 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 362: -#line 2942 "mrbgems/mruby-compiler/core/parse.y" + case 365: +#line 2989 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 8284 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8413 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 363: -#line 2948 "mrbgems/mruby-compiler/core/parse.y" + case 366: +#line 2995 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8292 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8421 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 364: -#line 2952 "mrbgems/mruby-compiler/core/parse.y" + case 367: +#line 2999 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 8300 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8429 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 365: -#line 2958 "mrbgems/mruby-compiler/core/parse.y" + case 368: +#line 3005 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8308 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8437 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 366: -#line 2962 "mrbgems/mruby-compiler/core/parse.y" + case 369: +#line 3009 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8316 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8445 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 367: -#line 2966 "mrbgems/mruby-compiler/core/parse.y" + case 370: +#line 3013 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8324 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8453 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 368: -#line 2970 "mrbgems/mruby-compiler/core/parse.y" + case 371: +#line 3017 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8461 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 369: -#line 2974 "mrbgems/mruby-compiler/core/parse.y" + case 372: +#line 3021 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8340 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8469 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 370: -#line 2978 "mrbgems/mruby-compiler/core/parse.y" + case 373: +#line 3025 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-2].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8348 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8477 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 371: -#line 2982 "mrbgems/mruby-compiler/core/parse.y" + case 374: +#line 3029 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8356 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8485 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 372: -#line 2986 "mrbgems/mruby-compiler/core/parse.y" + case 375: +#line 3033 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8364 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8493 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 373: -#line 2990 "mrbgems/mruby-compiler/core/parse.y" + case 376: +#line 3037 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8372 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8501 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 374: -#line 2994 "mrbgems/mruby-compiler/core/parse.y" + case 377: +#line 3041 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8380 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8509 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 375: -#line 2998 "mrbgems/mruby-compiler/core/parse.y" + case 378: +#line 3045 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8388 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8517 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 376: -#line 3002 "mrbgems/mruby-compiler/core/parse.y" + case 379: +#line 3049 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8396 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8525 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 377: -#line 3006 "mrbgems/mruby-compiler/core/parse.y" + case 380: +#line 3053 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8404 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8533 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 378: -#line 3010 "mrbgems/mruby-compiler/core/parse.y" + case 381: +#line 3057 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8412 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8541 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 379: -#line 3014 "mrbgems/mruby-compiler/core/parse.y" + case 382: +#line 3061 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 8420 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8549 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 380: -#line 3020 "mrbgems/mruby-compiler/core/parse.y" + case 383: +#line 3067 "mrbgems/mruby-compiler/core/parse.y" { local_add_blk(p, 0); (yyval.nd) = 0; } -#line 8429 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8558 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 381: -#line 3025 "mrbgems/mruby-compiler/core/parse.y" + case 384: +#line 3072 "mrbgems/mruby-compiler/core/parse.y" { p->cmd_start = TRUE; (yyval.nd) = (yyvsp[0].nd); } -#line 8438 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8567 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 382: -#line 3031 "mrbgems/mruby-compiler/core/parse.y" + case 385: +#line 3078 "mrbgems/mruby-compiler/core/parse.y" {local_add_blk(p, 0);} -#line 8444 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8573 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 383: -#line 3032 "mrbgems/mruby-compiler/core/parse.y" + case 386: +#line 3079 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8452 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8581 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 384: -#line 3036 "mrbgems/mruby-compiler/core/parse.y" + case 387: +#line 3083 "mrbgems/mruby-compiler/core/parse.y" { local_add_blk(p, 0); (yyval.nd) = 0; } -#line 8461 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8590 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 385: -#line 3041 "mrbgems/mruby-compiler/core/parse.y" + case 388: +#line 3088 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-2].nd); } -#line 8469 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8598 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 386: -#line 3048 "mrbgems/mruby-compiler/core/parse.y" + case 389: +#line 3095 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8477 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8606 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 387: -#line 3052 "mrbgems/mruby-compiler/core/parse.y" + case 390: +#line 3099 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8485 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8614 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 390: -#line 3062 "mrbgems/mruby-compiler/core/parse.y" + case 393: +#line 3109 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); new_bv(p, (yyvsp[0].id)); } -#line 8494 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8623 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 392: -#line 3070 "mrbgems/mruby-compiler/core/parse.y" + case 395: +#line 3117 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-2].nd); } -#line 8502 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8631 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 393: -#line 3074 "mrbgems/mruby-compiler/core/parse.y" + case 396: +#line 3121 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8510 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8639 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 394: -#line 3080 "mrbgems/mruby-compiler/core/parse.y" + case 397: +#line 3127 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8518 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8647 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 395: -#line 3084 "mrbgems/mruby-compiler/core/parse.y" + case 398: +#line 3131 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8526 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8655 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 396: -#line 3090 "mrbgems/mruby-compiler/core/parse.y" + case 399: +#line 3137 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); } -#line 8535 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8664 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 397: -#line 3097 "mrbgems/mruby-compiler/core/parse.y" + case 400: +#line 3144 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd)); local_unnest(p); nvars_unnest(p); } -#line 8545 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8674 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 398: -#line 3105 "mrbgems/mruby-compiler/core/parse.y" + case 401: +#line 3152 "mrbgems/mruby-compiler/core/parse.y" { if (typen((yyvsp[-1].nd)->car) == NODE_YIELD) { yyerror(p, "block given to yield"); @@ -8555,159 +8684,159 @@ yyreduce: } (yyval.nd) = (yyvsp[-1].nd); } -#line 8559 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8688 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 399: -#line 3115 "mrbgems/mruby-compiler/core/parse.y" + case 402: +#line 3162 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 8567 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8696 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 400: -#line 3119 "mrbgems/mruby-compiler/core/parse.y" + case 403: +#line 3166 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num)); call_with_block(p, (yyval.nd), (yyvsp[0].nd)); } -#line 8576 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8705 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 401: -#line 3124 "mrbgems/mruby-compiler/core/parse.y" + case 404: +#line 3171 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), (yyvsp[-1].nd), (yyvsp[-3].num)); call_with_block(p, (yyval.nd), (yyvsp[0].nd)); } -#line 8585 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8714 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 402: -#line 3131 "mrbgems/mruby-compiler/core/parse.y" + case 405: +#line 3178 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 8593 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8722 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 403: -#line 3135 "mrbgems/mruby-compiler/core/parse.y" + case 406: +#line 3182 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 8601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8730 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 404: -#line 3139 "mrbgems/mruby-compiler/core/parse.y" + case 407: +#line 3186 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 8609 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8738 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 405: -#line 3143 "mrbgems/mruby-compiler/core/parse.y" + case 408: +#line 3190 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 8617 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8746 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 406: -#line 3147 "mrbgems/mruby-compiler/core/parse.y" + case 409: +#line 3194 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM_2(p->mrb, call), (yyvsp[0].nd), (yyvsp[-1].num)); } -#line 8625 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8754 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 407: -#line 3151 "mrbgems/mruby-compiler/core/parse.y" + case 410: +#line 3198 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), MRB_SYM_2(p->mrb, call), (yyvsp[0].nd), tCOLON2); } -#line 8633 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8762 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 408: -#line 3155 "mrbgems/mruby-compiler/core/parse.y" + case 411: +#line 3202 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 8641 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8770 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 409: -#line 3159 "mrbgems/mruby-compiler/core/parse.y" + case 412: +#line 3206 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_zsuper(p); } -#line 8649 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8778 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 410: -#line 3163 "mrbgems/mruby-compiler/core/parse.y" + case 413: +#line 3210 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 8657 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8786 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 411: -#line 3169 "mrbgems/mruby-compiler/core/parse.y" + case 414: +#line 3216 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 8667 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8796 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 412: -#line 3176 "mrbgems/mruby-compiler/core/parse.y" + case 415: +#line 3223 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-3].num)); local_unnest(p); nvars_unnest(p); } -#line 8678 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8807 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 413: -#line 3183 "mrbgems/mruby-compiler/core/parse.y" + case 416: +#line 3230 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 8688 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8817 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 414: -#line 3190 "mrbgems/mruby-compiler/core/parse.y" + case 417: +#line 3237 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-3].num)); local_unnest(p); nvars_unnest(p); } -#line 8699 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8828 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 415: -#line 3201 "mrbgems/mruby-compiler/core/parse.y" + case 418: +#line 3248 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(cons((yyvsp[-3].nd), (yyvsp[-1].nd)), (yyvsp[0].nd)); } -#line 8707 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8836 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 416: -#line 3207 "mrbgems/mruby-compiler/core/parse.y" + case 419: +#line 3254 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[0].nd)) { (yyval.nd) = cons(cons(0, (yyvsp[0].nd)), 0); @@ -8716,383 +8845,415 @@ yyreduce: (yyval.nd) = 0; } } -#line 8720 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8849 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 418: -#line 3221 "mrbgems/mruby-compiler/core/parse.y" + case 421: +#line 3268 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(list3((yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd))); if ((yyvsp[0].nd)) (yyval.nd) = append((yyval.nd), (yyvsp[0].nd)); } -#line 8729 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8858 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 420: -#line 3229 "mrbgems/mruby-compiler/core/parse.y" + case 423: +#line 3276 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 8737 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8866 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 423: -#line 3237 "mrbgems/mruby-compiler/core/parse.y" + case 426: +#line 3284 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8745 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8874 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 425: -#line 3244 "mrbgems/mruby-compiler/core/parse.y" + case 428: +#line 3291 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8753 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8882 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 432: -#line 3258 "mrbgems/mruby-compiler/core/parse.y" + case 435: +#line 3305 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = concat_string(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8761 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8890 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 435: -#line 3266 "mrbgems/mruby-compiler/core/parse.y" + case 438: +#line 3313 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8769 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8898 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 436: -#line 3270 "mrbgems/mruby-compiler/core/parse.y" + case 439: +#line 3317 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_dstr(p, push((yyvsp[-1].nd), (yyvsp[0].nd))); + node *n = (yyvsp[-1].nd); + if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { + n = push(n, (yyvsp[0].nd)); + } + else { + cons_free((yyvsp[0].nd)); + } + (yyval.nd) = new_dstr(p, n); } -#line 8777 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8913 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 438: -#line 3277 "mrbgems/mruby-compiler/core/parse.y" + case 441: +#line 3331 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = append((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8785 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8921 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 439: -#line 3283 "mrbgems/mruby-compiler/core/parse.y" + case 442: +#line 3337 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 8793 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8929 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 440: -#line 3287 "mrbgems/mruby-compiler/core/parse.y" + case 443: +#line 3341 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = p->lex_strterm; p->lex_strterm = NULL; } -#line 8802 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8938 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 441: -#line 3293 "mrbgems/mruby-compiler/core/parse.y" + case 444: +#line 3347 "mrbgems/mruby-compiler/core/parse.y" { p->lex_strterm = (yyvsp[-2].nd); (yyval.nd) = list2((yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 8811 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8947 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 442: -#line 3298 "mrbgems/mruby-compiler/core/parse.y" + case 445: +#line 3352 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 8819 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8955 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 443: -#line 3302 "mrbgems/mruby-compiler/core/parse.y" + case 446: +#line 3356 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 8827 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8963 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 444: -#line 3308 "mrbgems/mruby-compiler/core/parse.y" + case 447: +#line 3362 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8835 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8971 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 445: -#line 3312 "mrbgems/mruby-compiler/core/parse.y" + case 448: +#line 3366 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_dxstr(p, push((yyvsp[-1].nd), (yyvsp[0].nd))); + node *n = (yyvsp[-1].nd); + if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { + n = push(n, (yyvsp[0].nd)); + } + else { + cons_free((yyvsp[0].nd)); + } + (yyval.nd) = new_dxstr(p, n); } -#line 8843 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8986 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 446: -#line 3318 "mrbgems/mruby-compiler/core/parse.y" + case 449: +#line 3379 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8851 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8994 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 447: -#line 3322 "mrbgems/mruby-compiler/core/parse.y" + case 450: +#line 3383 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dregx(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8859 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9002 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 451: -#line 3335 "mrbgems/mruby-compiler/core/parse.y" + case 454: +#line 3396 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info * inf = parsing_heredoc_inf(p); inf->doc = push(inf->doc, new_str(p, "", 0)); heredoc_end(p); } -#line 8869 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9012 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 452: -#line 3341 "mrbgems/mruby-compiler/core/parse.y" + case 455: +#line 3402 "mrbgems/mruby-compiler/core/parse.y" { heredoc_end(p); } -#line 8877 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9020 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 455: -#line 3351 "mrbgems/mruby-compiler/core/parse.y" + case 458: +#line 3412 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info * inf = parsing_heredoc_inf(p); inf->doc = push(inf->doc, (yyvsp[0].nd)); heredoc_treat_nextline(p); } -#line 8887 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9030 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 456: -#line 3357 "mrbgems/mruby-compiler/core/parse.y" + case 459: +#line 3418 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = p->lex_strterm; p->lex_strterm = NULL; } -#line 8896 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9039 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 457: -#line 3363 "mrbgems/mruby-compiler/core/parse.y" + case 460: +#line 3424 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info * inf = parsing_heredoc_inf(p); p->lex_strterm = (yyvsp[-2].nd); inf->doc = push(push(inf->doc, (yyvsp[-3].nd)), (yyvsp[-1].nd)); } -#line 8906 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9049 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 458: -#line 3371 "mrbgems/mruby-compiler/core/parse.y" + case 461: +#line 3432 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_words(p, list1((yyvsp[0].nd))); } -#line 8914 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9057 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 459: -#line 3375 "mrbgems/mruby-compiler/core/parse.y" + case 462: +#line 3436 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_words(p, push((yyvsp[-1].nd), (yyvsp[0].nd))); + node *n = (yyvsp[-1].nd); + if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { + n = push(n, (yyvsp[0].nd)); + } + else { + cons_free((yyvsp[0].nd)); + } + (yyval.nd) = new_words(p, n); } -#line 8922 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9072 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 460: -#line 3382 "mrbgems/mruby-compiler/core/parse.y" + case 463: +#line 3450 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDARG; (yyval.nd) = new_sym(p, (yyvsp[0].id)); } -#line 8931 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9081 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 461: -#line 3387 "mrbgems/mruby-compiler/core/parse.y" + case 464: +#line 3455 "mrbgems/mruby-compiler/core/parse.y" { + node *n = (yyvsp[-1].nd); p->lstate = EXPR_ENDARG; - (yyval.nd) = new_dsym(p, new_dstr(p, push((yyvsp[-1].nd), (yyvsp[0].nd)))); + if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { + n = push(n, (yyvsp[0].nd)); + } + else { + cons_free((yyvsp[0].nd)); + } + (yyval.nd) = new_dsym(p, new_dstr(p, n)); } -#line 8940 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9097 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 462: -#line 3394 "mrbgems/mruby-compiler/core/parse.y" + case 465: +#line 3469 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 8948 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9105 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 467: -#line 3404 "mrbgems/mruby-compiler/core/parse.y" + case 470: +#line 3479 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 8956 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9113 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 468: -#line 3408 "mrbgems/mruby-compiler/core/parse.y" + case 471: +#line 3483 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 8964 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9121 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 469: -#line 3414 "mrbgems/mruby-compiler/core/parse.y" + case 472: +#line 3489 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_symbols(p, list1((yyvsp[0].nd))); } -#line 8972 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9129 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 470: -#line 3418 "mrbgems/mruby-compiler/core/parse.y" + case 473: +#line 3493 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_symbols(p, push((yyvsp[-1].nd), (yyvsp[0].nd))); + node *n = (yyvsp[-1].nd); + if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { + n = push(n, (yyvsp[0].nd)); + } + (yyval.nd) = new_symbols(p, n); } -#line 8980 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9141 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 473: -#line 3426 "mrbgems/mruby-compiler/core/parse.y" + case 476: +#line 3505 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = negate_lit(p, (yyvsp[0].nd)); + (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 8988 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9149 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 474: -#line 3430 "mrbgems/mruby-compiler/core/parse.y" + case 477: +#line 3509 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = negate_lit(p, (yyvsp[0].nd)); + (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 8996 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9157 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 475: -#line 3436 "mrbgems/mruby-compiler/core/parse.y" + case 478: +#line 3515 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_lvar(p, (yyvsp[0].id)); } -#line 9004 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9165 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 476: -#line 3440 "mrbgems/mruby-compiler/core/parse.y" + case 479: +#line 3519 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_ivar(p, (yyvsp[0].id)); } -#line 9012 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9173 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 477: -#line 3444 "mrbgems/mruby-compiler/core/parse.y" + case 480: +#line 3523 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_gvar(p, (yyvsp[0].id)); } -#line 9020 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9181 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 478: -#line 3448 "mrbgems/mruby-compiler/core/parse.y" + case 481: +#line 3527 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_cvar(p, (yyvsp[0].id)); } -#line 9028 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9189 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 479: -#line 3452 "mrbgems/mruby-compiler/core/parse.y" + case 482: +#line 3531 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_const(p, (yyvsp[0].id)); } -#line 9036 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9197 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 480: -#line 3458 "mrbgems/mruby-compiler/core/parse.y" + case 483: +#line 3537 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 9044 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9205 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 481: -#line 3462 "mrbgems/mruby-compiler/core/parse.y" + case 484: +#line 3541 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 9052 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9213 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 482: -#line 3468 "mrbgems/mruby-compiler/core/parse.y" + case 485: +#line 3547 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = var_reference(p, (yyvsp[0].nd)); } -#line 9060 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9221 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 483: -#line 3472 "mrbgems/mruby-compiler/core/parse.y" + case 486: +#line 3551 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 9068 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9229 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 484: -#line 3476 "mrbgems/mruby-compiler/core/parse.y" + case 487: +#line 3555 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_self(p); } -#line 9076 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9237 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 485: -#line 3480 "mrbgems/mruby-compiler/core/parse.y" + case 488: +#line 3559 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_true(p); } -#line 9084 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9245 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 486: -#line 3484 "mrbgems/mruby-compiler/core/parse.y" + case 489: +#line 3563 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_false(p); } -#line 9092 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9253 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 487: -#line 3488 "mrbgems/mruby-compiler/core/parse.y" + case 490: +#line 3567 "mrbgems/mruby-compiler/core/parse.y" { const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); if (!fn) { @@ -9100,607 +9261,584 @@ yyreduce: } (yyval.nd) = new_str(p, fn, strlen(fn)); } -#line 9104 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9265 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 488: -#line 3496 "mrbgems/mruby-compiler/core/parse.y" + case 491: +#line 3575 "mrbgems/mruby-compiler/core/parse.y" { char buf[16]; dump_int(p->lineno, buf); (yyval.nd) = new_int(p, buf, 10, 0); } -#line 9115 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9276 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 489: -#line 3503 "mrbgems/mruby-compiler/core/parse.y" + case 492: +#line 3582 "mrbgems/mruby-compiler/core/parse.y" { -#ifdef MRB_UTF8_STRING - const char *enc = "UTF-8"; -#else - const char *enc = "ASCII-8BIT"; -#endif - (yyval.nd) = new_str(p, enc, strlen(enc)); + (yyval.nd) = new_fcall(p, MRB_SYM_2(p->mrb, __ENCODING__), 0); } -#line 9128 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9284 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 492: -#line 3518 "mrbgems/mruby-compiler/core/parse.y" + case 495: +#line 3592 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 9136 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9292 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 493: -#line 3522 "mrbgems/mruby-compiler/core/parse.y" + case 496: +#line 3596 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9145 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9301 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 494: -#line 3527 "mrbgems/mruby-compiler/core/parse.y" + case 497: +#line 3601 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9153 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9309 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 497: -#line 3543 "mrbgems/mruby-compiler/core/parse.y" + case 500: +#line 3617 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9163 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9319 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 498: -#line 3549 "mrbgems/mruby-compiler/core/parse.y" + case 501: +#line 3623 "mrbgems/mruby-compiler/core/parse.y" { -#if 1 - /* til real keyword args implemented */ - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - local_add_f(p, r); - (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, r, 0, - new_args_tail(p, 0, 0, b)); -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); - local_add_f(p, r); local_add_f(p, k); + local_add_f(p, r); (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); -#endif } -#line 9185 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9332 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 499: -#line 3567 "mrbgems/mruby-compiler/core/parse.y" + case 502: +#line 3632 "mrbgems/mruby-compiler/core/parse.y" { -#if 1 - /* til real keyword args implemented */ - mrb_sym r = intern_op(mul); - mrb_sym b = intern_op(and); - local_add_f(p, r); - (yyval.nd) = new_args(p, 0, 0, r, 0, - new_args_tail(p, 0, 0, b)); -#else mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); mrb_sym b = intern_op(and); - local_add_f(p, r); local_add_f(p, k); + local_add_f(p, r); (yyval.nd) = new_args(p, 0, 0, r, 0, new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); -#endif } -#line 9207 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9345 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 501: -#line 3588 "mrbgems/mruby-compiler/core/parse.y" + case 504: +#line 3644 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9215 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9353 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 502: -#line 3594 "mrbgems/mruby-compiler/core/parse.y" + case 505: +#line 3650 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); } -#line 9223 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9361 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 503: -#line 3600 "mrbgems/mruby-compiler/core/parse.y" + case 506: +#line 3656 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = new_kw_arg(p, (yyvsp[-1].id), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9233 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9371 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 504: -#line 3606 "mrbgems/mruby-compiler/core/parse.y" + case 507: +#line 3662 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9242 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9380 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 505: -#line 3613 "mrbgems/mruby-compiler/core/parse.y" + case 508: +#line 3669 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[-1].id), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9251 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9389 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 506: -#line 3618 "mrbgems/mruby-compiler/core/parse.y" + case 509: +#line 3674 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9260 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9398 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 507: -#line 3625 "mrbgems/mruby-compiler/core/parse.y" + case 510: +#line 3681 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9268 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9406 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 508: -#line 3629 "mrbgems/mruby-compiler/core/parse.y" + case 511: +#line 3685 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9276 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9414 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 509: -#line 3635 "mrbgems/mruby-compiler/core/parse.y" + case 512: +#line 3691 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9284 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9422 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 510: -#line 3639 "mrbgems/mruby-compiler/core/parse.y" + case 513: +#line 3695 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9292 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9430 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 513: -#line 3649 "mrbgems/mruby-compiler/core/parse.y" + case 516: +#line 3705 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, nsym((yyvsp[0].id))); } -#line 9300 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9438 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 514: -#line 3653 "mrbgems/mruby-compiler/core/parse.y" + case 517: +#line 3709 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, 0); } -#line 9308 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9446 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 515: -#line 3659 "mrbgems/mruby-compiler/core/parse.y" + case 518: +#line 3715 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9316 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9454 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 516: -#line 3663 "mrbgems/mruby-compiler/core/parse.y" + case 519: +#line 3719 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 9324 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9462 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 517: -#line 3667 "mrbgems/mruby-compiler/core/parse.y" + case 520: +#line 3723 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9470 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 518: -#line 3671 "mrbgems/mruby-compiler/core/parse.y" + case 521: +#line 3727 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 9340 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9478 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 519: -#line 3677 "mrbgems/mruby-compiler/core/parse.y" + case 522: +#line 3733 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9348 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9486 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 520: -#line 3681 "mrbgems/mruby-compiler/core/parse.y" + case 523: +#line 3737 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 9356 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9494 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 521: -#line 3687 "mrbgems/mruby-compiler/core/parse.y" + case 524: +#line 3743 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9364 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9502 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 522: -#line 3691 "mrbgems/mruby-compiler/core/parse.y" + case 525: +#line 3747 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9372 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9510 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 523: -#line 3695 "mrbgems/mruby-compiler/core/parse.y" + case 526: +#line 3751 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 9380 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9518 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 524: -#line 3699 "mrbgems/mruby-compiler/core/parse.y" + case 527: +#line 3755 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9388 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9526 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 525: -#line 3703 "mrbgems/mruby-compiler/core/parse.y" + case 528: +#line 3759 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9396 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9534 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 526: -#line 3707 "mrbgems/mruby-compiler/core/parse.y" + case 529: +#line 3763 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9404 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9542 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 527: -#line 3711 "mrbgems/mruby-compiler/core/parse.y" + case 530: +#line 3767 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 9412 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9550 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 528: -#line 3715 "mrbgems/mruby-compiler/core/parse.y" + case 531: +#line 3771 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9420 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9558 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 529: -#line 3719 "mrbgems/mruby-compiler/core/parse.y" + case 532: +#line 3775 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9428 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9566 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 530: -#line 3723 "mrbgems/mruby-compiler/core/parse.y" + case 533: +#line 3779 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 9436 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9574 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 531: -#line 3727 "mrbgems/mruby-compiler/core/parse.y" + case 534: +#line 3783 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9444 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9582 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 532: -#line 3731 "mrbgems/mruby-compiler/core/parse.y" + case 535: +#line 3787 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9452 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9590 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 533: -#line 3735 "mrbgems/mruby-compiler/core/parse.y" + case 536: +#line 3791 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9460 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9598 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 534: -#line 3739 "mrbgems/mruby-compiler/core/parse.y" + case 537: +#line 3795 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 9468 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9606 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 535: -#line 3743 "mrbgems/mruby-compiler/core/parse.y" + case 538: +#line 3799 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(and)); (yyval.nd) = new_args(p, 0, 0, 0, 0, 0); } -#line 9477 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9615 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 536: -#line 3750 "mrbgems/mruby-compiler/core/parse.y" + case 539: +#line 3806 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a constant"); (yyval.nd) = 0; } -#line 9486 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9624 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 537: -#line 3755 "mrbgems/mruby-compiler/core/parse.y" + case 540: +#line 3811 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be an instance variable"); (yyval.nd) = 0; } -#line 9495 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9633 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 538: -#line 3760 "mrbgems/mruby-compiler/core/parse.y" + case 541: +#line 3816 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a global variable"); (yyval.nd) = 0; } -#line 9504 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9642 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 539: -#line 3765 "mrbgems/mruby-compiler/core/parse.y" + case 542: +#line 3821 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a class variable"); (yyval.nd) = 0; } -#line 9513 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9651 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 540: -#line 3770 "mrbgems/mruby-compiler/core/parse.y" + case 543: +#line 3826 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a numbered parameter"); (yyval.nd) = 0; } -#line 9522 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9660 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 541: -#line 3777 "mrbgems/mruby-compiler/core/parse.y" + case 544: +#line 3833 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 9530 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9668 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 542: -#line 3781 "mrbgems/mruby-compiler/core/parse.y" + case 545: +#line 3837 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 9539 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9677 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 543: -#line 3788 "mrbgems/mruby-compiler/core/parse.y" + case 546: +#line 3844 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_arg(p, (yyvsp[0].id)); } -#line 9547 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9685 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 544: -#line 3792 "mrbgems/mruby-compiler/core/parse.y" + case 547: +#line 3848 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); } -#line 9555 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9693 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 545: -#line 3796 "mrbgems/mruby-compiler/core/parse.y" + case 548: +#line 3852 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn_param(p, (yyvsp[-1].nd), p->locals->car); local_resume(p, (yyvsp[-2].nd)); local_add_f(p, 0); } -#line 9565 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9703 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 546: -#line 3804 "mrbgems/mruby-compiler/core/parse.y" + case 549: +#line 3860 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9573 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9711 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 547: -#line 3808 "mrbgems/mruby-compiler/core/parse.y" + case 550: +#line 3864 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9581 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9719 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 548: -#line 3814 "mrbgems/mruby-compiler/core/parse.y" + case 551: +#line 3870 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[-1].id)); local_nest(p); (yyval.id) = (yyvsp[-1].id); } -#line 9591 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9729 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 549: -#line 3822 "mrbgems/mruby-compiler/core/parse.y" + case 552: +#line 3878 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(nsym((yyvsp[-1].id)), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9739 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 550: -#line 3830 "mrbgems/mruby-compiler/core/parse.y" + case 553: +#line 3886 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(nsym((yyvsp[-1].id)), cons((yyvsp[0].nd), locals_node(p))); local_unnest(p); } -#line 9611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9749 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 551: -#line 3838 "mrbgems/mruby-compiler/core/parse.y" + case 554: +#line 3894 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9757 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 552: -#line 3842 "mrbgems/mruby-compiler/core/parse.y" + case 555: +#line 3898 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9765 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 553: -#line 3848 "mrbgems/mruby-compiler/core/parse.y" + case 556: +#line 3904 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9635 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9773 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 554: -#line 3852 "mrbgems/mruby-compiler/core/parse.y" + case 557: +#line 3908 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9643 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9781 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 557: -#line 3862 "mrbgems/mruby-compiler/core/parse.y" + case 560: +#line 3918 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 9652 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9790 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 558: -#line 3867 "mrbgems/mruby-compiler/core/parse.y" + case 561: +#line 3923 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(mul)); (yyval.id) = -1; } -#line 9661 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9799 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 561: -#line 3878 "mrbgems/mruby-compiler/core/parse.y" + case 564: +#line 3934 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9669 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9807 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 562: -#line 3884 "mrbgems/mruby-compiler/core/parse.y" + case 565: +#line 3940 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9677 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9815 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 563: -#line 3888 "mrbgems/mruby-compiler/core/parse.y" + case 566: +#line 3944 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 9685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9823 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 564: -#line 3894 "mrbgems/mruby-compiler/core/parse.y" + case 567: +#line 3950 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 9694 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9832 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 565: -#line 3898 "mrbgems/mruby-compiler/core/parse.y" + case 568: +#line 3954 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_BEG;} -#line 9700 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9838 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 566: -#line 3899 "mrbgems/mruby-compiler/core/parse.y" + case 569: +#line 3955 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-1].nd) == 0) { yyerror(p, "can't define singleton method for ()."); @@ -9723,55 +9861,63 @@ yyreduce: } (yyval.nd) = (yyvsp[-1].nd); } -#line 9727 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9865 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 568: -#line 3925 "mrbgems/mruby-compiler/core/parse.y" + case 571: +#line 3981 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9735 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9873 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 569: -#line 3931 "mrbgems/mruby-compiler/core/parse.y" + case 572: +#line 3987 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 9744 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9882 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 570: -#line 3936 "mrbgems/mruby-compiler/core/parse.y" + case 573: +#line 3992 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9752 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9890 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 573: -#line 3946 "mrbgems/mruby-compiler/core/parse.y" + case 574: +#line 3998 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9762 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9900 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 574: -#line 3952 "mrbgems/mruby-compiler/core/parse.y" + case 575: +#line 4004 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(new_sym(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 9771 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9909 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 575: -#line 3957 "mrbgems/mruby-compiler/core/parse.y" + case 576: +#line 4009 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = cons(new_sym(p, (yyvsp[-1].id)), label_reference(p, (yyvsp[-1].id))); + } +#line 9917 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 577: +#line 4013 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); if (typen((yyvsp[-2].nd)->car) == NODE_DSTR) { @@ -9781,67 +9927,67 @@ yyreduce: (yyval.nd) = cons(new_sym(p, new_strsym(p, (yyvsp[-2].nd))), (yyvsp[0].nd)); } } -#line 9785 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9931 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 576: -#line 3967 "mrbgems/mruby-compiler/core/parse.y" + case 578: +#line 4023 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(new_kw_rest_args(p, 0), (yyvsp[0].nd)); } -#line 9794 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9940 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 589: -#line 3994 "mrbgems/mruby-compiler/core/parse.y" + case 591: +#line 4050 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = '.'; } -#line 9802 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9948 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 590: -#line 3998 "mrbgems/mruby-compiler/core/parse.y" + case 592: +#line 4054 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = 0; } -#line 9810 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9956 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 592: -#line 4005 "mrbgems/mruby-compiler/core/parse.y" + case 594: +#line 4061 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = tCOLON2; } -#line 9818 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9964 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 601: -#line 4026 "mrbgems/mruby-compiler/core/parse.y" + case 603: +#line 4082 "mrbgems/mruby-compiler/core/parse.y" {yyerrok;} -#line 9824 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9970 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 604: -#line 4032 "mrbgems/mruby-compiler/core/parse.y" + case 605: +#line 4087 "mrbgems/mruby-compiler/core/parse.y" { p->lineno += (yyvsp[0].num); p->column = 0; } -#line 9833 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9979 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 607: -#line 4043 "mrbgems/mruby-compiler/core/parse.y" + case 609: +#line 4099 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 9841 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9987 "mrbgems/mruby-compiler/core/y.tab.c" break; -#line 9845 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9991 "mrbgems/mruby-compiler/core/y.tab.c" default: break; } @@ -10073,7 +10219,7 @@ yyreturn: #endif return yyresult; } -#line 4047 "mrbgems/mruby-compiler/core/parse.y" +#line 4103 "mrbgems/mruby-compiler/core/parse.y" #define pylval (*((YYSTYPE*)(p->ylval))) @@ -10117,7 +10263,7 @@ yyerror_c(parser_state *p, const char *msg, char c) } static void -yywarn(parser_state *p, const char *s) +yywarning(parser_state *p, const char *s) { char* c; size_t n; @@ -10145,12 +10291,6 @@ yywarn(parser_state *p, const char *s) } static void -yywarning(parser_state *p, const char *s) -{ - yywarn(p, s); -} - -static void yywarning_s(parser_state *p, const char *msg, const char *s) { char buf[256]; @@ -12255,10 +12395,10 @@ parser_yylex(parser_state *p) if (last_state == EXPR_FNAME) goto gvar; tokfix(p); { - unsigned long n = strtoul(tok(p), NULL, 10); - if (n > INT_MAX) { - yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX)); - return 0; + mrb_int n = mrb_int_read(tok(p), NULL, NULL); + if (n > INT32_MAX) { + yywarning(p, "capture group index too big; always nil"); + return keyword_nil; } pylval.nd = new_nth_ref(p, (int)n); } @@ -12543,6 +12683,7 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt) int i = 0; if (!cxt) return; + if (!p->tree) return; if (intn(p->tree->car) != NODE_SCOPE) return; n0 = n = p->tree->cdr->car; while (n) { @@ -12563,53 +12704,39 @@ MRB_API void mrb_parser_parse(parser_state *p, mrbc_context *c) { struct mrb_jmpbuf buf1; - p->jmp = &buf1; + struct mrb_jmpbuf *prev = p->mrb->jmp; + p->mrb->jmp = &buf1; - MRB_TRY(p->jmp) { + MRB_TRY(p->mrb->jmp) { int n = 1; p->cmd_start = TRUE; p->in_def = p->in_single = 0; p->nerr = p->nwarn = 0; p->lex_strterm = NULL; - parser_init_cxt(p, c); - if (p->mrb->jmp) { - n = yyparse(p); - } - else { - struct mrb_jmpbuf buf2; - - p->mrb->jmp = &buf2; - MRB_TRY(p->mrb->jmp) { - n = yyparse(p); - } - MRB_CATCH(p->mrb->jmp) { - p->nerr++; - } - MRB_END_EXC(p->mrb->jmp); - p->mrb->jmp = 0; - } + n = yyparse(p); if (n != 0 || p->nerr > 0) { p->tree = 0; + p->mrb->jmp = prev; return; } - if (!p->tree) { - p->tree = new_nil(p); - } parser_update_cxt(p, c); if (c && c->dump_result) { mrb_parser_dump(p->mrb, p->tree, 0); } } - MRB_CATCH(p->jmp) { - yyerror(p, "memory allocation error"); + MRB_CATCH(p->mrb->jmp) { p->nerr++; - p->tree = 0; - return; + if (p->mrb->exc == NULL) { + yyerror(p, "memory allocation error"); + p->nerr++; + p->tree = 0; + } } MRB_END_EXC(p->jmp); + p->mrb->jmp = prev; } MRB_API parser_state* @@ -12994,8 +13121,13 @@ dump_args(mrb_state *mrb, node *n, int offset) } n = n->cdr; if (n->car) { + mrb_sym rest = sym(n->car); + dump_prefix(n, offset+1); - printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car))); + if (rest == MRB_OPSYM(mul)) + printf("rest=*\n"); + else + printf("rest=*%s\n", mrb_sym_name(mrb, rest)); } n = n->cdr; if (n->car) { @@ -13272,9 +13404,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) printf("args:\n"); dump_recur(mrb, tree->car, offset+2); if (tree->cdr) { - dump_prefix(tree, offset+1); - printf("block:\n"); - mrb_parser_dump(mrb, tree->cdr, offset+2); + if (tree->cdr->car) { + dump_prefix(tree, offset+1); + printf("kwargs:\n"); + mrb_parser_dump(mrb, tree->cdr->car, offset+2); + } + if (tree->cdr->cdr) { + dump_prefix(tree, offset+1); + printf("block:\n"); + mrb_parser_dump(mrb, tree->cdr->cdr, offset+2); + } } } break; @@ -13415,7 +13554,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_ZSUPER: - printf("NODE_ZSUPER\n"); + printf("NODE_ZSUPER:\n"); + if (tree) { + dump_prefix(tree, offset+1); + printf("args:\n"); + dump_recur(mrb, tree->car, offset+2); + if (tree->cdr) { + dump_prefix(tree, offset+1); + printf("block:\n"); + mrb_parser_dump(mrb, tree->cdr, offset+2); + } + } break; case NODE_RETURN: @@ -13741,7 +13890,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_KW_REST_ARGS: - printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree))); + if (tree) + printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree))); + else + printf("NODE_KW_REST_ARGS\n"); break; default: @@ -13750,3 +13902,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } #endif } + +typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sym, void *user); +void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user); + +void +mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user) +{ + const mrb_ast_node *n = p->tree; + if ((intptr_t)n->car == NODE_SCOPE) { + n = n->cdr->car; + for (; n; n = n->cdr) { + mrb_sym sym = sym(n->car); + if (sym && !func(mrb, sym, user)) break; + } + } +} diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index fe66e0e37..66176c3c1 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -2,7 +2,6 @@ #include <mruby/class.h> #include <mruby/numeric.h> #include <mruby/presym.h> -#include <math.h> #ifdef MRB_NO_FLOAT # error Complex conflicts with 'MRB_NO_FLOAT' configuration @@ -50,7 +49,7 @@ static struct RBasic* complex_alloc(mrb_state *mrb, struct RClass *c, struct mrb_complex **p) { struct RComplex *s; - s = (struct RComplex*)mrb_obj_alloc(mrb, MRB_TT_COMPLEX, c); + s = MRB_OBJ_ALLOC(mrb, MRB_TT_COMPLEX, c); #ifdef COMPLEX_INLINE *p = &s->r; #else @@ -184,7 +183,7 @@ complex_add(mrb_state *mrb, mrb_value x) default: { - mrb_float z = mrb_to_flo(mrb, y); + mrb_float z = mrb_as_float(mrb, y); return mrb_complex_new(mrb, p1->real+z, p1->imaginary); } } @@ -205,7 +204,7 @@ complex_sub(mrb_state *mrb, mrb_value x) default: { - mrb_float z = mrb_to_flo(mrb, y); + mrb_float z = mrb_as_float(mrb, y); return mrb_complex_new(mrb, p1->real-z, p1->imaginary); } } @@ -227,16 +226,12 @@ complex_mul(mrb_state *mrb, mrb_value x) default: { - mrb_float z = mrb_to_flo(mrb, y); + mrb_float z = mrb_as_float(mrb, y); return mrb_complex_new(mrb, p1->real*z, p1->imaginary*z); } } } -#ifndef MRB_NO_FLOAT -mrb_float mrb_div_flo(mrb_float, mrb_float); -#endif - /* Arithmetic on (significand, exponent) pairs avoids premature overflow in complex division */ struct float_pair { @@ -273,7 +268,7 @@ static void div_pair(struct float_pair *q, struct float_pair const *a, struct float_pair const *b) { - q->s = mrb_div_flo(a->s, b->s); + q->s = mrb_div_float(a->s, b->s); q->x = a->x - b->x; } @@ -285,8 +280,8 @@ complex_div(mrb_state *mrb, mrb_value self) a = complex_ptr(mrb, self); if (mrb_type(rhs) != MRB_TT_COMPLEX) { - mrb_float f = mrb_to_flo(mrb, rhs); - return complex_new(mrb, mrb_div_flo(a->real, f), mrb_div_flo(a->imaginary, f)); + mrb_float f = mrb_as_float(mrb, rhs); + return complex_new(mrb, mrb_div_float(a->real, f), mrb_div_float(a->imaginary, f)); } struct float_pair ar, ai, br, bi; @@ -356,7 +351,7 @@ cpx_int_div(mrb_state *mrb, mrb_value x) x = complex_new(mrb, (mrb_float)a, 0); return complex_div(mrb, x); default: - return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y))); + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); } } @@ -381,7 +376,7 @@ cpx_int_quo(mrb_state *mrb, mrb_value x) x = complex_new(mrb, (mrb_float)a, 0); return complex_div(mrb, x); default: - return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y))); + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); } } @@ -395,10 +390,10 @@ cpx_flo_div(mrb_state *mrb, mrb_value x) case MRB_TT_COMPLEX: return complex_div(mrb, complex_new(mrb, a, 0)); case MRB_TT_FLOAT: - a = mrb_div_flo(a, mrb_float(y)); + a = mrb_div_float(a, mrb_float(y)); return mrb_float_value(mrb, a); default: - a = mrb_div_flo(a, mrb_to_flo(mrb, y)); + a = mrb_div_float(a, mrb_as_float(mrb, y)); return mrb_float_value(mrb, a); } } @@ -429,10 +424,10 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) mrb_define_method(mrb, comp, "/", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "quo", complex_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "==", complex_eq, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->integer_class, "/", cpx_int_div, MRB_ARGS_REQ(1)); /* overrride */ - mrb_define_method(mrb, mrb->integer_class, "quo", cpx_int_quo, MRB_ARGS_REQ(1)); /* overrride */ - mrb_define_method(mrb, mrb->float_class, "/", cpx_flo_div, MRB_ARGS_REQ(1)); /* overrride */ - mrb_define_method(mrb, mrb->float_class, "quo", cpx_flo_div, MRB_ARGS_REQ(1)); /* overrride */ + mrb_define_method(mrb, mrb->integer_class, "/", cpx_int_div, MRB_ARGS_REQ(1)); /* override */ + mrb_define_method(mrb, mrb->integer_class, "quo", cpx_int_quo, MRB_ARGS_REQ(1)); /* override */ + mrb_define_method(mrb, mrb->float_class, "/", cpx_flo_div, MRB_ARGS_REQ(1)); /* override */ + mrb_define_method(mrb, mrb->float_class, "quo", cpx_flo_div, MRB_ARGS_REQ(1)); /* override */ } void diff --git a/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mrbgems/mruby-enumerator/mrblib/enumerator.rb index f007b8553..58efceb17 100644 --- a/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ b/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -89,7 +89,7 @@ class Enumerator include Enumerable ## - # @overload initialize(obj, method = :each, *args) + # @overload initialize(obj, method = :each, *args, **kwd) # # Creates a new Enumerator object, which can be used as an # Enumerable. @@ -114,7 +114,7 @@ class Enumerator # # Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum # instead. - def initialize(obj=NONE, meth=:each, *args, &block) + def initialize(obj=NONE, meth=:each, *args, **kwd, &block) if block obj = Generator.new(&block) elsif obj == NONE @@ -124,6 +124,7 @@ class Enumerator @obj = obj @meth = meth @args = args + @kwd = kwd @fib = nil @dst = nil @lookahead = nil @@ -131,7 +132,7 @@ class Enumerator @stop_exc = false end - attr_accessor :obj, :meth, :args + attr_accessor :obj, :meth, :args, :kwd attr_reader :fib def initialize_copy(obj) @@ -140,6 +141,7 @@ class Enumerator @obj = obj.obj @meth = obj.meth @args = obj.args + @kwd = obj.kwd @fib = nil @lookahead = nil @feedvalue = nil @@ -286,7 +288,7 @@ class Enumerator end def enumerator_block_call(&block) - @obj.__send__ @meth, *@args, &block + @obj.__send__ @meth, *@args, **@kwd, &block end private :enumerator_block_call @@ -631,7 +633,7 @@ module Kernel # def repeat(n) # raise ArgumentError, "#{n} is negative!" if n < 0 # unless block_given? - # return to_enum(__method__, n) # __method__ is :repeat here + # return to_enum(__callee__, n) do # __callee__ is :repeat here # end # each do |*val| # n.times { yield *val } diff --git a/mrbgems/mruby-error/src/exception.c b/mrbgems/mruby-error/src/exception.c index ca26b8819..ffa7d53bf 100644 --- a/mrbgems/mruby-error/src/exception.c +++ b/mrbgems/mruby-error/src/exception.c @@ -31,7 +31,7 @@ mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_gc_arena_restore(mrb, ai); mrb_gc_protect(mrb, result); if (error) { - mrb_exc_raise(mrb, result); /* rethrow catched exceptions */ + mrb_exc_raise(mrb, result); /* rethrow caught exceptions */ } return result; } diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 508f5ffcb..13dd3ea4c 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -9,10 +9,10 @@ #include <mruby/variable.h> struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc); -mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook); +mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p); mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self); +mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); void mrb_codedump_all(mrb_state*, struct RProc*); -void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); static struct RProc* create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) @@ -52,10 +52,19 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi e = NULL; } + if (file) { + if (strlen(file) >= UINT16_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "filename too long"); + } + } + else { + file = "(eval)"; + } + cxt = mrbc_context_new(mrb); cxt->lineno = (uint16_t)line; - mrbc_filename(mrb, cxt, file ? file : "(eval)"); + mrbc_filename(mrb, cxt, file); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; cxt->upper = scope && MRB_PROC_CFUNC_P(scope) ? NULL : scope; @@ -64,6 +73,7 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi /* only occur when memory ran out */ if (!p) { + mrbc_context_free(mrb, cxt); mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state (out of memory)"); } @@ -71,6 +81,11 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi /* parse error */ mrb_value str; + mrbc_context_free(mrb, cxt); + if (!p->error_buffer[0].message) { + mrb_parser_free(p); + mrb_raise(mrb, E_SYNTAX_ERROR, "compile error"); + } if (file) { str = mrb_format(mrb, "file %s line %d: %s", file, @@ -83,7 +98,6 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi p->error_buffer[0].message); } mrb_parser_free(p); - mrbc_context_free(mrb, cxt); mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); } @@ -127,44 +141,14 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi } static mrb_value -exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc, mrb_func_t posthook) +exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) { /* no argument passed from eval() */ - mrb->c->ci->argc = 0; + mrb->c->ci->n = 0; + mrb->c->ci->nk = 0; /* clear block */ mrb->c->ci->stack[1] = mrb_nil_value(); - return mrb_exec_irep(mrb, self, proc, posthook); -} - -static void -eval_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack) -{ - mrb_assert(mrb->c->stend >= stack + num); - mrb_proc_merge_lvar(mrb, irep, env, num, lv, stack); -} - -static mrb_value -eval_merge_lvar_hook(mrb_state *mrb, mrb_value dummy_self) -{ - const mrb_callinfo *orig_ci = &mrb->c->ci[1]; - const struct RProc *orig_proc = orig_ci->proc; - const mrb_irep *orig_irep = orig_proc->body.irep; - int orig_nlocals = orig_irep->nlocals; - - if (orig_nlocals > 1) { - struct RProc *proc = (struct RProc *)orig_proc->upper; - struct REnv *env = MRB_PROC_ENV(orig_proc); - eval_merge_lvar(mrb, (mrb_irep *)proc->body.irep, env, - orig_nlocals - 1, orig_irep->lv, - mrb->c->ci->stack + 3 /* hook proc + exc + ret val */); - } - - mrb_value exc = mrb->c->ci->stack[1]; - if (!mrb_nil_p(exc)) { - mrb_exc_raise(mrb, exc); - } - - return mrb->c->ci->stack[2]; + return mrb_exec_irep(mrb, self, proc); } static mrb_value @@ -176,30 +160,21 @@ f_eval(mrb_state *mrb, mrb_value self) const char *file = NULL; mrb_int line = 1; struct RProc *proc; - mrb_func_t posthook = NULL; mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line); proc = create_proc_from_string(mrb, s, len, binding, file, line); if (!mrb_nil_p(binding)) { self = mrb_iv_get(mrb, binding, MRB_SYM(recv)); - if (mrb_env_p(mrb_iv_get(mrb, binding, MRB_SYM(env)))) { - posthook = eval_merge_lvar_hook; - } } mrb_assert(!MRB_PROC_CFUNC_P(proc)); - return exec_irep(mrb, self, proc, posthook); + return exec_irep(mrb, self, proc); } static mrb_value f_instance_eval(mrb_state *mrb, mrb_value self) { - mrb_value b; - mrb_int argc; const mrb_value *argv; - - mrb_get_args(mrb, "*!&", &argv, &argc, &b); - - if (mrb_nil_p(b)) { + if (!mrb_block_given_p(mrb)) { const char *s; mrb_int len; const char *file = NULL; @@ -213,19 +188,44 @@ f_instance_eval(mrb_state *mrb, mrb_value self) MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv)); mrb_assert(!MRB_PROC_CFUNC_P(proc)); mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(cv)); - return exec_irep(mrb, self, proc, NULL); + return exec_irep(mrb, self, proc); } else { - mrb_get_args(mrb, "&", &b); + mrb_get_args(mrb, ""); return mrb_obj_instance_eval(mrb, self); } } +static mrb_value +f_class_eval(mrb_state *mrb, mrb_value self) +{ + if (!mrb_block_given_p(mrb)) { + const char *s; + mrb_int len; + const char *file = NULL; + mrb_int line = 1; + struct RProc *proc; + + mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); + proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); + MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(self)); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(self)); + return exec_irep(mrb, self, proc); + } + else { + mrb_get_args(mrb, ""); + return mrb_mod_module_eval(mrb, self); + } +} + void mrb_mruby_eval_gem_init(mrb_state* mrb) { mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3)); mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), MRB_SYM(instance_eval), f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(module_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(class_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); } void diff --git a/mrbgems/mruby-eval/test/eval.rb b/mrbgems/mruby-eval/test/eval.rb index e95171223..7e28ade07 100644 --- a/mrbgems/mruby-eval/test/eval.rb +++ b/mrbgems/mruby-eval/test/eval.rb @@ -151,3 +151,14 @@ assert('Access numbered parameter from eval') do hoge.fuga(3) { _1 + eval("_1") } } end + +assert('Module#class_eval with string') do + c = Class.new + c.class_eval "def foo() 42; end" + cc = c.new + assert_true cc.respond_to?(:foo) + assert_equal 42, c.new.foo + + b = c.class_eval("class A; def a; 55; end; end; class B; def b; A; end; end; B") + assert_equal 55, b.new.b.new.a +end diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 5f45bf04f..0d85bedad 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -7,7 +7,8 @@ #define FIBER_STACK_INIT_SIZE 64 #define FIBER_CI_INIT_SIZE 8 -#define CI_ACC_RESUMED -3 +/* copied from vm.c */ +#define CINFO_RESUMED 3 /* * call-seq: @@ -94,7 +95,6 @@ fiber_init(mrb_state *mrb, mrb_value self) c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value)); c->stend = c->stbase + slen; -#ifdef MRB_NAN_BOXING { mrb_value *p = c->stbase; mrb_value *pend = c->stend; @@ -104,9 +104,6 @@ fiber_init(mrb_state *mrb, mrb_value self) p++; } } -#else - memset(c->stbase, 0, slen * sizeof(mrb_value)); -#endif /* copy receiver from a block */ c->stbase[0] = mrb->c->ci->stack[0]; @@ -160,7 +157,7 @@ fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c) mrb_callinfo *ci; for (ci = c->ci; ci >= c->cibase; ci--) { - if (ci->acc < 0) { + if (ci->cci > 0) { mrb_raise(mrb, E_FIBER_ERROR, "can't cross C function boundary"); } } @@ -220,13 +217,13 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr if (vmexec) { c->ci--; /* pop dummy callinfo */ } - c->cibase->argc = (int)len; + c->cibase->n = len; value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; } else { value = fiber_result(mrb, a, len); if (vmexec) { - c->ci->stack[c->ci[1].acc] = value; + c->ci[1].stack[0] = value; } } @@ -264,7 +261,7 @@ fiber_resume(mrb_state *mrb, mrb_value self) mrb_bool vmexec = FALSE; mrb_get_args(mrb, "*!", &a, &len); - if (mrb->c->ci->acc < 0) { + if (mrb->c->ci->cci > 0) { vmexec = TRUE; } return fiber_switch(mrb, self, len, a, TRUE, vmexec); @@ -357,7 +354,7 @@ mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a) c->prev = NULL; if (c->vmexec) { c->vmexec = FALSE; - mrb->c->ci->acc = CI_ACC_RESUMED; + mrb->c->ci->cci = CINFO_RESUMED; c->ci--; /* pop callinfo for yield */ } MARK_CONTEXT_MODIFY(mrb->c); @@ -397,7 +394,7 @@ static mrb_value fiber_current(mrb_state *mrb, mrb_value self) { if (!mrb->c->fib) { - struct RFiber *f = (struct RFiber*)mrb_obj_alloc(mrb, MRB_TT_FIBER, mrb_class_ptr(self)); + struct RFiber *f = MRB_OBJ_ALLOC(mrb, MRB_TT_FIBER, mrb_class_ptr(self)); f->cxt = mrb->c; mrb->c->fib = f; diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb index 33e2dcb9f..5775913c3 100644 --- a/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -116,7 +116,6 @@ class Hash nk.each {|k| h[k] = self[k] } - h self.replace(h) end @@ -256,7 +255,6 @@ class Hash def keep_if(&block) return to_enum :keep_if unless block - keys = [] self.each do |k, v| unless block.call([k, v]) self.delete(k) diff --git a/mrbgems/mruby-io/README.md b/mrbgems/mruby-io/README.md index a518e6169..c07a6e89b 100644 --- a/mrbgems/mruby-io/README.md +++ b/mrbgems/mruby-io/README.md @@ -1,5 +1,4 @@ -mruby-io -======== +# mruby-io `IO` and `File` classes for mruby diff --git a/mrbgems/mruby-io/mrblib/io.rb b/mrbgems/mruby-io/mrblib/io.rb index 645733226..9192d7bf2 100644 --- a/mrbgems/mruby-io/mrblib/io.rb +++ b/mrbgems/mruby-io/mrblib/io.rb @@ -26,11 +26,11 @@ class IO end end - def self.popen(command, mode = 'r', opts={}, &block) + def self.popen(command, mode = 'r', **opts, &block) if !self.respond_to?(:_popen) raise NotImplementedError, "popen is not supported on this platform" end - io = self._popen(command, mode, opts) + io = self._popen(command, mode, **opts) return io unless block begin @@ -61,39 +61,14 @@ class IO end end - def self.read(path, length=nil, offset=nil, opt=nil) - if not opt.nil? # 4 arguments - offset ||= 0 - elsif not offset.nil? # 3 arguments - if offset.is_a? Hash - opt = offset - offset = 0 - else - opt = {} - end - elsif not length.nil? # 2 arguments - if length.is_a? Hash - opt = length - offset = 0 - length = nil - else - offset = 0 - opt = {} - end - else # only 1 argument - opt = {} - offset = 0 - length = nil - end - + def self.read(path, length=nil, offset=0, mode: "r") str = "" fd = -1 io = nil begin if path[0] == "|" - io = IO.popen(path[1..-1], (opt[:mode] || "r")) + io = IO.popen(path[1..-1], mode) else - mode = opt[:mode] || "r" fd = IO.sysopen(path, mode) io = IO.open(fd, mode) end @@ -209,7 +184,7 @@ class IO end array = [] - while 1 + while true begin _read_buf rescue EOFError @@ -256,7 +231,7 @@ class IO end array = [] - while 1 + while true begin _read_buf rescue EOFError diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index 03a6a070d..fe7861798 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -14,7 +14,6 @@ #include <sys/stat.h> #include <fcntl.h> -#include <limits.h> #include <errno.h> #include <stdlib.h> @@ -89,7 +88,7 @@ flock(int fd, int operation) { DWORD flags; flags = ((operation & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0) | ((operation & LOCK_SH) ? LOCKFILE_EXCLUSIVE_LOCK : 0); - memset(&ov, 0, sizeof(ov)); + ov = (OVERLAPPED){0}; return LockFileEx(h, flags, 0, 0xffffffff, 0xffffffff, &ov) ? 0 : -1; } #endif @@ -117,14 +116,14 @@ static mrb_value mrb_file_s_unlink(mrb_state *mrb, mrb_value obj) { const mrb_value *argv; - mrb_value pathv; mrb_int argc, i; char *path; mrb_get_args(mrb, "*", &argv, &argc); for (i = 0; i < argc; i++) { const char *utf8_path; - pathv = mrb_ensure_string_type(mrb, argv[i]); + mrb_value pathv = argv[i]; + mrb_ensure_string_type(mrb, pathv); utf8_path = RSTRING_CSTR(mrb, pathv); path = mrb_locale_from_utf8(utf8_path, -1); if (UNLINK(path) < 0) { @@ -497,7 +496,7 @@ mrb_file_truncate(mrb_state *mrb, mrb_value self) mrb_value lenv = mrb_get_arg1(mrb); fd = mrb_io_fileno(mrb, self); - length = mrb_int(mrb, lenv); + length = mrb_as_int(mrb, lenv); if (mrb_ftruncate(fd, length) != 0) { mrb_raise(mrb, E_IO_ERROR, "ftruncate failed"); } diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 234d7b1fc..8261cf998 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -169,7 +169,7 @@ mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode) } else { int flags = 0; - mrb_int flags0 = mrb_int(mrb, mode); + mrb_int flags0 = mrb_as_int(mrb, mode); switch (flags0 & MRB_O_ACCMODE) { case MRB_O_RDONLY: @@ -363,7 +363,7 @@ mrb_io_s_popen_args(mrb_state *mrb, mrb_value klass, NULL, }; - mrb_get_args(mrb, "z|o:", cmd, &mode, &kw); + mrb_get_args(mrb, "zo:", cmd, &mode, &kw); *flags = mrb_io_mode_to_flags(mrb, mode); *doexec = (strcmp("-", *cmd) != 0); @@ -397,6 +397,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) ofd[0] = INVALID_HANDLE_VALUE; ofd[1] = INVALID_HANDLE_VALUE; + mrb->c->ci->mid = 0; io = mrb_io_s_popen_args(mrb, klass, &cmd, &flags, &doexec, &opt_in, &opt_out, &opt_err); @@ -476,6 +477,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) int pw[2] = { -1, -1 }; int saved_errno; + mrb->c->ci->mid = 0; io = mrb_io_s_popen_args(mrb, klass, &cmd, &flags, &doexec, &opt_in, &opt_out, &opt_err); @@ -837,6 +839,7 @@ static mrb_value mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass) { mrb_int fd; + mrb->c->ci->mid = 0; mrb_get_args(mrb, "i", &fd); if (close((int)fd) == -1) { mrb_sys_fail(mrb, "close"); @@ -1415,7 +1418,7 @@ mrb_io_sync(mrb_state *mrb, mrb_value self) static off_t value2off(mrb_state *mrb, mrb_value offv) { - return (off_t)mrb_int(mrb, offv); + return (off_t)mrb_as_int(mrb, offv); } /* @@ -1475,6 +1478,7 @@ mrb_io_bufread(mrb_state *mrb, mrb_value self) mrb_value str; mrb_int len; + mrb->c->ci->mid = 0; mrb_get_args(mrb, "Si", &str, &len); mrb_assert(RSTRING_LEN(str) > 0); mrb_assert(RSTRING_PTR(str) != NULL); @@ -1491,6 +1495,7 @@ mrb_io_readchar(mrb_state *mrb, mrb_value self) unsigned char c; #endif + mrb->c->ci->mid = 0; mrb_get_args(mrb, "S", &buf); mrb_assert(RSTRING_LEN(buf) > 0); mrb_assert(RSTRING_PTR(buf) != NULL); diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 7afa6fa5f..5b3dd6b35 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -3,70 +3,73 @@ #include <mruby/array.h> #include <mruby/hash.h> #include <mruby/range.h> +#include <mruby/string.h> +#include <mruby/numeric.h> +#include <mruby/proc.h> #include <mruby/presym.h> static mrb_value mrb_f_caller(mrb_state *mrb, mrb_value self) { - mrb_value bt, v, length; + mrb_value bt, v; mrb_int bt_len, argc, lev, n; + argc = mrb_get_args(mrb, "|oi", &v, &n); + bt = mrb_get_backtrace(mrb); bt_len = RARRAY_LEN(bt); - argc = mrb_get_args(mrb, "|oo", &v, &length); switch (argc) { - case 0: - lev = 1; - n = bt_len - lev; - break; - case 1: - if (mrb_range_p(v)) { - mrb_int beg, len; - if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == MRB_RANGE_OK) { - lev = beg; - n = len; - } - else { - return mrb_nil_value(); - } + case 0: + lev = 1; + n = bt_len - 1; + break; + case 1: + if (mrb_range_p(v)) { + mrb_int beg, len; + if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == MRB_RANGE_OK) { + lev = beg; + n = len; } else { - lev = mrb_int(mrb, v); - if (lev < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v); - } - n = bt_len - lev; + return mrb_nil_value(); } - break; - case 2: - lev = mrb_int(mrb, v); - n = mrb_int(mrb, length); + } + else { + lev = mrb_as_int(mrb, v); if (lev < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v); } - if (n < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%v)", length); - } - break; - default: - lev = n = 0; - break; + n = bt_len - lev; + } + break; + case 2: + lev = mrb_as_int(mrb, v); + break; + default: + /* not reached */ + lev = n = 0; + break; } - - if (n == 0) { + if (lev >= bt_len) return mrb_nil_value(); + if (lev < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v); + } + if (n < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%d)", n); + } + if (n == 0 || bt_len <= lev) { return mrb_ary_new(mrb); } - - return mrb_funcall_id(mrb, bt, MRB_OPSYM(aref), 2, mrb_fixnum_value(lev), mrb_fixnum_value(n)); + if (bt_len <= n + lev) n = bt_len - lev - 1; + return mrb_ary_new_from_values(mrb, n, RARRAY_PTR(bt)+lev+1); } /* * call-seq: * __method__ -> symbol * - * Returns the name at the definition of the current method as a - * Symbol. + * Returns the called name of the current method as a Symbol. * If called outside of a method, it returns <code>nil</code>. * */ @@ -75,6 +78,27 @@ mrb_f_method(mrb_state *mrb, mrb_value self) { mrb_callinfo *ci = mrb->c->ci; ci--; + if (ci->proc->e.env->tt == MRB_TT_ENV && ci->proc->e.env->mid) + return mrb_symbol_value(ci->proc->e.env->mid); + else if (ci->mid) + return mrb_symbol_value(ci->mid); + else + return mrb_nil_value(); +} + +/* + * call-seq: + * __callee__ -> symbol + * + * Returns the called name of the current method as a Symbol. + * If called outside of a method, it returns <code>nil</code>. + * + */ +static mrb_value +mrb_f_callee(mrb_state *mrb, mrb_value self) +{ + mrb_callinfo *ci = mrb->c->ci; + ci--; if (ci->mid) return mrb_symbol_value(ci->mid); else @@ -106,11 +130,43 @@ mrb_f_method(mrb_state *mrb, mrb_value self) static mrb_value mrb_f_integer(mrb_state *mrb, mrb_value self) { - mrb_value arg; + mrb_value val, tmp; mrb_int base = 0; - mrb_get_args(mrb, "o|i", &arg, &base); - return mrb_convert_to_integer(mrb, arg, base); + mrb_get_args(mrb, "o|i", &val, &base); + if (mrb_nil_p(val)) { + if (base != 0) goto arg_error; + mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); + } + switch (mrb_type(val)) { +#ifndef MRB_NO_FLOAT + case MRB_TT_FLOAT: + if (base != 0) goto arg_error; + return mrb_float_to_integer(mrb, val); +#endif + + case MRB_TT_INTEGER: + if (base != 0) goto arg_error; + return val; + + case MRB_TT_STRING: + string_conv: + return mrb_str_to_integer(mrb, val, base, TRUE); + + default: + break; + } + if (base != 0) { + tmp = mrb_obj_as_string(mrb, val); + if (mrb_string_p(tmp)) { + val = tmp; + goto string_conv; + } +arg_error: + mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); + } + /* to raise TypeError */ + return mrb_to_integer(mrb, val); } #ifndef MRB_NO_FLOAT @@ -131,7 +187,7 @@ mrb_f_float(mrb_state *mrb, mrb_value self) { mrb_value arg = mrb_get_arg1(mrb); - return mrb_Float(mrb, arg); + return mrb_to_float(mrb, arg); } #endif @@ -201,7 +257,8 @@ mrb_f_hash(mrb_state *mrb, mrb_value self) if (mrb_nil_p(arg) || (mrb_array_p(arg) && RARRAY_LEN(arg) == 0)) { return mrb_hash_new(mrb); } - return mrb_ensure_hash_type(mrb, arg); + mrb_ensure_hash_type(mrb, arg); + return arg; } void @@ -212,6 +269,7 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb) mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2)); mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2)); mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE()); + mrb_define_method(mrb, krn, "__callee__", mrb_f_callee, MRB_ARGS_NONE()); mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ARG(1,1)); #ifndef MRB_NO_FLOAT mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1)); diff --git a/mrbgems/mruby-kernel-ext/test/kernel.rb b/mrbgems/mruby-kernel-ext/test/kernel.rb index fc4402b3d..e5876f976 100644 --- a/mrbgems/mruby-kernel-ext/test/kernel.rb +++ b/mrbgems/mruby-kernel-ext/test/kernel.rb @@ -38,17 +38,29 @@ assert('Kernel.caller, Kernel#caller') do end assert('Kernel#__method__') do - assert_equal(:m, Class.new {def m; __method__; end}.new.m) - assert_equal(:m, Class.new {define_method(:m) {__method__}}.new.m) c = Class.new do - [:m1, :m2].each do |m| - define_method(m) do - __method__ - end - end + def m1; __method__ end + define_method(:m2) {__method__} + alias m3 m1 + alias_method :m4, :m2 + end + assert_equal(:m1, c.new.m1) + assert_equal(:m2, c.new.m2) + assert_equal(:m1, c.new.m3) + assert_equal(:m2, c.new.m4) +end + +assert('Kernel#__callee__') do + c = Class.new do + def m1; __callee__ end + define_method(:m2) {__callee__} + alias m3 m1 + alias_method :m4, :m2 end assert_equal(:m1, c.new.m1) assert_equal(:m2, c.new.m2) + assert_equal(:m3, c.new.m3) + assert_equal(:m4, c.new.m4) end assert('Kernel#Integer') do diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index 0b85b1763..79fdb7c6f 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -12,7 +12,6 @@ #include <mruby/array.h> #include <mruby/presym.h> -#include <math.h> static void domain_error(mrb_state *mrb, const char *func) @@ -25,8 +24,6 @@ domain_error(mrb_state *mrb, const char *func) /* math functions not provided by Microsoft Visual C++ 2012 or older */ #if defined _MSC_VER && _MSC_VER <= 1700 -#include <float.h> - double asinh(double x) { diff --git a/mrbgems/mruby-metaprog/test/metaprog.rb b/mrbgems/mruby-metaprog/test/metaprog.rb index d63913020..4d2651702 100644 --- a/mrbgems/mruby-metaprog/test/metaprog.rb +++ b/mrbgems/mruby-metaprog/test/metaprog.rb @@ -104,6 +104,17 @@ assert('Kernel#global_variables', '15.3.1.3.14') do assert_equal(1, variables2.size - variables1.size) end +assert('Kernel#local_variables', '15.3.1.3.28') do + assert_equal Array, local_variables.class + + def local_var_list + a = "hello" + local_variables + end + + assert_equal [:a], local_var_list +end + assert('Kernel.local_variables', '15.3.1.2.7') do a, b = 0, 1 a += b diff --git a/mrbgems/mruby-method/README.md b/mrbgems/mruby-method/README.md index f299718df..41130bb82 100644 --- a/mrbgems/mruby-method/README.md +++ b/mrbgems/mruby-method/README.md @@ -1,5 +1,4 @@ -mruby-method -=== +# mruby-method An implementation of class **Method** and **UnboundMethod** for mruby diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index 02eddda9c..763bc5f7d 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -7,20 +7,21 @@ #include "mruby/presym.h" mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); -mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook); +mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p); static mrb_value args_shift(mrb_state *mrb) { - mrb_value *argv = mrb->c->ci->stack + 1; + mrb_callinfo *ci = mrb->c->ci; + mrb_value *argv = ci->stack + 1; - if (mrb->c->ci->argc > 0) { + if (ci->n < 15) { mrb_value obj = argv[0]; - memmove(argv, argv + 1, (mrb->c->ci->argc + 1 /* block */ - 1 /* first value */) * sizeof(mrb_value)); - mrb->c->ci->argc--; + memmove(argv, argv + 1, (ci->n + 1 /* block */ - 1 /* first value */) * sizeof(mrb_value)); + ci->n--; return obj; } - else if (mrb->c->ci->argc < 0 && RARRAY_LEN(*argv) > 0) { + else if (ci->n == 15 && RARRAY_LEN(*argv) > 0) { return mrb_ary_shift(mrb, *argv); } else { @@ -32,13 +33,14 @@ args_shift(mrb_state *mrb) static void args_unshift(mrb_state *mrb, mrb_value obj) { - mrb_value *argv = mrb->c->ci->stack + 1; + mrb_callinfo *ci = mrb->c->ci; + mrb_value *argv = ci->stack + 1; - if (mrb->c->ci->argc >= 0) { - mrb_value block = argv[mrb->c->ci->argc]; - argv[0] = mrb_ary_new_from_values(mrb, mrb->c->ci->argc, argv); + if (ci->n < 15) { + mrb_value block = argv[ci->n]; + argv[0] = mrb_ary_new_from_values(mrb, ci->n, argv); argv[1] = block; - mrb->c->ci->argc = -1; + ci->n = 15; } mrb_ary_unshift(mrb, *argv, obj); @@ -48,13 +50,14 @@ static struct RProc* method_missing_prepare(mrb_state *mrb, mrb_sym *mid, mrb_value recv, struct RClass **tc) { const mrb_sym id_method_missing = MRB_SYM(method_missing); + mrb_callinfo *ci = mrb->c->ci; if (*mid == id_method_missing) { method_missing: ; - int argc = mrb->c->ci->argc; - mrb_value *argv = mrb->c->ci->stack + 1; - mrb_value args = (argc < 0) ? argv[0] : mrb_ary_new_from_values(mrb, argc, argv); - mrb_method_missing(mrb, *mid, recv, args); + int n = ci->n; + mrb_value *argv = ci->stack + 1; + mrb_value args = (n == 15) ? argv[0] : mrb_ary_new_from_values(mrb, n, argv); + mrb_method_missing(mrb, id_method_missing, recv, args); } *tc = mrb_class(mrb, recv); @@ -81,7 +84,7 @@ method_missing_prepare(mrb_state *mrb, mrb_sym *mid, mrb_value recv, struct RCla static struct RObject * method_object_alloc(mrb_state *mrb, struct RClass *mclass) { - return (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mclass); + return MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mclass); } static struct RProc* @@ -242,7 +245,7 @@ mcall(mrb_state *mrb, mrb_value self, mrb_value recv) mrb->c->ci->mid = mid; mrb->c->ci->u.target_class = tc; - return mrb_exec_irep(mrb, recv, proc, NULL); + return mrb_exec_irep(mrb, recv, proc); } static mrb_value diff --git a/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mrbgems/mruby-numeric-ext/src/numeric_ext.c index dbc7f39d9..2f2a6c755 100644 --- a/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -1,4 +1,3 @@ -#include <limits.h> #include <mruby.h> #include <mruby/numeric.h> #include <mruby/presym.h> @@ -10,12 +9,12 @@ * Returns +true+ if all bits of <code>+int+ & +mask+</code> are 1. */ static mrb_value -mrb_int_allbits(mrb_state *mrb, mrb_value self) +int_allbits(mrb_state *mrb, mrb_value self) { mrb_int n, m; mrb_get_args(mrb, "i", &m); - n = mrb_int(mrb, self); + n = mrb_integer(self); return mrb_bool_value((n & m) == m); } @@ -26,12 +25,12 @@ mrb_int_allbits(mrb_state *mrb, mrb_value self) * Returns +true+ if any bits of <code>+int+ & +mask+</code> are 1. */ static mrb_value -mrb_int_anybits(mrb_state *mrb, mrb_value self) +int_anybits(mrb_state *mrb, mrb_value self) { mrb_int n, m; mrb_get_args(mrb, "i", &m); - n = mrb_int(mrb, self); + n = mrb_integer(self); return mrb_bool_value((n & m) != 0); } @@ -42,25 +41,85 @@ mrb_int_anybits(mrb_state *mrb, mrb_value self) * Returns +true+ if no bits of <code>+int+ & +mask+</code> are 1. */ static mrb_value -mrb_int_nobits(mrb_state *mrb, mrb_value self) +int_nobits(mrb_state *mrb, mrb_value self) { mrb_int n, m; mrb_get_args(mrb, "i", &m); - n = mrb_int(mrb, self); + n = mrb_integer(self); return mrb_bool_value((n & m) == 0); } +static void +zerodiv(mrb_state *mrb) +{ + mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0"); +} + +/* + * call-seq: + * num.remainder(numeric) -> real + * + * <code>x.remainder(y)</code> means <code>x-y*(x/y).truncate</code>. + * + * See Numeric#divmod. + */ +static mrb_value +int_remainder(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + mrb_int a, b; + + a = mrb_integer(x); + if (mrb_integer_p(y)) { + b = mrb_integer(y); + if (b == 0) zerodiv(mrb); + if (a == MRB_INT_MIN && b == -1) return mrb_fixnum_value(0); + return mrb_int_value(mrb, a % b); + } +#ifdef MRB_NO_FLOAT + mrb_raise(mrb, E_TYPE_ERROR, "non integer remainder"); +#else + mrb_float n = (mrb_float)a; + mrb_float m = mrb_as_float(mrb, y); + + if (isinf(m)) return mrb_float_value(mrb, n); + return mrb_float_value(mrb, n-m*trunc(n/m)); +#endif +} + +#ifndef MRB_NO_FLOAT +static mrb_value +flo_remainder(mrb_state *mrb, mrb_value self) +{ + mrb_float a, b; + + a = mrb_float(self); + mrb_get_args(mrb, "f", &b); + if (b == 0) zerodiv(mrb); + if (isinf(b)) return mrb_float_value(mrb, a); + return mrb_float_value(mrb, a-b*trunc(a/b)); +} +#endif + void mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) { struct RClass *i = mrb_class_get(mrb, "Integer"); - mrb_define_method(mrb, i, "allbits?", mrb_int_allbits, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, i, "anybits?", mrb_int_anybits, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, i, "nobits?", mrb_int_nobits, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, i, "allbits?", int_allbits, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, i, "anybits?", int_anybits, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, i, "nobits?", int_nobits, MRB_ARGS_REQ(1)); + + mrb_define_alias(mrb, i, "modulo", "%"); + mrb_define_method(mrb, i, "remainder", int_remainder, MRB_ARGS_REQ(1)); #ifndef MRB_NO_FLOAT + struct RClass *f = mrb_class_get(mrb, "Float"); + + mrb_define_alias(mrb, f, "modulo", "%"); + mrb_define_method(mrb, f, "remainder", flo_remainder, MRB_ARGS_REQ(1)); + mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(RADIX), mrb_fixnum_value(MRB_FLT_RADIX)); mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MANT_DIG), mrb_fixnum_value(MRB_FLT_MANT_DIG)); mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(EPSILON), mrb_float_value(mrb, MRB_FLT_EPSILON)); diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c index a65feea6d..69f1763ce 100644 --- a/mrbgems/mruby-object-ext/src/object.c +++ b/mrbgems/mruby-object-ext/src/object.c @@ -103,7 +103,7 @@ mrb_obj_instance_exec(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "*&!", &argv, &argc, &blk); c = mrb_singleton_class_ptr(mrb, self); - if (mrb->c->ci->acc < 0) { + if (mrb->c->ci->cci > 0) { return mrb_yield_with_class(mrb, blk, argc, argv, self, c); } mrb_vm_ci_target_class_set(mrb->c->ci, c); diff --git a/mrbgems/mruby-os-memsize/src/memsize.c b/mrbgems/mruby-os-memsize/src/memsize.c index 9947512cf..b6a25a204 100644 --- a/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mrbgems/mruby-os-memsize/src/memsize.c @@ -88,6 +88,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) mrb_hash_memsize(obj); break; } + case MRB_TT_STRUCT: case MRB_TT_ARRAY: { mrb_int len = RARRAY_LEN(obj); /* Arrays that do not fit within an RArray perform a heap allocation diff --git a/mrbgems/mruby-pack/README.md b/mrbgems/mruby-pack/README.md index efa51cc1b..712cf8e1c 100644 --- a/mrbgems/mruby-pack/README.md +++ b/mrbgems/mruby-pack/README.md @@ -1,5 +1,4 @@ -mruby-pack (pack / unpack) -========= +# mruby-pack (pack / unpack) mruby-pack provides `Array#pack` and `String#unpack` for mruby. @@ -8,41 +7,41 @@ mruby-pack provides `Array#pack` and `String#unpack` for mruby. Add the line below into your build configuration: ``` - conf.gem :github => 'iij/mruby-pack' + conf.gem :core => 'mruby-pack' ``` There is no dependency on other mrbgems. ## Supported template string - - A : arbitrary binary string (space padded, count is width) - - a : arbitrary binary string (null padded, count is width) - - C : 8-bit unsigned (unsigned char) - - c : 8-bit signed (signed char) - - D, d: 64-bit float, native format - - E : 64-bit float, little endian byte order - - e : 32-bit float, little endian byte order - - F, f: 32-bit float, native format - - G : 64-bit float, network (big-endian) byte order - - g : 32-bit float, network (big-endian) byte order - - H : hex string (high nibble first) - - h : hex string (low nibble first) - - I : unsigned integer, native endian (`unsigned int` in C) - - i : signed integer, native endian (`int` in C) - - L : 32-bit unsigned, native endian (`uint32_t`) - - l : 32-bit signed, native endian (`int32_t`) - - m : base64 encoded string (see RFC 2045, count is width) - - N : 32-bit unsigned, network (big-endian) byte order - - n : 16-bit unsigned, network (big-endian) byte order - - Q : 64-bit unsigned, native endian (`uint64_t`) - - q : 64-bit signed, native endian (`int64_t`) - - S : 16-bit unsigned, native endian (`uint16_t`) - - s : 16-bit signed, native endian (`int16_t`) - - U : UTF-8 character - - V : 32-bit unsigned, VAX (little-endian) byte order - - v : 16-bit unsigned, VAX (little-endian) byte order - - x : null byte - - Z : same as "a", except that null is added with * +- A : arbitrary binary string (space padded, count is width) +- a : arbitrary binary string (null padded, count is width) +- C : 8-bit unsigned (unsigned char) +- c : 8-bit signed (signed char) +- D, d: 64-bit float, native format +- E : 64-bit float, little endian byte order +- e : 32-bit float, little endian byte order +- F, f: 32-bit float, native format +- G : 64-bit float, network (big-endian) byte order +- g : 32-bit float, network (big-endian) byte order +- H : hex string (high nibble first) +- h : hex string (low nibble first) +- I : unsigned integer, native endian (`unsigned int` in C) +- i : signed integer, native endian (`int` in C) +- L : 32-bit unsigned, native endian (`uint32_t`) +- l : 32-bit signed, native endian (`int32_t`) +- m : base64 encoded string (see RFC 2045, count is width) +- N : 32-bit unsigned, network (big-endian) byte order +- n : 16-bit unsigned, network (big-endian) byte order +- Q : 64-bit unsigned, native endian (`uint64_t`) +- q : 64-bit signed, native endian (`int64_t`) +- S : 16-bit unsigned, native endian (`uint16_t`) +- s : 16-bit signed, native endian (`int16_t`) +- U : UTF-8 character +- V : 32-bit unsigned, VAX (little-endian) byte order +- v : 16-bit unsigned, VAX (little-endian) byte order +- x : null byte +- Z : same as "a", except that null is added with * ## License diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index e52171d6b..f0d4b8d9e 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -18,18 +18,23 @@ #define INT_OVERFLOW_P(n) ((n) < MRB_INT_MIN || (n) > MRB_INT_MAX) #define UINT_OVERFLOW_P(n) ((n) > MRB_INT_MAX) +#ifndef EOF +# define EOF (-1) /* for MRB_NO_STDIO */ +#endif + struct tmpl { mrb_value str; int idx; }; -enum { +enum pack_dir { PACK_DIR_CHAR, /* C */ PACK_DIR_SHORT, /* S */ PACK_DIR_LONG, /* L */ PACK_DIR_QUAD, /* Q */ //PACK_DIR_INT, /* i */ //PACK_DIR_VAX, + PACK_DIR_BER, /* w */ PACK_DIR_UTF8, /* U */ //PACK_DIR_BER, PACK_DIR_DOUBLE, /* E */ @@ -37,30 +42,33 @@ enum { PACK_DIR_STR, /* A */ PACK_DIR_HEX, /* h */ PACK_DIR_BASE64, /* m */ + PACK_DIR_QENC, /* M */ PACK_DIR_NUL, /* x */ + PACK_DIR_BACK, /* X */ + PACK_DIR_ABS, /* @ */ PACK_DIR_INVALID }; -enum { +enum pack_type { PACK_TYPE_INTEGER, PACK_TYPE_FLOAT, PACK_TYPE_STRING, PACK_TYPE_NONE }; -#define PACK_FLAG_s 0x00000001 /* native size ("_" "!") */ -#define PACK_FLAG_a 0x00000002 /* null padding ("a") */ -#define PACK_FLAG_Z 0x00000004 /* append nul char ("z") */ -#define PACK_FLAG_SIGNED 0x00000008 /* native size ("_" "!") */ -#define PACK_FLAG_GT 0x00000010 /* big endian (">") */ -#define PACK_FLAG_LT 0x00000020 /* little endian ("<") */ -#define PACK_FLAG_WIDTH 0x00000040 /* "count" is "width" */ -#define PACK_FLAG_LSB 0x00000080 /* LSB / low nibble first */ -#define PACK_FLAG_COUNT2 0x00000100 /* "count" is special... */ -#define PACK_FLAG_LITTLEENDIAN 0x00000200 /* little endian actually */ +#define PACK_FLAG_s 0x00000001 /* native size ("_" "!") */ +#define PACK_FLAG_a 0x00000002 /* null padding ("a") */ +#define PACK_FLAG_Z 0x00000004 /* append nul char ("z") */ +#define PACK_FLAG_SIGNED 0x00000008 /* native size ("_" "!") */ +#define PACK_FLAG_GT 0x00000010 /* big endian (">") */ +#define PACK_FLAG_LT 0x00000020 /* little endian ("<") */ +#define PACK_FLAG_WIDTH 0x00000040 /* "count" is "width" */ +#define PACK_FLAG_LSB 0x00000080 /* LSB / low nibble first */ +#define PACK_FLAG_COUNT2 0x00000100 /* "count" is special... */ +#define PACK_FLAG_LITTLEENDIAN 0x00000200 /* little endian actually */ -#define PACK_BASE64_IGNORE 0xff -#define PACK_BASE64_PADDING 0xfe +#define PACK_BASE64_IGNORE 0xff +#define PACK_BASE64_PADDING 0xfe const static unsigned char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -76,7 +84,7 @@ hex2int(unsigned char ch) else if (ch >= 'a' && ch <= 'f') return 10 + (ch - 'a'); else - return 0; + return -1; } static void @@ -113,7 +121,7 @@ str_len_ensure(mrb_state *mrb, mrb_value str, mrb_int len) static int -pack_c(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +pack_char(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) { str = str_len_ensure(mrb, str, sidx + 1); RSTRING_PTR(str)[sidx] = (char)mrb_integer(o); @@ -121,7 +129,7 @@ pack_c(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl } static int -unpack_c(mrb_state *mrb, const void *src, int srclen, mrb_value ary, unsigned int flags) +unpack_char(mrb_state *mrb, const void *src, int srclen, mrb_value ary, unsigned int flags) { if (flags & PACK_FLAG_SIGNED) mrb_ary_push(mrb, ary, mrb_fixnum_value(*(signed char *)src)); @@ -131,7 +139,7 @@ unpack_c(mrb_state *mrb, const void *src, int srclen, mrb_value ary, unsigned in } static int -pack_s(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +pack_short(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) { uint16_t n; @@ -148,7 +156,7 @@ pack_s(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int fl } static int -unpack_s(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) +unpack_short(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) { int n; @@ -165,7 +173,7 @@ unpack_s(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un } static int -pack_l(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +pack_long(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) { uint32_t n; @@ -219,7 +227,7 @@ u32tostr(char *buf, size_t len, uint32_t n) #endif /* MRB_INT64 */ static int -unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) +unpack_long(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) { #ifndef MRB_INT64 char msg[60]; @@ -254,7 +262,7 @@ unpack_l(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un } static int -pack_q(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +pack_quad(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) { uint64_t n; @@ -336,7 +344,7 @@ i64tostr(char *buf, size_t len, int64_t n) #endif /* MRB_INT64 */ static int -unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) +unpack_quad(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) { char msg[60]; uint64_t ull; @@ -375,6 +383,46 @@ unpack_q(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, un return 8; } +static int +pack_BER(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) +{ + mrb_int n = mrb_integer(o); + size_t i; + char *p; + + if (n < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "can't compress negative numbers"); + } + for (i=1; i<sizeof(mrb_int)+1; i++) { + mrb_int mask = ~((1L<<(7*i))-1); + if ((n & mask) == 0) break; + } + str = str_len_ensure(mrb, str, sidx + i); + p = RSTRING_PTR(str)+sidx; + for (size_t j=i; j>0; p++,j--) { + mrb_int x = (n>>(7*(j-1)))&0x7f; + *p = (char)x; + if (j > 1) *p |= 0x80; + } + return i; +} + +static int +unpack_BER(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, unsigned int flags) +{ + mrb_int i, n = 0; + const unsigned char *p = src; + const unsigned char *e = p + srclen; + + for (i=1; p<e; p++,i++) { + n <<= 7; + n |= *p & 0x7f; + if ((*p & 0x80) == 0) break; + } + mrb_ary_push(mrb, ary, mrb_int_value(mrb, n)); + return i; +} + #ifndef MRB_NO_FLOAT static int pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int flags) @@ -504,7 +552,7 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar #endif static int -pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, long count, unsigned int flags) +pack_utf8(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, int count, unsigned int flags) { char utf8[4]; int len = 0; @@ -621,7 +669,7 @@ unpack_utf8(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary } static int -pack_a(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +pack_str(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags) { mrb_int copylen, slen, padlen; char *dptr, *dptr0, pad, *sptr; @@ -659,7 +707,7 @@ pack_a(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, u } static int -unpack_a(mrb_state *mrb, const void *src, int slen, mrb_value ary, long count, unsigned int flags) +unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) { mrb_value dst; const char *cp, *sptr; @@ -693,7 +741,7 @@ unpack_a(mrb_state *mrb, const void *src, int slen, mrb_value ary, long count, u static int -pack_h(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +pack_hex(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags) { unsigned int a, ashift, b, bshift; long slen; @@ -724,10 +772,12 @@ pack_h(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, u a = b = 0; if (slen > 0) { a = hex2int(*sptr++); + if (a < 0) break; slen--; } if (slen > 0) { b = hex2int(*sptr++); + if (b < 0) break; slen--; } *dptr++ = (a << ashift) + (b << bshift); @@ -737,7 +787,7 @@ pack_h(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, u } static int -unpack_h(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) +unpack_hex(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) { mrb_value dst; int a, ashift, b, bshift; @@ -783,9 +833,8 @@ unpack_h(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, un return (int)(sptr - sptr0); } - static int -pack_m(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count) { mrb_int dstlen; unsigned long l; @@ -851,7 +900,7 @@ pack_m(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, u } static int -unpack_m(mrb_state *mrb, const void *src, int slen, mrb_value ary, unsigned int flags) +unpack_base64(mrb_state *mrb, const void *src, int slen, mrb_value ary) { mrb_value dst; int dlen; @@ -874,13 +923,13 @@ unpack_m(mrb_state *mrb, const void *src, int slen, mrb_value ary, unsigned int if (slen-- == 0) goto done; c = *sptr++; - if (c >= sizeof(base64_dec_tab)) - continue; - ch[i] = base64_dec_tab[c]; - if (ch[i] == PACK_BASE64_PADDING) { - ch[i] = 0; - padding++; - } + if (c >= sizeof(base64_dec_tab)) + continue; + ch[i] = base64_dec_tab[c]; + if (ch[i] == PACK_BASE64_PADDING) { + ch[i] = 0; + padding++; + } } while (c >= sizeof(base64_dec_tab) || ch[i] == PACK_BASE64_IGNORE); } @@ -907,25 +956,117 @@ done: } static int -pack_x(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, long count, unsigned int flags) +pack_qenc(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count) +{ + static const char hex_table[] = "0123456789ABCDEF"; + char buff[1024]; + char *s = RSTRING_PTR(src); + char *send = s + RSTRING_LEN(src); + int i = 0, n = 0, prev = EOF; + int dlen = 0; + + if (count <= 1) count = 72; + while (s < send) { + if ((*s > 126) || + (*s < 32 && *s != '\n' && *s != '\t') || + (*s == '=')) { + buff[i++] = '='; + buff[i++] = hex_table[(*s & 0xf0) >> 4]; + buff[i++] = hex_table[*s & 0x0f]; + n += 3; + prev = EOF; + } + else if (*s == '\n') { + if (prev == ' ' || prev == '\t') { + buff[i++] = '='; + buff[i++] = *s; + } + buff[i++] = *s; + n = 0; + prev = *s; + } + else { + buff[i++] = *s; + n++; + prev = *s; + } + if (n > count) { + buff[i++] = '='; + buff[i++] = '\n'; + n = 0; + prev = '\n'; + } + if (i > 1024 - 5) { + str_len_ensure(mrb, dst, didx+dlen+i); + memcpy(RSTRING_PTR(dst)+didx+dlen, buff, i); + dlen += i; + i = 0; + } + s++; + } + if (n > 0) { + buff[i++] = '='; + buff[i++] = '\n'; + } + if (i > 0) { + str_len_ensure(mrb, dst, didx+dlen+i); + memcpy(RSTRING_PTR(dst)+didx+dlen, buff, i); + dlen += i; + } + return dlen; +} + +static int +unpack_qenc(mrb_state *mrb, const void *src, int slen, mrb_value ary) +{ + mrb_value buf = mrb_str_new(mrb, 0, slen); + const char *s = (const char*)src, *ss = s; + const char *send = s + slen; + char *ptr = RSTRING_PTR(buf); + int c1, c2; + + while (s < send) { + if (*s == '=') { + if (++s == send) break; + if (s+1 < send && *s == '\r' && *(s+1) == '\n') + s++; + if (*s != '\n') { + if ((c1 = hex2int(*s)) == -1) break; + if (++s == send) break; + if ((c2 = hex2int(*s)) == -1) break; + *ptr++ = (char)(c1 << 4 | c2); + } + } + else { + *ptr++ = *s; + } + s++; + ss = s; + } + buf = mrb_str_resize(mrb, buf, (mrb_int)(ptr - RSTRING_PTR(buf))); + mrb_str_cat(mrb, buf, ss, send-ss); + mrb_ary_push(mrb, ary, buf); + return slen; +} + +static int +pack_nul(mrb_state *mrb, mrb_value dst, mrb_int didx, int count) { long i; - if (count < 0) return 0; dst = str_len_ensure(mrb, dst, didx + count); for (i = 0; i < count; i++) { RSTRING_PTR(dst)[didx + i] = '\0'; } return count; } -static int -unpack_x(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) + +static void +check_x(mrb_state *mrb, int a, int count, char c) { - if (count < 0) return slen; - if (slen < count) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "x outside of string"); + if (a < count) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%c outside of string", c); } - return count; } static void @@ -942,10 +1083,12 @@ has_tmpl(const struct tmpl *tmpl) } static void -read_tmpl(mrb_state *mrb, struct tmpl *tmpl, int *dirp, int *typep, int *sizep, int *countp, unsigned int *flagsp) +read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type *typep, int *sizep, int *countp, unsigned int *flagsp) { mrb_int t, tlen; - int ch, dir, type, size = 0; + int ch, size = 0; + enum pack_dir dir; + enum pack_type type; int count = 1; unsigned int flags = 0; const char *tptr; @@ -1052,11 +1195,21 @@ alias: size = 4; flags |= PACK_FLAG_SIGNED; break; + case 'w': + dir = PACK_DIR_BER; + type = PACK_TYPE_INTEGER; + flags |= PACK_FLAG_SIGNED; + break; case 'm': dir = PACK_DIR_BASE64; type = PACK_TYPE_STRING; flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2; break; + case 'M': + dir = PACK_DIR_QENC; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2; + break; case 'N': /* = "L>" */ dir = PACK_DIR_LONG; type = PACK_TYPE_INTEGER; @@ -1111,11 +1264,23 @@ alias: dir = PACK_DIR_NUL; type = PACK_TYPE_NONE; break; + case 'X': + dir = PACK_DIR_BACK; + type = PACK_TYPE_NONE; + break; + case '@': + dir = PACK_DIR_ABS; + type = PACK_TYPE_NONE; + break; case 'Z': dir = PACK_DIR_STR; type = PACK_TYPE_STRING; flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_Z; break; + case 'p': case 'P': + case '%': + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%c is not supported", (char)t); + break; default: dir = PACK_DIR_INVALID; type = PACK_TYPE_NONE; @@ -1124,19 +1289,21 @@ alias: /* read suffix [0-9*_!<>] */ while (tmpl->idx < tlen) { - ch = tptr[tmpl->idx++]; + ch = tptr[tmpl->idx]; if (ISDIGIT(ch)) { - count = ch - '0'; - while (tmpl->idx < tlen && ISDIGIT(tptr[tmpl->idx])) { - int ch = tptr[tmpl->idx++] - '0'; - if (count+ch > INT_MAX/10) { - mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length"); - } - count = count * 10 + ch; + char *e; + mrb_int n = mrb_int_read(tptr+tmpl->idx, tptr+tlen, &e); + if (e == NULL || n > INT_MAX) { + mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length"); } - continue; /* special case */ + count = (int)n; + tmpl->idx = e - tptr; + continue; } else if (ch == '*') { - count = -1; + if (type == PACK_TYPE_NONE) + count = 0; + else + count = -1; } else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') { if (strchr("sSiIlLqQ", (int)t) == NULL) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%c' allowed only after types sSiIlLqQ", ch); @@ -1148,10 +1315,11 @@ alias: } else if (ch == '>') { flags |= PACK_FLAG_GT; } - } else { - tmpl->idx--; + } + else { break; } + tmpl->idx++; } if ((flags & PACK_FLAG_LT) || (!(flags & PACK_FLAG_GT) && littleendian)) { @@ -1173,7 +1341,9 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) struct tmpl tmpl; int count; unsigned int flags; - int dir, ridx, size, type; + enum pack_dir dir; + enum pack_type type; + int ridx, size; prepare_tmpl(mrb, &tmpl); @@ -1186,8 +1356,22 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) if (dir == PACK_DIR_INVALID) continue; else if (dir == PACK_DIR_NUL) { - ridx += pack_x(mrb, mrb_nil_value(), result, ridx, count, flags); - if (ridx < 0) goto overflow; + grow: + if (ridx > INT_MAX - count) goto overflow; + ridx += pack_nul(mrb, result, ridx, count); + continue; + } + else if (dir == PACK_DIR_BACK) { + check_x(mrb, ridx, count, 'X'); + ridx -= count; + continue; + } + else if (dir == PACK_DIR_ABS) { + count -= ridx; + if (count > 0) goto grow; + count = -count; + check_x(mrb, ridx, count, '@'); + ridx -= count; continue; } @@ -1200,12 +1384,12 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) o = mrb_ary_ref(mrb, ary, aidx); if (type == PACK_TYPE_INTEGER) { - o = mrb_to_int(mrb, o); + o = mrb_to_integer(mrb, o); } #ifndef MRB_NO_FLOAT else if (type == PACK_TYPE_FLOAT) { if (!mrb_float_p(o)) { - mrb_float f = mrb_to_flo(mrb, o); + mrb_float f = mrb_as_float(mrb, o); o = mrb_float_value(mrb, f); } } @@ -1218,25 +1402,31 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) switch (dir) { case PACK_DIR_CHAR: - ridx += pack_c(mrb, o, result, ridx, flags); + ridx += pack_char(mrb, o, result, ridx, flags); break; case PACK_DIR_SHORT: - ridx += pack_s(mrb, o, result, ridx, flags); + ridx += pack_short(mrb, o, result, ridx, flags); break; case PACK_DIR_LONG: - ridx += pack_l(mrb, o, result, ridx, flags); + ridx += pack_long(mrb, o, result, ridx, flags); break; case PACK_DIR_QUAD: - ridx += pack_q(mrb, o, result, ridx, flags); + ridx += pack_quad(mrb, o, result, ridx, flags); + break; + case PACK_DIR_BER: + ridx += pack_BER(mrb, o, result, ridx, flags); break; case PACK_DIR_BASE64: - ridx += pack_m(mrb, o, result, ridx, count, flags); + ridx += pack_base64(mrb, o, result, ridx, count); + break; + case PACK_DIR_QENC: + ridx += pack_qenc(mrb, o, result, ridx, count); break; case PACK_DIR_HEX: - ridx += pack_h(mrb, o, result, ridx, count, flags); + ridx += pack_hex(mrb, o, result, ridx, count, flags); break; case PACK_DIR_STR: - ridx += pack_a(mrb, o, result, ridx, count, flags); + ridx += pack_str(mrb, o, result, ridx, count, flags); break; #ifndef MRB_NO_FLOAT case PACK_DIR_DOUBLE: @@ -1252,7 +1442,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) default: break; } - if (dir == PACK_DIR_STR || dir == PACK_DIR_BASE64 || dir == PACK_DIR_HEX) { + if (flags & PACK_FLAG_COUNT2) { /* always consumes 1 entry */ aidx++; break; @@ -1278,7 +1468,9 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) struct tmpl tmpl; int count; unsigned int flags; - int dir, size, type; + enum pack_dir dir; + enum pack_type type; + int size; int srcidx, srclen; const unsigned char *sptr; @@ -1294,24 +1486,39 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) if (dir == PACK_DIR_INVALID) continue; else if (dir == PACK_DIR_NUL) { - srcidx += unpack_x(mrb, sptr, srclen - srcidx, result, count, flags); + check_x(mrb, srclen-srcidx, count, 'x'); + srcidx += count; + continue; + } + else if (dir == PACK_DIR_BACK) { + check_x(mrb, srcidx, count, 'X'); + srcidx -= count; + continue; + } + else if (dir == PACK_DIR_ABS) { + check_x(mrb, srclen, count, '@'); + srcidx = count; continue; } - if (flags & PACK_FLAG_COUNT2) { - sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx; - switch (dir) { - case PACK_DIR_HEX: - srcidx += unpack_h(mrb, sptr, srclen - srcidx, result, count, flags); - break; - case PACK_DIR_STR: - srcidx += unpack_a(mrb, sptr, srclen - srcidx, result, count, flags); - break; - case PACK_DIR_BASE64: - srcidx += unpack_m(mrb, sptr, srclen - srcidx, result, flags); - break; - } + /* PACK_FLAG_COUNT2 directions */ + sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx; + switch (dir) { + case PACK_DIR_HEX: + srcidx += unpack_hex(mrb, sptr, srclen - srcidx, result, count, flags); + continue; + case PACK_DIR_STR: + srcidx += unpack_str(mrb, sptr, srclen - srcidx, result, count, flags); continue; + case PACK_DIR_BASE64: + srcidx += unpack_base64(mrb, sptr, srclen - srcidx, result); + continue; + break; + case PACK_DIR_QENC: + srcidx += unpack_qenc(mrb, sptr, srclen - srcidx, result); + continue; + default: + break; } while (count != 0) { @@ -1325,16 +1532,19 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) sptr = (const unsigned char*)RSTRING_PTR(str) + srcidx; switch (dir) { case PACK_DIR_CHAR: - srcidx += unpack_c(mrb, sptr, srclen - srcidx, result, flags); + srcidx += unpack_char(mrb, sptr, srclen - srcidx, result, flags); break; case PACK_DIR_SHORT: - srcidx += unpack_s(mrb, sptr, srclen - srcidx, result, flags); + srcidx += unpack_short(mrb, sptr, srclen - srcidx, result, flags); break; case PACK_DIR_LONG: - srcidx += unpack_l(mrb, sptr, srclen - srcidx, result, flags); + srcidx += unpack_long(mrb, sptr, srclen - srcidx, result, flags); break; case PACK_DIR_QUAD: - srcidx += unpack_q(mrb, sptr, srclen - srcidx, result, flags); + srcidx += unpack_quad(mrb, sptr, srclen - srcidx, result, flags); + break; + case PACK_DIR_BER: + srcidx += unpack_BER(mrb, sptr, srclen - srcidx, result, flags); break; #ifndef MRB_NO_FLOAT case PACK_DIR_FLOAT: diff --git a/mrbgems/mruby-pack/test/pack.rb b/mrbgems/mruby-pack/test/pack.rb index a248174a5..16db6607b 100644 --- a/mrbgems/mruby-pack/test/pack.rb +++ b/mrbgems/mruby-pack/test/pack.rb @@ -10,78 +10,59 @@ def assert_pack tmpl, packed, unpacked end # pack & unpack 'm' (base64) -assert('[""].pack("m")') do +assert('pack("m")') do assert_pack "m", "", [""] -end - -assert('["\0"].pack("m")') do assert_pack "m", "AA==\n", ["\0"] -end - -assert('["\0\0"].pack("m")') do assert_pack "m", "AAA=\n", ["\0\0"] -end - -assert('["\0\0\0"].pack("m")') do assert_pack "m", "AAAA\n", ["\0\0\0"] -end - -assert('["abc..xyzABC..XYZ"].pack("m")') do assert_pack "m", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n", ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"] -end -assert('"YWJ...".unpack("m") should "abc..xyzABC..XYZ"') do ary = ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"] assert_equal ary, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJT\nVFVWV1hZWg==\n".unpack("m") assert_equal ary, "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==\n".unpack("m") -end -assert('["A", "B"].pack') do assert_equal "QQ==\n", ["A", "B"].pack("m50") assert_equal ["A"], "QQ==\n".unpack("m50") assert_equal "QQ==Qg==", ["A", "B"].pack("m0 m0") assert_equal ["A", "B"], "QQ==Qg==".unpack("m10 m10") + assert_pack "m0", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==", ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"] end -assert('["abc..xyzABC..XYZ"].pack("m0")') do - assert_pack "m0", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWg==", ["abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"] +# pack & unpack 'M' (Quoted-printable) +assert('pack("M")') do + assert_pack "M", "123=\n", ["123"] + assert_pack "M", "=3D\n", ["=\n"] + assert_pack "M", "=E3=81=82=\n", ["あ"] + + assert_equal ["123"], "123=\n".unpack("M") + assert_equal ["=\n"], "=3D\n".unpack("M") + assert_equal ["あ"], "=E3=81=82=\n".unpack("M") end # pack & unpack 'H' -assert('["3031"].pack("H*")') do +assert('pack("H")') do assert_pack "H*", "01", ["3031"] -end - -assert('["10"].pack("H*")') do assert_pack "H*", "\020", ["10"] end -assert('[0,1,127,128,255].pack("C*")') do +assert('pack("C")') do assert_pack "C*", "\x00\x01\x7F\x80\xFF", [0, 1, 127, 128, 255] end -# pack "a" -assert('["abc"].pack("a")') do +assert('pack("a")') do assert_equal "a", ["abc"].pack("a") assert_equal "abc", ["abc"].pack("a*") assert_equal "abc\0", ["abc"].pack("a4") -end -# upack "a" -assert('["abc"].pack("a")') do assert_equal ["abc\0"], "abc\0".unpack("a4") assert_equal ["abc "], "abc ".unpack("a4") end -# pack "A" -assert('["abc"].pack("A")') do +assert('pack("A")') do assert_equal "a", ["abc"].pack("A") assert_equal "abc", ["abc"].pack("A*") assert_equal "abc ", ["abc"].pack("A4") -end -# upack "A" -assert('["abc"].pack("A")') do assert_equal ["abc"], "abc\0".unpack("A4") assert_equal ["abc"], "abc ".unpack("A4") end @@ -143,6 +124,12 @@ assert 'pack/unpack "I"' do assert_pack 'I', str, [12345] end +assert 'pack/unpack "w"' do + for x in [0,1,127,128,16383,16384,65535,65536] + assert_equal [x], [x].pack("w").unpack("w") + end +end + assert 'pack/unpack "U"' do assert_equal [], "".unpack("U") assert_equal [], "".unpack("U*") diff --git a/mrbgems/mruby-print/src/print.c b/mrbgems/mruby-print/src/print.c index c98bfb7bf..789808deb 100644 --- a/mrbgems/mruby-print/src/print.c +++ b/mrbgems/mruby-print/src/print.c @@ -6,7 +6,6 @@ #include <mruby/string.h> #include <string.h> -#include <stdlib.h> #if defined(_WIN32) # include <windows.h> # include <io.h> diff --git a/mrbgems/mruby-proc-binding/src/proc-binding.c b/mrbgems/mruby-proc-binding/src/proc-binding.c index 82d9d1d51..d176034d2 100644 --- a/mrbgems/mruby-proc-binding/src/proc-binding.c +++ b/mrbgems/mruby-proc-binding/src/proc-binding.c @@ -3,8 +3,6 @@ #include <mruby/proc.h> #include <mruby/variable.h> -void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); - /* provided by mruby-proc-ext */ mrb_value mrb_proc_source_location(mrb_state *mrb, struct RProc *p); diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index 9712fbd7e..ae917d33e 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -11,6 +11,7 @@ #include <mruby/array.h> #include <mruby/istruct.h> #include <mruby/presym.h> +#include <mruby/string.h> #include <time.h> @@ -22,8 +23,6 @@ worldwide. This software is distributed without any warranty. See <https://creativecommons.org/publicdomain/zero/1.0/>. */ -#include <stdint.h> - /* This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid generators. It has excellent speed, a state size (128 bits) that is large enough for mild parallelism, and it passes all tests we are aware @@ -60,12 +59,17 @@ rand_init(rand_state *t) #endif } +static uint32_t rand_uint32(rand_state *state); + static uint32_t rand_seed(rand_state *t, uint32_t seed) { uint32_t old_seed = t->seed[SEEDPOS]; rand_init(t); t->seed[SEEDPOS] = seed; + for (int i = 0; i < 10; i++) { + rand_uint32(t); + } return old_seed; } @@ -151,14 +155,6 @@ get_opt(mrb_state* mrb) return arg; } -static void -random_check(mrb_state *mrb, mrb_value random) { - struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); - if (!mrb_obj_is_kind_of(mrb, random, c) || !mrb_istruct_p(random)) { - mrb_raise(mrb, E_TYPE_ERROR, "Random instance required"); - } -} - static mrb_value random_default(mrb_state *mrb) { struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); @@ -218,6 +214,23 @@ random_m_srand(mrb_state *mrb, mrb_value self) return mrb_int_value(mrb, (mrb_int)old_seed); } +static mrb_value +random_m_bytes(mrb_state *mrb, mrb_value self) +{ + rand_state *t = random_ptr(self); + + mrb_int i; + mrb_get_args(mrb, "i", &i); + + mrb_value bytes = mrb_str_new(mrb, NULL, i); + uint8_t *p = (uint8_t*)RSTRING_PTR(bytes); + for (; i > 0; i--, p++) { + *p = (uint8_t)rand_uint32(t); + } + + return bytes; +} + /* * call-seq: * ary.shuffle! -> ary @@ -229,47 +242,13 @@ static mrb_value mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) { mrb_int i, max; - mrb_value r = mrb_nil_value(); rand_state *random; - /* - * MSC compiler bug generating invalid instructions with optimization - * enabled. MSC errantly uses a hardcoded value with optimizations on - * when using a fixed value from a union. - * Creating a temp volatile variable and reassigning back to the original - * value tricks the compiler to not perform this optimization; - */ -#if defined _MSC_VER && _MSC_VER >= 1923 - /* C++ will not cast away volatile easily, so we cannot do something like - * volatile mrb_value rr = r; r = (mrb_value)rr; with C++. - * That cast does work with C. - * We also have to trick the compiler to not optimize away the const_cast entirely - * by creating and manipulating an intermediate volatile pointer. - */ - volatile mrb_value *v_r; - volatile mrb_int ii; - mrb_value *p_r; - v_r = &r; - ii = 2; - v_r = v_r + 2; -#if defined __cplusplus - p_r = const_cast<mrb_value*>(v_r - ii); -#else - p_r = (mrb_value*)v_r - ii; -#endif - r = *p_r; -#endif - if (RARRAY_LEN(ary) > 1) { - mrb_get_args(mrb, "|o", &r); - - if (mrb_nil_p(r)) { + struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); + if (mrb_get_args(mrb, "|I", &random, c) == 0) { random = random_default_state(mrb); } - else { - random_check(mrb, r); - random = random_ptr(r); - } mrb_ary_modify(mrb, mrb_ary_ptr(ary)); max = RARRAY_LEN(ary); for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { @@ -324,18 +303,13 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) { mrb_int n = 0; mrb_bool given; - mrb_value r = mrb_nil_value(); rand_state *random; mrb_int len; + struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); - mrb_get_args(mrb, "|i?o", &n, &given, &r); - if (mrb_nil_p(r)) { + if (mrb_get_args(mrb, "|i?I", &n, &given, &random, c) < 2) { random = random_default_state(mrb); } - else { - random_check(mrb, r); - random = random_ptr(r); - } len = RARRAY_LEN(ary); if (!given) { /* pick one element */ switch (len) { @@ -393,13 +367,20 @@ random_f_srand(mrb_state *mrb, mrb_value self) return random_m_srand(mrb, random); } +static mrb_value +random_f_bytes(mrb_state *mrb, mrb_value self) +{ + mrb_value random = random_default(mrb); + return random_m_bytes(mrb, random); +} + void mrb_mruby_random_gem_init(mrb_state *mrb) { struct RClass *random; struct RClass *array = mrb->array_class; - mrb_static_assert1(sizeof(rand_state) <= ISTRUCT_DATA_SIZE); + mrb_static_assert(sizeof(rand_state) <= ISTRUCT_DATA_SIZE); mrb_define_method(mrb, mrb->kernel_module, "rand", random_f_rand, MRB_ARGS_OPT(1)); mrb_define_method(mrb, mrb->kernel_module, "srand", random_f_srand, MRB_ARGS_OPT(1)); @@ -408,10 +389,12 @@ void mrb_mruby_random_gem_init(mrb_state *mrb) MRB_SET_INSTANCE_TT(random, MRB_TT_ISTRUCT); mrb_define_class_method(mrb, random, "rand", random_f_rand, MRB_ARGS_OPT(1)); mrb_define_class_method(mrb, random, "srand", random_f_srand, MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, random, "bytes", random_f_bytes, MRB_ARGS_REQ(1)); mrb_define_method(mrb, random, "initialize", random_m_init, MRB_ARGS_OPT(1)); mrb_define_method(mrb, random, "rand", random_m_rand, MRB_ARGS_OPT(1)); mrb_define_method(mrb, random, "srand", random_m_srand, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, random, "bytes", random_m_bytes, MRB_ARGS_REQ(1)); mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1)); mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1)); diff --git a/mrbgems/mruby-random/test/random.rb b/mrbgems/mruby-random/test/random.rb index 37583c5d3..4a2f08261 100644 --- a/mrbgems/mruby-random/test/random.rb +++ b/mrbgems/mruby-random/test/random.rb @@ -31,6 +31,20 @@ assert("Random.srand") do assert_not_equal(r1, r3) end +assert("Random#bytes") do + r = Random.new(10) + num = 11 + a = r.bytes(num) + assert_kind_of String, a + assert_equal num, a.bytesize + b = r.bytes(num) + assert_kind_of String, b + assert_equal num, b.bytesize + assert_not_equal a, b + b = r.bytes(num / 2) + assert_equal num / 2, b.bytesize +end + assert("return class of Kernel.rand") do assert_kind_of(Integer, rand(3)) assert_kind_of(Integer, rand(1.5)) diff --git a/mrbgems/mruby-range-ext/mrblib/range.rb b/mrbgems/mruby-range-ext/mrblib/range.rb index 7fe502c9d..8b670afee 100644 --- a/mrbgems/mruby-range-ext/mrblib/range.rb +++ b/mrbgems/mruby-range-ext/mrblib/range.rb @@ -56,7 +56,7 @@ class Range def max(&block) val = self.begin last = self.end - return super if block + return super(&block) if block raise RangeError, "cannot get the maximum of endless range" if last.nil? @@ -72,7 +72,7 @@ class Range end # delegate to Enumerable - super + super() end def min(&block) @@ -80,7 +80,7 @@ class Range last = self.end if block raise RangeError, "cannot get the minimum of endless range with custom comparison method" if last.nil? - return super + return super(&block) end return val if last.nil? @@ -94,6 +94,6 @@ class Range end # delegate to Enumerable - super + super() end end diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index 7b919eb90..633c97b73 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -1,6 +1,5 @@ #include <mruby.h> #include <mruby/range.h> -#include <math.h> static mrb_bool r_le(mrb_state *mrb, mrb_value a, mrb_value b) @@ -81,7 +80,7 @@ range_size(mrb_state *mrb, mrb_value range) beg = RANGE_BEG(r); end = RANGE_END(r); - if ((mrb_fixnum_p(beg) || mrb_float_p(beg)) && mrb_nil_p(end)) { + if ((mrb_integer_p(beg) || mrb_float_p(beg)) && mrb_nil_p(end)) { return mrb_float_value(mrb, INFINITY); } @@ -136,7 +135,7 @@ range_size(mrb_state *mrb, mrb_value range) beg = RANGE_BEG(r); end = RANGE_END(r); - if (mrb_fixnum_p(beg) && mrb_nil_p(end)) { + if (mrb_integer_p(beg) && mrb_nil_p(end)) { return mrb_nil_value(); } @@ -147,7 +146,7 @@ range_size(mrb_state *mrb, mrb_value range) mrb_int b = mrb_integer(end); mrb_int c = b - a + excl; - return mrb_fixnum_value(c); + return mrb_int_value(mrb, c); } return mrb_nil_value(); } diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 2dfabe504..de413ba79 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -37,7 +37,7 @@ static struct RBasic* rational_alloc(mrb_state *mrb, struct RClass *c, struct mrb_rational **p) { struct RRational *s; - s = (struct RRational*)mrb_obj_alloc(mrb, MRB_TT_RATIONAL, c); + s = MRB_OBJ_ALLOC(mrb, MRB_TT_RATIONAL, c); #ifdef RATIONAL_INLINE *p = &s->r; #else @@ -155,7 +155,6 @@ rational_new_i(mrb_state *mrb, mrb_int n, mrb_int d) } #ifndef MRB_NO_FLOAT -#include <math.h> #if defined(MRB_INT32) || defined(MRB_USE_FLOAT32) #define frexp_rat(x,exp) frexpf((float)x, exp) @@ -255,20 +254,20 @@ rational_s_new(mrb_state *mrb, mrb_value self) } else { mrb_float numf = (mrb_float)numerator; - mrb_float denomf = mrb_to_flo(mrb, denomv); + mrb_float denomf = mrb_as_float(mrb, denomv); return rational_new_f(mrb, numf/denomf); } } else { - mrb_float numf = mrb_to_flo(mrb, numv); + mrb_float numf = mrb_as_float(mrb, numv); mrb_float denomf; if (mrb_integer_p(denomv)) { denomf = (mrb_float)mrb_integer(denomv); } else { - denomf = mrb_to_flo(mrb, denomv); + denomf = mrb_as_float(mrb, denomv); } return rational_new_f(mrb, numf/denomf); } @@ -278,7 +277,7 @@ rational_s_new(mrb_state *mrb, mrb_value self) #ifndef MRB_NO_FLOAT static mrb_float -rat_to_flo(struct mrb_rational *p) +rat_float(struct mrb_rational *p) { mrb_float f; @@ -296,7 +295,7 @@ static mrb_value rational_to_f(mrb_state *mrb, mrb_value self) { struct mrb_rational *p = rational_ptr(mrb, self); - return mrb_float_value(mrb, rat_to_flo(p)); + return mrb_float_value(mrb, rat_float(p)); } #endif @@ -346,8 +345,8 @@ rational_m(mrb_state *mrb, mrb_value self) return rational_new_i(mrb, mrb_integer(a), mrb_integer(b)); } else { - mrb_float x = mrb_to_flo(mrb, a); - mrb_float y = mrb_to_flo(mrb, b); + mrb_float x = mrb_as_float(mrb, a); + mrb_float y = mrb_as_float(mrb, b); return rational_new_f(mrb, x/y); } #endif @@ -395,7 +394,7 @@ rational_eq(mrb_state *mrb, mrb_value x) case MRB_TT_COMPLEX: { mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value, mrb_value); - result = mrb_complex_eq(mrb, y, x); + result = mrb_complex_eq(mrb, y, rational_to_f(mrb, x)); break; } #endif @@ -436,7 +435,7 @@ rational_cmp(mrb_state *mrb, mrb_value x) #ifndef MRB_NO_FLOAT case MRB_TT_FLOAT: { - mrb_float a = rat_to_flo(p1), b = mrb_to_flo(mrb, y); + mrb_float a = rat_float(p1), b = mrb_as_float(mrb, y); if (a > b) return mrb_fixnum_value(1); else if (a < b) @@ -458,7 +457,7 @@ rational_cmp(mrb_state *mrb, mrb_value x) #endif #ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_to_flo(p1), 0); + x = mrb_complex_new(mrb, rat_float(p1), 0); return mrb_funcall_id(mrb, x, MRB_OPSYM(cmp), 1, y); #endif default: @@ -480,10 +479,6 @@ rational_minus(mrb_state *mrb, mrb_value x) return rational_new(mrb, -n, p->denominator); } -#ifndef MRB_NO_FLOAT -mrb_float mrb_div_flo(mrb_float, mrb_float); -#endif - static mrb_value rational_add(mrb_state *mrb, mrb_value x) { @@ -514,7 +509,7 @@ rational_add(mrb_state *mrb, mrb_value x) case MRB_TT_FLOAT: { mrb_float z = p1->numerator + mrb_float(y) * p1->denominator; - return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator)); + return mrb_float_value(mrb, mrb_div_float(z, (mrb_float)p1->denominator)); } #endif @@ -551,7 +546,7 @@ rational_sub(mrb_state *mrb, mrb_value x) #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_to_flo(p1), 0); + x = mrb_complex_new(mrb, rat_float(p1), 0); return mrb_funcall_id(mrb, x, MRB_OPSYM(sub), 1, y); #endif @@ -559,8 +554,8 @@ rational_sub(mrb_state *mrb, mrb_value x) case MRB_TT_FLOAT: default: { - mrb_float z = p1->numerator - mrb_to_flo(mrb, y) * p1->denominator; - return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator)); + mrb_float z = p1->numerator - mrb_as_float(mrb, y) * p1->denominator; + return mrb_float_value(mrb, mrb_div_float(z, (mrb_float)p1->denominator)); } #else default: @@ -596,7 +591,7 @@ rational_mul(mrb_state *mrb, mrb_value x) case MRB_TT_FLOAT: { mrb_float z = p1->numerator * mrb_float(y); - return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator)); + return mrb_float_value(mrb, mrb_div_float(z, (mrb_float)p1->denominator)); } #endif @@ -630,7 +625,7 @@ mrb_rational_div(mrb_state *mrb, mrb_value x) #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_to_flo(p1), 0); + x = mrb_complex_new(mrb, rat_float(p1), 0); return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); #endif @@ -638,8 +633,8 @@ mrb_rational_div(mrb_state *mrb, mrb_value x) #ifndef MRB_NO_FLOAT case MRB_TT_FLOAT: { - mrb_float z = mrb_div_flo((mrb_float)p1->numerator, mrb_to_flo(mrb, y)); - return mrb_float_value(mrb, mrb_div_flo(z, (mrb_float)p1->denominator)); + mrb_float z = mrb_div_float((mrb_float)p1->numerator, mrb_as_float(mrb, y)); + return mrb_float_value(mrb, mrb_div_float(z, (mrb_float)p1->denominator)); } #else mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); @@ -656,7 +651,7 @@ mrb_int mrb_div_int(mrb_state *, mrb_int, mrb_int); * redefine Integer#/ */ static mrb_value -rat_int_div(mrb_state *mrb, mrb_value x) +rational_int_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); mrb_int a = mrb_integer(x); @@ -673,7 +668,7 @@ rat_int_div(mrb_state *mrb, mrb_value x) case MRB_TT_FLOAT: mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); #else - return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y))); + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); #endif } } @@ -684,7 +679,7 @@ rat_int_div(mrb_state *mrb, mrb_value x) */ static mrb_value -rat_int_quo(mrb_state *mrb, mrb_value x) +rational_int_quo(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); mrb_int a = mrb_integer(x); @@ -700,7 +695,7 @@ rat_int_quo(mrb_state *mrb, mrb_value x) #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); #else - return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y))); + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); #endif } } @@ -732,8 +727,8 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) mrb_define_method(mrb, rat, "quo", rational_div, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->integer_class, "to_r", fix_to_r, MRB_ARGS_NONE()); #ifndef MRB_USE_COMPLEX - mrb_define_method(mrb, mrb->integer_class, "/", rat_int_div, MRB_ARGS_REQ(1)); /* overrride */ - mrb_define_method(mrb, mrb->integer_class, "quo", rat_int_quo, MRB_ARGS_REQ(1)); /* overrride */ + mrb_define_method(mrb, mrb->integer_class, "/", rational_int_div, MRB_ARGS_REQ(1)); /* override */ + mrb_define_method(mrb, mrb->integer_class, "quo", rational_int_quo, MRB_ARGS_REQ(1)); /* override */ #endif mrb_define_method(mrb, mrb->kernel_module, "Rational", rational_m, MRB_ARGS_ARG(1,1)); } diff --git a/mrbgems/mruby-sleep/mrbgem.rake b/mrbgems/mruby-sleep/mrbgem.rake index 7a303b81c..024106a48 100644 --- a/mrbgems/mruby-sleep/mrbgem.rake +++ b/mrbgems/mruby-sleep/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-sleep') do |spec| spec.license = 'MIT' spec.authors = ['MATSUMOTO Ryosuke', 'mruby developers'] - spec.version = '0.0.1' + spec.summary = 'Kernel#sleep and Kernel#usleep' end diff --git a/mrbgems/mruby-socket/README.md b/mrbgems/mruby-socket/README.md index b727dc982..8084cdb70 100644 --- a/mrbgems/mruby-socket/README.md +++ b/mrbgems/mruby-socket/README.md @@ -1,5 +1,4 @@ -mruby-socket -============ +# mruby-socket "mruby-socket" mrbgem provides BSD socket interface for mruby. API is compatible with CRuby's "socket" library. diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c index 28418fa12..027404459 100644 --- a/mrbgems/mruby-socket/src/socket.c +++ b/mrbgems/mruby-socket/src/socket.c @@ -31,7 +31,6 @@ typedef size_t fsize_t; #endif -#include <stddef.h> #include <string.h> #include "mruby.h" @@ -65,52 +64,52 @@ #ifdef _WIN32 static const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { - if (af == AF_INET) - { - struct sockaddr_in in; - memset(&in, 0, sizeof(in)); - in.sin_family = AF_INET; - memcpy(&in.sin_addr, src, sizeof(struct in_addr)); - getnameinfo((struct sockaddr *)&in, sizeof(struct - sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); - return dst; - } - else if (af == AF_INET6) - { - struct sockaddr_in6 in; - memset(&in, 0, sizeof(in)); - in.sin6_family = AF_INET6; - memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); - getnameinfo((struct sockaddr *)&in, sizeof(struct - sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); - return dst; - } - return NULL; + if (af == AF_INET) + { + struct sockaddr_in in = {0}; + + in.sin_family = AF_INET; + memcpy(&in.sin_addr, src, sizeof(struct in_addr)); + getnameinfo((struct sockaddr *)&in, sizeof(struct + sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); + return dst; + } + else if (af == AF_INET6) + { + struct sockaddr_in6 in = {0}; + + in.sin6_family = AF_INET6; + memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); + getnameinfo((struct sockaddr *)&in, sizeof(struct + sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); + return dst; + } + return NULL; } static int inet_pton(int af, const char *src, void *dst) { - struct addrinfo hints, *res, *ressave; + struct addrinfo hints = {0}; + struct addrinfo *res, *ressave; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = af; + hints.ai_family = af; - if (getaddrinfo(src, NULL, &hints, &res) != 0) - { - printf("Couldn't resolve host %s\n", src); - return -1; - } + if (getaddrinfo(src, NULL, &hints, &res) != 0) + { + printf("Couldn't resolve host %s\n", src); + return -1; + } - ressave = res; + ressave = res; - while (res) - { - memcpy(dst, res->ai_addr, res->ai_addrlen); - res = res->ai_next; - } + while (res) + { + memcpy(dst, res->ai_addr, res->ai_addrlen); + res = res->ai_next; + } - freeaddrinfo(ressave); - return 0; + freeaddrinfo(ressave); + return 0; } #endif @@ -118,7 +117,7 @@ static int inet_pton(int af, const char *src, void *dst) static mrb_value mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) { - struct addrinfo hints, *res0, *res; + struct addrinfo hints = {0}, *res0, *res; mrb_value ai, ary, family, lastai, nodename, protocol, sa, service, socktype; mrb_int flags; int arena_idx, error; @@ -142,14 +141,13 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) if (mrb_string_p(service)) { servname = RSTRING_CSTR(mrb, service); } else if (mrb_integer_p(service)) { - servname = RSTRING_PTR(mrb_fixnum_to_str(mrb, service, 10)); + servname = RSTRING_PTR(mrb_integer_to_str(mrb, service, 10)); } else if (mrb_nil_p(service)) { servname = NULL; } else { mrb_raise(mrb, E_TYPE_ERROR, "service must be String, Integer, or nil"); } - memset(&hints, 0, sizeof(hints)); hints.ai_flags = (int)flags; if (mrb_integer_p(family)) { @@ -574,7 +572,7 @@ mrb_ipsocket_recvfrom(mrb_state *mrb, mrb_value self) buf = mrb_str_new_capa(mrb, maxlen); socklen = sizeof(ss); n = recvfrom(fd, RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags, - (struct sockaddr *)&ss, &socklen); + (struct sockaddr *)&ss, &socklen); if (n == -1) { mrb_sys_fail(mrb, "recvfrom"); } @@ -938,8 +936,8 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) constants = mrb_define_module_under(mrb, sock, "Constants"); #define define_const(SYM) \ - do { \ - mrb_define_const(mrb, constants, #SYM, mrb_int_value(mrb, SYM)); \ + do { \ + mrb_define_const(mrb, constants, #SYM, mrb_int_value(mrb, SYM)); \ } while (0) #include "const.cstub" diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 839ee4dc4..8de3a4541 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -5,15 +5,11 @@ */ #include <mruby.h> -#include <limits.h> -#include <string.h> #include <mruby/string.h> #include <mruby/hash.h> #include <mruby/numeric.h> #include <mruby/presym.h> -#ifndef MRB_NO_FLOAT -#include <math.h> -#endif +#include <string.h> #include <ctype.h> #define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ @@ -21,9 +17,6 @@ #define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n))) mrb_value mrb_str_format(mrb_state *, mrb_int, const mrb_value *, mrb_value); -#ifndef MRB_NO_FLOAT -static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int); -#endif static char* remove_sign_bits(char *str, int base) @@ -71,35 +64,24 @@ sign_bits(int base, const char *p) return c; } -static mrb_value -mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) +static char * +mrb_uint_to_cstr(char *buf, size_t len, mrb_int num, int base) { - char buf[66], *b = buf + sizeof buf; - mrb_int num = mrb_integer(x); - const int mask = base -1; + char *b = buf + len - 1; + const int mask = base-1; int shift; -#ifdef MRB_INT64 - uint64_t val = (uint64_t)num; -#else - uint32_t val = (uint32_t)num; -#endif + mrb_uint val = (uint64_t)num; char d; - switch (base) { - case 2: - shift = 1; - break; - case 8: - shift = 3; - break; - case 16: - shift = 4; - break; - default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); - } if (num == 0) { - return mrb_str_new_lit(mrb, "0"); + buf[0] = '0'; buf[1] = '\0'; + return buf; + } + switch (base) { + case 16: d = 'f'; shift = 4; break; + case 8: d = '7'; shift = 3; break; + case 2: d = '1'; shift = 1; break; + default: return NULL; } *--b = '\0'; do { @@ -108,19 +90,12 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) if (num < 0) { b = remove_sign_bits(b, base); - switch (base) { - case 16: d = 'f'; break; - case 8: d = '7'; break; - case 2: d = '1'; break; - default: d = 0; break; - } - if (d && *b != d) { *--b = d; } } - return mrb_str_new_cstr(mrb, b); + return b; } #define FNONE 0 @@ -133,7 +108,52 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) #define FPREC 64 #define FPREC0 128 -#define CHECK(l) do {\ +#ifndef MRB_NO_FLOAT +static int +fmt_float(char *buf, size_t buf_size, char fmt, int flags, mrb_int width, int prec, mrb_float f) +{ + char sign = '\0'; + int left_align = 0; + int zero_pad = 0; + + if (flags & FSHARP) fmt |= 0x80; + if (flags & FPLUS) sign = '+'; + if (flags & FMINUS) left_align = 1; + if (flags & FZERO) zero_pad = 1; + if (flags & FSPACE) sign = ' '; + + int len = mrb_format_float(f, buf, buf_size, fmt, prec, sign); + + // buf[0] < '0' returns true if the first character is space, + or - + // buf[1] < '9' matches a digit, and doesn't match when we get back +nan or +inf + if (buf[0] < '0' && buf[1] <= '9' && zero_pad) { + buf++; + width--; + len--; + } + if (*buf < '0' || *buf >= '9') { + // For inf or nan, we don't want to zero pad. + zero_pad = 0; + } + if (len >= width) { + return len; + } + buf[width] = '\0'; + if (left_align) { + memset(&buf[len], ' ', width - len); + return width; + } + memmove(&buf[width - len], buf, len); + if (zero_pad) { + memset(buf, '0', width - len); + } else { + memset(buf, ' ', width - len); + } + return width; +} +#endif + +#define CHECK(l) do { \ while ((l) >= bsiz - blen) {\ if (bsiz > MRB_INT_MAX/2) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \ bsiz*=2;\ @@ -221,7 +241,6 @@ check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len) #define GETASTER(num) do { \ mrb_value tmp_v; \ t = p++; \ - n = 0; \ GETNUM(n, val); \ if (*p == '$') { \ tmp_v = GETPOSARG(n); \ @@ -230,27 +249,17 @@ check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len) tmp_v = GETNEXTARG(); \ p = t; \ } \ - num = mrb_int(mrb, tmp_v); \ + num = mrb_as_int(mrb, tmp_v); \ } while (0) static const char * -get_num(mrb_state *mrb, const char *p, const char *end, mrb_int *valp) +get_num(mrb_state *mrb, const char *p, const char *end, int *valp) { - mrb_int next_n = *valp; - for (; p < end && ISDIGIT(*p); p++) { - if (mrb_int_mul_overflow(10, next_n, &next_n)) { - return NULL; - } - if (MRB_INT_MAX - (*p - '0') < next_n) { - return NULL; - } - next_n += *p - '0'; - } - if (p >= end) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %%*[0-9]"); - } - *valp = next_n; - return p; + char *e; + mrb_int n = mrb_int_read(p, end, &e); + if (e == NULL || n > INT_MAX) return NULL; + *valp = (int)n; + return e; } static void @@ -326,10 +335,6 @@ get_hash(mrb_state *mrb, mrb_value *hash, mrb_int argc, const mrb_value *argv) * | equal to the precision, or in dd.dddd form otherwise. * | The precision specifies the number of significant digits. * G | Equivalent to 'g', but use an uppercase 'E' in exponent form. - * a | Convert floating-point argument as [-]0xh.hhhhp[+-]dd, - * | which is consisted from optional sign, "0x", fraction part - * | as hexadecimal, "p", and exponential part as decimal. - * A | Equivalent to 'a', but use uppercase 'X' and 'P'. * * Field | Other Format * ------+-------------------------------------------------------------- @@ -364,7 +369,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, mrb_int argc, const mrb_value *argv) * | | For the conversions 'x', 'X', 'b' and 'B' * | | on non-zero, prefix the result with "0x", * | | "0X", "0b" and "0B", respectively. - * | | For 'a', 'A', 'e', 'E', 'f', 'g', and 'G', + * | | For 'e', 'E', 'f', 'g', and 'G', * | | force a decimal point to be added, * | | even if no digits follow. * | | For 'g' and 'G', do not remove trailing zeros. @@ -547,50 +552,6 @@ mrb_f_sprintf(mrb_state *mrb, mrb_value obj) } } -static int -mrb_int2str(char *buf, size_t len, mrb_int n) -{ -#ifdef MRB_NO_STDIO - char *bufend = buf + len; - char *p = bufend - 1; - - if (len < 1) return -1; - - *p -- = '\0'; - len --; - - if (n < 0) { - if (len < 1) return -1; - - *p -- = '-'; - len --; - n = -n; - } - - if (n > 0) { - for (; n > 0; len --, n /= 10) { - if (len < 1) return -1; - - *p -- = '0' + (n % 10); - } - p ++; - } - else if (len > 0) { - *p = '0'; - len --; - } - else { - return -1; - } - - memmove(buf, p, bufend - p); - - return bufend - p - 1; -#else - return snprintf(buf, len, "%" MRB_PRId, n); -#endif /* MRB_NO_STDIO */ -} - mrb_value mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt) { @@ -599,9 +560,9 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm mrb_int blen; mrb_int bsiz; mrb_value result; - mrb_int n; - mrb_int width; - mrb_int prec; + int n; + int width; + int prec; int nextarg = 1; int posarg = 0; mrb_value nextvalue; @@ -625,7 +586,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm ++argc; --argv; - mrb_to_str(mrb, fmt); + mrb_ensure_string_type(mrb, fmt); p = RSTRING_PTR(fmt); end = p + RSTRING_LEN(fmt); blen = 0; @@ -688,7 +649,6 @@ retry: case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - n = 0; GETNUM(n, width); if (*p == '$') { if (!mrb_undef_p(nextvalue)) { @@ -732,6 +692,9 @@ retry: CHECK_FOR_WIDTH(flags); flags |= FWIDTH; GETASTER(width); + if (width > INT16_MAX || INT16_MIN > width) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "width too big"); + } if (width < 0) { flags |= FMINUS; width = -width; @@ -745,7 +708,6 @@ retry: } flags |= FPREC|FPREC0; - prec = 0; p++; if (*p == '*') { GETASTER(prec); @@ -755,7 +717,6 @@ retry: p++; goto retry; } - GETNUM(prec, precision); goto retry; @@ -898,19 +859,18 @@ retry: switch (mrb_type(val)) { #ifndef MRB_NO_FLOAT case MRB_TT_FLOAT: - val = mrb_flo_to_fixnum(mrb, val); - if (mrb_integer_p(val)) goto bin_retry; - break; + val = mrb_float_to_integer(mrb, val); + goto bin_retry; #endif case MRB_TT_STRING: - val = mrb_str_to_inum(mrb, val, 0, TRUE); + val = mrb_str_to_integer(mrb, val, 0, TRUE); goto bin_retry; case MRB_TT_INTEGER: v = mrb_integer(val); break; default: - val = mrb_Integer(mrb, val); - goto bin_retry; + v = mrb_as_int(mrb, val); + break; } switch (*p) { @@ -946,21 +906,15 @@ retry: sc = '-'; width--; } - mrb_assert(base == 10); - mrb_int2str(nbuf, sizeof(nbuf)-1, v); - s = nbuf; + s = mrb_int_to_cstr(nbuf, sizeof(nbuf), v, base); if (v < 0) s++; /* skip minus sign */ } else { - s = nbuf; + /* print as unsigned */ + s = mrb_uint_to_cstr(nbuf, sizeof(nbuf), v, base); if (v < 0) { dots = 1; - val = mrb_fix2binstr(mrb, mrb_int_value(mrb, v), base); } - else { - val = mrb_fixnum_to_str(mrb, mrb_int_value(mrb, v), base); - } - strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-2); } { size_t size; @@ -1053,15 +1007,12 @@ retry: case 'g': case 'G': case 'e': - case 'E': - case 'a': - case 'A': { + case 'E': { mrb_value val = GETARG(); double fval; mrb_int need = 6; - char fbuf[64]; - fval = mrb_float(mrb_Float(mrb, val)); + fval = mrb_as_float(mrb, val); if (!isfinite(fval)) { const char *expr; const mrb_int elen = 3; @@ -1108,7 +1059,7 @@ retry: need = BIT_DIGITS(i); } if (need > MRB_INT_MAX - ((flags&FPREC) ? prec : 6)) { - too_big_width: + too_big_width_prec: mrb_raise(mrb, E_ARGUMENT_ERROR, (width > prec ? "width too big" : "prec too big")); } @@ -1116,13 +1067,12 @@ retry: if ((flags&FWIDTH) && need < width) need = width; if (need > MRB_INT_MAX - 20) { - goto too_big_width; + goto too_big_width_prec; } need += 20; CHECK(need); - fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec); - n = mrb_float_to_cstr(mrb, &buf[blen], need, fbuf, fval); + n = fmt_float(&buf[blen], need, *p, flags, width, prec, fval); if (n < 0 || n >= need) { mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); } @@ -1149,35 +1099,6 @@ retry: return result; } -#ifndef MRB_NO_FLOAT -static void -fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec) -{ - char *end = buf + size; - int n; - - *buf++ = '%'; - if (flags & FSHARP) *buf++ = '#'; - if (flags & FPLUS) *buf++ = '+'; - if (flags & FMINUS) *buf++ = '-'; - if (flags & FZERO) *buf++ = '0'; - if (flags & FSPACE) *buf++ = ' '; - - if (flags & FWIDTH) { - n = mrb_int2str(buf, end - buf, width); - buf += n; - } - - if (flags & FPREC) { - *buf ++ = '.'; - n = mrb_int2str(buf, end - buf, prec); - buf += n; - } - - *buf++ = c; - *buf = '\0'; -} -#endif void mrb_mruby_sprintf_gem_init(mrb_state *mrb) diff --git a/mrbgems/mruby-sprintf/test/sprintf.rb b/mrbgems/mruby-sprintf/test/sprintf.rb index 0a8166bae..aedc2787a 100644 --- a/mrbgems/mruby-sprintf/test/sprintf.rb +++ b/mrbgems/mruby-sprintf/test/sprintf.rb @@ -10,11 +10,11 @@ assert('String#%') do assert_equal 15, ("%b" % (1<<14)).size skip unless Object.const_defined?(:Float) assert_equal "1.0", "%3.1f" % 1.01 - assert_equal " 1234567.12", "% 4.2f" % 1234567.123456789 - assert_equal "1234567.12", "%-4.2f" % 1234567.123456789 - assert_equal "+1234567.12", "%+4.2f" % 1234567.123456789 - assert_equal "1234567.12", "%04.2f" % 1234567.123456789 - assert_equal "00000000001234567.12", "%020.2f" % 1234567.123456789 + assert_equal " 12345.12", "% 4.2f" % 12345.1234 + assert_equal "12345.12", "%-4.2f" % 12345.12345 + assert_equal "+12345.12", "%+4.2f" % 12345.1234 + assert_equal "12345.12", "%04.2f" % 12345.12345 + assert_equal "0012345.12", "%010.2f" % 12345.1234 end assert('String#% with inf') do diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb index ff113dd95..d485c51ef 100644 --- a/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mrbgems/mruby-string-ext/mrblib/string.rb @@ -111,36 +111,6 @@ class String (s == self) ? nil : self.replace(s) end - ## - # call-seq: - # str.casecmp(other_str) -> -1, 0, +1 or nil - # - # Case-insensitive version of <code>String#<=></code>. - # - # "abcdef".casecmp("abcde") #=> 1 - # "aBcDeF".casecmp("abcdef") #=> 0 - # "abcdef".casecmp("abcdefg") #=> -1 - # "abcdef".casecmp("ABCDEF") #=> 0 - # - def casecmp(str) - self.downcase <=> str.__to_str.downcase - rescue NoMethodError - nil - end - - ## - # call-seq: - # str.casecmp?(other) -> true, false, or nil - # - # Returns true if str and other_str are equal after case folding, - # false if they are not equal, and nil if other_str is not a string. - - def casecmp?(str) - c = self.casecmp(str) - return nil if c.nil? - return c == 0 - end - def partition(sep) raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String n = index(sep) @@ -344,8 +314,6 @@ class String end def codepoints(&block) - len = self.size - if block_given? self.split('').each do|x| block.call(x.ord) @@ -459,14 +427,14 @@ class String break if exclusive and n == 0 yield bs break if n == 0 + bsiz = bs.size + break if bsiz > max.size || bsiz == 0 bs = bs.succ end self end def __upto_endless(&block) - return to_enum(:__upto_endless) unless block - len = self.length # both edges are all digits bi = self.to_i(10) diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 09cbf7995..e3dabcc18 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -35,7 +35,7 @@ str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) static mrb_value int_chr_binary(mrb_state *mrb, mrb_value num) { - mrb_int cp = mrb_int(mrb, num); + mrb_int cp = mrb_as_int(mrb, num); char c; mrb_value str; @@ -195,14 +195,14 @@ static mrb_value mrb_str_start_with(mrb_state *mrb, mrb_value self) { const mrb_value *argv; - mrb_value sub; mrb_int argc, i; mrb_get_args(mrb, "*", &argv, &argc); for (i = 0; i < argc; i++) { size_t len_l, len_r; int ai = mrb_gc_arena_save(mrb); - sub = mrb_ensure_string_type(mrb, argv[i]); + mrb_value sub = argv[i]; + mrb_ensure_string_type(mrb, sub); mrb_gc_arena_restore(mrb, ai); len_l = RSTRING_LEN(self); len_r = RSTRING_LEN(sub); @@ -225,14 +225,14 @@ static mrb_value mrb_str_end_with(mrb_state *mrb, mrb_value self) { const mrb_value *argv; - mrb_value sub; mrb_int argc, i; mrb_get_args(mrb, "*", &argv, &argc); for (i = 0; i < argc; i++) { size_t len_l, len_r; int ai = mrb_gc_arena_save(mrb); - sub = mrb_ensure_string_type(mrb, argv[i]); + mrb_value sub = argv[i]; + mrb_ensure_string_type(mrb, sub); mrb_gc_arena_restore(mrb, ai); len_l = RSTRING_LEN(self); len_r = RSTRING_LEN(sub); @@ -262,7 +262,7 @@ enum tr_pattern_type { <range> ::= <ch> '-' <ch> */ struct tr_pattern { - uint8_t type; // 1:in-order, 2:range + uint8_t type; // 1:in-order, 2:range mrb_bool flag_reverse : 1; mrb_bool flag_on_heap : 1; uint16_t n; @@ -329,9 +329,9 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte mrb_int len; while (i < pattern_length) { - if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') + if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') break; - i++; + i++; } len = i - start_pos; @@ -375,7 +375,7 @@ tr_find_character(const struct tr_pattern *pat, const char *pat_str, int ch) if (pat->type == TR_IN_ORDER) { int i; for (i = 0; i < pat->n; i++) { - if (pat_str[pat->val.start_pos + i] == ch) ret = n_sum + i; + if (pat_str[pat->val.start_pos + i] == ch) ret = n_sum + i; } } else if (pat->type == TR_RANGE) { @@ -509,7 +509,7 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee if (n >= 0) { flag_changed = TRUE; if (rep == NULL) { - j--; + j--; } else { mrb_int c = tr_get_character(rep, RSTRING_PTR(p2), n); @@ -521,8 +521,8 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee if (c > 0x80) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c); } - lastch = c; - s[i] = (char)c; + lastch = c; + s[i] = (char)c; } } } @@ -835,13 +835,13 @@ mrb_str_count(mrb_state *mrb, mrb_value str) static mrb_value mrb_str_hex(mrb_state *mrb, mrb_value self) { - return mrb_str_to_inum(mrb, self, 16, FALSE); + return mrb_str_to_integer(mrb, self, 16, FALSE); } static mrb_value mrb_str_oct(mrb_state *mrb, mrb_value self) { - return mrb_str_to_inum(mrb, self, 8, FALSE); + return mrb_str_to_integer(mrb, self, 8, FALSE); } /* @@ -1174,6 +1174,60 @@ mrb_str_del_suffix(mrb_state *mrb, mrb_value self) return mrb_str_substr(mrb, self, 0, slen-plen); } +#define lesser(a,b) (((a)>(b))?(b):(a)) + +/* + * call-seq: + * str.casecmp(other_str) -> -1, 0, +1 or nil + * + * Case-insensitive version of <code>String#<=></code>. + * + * "abcdef".casecmp("abcde") #=> 1 + * "aBcDeF".casecmp("abcdef") #=> 0 + * "abcdef".casecmp("abcdefg") #=> -1 + * "abcdef".casecmp("ABCDEF") #=> 0 + */ +static mrb_value +mrb_str_casecmp(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + mrb_get_args(mrb, "o", &str); + if (!mrb_string_p(str)) return mrb_nil_value(); + + struct RString *s1 = mrb_str_ptr(self); + struct RString *s2 = mrb_str_ptr(str); + mrb_int len = lesser(RSTR_LEN(s1), RSTR_LEN(s2)); + char *p1 = RSTR_PTR(s1); + char *p2 = RSTR_PTR(s2); + + for (mrb_int i=0; i<len; i++) { + int c1 = p1[i], c2 = p2[i]; + if (ISASCII(c1) && ISUPPER(c1)) c1 = TOLOWER(c1); + if (ISASCII(c2) && ISUPPER(c2)) c2 = TOLOWER(c2); + if (c1 > c2) return mrb_fixnum_value(1); + if (c1 < c2) return mrb_fixnum_value(-1); + } + if (RSTR_LEN(s1) == RSTR_LEN(s2)) return mrb_fixnum_value(0); + if (RSTR_LEN(s1) > RSTR_LEN(s2)) return mrb_fixnum_value(1); + return mrb_fixnum_value(-1); +} + +/* + * call-seq: + * str.casecmp?(other) -> true, false, or nil + * + * Returns true if str and other_str are equal after case folding, + * false if they are not equal, and nil if other is not a string. + */ +static mrb_value +mrb_str_casecmp_p(mrb_state *mrb, mrb_value self) +{ + mrb_value c = mrb_str_casecmp(mrb, self); + if (mrb_nil_p(c)) return c; + return mrb_bool_value(mrb_fixnum(c) == 0); +} + static mrb_value mrb_str_lines(mrb_state *mrb, mrb_value self) { @@ -1184,6 +1238,7 @@ mrb_str_lines(mrb_state *mrb, mrb_value self) char *p = b, *t; char *e = b + RSTRING_LEN(self); + mrb->c->ci->mid = 0; result = mrb_ary_new(mrb); ai = mrb_gc_arena_save(mrb); while (p < e) { @@ -1230,6 +1285,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, s, "delete_prefix", mrb_str_del_prefix, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "delete_suffix!", mrb_str_del_suffix_bang, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "delete_suffix", mrb_str_del_suffix, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "casecmp", mrb_str_casecmp, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "casecmp?", mrb_str_casecmp_p, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "__lines", mrb_str_lines, MRB_ARGS_NONE()); diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 54afefd74..2d864bdaf 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -18,6 +18,8 @@ #define RSTRUCT_LEN(st) RARRAY_LEN(st) #define RSTRUCT_PTR(st) RARRAY_PTR(st) +#define mrb_struct_p(o) (mrb_type(o) == MRB_TT_STRUCT) + static struct RClass * struct_class(mrb_state *mrb) { @@ -58,18 +60,13 @@ static mrb_value struct_members(mrb_state *mrb, mrb_value s) { mrb_value members = struct_s_members(mrb, mrb_obj_class(mrb, s)); - if (!mrb_array_p(s)) { + if (!mrb_struct_p(s) || RSTRUCT_LEN(s) == 0) { mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { - if (RSTRUCT_LEN(s) == 0) { /* probably uninitialized */ - mrb_ary_resize(mrb, s, RARRAY_LEN(members)); - } - else { - mrb_raisef(mrb, E_TYPE_ERROR, - "struct size differs (%i required %i given)", - RARRAY_LEN(members), RSTRUCT_LEN(s)); - } + mrb_raisef(mrb, E_TYPE_ERROR, + "struct size differs (%i required %i given)", + RARRAY_LEN(members), RSTRUCT_LEN(s)); } return members; } @@ -202,7 +199,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl } else { /* old style: should we warn? */ - mrb_to_str(mrb, name); + mrb_ensure_string_type(mrb, name); id = mrb_obj_to_sym(mrb, name); if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) { mrb_name_error(mrb, id, "identifier %v needs to be constant", name); @@ -213,7 +210,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl } c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass); } - MRB_SET_INSTANCE_TT(c, MRB_TT_ARRAY); + MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT); nstr = mrb_obj_value(c); mrb_iv_set(mrb, nstr, MRB_SYM(__members__), members); @@ -362,7 +359,7 @@ mrb_struct_init_copy(mrb_state *mrb, mrb_value copy) if (!mrb_obj_is_instance_of(mrb, s, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } - if (!mrb_array_p(s)) { + if (!mrb_struct_p(s)) { mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } mrb_ary_replace(mrb, copy, s); @@ -435,7 +432,7 @@ mrb_struct_aref(mrb_state *mrb, mrb_value s) if (mrb_symbol_p(idx)) { return struct_aref_sym(mrb, s, mrb_symbol(idx)); } - return struct_aref_int(mrb, s, mrb_int(mrb, idx)); + return struct_aref_int(mrb, s, mrb_as_int(mrb, idx)); } static mrb_value @@ -499,7 +496,7 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) return mrb_struct_aset_sym(mrb, s, mrb_symbol(idx), val); } - i = mrb_int(mrb, idx); + i = mrb_as_int(mrb, idx); if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) { mrb_raisef(mrb, E_INDEX_ERROR, diff --git a/mrbgems/mruby-struct/test/struct.rb b/mrbgems/mruby-struct/test/struct.rb index 93930730b..db0fa56d8 100644 --- a/mrbgems/mruby-struct/test/struct.rb +++ b/mrbgems/mruby-struct/test/struct.rb @@ -136,7 +136,7 @@ end assert('Struct#to_h') do s = Struct.new(:white, :red, :green).new('ruuko', 'yuzuki', 'hitoe') - assert_equal(:white => 'ruuko', :red => 'yuzuki', :green => 'hitoe') { s.to_h } + assert_equal({:white => 'ruuko', :red => 'yuzuki', :green => 'hitoe'}) { s.to_h } end assert('Struct#values_at') do diff --git a/mrbgems/mruby-inline-struct/mrbgem.rake b/mrbgems/mruby-test-inline-struct/mrbgem.rake index 91ad9f44b..6cbca5417 100644 --- a/mrbgems/mruby-inline-struct/mrbgem.rake +++ b/mrbgems/mruby-test-inline-struct/mrbgem.rake @@ -1,4 +1,4 @@ -MRuby::Gem::Specification.new('mruby-inline-struct') do |spec| +MRuby::Gem::Specification.new('mruby-test-inline-struct') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'inline structure' diff --git a/mrbgems/mruby-inline-struct/test/inline.c b/mrbgems/mruby-test-inline-struct/test/inline.c index 6764b1af4..7537bffc6 100644 --- a/mrbgems/mruby-inline-struct/test/inline.c +++ b/mrbgems/mruby-test-inline-struct/test/inline.c @@ -57,7 +57,8 @@ static mrb_value istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self) { char *ptr; - mrb_get_args(mrb, "I", &ptr); + struct RClass *klass = mrb_class_get(mrb, "InlineStructTest"); + mrb_get_args(mrb, "I", &ptr, klass); return mrb_bool_value(ptr[0] == 's'); } @@ -69,7 +70,7 @@ istruct_test_mutate(mrb_state *mrb, mrb_value self) return mrb_nil_value(); } -void mrb_mruby_inline_struct_gem_test(mrb_state *mrb) +void mrb_mruby_test_inline_struct_gem_test(mrb_state *mrb) { struct RClass *cls; diff --git a/mrbgems/mruby-inline-struct/test/inline.rb b/mrbgems/mruby-test-inline-struct/test/inline.rb index f959a17c4..f959a17c4 100644 --- a/mrbgems/mruby-inline-struct/test/inline.rb +++ b/mrbgems/mruby-test-inline-struct/test/inline.rb diff --git a/mrbgems/mruby-test/driver.c b/mrbgems/mruby-test/driver.c index 958e87dd1..21e272536 100644 --- a/mrbgems/mruby-test/driver.c +++ b/mrbgems/mruby-test/driver.c @@ -220,14 +220,14 @@ mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose) mrbtest = mrb_define_module(mrb, "Mrbtest"); - mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX)); - mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN)); - mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); - #ifndef MRB_NO_FLOAT #ifdef MRB_USE_FLOAT32 +#ifdef MRB_WORDBOX_NO_FLOAT_TRUNCATE mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-5)); #else + mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-4)); +#endif +#else mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-10)); #endif #endif diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 2a5e9dd6b..6b9762acf 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -4,10 +4,6 @@ ** See Copyright Notice in mruby.h */ -#ifndef MRB_NO_FLOAT -#include <math.h> -#endif - #include <mruby.h> #include <mruby/class.h> #include <mruby/data.h> @@ -20,6 +16,7 @@ #include <string.h> #endif + #include <stdlib.h> #ifndef _WIN32 #include <unistd.h> @@ -85,8 +82,12 @@ double round(double x) { /** end of Time class configuration */ -#ifndef NO_GETTIMEOFDAY -# ifdef _WIN32 +#if (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(CLOCK_REALTIME) +# define USE_CLOCK_GETTIME +#endif + +#if !defined(NO_GETTIMEOFDAY) +# if defined(_WIN32) && !defined(USE_CLOCK_GETTIME) # define WIN32_LEAN_AND_MEAN /* don't include winsock.h */ # include <windows.h> # define gettimeofday my_gettimeofday @@ -177,17 +178,6 @@ timegm(struct tm *tm) * second level. Also, there are only 2 timezones, namely UTC and LOCAL. */ -typedef struct mrb_timezone_name { - const char name[8]; - size_t len; -} mrb_timezone_name; - -static const mrb_timezone_name timezone_names[] = { - { "none", sizeof("none") - 1 }, - { "UTC", sizeof("UTC") - 1 }, - { "LOCAL", sizeof("LOCAL") - 1 }, -}; - #ifndef MRB_NO_STDIO static const char mon_names[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", @@ -389,7 +379,7 @@ current_mrb_time(mrb_state *mrb) sec = ts.tv_sec; usec = ts.tv_nsec / 1000; } -#elif (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(CLOCK_REALTIME) +#elif defined(USE_CLOCK_GETTIME) { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); @@ -690,19 +680,35 @@ mrb_time_year(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(tm->datetime.tm_year + 1900); } +static size_t +time_zonename(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t len) +{ +#if defined(_MSC_VER) && _MSC_VER < 1900 || defined(__MINGW64__) || defined(__MINGW32__) + struct tm datetime = {0}; + time_t utc_sec = timegm(&tm->datetime); + int offset = abs((int)(utc_sec - tm->sec) / 60); + datetime.tm_year = 100; + datetime.tm_hour = offset / 60; + datetime.tm_min = offset % 60; + buf[0] = utc_sec < tm->sec ? '-' : '+'; + return strftime(buf+1, len-1, "%H%M", &datetime) + 1; +#else + return strftime(buf, len, "%z", &tm->datetime); +#endif +} + /* 15.2.19.7.33 */ /* Returns name of time's timezone. */ static mrb_value mrb_time_zone(mrb_state *mrb, mrb_value self) { - struct mrb_time *tm; - - tm = time_get_ptr(mrb, self); - if (tm->timezone <= MRB_TIMEZONE_NONE) return mrb_nil_value(); - if (tm->timezone >= MRB_TIMEZONE_LAST) return mrb_nil_value(); - return mrb_str_new_static(mrb, - timezone_names[tm->timezone].name, - timezone_names[tm->timezone].len); + struct mrb_time *tm = time_get_ptr(mrb, self); + if (tm->timezone == MRB_TIMEZONE_UTC) { + return mrb_str_new_lit(mrb, "UTC"); + } + char buf[64]; + size_t len = time_zonename(mrb, tm, buf, sizeof(buf)); + return mrb_str_new(mrb, buf, len); } /* 15.2.19.7.4 */ @@ -886,7 +892,7 @@ mrb_time_min(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(tm->datetime.tm_min); } -/* 15.2.19.7.21 and 15.2.19.7.22 */ +/* 15.2.19.7.21 (mon) and 15.2.19.7.22 (month) */ /* Returns month of time. */ static mrb_value mrb_time_mon(mrb_state *mrb, mrb_value self) @@ -938,7 +944,7 @@ mrb_time_to_i(mrb_state *mrb, mrb_value self) } /* 15.2.19.7.26 */ -/* Returns an Integer with the time since the epoch in microseconds. */ +/* Returns the number of microseconds for time. */ static mrb_value mrb_time_usec(mrb_state *mrb, mrb_value self) { @@ -972,44 +978,20 @@ mrb_time_utc_p(mrb_state *mrb, mrb_value self) return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC); } -static size_t -time_to_s_utc(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len) -{ - return strftime(buf, buf_len, TO_S_FMT "UTC", &tm->datetime); -} - -static size_t -time_to_s_local(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len) -{ -#if defined(_MSC_VER) && _MSC_VER < 1900 || defined(__MINGW64__) || defined(__MINGW32__) - struct tm datetime = {0}; - time_t utc_sec = timegm(&tm->datetime); - size_t len; - int offset; - - if (utc_sec == (time_t)-1) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time"); - } - offset = abs((int)(utc_sec - tm->sec) / 60); - datetime.tm_year = 100; - datetime.tm_hour = offset / 60; - datetime.tm_min = offset % 60; - len = strftime(buf, buf_len, TO_S_FMT, &tm->datetime); - buf[len++] = utc_sec < tm->sec ? '-' : '+'; - - return len + strftime(buf + len, buf_len - len, "%H%M", &datetime); -#else - return strftime(buf, buf_len, TO_S_FMT "%z", &tm->datetime); -#endif -} - static mrb_value mrb_time_to_s(mrb_state *mrb, mrb_value self) { - char buf[64]; struct mrb_time *tm = time_get_ptr(mrb, self); - mrb_bool utc = tm->timezone == MRB_TIMEZONE_UTC; - size_t len = (utc ? time_to_s_utc : time_to_s_local)(mrb, tm, buf, sizeof(buf)); + char buf[64]; + size_t len; + + if (tm->timezone == MRB_TIMEZONE_UTC) { + len = strftime(buf, sizeof(buf), TO_S_FMT "UTC", &tm->datetime); + } + else { + len = strftime(buf, sizeof(buf), TO_S_FMT, &tm->datetime); + len += time_zonename(mrb, tm, buf+len, sizeof(buf)-len); + } mrb_value str = mrb_str_new(mrb, buf, len); RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); return str; diff --git a/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb b/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb index 774562398..664008d1c 100644 --- a/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +++ b/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb @@ -1,5 +1,5 @@ -def self.include (*modules) +def self.include(*modules) self.class.include(*modules) end diff --git a/mrblib/10error.rb b/mrblib/10error.rb index 054603514..aa9da91bb 100644 --- a/mrblib/10error.rb +++ b/mrblib/10error.rb @@ -2,8 +2,8 @@ class ArgumentError < StandardError end -# ISO 15.2.25 says "LocalJumpError < StandardError" -class LocalJumpError < ScriptError +# ISO 15.2.25 +class LocalJumpError < StandardError end # ISO 15.2.26 diff --git a/mrblib/array.rb b/mrblib/array.rb index 18b729128..6b4f74b96 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -4,7 +4,6 @@ # # ISO 15.2.12 class Array - ## # Calls the given block for each element of +self+ # and pass the respective element. @@ -193,13 +192,6 @@ class Array return block.call if ret.nil? && block ret end -end - -## -# Array is enumerable -class Array - # ISO 15.2.12.3 - include Enumerable ## # Sort all elements and replace +self+ with these @@ -276,4 +268,10 @@ class Array def to_a self end + alias entries to_a + + ## + # Array is enumerable + # ISO 15.2.12.3 + include Enumerable end diff --git a/mrblib/hash.rb b/mrblib/hash.rb index 085536c6c..ac70f4c70 100644 --- a/mrblib/hash.rb +++ b/mrblib/hash.rb @@ -4,6 +4,12 @@ # ISO 15.2.13 class Hash ## + # Hash is enumerable + # + # ISO 15.2.13.3 + include Enumerable + + ## # Equality---Two hashes are equal if they each contain the same number # of keys and if each key-value pair is equal to (according to # <code>Object#==</code>) the corresponding elements in the other @@ -297,11 +303,3 @@ class Hash h end end - -## -# Hash is enumerable -# -# ISO 15.2.13.3 -class Hash - include Enumerable -end diff --git a/mrblib/range.rb b/mrblib/range.rb index 36886d50c..4a8e10f30 100644 --- a/mrblib/range.rb +++ b/mrblib/range.rb @@ -3,6 +3,11 @@ # # ISO 15.2.14 class Range + ## + # Range is enumerable + # + # ISO 15.2.14.3 + include Enumerable ## # Calls the given block for each element of +self+ @@ -15,7 +20,7 @@ class Range val = self.begin last = self.end - if val.kind_of?(Fixnum) && last.nil? + if val.kind_of?(Integer) && last.nil? i = val while true block.call(i) @@ -32,7 +37,7 @@ class Range end end - if val.kind_of?(Integer) && last.kind_of?(Integer) # fixnums are special + if val.kind_of?(Integer) && last.kind_of?(Integer) # integers are special lim = last lim += 1 unless exclude_end? i = val @@ -74,16 +79,19 @@ class Range h end + ## + # call-seq: + # rng.to_a -> array + # rng.entries -> array + # + # Returns an array containing the items in the range. + # + # (1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7] + # (1..).to_a #=> RangeError: cannot convert endless range to an array def to_a - raise RangeError, "cannot convert endless range to an array" if self.last.nil? + a = __num_to_a + return a if a super end -end - -## -# Range is enumerable -# -# ISO 15.2.14.3 -class Range - include Enumerable + alias entries to_a end diff --git a/mrblib/string.rb b/mrblib/string.rb index 675026e73..2b3178688 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -42,32 +42,6 @@ class String self end - # private method for gsub/sub - def __sub_replace(pre, m, post) - s = "" - i = 0 - while j = index("\\", i) - break if j == length-1 - t = case self[j+1] - when "\\" - "\\" - when "`" - pre - when "&", "0" - m - when "'" - post - when "1", "2", "3", "4", "5", "6", "7", "8", "9" - "" - else - self[j, 2] - end - s += self[i, j-i] + t - i = j + 2 - end - s + self[i, length-i] - end - ## # Replace all matches of +pattern+ with +replacement+. # Call block (if given) for each match and replace @@ -84,9 +58,6 @@ class String if args.length == 2 && block block = nil end - if !replace.nil? || !block - replace.__to_str - end offset = 0 result = [] while found = index(pattern, offset) @@ -95,7 +66,7 @@ class String result << if block block.call(pattern).to_s else - replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "") + self.__sub_replace(replace, pattern, found) end if plen == 0 result << self[offset, 1] @@ -144,25 +115,20 @@ class String end pattern, replace = *args - pattern.__to_str if args.length == 2 && block block = nil end - unless block - replace.__to_str - end result = [] - this = dup found = index(pattern) - return this unless found - result << this[0, found] + return self.dup unless found + result << self[0, found] offset = found + pattern.length result << if block block.call(pattern).to_s else - replace.__sub_replace(this[0, found], pattern, this[offset..-1] || "") + self.__sub_replace(replace, pattern, found) end - result << this[offset..-1] if offset < length + result << self[offset..-1] if offset < length result.join end diff --git a/src/array.c b/src/array.c index e83f7e2d8..c100591eb 100644 --- a/src/array.c +++ b/src/array.c @@ -29,7 +29,7 @@ ary_new_capa(mrb_state *mrb, mrb_int capa) } blen = capa * sizeof(mrb_value); - a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); + a = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class); if (capa <= MRB_ARY_EMBED_LEN_MAX) { ARY_SET_EMBED_LEN(a, 0); } @@ -578,7 +578,7 @@ mrb_ary_shift(mrb_state *mrb, mrb_value self) return val; } -MRB_API mrb_value +static mrb_value mrb_ary_shift_m(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); @@ -591,6 +591,7 @@ mrb_ary_shift_m(mrb_state *mrb, mrb_value self) }; ary_modify_check(mrb, a); if (len == 0 || n == 0) return mrb_ary_new(mrb); + if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array shift"); if (n > len) n = len; val = mrb_ary_new_from_values(mrb, n, ARY_PTR(a)); if (ARY_SHARED_P(a)) { @@ -693,19 +694,6 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) return self; } -MRB_API mrb_value -mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) -{ - struct RArray *a = mrb_ary_ptr(ary); - mrb_int len = ARY_LEN(a); - - /* range check */ - if (n < 0) n += len; - if (n < 0 || len <= n) return mrb_nil_value(); - - return ARY_PTR(a)[n]; -} - MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) { @@ -754,13 +742,16 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val /* range check */ if (head < 0) { head += alen; - if (head < 0) { - mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); - } + if (head < 0) goto out_of_range; + } + if (head > ARY_MAX_SIZE - len) { + out_of_range: + mrb_raisef(mrb, E_INDEX_ERROR, "index %i is out of array", head); } tail = head + len; if (alen < len || alen < tail) { len = alen - head; + tail = head + len; } /* size check */ @@ -786,12 +777,10 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val argv = &rpl; } if (head >= alen) { - if (head > ARY_MAX_SIZE - argc) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", head); - } + if (head > ARY_MAX_SIZE - argc) goto out_of_range; len = head + argc; if (len > ARY_CAPA(a)) { - ary_expand_capa(mrb, a, head + argc); + ary_expand_capa(mrb, a, len); } ary_fill_with_nil(ARY_PTR(a) + alen, head - alen); if (argc > 0) { @@ -803,7 +792,8 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val mrb_int newlen; if (alen - len > ARY_MAX_SIZE - argc) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %i too big", alen + argc - len); + head = alen + argc - len; + goto out_of_range; } newlen = alen + argc - len; if (newlen > ARY_CAPA(a)) { @@ -812,7 +802,6 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val if (len != argc) { mrb_value *ptr = ARY_PTR(a); - tail = head + len; value_move(ptr + head + argc, ptr + tail, alen - tail); ARY_SET_LEN(a, newlen); } @@ -843,7 +832,7 @@ ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len) return mrb_ary_new_from_values(mrb, len, ARY_PTR(a)+beg); } ary_make_shared(mrb, a); - b = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); + b = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class); b->as.heap.ptr = a->as.heap.ptr + beg; b->as.heap.len = len; b->as.heap.aux.shared = a->as.heap.aux.shared; @@ -1095,7 +1084,7 @@ mrb_ary_index_m(mrb_state *mrb, mrb_value self) for (i = 0; i < RARRAY_LEN(self); i++) { if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { - return mrb_fixnum_value(i); + return mrb_int_value(mrb, i); } } return mrb_nil_value(); @@ -1109,7 +1098,7 @@ mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) for (i = RARRAY_LEN(self) - 1; i >= 0; i--) { if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { - return mrb_fixnum_value(i); + return mrb_int_value(mrb, i); } if (i > (len = RARRAY_LEN(self))) { i = len; @@ -1148,7 +1137,7 @@ mrb_ary_size(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - return mrb_fixnum_value(ARY_LEN(a)); + return mrb_int_value(mrb, ARY_LEN(a)); } MRB_API mrb_value @@ -1190,15 +1179,16 @@ mrb_ary_empty_p(mrb_state *mrb, mrb_value self) } MRB_API mrb_value -mrb_ary_entry(mrb_value ary, mrb_int offset) +mrb_ary_entry(mrb_value ary, mrb_int n) { - if (offset < 0) { - offset += RARRAY_LEN(ary); - } - if (offset < 0 || RARRAY_LEN(ary) <= offset) { - return mrb_nil_value(); - } - return RARRAY_PTR(ary)[offset]; + struct RArray *a = mrb_ary_ptr(ary); + mrb_int len = ARY_LEN(a); + + /* range check */ + if (n < 0) n += len; + if (n < 0 || len <= n) return mrb_nil_value(); + + return ARY_PTR(a)[n]; } static mrb_value @@ -1292,6 +1282,7 @@ mrb_ary_eq(mrb_state *mrb, mrb_value ary1) { mrb_value ary2 = mrb_get_arg1(mrb); + mrb->c->ci->mid = 0; if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); if (!mrb_array_p(ary2)) { return mrb_false_value(); @@ -1306,6 +1297,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) { mrb_value ary2 = mrb_get_arg1(mrb); + mrb->c->ci->mid = 0; if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0); if (!mrb_array_p(ary2)) { return mrb_nil_value(); diff --git a/src/backtrace.c b/src/backtrace.c index 6e7e66f8c..d6648cc43 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -32,44 +32,64 @@ mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); static void each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) { - ptrdiff_t i; - int n = 0; - if (ciidx >= mrb->c->ciend - mrb->c->cibase) ciidx = 10; /* ciidx is broken... */ - for (i=ciidx; i >= 0; i--) { + for (ptrdiff_t i=ciidx; i >= 0; i--) { struct backtrace_location loc; mrb_callinfo *ci; - const mrb_irep *irep; + const mrb_irep *irep = 0; const mrb_code *pc; uint32_t idx; ci = &mrb->c->cibase[i]; - if (!ci->proc) continue; - if (MRB_PROC_CFUNC_P(ci->proc)) continue; - - irep = ci->proc->body.irep; - if (!irep) continue; - - if (mrb->c->cibase[i].pc) { - pc = &mrb->c->cibase[i].pc[-1]; + if (!ci->proc || MRB_PROC_CFUNC_P(ci->proc)) { + if (!ci->mid) continue; + loc.lineno = -1; + idx = 0; } else { - continue; + irep = ci->proc->body.irep; + if (!irep) continue; + if (mrb->c->cibase[i].pc) { + pc = &mrb->c->cibase[i].pc[-1]; + } + else { + continue; + } + idx = (uint32_t)(pc - irep->iseq); + loc.lineno = mrb_debug_get_line(mrb, irep, idx); + } + loc.method_id = ci->mid; + if (loc.lineno == -1) { + for (ptrdiff_t j=i-1; j >= 0; j--) { + ci = &mrb->c->cibase[j]; + + if (!ci->proc) continue; + if (MRB_PROC_CFUNC_P(ci->proc)) continue; + + irep = ci->proc->body.irep; + if (!irep) continue; + + if (mrb->c->cibase[j].pc) { + pc = &mrb->c->cibase[j].pc[-1]; + } + else { + continue; + } + + idx = (uint32_t)(pc - irep->iseq); + loc.lineno = mrb_debug_get_line(mrb, irep, idx); + if (loc.lineno > 0) break; + } } - - idx = (uint32_t)(pc - irep->iseq); - loc.lineno = mrb_debug_get_line(mrb, irep, idx); - if (n++ == 0 && loc.lineno == -1 && ci->acc < 0) continue; loc.filename = mrb_debug_get_filename(mrb, irep, idx); if (!loc.filename) { loc.filename = "(unknown)"; } - loc.method_id = ci->mid; func(mrb, &loc, data); } } @@ -82,22 +102,24 @@ print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) mrb_int i; mrb_int n = RARRAY_LEN(backtrace); mrb_value *loc, mesg; - FILE *stream = stderr; if (n != 0) { - fprintf(stream, "trace (most recent call last):\n"); + if (n > 1) { + fprintf(stderr, "trace (most recent call last):\n"); + } for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) { if (mrb_string_p(*loc)) { - fprintf(stream, "\t[%d] %.*s\n", + fprintf(stderr, "\t[%d] %.*s\n", (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); } } if (mrb_string_p(*loc)) { - fprintf(stream, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); + fprintf(stderr, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); } } mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); - fprintf(stream, "%.*s\n", (int)RSTRING_LEN(mesg), RSTRING_PTR(mesg)); + fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); + fputc('\n', stderr); } /* mrb_print_backtrace diff --git a/src/cdump.c b/src/cdump.c new file mode 100644 index 000000000..ecc27d9a1 --- /dev/null +++ b/src/cdump.c @@ -0,0 +1,468 @@ +/* +** dump.c - mruby binary dumper (mrbc binary format) +** +** See Copyright Notice in mruby.h +*/ + +#include <mruby.h> +#include <mruby/string.h> +#include <mruby/dump.h> +#include <mruby/irep.h> +#include <mruby/debug.h> + +#include <string.h> + +#ifndef MRB_NO_STDIO + +#ifndef MRB_NO_FLOAT +#include <mruby/endian.h> +#define MRB_FLOAT_FMT "%.17g" +#endif + +static int +cdump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp) +{ + if (p->tt & IREP_TT_NFLAG) { /* number */ + switch (p->tt) { +#ifdef MRB_64BIT + case IREP_TT_INT64: + if (p->u.i64 < INT32_MIN || INT32_MAX < p->u.i64) { + fprintf(fp, "{IREP_TT_INT64, {.i64=%" PRId64 "}},\n", p->u.i64); + } + else { + fprintf(fp, "{IREP_TT_INT32, {.i32=%" PRId32 "}},\n", (int32_t)p->u.i64); + } + break; +#endif + case IREP_TT_INT32: + fprintf(fp, "{IREP_TT_INT32, {.i32=%" PRId32 "}},\n", p->u.i32); + break; + case IREP_TT_FLOAT: +#ifndef MRB_NO_FLOAT + if (p->u.f == 0) { + fprintf(fp, "{IREP_TT_FLOAT, {.f=%#.1f}},\n", p->u.f); + } + else { + fprintf(fp, "{IREP_TT_FLOAT, {.f=" MRB_FLOAT_FMT "}},\n", p->u.f); + } +#endif + break; + case IREP_TT_BIGINT: + { + const char *s = p->u.str; + int len = s[0]+2; + fputs("{IREP_TT_BIGINT, {\"", fp); + for (int i=0; i<len; i++) { + fprintf(fp, "\\x%02x", (int)s[i]&0xff); + } + fputs("\"}},\n", fp); + } + break; + } + } + else { /* string */ + int i, len = p->tt>>2; + const char *s = p->u.str; + fprintf(fp, "{IREP_TT_STR|(%d<<2), {\"", len); + for (i=0; i<len; i++) { + fprintf(fp, "\\x%02x", (int)s[i]&0xff); + } + fputs("\"}},\n", fp); + } + return MRB_DUMP_OK; +} + +static mrb_bool +sym_name_word_p(const char *name, mrb_int len) +{ + if (len == 0) return FALSE; + if (name[0] != '_' && !ISALPHA(name[0])) return FALSE; + for (int i = 1; i < len; i++) { + if (name[i] != '_' && !ISALNUM(name[i])) return FALSE; + } + return TRUE; +} + +static mrb_bool +sym_name_with_equal_p(const char *name, mrb_int len) +{ + return len >= 2 && name[len-1] == '=' && sym_name_word_p(name, len-1); +} + +static mrb_bool +sym_name_with_question_mark_p(const char *name, mrb_int len) +{ + return len >= 2 && name[len-1] == '?' && sym_name_word_p(name, len-1); +} + +static mrb_bool +sym_name_with_bang_p(const char *name, mrb_int len) +{ + return len >= 2 && name[len-1] == '!' && sym_name_word_p(name, len-1); +} + +static mrb_bool +sym_name_ivar_p(const char *name, mrb_int len) +{ + return len >= 2 && name[0] == '@' && sym_name_word_p(name+1, len-1); +} + +static mrb_bool +sym_name_cvar_p(const char *name, mrb_int len) +{ + return len >= 3 && name[0] == '@' && sym_name_ivar_p(name+1, len-1); +} + +#define OPERATOR_SYMBOL(sym_name, name) {name, sym_name, sizeof(sym_name)-1} +struct operator_symbol { + const char *name; + const char *sym_name; + uint16_t sym_name_len; +}; +static const struct operator_symbol operator_table[] = { + OPERATOR_SYMBOL("!", "not"), + OPERATOR_SYMBOL("%", "mod"), + OPERATOR_SYMBOL("&", "and"), + OPERATOR_SYMBOL("*", "mul"), + OPERATOR_SYMBOL("+", "add"), + OPERATOR_SYMBOL("-", "sub"), + OPERATOR_SYMBOL("/", "div"), + OPERATOR_SYMBOL("<", "lt"), + OPERATOR_SYMBOL(">", "gt"), + OPERATOR_SYMBOL("^", "xor"), + OPERATOR_SYMBOL("`", "tick"), + OPERATOR_SYMBOL("|", "or"), + OPERATOR_SYMBOL("~", "neg"), + OPERATOR_SYMBOL("!=", "neq"), + OPERATOR_SYMBOL("!~", "nmatch"), + OPERATOR_SYMBOL("&&", "andand"), + OPERATOR_SYMBOL("**", "pow"), + OPERATOR_SYMBOL("+@", "plus"), + OPERATOR_SYMBOL("-@", "minus"), + OPERATOR_SYMBOL("<<", "lshift"), + OPERATOR_SYMBOL("<=", "le"), + OPERATOR_SYMBOL("==", "eq"), + OPERATOR_SYMBOL("=~", "match"), + OPERATOR_SYMBOL(">=", "ge"), + OPERATOR_SYMBOL(">>", "rshift"), + OPERATOR_SYMBOL("[]", "aref"), + OPERATOR_SYMBOL("||", "oror"), + OPERATOR_SYMBOL("<=>", "cmp"), + OPERATOR_SYMBOL("===", "eqq"), + OPERATOR_SYMBOL("[]=", "aset"), +}; + +static const char* +sym_operator_name(const char *sym_name, mrb_int len) +{ + mrb_sym table_size = sizeof(operator_table)/sizeof(struct operator_symbol); + if (operator_table[table_size-1].sym_name_len < len) return NULL; + + mrb_sym start, idx; + int cmp; + const struct operator_symbol *op_sym; + for (start = 0; table_size != 0; table_size/=2) { + idx = start+table_size/2; + op_sym = &operator_table[idx]; + cmp = (int)len-(int)op_sym->sym_name_len; + if (cmp == 0) { + cmp = memcmp(sym_name, op_sym->sym_name, len); + if (cmp == 0) return op_sym->name; + } + if (0 < cmp) { + start = ++idx; + --table_size; + } + } + return NULL; +} + +static const char* +sym_var_name(mrb_state *mrb, const char *initname, const char *key, int n) +{ + char buf[32]; + mrb_value s = mrb_str_new_cstr(mrb, initname); + mrb_str_cat_lit(mrb, s, "_"); + mrb_str_cat_cstr(mrb, s, key); + mrb_str_cat_lit(mrb, s, "_"); + snprintf(buf, sizeof(buf), "%d", n); + mrb_str_cat_cstr(mrb, s, buf); + return RSTRING_PTR(s); +} + +static int +cdump_sym(mrb_state *mrb, mrb_sym sym, const char *var_name, int idx, mrb_value init_syms_code, FILE *fp) +{ + if (sym == 0) return MRB_DUMP_INVALID_ARGUMENT; + + mrb_int len; + const char *name = mrb_sym_name_len(mrb, sym, &len), *op_name; + if (!name) return MRB_DUMP_INVALID_ARGUMENT; + if (sym_name_word_p(name, len)) { + fprintf(fp, "MRB_SYM(%s)", name); + } + else if (sym_name_with_equal_p(name, len)) { + fprintf(fp, "MRB_SYM_E(%.*s)", (int)(len-1), name); + } + else if (sym_name_with_question_mark_p(name, len)) { + fprintf(fp, "MRB_SYM_Q(%.*s)", (int)(len-1), name); + } + else if (sym_name_with_bang_p(name, len)) { + fprintf(fp, "MRB_SYM_B(%.*s)", (int)(len-1), name); + } + else if (sym_name_ivar_p(name, len)) { + fprintf(fp, "MRB_IVSYM(%s)", name+1); + } + else if (sym_name_cvar_p(name, len)) { + fprintf(fp, "MRB_CVSYM(%s)", name+2); + } + else if ((op_name = sym_operator_name(name, len))) { + fprintf(fp, "MRB_OPSYM(%s)", op_name); + } + else { + char buf[32]; + mrb_value name_obj = mrb_str_new(mrb, name, len); + mrb_str_cat_lit(mrb, init_syms_code, " "); + mrb_str_cat_cstr(mrb, init_syms_code, var_name); + snprintf(buf, sizeof(buf), "[%d] = ", idx); + mrb_str_cat_cstr(mrb, init_syms_code, buf); + mrb_str_cat_lit(mrb, init_syms_code, "mrb_intern_lit(mrb, "); + mrb_str_cat_str(mrb, init_syms_code, mrb_str_dump(mrb, name_obj)); + mrb_str_cat_lit(mrb, init_syms_code, ");\n"); + fputs("0", fp); + } + fputs(", ", fp); + return MRB_DUMP_OK; +} + +static int +cdump_syms(mrb_state *mrb, const char *name, const char *key, int n, int syms_len, const mrb_sym *syms, mrb_value init_syms_code, FILE *fp) +{ + int ai = mrb_gc_arena_save(mrb); + mrb_int code_len = RSTRING_LEN(init_syms_code); + const char *var_name = sym_var_name(mrb, name, key, n); + fprintf(fp, "mrb_DEFINE_SYMS_VAR(%s, %d, (", var_name, syms_len); + for (int i=0; i<syms_len; i++) { + cdump_sym(mrb, syms[i], var_name, i, init_syms_code, fp); + } + fputs("), ", fp); + if (code_len == RSTRING_LEN(init_syms_code)) fputs("const", fp); + fputs(");\n", fp); + mrb_gc_arena_restore(mrb, ai); + return MRB_DUMP_OK; +} + +//Handle the simple/common case of debug_info: +// - 1 file associated with a single irep +// - mrb_debug_line_ary format only +static int +simple_debug_info(mrb_irep_debug_info *info) +{ + if (!info || info->flen != 1) { + return 0; + } + return 1; +} + +//Adds debug information to c-structs and +//adds filenames in init_syms_code block +static int +cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, + mrb_value init_syms_code, FILE *fp) +{ + char buffer[256]; + const char *filename; + mrb_int file_len; + int len, i; + const char *line_type = "mrb_debug_line_ary"; + + if (!simple_debug_info(info)) + return MRB_DUMP_INVALID_IREP; + + len = info->files[0]->line_entry_count; + + filename = mrb_sym_name_len(mrb, info->files[0]->filename_sym, &file_len); + snprintf(buffer, sizeof(buffer), " %s_debug_file_%d.filename_sym = mrb_intern_lit(mrb,\"", + name, n); + mrb_str_cat_cstr(mrb, init_syms_code, buffer); + mrb_str_cat_cstr(mrb, init_syms_code, filename); + mrb_str_cat_cstr(mrb, init_syms_code, "\");\n"); + + switch (info->files[0]->line_type) { + case mrb_debug_line_ary: + fprintf(fp, "static uint16_t %s_debug_lines_%d[%d] = {", name, n, len); + for (i=0; i<len; i++) { + if (i%10 == 0) fputs("\n", fp); + fprintf(fp, "0x%04x,", info->files[0]->lines.ary[i]); + } + fputs("};\n", fp); + break; + + case mrb_debug_line_flat_map: + line_type = "mrb_debug_line_flat_map"; + fprintf(fp, "static struct mrb_irep_debug_info_line %s_debug_lines_%d[%d] = {", name, n, len); + for (i=0; i<len; i++) { + mrb_irep_debug_info_line *fmap = &info->files[0]->lines.flat_map[i]; + fprintf(fp, "\t{.start_pos=0x%04x,.line=%d},\n", fmap->start_pos, fmap->line); + } + fputs("};\n", fp); + break; + + case mrb_debug_line_packed_map: + line_type = "mrb_debug_line_packed_map"; + fprintf(fp, "static char %s_debug_lines_%d[] = \"", name, n); + uint8_t *pmap = info->files[0]->lines.packed_map; + for (i=0; i<len; i++) { + fprintf(fp, "\\x%02x", pmap[i]&0xff); + } + fputs("\";\n", fp); + break; + } + fprintf(fp, "static mrb_irep_debug_info_file %s_debug_file_%d = {\n", name, n); + fprintf(fp, "%d, %d, %d, %s, {%s_debug_lines_%d}};\n", + info->files[0]->start_pos, + info->files[0]->filename_sym, + info->files[0]->line_entry_count, + line_type, + name,n); + fprintf(fp, "static mrb_irep_debug_info_file *%s_debug_file_%d_ = &%s_debug_file_%d;\n", name, n, name, n); + + fprintf(fp, "static mrb_irep_debug_info %s_debug_%d = {\n", name, n); + fprintf(fp, "%d, %d, &%s_debug_file_%d_};\n", info->pc_count, info->flen, name, n); + + return MRB_DUMP_OK; +} + +static int +cdump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *name, int n, mrb_value init_syms_code, int *mp) +{ + int i, len; + int max = *mp; + int debug_available = 0; + + /* dump reps */ + if (irep->reps) { + for (i=0,len=irep->rlen; i<len; i++) { + *mp += len; + if (cdump_irep_struct(mrb, irep->reps[i], flags, fp, name, max+i, init_syms_code, mp) != MRB_DUMP_OK) + return MRB_DUMP_INVALID_ARGUMENT; + } + fprintf(fp, "static const mrb_irep *%s_reps_%d[%d] = {\n", name, n, len); + for (i=0,len=irep->rlen; i<len; i++) { + fprintf(fp, " &%s_irep_%d,\n", name, max+i); + } + fputs("};\n", fp); + } + /* dump pool */ + if (irep->pool) { + len=irep->plen; + fprintf(fp, "static const mrb_pool_value %s_pool_%d[%d] = {\n", name, n, len); + for (i=0; i<len; i++) { + if (cdump_pool(mrb, &irep->pool[i], fp) != MRB_DUMP_OK) + return MRB_DUMP_INVALID_ARGUMENT; + } + fputs("};\n", fp); + } + /* dump syms */ + if (irep->syms) { + cdump_syms(mrb, name, "syms", n, irep->slen, irep->syms, init_syms_code, fp); + } + /* dump iseq */ + len=irep->ilen+sizeof(struct mrb_irep_catch_handler)*irep->clen; + fprintf(fp, "static const mrb_code %s_iseq_%d[%d] = {", name, n, len); + for (i=0; i<len; i++) { + if (i%20 == 0) fputs("\n", fp); + fprintf(fp, "0x%02x,", irep->iseq[i]); + } + fputs("};\n", fp); + /* dump lv */ + if (irep->lv) { + cdump_syms(mrb, name, "lv", n, irep->nlocals-1, irep->lv, init_syms_code, fp); + } + /* dump debug */ + if (flags & MRB_DUMP_DEBUG_INFO) { + if(cdump_debug(mrb, name, n, irep->debug_info, + init_syms_code, fp) == MRB_DUMP_OK) { + debug_available = 1; + } + } + + + /* dump irep */ + fprintf(fp, "static const mrb_irep %s_irep_%d = {\n", name, n); + fprintf(fp, " %d,%d,%d,\n", irep->nlocals, irep->nregs, irep->clen); + fprintf(fp, " MRB_IREP_STATIC,%s_iseq_%d,\n", name, n); + if (irep->pool) { + fprintf(fp, " %s_pool_%d,", name, n); + } + else { + fputs( " NULL,", fp); + } + if (irep->syms) { + fprintf(fp, "%s_syms_%d,", name, n); + } + else { + fputs( "NULL,", fp); + } + if (irep->reps) { + fprintf(fp, "%s_reps_%d,\n", name, n); + } + else { + fputs( "NULL,\n", fp); + } + if (irep->lv) { + fprintf(fp, " %s_lv_%d,\n", name, n); + } + else { + fputs( " NULL,\t\t\t\t\t/* lv */\n", fp); + } + if(debug_available) { + fprintf(fp, " &%s_debug_%d,\n", name, n); + } + else { + fputs(" NULL,\t\t\t\t\t/* debug_info */\n", fp); + } + fprintf(fp, " %d,%d,%d,%d,0\n};\n", irep->ilen, irep->plen, irep->slen, irep->rlen); + + return MRB_DUMP_OK; +} + +int +mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname) +{ + if (fp == NULL || initname == NULL || initname[0] == '\0') { + return MRB_DUMP_INVALID_ARGUMENT; + } + if (fprintf(fp, "#include <mruby.h>\n" + "#include <mruby/irep.h>\n" + "#include <mruby/debug.h>\n" + "#include <mruby/proc.h>\n" + "#include <mruby/presym.h>\n" + "\n") < 0) { + return MRB_DUMP_WRITE_FAULT; + } + fputs("#define mrb_BRACED(...) {__VA_ARGS__}\n", fp); + fputs("#define mrb_DEFINE_SYMS_VAR(name, len, syms, qualifier) \\\n", fp); + fputs(" static qualifier mrb_sym name[len] = mrb_BRACED syms\n", fp); + fputs("\n", fp); + mrb_value init_syms_code = mrb_str_new_capa(mrb, 0); + int max = 1; + int n = cdump_irep_struct(mrb, irep, flags, fp, initname, 0, init_syms_code, &max); + if (n != MRB_DUMP_OK) return n; + fprintf(fp, + "%s\n" + "const struct RProc %s[] = {{\n", + (flags & MRB_DUMP_STATIC) ? "static" + : "#ifdef __cplusplus\n" + "extern\n" + "#endif", + initname); + fprintf(fp, "NULL,NULL,MRB_TT_PROC,MRB_GC_RED,0,{&%s_irep_0},NULL,{NULL},\n}};\n", initname); + fputs("static void\n", fp); + fprintf(fp, "%s_init_syms(mrb_state *mrb)\n", initname); + fputs("{\n", fp); + fputs(RSTRING_PTR(init_syms_code), fp); + fputs("}\n", fp); + return MRB_DUMP_OK; +} +#endif diff --git a/src/class.c b/src/class.c index dfd25b371..97a37c54a 100644 --- a/src/class.c +++ b/src/class.c @@ -4,7 +4,6 @@ ** See Copyright Notice in mruby.h */ -#include <stdarg.h> #include <mruby.h> #include <mruby/array.h> #include <mruby/hash.h> @@ -341,7 +340,7 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o) struct RClass *sc, *c; if (o->c->tt == MRB_TT_SCLASS) return; - sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); + sc = MRB_OBJ_ALLOC(mrb, MRB_TT_SCLASS, mrb->class_class); sc->flags |= MRB_FL_CLASS_IS_INHERITED; sc->mt = mt_new(mrb); sc->iv = 0; @@ -800,18 +799,12 @@ mrb_notimplement_m(mrb_state *mrb, mrb_value self) return mrb_nil_value(); } -static mrb_value -to_ary(mrb_state *mrb, mrb_value val) -{ - mrb_check_type(mrb, val, MRB_TT_ARRAY); - return val; -} - -static mrb_value -to_hash(mrb_state *mrb, mrb_value val) +static void +ensure_class_type(mrb_state *mrb, mrb_value val) { - mrb_check_type(mrb, val, MRB_TT_HASH); - return val; + if (!class_ptr_p(val)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", val); + } } #define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss) @@ -819,9 +812,9 @@ to_hash(mrb_state *mrb, mrb_value val) MRB_API mrb_int mrb_get_argc(mrb_state *mrb) { - mrb_int argc = mrb->c->ci->argc; + mrb_int argc = mrb->c->ci->n; - if (argc < 0) { + if (argc == 15) { struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]); argc = ARY_LEN(a); @@ -832,9 +825,9 @@ mrb_get_argc(mrb_state *mrb) MRB_API const mrb_value* mrb_get_argv(mrb_state *mrb) { - mrb_int argc = mrb->c->ci->argc; + mrb_int argc = mrb->c->ci->n; mrb_value *array_argv = mrb->c->ci->stack + 1; - if (argc < 0) { + if (argc == 15) { struct RArray *a = mrb_ary_ptr(*array_argv); array_argv = ARY_PTR(a); @@ -845,21 +838,36 @@ mrb_get_argv(mrb_state *mrb) MRB_API mrb_value mrb_get_arg1(mrb_state *mrb) { - mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->ci->stack + 1; - if (argc < 0) { + mrb_callinfo *ci = mrb->c->ci; + mrb_int argc = ci->n; + mrb_value *array_argv = ci->stack + 1; + if (argc == 15) { struct RArray *a = mrb_ary_ptr(*array_argv); argc = ARY_LEN(a); array_argv = ARY_PTR(a); } + if (argc == 0 && ci->nk == 15) { + mrb_int n = ci->n; + if (n == 15) n = 1; + return ci->stack[n+1]; /* kwhash next to positional arguments */ + } if (argc != 1) { mrb_argnum_error(mrb, argc, 1, 1); } return array_argv[0]; } -void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); +mrb_int mrb_ci_bidx(mrb_callinfo *ci); + +MRB_API mrb_bool +mrb_block_given_p(mrb_state *mrb) +{ + mrb_callinfo *ci = mrb->c->ci; + mrb_value b = ci->stack[mrb_ci_bidx(ci)]; + + return !mrb_nil_p(b); +} /* retrieve arguments from mrb_state. @@ -873,52 +881,53 @@ void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); string mruby type C type note ---------------------------------------------------------------------------------------------- o: Object [mrb_value] - C: Class/Module [mrb_value] + C: Class/Module [mrb_value] when ! follows, the value may be nil S: String [mrb_value] when ! follows, the value may be nil A: Array [mrb_value] when ! follows, the value may be nil H: Hash [mrb_value] when ! follows, the value may be nil s: String [const char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil z: String [const char*] NUL terminated string; z! gives NULL for nil a: Array [const mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil - c: Class/Module [strcut RClass*] + c: Class/Module [strcut RClass*] c! gives NULL for nil f: Integer/Float [mrb_float] i: Integer/Float [mrb_int] b: boolean [mrb_bool] n: String/Symbol [mrb_sym] d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil - I: inline struct [void*] + I: inline struct [void*,struct RClass] I! gives NULL for nil &: block [mrb_value] &! raises exception if no block given *: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack |: optional Following arguments are optional ?: optional given [mrb_bool] true if preceding argument (optional) is given ':': keyword args [mrb_kwargs const] Get keyword arguments + + format modifiers: + + string note + ---------------------------------------------------------------------------------------------- + !: Switch to the alternate mode; The behaviour changes depending on the specifier + +: Request a not frozen object; However, except nil value */ MRB_API mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...) { const char *fmt = format; char c; - mrb_int i = 0; + int i = 0; va_list ap; - mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->ci->stack+1; - mrb_bool argv_on_stack = argc >= 0; + mrb_callinfo *ci = mrb->c->ci; + int argc = ci->n; + const mrb_value *argv = ci->stack+1; + mrb_bool argv_on_stack; mrb_bool opt = FALSE; mrb_bool opt_skip = TRUE; - mrb_bool given = TRUE; - mrb_value kdict; + const mrb_value *pickarg = NULL; /* arguments currently being processed */ + mrb_value kdict = mrb_nil_value(); mrb_bool reqkarg = FALSE; int argc_min = 0, argc_max = 0; - if (!argv_on_stack) { - struct RArray *a = mrb_ary_ptr(*array_argv); - array_argv = ARY_PTR(a); - argc = ARY_LEN(a); - } va_start(ap, format); -#define ARGV array_argv - while ((c = *fmt++)) { switch (c) { case '|': @@ -930,6 +939,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) if (!reqkarg) reqkarg = strchr(fmt, ':') ? TRUE : FALSE; goto check_exit; case '!': + case '+': break; case ':': reqkarg = TRUE; @@ -945,27 +955,85 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } check_exit: - if (reqkarg && argc > argc_min && mrb_hash_p(kdict = ARGV[argc - 1])) { - mrb_hash_check_kdict(mrb, kdict); - argc --; + if (!reqkarg && ci->nk > 0) { + mrb_assert(ci->nk == 15); + kdict = ci->stack[mrb_ci_bidx(ci)-1]; + if (mrb_hash_p(kdict) && mrb_hash_size(mrb, kdict) > 0) { + if (argc < 14) { + ci->n++; + argc++; /* include kdict in normal arguments */ + } + else { + /* 14+1 == 15 so pack first */ + if (argc == 14) { + /* pack arguments and kdict */ + ci->stack[1] = mrb_ary_new_from_values(mrb, argc+1, &ci->stack[1]); + argc = ci->n = 15; + } + else { + /* push kdict to packed arguments */ + mrb_ary_push(mrb, ci->stack[1], kdict); + } + ci->stack[2] = ci->stack[mrb_ci_bidx(ci)]; + } + ci->nk = 0; + } } - else { - kdict = mrb_nil_value(); + if (reqkarg && ci->nk > 0) { + kdict = ci->stack[mrb_ci_bidx(ci)-1]; + mrb_assert(ci->nk == 15); + mrb_assert(mrb_hash_p(kdict)); + } + + argv_on_stack = argc < 15; + if (!argv_on_stack) { + struct RArray *a = mrb_ary_ptr(*argv); + argv = ARY_PTR(a); + argc = ARY_LEN(a); } opt = FALSE; i = 0; while ((c = *format++)) { - mrb_value *argv = ARGV; - mrb_bool altmode; + mrb_bool altmode = FALSE; + mrb_bool needmodify = FALSE; + + for (; *format; format++) { + switch (*format) { + case '!': + if (altmode) goto modifier_exit; /* not accept for multiple '!' */ + altmode = TRUE; + break; + case '+': + if (needmodify) goto modifier_exit; /* not accept for multiple '+' */ + needmodify = TRUE; + break; + default: + goto modifier_exit; + } + } + modifier_exit: switch (c) { case '|': case '*': case '&': case '?': case ':': + if (needmodify) { + bad_needmodify: + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong `%c+` modified specifier`", c); + } break; default: - if (argc <= i) { + if (i < argc) { + pickarg = &argv[i++]; + if (needmodify && !mrb_nil_p(*pickarg)) { + if (mrb_immediate_p(*pickarg)) { + mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", *pickarg); + } + mrb_check_frozen(mrb, mrb_obj_ptr(*pickarg)); + } + } + else { if (opt) { - given = FALSE; + pickarg = NULL; } else { mrb_argnum_error(mrb, argc, argc_min, argc_max); @@ -974,38 +1042,26 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) break; } - if (*format == '!') { - format ++; - altmode = TRUE; - } - else { - altmode = FALSE; - } - switch (c) { case 'o': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - *p = argv[i++]; - } - } - break; case 'C': + case 'S': + case 'A': + case 'H': { mrb_value *p; p = va_arg(ap, mrb_value*); - if (i < argc) { - mrb_value ss; - - ss = argv[i++]; - if (!class_ptr_p(ss)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss); + if (pickarg) { + if (!(altmode && mrb_nil_p(*pickarg))) { + switch (c) { + case 'C': ensure_class_type(mrb, *pickarg); break; + case 'S': mrb_ensure_string_type(mrb, *pickarg); break; + case 'A': mrb_ensure_array_type(mrb, *pickarg); break; + case 'H': mrb_ensure_hash_type(mrb, *pickarg); break; + } } - *p = ss; + *p = *pickarg; } } break; @@ -1014,114 +1070,72 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) struct RClass **p; p = va_arg(ap, struct RClass**); - if (i < argc) { - mrb_value ss; - - ss = argv[i++]; - if (!class_ptr_p(ss)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss); - } - *p = mrb_class_ptr(ss); - } - } - break; - case 'S': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - *p = argv[i++]; - if (!(altmode && mrb_nil_p(*p))) { - mrb_to_str(mrb, *p); - } - } - } - break; - case 'A': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - *p = argv[i++]; - if (!(altmode && mrb_nil_p(*p))) { - *p = to_ary(mrb, *p); + if (pickarg) { + if (altmode && mrb_nil_p(*pickarg)) { + *p = NULL; } - } - } - break; - case 'H': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - *p = argv[i++]; - if (!(altmode && mrb_nil_p(*p))) { - *p = to_hash(mrb, *p); + else { + ensure_class_type(mrb, *pickarg); + *p = mrb_class_ptr(*pickarg); } } } break; case 's': { - mrb_value ss; const char **ps = 0; mrb_int *pl = 0; ps = va_arg(ap, const char**); pl = va_arg(ap, mrb_int*); - if (i < argc) { - ss = argv[i++]; - if (altmode && mrb_nil_p(ss)) { + if (needmodify) goto bad_needmodify; + if (pickarg) { + if (altmode && mrb_nil_p(*pickarg)) { *ps = NULL; *pl = 0; } else { - mrb_to_str(mrb, ss); - *ps = RSTRING_PTR(ss); - *pl = RSTRING_LEN(ss); + mrb_ensure_string_type(mrb, *pickarg); + *ps = RSTRING_PTR(*pickarg); + *pl = RSTRING_LEN(*pickarg); } } } break; case 'z': { - mrb_value ss; const char **ps; ps = va_arg(ap, const char**); - if (i < argc) { - ss = argv[i++]; - if (altmode && mrb_nil_p(ss)) { + if (needmodify) goto bad_needmodify; + if (pickarg) { + if (altmode && mrb_nil_p(*pickarg)) { *ps = NULL; } else { - mrb_to_str(mrb, ss); - *ps = RSTRING_CSTR(mrb, ss); + mrb_ensure_string_type(mrb, *pickarg); + *ps = RSTRING_CSTR(mrb, *pickarg); } } } break; case 'a': { - mrb_value aa; struct RArray *a; const mrb_value **pb; mrb_int *pl; pb = va_arg(ap, const mrb_value**); pl = va_arg(ap, mrb_int*); - if (i < argc) { - aa = argv[i++]; - if (altmode && mrb_nil_p(aa)) { + if (needmodify) goto bad_needmodify; + if (pickarg) { + if (altmode && mrb_nil_p(*pickarg)) { *pb = 0; *pl = 0; } else { - aa = to_ary(mrb, aa); - a = mrb_ary_ptr(aa); + mrb_ensure_array_type(mrb, *pickarg); + a = mrb_ary_ptr(*pickarg); *pb = ARY_PTR(a); *pl = ARY_LEN(a); } @@ -1131,16 +1145,23 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) case 'I': { void* *p; - mrb_value ss; + struct RClass *klass; p = va_arg(ap, void**); - if (i < argc) { - ss = argv[i++]; - if (!mrb_istruct_p(ss)) - { - mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", ss); + klass = va_arg(ap, struct RClass*); + if (pickarg) { + if (altmode && mrb_nil_p(*pickarg)) { + *p = NULL; + } + else { + if (!mrb_obj_is_kind_of(mrb, *pickarg, klass)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not a %C", *pickarg, klass); + } + if (!mrb_istruct_p(*pickarg)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", *pickarg); + } + *p = mrb_istruct_ptr(*pickarg); } - *p = mrb_istruct_ptr(ss); } } break; @@ -1150,8 +1171,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_float *p; p = va_arg(ap, mrb_float*); - if (i < argc) { - *p = mrb_to_flo(mrb, argv[i++]); + if (pickarg) { + *p = mrb_as_float(mrb, *pickarg); } } break; @@ -1161,8 +1182,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_int *p; p = va_arg(ap, mrb_int*); - if (i < argc) { - *p = mrb_integer(mrb_to_int(mrb, argv[i++])); + if (pickarg) { + *p = mrb_as_int(mrb, *pickarg); } } break; @@ -1170,9 +1191,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { mrb_bool *boolp = va_arg(ap, mrb_bool*); - if (i < argc) { - mrb_value b = argv[i++]; - *boolp = mrb_test(b); + if (pickarg) { + *boolp = mrb_test(*pickarg); } } break; @@ -1181,11 +1201,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_sym *symp; symp = va_arg(ap, mrb_sym*); - if (i < argc) { - mrb_value ss; - - ss = argv[i++]; - *symp = to_sym(mrb, ss); + if (pickarg) { + *symp = to_sym(mrb, *pickarg); } } break; @@ -1196,13 +1213,12 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) datap = va_arg(ap, void**); type = va_arg(ap, struct mrb_data_type const*); - if (i < argc) { - mrb_value dd = argv[i++]; - if (altmode && mrb_nil_p(dd)) { + if (pickarg) { + if (altmode && mrb_nil_p(*pickarg)) { *datap = 0; } else { - *datap = mrb_data_get_ptr(mrb, dd, type); + *datap = mrb_data_get_ptr(mrb, *pickarg, type); } } } @@ -1213,12 +1229,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_value *p, *bp; p = va_arg(ap, mrb_value*); - if (mrb->c->ci->argc < 0) { - bp = mrb->c->ci->stack + 2; - } - else { - bp = mrb->c->ci->stack + mrb->c->ci->argc + 1; - } + bp = ci->stack + mrb_ci_bidx(ci); if (altmode && mrb_nil_p(*bp)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); } @@ -1234,7 +1245,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_bool *p; p = va_arg(ap, mrb_bool*); - *p = given; + *p = pickarg ? TRUE : FALSE; } break; @@ -1288,7 +1299,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large"); } - for (j = required; j > 0; j --, kname ++, values ++) { + for (j = required; j > 0; j--, kname++, values++) { mrb_value k = mrb_symbol_value(*kname); if (!mrb_hash_key_p(mrb, ksrc, k)) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "missing keyword: %n", *kname); @@ -1297,7 +1308,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_gc_protect(mrb, *values); } - for (j = kwnum - required; j > 0; j --, kname ++, values ++) { + for (j = kwnum - required; j > 0; j--, kname++, values++) { mrb_value k = mrb_symbol_value(*kname); if (mrb_hash_key_p(mrb, ksrc, k)) { *values = mrb_hash_delete_key(mrb, ksrc, k); @@ -1328,8 +1339,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } -#undef ARGV - if (!c && argc > i) { mrb_argnum_error(mrb, argc, argc_min, argc_max); } @@ -1344,7 +1353,7 @@ boot_defclass(mrb_state *mrb, struct RClass *super) { struct RClass *c; - c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class); + c = MRB_OBJ_ALLOC(mrb, MRB_TT_CLASS, mrb->class_class); if (super) { c->super = super; mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); @@ -1367,7 +1376,7 @@ boot_initmod(mrb_state *mrb, struct RClass *mod) static struct RClass* include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) { - struct RClass *ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); + struct RClass *ic = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, mrb->class_class); if (m->tt == MRB_TT_ICLASS) { m = m->c; } @@ -1435,7 +1444,7 @@ fix_include_module(mrb_state *mrb, struct RBasic *obj, void *data) { struct RClass **m = (struct RClass**)data; - if (obj->tt == MRB_TT_ICLASS && obj->c == m[0] && (obj->flags & MRB_FL_CLASS_IS_ORIGIN) == 0) { + if (obj->tt == MRB_TT_ICLASS && obj->c == m[0] && !MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) { struct RClass *ic = (struct RClass*)obj; include_module_at(mrb, ic, ic, m[1], 1); } @@ -1498,7 +1507,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) else { c0 = c; } - origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c0); + origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c0); origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED; origin->super = c->super; c->super = origin; @@ -1713,7 +1722,11 @@ mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, m static void mc_clear(mrb_state *mrb) { - memset(mrb->cache, 0, MRB_METHOD_CACHE_SIZE*sizeof(mrb->cache[0])); + static const struct mrb_cache_entry ce_zero ={0}; + + for (int i=0; i<MRB_METHOD_CACHE_SIZE; i++) { + mrb->cache[i] = ce_zero; + } } void @@ -2169,7 +2182,7 @@ mrb_class_new(mrb_state *mrb, struct RClass *super) MRB_API struct RClass* mrb_module_new(mrb_state *mrb) { - struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class); + struct RClass *m = MRB_OBJ_ALLOC(mrb, MRB_TT_MODULE, mrb->module_class); boot_initmod(mrb, m); return m; } @@ -2197,6 +2210,7 @@ mrb_obj_class(mrb_state *mrb, mrb_value obj) MRB_API void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) { + if (a == b) return; mrb_method_t m = mrb_method_search(mrb, c, b); if (!MRB_METHOD_CFUNC_P(m)) { @@ -2207,7 +2221,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) } else if (p->color != MRB_GC_RED) { struct RClass *tc = MRB_PROC_TARGET_CLASS(p); - struct REnv *e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL); + struct REnv *e = MRB_OBJ_ALLOC(mrb, MRB_TT_ENV, NULL); e->mid = b; if (tc) { @@ -2216,6 +2230,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) } p->e.env = e; p->flags |= MRB_PROC_ENVSET; + mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)e); } } mrb_define_method_raw(mrb, c, a, m); @@ -2269,6 +2284,8 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass) } } +void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); + static mrb_value mrb_mod_alias(mrb_state *mrb, mrb_value mod) { @@ -2277,6 +2294,7 @@ mrb_mod_alias(mrb_state *mrb, mrb_value mod) mrb_get_args(mrb, "nn", &new_name, &old_name); mrb_alias_method(mrb, c, new_name, old_name); + mrb_method_added(mrb, c, new_name); return mod; } @@ -2389,7 +2407,7 @@ mrb_mod_const_get(mrb_state *mrb, mrb_value mod) } /* const get with class path string */ - path = mrb_ensure_string_type(mrb, path); + mrb_ensure_string_type(mrb, path); ptr = RSTRING_PTR(path); len = RSTRING_LEN(path); off = 0; @@ -2445,6 +2463,7 @@ mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) mrb_sym sym; mrb_get_args(mrb, "n", &sym); + mrb->c->ci->mid = 0; if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) { mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym); @@ -2492,6 +2511,22 @@ mrb_mod_method_defined(mrb_state *mrb, mrb_value mod) return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id)); } +void +mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid) +{ + mrb_sym added; + mrb_value recv = mrb_obj_value(c); + + if (c->tt == MRB_TT_SCLASS) { + added = MRB_SYM(singleton_method_added); + recv = mrb_iv_get(mrb, recv, MRB_SYM(__attached__)); + } + else { + added = MRB_SYM(method_added); + } + mrb_funcall_id(mrb, recv, added, 1, mrb_symbol_value(mid)); +} + mrb_value mrb_mod_define_method_m(mrb_state *mrb, struct RClass *c) { @@ -2516,11 +2551,12 @@ mrb_mod_define_method_m(mrb_state *mrb, struct RClass *c) if (mrb_nil_p(blk)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); } - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class); mrb_proc_copy(p, mrb_proc_ptr(blk)); p->flags |= MRB_PROC_STRICT; MRB_METHOD_FROM_PROC(m, p); mrb_define_method_raw(mrb, c, mid, m); + mrb_method_added(mrb, c, mid); return mrb_symbol_value(mid); } @@ -2800,20 +2836,21 @@ inspect_main(mrb_state *mrb, mrb_value mod) } static const mrb_code new_iseq[] = { - OP_ENTER, 0x0, 0x10, 0x1, /* OP_ENTER 0:0:1:0:0:0:1 */ - OP_LOADSELF, 0x3, /* OP_LOADSELF R3 */ - OP_SEND, 0x3, 0x0, 0x0, /* OP_SEND R3 :allocate 0 */ - OP_MOVE, 0x0, 0x3, /* OP_MOVE R0 R3 */ - OP_MOVE, 0x4, 0x1, /* OP_MOVE R4 R1 */ - OP_MOVE, 0x5, 0x2, /* OP_MOVE R5 R2 */ - OP_SENDVB, 0x3, 0x1, /* OP_SENDVB R3 :initialize */ - OP_RETURN, 0x0 /* OP_RETURN R0 */ + OP_ENTER, 0x0, 0x10, 0x3, // OP_ENTER 0:0:1:0:0:1:1 + OP_LOADSELF, 4, // OP_LOADSELF R4 + OP_SEND, 4, 0, 0, // OP_SEND R4 :allocate n=0 + OP_MOVE, 0, 4, // OP_MOVE R0 R4 + OP_MOVE, 4, 3, // OP_MOVE R4 R3 (&) + OP_MOVE, 3, 2, // OP_MOVE R3 R2 (**) + OP_MOVE, 2, 1, // OP_MOVE R2 R1 (*) + OP_SSENDB, 1, 1, 255, // OP_SSENDB R1 :initialize n=*|nk=* + OP_RETURN, 0 // OP_RETURN R0 }; MRB_PRESYM_DEFINE_VAR_AND_INITER(new_syms, 2, MRB_SYM(allocate), MRB_SYM(initialize)) static const mrb_irep new_irep = { - 3, 6, 0, MRB_IREP_STATIC, + 4, 5, 0, MRB_IREP_STATIC, new_iseq, NULL, new_syms, NULL, NULL, NULL, sizeof(new_iseq), 0, 2, 0, 0, }; @@ -2879,6 +2916,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.5 */ mrb_define_method(mrb, bob, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */ mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.3.1.3.18 */ + mrb_define_method(mrb, bob, "singleton_method_added", mrb_bob_init, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); mrb_define_method(mrb, cls, "allocate", mrb_instance_alloc, MRB_ARGS_NONE()); @@ -2919,13 +2957,14 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */ mrb_define_method(mrb, mod, "dup", mrb_mod_dup, MRB_ARGS_NONE()); + mrb_define_method(mrb, bob, "method_added", mrb_bob_init, MRB_ARGS_REQ(1)); mrb_undef_method(mrb, cls, "append_features"); mrb_undef_method(mrb, cls, "prepend_features"); mrb_undef_method(mrb, cls, "extend_object"); mrb_undef_method(mrb, cls, "module_function"); - mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class); + mrb->top_self = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb->object_class); mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE()); mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE()); mrb_define_singleton_method(mrb, mrb->top_self, "define_method", top_define_method, MRB_ARGS_ARG(1,1)); diff --git a/src/codedump.c b/src/codedump.c index f382bb7eb..ef03e88f3 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -57,7 +57,31 @@ print_header(mrb_state *mrb, const mrb_irep *irep, uint32_t i) printf("%03d ", (int)i); } -#define CASE(insn,ops) case insn: FETCH_ ## ops (); +static void +print_args(uint8_t i) +{ + uint8_t n = i&0xf; + uint8_t nk = (i>>4)&0xf; + + if (n == 15) { + printf("n=*"); + } + else { + printf("n=%d", n); + } + if (nk > 0) { + printf("|"); + if (nk == 15) { + printf("nk=*"); + } + else { + printf("nk=%d", nk); + } + } + printf(" (0x%02x)\n", i); +} + +#define CASE(insn,ops) case insn: FETCH_ ## ops (); L_ ## insn static void codedump(mrb_state *mrb, const mrb_irep *irep) @@ -68,7 +92,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep) const char *file = NULL, *next_file; if (!irep) return; - printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d iseq=%d\n", (void*)irep, + printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d ilen=%d\n", (void*)irep, irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen); if (irep->lv) { @@ -128,191 +152,197 @@ codedump(mrb_state *mrb, const mrb_irep *irep) print_header(mrb, irep, (uint32_t)i); ins = READ_B(); switch (ins) { - CASE(OP_NOP, Z); - printf("OP_NOP\n"); + CASE(OP_NOP, Z): + printf("NOP\n"); break; - CASE(OP_MOVE, BB); - printf("OP_MOVE\tR%d\tR%d\t", a, b); + CASE(OP_MOVE, BB): + printf("MOVE\t\tR%d\tR%d\t", a, b); print_lv_ab(mrb, irep, a, b); break; - CASE(OP_LOADL16, BS); - goto op_loadl; - CASE(OP_LOADL, BB); - op_loadl: + + CASE(OP_LOADL, BB): switch (irep->pool[b].tt) { - case IREP_TT_FLOAT: #ifndef MRB_NO_FLOAT - printf("OP_LOADL\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f); -#endif + case IREP_TT_FLOAT: + printf("LOADL\t\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f); break; +#endif case IREP_TT_INT32: - printf("OP_LOADL\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32); + printf("LOADL\t\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32); break; #ifdef MRB_64BIT case IREP_TT_INT64: - printf("OP_LOADL\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64); + printf("LOADL\t\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64); break; #endif default: - printf("OP_LOADL\tR%d\tL(%d)\t", a, b); + printf("LOADL\t\tR%d\tL(%d)\t", a, b); break; } print_lv_a(mrb, irep, a); break; - CASE(OP_LOADI, BB); - printf("OP_LOADI\tR%d\t%d\t", a, b); + CASE(OP_LOADI, BB): + printf("LOADI\t\tR%d\t%d\t", a, b); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADINEG, BB); - printf("OP_LOADI\tR%d\t-%d\t", a, b); + CASE(OP_LOADINEG, BB): + printf("LOADI\tR%d\t-%d\t", a, b); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADI16, BS); - printf("OP_LOADI16\tR%d\t%d\t", a, (int)(int16_t)b); + CASE(OP_LOADI16, BS): + printf("LOADI16\tR%d\t%d\t", a, (int)(int16_t)b); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADI32, BSS); - printf("OP_LOADI32\tR%d\t%d\t", a, (int32_t)(((uint32_t)b<<16)+c)); + CASE(OP_LOADI32, BSS): + printf("LOADI32\tR%d\t%d\t", a, (int32_t)(((uint32_t)b<<16)+c)); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADI__1, B); - printf("OP_LOADI__1\tR%d\t\t", a); + CASE(OP_LOADI__1, B): + printf("LOADI__1\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADI_0, B); goto L_LOADI; - CASE(OP_LOADI_1, B); goto L_LOADI; - CASE(OP_LOADI_2, B); goto L_LOADI; - CASE(OP_LOADI_3, B); goto L_LOADI; - CASE(OP_LOADI_4, B); goto L_LOADI; - CASE(OP_LOADI_5, B); goto L_LOADI; - CASE(OP_LOADI_6, B); goto L_LOADI; - CASE(OP_LOADI_7, B); + CASE(OP_LOADI_0, B): goto L_LOADI; + CASE(OP_LOADI_1, B): goto L_LOADI; + CASE(OP_LOADI_2, B): goto L_LOADI; + CASE(OP_LOADI_3, B): goto L_LOADI; + CASE(OP_LOADI_4, B): goto L_LOADI; + CASE(OP_LOADI_5, B): goto L_LOADI; + CASE(OP_LOADI_6, B): goto L_LOADI; + CASE(OP_LOADI_7, B): L_LOADI: - printf("OP_LOADI_%d\tR%d\t\t", ins-(int)OP_LOADI_0, a); + printf("LOADI_%d\tR%d\t\t", ins-(int)OP_LOADI_0, a); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADSYM16, BS); - goto op_loadsym; - CASE(OP_LOADSYM, BB); - op_loadsym: - printf("OP_LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_LOADSYM, BB): + printf("LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADNIL, B); - printf("OP_LOADNIL\tR%d\t\t", a); + CASE(OP_LOADNIL, B): + printf("LOADNIL\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADSELF, B); - printf("OP_LOADSELF\tR%d\t\t", a); + CASE(OP_LOADSELF, B): + printf("LOADSELF\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADT, B); - printf("OP_LOADT\tR%d\t\t", a); + CASE(OP_LOADT, B): + printf("LOADT\t\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_LOADF, B); - printf("OP_LOADF\tR%d\t\t", a); + CASE(OP_LOADF, B): + printf("LOADF\t\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_GETGV, BB); - printf("OP_GETGV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_GETGV, BB): + printf("GETGV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_SETGV, BB); - printf("OP_SETGV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); + CASE(OP_SETGV, BB): + printf("SETGV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; - CASE(OP_GETSV, BB); - printf("OP_GETSV\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_GETSV, BB): + printf("GETSV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_SETSV, BB); - printf("OP_SETSV\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); + CASE(OP_SETSV, BB): + printf("SETSV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; - CASE(OP_GETCONST, BB); - printf("OP_GETCONST\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_GETCONST, BB): + printf("GETCONST\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_SETCONST, BB); - printf("OP_SETCONST\t:%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); + CASE(OP_SETCONST, BB): + printf("SETCONST\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; - CASE(OP_GETMCNST, BB); - printf("OP_GETMCNST\tR%d\tR%d::%s", a, a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_GETMCNST, BB): + printf("GETMCNST\tR%d\tR%d::%s\t", a, a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_SETMCNST, BB); - printf("OP_SETMCNST\tR%d::%s\tR%d", a+1, mrb_sym_dump(mrb, irep->syms[b]), a); + CASE(OP_SETMCNST, BB): + printf("SETMCNST\tR%d::%s\tR%d\t", a+1, mrb_sym_dump(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; - CASE(OP_GETIV, BB); - printf("OP_GETIV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_GETIV, BB): + printf("GETIV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_SETIV, BB); - printf("OP_SETIV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); + CASE(OP_SETIV, BB): + printf("SETIV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; - CASE(OP_GETUPVAR, BBB); - printf("OP_GETUPVAR\tR%d\t%d\t%d", a, b, c); + CASE(OP_GETUPVAR, BBB): + printf("GETUPVAR\tR%d\t%d\t%d\t", a, b, c); print_lv_a(mrb, irep, a); break; - CASE(OP_SETUPVAR, BBB); - printf("OP_SETUPVAR\tR%d\t%d\t%d", a, b, c); + CASE(OP_SETUPVAR, BBB): + printf("SETUPVAR\tR%d\t%d\t%d\t", a, b, c); print_lv_a(mrb, irep, a); break; - CASE(OP_GETCV, BB); - printf("OP_GETCV\tR%d\t%s", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_GETCV, BB): + printf("GETCV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_SETCV, BB); - printf("OP_SETCV\t%s\tR%d", mrb_sym_dump(mrb, irep->syms[b]), a); + CASE(OP_SETCV, BB): + printf("SETCV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); print_lv_a(mrb, irep, a); break; - CASE(OP_JMP, S); + CASE(OP_GETIDX, B): + printf("GETIDX\tR%d\tR%d\n", a, a+1); + break; + CASE(OP_SETIDX, B): + printf("SETIDX\tR%d\tR%d\tR%d\n", a, a+1, a+2); + break; + CASE(OP_JMP, S): i = pc - irep->iseq; - printf("OP_JMP\t\t%03d\n", (int)i+(int16_t)a); + printf("JMP\t\t%03d\n", (int)i+(int16_t)a); break; - CASE(OP_JMPUW, S); + CASE(OP_JMPUW, S): i = pc - irep->iseq; - printf("OP_JMPUW\t\t%03d\n", (int)i+(int16_t)a); + printf("JMPUW\t\t%03d\n", (int)i+(int16_t)a); break; - CASE(OP_JMPIF, BS); + CASE(OP_JMPIF, BS): i = pc - irep->iseq; - printf("OP_JMPIF\tR%d\t%03d\t", a, (int)i+(int16_t)b); + printf("JMPIF\t\tR%d\t%03d\t", a, (int)i+(int16_t)b); print_lv_a(mrb, irep, a); break; - CASE(OP_JMPNOT, BS); + CASE(OP_JMPNOT, BS): i = pc - irep->iseq; - printf("OP_JMPNOT\tR%d\t%03d\t", a, (int)i+(int16_t)b); + printf("JMPNOT\tR%d\t%03d\t", a, (int)i+(int16_t)b); print_lv_a(mrb, irep, a); break; - CASE(OP_JMPNIL, BS); + CASE(OP_JMPNIL, BS): i = pc - irep->iseq; - printf("OP_JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b); + printf("JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b); print_lv_a(mrb, irep, a); break; - CASE(OP_SENDV, BB); - printf("OP_SENDV\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_SSEND, BBB): + printf("SSEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c); break; - CASE(OP_SENDVB, BB); - printf("OP_SENDVB\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_SSENDB, BBB): + printf("SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c); break; - CASE(OP_SEND, BBB); - printf("OP_SEND\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c); + CASE(OP_SEND, BBB): + printf("SEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c); break; - CASE(OP_SENDB, BBB); - printf("OP_SENDB\tR%d\t:%s\t%d\n", a, mrb_sym_dump(mrb, irep->syms[b]), c); + CASE(OP_SENDB, BBB): + printf("SENDB\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c); break; - CASE(OP_CALL, Z); - printf("OP_CALL\n"); + CASE(OP_CALL, Z): + printf("CALL\n"); break; - CASE(OP_SUPER, BB); - printf("OP_SUPER\tR%d\t%d\n", a, b); + CASE(OP_SUPER, BB): + printf("SUPER\t\tR%d\t", a); + print_args(b); break; - CASE(OP_ARGARY, BS); - printf("OP_ARGARY\tR%d\t%d:%d:%d:%d (%d)", a, + CASE(OP_ARGARY, BS): + printf("ARGARY\tR%d\t%d:%d:%d:%d (%d)\t", a, (b>>11)&0x3f, (b>>10)&0x1, (b>>5)&0x1f, @@ -320,41 +350,41 @@ codedump(mrb_state *mrb, const mrb_irep *irep) (b>>0)&0xf); print_lv_a(mrb, irep, a); break; - CASE(OP_ENTER, W); - printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n", + CASE(OP_ENTER, W): + printf("ENTER\t\t%d:%d:%d:%d:%d:%d:%d (0x%x)\n", MRB_ASPEC_REQ(a), MRB_ASPEC_OPT(a), MRB_ASPEC_REST(a), MRB_ASPEC_POST(a), MRB_ASPEC_KEY(a), MRB_ASPEC_KDICT(a), - MRB_ASPEC_BLOCK(a)); + MRB_ASPEC_BLOCK(a), a); break; - CASE(OP_KEY_P, BB); - printf("OP_KEY_P\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_KEY_P, BB): + printf("KEY_P\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_KEYEND, Z); - printf("OP_KEYEND\n"); + CASE(OP_KEYEND, Z): + printf("KEYEND\n"); break; - CASE(OP_KARG, BB); - printf("OP_KARG\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_KARG, BB): + printf("KARG\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_RETURN, B); - printf("OP_RETURN\tR%d\t\t", a); + CASE(OP_RETURN, B): + printf("RETURN\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_RETURN_BLK, B); - printf("OP_RETURN_BLK\tR%d\t\t", a); + CASE(OP_RETURN_BLK, B): + printf("RETURN_BLK\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_BREAK, B); - printf("OP_BREAK\tR%d\t\t", a); + CASE(OP_BREAK, B): + printf("BREAK\t\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_BLKPUSH, BS); - printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d (%d)", a, + CASE(OP_BLKPUSH, BS): + printf("BLKPUSH\tR%d\t%d:%d:%d:%d (%d)\t", a, (b>>11)&0x3f, (b>>10)&0x1, (b>>5)&0x1f, @@ -362,192 +392,213 @@ codedump(mrb_state *mrb, const mrb_irep *irep) (b>>0)&0xf); print_lv_a(mrb, irep, a); break; - CASE(OP_LAMBDA, BB); - printf("OP_LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); - break; - CASE(OP_BLOCK, BB); - printf("OP_BLOCK\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); - break; - CASE(OP_METHOD, BB); - printf("OP_METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + CASE(OP_LAMBDA, BB): + printf("LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); break; - CASE(OP_LAMBDA16, BS); - printf("OP_LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + CASE(OP_BLOCK, BB): + printf("BLOCK\t\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); break; - CASE(OP_BLOCK16, BS); - printf("OP_BLOCK\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + CASE(OP_METHOD, BB): + printf("METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); break; - CASE(OP_METHOD16, BS); - printf("OP_METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + CASE(OP_RANGE_INC, B): + printf("RANGE_INC\tR%d\n", a); break; - CASE(OP_RANGE_INC, B); - printf("OP_RANGE_INC\tR%d\n", a); + CASE(OP_RANGE_EXC, B): + printf("RANGE_EXC\tR%d\n", a); break; - CASE(OP_RANGE_EXC, B); - printf("OP_RANGE_EXC\tR%d\n", a); + CASE(OP_DEF, BB): + printf("DEF\t\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); break; - CASE(OP_DEF, BB); - printf("OP_DEF\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_UNDEF, B): + printf("UNDEF\t\t:%s\n", mrb_sym_dump(mrb, irep->syms[a])); break; - CASE(OP_UNDEF, B); - printf("OP_UNDEF\t:%s\n", mrb_sym_dump(mrb, irep->syms[a])); + CASE(OP_ALIAS, BB): + printf("ALIAS\t\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b])); break; - CASE(OP_ALIAS, BB); - printf("OP_ALIAS\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_ADD, B): + printf("ADD\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_ADD, B); - printf("OP_ADD\tR%d\tR%d\n", a, a+1); - break; - CASE(OP_ADDI, BB); - printf("OP_ADDI\tR%d\t%d\n", a, b); + CASE(OP_ADDI, BB): + printf("ADDI\t\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a); break; - CASE(OP_SUB, B); - printf("OP_SUB\tR%d\tR%d\n", a, a+1); + CASE(OP_SUB, B): + printf("SUB\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_SUBI, BB); - printf("OP_SUBI\tR%d\t%d\n", a, b); + CASE(OP_SUBI, BB): + printf("SUBI\t\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a); break; - CASE(OP_MUL, B); - printf("OP_MUL\tR%d\tR%d\n", a, a+1); + CASE(OP_MUL, B): + printf("MUL\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_DIV, B); - printf("OP_DIV\tR%d\tR%d\n", a, a+1); + CASE(OP_DIV, B): + printf("DIV\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_LT, B); - printf("OP_LT\t\tR%d\tR%d\n", a, a+1); + CASE(OP_LT, B): + printf("LT\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_LE, B); - printf("OP_LE\t\tR%d\tR%d\n", a, a+1); + CASE(OP_LE, B): + printf("LE\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_GT, B); - printf("OP_GT\t\tR%d\tR%d\n", a, a+1); + CASE(OP_GT, B): + printf("GT\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_GE, B); - printf("OP_GE\t\tR%d\tR%d\n", a, a+1); + CASE(OP_GE, B): + printf("GE\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_EQ, B); - printf("OP_EQ\t\tR%d\tR%d\n", a, a+1); + CASE(OP_EQ, B): + printf("EQ\t\tR%d\tR%d\n", a, a+1); break; - CASE(OP_ARRAY, BB); - printf("OP_ARRAY\tR%d\t%d\t", a, b); + CASE(OP_ARRAY, BB): + printf("ARRAY\t\tR%d\tR%d\t%d\t", a, a, b); print_lv_a(mrb, irep, a); break; - CASE(OP_ARRAY2, BBB); - printf("OP_ARRAY\tR%d\tR%d\t%d\t", a, b, c); + CASE(OP_ARRAY2, BBB): + printf("ARRAY\t\tR%d\tR%d\t%d\t", a, b, c); print_lv_ab(mrb, irep, a, b); break; - CASE(OP_ARYCAT, B); - printf("OP_ARYCAT\tR%d\t", a); + CASE(OP_ARYCAT, B): + printf("ARYCAT\tR%d\tR%d\t", a, a+1); print_lv_a(mrb, irep, a); break; - CASE(OP_ARYPUSH, B); - printf("OP_ARYPUSH\tR%d\t", a); + CASE(OP_ARYPUSH, BB): + printf("ARYPUSH\tR%d\t%d\t", a, b); print_lv_a(mrb, irep, a); break; - CASE(OP_ARYDUP, B); - printf("OP_ARYDUP\tR%d\t", a); + CASE(OP_ARYDUP, B): + printf("ARYDUP\tR%d\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_AREF, BBB); - printf("OP_AREF\tR%d\tR%d\t%d", a, b, c); + CASE(OP_AREF, BBB): + printf("AREF\t\tR%d\tR%d\t%d", a, b, c); print_lv_ab(mrb, irep, a, b); break; - CASE(OP_ASET, BBB); - printf("OP_ASET\tR%d\tR%d\t%d", a, b, c); + CASE(OP_ASET, BBB): + printf("ASET\t\tR%d\tR%d\t%d", a, b, c); print_lv_ab(mrb, irep, a, b); break; - CASE(OP_APOST, BBB); - printf("OP_APOST\tR%d\t%d\t%d", a, b, c); + CASE(OP_APOST, BBB): + printf("APOST\t\tR%d\t%d\t%d", a, b, c); + print_lv_a(mrb, irep, a); + break; + CASE(OP_INTERN, B): + printf("INTERN\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_INTERN, B); - printf("OP_INTERN\tR%d", a); + CASE(OP_SYMBOL, BB): + mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); + printf("SYMBOL\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); print_lv_a(mrb, irep, a); break; - CASE(OP_STRING16, BS); - goto op_string; - CASE(OP_STRING, BB); - op_string: + CASE(OP_STRING, BB): + mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); if ((irep->pool[b].tt & IREP_TT_NFLAG) == 0) { - printf("OP_STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + printf("STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); } else { - printf("OP_STRING\tR%d\tL(%d)\t", a, b); + printf("STRING\tR%d\tL(%d)\t", a, b); } print_lv_a(mrb, irep, a); break; - CASE(OP_STRCAT, B); - printf("OP_STRCAT\tR%d\t", a); + CASE(OP_STRCAT, B): + printf("STRCAT\tR%d\tR%d", a, a+1); print_lv_a(mrb, irep, a); break; - CASE(OP_HASH, BB); - printf("OP_HASH\tR%d\t%d\t", a, b); + CASE(OP_HASH, BB): + printf("HASH\t\tR%d\t%d\t", a, b); print_lv_a(mrb, irep, a); break; - CASE(OP_HASHADD, BB); - printf("OP_HASHADD\tR%d\t%d\t", a, b); + CASE(OP_HASHADD, BB): + printf("HASHADD\tR%d\t%d\t", a, b); print_lv_a(mrb, irep, a); break; - CASE(OP_HASHCAT, B); - printf("OP_HASHCAT\tR%d\t", a); + CASE(OP_HASHCAT, B): + printf("HASHCAT\tR%d\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_OCLASS, B); - printf("OP_OCLASS\tR%d\t\t", a); + CASE(OP_OCLASS, B): + printf("OCLASS\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_CLASS, BB); - printf("OP_CLASS\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_CLASS, BB): + printf("CLASS\t\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_MODULE, BB); - printf("OP_MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); + CASE(OP_MODULE, BB): + printf("MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); print_lv_a(mrb, irep, a); break; - CASE(OP_EXEC, BB); - printf("OP_EXEC\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]); + CASE(OP_EXEC, BB): + printf("EXEC\t\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]); print_lv_a(mrb, irep, a); break; - CASE(OP_SCLASS, B); - printf("OP_SCLASS\tR%d\t", a); + CASE(OP_SCLASS, B): + printf("SCLASS\t\tR%d\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_TCLASS, B); - printf("OP_TCLASS\tR%d\t\t", a); + CASE(OP_TCLASS, B): + printf("TCLASS\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_ERR, B); + CASE(OP_ERR, B): if ((irep->pool[a].tt & IREP_TT_NFLAG) == 0) { - printf("OP_ERR\t%s\n", irep->pool[a].u.str); + printf("ERR\t\t%s\n", irep->pool[a].u.str); } else { - printf("OP_ERR\tL(%d)\n", a); + printf("ERR\tL(%d)\n", a); } break; - CASE(OP_EXCEPT, B); - printf("OP_EXCEPT\tR%d\t\t", a); + CASE(OP_EXCEPT, B): + printf("EXCEPT\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_RESCUE, BB); - printf("OP_RESCUE\tR%d\tR%d", a, b); + CASE(OP_RESCUE, BB): + printf("RESCUE\tR%d\tR%d", a, b); print_lv_ab(mrb, irep, a, b); break; - CASE(OP_RAISEIF, B); - printf("OP_RAISEIF\tR%d\t\t", a); + CASE(OP_RAISEIF, B): + printf("RAISEIF\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; - CASE(OP_DEBUG, BBB); - printf("OP_DEBUG\t%d\t%d\t%d\n", a, b, c); + CASE(OP_DEBUG, BBB): + printf("DEBUG\t\t%d\t%d\t%d\n", a, b, c); + break; + + CASE(OP_STOP, Z): + printf("STOP\n"); break; - CASE(OP_STOP, Z); - printf("OP_STOP\n"); + CASE(OP_EXT1, Z): + ins = READ_B(); + switch (ins) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); goto L_OP_ ## i; +#include "mruby/ops.h" +#undef OPCODE + } + break; + CASE(OP_EXT2, Z): + ins = READ_B(); + switch (ins) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); goto L_OP_ ## i; +#include "mruby/ops.h" +#undef OPCODE + } + break; + CASE(OP_EXT3, Z): + ins = READ_B(); + switch (ins) { +#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); goto L_OP_ ## i; +#include "mruby/ops.h" +#undef OPCODE + } break; default: - printf("OP_unknown (0x%x)\n", ins); + printf("unknown_op (0x%x)\n", ins); break; } mrb_gc_arena_restore(mrb, ai); diff --git a/src/debug.c b/src/debug.c index c03c91cf5..e570e8068 100644 --- a/src/debug.c +++ b/src/debug.c @@ -35,19 +35,46 @@ get_file(mrb_irep_debug_info *info, uint32_t pc) return *ret; } -static mrb_debug_line_type -select_line_type(const uint16_t *lines, size_t lines_len) +size_t +mrb_packed_int_len(uint32_t num) { - size_t line_count = 0; - int prev_line = -1; - size_t i; - for (i = 0; i < lines_len; ++i) { - if (lines[i] != prev_line) { - ++line_count; - } - } - return (sizeof(uint16_t) * lines_len) <= (sizeof(mrb_irep_debug_info_line) * line_count) - ? mrb_debug_line_ary : mrb_debug_line_flat_map; + size_t llen = 0; + + do { + llen++; + } while (num >>= 7); + return llen; +} + +size_t +mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend) +{ + size_t llen = 0; + + do { + uint8_t byte = num & 0x7f; + num >>= 7; + if (num != 0) byte |= 0x80; + if (p < pend) *p++ = byte; + llen++; + } while (num != 0); + + return llen; +} + +uint32_t +mrb_packed_int_decode(uint8_t *p, uint8_t **newpos) +{ + size_t i = 0, shift = 0; + uint32_t n = 0; + + do { + n |= ((uint32_t)(p[i] & 0x7f)) << shift; + i++; + shift += 7; + } while (shift < sizeof(uint32_t) * 8 && (p[i - 1] & 0x80)); + if (newpos) *newpos = p + i; + return n; } MRB_API char const* @@ -102,6 +129,19 @@ mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) return ret->line; } + + case mrb_debug_line_packed_map: { + uint8_t *p = f->lines.packed_map; + uint8_t *pend = p + f->line_entry_count; + uint32_t pos = 0, line = 0, line_diff; + while (p < pend) { + pos += mrb_packed_int_decode(p, &p); + line_diff = mrb_packed_int_decode(p, &p); + if (pc < pos) break; + line += line_diff; + } + return line; + } } } } @@ -144,10 +184,7 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, } f = (mrb_irep_debug_info_file*)mrb_malloc(mrb, sizeof(*f)); - d->files = (mrb_irep_debug_info_file**)( - d->files - ? mrb_realloc(mrb, d->files, sizeof(mrb_irep_debug_info_file*) * (d->flen + 1)) - : mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file*))); + d->files = (mrb_irep_debug_info_file**)mrb_realloc(mrb, d->files, sizeof(mrb_irep_debug_info_file*) * (d->flen + 1)); d->files[d->flen++] = f; file_pc_count = end_pos - start_pos; @@ -157,42 +194,32 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, fn_len = strlen(filename); f->filename_sym = mrb_intern(mrb, filename, fn_len); - - f->line_type = select_line_type(lines + start_pos, end_pos - start_pos); + f->line_type = mrb_debug_line_packed_map; f->lines.ptr = NULL; - switch (f->line_type) { - case mrb_debug_line_ary: - f->line_entry_count = file_pc_count; - f->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count); - for (i = 0; i < file_pc_count; ++i) { - f->lines.ary[i] = lines[start_pos + i]; - } - break; - - case mrb_debug_line_flat_map: { - uint16_t prev_line = 0; - mrb_irep_debug_info_line m; - f->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1); - f->line_entry_count = 0; - for (i = 0; i < file_pc_count; ++i) { - if (lines[start_pos + i] == prev_line) { continue; } - - f->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc( - mrb, f->lines.flat_map, - sizeof(mrb_irep_debug_info_line) * (f->line_entry_count + 1)); - m.start_pos = start_pos + i; - m.line = lines[start_pos + i]; - f->lines.flat_map[f->line_entry_count] = m; - - /* update */ - ++f->line_entry_count; - prev_line = lines[start_pos + i]; - } - } break; - - default: mrb_assert(0); break; + uint16_t prev_line = 0; + uint32_t prev_pc = 0; + size_t packed_size = 0; + uint8_t *p, *pend; + + for (i = 0; i < file_pc_count; ++i) { + if (lines[start_pos + i] == prev_line) continue; + packed_size += mrb_packed_int_len(start_pos+i-prev_pc); + prev_pc = start_pos+i; + packed_size += mrb_packed_int_len(lines[start_pos+i]-prev_line); + prev_line = lines[start_pos + i]; + } + p = f->lines.packed_map = (uint8_t*)mrb_malloc(mrb, packed_size); + pend = p + packed_size; + prev_line = 0; prev_pc = 0; + for (i = 0; i < file_pc_count; ++i) { + if (lines[start_pos + i] == prev_line) continue; + p += mrb_packed_int_encode(start_pos+i-prev_pc, p, pend); + prev_pc = start_pos + i; + p += mrb_packed_int_encode(lines[start_pos + i]-prev_line, p, pend); + prev_line = lines[start_pos + i]; } + f->line_entry_count = (uint32_t)packed_size; return f; } diff --git a/src/dump.c b/src/dump.c index 91edf17d3..4327cb375 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1,20 +1,18 @@ /* -** dump.c - mruby binary dumper (mrbc binary format) +** cdump.c - mruby binary dumper (in C) ** ** See Copyright Notice in mruby.h */ -#include <string.h> -#include <limits.h> -#include <math.h> +#include <mruby.h> #include <mruby/dump.h> #include <mruby/string.h> #include <mruby/irep.h> #include <mruby/debug.h> +#include <string.h> #ifndef MRB_NO_FLOAT #include <mruby/endian.h> -#define MRB_FLOAT_FMT "%.17g" #endif static size_t get_irep_record_size_1(mrb_state *mrb, const mrb_irep *irep); @@ -414,6 +412,10 @@ get_debug_record_size(mrb_state *mrb, const mrb_irep *irep) ret += (sizeof(uint32_t) + sizeof(uint16_t)) * (size_t)(file->line_entry_count); break; + case mrb_debug_line_packed_map: + ret += (size_t)(file->line_entry_count); + break; + default: mrb_assert(0); break; } } @@ -508,6 +510,11 @@ write_debug_record_1(mrb_state *mrb, const mrb_irep *irep, uint8_t *bin, mrb_sym } } break; + case mrb_debug_line_packed_map: { + memcpy(cur, file->lines.packed_map, file->line_entry_count); + cur += file->line_entry_count; + } break; + default: mrb_assert(0); break; } } @@ -929,428 +936,4 @@ mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *f return result; } -static int -dump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp) -{ - if (p->tt & IREP_TT_NFLAG) { /* number */ - switch (p->tt) { -#ifdef MRB_64BIT - case IREP_TT_INT64: - if (p->u.i64 < INT32_MIN || INT32_MAX < p->u.i64) { - fprintf(fp, "{IREP_TT_INT64, {.i64=%" PRId64 "}},\n", p->u.i64); - } - else { - fprintf(fp, "{IREP_TT_INT32, {.i32=%" PRId32 "}},\n", (int32_t)p->u.i64); - } - break; -#endif - case IREP_TT_INT32: - fprintf(fp, "{IREP_TT_INT32, {.i32=%" PRId32 "}},\n", p->u.i32); - break; - case IREP_TT_FLOAT: -#ifndef MRB_NO_FLOAT - if (p->u.f == 0) { - fprintf(fp, "{IREP_TT_FLOAT, {.f=%#.1f}},\n", p->u.f); - } - else { - fprintf(fp, "{IREP_TT_FLOAT, {.f=" MRB_FLOAT_FMT "}},\n", p->u.f); - } -#endif - break; - case IREP_TT_BIGINT: - { - const char *s = p->u.str; - int len = s[0]+2; - fputs("{IREP_TT_BIGINT, {\"", fp); - for (int i=0; i<len; i++) { - fprintf(fp, "\\x%02x", (int)s[i]&0xff); - } - fputs("\"}},\n", fp); - } - break; - } - } - else { /* string */ - int i, len = p->tt>>2; - const char *s = p->u.str; - fprintf(fp, "{IREP_TT_STR|(%d<<2), {\"", len); - for (i=0; i<len; i++) { - fprintf(fp, "\\x%02x", (int)s[i]&0xff); - } - fputs("\"}},\n", fp); - } - return MRB_DUMP_OK; -} - -static mrb_bool -sym_name_word_p(const char *name, mrb_int len) -{ - if (len == 0) return FALSE; - if (name[0] != '_' && !ISALPHA(name[0])) return FALSE; - for (int i = 1; i < len; i++) { - if (name[i] != '_' && !ISALNUM(name[i])) return FALSE; - } - return TRUE; -} - -static mrb_bool -sym_name_with_equal_p(const char *name, mrb_int len) -{ - return len >= 2 && name[len-1] == '=' && sym_name_word_p(name, len-1); -} - -static mrb_bool -sym_name_with_question_mark_p(const char *name, mrb_int len) -{ - return len >= 2 && name[len-1] == '?' && sym_name_word_p(name, len-1); -} - -static mrb_bool -sym_name_with_bang_p(const char *name, mrb_int len) -{ - return len >= 2 && name[len-1] == '!' && sym_name_word_p(name, len-1); -} - -static mrb_bool -sym_name_ivar_p(const char *name, mrb_int len) -{ - return len >= 2 && name[0] == '@' && sym_name_word_p(name+1, len-1); -} - -static mrb_bool -sym_name_cvar_p(const char *name, mrb_int len) -{ - return len >= 3 && name[0] == '@' && sym_name_ivar_p(name+1, len-1); -} - -#define OPERATOR_SYMBOL(sym_name, name) {name, sym_name, sizeof(sym_name)-1} -struct operator_symbol { - const char *name; - const char *sym_name; - uint16_t sym_name_len; -}; -static const struct operator_symbol operator_table[] = { - OPERATOR_SYMBOL("!", "not"), - OPERATOR_SYMBOL("%", "mod"), - OPERATOR_SYMBOL("&", "and"), - OPERATOR_SYMBOL("*", "mul"), - OPERATOR_SYMBOL("+", "add"), - OPERATOR_SYMBOL("-", "sub"), - OPERATOR_SYMBOL("/", "div"), - OPERATOR_SYMBOL("<", "lt"), - OPERATOR_SYMBOL(">", "gt"), - OPERATOR_SYMBOL("^", "xor"), - OPERATOR_SYMBOL("`", "tick"), - OPERATOR_SYMBOL("|", "or"), - OPERATOR_SYMBOL("~", "neg"), - OPERATOR_SYMBOL("!=", "neq"), - OPERATOR_SYMBOL("!~", "nmatch"), - OPERATOR_SYMBOL("&&", "andand"), - OPERATOR_SYMBOL("**", "pow"), - OPERATOR_SYMBOL("+@", "plus"), - OPERATOR_SYMBOL("-@", "minus"), - OPERATOR_SYMBOL("<<", "lshift"), - OPERATOR_SYMBOL("<=", "le"), - OPERATOR_SYMBOL("==", "eq"), - OPERATOR_SYMBOL("=~", "match"), - OPERATOR_SYMBOL(">=", "ge"), - OPERATOR_SYMBOL(">>", "rshift"), - OPERATOR_SYMBOL("[]", "aref"), - OPERATOR_SYMBOL("||", "oror"), - OPERATOR_SYMBOL("<=>", "cmp"), - OPERATOR_SYMBOL("===", "eqq"), - OPERATOR_SYMBOL("[]=", "aset"), -}; - -static const char* -sym_operator_name(const char *sym_name, mrb_int len) -{ - mrb_sym table_size = sizeof(operator_table)/sizeof(struct operator_symbol); - if (operator_table[table_size-1].sym_name_len < len) return NULL; - - mrb_sym start, idx; - int cmp; - const struct operator_symbol *op_sym; - for (start = 0; table_size != 0; table_size/=2) { - idx = start+table_size/2; - op_sym = &operator_table[idx]; - cmp = (int)len-(int)op_sym->sym_name_len; - if (cmp == 0) { - cmp = memcmp(sym_name, op_sym->sym_name, len); - if (cmp == 0) return op_sym->name; - } - if (0 < cmp) { - start = ++idx; - --table_size; - } - } - return NULL; -} - -static const char* -sym_var_name(mrb_state *mrb, const char *initname, const char *key, int n) -{ - char buf[32]; - mrb_value s = mrb_str_new_cstr(mrb, initname); - mrb_str_cat_lit(mrb, s, "_"); - mrb_str_cat_cstr(mrb, s, key); - mrb_str_cat_lit(mrb, s, "_"); - snprintf(buf, sizeof(buf), "%d", n); - mrb_str_cat_cstr(mrb, s, buf); - return RSTRING_PTR(s); -} - -static int -dump_sym(mrb_state *mrb, mrb_sym sym, const char *var_name, int idx, mrb_value init_syms_code, FILE *fp) -{ - if (sym == 0) return MRB_DUMP_INVALID_ARGUMENT; - - mrb_int len; - const char *name = mrb_sym_name_len(mrb, sym, &len), *op_name; - if (!name) return MRB_DUMP_INVALID_ARGUMENT; - if (sym_name_word_p(name, len)) { - fprintf(fp, "MRB_SYM(%s)", name); - } - else if (sym_name_with_equal_p(name, len)) { - fprintf(fp, "MRB_SYM_E(%.*s)", (int)(len-1), name); - } - else if (sym_name_with_question_mark_p(name, len)) { - fprintf(fp, "MRB_SYM_Q(%.*s)", (int)(len-1), name); - } - else if (sym_name_with_bang_p(name, len)) { - fprintf(fp, "MRB_SYM_B(%.*s)", (int)(len-1), name); - } - else if (sym_name_ivar_p(name, len)) { - fprintf(fp, "MRB_IVSYM(%s)", name+1); - } - else if (sym_name_cvar_p(name, len)) { - fprintf(fp, "MRB_CVSYM(%s)", name+2); - } - else if ((op_name = sym_operator_name(name, len))) { - fprintf(fp, "MRB_OPSYM(%s)", op_name); - } - else { - char buf[32]; - mrb_value name_obj = mrb_str_new(mrb, name, len); - mrb_str_cat_lit(mrb, init_syms_code, " "); - mrb_str_cat_cstr(mrb, init_syms_code, var_name); - snprintf(buf, sizeof(buf), "[%d] = ", idx); - mrb_str_cat_cstr(mrb, init_syms_code, buf); - mrb_str_cat_lit(mrb, init_syms_code, "mrb_intern_lit(mrb, "); - mrb_str_cat_str(mrb, init_syms_code, mrb_str_dump(mrb, name_obj)); - mrb_str_cat_lit(mrb, init_syms_code, ");\n"); - fputs("0", fp); - } - fputs(", ", fp); - return MRB_DUMP_OK; -} - -static int -dump_syms(mrb_state *mrb, const char *name, const char *key, int n, int syms_len, const mrb_sym *syms, mrb_value init_syms_code, FILE *fp) -{ - int ai = mrb_gc_arena_save(mrb); - mrb_int code_len = RSTRING_LEN(init_syms_code); - const char *var_name = sym_var_name(mrb, name, key, n); - fprintf(fp, "mrb_DEFINE_SYMS_VAR(%s, %d, (", var_name, syms_len); - for (int i=0; i<syms_len; i++) { - dump_sym(mrb, syms[i], var_name, i, init_syms_code, fp); - } - fputs("), ", fp); - if (code_len == RSTRING_LEN(init_syms_code)) fputs("const", fp); - fputs(");\n", fp); - mrb_gc_arena_restore(mrb, ai); - return MRB_DUMP_OK; -} - -//Handle the simple/common case of debug_info: -// - 1 file associated with a single irep -// - mrb_debug_line_ary format only -static int -simple_debug_info(mrb_irep_debug_info *info) -{ - if (!info || - info->flen != 1 || - info->files[0]->line_type != mrb_debug_line_ary) { - return 0; - } - return 1; -} - -//Adds debug information to c-structs and -//adds filenames in init_syms_code block -static int -dump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, - mrb_value init_syms_code, FILE *fp) -{ - char buffer[256]; - const char *filename; - mrb_int file_len; - int len, i; - - if (!simple_debug_info(info)) - return MRB_DUMP_INVALID_IREP; - - len = info->files[0]->line_entry_count; - - filename = mrb_sym_name_len(mrb, info->files[0]->filename_sym, &file_len); - snprintf(buffer, sizeof(buffer), " %s_debug_file_%d.filename_sym = mrb_intern_lit(mrb,\"", - name, n); - mrb_str_cat_cstr(mrb, init_syms_code, buffer); - mrb_str_cat_cstr(mrb, init_syms_code, filename); - mrb_str_cat_cstr(mrb, init_syms_code, "\");\n"); - - fprintf(fp, "static uint16_t %s_debug_lines_%d[%d] = {", name, n, len); - for (i=0; i<len; i++) { - if (i%10 == 0) fputs("\n", fp); - fprintf(fp, "0x%04x,", info->files[0]->lines.ary[i]); - } - fputs("};\n", fp); - - fprintf(fp, "static mrb_irep_debug_info_file %s_debug_file_%d = {\n", name, n); - fprintf(fp, "%d, %d, %d, mrb_debug_line_ary, {%s_debug_lines_%d}};\n", - info->files[0]->start_pos, - info->files[0]->filename_sym, - info->files[0]->line_entry_count, - name,n); - fprintf(fp, "static mrb_irep_debug_info_file *%s_debug_file_%d_ = &%s_debug_file_%d;\n", name, n, name, n); - - fprintf(fp, "static mrb_irep_debug_info %s_debug_%d = {\n", name, n); - fprintf(fp, "%d, %d, &%s_debug_file_%d_};\n", info->pc_count, info->flen, name, n); - - return MRB_DUMP_OK; -} - -static int -dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *name, int n, mrb_value init_syms_code, int *mp) -{ - int i, len; - int max = *mp; - int debug_available = 0; - - /* dump reps */ - if (irep->reps) { - for (i=0,len=irep->rlen; i<len; i++) { - *mp += len; - if (dump_irep_struct(mrb, irep->reps[i], flags, fp, name, max+i, init_syms_code, mp) != MRB_DUMP_OK) - return MRB_DUMP_INVALID_ARGUMENT; - } - fprintf(fp, "static const mrb_irep *%s_reps_%d[%d] = {\n", name, n, len); - for (i=0,len=irep->rlen; i<len; i++) { - fprintf(fp, " &%s_irep_%d,\n", name, max+i); - } - fputs("};\n", fp); - } - /* dump pool */ - if (irep->pool) { - len=irep->plen; - fprintf(fp, "static const mrb_pool_value %s_pool_%d[%d] = {\n", name, n, len); - for (i=0; i<len; i++) { - if (dump_pool(mrb, &irep->pool[i], fp) != MRB_DUMP_OK) - return MRB_DUMP_INVALID_ARGUMENT; - } - fputs("};\n", fp); - } - /* dump syms */ - if (irep->syms) { - dump_syms(mrb, name, "syms", n, irep->slen, irep->syms, init_syms_code, fp); - } - /* dump iseq */ - len=irep->ilen+sizeof(struct mrb_irep_catch_handler)*irep->clen; - fprintf(fp, "static const mrb_code %s_iseq_%d[%d] = {", name, n, len); - for (i=0; i<len; i++) { - if (i%20 == 0) fputs("\n", fp); - fprintf(fp, "0x%02x,", irep->iseq[i]); - } - fputs("};\n", fp); - /* dump lv */ - if (irep->lv) { - dump_syms(mrb, name, "lv", n, irep->nlocals-1, irep->lv, init_syms_code, fp); - } - /* dump debug */ - if (flags & MRB_DUMP_DEBUG_INFO) { - if(dump_debug(mrb, name, n, irep->debug_info, - init_syms_code, fp) == MRB_DUMP_OK) { - debug_available = 1; - } - } - - - /* dump irep */ - fprintf(fp, "static const mrb_irep %s_irep_%d = {\n", name, n); - fprintf(fp, " %d,%d,%d,\n", irep->nlocals, irep->nregs, irep->clen); - fprintf(fp, " MRB_IREP_STATIC,%s_iseq_%d,\n", name, n); - if (irep->pool) { - fprintf(fp, " %s_pool_%d,", name, n); - } - else { - fputs( " NULL,", fp); - } - if (irep->syms) { - fprintf(fp, "%s_syms_%d,", name, n); - } - else { - fputs( "NULL,", fp); - } - if (irep->reps) { - fprintf(fp, "%s_reps_%d,\n", name, n); - } - else { - fputs( "NULL,\n", fp); - } - if (irep->lv) { - fprintf(fp, " %s_lv_%d,\n", name, n); - } - else { - fputs( " NULL,\t\t\t\t\t/* lv */\n", fp); - } - if(debug_available) { - fprintf(fp, " &%s_debug_%d,\n", name, n); - } - else { - fputs(" NULL,\t\t\t\t\t/* debug_info */\n", fp); - } - fprintf(fp, " %d,%d,%d,%d,0\n};\n", irep->ilen, irep->plen, irep->slen, irep->rlen); - - return MRB_DUMP_OK; -} - -int -mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname) -{ - if (fp == NULL || initname == NULL || initname[0] == '\0') { - return MRB_DUMP_INVALID_ARGUMENT; - } - if (fprintf(fp, "#include <mruby.h>\n" - "#include <mruby/irep.h>\n" - "#include <mruby/debug.h>\n" - "#include <mruby/proc.h>\n" - "#include <mruby/presym.h>\n" - "\n") < 0) { - return MRB_DUMP_WRITE_FAULT; - } - fputs("#define mrb_BRACED(...) {__VA_ARGS__}\n", fp); - fputs("#define mrb_DEFINE_SYMS_VAR(name, len, syms, qualifier) \\\n", fp); - fputs(" static qualifier mrb_sym name[len] = mrb_BRACED syms\n", fp); - fputs("\n", fp); - mrb_value init_syms_code = mrb_str_new_capa(mrb, 0); - int max = 1; - int n = dump_irep_struct(mrb, irep, flags, fp, initname, 0, init_syms_code, &max); - if (n != MRB_DUMP_OK) return n; - fprintf(fp, - "%s\n" - "const struct RProc %s[] = {{\n", - (flags & MRB_DUMP_STATIC) ? "static" - : "#ifdef __cplusplus\n" - "extern\n" - "#endif", - initname); - fprintf(fp, "NULL,NULL,MRB_TT_PROC,MRB_GC_RED,0,{&%s_irep_0},NULL,{NULL},\n}};\n", initname); - fputs("static void\n", fp); - fprintf(fp, "%s_init_syms(mrb_state *mrb)\n", initname); - fputs("{\n", fp); - fputs(RSTRING_PTR(init_syms_code), fp); - fputs("}\n", fp); - return MRB_DUMP_OK; -} - #endif /* MRB_NO_STDIO */ diff --git a/src/error.c b/src/error.c index 5d9b367bd..5fa872c9b 100644 --- a/src/error.c +++ b/src/error.c @@ -5,7 +5,6 @@ */ #include <errno.h> -#include <stdarg.h> #include <stdlib.h> #include <mruby.h> #include <mruby/array.h> @@ -18,18 +17,51 @@ #include <mruby/throw.h> #include <mruby/presym.h> -MRB_API mrb_value -mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len) +static void +exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) +{ + if (mrb_string_p(mesg)) { + exc->flags |= MRB_EXC_MESG_STRING_FLAG; + exc->mesg = RSTRING(mesg); + mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, mesg); + } + else { + exc->flags &= ~MRB_EXC_MESG_STRING_FLAG; + if (mrb_nil_p(mesg)) { + exc->mesg = 0; + } + else { + mrb_obj_iv_set(mrb, (struct RObject*)exc, MRB_SYM(mesg), mesg); + } + } +} + +static mrb_value +exc_mesg_get(mrb_state *mrb, struct RException *exc) { - mrb_value arg = mrb_str_new(mrb, ptr, len); - return mrb_obj_new(mrb, c, 1, &arg); + if ((exc->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + return mrb_obj_value(exc->mesg); + } + else { + return mrb_obj_iv_get(mrb, (struct RObject*)exc, MRB_SYM(mesg)); + } } MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) { - mrb_to_str(mrb, str); - return mrb_obj_new(mrb, c, 1, &str); + mrb_ensure_string_type(mrb, str); + + struct RBasic* e = mrb_obj_alloc(mrb, MRB_TT_EXCEPTION, c); + mrb_value exc = mrb_obj_value(e); + mrb_iv_set(mrb, exc, MRB_SYM(mesg), str); + return exc; +} + +MRB_API mrb_value +mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len) +{ + return mrb_exc_new_str(mrb, c, mrb_str_new(mrb, ptr, len)); } /* @@ -46,7 +78,7 @@ exc_initialize(mrb_state *mrb, mrb_value exc) mrb_value mesg; if (mrb_get_args(mrb, "|o", &mesg) == 1) { - mrb_iv_set(mrb, exc, MRB_SYM(mesg), mesg); + exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); } return exc; } @@ -75,7 +107,7 @@ exc_exception(mrb_state *mrb, mrb_value self) if (argc == 0) return self; if (mrb_obj_equal(mrb, self, a)) return self; exc = mrb_obj_clone(mrb, self); - mrb_iv_set(mrb, exc, MRB_SYM(mesg), a); + exc_mesg_set(mrb, mrb_exc_ptr(exc), a); return exc; } @@ -91,7 +123,7 @@ exc_exception(mrb_state *mrb, mrb_value self) static mrb_value exc_to_s(mrb_state *mrb, mrb_value exc) { - mrb_value mesg = mrb_attr_get(mrb, exc, MRB_SYM(mesg)); + mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); struct RObject *p; if (!mrb_string_p(mesg)) { @@ -131,7 +163,7 @@ exc_message(mrb_state *mrb, mrb_value exc) mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc) { - mrb_value mesg = mrb_attr_get(mrb, exc, MRB_SYM(mesg)); + mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); mrb_value cname = mrb_mod_to_s(mrb, mrb_obj_value(mrb_obj_class(mrb, exc))); mesg = mrb_obj_as_string(mrb, mesg); return RSTRING_LEN(mesg) == 0 ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); @@ -287,7 +319,7 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap) #else i = *p == 'd' ? (mrb_int)va_arg(ap, int) : va_arg(ap, mrb_int); #endif - obj = mrb_fixnum_value(i); + obj = mrb_int_value(mrb, i); goto L_cat_obj; #ifndef MRB_NO_FLOAT case 'f': @@ -302,6 +334,7 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap) obj = mrb_str_new(mrb, chars, len); goto L_cat_obj; } + L_cat_plain: mrb_str_cat(mrb, result, b, e - b - 1); mrb_str_cat(mrb, result, chars, len); b = ++p; @@ -325,10 +358,15 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap) obj = va_arg(ap, mrb_value); L_cat_obj: str = (inspect ? mrb_inspect : mrb_obj_as_string)(mrb, obj); - chars = RSTRING_PTR(str); - len = RSTRING_LEN(str); - inspect = FALSE; - goto L_cat; + if (mrb_type(str) != MRB_TT_STRING) { + chars = "void (no string conversion)"; + len = strlen(chars); + } + else { + chars = RSTRING_PTR(str); + len = RSTRING_LEN(str); + } + goto L_cat_plain; case 'C': cls = va_arg(ap, struct RClass*); L_cat_class: @@ -352,7 +390,7 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap) L_cat_current: chars = p; len = 1; - goto L_cat; + goto L_cat_plain; default: mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); } @@ -381,41 +419,37 @@ mrb_format(mrb_state *mrb, const char *format, ...) return str; } -static mrb_noreturn void -raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list ap, int argc, mrb_value *argv) +static mrb_value +error_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list ap) { - mrb_value mesg; - - mesg = mrb_vformat(mrb, fmt, ap); - if (argv == NULL) { - argv = &mesg; - } - else { - argv[0] = mesg; - } - mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv)); + mrb_value mesg = mrb_vformat(mrb, fmt, ap); + return mrb_exc_new_str(mrb, c, mesg); } MRB_API mrb_noreturn void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...) { - va_list args; + va_list ap; + mrb_value exc; + + va_start(ap, fmt); + exc = error_va(mrb, c, fmt, ap); + va_end(ap); - va_start(args, fmt); - raise_va(mrb, c, fmt, args, 0, NULL); - va_end(args); + mrb_exc_raise(mrb, exc); } MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...) { - mrb_value argv[2]; - va_list args; + va_list ap; + mrb_value exc; - va_start(args, fmt); - argv[1] = mrb_symbol_value(id); - raise_va(mrb, E_NAME_ERROR, fmt, args, 1, argv); - va_end(args); + va_start(ap, fmt); + exc = error_va(mrb, E_NAME_ERROR, fmt, ap); + va_end(ap); + mrb_iv_set(mrb, exc, MRB_IVSYM(name), mrb_symbol_value(id)); + mrb_exc_raise(mrb, exc); } MRB_API void @@ -524,16 +558,14 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg) MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, ...) { - mrb_value exc; - mrb_value argv[3]; va_list ap; + mrb_value exc; va_start(ap, fmt); - argv[0] = mrb_vformat(mrb, fmt, ap); - argv[1] = mrb_symbol_value(id); - argv[2] = args; + exc = error_va(mrb, E_NOMETHOD_ERROR, fmt, ap); va_end(ap); - exc = mrb_obj_new(mrb, E_NOMETHOD_ERROR, 3, argv); + mrb_iv_set(mrb, exc, MRB_IVSYM(name), mrb_symbol_value(id)); + mrb_iv_set(mrb, exc, MRB_IVSYM(args), args); mrb_exc_raise(mrb, exc); } @@ -15,7 +15,7 @@ mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb { struct RData *data; - data = (struct RData*)mrb_obj_alloc(mrb, MRB_TT_DATA, klass); + data = MRB_OBJ_ALLOC(mrb, MRB_TT_DATA, klass); data->data = ptr; data->type = type; @@ -145,52 +145,72 @@ mrb_obj_id(mrb_value obj) } } -#if defined(MRB_NAN_BOXING) && defined(MRB_64BIT) -#define mrb_xxx_boxing_cptr_value mrb_nan_boxing_cptr_value -#endif - #ifdef MRB_WORD_BOXING -#define mrb_xxx_boxing_cptr_value mrb_word_boxing_cptr_value - #ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f) { union mrb_value_ v; +#ifdef MRB_WORDBOX_NO_FLOAT_TRUNCATE v.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class); v.fp->f = f; MRB_SET_FROZEN_FLAG(v.bp); +#elif defined(MRB_64BIT) && defined(MRB_USE_FLOAT32) + v.w = 0; + v.f = f; + v.w = ((v.w<<2) & ~3) | 2; +#else + v.f = f; + v.w = (v.w & ~3) | 2; +#endif return v.value; } -#endif /* MRB_NO_FLOAT */ -MRB_API mrb_value -mrb_word_boxing_int_value(mrb_state *mrb, mrb_int n) -{ - if (FIXABLE(n)) return mrb_fixnum_value(n); - else { - union mrb_value_ v; - v.p = mrb_obj_alloc(mrb, MRB_TT_INTEGER, mrb->integer_class); - v.ip->i = n; - MRB_SET_FROZEN_FLAG(v.ip); - return v.value; - } +#ifndef MRB_WORDBOX_NO_FLOAT_TRUNCATE +MRB_API mrb_float +mrb_word_boxing_value_float(mrb_value v) +{ + union mrb_value_ u; + u.value = v; + u.w = u.w & ~3; +#if defined(MRB_64BIT) && defined(MRB_USE_FLOAT32) + u.w >>= 2; +#endif + return u.f; } -#endif /* MRB_WORD_BOXING */ +#endif +#endif /* MRB_NO_FLOAT */ -#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT)) MRB_API mrb_value -mrb_xxx_boxing_cptr_value(mrb_state *mrb, void *p) +mrb_word_boxing_cptr_value(mrb_state *mrb, void *p) { mrb_value v; - struct RCptr *cptr = (struct RCptr*)mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class); + struct RCptr *cptr = MRB_OBJ_ALLOC(mrb, MRB_TT_CPTR, mrb->object_class); SET_OBJ_VALUE(v, cptr); cptr->p = p; return v; } +#endif /* MRB_WORD_BOXING */ + +#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_INT64)) +MRB_API mrb_value +mrb_boxing_int_value(mrb_state *mrb, mrb_int n) +{ + if (FIXABLE(n)) return mrb_fixnum_value(n); + else { + mrb_value v; + struct RInteger *p; + + p = (struct RInteger*)mrb_obj_alloc(mrb, MRB_TT_INTEGER, mrb->integer_class); + p->i = n; + MRB_SET_FROZEN_FLAG((struct RBasic*)p); + SET_OBJ_VALUE(v, p); + return v; + } +} #endif #if defined _MSC_VER && _MSC_VER < 1900 diff --git a/src/fmt_fp.c b/src/fmt_fp.c index d3fe97ce3..bcb9ccc24 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -1,463 +1,363 @@ #include <mruby.h> -#if !defined(MRB_NO_FLOAT) -#if defined(MRB_NO_STDIO) || defined(_WIN32) || defined(_WIN64) -/* - -Most code in this file originates from musl (src/stdio/vfprintf.c) -which, just like mruby itself, is licensed under the MIT license. - -Copyright (c) 2005-2014 Rich Felker, et al. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -#include <limits.h> #include <string.h> -#include <math.h> -#include <float.h> -#include <ctype.h> -#include <mruby/string.h> +#ifndef MRB_NO_FLOAT +/*********************************************************************** -struct fmt_args; + Routine for converting a single-precision + floating point number into a string. -typedef void output_func(struct fmt_args *f, const char *s, size_t l); + The code in this function was inspired from Fred Bayer's pdouble.c. + Since pdouble.c was released as Public Domain, I'm releasing this + code as public domain as well. -struct fmt_args { - mrb_state *mrb; - output_func *output; - void *opaque; -}; + Dave Hylands -struct mrb_cstr { - char *buf; - size_t len; -}; + The original code can be found in https://github.com/dhylands/format-float +***********************************************************************/ -#define MAX(a,b) ((a)>(b) ? (a) : (b)) -#define MIN(a,b) ((a)<(b) ? (a) : (b)) +/*********************************************************************** -/* Convenient bit representation for modifier flags, which all fall - * within 31 codepoints of the space character. */ + I modified the routine for mruby: -#define ALT_FORM (1U<<('#'-' ')) -#define ZERO_PAD (1U<<('0'-' ')) -#define LEFT_ADJ (1U<<('-'-' ')) -#define PAD_POS (1U<<(' '-' ')) -#define MARK_POS (1U<<('+'-' ')) + * support `double` + * support `#` (alt_form) modifier -#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS) + My modifications in this file are also placed in the public domain. -static output_func strcat_value; -static output_func strcat_cstr; + Matz (Yukihiro Matsumoto) -static void -strcat_value(struct fmt_args *f, const char *s, size_t l) -{ - mrb_value str = *(mrb_value*)f->opaque; - mrb_str_cat(f->mrb, str, s, l); -} +***********************************************************************/ -static void -strcat_cstr(struct fmt_args *f, const char *s, size_t l) -{ - struct mrb_cstr *cstr = (struct mrb_cstr*)f->opaque; +#include <math.h> - if (l > cstr->len) { - mrb_state *mrb = f->mrb; +#ifdef MRB_USE_FLOAT32 - mrb_raise(mrb, E_ARGUMENT_ERROR, "string buffer too small"); - } +// 1 sign bit, 8 exponent bits, and 23 mantissa bits. +// exponent values 0 and 255 are reserved, exponent can be 1 to 254. +// exponent is stored with a bias of 127. +// The min and max floats are on the order of 1x10^37 and 1x10^-37 - memcpy(cstr->buf, s, l); +#define FLT_DECEXP 32 +#define FLT_ROUND_TO_ONE 0.9999995F +#define FLT_MIN_BUF_SIZE 6 // -9e+99 - cstr->buf += l; - cstr->len -= l; -} +#else -static void -out(struct fmt_args *f, const char *s, size_t l) -{ - f->output(f, s, l); -} +// 1 sign bit, 11 exponent bits, and 52 mantissa bits. -#define PAD_SIZE 256 -static void -pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint32_t fl) -{ - char pad[PAD_SIZE]; - if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; - l = w - l; - memset(pad, c, l>PAD_SIZE ? PAD_SIZE : l); - for (; l >= PAD_SIZE; l -= PAD_SIZE) - out(f, pad, PAD_SIZE); - out(f, pad, l); -} +#define FLT_DECEXP 256 +#define FLT_ROUND_TO_ONE 0.999999999995 +#define FLT_MIN_BUF_SIZE 7 // -9e+199 -static const char xdigits[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; +#endif /* MRB_USE_FLOAT32 */ -static char* -fmt_u(uint32_t x, char *s) -{ - for (; x; x /= 10) *--s = '0' + x % 10; - return s; -} - -/* Do not override this check. The floating-point printing code below - * depends on the float.h constants being right. If they are wrong, it - * may overflow the stack. */ -#if LDBL_MANT_DIG == 53 -typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; +static const mrb_float g_pos_pow[] = { +#ifndef MRB_USE_FLOAT32 + 1e256, 1e128, 1e64, #endif + 1e32, 1e16, 1e8, 1e4, 1e2, 1e1 +}; +static const mrb_float g_neg_pow[] = { +#ifndef MRB_USE_FLOAT32 + 1e-256, 1e-128, 1e-64, +#endif + 1e-32, 1e-16, 1e-8, 1e-4, 1e-2, 1e-1 +}; -static int -fmt_fp(struct fmt_args *f, long double y, ptrdiff_t w, ptrdiff_t p, uint32_t fl, int t) -{ - uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion - + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion - uint32_t *a, *d, *r, *z; - uint32_t i; - int e2=0, e, j; - ptrdiff_t l; - char buf[9+LDBL_MANT_DIG/4], *s; - const char *prefix="-0X+0X 0X-0x+0x 0x"; - ptrdiff_t pl; - char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr; - - pl=1; - if (signbit(y)) { - y=-y; - } else if (fl & MARK_POS) { - prefix+=3; - } else if (fl & PAD_POS) { - prefix+=6; - } else prefix++, pl=0; - - if (!isfinite(y)) { - const char *ss = (t&32)?"inf":"INF"; - if (y!=y) ss=(t&32)?"nan":"NAN"; - pad(f, ' ', w, 3+pl, fl&~ZERO_PAD); - out(f, prefix, pl); - out(f, ss, 3); - pad(f, ' ', w, 3+pl, fl^LEFT_ADJ); - return (int)MAX(w, 3+pl); +/* + * mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, char sign) + * + * fmt: should be one of 'e', 'E', 'f', 'F', 'g', or 'G'. (|0x80 for '#') + * prec: is the precision (as specified in printf) + * sign: should be '\0', '+', or ' ' ('\0' is the normal one - only print + * a sign if ```f``` is negative. Anything else is printed as the + * sign character for positive numbers. + */ + +int +mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, char sign) { + char *s = buf; + int buf_remaining = buf_size - 1; + int alt_form = 0; + + if ((uint8_t)fmt & 0x80) { + fmt &= 0x7f; /* turn off alt_form flag */ + alt_form = 1; } + if (buf_size <= FLT_MIN_BUF_SIZE) { + // Smallest exp notion is -9e+99 (-9e+199) which is 6 (7) chars plus terminating + // null. - y = frexp((double)y, &e2) * 2; - if (y) e2--; - - if ((t|32)=='a') { - long double round = 8.0; - ptrdiff_t re; - - if (t&32) prefix += 9; - pl += 2; + if (buf_size >= 2) { + *s++ = '?'; + } + if (buf_size >= 1) { + *s++ = '\0'; + } + return buf_size >= 2; + } + if (signbit(f)) { + *s++ = '-'; + f = -f; + } else if (sign) { + *s++ = sign; + } + buf_remaining -= (s - buf); // Adjust for sign + + { + char uc = fmt & 0x20; + if (isinf(f)) { + *s++ = 'I' ^ uc; + *s++ = 'N' ^ uc; + *s++ = 'F' ^ uc; + goto ret; + } else if (isnan(f)) { + *s++ = 'N' ^ uc; + *s++ = 'A' ^ uc; + *s++ = 'N' ^ uc; + ret: + *s = '\0'; + return s - buf; + } + } - if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; - else re=LDBL_MANT_DIG/4-1-p; + if (prec < 0) { + prec = 6; + } + char e_char = 'E' | (fmt & 0x20); // e_char will match case of fmt + fmt |= 0x20; // Force fmt to be lowercase + char org_fmt = fmt; + if (fmt == 'g' && prec == 0) { + prec = 1; + } + int e, e1; + int dec = 0; + char e_sign = '\0'; + int num_digits = 0; + const mrb_float *pos_pow = g_pos_pow; + const mrb_float *neg_pow = g_neg_pow; + + if (f == 0.0) { + e = 0; + if (fmt == 'e') { + e_sign = '+'; + } else if (fmt == 'f') { + num_digits = prec + 1; + } + } else if (f < 1.0) { // f < 1.0 + char first_dig = '0'; + if (f >= FLT_ROUND_TO_ONE) { + first_dig = '1'; + } - if (re) { - while (re--) round*=16; - if (*prefix=='-') { - y=-y; - y-=round; - y+=round; - y=-y; + // Build negative exponent + for (e = 0, e1 = FLT_DECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { + if (*neg_pow > f) { + e += e1; + f *= *pos_pow; } - else { - y+=round; - y-=round; + } + char e_sign_char = '-'; + if (f < 1.0) { + if (f >= FLT_ROUND_TO_ONE) { + f = 1.0; + if (e == 0) { + e_sign_char = '+'; + } + } else { + e++; + f *= 10.0; } } - estr=fmt_u(e2<0 ? -e2 : e2, ebuf); - if (estr==ebuf) *--estr='0'; - *--estr = (e2<0 ? '-' : '+'); - *--estr = t+('p'-'a'); - - s=buf; - do { - int x=(int)y; - *s++=xdigits[x]|(t&32); - y=16*(y-x); - if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.'; - } while (y); - - if (p && s-buf-2 < p) - l = (p+2) + (ebuf-estr); - else - l = (s-buf) + (ebuf-estr); - - pad(f, ' ', w, pl+l, fl); - out(f, prefix, pl); - pad(f, '0', w, pl+l, fl^ZERO_PAD); - out(f, buf, s-buf); - pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0); - out(f, estr, ebuf-estr); - pad(f, ' ', w, pl+l, fl^LEFT_ADJ); - return (int)MAX(w, pl+l); - } - if (p<0) p=6; - - if (y) y *= 268435456.0, e2-=28; + // If the user specified 'g' format, and e is <= 4, then we'll switch + // to the fixed format ('f') - if (e2<0) a=r=z=big; - else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; + if (fmt == 'f' || (fmt == 'g' && e <= 4)) { + fmt = 'f'; + dec = -1; + *s++ = first_dig; - do { - *z = (uint32_t)y; - y = 1000000000*(y-*z++); - } while (y); - - while (e2>0) { - uint32_t carry=0; - int sh=MIN(29,e2); - for (d=z-1; d>=a; d--) { - uint64_t x = ((uint64_t)*d<<sh)+carry; - *d = x % 1000000000; - carry = (uint32_t)(x / 1000000000); + if (org_fmt == 'g') { + prec += (e - 1); + } + // truncate precision to prevent buffer overflow + if (prec + 2 > buf_remaining) { + prec = buf_remaining - 2; + } + num_digits = prec; + if (num_digits || alt_form) { + *s++ = '.'; + while (--e && num_digits) { + *s++ = '0'; + num_digits--; + } + } + } else { + // For e & g formats, we'll be printing the exponent, so set the + // sign. + e_sign = e_sign_char; + dec = 0; + + if (prec > (buf_remaining - FLT_MIN_BUF_SIZE)) { + prec = buf_remaining - FLT_MIN_BUF_SIZE; + if (fmt == 'g') { + prec++; + } + } } - if (carry) *--a = carry; - while (z>a && !z[-1]) z--; - e2-=sh; - } - while (e2<0) { - uint32_t carry=0, *b; - int sh=MIN(9,-e2), need=1+((int)p+LDBL_MANT_DIG/3+8)/9; - for (d=a; d<z; d++) { - uint32_t rm = *d & ((1<<sh)-1); - *d = (*d>>sh) + carry; - carry = (1000000000>>sh) * rm; + } else { + // Build positive exponent + for (e = 0, e1 = FLT_DECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { + if (*pos_pow <= f) { + e += e1; + f *= *neg_pow; + } } - if (!*a) a++; - if (carry) *z++ = carry; - /* Avoid (slow!) computation past requested precision */ - b = (t|32)=='f' ? r : a; - if (z-b > need) z = b+need; - e2+=sh; - } - if (a<z) for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); - else e=0; - - /* Perform rounding: j is precision after the radix (possibly neg) */ - j = (int)p - ((t|32)!='f')*e - ((t|32)=='g' && p); - if (j < 9*(z-r-1)) { - uint32_t x; - /* We avoid C's broken division of negative numbers */ - d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP); - j += 9*LDBL_MAX_EXP; - j %= 9; - for (i=10, j++; j<9; i*=10, j++); - x = *d % i; - /* Are there any significant digits past j? */ - if (x || d+1!=z) { - long double round = 2/LDBL_EPSILON; - long double small; - if (*d/i & 1) round += 2; - if (x<i/2) small=0.5; - else if (x==i/2 && d+1==z) small=1.0; - else small=1.5; - if (pl && *prefix=='-') round*=-1, small*=-1; - *d -= x; - /* Decide whether to round by probing round+small */ - if (round+small != round) { - *d = *d + i; - while (*d > 999999999) { - *d--=0; - if (d<a) *--a=0; - (*d)++; + // If the user specified fixed format (fmt == 'f') and e makes the + // number too big to fit into the available buffer, then we'll + // switch to the 'e' format. + + if (fmt == 'f') { + if (e >= buf_remaining) { + fmt = 'e'; + } else if ((e + prec + 2) > buf_remaining) { + prec = buf_remaining - e - 2; + if (prec < 0) { + // This means no decimal point, so we can add one back + // for the decimal. + prec++; } - for (i=10, e=9*(int)(r-a); *a>=i; i*=10, e++); } } - if (z>d+1) z=d+1; - } - for (; z>a && !z[-1]; z--); - - if ((t|32)=='g') { - if (!p) p++; - if (p>e && e>=-4) { - t--; - p-=e+1; - } - else { - t-=2; - p--; - } - if (!(fl&ALT_FORM)) { - /* Count trailing zeros in last place */ - if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++); - else j=9; - if ((t|32)=='f') - p = MIN(p,MAX(0,9*(z-r-1)-j)); - else - p = MIN(p,MAX(0,9*(z-r-1)+e-j)); + if (fmt == 'e' && prec > (buf_remaining - 6)) { + prec = buf_remaining - 6; } - } - l = 1 + p + (p || (fl&ALT_FORM)); - if ((t|32)=='f') { - if (e>0) l+=e; - } - else { - estr=fmt_u(e<0 ? -e : e, ebuf); - while(ebuf-estr<2) *--estr='0'; - *--estr = (e<0 ? '-' : '+'); - *--estr = t; - l += ebuf-estr; - } + // If the user specified 'g' format, and e is < prec, then we'll switch + // to the fixed format. - pad(f, ' ', w, pl+l, fl); - out(f, prefix, pl); - pad(f, '0', w, pl+l, fl^ZERO_PAD); - - if ((t|32)=='f') { - if (a>r) a=r; - for (d=a; d<=r; d++) { - char *ss = fmt_u(*d, buf+9); - if (d!=a) while (ss>buf) *--ss='0'; - else if (ss==buf+9) *--ss='0'; - out(f, ss, buf+9-ss); + if (fmt == 'g' && e < prec) { + fmt = 'f'; + prec -= (e + 1); } - if (p || (fl&ALT_FORM)) out(f, ".", 1); - for (; d<z && p>0; d++, p-=9) { - char *ss = fmt_u(*d, buf+9); - while (ss>buf) *--ss='0'; - out(f, ss, MIN(9,p)); + if (fmt == 'f') { + dec = e; + num_digits = prec + e + 1; + } else { + e_sign = '+'; } - pad(f, '0', p+9, 9, 0); } - else { - if (z<=a) z=a+1; - for (d=a; d<z && p>=0; d++) { - char *ss = fmt_u(*d, buf+9); - if (ss==buf+9) *--ss='0'; - if (d!=a) while (ss>buf) *--ss='0'; - else { - out(f, ss++, 1); - if (p>0||(fl&ALT_FORM)) out(f, ".", 1); - } - out(f, ss, MIN(buf+9-ss, p)); - p -= (int)(buf+9-ss); - } - pad(f, '0', p+18, 18, 0); - out(f, estr, ebuf-estr); + if (prec < 0) { + // This can happen when the prec is trimmed to prevent buffer overflow + prec = 0; } - pad(f, ' ', w, pl+l, fl^LEFT_ADJ); - - return (int)MAX(w, pl+l); -} - -static int -fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) -{ - ptrdiff_t w, p; - uint32_t fl; - - if (*fmt != '%') { - return -1; - } - ++fmt; - - /* Read modifier flags */ - for (fl=0; (unsigned)*fmt-' '<32 && (FLAGMASK&(1U<<(*fmt-' '))); fmt++) - fl |= 1U<<(*fmt-' '); - - /* - and 0 flags are mutually exclusive */ - if (fl & LEFT_ADJ) fl &= ~ZERO_PAD; - - for (w = 0; ISDIGIT(*fmt); ++fmt) { - w = 10 * w + (*fmt - '0'); + // We now have f as a floating point number between >= 1 and < 10 + // (or equal to zero), and e contains the absolute value of the power of + // 10 exponent. and (dec + 1) == the number of dgits before the decimal. + + // For e, prec is # digits after the decimal + // For f, prec is # digits after the decimal + // For g, prec is the max number of significant digits + // + // For e & g there will be a single digit before the decimal + // for f there will be e digits before the decimal + + if (fmt == 'e') { + num_digits = prec + 1; + } else if (fmt == 'g') { + if (prec == 0) { + prec = 1; + } + num_digits = prec; } - if (*fmt == '.') { - ++fmt; - for (p = 0; ISDIGIT(*fmt); ++fmt) { - p = 10 * p + (*fmt - '0'); + // Print the digits of the mantissa + for (int i = 0; i < num_digits; ++i, --dec) { + int8_t d = (int8_t)((int)f)%10; + *s++ = '0' + d; + if (dec == 0 && (prec > 0 || alt_form)) { + *s++ = '.'; } - } - else { - p = -1; + f -= (mrb_float)d; + f *= 10.0; } - switch (*fmt) { - case 'e': case 'f': case 'g': case 'a': - case 'E': case 'F': case 'G': case 'A': - return fmt_fp(f, flo, w, p, fl, *fmt); - default: - return -1; + // Round + if (f >= 5.0) { + char *rs = s; + rs--; + while (1) { + if (*rs == '.') { + rs--; + continue; + } + if (*rs < '0' || *rs > '9') { + // + or - + rs++; // So we sit on the digit to the right of the sign + break; + } + if (*rs < '9') { + (*rs)++; + break; + } + *rs = '0'; + if (rs == buf) { + break; + } + rs--; + } + if (*rs == '0') { + // We need to insert a 1 + if (rs[1] == '.' && fmt != 'f') { + // We're going to round 9.99 to 10.00 + // Move the decimal point + rs[0] = '.'; + rs[1] = '0'; + if (e_sign == '-') { + e--; + } else { + e++; + } + } + s++; + char *ss = s; + while (ss > rs) { + *ss = ss[-1]; + ss--; + } + *rs = '1'; + if (f < 1.0 && fmt == 'f') { + // We rounded up to 1.0 + prec--; + } + } } -} -MRB_API mrb_value -mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) -{ - struct fmt_args f; - mrb_value str = mrb_str_new_capa(mrb, 24); - - f.mrb = mrb; - f.output = strcat_value; - f.opaque = (void*)&str; - if (fmt_core(&f, fmt, mrb_float(flo)) < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string"); + if (org_fmt == 'g' && prec > 0 && !alt_form) { + // Remove trailing zeros and a trailing decimal point + while (s[-1] == '0') { + s--; + } + if (s[-1] == '.') { + s--; + } } - return str; -} - -MRB_API int -mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval) -{ - struct fmt_args f; - struct mrb_cstr cstr; - - cstr.buf = buf; - cstr.len = len - 1; /* reserve NUL terminator */ - f.mrb = mrb; - f.output = strcat_cstr; - f.opaque = (void*)&cstr; - if (fmt_core(&f, fmt, fval) < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string"); + // Append the exponent + if (e_sign) { + *s++ = e_char; + *s++ = e_sign; + if (e >= 100) { + *s++ = '0' + (e / 100); + e %= 100; + } + *s++ = '0' + (e / 10); + *s++ = '0' + (e % 10); } - *cstr.buf = '\0'; - return (int)(cstr.buf - buf); -} -#else /* MRB_NO_STDIO || _WIN32 || _WIN64 */ -#include <stdio.h> - -MRB_API mrb_value -mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) -{ - char buf[25]; - - snprintf(buf, sizeof(buf), fmt, mrb_float(flo)); - return mrb_str_new_cstr(mrb, buf); -} + *s = '\0'; -MRB_API int -mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval) -{ - return snprintf(buf, len, fmt, fval); + return s - buf; } -#endif /* MRB_NO_STDIO || _WIN32 || _WIN64 */ #endif @@ -5,7 +5,6 @@ */ #include <string.h> -#include <stdlib.h> #ifdef MRB_USE_MALLOC_TRIM #include <malloc.h> #endif @@ -24,6 +23,10 @@ #include <mruby/throw.h> #include <mruby/presym.h> +#ifdef MRB_GC_STRESS +#include <stdlib.h> +#endif + /* = Tri-color Incremental Garbage Collection @@ -131,12 +134,6 @@ typedef struct { struct RFiber fiber; struct RException exc; struct RBreak brk; -#ifdef MRB_WORD_BOXING -#ifndef MRB_NO_FLOAT - struct RFloat floatv; -#endif - struct RCptr cptr; -#endif } as; } RVALUE; @@ -203,7 +200,7 @@ gettimeofday_time(void) #define GC_RED MRB_GC_RED #define GC_WHITES (GC_WHITE_A | GC_WHITE_B) #define GC_COLOR_MASK 7 -mrb_static_assert1(MRB_GC_RED <= GC_COLOR_MASK); +mrb_static_assert(MRB_GC_RED <= GC_COLOR_MASK); #define paint_gray(o) ((o)->color = GC_GRAY) #define paint_black(o) ((o)->color = GC_BLACK) @@ -295,7 +292,7 @@ MRB_API void* mrb_alloca(mrb_state *mrb, size_t size) { struct RString *s; - s = (struct RString*)mrb_obj_alloc(mrb, MRB_TT_STRING, mrb->string_class); + s = MRB_OBJ_ALLOC(mrb, MRB_TT_STRING, mrb->string_class); return s->as.heap.ptr = (char*)mrb_malloc(mrb, size); } @@ -602,27 +599,7 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) gc->gray_list = obj; } -static mrb_int -ci_nregs(mrb_callinfo *ci) -{ - const struct RProc *p = ci->proc; - mrb_int n = 0; - - if (!p) { - if (ci->argc < 0) return 3; - return ci->argc+2; - } - if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { - n = p->body.irep->nregs; - } - if (ci->argc < 0) { - if (n < 3) n = 3; /* self + args + blk */ - } - if (ci->argc > n) { - n = ci->argc + 2; /* self + blk */ - } - return n; -} +mrb_int mrb_ci_nregs(mrb_callinfo *ci); static void mark_context_stack(mrb_state *mrb, struct mrb_context *c) @@ -634,7 +611,7 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c) if (c->stbase == NULL) return; if (c->ci) { e = (c->ci->stack ? c->ci->stack - c->stbase : 0); - e += ci_nregs(c->ci); + e += mrb_ci_nregs(c->ci); } else { e = 0; @@ -709,7 +686,6 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_OBJECT: case MRB_TT_DATA: - case MRB_TT_EXCEPTION: mrb_gc_mark_iv(mrb, (struct RObject*)obj); break; @@ -745,6 +721,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) } break; + case MRB_TT_STRUCT: case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; @@ -781,6 +758,13 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) } break; + case MRB_TT_EXCEPTION: + mrb_gc_mark_iv(mrb, (struct RObject*)obj); + if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->mesg); + } + break; + default: break; } @@ -860,6 +844,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) } break; + case MRB_TT_STRUCT: case MRB_TT_ARRAY: if (ARY_SHARED_P(obj)) mrb_ary_decref(mrb, ((struct RArray*)obj)->as.heap.aux.shared); @@ -1010,7 +995,6 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_OBJECT: case MRB_TT_DATA: - case MRB_TT_EXCEPTION: children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); break; @@ -1030,7 +1014,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) i = c->ci->stack - c->stbase; if (c->ci) { - i += ci_nregs(c->ci); + i += mrb_ci_nregs(c->ci); } if (c->stbase + i > c->stend) i = c->stend - c->stbase; children += i; @@ -1044,6 +1028,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) } break; + case MRB_TT_STRUCT: case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; @@ -1062,6 +1047,13 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) children+=2; break; + case MRB_TT_EXCEPTION: + children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); + if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + children++; + } + break; + default: break; } @@ -1468,7 +1460,7 @@ gc_disable(mrb_state *mrb, mrb_value obj) /* * call-seq: - * GC.interval_ratio -> fixnum + * GC.interval_ratio -> int * * Returns ratio of GC interval. Default value is 200(%). * @@ -1477,12 +1469,12 @@ gc_disable(mrb_state *mrb, mrb_value obj) static mrb_value gc_interval_ratio_get(mrb_state *mrb, mrb_value obj) { - return mrb_fixnum_value(mrb->gc.interval_ratio); + return mrb_int_value(mrb, mrb->gc.interval_ratio); } /* * call-seq: - * GC.interval_ratio = fixnum -> nil + * GC.interval_ratio = int -> nil * * Updates ratio of GC interval. Default value is 200(%). * GC start as soon as after end all step of GC if you set 100(%). @@ -1501,7 +1493,7 @@ gc_interval_ratio_set(mrb_state *mrb, mrb_value obj) /* * call-seq: - * GC.step_ratio -> fixnum + * GC.step_ratio -> int * * Returns step span ratio of Incremental GC. Default value is 200(%). * @@ -1510,12 +1502,12 @@ gc_interval_ratio_set(mrb_state *mrb, mrb_value obj) static mrb_value gc_step_ratio_get(mrb_state *mrb, mrb_value obj) { - return mrb_fixnum_value(mrb->gc.step_ratio); + return mrb_int_value(mrb, mrb->gc.step_ratio); } /* * call-seq: - * GC.step_ratio = fixnum -> nil + * GC.step_ratio = int -> nil * * Updates step span ratio of Incremental GC. Default value is 200(%). * 1 step of incrementalGC becomes long if a rate is big. diff --git a/src/hash.c b/src/hash.c index 3b5d17761..fc6b6fa6b 100644 --- a/src/hash.c +++ b/src/hash.c @@ -69,8 +69,8 @@ #define AR_MAX_SIZE 16 #define H_MAX_SIZE EA_MAX_CAPA -mrb_static_assert1(offsetof(struct RHash, iv) == offsetof(struct RObject, iv)); -mrb_static_assert1(AR_MAX_SIZE < (1 << MRB_HASH_AR_EA_CAPA_BIT)); +mrb_static_assert(offsetof(struct RHash, iv) == offsetof(struct RObject, iv)); +mrb_static_assert(AR_MAX_SIZE < (1 << MRB_HASH_AR_EA_CAPA_BIT)); typedef struct hash_entry { mrb_value key; @@ -243,7 +243,7 @@ DEFINE_SWITCHER(ht, HT) * assumptions. */ # define HT_ASSERT_SAFE_READ(attr_name) \ - mrb_static_assert1( \ + mrb_static_assert( \ offsetof(hash_table, attr_name) + sizeof(((hash_table*)0)->attr_name) <= \ sizeof(hash_entry)) HT_ASSERT_SAFE_READ(ea); @@ -326,8 +326,15 @@ obj_hash_code(mrb_state *mrb, mrb_value key, struct RHash *h) case MRB_TT_TRUE: case MRB_TT_FALSE: case MRB_TT_SYMBOL: + hash_code = U32(mrb_fixnum(key)); + break; case MRB_TT_INTEGER: + if (mrb_fixnum_p(key)) { + hash_code = U32(mrb_fixnum(key)); + break; + } #ifndef MRB_NO_FLOAT + /* fall through */ case MRB_TT_FLOAT: #endif hash_code = U32(mrb_obj_id(key)); @@ -970,7 +977,7 @@ h_key_for(mrb_state *mrb, mrb_value key) static struct RHash* h_alloc(mrb_state *mrb) { - return (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class); + return MRB_OBJ_ALLOC(mrb, MRB_TT_HASH, mrb->hash_class); } static void @@ -1189,15 +1196,6 @@ mrb_hash_init_copy(mrb_state *mrb, mrb_value self) return self; } -void -mrb_hash_check_kdict(mrb_state *mrb, mrb_value self) -{ - h_each(mrb_hash_ptr(self), entry, { - if (mrb_symbol_p(entry->key)) continue; - mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword argument hash with non symbol keys"); - }); -} - MRB_API mrb_value mrb_hash_dup(mrb_state *mrb, mrb_value self) { @@ -1482,6 +1480,7 @@ static mrb_value mrb_hash_delete(mrb_state *mrb, mrb_value self) { mrb_value key = mrb_get_arg1(mrb); + mrb->c->ci->mid = 0; return mrb_hash_delete_key(mrb, self, key); } diff --git a/src/kernel.c b/src/kernel.c index 25aa41baf..5ecebabeb 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -84,8 +84,8 @@ mrb_equal_m(mrb_state *mrb, mrb_value self) * Document-method: object_id * * call-seq: - * obj.__id__ -> fixnum - * obj.object_id -> fixnum + * obj.__id__ -> int + * obj.object_id -> int * * Returns an integer identifier for <i>obj</i>. The same number will * be returned on all calls to <code>id</code> for a given object, and @@ -97,7 +97,7 @@ mrb_equal_m(mrb_state *mrb, mrb_value self) mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self) { - return mrb_int_value(mrb, mrb_obj_id(self)); + return mrb_fixnum_value(mrb_obj_id(self)); } static int @@ -186,13 +186,10 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) bp = &e->stack[bidx]; } else { - bp = ci->stack+1; - if (ci->argc >= 0) { - bp += ci->argc; - } - else { - bp++; - } + uint8_t n = ci->n == 15 ? 1 : ci->n; + uint8_t k = ci->nk == 15 ? 1 : ci->nk*2; + bidx = n + k + 1; /* self + args + kargs => bidx */ + bp = &ci->stack[bidx]; } block_given: if (mrb_nil_p(*bp)) @@ -293,7 +290,7 @@ mrb_obj_frozen(mrb_state *mrb, mrb_value self) /* 15.3.1.3.15 */ /* * call-seq: - * obj.hash -> fixnum + * obj.hash -> int * * Generates a <code>Integer</code> hash value for this object. This * function must have the property that <code>a.eql?(b)</code> implies @@ -423,8 +420,8 @@ mrb_f_raise(mrb_state *mrb, mrb_value self) mrb_value a[2], exc; mrb_int argc; - argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); + mrb->c->ci->mid = 0; switch (argc) { case 0: mrb_raise(mrb, E_RUNTIME_ERROR, ""); @@ -510,7 +507,7 @@ mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) * # ... * end * def method_missing(methId) - * str = methId.id2name + * str = methId.to_s * romanToInt(str) * end * end @@ -527,6 +524,7 @@ mrb_obj_missing(mrb_state *mrb, mrb_value mod) const mrb_value *a; mrb_int alen; + mrb->c->ci->mid = 0; mrb_get_args(mrb, "n*!", &name, &a, &alen); mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a)); /* not reached */ @@ -584,6 +582,7 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) mrb_sym eqq = MRB_OPSYM(eqq); mrb_value ary; + mrb->c->ci->mid = 0; if (mrb_array_p(self)) { ary = self; } @@ -610,6 +609,17 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) return mrb_false_value(); } +static mrb_value +mrb_encoding(mrb_state *mrb, mrb_value self) +{ + mrb_get_args(mrb, ""); +#ifdef MRB_UTF8_STRING + return mrb_str_new_lit(mrb, "UTF-8"); +#else + return mrb_str_new_lit(mrb, "ASCII-8BIT"); +#endif +} + mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); void @@ -649,8 +659,8 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ARG(1,1)); /* 15.3.1.3.43 */ mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ - mrb_define_method(mrb, krn, "__to_int", mrb_to_int, MRB_ARGS_NONE()); /* internal */ - mrb_define_method(mrb, krn, "__to_str", mrb_to_str, MRB_ARGS_NONE()); /* internal */ + mrb_define_method(mrb, krn, "__to_int", mrb_to_integer, MRB_ARGS_NONE()); /* internal */ + mrb_define_method(mrb, krn, "__ENCODING__", mrb_encoding, MRB_ARGS_NONE()); mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); } diff --git a/src/load.c b/src/load.c index f370dc67e..2d1ec507e 100644 --- a/src/load.c +++ b/src/load.c @@ -4,10 +4,7 @@ ** See Copyright Notice in mruby.h */ -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> +#include <mruby.h> #include <mruby/dump.h> #include <mruby/irep.h> #include <mruby/proc.h> @@ -16,6 +13,7 @@ #include <mruby/error.h> #include <mruby/data.h> #include <mruby/endian.h> +#include <string.h> #if SIZE_MAX < UINT32_MAX # error size_t must be at least 32 bits wide @@ -60,8 +58,6 @@ str_to_double(mrb_state *mrb, const char *p) } #endif -mrb_value mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, mrb_int base, int badcheck); - static mrb_bool read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags, mrb_irep **irepp) { @@ -102,7 +98,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag if (irep->ilen > 0) { size_t data_len = sizeof(mrb_code) * irep->ilen + sizeof(struct mrb_irep_catch_handler) * irep->clen; - mrb_static_assert1(sizeof(struct mrb_irep_catch_handler) == 13); + mrb_static_assert(sizeof(struct mrb_irep_catch_handler) == 13); if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) { return FALSE; } @@ -146,7 +142,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag } break; case IREP_TT_INT64: -#ifdef MRB_64BIT +#ifdef MRB_INT64 { uint64_t i64 = bin_to_uint32(src); src += sizeof(uint32_t); @@ -158,7 +154,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag } break; #else - return FALSE; /* INT64 not supported on MRB_32BIT */ + return FALSE; #endif case IREP_TT_BIGINT: @@ -364,6 +360,12 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t * } } break; + case mrb_debug_line_packed_map: { + file->lines.packed_map = (uint8_t*)mrb_calloc(mrb, 1, (size_t)file->line_entry_count); + memcpy(file->lines.packed_map, bin, file->line_entry_count); + bin += file->line_entry_count; + } break; + default: return MRB_DUMP_GENERAL_FAILURE; } } @@ -604,11 +606,7 @@ read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags) static struct RProc* mrb_proc_read_irep(mrb_state *mrb, const uint8_t *bin) { -#if defined(MRB_USE_LINK_TIME_RO_DATA_P) || defined(MRB_USE_CUSTOM_RO_DATA_P) uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC; -#else - uint8_t flags = FLAG_SRC_STATIC; -#endif return read_irep(mrb, bin, (size_t)-1, flags); } @@ -679,7 +677,7 @@ mrb_load_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize) MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc) { - return mrb_vm_run(mrb, proc, mrb_top_self(mrb), 0); + return mrb_top_run(mrb, proc, mrb_top_self(mrb), 0); } #ifndef MRB_NO_STDIO diff --git a/src/numeric.c b/src/numeric.c index fe1a18f04..fd9f5ce2c 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -4,36 +4,25 @@ ** See Copyright Notice in mruby.h */ -#ifndef MRB_NO_FLOAT -#include <float.h> -#include <math.h> -#endif -#include <limits.h> -#include <stdlib.h> -#include <string.h> - #include <mruby.h> #include <mruby/array.h> #include <mruby/numeric.h> #include <mruby/string.h> #include <mruby/class.h> #include <mruby/presym.h> +#include <string.h> #ifndef MRB_NO_FLOAT #ifdef MRB_USE_FLOAT32 #define trunc(f) truncf(f) -#define floor(f) floorf(f) -#define ceil(f) ceilf(f) #define fmod(x,y) fmodf(x,y) -#define FLO_TO_STR_PREC 8 #else -#define FLO_TO_STR_PREC 16 #endif #endif #ifndef MRB_NO_FLOAT MRB_API mrb_float -mrb_to_flo(mrb_state *mrb, mrb_value val) +mrb_as_float(mrb_state *mrb, mrb_value val) { switch (mrb_type(val)) { case MRB_TT_INTEGER: @@ -137,10 +126,6 @@ mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y) return 0; } -#ifndef MRB_NO_FLOAT -mrb_float mrb_div_flo(mrb_float x, mrb_float y); -#endif - /* 15.2.8.3.4 */ /* 15.2.9.3.4 */ /* @@ -164,7 +149,7 @@ int_div(mrb_state *mrb, mrb_value x) #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); #else - return mrb_float_value(mrb, mrb_div_flo((mrb_float)a, mrb_to_flo(mrb, y))); + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); #endif } @@ -191,7 +176,7 @@ int_idiv(mrb_state *mrb, mrb_value x) if (y == 0) { int_zerodiv(mrb); } - return mrb_fixnum_value(mrb_integer(x) / y); + return mrb_int_value(mrb, mrb_integer(x) / y); } static mrb_value @@ -218,8 +203,9 @@ coerce_step_counter(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "oo", &num, &step); #ifndef MRB_NO_FLOAT - if (mrb_float_p(self) || mrb_float_p(num) || mrb_float_p(step)) { - return mrb_Float(mrb, self); + mrb->c->ci->mid = 0; + if (mrb_float_p(num) || mrb_float_p(step)) { + return mrb_to_float(mrb, self); } #endif @@ -240,7 +226,7 @@ static mrb_value flo_pow(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - mrb_float d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); + mrb_float d = pow(mrb_as_float(mrb, x), mrb_as_float(mrb, y)); return mrb_float_value(mrb, d); } @@ -255,7 +241,7 @@ flo_idiv(mrb_state *mrb, mrb_value xv) } mrb_float -mrb_div_flo(mrb_float x, mrb_float y) +mrb_div_float(mrb_float x, mrb_float y) { if (y != 0.0) { return x / y; @@ -275,14 +261,39 @@ flo_div(mrb_state *mrb, mrb_value x) mrb_float a = mrb_float(x); if (mrb_float_p(y)) { - a = mrb_div_flo(a, mrb_float(y)); + a = mrb_div_float(a, mrb_float(y)); } else { - a = mrb_div_flo(a, mrb_to_flo(mrb, y)); + a = mrb_div_float(a, mrb_as_float(mrb, y)); } return mrb_float_value(mrb, a); } +/* the argument `fmt` is no longer used; you can pass `NULL` */ +mrb_value +mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) +{ + char buf[25]; +#ifdef MRB_USE_FLOAT32 + const int prec = 7; +#else + const int prec = 15; +#endif + + mrb_format_float(mrb_float(flo), buf, sizeof(buf), 'g', prec, '\0'); + for (char *p = buf; *p; p++) { + if (*p == '.') goto exit; + if (*p == 'e') { + memmove(p+2, p, strlen(p)+1); + memcpy(p, ".0", 2); + goto exit; + } + } + strcat(buf, ".0"); + exit: + return mrb_str_new_cstr(mrb, buf); +} + /* 15.2.9.3.16(x) */ /* * call-seq: @@ -307,49 +318,14 @@ flo_to_s(mrb_state *mrb, mrb_value flt) if (isinf(f)) { str = f < 0 ? mrb_str_new_lit(mrb, "-Infinity") : mrb_str_new_lit(mrb, "Infinity"); - goto exit; } else if (isnan(f)) { str = mrb_str_new_lit(mrb, "NaN"); - goto exit; } else { - char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g"; - mrb_int len; - char *begp, *p, *endp; - - str = mrb_float_to_str(mrb, flt, fmt); - - insert_dot_zero: - begp = RSTRING_PTR(str); - len = RSTRING_LEN(str); - for (p = begp, endp = p + len; p < endp; ++p) { - if (*p == '.') { - goto exit; - } - else if (*p == 'e') { - ptrdiff_t e_pos = p - begp; - mrb_str_cat(mrb, str, ".0", 2); - p = RSTRING_PTR(str) + e_pos; - memmove(p + 2, p, len - e_pos); - memcpy(p, ".0", 2); - goto exit; - } - } - - if (FLO_TO_STR_PREC + (begp[0] == '-') <= len) { - --fmt[sizeof(fmt) - 3]; /* %.16g(%.8g) -> %.15g(%.7g) */ - str = mrb_float_to_str(mrb, flt, fmt); - goto insert_dot_zero; - } - else { - mrb_str_cat(mrb, str, ".0", 2); - } - - goto exit; + str = mrb_float_to_str(mrb, flt, NULL); } - exit: RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); return str; } @@ -376,7 +352,7 @@ flo_add(mrb_state *mrb, mrb_value x) return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); #endif default: - return mrb_float_value(mrb, a + mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, a + mrb_as_float(mrb, y)); } } @@ -404,7 +380,7 @@ flo_sub(mrb_state *mrb, mrb_value x) return mrb_funcall_id(mrb, x, MRB_OPSYM(minus), 0); #endif default: - return mrb_float_value(mrb, a - mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, a - mrb_as_float(mrb, y)); } } @@ -431,7 +407,7 @@ flo_mul(mrb_state *mrb, mrb_value x) return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); #endif default: - return mrb_float_value(mrb, a * mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, a * mrb_as_float(mrb, y)); } } @@ -490,7 +466,7 @@ flo_mod(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); mrb_float mod; - flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod); + flodivmod(mrb, mrb_float(x), mrb_as_float(mrb, y), 0, &mod); return mrb_float_value(mrb, mod); } #endif @@ -551,7 +527,7 @@ flo_eq(mrb_state *mrb, mrb_value x) return mrb_bool_value(mrb_float(x) == mrb_float(y)); #ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: - return mrb_bool_value(mrb_float(x) == mrb_to_flo(mrb, y)); + return mrb_bool_value(mrb_float(x) == mrb_as_float(mrb, y)); #endif #ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: @@ -761,49 +737,127 @@ mrb_check_num_exact(mrb_state *mrb, mrb_float num) } } +static mrb_value +flo_ceil_floor(mrb_state *mrb, mrb_value num, double (*func)(double)) +{ + mrb_float f = mrb_float(num); + mrb_int ndigits = 0; +#ifdef MRB_USE_FLOAT32 + const int fprec = 7; +#else + const int fprec = 15; +#endif + + mrb_get_args(mrb, "|i", &ndigits); + if (f == 0.0) { + return ndigits > 0 ? mrb_float_value(mrb, f) : mrb_fixnum_value(0); + } + if (ndigits > 0) { + if (ndigits > fprec) return num; + mrb_float d = pow(10, ndigits); + f = func(f * d) / d; + return mrb_float_value(mrb, f); + } + if (ndigits < 0) { + mrb_float d = pow(10, -ndigits); + f = func(f / d) * d; + } + else { /* ndigits == 0 */ + f = func(f); + } + mrb_check_num_exact(mrb, f); + return mrb_int_value(mrb, (mrb_int)f); +} + /* 15.2.9.3.10 */ /* * call-seq: - * flt.floor -> integer + * float.floor([ndigits]) -> integer or float * - * Returns the largest integer less than or equal to <i>flt</i>. + * Returns the largest number less than or equal to +float+ with + * a precision of +ndigits+ decimal digits (default: 0). + * + * When the precision is negative, the returned value is an integer + * with at least <code>ndigits.abs</code> trailing zeros. + * + * Returns a floating point number when +ndigits+ is positive, + * otherwise returns an integer. * * 1.2.floor #=> 1 * 2.0.floor #=> 2 * (-1.2).floor #=> -2 * (-2.0).floor #=> -2 + * + * 1.234567.floor(2) #=> 1.23 + * 1.234567.floor(3) #=> 1.234 + * 1.234567.floor(4) #=> 1.2345 + * 1.234567.floor(5) #=> 1.23456 + * + * 34567.89.floor(-5) #=> 0 + * 34567.89.floor(-4) #=> 30000 + * 34567.89.floor(-3) #=> 34000 + * 34567.89.floor(-2) #=> 34500 + * 34567.89.floor(-1) #=> 34560 + * 34567.89.floor(0) #=> 34567 + * 34567.89.floor(1) #=> 34567.8 + * 34567.89.floor(2) #=> 34567.89 + * 34567.89.floor(3) #=> 34567.89 + * + * Note that the limited precision of floating point arithmetic + * might lead to surprising results: + * + * (0.3 / 0.1).floor #=> 2 (!) */ - static mrb_value flo_floor(mrb_state *mrb, mrb_value num) { - mrb_float f = floor(mrb_float(num)); - - mrb_check_num_exact(mrb, f); - return mrb_int_value(mrb, (mrb_int)f); + return flo_ceil_floor(mrb, num, floor); } /* 15.2.9.3.8 */ /* * call-seq: - * flt.ceil -> integer + * float.ceil([ndigits]) -> integer or float + * + * Returns the smallest number greater than or equal to +float+ with + * a precision of +ndigits+ decimal digits (default: 0). + * + * When the precision is negative, the returned value is an integer + * with at least <code>ndigits.abs</code> trailing zeros. * - * Returns the smallest <code>Integer</code> greater than or equal to - * <i>flt</i>. + * Returns a floating point number when +ndigits+ is positive, + * otherwise returns an integer. * * 1.2.ceil #=> 2 * 2.0.ceil #=> 2 * (-1.2).ceil #=> -1 * (-2.0).ceil #=> -2 + * + * 1.234567.ceil(2) #=> 1.24 + * 1.234567.ceil(3) #=> 1.235 + * 1.234567.ceil(4) #=> 1.2346 + * 1.234567.ceil(5) #=> 1.23457 + * + * 34567.89.ceil(-5) #=> 100000 + * 34567.89.ceil(-4) #=> 40000 + * 34567.89.ceil(-3) #=> 35000 + * 34567.89.ceil(-2) #=> 34600 + * 34567.89.ceil(-1) #=> 34570 + * 34567.89.ceil(0) #=> 34568 + * 34567.89.ceil(1) #=> 34567.9 + * 34567.89.ceil(2) #=> 34567.89 + * 34567.89.ceil(3) #=> 34567.89 + * + * Note that the limited precision of floating point arithmetic + * might lead to surprising results: + * + * (2.1 / 0.7).ceil #=> 4 (!) */ static mrb_value flo_ceil(mrb_state *mrb, mrb_value num) { - mrb_float f = ceil(mrb_float(num)); - - mrb_check_num_exact(mrb, f); - return mrb_int_value(mrb, (mrb_int)f); + return flo_ceil_floor(mrb, num, ceil); } /* 15.2.9.3.12 */ @@ -853,6 +907,7 @@ flo_round(mrb_state *mrb, mrb_value num) mrb_check_num_exact(mrb, number); f = 1.0; + if (ndigits < -DBL_DIG-2) return mrb_fixnum_value(0); i = ndigits >= 0 ? ndigits : -ndigits; if (ndigits > DBL_DIG+2) return num; while (--i >= 0) @@ -891,6 +946,18 @@ flo_round(mrb_state *mrb, mrb_value num) } /* 15.2.9.3.14 */ +static mrb_value +flo_to_i(mrb_state *mrb, mrb_value num) +{ + mrb_float f = mrb_float(num); + + if (f > 0.0) f = floor(f); + if (f < 0.0) f = ceil(f); + + mrb_check_num_exact(mrb, f); + return mrb_int_value(mrb, (mrb_int)f); +} + /* 15.2.9.3.15 */ /* * call-seq: @@ -903,13 +970,8 @@ flo_round(mrb_state *mrb, mrb_value num) static mrb_value flo_truncate(mrb_state *mrb, mrb_value num) { - mrb_float f = mrb_float(num); - - if (f > 0.0) f = floor(f); - if (f < 0.0) f = ceil(f); - - mrb_check_num_exact(mrb, f); - return mrb_int_value(mrb, (mrb_int)f); + if (signbit(mrb_float(num))) return flo_ceil(mrb, num); + return flo_floor(mrb, num); } static mrb_value @@ -917,6 +979,15 @@ flo_nan_p(mrb_state *mrb, mrb_value num) { return mrb_bool_value(isnan(mrb_float(num))); } + +static mrb_value +flo_abs(mrb_state *mrb, mrb_value num) +{ + mrb_float f = mrb_float(num); + + if (signbit(f)) return mrb_float_value(mrb, -f); + return num; +} #endif /* @@ -967,7 +1038,7 @@ fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); #else - return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, (mrb_float)a * mrb_as_float(mrb, y)); #endif } } @@ -980,7 +1051,7 @@ mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) } #ifndef MRB_NO_FLOAT if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, mrb_float(x) * mrb_as_float(mrb, y)); } #endif #if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) @@ -999,7 +1070,7 @@ mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) /* 15.2.8.3.3 */ /* * call-seq: - * fix * numeric -> numeric_result + * int * numeric -> numeric_result * * Performs multiplication: the class of the resulting object depends on * the class of <code>numeric</code> and on the magnitude of the @@ -1015,7 +1086,7 @@ int_mul(mrb_state *mrb, mrb_value x) } static void -fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) +intdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) { if (y == 0) { int_zerodiv(mrb); @@ -1039,10 +1110,9 @@ fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) /* 15.2.8.3.5 */ /* * call-seq: - * fix % other -> real - * fix.modulo(other) -> real + * int % other -> real * - * Returns <code>fix</code> modulo <code>other</code>. + * Returns <code>int</code> modulo <code>other</code>. * See <code>numeric.divmod</code> for more information. */ @@ -1053,27 +1123,29 @@ int_mod(mrb_state *mrb, mrb_value x) mrb_int a, b; a = mrb_integer(x); - if (mrb_integer_p(y) && a != MRB_INT_MIN && (b=mrb_integer(y)) != MRB_INT_MIN) { - mrb_int mod; - - fixdivmod(mrb, a, b, NULL, &mod); - return mrb_fixnum_value(mod); + if (mrb_integer_p(y)) { + b = mrb_integer(y); + if (b == 0) int_zerodiv(mrb); + if (a == MRB_INT_MIN && b == -1) return mrb_fixnum_value(0); + mrb_int mod = a % b; + if ((a < 0) != (b < 0) && mod != 0) { + mod += b; + } + return mrb_int_value(mrb, mod); } #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer modulo"); #else - else { - mrb_float mod; + mrb_float mod; - flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), NULL, &mod); - return mrb_float_value(mrb, mod); - } + flodivmod(mrb, (mrb_float)a, mrb_as_float(mrb, y), NULL, &mod); + return mrb_float_value(mrb, mod); #endif } /* * call-seq: - * fix.divmod(numeric) -> array + * int.divmod(numeric) -> array * * See <code>Numeric#divmod</code>. */ @@ -1085,7 +1157,7 @@ int_divmod(mrb_state *mrb, mrb_value x) if (mrb_integer_p(y)) { mrb_int div, mod; - fixdivmod(mrb, mrb_integer(x), mrb_integer(y), &div, &mod); + intdivmod(mrb, mrb_integer(x), mrb_integer(y), &div, &mod); return mrb_assoc_new(mrb, mrb_int_value(mrb, div), mrb_int_value(mrb, mod)); } #ifdef MRB_NO_FLOAT @@ -1095,7 +1167,7 @@ int_divmod(mrb_state *mrb, mrb_value x) mrb_float div, mod; mrb_value a, b; - flodivmod(mrb, (mrb_float)mrb_integer(x), mrb_to_flo(mrb, y), &div, &mod); + flodivmod(mrb, (mrb_float)mrb_integer(x), mrb_as_float(mrb, y), &div, &mod); a = mrb_int_value(mrb, (mrb_int)div); b = mrb_float_value(mrb, mod); return mrb_assoc_new(mrb, a, b); @@ -1111,7 +1183,7 @@ flo_divmod(mrb_state *mrb, mrb_value x) mrb_float div, mod; mrb_value a, b; - flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod); + flodivmod(mrb, mrb_float(x), mrb_as_float(mrb, y), &div, &mod); if (!FIXABLE_FLOAT(div)) a = mrb_float_value(mrb, div); else @@ -1124,9 +1196,9 @@ flo_divmod(mrb_state *mrb, mrb_value x) /* 15.2.8.3.7 */ /* * call-seq: - * fix == other -> true or false + * int == other -> true or false * - * Return <code>true</code> if <code>fix</code> equals <code>other</code> + * Return <code>true</code> if <code>int</code> equals <code>other</code> * numerically. * * 1 == 2 #=> false @@ -1161,7 +1233,7 @@ int_equal(mrb_state *mrb, mrb_value x) /* 15.2.8.3.8 */ /* * call-seq: - * ~fix -> integer + * ~int -> integer * * One's complement: returns a number where each bit is flipped. * ex.0---00001 (1)-> 1---11110 (-2) @@ -1194,7 +1266,7 @@ static mrb_value flo_xor(mrb_state *mrb, mrb_value x); /* 15.2.8.3.9 */ /* * call-seq: - * fix & integer -> integer_result + * int & integer -> integer_result * * Bitwise AND. */ @@ -1210,7 +1282,7 @@ int_and(mrb_state *mrb, mrb_value x) /* 15.2.8.3.10 */ /* * call-seq: - * fix | integer -> integer_result + * int | integer -> integer_result * * Bitwise OR. */ @@ -1226,7 +1298,7 @@ int_or(mrb_state *mrb, mrb_value x) /* 15.2.8.3.11 */ /* * call-seq: - * fix ^ integer -> integer_result + * int ^ integer -> integer_result * * Bitwise EXCLUSIVE OR. */ @@ -1241,45 +1313,48 @@ int_xor(mrb_state *mrb, mrb_value x) #define NUMERIC_SHIFT_WIDTH_MAX (MRB_INT_BIT-1) -static mrb_value -lshift(mrb_state *mrb, mrb_int val, mrb_int width) +mrb_bool +mrb_num_shift(mrb_state *mrb, mrb_int val, mrb_int width, mrb_int *num) { - mrb_assert(width >= 0); - if (val > 0) { + if (width < 0) { /* rshift */ + if (width == MRB_INT_MIN || -width >= NUMERIC_SHIFT_WIDTH_MAX) { + if (val < 0) { + *num = -1; + } + else { + *num = 0; + } + } + else { + *num = val >> -width; + } + } + else if (val > 0) { if ((width > NUMERIC_SHIFT_WIDTH_MAX) || (val > (MRB_INT_MAX >> width))) { - int_overflow(mrb, "bit shift"); + return FALSE; } - return mrb_int_value(mrb, val << width); + *num = val << width; } else { if ((width > NUMERIC_SHIFT_WIDTH_MAX) || - (val <= (MRB_INT_MIN >> width))) { - int_overflow(mrb, "bit shift"); + (val < (MRB_INT_MIN >> width))) { + return FALSE; } - return mrb_int_value(mrb, (val * ((mrb_int)1 << width))); + if (width == NUMERIC_SHIFT_WIDTH_MAX) + *num = MRB_INT_MIN; + else + *num = val * ((mrb_int)1 << width); } -} - -static mrb_value -rshift(mrb_state *mrb, mrb_int val, mrb_int width) -{ - mrb_assert(width >= 0); - if (width >= NUMERIC_SHIFT_WIDTH_MAX) { - if (val < 0) { - return mrb_fixnum_value(-1); - } - return mrb_fixnum_value(0); - } - return mrb_int_value(mrb, val >> width); + return TRUE; } /* 15.2.8.3.12 */ /* * call-seq: - * fix << count -> integer or float + * int << count -> integer or float * - * Shifts _fix_ left _count_ positions (right if _count_ is negative). + * Shifts _int_ left _count_ positions (right if _count_ is negative). */ static mrb_value @@ -1293,19 +1368,18 @@ int_lshift(mrb_state *mrb, mrb_value x) } val = mrb_integer(x); if (val == 0) return x; - if (width < 0) { - if (width == MRB_INT_MIN) return rshift(mrb, val, MRB_INT_BIT); - return rshift(mrb, val, -width); + if (!mrb_num_shift(mrb, val, width, &val)) { + int_overflow(mrb, "bit shift"); } - return lshift(mrb, val, width); + return mrb_int_value(mrb, val); } /* 15.2.8.3.13 */ /* * call-seq: - * fix >> count -> integer or float + * int >> count -> integer or float * - * Shifts _fix_ right _count_ positions (left if _count_ is negative). + * Shifts _int_ right _count_ positions (left if _count_ is negative). */ static mrb_value @@ -1319,19 +1393,19 @@ int_rshift(mrb_state *mrb, mrb_value x) } val = mrb_integer(x); if (val == 0) return x; - if (width < 0) { - if (width == MRB_INT_MIN) int_overflow(mrb, "bit shift"); - return lshift(mrb, val, -width); + if (width == MRB_INT_MIN) int_overflow(mrb, "bit shift"); + if (!mrb_num_shift(mrb, val, -width, &val)) { + int_overflow(mrb, "bit shift"); } - return rshift(mrb, val, width); + return mrb_int_value(mrb, val); } /* 15.2.8.3.23 */ /* * call-seq: - * fix.to_f -> float + * int.to_f -> float * - * Converts <i>fix</i> to a <code>Float</code>. + * Converts <i>int</i> to a <code>Float</code>. * */ @@ -1357,13 +1431,12 @@ int_to_f(mrb_state *mrb, mrb_value num) */ /* ------------------------------------------------------------------------*/ MRB_API mrb_value -mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) +mrb_float_to_integer(mrb_state *mrb, mrb_value x) { mrb_int z = 0; if (!mrb_float_p(x)) { mrb_raise(mrb, E_TYPE_ERROR, "non float value"); - z = 0; /* not reached. just suppress warnings. */ } else { mrb_float d = mrb_float(x); @@ -1406,7 +1479,7 @@ int_plus(mrb_state *mrb, mrb_value x, mrb_value y) #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer addition"); #else - return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, (mrb_float)a + mrb_as_float(mrb, y)); #endif } } @@ -1419,7 +1492,7 @@ mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y) } #ifndef MRB_NO_FLOAT if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, mrb_float(x) + mrb_as_float(mrb, y)); } #endif #if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) @@ -1438,7 +1511,7 @@ mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y) /* 15.2.8.3.1 */ /* * call-seq: - * fix + numeric -> numeric_result + * int + numeric -> numeric_result * * Performs addition: the class of the resulting object depends on * the class of <code>numeric</code> and on the magnitude of the @@ -1478,7 +1551,7 @@ int_minus(mrb_state *mrb, mrb_value x, mrb_value y) #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer subtraction"); #else - return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, (mrb_float)a - mrb_as_float(mrb, y)); #endif } } @@ -1491,7 +1564,7 @@ mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y) } #ifndef MRB_NO_FLOAT if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y)); + return mrb_float_value(mrb, mrb_float(x) - mrb_as_float(mrb, y)); } #endif #if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) @@ -1511,7 +1584,7 @@ mrb_num_minus(mrb_state *mrb, mrb_value x, mrb_value y) /* 15.2.8.3.16 */ /* * call-seq: - * fix - numeric -> numeric_result + * int - numeric -> numeric_result * * Performs subtraction: the class of the resulting object depends on * the class of <code>numeric</code> and on the magnitude of the @@ -1525,35 +1598,51 @@ int_sub(mrb_state *mrb, mrb_value self) return int_minus(mrb, self, other); } - -MRB_API mrb_value -mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base) +MRB_API char* +mrb_int_to_cstr(char *buf, size_t len, mrb_int n, mrb_int base) { - char buf[MRB_INT_BIT+1]; - char *b = buf + sizeof buf; - mrb_int val = mrb_integer(x); - mrb_value str; + char *bufend = buf + len; + char *b = bufend-1; - if (base < 2 || 36 < base) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); - } + if (base < 2 || 36 < base) return NULL; + if (len < 2) return NULL; - if (val == 0) { - *--b = '0'; + if (n == 0) { + buf[0] = '0'; + buf[1] = '\0'; + return buf; } - else if (val < 0) { + + *b = '\0'; + if (n < 0) { do { - *--b = mrb_digitmap[-(val % base)]; - } while (val /= base); - *--b = '-'; + if (b-- == buf) return NULL; + *b = mrb_digitmap[-(n % base)]; + } while (n /= base); + if (b-- == buf) return NULL; + *b = '-'; } else { do { - *--b = mrb_digitmap[(int)(val % base)]; - } while (val /= base); + if (b-- == buf) return NULL; + *b = mrb_digitmap[(int)(n % base)]; + } while (n /= base); } + return b; +} - str = mrb_str_new(mrb, b, buf + sizeof(buf) - b); +MRB_API mrb_value +mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base) +{ + char buf[MRB_INT_BIT+1]; + mrb_int val = mrb_integer(x); + + if (base < 2 || 36 < base) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); + } + const char *p = mrb_int_to_cstr(buf, sizeof(buf), val, base); + mrb_assert(p != NULL); + mrb_value str = mrb_str_new_cstr(mrb, p); RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); return str; } @@ -1561,9 +1650,9 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base) /* 15.2.8.3.25 */ /* * call-seq: - * fix.to_s(base=10) -> string + * int.to_s(base=10) -> string * - * Returns a string containing the representation of <i>fix</i> radix + * Returns a string containing the representation of <i>int</i> radix * <i>base</i> (between 2 and 36). * * 12345.to_s #=> "12345" @@ -1580,7 +1669,7 @@ int_to_s(mrb_state *mrb, mrb_value self) mrb_int base = 10; mrb_get_args(mrb, "|i", &base); - return mrb_fixnum_to_str(mrb, self, base); + return mrb_integer_to_str(mrb, self, base); } /* compare two numbers: (1:0:-1; -2 for error) */ @@ -1596,7 +1685,7 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) #ifdef MRB_NO_FLOAT x = mrb_integer(v1); #else - x = mrb_to_flo(mrb, v1); + x = mrb_as_float(mrb, v1); #endif switch (mrb_type(v2)) { case MRB_TT_INTEGER: @@ -1612,7 +1701,7 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) break; #ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: - y = mrb_to_flo(mrb, v2); + y = mrb_as_float(mrb, v2); break; #endif #endif @@ -1635,7 +1724,7 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) * < => -1 * = => 0 * > => +1 - * Comparison---Returns -1, 0, or +1 depending on whether <i>fix</i> is + * Comparison---Returns -1, 0, or +1 depending on whether <i>int</i> is * less than, equal to, or greater than <i>numeric</i>. This is the * basis for the tests in <code>Comparable</code>. When the operands are * not comparable, it returns nil instead of raising an exception. @@ -1817,21 +1906,21 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, ">>", flo_rshift, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "<<", flo_lshift, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */ + mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_OPT(1)); /* 15.2.9.3.8 */ mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ - mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_NONE()); /* 15.2.9.3.10 */ + mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_OPT(1)); /* 15.2.9.3.10 */ mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, MRB_ARGS_NONE()); /* 15.2.9.3.11 */ mrb_define_method(mrb, fl, "round", flo_round, MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */ mrb_define_method(mrb, fl, "to_f", flo_to_f, MRB_ARGS_NONE()); /* 15.2.9.3.13 */ - mrb_define_method(mrb, fl, "to_i", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.14 */ - mrb_define_method(mrb, fl, "to_int", flo_truncate, MRB_ARGS_NONE()); - mrb_define_method(mrb, fl, "truncate", flo_truncate, MRB_ARGS_NONE()); /* 15.2.9.3.15 */ + mrb_define_method(mrb, fl, "to_i", flo_to_i, MRB_ARGS_NONE()); /* 15.2.9.3.14 */ + mrb_define_method(mrb, fl, "truncate", flo_truncate, MRB_ARGS_OPT(1)); /* 15.2.9.3.15 */ mrb_define_method(mrb, fl, "divmod", flo_divmod, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "eql?", flo_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ mrb_define_method(mrb, fl, "to_s", flo_to_s, MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */ mrb_define_method(mrb, fl, "inspect", flo_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, fl, "nan?", flo_nan_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, fl, "abs", flo_abs, MRB_ARGS_NONE()); /* 15.2.7.4.3 */ #ifdef INFINITY mrb_define_const_id(mrb, fl, MRB_SYM(INFINITY), mrb_float_value(mrb, INFINITY)); diff --git a/src/object.c b/src/object.c index a44eab4bb..de0298fab 100644 --- a/src/object.c +++ b/src/object.c @@ -14,12 +14,18 @@ MRB_API mrb_bool mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2) { +#if defined(MRB_NAN_BOXING) + return v1.u == v2.u; +#elif defined(MRB_WORD_BOXING) + return v1.w == v2.w; +#else /* MRB_NO_BOXING */ if (mrb_type(v1) != mrb_type(v2)) return FALSE; switch (mrb_type(v1)) { case MRB_TT_TRUE: return TRUE; case MRB_TT_FALSE: + return (mrb_fixnum(v1) == mrb_fixnum(v2)); case MRB_TT_INTEGER: return (mrb_integer(v1) == mrb_integer(v2)); case MRB_TT_SYMBOL: @@ -33,6 +39,7 @@ mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2) default: return (mrb_ptr(v1) == mrb_ptr(v2)); } +#endif } MRB_API mrb_bool @@ -316,44 +323,15 @@ mrb_init_object(mrb_state *mrb) mrb_define_method(mrb, f, "inspect", false_to_s, MRB_ARGS_NONE()); } -static const struct types { - const enum mrb_vtype type; - const char *name; -} builtin_types[] = { -/* {MRB_TT_NIL, "nil"}, */ - {MRB_TT_FALSE, "false"}, - {MRB_TT_TRUE, "true"}, - {MRB_TT_INTEGER,"Integer"}, - {MRB_TT_SYMBOL, "Symbol"}, /* :symbol */ - {MRB_TT_MODULE, "Module"}, - {MRB_TT_OBJECT, "Object"}, - {MRB_TT_CLASS, "Class"}, - {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */ - {MRB_TT_SCLASS, "SClass"}, - {MRB_TT_PROC, "Proc"}, -#ifndef MRB_NO_FLOAT - {MRB_TT_FLOAT, "Float"}, -#endif - {MRB_TT_ARRAY, "Array"}, - {MRB_TT_HASH, "Hash"}, - {MRB_TT_STRING, "String"}, - {MRB_TT_RANGE, "Range"}, -/* {MRB_TT_BIGNUM, "Bignum"}, */ - {MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */ -/* {MRB_TT_UNDEF, "undef"}, */ /* internal use: #undef; should not happen */ - {MRB_TT_MAXDEFINE, 0} -}; - static const char* type_name(enum mrb_vtype t) { - const struct types *type = builtin_types; - - while (type->type < MRB_TT_MAXDEFINE) { - if (type->type == t) return type->name; - type++; + switch (t) { +#define MRB_VTYPE_NAME(tt, type, name) case tt: return name; + MRB_VTYPE_FOREACH(MRB_VTYPE_NAME) +#undef MRB_VTYPE_NAME + default: return NULL; } - return NULL; } static mrb_value @@ -409,7 +387,7 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t) ename = "nil"; } else if (mrb_integer_p(x)) { - ename = "Fixnum"; + ename = "Integer"; } else if (mrb_symbol_p(x)) { ename = "Symbol"; @@ -507,13 +485,13 @@ mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c) } MRB_API mrb_value -mrb_to_int(mrb_state *mrb, mrb_value val) +mrb_to_integer(mrb_state *mrb, mrb_value val) { if (!mrb_integer_p(val)) { #ifndef MRB_NO_FLOAT if (mrb_float_p(val)) { - return mrb_flo_to_fixnum(mrb, val); + return mrb_float_to_integer(mrb, val); } #endif if (mrb_string_p(val)) { @@ -524,55 +502,9 @@ mrb_to_int(mrb_state *mrb, mrb_value val) return val; } -MRB_API mrb_value -mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base) -{ - mrb_value tmp; - - if (mrb_nil_p(val)) { - if (base != 0) goto arg_error; - mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); - } - switch (mrb_type(val)) { #ifndef MRB_NO_FLOAT - case MRB_TT_FLOAT: - if (base != 0) goto arg_error; - return mrb_flo_to_fixnum(mrb, val); -#endif - - case MRB_TT_INTEGER: - if (base != 0) goto arg_error; - return val; - - case MRB_TT_STRING: - string_conv: - return mrb_str_to_inum(mrb, val, base, TRUE); - - default: - break; - } - if (base != 0) { - tmp = mrb_check_string_type(mrb, val); - if (!mrb_nil_p(tmp)) { - val = tmp; - goto string_conv; - } -arg_error: - mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); - } - /* to raise TypeError */ - return mrb_to_int(mrb, val); -} - MRB_API mrb_value -mrb_Integer(mrb_state *mrb, mrb_value val) -{ - return mrb_convert_to_integer(mrb, val, 0); -} - -#ifndef MRB_NO_FLOAT -MRB_API mrb_value -mrb_Float(mrb_state *mrb, mrb_value val) +mrb_to_float(mrb_state *mrb, mrb_value val) { if (mrb_nil_p(val)) { mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float"); @@ -594,19 +526,6 @@ mrb_Float(mrb_state *mrb, mrb_value val) #endif MRB_API mrb_value -mrb_to_str(mrb_state *mrb, mrb_value val) -{ - return mrb_ensure_string_type(mrb, val); -} - -/* obsolete: use mrb_ensure_string_type() instead */ -MRB_API mrb_value -mrb_string_type(mrb_state *mrb, mrb_value str) -{ - return mrb_ensure_string_type(mrb, str); -} - -MRB_API mrb_value mrb_ensure_string_type(mrb_state *mrb, mrb_value str) { if (!mrb_string_p(str)) { diff --git a/src/proc.c b/src/proc.c index 78ce0e791..c79a53399 100644 --- a/src/proc.c +++ b/src/proc.c @@ -46,7 +46,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep) struct RProc *p; mrb_callinfo *ci = mrb->c->ci; - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class); if (ci) { struct RClass *tc = NULL; @@ -79,13 +79,15 @@ struct REnv* mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc) { struct REnv *e; - mrb_int bidx; + mrb_int bidx = 1; + int n = ci->n; + int nk = ci->nk; - e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, tc); + e = MRB_OBJ_ALLOC(mrb, MRB_TT_ENV, NULL); + e->c = tc; MRB_ENV_SET_LEN(e, nstacks); - bidx = ci->argc; - if (bidx < 0) bidx = 2; - else bidx += 1; + bidx += (n == 15) ? 1 : n; + bidx += (nk == 15) ? 1 : (2*nk); MRB_ENV_SET_BIDX(e, bidx); e->mid = ci->mid; e->stack = stack; @@ -105,7 +107,7 @@ closure_setup(mrb_state *mrb, struct RProc *p) /* do nothing, because e is assigned already */ } else if (up) { - struct RClass *tc = MRB_PROC_TARGET_CLASS(p); + struct RClass *tc = ci->u.target_class; e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, ci->stack, tc); ci->u.env = e; @@ -134,7 +136,7 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) { struct RProc *p; - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class); p->body.func = func; p->flags |= MRB_PROC_CFUNC_FL; p->upper = 0; @@ -224,7 +226,7 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) /* Calling Proc.new without a block is not implemented yet */ mrb_get_args(mrb, "&!", &blk); - p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class)); + p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class)); mrb_proc_copy(p, mrb_proc_ptr(blk)); proc = mrb_obj_value(p); mrb_funcall_with_block(mrb, proc, MRB_SYM(initialize), 0, NULL, proc); @@ -278,7 +280,7 @@ proc_lambda(mrb_state *mrb, mrb_value self) } p = mrb_proc_ptr(blk); if (!MRB_PROC_STRICT_P(p)) { - struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c); + struct RProc *p2 = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, p->c); mrb_proc_copy(p2, p); p2->flags |= MRB_PROC_STRICT; return mrb_obj_value(p2); @@ -417,7 +419,19 @@ mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, c mrb_sym *destlv = (mrb_sym*)irep->lv + irep->nlocals - 1 /* self */; mrb_value *destst = env->stack + irep->nlocals; memmove(destlv, lv, sizeof(mrb_sym) * num); - memmove(destst, stack, sizeof(mrb_value) * num); + if (stack) { + memmove(destst, stack, sizeof(mrb_value) * num); + for (int i = 0; i < num; i++) { + if (!mrb_immediate_p(stack[i])) { + mrb_field_write_barrier(mrb, (struct RBasic*)env, (struct RBasic*)mrb_obj_ptr(stack[i])); + } + } + } + else { + for (int i = num; i > 0; i--, destst++) { + *destst = mrb_nil_value(); + } + } irep->nlocals += num; irep->nregs = irep->nlocals; MRB_ENV_SET_LEN(env, irep->nlocals); diff --git a/src/range.c b/src/range.c index cb60bb63c..7507173b6 100644 --- a/src/range.c +++ b/src/range.c @@ -9,11 +9,12 @@ #include <mruby/range.h> #include <mruby/string.h> #include <mruby/array.h> +#include <mruby/numeric.h> #include <mruby/presym.h> -#define RANGE_INITIALIZED_MASK 1 -#define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_MASK) -#define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_MASK) +#define RANGE_INITIALIZED_FLAG 1 +#define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_FLAG) +#define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_FLAG) static void r_check(mrb_state *mrb, mrb_value a, mrb_value b) @@ -25,13 +26,13 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b) ta = mrb_type(a); tb = mrb_type(b); #ifdef MRB_NO_FLOAT - if (ta == MRB_TT_INTEGER && tb == MRB_TT_INTEGER ) { + if (ta == MRB_TT_INTEGER && tb == MRB_TT_INTEGER ) return; #else if ((ta == MRB_TT_INTEGER || ta == MRB_TT_FLOAT) && (tb == MRB_TT_INTEGER || tb == MRB_TT_FLOAT)) { -#endif return; } +#endif if (mrb_nil_p(a) || mrb_nil_p(b)) return; @@ -88,7 +89,7 @@ range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, m } } else { - r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class); + r = MRB_OBJ_ALLOC(mrb, MRB_TT_RANGE, mrb->range_class); range_ptr_alloc_edges(mrb, r); } @@ -342,6 +343,59 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy) return copy; } +static mrb_value +range_num_to_a(mrb_state *mrb, mrb_value range) +{ + struct RRange *r = mrb_range_ptr(mrb, range); + mrb_value beg = RANGE_BEG(r); + mrb_value end = RANGE_END(r); + mrb_value ary; + + mrb->c->ci->mid = 0; + if (mrb_nil_p(end)) { + mrb_raise(mrb, E_RANGE_ERROR, "cannot convert endless range to an array"); + } + if (mrb_integer_p(beg)) { + if (mrb_integer_p(end)) { + mrb_int a = mrb_integer(beg); + mrb_int b = mrb_integer(end); + mrb_int len; + + if (mrb_int_sub_overflow(b, a, &len)) { + mrb_raise(mrb, E_RANGE_ERROR, "integer range too long"); + } + if (!RANGE_EXCL(r)) len++; + ary = mrb_ary_new_capa(mrb, len); + for (mrb_int i=0; i<len; i++) { + mrb_ary_push(mrb, ary, mrb_int_value(mrb, a+i)); + } + return ary; + } +#ifndef MRB_NO_FLOAT + if (mrb_float_p(end)) { + mrb_float a = (mrb_float)mrb_integer(beg); + mrb_float b = mrb_float(end); + + ary = mrb_ary_new_capa(mrb, (mrb_int)(b - a) + 1); + if (RANGE_EXCL(r)) { + while (a < b) { + mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a)); + a += 1.0; + } + } + else { + while (a <= b) { + mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a)); + a += 1.0; + } + } + return ary; + } +#endif + } + return mrb_nil_value(); +} + mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)) { @@ -409,8 +463,8 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, if (!mrb_range_p(range)) return MRB_RANGE_TYPE_MISMATCH; r = mrb_range_ptr(mrb, range); - beg = mrb_nil_p(RANGE_BEG(r)) ? 0 : mrb_int(mrb, RANGE_BEG(r)); - end = mrb_nil_p(RANGE_END(r)) ? -1 : mrb_int(mrb, RANGE_END(r)); + beg = mrb_nil_p(RANGE_BEG(r)) ? 0 : mrb_as_int(mrb, RANGE_BEG(r)); + end = mrb_nil_p(RANGE_END(r)) ? -1 : mrb_as_int(mrb, RANGE_END(r)); excl = mrb_nil_p(RANGE_END(r)) ? 0 : RANGE_EXCL(r); if (beg < 0) { @@ -456,4 +510,5 @@ mrb_init_range(mrb_state *mrb) mrb_define_method(mrb, r, "inspect", range_inspect, MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */ mrb_define_method(mrb, r, "eql?", range_eql, MRB_ARGS_REQ(1)); /* 15.2.14.4.14(x) */ mrb_define_method(mrb, r, "initialize_copy", range_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.14.4.15(x) */ + mrb_define_method(mrb, r, "__num_to_a", range_num_to_a, MRB_ARGS_NONE()); } diff --git a/src/readflt.c b/src/readflt.c new file mode 100644 index 000000000..b320a43c1 --- /dev/null +++ b/src/readflt.c @@ -0,0 +1,119 @@ +#include <mruby.h> + +#ifndef MRB_NO_FLOAT +/* + * strtod implementation. + * author: Yasuhiro Matsumoto (@mattn) + * license: public domain + */ + +/* +The original code can be found in https://github.com/mattn/strtod + +I modified the routine for mruby: + + * renamed the function `vim_strtod` -> `mrb_float_read` + * simplified the code + +My modifications in this file are also placed in the public domain. + +Matz (Yukihiro Matsumoto) +*/ + +#include <string.h> +#include <math.h> +#include <errno.h> + +MRB_API double +mrb_float_read(const char *str, char **end) +{ + double d = 0.0; + int sign; + int n = 0; + const char *p, *a; + + a = p = str; + while (ISSPACE(*p)) + ++p; + + /* decimal part */ + sign = 1; + if (*p == '-') { + sign = -1; + ++p; + } else if (*p == '+') + ++p; + if (ISDIGIT(*p)) { + d = (double)(*p++ - '0'); + while (*p && ISDIGIT(*p)) { + d = d * 10.0 + (double)(*p - '0'); + ++p; + ++n; + } + a = p; + } else if (*p != '.') + goto done; + d *= sign; + + /* fraction part */ + if (*p == '.') { + double f = 0.0; + double base = 0.1; + ++p; + + if (ISDIGIT(*p)) + { + while (*p && ISDIGIT(*p)) { + f += base * (*p - '0') ; + base /= 10.0; + ++p; + ++n; + } + } + d += f * sign; + a = p; + } + + /* exponential part */ + if ((*p == 'E') || (*p == 'e')) { + int e = 0; + ++p; + + sign = 1; + if (*p == '-') { + sign = -1; + ++p; + } else if (*p == '+') + ++p; + + if (ISDIGIT(*p)) { + while (*p == '0') + ++p; + if (*p == '\0') --p; + e = (int)(*p++ - '0'); + for (; *p && ISDIGIT(*p); p++) { + if (e < 10000) + e = e * 10 + (*p - '0'); + } + e *= sign; + } + else if (!ISDIGIT(*(a-1))) { + a = str; + goto done; + } + else if (*p == 0) + goto done; + d *= pow(10.0, (double) e); + a = p; + } + else if (p > str && !ISDIGIT(*(p-1))) { + a = str; + goto done; + } + +done: + if (end) + *end = (char*)a; + return d; +} +#endif diff --git a/src/readint.c b/src/readint.c new file mode 100644 index 000000000..5fae222c2 --- /dev/null +++ b/src/readint.c @@ -0,0 +1,30 @@ +#include <mruby.h> +#include <mruby/numeric.h> +#include <errno.h> + +/* mrb_int_read(): read mrb_int from a string (base 10 only) */ +/* const char *p - string to read */ +/* const char *e - end of string */ +/* char **endp - end of parsed integer */ + +/* if integer overflows, errno will be set to ERANGE */ +/* also endp will be set to NULL on overflow */ +MRB_API mrb_int +mrb_int_read(const char *p, const char *e, char **endp) +{ + mrb_int n = 0; + int ch; + + while ((e == NULL || p < e) && ISDIGIT(*p)) { + ch = *p - '0'; + if (mrb_int_mul_overflow(n, 10, &n) || + mrb_int_add_overflow(n, ch, &n)) { + if (endp) *endp = NULL; + errno = ERANGE; + return MRB_INT_MAX; + } + p++; + } + if (endp) *endp = (char*)p; + return n; +} diff --git a/src/string.c b/src/string.c index e440bff8c..6c9dd2996 100644 --- a/src/string.c +++ b/src/string.c @@ -8,14 +8,6 @@ # define _CRT_NONSTDC_NO_DEPRECATE #endif -#ifndef MRB_NO_FLOAT -#include <float.h> -#include <math.h> -#endif -#include <limits.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> #include <mruby.h> #include <mruby/array.h> #include <mruby/class.h> @@ -23,6 +15,7 @@ #include <mruby/string.h> #include <mruby/numeric.h> #include <mruby/presym.h> +#include <string.h> typedef struct mrb_shared_string { int refcnt; @@ -32,7 +25,7 @@ typedef struct mrb_shared_string { const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; -#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class)) +#define mrb_obj_alloc_string(mrb) MRB_OBJ_ALLOC((mrb), MRB_TT_STRING, (mrb)->string_class) static struct RString* str_init_normal_capa(mrb_state *mrb, struct RString *s, @@ -244,7 +237,7 @@ str_modify_keep_ascii(mrb_state *mrb, struct RString *s) static void check_null_byte(mrb_state *mrb, mrb_value str) { - mrb_to_str(mrb, str); + mrb_ensure_string_type(mrb, str); if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); } @@ -839,8 +832,15 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0) { struct RString *s; + const char *p = RSTRING_PTR(str0); + size_t len = RSTRING_LEN(str0); check_null_byte(mrb, str0); - s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0)); + if (RSTR_EMBEDDABLE_P(len)) { + s = str_init_embed(mrb_obj_alloc_string(mrb), p, len); + } + else { + s = str_init_normal(mrb, mrb_obj_alloc_string(mrb), p, len); + } return RSTR_PTR(s); } @@ -897,14 +897,14 @@ static mrb_value mrb_str_size(mrb_state *mrb, mrb_value self) { mrb_int len = RSTRING_CHAR_LEN(self); - return mrb_fixnum_value(len); + return mrb_int_value(mrb, len); } static mrb_value mrb_str_bytesize(mrb_state *mrb, mrb_value self) { mrb_int len = RSTRING_LEN(self); - return mrb_fixnum_value(len); + return mrb_int_value(mrb, len); } /* 15.2.10.5.1 */ @@ -1018,7 +1018,7 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1) else { result = mrb_str_cmp(mrb, str1, str2); } - return mrb_fixnum_value(result); + return mrb_int_value(mrb, result); } static mrb_bool @@ -1071,7 +1071,7 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value str) MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value ptr) { - mrb_to_str(mrb, ptr); + mrb_ensure_string_type(mrb, ptr); return RSTRING_LEN(ptr); } @@ -1102,8 +1102,8 @@ static enum str_convert_range str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_int *beg, mrb_int *len) { if (!mrb_undef_p(alen)) { - *beg = mrb_int(mrb, indx); - *len = mrb_int(mrb, alen); + *beg = mrb_as_int(mrb, indx); + *len = mrb_as_int(mrb, alen); return STR_CHAR_RANGE; } else { @@ -1123,7 +1123,7 @@ str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, goto range_arg; default: - indx = mrb_to_int(mrb, indx); + indx = mrb_to_integer(mrb, indx); if (mrb_integer_p(indx)) { *beg = mrb_integer(indx); *len = 1; @@ -1146,7 +1146,7 @@ range_arg: return STR_OUT_OF_RANGE; } -static mrb_value +mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen) { mrb_int beg, len; @@ -1175,14 +1175,14 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen) /* 15.2.10.5.34 */ /* * call-seq: - * str[fixnum] => fixnum or nil - * str[fixnum, fixnum] => new_str or nil - * str[range] => new_str or nil - * str[other_str] => new_str or nil - * str.slice(fixnum) => fixnum or nil - * str.slice(fixnum, fixnum) => new_str or nil - * str.slice(range) => new_str or nil - * str.slice(other_str) => new_str or nil + * str[int] => int or nil + * str[int, int] => new_str or nil + * str[range] => new_str or nil + * str[other_str] => new_str or nil + * str.slice(int) => int or nil + * str.slice(int, int) => new_str or nil + * str.slice(range) => new_str or nil + * str.slice(other_str) => new_str or nil * * Element Reference---If passed a single <code>Integer</code>, returns the code * of the character at that position. If passed two <code>Integer</code> @@ -1239,13 +1239,11 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb if (end > len) { end = len; } if (pos < 0 || pos > len) { - str_out_of_index(mrb, mrb_fixnum_value(pos)); + str_out_of_index(mrb, mrb_int_value(mrb, pos)); } replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep)); - newlen = replen + (len - (end - pos)); - - if (newlen >= MRB_SSIZE_MAX || newlen < replen /* overflowed */) { + if (mrb_int_add_overflow(replen, len - (end - pos), &newlen) || newlen >= MRB_SSIZE_MAX) { mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big"); } @@ -1358,8 +1356,7 @@ mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_ { mrb_int beg, len, charlen; - mrb_to_str(mrb, replace); - + mrb_ensure_string_type(mrb, replace); switch (str_convert_range(mrb, str, indx, alen, &beg, &len)) { case STR_OUT_OF_RANGE: default: @@ -1376,14 +1373,17 @@ mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_ str_range_to_bytes(str, &beg, &len); /* fall through */ case STR_BYTE_RANGE_CORRECTED: - str_replace_partial(mrb, str, beg, beg + len, replace); + if (mrb_int_add_overflow(beg, len, &len)) { + mrb_raise(mrb, E_RUNTIME_ERROR, "string index too big"); + } + str_replace_partial(mrb, str, beg, len, replace); } } /* * call-seq: - * str[fixnum] = replace - * str[fixnum, fixnum] = replace + * str[int] = replace + * str[int, int] = replace * str[range] = replace * str[other_str] = replace * @@ -1731,30 +1731,43 @@ mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) return str_substr(mrb, str, beg, len); } +/* + * 32 bit magic FNV-0 and FNV-1 prime + */ +#define FNV_32_PRIME ((uint32_t)0x01000193) +#define FNV1_32_INIT ((uint32_t)0x811c9dc5) + uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str) { - /* 1-8-7 */ struct RString *s = mrb_str_ptr(str); - mrb_int len = RSTR_LEN(s); - char *p = RSTR_PTR(s); - uint32_t hash = 0; + const unsigned char *bp = (unsigned char*)RSTR_PTR(s); /* start of buffer */ + const unsigned char *be = bp + RSTR_LEN(s); /* beyond end of buffer */ + uint32_t hval = FNV1_32_INIT; + + /* + * FNV-1 hash each octet in the buffer + */ + while (bp < be) { + /* multiply by the 32 bit FNV magic prime mod 2^32 */ +#if defined(NO_FNV_GCC_OPTIMIZATION) + hval *= FNV_32_PRIME; +#else + hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); +#endif - for(int i = 0; i < len; ++i) { - hash += p[i]; - hash += (hash << 10); - hash ^= (hash >> 6); + /* xor the bottom with the current octet */ + hval ^= (uint32_t)*bp++; } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; + + /* return our new hash value */ + return hval; } /* 15.2.10.5.20 */ /* * call-seq: - * str.hash => fixnum + * str.hash => int * * Return a hash based on the string's length and content. */ @@ -1762,14 +1775,14 @@ static mrb_value mrb_str_hash_m(mrb_state *mrb, mrb_value self) { mrb_int key = mrb_str_hash(mrb, self); - return mrb_fixnum_value(key); + return mrb_int_value(mrb, key); } /* 15.2.10.5.21 */ /* * call-seq: * str.include? other_str => true or false - * str.include? fixnum => true or false + * str.include? int => true or false * * Returns <code>true</code> if <i>str</i> contains the given string or * character. @@ -1792,7 +1805,7 @@ mrb_str_include(mrb_state *mrb, mrb_value self) /* 15.2.10.5.22 */ /* * call-seq: - * str.index(substring [, offset]) => fixnum or nil + * str.index(substring [, offset]) => int or nil * * Returns the index of the first occurrence of the given * <i>substring</i>. Returns <code>nil</code> if not found. @@ -1824,7 +1837,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) if (pos == -1) return mrb_nil_value(); BYTES_ALIGN_CHECK(pos); - return mrb_fixnum_value(pos); + return mrb_int_value(mrb, pos); } /* 15.2.10.5.24 */ @@ -1873,7 +1886,7 @@ mrb_str_init(mrb_state *mrb, mrb_value self) * str.to_sym => symbol * * Returns the <code>Symbol</code> corresponding to <i>str</i>, creating the - * symbol if it did not previously exist. See <code>Symbol#id2name</code>. + * symbol if it did not previously exist. * * "Koala".intern #=> :Koala * s = 'cat'.to_sym #=> :cat @@ -1901,7 +1914,7 @@ mrb_obj_as_string(mrb_state *mrb, mrb_value obj) case MRB_TT_SYMBOL: return mrb_sym_str(mrb, mrb_symbol(obj)); case MRB_TT_INTEGER: - return mrb_fixnum_to_str(mrb, obj, 10); + return mrb_integer_to_str(mrb, obj, 10); case MRB_TT_SCLASS: case MRB_TT_CLASS: case MRB_TT_MODULE: @@ -2018,7 +2031,7 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str) /* 15.2.10.5.31 */ /* * call-seq: - * str.rindex(substring [, offset]) => fixnum or nil + * str.rindex(substring [, offset]) => int or nil * * Returns the index of the last occurrence of the given <i>substring</i>. * Returns <code>nil</code> if not found. If the second parameter is @@ -2053,7 +2066,7 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) if (pos >= 0) { pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); BYTES_ALIGN_CHECK(pos); - return mrb_fixnum_value(pos); + return mrb_int_value(mrb, pos); } return mrb_nil_value(); } @@ -2199,8 +2212,8 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) return result; } -mrb_value -mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, mrb_int base, int badcheck) +static mrb_value +mrb_str_len_to_integer(mrb_state *mrb, const char *str, size_t len, mrb_int base, int badcheck) { const char *p = str; const char *pend = str + len; @@ -2363,12 +2376,6 @@ mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, mrb_int base, i return mrb_fixnum_value(0); } -MRB_API mrb_value -mrb_cstr_to_inum(mrb_state *mrb, const char *str, mrb_int base, mrb_bool badcheck) -{ - return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck); -} - /* obslete: use RSTRING_CSTR() or mrb_string_cstr() */ MRB_API const char* mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) @@ -2401,15 +2408,15 @@ mrb_string_cstr(mrb_state *mrb, mrb_value str) } MRB_API mrb_value -mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck) +mrb_str_to_integer(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck) { const char *s; mrb_int len; - mrb_to_str(mrb, str); + mrb_ensure_string_type(mrb, str); s = RSTRING_PTR(str); len = RSTRING_LEN(str); - return mrb_str_len_to_inum(mrb, s, len, base, badcheck); + return mrb_str_len_to_integer(mrb, s, len, base, badcheck); } /* 15.2.10.5.38 */ @@ -2439,14 +2446,14 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self) mrb_int base = 10; mrb_get_args(mrb, "|i", &base); - if (base < 0) { + if (base < 0 || 36 < base) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base); } - return mrb_str_to_inum(mrb, self, base, FALSE); + return mrb_str_to_integer(mrb, self, base, FALSE); } #ifndef MRB_NO_FLOAT -double +static double mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck) { char buf[DBL_DIG * 4 + 20]; @@ -2466,7 +2473,7 @@ mrb_str_len_to_dbl(mrb_state *mrb, const char *s, size_t len, mrb_bool badcheck) mrb_value x; if (!badcheck) return 0.0; - x = mrb_str_len_to_inum(mrb, p, pend-p, 0, badcheck); + x = mrb_str_len_to_integer(mrb, p, pend-p, 0, badcheck); if (mrb_integer_p(x)) d = (double)mrb_integer(x); else /* if (mrb_float_p(x)) */ @@ -2536,12 +2543,6 @@ bad: } MRB_API double -mrb_cstr_to_dbl(mrb_state *mrb, const char *s, mrb_bool badcheck) -{ - return mrb_str_len_to_dbl(mrb, s, strlen(s), badcheck); -} - -MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck) { return mrb_str_len_to_dbl(mrb, RSTRING_PTR(str), RSTRING_LEN(str), badcheck); @@ -2711,7 +2712,7 @@ mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2) MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) { - mrb_to_str(mrb, str2); + mrb_ensure_string_type(mrb, str2); return mrb_str_cat_str(mrb, str1, str2); } @@ -2734,7 +2735,7 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) /* * call-seq: - * str.bytes -> array of fixnums + * str.bytes -> array of int * * Returns an array of bytes in _str_. * @@ -2843,7 +2844,7 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str) } } else { - beg = mrb_integer(mrb_to_int(mrb, a1)); + beg = mrb_integer(mrb_to_integer(mrb, a1)); len = 1; empty = FALSE; } @@ -2860,6 +2861,51 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str) } } +static mrb_value +sub_replace(mrb_state *mrb, mrb_value self) +{ + char *p, *match; + mrb_int plen, mlen; + mrb_int found, offset; + mrb_value result; + + mrb_get_args(mrb, "ssi", &p, &plen, &match, &mlen, &found); + result = mrb_str_new(mrb, 0, 0); + for (mrb_int i=0; i<plen; i++) { + if (p[i] != '\\' || i+1==plen) { + mrb_str_cat(mrb, result, p+i, 1); + continue; + } + i++; + switch (p[i]) { + case '\\': + mrb_str_cat(mrb, result, "\\", 1); + break; + case '`': + mrb_str_cat(mrb, result, RSTRING_PTR(self), chars2bytes(self, 0, found)); + break; + case '&': case '0': + mrb_str_cat(mrb, result, match, mlen); + break; + case '\'': + offset = chars2bytes(self, 0, found) + mlen; + if (RSTRING_LEN(self) > offset) { + mrb_str_cat(mrb, result, RSTRING_PTR(self)+offset, RSTRING_LEN(self)-offset); + } + break; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + /* ignore sub-group match (no Regexp supported) */ + break; + default: + mrb_str_cat(mrb, result, &p[i-1], 2); + break; + } + } + return result; +} + /* ---------------------------*/ void mrb_init_string(mrb_state *mrb) @@ -2921,251 +2967,6 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1)); -} - -#ifndef MRB_NO_FLOAT -/* - * Source code for the "strtod" library procedure. - * - * Copyright (c) 1988-1993 The Regents of the University of California. - * Copyright (c) 1994 Sun Microsystems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies. The University of California - * makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * RCS: @(#) $Id: strtod.c 11708 2007-02-12 23:01:19Z shyouhei $ - */ -#include <ctype.h> -#include <errno.h> - -static const int maxExponent = 511; /* Largest possible base 10 exponent. Any - * exponent larger than this will already - * produce underflow or overflow, so there's - * no need to worry about additional digits. - */ -static const double powersOf10[] = {/* Table giving binary powers of 10. Entry */ - 10., /* is 10^2^i. Used to convert decimal */ - 100., /* exponents into floating-point numbers. */ - 1.0e4, - 1.0e8, - 1.0e16, - 1.0e32, - 1.0e64, - 1.0e128, - 1.0e256 -}; - -MRB_API double -mrb_float_read(const char *string, char **endPtr) -/* const char *string; A decimal ASCII floating-point number, - * optionally preceded by white space. - * Must have form "-I.FE-X", where I is the - * integer part of the mantissa, F is the - * fractional part of the mantissa, and X - * is the exponent. Either of the signs - * may be "+", "-", or omitted. Either I - * or F may be omitted, or both. The decimal - * point isn't necessary unless F is present. - * The "E" may actually be an "e". E and X - * may both be omitted (but not just one). - */ -/* char **endPtr; If non-NULL, store terminating character's - * address here. */ -{ - int sign, expSign = FALSE; - double fraction, dblExp; - const double *d; - const char *p; - int c; - int exp = 0; /* Exponent read from "EX" field. */ - int fracExp = 0; /* Exponent that derives from the fractional - * part. Under normal circumstances, it is - * the negative of the number of digits in F. - * However, if I is very long, the last digits - * of I get dropped (otherwise a long I with a - * large negative exponent could cause an - * unnecessary overflow on I alone). In this - * case, fracExp is incremented one for each - * dropped digit. */ - int mantSize; /* Number of digits in mantissa. */ - int decPt; /* Number of mantissa digits BEFORE decimal - * point. */ - const char *pExp; /* Temporarily holds location of exponent - * in string. */ - - /* - * Strip off leading blanks and check for a sign. - */ - - p = string; - while (ISSPACE(*p)) { - p += 1; - } - if (*p == '-') { - sign = TRUE; - p += 1; - } - else { - if (*p == '+') { - p += 1; - } - sign = FALSE; - } - - /* - * Count the number of digits in the mantissa (including the decimal - * point), and also locate the decimal point. - */ - - decPt = -1; - for (mantSize = 0; ; mantSize += 1) - { - c = *p; - if (!ISDIGIT(c)) { - if ((c != '.') || (decPt >= 0)) { - break; - } - decPt = mantSize; - } - p += 1; - } - - /* - * Now suck up the digits in the mantissa. Use two integers to - * collect 9 digits each (this is faster than using floating-point). - * If the mantissa has more than 18 digits, ignore the extras, since - * they can't affect the value anyway. - */ - - pExp = p; - p -= mantSize; - if (decPt < 0) { - decPt = mantSize; - } - else { - mantSize -= 1; /* One of the digits was the point. */ - } - if (mantSize > 18) { - if (decPt - 18 > 29999) { - fracExp = 29999; - } - else { - fracExp = decPt - 18; - } - mantSize = 18; - } - else { - fracExp = decPt - mantSize; - } - if (mantSize == 0) { - fraction = 0.0; - p = string; - goto done; - } - else { - int frac1, frac2; - frac1 = 0; - for ( ; mantSize > 9; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac1 = 10*frac1 + (c - '0'); - } - frac2 = 0; - for (; mantSize > 0; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac2 = 10*frac2 + (c - '0'); - } - fraction = (1.0e9 * frac1) + frac2; - } - - /* - * Skim off the exponent. - */ - - p = pExp; - if ((*p == 'E') || (*p == 'e')) { - p += 1; - if (*p == '-') { - expSign = TRUE; - p += 1; - } - else { - if (*p == '+') { - p += 1; - } - expSign = FALSE; - } - while (ISDIGIT(*p)) { - exp = exp * 10 + (*p - '0'); - if (exp > 19999) { - exp = 19999; - } - p += 1; - } - } - if (expSign) { - exp = fracExp - exp; - } - else { - exp = fracExp + exp; - } - - /* - * Generate a floating-point number that represents the exponent. - * Do this by processing the exponent one bit at a time to combine - * many powers of 2 of 10. Then combine the exponent with the - * fraction. - */ - - if (exp < 0) { - expSign = TRUE; - exp = -exp; - } - else { - expSign = FALSE; - } - if (exp > maxExponent) { - exp = maxExponent; - errno = ERANGE; - } - dblExp = 1.0; - for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { - if (exp & 01) { - dblExp *= *d; - } - } - if (expSign) { - fraction /= dblExp; - } - else { - fraction *= dblExp; - } - -done: - if (endPtr != NULL) { - *endPtr = (char *) p; - } - - if (sign) { - return -fraction; - } - return fraction; + mrb_define_method(mrb, s, "__sub_replace", sub_replace, MRB_ARGS_REQ(3)); /* internal */ } -#endif diff --git a/src/symbol.c b/src/symbol.c index 3cd925d99..cc8986eaa 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -4,7 +4,6 @@ ** See Copyright Notice in mruby.h */ -#include <limits.h> #include <string.h> #include <mruby.h> #include <mruby/khash.h> @@ -54,13 +53,6 @@ presym_sym2name(mrb_sym sym, mrb_int *lenp) #endif /* MRB_NO_PRESYM */ /* ------------------------------------------------------ */ -typedef struct symbol_name { - mrb_bool lit : 1; - uint8_t prev; - uint16_t len; - const char *name; -} symbol_name; - static void sym_validate_len(mrb_state *mrb, size_t len) { @@ -81,7 +73,11 @@ static const char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS static mrb_sym sym_inline_pack(const char *name, size_t len) { +#if defined(MRB_WORD_BOXING) && defined(MRB_32BIT) && !defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE) + const size_t pack_length_max = 4; +#else const size_t pack_length_max = 5; +#endif char c; const char *p; @@ -138,11 +134,38 @@ symhash(const char *key, size_t len) return hash & 0xff; } +size_t mrb_packed_int_len(uint32_t num); +size_t mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend); +uint32_t mrb_packed_int_decode(uint8_t *p, uint8_t **newpos); + +#define sym_lit_p(mrb, i) (mrb->symflags[i>>3]&(1<<(i&7))) +#define sym_lit_set(mrb, i) mrb->symflags[i>>3]|=(1<<(i&7)) +#define sym_flags_clear(mrb, i) mrb->symflags[i>>3]&=~(1<<(i&7)) +#define sym_len(mrb, i) (size_t)(sym_lit_p(mrb, i)?strlen(mrb->symtbl[i]):mrb_packed_int_decode(mrb->symtbl[i],NULL)) + +static mrb_bool +sym_check(mrb_state *mrb, const char *name, size_t len, mrb_sym i) +{ + const char *symname = mrb->symtbl[i]; + size_t symlen; + + if (sym_lit_p(mrb, i)) { + symlen = strlen(symname); + } + else { + /* length in BER */ + symlen = mrb_packed_int_decode((uint8_t*)symname, (uint8_t**)&symname); + } + if (len == symlen && memcmp(symname, name, len) == 0) { + return TRUE; + } + return FALSE; +} + static mrb_sym find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) { mrb_sym i; - symbol_name *sname; uint8_t hash; #ifndef MRB_NO_PRESYM @@ -160,24 +183,24 @@ find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) i = mrb->symhash[hash]; if (i == 0) return 0; - do { - sname = &mrb->symtbl[i]; - if (sname->len == len && memcmp(sname->name, name, len) == 0) { + for (;;) { + if (sym_check(mrb, name, len, i)) { return (i+MRB_PRESYM_MAX); } - if (sname->prev == 0xff) { + uint8_t diff = mrb->symlink[i]; + if (diff == 0xff) { i -= 0xff; - sname = &mrb->symtbl[i]; - while (mrb->symtbl < sname) { - if (sname->len == len && memcmp(sname->name, name, len) == 0) { - return (mrb_sym)((sname - mrb->symtbl)+MRB_PRESYM_MAX); + while (i > 0) { + if (sym_check(mrb, name, len, i)) { + return (i+MRB_PRESYM_MAX); } - sname--; + i--; } return 0; } - i -= sname->prev; - } while (sname->prev > 0); + if (diff == 0) return 0; + i -= diff; + } return 0; } @@ -185,7 +208,6 @@ static mrb_sym sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) { mrb_sym sym; - symbol_name *sname; uint8_t hash; sym_validate_len(mrb, len); @@ -194,35 +216,38 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) /* registering a new symbol */ sym = mrb->symidx + 1; - if (mrb->symcapa < sym) { + if (mrb->symcapa <= sym) { size_t symcapa = mrb->symcapa; if (symcapa == 0) symcapa = 100; else symcapa = (size_t)(symcapa * 6 / 5); - mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(symcapa+1)); + mrb->symtbl = (const char**)mrb_realloc(mrb, mrb->symtbl, sizeof(char*)*symcapa); + mrb->symflags = (uint8_t*)mrb_realloc(mrb, mrb->symflags, symcapa/8+1); + memset(mrb->symflags+mrb->symcapa/8+1, 0, (symcapa-mrb->symcapa)/8); + mrb->symlink = (uint8_t*)mrb_realloc(mrb, mrb->symlink, symcapa); mrb->symcapa = symcapa; } - sname = &mrb->symtbl[sym]; - sname->len = (uint16_t)len; - if (lit || mrb_ro_data_p(name)) { - sname->name = name; - sname->lit = TRUE; + sym_flags_clear(mrb, sym); + if ((lit || mrb_ro_data_p(name)) && strlen(name) == len) { + sym_lit_set(mrb, sym); + mrb->symtbl[sym] = name; } else { - char *p = (char *)mrb_malloc(mrb, len+1); - memcpy(p, name, len); - p[len] = 0; - sname->name = (const char*)p; - sname->lit = FALSE; + int ilen = mrb_packed_int_len(len); + char *p = (char *)mrb_malloc(mrb, len+ilen+1); + mrb_packed_int_encode(len, (uint8_t*)p, (uint8_t*)p+ilen); + memcpy(p+ilen, name, len); + p[ilen+len] = 0; + mrb->symtbl[sym] = p; } if (mrb->symhash[hash]) { mrb_sym i = sym - mrb->symhash[hash]; if (i > 0xff) - sname->prev = 0xff; + mrb->symlink[sym] = 0xff; else - sname->prev = i; + mrb->symlink[sym] = i; } else { - sname->prev = 0; + mrb->symlink[sym] = 0; } mrb->symhash[hash] = mrb->symidx = sym; @@ -320,8 +345,15 @@ sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp) return NULL; } - if (lenp) *lenp = mrb->symtbl[sym].len; - return mrb->symtbl[sym].name; + const char *symname = mrb->symtbl[sym]; + if (!sym_lit_p(mrb, sym)) { + size_t len = mrb_packed_int_decode((uint8_t*)symname, (uint8_t**)&symname); + if (lenp) *lenp = (mrb_int)len; + } + else if (lenp) { + *lenp = (mrb_int)strlen(symname); + } + return symname; } MRB_API const char* @@ -334,25 +366,19 @@ mrb_sym_name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) #endif } -mrb_bool -mrb_sym_static_p(mrb_state *mrb, mrb_sym sym) -{ - if (SYMBOL_INLINE_P(sym)) return TRUE; - if (sym > MRB_PRESYM_MAX) return FALSE; - return TRUE; -} - void mrb_free_symtbl(mrb_state *mrb) { mrb_sym i, lim; for (i=1, lim=mrb->symidx+1; i<lim; i++) { - if (!mrb->symtbl[i].lit) { - mrb_free(mrb, (char*)mrb->symtbl[i].name); + if (!sym_lit_p(mrb, i)) { + mrb_free(mrb, (char*)mrb->symtbl[i]); } } mrb_free(mrb, mrb->symtbl); + mrb_free(mrb, mrb->symlink); + mrb_free(mrb, mrb->symflags); } void @@ -397,12 +423,11 @@ mrb_init_symtbl(mrb_state *mrb) /* 15.2.11.3.3 */ /* * call-seq: - * sym.id2name -> string * sym.to_s -> string * * Returns the name or string corresponding to <i>sym</i>. * - * :fred.id2name #=> "fred" + * :fred.to_s #=> "fred" */ static mrb_value sym_to_s(mrb_state *mrb, mrb_value sym) @@ -410,6 +435,30 @@ sym_to_s(mrb_state *mrb, mrb_value sym) return mrb_sym_str(mrb, mrb_symbol(sym)); } +/* + * call-seq: + * sym.name -> string + * + * Returns the name or string corresponding to <i>sym</i>. Unlike #to_s, the + * returned string is frozen. + * + * :fred.name #=> "fred" + * :fred.name.frozen? #=> true + */ +static mrb_value +sym_name(mrb_state *mrb, mrb_value vsym) +{ + mrb_sym sym = mrb_symbol(vsym); + mrb_int len; + const char *name = mrb_sym_name_len(mrb, sym, &len); + + mrb_assert(name != NULL); + if (SYMBOL_INLINE_P(sym)) { + return mrb_str_new_frozen(mrb, name, len); + } + return mrb_str_new_static_frozen(mrb, name, len); +} + /* 15.2.11.3.4 */ /* * call-seq: @@ -596,7 +645,7 @@ mrb_sym_str(mrb_state *mrb, mrb_sym sym) } static const char* -sym_name(mrb_state *mrb, mrb_sym sym, mrb_bool dump) +sym_cstr(mrb_state *mrb, mrb_sym sym, mrb_bool dump) { mrb_int len; const char *name = mrb_sym_name_len(mrb, sym, &len); @@ -615,13 +664,13 @@ sym_name(mrb_state *mrb, mrb_sym sym, mrb_bool dump) MRB_API const char* mrb_sym_name(mrb_state *mrb, mrb_sym sym) { - return sym_name(mrb, sym, FALSE); + return sym_cstr(mrb, sym, FALSE); } MRB_API const char* mrb_sym_dump(mrb_state *mrb, mrb_sym sym) { - return sym_name(mrb, sym, TRUE); + return sym_cstr(mrb, sym, TRUE); } #define lesser(a,b) (((a)>(b))?(b):(a)) @@ -665,8 +714,8 @@ mrb_init_symbol(mrb_state *mrb) MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL); mrb_undef_class_method(mrb, sym, "new"); - mrb_define_method(mrb, sym, "id2name", sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.2 */ mrb_define_method(mrb, sym, "to_s", sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.3 */ + mrb_define_method(mrb, sym, "name", sym_name, MRB_ARGS_NONE()); mrb_define_method(mrb, sym, "to_sym", sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */ mrb_define_method(mrb, sym, "inspect", sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */ mrb_define_method(mrb, sym, "<=>", sym_cmp, MRB_ARGS_REQ(1)); diff --git a/src/variable.c b/src/variable.c index 646353bfd..d89295229 100644 --- a/src/variable.c +++ b/src/variable.c @@ -766,16 +766,17 @@ mod_const_check(mrb_state *mrb, mrb_value mod) } static mrb_value -const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) +const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym, mrb_bool skip) { struct RClass *c = base; mrb_value v; mrb_bool retry = FALSE; mrb_value name; + if (skip) c = c->super; L_RETRY: while (c) { - if (c->iv) { + if (!MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_PREPENDED) && c->iv) { if (iv_get(mrb, c->iv, sym, &v)) return v; } @@ -794,7 +795,7 @@ MRB_API mrb_value mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) { mod_const_check(mrb, mod); - return const_get(mrb, mrb_class_ptr(mod), sym); + return const_get(mrb, mrb_class_ptr(mod), sym, FALSE); } mrb_value @@ -803,9 +804,9 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) struct RClass *c; struct RClass *c2; mrb_value v; - const struct RProc *proc; + const struct RProc *proc = mrb->c->ci->proc; - c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); + c = MRB_PROC_TARGET_CLASS(proc); if (!c) c = mrb->object_class; if (iv_get(mrb, c->iv, sym, &v)) { return v; @@ -821,8 +822,7 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) c2 = mrb_class_ptr(klass); } if (c2 && (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE)) c = c2; - mrb_assert(!MRB_PROC_CFUNC_P(mrb->c->ci->proc)); - proc = mrb->c->ci->proc; + proc = proc->upper; while (proc) { c2 = MRB_PROC_TARGET_CLASS(proc); if (c2 && iv_get(mrb, c2->iv, sym, &v)) { @@ -830,7 +830,7 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) } proc = proc->upper; } - return const_get(mrb, c, sym); + return const_get(mrb, c, sym, TRUE); } MRB_API void @@ -4,11 +4,6 @@ ** See Copyright Notice in mruby.h */ -#include <stddef.h> -#include <stdarg.h> -#ifndef MRB_NO_FLOAT -#include <math.h> -#endif #include <mruby.h> #include <mruby/array.h> #include <mruby/class.h> @@ -44,9 +39,9 @@ void abort(void); #define MRB_STACK_GROWTH 128 #endif -/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */ -#ifndef MRB_FUNCALL_DEPTH_MAX -#define MRB_FUNCALL_DEPTH_MAX 512 +/* Maximum recursive depth. Should be set lower on memory constrained systems. */ +#ifndef MRB_CALL_LEVEL_MAX +#define MRB_CALL_LEVEL_MAX 512 #endif /* Maximum stack depth. Should be set lower on memory constrained systems. @@ -69,6 +64,7 @@ mrb_gc_arena_shrink(mrb_state *mrb, int idx) mrb_gc *gc = &mrb->gc; int capa = gc->arena_capa; + mrb->gc.arena_idx = idx; if (idx < capa / 4) { capa >>= 2; if (capa < MRB_GC_ARENA_SIZE) { @@ -81,24 +77,21 @@ mrb_gc_arena_shrink(mrb_state *mrb, int idx) } } #else -#define mrb_gc_arena_shrink(mrb,idx) +#define mrb_gc_arena_shrink(mrb,idx) mrb_gc_arena_restore(mrb,idx) #endif -#define CALL_MAXARGS 127 +#define CALL_MAXARGS 15 +#define CALL_VARARGS (CALL_MAXARGS<<4 | CALL_MAXARGS) void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); static inline void stack_clear(mrb_value *from, size_t count) { -#ifdef MRB_NAN_BOXING while (count-- > 0) { SET_NIL_VALUE(*from); from++; } -#else - memset(from, 0, sizeof(mrb_value)*count); -#endif } static inline void @@ -245,13 +238,14 @@ top_proc(mrb_state *mrb, const struct RProc *proc) return proc; } -#define CI_ACC_SKIP -1 -#define CI_ACC_DIRECT -2 -#define CI_ACC_RESUMED -3 +#define CINFO_NONE 0 +#define CINFO_SKIP 1 +#define CINFO_DIRECT 2 +#define CINFO_RESUMED 3 static inline mrb_callinfo* -cipush(mrb_state *mrb, mrb_int push_stacks, mrb_int acc, - struct RClass *target_class, const struct RProc *proc, mrb_sym mid, mrb_int argc) +cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, + struct RClass *target_class, const struct RProc *proc, mrb_sym mid, uint8_t argc) { struct mrb_context *c = mrb->c; mrb_callinfo *ci = c->ci; @@ -259,6 +253,9 @@ cipush(mrb_state *mrb, mrb_int push_stacks, mrb_int acc, if (ci + 1 == c->ciend) { ptrdiff_t size = ci - c->cibase; + if (size > MRB_CALL_LEVEL_MAX) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2); c->ci = c->cibase + size; c->ciend = c->cibase + size * 2; @@ -267,8 +264,9 @@ cipush(mrb_state *mrb, mrb_int push_stacks, mrb_int acc, ci->mid = mid; mrb_vm_ci_proc_set(ci, proc); ci->stack = ci[-1].stack + push_stacks; - ci->argc = (int16_t)argc; - ci->acc = (int16_t)acc; + ci->n = argc & 0xf; + ci->nk = (argc>>4) & 0xf; + ci->cci = cci; ci->u.target_class = target_class; return ci; @@ -314,7 +312,7 @@ mrb_protect_error(mrb_state *mrb, mrb_protect_error_func *body, void *userdata, mrb_value result = mrb_nil_value(); int ai = mrb_gc_arena_save(mrb); const struct mrb_context *c = mrb->c; - int ci_index = c->ci - c->cibase; + ptrdiff_t ci_index = c->ci - c->cibase; if (error) { *error = FALSE; } @@ -335,9 +333,9 @@ mrb_protect_error(mrb_state *mrb, mrb_protect_error_func *body, void *userdata, } else { // It was probably switched by mrb_fiber_resume(). - // Simply destroy all successive CI_ACC_DIRECTs once the fiber has been switched. + // Simply destroy all successive CINFO_DIRECTs once the fiber has been switched. c = mrb->c; - while (c->ci > c->cibase && c->ci->acc == CI_ACC_DIRECT) { + while (c->ci > c->cibase && c->ci->cci == CINFO_DIRECT) { cipop(mrb); } } @@ -396,27 +394,41 @@ mrb_funcall_id(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, ...) } static mrb_int -ci_nregs(mrb_callinfo *ci) +mrb_ci_kidx(mrb_callinfo *ci) +{ + if (ci->nk == 0) return -1; + return (ci->n % 14) + 1; +} + +static mrb_int +mrb_bidx(uint16_t c) +{ + uint8_t n = c & 0xf; + uint8_t k = (c>>4) & 0xf; + if (n == 15) n = 1; + if (k == 15) n += 1; + else n += k*2; + return n + 1; /* self + args + kargs */ +} + +mrb_int +mrb_ci_bidx(mrb_callinfo *ci) +{ + return mrb_bidx(ci->n|(ci->nk<<4)); +} + +mrb_int +mrb_ci_nregs(mrb_callinfo *ci) { const struct RProc *p; - mrb_int n = 0; - if (!ci) return 3; + if (!ci) return 4; + uint8_t nregs = mrb_ci_bidx(ci) + 1; /* self + args + kargs + blk */ p = ci->proc; - if (!p) { - if (ci->argc < 0) return 3; - return ci->argc+2; - } - if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { - n = p->body.irep->nregs; - } - if (ci->argc < 0) { - if (n < 3) n = 3; /* self + args + blk */ - } - if (ci->argc > n) { - n = ci->argc + 2; /* self + blk */ + if (p && !MRB_PROC_CFUNC_P(p) && p->body.irep && p->body.irep->nregs > nregs) { + return p->body.irep->nregs; } - return n; + return nregs; } MRB_API mrb_value @@ -448,46 +460,45 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc else { mrb_method_t m; struct RClass *c; - mrb_callinfo *ci; - mrb_int n = ci_nregs(mrb->c->ci); + mrb_callinfo *ci = mrb->c->ci; + mrb_int n = mrb_ci_nregs(ci); ptrdiff_t voff = -1; if (!mrb->c->stbase) { stack_init(mrb); } + if (ci - mrb->c->cibase > MRB_CALL_LEVEL_MAX) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + } + if (mrb->c->stbase <= argv && argv < mrb->c->stend) { + voff = argv - mrb->c->stbase; + } if (argc < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc); } c = mrb_class(mrb, self); m = mrb_method_search_vm(mrb, &c, mid); + mrb_stack_extend(mrb, n + argc + 3); + if (MRB_METHOD_UNDEF_P(m) || argc >= 15) { + mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); + + ci->stack[n+1] = args; + argc = 15; + } if (MRB_METHOD_UNDEF_P(m)) { mrb_sym missing = MRB_SYM(method_missing); - mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); + mrb_value args = ci->stack[n+1]; + m = mrb_method_search_vm(mrb, &c, missing); if (MRB_METHOD_UNDEF_P(m)) { mrb_method_missing(mrb, mid, self, args); } mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); mrb_stack_extend(mrb, n+2); - mrb->c->ci->stack[n+1] = args; - argc = -1; - } - if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); + ci->stack[n+1] = args; + argc = 15; } ci = cipush(mrb, n, 0, c, NULL, mid, argc); - if (argc < 0) argc = 1; - if (mrb->c->stbase <= argv && argv < mrb->c->stend) { - voff = argv - mrb->c->stbase; - } - if (argc >= CALL_MAXARGS) { - mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - - mrb->c->ci->stack[1] = args; - ci->argc = -1; - argc = 1; - } - mrb_stack_extend(mrb, argc + 2); if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); @@ -499,19 +510,23 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (voff >= 0) { argv = mrb->c->stbase + voff; } - mrb->c->ci->stack[0] = self; - if (ci->argc > 0) { - stack_copy(mrb->c->ci->stack+1, argv, argc); + ci->stack[0] = self; + if (argc < 15) { + if (argc > 0) + stack_copy(ci->stack+1, argv, argc); + ci->stack[argc+1] = blk; + } + else { + ci->stack[2] = blk; } - mrb->c->ci->stack[argc+1] = blk; if (MRB_METHOD_CFUNC_P(m)) { - ci->acc = CI_ACC_DIRECT; + ci->cci = CINFO_DIRECT; val = MRB_METHOD_CFUNC(m)(mrb, self); cipop(mrb); } else { - ci->acc = CI_ACC_SKIP; + ci->cci = CINFO_SKIP; val = mrb_run(mrb, MRB_METHOD_PROC(m), self); } } @@ -526,68 +541,8 @@ mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, cons return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value()); } -#define DECOMPOSE32(n) (((n) >> 24) & 0xff), (((n) >> 16) & 0xff), (((n) >> 8) & 0xff), (((n) >> 0) & 0xff) -#define CATCH_HANDLER_MAKE_BYTECODE(t, b, e, j) t, DECOMPOSE32(b), DECOMPOSE32(e), DECOMPOSE32(j) -#define CATCH_HANDLER_NUM_TO_BYTE(n) ((n) * sizeof(struct mrb_irep_catch_handler)) - -static void -exec_irep_prepare_posthook(mrb_state *mrb, mrb_callinfo *ci, int nregs, mrb_func_t posthook) -{ - /* - * stack: [proc, errinfo, return value by called proc] - * - * begin - * OP_NOP # A dummy instruction built in to make the catch handler react. - * ensure - * OP_EXCEPT R1 # Save the exception object. - * OP_CALL # Call a C function for the hook. - * # The stack is kept as it is in the called proc. - * # The exception will be rethrown within the hook function. - * end - */ - static const mrb_code hook_iseq[] = { - OP_NOP, - OP_EXCEPT, 1, - OP_CALL, - CATCH_HANDLER_MAKE_BYTECODE(MRB_CATCH_ENSURE, 0, 1, 1), - }; - static const mrb_irep hook_irep = { - 1, 3, 1, MRB_IREP_STATIC, hook_iseq, - NULL, NULL, NULL, NULL, NULL, - sizeof(hook_iseq) / sizeof(hook_iseq[0]) - CATCH_HANDLER_NUM_TO_BYTE(1), - 0, 0, 0, 0 - }; - static const struct RProc hook_caller = { - NULL, NULL, MRB_TT_PROC, MRB_GC_RED, MRB_FL_OBJ_IS_FROZEN, { &hook_irep }, NULL, { NULL } - }; - - struct RProc *hook = mrb_proc_new_cfunc(mrb, posthook); - int acc = 2; - memmove(ci->stack + acc, ci->stack, sizeof(mrb_value) * nregs); - ci->stack[0] = mrb_obj_value(hook); - ci->stack[1] = mrb_nil_value(); - mrb_callinfo hook_ci = { 0, 0, ci->acc, &hook_caller, ci->stack, &hook_iseq[1], { NULL } }; - ci = cipush(mrb, acc, acc, NULL, ci[0].proc, ci[0].mid, ci[0].argc); - ci->u.env = ci[-1].u.env; - ci[-1] = hook_ci; -} - -/* - * If `posthook` is given, `posthook` will be called even if an - * exception or global jump occurs in `p`. Exception or global jump objects - * are stored in `mrb->c->stack[1]` and should be rethrown in `posthook`. - * - * if (!mrb_nil_p(mrb->c->stack[1])) { - * mrb_exc_raise(mrb, mrb->c->stack[1]); - * } - * - * If you want to return the return value by `proc` as it is, please do - * `return mrb->c->stack[2]`. - * - * However, if `proc` is a C function, it will be ignored. - */ static mrb_value -exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook) +exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) { mrb_callinfo *ci = mrb->c->ci; int keep, nregs; @@ -598,19 +553,13 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook) return MRB_PROC_CFUNC(p)(mrb, self); } nregs = p->body.irep->nregs; - if (ci->argc < 0) keep = 3; - else keep = ci->argc + 2; - int extra = posthook ? (2 /* hook proc + errinfo */) : 0; + keep = mrb_ci_bidx(ci)+1; if (nregs < keep) { - mrb_stack_extend(mrb, keep + extra); + mrb_stack_extend(mrb, keep); } else { - mrb_stack_extend(mrb, nregs + extra); - stack_clear(ci->stack+keep, nregs-keep + extra); - } - - if (posthook) { - exec_irep_prepare_posthook(mrb, ci, (nregs < keep ? keep : nregs), posthook); + mrb_stack_extend(mrb, nregs); + stack_clear(ci->stack+keep, nregs-keep); } cipush(mrb, 0, 0, NULL, NULL, 0, 0); @@ -619,21 +568,21 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook) } mrb_value -mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook) +mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) { mrb_callinfo *ci = mrb->c->ci; - if (ci->acc >= 0) { - return exec_irep(mrb, self, p, posthook); + if (ci->cci == CINFO_NONE) { + return exec_irep(mrb, self, p); } else { mrb_value ret; if (MRB_PROC_CFUNC_P(p)) { - cipush(mrb, 0, CI_ACC_DIRECT, mrb_vm_ci_target_class(ci), p, ci->mid, ci->argc); + cipush(mrb, 0, CINFO_DIRECT, mrb_vm_ci_target_class(ci), p, ci->mid, ci->n|(ci->nk<<4)); ret = MRB_PROC_CFUNC(p)(mrb, self); cipop(mrb); } else { - int keep = (ci->argc < 0 ? 1 : ci->argc) + 2 /* receiver + block */; + int keep = mrb_ci_bidx(ci) + 1; /* receiver + block */ ret = mrb_top_run(mrb, p, self, keep); } if (mrb->exc && mrb->jmp) { @@ -667,19 +616,31 @@ mrb_f_send(mrb_state *mrb, mrb_value self) { mrb_sym name; mrb_value block, *regs; - const mrb_value *argv; - mrb_int argc, i, len; mrb_method_t m; struct RClass *c; - mrb_callinfo *ci; + mrb_callinfo *ci = mrb->c->ci; + int n = ci->n; - mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block); - ci = mrb->c->ci; - if (ci->acc < 0) { - funcall: + if (ci->cci > CINFO_NONE) { + funcall:; + const mrb_value *argv; + mrb_int argc; + mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block); return mrb_funcall_with_block(mrb, self, name, argc, argv, block); } + regs = mrb->c->ci->stack+1; + + if (n == 0) { + mrb_argnum_error(mrb, 0, 1, -1); + } + else if (n == 15) { + name = mrb_obj_to_sym(mrb, RARRAY_PTR(regs[0])[0]); + } + else { + name = mrb_obj_to_sym(mrb, regs[0]); + } + c = mrb_class(mrb, self); m = mrb_method_search_vm(mrb, &c, name); if (MRB_METHOD_UNDEF_P(m)) { /* call method_mising */ @@ -688,16 +649,19 @@ mrb_f_send(mrb_state *mrb, mrb_value self) ci->mid = name; ci->u.target_class = c; - regs = mrb->c->ci->stack+1; /* remove first symbol from arguments */ - if (ci->argc >= 0) { - for (i=0,len=ci->argc; i<len; i++) { + if (n == 15) { /* variable length arguments */ + regs[0] = mrb_ary_subseq(mrb, regs[0], 1, RARRAY_LEN(regs[0]) - 1); + } + else { /* n > 0 */ + for (int i=0; i<n; i++) { regs[i] = regs[i+1]; } - ci->argc--; - } - else { /* variable length arguments */ - regs[0] = mrb_ary_subseq(mrb, regs[0], 1, RARRAY_LEN(regs[0]) - 1); + regs[n] = regs[n+1]; /* copy kdict or block */ + if (ci->nk > 0) { + regs[n+1] = regs[n+2]; /* copy block */ + } + ci->n--; } if (MRB_METHOD_CFUNC_P(m)) { @@ -706,7 +670,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) } return MRB_METHOD_CFUNC(m)(mrb, self); } - return exec_irep(mrb, self, MRB_METHOD_PROC(m), NULL); + return exec_irep(mrb, self, MRB_METHOD_PROC(m)); } static mrb_value @@ -720,23 +684,24 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); } ci = mrb->c->ci; - if (ci->acc == CI_ACC_DIRECT) { + if (ci->cci == CINFO_DIRECT) { return mrb_yield_with_class(mrb, blk, 1, &self, self, c); } ci->u.target_class = c; p = mrb_proc_ptr(blk); mrb_vm_ci_proc_set(ci, p); - ci->argc = 1; + ci->n = 1; + ci->nk = 0; ci->mid = ci[-1].mid; if (MRB_PROC_CFUNC_P(p)) { - mrb_stack_extend(mrb, 3); + mrb_stack_extend(mrb, 4); mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; mrb->c->ci->stack[2] = mrb_nil_value(); return MRB_PROC_CFUNC(p)(mrb, self); } nregs = p->body.irep->nregs; - if (nregs < 3) nregs = 3; + if (nregs < 4) nregs = 4; mrb_stack_extend(mrb, nregs); mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; @@ -792,21 +757,11 @@ mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) { mrb_value a, b; - struct RClass *c; if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented"); } - switch (mrb_type(self)) { - case MRB_TT_MODULE: - case MRB_TT_CLASS: - case MRB_TT_ICLASS: - c = mrb_class_ptr(self); - break; - default: - c = mrb_singleton_class_ptr(mrb, self); - } - return eval_under(mrb, self, b, c); + return eval_under(mrb, self, b, mrb_singleton_class_ptr(mrb, self)); } MRB_API mrb_value @@ -822,33 +777,31 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); } ci = mrb->c->ci; - n = ci_nregs(ci); - if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } + n = mrb_ci_nregs(ci); p = mrb_proc_ptr(b); - ci = cipush(mrb, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */); + ci = cipush(mrb, n, CINFO_SKIP, c, p, mid, 0 /* dummy */); + ci->nk = 0; if (argc >= CALL_MAXARGS) { - ci->argc = -1; + ci->n = 15; n = 3; } else { - ci->argc = (int)argc; + ci->n = argc; n = argc + 2; } mrb_stack_extend(mrb, n); mrb->c->ci->stack[0] = self; - if (ci->argc < 0) { + if (ci->n == 15) { mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); argc = 1; } else if (argc > 0) { stack_copy(mrb->c->ci->stack+1, argv, argc); } - mrb->c->ci->stack[argc+1] = mrb_nil_value(); + mrb->c->ci->stack[argc+1] = mrb_nil_value(); /* clear blk */ if (MRB_PROC_CFUNC_P(p)) { - ci->acc = CI_ACC_DIRECT; + ci->cci = CINFO_DIRECT; val = MRB_PROC_CFUNC(p)(mrb, self); cipop(mrb); } @@ -890,11 +843,13 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const p = mrb_proc_ptr(b); ci = mrb->c->ci; - mrb_stack_extend(mrb, 3); + mrb_stack_extend(mrb, 4); mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); mrb->c->ci->stack[2] = mrb_nil_value(); - ci->argc = -1; - return exec_irep(mrb, self, p, NULL); + mrb->c->ci->stack[3] = mrb_nil_value(); + ci->n = 15; + ci->nk = 0; + return exec_irep(mrb, self, p); } static struct RBreak* @@ -902,7 +857,7 @@ break_new(mrb_state *mrb, uint32_t tag, const struct RProc *p, mrb_value val) { struct RBreak *brk; - brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL); + brk = MRB_OBJ_ALLOC(mrb, MRB_TT_BREAK, NULL); mrb_break_proc_set(brk, p); mrb_break_value_set(brk, val); mrb_break_tag_set(brk, tag); @@ -975,9 +930,9 @@ argnum_error(mrb_state *mrb, mrb_int num) { mrb_value exc; mrb_value str; - mrb_int argc = mrb->c->ci->argc; + mrb_int argc = mrb->c->ci->n; - if (argc < 0) { + if (argc == 15) { mrb_value args = mrb->c->ci->stack[1]; if (mrb_array_p(args)) { argc = RARRAY_LEN(args); @@ -1079,7 +1034,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #ifndef DIRECT_THREADED #define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) { -#define CASE(insn,ops) case insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; +#define CASE(insn,ops) case insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; L_ ## insn ## _BODY: #define NEXT goto L_END_DISPATCH #define JUMP NEXT #define END_DISPATCH L_END_DISPATCH:;}} @@ -1087,7 +1042,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #else #define INIT_DISPATCH JUMP; return mrb_nil_value(); -#define CASE(insn,ops) L_ ## insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; +#define CASE(insn,ops) L_ ## insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; L_ ## insn ## _BODY: #define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn] #define JUMP NEXT @@ -1125,19 +1080,76 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta return result; } -static mrb_bool +static struct RClass* check_target_class(mrb_state *mrb) { - if (!mrb_vm_ci_target_class(mrb->c->ci)) { + struct RClass *target = mrb_vm_ci_target_class(mrb->c->ci); + if (!target) { mrb_value exc = mrb_exc_new_lit(mrb, E_TYPE_ERROR, "no target class or module"); mrb_exc_set(mrb, exc); - return FALSE; } - return TRUE; + return target; +} + +static mrb_value +hash_new_from_values(mrb_state *mrb, mrb_int argc, mrb_value *regs) +{ + mrb_value hash = mrb_hash_new_capa(mrb, argc); + while (argc--) { + mrb_hash_set(mrb, hash, regs[0], regs[1]); + regs += 2; + } + return hash; } mrb_value mrb_obj_missing(mrb_state *mrb, mrb_value mod); -void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); + +static mrb_method_t +prepare_missing(mrb_state *mrb, mrb_value recv, mrb_sym mid, struct RClass **clsp, uint32_t a, uint16_t *c, mrb_value blk, int super) +{ + mrb_sym missing = MRB_SYM(method_missing); + mrb_callinfo *ci = mrb->c->ci; + uint16_t b = *c; + mrb_int n = b & 0xf; + mrb_int nk = (b>>4) & 0xf; + mrb_value *argv = &ci->stack[a+1]; + mrb_value args; + mrb_method_t m; + + /* pack positional arguments */ + if (n == 15) args = argv[0]; + else args = mrb_ary_new_from_values(mrb, n, argv); + + if (mrb_func_basic_p(mrb, recv, missing, mrb_obj_missing)) { + method_missing: + if (super) mrb_no_method_error(mrb, mid, args, "no superclass method '%n'", mid); + else mrb_method_missing(mrb, mid, recv, args); + /* not reached */ + } + if (mid != missing) { + *clsp = mrb_class(mrb, recv); + } + m = mrb_method_search_vm(mrb, clsp, missing); + if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */ + mrb_stack_extend(mrb, a+4); + + argv = &ci->stack[a+1]; /* maybe reallocated */ + argv[0] = args; + if (nk == 0) { + argv[1] = blk; + } + else { + mrb_assert(nk == 15); + argv[1] = argv[n]; + argv[2] = blk; + } + *c = 15 | (nk<<4); + mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); + return m; +} + +void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); +mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len); MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) @@ -1191,11 +1203,7 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_LOADL16, BS) { - goto op_loadl; - } CASE(OP_LOADL, BB) { - op_loadl: switch (pool[b].tt) { /* number */ case IREP_TT_INT32: regs[a] = mrb_int_value(mrb, (mrb_int)pool[b].u.i32); @@ -1267,11 +1275,6 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_LOADSYM16, BS) { - SET_SYM_VALUE(regs[a], syms[b]); - NEXT; - } - CASE(OP_LOADNIL, B) { SET_NIL_VALUE(regs[a]); NEXT; @@ -1336,6 +1339,42 @@ RETRY_TRY_BLOCK: NEXT; } + CASE(OP_GETIDX, B) { + mrb_value va = regs[a], vb = regs[a+1]; + switch (mrb_type(va)) { + case MRB_TT_ARRAY: + if (!mrb_integer_p(vb)) goto getidx_fallback; + regs[a] = mrb_ary_entry(va, mrb_integer(vb)); + break; + case MRB_TT_HASH: + regs[a] = mrb_hash_get(mrb, va, vb); + break; + case MRB_TT_STRING: + switch (mrb_type(vb)) { + case MRB_TT_INTEGER: + case MRB_TT_STRING: + case MRB_TT_RANGE: + regs[a] = mrb_str_aref(mrb, va, vb, mrb_undef_value()); + break; + default: + goto getidx_fallback; + } + break; + default: + getidx_fallback: + c = 1; + mid = MRB_OPSYM(aref); + goto L_SEND_SYM; + } + NEXT; + } + + CASE(OP_SETIDX, B) { + c = 2; + mid = MRB_OPSYM(aset); + goto L_SEND_SYM; + } + CASE(OP_GETCONST, BB) { mrb_value val; mrb_sym sym = syms[b]; @@ -1500,77 +1539,75 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_SENDV, BB) { - c = CALL_MAXARGS; - goto L_SEND; - }; + CASE(OP_SSEND, BBB) { + regs[a] = regs[0]; + insn = OP_SEND; + } + goto L_SENDB; - CASE(OP_SENDVB, BB) { - c = CALL_MAXARGS; - goto L_SENDB; - }; + CASE(OP_SSENDB, BBB) { + regs[a] = regs[0]; + } + goto L_SENDB; CASE(OP_SEND, BBB) - L_SEND: - { - /* push nil after arguments */ - int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1; - SET_NIL_VALUE(regs[bidx]); - goto L_SENDB; - }; + goto L_SENDB; + L_SEND_SYM: - { - /* push nil after arguments */ - int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1; - SET_NIL_VALUE(regs[bidx]); - goto L_SENDB_SYM; - }; + c = 1; + /* push nil after arguments */ + SET_NIL_VALUE(regs[a+2]); + goto L_SENDB_SYM; CASE(OP_SENDB, BBB) L_SENDB: mid = syms[b]; L_SENDB_SYM: { - mrb_int argc = (c == CALL_MAXARGS) ? -1 : c; - mrb_int bidx = (argc < 0) ? a+2 : a+c+1; + int n = c&0xf; + int nk = (c>>4)&0xf; + mrb_callinfo *ci = mrb->c->ci; + mrb_int bidx = a + mrb_bidx(c); mrb_method_t m; struct RClass *cls; - mrb_callinfo *ci = mrb->c->ci; - mrb_value recv, blk; + mrb_value recv; - mrb_assert(bidx < irep->nregs); + if (0 < nk && nk < 15) { /* pack keyword arguments */ + mrb_int kidx = a+n+1; + mrb_value kdict = hash_new_from_values(mrb, nk, regs+kidx); + regs[kidx] = kdict; + nk = 15; + c = n | (nk<<4); + } - recv = regs[a]; - blk = regs[bidx]; - if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { - blk = mrb_type_convert(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc)); - /* The stack might have been reallocated during mrb_type_convert(), - see #3622 */ - regs[bidx] = blk; + mrb_assert(bidx < irep->nregs+a); + mrb_value blk; + mrb_int new_bidx = a+mrb_bidx(c); + if (insn == OP_SEND) { + /* clear block argument */ + SET_NIL_VALUE(regs[new_bidx]); + SET_NIL_VALUE(blk); + } + else { + blk = regs[bidx]; + if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { + blk = mrb_type_convert(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc)); + /* The stack might have been reallocated during mrb_type_convert(), + see #3622 */ + } + regs[new_bidx] = blk; } + + recv = regs[a]; cls = mrb_class(mrb, recv); m = mrb_method_search_vm(mrb, &cls, mid); if (MRB_METHOD_UNDEF_P(m)) { - mrb_sym missing = MRB_SYM(method_missing); - m = mrb_method_search_vm(mrb, &cls, missing); - if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) { - mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1); - mrb_method_missing(mrb, mid, recv, args); - } - if (argc >= 0) { - if (a+2 >= irep->nregs) { - mrb_stack_extend(mrb, a+3); - } - regs[a+1] = mrb_ary_new_from_values(mrb, c, regs+a+1); - regs[a+2] = blk; - argc = -1; - } - mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid)); - mid = missing; + m = prepare_missing(mrb, recv, mid, &cls, a, &c, blk, 0); + mid = MRB_SYM(method_missing); } /* push callinfo */ - ci = cipush(mrb, a, a, cls, NULL, mid, argc); + ci = cipush(mrb, a, 0, cls, NULL, mid, c); if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { @@ -1580,14 +1617,13 @@ RETRY_TRY_BLOCK: recv = p->body.func(mrb, recv); } else if (MRB_METHOD_NOARG_P(m) && - (argc > 0 || (argc == -1 && RARRAY_LEN(regs[1]) != 0))) { + !(n == 0 || (n == CALL_MAXARGS && RARRAY_LEN(regs[1]) == 0))) { argnum_error(mrb, 0); goto L_RAISE; } else { recv = MRB_METHOD_FUNC(m)(mrb, recv); } - mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; ci = mrb->c->ci; @@ -1598,7 +1634,7 @@ RETRY_TRY_BLOCK: } } if (!ci->u.target_class) { /* return from context modifying method (resume/yield) */ - if (ci->acc == CI_ACC_RESUMED) { + if (ci->cci == CINFO_RESUMED) { mrb->jmp = prev_jmp; return recv; } @@ -1610,11 +1646,10 @@ RETRY_TRY_BLOCK: syms = irep->syms; } } - mrb->c->ci->stack[0] = recv; + ci->stack[0] = recv; /* pop stackpos */ ci = cipop(mrb); pc = ci->pc; - JUMP; } else { /* setup environment for calling method */ @@ -1622,19 +1657,18 @@ RETRY_TRY_BLOCK: irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); + mrb_stack_extend(mrb, (irep->nregs < 4) ? 4 : irep->nregs); pc = irep->iseq; - JUMP; } } + JUMP; CASE(OP_CALL, Z) { - mrb_callinfo *ci; - mrb_value recv = mrb->c->ci->stack[0]; + mrb_callinfo *ci = mrb->c->ci; + mrb_value recv = ci->stack[0]; struct RProc *m = mrb_proc_ptr(recv); /* replace callinfo */ - ci = mrb->c->ci; ci->u.target_class = MRB_PROC_TARGET_CLASS(m); mrb_vm_ci_proc_set(ci, m); if (MRB_PROC_ENV_P(m)) { @@ -1644,13 +1678,12 @@ RETRY_TRY_BLOCK: /* prepare stack */ if (MRB_PROC_CFUNC_P(m)) { recv = MRB_PROC_CFUNC(m)(mrb, recv); - mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; /* pop stackpos */ ci = cipop(mrb); pc = ci->pc; - regs[ci[1].acc] = recv; + ci[1].stack[0] = recv; irep = mrb->c->ci->proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1664,18 +1697,14 @@ RETRY_TRY_BLOCK: mrb->c->ci->stack[0] = mrb_nil_value(); a = 0; c = OP_R_NORMAL; - goto L_RETURN; + goto L_OP_RETURN_BODY; } pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, irep->nregs); - if (ci->argc < 0) { - if (irep->nregs > 3) { - stack_clear(regs+3, irep->nregs-3); - } - } - else if (ci->argc+2 < irep->nregs) { - stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2); + mrb_int nargs = mrb_ci_bidx(ci)+1; + if (nargs < irep->nregs) { + mrb_stack_extend(mrb, irep->nregs); + stack_clear(regs+nargs, irep->nregs-nargs); } if (MRB_PROC_ENV_P(m)) { regs[0] = MRB_PROC_ENV(m)->stack[0]; @@ -1686,11 +1715,10 @@ RETRY_TRY_BLOCK: } CASE(OP_SUPER, BB) { - mrb_int argc = (b == CALL_MAXARGS) ? -1 : b; - int bidx = (argc < 0) ? a+2 : a+b+1; mrb_method_t m; struct RClass *cls; mrb_callinfo *ci = mrb->c->ci; + mrb_int bidx = mrb_bidx(b)+a; mrb_value recv, blk; const struct RProc *p = ci->proc; mrb_sym mid = ci->mid; @@ -1712,13 +1740,12 @@ RETRY_TRY_BLOCK: else if (target_class->tt == MRB_TT_MODULE) { target_class = mrb_vm_ci_target_class(ci); if (target_class->tt != MRB_TT_ICLASS) { - mrb_value exc = mrb_exc_new_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]"); - mrb_exc_set(mrb, exc); - goto L_RAISE; + goto super_typeerror; } } recv = regs[0]; if (!mrb_obj_is_kind_of(mrb, recv, target_class)) { + super_typeerror: ; mrb_value exc = mrb_exc_new_lit(mrb, E_TYPE_ERROR, "self has wrong type to call super in this context"); mrb_exc_set(mrb, exc); @@ -1735,37 +1762,15 @@ RETRY_TRY_BLOCK: cls = target_class->super; m = mrb_method_search_vm(mrb, &cls, mid); if (MRB_METHOD_UNDEF_P(m)) { - mrb_sym missing = MRB_SYM(method_missing); - - if (mrb_func_basic_p(mrb, recv, missing, mrb_obj_missing)) { - mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1); - mrb_no_method_error(mrb, mid, args, "no superclass method '%n'", mid); - } - if (mid != missing) { - cls = mrb_class(mrb, recv); - } - m = mrb_method_search_vm(mrb, &cls, missing); - if (MRB_METHOD_UNDEF_P(m)) { /* just in case */ - mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1); - mrb_method_missing(mrb, missing, recv, args); - } - mid = missing; - if (argc >= 0) { - if (a+2 >= irep->nregs) { - mrb_stack_extend(mrb, a+3); - } - regs[a+1] = mrb_ary_new_from_values(mrb, b, regs+a+1); - regs[a+2] = blk; - argc = -1; - } - mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); + m = prepare_missing(mrb, recv, mid, &cls, a, &b, blk, 1); + mid = MRB_SYM(method_missing); } /* push callinfo */ - ci = cipush(mrb, a, 0, cls, NULL, mid, argc); + ci = cipush(mrb, a, 0, cls, NULL, mid, b); /* prepare stack */ - mrb->c->ci->stack[0] = recv; + ci->stack[0] = recv; if (MRB_METHOD_CFUNC_P(m)) { mrb_value v; @@ -1779,7 +1784,7 @@ RETRY_TRY_BLOCK: ci = mrb->c->ci; mrb_assert(!mrb_break_p(v)); if (!mrb_vm_ci_target_class(ci)) { /* return from context modifying method (resume/yield) */ - if (ci->acc == CI_ACC_RESUMED) { + if (ci->cci == CINFO_RESUMED) { mrb->jmp = prev_jmp; return v; } @@ -1797,15 +1802,12 @@ RETRY_TRY_BLOCK: JUMP; } else { - /* fill callinfo */ - ci->acc = a; - /* setup environment for calling method */ mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m))); irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); + mrb_stack_extend(mrb, (irep->nregs < 4) ? 4 : irep->nregs); pc = irep->iseq; JUMP; } @@ -1831,12 +1833,12 @@ RETRY_TRY_BLOCK: else { struct REnv *e = uvenv(mrb, lv-1); if (!e) goto L_NOSUPER; - if (MRB_ENV_LEN(e) <= m1+r+m2+kd+1) + if (MRB_ENV_LEN(e) <= m1+r+m2+1) goto L_NOSUPER; stack = e->stack + 1; } if (r == 0) { - regs[a] = mrb_ary_new_from_values(mrb, m1+m2+kd, stack); + regs[a] = mrb_ary_new_from_values(mrb, m1+m2, stack); } else { mrb_value *pp = NULL; @@ -1849,7 +1851,7 @@ RETRY_TRY_BLOCK: pp = ARY_PTR(ary); len = ARY_LEN(ary); } - regs[a] = mrb_ary_new_capa(mrb, m1+len+m2+kd); + regs[a] = mrb_ary_new_capa(mrb, m1+len+m2); rest = mrb_ary_ptr(regs[a]); if (m1 > 0) { stack_copy(ARY_PTR(rest), stack, m1); @@ -1860,12 +1862,15 @@ RETRY_TRY_BLOCK: if (m2 > 0) { stack_copy(ARY_PTR(rest)+m1+len, stack+m1+1, m2); } - if (kd) { - stack_copy(ARY_PTR(rest)+m1+len+m2, stack+m1+m2+1, kd); - } - ARY_SET_LEN(rest, m1+len+m2+kd); + ARY_SET_LEN(rest, m1+len+m2); + } + if (kd) { + regs[a+1] = stack[m1+r+m2]; + regs[a+2] = stack[m1+r+m2+1]; + } + else { + regs[a+1] = stack[m1+r+m2]; } - regs[a+1] = stack[m1+r+m2]; mrb_gc_arena_restore(mrb, ai); NEXT; } @@ -1879,17 +1884,48 @@ RETRY_TRY_BLOCK: /* unused int b = MRB_ASPEC_BLOCK(a); */ - mrb_int argc = mrb->c->ci->argc; + mrb_int const len = m1 + o + r + m2; + + mrb_callinfo *ci = mrb->c->ci; + mrb_int argc = ci->n; mrb_value *argv = regs+1; mrb_value * const argv0 = argv; - mrb_int const len = m1 + o + r + m2; - mrb_int const blk_pos = len + kd + 1; - mrb_value *blk = &argv[argc < 0 ? 1 : argc]; + mrb_int const kw_pos = len + kd; /* where kwhash should be */ + mrb_int const blk_pos = kw_pos + 1; /* where block should be */ + mrb_value blk = regs[mrb_ci_bidx(ci)]; mrb_value kdict = mrb_nil_value(); - mrb_int kargs = kd; + + /* keyword arguments */ + if (ci->nk > 0) { + mrb_int kidx = mrb_ci_kidx(ci); + kdict = regs[kidx]; + if (!mrb_hash_p(kdict) || mrb_hash_size(mrb, kdict) == 0) { + kdict = mrb_nil_value(); + ci->nk = 0; + } + } + if (!kd && !mrb_nil_p(kdict)) { + if (argc < 14) { + ci->n++; + argc++; /* include kdict in normal arguments */ + } + else if (argc == 14) { + /* pack arguments and kdict */ + regs[1] = mrb_ary_new_from_values(mrb, argc+1, ®s[1]); + argc = ci->n = 15; + } + else {/* argc == 15 */ + /* push kdict to packed arguments */ + mrb_ary_push(mrb, regs[1], regs[2]); + } + ci->nk = 0; + } + if (kd && MRB_ASPEC_KEY(a) > 0 && mrb_hash_p(kdict)) { + kdict = mrb_hash_dup(mrb, kdict); + } /* arguments is passed with Array */ - if (argc < 0) { + if (argc == 15) { struct RArray *ary = mrb_ary_ptr(regs[1]); argv = ARY_PTR(ary); argc = (int)ARY_LEN(ary); @@ -1897,8 +1933,8 @@ RETRY_TRY_BLOCK: } /* strict argument check */ - if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) { - if (argc < m1 + m2 || (r == 0 && argc > len + kd)) { + if (ci->proc && MRB_PROC_STRICT_P(ci->proc)) { + if (argc < m1 + m2 || (r == 0 && argc > len)) { argnum_error(mrb, m1+m2); goto L_RAISE; } @@ -1910,40 +1946,13 @@ RETRY_TRY_BLOCK: argv = RARRAY_PTR(argv[0]); } - if (kd) { - /* check last arguments is hash if method takes keyword arguments */ - if (argc == m1+m2) { - kdict = mrb_hash_new(mrb); - kargs = 0; - } - else { - if (argv && argc > 0 && mrb_hash_p(argv[argc-1])) { - kdict = argv[argc-1]; - mrb_hash_check_kdict(mrb, kdict); - } - else if (r || argc <= m1+m2+o - || !(mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc))) { - kdict = mrb_hash_new(mrb); - kargs = 0; - } - else { - argnum_error(mrb, m1+m2); - goto L_RAISE; - } - if (MRB_ASPEC_KEY(a) > 0) { - kdict = mrb_hash_dup(mrb, kdict); - } - } - } - - /* no rest arguments */ - if (argc-kargs < len) { + /* rest arguments */ + mrb_value rest = mrb_nil_value(); + if (argc < len) { mrb_int mlen = m2; if (argc < m1+m2) { mlen = m1 < argc ? argc - m1 : 0; } - regs[blk_pos] = *blk; /* move block */ - if (kd) regs[len + 1] = kdict; /* copy mandatory and optional arguments */ if (argv0 != argv && argv) { @@ -1961,40 +1970,39 @@ RETRY_TRY_BLOCK: } /* initialize rest arguments with empty Array */ if (r) { - regs[m1+o+1] = mrb_ary_new_capa(mrb, 0); + rest = mrb_ary_new_capa(mrb, 0); + regs[m1+o+1] = rest; } /* skip initializer of passed arguments */ - if (o > 0 && argc-kargs > m1+m2) - pc += (argc - kargs - m1 - m2)*3; + if (o > 0 && argc > m1+m2) + pc += (argc - m1 - m2)*3; } else { mrb_int rnum = 0; if (argv0 != argv) { - regs[blk_pos] = *blk; /* move block */ - if (kd) regs[len + 1] = kdict; value_move(®s[1], argv, m1+o); } if (r) { - mrb_value ary; - - rnum = argc-m1-o-m2-kargs; - ary = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); - regs[m1+o+1] = ary; + rnum = argc-m1-o-m2; + rest = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); + regs[m1+o+1] = rest; } - if (m2) { - if (argc-m2 > m1) { - value_move(®s[m1+o+r+1], &argv[m1+o+rnum], m2); - } - } - if (argv0 == argv) { - regs[blk_pos] = *blk; /* move block */ - if (kd) regs[len + 1] = kdict; + if (m2 > 0 && argc-m2 > m1) { + value_move(®s[m1+o+r+1], &argv[m1+o+rnum], m2); } pc += o*3; } + /* need to be update blk first to protect blk from GC */ + regs[blk_pos] = blk; /* move block */ + if (kd) { + if (mrb_nil_p(kdict)) + kdict = mrb_hash_new_capa(mrb, 0); + regs[kw_pos] = kdict; /* set kwhash */ + } + /* format arguments for generated code */ - mrb->c->ci->argc = (int16_t)(len + kd); + mrb->c->ci->n = len; /* clear local (but non-argument) variables */ if (irep->nlocals-blk_pos-1 > 0) { @@ -2005,9 +2013,10 @@ RETRY_TRY_BLOCK: CASE(OP_KARG, BB) { mrb_value k = mrb_symbol_value(syms[b]); - mrb_value kdict = regs[mrb->c->ci->argc]; + mrb_int kidx = mrb_ci_kidx(mrb->c->ci); + mrb_value kdict; - if (!mrb_hash_p(kdict) || !mrb_hash_key_p(mrb, kdict, k)) { + if (kidx < 0 || !mrb_hash_p(kdict=regs[kidx]) || !mrb_hash_key_p(mrb, kdict, k)) { mrb_value str = mrb_format(mrb, "missing keyword: %v", k); mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); goto L_RAISE; @@ -2019,10 +2028,11 @@ RETRY_TRY_BLOCK: CASE(OP_KEY_P, BB) { mrb_value k = mrb_symbol_value(syms[b]); - mrb_value kdict = regs[mrb->c->ci->argc]; + mrb_int kidx = mrb_ci_kidx(mrb->c->ci); + mrb_value kdict; mrb_bool key_p = FALSE; - if (mrb_hash_p(kdict)) { + if (kidx >= 0 && mrb_hash_p(kdict=regs[kidx])) { key_p = mrb_hash_key_p(mrb, kdict, k); } regs[a] = mrb_bool_value(key_p); @@ -2030,9 +2040,10 @@ RETRY_TRY_BLOCK: } CASE(OP_KEYEND, Z) { - mrb_value kdict = regs[mrb->c->ci->argc]; + mrb_int kidx = mrb_ci_kidx(mrb->c->ci); + mrb_value kdict; - if (mrb_hash_p(kdict) && !mrb_hash_empty_p(mrb, kdict)) { + if (kidx >= 0 && mrb_hash_p(kdict=regs[kidx]) && !mrb_hash_empty_p(mrb, kdict)) { mrb_value keys = mrb_hash_keys(mrb, kdict); mrb_value key1 = RARRAY_PTR(keys)[0]; mrb_value str = mrb_format(mrb, "unknown keyword: %v", key1); @@ -2058,14 +2069,8 @@ RETRY_TRY_BLOCK: ci = mrb->c->ci; if (ci->mid) { - mrb_value blk; + mrb_value blk = regs[mrb_ci_bidx(ci)]; - if (ci->argc < 0) { - blk = regs[2]; - } - else { - blk = regs[ci->argc+1]; - } if (mrb_proc_p(blk)) { struct RProc *p = mrb_proc_ptr(blk); @@ -2086,7 +2091,7 @@ RETRY_TRY_BLOCK: } while ((ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL)) == NULL) { ci = cipop(mrb); - if (ci[1].acc == CI_ACC_SKIP && prev_jmp) { + if (ci[1].cci == CINFO_SKIP && prev_jmp) { mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } @@ -2134,7 +2139,7 @@ RETRY_TRY_BLOCK: switch (c) { case OP_R_RETURN: /* Fall through to OP_R_NORMAL otherwise */ - if (ci->acc >=0 && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) { + if (ci->cci == CINFO_NONE && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) { const struct RProc *dst; mrb_callinfo *cibase; cibase = mrb->c->cibase; @@ -2150,7 +2155,7 @@ RETRY_TRY_BLOCK: } /* check jump destination */ while (cibase <= ci && ci->proc != dst) { - if (ci->acc < 0) { /* jump cross C boudary */ + if (ci->cci > CINFO_NONE) { /* jump cross C boundary */ localjump_error(mrb, LOCALJUMP_ERROR_RETURN); goto L_RAISE; } @@ -2258,7 +2263,7 @@ RETRY_TRY_BLOCK: c->prev = NULL; ci = mrb->c->ci; } - if (ci->acc < 0) { + if (ci->cci > CINFO_NONE) { ci = cipop(mrb); mrb_gc_arena_restore(mrb, ai); mrb->c->vmexec = FALSE; @@ -2284,7 +2289,7 @@ RETRY_TRY_BLOCK: } } while (mrb->c->cibase < ci && ci[-1].proc != proc->upper) { - if (ci[-1].acc == CI_ACC_SKIP) { + if (ci[-1].cci == CINFO_SKIP) { goto L_BREAK_ERROR; } CHECKPOINT_RESTORE(RBREAK_TAG_BREAK_UPPER) { @@ -2322,21 +2327,21 @@ RETRY_TRY_BLOCK: mrb->jmp = prev_jmp; return v; } - acc = ci->acc; + acc = ci->cci; ci = cipop(mrb); - if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) { + if (acc == CINFO_SKIP || acc == CINFO_DIRECT) { mrb_gc_arena_restore(mrb, ai); mrb->jmp = prev_jmp; return v; } - pc = ci[0].pc; + pc = ci->pc; DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); - proc = mrb->c->ci->proc; + proc = ci->proc; irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - regs[acc] = v; + ci[1].stack[0] = v; mrb_gc_arena_restore(mrb, ai); } JUMP; @@ -2360,7 +2365,7 @@ RETRY_TRY_BLOCK: } stack = e->stack + 1; } - if (mrb_nil_p(stack[m1+r+m2])) { + if (mrb_nil_p(stack[m1+r+m2+kd])) { localjump_error(mrb, LOCALJUMP_ERROR_YIELD); goto L_RAISE; } @@ -2385,7 +2390,6 @@ RETRY_TRY_BLOCK: OP_MATH_CASE_FLOAT(op_name, float, float); \ OP_MATH_CASE_STRING_##op_name(); \ default: \ - c = 1; \ mid = MRB_OPSYM(op_name); \ goto L_SEND_SYM; \ } \ @@ -2440,9 +2444,7 @@ RETRY_TRY_BLOCK: CASE(OP_DIV, B) { #ifndef MRB_NO_FLOAT mrb_float x, y, f; - mrb_float mrb_div_flo(mrb_float x, mrb_float y); #endif - mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); /* need to check if op is overridden */ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { @@ -2469,13 +2471,12 @@ RETRY_TRY_BLOCK: break; #endif default: - c = 1; mid = MRB_OPSYM(div); goto L_SEND_SYM; } #ifndef MRB_NO_FLOAT - f = mrb_div_flo(x, y); + f = mrb_div_float(x, y); SET_FLOAT_VALUE(mrb, regs[a], f); #endif NEXT; @@ -2488,7 +2489,6 @@ RETRY_TRY_BLOCK: OP_MATHI_CASE_FLOAT(op_name); \ default: \ SET_INT_VALUE(mrb,regs[a+1], b); \ - c = 1; \ mid = MRB_OPSYM(op_name); \ goto L_SEND_SYM; \ } \ @@ -2534,7 +2534,6 @@ RETRY_TRY_BLOCK: result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\ break;\ default:\ - c = 1;\ mid = MRB_OPSYM(sym);\ goto L_SEND_SYM;\ }\ @@ -2563,7 +2562,6 @@ RETRY_TRY_BLOCK: result = OP_CMP_BODY(op,mrb_float,mrb_float);\ break;\ default:\ - c = 1;\ mid = MRB_OPSYM(sym);\ goto L_SEND_SYM;\ }\ @@ -2625,14 +2623,18 @@ RETRY_TRY_BLOCK: regs[a] = splat; } else { + mrb_assert(mrb_type(regs[a]) == MRB_TT_ARRAY); mrb_ary_concat(mrb, regs[a], splat); } mrb_gc_arena_restore(mrb, ai); NEXT; } - CASE(OP_ARYPUSH, B) { - mrb_ary_push(mrb, regs[a], regs[a+1]); + CASE(OP_ARYPUSH, BB) { + mrb_assert(mrb_type(regs[a]) == MRB_TT_ARRAY); + for (mrb_int i=0; i<b; i++) { + mrb_ary_push(mrb, regs[a], regs[a+i+1]); + } NEXT; } @@ -2667,6 +2669,7 @@ RETRY_TRY_BLOCK: } CASE(OP_ASET, BBB) { + mrb_assert(mrb_type(regs[a]) == MRB_TT_ARRAY); mrb_ary_set(mrb, regs[b], c, regs[a]); NEXT; } @@ -2709,16 +2712,29 @@ RETRY_TRY_BLOCK: mrb_sym sym = mrb_intern_str(mrb, regs[a]); regs[a] = mrb_symbol_value(sym); - mrb_gc_arena_restore(mrb, ai); NEXT; } - CASE(OP_STRING16, BS) { - goto op_string; + CASE(OP_SYMBOL, BB) { + size_t len; + mrb_sym sym; + + mrb_assert((pool[b].tt&IREP_TT_NFLAG)==0); + len = pool[b].tt >> 2; + if (pool[b].tt & IREP_TT_SFLAG) { + sym = mrb_intern_static(mrb, pool[b].u.str, len); + } + else { + sym = mrb_intern(mrb, pool[b].u.str, len); + } + regs[a] = mrb_symbol_value(sym); + NEXT; } + CASE(OP_STRING, BB) { size_t len; - op_string: + + mrb_assert((pool[b].tt&IREP_TT_NFLAG)==0); len = pool[b].tt >> 2; if (pool[b].tt & IREP_TT_SFLAG) { regs[a] = mrb_str_new_static(mrb, pool[b].u.str, len); @@ -2753,7 +2769,8 @@ RETRY_TRY_BLOCK: int i; int lim = a+b*2+1; - hash = mrb_ensure_hash_type(mrb, regs[a]); + hash = regs[a]; + mrb_ensure_hash_type(mrb, hash); for (i=a+1; i<lim; i+=2) { mrb_hash_set(mrb, hash, regs[i], regs[i+1]); } @@ -2761,8 +2778,9 @@ RETRY_TRY_BLOCK: NEXT; } CASE(OP_HASHCAT, B) { - mrb_value hash = mrb_ensure_hash_type(mrb, regs[a]); + mrb_value hash = regs[a]; + mrb_ensure_hash_type(mrb, hash); mrb_hash_merge(mrb, hash, regs[a+1]); mrb_gc_arena_restore(mrb, ai); NEXT; @@ -2795,18 +2813,6 @@ RETRY_TRY_BLOCK: c = OP_L_METHOD; goto L_MAKE_LAMBDA; } - CASE(OP_LAMBDA16, BS) { - c = OP_L_LAMBDA; - goto L_MAKE_LAMBDA; - } - CASE(OP_BLOCK16, BS) { - c = OP_L_BLOCK; - goto L_MAKE_LAMBDA; - } - CASE(OP_METHOD16, BS) { - c = OP_L_METHOD; - goto L_MAKE_LAMBDA; - } CASE(OP_RANGE_INC, B) { mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], FALSE); @@ -2862,10 +2868,7 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_EXEC16, BS) - goto L_EXEC; CASE(OP_EXEC, BB) - L_EXEC: { mrb_value recv = regs[a]; struct RProc *p; @@ -2879,7 +2882,7 @@ RETRY_TRY_BLOCK: p->flags |= MRB_PROC_SCOPE; /* prepare call stack */ - cipush(mrb, a, a, mrb_class_ptr(recv), p, 0, 0); + cipush(mrb, a, 0, mrb_class_ptr(recv), p, 0, 0); irep = p->body.irep; pool = irep->pool; @@ -2894,10 +2897,13 @@ RETRY_TRY_BLOCK: struct RClass *target = mrb_class_ptr(regs[a]); struct RProc *p = mrb_proc_ptr(regs[a+1]); mrb_method_t m; + mrb_sym mid = syms[b]; MRB_METHOD_FROM_PROC(m, p); - mrb_define_method_raw(mrb, target, syms[b], m); + mrb_define_method_raw(mrb, target, mid, m); + mrb_method_added(mrb, target, mid); mrb_gc_arena_restore(mrb, ai); + regs[a] = mrb_symbol_value(mid); NEXT; } @@ -2908,24 +2914,24 @@ RETRY_TRY_BLOCK: } CASE(OP_TCLASS, B) { - if (!check_target_class(mrb)) goto L_RAISE; - regs[a] = mrb_obj_value(mrb_vm_ci_target_class(mrb->c->ci)); + struct RClass *target = check_target_class(mrb); + if (!target) goto L_RAISE; + regs[a] = mrb_obj_value(target); NEXT; } CASE(OP_ALIAS, BB) { - struct RClass *target; + struct RClass *target = check_target_class(mrb); - if (!check_target_class(mrb)) goto L_RAISE; - target = mrb_vm_ci_target_class(mrb->c->ci); + if (!target) goto L_RAISE; mrb_alias_method(mrb, target, syms[a], syms[b]); + mrb_method_added(mrb, target, syms[a]); NEXT; } CASE(OP_UNDEF, B) { - struct RClass *target; + struct RClass *target = check_target_class(mrb); - if (!check_target_class(mrb)) goto L_RAISE; - target = mrb_vm_ci_target_class(mrb->c->ci); + if (!target) goto L_RAISE; mrb_undef_method_id(mrb, target, syms[a]); NEXT; } @@ -2954,7 +2960,34 @@ RETRY_TRY_BLOCK: goto L_RAISE; } - CASE(OP_SENDVK, BB) { /* not yet implemented */ + CASE(OP_EXT1, Z) { + insn = READ_B(); + switch (insn) { +#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _1(); mrb->c->ci->pc = pc; goto L_OP_ ## insn ## _BODY; +#include "mruby/ops.h" +#undef OPCODE + } + pc--; + NEXT; + } + CASE(OP_EXT2, Z) { + insn = READ_B(); + switch (insn) { +#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _2(); mrb->c->ci->pc = pc; goto L_OP_ ## insn ## _BODY; +#include "mruby/ops.h" +#undef OPCODE + } + pc--; + NEXT; + } + CASE(OP_EXT3, Z) { + uint8_t insn = READ_B(); + switch (insn) { +#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _3(); mrb->c->ci->pc = pc; goto L_OP_ ## insn ## _BODY; +#include "mruby/ops.h" +#undef OPCODE + } + pc--; NEXT; } @@ -2981,7 +3014,7 @@ RETRY_TRY_BLOCK: } MRB_CATCH(&c_jmp) { mrb_callinfo *ci = mrb->c->ci; - while (ci > mrb->c->cibase && ci->acc == CI_ACC_DIRECT) { + while (ci > mrb->c->cibase && ci->cci == CINFO_DIRECT) { ci = cipop(mrb); } exc_catched = TRUE; @@ -2994,12 +3027,7 @@ RETRY_TRY_BLOCK: static mrb_value mrb_run(mrb_state *mrb, const struct RProc *proc, mrb_value self) { - if (mrb->c->ci->argc < 0) { - return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */ - } - else { - return mrb_vm_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */ - } + return mrb_vm_run(mrb, proc, self, mrb_ci_bidx(mrb->c->ci) + 1); } MRB_API mrb_value @@ -3014,7 +3042,7 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st mrb_vm_ci_env_set(mrb->c->ci, NULL); return mrb_vm_run(mrb, proc, self, stack_keep); } - cipush(mrb, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); + cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, 0, 0); v = mrb_vm_run(mrb, proc, self, stack_keep); return v; diff --git a/tasks/doc.rake b/tasks/doc.rake index 8013ed038..8a9108f1a 100644 --- a/tasks/doc.rake +++ b/tasks/doc.rake @@ -18,7 +18,10 @@ namespace :doc do sh "doxygen Doxyfile" rescue puts "ERROR: To generate C API documents, you need Doxygen." + puts "On Debian-based systems:" puts " $ sudo apt-get install doxygen" + puts "On RHEL-based systems:" + puts " $ sudo dnf install doxygen" end end diff --git a/tasks/libmruby.rake b/tasks/libmruby.rake index 9a7a57ff7..1fb3cbc31 100644 --- a/tasks/libmruby.rake +++ b/tasks/libmruby.rake @@ -14,7 +14,8 @@ MRuby.each_target do file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libmruby_static] do |t| mkdir_p File.dirname t.name open(t.name, 'w') do |f| - f.puts "MRUBY_CFLAGS = #{cc.all_flags}" + gemincs = gems.map { |g| g.export_include_paths.map { |n| g.filename(n) } }.flatten.uniq + f.puts "MRUBY_CFLAGS = #{cc.all_flags([], gemincs)}" f.puts "MRUBY_CC = #{cc.command}" f.puts "MRUBY_LD = #{linker.command}" diff --git a/test/bintest.rb b/test/bintest.rb index a6888c9fb..773d61edc 100644 --- a/test/bintest.rb +++ b/test/bintest.rb @@ -3,13 +3,27 @@ require 'test/assert.rb' GEMNAME = "" -def cmd(s) +def cmd_list(s) path = s == "mrbc" ? ENV['MRBCFILE'] : "#{ENV['BUILD_DIR']}/bin/#{s}" path = path.sub(/\.exe\z/, "") if /mswin(?!ce)|mingw|bccwin/ =~ RbConfig::CONFIG['host_os'] path = "#{path}.exe".tr("/", "\\") end - path + + path_list = [path] + + emu = ENV['EMULATOR'] + path_list.unshift emu if emu && !emu.empty? + + path_list +end + +def cmd(s) + return cmd_list(s).join(' ') +end + +def cmd_bin(s) + return cmd_list(s).pop end def shellquote(s) diff --git a/test/t/bs_block.rb b/test/t/bs_block.rb index 995e52559..f4e4da375 100644 --- a/test/t/bs_block.rb +++ b/test/t/bs_block.rb @@ -520,3 +520,15 @@ assert('BS Block 38') do assert_equal [1,2,3,4,5], iter{|a,b,c=:c,d,e| [a,b,c,d,e]} end + +assert('BS Block 39') do + def iter + yield 1 + end + + assert_equal([1, 2, nil]) do + iter{|a, b=2, c| + [a, b, c] + } + end +end diff --git a/test/t/class.rb b/test/t/class.rb index e2839111c..1b4b84890 100644 --- a/test/t/class.rb +++ b/test/t/class.rb @@ -375,6 +375,20 @@ assert('clone Class') do assert_true(Foo.clone.new.func) end +assert('class definition in singleton class') do + class AClassS + class << self + class BClass + end + + def iclass + BClass + end + end + end + assert_equal(Class, AClassS.iclass.class) +end + assert('class variable and class << self style class method') do class ClassVariableTest @@class_variable = "value" diff --git a/test/t/float.rb b/test/t/float.rb index f6f6d01dd..e4c25b34e 100644 --- a/test/t/float.rb +++ b/test/t/float.rb @@ -277,8 +277,6 @@ assert('Float#to_s') do assert_equal("-1.0e-10", -0.0000000001.to_s) assert_equal("1.0e+20", 1e20.to_s) assert_equal("-1.0e+20", -1e20.to_s) - assert_equal("1.0e+16", 10000000000000000.0.to_s) - assert_equal("-1.0e+16", -10000000000000000.0.to_s) assert_equal("100000.0", 100000.0.to_s) assert_equal("-100000.0", -100000.0.to_s) if uses_float @@ -305,4 +303,16 @@ assert('Float#eql?') do assert_not_operator(5.0, :eql?, "5.0") end +assert('Float#abs') do + f = 1.0 + assert_equal(1.0, f.abs) + f = -1.0 + assert_equal(1.0, f.abs) + f = 0.0 + assert_equal(0.0, f.abs) + # abs(negative zero) should be positive zero + f = -0.0 + assert_equal(0.0, f.abs) +end + end # const_defined?(:Float) diff --git a/test/t/hash.rb b/test/t/hash.rb index 9bc2668ae..1b4db056e 100644 --- a/test/t/hash.rb +++ b/test/t/hash.rb @@ -1006,3 +1006,9 @@ assert('#== receiver should be specified value') do %i[has_value? value?].each{|m| assert_nothing_raised{h.__send__(m, v1)}} end end + +assert('test value ommision') do + x = 1 + y = 2 + assert_equal({x:1, y:2}, {x:, y:}) +end diff --git a/test/t/methods.rb b/test/t/methods.rb index f9c25dc33..9005d7976 100644 --- a/test/t/methods.rb +++ b/test/t/methods.rb @@ -107,3 +107,32 @@ assert('The undef statement (method undefined)', '13.3.7 a) 5)') do undef :non_existing_method end end + +assert('method_added hook') do + c = Class.new do + # method to retrieve @name + def self.name; @name; end + # hook method on method definition + def self.method_added(name) @name = name; end + # method definition + def foo; end + end + assert_equal(:foo, c.name) + c.define_method(:bar){} + assert_equal(:bar, c.name) +end + +assert('singleton_method_added hook') do + a = Object.new + # method to retrieve @name + def a.name; @name; end + # hook method on singleton method definition + def a.singleton_method_added(name) @name = name; end + # singleton method definition + def a.foo; end + assert_equal(:foo, a.name) + class <<a + def bar; end + end + assert_equal(:bar, a.name) +end diff --git a/test/t/superclass.rb b/test/t/superclass.rb index f213b1247..81630192d 100644 --- a/test/t/superclass.rb +++ b/test/t/superclass.rb @@ -23,8 +23,7 @@ [:Exception, :Object, '15.2.22.2'], [:StandardError, :Exception, '15.2.23.2'], [:ArgumentError, :StandardError, '15.2.24.2'], - # [:LocalJumpError, :StandardError, '15.2.25.2'], - [:LocalJumpError, :ScriptError, '15.2.25.2'], # mruby specific + [:LocalJumpError, :StandardError, '15.2.25.2'], [:RangeError, :StandardError, '15.2.26.2'], [:RegexpError, :StandardError, '15.2.27.2'], [:RuntimeError, :StandardError, '15.2.28.2'], diff --git a/test/t/symbol.rb b/test/t/symbol.rb index 5c674a9cb..4cb210757 100644 --- a/test/t/symbol.rb +++ b/test/t/symbol.rb @@ -17,10 +17,6 @@ assert('Symbol#===', '15.2.11.3.1') do assert_false :abc === :cba end -assert('Symbol#id2name', '15.2.11.3.2') do - assert_equal 'abc', :abc.id2name -end - assert('Symbol#to_s', '15.2.11.3.3') do assert_equal 'abc', :abc.to_s end diff --git a/test/t/syntax.rb b/test/t/syntax.rb index b3ee2d438..a89432b68 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -48,7 +48,32 @@ assert('yield', '11.3.5') do end end -assert('redo in a for loop (#3275)') do +assert('break', '11.5.2.4.3') do + n = 0 + a = [] + while true + n += 1 + a.push(n) + if n > 3 + break + end + end + + assert_equal [1,2,3,4], a + + n = 0 + a = [] + 6.times do + n += 1 + a.push(n) + if n > 3 + break + end + end + assert_equal [1,2,3,4], a +end + +assert('redo', '11.5.2.4.5') do sum = 0 for i in 1..10 sum += i @@ -59,6 +84,17 @@ assert('redo in a for loop (#3275)') do end assert_equal 220, sum + + n = 0 + a = [] + 3.times do + n += 1 + if n == 2 + redo + end + a.push(n) + end + assert_equal [1,3,4], a end assert('Abbreviated variable assignment', '11.4.2.3.2') do @@ -188,6 +224,18 @@ assert('Abbreviated variable assignment as returns') do assert_equal 1, Syntax4AbbrVarAsgnAsReturns::A.new.b end +assert('Abbreviated variable assignment of object attribute') do + module Syntax4AbbrVarAsgnObjectAttr + class A + attr_accessor :c + def b + self.c ||= 1 + end + end + end + assert_equal 1, Syntax4AbbrVarAsgnObjectAttr::A.new.b +end + assert('Splat and multiple assignment') do *a = *[1,2,3] b, *c = *[7,8,9] @@ -504,8 +552,7 @@ assert 'keyword arguments' do assert_raise(ArgumentError) { m } assert_raise(ArgumentError) { m 'a' => 1, a: 1 } h = { a: 1 } - assert_equal 1, m(h) - assert_equal({ a: 1 }, h) + assert_equal 1, m(**h) def m(a: 1) a end assert_equal 1, m @@ -520,23 +567,23 @@ assert 'keyword arguments' do def m(a, **) a end assert_equal 1, m(1) assert_equal 1, m(1, a: 2, b: 3) - assert_equal({ 'a' => 1, b: 2 }, m('a' => 1, b: 2)) + assert_raise(ArgumentError) { m('a' => 1, b: 2) } def m(a, **k) [a, k] end assert_equal [1, {}], m(1) assert_equal [1, {a: 2, b: 3}], m(1, a: 2, b: 3) - assert_equal [{'a' => 1, b: 2}, {}], m('a' => 1, b: 2) + assert_raise(ArgumentError) { m('a' => 1, b: 2) } def m(a=1, **) a end assert_equal 1, m assert_equal 2, m(2, a: 1, b: 0) - assert_raise(ArgumentError) { m('a' => 1, a: 2) } def m(a=1, **k) [a, k] end assert_equal [1, {}], m assert_equal [1, {a: 1}], m(a: 1) assert_equal [2, {a: 1, b: 2}], m(2, a: 1, b: 2) - assert_equal [{a: 1}, {b: 2}], m({a: 1}, {b: 2}) + assert_equal [{a: 1}, {b: 2}], m({a: 1}, b: 2) + assert_raise(ArgumentError) { m({a: 1}, {b: 2}) } def m(*, a:) a end assert_equal 1, m(a: 1) @@ -561,34 +608,27 @@ assert 'keyword arguments' do def m(*a, **) a end assert_equal [], m() assert_equal [1, 2, 3], m(1, 2, 3, a: 4, b: 5) - assert_raise(ArgumentError) { m("a" => 1, a: 1) } assert_equal [1], m(1, **{a: 2}) def m(*, **k) k end assert_equal({}, m()) assert_equal({a: 4, b: 5}, m(1, 2, 3, a: 4, b: 5)) - assert_raise(ArgumentError) { m("a" => 1, a: 1) } def m(a = nil, b = nil, **k) [a, k] end assert_equal [nil, {}], m() assert_equal([nil, {a: 1}], m(a: 1)) - assert_raise(ArgumentError) { m("a" => 1, a: 1) } assert_equal([{"a" => 1}, {a: 1}], m({ "a" => 1 }, a: 1)) assert_equal([{a: 1}, {}], m({a: 1}, {})) - assert_equal([nil, {}], m({})) + assert_equal([{}, {}], m({})) def m(*a, **k) [a, k] end assert_equal([[], {}], m()) assert_equal([[1], {}], m(1)) assert_equal([[], {a: 1, b: 2}], m(a: 1, b: 2)) assert_equal([[1, 2, 3], {a: 2}], m(1, 2, 3, a: 2)) - assert_raise(ArgumentError) { m("a" => 1, a: 1) } - assert_raise(ArgumentError) { m("a" => 1) } assert_equal([[], {a: 1}], m(a: 1)) - assert_raise(ArgumentError) { m("a" => 1, a: 1) } assert_equal([[{"a" => 1}], {a: 1}], m({ "a" => 1 }, a: 1)) - assert_equal([[{a: 1}], {}], m({a: 1}, {})) - assert_raise(ArgumentError) { m({a: 1}, {"a" => 1}) } + assert_equal([[{a: 1}, {}], {}], m({a: 1}, {})) def m(a:, b:) [a, b] end assert_equal([1, 2], m(a: 1, b: 2)) @@ -597,23 +637,21 @@ assert 'keyword arguments' do def m(a:, b: 1) [a, b] end assert_equal([1, 1], m(a: 1)) assert_equal([1, 2], m(a: 1, b: 2)) + assert_raise(ArgumentError) { m(b: 1) } assert_raise(ArgumentError) { m("a" => 1, a: 1, b: 2) } def m(a:, **) a end assert_equal(1, m(a: 1)) assert_equal(1, m(a: 1, b: 2)) - assert_raise(ArgumentError) { m("a" => 1, a: 1, b: 2) } def m(a:, **k) [a, k] end assert_equal([1, {}], m(a: 1)) assert_equal([1, {b: 2, c: 3}], m(a: 1, b: 2, c: 3)) - assert_raise(ArgumentError) { m("a" => 1, a: 1, b: 2) } -=begin def m(a:, &b) [a, b] end assert_equal([1, nil], m(a: 1)) - assert_equal([1, l], m(a: 1, &(l = ->{}))) -=end + result = m(a: 1, &(l = ->{})) + assert_equal([1, l], result) def m(a: 1, b:) [a, b] end assert_equal([1, 0], m(b: 0)) @@ -651,21 +689,12 @@ assert 'keyword arguments' do assert_equal([{ a: 1, b: 2}, nil], m(a: 1, b: 2)) assert_equal :blk, m{ :blk }[1].call - def m(hsh = {}) hsh end - assert_equal({ a: 1, b: 2 }, m(a: 1, b: 2)) - assert_equal({ a: 1, 'b' => 2 }, m(a: 1, 'b' => 2)) - - def m(hsh) hsh end - assert_equal({ a: 1, b: 2 }, m(a: 1, b: 2)) - assert_equal({ a: 1, 'b' => 2 }, m(a: 1, 'b' => 2)) - =begin def m(a, b=1, *c, (*d, (e)), f: 2, g:, h:, **k, &l) [a, b, c, d, e, f, g, h, k, l] end result = m(9, 8, 7, 6, f: 5, g: 4, h: 3, &(l = ->{})) assert_equal([9, 8, [7], [], 6, 5, 4, 3, {}, l], result) - def m a, b=1, *c, d, e:, f: 2, g:, **k, &l [a, b, c, d, e, f, g, k, l] end @@ -706,3 +735,29 @@ assert('argument forwarding') do o.a(1,2,3){} o.b(1,2,3){} end + +assert('endless def') do + c = Class.new { + def m1 = 42 + def m2() = 42 + def m3(x) = x+1 + def self.s1 = 42 + def self.s2() = 42 + def self.s3(x) = x + 1 + def cm1 = m3 42 + def cm2() = m3 42 + def cm3(x) = m3 x+1 + def self.cs1 = s3 42 + def self.cs2() = s3 42 + def self.cs3(x) = s3 x + 1 + } + o = c.new + assert_equal(42, o.m1) + assert_equal(43, o.m3(o.m2)) + assert_equal(42, c.s1) + assert_equal(43, c.s3(c.s2)) + assert_equal(43, o.cm1) + assert_equal(45, o.cm3(o.cm2)) + assert_equal(43, c.cs1) + assert_equal(45, c.cs3(c.cs2)) +end diff --git a/test/t/unicode.rb b/test/t/unicode.rb index 8622ae08a..c8602da5a 100644 --- a/test/t/unicode.rb +++ b/test/t/unicode.rb @@ -1,15 +1,15 @@ # Test of the \u notation assert('bare \u notation test') do - # Mininum and maximum one byte characters + # Minimum and maximum one byte characters assert_equal("\x00", "\u0000") assert_equal("\x7F", "\u007F") - # Mininum and maximum two byte characters + # Minimum and maximum two byte characters assert_equal("\xC2\x80", "\u0080") assert_equal("\xDF\xBF", "\u07FF") - # Mininum and maximum three byte characters + # Minimum and maximum three byte characters assert_equal("\xE0\xA0\x80", "\u0800") assert_equal("\xEF\xBF\xBF", "\uFFFF") @@ -17,19 +17,19 @@ assert('bare \u notation test') do end assert('braced \u notation test') do - # Mininum and maximum one byte characters + # Minimum and maximum one byte characters assert_equal("\x00", "\u{0000}") assert_equal("\x7F", "\u{007F}") - # Mininum and maximum two byte characters + # Minimum and maximum two byte characters assert_equal("\xC2\x80", "\u{0080}") assert_equal("\xDF\xBF", "\u{07FF}") - # Mininum and maximum three byte characters + # Minimum and maximum three byte characters assert_equal("\xE0\xA0\x80", "\u{0800}") assert_equal("\xEF\xBF\xBF", "\u{FFFF}") - # Mininum and maximum four byte characters + # Minimum and maximum four byte characters assert_equal("\xF0\x90\x80\x80", "\u{10000}") assert_equal("\xF4\x8F\xBF\xBF", "\u{10FFFF}") end |
