From c91eb5b8b48af762b82982227edd8b31fb8b6879 Mon Sep 17 00:00:00 2001 From: pyama Date: Wed, 20 Sep 2023 11:23:54 +0900 Subject: [PATCH 1/7] mruby 3.2.0 --- mruby/.editorconfig | 3 +- mruby/.git-blame-ignore-revs | 2 + mruby/.github/linters/.markdown-lint.yml | 3 - mruby/.github/workflows/build.yml | 152 +- mruby/.github/workflows/codeql-analysis.yml | 21 +- mruby/.github/workflows/lint.yml | 14 +- mruby/.github/workflows/oss-fuzz.yml | 5 +- mruby/.github/workflows/super-linter.yml | 26 +- mruby/.pre-commit-config.yaml | 30 +- mruby/.yardopts | 10 +- mruby/AUTHORS | 59 +- mruby/CONTRIBUTING.md | 52 +- mruby/Doxyfile | 13 +- mruby/LEGAL | 35 + mruby/LICENSE | 2 +- mruby/Makefile | 8 + mruby/NEWS | 67 +- mruby/README.md | 28 +- mruby/Rakefile | 39 +- mruby/SECURITY.md | 16 +- mruby/TODO.md | 15 +- mruby/benchmark/bm_ao_render.rb | 10 +- mruby/benchmark/bm_fib.rb | 1 - mruby/benchmark/bm_so_lists.rb | 4 +- mruby/build_config/IntelGalileo.rb | 2 +- mruby/build_config/android_arm64_v8a.rb | 2 +- mruby/build_config/android_armeabi.rb | 2 +- .../android_armeabi_v7a_neon_hard.rb | 2 +- mruby/build_config/boxing.rb | 2 +- mruby/build_config/cross-mingw-winetest.rb | 15 +- mruby/build_config/helpers/wine_runner.rb | 4 +- mruby/build_config/host-debug.rb | 2 +- mruby/build_config/host-f32.rb | 2 +- mruby/build_config/host-gprof.rb | 2 +- mruby/build_config/host-m32.rb | 2 +- mruby/codespell.txt | 3 + mruby/doc/guides/compile.md | 76 +- mruby/doc/guides/debugger.md | 2 +- mruby/doc/guides/gc-arena-howto.md | 40 +- mruby/doc/guides/link.md | 26 +- mruby/doc/guides/mrbconf.md | 215 +- mruby/doc/guides/mrbgems.md | 138 +- mruby/doc/guides/symbol.md | 20 +- mruby/doc/internal/boxing.md | 54 +- mruby/doc/internal/opcode.md | 230 +- mruby/doc/limitations.md | 20 +- mruby/doc/mruby3.0.md | 60 +- mruby/doc/mruby3.1.md | 4 +- mruby/doc/mruby3.2.md | 80 + .../c_and_ruby_extension_example/README.md | 3 +- .../mrbgems/c_extension_example/README.md | 3 +- .../mrbgems/cdata_extension_example/README.md | 3 + .../cdata_extension_example/mrbgem.rake | 23 + .../cdata_extension_example/src/example.c | 77 + .../cdata_extension_example/test/example.c | 7 + .../mrbgems/mruby-YOUR-bigint/TODO-HINT.md | 39 + .../mrbgems/mruby-YOUR-bigint/core/bigint.c | 70 + .../mrbgems/mruby-YOUR-bigint/mrbgem.rake | 12 + .../mrbgems/ruby_extension_example/README.md | 3 +- mruby/include/mrbconf.h | 11 + mruby/include/mruby.h | 97 +- mruby/include/mruby/array.h | 3 - mruby/include/mruby/boxing_word.h | 4 +- mruby/include/mruby/class.h | 11 - mruby/include/mruby/compile.h | 6 +- mruby/include/mruby/debug.h | 7 +- mruby/include/mruby/dump.h | 8 +- mruby/include/mruby/error.h | 51 +- mruby/include/mruby/gc.h | 6 +- mruby/include/mruby/hash.h | 6 - mruby/include/mruby/internal.h | 208 + mruby/include/mruby/irep.h | 33 +- mruby/include/mruby/numeric.h | 15 +- mruby/include/mruby/object.h | 4 + mruby/include/mruby/ops.h | 4 +- mruby/include/mruby/proc.h | 88 +- mruby/include/mruby/range.h | 2 - mruby/include/mruby/string.h | 27 +- mruby/include/mruby/throw.h | 13 +- mruby/include/mruby/value.h | 43 +- mruby/include/mruby/variable.h | 23 - mruby/include/mruby/version.h | 10 +- mruby/lib/mruby/build.rb | 12 +- mruby/lib/mruby/build/command.rb | 6 +- mruby/lib/mruby/build/load_gems.rb | 395 +- mruby/lib/mruby/doc.rb | 50 + mruby/lib/mruby/gem.rb | 4 +- mruby/lib/mruby/presym.rb | 2 +- mruby/mrbgems/math.gembox | 4 + mruby/mrbgems/mruby-array-ext/mrblib/array.rb | 16 +- mruby/mrbgems/mruby-array-ext/src/array.c | 46 +- mruby/mrbgems/mruby-bigint/README-fgmp.md | 154 + mruby/mrbgems/mruby-bigint/README.md | 7 + mruby/mrbgems/mruby-bigint/core/bigint.c | 1506 +++ mruby/mrbgems/mruby-bigint/core/bigint.h | 63 + mruby/mrbgems/mruby-bigint/mrbgem.rake | 10 + mruby/mrbgems/mruby-bigint/test/bigint.rb | 23 + mruby/mrbgems/mruby-bin-config/mruby-config | 0 .../mruby-bin-debugger/tools/mrdb/apibreak.c | 7 +- .../mruby-bin-debugger/tools/mrdb/mrdb.c | 1 + mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb | 6 + .../mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 11 +- .../mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c | 40 +- .../mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c | 74 + .../mruby-bin-mruby/tools/mruby/mruby.c | 23 +- .../tools/mruby-strip/mruby-strip.c | 5 +- .../mruby-binding-core/src/binding-core.c | 2 +- mruby/mrbgems/mruby-binding/src/binding.c | 7 +- mruby/mrbgems/mruby-binding/test/binding.c | 3 +- mruby/mrbgems/mruby-class-ext/src/class.c | 85 + mruby/mrbgems/mruby-class-ext/test/class.rb | 29 + mruby/mrbgems/mruby-cmath/mrbgem.rake | 2 +- mruby/mrbgems/mruby-cmath/test/cmath.rb | 2 +- .../mrbgems/mruby-compar-ext/mrblib/compar.rb | 76 +- mruby/mrbgems/mruby-compiler/core/codegen.c | 634 +- mruby/mrbgems/mruby-compiler/core/parse.y | 357 +- mruby/mrbgems/mruby-compiler/core/y.tab.c | 9931 +++++++++-------- mruby/mrbgems/mruby-complex/mrblib/complex.rb | 6 + mruby/mrbgems/mruby-complex/src/complex.c | 137 +- mruby/mrbgems/mruby-data/mrbgem.rake | 5 + mruby/mrbgems/mruby-data/src/data.c | 462 + mruby/mrbgems/mruby-data/test/data.rb | 76 + mruby/mrbgems/mruby-dir/README.md | 53 + mruby/mrbgems/mruby-dir/mrbgem.rake | 4 + mruby/mrbgems/mruby-dir/mrblib/dir.rb | 68 + mruby/mrbgems/mruby-dir/src/Win/dirent.c | 154 + mruby/mrbgems/mruby-dir/src/dir.c | 321 + mruby/mrbgems/mruby-dir/test/dir.rb | 137 + mruby/mrbgems/mruby-dir/test/dirtest.c | 142 + mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb | 42 +- .../mruby-enumerator/mrblib/enumerator.rb | 16 +- mruby/mrbgems/mruby-errno/README.md | 25 + mruby/mrbgems/mruby-errno/mrbgem.rake | 5 + mruby/mrbgems/mruby-errno/mrblib/errno.rb | 15 + mruby/mrbgems/mruby-errno/src/errno.c | 324 + mruby/mrbgems/mruby-errno/src/gen.rb | 18 + .../mrbgems/mruby-errno/src/known_errors.def | 156 + .../mruby-errno/src/known_errors_def.cstub | 780 ++ mruby/mrbgems/mruby-errno/test/errno.rb | 58 + mruby/mrbgems/mruby-error/src/exception.c | 2 +- mruby/mrbgems/mruby-eval/src/eval.c | 19 +- mruby/mrbgems/mruby-exit/src/mruby-exit.c | 72 +- mruby/mrbgems/mruby-fiber/src/fiber.c | 71 +- mruby/mrbgems/mruby-fiber/test/fiber.rb | 40 +- mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb | 42 +- mruby/mrbgems/mruby-hash-ext/src/hash-ext.c | 1 + mruby/mrbgems/mruby-hash-ext/test/hash.rb | 5 +- mruby/mrbgems/mruby-io/README.md | 264 +- mruby/mrbgems/mruby-io/include/mruby/ext/io.h | 16 +- mruby/mrbgems/mruby-io/mrbgem.rake | 2 - mruby/mrbgems/mruby-io/mrblib/io.rb | 200 +- mruby/mrbgems/mruby-io/src/file.c | 4 +- mruby/mrbgems/mruby-io/src/io.c | 958 +- mruby/mrbgems/mruby-io/test/file.rb | 2 +- mruby/mrbgems/mruby-io/test/io.rb | 39 +- mruby/mrbgems/mruby-kernel-ext/src/kernel.c | 7 +- mruby/mrbgems/mruby-math/src/math.c | 9 +- mruby/mrbgems/mruby-metaprog/src/metaprog.c | 38 +- mruby/mrbgems/mruby-metaprog/test/metaprog.rb | 8 +- mruby/mrbgems/mruby-method/README.md | 46 +- mruby/mrbgems/mruby-method/src/method.c | 65 +- mruby/mrbgems/mruby-method/test/method.rb | 6 +- .../mruby-numeric-ext/mrblib/numeric_ext.rb | 78 + .../mruby-numeric-ext/src/numeric_ext.c | 231 +- .../mrbgems/mruby-numeric-ext/test/numeric.rb | 30 + .../mruby-objectspace/src/mruby_objectspace.c | 5 +- mruby/mrbgems/mruby-os-memsize/mrbgem.rake | 8 +- mruby/mrbgems/mruby-os-memsize/src/memsize.c | 24 +- mruby/mrbgems/mruby-pack/mrbgem.rake | 2 - mruby/mrbgems/mruby-pack/src/pack.c | 128 +- mruby/mrbgems/mruby-pack/test/pack.rb | 1 - mruby/mrbgems/mruby-print/mrblib/print.rb | 2 - mruby/mrbgems/mruby-print/src/print.c | 48 +- mruby/mrbgems/mruby-proc-binding/mrbgem.rake | 1 + mruby/mrbgems/mruby-proc-ext/src/proc.c | 44 +- mruby/mrbgems/mruby-proc-ext/test/proc.rb | 4 +- mruby/mrbgems/mruby-random/src/random.c | 71 +- mruby/mrbgems/mruby-random/test/random.rb | 22 +- mruby/mrbgems/mruby-range-ext/src/range.c | 85 +- mruby/mrbgems/mruby-range-ext/test/range.rb | 16 +- mruby/mrbgems/mruby-rational/mrbgem.rake | 2 +- mruby/mrbgems/mruby-rational/src/rational.c | 207 +- mruby/mrbgems/mruby-rational/test/rational.rb | 15 + mruby/mrbgems/mruby-set/LICENSE | 24 + mruby/mrbgems/mruby-set/README.md | 34 + mruby/mrbgems/mruby-set/mrbgem.rake | 7 + mruby/mrbgems/mruby-set/mrblib/set.rb | 329 + mruby/mrbgems/mruby-set/mruby-set.gem | 6 + mruby/mrbgems/mruby-set/test/set.rb | 632 ++ mruby/mrbgems/mruby-sleep/README.md | 4 +- mruby/mrbgems/mruby-sleep/src/sleep.c | 2 +- mruby/mrbgems/mruby-socket/README.md | 16 +- mruby/mrbgems/mruby-socket/mrbgem.rake | 1 - mruby/mrbgems/mruby-socket/src/const.cstub | 21 + mruby/mrbgems/mruby-socket/src/const.def | 7 + mruby/mrbgems/mruby-socket/src/socket.c | 26 +- mruby/mrbgems/mruby-sprintf/src/sprintf.c | 56 +- .../mrbgems/mruby-string-ext/mrblib/string.rb | 12 +- mruby/mrbgems/mruby-string-ext/src/string.c | 143 +- .../mrbgems/mruby-string-ext/test/numeric.rb | 2 - mruby/mrbgems/mruby-string-ext/test/string.rb | 15 +- mruby/mrbgems/mruby-struct/mrblib/struct.rb | 1 + mruby/mrbgems/mruby-struct/src/struct.c | 127 +- mruby/mrbgems/mruby-symbol-ext/src/symbol.c | 1 + mruby/mrbgems/mruby-symbol-ext/test/symbol.rb | 1 - .../mruby-test-inline-struct/test/inline.c | 14 +- mruby/mrbgems/mruby-test/README.md | 3 +- mruby/mrbgems/mruby-test/driver.c | 25 +- mruby/mrbgems/mruby-time/src/time.c | 30 +- mruby/mrbgems/mruby-time/test/time.rb | 4 - .../mruby-toplevel-ext/mrblib/toplevel.rb | 1 - mruby/mrbgems/stdlib-ext.gembox | 3 + mruby/mrbgems/stdlib-io.gembox | 6 + mruby/mrbgems/stdlib.gembox | 3 + mruby/mrblib/00class.rb | 6 +- mruby/mrblib/00kernel.rb | 35 + mruby/mrblib/10error.rb | 13 + mruby/mrblib/array.rb | 66 +- mruby/mrblib/compar.rb | 18 + mruby/mrblib/hash.rb | 68 +- mruby/mrblib/numeric.rb | 28 - mruby/mrblib/string.rb | 31 +- mruby/mruby-source.gemspec | 5 +- mruby/oss-fuzz/mruby_proto_fuzzer.cpp | 51 +- mruby/oss-fuzz/proto_to_ruby.cpp | 720 +- mruby/oss-fuzz/proto_to_ruby.h | 84 +- mruby/src/array.c | 121 +- mruby/src/backtrace.c | 105 +- mruby/src/cdump.c | 21 +- mruby/src/class.c | 394 +- mruby/src/codedump.c | 468 +- mruby/src/debug.c | 18 +- mruby/src/dump.c | 6 +- mruby/src/error.c | 110 +- mruby/src/etc.c | 38 +- mruby/src/fmt_fp.c | 14 +- mruby/src/gc.c | 127 +- mruby/src/hash.c | 34 +- mruby/src/kernel.c | 130 +- mruby/src/load.c | 45 +- mruby/src/numeric.c | 880 +- mruby/src/numops.c | 112 + mruby/src/object.c | 50 +- mruby/src/print.c | 11 - mruby/src/proc.c | 35 +- mruby/src/range.c | 12 +- mruby/src/{readflt.c => readfloat.c} | 67 +- mruby/src/readint.c | 20 +- mruby/src/readnum.c | 43 + mruby/src/state.c | 4 +- mruby/src/string.c | 516 +- mruby/src/symbol.c | 42 +- mruby/src/variable.c | 18 +- mruby/src/vm.c | 876 +- mruby/tasks/benchmark.rake | 14 +- mruby/tasks/doc.rake | 39 +- mruby/tasks/mrbgems.rake | 1 + mruby/tasks/toolchains/android.rake | 121 +- mruby/tasks/toolchains/gcc.rake | 6 +- mruby/test/assert.rb | 4 +- mruby/test/bintest.rb | 6 +- mruby/test/t/array.rb | 2 + mruby/test/t/bs_block.rb | 4 +- mruby/test/t/comparable.rb | 1 - mruby/test/t/hash.rb | 5 + mruby/test/t/integer.rb | 21 +- mruby/test/t/lang.rb | 2 +- mruby/test/t/module.rb | 12 +- mruby/test/t/string.rb | 5 +- mruby/test/t/syntax.rb | 4 +- 270 files changed, 19130 insertions(+), 10192 deletions(-) create mode 100644 mruby/doc/mruby3.2.md create mode 100644 mruby/examples/mrbgems/cdata_extension_example/README.md create mode 100644 mruby/examples/mrbgems/cdata_extension_example/mrbgem.rake create mode 100644 mruby/examples/mrbgems/cdata_extension_example/src/example.c create mode 100644 mruby/examples/mrbgems/cdata_extension_example/test/example.c create mode 100644 mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md create mode 100644 mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c create mode 100644 mruby/examples/mrbgems/mruby-YOUR-bigint/mrbgem.rake create mode 100644 mruby/include/mruby/internal.h create mode 100644 mruby/lib/mruby/doc.rb create mode 100644 mruby/mrbgems/mruby-bigint/README-fgmp.md create mode 100644 mruby/mrbgems/mruby-bigint/README.md create mode 100644 mruby/mrbgems/mruby-bigint/core/bigint.c create mode 100644 mruby/mrbgems/mruby-bigint/core/bigint.h create mode 100644 mruby/mrbgems/mruby-bigint/mrbgem.rake create mode 100644 mruby/mrbgems/mruby-bigint/test/bigint.rb mode change 100644 => 100755 mruby/mrbgems/mruby-bin-config/mruby-config create mode 100644 mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c create mode 100644 mruby/mrbgems/mruby-class-ext/test/class.rb create mode 100644 mruby/mrbgems/mruby-data/mrbgem.rake create mode 100644 mruby/mrbgems/mruby-data/src/data.c create mode 100644 mruby/mrbgems/mruby-data/test/data.rb create mode 100644 mruby/mrbgems/mruby-dir/README.md create mode 100644 mruby/mrbgems/mruby-dir/mrbgem.rake create mode 100644 mruby/mrbgems/mruby-dir/mrblib/dir.rb create mode 100644 mruby/mrbgems/mruby-dir/src/Win/dirent.c create mode 100644 mruby/mrbgems/mruby-dir/src/dir.c create mode 100644 mruby/mrbgems/mruby-dir/test/dir.rb create mode 100644 mruby/mrbgems/mruby-dir/test/dirtest.c create mode 100644 mruby/mrbgems/mruby-errno/README.md create mode 100644 mruby/mrbgems/mruby-errno/mrbgem.rake create mode 100644 mruby/mrbgems/mruby-errno/mrblib/errno.rb create mode 100644 mruby/mrbgems/mruby-errno/src/errno.c create mode 100755 mruby/mrbgems/mruby-errno/src/gen.rb create mode 100644 mruby/mrbgems/mruby-errno/src/known_errors.def create mode 100644 mruby/mrbgems/mruby-errno/src/known_errors_def.cstub create mode 100644 mruby/mrbgems/mruby-errno/test/errno.rb create mode 100644 mruby/mrbgems/mruby-set/LICENSE create mode 100644 mruby/mrbgems/mruby-set/README.md create mode 100644 mruby/mrbgems/mruby-set/mrbgem.rake create mode 100644 mruby/mrbgems/mruby-set/mrblib/set.rb create mode 100644 mruby/mrbgems/mruby-set/mruby-set.gem create mode 100644 mruby/mrbgems/mruby-set/test/set.rb create mode 100644 mruby/mrblib/00kernel.rb create mode 100644 mruby/src/numops.c rename mruby/src/{readflt.c => readfloat.c} (69%) create mode 100644 mruby/src/readnum.c diff --git a/mruby/.editorconfig b/mruby/.editorconfig index 70cc78f0..f966739f 100644 --- a/mruby/.editorconfig +++ b/mruby/.editorconfig @@ -29,9 +29,10 @@ indent_style = space trim_trailing_whitespace = true #max_line_length = 120 +# limitation to US-ASCII [*.bat] -charset = latin1 end_of_line = crlf +indent_style = space #max_line_length = 80 [*.{yaml,yml}] diff --git a/mruby/.git-blame-ignore-revs b/mruby/.git-blame-ignore-revs index 3dab080a..7d2ec818 100644 --- a/mruby/.git-blame-ignore-revs +++ b/mruby/.git-blame-ignore-revs @@ -2,3 +2,5 @@ 6fc5dc986a5ffc1a74c63ad0617ea1dcc10d3cdd # reformatted doc/opcode.md 61e8a540869c57ebddac53cf9d243db407d57fff +# reindent parse.y +650ffb9d8410e1ae2206890ef6e2a8643c600454 diff --git a/mruby/.github/linters/.markdown-lint.yml b/mruby/.github/linters/.markdown-lint.yml index a1023acb..5c6cbec4 100644 --- a/mruby/.github/linters/.markdown-lint.yml +++ b/mruby/.github/linters/.markdown-lint.yml @@ -4,9 +4,6 @@ # MD001 heading-increment/header-increment - Heading levels should only increment by one level at a time MD001: false -# MD010 no-hard-tabs - Hard tabs -MD010: false - # MD013 line-length - Line length MD013: false diff --git a/mruby/.github/workflows/build.yml b/mruby/.github/workflows/build.yml index bf963ff0..ec82c0de 100644 --- a/mruby/.github/workflows/build.yml +++ b/mruby/.github/workflows/build.yml @@ -2,90 +2,32 @@ name: Build & Test on: [push, pull_request] -jobs: - Ubuntu-1804-gcc: - runs-on: ubuntu-18.04 - timeout-minutes: 10 - env: - MRUBY_CONFIG: ci/gcc-clang - CC: gcc - steps: - - uses: actions/checkout@v2.4.0 - - name: Ruby version - run: ruby -v - - name: Compiler version - run: ${{ env.CC }} --version - - name: Build and test - run: rake -m test:build && rake test:run - - Ubuntu-1804-clang: - runs-on: ubuntu-18.04 - timeout-minutes: 10 - env: - MRUBY_CONFIG: ci/gcc-clang - CC: clang - steps: - - uses: actions/checkout@v2.4.0 - - name: Ruby version - run: ruby -v - - name: Compiler version - run: ${{ env.CC }} --version - - name: Build and test - run: rake -m test:build && rake test:run - - Ubuntu-2004-gcc: - runs-on: ubuntu-20.04 - timeout-minutes: 10 - env: - MRUBY_CONFIG: ci/gcc-clang - CC: gcc - steps: - - uses: actions/checkout@v2.4.0 - - name: Ruby version - run: ruby -v - - name: Compiler version - run: ${{ env.CC }} --version - - name: Build and test - run: rake -m test:build && rake test:run - - Ubuntu-2004-clang: - runs-on: ubuntu-20.04 - timeout-minutes: 10 - env: - MRUBY_CONFIG: ci/gcc-clang - CC: clang - steps: - - uses: actions/checkout@v2.4.0 - - name: Ruby version - run: ruby -v - - name: Compiler version - run: ${{ env.CC }} --version - - name: Build and test - run: rake -m test:build && rake test:run +permissions: + contents: read - macOS: - runs-on: macos-latest - timeout-minutes: 10 - env: - MRUBY_CONFIG: ci/gcc-clang - CC: clang - steps: - - uses: actions/checkout@v2.4.0 - - name: Ruby version - run: ruby -v - - name: Compiler version - run: ${{ env.CC }} --version - - name: Build and test - run: rake -m test:build && rake test:run - - Windows-MinGW: - runs-on: windows-latest +jobs: + GCC-CLANG: + name: "${{ matrix.os }}-${{ matrix.altname || matrix.cc }}" + runs-on: ${{ matrix.os }} timeout-minutes: 10 + strategy: + fail-fast: false + max-parallel: 8 + matrix: + include: + - {os: ubuntu-22.04, cc: gcc, cxx: g++} + - {os: ubuntu-22.04, cc: clang, cxx: clang++} + - {os: ubuntu-20.04, cc: gcc, cxx: g++} + - {os: ubuntu-20.04, cc: clang, cxx: clang++} + - {os: macos-latest, cc: clang, cxx: clang++} + - {os: windows-latest, cc: gcc, cxx: g++, altname: "mingw-gcc"} env: MRUBY_CONFIG: ci/gcc-clang - CC: gcc + CC: ${{ matrix.cc }} + CXX: ${{ matrix.cxx }} + LD: ${{ matrix.cc }} steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Compiler version @@ -93,63 +35,17 @@ jobs: - name: Build and test run: rake -m test:build && rake test:run - Windows-Cygwin: - runs-on: windows-latest - timeout-minutes: 15 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - MRUBY_CONFIG: ci/gcc-clang - CC: gcc - installer-path: '%TMP%\cygwin-setup.exe' - cygwin-root: C:\cygwin - package-dir: C:\cygwin-package - cache-version: v1 - steps: - - uses: actions/checkout@v2.4.0 - - uses: actions/cache@v2.1.7 - with: - path: ${{ env.package-dir }} - key: ${{ runner.os }}-cygwin-${{ env.cache-version }} - - name: Download Cygwin installer - shell: cmd - run: > - bitsadmin /transfer download /priority foreground - https://cygwin.com/setup-x86_64.exe ${{ env.installer-path }} - - name: Install Cygwin - shell: cmd - run: > - ${{ env.installer-path }} - --quiet-mode --no-shortcuts --no-startmenu --no-desktop --no-admin - --only-site --site http://mirrors.kernel.org/sourceware/cygwin/ - --root ${{ env.cygwin-root }} - --local-package-dir ${{ env.package-dir }} - --packages gcc-core,gcc-g++,ruby - - name: Set PATH for Cygwin - run: | - echo '::set-env name=PATH::${{ env.cygwin-root }}\bin;${{ env.cygwin-root }}\usr\bin' - - name: Ruby version - shell: cmd - run: ruby -v - - name: Compiler version - run: ${{ env.CC }} --version - - name: Build and test - shell: cmd - run: ruby /usr/bin/rake -m test:build && ruby /usr/bin/rake test:run - - name: Set PATH for cache archiving (tar) - # set Windows path so that Cygwin tar is not used for cache archiving - run: echo '::set-env name=PATH::C:\windows\System32' - Windows-VC: - runs-on: windows-latest + runs-on: windows-2022 timeout-minutes: 10 env: MRUBY_CONFIG: ci/msvc steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Ruby version run: ruby -v - name: Build and test shell: cmd run: | - call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" rake -m test:build && rake test:run diff --git a/mruby/.github/workflows/codeql-analysis.yml b/mruby/.github/workflows/codeql-analysis.yml index 184ca54c..10117d54 100644 --- a/mruby/.github/workflows/codeql-analysis.yml +++ b/mruby/.github/workflows/codeql-analysis.yml @@ -1,19 +1,26 @@ -name: "Code scanning - action" +name: Code scanning - action on: push: + branches-ignore: + - dependabot/** pull_request: schedule: - cron: '0 19 * * 4' +permissions: + contents: read + jobs: CodeQL-Build: - + permissions: + actions: read # for github/codeql-action/init to get workflow details + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/autobuild to send a status report runs-on: ubuntu-latest - steps: - name: Checkout repository - uses: actions/checkout@v2.4.0 + uses: actions/checkout@v3 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -21,7 +28,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java @@ -29,7 +36,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -43,4 +50,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/mruby/.github/workflows/lint.yml b/mruby/.github/workflows/lint.yml index 880b7ab6..c31b7411 100644 --- a/mruby/.github/workflows/lint.yml +++ b/mruby/.github/workflows/lint.yml @@ -2,29 +2,33 @@ name: Lint on: [pull_request] +permissions: + contents: read + jobs: misspell: name: Check spelling with misspell runs-on: ubuntu-latest steps: - name: Check Out - uses: actions/checkout@v2.4.0 + uses: actions/checkout@v3 - name: Install run: wget -O - -q https://git.io/misspell | sh -s -- -b . - - name: Misspell + - name: Run misspell run: git ls-files --empty-directory | xargs ./misspell -error pre-commit: name: Run pre-commit runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.4.0 - - name: Check merge conflict + - name: Check Out + uses: actions/checkout@v3 + - name: Install run: | 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@v2.1.7 + - uses: actions/cache@v3 with: path: ~/.cache/pre-commit key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} diff --git a/mruby/.github/workflows/oss-fuzz.yml b/mruby/.github/workflows/oss-fuzz.yml index da3cc289..414c750e 100644 --- a/mruby/.github/workflows/oss-fuzz.yml +++ b/mruby/.github/workflows/oss-fuzz.yml @@ -1,5 +1,8 @@ name: CIFuzz on: [pull_request] +permissions: + contents: read + jobs: Fuzzing: runs-on: ubuntu-latest @@ -16,7 +19,7 @@ jobs: fuzz-seconds: 600 dry-run: false - name: Upload Crash - uses: actions/upload-artifact@v2.3.1 + uses: actions/upload-artifact@v3 if: failure() with: name: artifacts diff --git a/mruby/.github/workflows/super-linter.yml b/mruby/.github/workflows/super-linter.yml index f7a7a6fb..538ccf07 100644 --- a/mruby/.github/workflows/super-linter.yml +++ b/mruby/.github/workflows/super-linter.yml @@ -1,23 +1,31 @@ -name: Super Linter +name: Super-Linter -on: - push: - branches-ignore: [master] - # Remove the line above to run when pushing to master - pull_request: - branches: [master] +on: [pull_request] + +permissions: + contents: read jobs: build: + permissions: + contents: read # for actions/checkout to fetch code + statuses: write # for github/super-linter/slim to mark status of each linter run name: Lint Code Base runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.4.0 - - uses: github/super-linter@v4.8.5 + - name: Checkout Code + uses: actions/checkout@v3 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + - name: Lint Code Base + uses: github/super-linter/slim@v4.10.1 env: ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true # VALIDATE_BASH_EXEC: true # VALIDATE_EDITORCONFIG: true # VALIDATE_SHELL_SHFMT: true + DEFAULT_BRANCH: master GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VALIDATE_ALL_CODEBASE: false diff --git a/mruby/.pre-commit-config.yaml b/mruby/.pre-commit-config.yaml index 266f88c8..4c7bc52e 100644 --- a/mruby/.pre-commit-config.yaml +++ b/mruby/.pre-commit-config.yaml @@ -3,20 +3,21 @@ default_stages: [commit, push] default_language_version: # force all unspecified Python hooks to run python3 python: python3 -minimum_pre_commit_version: "1.20.0" +minimum_pre_commit_version: '2.18.1' repos: - repo: meta hooks: - id: identity - id: check-hooks-apply - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.4.0 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-shebang-scripts-are-executable - id: check-vcs-permalinks - id: check-yaml - id: detect-private-key @@ -26,20 +27,29 @@ repos: - id: fix-byte-order-marker - id: mixed-line-ending - id: trailing-whitespace - # - repo: git://github.com/Lucas-C/pre-commit-hooks - # rev: v1.1.9 - # hooks: - # - id: forbid-tabs - # - id: remove-tabs + - repo: https://github.com/Lucas-C/pre-commit-hooks + rev: v1.3.1 + hooks: + - id: forbid-tabs + exclude: Makefile$|Makefile\..+$|makefile$|\.mk$ + - id: remove-tabs + args: [--whitespaces-count, '2'] + exclude: Makefile$|Makefile\..+$|makefile$|\.mk$ - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.2.2 hooks: - id: codespell name: Run codespell description: Check spelling with codespell entry: codespell --ignore-words=codespell.txt + - repo: https://github.com/jumanjihouse/pre-commit-hooks + rev: 3.0.0 + hooks: + - id: script-must-not-have-extension + name: Local policy is to exclude extension from all shell files + types: [shell] - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.30.0 + rev: v0.33.0 hooks: - id: markdownlint name: Run markdownlint @@ -48,7 +58,7 @@ repos: types: [markdown] files: \.(md|mdown|markdown)$ - repo: https://github.com/adrienverge/yamllint - rev: v1.26.3 + rev: v1.28.0 hooks: - id: yamllint name: Run yamllint diff --git a/mruby/.yardopts b/mruby/.yardopts index 4499bf51..f87c2652 100644 --- a/mruby/.yardopts +++ b/mruby/.yardopts @@ -11,7 +11,13 @@ mrbgems/*/src/**/*.c mrbgems/*/mrblib/**/*.rb mrbgems/*/include/**/*.h - -AUTHORS -LICENSE CONTRIBUTING.md +SECURITY.md +TODO.md +doc/*.md doc/guides/*.md +doc/internal/*.md +AUTHORS +LEGAL +LICENSE +NEWS diff --git a/mruby/AUTHORS b/mruby/AUTHORS index 404cb2f9..fce97efc 100644 --- a/mruby/AUTHORS +++ b/mruby/AUTHORS @@ -1,48 +1,49 @@ # Authors of mruby (mruby developers) -## The List of Contributors sorted by number of commits (as of 2022-01-10 69b1667) +## The List of Contributors sorted by number of commits (as of 2022-01-08 4462e3d) - 7956 Yukihiro "Matz" Matsumoto (@matz)* + 8860 Yukihiro "Matz" Matsumoto (@matz)* 586 KOBAYASHI Shuji (@shuujii) - 376 Daniel Bovensiepen (@bovi) + 441 dearblue (@dearblue)* + 378 Daniel Bovensiepen (@bovi)* 346 Takeshi Watanabe (@take-cheeze)* - 342 dearblue (@dearblue)* 334 Masaki Muranaka (@monaka) - 298 Tomoyuki Sahara (@tsahara)* + 328 Tomoyuki Sahara (@tsahara)* 234 Jun Hiroe (@suzukaze) - 219 Cremno (@cremno)* - 208 Yuki Kurihara (@ksss)+ - 148 Yasuhiro Matsumoto (@mattn)* + 220 Cremno (@cremno)* + 209 Yuki Kurihara (@ksss)+ + 151 Yasuhiro Matsumoto (@mattn)* 113 Carson McDonald (@carsonmcdonald) + 113 John Bampton (@jbampton) 103 Tomasz Dąbrowski (@dabroz)* + 84 Akira Yumiyama (@akiray03)* 84 skandhas (@skandhas) 80 Masamitsu MURASE (@masamitsu-murase) 74 Yuichiro MASUI (@masuidrive) + 73 Hiroshi Mimaki (@mimaki)* 71 Tatsuhiko Kubo (@cubicdaiya)* - 68 Hiroshi Mimaki (@mimaki)* - 63 Akira Yumiyama (@akiray03)* - 62 Paolo Bosetti (@pbosetti)* + 65 Yuichiro Kaneko (@yui-knk)+ + 64 Paolo Bosetti (@pbosetti)* 59 Kurebayashi, Takahiro (@crimsonwoods)* 56 h2so5 (@h2so5) 52 Ralph Desir (@Mav7)* - 49 John Bampton (@jbampton) 45 Rory O'Connell (@RoryO)* - 43 Yuichiro Kaneko (@yui-knk)+ 42 fleuria (@flaneur2020) 40 Christopher Aue (@christopheraue) 40 Seba Gamboa (@sagmor) 38 Koji Yoshioka (@kyab)*+ 38 Kouhei Sutou (@kou)* + 32 Masayoshi Takahashi (@takahashim)+ 31 MATSUMOTO Ryosuke (@matsumotory)* 30 Nobuyoshi Nakada (@nobu) - 28 Masayoshi Takahashi (@takahashim)+ - 24 Julian Aron Prenner (@furunkel)* + 26 Julian Aron Prenner (@furunkel)* 24 Ryan Scott (@ryan-scott-dev)* 22 Clayton Smith (@clayton-shopify) + 22 Uchio Kondo (@udzura)* 22 Zachary Scott (@zzak)* 22 mirichi (@mirichi) 21 Jared Breeden (@jbreeden)* - 20 Uchio Kondo (@udzura)* + 21 Ryan Lopopolo (@lopopolo) 19 Bouke van der Bijl (@bouk) 19 Felix Jones (@felixjones)* 19 Hidetaka Takano (@TJ-Hidetaka-Takano) @@ -50,13 +51,13 @@ 18 Corey Powell (@IceDragon200) 18 Jon Maken (@jonforums)+ 18 Mitchell Blank Jr (@mitchblank)* - 17 Ryan Lopopolo (@lopopolo) 16 bggd (@bggd) 16 kano4 (@kano4) 14 Blaž Hrastnik (@archseer)* 14 Jose Narvaez (@goyox86) 14 Kazuki Tsujimoto (@k-tsj) 14 Tadashi FUKUZAWA (@FUKUZAWA-Tadashi)+ + 14 fn ⌃ ⌥ (@FnControlOption) 13 Patrick Hogan (@pbhogan) 12 Akira Kuroda (@akuroda) 12 Kouki Ooyatsu (kaishuu0123)* @@ -66,10 +67,10 @@ 12 Ukrainskiy Sergey (@ukrainskiysergey) 12 Xuejie "Rafael" Xiao (@xxuejie)* 11 Julien Ammous (@schmurfy) + 11 Kazuho Oku (@kazuho) 11 Seeker (@SeekingMeaning) 11 YAMAMOTO Masaya (pandax381) 11 takkaw (@takkaw) - 10 Kazuho Oku (@kazuho) 10 Miura Hideki (@miura1729) 10 Narihiro Nakamura (@authorNari) 10 Ray Chason (@chasonr)* @@ -95,18 +96,22 @@ 6 Kenji Okimoto (@okkez)+ 6 Selman ULUG (@selman) 6 Yusuke Endoh (@mame)* + 5 Chris Reuter (@suetanvil) 5 Davide D'Agostino (@DAddYE) 5 Eric Hodel (@drbrain) 5 Hendrik (@Asmod4n) 5 Ichito Nagata (@i110) 5 Keita Obo (@ktaobo)* 5 Max Anselm (@silverhammermba) + 5 Rodrigo Malizia (@rmalizia44)+ 5 SiZiOUS (@sizious) 5 Syohei YOSHIDA (@syohex) 5 TOMITA Masahiro (@tmtm) 5 Yurie Yamane (@yurie)+ 5 dreamedge (@dreamedge) + 5 masahino (@masahino) 5 nkshigeru (@nkshigeru) + 5 xuejianqing (@joans321) 4 Dante Catalfamo (@dantecatalfamo) 4 Goro Kikuchi (@gorogit) 4 Herwin Weststrate (@herwinw) @@ -121,26 +126,26 @@ 4 Yuhei Okazaki (@Yuuhei-Okazaki)* 4 Yuji Yamano (@yyamano) 4 kurodash (@kurodash)* - 4 masahino (@masahino) 4 wanabe (@wanabe)* - 4 xuejianqing (@joans321) 3 Anton Davydov (@davydovanton) 3 Carlo Prelz (@asfluido)* 3 David Turnbull (@AE9RB) 3 Franck Verrot (@franckverrot) + 3 HASUMI Hitoshi (@hasumikin) 3 Horimoto Yasuhiro (@komainu8) 3 J. Mutua (@katmutua)+ 3 Jan Berdajs (@mrbrdo) + 3 Jonas Minnberg (@sasq64) 3 Joseph McCullough (@joequery) 3 Mark McCurry (@fundamental) 3 Nobuhiro Iwamatsu (@iwamatsu) 3 Per Lundberg (@perlun)* 3 Rob Fors (@robfors)* - 3 Rodrigo Malizia (@rmalizia44)+ 3 Sebastián Katzer (@katzer)* 3 Shouji Kuboyama (@Shokuji)* 3 Shuta Kimura (@kimushu)+ 3 TERAJIMA, Motoyuki (@trmmy) + 3 Taichi AOKI (@aoki1980taichi) 3 Takashi Kokubun (@k0kubun) 3 Tatsuhiro Tsujikawa (@tatsuhiro-t) 3 Thiago Scalone (@scalone) @@ -148,6 +153,7 @@ 3 William Light (@wrl) 3 bamchoh (@bamchoh) 3 sasaki takeru (@takeru) + 3 windwiny (@windwiny) 2 Akira Moroo (@retrage) 2 Artur K (@nemerle) 2 Christian Mauceri (@mauceri) @@ -158,7 +164,6 @@ 2 Francois Chagnon (@EiNSTeiN-)* 2 Gilad Zohari (@gzohari) 2 Go Saito (@govm) - 2 HASUMI Hitoshi (@hasumikin) 2 Hirohito Higashi (@HirohitoHigashi) 2 Hiroyuki Iwatsuki (@iwadon) 2 Huei-Horng Yo (@hiroshiyui) @@ -188,15 +193,14 @@ 2 Yutaka HARA (@yhara)*+ 2 Zhang Xiaohui (@hifoolno) 2 icm7216 (@icm7216) - 2 windwiny (@windwiny) 1 A-Sat (@asatou)+ 1 Abinoam Praxedes Marques Junior (@abinoam) 1 Alex Wang (@nanamiwang)+ 1 Andrew Nordman (@cadwallion) + 1 Ashish Kurmi (@boahc077) 1 Atsushi Morimoto (@mynz) 1 Ben A Morgan (@BenMorganIO) 1 Benoit Daloze (@eregon) - 1 Chris Reuter (@suetanvil) 1 Daehyub Kim (@lateau) 1 Daniel Varga (@vargad) 1 Edgar Boda-Majer (@eboda) @@ -205,6 +209,8 @@ 1 Francis Bogsanyi (@fbogsany) 1 Guo Xiao (@guoxiao) 1 Gwen Boatrite (@boatrit) + 1 Gwendolyn Boatrite (@boatrite) + 1 HARADA Makoto (@haramako) 1 HAYASHI Kentaro (@kenhys) 1 Hiroki Mori (@yamori813)+ 1 Hiromasa Ishii (@Hir0)+ @@ -225,6 +231,7 @@ 1 Kazuhiro NISHIYAMA (@znz) 1 Kei Sawada (@remore) 1 Kim H Madsen (@kimhmadsen) + 1 Koichi ITO (@koic) 1 Konstantin Haase (@rkh) 1 Leo Neat (@Leo-Neat) 1 Lian Cheng (@liancheng) @@ -253,13 +260,17 @@ 1 Robert Rowe (@CaptainJet) 1 Ryan Scott Lewis (@RyanScottLewis) 1 Ryo Okubo (@syucream) + 1 SAkira a.k.a. Akira Suzuki (@sakisakira) 1 Santiago Rodriguez (@sanrodari) 1 Satoh, Hiroh (@cho45)+ 1 Sayed Abdelhaleem (@visualsayed) + 1 Sergey Ukrainskiy (@ukrainskiysergey) 1 Shugo Maeda (@shugo) 1 Sorah Fukumori (@sorah) + 1 Stephen Jothen (@sjothen) 1 Stuart Hinson (@stuarth) 1 Takuma Kume (@takumakume)+ + 1 Takuya ASADA (@syuu1228) 1 Thomas Schmidt (@digitaltom) 1 Timo Schilling (@timoschilling) 1 Tom Black (@blacktm) diff --git a/mruby/CONTRIBUTING.md b/mruby/CONTRIBUTING.md index 516be1e3..61d67312 100644 --- a/mruby/CONTRIBUTING.md +++ b/mruby/CONTRIBUTING.md @@ -8,14 +8,14 @@ Contributors agree to license their contribution(s) under MIT license. To make it easy to review and understand your change please keep the following 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`) -* 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 -* Explain your change (i.e. with a link to the issue you are fixing) -* Use mrbgem to provide non ISO features (classes, modules and methods) unless +- 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`) +- 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 +- Explain your change (i.e. with a link to the issue you are fixing) +- 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 @@ -33,9 +33,22 @@ To run a single hook use `pre-commit run --all-files ` To update use `pre-commit autoupdate` -* [Quick start](https://pre-commit.com/#quick-start) -* [Usage](https://pre-commit.com/#usage) -* [pre-commit-autoupdate](https://pre-commit.com/#pre-commit-autoupdate) +Sometimes you might need to skip one or more hooks which can be done with the `SKIP` environment variable. + +`$ SKIP=yamllint git commit -m "foo"` + +For convenience, we have added `pre-commit run --all-files` and `pre-commit autoupdate` +to both the Makefile and the Rakefile. Run them with: + +- `make check` or `rake check` +- `make checkupdate` or `rake checkupdate` + +### pre-commit quick links + +- [Quick start](https://pre-commit.com/#quick-start) +- [Usage](https://pre-commit.com/#usage) +- [pre-commit autoupdate](https://pre-commit.com/#pre-commit-autoupdate) +- [Temporarily disabling hooks](https://pre-commit.com/#temporarily-disabling-hooks) ## Spell Checking @@ -50,8 +63,8 @@ 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) +- `-i` string: ignore the following corrections, comma separated +- `-w`: Overwrite file with corrections (default is just to display) ## Coding conventions @@ -101,3 +114,16 @@ language itself. Please note the following hints for your Ruby code: mruby is currently targeting to execute Ruby code which complies to ISO/IEC 30170:2012 (), unless there's a clear reason, e.g. the latest Ruby has changed behavior from ISO. + +## Building documentation + +### mruby API + +- [YARD](https://yardoc.org/) - YARD is a documentation generation tool for the Ruby programming language +- [yard-mruby](https://rubygems.org/gems/yard-mruby) - Document MRuby sources with YARD +- [yard-coderay](https://rubygems.org/gems/yard-coderay) - Adds coderay syntax highlighting to YARD docs + +### C API + +- [Doxygen](https://www.doxygen.nl/) - Generate documentation from source code +- [Graphviz](https://graphviz.org/) - Graphviz is open source graph visualization software diff --git a/mruby/Doxyfile b/mruby/Doxyfile index 0dd49db4..ece327c8 100644 --- a/mruby/Doxyfile +++ b/mruby/Doxyfile @@ -16,13 +16,20 @@ OUTPUT_DIRECTORY = doc/capi USE_MDFILE_AS_MAINPAGE = README.md -INPUT = README.md \ +INPUT = CONTRIBUTING.md \ + README.md \ + SECURITY.md \ + TODO.md \ src \ include \ include/mruby \ mrblib \ doc \ - doc/guides + doc/guides \ + doc/internal \ + LEGAL \ + LICENSE \ + NEWS # Red for Ruby HTML_COLORSTYLE_HUE = 359 @@ -275,7 +282,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = no_extension=md # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable diff --git a/mruby/LEGAL b/mruby/LEGAL index ecddf6b9..24c8dc67 100644 --- a/mruby/LEGAL +++ b/mruby/LEGAL @@ -3,3 +3,38 @@ LEGAL NOTICE INFORMATION All the files in this distribution are covered under the MIT license (see the file LICENSE) except some files mentioned below: + +- src/readfloat.c: public domain by Yasuhiro Matsumoto (@mattn) +- src/fmt_fp.c: public domain by Dave Hylands (@dhylands) +- mrbgems/mruby-dir/src/Win/dirent.c: MIT-like license by Kevlin Henney + +[src/readfloat.c] + +strtod implementation. +author: Yasuhiro Matsumoto (@mattn) +license: public domain + +The original code can be found in https://github.com/mattn/strtod + +[src/fmt_fp.c] + +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. + +Dave Hylands + +The original code can be found in https://github.com/dhylands/format-float + +[mrbgems/mruby-dir/src/Win/dirent.c] used only for Windows platform + +Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose is hereby granted without fee, provided +that this copyright and permissions notice appear in all copies and +derivatives. + +This software is supplied "as is" without express or implied warranty. + +But that said, if there are any problems please get in touch. diff --git a/mruby/LICENSE b/mruby/LICENSE index 985dd366..7461282a 100644 --- a/mruby/LICENSE +++ b/mruby/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010-2021 mruby developers +Copyright (c) 2010-2023 mruby developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/mruby/Makefile b/mruby/Makefile index 6e20d9db..4e70a8e6 100644 --- a/mruby/Makefile +++ b/mruby/Makefile @@ -13,3 +13,11 @@ test : all clean : $(RAKE) clean .PHONY : clean + +check : + pre-commit run --all-files +.PHONY : check + +checkupdate : + pre-commit autoupdate +.PHONY : checkupdate diff --git a/mruby/NEWS b/mruby/NEWS index 8e8c1e41..34cf8452 100644 --- a/mruby/NEWS +++ b/mruby/NEWS @@ -1,11 +1,64 @@ -* NEWS +NEWS +---- -This document is a list of user visible feature changes made between -releases except for bug fixes. +# User visible changes in `mruby3.2` -Note that each entry is kept so brief that no reason behind or -reference information is supplied with. For a full list of changes -with all sufficient information, see the ChangeLog file. +# The language +- Now `a::B = c` should evaluate `a` then `c`. +- Anonymous arguments `*`, `**`, `&` can be passed for forwarding. +- Multi-precision integer is available now via `mruby-bigint` gem. -** Information about first release v1.0.0 +# mruby VM and bytecode + +- `OP_ARYDUP` was renamed to `OP_ARYSPLAT`. The instruction name + was changed but instruction number and basic behavior have not + changed (except that `ARYDUP nil` makes `[]`). + +# Tools + +## `mruby` + +- `-b` only specifies the script is the binary. The files loaded by `-r` are not affected by the option. +- `mruby` now loads complied binary if the suffix is `.mrb`. + +## `mrbc` + +- Add `--no-optimize` option to disable optimization. + +# mrbgems + +## mruby-class-ext + +- Add `Class#subclasses` method. +- Add `Module#undefined_instance_methods` method. + +## New bundled gems + +- mruby-errno from [https://github.com/iij/mruby-errno.git] +- mruby-set from [https://github.com/yui-knk/mruby-set.git] +- mruby-dir from [https://github.com/iij/mruby-dir.git] + +# CVEs + +Following CVEs are fixed. + +- [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080) +- [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240) +- [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326) +- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) +- [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481) +- [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525) +- [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570) +- [CVE-2022-0614](https://nvd.nist.gov/vuln/detail/CVE-2022-0614) +- [CVE-2022-0623](https://nvd.nist.gov/vuln/detail/CVE-2022-0623) +- [CVE-2022-0630](https://nvd.nist.gov/vuln/detail/CVE-2022-0630) +- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) +- [CVE-2022-0632](https://nvd.nist.gov/vuln/detail/CVE-2022-0632) +- [CVE-2022-0717](https://nvd.nist.gov/vuln/detail/CVE-2022-0717) +- [CVE-2022-0890](https://nvd.nist.gov/vuln/detail/CVE-2022-0890) +- [CVE-2022-1106](https://nvd.nist.gov/vuln/detail/CVE-2022-1106) +- [CVE-2022-1212](https://nvd.nist.gov/vuln/detail/CVE-2022-1212) +- [CVE-2022-1276](https://nvd.nist.gov/vuln/detail/CVE-2022-1276) +- [CVE-2022-1286](https://nvd.nist.gov/vuln/detail/CVE-2022-1286) +- [CVE-2022-1934](https://nvd.nist.gov/vuln/detail/CVE-2022-1934) diff --git a/mruby/README.md b/mruby/README.md index 271551df..cf310e01 100644 --- a/mruby/README.md +++ b/mruby/README.md @@ -1,17 +1,17 @@ # mruby -[![Build Status][build-status-img]][travis-ci] [![GitHub Super-Linter](https://github.com/mruby/mruby/workflows/Lint%20Code%20Base/badge.svg)](https://github.com/marketplace/actions/super-linter) ## What is mruby mruby is the lightweight implementation of the Ruby language complying to (part -of) the [ISO standard][ISO-standard]. Its syntax is Ruby 2.x compatible. +of) the [ISO standard][ISO-standard] with more recent features provided by Ruby 3.x. +Also, its syntax is Ruby 3.x compatible except for pattern matching. -mruby can be linked and embedded within your application. We provide the +mruby can be linked and embedded within your application. We provide the interpreter program "mruby", and the interactive mruby shell "mirb" as examples. You can also compile Ruby programs into compiled byte code using the mruby -compiler "mrbc". All those tools reside in the "bin" directory. "mrbc" is +compiler "mrbc". All those tools reside in the "bin" directory. "mrbc" is also able to generate compiled byte code in a C source file, see the "mrbtest" program under the "test" directory for an example. @@ -20,7 +20,7 @@ of the Ministry of Economy, Trade and Industry of Japan. ## How to get mruby -The stable version 3.1.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.1.0.zip](https://github.com/mruby/mruby/archive/3.1.0.zip) +The stable version 3.2.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.2.0.zip](https://github.com/mruby/mruby/archive/3.2.0.zip) The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master) @@ -43,11 +43,17 @@ We don't have a mailing list, but you can use [GitHub issues](https://github.com ## How to compile, test, and install (mruby and gems) -See the [compile.md](doc/guides/compile.md) file. +For the simplest case, type + +``` +rake all test +``` + +See the [compile.md](doc/guides/compile.md) file for the detail. ## Building documentation -There are two sets of documentation in mruby: the mruby API (generated by yard) and C API (Doxygen) +There are two sets of documentation in mruby: the mruby API (generated by yard) and C API (Doxygen and Graphviz) To build both of them, simply go @@ -67,7 +73,7 @@ rake view_capi mruby contains a package manager called *mrbgems*. To create extensions in C and/or Ruby you should create a *GEM*. For a documentation of how to use mrbgems consult the file [mrbgems.md](doc/guides/mrbgems.md). -For example code of how to use mrbgems look into the folder *examples/mrbgems/*. +For example code of how to use mrbgems look into the folder [examples/mrbgems/](examples/mrbgems). ## License @@ -79,7 +85,7 @@ mruby has chosen a MIT License due to its permissive license allowing developers to target various environments such as embedded systems. However, the license requires the display of the copyright notice and license information in manuals for instance. Doing so for big projects can be -complicated or troublesome. This is why mruby has decided to display "mruby +complicated or troublesome. This is why mruby has decided to display "mruby developers" as the copyright name to make it simple conventionally. In the future, mruby might ask you to distribute your new code (that you will commit,) under the MIT License as a member of @@ -93,10 +99,8 @@ Please ask us if you want to distribute your code under another license. ## How to Contribute See the [contribution guidelines][contribution-guidelines], and then send a pull -request to . We consider you have granted +request to . We consider you have granted non-exclusive right to your contributed code under MIT license. [ISO-standard]: https://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579 -[build-status-img]: https://travis-ci.org/mruby/mruby.svg?branch=master [contribution-guidelines]: https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md -[travis-ci]: https://travis-ci.org/mruby/mruby diff --git a/mruby/Rakefile b/mruby/Rakefile index 227d1d5d..5a8fbdb5 100644 --- a/mruby/Rakefile +++ b/mruby/Rakefile @@ -1,4 +1,3 @@ -# encoding: utf-8 # Build description. # basic build file for mruby MRUBY_ROOT = File.dirname(File.expand_path(__FILE__)) @@ -67,3 +66,41 @@ task :deep_clean => %w[clean doc:clean] do end puts "Cleaned up mrbgems build folder" end + +PREFIX = ENV['PREFIX'] || ENV['INSTALL_PREFIX'] || '/usr/local' + +desc "install compiled products" +task :install => :install_bin do + if host = MRuby.targets['host'] + install_D host.libmruby_static, File.join(PREFIX, "lib", File.basename(host.libmruby_static)) + # install mruby.h and mrbconf.h + Dir.glob(File.join(MRUBY_ROOT, "include", "*.h")) do |src| + install_D src, File.join(PREFIX, "include", File.basename(src)) + end + Dir.glob(File.join(MRUBY_ROOT, "include", "mruby", "*.h")) do |src| + install_D src, File.join(PREFIX, "include", "mruby", File.basename(src)) + end + Dir.glob(File.join(File.join(MRUBY_ROOT, "build", "host", "include", "mruby", "presym", "*.h"))) do |src| + install_D src, File.join(PREFIX, "include", "mruby", "presym", File.basename(src)) + end + end +end + +desc "install compiled executable (on host)" +task :install_bin => :all do + if host = MRuby.targets['host'] + Dir.glob(File.join(MRUBY_ROOT, "bin", "*")) do |src| + install_D src, File.join(PREFIX, "bin", File.basename(src)) + end + end +end + +desc "run all pre-commit hooks against all files" +task :check do + sh "pre-commit run --all-files" +end + +desc "check the pre-commit hooks for updates" +task :checkupdate do + sh "pre-commit autoupdate" +end diff --git a/mruby/SECURITY.md b/mruby/SECURITY.md index 2f0ae5b2..779b06c3 100644 --- a/mruby/SECURITY.md +++ b/mruby/SECURITY.md @@ -6,13 +6,15 @@ If you have any security concern, contact . ## Scope -We consider following issues as vulnerabilities: +We consider the following issues as vulnerabilities: -* Remote code execution -* Crash caused by a valid Ruby script +- Remote code execution +- Crash caused by a valid Ruby script -We *don't* consider following issues as vulnerabilities: +We *don't* consider the following issues as vulnerabilities: -* Runtime C undefined behavior (including integer overflow) -* Crash caused by misused API -* Crash caused by tweaked compiled binary +- Runtime C undefined behavior (including integer overflow) +- Crash caused by misused API +- Crash caused by modified compiled binary +- ASAN/Valgrind warning for too big memory allocation + mruby assumes `malloc(3)` returns `NULL` for too big allocations diff --git a/mruby/TODO.md b/mruby/TODO.md index 3a08e0a1..9d3576d2 100644 --- a/mruby/TODO.md +++ b/mruby/TODO.md @@ -1,14 +1,13 @@ -# Thing to Do in the future +# Things to Do in the future # After mruby 3.1 -* multi-precision integer -* parser and code generator independent from `mrb_state` (picoruby?) -* variable sized AST node -* iv/hash entry cache -* more peephole optimization (if possible) +- parser and code generator independent from `mrb_state` (picoruby?) +- variable sized AST node +- iv/hash entry cache +- more peephole optimization (if possible) # Things to do (Things we need to consider) -* `begin ... end while cond` to behave as CRuby -* special variables ($1,$2..) +- `begin ... end while cond` to behave as CRuby +- special variables ($1,$2..) diff --git a/mruby/benchmark/bm_ao_render.rb b/mruby/benchmark/bm_ao_render.rb index af916974..91e2d341 100644 --- a/mruby/benchmark/bm_ao_render.rb +++ b/mruby/benchmark/bm_ao_render.rb @@ -179,7 +179,7 @@ def clamp(f) i.to_i end -def otherBasis(basis, n) +def orthoBasis(basis, n) basis[2] = Vec.new(n.x, n.y, n.z) basis[1] = Vec.new(0.0, 0.0, 0.0) @@ -211,7 +211,7 @@ def initialize def ambient_occlusion(isect) basis = Array.new(3) - otherBasis(basis, isect.n) + orthoBasis(basis, isect.n) ntheta = NAO_SAMPLES nphi = NAO_SAMPLES @@ -243,8 +243,6 @@ def ambient_occlusion(isect) @plane.intersect(ray, occisect) if occisect.hit occlusion = occlusion + 1.0 - else - 0.0 end end end @@ -254,7 +252,6 @@ def ambient_occlusion(isect) end def render(w, h, nsubsamples) - cnt = 0 nsf = nsubsamples.to_f h.times do |y| w.times do |x| @@ -263,7 +260,6 @@ def render(w, h, nsubsamples) # Subsampling nsubsamples.times do |v| nsubsamples.times do |u| - cnt = cnt + 1 wf = w.to_f hf = h.to_f xf = x.to_f @@ -288,8 +284,6 @@ def render(w, h, nsubsamples) rad.x = rad.x + col.x rad.y = rad.y + col.y rad.z = rad.z + col.z - else - 0.0 end end end diff --git a/mruby/benchmark/bm_fib.rb b/mruby/benchmark/bm_fib.rb index 4b395f9c..cb43b4a7 100644 --- a/mruby/benchmark/bm_fib.rb +++ b/mruby/benchmark/bm_fib.rb @@ -1,4 +1,3 @@ - def fib n return n if n < 2 fib(n-2) + fib(n-1) diff --git a/mruby/benchmark/bm_so_lists.rb b/mruby/benchmark/bm_so_lists.rb index fdee0e4d..3b9f291b 100644 --- a/mruby/benchmark/bm_so_lists.rb +++ b/mruby/benchmark/bm_so_lists.rb @@ -1,9 +1,11 @@ # from http://www.bagley.org/~doug/shootout/bench/lists/lists.ruby +# which is lost long time ago. The past content can be retrieved from +# https://web.archive.org/web/20040805115204/http://www.bagley.org/~doug/shootout/bench/lists/lists.ruby NUM = 300 SIZE = 10000 -def test_lists() +def test_lists # create a list of integers (Li1) from 1 to SIZE li1 = (1..SIZE).to_a # copy the list to li2 (not by individual items) diff --git a/mruby/build_config/IntelGalileo.rb b/mruby/build_config/IntelGalileo.rb index f1f39e5d..2b5c05f2 100644 --- a/mruby/build_config/IntelGalileo.rb +++ b/mruby/build_config/IntelGalileo.rb @@ -12,7 +12,7 @@ #ARDUINO_GALILEO_PATH = '/opt/arduino' GALILEO_BIN_PATH = "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i386-pokysdk-darwin/usr/bin/i586-poky-linux-uclibc" - GALILEO_SYSROOT = "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc" + GALILEO_SYSROOT = "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc" GALILEO_X86_PATH = "#{GALILEO_ARDUINO_PATH}/hardware/arduino/x86" diff --git a/mruby/build_config/android_arm64_v8a.rb b/mruby/build_config/android_arm64_v8a.rb index 7fab2f06..8763b008 100644 --- a/mruby/build_config/android_arm64_v8a.rb +++ b/mruby/build_config/android_arm64_v8a.rb @@ -2,7 +2,7 @@ MRuby::CrossBuild.new('android-arm64-v8a') do |conf| params = { :arch => 'arm64-v8a', - :platform => 'android-24', + :sdk_version => 26, :toolchain => :clang, } toolchain :android, params diff --git a/mruby/build_config/android_armeabi.rb b/mruby/build_config/android_armeabi.rb index 41a657c3..cef0e3ad 100644 --- a/mruby/build_config/android_armeabi.rb +++ b/mruby/build_config/android_armeabi.rb @@ -2,7 +2,7 @@ MRuby::CrossBuild.new('android-armeabi') do |conf| params = { :arch => 'armeabi', - :platform => 'android-24', + :sdk_version => 26, :toolchain => :clang, } toolchain :android, params diff --git a/mruby/build_config/android_armeabi_v7a_neon_hard.rb b/mruby/build_config/android_armeabi_v7a_neon_hard.rb index 6129b238..150d1d20 100644 --- a/mruby/build_config/android_armeabi_v7a_neon_hard.rb +++ b/mruby/build_config/android_armeabi_v7a_neon_hard.rb @@ -4,7 +4,7 @@ :arch => 'armeabi-v7a', :mfpu => 'neon', :mfloat_abi => 'hard', - :platform => 'android-24', + :sdk_version => 26, :toolchain => :clang, } toolchain :android, params diff --git a/mruby/build_config/boxing.rb b/mruby/build_config/boxing.rb index d861bd53..8a31ab45 100644 --- a/mruby/build_config/boxing.rb +++ b/mruby/build_config/boxing.rb @@ -5,7 +5,7 @@ boxings.product(bits, ints) do |boxing, bit, int| MRuby::Build.new("boxing-#{boxing}-m#{bit}-i#{int}") do |conf| conf.toolchain :gcc - conf.gembox 'default' + conf.gembox 'full-core' conf.compilers.each do |c| c.defines << "MRB_#{boxing.upcase}_BOXING" c.defines << "MRB_INT#{int}" diff --git a/mruby/build_config/cross-mingw-winetest.rb b/mruby/build_config/cross-mingw-winetest.rb index fad06b26..94fa67d1 100644 --- a/mruby/build_config/cross-mingw-winetest.rb +++ b/mruby/build_config/cross-mingw-winetest.rb @@ -1,4 +1,3 @@ - # Cross-compile using MinGW and test using Wine. # # Steps: @@ -16,11 +15,11 @@ # # 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: +# double-check.) To confirm, run: # # wine cmd /c dir 'z:\\' # -# This should give you a DOS-style equivalent of 'ls /'. If not, +# 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'. # @@ -40,8 +39,8 @@ # # 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 +# 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. # @@ -50,11 +49,11 @@ # # 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 +# 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. +# unit tests due to small errors in some floating-point +# operations. It's unclear if this indicates more serious problems. # diff --git a/mruby/build_config/helpers/wine_runner.rb b/mruby/build_config/helpers/wine_runner.rb index 9a7eb46b..67da288e 100755 --- a/mruby/build_config/helpers/wine_runner.rb +++ b/mruby/build_config/helpers/wine_runner.rb @@ -35,7 +35,7 @@ def clean(output, stderr = false) result_text = results.join("\n") result_text += "\n" if ends_with_newline - return result_text + result_text end @@ -46,7 +46,7 @@ def main end # For simplicity, just read all of stdin into memory and pass that - # as an argument when invoking wine. (Skipped if STDIN was not + # as an argument when invoking wine. (Skipped if STDIN was not # redirected.) if !STDIN.tty? input = STDIN.read diff --git a/mruby/build_config/host-debug.rb b/mruby/build_config/host-debug.rb index 600a4d78..66e622ad 100644 --- a/mruby/build_config/host-debug.rb +++ b/mruby/build_config/host-debug.rb @@ -8,7 +8,7 @@ conf.gembox 'full-core' # C compiler settings - conf.cc.defines = %w(MRB_USE_DEBUG_HOOK MRB_NO_BOXING) + conf.cc.defines = %w(MRB_USE_DEBUG_HOOK MRB_NO_BOXING MRB_UTF8_STRING) # Generate mruby debugger command (require mruby-eval) conf.gem :core => "mruby-bin-debugger" diff --git a/mruby/build_config/host-f32.rb b/mruby/build_config/host-f32.rb index a449547a..ef15231a 100644 --- a/mruby/build_config/host-f32.rb +++ b/mruby/build_config/host-f32.rb @@ -3,7 +3,7 @@ toolchain :gcc # include the GEM box - conf.gembox 'default' + conf.gembox 'full-core' conf.cc.defines << 'MRB_USE_FLOAT32' diff --git a/mruby/build_config/host-gprof.rb b/mruby/build_config/host-gprof.rb index 2bdf5beb..aab119b3 100644 --- a/mruby/build_config/host-gprof.rb +++ b/mruby/build_config/host-gprof.rb @@ -3,7 +3,7 @@ toolchain :gcc # include the GEM box - conf.gembox 'default' + conf.gembox 'full-core' conf.cc.flags << '-pg' conf.linker.flags << '-pg' diff --git a/mruby/build_config/host-m32.rb b/mruby/build_config/host-m32.rb index 9e27a079..5d67ccd6 100644 --- a/mruby/build_config/host-m32.rb +++ b/mruby/build_config/host-m32.rb @@ -3,7 +3,7 @@ toolchain :gcc # include the GEM box - conf.gembox 'default' + conf.gembox 'full-core' conf.cc.flags << '-m32' conf.linker.flags << '-m32' diff --git a/mruby/codespell.txt b/mruby/codespell.txt index dcc0ddb4..d6d80b07 100644 --- a/mruby/codespell.txt +++ b/mruby/codespell.txt @@ -1,8 +1,10 @@ ans ba +clen creat delet disabl +falsy filetest fo hel @@ -12,6 +14,7 @@ methid nd quitt remore +ro runn sting upto diff --git a/mruby/doc/guides/compile.md b/mruby/doc/guides/compile.md index 2923a267..4302d136 100644 --- a/mruby/doc/guides/compile.md +++ b/mruby/doc/guides/compile.md @@ -7,17 +7,17 @@ binaries. To compile mruby out of the source code you need the following tools: -* C Compiler (e.g. `gcc` or `clang`) -* Linker (e.g. `gcc` or `clang`) -* Archive utility (e.g. `ar`) -* Ruby 2.5 or later (e.g. `ruby` or `jruby`) +- C Compiler (e.g. `gcc` or `clang`) +- Linker (e.g. `gcc` or `clang`) +- Archive utility (e.g. `ar`) +- Ruby 2.5 or later (e.g. `ruby` or `jruby`) Optional: -* Git (to update mruby source and integrate mrbgems easier) -* C++ compiler (to use mrbgems which include `*.cpp`, `*.cxx`, `*.cc`) -* Bison (to compile `mrbgems/mruby-compiler/core/parse.y`) -* gperf (to compile `mrbgems/mruby-compiler/core/keywords`) +- Git (to update mruby source and integrate mrbgems easier) +- C++ compiler (to use mrbgems which include `*.cpp`, `*.cxx`, `*.cc`) +- Bison (to compile `mrbgems/mruby-compiler/core/parse.y`) +- gperf (to compile `mrbgems/mruby-compiler/core/keywords`) Note that `bison` bundled with macOS is too old to compile `mruby`. Try `brew install bison` and follow the instruction shown to update @@ -103,8 +103,8 @@ in `ANDROID_STANDALONE_TOOLCHAIN`. It is possible to select which tools should be compiled during the compilation process. For example, -* `mruby` -* `mirb` +- `mruby` +- `mirb` The configuration are done via `mrbgems`. See `Mrbgems` section. @@ -332,11 +332,11 @@ conf.enable_debug When debugging mode is enabled -* Macro `MRB_DEBUG` would be defined. - * 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. - * You can have better backtrace of mruby scripts with this. +- Macro `MRB_DEBUG` would be defined. + - 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. + - You can have better backtrace of mruby scripts with this. ## Cross-Compilation @@ -401,19 +401,19 @@ root directory. The structure of this directory will look like this: The compilation workflow will look like this: -* compile minimal `mrbc` from `src` and `mrblib` sources - * compile all files under `src` (object files will be stored in `build/host/mrbc/src`) - * compile `mruby-compiler` gem - * create `build/host/mrbc/lib/libmruby_core.a` out of all object files (C only) - * create `build/host/mrbc/bin/mrbc` via `mruby-bin-mrbc` gem -* compile all files under `src` and store result in `build/host/src` -* create `build/host/mrblib/mrblib.c` by compiling all `*.rb` files under `mrblib` with `build/host/mrbc/bin/mrbc` -* compile `build/host/mrblib/mrblib.c` to `build/host/mrblib/mrblib.o` -* create `build/host/lib/libmruby.a` out of all object files (C and Ruby) -* compile (normal) mrbgems specified in the configuration file -* create `build/host/lib/libmruby.a` from object files from gems and `libmruby_core.a` -* create binary commands according to binary gems (e.g. `mirb` and `mruby`) -* copy binaries under `build/host/bin` to `bin` directory +- compile minimal `mrbc` from `src` and `mrblib` sources + - compile all files under `src` (object files will be stored in `build/host/mrbc/src`) + - compile `mruby-compiler` gem + - create `build/host/mrbc/lib/libmruby_core.a` out of all object files (C only) + - create `build/host/mrbc/bin/mrbc` via `mruby-bin-mrbc` gem +- compile all files under `src` and store result in `build/host/src` +- create `build/host/mrblib/mrblib.c` by compiling all `*.rb` files under `mrblib` with `build/host/mrbc/bin/mrbc` +- compile `build/host/mrblib/mrblib.c` to `build/host/mrblib/mrblib.o` +- create `build/host/lib/libmruby.a` out of all object files (C and Ruby) +- compile (normal) mrbgems specified in the configuration file +- create `build/host/lib/libmruby.a` from object files from gems and `libmruby_core.a` +- create binary commands according to binary gems (e.g. `mirb` and `mruby`) +- copy binaries under `build/host/bin` to `bin` directory ``` _____ _____ ______ ____ ____ _____ _____ ____ @@ -465,13 +465,13 @@ for we don't have `host/mrbc` directory (`host` directory itself works as placeholder for `mrbc`). Afterwards the cross compilation process proceeds like this: -* cross-compile all files under `src` and store result in `build/i386/src` -* create `build/i386/lib/libmruby_core.a` out of C object files -* create `build/i386/mrblib/mrblib.c` by compiling all `*.rb` files under `mrblib` with native `build/host/bin/mrbc` -* cross-compile `build/i386/mrblib/mrblib.c` to `build/i386/mrblib/mrblib.o` -* create `build/i386/lib/libmruby.a` from object files from gems and `libmruby_core.a` -* create binary commands according to binary gems (e.g. `mirb` and `mruby`) -* copy binaries under `build/host/bin` to `bin` directory +- cross-compile all files under `src` and store result in `build/i386/src` +- create `build/i386/lib/libmruby_core.a` out of C object files +- create `build/i386/mrblib/mrblib.c` by compiling all `*.rb` files under `mrblib` with native `build/host/bin/mrbc` +- cross-compile `build/i386/mrblib/mrblib.c` to `build/i386/mrblib/mrblib.o` +- create `build/i386/lib/libmruby.a` from object files from gems and `libmruby_core.a` +- create binary commands according to binary gems (e.g. `mirb` and `mruby`) +- copy binaries under `build/host/bin` to `bin` directory ``` _______________________________________________________________ @@ -545,7 +545,7 @@ For example, when you have a C source file (`c.c`) and try to compile and link it with `libmruby.a`, you can run the following command, ``` -gcc `mruby-config --cflags` c.c `mruby-config --ldflags` `mruby-config --libs` +`mruby-config --cc --cflags` c.c `mruby-config --ldflags --libs` ``` When you use `make`, add following lines in `Makefile` @@ -556,3 +556,7 @@ CFLAGS = `$(MRB_CONFIG) --cflags` LDFLAGS = `$(MRB_CONFIG) --ldflags` LIBS = `$(MRB_CONFIG) --libs` ``` + +## Tips + +- If you see compilation troubles, try `rake clean` first. diff --git a/mruby/doc/guides/debugger.md b/mruby/doc/guides/debugger.md index 18673c47..ef48005a 100644 --- a/mruby/doc/guides/debugger.md +++ b/mruby/doc/guides/debugger.md @@ -82,7 +82,7 @@ You can debug the mruby binary files. #### 2.2.2.1 Debugging the binary files -* notice +- notice To debug mruby binary files, you need to compile mruby files with option `-g`. ```bash diff --git a/mruby/doc/guides/gc-arena-howto.md b/mruby/doc/guides/gc-arena-howto.md index 2c1cdc1f..22cd4ef1 100644 --- a/mruby/doc/guides/gc-arena-howto.md +++ b/mruby/doc/guides/gc-arena-howto.md @@ -7,19 +7,19 @@ _Some parts are updated to reflect recent changes._ When you are extending mruby using C language, you may encounter mysterious "arena overflow error" or memory leak or very slow -execution speed. This is an error indicating overflow of "GC arena" +execution speed. This is an error indicating overflow of "GC arena" implementing "conservative GC". GC (garbage collector) must ensure that object is "alive", in other -words, that it is referenced by somewhere from the program. This can be +words, that it is referenced by somewhere from the program. This can be determined by checking if the object can be directly or indirectly -referenced by root. The local variables, global variables and -constants etc are root. +referenced by root. The local variables, global variables and +constants etc. are root. If program execution is performed inside mruby VM, there is nothing to worry about because GC can access all roots owned by the VM. -The problem arises when executing C functions. The object referenced +The problem arises when executing C functions. The object referenced by C variable is also "alive", but mruby GC cannot aware of this, so it might mistakenly recognize the objects referenced by only C variables as dead. @@ -27,15 +27,15 @@ variables as dead. This can be a fatal bug if the GC tries to collect a live object. In CRuby, we scan C stack area, and use C variable as root to check -whether object is alive or not. Of course, because we are accessing C +whether object is alive or not. Of course, because we are accessing C stack just as memory region, we never know it is an integer or a -pointer. We workaround this by assuming that if it looks like a -pointer, then assume it as a pointer. We call it "conservative". +pointer. We work around this by assuming that if it looks like a +pointer, then assume it as a pointer. We call it "conservative". By the way, CRuby's "conservative GC" has some problems. The biggest problem is we have no way to access to the stack area in -portable way. Therefore, we cannot use this method if we'd like to +portable way. Therefore, we cannot use this method if we'd like to implement highly portable runtime, like mruby. So we came up with another plan to implement "conservative GC" in mruby. @@ -65,14 +65,14 @@ objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in doc/guides/mrbconf.md). If you create many objects in C functions, memory usage will increase, since -GC never kick in. This memory usage may look like memory leak, but will also +GC never kicks in. This memory usage may look like memory leaks, but will also make execution slower as more memory will need to be allocated. With the build time configuration, you can limit the maximum size of -arena (e.g., 100). Then if you create many objects, arena overflows, +arena (e.g., 100). Then if you create many objects, arena overflows, thus you will get an "arena overflow error". -To workaround these problems, we have `mrb_gc_arena_save()` and +To work around these problems, we have `mrb_gc_arena_save()` and `mrb_gc_arena_restore()` functions. `int mrb_gc_arena_save(mrb)` returns the current position of the stack @@ -93,7 +93,7 @@ In mruby, C function calls are surrounded by this save/restore, but we can further optimize memory usage by surrounding save/restore, and can avoid creating arena overflow bugs. -Let's take a real example. Here is the source code of `Array#inspect`: +Let's take a real example. Here is the source code of `Array#inspect`: ```c static mrb_value @@ -146,23 +146,23 @@ of array using `inspect` method, we join them together so that we can get `inspect` representation of the entire array. After the `inspect` representation is created, we no longer require the -individual string representation. This means that we don't have to register +individual string representation. This means that we don't have to register these temporal objects into GC arena. Therefore, in order to keep the arena size small; the `ary_inspect()` function will do the following: -* save the position of the stack top using `mrb_gc_arena_save()`. -* get `inspect` representation of each element. -* append it to the constructing entire `inspect` representation of array. -* restore stack top position using `mrb_gc_arena_restore()`. +- save the position of the stack top using `mrb_gc_arena_save()`. +- get `inspect` representation of each element. +- append it to the constructing entire `inspect` representation of array. +- restore stack top position using `mrb_gc_arena_restore()`. Please note that the final `inspect` representation of entire array -was created before the call of `mrb_gc_arena_restore()`. Otherwise, +was created before the call of `mrb_gc_arena_restore()`. Otherwise, required temporal object may be deleted by GC. We may have an usecase where after creating many temporal objects, we'd -like to keep some of them. In this case, we cannot use the same idea +like to keep some of them. In this case, we cannot use the same idea in `ary_inspect()` like appending objects to existing one. Instead, after `mrb_gc_arena_restore()`, we must re-register the objects we want to keep in the arena using `mrb_gc_protect(mrb, obj)`. diff --git a/mruby/doc/guides/link.md b/mruby/doc/guides/link.md index 8d70330f..861f7136 100644 --- a/mruby/doc/guides/link.md +++ b/mruby/doc/guides/link.md @@ -2,13 +2,13 @@ You have two ways to link `libmruby` to your application. -* using executable gem. -* using normal compilation process +- using executable gem. +- using normal compilation process ## Executable Gems If your application is relatively small, `mrbgem` is an easier way to -create the executable. By tradition, the gem name start with +create the executable. By tradition, the gem name start with `mruby-bin-`, e.g. `mruby-bin-debugger`. ### `mrbgem.rake` file @@ -28,7 +28,7 @@ end ### Source tree structure The source file for the gem executable should be in -`/tools/`. Currently, we support C or C++ source code +`/tools/`. Currently, we support C or C++ source code (`.c`, `.cpp`, `.cxx`, `.cc`) for the executable. Ruby source files are not supported. Put the functionality in the different gem and specify dependency to it in `mrbgem.rake`. @@ -37,7 +37,7 @@ it in `mrbgem.rake`. The `libmruby` is a normal library so that you can just link it to your application. Specify proper compiler options (`-I` etc.) and linker options -(`-Lmruby` etc.) to compile and link your application. Specify those options in +(`-lmruby` etc.) to compile and link your application. Specify those options in your build script (e.g. `Makefile`). ### Compiler options @@ -45,14 +45,14 @@ your build script (e.g. `Makefile`). You need to specify compiler options that are compatible to mruby configuration, for example: -* `-I` to specify the place for mruby header files -* `-D` to specify mruby configuration macros +- `-I` to specify the place for mruby header files +- `-D` to specify mruby configuration macros To retrieve compiler options used to build `mruby`, you can use `mruby-config` command with following options: -* `--cc` compiler name -* `--cflags` options passed to compiler +- `--cc` compiler name +- `--cflags` options passed to compiler ``` $ mruby-config --cflags @@ -66,10 +66,10 @@ compatible to mruby configuration. To retrieve linker options, you can use `mruby-config` with following options: -* `--ld` linker name -* `--ldflags` options passed to linker -* `--ldflags-before-libs` options passed to linker before linked libraries -* `--libs` linked libraries +- `--ld` linker name +- `--ldflags` options passed to linker +- `--ldflags-before-libs` options passed to linker before linked libraries +- `--libs` linked libraries ``` $ mruby-config --ldflags diff --git a/mruby/doc/guides/mrbconf.md b/mruby/doc/guides/mrbconf.md index e71346ae..771922a4 100644 --- a/mruby/doc/guides/mrbconf.md +++ b/mruby/doc/guides/mrbconf.md @@ -1,209 +1,252 @@ # mruby configuration macros +## The configuration file + +You can do the build configuration in the build configuration file. The default +configuration file is `build_config/default.rb`. + +You can specify your own configuration file by the `MRUBY_CONFIG` environment +variable (you can use `CONFIG` for shorthand for `MRUBY_CONFIG`). If the path +doesn't exist, `build_config/${MRUBY_CONFIG}.rb` is used. + ## How to use these macros -You can use mrbconfs with following ways: +Just add the configuration value to the `MRuby::Build#defines` attribute. +This is the same for `MRuby::CrossBuild`. + +```ruby +# build_config.rb -* Write them in `mrbconf.h`. - * Using compiler flags is preferred when building a cross binaries or multiple mruby binaries - since it's easier to use different mrbconf per each `MRuby::Build`. - * Most flags can be enabled by just commenting in. -* Pass them as compiler flags. - * Make sure you pass the same flags to all compilers since some mrbconf(e.g., `MRB_GC_FIXED_ARENA`) - changes `struct` layout and cause memory access error when C and other language(e.g., C++) is mixed. +MRuby::Build.new do |conf| + ..... + conf.defines << 'MRB_GC_FIXED_ARENA' + conf.defines << 'MRB_NO_METHOD_CACHE' + ..... +end +``` + +***NOTE*** + +- Use common definitions (`conf.defines`) instead of per-compiler definitions (e.g., `conf.cc.defines`) unless there is a special reason not to. +- It is now deprecated to edit the `include/mruby/mrbconf.h` file or give it directly as a compiler flag, as was the case before. ## stdio setting `MRB_NO_STDIO` -* When defined `` functions won't be used. -* Some features will be disabled when this is enabled: - * `mrb_irep` load/dump from/to file. - * Compiling mruby script from a file. - * Printing features in **src/print.c**. +- When defined `` functions won't be used. +- Some features will be disabled when this is enabled: + - `mrb_irep` load/dump from/to file. + - Compiling mruby script from a file. + - Printing features in **src/print.c**. ## Debug macros `MRB_USE_DEBUG_HOOK` -* When defined code fetch hook and debug OP hook will be enabled. -* When using any of the hook set function pointer `code_fetch_hook` and/or `debug_op_hook` of `mrb_state`. -* Fetch hook will be called before any OP. -* Debug OP hook will be called when dispatching `OP_DEBUG`. +- When defined code fetch hook and debug OP hook will be enabled. +- When using any of the hook set function pointer `code_fetch_hook` and/or `debug_op_hook` of `mrb_state`. +- Fetch hook will be called before any OP. +- Debug OP hook will be called when dispatching `OP_DEBUG`. `MRB_DEBUG` -* When defined `mrb_assert*` macro will be defined with macros from ``. -* Could be enabled via `enable_debug` method of `MRuby::Build`. +- When defined `mrb_assert*` macro will be defined with macros from ``. +- Could be enabled via `enable_debug` method of `MRuby::Build`. ## Stack configuration `MRB_STACK_EXTEND_DOUBLING` -* If defined doubles the stack size when extending it. -* Else extends stack with `MRB_STACK_GROWTH`. +- If defined doubles the stack size when extending it. +- Otherwise extends stack with `MRB_STACK_GROWTH`. `MRB_STACK_GROWTH` -* Default value is `128`. -* Used in stack extending. -* Ignored when `MRB_STACK_EXTEND_DOUBLING` is defined. +- Default value is `128`. +- Used in stack extending. +- Ignored when `MRB_STACK_EXTEND_DOUBLING` is defined. `MRB_STACK_MAX` -* Default value is `0x40000 - MRB_STACK_GROWTH`. -* Raises `RuntimeError` when stack size exceeds this value. +- Default value is `0x40000 - MRB_STACK_GROWTH`. +- Raises `RuntimeError` when stack size exceeds this value. ## Primitive type configuration `MRB_USE_FLOAT32` -* When defined single precision floating-point type(C type `float`) is used as `mrb_float`. -* Otherwise, double precision floating-point type(C type `double`) is used as `mrb_float`. +- When defined single-precision floating-point type(C type `float`) is used as `mrb_float`. +- Otherwise, double-precision floating-point type(C type `double`) is used as `mrb_float`. `MRB_NO_FLOAT` -* When defined removes floating-point numbers from mruby. -* It makes mruby easier to handle in "Microcontroller without FPU" and "Kernel Space". +- When defined removes floating-point numbers from mruby. +- It makes mruby easier to handle in "Micro-controller without FPU" and "Kernel Space". `MRB_INT32` -* When defined, or `MRB_INT64` are not defined on 32-bit CPU mode, `mrb_int` will be defined as `int32_t`. -* Conflicts with `MRB_INT64`. +- When defined, or `MRB_INT64` are not defined on 32-bit CPU mode, `mrb_int` will be defined as `int32_t`. +- Conflicts with `MRB_INT64`. `MRB_INT64` -* When defined, or `MRB_INT32` are not defined on 64-bit CPU mode, `mrb_int` will be defined as `int64_t`. -* Conflicts with `MRB_INT32`. +- When defined, or `MRB_INT32` are not defined on 64-bit CPU mode, `mrb_int` will be defined as `int64_t`. +- Conflicts with `MRB_INT32`. ## Garbage collector configuration `MRB_GC_STRESS` -* When defined full GC is emitted per each `RBasic` allocation. -* Mainly used in memory manager debugging. +- When defined full GC is emitted per each `RBasic` allocation. +- Mainly used in memory manager debugging. +- If defined at the same time as `MRB_DEBUG`, full GC is emitted also per each heap allocation (`mrb_malloc()` or etc.). + This configuration slows down mruby execution by a factor of 2 to 3 or even more. `MRB_GC_TURN_OFF_GENERATIONAL` -* When defined turns generational GC by default. +- When defined turns generational GC by default. `MRB_GC_FIXED_ARENA` -* When defined used fixed size GC arena. -* Raises `RuntimeError` when this is defined and GC arena size exceeds `MRB_GC_ARENA_SIZE`. -* Useful tracking unnecessary mruby object allocation. +- When defined used fixed size GC arena. +- Raises `RuntimeError` when this is defined and GC arena size exceeds `MRB_GC_ARENA_SIZE`. +- Useful tracking unnecessary mruby object allocation. `MRB_GC_ARENA_SIZE` -* Default value is `100`. -* Ignored when `MRB_GC_FIXED_ARENA` isn't defined. -* Defines fixed GC arena size. +- Default value is `100`. +- Ignored when `MRB_GC_FIXED_ARENA` isn't defined. +- Defines fixed GC arena size. `MRB_HEAP_PAGE_SIZE` -* Defines value is `1024`. -* Specifies number of `RBasic` per each heap page. +- Defines value is `1024`. +- Specifies number of `RBasic` per each heap page. +- To calculate the number of bytes per heap page, it is "(size of management data per heap page) + (size per object) * `MRB_HEAP_PAGE_SIZE`". + In mruby 3.1.0, the "size of management data per heap page" is 6 words, also "size per object" is 6 words. + For a 32-bit CPU, `(6 * 4) + (6 * 4) * MRB_HEAP_PAGE_SIZE` gives the bytes of size per heap page. + Conversely, for example, to keep the size per heap page to 4 Ki bytes, + calculate `(4096 - (6 * 4)) / (6 * 4)` to specify `MRB_HEAP_PAGE_SIZE=169`. ## Memory pool configuration `POOL_ALIGNMENT` -* Default value is `4`. -* If you're allocating data types that requires alignment more than default value define the +- Default value is `4`. +- If you're allocating data types that requires alignment more than default value define the largest value of required alignment. `POOL_PAGE_SIZE` -* Default value is `16000`. -* Specifies page size of pool page. -* Smaller the value is increases memory overhead. +- Default value is `16000`. +- Specifies page size of pool page. +- Smaller the value is increases memory overhead. ## State atexit configuration `MRB_FIXED_STATE_ATEXIT_STACK` -* If defined enables fixed size `mrb_state` atexit stack. -* Raises `RuntimeError` when `mrb_state_atexit` call count to same `mrb_state` exceeds +- If defined enables fixed size `mrb_state` atexit stack. +- Raises `RuntimeError` when `mrb_state_atexit` call count to same `mrb_state` exceeds `MRB_FIXED_STATE_ATEXIT_STACK_SIZE`'s value. `MRB_FIXED_STATE_ATEXIT_STACK_SIZE` -* Default value is `5`. -* If `MRB_FIXED_STATE_ATEXIT_STACK` isn't defined this macro is ignored. +- Default value is `5`. +- If `MRB_FIXED_STATE_ATEXIT_STACK` isn't defined this macro is ignored. ## `mrb_value` configuration `MRB_ENDIAN_BIG` -* If defined compiles mruby for big endian machines. -* Used in `MRB_NAN_BOXING`. -* Some mrbgem use this mrbconf. +- If defined compiles mruby for big endian machines. +- Used in `MRB_NAN_BOXING`. +- Some mrbgem use this mrbconf. `MRB_NAN_BOXING` -* If defined represent `mrb_value` in boxed `double`. -* Conflicts with `MRB_USE_FLOAT32` and `MRB_NO_FLOAT`. +- If defined represent `mrb_value` in boxed `double`. +- Conflicts with `MRB_USE_FLOAT32` and `MRB_NO_FLOAT`. `MRB_WORD_BOXING` -* If defined represent `mrb_value` as a word. -* If defined `Float` will be a mruby object with `RBasic`. +- If defined represent `mrb_value` as a word. +- If defined `Float` will be a mruby object with `RBasic`. ## Reduce heap memory configuration `MRB_USE_ETEXT_RO_DATA_P` -* 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. +- 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. +- Define this macro when the default `mrb_ro_data_p()` does not work for any reason. `MRB_USE_CUSTOM_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)`. -* Return `TRUE` if `ptr` is in the read-only section, otherwise return `FALSE`. +- 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)`. +- Return `TRUE` if `ptr` is in the read-only section, otherwise return `FALSE`. ## Other configuration +`MRB_MALLOC_TRIM` + +- call malloc_trim(0) for each mrb_full_gc() call + `MRB_UTF8_STRING` -* Adds UTF-8 encoding support to character-oriented String instance methods. -* If it isn't defined, they only support the US-ASCII encoding. +- Adds UTF-8 encoding support to character-oriented String instance methods. +- If it isn't defined, they only support the US-ASCII encoding. + +`MRB_STR_LENGTH_MAX` + +- The maximum length of strings (default 1MB) +- set this value to zero to skip the check + +`MRB_ARY_LENGTH_MAX` + +- The maximum length of strings (default 1MB) +- set this value to zero to skip the check `MRB_FUNCALL_ARGC_MAX` -* Default value is `16`. -* Specifies 4th argument(`argc`) max value of `mrb_funcall`. -* Raises `ArgumentError` when the `argc` argument is bigger then this value `mrb_funcall`. +- Default value is `16`. +- Specifies 4th argument(`argc`) max value of `mrb_funcall`. +- Raises `ArgumentError` when the `argc` argument is bigger then this value `mrb_funcall`. `KHASH_DEFAULT_SIZE` -* Default value is `32`. -* Specifies default size of khash table bucket. -* Used in `kh_init_ ## name` function. +- Default value is `32`. +- Specifies default size of khash table bucket. +- Used in `kh_init_ ## name` function. `MRB_NO_METHOD_CACHE` -* Disable method cache to save memory. +- Disable method cache to save memory. `MRB_METHOD_CACHE_SIZE` -* Default value is `256`. -* Ignored if `MRB_NO_METHOD_CACHE` is defined. -* Need to be the power of 2. +- Default value is `256`. +- Ignored if `MRB_NO_METHOD_CACHE` is defined. +- Need to be the power of 2. `MRB_USE_METHOD_T_STRUCT` -* Use C struct to represent `mrb_method_t` -* No `MRB_USE_METHOD_T_STRUCT` requires highest 2 bits of function pointers to be zero -* Define this macro on machines that use higher bits of pointers +- Use C struct to represent `mrb_method_t` +- No `MRB_USE_METHOD_T_STRUCT` requires highest 2 bits of function pointers to be zero +- Define this macro on machines that use higher bits of pointers `MRB_USE_ALL_SYMBOLS` -* Make it available `Symbol.all_symbols` in `mrbgems/mruby-symbol-ext` -* Increase heap memory usage. +- Make it available `Symbol.all_symbols` in `mrbgems/mruby-symbol-ext` +- Increase heap memory usage. + +`MRB_NO_DIRECT_THREADING` + +- Turn off direct threading optimization in VM loop diff --git a/mruby/doc/guides/mrbgems.md b/mruby/doc/guides/mrbgems.md index 03f8829e..e81a30ac 100644 --- a/mruby/doc/guides/mrbgems.md +++ b/mruby/doc/guides/mrbgems.md @@ -6,7 +6,7 @@ standardised way into mruby. Conventionally, each mrbgem name is prefixed by ## Usage -You have to activate mrbgems explicitly in your build configuration. To add +You have to activate mrbgems explicitly in your build configuration. To add a gem, add the following line to your build configuration file, for example: ```ruby @@ -21,9 +21,9 @@ conf.gem 'examples/mrbgems/ruby_extension_example' In that case, -* if your build configuration file is in the `build_config` directory, it's +- if your build configuration file is in the `build_config` directory, it's relative from `MRUBY_ROOT`. -* otherwise, it is relative from the directory where your build configuration is. +- otherwise, it is relative from the directory where your build configuration is. A remote GIT repository location for a GEM is also supported: @@ -33,6 +33,9 @@ conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master' conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master' ``` +NOTE: `:bitbucket` option supports only git. Hg is unsupported in this +version. + You can specify the subdirectory of the repository with `:path` option: ```ruby @@ -55,19 +58,48 @@ 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`. +Note that if more than one git-based gem has the same base name +(i.e. the default checkout directory name), it is (now) an error +**UNLESS** they have the same repository URL, branch name and +commit-id (i.e. checksum hash). You can bypass this by explicitly +importing your preferred version **first** and setting the +`canonical:` option to `true`: + +```ruby +conf.gem github: 'me/mruby-yaml', branch: 'my-hacked-branch', canonical: true +``` + +If you do this, the system will (mostly) silently ignore other +attempts to clone a gem with this name. + +Note that this only affects cloning the gem from git. It does not +resolve version conflicts. If the version as specified in the gem's +rakefile is incompatible with a dependency, your build will still +fail. + +### Tweak the gem in your build configuration file -NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. +You can give blocks in the `conf.gem` call to make adjustments for +environments where the original gem does not expect them: + +```ruby +conf.gem core: "mruby-bin-mirb" do |g| + # For cross build to NetBSD + g.linker.libraries = %w(edit termcap) +end +``` + +However, it should be used with caution, as it may deviate from the intent +of the gem's author. ## GemBox There are instances when you wish to add a collection of mrbgems into mruby at once, or be able to substitute mrbgems based on configuration, without having to -add each gem to your build configuration file. A packaged collection of mrbgems -is called a GemBox. A GemBox is a file that contains a list of mrbgems to load +add each gem to your build configuration file. A packaged collection of mrbgems +is called a GemBox. A GemBox is a file that contains a list of mrbgems to load into mruby, in the same format as if you were adding them to the build config -via `config.gem`, but wrapped in an `MRuby::GemBox` object. GemBoxes are +via `config.gem`, but wrapped in an `MRuby::GemBox` object. GemBoxes are loaded into mruby via `config.gembox 'boxname'`. Below we have created a GemBox containing `mruby-time` and `mrbgems-example`: @@ -79,7 +111,7 @@ MRuby::GemBox.new do |conf| end ``` -As mentioned, the GemBox uses the same conventions as `MRuby::Build`. The GemBox +As mentioned, the GemBox uses the same conventions as `MRuby::Build`. The GemBox must be saved with a `.gembox` extension inside the `mrbgems` directory to be picked up by mruby. @@ -94,7 +126,7 @@ conf.gembox 'custom' This will cause the `custom` GemBox to be read in during the build process, adding `mruby-time` and `mrbgems-example` to the build. -If you want, you can put GemBox outside of mruby directory. In that case you must +If you want, you can put GemBox outside the mruby directory. In that case you must specify an absolute path like below. ```ruby @@ -143,7 +175,7 @@ GEM directory. A typical GEM specification could look like this for example: MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'Example mrbgem using C and ruby' + spec.summary = 'Example mrbgem using C and Ruby' end ``` @@ -154,15 +186,15 @@ the GEM functionality to tools like `mruby` and `mirb`. The following properties can be set inside your `MRuby::Gem::Specification` for information purpose: -* `spec.license` or `spec.licenses` (A single license or a list of them under which this GEM is licensed) -* `spec.author` or `spec.authors` (Developer name or a list of them) -* `spec.version` (Current version) -* `spec.description` (Detailed description) -* `spec.summary` - * One line short description of mrbgem. - * Printed in build summary of rake when set. -* `spec.homepage` (Homepage) -* `spec.requirements` (External requirements as information for user) +- `spec.license` or `spec.licenses` (A single license or a list of them under which this GEM is licensed) +- `spec.author` or `spec.authors` (Developer name or a list of them) +- `spec.version` (Current version) +- `spec.description` (Detailed description) +- `spec.summary` + - One line short description of mrbgem. + - Printed in build summary of rake when set. +- `spec.homepage` (Homepage) +- `spec.requirements` (External requirements as information for user) The `license` and `author` properties are required in every GEM! @@ -193,15 +225,15 @@ The version requirements and default gem information are optional. Version requirement supports following operators: -* '=': is equal -* '!=': is not equal -* '>': is greater -* '<': is lesser -* '>=': 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' +- '=': is equal +- '!=': is not equal +- '>': is greater +- '<': is lesser +- '>=': 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' When more than one version requirements is passed, the dependency must satisfy all of it. @@ -214,8 +246,8 @@ 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. +- `spec.add_conflict(gem, *requirements)` + - The `requirements` argument is same as in `add_dependency` method. like following code: @@ -234,18 +266,18 @@ end In case your GEM has more complex build requirements you can use the following options additionally inside your GEM specification: -* `spec.cc.flags` (C compiler flags) -* `spec.cc.defines` (C compiler defines) -* `spec.cc.include_paths` (C compiler include paths) -* `spec.linker.flags` (Linker flags) -* `spec.linker.libraries` (Linker libraries) -* `spec.linker.library_paths` (Linker additional library path) -* `spec.bins` (Generate binary file) -* `spec.rbfiles` (Ruby files to compile) -* `spec.objs` (Object files to compile) -* `spec.test_rbfiles` (Ruby test files for integration into mrbtest) -* `spec.test_objs` (Object test files for integration into mrbtest) -* `spec.test_preload` (Initialization files for mrbtest) +- `spec.cc.flags` (C compiler flags) +- `spec.cc.defines` (C compiler defines) +- `spec.cc.include_paths` (C compiler include paths) +- `spec.linker.flags` (Linker flags) +- `spec.linker.libraries` (Linker libraries) +- `spec.linker.library_paths` (Linker additional library path) +- `spec.bins` (Generate binary file) +- `spec.rbfiles` (Ruby files to compile) +- `spec.objs` (Object files to compile) +- `spec.test_rbfiles` (Ruby test files for integration into mrbtest) +- `spec.test_objs` (Object test files for integration into mrbtest) +- `spec.test_preload` (Initialization files for mrbtest) You also can use `spec.mruby.cc` and `spec.mruby.linker` to add extra global parameters for the compiler and linker. @@ -380,7 +412,7 @@ See C and Ruby example. ## Binary gems Some gems can generate executables under `bin` directory. Those gems are called -binary gems. Names of binary gems are conventionally prefixed by `mruby-bin`, +binary gems. Names of binary gems are conventionally prefixed by `mruby-bin`, e.g. `mruby-bin-mirb` and `mruby-bin-strip`. To specify the name of executable, you need to specify `spec.bins` in the @@ -397,21 +429,21 @@ binary gems, to separate normal gems and binary gems. ``` +- 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/mruby/doc/guides/symbol.md b/mruby/doc/guides/symbol.md index 8f90ce59..c76420da 100644 --- a/mruby/doc/guides/symbol.md +++ b/mruby/doc/guides/symbol.md @@ -1,7 +1,7 @@ # Symbols 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 +`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 @@ -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 @@ -71,9 +71,9 @@ can be specified for it). Other than that, describe only word characters excluding leading and ending punctuations. These macros are converted to static symbol IDs at compile time, unless -preallocate symbols are disabled by `conf.disable_presym`. In that case, +preallocate symbols are disabled by `conf.disable_presym`. In that case, these macros are expanded to `mrb_intern_lit` calls, therefore the mruby state -variable is required. The above macros assume the variable name is `mrb`. If +variable is required. The above macros assume the variable name is `mrb`. If its name is not `mrb`, you need to use macros with `_2` suffix, such as `MRB_SYM_2` to specify `mrb_state*` variable. diff --git a/mruby/doc/internal/boxing.md b/mruby/doc/internal/boxing.md index e62294fe..f3bd086e 100644 --- a/mruby/doc/internal/boxing.md +++ b/mruby/doc/internal/boxing.md @@ -2,9 +2,9 @@ The mruby objects and data are represented by C data type `mrb_value`. There are three options how to pack the data values in the `mrb_value`. -* Word Boxing -* NaN Boxing -* No Boxing +- Word Boxing +- NaN Boxing +- No Boxing ## Word Boxing @@ -14,38 +14,38 @@ Some values (called immediate values, e.g. integers, booleans, symbols, etc.) ar The Word boxing packing bit patterns are like following: -| Types | Bit Pattern | -|--------|-------------------------------------| -| object | xxxxxxxx xxxxxxxx xxxxxxxx xxxxx000 | -| fixnum | xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxx1 | -| nil | 00000000 00000000 00000000 00000000 | -| true | 00000000 00000000 00000000 00001100 | -| false | 00000000 00000000 00000000 00000100 | -| undef | 00000000 00000000 00000000 00010100 | -| symbol | xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx10 | +| Types | Bit Pattern | +|--------|---------------------------------------| +| object | `xxxxxxxx xxxxxxxx xxxxxxxx xxxxx000` | +| fixnum | `xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxx1` | +| nil | `00000000 00000000 00000000 00000000` | +| true | `00000000 00000000 00000000 00001100` | +| false | `00000000 00000000 00000000 00000100` | +| undef | `00000000 00000000 00000000 00010100` | +| symbol | `xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx10` | On 64 bit platform (unless `MRB_WORDBOX_NO_FLOAT_TRUNCATE`), float values are also packed in the `mrb_value`. In that case, we drop least significant 2 bits from mantissa. -If you need full precision for floating point numbers, define `MRB_WORDBOX_NO_FLOAT_TRUNCATE`. +If you need full precision for floating-point numbers, define `MRB_WORDBOX_NO_FLOAT_TRUNCATE`. ## NaN Boxing -NaN boxing packs the Ruby data in a floating point numbers, which represent NaN (Not a Number) values. Under IEEE753 definitions every value that exponent is all set are considered as NaN. That means NaN can represent `2^51` values. NaN boxing is a teaching to pack the values in those NaN representation. In theory, 64 bits pointers are too big to fit in NaN, but practically most OS uses only 48 bits at most for pointers (except for some OS e.g. Solaris). +NaN boxing packs the Ruby data in a floating-point numbers, which represent NaN (Not a Number) values. Under IEEE753 definitions every value that exponent is all set are considered as NaN. That means NaN can represent `2^51` values. NaN boxing is a teaching to pack the values in those NaN representation. In theory, 64 bits pointers are too big to fit in NaN, but practically most OS uses only 48 bits at most for pointers (except for some OS e.g. Solaris). The NaN boxing packing bit patterns are like following: -| Types | Bit Pattern | -|--------|-------------------------------------------------------------------------| -| 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 | -| fixnum | 01111111 11111001 00000000 00000000 IIIIIIII IIIIIIII IIIIIIII IIIIIIII | -| symbol | 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 | -| nil | 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | - -The object values appear far more frequently than floating point numbers, so we offset the value so that object pointers are unchanged. This technique is called "favor pointer"". +| Types | Bit Pattern | +|--------|---------------------------------------------------------------------------| +| 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` | +| fixnum | `01111111 11111001 00000000 00000000 IIIIIIII IIIIIIII IIIIIIII IIIIIIII` | +| symbol | `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` | +| nil | `00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000` | + +The object values appear far more frequently than floating-point numbers, so we offset the value so that object pointers are unchanged. This technique is called "favor pointer". ## No Boxing diff --git a/mruby/doc/internal/opcode.md b/mruby/doc/internal/opcode.md index 11f2133c..7effcce4 100644 --- a/mruby/doc/internal/opcode.md +++ b/mruby/doc/internal/opcode.md @@ -7,122 +7,130 @@ reducing the memory consumption of mruby VM. # Instructions Instructions are bytes. There can be 256 instructions. Currently, we -have 94 instructions. Instructions can take 0 to 3 operands. +have 106 instructions. Instructions can take 0 to 3 operands. ## operands The size of operands can be either 8bits, 16bits or 24bits. -In the table.1 below, the second field describes the size (and -sign) of operands. +In the table.1 below, the second field describes the size +of operands. -* B: 8bit -* S: 16bit -* sS: signed 16bit -* W: 24bit +- B: 8bit +- S: 16bit +- W: 24bit + +If the first and second operands are of type `B` (8bits), they may be +extended to 16bits by the operand extension instruction immediately +preceding them. +See also `OP_EXT1`, `OP_EXT2` and `OP_EXT3`. ## 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_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_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(b)[c] = R(a)` | -| `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` | -|------------------|--------------|----------------------------------------------------------| +| 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_GETIDX` | `B` | `R(a) = R(a)[R(a+1)]` | +| `OP_SETIDX` | `B` | `R(a)[R(a+1)] = R(a+2)` | +| `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_SSEND` | `BBB` | `R(a) = self.send(Syms(b),R(a+1)..,R(a+n+1):R(a+n+2)..) (c=n\|k<<4)` | +| `OP_SSENDB` | `BBB` | `R(a) = self.send(Syms(b),R(a+1)..,R(a+n+1):R(a+n+2)..,&R(a+n+2k+1))` | +| `OP_SEND` | `BBB` | `R(a) = R(a).send(Syms(b),R(a+1)..,R(a+n+1):R(a+n+2)..) (c=n\|k<<4)` | +| `OP_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))` | +| `OP_CALL` | `-` | `self.call(*, **, &) (But overlay the current call frame; tailcall)` | +| `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_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_ARYSPLAT` | `B` | `R(a) = ary_splat(R(a))` | +| `OP_AREF` | `BBB` | `R(a) = R(b)[c]` | +| `OP_ASET` | `BBB` | `R(b)[c] = R(a)` | +| `OP_APOST` | `BBB` | `*R(a),R(a+1)..R(a+c) = R(a)[b..]` | +| `OP_INTERN` | `B` | `R(a) = intern(R(a))` | +| `OP_SYMBOL` | `BB` | `R(a) = intern(Pool(b))` | +| `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 (a) 16bit` | +| `OP_EXT2` | `-` | `make 2nd operand (b) 16bit` | +| `OP_EXT3` | `-` | `make 1st and 2nd operands 16bit` | +| `OP_STOP` | `-` | `stop VM` | diff --git a/mruby/doc/limitations.md b/mruby/doc/limitations.md index 3364e704..ae09ecf3 100644 --- a/mruby/doc/limitations.md +++ b/mruby/doc/limitations.md @@ -107,10 +107,10 @@ true The declaration form of following visibility methods are not implemented. -* `public` -* `private` -* `protected` -* `module_function` +- `public` +- `private` +- `protected` +- `module_function` Especially, `module_function` method is not dummy, but no declaration form. @@ -199,7 +199,7 @@ The re-defined `+` operator does not accept any arguments. ` 'ab' ` Behavior of the operator wasn't changed. -## `Kernel#binding` is not supported +## `Kernel#binding` is not supported until [3.0.0 (2021-03-05)] `Kernel#binding` method is not supported. @@ -210,7 +210,7 @@ $ ruby -e 'puts Proc.new {}.binding' # ``` -#### mruby [3.1.0 (2022-05-12)] +#### mruby [3.0.0 (2021-03-05)] ``` $ ./bin/mruby -e 'puts Proc.new {}.binding' @@ -219,6 +219,12 @@ trace (most recent call last): -e:1: undefined method 'binding' (NoMethodError) ``` +#### mruby [3.1.0 (2022-05-12)] + +`binding` has been supported since 3.1.0. + +See also [mrbgems/mruby-binding](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-binding) and [mrbgems/mruby-binding-core](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-binding-core). + ## `nil?` redefinition in conditional expressions Redefinition of `nil?` is ignored in conditional expressions. @@ -231,7 +237,7 @@ end puts(a.nil? ? "truthy" : "falsy") ``` -Ruby outputs `falsy`. mruby outputs `truthy`. +Ruby outputs `truthy`. mruby outputs `falsy`. ## Argument Destructuring diff --git a/mruby/doc/mruby3.0.md b/mruby/doc/mruby3.0.md index 09d2c4af..c1acb5ec 100644 --- a/mruby/doc/mruby3.0.md +++ b/mruby/doc/mruby3.0.md @@ -7,17 +7,17 @@ Typical build configuration files are located in `build_config` directory. For examples: -* `default`: the default configuration -* `host-gprof`: compiles with `gprof` for performance tuning -* `host-m32`: compiles in gcc 32bit mode on 64bit platforms -* `boxing`: compiles all three boxing options -* `clang-asan`: compiles with `clang`'s Address Sanitizer +- `default`: the default configuration +- `host-gprof`: compiles with `gprof` for performance tuning +- `host-m32`: compiles in gcc 32bit mode on 64bit platforms +- `boxing`: compiles all three boxing options +- `clang-asan`: compiles with `clang`'s Address Sanitizer You can specify the build configuration file with the `MRUBY_CONFIG` environment variable (or `CONFIG` in short). If the value specified by `MRUBY_CONFIG` is not the path to the configuration file, `build_config/${MRUBY_CONFIG}.rb` is -used. So you can specify it as `rake MRUBY_CONFIG=boxing`, +used. So you can specify it as `rake MRUBY_CONFIG=boxing`, for example. # Build Configuration Contribution @@ -32,10 +32,10 @@ pull-request. We have ported some new syntax from CRuby. -* Single line pattern matching (`12 => x`); +- Single line pattern matching (`12 => x`); mruby matches only with local variables at the moment -* Numbered block parameter (`x.map{_1 * 2}`) -* End-less `def` (`def double(x) = x*2`) +- Numbered block parameter (`x.map{_1 * 2}`) +- End-less `def` (`def double(x) = x*2`) # Configuration Options Changed @@ -59,11 +59,11 @@ Some configuration macro names are changed for consistency (use `MRB_USE_XXX` | `ENABLE_READLINE` | `MRB_USE_READLINE` | | `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`. -* `MRB_USE_METHOD_T_STRUCT` uses `struct` version of `mrb_method_t`. More +- `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`. +- `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. +- `MRB_` prefix is added to those without. ## `MRB_NO_BOXING` @@ -75,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 +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 pointer number. Nothing +Pack `mrb_value` in a floating-point number. Nothing changed from previous versions. ## `MRB_USE_MALLOC_TRIM` @@ -112,40 +112,40 @@ $ bin/mruby -r lib1.rb -r lib2.rb < app.mrb Instructions that access pool[i]/syms[i] where i>255. -* `OP_LOADL16` -* `OP_STRING16` -* `OP_LOADSYM16` +- `OP_LOADL16` +- `OP_STRING16` +- `OP_LOADSYM16` -Instructions that load a 32 bit integer. +Instructions that load a 32-bit integer. -* `OP_LOADI32` +- `OP_LOADI32` Instruction that unwinds jump table for rescue/ensure. -* `OP_JMPUW` +- `OP_JMPUW` Renamed from `OP_RAISE` -* `OP_RAISEIF` +- `OP_RAISEIF` Instruction that is reserved for the future keyword argument support. -* OP_SENDVK +- OP_SENDVK ## Removed Instructions Instructions for old exception handling -* `OP_ONERR` -* `OP_POPERR` -* `OP_EPUSH` -* `OP_EPOP` +- `OP_ONERR` +- `OP_POPERR` +- `OP_EPUSH` +- `OP_EPOP` No more operand extension -* `OP_EXT1` -* `OP_EXT2` -* `OP_EXT3` +- `OP_EXT1` +- `OP_EXT2` +- `OP_EXT3` ## Changed Instructions diff --git a/mruby/doc/mruby3.1.md b/mruby/doc/mruby3.1.md index 158b8ea7..188cc836 100644 --- a/mruby/doc/mruby3.1.md +++ b/mruby/doc/mruby3.1.md @@ -155,12 +155,12 @@ Now takes 2 operands and pushes multiple entries to an array. ### 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. +`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. +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 allocate integer values in the heap, if the value does not fit in the 32 bit range, just like we did in Word Boxing. diff --git a/mruby/doc/mruby3.2.md b/mruby/doc/mruby3.2.md new file mode 100644 index 00000000..1ca18d6b --- /dev/null +++ b/mruby/doc/mruby3.2.md @@ -0,0 +1,80 @@ +# User visible changes in `mruby3.2` from `mruby3.1` + +# The language + +- Now `a::B = c` should evaluate `a` then `c`. +- Anonymous arguments `*`, `**`, `&` can be passed for forwarding. +- Multi-precision integer is available now via `mruby-bigint` gem. + +# mruby VM and bytecode + +- `OP_ARYDUP` was renamed to `OP_ARYSPLAT`. The instruction name + was changed but instruction number and basic behavior have not + changed (except that `ARYDUP nil` makes `[]`). + +# Tools + +## `mruby` + +- `-b` only specifies the script is the binary. The files loaded by `-r` are not affected by the option. +- `mruby` now loads complied binary if the suffix is `.mrb`. + +## `mrbc` + +- Add `--no-optimize` option to disable optimization. + +# mrbgems + +## mruby-class-ext + +- Add `Class#subclasses` method. +- Add `Module#undefined_instance_methods` method. + +## New bundled gems + +- mruby-errno from [https://github.com/iij/mruby-errno.git] +- mruby-set from [https://github.com/yui-knk/mruby-set.git] +- mruby-dir from [https://github.com/iij/mruby-dir.git] +- mruby-data + +# Breaking Changes + +## `mrb_vm_run()` may detach top-level local variables referenced from blocks + +When the `mrb_vm_run()` function (including `mrb_top_run()`) is called, +the previous top-level local variables referenced from blocks is detached under either of the following conditions. + +- If the `stack_keep` parameter is given as 0. +- If the number of variables in `irep` to be executed is less than the number of previous top-level local variables. + +This change also affects API functions such as `mrb_load_string()` and `mrb_load_file()`. +The conditions under which the previous top-level local variables referenced from blocks is detached in these functions are as follows: + +- If the function has no `mrbc_context` pointer parameter, or the `mrbc_context` pointer parameter is set to `NULL`. +- If the number of variables held in the `mrbc_context` pointer is less than the number of previous top-level local variables. + +Intentional reliance on previous behavior may cause compatibility problems in your application. + +# CVEs + +Following CVEs are fixed. + +- [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080) +- [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240) +- [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326) +- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) +- [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481) +- [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525) +- [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570) +- [CVE-2022-0614](https://nvd.nist.gov/vuln/detail/CVE-2022-0614) +- [CVE-2022-0623](https://nvd.nist.gov/vuln/detail/CVE-2022-0623) +- [CVE-2022-0630](https://nvd.nist.gov/vuln/detail/CVE-2022-0630) +- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) +- [CVE-2022-0632](https://nvd.nist.gov/vuln/detail/CVE-2022-0632) +- [CVE-2022-0717](https://nvd.nist.gov/vuln/detail/CVE-2022-0717) +- [CVE-2022-0890](https://nvd.nist.gov/vuln/detail/CVE-2022-0890) +- [CVE-2022-1106](https://nvd.nist.gov/vuln/detail/CVE-2022-1106) +- [CVE-2022-1212](https://nvd.nist.gov/vuln/detail/CVE-2022-1212) +- [CVE-2022-1276](https://nvd.nist.gov/vuln/detail/CVE-2022-1276) +- [CVE-2022-1286](https://nvd.nist.gov/vuln/detail/CVE-2022-1286) +- [CVE-2022-1934](https://nvd.nist.gov/vuln/detail/CVE-2022-1934) diff --git a/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md b/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md index 0b428b0b..7678da41 100644 --- a/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md +++ b/mruby/examples/mrbgems/c_and_ruby_extension_example/README.md @@ -1,4 +1,3 @@ -C and Ruby Extension Example -========= +# C and Ruby Extension Example This is an example gem which implements a C and Ruby extension. diff --git a/mruby/examples/mrbgems/c_extension_example/README.md b/mruby/examples/mrbgems/c_extension_example/README.md index 3803c206..87ec7bc7 100644 --- a/mruby/examples/mrbgems/c_extension_example/README.md +++ b/mruby/examples/mrbgems/c_extension_example/README.md @@ -1,4 +1,3 @@ -C Extension Example -========= +# C Extension Example This is an example gem which implements a C extension. diff --git a/mruby/examples/mrbgems/cdata_extension_example/README.md b/mruby/examples/mrbgems/cdata_extension_example/README.md new file mode 100644 index 00000000..1739b63e --- /dev/null +++ b/mruby/examples/mrbgems/cdata_extension_example/README.md @@ -0,0 +1,3 @@ +# C Data Extension Example + +This is an example gem which implements a C extension with Data. diff --git a/mruby/examples/mrbgems/cdata_extension_example/mrbgem.rake b/mruby/examples/mrbgems/cdata_extension_example/mrbgem.rake new file mode 100644 index 00000000..b642d0fa --- /dev/null +++ b/mruby/examples/mrbgems/cdata_extension_example/mrbgem.rake @@ -0,0 +1,23 @@ +MRuby::Gem::Specification.new('cdata_extension_example') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + + # Add compile flags + # spec.cc.flags << '-g' + + # Add cflags to all + # spec.mruby.cc.flags << '-g' + + # Add libraries + # spec.linker.libraries << 'external_lib' + + # Default build files + # spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb") + # spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb") + # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) } + # spec.test_preload = 'test/assert.rb' + + # Values accessible as TEST_ARGS inside test scripts + # spec.test_args = {'tmp_dir' => Dir::tmpdir} +end diff --git a/mruby/examples/mrbgems/cdata_extension_example/src/example.c b/mruby/examples/mrbgems/cdata_extension_example/src/example.c new file mode 100644 index 00000000..ac5593e7 --- /dev/null +++ b/mruby/examples/mrbgems/cdata_extension_example/src/example.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include + +static void mrb_foo_free(mrb_state *mrb, void *ptr) { + /* custom destructor */ + mrb_free(mrb, ptr); +} +struct mrb_data_type mrb_foo_type = { "Foo", mrb_foo_free }; + +struct Foo { + int bar; + char baz[32]; +}; + +static mrb_value +mrb_foo_initialize(mrb_state *mrb, mrb_value self) +{ + struct Foo *f; + + f = (struct Foo*)mrb_malloc(mrb, sizeof(struct Foo)); + f->bar = 0; + + DATA_PTR(self) = f; + DATA_TYPE(self) = &mrb_foo_type; + + return self; +} + +static mrb_value +mrb_foo_get_bar(mrb_state *mrb, mrb_value self) +{ + struct Foo *f; + + f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type); + if(f == NULL) { + mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data"); + } + + return mrb_fixnum_value(f->bar); +} + +static mrb_value +mrb_foo_set_bar(mrb_state *mrb, mrb_value self) +{ + struct Foo *f; + int v; + + f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type); + if(f == NULL) { + mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data"); + } + + mrb_get_args(mrb, "i", &v); + + f->bar = v; + + return mrb_fixnum_value(f->bar); +} + +void +mrb_cdata_extension_example_gem_init(mrb_state* mrb) { + struct RClass *class_foo; + + class_foo = mrb_define_class(mrb, "Foo", mrb->object_class); + MRB_SET_INSTANCE_TT(class_foo, MRB_TT_CDATA); + mrb_define_method(mrb, class_foo, "initialize", mrb_foo_initialize, MRB_ARGS_NONE()); + mrb_define_method(mrb, class_foo, "bar", mrb_foo_get_bar, MRB_ARGS_NONE()); + mrb_define_method(mrb, class_foo, "bar=", mrb_foo_set_bar, MRB_ARGS_REQ(1)); +} + +void +mrb_cdata_extension_example_gem_final(mrb_state* mrb) { + /* gem finalizer */ +} diff --git a/mruby/examples/mrbgems/cdata_extension_example/test/example.c b/mruby/examples/mrbgems/cdata_extension_example/test/example.c new file mode 100644 index 00000000..271de626 --- /dev/null +++ b/mruby/examples/mrbgems/cdata_extension_example/test/example.c @@ -0,0 +1,7 @@ +#include + +void +mrb_cdata_extension_example_gem_test(mrb_state *mrb) +{ + /* test initializer in C */ +} diff --git a/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md b/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md new file mode 100644 index 00000000..4027df96 --- /dev/null +++ b/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md @@ -0,0 +1,39 @@ +# Hints for creating your own bigint GEM + +This example gem, mruby-YOUR-bigint, is available under the Creative Commons Zero License (CC0). + +This file is placed for the purpose of describing hints for creating a `mruby-bigint` compatible GEM to realize multiple integers. + +The file structure in this example is as follows: + +``` ++- mruby-YOUR-bigint/ <- Make this directory public if necessary. + | Change the name of copied directory. + | + +- TODO-HINT.md <- This file is currently viewing by you. + | Remove this from copied directory. + | + +- core/ + | | + | +- bigint.c <- Body of the implementation. + | + +- mrbgem.rake <- GEM name is "mruby-bigint". + May be depended on by other GEMs. +``` + +Implementors of own bigints should copy below this directory to another directory and do the following: + +- Rewrite `spec.author`, `spec.license`, `spec.homepage` and `spec.summary` in `/mrbgem.rake` file to those of your own implementors. +- Implement the respective functions in `/core/bigint.c`. + - Define and use an object structure for `MRB_TT_BIGINT` type-tag. + It is recommended to use `mrb_static_assert_object_size()` to ensure that the size of the object structure is within 6 words. +- Delete this file from the destination of the copy. + +If you wish to use it as an alternative to the `mruby-bigint` provided by mruby, please leave the GEM name in `/mrbgem.rake` as it is. +This is an important factor when it is depended from other GEMs with `spec.add_dependency 'mruby-bigint'`. + +The name of the top directory of GEM can be changed arbitrarily. +The name of the git repository can also be changed arbitrarily. + +Note that there is no need for an initialization function as there is in normal GEM. +If you need it, create a file `/src/bigint.c` for example, and implement the `mrb_mruby_bigint_gem_init()` function. diff --git a/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c b/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c new file mode 100644 index 00000000..3cfc717b --- /dev/null +++ b/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c @@ -0,0 +1,70 @@ +/* + * If placed under the "mruby/examples/mrbgems/mruby-YOUR-bigint" directory, + * this file is available under the Creative Commons Zero License (CC0). + * Note that file is incomplete. + * + * TODO: If this file is copied and another implementation is written, + * remove this comment block from the copied file. + */ + +#include +#include + +/* + * The "mruby/internal.h" file should be placed after the other mruby header files. + */ +#include + +/* + * The "mruby/presym.h" file is placed at the end of the mruby header file. + */ +#include + +/* + * Define your own struct RBigint. + * + * - Object type must be MRB_TT_BIGINT. + * - If the structure is named RBigint, MRB_OBJ_ALLOC() can be used as is. + */ +struct RBigint { + /* + * Put MRB_OBJECT_HEADER before the first member of the structure. + */ + MRB_OBJECT_HEADER; + + /* + * Up to 3 words can be freely configured. + */ + size_t len; + size_t capa; + uintptr_t *num; +}; + +/* + * Assert with mrb_static_assert_object_size() that the entire structure is within 6 words. + */ +mrb_static_assert_object_size(struct RBigint); + +/* + * The lower 16 bits of the object flags (`obj->flags`) can be used freely by the GEM author. + */ +#define MY_BIGINT_NEGATIVE_FLAG 1 +#define MY_BIGINT_NEGATIVE_P(obj) ((obj)->flags & MY_BIGINT_NEGATIVE_FLAG) + +/* + * Implement the functions declared in `#ifdef MRUBY_USE_BIGINT ... #endif` in the "mruby/internal.h" file. + */ + +mrb_value +mrb_bint_new_int(mrb_state *mrb, mrb_int x) +{ + struct RBigint *obj = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class); + + ... + + return mrb_obj_value(obj); +} + +/* + * The implementation function continues... + */ diff --git a/mruby/examples/mrbgems/mruby-YOUR-bigint/mrbgem.rake b/mruby/examples/mrbgems/mruby-YOUR-bigint/mrbgem.rake new file mode 100644 index 00000000..9695a3f8 --- /dev/null +++ b/mruby/examples/mrbgems/mruby-YOUR-bigint/mrbgem.rake @@ -0,0 +1,12 @@ +MRuby::Gem::Specification.new('mruby-bigint') do |spec| + spec.author = 'YOUR-NAME-HERE' + spec.license = 'YOUR-LICENSE-HERE' + spec.summary = 'Yet another multi-precision Integer extension' + spec.homepage = 'https://gem.example/for/mruby-YOUR-bigint' + spec.build.defines << 'MRB_USE_BIGINT' + #spec.build.linker.libraries << 'gmp' # when uses libgmp + + spec.build.libmruby_core_objs << Dir.glob(File.join(__dir__, 'core/**/*.c')).map { |fn| + objfile(fn.relative_path_from(__dir__).pathmap("#{spec.build_dir}/%X")) + } +end diff --git a/mruby/examples/mrbgems/ruby_extension_example/README.md b/mruby/examples/mrbgems/ruby_extension_example/README.md index 906a0d8f..9f383d67 100644 --- a/mruby/examples/mrbgems/ruby_extension_example/README.md +++ b/mruby/examples/mrbgems/ruby_extension_example/README.md @@ -1,4 +1,3 @@ -Pure Ruby Extension Example -========= +# Pure Ruby Extension Example This is an example gem which implements a pure Ruby extension. diff --git a/mruby/include/mrbconf.h b/mruby/include/mrbconf.h index e11a55e8..1629a5c4 100644 --- a/mruby/include/mrbconf.h +++ b/mruby/include/mrbconf.h @@ -46,6 +46,7 @@ //#define MRB_NO_METHOD_CACHE /* size of the method cache (need to be the power of 2) */ //#define MRB_METHOD_CACHE_SIZE (1<<8) +//#define MRB_USE_INLINE_METHOD_CACHE /* add -DMRB_USE_METHOD_T_STRUCT on machines that use higher bits of function pointers */ /* no MRB_USE_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */ @@ -107,6 +108,16 @@ /* string class to handle UTF-8 encoding */ //#define MRB_UTF8_STRING +/* maximum length of strings */ +/* the default value is 1MB */ +/* set this value to zero to skip the check */ +//#define MRB_STR_LENGTH_MAX 1048576 + +/* maximum length of arrays */ +/* the default value is 2**17 entries */ +/* set this value to zero to skip the check */ +//#define MRB_ARY_LENGTH_MAX 131072 + /* argv max size in mrb_funcall */ //#define MRB_FUNCALL_ARGC_MAX 16 diff --git a/mruby/include/mruby.h b/mruby/include/mruby.h index 3e92021a..2d96b25e 100644 --- a/mruby/include/mruby.h +++ b/mruby/include/mruby.h @@ -1,7 +1,7 @@ /* ** mruby - An embeddable Ruby implementation ** -** Copyright (c) mruby developers 2010-2021 +** Copyright (c) mruby developers 2010-2023 ** ** Permission is hereby granted, free of charge, to any person obtaining ** a copy of this software and associated documentation files (the @@ -154,7 +154,7 @@ typedef uint8_t mrb_code; */ typedef uint32_t mrb_aspec; -struct mrb_irep; +typedef struct mrb_irep mrb_irep; struct mrb_state; /** @@ -178,6 +178,7 @@ typedef struct { uint8_t cci; /* called from C function */ mrb_sym mid; const struct RProc *proc; + struct RProc *blk; mrb_value *stack; const mrb_code *pc; /* current address on iseq of this proc */ union { @@ -312,7 +313,7 @@ typedef struct mrb_state { struct RClass *eException_class; struct RClass *eStandardError_class; struct RObject *nomem_err; /* pre-allocated NoMemoryError */ - struct RObject *stack_err; /* pre-allocated SysStackError */ + struct RObject *stack_err; /* pre-allocated SystemStackError */ #ifdef MRB_GC_FIXED_ARENA struct RObject *arena_err; /* pre-allocated arena overflow error */ #endif @@ -361,7 +362,18 @@ MRB_API struct RClass *mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name); MRB_API struct RClass *mrb_define_module_id(mrb_state *mrb, mrb_sym name); +/** + * Returns the singleton class of an object. + * + * Raises a `TypeError` exception for immediate values. + */ MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val); + +/** + * Returns the singleton class of an object. + * + * Returns `NULL` for immediate values, + */ MRB_API struct RClass *mrb_singleton_class_ptr(mrb_state *mrb, mrb_value val); /** @@ -686,9 +698,9 @@ MRB_API struct RClass * mrb_module_new(mrb_state *mrb); * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); * cd = mrb_class_defined(mrb, "ExampleClass"); * - * // If mrb_class_defined returns 1 then puts "True" - * // If mrb_class_defined returns 0 then puts "False" - * if (cd == 1){ + * // If mrb_class_defined returns TRUE then puts "True" + * // If mrb_class_defined returns FALSE then puts "False" + * if (cd) { * puts("True"); * } * else { @@ -735,9 +747,9 @@ MRB_API struct RClass* mrb_exc_get_id(mrb_state *mrb, mrb_sym name); * example_inner = mrb_define_class_under(mrb, example_outer, "ExampleInner", mrb->object_class); * cd = mrb_class_defined_under(mrb, example_outer, "ExampleInner"); * - * // If mrb_class_defined_under returns 1 then puts "True" - * // If mrb_class_defined_under returns 0 then puts "False" - * if (cd == 1){ + * // If mrb_class_defined_under returns TRUE then puts "True" + * // If mrb_class_defined_under returns FALSE then puts "False" + * if (cd) { * puts("True"); * } * else { @@ -821,14 +833,14 @@ MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj); * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); * mrb_define_method(mrb, example_class, "example_method", exampleMethod, MRB_ARGS_NONE()); * mid = mrb_intern_str(mrb, mrb_str_new_lit(mrb, "example_method" )); - * obj_resp = mrb_obj_respond_to(mrb, example_class, mid); // => 1(true in Ruby world) + * obj_resp = mrb_obj_respond_to(mrb, example_class, mid); // => TRUE (true in Ruby world) * - * // If mrb_obj_respond_to returns 1 then puts "True" - * // If mrb_obj_respond_to returns 0 then puts "False" - * if (obj_resp == 1) { + * // If mrb_obj_respond_to returns TRUE then puts "True" + * // If mrb_obj_respond_to returns FALSE then puts "False" + * if (obj_resp) { * puts("True"); * } - * else if (obj_resp == 0) { + * else { * puts("False"); * } * } @@ -948,14 +960,14 @@ typedef const char *mrb_args_format; /** * Get keyword arguments by `mrb_get_args()` with `:` specifier. * - * `mrb_kwargs::num` indicates that the number of keyword values. + * `mrb_kwargs::num` indicates that the total number of keyword values. * - * `mrb_kwargs::values` is an object array, and the keyword argument corresponding to the string array is assigned. - * Note that `undef` is assigned if there is no keyword argument corresponding to `mrb_kwargs::optional`. + * `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the `mrb_sym` array are required. * - * `mrb_kwargs::table` accepts a string array. + * `mrb_kwargs::table` accepts a `mrb_sym` array of C. * - * `mrb_kwargs::required` indicates that the specified number of keywords starting from the beginning of the string array are required. + * `mrb_kwargs::values` is an object array of C, and the keyword argument corresponding to the `mrb_sym` array is assigned. + * Note that `undef` is assigned if there is no keyword argument corresponding over `mrb_kwargs::required` to `mrb_kwargs::num`. * * `mrb_kwargs::rest` is the remaining keyword argument that can be accepted as `**rest` in Ruby. * If `NULL` is specified, `ArgumentError` is raised when there is an undefined keyword. @@ -964,11 +976,11 @@ typedef const char *mrb_args_format; * * // def method(a: 1, b: 2) * - * uint32_t kw_num = 2; - * const char *kw_names[kw_num] = { "a", "b" }; - * uint32_t kw_required = 0; + * mrb_int kw_num = 2; + * mrb_int kw_required = 0; + * mrb_sym kw_names[] = { mrb_intern_lit(mrb, "a"), mrb_intern_lit(mrb, "b") }; * mrb_value kw_values[kw_num]; - * const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL }; + * mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, NULL }; * * mrb_get_args(mrb, ":", &kwargs); * if (mrb_undef_p(kw_values[0])) { kw_values[0] = mrb_fixnum_value(1); } @@ -979,10 +991,12 @@ typedef const char *mrb_args_format; * * mrb_value str, kw_rest; * uint32_t kw_num = 3; - * const mrb_sym kw_names[kw_num] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) }; * uint32_t kw_required = 1; + * // Note that `#include ` is required beforehand because `MRB_SYM()` is used. + * // If the usage of `MRB_SYM()` is not desired, replace it with `mrb_intern_lit()`. + * mrb_sym kw_names[] = { MRB_SYM(x), MRB_SYM(y), MRB_SYM(z) }; * mrb_value kw_values[kw_num]; - * const mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest }; + * mrb_kwargs kwargs = { kw_num, kw_required, kw_names, kw_values, &kw_rest }; * * mrb_get_args(mrb, "S:", &str, &kwargs); * // or: mrb_get_args(mrb, ":S", &kwargs, &str); @@ -993,8 +1007,8 @@ typedef struct mrb_kwargs mrb_kwargs; struct mrb_kwargs { - uint32_t num; /* number of keyword arguments */ - uint32_t required; /* number of required keyword arguments */ + mrb_int num; /* number of keyword arguments */ + mrb_int required; /* number of required keyword arguments */ const mrb_sym *table; /* C array of symbols for keyword names */ mrb_value *values; /* keyword argument values */ mrb_value *rest; /* keyword rest (dict) */ @@ -1012,6 +1026,13 @@ struct mrb_kwargs */ MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...); +/** + * Array version of mrb_get_args() + * + * @param ptr Array of void*, in the same order as the varargs version. + */ +MRB_API mrb_int mrb_get_args_a(mrb_state *mrb, mrb_args_format format, void** ptr); + MRB_INLINE mrb_sym mrb_get_mid(mrb_state *mrb) /* get method symbol */ { @@ -1178,13 +1199,13 @@ MRB_API void mrb_free(mrb_state*, void*); */ #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); +MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, mrb_int len); /** * Turns a C string into a Ruby string value. */ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*); -MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len); +MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, mrb_int len); #define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit)) MRB_API mrb_value mrb_obj_freeze(mrb_state*, mrb_value); @@ -1336,7 +1357,7 @@ MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self); #define TOLOWER(c) (ISUPPER(c) ? ((c) | 0x20) : (c)) #endif -MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len); +MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, mrb_int len); MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc); MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg); @@ -1404,6 +1425,9 @@ MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value 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) +/* check if val is an integer (including Bigint) */ +MRB_API mrb_value mrb_ensure_integer_type(mrb_state *mrb, mrb_value val); +/* check if val fit in mrb_int */ MRB_API mrb_value mrb_ensure_int_type(mrb_state *mrb, mrb_value val); #define mrb_as_int(mrb, val) mrb_integer(mrb_ensure_int_type(mrb, val)) /* obsolete: use mrb_ensure_int_type() instead */ @@ -1436,6 +1460,10 @@ MRB_API mrb_bool mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mr * Resume a Fiber * * Implemented in mruby-fiber + * + * Switches to the specified fiber and executes. Like the `Fiber#resume` method. + * + * @note It can only be called before entering the mruby VM (e.g. in the `main()` function). */ MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int argc, const mrb_value *argv); @@ -1443,6 +1471,15 @@ MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int argc, * Yield a Fiber * * Implemented in mruby-fiber + * + * Passes control to the caller fiber of the running fiber. Like the `Fiber.yield` method. + * + * @note This function is only available from inside a function defined as a method by, + * for example, `mrb_define_method()`. + * Also, the work following `mrb_fiber_yield()` cannot be performed, + * and the return value of `mrb_fiber_yield()` must be returned as is. + * + * return mrb_fiber_yield(mrb, argc, argv); */ MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int argc, const mrb_value *argv); diff --git a/mruby/include/mruby/array.h b/mruby/include/mruby/array.h index 8bb65247..df5a16a9 100644 --- a/mruby/include/mruby/array.h +++ b/mruby/include/mruby/array.h @@ -85,7 +85,6 @@ struct RArray { #define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED) #define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED) -void mrb_ary_decref(mrb_state*, mrb_shared_array*); MRB_API void mrb_ary_modify(mrb_state*, struct RArray*); MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int); @@ -296,8 +295,6 @@ MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep); */ MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len); -/* helper functions */ -mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len); MRB_END_DECL diff --git a/mruby/include/mruby/boxing_word.h b/mruby/include/mruby/boxing_word.h index 3dff13e1..d3ca18eb 100644 --- a/mruby/include/mruby/boxing_word.h +++ b/mruby/include/mruby/boxing_word.h @@ -180,6 +180,8 @@ mrb_integer_func(mrb_value o) { #else #define mrb_float_p(o) WORDBOX_OBJ_TYPE_P(o, FLOAT) #endif +#else +#define mrb_float_p(o) FALSE #endif #define mrb_array_p(o) WORDBOX_OBJ_TYPE_P(o, ARRAY) #define mrb_string_p(o) WORDBOX_OBJ_TYPE_P(o, STRING) @@ -222,9 +224,7 @@ 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/mruby/include/mruby/class.h b/mruby/include/mruby/class.h index b97bc399..ff16f1ac 100644 --- a/mruby/include/mruby/class.h +++ b/mruby/include/mruby/class.h @@ -73,8 +73,6 @@ mrb_class(mrb_state *mrb, mrb_value v) #define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt))) #define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK) -struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); -struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, mrb_method_t); MRB_API void mrb_alias_method(mrb_state*, struct RClass *c, mrb_sym a, mrb_sym b); MRB_API void mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym sym); @@ -83,15 +81,6 @@ MRB_API mrb_method_t mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym); MRB_API mrb_method_t mrb_method_search(mrb_state*, struct RClass*, mrb_sym); MRB_API struct RClass* mrb_class_real(struct RClass* cl); -mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); - -void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym); -mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int); -mrb_value mrb_class_find_path(mrb_state*, struct RClass*); -mrb_value mrb_mod_to_s(mrb_state*, mrb_value); -void mrb_gc_mark_mt(mrb_state*, struct RClass*); -size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); -void mrb_gc_free_mt(mrb_state*, struct RClass*); #ifndef MRB_NO_METHOD_CACHE void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c); diff --git a/mruby/include/mruby/compile.h b/mruby/include/mruby/compile.h index 5c52a13a..70cf9a93 100644 --- a/mruby/include/mruby/compile.h +++ b/mruby/include/mruby/compile.h @@ -99,9 +99,9 @@ enum mrb_string_type { struct mrb_parser_heredoc_info { mrb_bool allow_indent:1; mrb_bool remove_indent:1; + mrb_bool line_head:1; size_t indent; mrb_ast_node *indented; - mrb_bool line_head:1; enum mrb_string_type type; const char *term; int term_len; @@ -127,7 +127,7 @@ struct mrb_parser_state { int column; enum mrb_lex_state_enum lstate; - mrb_ast_node *lex_strterm; /* (type nest_level beg . end) */ + struct parser_lex_strterm *lex_strterm; unsigned int cond_stack; unsigned int cmdarg_stack; @@ -143,10 +143,8 @@ struct mrb_parser_state { int tidx; int tsiz; - mrb_ast_node *all_heredocs; /* list of mrb_parser_heredoc_info* */ mrb_ast_node *heredocs_from_nextline; mrb_ast_node *parsing_heredoc; - mrb_ast_node *lex_strterm_before_heredoc; void *ylval; diff --git a/mruby/include/mruby/debug.h b/mruby/include/mruby/debug.h index 7319ccb3..4a62cce4 100644 --- a/mruby/include/mruby/debug.h +++ b/mruby/include/mruby/debug.h @@ -31,10 +31,11 @@ typedef struct mrb_irep_debug_info_file { uint32_t line_entry_count; mrb_debug_line_type line_type; union { + const char *s; void *ptr; - uint16_t *ary; - mrb_irep_debug_info_line *flat_map; - uint8_t *packed_map; + const uint16_t *ary; + const mrb_irep_debug_info_line *flat_map; + const uint8_t *packed_map; } lines; } mrb_irep_debug_info_file; diff --git a/mruby/include/mruby/dump.h b/mruby/include/mruby/dump.h index fea0ac2b..863f2264 100644 --- a/mruby/include/mruby/dump.h +++ b/mruby/include/mruby/dump.h @@ -21,15 +21,13 @@ MRB_BEGIN_DECL #define MRB_DUMP_STATIC 2 #define DUMP_DEBUG_INFO MRB_DUMP_DEBUG_INFO /* deprecated */ -int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); #ifndef MRB_NO_STDIO -int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*); -int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); -int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); -mrb_irep *mrb_read_irep_file(mrb_state*, FILE*); MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*); MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*); +mrb_irep *mrb_read_irep_file(mrb_state*, FILE*); +int mrb_dump_irep_binary(mrb_state*, const mrb_irep*, uint8_t, FILE*); #endif +/* avoid mrb_read_irep(); use mrb_read_irep_buf() instead (may cause buffer overflow) */ MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*); MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t); diff --git a/mruby/include/mruby/error.h b/mruby/include/mruby/error.h index 80c21434..ccf2cdb6 100644 --- a/mruby/include/mruby/error.h +++ b/mruby/include/mruby/error.h @@ -17,20 +17,24 @@ MRB_BEGIN_DECL struct RException { MRB_OBJECT_HEADER; struct iv_tbl *iv; - struct RString *mesg; + struct RObject *mesg; // NULL or probably RString + struct RObject *backtrace; // NULL, RArray or RData }; +/* error that should terminate execution */ +#define MRB_EXC_EXIT 65536 +#define MRB_EXC_EXIT_P(e) ((e)->flags & MRB_EXC_EXIT) +/* retrieve status value from exc; need and */ +#define MRB_EXC_EXIT_STATUS(mrb,e) ((int)mrb_as_int((mrb),mrb_obj_iv_get((mrb),(e),MRB_SYM(status)))) +/* exit with SystemExit status */ +#define MRB_EXC_CHECK_EXIT(mrb,e) do {if (MRB_EXC_EXIT_P(e)) exit(MRB_EXC_EXIT_STATUS((mrb),(e)));} while (0) + #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_noreturn 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); #define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) -#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_lit(mrb, c, lit) MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv); -mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); -mrb_value mrb_get_backtrace(mrb_state *mrb); - MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...); /* declaration for `fail` method */ @@ -70,39 +74,6 @@ mrb_break_value_set(struct RBreak *brk, mrb_value val) #define mrb_break_proc_get(brk) ((brk)->proc) #define mrb_break_proc_set(brk, p) ((brk)->proc = p) -#define RBREAK_TAG_FOREACH(f) \ - f(RBREAK_TAG_BREAK, 0) \ - f(RBREAK_TAG_BREAK_UPPER, 1) \ - f(RBREAK_TAG_BREAK_INTARGET, 2) \ - f(RBREAK_TAG_RETURN_BLOCK, 3) \ - f(RBREAK_TAG_RETURN, 4) \ - f(RBREAK_TAG_RETURN_TOPLEVEL, 5) \ - f(RBREAK_TAG_JUMP, 6) \ - f(RBREAK_TAG_STOP, 7) - -#define RBREAK_TAG_DEFINE(tag, i) tag = i, -enum { - RBREAK_TAG_FOREACH(RBREAK_TAG_DEFINE) -}; -#undef RBREAK_TAG_DEFINE - -#define RBREAK_TAG_BIT 3 -#define RBREAK_TAG_BIT_OFF 8 -#define RBREAK_TAG_MASK (~(~UINT32_C(0) << RBREAK_TAG_BIT)) - -static inline uint32_t -mrb_break_tag_get(struct RBreak *brk) -{ - return (brk->flags >> RBREAK_TAG_BIT_OFF) & RBREAK_TAG_MASK; -} - -static inline void -mrb_break_tag_set(struct RBreak *brk, uint32_t tag) -{ - brk->flags &= ~(RBREAK_TAG_MASK << RBREAK_TAG_BIT_OFF); - brk->flags |= (tag & RBREAK_TAG_MASK) << RBREAK_TAG_BIT_OFF; -} - /** * Protect * diff --git a/mruby/include/mruby/gc.h b/mruby/include/mruby/gc.h index 9f9bba41..ba56cefd 100644 --- a/mruby/include/mruby/gc.h +++ b/mruby/include/mruby/gc.h @@ -48,7 +48,8 @@ typedef struct mrb_heap_page { struct mrb_heap_page *free_next; struct mrb_heap_page *free_prev; mrb_bool old:1; - void *objects[]; + /* Flexible array members area a C99 feature, not C++ compatible */ + /* void* objects[]; */ } mrb_heap_page; #ifdef _MSC_VER @@ -84,8 +85,7 @@ typedef struct mrb_gc { size_t majorgc_old_threshold; } mrb_gc; -MRB_API mrb_bool -mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object); +MRB_API mrb_bool mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object); #define MRB_GC_RED 7 diff --git a/mruby/include/mruby/hash.h b/mruby/include/mruby/hash.h index 1b37a12d..e591172e 100644 --- a/mruby/include/mruby/hash.h +++ b/mruby/include/mruby/hash.h @@ -35,7 +35,6 @@ struct RHash { #define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v))) #define mrb_hash_value(p) mrb_obj_value((void*)(p)) -size_t mrb_hash_memsize(mrb_value obj); MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa); /* @@ -226,11 +225,6 @@ MRB_API void mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2); #define MRB_RHASH_DEFAULT_P(hash) (RHASH(hash)->flags & MRB_HASH_DEFAULT) #define MRB_RHASH_PROCDEFAULT_P(hash) (RHASH(hash)->flags & MRB_HASH_PROC_DEFAULT) -/* GC functions */ -void mrb_gc_mark_hash(mrb_state*, struct RHash*); -size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); -void mrb_gc_free_hash(mrb_state*, struct RHash*); - /* return non zero to break the loop */ typedef int (mrb_hash_foreach_func)(mrb_state *mrb, mrb_value key, mrb_value val, void *data); MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p); diff --git a/mruby/include/mruby/internal.h b/mruby/include/mruby/internal.h new file mode 100644 index 00000000..db64fd38 --- /dev/null +++ b/mruby/include/mruby/internal.h @@ -0,0 +1,208 @@ +/** +** @file mruby/internal.h - Functions only called from within the library +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_INTERNAL_H +#define MRUBY_INTERNAL_H + +#ifdef MRUBY_ARRAY_H +void mrb_ary_decref(mrb_state*, mrb_shared_array*); +mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len); +#endif + +#ifdef MRUBY_CLASS_H +struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); +struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); +mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); +void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym); +mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int); +mrb_value mrb_class_find_path(mrb_state*, struct RClass*); +mrb_value mrb_mod_to_s(mrb_state *, mrb_value); +void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); +mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); +mrb_method_t mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid); +#endif + +/* debug */ +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(const uint8_t *p, const uint8_t **newpos); + +/* dump */ +#ifdef MRUBY_IREP_H +int mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); +#ifndef MRB_NO_STDIO +int mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); +int mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep*, uint8_t flags, FILE *f, const char *initname); +#endif +#endif + +/* codedump */ +void mrb_codedump_all(mrb_state *mrb, struct RProc *proc); +#ifndef MRB_NO_STDIO +void mrb_codedump_all_file(mrb_state *mrb, struct RProc *proc, FILE *out); +#endif + +/* error */ +mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); +mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); +mrb_value mrb_get_backtrace(mrb_state *mrb); +void mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg); +mrb_value mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc); + +/* gc */ +void mrb_gc_mark_mt(mrb_state*, struct RClass*); +size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); +void mrb_gc_free_mt(mrb_state*, struct RClass*); + +/* hash */ +size_t mrb_hash_memsize(mrb_value obj); +void mrb_gc_mark_hash(mrb_state*, struct RHash*); +size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); +void mrb_gc_free_hash(mrb_state*, struct RHash*); + +/* irep */ +struct mrb_insn_data mrb_decode_insn(const mrb_code *pc); +#ifdef MRUBY_IREP_H +void mrb_irep_free(mrb_state*, struct mrb_irep*); +void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep); + +static inline const struct mrb_irep_catch_handler * +mrb_irep_catch_handler_table(const struct mrb_irep *irep) +{ + if (irep->clen > 0) { + return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen); + } + else { + return (const struct mrb_irep_catch_handler*)NULL; + } +} +#endif + +/* numeric */ +mrb_value mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_int mrb_div_int(mrb_int x, mrb_int y); +mrb_value mrb_int_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_noreturn void mrb_int_zerodiv(mrb_state *mrb); +mrb_noreturn void mrb_int_overflow(mrb_state *mrb, const char *reason); + +#ifdef MRB_USE_COMPLEX +mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y); +mrb_value mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y); +void mrb_complex_copy(mrb_state *mrb, mrb_value x, mrb_value y); +#endif +#ifdef MRB_USE_RATIONAL +mrb_value mrb_rational_new(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y); +void mrb_rational_copy(mrb_state *mrb, mrb_value x, mrb_value y); +#endif + +#ifdef MRUBY_PROC_H +struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*); +void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b); +mrb_int mrb_proc_arity(const struct RProc *p); +struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc); +#endif + +/* range */ +#ifdef MRUBY_RANGE_H +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)); +void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r); +#endif + +/* string */ +void mrb_gc_free_str(mrb_state*, struct RString*); +uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str); +mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); +mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); +mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); +mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); +mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len); +uint32_t mrb_byte_hash(const uint8_t*, mrb_int); +uint32_t mrb_byte_hash_step(const uint8_t*, mrb_int, uint32_t); + +#ifdef MRB_UTF8_STRING +mrb_int mrb_utf8len(const char *str, const char *end); +mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len); +#endif + +/* variable */ +mrb_value mrb_vm_special_get(mrb_state*, mrb_sym); +void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value); +mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); +void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); +mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); +void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); +size_t mrb_obj_iv_tbl_memsize(mrb_value); +mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*); +void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); +mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod); +mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); +mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value); +mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); +mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); +mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); +mrb_bool mrb_ident_p(const char *s, mrb_int len); + +/* GC functions */ +void mrb_gc_mark_gv(mrb_state*); +void mrb_gc_free_gv(mrb_state*); +void mrb_gc_mark_iv(mrb_state*, struct RObject*); +size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); +void mrb_gc_free_iv(mrb_state*, struct RObject*); + +/* VM */ +mrb_int mrb_ci_bidx(mrb_callinfo *ci); +mrb_int mrb_ci_nregs(mrb_callinfo *ci); +mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p); +mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value); +mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); +mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); + +#ifdef MRB_USE_BIGINT +mrb_value mrb_bint_new_int(mrb_state *mrb, mrb_int x); +mrb_value mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base); +mrb_value mrb_as_bint(mrb_state *mrb, mrb_value x); +mrb_value mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_mul(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_div(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_divmod(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_add_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_sub_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_div_ii(mrb_state *mrb, mrb_int x, mrb_int y); +mrb_value mrb_bint_mod(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_rem(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_pow(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_int y, mrb_value z); +mrb_value mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_or(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_rev(mrb_state *mrb, mrb_value x); +mrb_value mrb_bint_lshift(mrb_state *mrb, mrb_value x, mrb_int width); +mrb_value mrb_bint_rshift(mrb_state *mrb, mrb_value x, mrb_int width); +mrb_value mrb_bint_to_s(mrb_state *mrb, mrb_value x, mrb_int base); +#ifndef MRB_NO_FLOAT +mrb_value mrb_bint_new_float(mrb_state *mrb, mrb_float x); +mrb_float mrb_bint_as_float(mrb_state *mrb, mrb_value x); +#endif +mrb_int mrb_bint_as_int(mrb_state *mrb, mrb_value x); +mrb_int mrb_bint_cmp(mrb_state *mrb, mrb_value x, mrb_value y); +void mrb_gc_free_bint(mrb_state *mrb, struct RBasic *x); +void mrb_bint_copy(mrb_state *mrb, mrb_value x, mrb_value y); +size_t mrb_bint_memsize(mrb_value x); +mrb_value mrb_bint_hash(mrb_state *mrb, mrb_value x); +#endif + +#endif /* MRUBY_INTERNAL_H */ diff --git a/mruby/include/mruby/irep.h b/mruby/include/mruby/irep.h index 8382c3b1..ba390a05 100644 --- a/mruby/include/mruby/irep.h +++ b/mruby/include/mruby/irep.h @@ -52,7 +52,7 @@ struct mrb_irep_catch_handler { }; /* Program data array struct */ -typedef struct mrb_irep { +struct mrb_irep { uint16_t nlocals; /* Number of local variables */ uint16_t nregs; /* Number of register variables */ uint16_t clen; /* Number of catch handlers */ @@ -76,7 +76,7 @@ typedef struct mrb_irep { uint16_t plen, slen; uint16_t rlen; uint16_t refcnt; -} mrb_irep; +}; #define MRB_ISEQ_NO_FREE 1 #define MRB_IREP_NO_FREE 2 @@ -99,7 +99,7 @@ MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*); /* * @param [const void*] irep code - * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted. + * @param [size_t] size of irep buffer. */ MRB_API mrb_value mrb_load_irep_buf(mrb_state*, const void*, size_t); @@ -108,40 +108,25 @@ MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*); /* * @param [const void*] irep code - * @param [size_t] size of irep buffer. If -1 is given, it is considered unrestricted. + * @param [size_t] size of irep buffer. */ MRB_API mrb_value mrb_load_irep_buf_cxt(mrb_state*, const void*, size_t, mrbc_context*); -void mrb_irep_free(mrb_state*, struct mrb_irep*); -void mrb_irep_incref(mrb_state*, struct mrb_irep*); -void mrb_irep_decref(mrb_state*, struct mrb_irep*); -void mrb_irep_cutref(mrb_state*, struct mrb_irep*); -void mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep); - struct mrb_insn_data { uint8_t insn; - uint16_t a; + uint32_t a; uint16_t b; uint16_t c; const mrb_code *addr; }; -struct mrb_insn_data mrb_decode_insn(const mrb_code *pc); - -static inline const struct mrb_irep_catch_handler * -mrb_irep_catch_handler_table(const struct mrb_irep *irep) -{ - if (irep->clen > 0) { - return (const struct mrb_irep_catch_handler*)(irep->iseq + irep->ilen); - } - else { - return (const struct mrb_irep_catch_handler*)NULL; - } -} - #define mrb_irep_catch_handler_pack(n, v) uint32_to_bin(n, v) #define mrb_irep_catch_handler_unpack(v) bin_to_uint32(v) +void mrb_irep_incref(mrb_state*, struct mrb_irep*); +void mrb_irep_decref(mrb_state*, struct mrb_irep*); +void mrb_irep_cutref(mrb_state*, struct mrb_irep*); + MRB_END_DECL #endif /* MRUBY_IREP_H */ diff --git a/mruby/include/mruby/numeric.h b/mruby/include/mruby/numeric.h index aec46413..48adea3d 100644 --- a/mruby/include/mruby/numeric.h +++ b/mruby/include/mruby/numeric.h @@ -30,16 +30,17 @@ MRB_BEGIN_DECL #endif #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); +/* utility functions */ +MRB_API mrb_value mrb_num_add(mrb_state *mrb, mrb_value x, mrb_value y); +MRB_API mrb_value mrb_num_sub(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); +/* obsolete old names */ +#define mrb_num_plus(mrb, x, y) mrb_num_add(mrb, x, y) +#define mrb_num_minus(mrb, x, y) mrb_num_sub(mrb, x, 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) @@ -166,10 +167,6 @@ 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/mruby/include/mruby/object.h b/mruby/include/mruby/object.h index f75e99f1..a6ecab1e 100644 --- a/mruby/include/mruby/object.h +++ b/mruby/include/mruby/object.h @@ -40,4 +40,8 @@ struct RFiber { struct mrb_context *cxt; }; +#define mrb_static_assert_object_size(st) \ + mrb_static_assert(sizeof(st) <= sizeof(void*) * 6, \ + #st " size must be within 6 words") + #endif /* MRUBY_OBJECT_H */ diff --git a/mruby/include/mruby/ops.h b/mruby/include/mruby/ops.h index 7f3b77bf..cda796f0 100644 --- a/mruby/include/mruby/ops.h +++ b/mruby/include/mruby/ops.h @@ -61,7 +61,7 @@ OPCODE(SSEND, BBB) /* R[a] = self.send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n 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(CALL, Z) /* self.call(*, **, &) (But overlay the current call frame; tailcall) */ 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) */ @@ -87,7 +87,7 @@ 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(ARYSPLAT, B) /* R[a] = ary_splat(R[a]) */ OPCODE(AREF, BBB) /* R[a] = R[b][c] */ OPCODE(ASET, BBB) /* R[b][c] = R[a] */ OPCODE(APOST, BBB) /* *R[a],R[a+1]..R[a+c] = R[a][b..] */ diff --git a/mruby/include/mruby/proc.h b/mruby/include/mruby/proc.h index a6aa4ed7..d4e576f2 100644 --- a/mruby/include/mruby/proc.h +++ b/mruby/include/mruby/proc.h @@ -26,17 +26,18 @@ struct REnv { #define MRB_ENV_SET_LEN(e,len) ((e)->flags = (((e)->flags & ~0xff)|((unsigned int)(len) & 0xff))) #define MRB_ENV_LEN(e) ((mrb_int)((e)->flags & 0xff)) #define MRB_ENV_CLOSED (1<<20) -#define MRB_ENV_TOUCHED (1<<19) -#define MRB_ENV_HEAPED (1<<18) #define MRB_ENV_CLOSE(e) ((e)->flags |= MRB_ENV_CLOSED) -#define MRB_ENV_TOUCH(e) ((e)->flags |= MRB_ENV_TOUCHED) -#define MRB_ENV_HEAP(e) ((e)->flags |= MRB_ENV_HEAPED) -#define MRB_ENV_HEAP_P(e) ((e)->flags & MRB_ENV_HEAPED) #define MRB_ENV_ONSTACK_P(e) (((e)->flags & MRB_ENV_CLOSED) == 0) #define MRB_ENV_BIDX(e) (((e)->flags >> 8) & 0xff) #define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0xff<<8))|((unsigned int)(idx) & 0xff)<<8)) -void mrb_env_unshare(mrb_state*, struct REnv*); +/* + * Returns TRUE on success. + * If the function fails: + * * Returns FALSE if noraise is TRUE. + * * Raises a NoMemoryError exception if noraise is FALSE. + */ +mrb_bool mrb_env_unshare(mrb_state*, struct REnv*, mrb_bool noraise); struct RProc { MRB_OBJECT_HEADER; @@ -89,11 +90,8 @@ struct RProc { #define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v))) struct RProc *mrb_proc_new(mrb_state*, const mrb_irep*); -struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*); MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t); MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals); -void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b); -mrb_int mrb_proc_arity(const struct RProc *p); /* following functions are defined in mruby-proc-ext so please include it when using */ MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv); @@ -138,73 +136,11 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc); -static inline void -mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p) -{ - ci->proc = p; - ci->pc = (p && !MRB_PROC_CFUNC_P(p)) ? p->body.irep->iseq : NULL; -} - -static inline struct RClass * -mrb_vm_ci_target_class(const mrb_callinfo *ci) -{ - if (ci->u.env && ci->u.env->tt == MRB_TT_ENV) { - return ci->u.env->c; - } - else { - return ci->u.target_class; - } -} - -static inline void -mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc) -{ - struct REnv *e = ci->u.env; - if (e) { - if (e->tt == MRB_TT_ENV) { - e->c = tc; - } - else { - ci->u.target_class = tc; - } - } -} - -static inline struct REnv * -mrb_vm_ci_env(const mrb_callinfo *ci) -{ - if (ci->u.env && ci->u.env->tt == MRB_TT_ENV) { - return ci->u.env; - } - else { - return NULL; - } -} - -static inline void -mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) -{ - if (ci->u.env) { - if (ci->u.env->tt == MRB_TT_ENV) { - if (e) { - e->c = ci->u.env->c; - ci->u.env = e; - } - else { - ci->u.target_class = ci->u.env->c; - } - } - else { - if (e) { - e->c = ci->u.target_class; - ci->u.env = e; - } - } - } - else { - ci->u.env = e; - } -} +void mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p); +struct RClass * mrb_vm_ci_target_class(const mrb_callinfo *ci); +void mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc); +struct REnv * mrb_vm_ci_env(const mrb_callinfo *ci); +void mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e); MRB_END_DECL diff --git a/mruby/include/mruby/range.h b/mruby/include/mruby/range.h index fea700c2..3898ef3c 100644 --- a/mruby/include/mruby/range.h +++ b/mruby/include/mruby/range.h @@ -71,8 +71,6 @@ enum mrb_range_beg_len { }; MRB_API enum mrb_range_beg_len mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); -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)); -void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r); MRB_END_DECL diff --git a/mruby/include/mruby/string.h b/mruby/include/mruby/string.h index b296832a..cd300f8b 100644 --- a/mruby/include/mruby/string.h +++ b/mruby/include/mruby/string.h @@ -102,7 +102,6 @@ struct RStringEmbed { #define RSTRING_LEN(s) RSTR_LEN(RSTRING(s)) #define RSTRING_CAPA(s) RSTR_CAPA(RSTRING(s)) #define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s)) -MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define RSTRING_CSTR(mrb,s) mrb_string_cstr(mrb, s) #define MRB_STR_SHARED 1 @@ -115,8 +114,6 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT) #define MRB_STR_TYPE_MASK 15 -void mrb_gc_free_str(mrb_state*, struct RString*); - MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s); /* mrb_str_modify() with keeping ASCII flag if set */ MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s); @@ -324,7 +321,7 @@ 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); -MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, size_t capa); +MRB_API mrb_value mrb_str_new_capa(mrb_state *mrb, mrb_int capa); #define mrb_str_buf_new(mrb, capa) mrb_str_new_capa(mrb, (capa)) /* NULL terminated C string from mrb_value */ @@ -332,9 +329,11 @@ MRB_API const char *mrb_string_cstr(mrb_state *mrb, mrb_value str); /* NULL terminated C string from mrb_value; `str` will be updated */ MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *str); /* obsolete: use RSTRING_PTR() */ -MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str); +#define mrb_string_value_ptr(mrb, str) RSTRING_PTR(str) /* obsolete: use RSTRING_LEN() */ -MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str); +#define mrb_string_value_len(mrb, str) RSTRING_LEN(str) +/* obsolete: substituted by a macro; shall be removed */ +#define mrb_str_strlen(mrb, s) strlen(RSTR_PTR(s)) /** * Duplicates a string object. @@ -422,27 +421,11 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2); */ MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str); -uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str); -mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); - -/** - * Returns a printable version of str, surrounded by quote marks, with special characters escaped. - */ -mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); - /* For backward compatibility */ #define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr) #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) #define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2) -mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp); -mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); - -#ifdef MRB_UTF8_STRING -mrb_int mrb_utf8len(const char *str, const char *end); -mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len); -#endif - MRB_END_DECL #endif /* MRUBY_STRING_H */ diff --git a/mruby/include/mruby/throw.h b/mruby/include/mruby/throw.h index 52171e9b..547eea12 100644 --- a/mruby/include/mruby/throw.h +++ b/mruby/include/mruby/throw.h @@ -7,10 +7,8 @@ #ifndef MRB_THROW_H #define MRB_THROW_H -#if defined(MRB_USE_CXX_ABI) -# if !defined(__cplusplus) +#if defined(MRB_USE_CXX_ABI) && !defined(__cplusplus) # error Trying to use C++ exception handling in C code -# endif #endif #if defined(MRB_USE_CXX_EXCEPTION) @@ -52,14 +50,15 @@ typedef mrb_int mrb_jmpbuf_impl; #endif +#if defined(MRB_USE_CXX_EXCEPTION) +extern mrb_int mrb_jmpbuf_id; +#endif + struct mrb_jmpbuf { mrb_jmpbuf_impl impl; #if defined(MRB_USE_CXX_EXCEPTION) - static mrb_int jmpbuf_id; -# if defined(__cplusplus) - mrb_jmpbuf() : impl(jmpbuf_id++) {} -# endif + mrb_jmpbuf() : impl(mrb_jmpbuf_id++) {} #endif }; diff --git a/mruby/include/mruby/value.h b/mruby/include/mruby/value.h index ad439334..6666a9c1 100644 --- a/mruby/include/mruby/value.h +++ b/mruby/include/mruby/value.h @@ -100,9 +100,13 @@ 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); +MRB_API mrb_bool mrb_read_int(const char *p, const char *e, char **endp, mrb_int *np); +/* obsolete; do not use mrb_int_read() */ +MRB_API mrb_int mrb_int_read(const char*, const char*, char**); #ifndef MRB_NO_FLOAT -MRB_API double mrb_float_read(const char*, char**); +MRB_API mrb_bool mrb_read_float(const char *p, char **endp, double *fp); +/* obsolete; do not use mrb_float_read() */ +MRB_API double mrb_float_read(const char *p, char **endp); #ifdef MRB_USE_FLOAT32 typedef float mrb_float; #else @@ -148,13 +152,14 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; 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_CDATA, struct RData, "C 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") + f(MRB_TT_RATIONAL, struct RRational, "Rational") \ + f(MRB_TT_BIGINT, struct RBigint, "Integer") enum mrb_vtype { #define MRB_VTYPE_DEFINE(tt, type, name) tt, @@ -163,6 +168,9 @@ enum mrb_vtype { MRB_TT_MAXDEFINE }; +/* obsolete name for MRB_TT_CDATA */ +#define MRB_TT_DATA MRB_TT_CDATA + #define MRB_VTYPE_TYPEOF(tt) MRB_TYPEOF_##tt #define MRB_VTYPE_TYPEDEF(tt, type, name) typedef type MRB_VTYPE_TYPEOF(tt); @@ -182,8 +190,8 @@ MRB_VTYPE_FOREACH(MRB_VTYPE_TYPEDEF) * * Actual implementation depends on configured boxing type. * - * @see mruby/boxing_no.h Default boxing representation - * @see mruby/boxing_word.h Word representation + * @see mruby/boxing_word.h Word boxing representation (Default) + * @see mruby/boxing_no.h No boxing representation * @see mruby/boxing_nan.h Boxed double representation */ typedef void mrb_value; @@ -237,9 +245,11 @@ struct RCptr { #ifndef mrb_true_p #define mrb_true_p(o) (mrb_type(o) == MRB_TT_TRUE) #endif -#ifndef MRB_NO_FLOAT #ifndef mrb_float_p +#ifndef MRB_NO_FLOAT #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) +#else +#define mrb_float_p(o) FALSE #endif #endif #ifndef mrb_array_p @@ -285,7 +295,7 @@ struct RCptr { #define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV) #endif #ifndef mrb_data_p -#define mrb_data_p(o) (mrb_type(o) == MRB_TT_DATA) +#define mrb_data_p(o) (mrb_type(o) == MRB_TT_CDATA) #endif #ifndef mrb_fiber_p #define mrb_fiber_p(o) (mrb_type(o) == MRB_TT_FIBER) @@ -300,6 +310,9 @@ struct RCptr { #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) #endif #define mrb_test(o) mrb_bool(o) +#ifndef mrb_bigint_p +#define mrb_bigint_p(o) (mrb_type(o) == MRB_TT_BIGINT) +#endif /** * Returns a float in Ruby. @@ -355,8 +368,6 @@ mrb_obj_value(void *p) { mrb_value v; SET_OBJ_VALUE(v, (struct RBasic*)p); - mrb_assert(p == mrb_ptr(v)); - mrb_assert(((struct RBasic*)p)->tt == mrb_type(v)); return v; } @@ -424,10 +435,20 @@ mrb_ro_data_p(const char *p) #elif defined(__APPLE__) #define MRB_LINK_TIME_RO_DATA_P #include +#include // for _NSGetMachExecuteHeader static inline mrb_bool mrb_ro_data_p(const char *p) { - return (char*)get_etext() < p && p < (char*)get_edata(); +#ifdef __LP64__ + struct mach_header_64 *mhp; +#else + struct mach_header *mhp; +#endif + mhp = _NSGetMachExecuteHeader(); + unsigned long textsize, datasize; + char *text = (char*)getsegmentdata(mhp, SEG_TEXT, &textsize); + char *data = (char*)getsegmentdata(mhp, SEG_DATA, &datasize); + return text + textsize < p && p < data + datasize; } #endif /* Linux or macOS */ #endif /* MRB_NO_DEFAULT_RO_DATA_P */ diff --git a/mruby/include/mruby/variable.h b/mruby/include/mruby/variable.h index 3dc2c9a6..0a7b7b42 100644 --- a/mruby/include/mruby/variable.h +++ b/mruby/include/mruby/variable.h @@ -14,13 +14,6 @@ */ MRB_BEGIN_DECL -mrb_value mrb_vm_special_get(mrb_state*, mrb_sym); -void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value); -mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); -void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); -mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); -void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); -size_t mrb_obj_iv_tbl_memsize(mrb_value); MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym); @@ -99,22 +92,6 @@ MRB_API mrb_value mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym); MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_value v); MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v); MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym); -mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*); -void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); -mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod); -mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); -mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value); -mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); -mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); -mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); -mrb_bool mrb_ident_p(const char *s, mrb_int len); - -/* GC functions */ -void mrb_gc_mark_gv(mrb_state*); -void mrb_gc_free_gv(mrb_state*); -void mrb_gc_mark_iv(mrb_state*, struct RObject*); -size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); -void mrb_gc_free_iv(mrb_state*, struct RObject*); /* return non zero to break the loop */ typedef int (mrb_iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*); diff --git a/mruby/include/mruby/version.h b/mruby/include/mruby/version.h index cf713da2..01492e0c 100644 --- a/mruby/include/mruby/version.h +++ b/mruby/include/mruby/version.h @@ -27,7 +27,7 @@ MRB_BEGIN_DECL /* * The version of Ruby used by mruby. */ -#define MRUBY_RUBY_VERSION "3.1" +#define MRUBY_RUBY_VERSION "3.2" /* * Ruby engine. @@ -42,7 +42,7 @@ MRB_BEGIN_DECL /* * Minor release version number. */ -#define MRUBY_RELEASE_MINOR 1 +#define MRUBY_RELEASE_MINOR 2 /* * Tiny release version number. @@ -80,17 +80,17 @@ MRB_BEGIN_DECL /* * Release year. */ -#define MRUBY_RELEASE_YEAR 2022 +#define MRUBY_RELEASE_YEAR 2023 /* * Release month. */ -#define MRUBY_RELEASE_MONTH 5 +#define MRUBY_RELEASE_MONTH 2 /* * Release day. */ -#define MRUBY_RELEASE_DAY 12 +#define MRUBY_RELEASE_DAY 24 /* * Release date as a string. diff --git a/mruby/lib/mruby/build.rb b/mruby/lib/mruby/build.rb index 66005a6d..4925cee3 100644 --- a/mruby/lib/mruby/build.rb +++ b/mruby/lib/mruby/build.rb @@ -123,6 +123,7 @@ def initialize(name='host', build_dir=nil, internal: false, &block) @enable_test = false @enable_lock = true @enable_presym = true + @enable_benchmark = true @mrbcfile_external = false @internal = internal @toolchains = [] @@ -232,6 +233,14 @@ def enable_cxx_abi @cxx_abi_enabled = true end + def benchmark_enabled? + @enable_benchmark + end + + def disable_benchmark + @enable_benchmark = false + end + def compile_as_cxx(src, cxx_src = nil, obj = nil, includes = []) # # If `cxx_src` is specified, this method behaves the same as before as @@ -491,7 +500,8 @@ def create_mrbc_build v = instance_variable_get(n) v = case v when nil, true, false, Numeric; v - when String, Command; v.clone + when String; v.clone + when Command; v.clone.tap { |u| u.build = build } else Marshal.load(Marshal.dump(v)) # deep clone end build.instance_variable_set(n, v) diff --git a/mruby/lib/mruby/build/command.rb b/mruby/lib/mruby/build/command.rb index 31a595ef..c8a3037e 100644 --- a/mruby/lib/mruby/build/command.rb +++ b/mruby/lib/mruby/build/command.rb @@ -25,11 +25,7 @@ def clone end def shellquote(s) - if ENV['OS'] == 'Windows_NT' - "\"#{s}\"" - else - "#{s}" - end + "\"#{s}\"" end private diff --git a/mruby/lib/mruby/build/load_gems.rb b/mruby/lib/mruby/build/load_gems.rb index 6609a5c8..34d35ebd 100644 --- a/mruby/lib/mruby/build/load_gems.rb +++ b/mruby/lib/mruby/build/load_gems.rb @@ -1,5 +1,8 @@ +require 'yaml' + module MRuby module LoadGems + def gembox(gemboxfile) gembox = File.expand_path("#{gemboxfile}.gembox", "#{MRUBY_ROOT}/mrbgems") fail "Can't find gembox '#{gembox}'" unless File.exist?(gembox) @@ -12,28 +15,30 @@ def gembox(gemboxfile) GemBox.path = nil end - def gem(gemdir, &block) - if gemdir.is_a?(Hash) - gemdir = load_special_path_gem(gemdir) - elsif GemBox.path - gemdir = File.expand_path(gemdir, File.dirname(GemBox.path)) - else - caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1])) - if caller_dir == "#{MRUBY_ROOT}/build_config" - caller_dir = MRUBY_ROOT - end - gemdir = File.expand_path(gemdir, caller_dir) - end + def gem(gem_src, &block) + + caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1])) + + gem_src = {gemdir: gem_src} if gem_src.is_a? String - gemrake = File.join(gemdir, "mrbgem.rake") + @gem_checkouts ||= {} + checkout = GemLoader + .new(self, caller_dir, @gem_checkouts, **gem_src) + .fetch! + return nil unless checkout + @gem_checkouts[checkout.gemdir] = checkout + # Load the gem's rakefile + gemrake = File.join(checkout.full_gemdir, "mrbgem.rake") fail "Can't find #{gemrake}" unless File.exist?(gemrake) + Gem.current = nil load gemrake return nil unless Gem.current current = Gem.current - current.dir = gemdir + # Add it to gems + current.dir = checkout.full_gemdir current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current current.build_config_initializer = block gems << current @@ -44,92 +49,324 @@ def gem(gemdir, &block) current end - def load_special_path_gem(params) - if params[:github] - params[:git] = "https://github.com/#{params[:github]}.git" - elsif params[:bitbucket] - if params[:method] == "ssh" - params[:git] = "git@bitbucket.org:#{params[:bitbucket]}.git" + + # Class to represent the relationship between a gem dependency and + # its remote repository (if any). + class GemCheckout + attr_reader :gemdir, :repo, :branch, :commit + + def initialize(gemdir, repo, branch, commit, canonical, path = nil) + @gemdir = gemdir # Working copy of the gem + @path = path # Path to gem relative to checkout + + @repo = repo # Remote gem repo + @branch = branch # Branch to check out + @commit = commit # Commit-id to use + + @canonical = canonical # This is the One True checkout + end + + def full_gemdir + return @gemdir unless @path + return File.join(@gemdir, @path) + end + + def canonical?() return @canonical; end + def git?() return !!@repo; end + def gemname() return File.basename(@gemdir); end + + def hash + return [@gemdir, @repo, @branch, @commit, @canonical, @path].hash + end + + def ==(other) + return @gemdir == other.gemdir && + @repo == other.repo && + @branch == other.branch && + @commit == other.commit && + @canonical == other.canonical? && + full_gemdir == other.full_gemdir + end + alias_method :eql?, :== + + def to_s + desc = @gemdir + desc += " -> #{@repo}/#{@branch}" if git? + desc += "/#{commit}" if commit + return desc + end + end + + # Class to decode the argument set given to 'MRuby::Build::gem', + # and git-clone+git-checkout the sources if needed. + class GemLoader + def initialize(build, + build_config_dir, # Parent dir. of build_config + gem_checkouts, # Hash of existing checkouts + + # Git repo: + git: nil, + branch: "master", + checksum_hash: nil, + options: [], + path: nil, # path to root relative to gem checkout + + # Git repo on GitHub + github: nil, + + # Git repo on BitBucket + bitbucket: nil, + method: nil, + + # mgem entry + mgem: nil, + + # Core package + core: nil, + + # Local file(s) + gemdir: nil, + + # Related flags: + canonical: false # Ignore subsequent checkout of this gem + ) + # Tolerate a single string option + options = [options] unless options.is_a? Array + + @build = build + @build_config_dir = build_config_dir + @gem_checkouts = gem_checkouts + @canonical = canonical + + @git = git + @path = path + @branch = branch + @checksum_hash = checksum_hash + @options = options + @canonical = canonical + + @github = github + + @bitbucket = bitbucket + @method = method + + @mgem = mgem + @core = core + @gemdir = gemdir + + + actions = [git, github, bitbucket, mgem, core, gemdir] + fail("Need to set exactly ONE of git, github, bitbucket, mgem, core, " + + "or gemdir") unless actions.compact.size == 1 + end + + # Retrieve the repo and return the details in a GemCheckout + # object or nil if nothing needed to be done. + def fetch! + return fromGemdir! if @gemdir + return fromCore! if @core + return fromGitHub! if @github + return fromBitBucket! if @bitbucket + + return fromMGem! if @mgem + + return fromGit!(@git, @branch) if @git + + # Shouldn't be reachable, but... + fail "Invalid gem configuration!" + end + + private + + # + # Local Paths + # + + def fromGemdir! + gem_src = @gemdir + + # If @gemdir is a relative path, we first convert it to an + # absolute path; this depends on circumstances. + if MRuby::GemBox.path + # If GemBox.path is set, it means that this fetch operation is + # happening as part of a gembox evaluation and we use the + # gembox's path as the starting point. + gem_src = File.expand_path(gem_src, File.dirname(MRuby::GemBox.path)) else - params[:git] = "https://bitbucket.org/#{params[:bitbucket]}.git" + # Otherwise, we use the path to the build_config.rb file that + # requested this gem. This path was extracted earlier and + # stored in @build_config_dir via the second argument of + # 'initialize'. + root_dir = @build_config_dir + + # And we default to the repo root if the file is one of the + # stock configs in build_config/. + root_dir = MRUBY_ROOT if root_dir == "#{MRUBY_ROOT}/build_config" + + gem_src = File.expand_path(gem_src, root_dir) end - elsif params[:mgem] - mgem_list_dir = "#{gem_clone_dir}/mgem-list" - mgem_list_url = 'https://github.com/mruby/mgem-list.git' - if File.exist? mgem_list_dir - git.run_pull mgem_list_dir, mgem_list_url if $pull_gems + + return GemCheckout.new(gem_src, nil, nil, nil, @canonical) + end + + def fromCore! + return GemCheckout.new("#{@build.root}/mrbgems/#{@core}", nil, nil, + nil, @canonical) + end + + + # + # Git forges + # + + def fromGitHub! + url = "https://github.com/#{@github}.git" + return fromGit!(url, @branch) + end + + def fromBitBucket! + if @method == "ssh" + url = "git@bitbucket.org:#{@bitbucket}.git" else - mkdir_p mgem_list_dir - git.run_clone mgem_list_dir, mgem_list_url, "--depth 1" + url = "https://bitbucket.org/#{@bitbucket}.git" end - require 'yaml' + return fromGit!(url, @branch) + end + + + # + # mgem file + # + + def fromMGem! + mgem = fetchMGem(@mgem) + + url = mgem['repository'] + branch = mgem['branch'] || @branch + + return fromGit!(url, branch) + end + + # Fetch the contents of the named mgem item. Will clone the + # mgem-list repo if not present + def fetchMGem(mgem) + list_dir = "#{@build.gem_clone_dir}/mgem-list" + url = 'https://github.com/mruby/mgem-list.git' + + git_clone_dependency(url, list_dir, nil, 'master') + + conf_path = "#{list_dir}/#{mgem}.gem" + conf_path = "#{list_dir}/mruby-#{mgem}.gem" unless + File.exist? conf_path + fail "mgem not found: #{mgem}" unless File.exist? conf_path - conf_path = "#{mgem_list_dir}/#{params[:mgem]}.gem" - conf_path = "#{mgem_list_dir}/mruby-#{params[:mgem]}.gem" unless File.exist? conf_path - fail "mgem not found: #{params[:mgem]}" unless File.exist? conf_path conf = YAML.load File.read conf_path + fail "unknown mgem protocol: #{conf['protocol']}" if + conf['protocol'] != 'git' - fail "unknown mgem protocol: #{conf['protocol']}" if conf['protocol'] != 'git' - params[:git] = conf['repository'] - params[:branch] = conf['branch'] if conf['branch'] + return conf end - if params[:core] - gemdir = "#{root}/mrbgems/#{params[:core]}" - elsif params[:git] - url = params[:git] - gemdir = "#{gem_clone_dir}/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}" - # by default the 'master' branch is used - branch = params[:branch] ? params[:branch] : 'master' + # + # Git checkouts + # - lock = locks[url] if lock_enabled? + def fromGit!(url, branch) + repo_dir = "#{@build.gem_clone_dir}/" + + "#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}" + commit = @checksum_hash - if File.exist?(gemdir) - if $pull_gems - # Jump to the top of the branch - git.run_checkout gemdir, branch - git.run_pull gemdir, url - elsif params[:checksum_hash] - git.run_checkout_detach gemdir, params[:checksum_hash] - elsif lock - git.run_checkout_detach gemdir, lock['commit'] - end - else - options = [params[:options]] || [] - options << "--recursive" - options << "--branch \"#{branch}\"" - options << "--depth 1" unless params[:checksum_hash] || lock - mkdir_p "#{gem_clone_dir}" - git.run_clone gemdir, url, options - - # Jump to the specified commit - if params[:checksum_hash] - git.run_checkout_detach gemdir, params[:checksum_hash] - elsif lock - git.run_checkout_detach gemdir, lock['commit'] - end + return nil if skip_this?(url, repo_dir, branch, commit) + + # If there's a lockfile entry for this repo AND the user hasn't + # specified a specific commit ID, we use the locked branch and + # commit. + lock = @build.locks[url] if @build.lock_enabled? + if !commit && lock + branch = lock['branch'] + commit = lock['commit'] end - if lock_enabled? - @gem_dir_to_repo_url[gemdir] = url unless params[:path] - locks[url] = { + # Clone the dependency (if needed) and checkout the expected + # revision. + git_clone_dependency(url, repo_dir, commit, branch) + git_checkout_dependency(repo_dir, commit, branch) + + # Set the lockfile entry if enabled + if @build.lock_enabled? + @build.gem_dir_to_repo_url[repo_dir] = url + @build.locks[url] = { 'url' => url, - 'branch' => git.current_branch(gemdir), - 'commit' => git.commit_hash(gemdir), + 'branch' => @build.git.current_branch(repo_dir), + 'commit' => @build.git.commit_hash(repo_dir), } end - gemdir << "/#{params[:path]}" if params[:path] - elsif params[:path] - require 'pathname' - gemdir = Pathname.new(params[:path]).absolute? ? params[:path] : "#{root}/#{params[:path]}" - else - fail "unknown gem option #{params}" + return GemCheckout.new(repo_dir, url, branch, commit, @canonical,@path) end - gemdir + + # Test if this repo can be skipped. This will happen if it's + # already in @gem_checkouts and EITHER it is identical (same + # url, branch, commit-ID and subdirectory path) as the current + # checkout OR its "canonical" flag is true. If it's in + # @gem_checkouts and neither of these conditions is true, that's + # a fatal error; it means there are multiple incompatible + # versions of this gem to be checked out into this directory. + # + # Otherwise, returns false. + def skip_this?(url, repo_dir, branch, commit) + prev = @gem_checkouts[repo_dir] + return false unless prev + + # Canonical declarations must precede all others. + fail("Attempted to re-declare #{prev.gemname} as canonical!\n" + + "('canonical' can only be used on its first declaration.)") if + prev && @canonical + + # If prev is canonical, we can ignore this + if prev.canonical? + puts "Found canonical #{prev.gemname}; skipping this one." + return true + end + + # If this checkout is identical to the current one, we can skip it. + candidate = GemCheckout.new(repo_dir, url, branch, commit, @canonical, + @path) + if prev == candidate + puts "Found duplicate checkout for #{repo_dir}; ignoring." + return true + end + + # Otherwise, we have a checkout conflict. This is an error. + fail "Conflicting gem definitions for '#{repo_dir}':\n" + + " #{candidate}\n" + + " #{prev}\n" + end + + + # Retrieve a git repo if it's not present. Return + # [path_to_checkout, did_clone] + def git_clone_dependency(url, repo_dir, commit, branch) + return if + File.exist?(repo_dir) && File.exist?(File.join(repo_dir, '.git')) + + FileUtils.mkdir_p repo_dir + + options = @options.dup + options << "--recursive" + options << "--branch \"#{branch}\"" + options << "--depth 1" unless commit + + @build.git.run_clone repo_dir, url, options + end + + def git_checkout_dependency(repo_dir, commit, branch) + return unless commit + @build.git.run_checkout_detach(repo_dir, commit) + end end def enable_gems? diff --git a/mruby/lib/mruby/doc.rb b/mruby/lib/mruby/doc.rb new file mode 100644 index 00000000..6cc19b0a --- /dev/null +++ b/mruby/lib/mruby/doc.rb @@ -0,0 +1,50 @@ +autoload :Pathname, 'pathname' + +module MRuby + module Documentation + def Documentation.update_opcode_md + mrubydir = Pathname(MRUBY_ROOT) + path_ops_h = mrubydir + "include/mruby/ops.h" + path_opcode_md = mrubydir + "doc/internal/opcode.md" + + opspecs = { + "Z" => { prefix: "", modified: "-" }, + "B" => { prefix: "\'" }, + "BB" => { prefix: "\"" }, + "BBB" => { prefix: "\"" }, + "BS" => { prefix: "\'" }, + "BSS" => { prefix: "\'" }, + "S" => { prefix: "" }, + "W" => { prefix: "" }, + } + + diff = "" + + spliter = <<~'SPLITER' + | Instruction Name | Operand type | Semantics | + |--------------------|----------------|------------------------------------------------------------| + SPLITER + + diff = path_opcode_md.read.sub(/^#{Regexp.escape spliter}.*?(?=\z|^$\n)/m) do + repl = spliter + + ops = path_ops_h.read + ops.scan(/^\s*OPCODE\s*\(\s*(\w+)\s*,\s*(\w+)\s*\)\s*(?:\/\*\s*(.*?)\s*\*\/\s*)?/).each do |ins, opr, cmt| + if cmt + cmt.sub!(/\s*#.*/, "") + cmt.sub!(/\b(?=L_\w+\b)/, "OP_") + cmt.gsub!(/\b(Irep|Pool|R|Syms)\[([^\[\]]+)\]/, "\\1(\\2)") + cmt.gsub!(/[\\\|]/) { |m| "\\#{m}" } # Ruby-2.5 is not support "Numbered block parameter" + end + spec = opspecs[opr] or raise "unknown operand type: #{opr}" + item = format(%(| %-18s | %-14s | %-58s |\n), "`OP_#{ins}`", "`#{spec[:modified] || opr}`", cmt && "`#{cmt}`") + repl << item + end + + repl + end + + path_opcode_md.binwrite diff + end + end +end diff --git a/mruby/lib/mruby/gem.rb b/mruby/lib/mruby/gem.rb index fa0bb3a4..64c6f3de 100644 --- a/mruby/lib/mruby/gem.rb +++ b/mruby/lib/mruby/gem.rb @@ -170,7 +170,7 @@ def search_package(name, version_query=nil) end def funcname - @funcname ||= @name.gsub('-', '_') + @funcname ||= @name.tr('-', '_') end def compilers @@ -225,7 +225,7 @@ def generate_gem_init(fname) f.puts %Q[ }] f.puts %Q[ struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);] f.puts %Q[ mrb_vm_ci_env_set(mrb->c->cibase, NULL);] - f.puts %Q[ mrb_env_unshare(mrb, e);] + f.puts %Q[ mrb_env_unshare(mrb, e, FALSE);] end f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] f.puts %Q[}] diff --git a/mruby/lib/mruby/presym.rb b/mruby/lib/mruby/presym.rb index 016c2b20..7f74569f 100644 --- a/mruby/lib/mruby/presym.rb +++ b/mruby/lib/mruby/presym.rb @@ -102,7 +102,7 @@ def list_path @list_path ||= "#{@build.build_dir}/presym".freeze end - def header_dir; + def header_dir @header_dir ||= "#{@build.build_dir}/include/mruby/presym".freeze end diff --git a/mruby/mrbgems/math.gembox b/mruby/mrbgems/math.gembox index 88f70ddd..d2947314 100644 --- a/mruby/mrbgems/math.gembox +++ b/mruby/mrbgems/math.gembox @@ -7,4 +7,8 @@ MRuby::GemBox.new do |conf| # Use Rational/Complex numbers conf.gem :core => "mruby-rational" conf.gem :core => "mruby-complex" + # Use Complex math functions in CMath module + conf.gem :core => "mruby-cmath" + # Use Multi-precision Integer + conf.gem :core => "mruby-bigint" end diff --git a/mruby/mrbgems/mruby-array-ext/mrblib/array.rb b/mruby/mrbgems/mruby-array-ext/mrblib/array.rb index 1722a363..d493a065 100644 --- a/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +++ b/mruby/mrbgems/mruby-array-ext/mrblib/array.rb @@ -239,7 +239,7 @@ def intersect?(ary) # # Returns a new array that is a one-dimensional flattening of this # array (recursively). That is, for every element that is an array, - # extract its elements into the new array. If the optional + # extract its elements into the new array. If the optional # level argument determines the level of recursion to flatten. # # s = [ 1, 2, 3 ] #=> [1, 2, 3] @@ -262,7 +262,7 @@ def flatten(depth=nil) # # Flattens +self+ in place. # Returns nil if no modifications were made (i.e., - # ary contains no subarrays.) If the optional level + # ary contains no subarrays.) If the optional level # argument determines the level of recursion to flatten. # # a = [ 1, 2, [3, [4, 5] ] ] @@ -313,7 +313,7 @@ def reverse_each(&block) # ary.fetch(index) { |index| block } -> obj # # Tries to return the element at position +index+, but throws an IndexError - # exception if the referenced +index+ lies outside of the array bounds. This + # exception if the referenced +index+ lies outside of the array bounds. This # error can be prevented by supplying a second argument, which will act as a # +default+ value. # @@ -539,7 +539,7 @@ def insert(idx, *args) # the given condition in O(log n) where n is the size of the array. # # You can use this method in two use cases: a find-minimum mode and - # a find-any mode. In either case, the elements of the array must be + # a find-any mode. In either case, the elements of the array must be # monotone (or sorted) with respect to the block. # # In find-minimum mode (this is a good choice for typical use case), @@ -551,7 +551,7 @@ def insert(idx, *args) # - the block returns true for any element whose index is greater # than or equal to i. # - # This method returns the i-th element. If i is equal to ary.size, + # This method returns the i-th element. If i is equal to ary.size, # it returns nil. # # ary = [0, 4, 7, 10, 12] @@ -570,7 +570,7 @@ def insert(idx, *args) # j <= k < ary.size. # # Under this condition, this method returns any element whose index - # is within i...j. If i is equal to j (i.e., there is no element + # is within i...j. If i is equal to j (i.e., there is no element # that satisfies the block), this method returns nil. # # ary = [0, 4, 7, 10, 12] @@ -580,7 +580,7 @@ def insert(idx, *args) # ary.bsearch {|x| 4 - (x / 2).truncate } #=> nil # # You must not mix the two modes at a time; the block must always - # return either true/false, or always return a number. It is + # return either true/false, or always return a number. It is # undefined which value is actually picked up at each iteration. def bsearch(&block) @@ -707,7 +707,7 @@ def select!(&block) # == to +obj+. # # If a block is given instead of an argument, returns the _index_ of the - # first object for which the block returns +true+. Returns +nil+ if no + # first object for which the block returns +true+. Returns +nil+ if no # match is found. # # ISO 15.2.12.5.14 diff --git a/mruby/mrbgems/mruby-array-ext/src/array.c b/mruby/mrbgems/mruby-array-ext/src/array.c index ae8a55d4..385ad511 100644 --- a/mruby/mrbgems/mruby-array-ext/src/array.c +++ b/mruby/mrbgems/mruby-array-ext/src/array.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /* @@ -32,7 +33,7 @@ mrb_ary_assoc(mrb_state *mrb, mrb_value ary) mrb_value v; mrb_value k = mrb_get_arg1(mrb); - for (i = 0; i < RARRAY_LEN(ary); ++i) { + for (i = 0; i < RARRAY_LEN(ary); i++) { v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]); if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 && mrb_equal(mrb, RARRAY_PTR(v)[0], k)) @@ -62,7 +63,7 @@ mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) mrb_value v; mrb_value value = mrb_get_arg1(mrb); - for (i = 0; i < RARRAY_LEN(ary); ++i) { + for (i = 0; i < RARRAY_LEN(ary); i++) { v = RARRAY_PTR(ary)[i]; if (mrb_array_p(v) && RARRAY_LEN(v) > 1 && @@ -103,14 +104,14 @@ ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) static mrb_value mrb_ary_values_at(mrb_state *mrb, mrb_value self) { - mrb_int argc; - const mrb_value *argv; - - mrb_get_args(mrb, "*", &argv, &argc); + mrb_int argc = mrb_get_argc(mrb); + const mrb_value *argv = mrb_get_argv(mrb); return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, ary_ref); } +mrb_value mrb_ary_delete_at(mrb_state *mrb, mrb_value self); + /* * call-seq: * ary.slice!(index) -> obj or nil @@ -136,8 +137,7 @@ static mrb_value mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - mrb_int i, j, k, len, alen; - mrb_value val; + mrb_int i, j, len, alen; mrb_value *ptr; mrb_value ary; @@ -146,21 +146,13 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) if (mrb_get_argc(mrb) == 1) { mrb_value index = mrb_get_arg1(mrb); - switch (mrb_type(index)) { - case MRB_TT_RANGE: + if (mrb_type(index) == MRB_TT_RANGE) { if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) { goto delete_pos_len; } - else { - return mrb_nil_value(); - } - case MRB_TT_INTEGER: - val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index); - return val; - default: - val = mrb_funcall_id(mrb, self, MRB_SYM(delete_at), 1, index); - return val; + return mrb_nil_value(); } + return mrb_ary_delete_at(mrb, self); } mrb_get_args(mrb, "ii", &i, &len); @@ -172,16 +164,12 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) if (alen == i) return mrb_ary_new(mrb); if (len > alen - i) len = alen - i; - ary = mrb_ary_new_capa(mrb, len); - ptr = ARY_PTR(a); - for (j = i, k = 0; k < len; ++j, ++k) { - mrb_ary_push(mrb, ary, ptr[j]); - } + ptr = ARY_PTR(a) + i; + ary = mrb_ary_new_from_values(mrb, len, ptr); - ptr += i; - for (j = i; j < alen - len; ++j) { + for (j = i; j < alen - len; j++) { *ptr = *(ptr+len); - ++ptr; + ptr++; } mrb_ary_resize(mrb, self, alen - len); @@ -205,7 +193,7 @@ mrb_ary_compact(mrb_state *mrb, mrb_value self) mrb_int len = RARRAY_LEN(self); mrb_value *p = RARRAY_PTR(self); - for (mrb_int i = 0; i < len; ++i) { + for (mrb_int i = 0; i < len; i++) { if (!mrb_nil_p(p[i])) { mrb_ary_push(mrb, ary, p[i]); } @@ -233,7 +221,7 @@ mrb_ary_compact_bang(mrb_state *mrb, mrb_value self) mrb_value *p = ARY_PTR(a); mrb_ary_modify(mrb, a); - for (i = 0; i < len; ++i) { + for (i = 0; i < len; i++) { if (!mrb_nil_p(p[i])) { if (i != j) p[j] = p[i]; j++; diff --git a/mruby/mrbgems/mruby-bigint/README-fgmp.md b/mruby/mrbgems/mruby-bigint/README-fgmp.md new file mode 100644 index 00000000..24e131ba --- /dev/null +++ b/mruby/mrbgems/mruby-bigint/README-fgmp.md @@ -0,0 +1,154 @@ +# fgmp + +FGMP is a public domain implementation of a subset of the GNU gmp library with the same API. + +WELCOME TO FGMP. + +FGMP is a public domain implementation of a subset of the GNU gmp library +with the same API. + +For instance, you can link the following trivial program with either +this code, or libgmp.a and get the same results. + +```c +#include +#include "gmp.h" +main() +{ + MP_INT a; MP_INT b; MP_INT c; + + mpz_init_set_ui(&a,1); mpz_init_set_ui(&b,2); mpz_init(&c); + mpz_add(&c,&a,&b); + printf("\n%s\n", mpz_get_str(NULL,10,&c)); +} +``` + +FGMP is really in the public domain. You can do whatever you want with +it. + +I wrote FGMP so that we would all have access to a (truly free) +implementation of this subset of the API of GNU libgmp. I encourage +everyone to distribute this as widely as possible. + +If you need more documentation, I suggest you look at the file +gmp.texi which is included with the GNU gmp library. + +You can send me bug reports, implementations of missing functions, flames +and rants by Email. + +Any submissions of new code to be integrated into fgmp must also be +placed in the public domain (For the particularly dense, you can +release a new fgmp yourself under different licensing terms. This +is a condition for including a submission in a release of FGMP that +I personally prepare). + +Mark Henderson + +# This is the fifth BETA release. 1.0b5 + +I hearby place this file and all of FGMP in the public domain. + +Thanks to Paul Rouse for changes to get fgmp +to work on a 286 MS-DOS compiler, the functions mpz_sqrt and +mpz_sqrtrem, plus other general bug fixes. + +Thanks also to Erick Gallesio for a fix +to mpz_init_set_str + +Define B64 if your "long" type is 64 bits. Otherwise we assume 32 +bit longs. (The 64 bit version hasn't been tested enough) + +``` +Platforms: +Linux 0.99 (gcc) +IBM RS6000/AIX 3.2 (IBM xlc compiler and gcc 2.3) +Sun OS 4.1, Sun 3/4 +DEC Alpha OSF/1 (only lightly tested, 64 bit longs do make a difference, + thanks to DEC for providing access via axposf.pa.dec.com). Define B64 + for this platform +MS-DOS 286 C compiler (see credits above) +``` + +# Some differences between gmp and fgmp + +1. fgmp is considerably slower than gmp +2. fgmp does not implement the following: + all mpq_* + internal mpn_* functions + mpz_perfect_square_p + mpz_inp_raw, mpz_out_raw + mp_set_memory_functions, mpz_out_str, mpz_inp_str +3. fgmp implements the following in addition to the routines in GNU gmp. + `int mpz_jacobi(MP_INT *a, MP_INT *b)` + - finds the jacobi symbol (a/b) +4. mpz_sizeinbase often overestimates the exact value + +5. To convert your gmp based program to fgmp (subject to the +above) + +- recompile your source. Make sure to include the gmp.h file included + with fgmp rather than that included with gmp. (The point is to recompile + all files which include gmp.h) +- link with gmp.o instead of libgmp.a + +Here's a complete sorted list of function implemented in fgmp: + +``` +_mpz_realloc +mpz_abs +mpz_add +mpz_add_ui +mpz_and +mpz_clear +mpz_cmp +mpz_cmp_si +mpz_cmp_ui +mpz_div +mpz_div_2exp +mpz_div_ui +mpz_divmod +mpz_divmod_ui +mpz_fac_ui +mpz_gcd +mpz_gcdext +mpz_get_si +mpz_get_str +mpz_get_ui +mpz_init +mpz_init_set +mpz_init_set_si +mpz_init_set_str +mpz_init_set_ui +mpz_jacobi +mpz_mdiv +mpz_mdiv_ui +mpz_mdivmod +mpz_mdivmod_ui +mpz_mmod +mpz_mmod_ui +mpz_mod +mpz_mod_2exp +mpz_mod_ui +mpz_mul +mpz_mul_2exp +mpz_mul_ui +mpz_neg +mpz_or +mpz_pow_ui +mpz_powm +mpz_powm_ui +mpz_probab_prime_p +mpz_random +mpz_random2 +mpz_set +mpz_set_si +mpz_set_str +mpz_set_ui +mpz_size +mpz_sizeinbase +mpz_sqrt +mpz_sqrtrem +mpz_sub +mpz_sub_ui +mpz_xor +``` diff --git a/mruby/mrbgems/mruby-bigint/README.md b/mruby/mrbgems/mruby-bigint/README.md new file mode 100644 index 00000000..5a5316bb --- /dev/null +++ b/mruby/mrbgems/mruby-bigint/README.md @@ -0,0 +1,7 @@ +# Multi-precision Integer extension for mruby + +This extension uses fgmp, which is a public domain implementation of a subset of the GNU gmp library by Mark Henderson . +But it's heavily modified to fit with mruby. You can get the original source code from . +You can read the original README for fgmp in [README-fgmp.md](README-fgmp.md). + +If you want to create your own Multi-precision Integer GEM, see [examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md](../../examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md). diff --git a/mruby/mrbgems/mruby-bigint/core/bigint.c b/mruby/mrbgems/mruby-bigint/core/bigint.c new file mode 100644 index 00000000..5c757729 --- /dev/null +++ b/mruby/mrbgems/mruby-bigint/core/bigint.c @@ -0,0 +1,1506 @@ +/** +** @file mruby/bigint.c - Multi-precision Integer +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "bigint.h" + +#define DIG_SIZE (MPZ_DIG_SIZE) +#define DIG_BASE (1ULL << DIG_SIZE) +#define DIG_MASK (DIG_BASE - 1) +#define HIGH(x) ((x) >> DIG_SIZE) +#define LOW(x) ((x) & DIG_MASK) + +#define iabs(x) (((x)>0)?(x):(-x)) +#define imax(x,y) (((x)>(y))?(x):(y)) +#define imin(x,y) (((x)<(y))?(x):(y)) +#define dg(x,i) (((size_t)i < (x)->sz)?(x)->p[i]:0) + +static void +mpz_init(mrb_state *mrb, mpz_t *s) +{ + s->p = NULL; + s->sn=0; + s->sz=0; +} + +static void +mpz_realloc(mrb_state *mrb, mpz_t *x, size_t size) +{ + if (x->sz < size) { + x->p=(mp_limb*)mrb_realloc(mrb, x->p, size*sizeof(mp_limb)); + for (size_t i=x->sz; ip[i] = 0; + x->sz = size; + } +} + +static void +mpz_set(mrb_state *mrb, mpz_t *y, mpz_t *x) +{ + size_t i, k = x->sz; + + mpz_realloc(mrb, y, k); + for (i=0;i < k; i++) + y->p[i] = x->p[i]; + + for (;isz;i++) + y->p[i] = 0; + + y->sn = x->sn; +} + +static void +mpz_init_set(mrb_state *mrb, mpz_t *s, mpz_t *t) +{ + mpz_init(mrb, s); + mpz_set(mrb, s, t); +} + +static void +mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) +{ + mrb_uint u; + + if (v == 0) { + y->sn=0; + u = 0; + } + else if (v > 0) { + y->sn = 1; + u = v; + } + if (v < 0) { + y->sn = -1; + if (v == MRB_INT_MIN) u = v; + else u = -v; + } +#if MRB_INT_BIT > DIG_SIZE + if ((u & ~DIG_MASK) != 0) { + mpz_realloc(mrb, y, 2); + y->p[1] = (mp_limb)HIGH(u); + y->p[0] = (mp_limb)LOW(u); + } + else +#endif + { + mpz_realloc(mrb, y, 1); + y->p[0] = (mp_limb)u; + } +} + +static void +mpz_init_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) +{ + mpz_init(mrb, y); + mpz_set_int(mrb, y, v); +} + +static void +mpz_clear(mrb_state *mrb, mpz_t *s) +{ + if (s->p) mrb_free(mrb, s->p); + s->p = NULL; + s->sn = 0; + s->sz = 0; +} + +static void +mpz_move(mrb_state *mrb, mpz_t *y, mpz_t *x) +{ + mpz_clear(mrb, y); + y->sn = x->sn; + y->sz = x->sz; + y->p = x->p; + x->p = NULL; + x->sn = 0; + x->sz = 0; +} + +static size_t +digits(mpz_t *x) +{ + size_t i; + + if (x->sz == 0) return 0; + for (i = x->sz - 1; x->p[i] == 0 ; i--) + if (i == 0) break; + return i+1; +} + +static void +trim(mpz_t *x) +{ + while (x->sz && x->p[x->sz-1] == 0) { + x->sz--; + } +} + +/* z = x + y, without regard for sign */ +static void +uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) +{ + if (y->sz < x->sz) { + mpz_t *t; /* swap x,y */ + t=x; x=y; y=t; + } + + /* now y->sz >= x->sz */ + mpz_realloc(mrb, z, y->sz+1); + + mp_dbl_limb c = 0; + size_t i; + for (i=0; isz; i++) { + c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i]; + z->p[i] = LOW(c); + c >>= DIG_SIZE; + } + for (;isz; i++) { + c += y->p[i]; + z->p[i] = LOW(c); + c >>= DIG_SIZE; + } + z->p[y->sz] = (mp_limb)c; + trim(z); +} + +/* z = y - x, ignoring sign */ +/* precondition: abs(y) >= abs(x) */ +static void +usub(mrb_state *mrb, mpz_t *z, mpz_t *y, mpz_t *x) +{ + mpz_realloc(mrb, z, (size_t)(y->sz)); + mp_dbl_limb_signed b = 0; + size_t i; + for (i=0;isz;i++) { + b += (mp_dbl_limb_signed)y->p[i]; + b -= (mp_dbl_limb_signed)x->p[i]; + z->p[i] = LOW(b); + b = HIGH(b); + } + for (;isz; i++) { + b += y->p[i]; + z->p[i] = LOW(b); + b = HIGH(b); + } + z->sz = digits(z); +} + +/* compare abs(x) and abs(y) */ +static int +ucmp(mpz_t *y, mpz_t *x) +{ + if (y->sz < x->sz) return -1; + if (y->sz > x->sz) return 1; + if (x->sz == 0) return 0; + for (size_t i=x->sz-1;; i--) { + mp_limb a = y->p[i]; + mp_limb b = x->p[i]; + if (a > b) return 1; + if (a < b) return -1; + if (i == 0) break; + } + return 0; +} + +static int +uzero(mpz_t *x) +{ + for (size_t i=0; i < x->sz; i++) + if (x->p[i] != 0) + return 0; + return 1; +} + +static void +zero(mpz_t *x) +{ + x->sn=0; + if (x->p) { + x->sz=1; + x->p[0]=0; + } + else { + x->sz=0; + } +} + +/* z = x + y */ +static void +mpz_add(mrb_state *mrb, mpz_t *zz, mpz_t *x, mpz_t *y) +{ + int mg; + mpz_t z; + + if (x->sn == 0) { + mpz_set(mrb, zz, y); + return; + } + if (y->sn == 0) { + mpz_set(mrb, zz, x); + return; + } + mpz_init(mrb, &z); + + if (x->sn > 0 && y->sn > 0) { + uadd(mrb, &z, x, y); + z.sn = 1; + } + else if (x->sn < 0 && y->sn < 0) { + uadd(mrb, &z, x, y); + z.sn = -1; + } + else { + /* signs differ */ + if ((mg = ucmp(x,y)) == 0) { + zero(&z); + } + else if (mg > 0) { /* abs(y) < abs(x) */ + usub(mrb, &z, x, y); + z.sn = (x->sn > 0 && y->sn < 0) ? 1 : (-1); + } + else { /* abs(y) > abs(x) */ + usub(mrb, &z, y, x); + z.sn = (x->sn < 0 && y->sn > 0) ? 1 : (-1); + } + } + trim(&z); + mpz_move(mrb, zz, &z); +} + +/* z = x - y -- just use mpz_add - I'm lazy */ +static void +mpz_sub(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) +{ + mpz_t u; + + mpz_init(mrb, &u); + mpz_set(mrb, &u, y); + u.sn = -(u.sn); + mpz_add(mrb, z, x, &u); + mpz_clear(mrb, &u); +} + +/* x = y - n */ +static void +mpz_sub_int(mrb_state *mrb, mpz_t *x, mpz_t *y, mrb_int n) +{ + mpz_t z; + + mpz_init_set_int(mrb, &z, n); + mpz_sub(mrb, x, y, &z); + mpz_clear(mrb, &z); +} + +/* w = u * v */ +static void +mpz_mul(mrb_state *mrb, mpz_t *ww, mpz_t *u, mpz_t *v) +{ + size_t i, j; + mpz_t w; + + if (uzero(u) || uzero(v)) { + mpz_set_int(mrb, ww, 0); + return; + } + mpz_init(mrb, &w); + mpz_realloc(mrb, &w, u->sz + v->sz); + for (j=0; j < u->sz; j++) { + mp_dbl_limb cc = (mp_limb)0; + mp_limb u0 = u->p[j]; + if (u0 == 0) continue; + for (i=0; i < v->sz; i++) { + mp_limb v0 = v->p[i]; + if (v0 == 0) continue; + cc += (mp_dbl_limb)w.p[i+j] + (mp_dbl_limb)u0 * (mp_dbl_limb)v0; + w.p[i+j] = LOW(cc); + cc = HIGH(cc); + } + if (cc) { + w.p[i+j] = (mp_limb)cc; + } + } + w.sn = u->sn * v->sn; + trim(&w); + mpz_move(mrb, ww, &w); +} + +static void +mpz_mul_int(mrb_state *mrb, mpz_t *x, mpz_t *y, mrb_int n) +{ + if (n == 0) { + zero(x); + return; + } + + mpz_t z; + + mpz_init_set_int(mrb, &z, n); + mpz_mul(mrb, x, y, &z); + mpz_clear(mrb, &z); +} + +/* number of leading zero bits in digit */ +static int +lzb(mp_limb x) +{ + if (x == 0) return 0; +#if (defined(__GNUC__) || __has_builtin(__builtin_clz)) + if (sizeof(mp_limb) == sizeof(int64_t)) + return __builtin_clzll(x); + else if (sizeof(mp_limb) == sizeof(int32_t)) + return __builtin_clz(x); +#endif + + int j=0; + + for (mp_limb i = ((mp_limb)1 << (DIG_SIZE-1)); i && !(x&i) ; j++,i>>=1) + ; + return j; +} + +/* c1 = a>>n */ +/* n must be < DIG_SIZE */ +static void +urshift(mrb_state *mrb, mpz_t *c1, mpz_t *a, size_t n) +{ + mrb_assert(n < DIG_SIZE); + + if (n == 0) + mpz_set(mrb, c1, a); + else if (uzero(a)) { + mpz_set_int(mrb, c1, 0); + } + else { + mpz_t c; + mp_limb cc = 0; + mp_dbl_limb rm = (((mp_dbl_limb)1<sz); + for (size_t i=a->sz-1;; i--) { + c.p[i] = ((a->p[i] >> n) | cc) & DIG_MASK; + cc = (a->p[i] & rm) << (DIG_SIZE - n); + if (i == 0) break; + } + trim(&c); + mpz_move(mrb, c1, &c); + } +} + +/* c1 = a<sz+1); + + size_t i; + for (i=0; isz; i++) { + c.p[i] = ((a->p[i] << n) | cc) & DIG_MASK; + cc = (a->p[i] & rm) >> (DIG_SIZE-n); + } + c.p[i] = cc; + trim(&c); + mpz_move(mrb, c1, &c); + } +} + +/* internal routine to compute x/y and x%y ignoring signs */ +/* qq = xx/yy; rr = xx%yy */ +static void +udiv(mrb_state *mrb, mpz_t *qq, mpz_t *rr, mpz_t *xx, mpz_t *yy) +{ + /* simple cases */ + int cmp = ucmp(xx, yy); + if (cmp == 0) { + mpz_set_int(mrb, qq, 1); + zero(rr); + return; + } + else if (cmp < 0) { + zero(qq); + mpz_set(mrb, rr, xx); + return; + } + + mpz_t q, x, y; + size_t i; + + mrb_assert(!uzero(yy)); /* divided by zero */ + mpz_init(mrb, &q); + mpz_init(mrb, &x); + mpz_init(mrb, &y); + mpz_realloc(mrb, &x, xx->sz+1); + size_t yd = digits(yy); + size_t ns = lzb(yy->p[yd-1]); + ulshift(mrb, &x, xx, ns); + ulshift(mrb, &y, yy, ns); + size_t xd = digits(&x); + mpz_realloc(mrb, &q, xd); + mp_dbl_limb z = y.p[yd-1]; + if (xd>=yd) { + for (size_t j=xd-yd;; j--) { + mp_dbl_limb_signed b=0; + mp_dbl_limb qhat; + + if (j+yd == xd) + qhat = x.p[j+yd-1] / z; + else + qhat = (((mp_dbl_limb)x.p[j+yd] << DIG_SIZE) + x.p[j+yd-1]) / z; + if (qhat) { + for (i=0; isz; + urshift(mrb, rr, &x, ns); + trim(&q); + mpz_move(mrb, qq, &q); + mpz_clear(mrb, &x); + mpz_clear(mrb, &y); +} + +static void +mpz_mdiv(mrb_state *mrb, mpz_t *q, mpz_t *x, mpz_t *y) +{ + mpz_t r; + short sn1 = x->sn, sn2 = y->sn, qsign; + + if (uzero(x)) { + mpz_init_set_int(mrb, q, 0); + return; + } + mpz_init(mrb, &r); + udiv(mrb, q, &r, x, y); + qsign = q->sn = sn1*sn2; + if (uzero(q)) + q->sn = 0; + /* now if r != 0 and q < 0 we need to round q towards -inf */ + if (!uzero(&r) && qsign < 0) + mpz_sub_int(mrb, q, q, 1); + mpz_clear(mrb, &r); +} + +static void +mpz_mmod(mrb_state *mrb, mpz_t *r, mpz_t *x, mpz_t *y) +{ + mpz_t q; + short sn1 = x->sn, sn2 = y->sn, sn3; + + mpz_init(mrb, &q); + if (sn1 == 0) { + zero(r); + return; + } + udiv(mrb, &q, r, x, y); + mpz_clear(mrb, &q); + if (uzero(r)) { + r->sn = 0; + return; + } + sn3 = sn1*sn2; + if (sn3 > 0) + r->sn = sn1; + else if (sn1 < 0 && sn2 > 0) { + r->sn = 1; + mpz_sub(mrb, r, y, r); + } + else { + r->sn = 1; + mpz_add(mrb, r, y, r); + } +} + +static void +mpz_mdivmod(mrb_state *mrb, mpz_t *q, mpz_t *r, mpz_t *x, mpz_t *y) +{ + short sn1 = x->sn, sn2 = y->sn, qsign; + + if (sn1 == 0) { + zero(q); + zero(r); + return; + } + udiv(mrb, q, r, x, y); + qsign = q->sn = sn1*sn2; + if (uzero(r)) { + /* q != 0, since q=r=0 would mean x=0, which was tested above */ + r->sn = 0; + return; + } + if (q->sn > 0) + r->sn = sn1; + else if (sn1 < 0 && sn2 > 0) { + r->sn = 1; + mpz_sub(mrb, r, y, r); + } + else { + r->sn = 1; + mpz_add(mrb, r, y, r); + } + if (uzero(q)) + q->sn = 0; + /* now if r != 0 and q < 0 we need to round q towards -inf */ + if (!uzero(r) && qsign < 0) + mpz_sub_int(mrb, q, q, 1); +} + +static void +mpz_mod(mrb_state *mrb, mpz_t *r, mpz_t *x, mpz_t *y) +{ + mpz_t q; + short sn = x->sn; + mpz_init(mrb, &q); + if (x->sn == 0) { + zero(r); + return; + } + udiv(mrb, &q, r, x, y); + r->sn = sn; + if (uzero(r)) + r->sn = 0; + mpz_clear(mrb, &q); +} + +static mrb_int +mpz_cmp(mrb_state *mrb, mpz_t *x, mpz_t *y) +{ + int abscmp; + if (x->sn < 0 && y->sn > 0) + return (-1); + if (x->sn > 0 && y->sn < 0) + return 1; + abscmp=ucmp(x, y); + if (x->sn >=0 && y->sn >=0) + return abscmp; + return (-abscmp); // if (x->sn <=0 && y->sn <=0) +} + +/* 2<=base<=36 - this overestimates the optimal value, which is OK */ +static size_t +mpz_sizeinbase(mpz_t *x, mrb_int base) +{ + size_t i, j; + + size_t bits = digits(x) * DIG_SIZE; + mrb_assert(2 <= base && base <= 36); + + if (x->sz == 0) return 0; + for (j=0,i=1; i<=(size_t)base; i*=2,j++) + ; + return bits/(j-1)+1; +} + +static int +mpz_init_set_str(mrb_state *mrb, mpz_t *x, const char *s, mrb_int len, mrb_int base) +{ + int retval = 0; + mpz_t t, m, bb; + short sn; + uint8_t k; + mpz_init(mrb, x); + mpz_init_set_int(mrb, &m, 1); + mpz_init(mrb, &t); + zero(x); + if (*s == '-') { + sn = -1; s++; + } + else + sn = 1; + mpz_init_set_int(mrb, &bb, base); + for (mrb_int i = len-1; i>=0; i--) { + if (s[i]=='_') continue; + if (s[i] >= '0' && s[i] <= '9') + k = (uint8_t)s[i] - (uint8_t)'0'; + else if (s[i] >= 'A' && s[i] <= 'Z') + k = (uint8_t)s[i] - (uint8_t)'A'+10; + else if (s[i] >= 'a' && s[i] <= 'z') + k = (uint8_t)s[i] - (uint8_t)'a'+10; + else { + retval = (-1); + break; + } + if (k >= base) { + retval = (-1); + break; + } + mpz_mul_int(mrb, &t, &m, (mrb_int)k); + mpz_add(mrb, x, x, &t); + mpz_mul(mrb, &m, &m, &bb); + } + x->sn = sn; + mpz_clear(mrb, &m); + mpz_clear(mrb, &bb); + mpz_clear(mrb, &t); + return retval; +} + +static char* +mpz_get_str(mrb_state *mrb, char *s, mrb_int sz, mrb_int base, mpz_t *x) +{ + mrb_assert(2 <= base && base <= 36); + if (uzero(x)) { + *s='0'; + *(s+1)='\0'; + return s; + } + + char *ps = s; + char *se = s+sz; + int xlen = (int)digits(x); + mp_limb *t = (mp_limb*)mrb_malloc(mrb, xlen*sizeof(mp_limb)); + mp_limb *tend = t + xlen; + memcpy(t, x->p, xlen*sizeof(mp_limb)); + mp_limb b2 = (mp_limb)base; + const int blim = (sizeof(mp_limb)<4)?(base<=10?4:3):(base<=10?9:5); + for (int i=1; i= t) { + mp_limb d0 = *d; + a = (a<sn < 0) { + *s++ = '-'; + } + + /* reverse string */ + for (char *u = ps,*v=s-1; u < v; u++,v--) { + char temp = *u; + *u = *v; + *v = temp; + } + *s = '\0'; /* null termination */ + return ps; +} + +static int +mpz_get_int(mpz_t *y, mrb_int *v) +{ + if (uzero(y)) { + *v = 0; + return TRUE; + } + + mp_dbl_limb i = 0; + mp_limb *d = y->p + y->sz; + + while (d-- > y->p) { + if (HIGH(i) != 0) { + /* will overflow */ + return FALSE; + } + i = (i << DIG_SIZE) | *d; + } + if (i > MRB_INT_MAX) { + /* overflow */ + return FALSE; + } + if (y->sn < 0) { + *v = -(mrb_int)i; + } + else { + *v = (mrb_int)i; + } + return TRUE; +} + +static void +mpz_mul_2exp(mrb_state *mrb, mpz_t *z, mpz_t *x, mrb_int e) +{ + if (e==0) + mpz_set(mrb, z, x); + else { + short sn = x->sn; + size_t digs = e / DIG_SIZE; + size_t bs = e % DIG_SIZE; + mpz_t y; + + mpz_init(mrb, &y); + mpz_realloc(mrb, &y, x->sz+digs); + for (size_t i=0;isz;i++) + y.p[i+digs] = x->p[i]; + if (bs) { + ulshift(mrb, z, &y, bs); + mpz_clear(mrb, &y); + } + else { + mpz_move(mrb, z, &y); + } + z->sn = sn; + } +} + +static void +mpz_div_2exp(mrb_state *mrb, mpz_t *z, mpz_t *x, mrb_int e) +{ + short sn = x->sn; + if (e==0) + mpz_set(mrb, z, x); + else { + size_t digs = e / DIG_SIZE; + size_t bs = e % DIG_SIZE; + mpz_t y; + + mpz_init(mrb, &y); + mpz_realloc(mrb, &y, x->sz-digs); + for (size_t i=0; i < x->sz-digs; i++) + y.p[i] = x->p[i+digs]; + if (bs) { + urshift(mrb, z, &y, bs); + mpz_clear(mrb, &y); + } + else { + mpz_move(mrb, z, &y); + } + if (uzero(z)) + z->sn = 0; + else { + z->sn = sn; + } + } +} + +static void +mpz_neg(mrb_state *mrb, mpz_t *x, mpz_t *y) +{ + if (x!=y) + mpz_set(mrb, x, y); + x->sn = -(y->sn); +} + +static void +mpz_and(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ +{ + size_t sz = imin(x->sz, y->sz); + + mpz_realloc(mrb, z, sz); + for (size_t i=0; i < sz; i++) + z->p[i] = x->p[i] & y->p[i]; + if (x->sn < 0 && y->sn < 0) + z->sn = (-1); + else + z->sn = 1; + if (uzero(z)) + z->sn = 0; +} + +static void +mpz_or(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ +{ + size_t i; + size_t sz = imax(x->sz, y->sz); + + mpz_realloc(mrb, z, sz); + for (i=0; i < sz; i++) + z->p[i] = dg(x,i) | dg(y,i); + if (x->sn < 0 || y->sn < 0) + z->sn = (-1); + else + z->sn = 1; + if (uzero(z)) + z->sn = 0; +} + +static void +mpz_xor(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ +{ + size_t i; + + size_t sz = imax(x->sz, y->sz); + mpz_realloc(mrb, z, sz); + for (i=0; i < sz; i++) + z->p[i] = dg(x,i) ^ dg(y,i); + if ((x->sn <= 0 && y->sn > 0) || (x->sn > 0 && y->sn <=0)) + z->sn = (-1); + else + z->sn = 1; + if (uzero(z)) + z->sn = 0; +} + +static void +mpz_pow(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int e) +{ + mpz_t t; + mrb_uint mask = 1ULL<<(sizeof(mrb_int)*8-1); + + if (e==0) { + mpz_set_int(mrb, zz, 1L); + return; + } + + mpz_init(mrb, &t); + mpz_set(mrb, &t, x); + for (;!(mask &e); mask>>=1) + ; + mask>>=1; + for (;mask!=0; mask>>=1) { + mpz_mul(mrb, &t, &t, &t); + if (e & mask) + mpz_mul(mrb, &t, &t, x); + } + mpz_move(mrb, zz, &t); +} + +static void +mpz_powm(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int ex, mpz_t *n) +{ + mpz_t t, b; + + if (ex == 0) { + mpz_set_int(mrb, zz, 1); + return; + } + + if (ex < 0) { + return; + } + + mpz_init_set_int(mrb, &t, 1); + mpz_init_set(mrb, &b, x); + + while (ex > 0) { + if ((ex & 1) == 1) { + mpz_mul(mrb, &t, &t, &b); + mpz_mod(mrb, &t, &t, n); + } + ex >>= 1; + mpz_mul(mrb, &b, &b, &b); + mpz_mod(mrb, &b, &b, n); + } + mpz_move(mrb, zz, &t); + mpz_clear(mrb, &b); +} + +/* --- mruby functions --- */ +static struct RBigint* +bint_new(mrb_state *mrb) +{ + struct RBigint *b = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class); + mpz_init(mrb, &b->mp); + return b; +} + +static struct RBigint* +bint_new_int(mrb_state *mrb, mrb_int x) +{ + struct RBigint *b = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class); + mpz_init_set_int(mrb, &b->mp, x); + return b; +} + +mrb_value +mrb_bint_new(mrb_state *mrb) +{ + struct RBigint *b = bint_new(mrb); + return mrb_obj_value(b); +} + +mrb_value +mrb_bint_new_int(mrb_state *mrb, mrb_int x) +{ + struct RBigint *b = bint_new_int(mrb, x); + return mrb_obj_value(b); +} + +mrb_value +mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base) +{ + struct RBigint *b = MRB_OBJ_ALLOC(mrb, MRB_TT_BIGINT, mrb->integer_class); + int sn = 1; + if (base < 0) { + base = -base; + sn = -1; + } + mrb_assert(2 <= base && base <= 36); + mpz_init_set_str(mrb, &b->mp, x, len, base); + if (sn < 0) { + b->mp.sn = sn; + } + return mrb_obj_value(b); +} + +static mrb_value +bint_norm(mrb_state *mrb, struct RBigint *b) +{ + mrb_int i; + + if (mpz_get_int(&b->mp, &i)) { + return mrb_int_value(mrb, i); + } + return mrb_obj_value(b); +} + +void +mrb_gc_free_bint(mrb_state *mrb, struct RBasic *x) +{ + struct RBigint *b = (struct RBigint*)x; + mpz_clear(mrb, &b->mp); +} + +#ifndef MRB_NO_FLOAT +mrb_value +mrb_bint_new_float(mrb_state *mrb, mrb_float x) +{ + /* x should not be NaN nor Infinity */ + mrb_assert(x == x && x != x * 0.5); + + int sn; + if (x < 0.0) { + x = -x; + sn = -1; + } + else { + sn = 1; + } + if (x < 1.0) { + return mrb_fixnum_value(0); + } + + struct RBigint *bint = bint_new(mrb); + mpz_t *r = &bint->mp; + r->sn = sn; + + mrb_float b = (double)DIG_BASE; + mrb_float bi = 1.0 / b; + size_t rn; + mp_limb *rp; + mp_limb f; + + for (rn = 1; x >= b; rn++) + x *= bi; + + mpz_realloc(mrb, r, rn); + rp = r->p; + for (size_t i=rn-1;;i--) { + f = LOW((mp_limb)x); + x -= f; + mrb_assert(x < 1.0); + rp[i] = f; + if (i == 0) break; + } + return bint_norm(mrb, bint); +} + +mrb_float +mrb_bint_as_float(mrb_state *mrb, mrb_value self) +{ + struct RBigint *b = RBIGINT(self); + mpz_t *i = &b->mp; + mp_limb *d = i->p + i->sz; + mrb_float val = 0; + + while (d-- > i->p) { + val = val * DIG_BASE + *d; + } + + if (i->sn < 0) { + val = -val; + } + return val; +} +#endif + +mrb_value +mrb_as_bint(mrb_state *mrb, mrb_value x) +{ + if (mrb_bigint_p(x)) return x; + return mrb_bint_new_int(mrb, mrb_as_int(mrb, x)); +} + +mrb_int +mrb_bint_as_int(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + mrb_int i; + + if (!mpz_get_int(&b->mp, &i)) { + mrb_raise(mrb, E_RANGE_ERROR, "integer out of range"); + } + return i; +} + +mrb_value +mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1+v2); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_add(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1-v2); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_sub(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1*v2); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_mul(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb,v1*v2); + } +#endif + if (mrb_integer_p(y) && mrb_integer(y) == 0) { + mrb_int_zerodiv(mrb); + } + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + if (b2->mp.sn == 0 || uzero(&b2->mp)) { + mrb_int_zerodiv(mrb); + } + mpz_mdiv(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_add_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb, &z1, x); + mpz_init_set_int(mrb, &z2, y); + mpz_add(mrb, &b->mp, &z1, &z2); + mpz_clear(mrb, &z1); + mpz_clear(mrb, &z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_sub_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb, &z1, x); + mpz_init_set_int(mrb, &z2, y); + mpz_sub(mrb, &b->mp, &z1, &z2); + mpz_clear(mrb, &z1); + mpz_clear(mrb, &z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb, &z1, x); + mpz_init_set_int(mrb, &z2, y); + mpz_mul(mrb, &b->mp, &z1, &z2); + mpz_clear(mrb, &z1); + mpz_clear(mrb, &z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_div_ii(mrb_state *mrb, mrb_int x, mrb_int y) +{ + struct RBigint *b = bint_new(mrb); + mpz_t z1, z2; + + mpz_init_set_int(mrb, &z1, x); + mpz_init_set_int(mrb, &z2, y); + mpz_mdiv(mrb, &b->mp, &z1, &z2); + mpz_clear(mrb, &z1); + mpz_clear(mrb, &z2); + return bint_norm(mrb, b); +} + +mrb_value +mrb_bint_mod(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + return mrb_float_value(mrb, fmod(v1, v2)); + } +#endif + if (mrb_integer_p(y) && mrb_integer(y) == 0) { + mrb_int_zerodiv(mrb); + } + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + if (b2->mp.sn == 0 || uzero(&b2->mp)) { + mrb_int_zerodiv(mrb); + } + mpz_mmod(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_rem(mrb_state *mrb, mrb_value x, mrb_value y) +{ + /* called from mrbgems/mruby-numeric-ext/src/numeric_ext.c */ + /* y should not be float */ + if (mrb_integer_p(y) && mrb_integer(y) == 0) { + mrb_int_zerodiv(mrb); + } + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + if (b2->mp.sn == 0 || uzero(&b2->mp)) { + mrb_int_zerodiv(mrb); + } + mpz_mod(mrb, &b3->mp, &b->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_divmod(mrb_state *mrb, mrb_value x, mrb_value y) +{ + /* called from src/numeric.c */ + /* y should not be float */ + if (mrb_integer_p(y) && mrb_integer(y) == 0) { + mrb_int_zerodiv(mrb); + } + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + struct RBigint *b4 = bint_new(mrb); + if (b2->mp.sn == 0 || uzero(&b2->mp)) { + mrb_int_zerodiv(mrb); + } + mpz_mdivmod(mrb, &b3->mp, &b4->mp, &b->mp, &b2->mp); + x = bint_norm(mrb, b3); + y = bint_norm(mrb, b4); + return mrb_assoc_new(mrb, x, y); +} + +mrb_int +mrb_bint_cmp(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float v1 = mrb_bint_as_float(mrb, x); + mrb_float v2 = mrb_float(y); + if (v1 == v2) return 0; + if (v1 > v2) return 1; + return -1; + } +#endif + struct RBigint *b = RBIGINT(x); + if (!mrb_bigint_p(y)) { + if (!mrb_integer_p(y)) return -2; /* type mismatch */ + + mrb_int i1, i2 = mrb_integer(y); + if (mpz_get_int(&b->mp, &i1)) { + if (i1 == i2) return 0; + if (i1 > i2) return 1; + return -1; + } + if (b->mp.sn > 0) return 1; + return -1; + } + struct RBigint *b2 = RBIGINT(y); + return mpz_cmp(mrb, &b->mp, &b2->mp); +} + +mrb_value +mrb_bint_pow(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b = RBIGINT(x); + switch (mrb_type(y)) { + case MRB_TT_INTEGER: + { + struct RBigint *b3 = bint_new(mrb); + mpz_pow(mrb, &b3->mp, &b->mp, mrb_integer(y)); + return mrb_obj_value(b3); + } + case MRB_TT_BIGINT: + mrb_raise(mrb, E_TYPE_ERROR, "too big power"); + default: + mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be convert to integer", y); + } + return mrb_nil_value(); +} + +mrb_value +mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_int exp, mrb_value mod) +{ + struct RBigint *b = RBIGINT(x); + switch (mrb_type(mod)) { + case MRB_TT_INTEGER: + { + mrb_int m = mrb_integer(mod); + if (m == 0) mrb_int_zerodiv(mrb); + struct RBigint *b2 = bint_new_int(mrb, m); + struct RBigint *b3 = bint_new(mrb); + mpz_powm(mrb, &b3->mp, &b->mp, exp, &b2->mp); + return bint_norm(mrb, b3); + } + case MRB_TT_BIGINT: + { + struct RBigint *b2 = RBIGINT(mod); + struct RBigint *b3 = bint_new(mrb); + if (uzero(&b2->mp)) mrb_int_zerodiv(mrb); + mpz_powm(mrb, &b3->mp, &b->mp, exp, &b2->mp); + return bint_norm(mrb, b3); + } + mrb_raise(mrb, E_TYPE_ERROR, "too big power"); + default: + mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be convert to integer", mod); + } + return mrb_nil_value(); +} + +mrb_value +mrb_bint_to_s(mrb_state *mrb, mrb_value x, mrb_int base) +{ + struct RBigint *b = RBIGINT(x); + + if (b->mp.sz == 0) return mrb_str_new_lit(mrb, "0"); + + size_t len = mpz_sizeinbase(&b->mp, (int)base); + if (MRB_INT_MAX-2 < len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string from Integer"); + } + mrb_value str = mrb_str_new(mrb, NULL, len+2); + mpz_get_str(mrb, RSTRING_PTR(str), len, base, &b->mp); + RSTR_SET_LEN(RSTRING(str), strlen(RSTRING_PTR(str))); + return str; +} + +mrb_value +mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b1 = RBIGINT(x); + struct RBigint *b3 = bint_new(mrb); + +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mpz_t z; + mpz_init_set_int(mrb, &z, (mrb_int)mrb_float(y)); + mpz_and(mrb, &b3->mp, &b1->mp, &z); + mpz_clear(mrb, &z); + return bint_norm(mrb, b3); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b2 = RBIGINT(y); + mpz_and(mrb, &b3->mp, &b1->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_or(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b1 = RBIGINT(x); + struct RBigint *b3 = bint_new(mrb); + +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mpz_t z; + mpz_init_set_int(mrb, &z, (mrb_int)mrb_float(y)); + mpz_or(mrb, &b3->mp, &b1->mp, &z); + mpz_clear(mrb, &z); + return bint_norm(mrb, b3); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b2 = RBIGINT(y); + mpz_or(mrb, &b3->mp, &b1->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b3 = bint_new(mrb); + struct RBigint *b1 = RBIGINT(x); + +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mpz_t z; + mpz_init_set_int(mrb, &z, (mrb_int)mrb_float(y)); + mpz_xor(mrb, &b3->mp, &b1->mp, &z); + mpz_clear(mrb, &z); + return bint_norm(mrb, b3); + } +#endif + y = mrb_as_bint(mrb, y); + struct RBigint *b2 = RBIGINT(y); + mpz_xor(mrb, &b3->mp, &b1->mp, &b2->mp); + return bint_norm(mrb, b3); +} + +mrb_value +mrb_bint_rev(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b1 = RBIGINT(x); + struct RBigint *b2 = bint_new(mrb); + + mpz_neg(mrb, &b2->mp, &b1->mp); + mpz_sub_int(mrb, &b2->mp, &b2->mp, 1); + return bint_norm(mrb, b2); +} + +mrb_value +mrb_bint_lshift(mrb_state *mrb, mrb_value x, mrb_int width) +{ + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = bint_new(mrb); + if (width < 0) { + mpz_div_2exp(mrb, &b2->mp, &b->mp, -width); + } + else { + mpz_mul_2exp(mrb, &b2->mp, &b->mp, width); + } + return bint_norm(mrb, b2); +} + +mrb_value +mrb_bint_rshift(mrb_state *mrb, mrb_value x, mrb_int width) +{ + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = bint_new(mrb); + if (width < 0) { + mpz_mul_2exp(mrb, &b2->mp, &b->mp, -width); + } + else { + mpz_div_2exp(mrb, &b2->mp, &b->mp, width); + } + return bint_norm(mrb, b2); +} + +void +mrb_bint_copy(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + mpz_init_set(mrb, &b->mp, &b2->mp); +} + +size_t +mrb_bint_memsize(mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + return b->mp.sz * sizeof(mp_limb); +} + +mrb_value +mrb_bint_hash(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + uint32_t hash = mrb_byte_hash((uint8_t*)b->mp.p, b->mp.sz); + hash = mrb_byte_hash_step((uint8_t*)&b->mp.sn, sizeof(b->mp.sn), hash); + return mrb_int_value(mrb, hash); +} diff --git a/mruby/mrbgems/mruby-bigint/core/bigint.h b/mruby/mrbgems/mruby-bigint/core/bigint.h new file mode 100644 index 00000000..a9a4194f --- /dev/null +++ b/mruby/mrbgems/mruby-bigint/core/bigint.h @@ -0,0 +1,63 @@ +/** +** @file mruby/bigint.h - Multi-precision Integer +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_BIGINT_H +#define MRUBY_BIGINT_H +/* + * FREE GMP - a public domain implementation of a subset of the + * gmp library + * + * I hearby place the file in the public domain. + * + * Do whatever you want with this code. Change it. Sell it. Claim you + * wrote it. + * Bugs, complaints, flames, rants: please send email to + * Mark Henderson + * I'm already aware that fgmp is considerably slower than gmp + * + * CREDITS: + * Paul Rouse - generic bug fixes, mpz_sqrt and + * mpz_sqrtrem, and modifications to get fgmp to compile on a system + * with int and long of different sizes (specifically MS-DOS,286 compiler) + * Also see the file "notes" included with the fgmp distribution, for + * more credits. + * + * VERSION 1.0 - beta 5 + */ + +#include + +#if defined(MRB_INT32) && defined(_WIN32) && !defined(MRB_NO_MPZ64BIT) +#define MRB_NO_MPZ64BIT +#endif + +#ifdef MRB_NO_MPZ64BIT +typedef uint16_t mp_limb; +typedef uint32_t mp_dbl_limb; +typedef int32_t mp_dbl_limb_signed; +#define MPZ_DIG_SIZE 16 +#else +typedef uint32_t mp_limb; +typedef uint64_t mp_dbl_limb; +typedef int64_t mp_dbl_limb_signed; +#define MPZ_DIG_SIZE 32 +#endif + +typedef struct _mpz_t { + mp_limb *p; + short sn; + size_t sz; +} mpz_t; + +struct RBigint { + MRB_OBJECT_HEADER; + mpz_t mp; +}; +#define RBIGINT(v) ((struct RBigint*)mrb_ptr(v)) + +mrb_static_assert_object_size(struct RBigint); + +#endif /* MRUBY_BIGINT_H */ diff --git a/mruby/mrbgems/mruby-bigint/mrbgem.rake b/mruby/mrbgems/mruby-bigint/mrbgem.rake new file mode 100644 index 00000000..a1039bf5 --- /dev/null +++ b/mruby/mrbgems/mruby-bigint/mrbgem.rake @@ -0,0 +1,10 @@ +MRuby::Gem::Specification.new('mruby-bigint') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'Integer class extension to multiple-precision' + spec.build.defines << "MRB_USE_BIGINT" + + spec.build.libmruby_core_objs << Dir.glob(File.join(__dir__, "core/**/*.c")).map { |fn| + objfile(fn.relative_path_from(__dir__).pathmap("#{spec.build_dir}/%X")) + } +end diff --git a/mruby/mrbgems/mruby-bigint/test/bigint.rb b/mruby/mrbgems/mruby-bigint/test/bigint.rb new file mode 100644 index 00000000..8ab09548 --- /dev/null +++ b/mruby/mrbgems/mruby-bigint/test/bigint.rb @@ -0,0 +1,23 @@ +assert 'Bigint basic' do + n = 1<<65 + assert_equal 36893488147419103232, n + assert_equal 36893488147419104229, n+997 + assert_equal 36893488147419102235, n-997 + assert_equal 36782807682976845922304, n*997 + assert_equal 37004501652376231, n.div(997) +end + +assert 'Bigint to_s' do + n = 1197857166996989179607278372168909873645893814254642585755536286462800958278984531968 + assert_equal n, "11978_571669_96989179607278372168909873645893814254642585755536286462800958278984531968".to_i + assert_equal(-n, "-11978_571669_96989179607278372168909873645893814254642585755536286462800958278984531968".to_i) + n = 0x1197857166996989179607278372168909873645893814254642585755536286462800958278984531968 + assert_equal n, "1197857166996989179607278372168909873645893814254642585755536286462800958278984531968".to_i(16) +end + +assert 'Bigint pow' do + n = 18446744073709551616 + assert_equal n, 2 ** 64 + assert_equal n, 1 << 64 + assert_equal 2, n >> 63 +end diff --git a/mruby/mrbgems/mruby-bin-config/mruby-config b/mruby/mrbgems/mruby-bin-config/mruby-config old mode 100644 new mode 100755 diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index 55c6cd12..a69d65dd 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "mrdberror.h" #include "apibreak.h" #include "apistring.h" @@ -20,8 +21,6 @@ #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) { @@ -47,8 +46,8 @@ check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno) case mrb_debug_line_packed_map: { - uint8_t *p = info_file->lines.packed_map; - uint8_t *pend = p + count; + const uint8_t *p = info_file->lines.packed_map; + const uint8_t *pend = p + count; uint32_t line = 0; while (p < pend) { mrb_packed_int_decode(p, &p); diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index ee2ae0ac..340a57b5 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "mrdb.h" #include "apibreak.h" diff --git a/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb b/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb index 62f863c2..57f8dc8f 100644 --- a/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +++ b/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb @@ -7,6 +7,12 @@ assert_true o.include?('=> 2') end +assert('mirb multi-line') do + o, s = Open3.capture2(cmd("mirb"), :stdin_data => "def a(b)\n return b\n end\na(1)\n") + assert_true o.include?('=> :a') + assert_true o.include?('=> 1') +end + assert('regression for #1563') do o, s = Open3.capture2(cmd("mirb"), :stdin_data => "a=1;b=2;c=3\nb\nc") assert_true o.include?('=> 3') diff --git a/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index db92d726..78c3ed40 100644 --- a/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include #include #include @@ -148,7 +150,7 @@ is_code_block_open(struct mrb_parser_state *parser) /* check if parser error are available */ if (0 < parser->nerr) { - const char unexpected_end[] = "syntax error, unexpected $end"; + const char unexpected_end[] = "syntax error, unexpected end of file"; const char *message = parser->error_buffer[0].message; /* a parser error occur, we have to check if */ @@ -379,8 +381,6 @@ print_cmdline(int code_block_open) } #endif -void mrb_codedump_all(mrb_state*, struct RProc*); - static int check_keyword(const char *buf, const char *word) { @@ -519,7 +519,7 @@ main(int argc, char **argv) fclose(lfp); e = mrb_vm_ci_env(mrb->c->cibase); mrb_vm_ci_env_set(mrb->c->cibase, NULL); - mrb_env_unshare(mrb, e); + mrb_env_unshare(mrb, e, FALSE); mrbc_cleanup_local_variables(mrb, cxt); } @@ -674,6 +674,7 @@ main(int argc, char **argv) stack_keep = proc->body.irep->nlocals; /* did an exception occur? */ if (mrb->exc) { + MRB_EXC_CHECK_EXIT(mrb, mrb->exc); p(mrb, mrb_obj_value(mrb->exc), 0); mrb->exc = 0; } @@ -704,7 +705,7 @@ main(int argc, char **argv) if (args.rfp) fclose(args.rfp); mrb_free(mrb, args.argv); if (args.libv) { - for (i = 0; i < args.libc; ++i) { + for (i = 0; i < args.libc; i++) { mrb_free(mrb, args.libv[i]); } mrb_free(mrb, args.libv); diff --git a/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index 7732914d..505d4509 100644 --- a/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -9,6 +9,7 @@ #include #include #include +#include #define RITEBIN_EXT ".mrb" #define C_EXT ".c" @@ -25,7 +26,8 @@ struct mrbc_args { mrb_bool verbose : 1; mrb_bool remove_lv : 1; mrb_bool no_ext_ops : 1; - uint8_t flags : 4; + mrb_bool no_optimize : 1; + uint8_t flags : 2; }; static void @@ -42,6 +44,7 @@ usage(const char *name) "-s define as static variable", "--remove-lv remove local variables", "--no-ext-ops prohibit using OP_EXTs", + "--no-optimize disable peephole optimization", "--verbose run at verbose mode", "--version print the version", "--copyright print the copyright", @@ -169,6 +172,10 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args) args->no_ext_ops = TRUE; break; } + else if (strcmp(argv[i] + 2, "no-optimize") == 0) { + args->no_optimize = TRUE; + break; + } return -1; default: return i; @@ -224,6 +231,7 @@ load_file(mrb_state *mrb, struct mrbc_args *args) c->dump_result = TRUE; c->no_exec = TRUE; c->no_ext_ops = args->no_ext_ops; + c->no_optimize = args->no_optimize; if (input[0] == '-' && input[1] == '\0') { infile = stdin; } @@ -338,7 +346,7 @@ main(int argc, char **argv) } } else { - fprintf(stderr, "Output file is required\n"); + fputs("Output file is required\n", stderr); return EXIT_FAILURE; } result = dump_file(mrb, wfp, args.outfile, mrb_proc_ptr(load), &args); @@ -366,31 +374,3 @@ mrb_final_mrbgems(mrb_state *mrb) { } #endif - -#ifdef MRB_USE_COMPLEX -mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value comp) -{ - /* dummy method */ - return mrb_nil_value(); -} -mrb_value mrb_complex_to_f(mrb_state *mrb, mrb_value comp) -{ - /* dummy method */ - return mrb_nil_value(); -} -#endif - -#ifdef MRB_USE_RATIONAL -mrb_value -mrb_rational_to_i(mrb_state *mrb, mrb_value rat) -{ - /* dummy method */ - return mrb_nil_value(); -} -mrb_value -mrb_rational_to_f(mrb_state *mrb, mrb_value rat) -{ - /* dummy method */ - return mrb_nil_value(); -} -#endif diff --git a/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c new file mode 100644 index 00000000..13ca0393 --- /dev/null +++ b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c @@ -0,0 +1,74 @@ +#include + +/* + functions defined in mrbgems referenced from the core should be listed here + to avoid link errors, since mrbc does not link any mrbgem ignoring configuration. +*/ + +#ifdef MRB_USE_COMPLEX +mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +mrb_value mrb_complex_to_f(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +void mrb_complex_copy(mrb_state *mrb, mrb_value x, mrb_value y) +{ +} +#endif + +#ifdef MRB_USE_RATIONAL +mrb_value mrb_rational_new(mrb_state *mrb, mrb_int x, mrb_int y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_to_i(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +mrb_value mrb_rational_to_f(mrb_state *mrb, mrb_value x) +{ + return mrb_nil_value(); +} +void mrb_rational_copy(mrb_state *mrb, mrb_value x, mrb_value y) +{ +} +#endif diff --git a/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index b189aca6..3faaaccd 100644 --- a/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #if defined(_WIN32) || defined(_WIN64) # include /* for setmode */ @@ -63,6 +65,16 @@ usage(const char *name) printf(" %s\n", *p++); } +static mrb_bool +mrb_extension_p(const char *path) +{ + const char *e = strrchr(path, '.'); + if (e && e[1] == 'm' && e[2] == 'r' && e[3] == 'b' && e[4] == '\0') { + return TRUE; + } + return FALSE; +} + static void options_init(struct options *opts, int argc, char **argv) { @@ -92,7 +104,7 @@ options_opt(struct options *opts) if (opts->opt[1] == '-') { /* `--` */ if (!opts->opt[2]) { - ++opts->argv, --opts->argc; + opts->argv++, opts->argc--; return NULL; } /* long option */ @@ -102,7 +114,7 @@ options_opt(struct options *opts) } else { /* short option */ - ++opts->opt; + opts->opt++; goto short_opt; } } @@ -323,7 +335,7 @@ main(int argc, char **argv) return EXIT_FAILURE; } mrbc_filename(mrb, c, args.libv[i]); - if (args.mrbfile) { + if (mrb_extension_p(args.libv[i])) { v = mrb_load_irep_file_cxt(mrb, lfp, c); } else { @@ -332,7 +344,7 @@ main(int argc, char **argv) fclose(lfp); e = mrb_vm_ci_env(mrb->c->cibase); mrb_vm_ci_env_set(mrb->c->cibase, NULL); - mrb_env_unshare(mrb, e); + mrb_env_unshare(mrb, e, FALSE); mrbc_cleanup_local_variables(mrb, c); } @@ -340,7 +352,7 @@ main(int argc, char **argv) mrbc_filename(mrb, c, cmdline); /* Load program */ - if (args.mrbfile) { + if (args.mrbfile || mrb_extension_p(cmdline)) { v = mrb_load_irep_file_cxt(mrb, args.rfp, c); } else if (args.rfp) { @@ -356,6 +368,7 @@ main(int argc, char **argv) mrb_gc_arena_restore(mrb, ai); mrbc_context_free(mrb, c); if (mrb->exc) { + MRB_EXC_CHECK_EXIT(mrb, mrb->exc); if (!mrb_undef_p(v)) { mrb_print_error(mrb); } diff --git a/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c index 0c632b7c..8615afce 100644 --- a/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c +++ b/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c @@ -8,6 +8,7 @@ #include #include #include +#include struct strip_args { int argc_start; @@ -34,7 +35,7 @@ parse_args(int argc, char **argv, struct strip_args *args) args->argv = argv; args->lvar = FALSE; - for (i = 1; i < argc; ++i) { + for (i = 1; i < argc; i++) { const size_t len = strlen(argv[i]); if (len >= 2 && argv[i][0] == '-') { switch (argv[i][1]) { @@ -64,7 +65,7 @@ strip(mrb_state *mrb, struct strip_args *args) { int i; - for (i = args->argc_start; i < args->argc; ++i) { + for (i = args->argc_start; i < args->argc; i++) { char *filename; FILE *rfile; mrb_irep *irep; diff --git a/mruby/mrbgems/mruby-binding-core/src/binding-core.c b/mruby/mrbgems/mruby-binding-core/src/binding-core.c index 5e104e72..47ec34f8 100644 --- a/mruby/mrbgems/mruby-binding-core/src/binding-core.c +++ b/mruby/mrbgems/mruby-binding-core/src/binding-core.c @@ -254,7 +254,7 @@ mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv * (*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; (*envp)->mid = 0; - (*envp)->flags = MRB_ENV_CLOSED | MRB_ENV_HEAPED; + (*envp)->flags = MRB_ENV_CLOSED; MRB_ENV_SET_LEN(*envp, 1); return lvspace; diff --git a/mruby/mrbgems/mruby-binding/src/binding.c b/mruby/mrbgems/mruby-binding/src/binding.c index eb44f0e9..de3147f6 100644 --- a/mruby/mrbgems/mruby-binding/src/binding.c +++ b/mruby/mrbgems/mruby-binding/src/binding.c @@ -4,12 +4,11 @@ #include #include #include -#include #include +#include +#include -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); @@ -45,7 +44,7 @@ binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char struct expand_lvspace { mrb_irep *irep; struct REnv *env; - size_t numvar; + int numvar; mrb_sym syms[LV_BUFFERS]; }; diff --git a/mruby/mrbgems/mruby-binding/test/binding.c b/mruby/mrbgems/mruby-binding/test/binding.c index 5a37ca04..efc982a7 100644 --- a/mruby/mrbgems/mruby-binding/test/binding.c +++ b/mruby/mrbgems/mruby-binding/test/binding.c @@ -1,9 +1,10 @@ #include +#include static mrb_value binding_in_c(mrb_state *mrb, mrb_value self) { - return mrb_funcall_argv(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "binding"), 0, NULL); + return mrb_funcall_argv(mrb, mrb_obj_value(mrb->object_class), MRB_SYM(binding), 0, NULL); } void diff --git a/mruby/mrbgems/mruby-class-ext/src/class.c b/mruby/mrbgems/mruby-class-ext/src/class.c index 290ddf4b..dbe06152 100644 --- a/mruby/mrbgems/mruby-class-ext/src/class.c +++ b/mruby/mrbgems/mruby-class-ext/src/class.c @@ -1,7 +1,10 @@ #include "mruby.h" #include "mruby/class.h" #include "mruby/string.h" +#include "mruby/array.h" #include "mruby/proc.h" +#include "mruby/variable.h" +#include "mruby/presym.h" static mrb_value mrb_mod_name(mrb_state *mrb, mrb_value self) @@ -56,6 +59,84 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self) return mrb_yield_cont(mrb, blk, self, argc, argv); } +struct subclass_args { + struct RClass *c; + mrb_value ary; +}; + +static int +add_subclasses(mrb_state *mrb, struct RBasic *obj, void *data) +{ + struct subclass_args *args = (struct subclass_args*)data; + if (obj->tt == MRB_TT_CLASS) { + struct RClass *c = (struct RClass*)obj; + if (mrb_class_real(c->super) == args->c) { + mrb_ary_push(mrb, args->ary, mrb_obj_value(obj)); + } + } + return MRB_EACH_OBJ_OK; +} + +/* + * call-seq: + * subclasses -> array + * + * Returns an array of classes where the receiver is the + * direct superclass of the class, excluding singleton classes. + * The order of the returned array is not defined. + * + * class A; end + * class B < A; end + * class C < B; end + * class D < A; end + * + * A.subclasses #=> [D, B] + * B.subclasses #=> [C] + * C.subclasses #=> [] + */ +static mrb_value +mrb_class_subclasses(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + mrb_value ary; + + c = mrb_class_ptr(self); + ary = mrb_ary_new(mrb); + + if (c->flags & MRB_FL_CLASS_IS_INHERITED) { + struct subclass_args arg = {c, ary}; + mrb_objspace_each_objects(mrb, add_subclasses, &arg); + } + return ary; +} + +/* + * call-seq: + * attached_object -> object + * + * Returns the object for which the receiver is the singleton class. + * Raises an TypeError if the class is not a singleton class. + * + * class Foo; end + * + * Foo.singleton_class.attached_object #=> Foo + * Foo.attached_object #=> TypeError: not a singleton class + * Foo.new.singleton_class.attached_object #=> # + * TrueClass.attached_object #=> TypeError: not a singleton class + * NilClass.attached_object #=> TypeError: not a singleton class + */ +static mrb_value +mrb_class_attached_object(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + + c = mrb_class_ptr(self); + if (c->tt != MRB_TT_SCLASS) { + mrb_raise(mrb, E_TYPE_ERROR, "not a singleton class"); + } + return mrb_obj_iv_get(mrb, (struct RObject*)c, MRB_SYM(__attached__)); +} + void mrb_mruby_class_ext_gem_init(mrb_state *mrb) { @@ -65,6 +146,10 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb) mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE()); mrb_define_method(mrb, mod, "module_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); mrb_define_method(mrb, mod, "class_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); + + struct RClass *cls = mrb->class_class; + mrb_define_method(mrb, cls, "subclasses", mrb_class_subclasses, MRB_ARGS_NONE()); + mrb_define_method(mrb, cls, "attached_object", mrb_class_attached_object, MRB_ARGS_NONE()); } void diff --git a/mruby/mrbgems/mruby-class-ext/test/class.rb b/mruby/mrbgems/mruby-class-ext/test/class.rb new file mode 100644 index 00000000..fba2a19f --- /dev/null +++ b/mruby/mrbgems/mruby-class-ext/test/class.rb @@ -0,0 +1,29 @@ +assert 'Class#subclasses' do + a = Class.new + b = Class.new(a) + c = Class.new(b) + d = Class.new(a) + + a_sub = a.subclasses + assert_equal(2, a_sub.size) + assert_true(a_sub.include?(b)) + assert_true(a_sub.include?(d)) + assert_equal([c], b.subclasses) + assert_equal([], c.subclasses) +end + +assert 'Class#attached_object' do + foo = Class.new + foo_s = class < 'mruby-complex' end diff --git a/mruby/mrbgems/mruby-cmath/test/cmath.rb b/mruby/mrbgems/mruby-cmath/test/cmath.rb index ddd0e510..b48939ca 100644 --- a/mruby/mrbgems/mruby-cmath/test/cmath.rb +++ b/mruby/mrbgems/mruby-cmath/test/cmath.rb @@ -27,7 +27,7 @@ def assert_complex(c1, c2) assert('CMath trigonometric_functions') do assert_complex(Math.sinh(2).i, CMath.sin(2i)) - assert_complex(Math.cosh(2)+0i, CMath.cos(2i)) + assert_complex(Math.cosh(2)+0i, CMath.cos(2i)) assert_complex(Math.tanh(2).i, CMath.tan(2i)) assert_complex(Math.sin(2).i, CMath.sinh(2i)) assert_complex(Math.cos(2)+0i, CMath.cosh(2i)) diff --git a/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb b/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb index d66f816e..18bba791 100644 --- a/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +++ b/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb @@ -1,28 +1,80 @@ module Comparable ## - # Returns min if obj <=> min is less - # than zero, max if obj <=> max is - # greater than zero and obj otherwise. + # call-seq: + # obj.clamp(min, max) -> obj + # obj.clamp(range) -> obj # - # 12.clamp(0, 100) #=> 12 - # 523.clamp(0, 100) #=> 100 - # -3.123.clamp(0, 100) #=> 0 + # In (min, max) form, returns _min_ if _obj_ + # <=> _min_ is less than zero, _max_ if _obj_ + # <=> _max_ is greater than zero, and _obj_ + # otherwise. # - # 'd'.clamp('a', 'f') #=> 'd' - # 'z'.clamp('a', 'f') #=> 'f' + # 12.clamp(0, 100) #=> 12 + # 523.clamp(0, 100) #=> 100 + # -3.123.clamp(0, 100) #=> 0 # - def clamp(min, max) - if (min <=> max) > 0 + # 'd'.clamp('a', 'f') #=> 'd' + # 'z'.clamp('a', 'f') #=> 'f' + # + # In (range) form, returns _range.begin_ if _obj_ + # <=> _range.begin_ is less than zero, _range.end_ + # if _obj_ <=> _range.end_ is greater than zero, and + # _obj_ otherwise. + # + # 12.clamp(0..100) #=> 12 + # 523.clamp(0..100) #=> 100 + # -3.123.clamp(0..100) #=> 0 + # + # 'd'.clamp('a'..'f') #=> 'd' + # 'z'.clamp('a'..'f') #=> 'f' + # + # If _range.begin_ is +nil+, it is considered smaller than _obj_, + # and if _range.end_ is +nil+, it is considered greater than + # _obj_. + # + # -20.clamp(0..) #=> 0 + # 523.clamp(..100) #=> 100 + # + # When _range.end_ is excluded and not +nil+, an exception is + # raised. + # + # 100.clamp(0...100) # ArgumentError + # + def clamp(min, max=nil) + if max.nil? + if min.kind_of?(Range) + max = min.end + if max.nil? + max = self + elsif min.exclude_end? + raise ArgumentError, "cannot clamp with an exclusive range" + end + min = min.begin + if min.nil? + min = self + end + else + raise TypeError, "wrong argument type #{min.class}" + end + end + c = min <=> max + if c.nil? + raise ArgumentError, "comparison of #{min.class} with #{max.class} failed" + elsif c > 0 raise ArgumentError, "min argument must be smaller than max argument" end c = self <=> min - if c == 0 + if c.nil? + raise ArgumentError, "comparison of #{self.class} with #{min.class} failed" + elsif c == 0 return self elsif c < 0 return min end c = self <=> max - if c > 0 + if c.nil? + raise ArgumentError, "comparison of #{self.class} with #{max.class} failed" + elsif c > 0 return max else return self diff --git a/mruby/mrbgems/mruby-compiler/core/codegen.c b/mruby/mrbgems/mruby-compiler/core/codegen.c index 98721496..41e269e6 100644 --- a/mruby/mrbgems/mruby-compiler/core/codegen.c +++ b/mruby/mrbgems/mruby-compiler/core/codegen.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifndef MRB_CODEGEN_LEVEL_MAX #define MRB_CODEGEN_LEVEL_MAX 256 @@ -57,7 +58,7 @@ typedef struct scope { uint32_t pc; uint32_t lastpc; uint32_t lastlabel; - size_t ainfo:15; + uint16_t ainfo:15; mrb_bool mscope:1; struct loopinfo *loop; @@ -101,8 +102,8 @@ static void loop_pop(codegen_scope *s, int val); static int catch_handler_new(codegen_scope *s); static void catch_handler_set(codegen_scope *s, int ent, enum mrb_catch_type type, uint32_t begin, uint32_t end, uint32_t target); -static void gen_assignment(codegen_scope *s, node *tree, int sp, int val); -static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val); +static void gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val); +static void gen_massignment(codegen_scope *s, node *tree, int sp, int val); static void codegen(codegen_scope *s, node *tree, int val); static void raise_error(codegen_scope *s, const char *msg); @@ -194,7 +195,7 @@ emit_B(codegen_scope *s, uint32_t pc, uint8_t i) else { s->icapa *= 2; } - s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa); + s->iseq = (mrb_code*)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa); if (s->lines) { s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->icapa); } @@ -286,10 +287,10 @@ genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) } static void -genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c) +genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint16_t c) { genop_2(s, i, a, b); - gen_B(s, c); + gen_B(s, (uint8_t)c); } static void @@ -594,9 +595,22 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) switch (data.insn) { case OP_MOVE: - if (dst == src) return; /* remove useless MOVE */ - if (data.b == dst && data.a == src) /* skip swapping MOVE */ + if (dst == src) return; /* remove useless MOVE */ + if (data.a == src) { + if (data.b == dst) /* skip swapping MOVE */ + return; + if (data.a < s->nlocals) goto normal; + rewind_pc(s); + s->lastpc = addr_pc(s, mrb_prev_pc(s, data.addr)); + gen_move(s, dst, data.b, FALSE); + return; + } + if (dst == data.a) { /* skip overwritten move */ + rewind_pc(s); + s->lastpc = addr_pc(s, mrb_prev_pc(s, data.addr)); + gen_move(s, dst, src, FALSE); return; + } goto normal; case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF: case OP_LOADI__1: @@ -606,7 +620,7 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) rewind_pc(s); genop_1(s, data.insn, dst); return; - case OP_HASH: case OP_ARRAY: + case OP_HASH: if (data.b != 0) goto normal; /* fall through */ case OP_LOADI: case OP_LOADINEG: @@ -631,6 +645,19 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) genop_2SS(s, data.insn, dst, i); } return; + case OP_ARRAY: + if (data.a != src || data.a < s->nlocals || data.a < dst) goto normal; + rewind_pc(s); + if (data.b == 0 || dst == data.a) + genop_2(s, OP_ARRAY, dst, 0); + else + genop_3(s, OP_ARRAY2, dst, data.a, data.b); + return; + case OP_ARRAY2: + if (data.a != src || data.a < s->nlocals || data.a < dst) goto normal; + rewind_pc(s); + genop_3(s, OP_ARRAY2, dst, data.b, data.c); + return; case OP_AREF: case OP_GETUPVAR: if (data.a != src || data.a < s->nlocals) goto normal; @@ -831,15 +858,16 @@ gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst) 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) { + if (!get_int_operand(s, &data0, &n0)) { goto normal; } if (op == OP_MUL) { if (mrb_int_mul_overflow(n0, n, &n)) goto normal; } else { /* OP_DIV */ + if (n == 0) goto normal; if (n0 == MRB_INT_MIN && n == -1) goto normal; - n = mrb_div_int(s->mrb, n0, n); + n = mrb_div_int(n0, n); } s->pc = addr_pc(s, data0.addr); gen_int(s, dst, n); @@ -961,8 +989,19 @@ pop_n_(codegen_scope *s, int n) #define pop_n(n) pop_n_(s,n) #define cursp() (s->sp) +static mrb_pool_value* +lit_pool_extend(codegen_scope *s) +{ + if (s->irep->plen == s->pcapa) { + s->pcapa *= 2; + s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa); + } + + return &s->pool[s->irep->plen++]; +} + static int -new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg) +new_litbint(codegen_scope *s, const char *p, int base, mrb_bool neg) { int i; size_t plen; @@ -981,125 +1020,115 @@ new_litbn(codegen_scope *s, const char *p, int base, mrb_bool neg) return i; } - if (s->irep->plen == s->pcapa) { - s->pcapa *= 2; - s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa); - } + pv = lit_pool_extend(s); + + char *buf; + pv->tt = IREP_TT_BIGINT; + buf = (char*)codegen_realloc(s, NULL, plen+3); + buf[0] = (char)plen; + if (neg) buf[1] = -base; + else buf[1] = base; + memcpy(buf+2, p, plen); + buf[plen+2] = '\0'; + pv->u.str = buf; - pv = &s->pool[s->irep->plen]; - i = s->irep->plen++; - { - char *buf; - pv->tt = IREP_TT_BIGINT; - buf = (char*)codegen_realloc(s, NULL, plen+3); - buf[0] = (char)plen; - buf[1] = base; - if (neg) buf[1] = 0x80; - memcpy(buf+2, p, plen); - buf[plen+2] = '\0'; - pv->u.str = buf; - } return i; } static int -new_lit(codegen_scope *s, mrb_value val) +new_lit_str(codegen_scope *s, const char *str, mrb_int len) { int i; mrb_pool_value *pv; - switch (mrb_type(val)) { - case MRB_TT_STRING: - for (i=0; iirep->plen; i++) { - mrb_int len; - pv = &s->pool[i]; - if (pv->tt & IREP_TT_NFLAG) continue; - len = pv->tt>>2; - if (RSTRING_LEN(val) != len) continue; - if (memcmp(pv->u.str, RSTRING_PTR(val), len) == 0) - return i; - } - break; -#ifndef MRB_NO_FLOAT - case MRB_TT_FLOAT: - for (i=0; iirep->plen; i++) { - mrb_float f1, f2; - pv = &s->pool[i]; - if (pv->tt != IREP_TT_FLOAT) continue; - pv = &s->pool[i]; - f1 = pv->u.f; - f2 = mrb_float(val); - if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i; - } - break; -#endif - case MRB_TT_INTEGER: - for (i=0; iirep->plen; i++) { - mrb_int v = mrb_integer(val); - pv = &s->pool[i]; - if (pv->tt == IREP_TT_INT32) { - if (v == pv->u.i32) return i; - } -#ifdef MRB_64BIT - else if (pv->tt == IREP_TT_INT64) { - if (v == pv->u.i64) return i; - } - continue; -#endif - } - break; - default: - /* should not happen */ - return 0; + for (i=0; iirep->plen; i++) { + pv = &s->pool[i]; + if (pv->tt & IREP_TT_NFLAG) continue; + mrb_int plen = pv->tt>>2; + if (len != plen) continue; + if (memcmp(pv->u.str, str, plen) == 0) + return i; } - if (s->irep->plen == s->pcapa) { - s->pcapa *= 2; - s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa); + pv = lit_pool_extend(s); + + if (mrb_ro_data_p(str)) { + pv->tt = (uint32_t)(len<<2) | IREP_TT_SSTR; + pv->u.str = str; + } + else { + char *p; + pv->tt = (uint32_t)(len<<2) | IREP_TT_STR; + p = (char*)codegen_realloc(s, NULL, len+1); + memcpy(p, str, len); + p[len] = '\0'; + pv->u.str = p; } - pv = &s->pool[s->irep->plen]; - i = s->irep->plen++; + return i; +} - switch (mrb_type(val)) { - case MRB_TT_STRING: - if (RSTR_NOFREE_P(RSTRING(val))) { - pv->tt = (uint32_t)(RSTRING_LEN(val)<<2) | IREP_TT_SSTR; - pv->u.str = RSTRING_PTR(val); +static int +new_lit_cstr(codegen_scope *s, const char *str) +{ + return new_lit_str(s, str, (mrb_int)strlen(str)); +} + +static int +new_lit_int(codegen_scope *s, mrb_int num) +{ + int i; + mrb_pool_value *pv; + + for (i=0; iirep->plen; i++) { + pv = &s->pool[i]; + if (pv->tt == IREP_TT_INT32) { + if (num == pv->u.i32) return i; } - else { - char *p; - mrb_int len = RSTRING_LEN(val); - pv->tt = (uint32_t)(len<<2) | IREP_TT_STR; - p = (char*)codegen_realloc(s, NULL, len+1); - memcpy(p, RSTRING_PTR(val), len); - p[len] = '\0'; - pv->u.str = p; +#ifdef MRB_64BIT + else if (pv->tt == IREP_TT_INT64) { + if (num == pv->u.i64) return i; } - break; - -#ifndef MRB_NO_FLOAT - case MRB_TT_FLOAT: - pv->tt = IREP_TT_FLOAT; - pv->u.f = mrb_float(val); - break; + continue; #endif - case MRB_TT_INTEGER: + } + + pv = lit_pool_extend(s); + #ifdef MRB_INT64 - pv->tt = IREP_TT_INT64; - pv->u.i64 = mrb_integer(val); + pv->tt = IREP_TT_INT64; + pv->u.i64 = num; #else - pv->tt = IREP_TT_INT32; - pv->u.i32 = mrb_integer(val); + pv->tt = IREP_TT_INT32; + pv->u.i32 = num; #endif - break; - default: - /* should not happen */ - break; + return i; +} + +#ifndef MRB_NO_FLOAT +static int +new_lit_float(codegen_scope *s, mrb_float num) +{ + int i; + mrb_pool_value *pv; + + for (i=0; iirep->plen; i++) { + mrb_float f; + pv = &s->pool[i]; + if (pv->tt != IREP_TT_FLOAT) continue; + f = pv->u.f; + if (f == num && !signbit(f) == !signbit(num)) return i; } + + pv = lit_pool_extend(s); + + pv->tt = IREP_TT_FLOAT; + pv->u.f = num; + return i; } +#endif static int new_sym(codegen_scope *s, mrb_sym sym) @@ -1153,7 +1182,7 @@ gen_int(codegen_scope *s, uint16_t dst, mrb_int 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))); + genop_2(s, OP_LOADL, dst, new_lit_int(s, i)); } } @@ -1227,7 +1256,7 @@ search_upvar(codegen_scope *s, mrb_sym id, int *idx) if (*idx > 0) { return lv; } - lv ++; + lv++; up = up->prev; } @@ -1249,10 +1278,21 @@ search_upvar(codegen_scope *s, mrb_sym id, int *idx) } if (MRB_PROC_SCOPE_P(u)) break; u = u->upper; - lv ++; + lv++; } - codegen_error(s, "Can't found local variables"); + if (id == MRB_OPSYM_2(s->mrb, and)) { + codegen_error(s, "No anonymous block parameter"); + } + else if (id == MRB_OPSYM_2(s->mrb, mul)) { + codegen_error(s, "No anonymous rest parameter"); + } + else if (id == MRB_OPSYM_2(s->mrb, pow)) { + codegen_error(s, "No anonymous keyword rest parameter"); + } + else { + codegen_error(s, "Can't find local variables"); + } return -1; /* not reached */ } @@ -1275,10 +1315,10 @@ for_body(codegen_scope *s, node *tree) n2 = tree->car; genop_W(s, OP_ENTER, 0x40000); if (n2->car && !n2->car->cdr && !n2->cdr) { - gen_assignment(s, n2->car->car, 1, NOVAL); + gen_assignment(s, n2->car->car, NULL, 1, NOVAL); } else { - gen_vmassignment(s, n2, 1, VAL); + gen_massignment(s, n2, 1, VAL); } /* construct loop */ lp = loop_push(s, LOOP_FOR); @@ -1444,7 +1484,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) pos = 1; while (n) { if (nint(n->car->car) == NODE_MASGN) { - gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); + gen_massignment(s, n->car->cdr->car, pos, NOVAL); } pos++; n = n->cdr; @@ -1456,7 +1496,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) pos = ma+oa+ra+1; while (n) { if (nint(n->car->car) == NODE_MASGN) { - gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); + gen_massignment(s, n->car->cdr->car, pos, NOVAL); } pos++; n = n->cdr; @@ -1512,11 +1552,11 @@ attrsym(codegen_scope *s, mrb_sym a) char *name2; name = mrb_sym_name_len(s->mrb, a, &len); - name2 = (char *)codegen_palloc(s, - (size_t)len - + 1 /* '=' */ - + 1 /* '\0' */ - ); + name2 = (char*)codegen_palloc(s, + (size_t)len + + 1 /* '=' */ + + 1 /* '\0' */ + ); mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); memcpy(name2, name, (size_t)len); name2[len] = '='; @@ -1530,7 +1570,7 @@ attrsym(codegen_scope *s, mrb_sym a) #define GEN_VAL_STACK_MAX 99 static int -gen_values(codegen_scope *s, node *t, int val, int extra, int limit) +gen_values(codegen_scope *s, node *t, int val, int limit) { int n = 0; int first = 1; @@ -1551,7 +1591,7 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit) while (t) { int is_splat = nint(t->car->car) == NODE_SPLAT; - if (is_splat || n+extra >= limit-1 || cursp() >= slimit) { /* flush stack */ + if (is_splat || cursp() >= slimit) { /* flush stack */ pop_n(n); if (first) { if (n == 0) { @@ -1590,6 +1630,11 @@ gen_values(codegen_scope *s, node *t, int val, int extra, int limit) } return -1; /* variable length */ } + else if (n > limit) { + pop_n(n); + genop_2(s, OP_ARRAY, cursp(), n); + return -1; + } return n; } @@ -1600,10 +1645,16 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit) if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX; int len = 0; mrb_bool update = FALSE; + mrb_bool first = TRUE; while (tree) { if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) { - if (val && len > 0) { + if (val && first) { + genop_2(s, OP_HASH, cursp(), 0); + push(); + update = TRUE; + } + else if (val && len > 0) { pop_n(len*2); if (!update) { genop_2(s, OP_HASH, cursp(), len); @@ -1642,6 +1693,13 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit) update = TRUE; len = 0; } + first = FALSE; + } + if (val && len > limit) { + pop_n(len*2); + genop_2(s, OP_HASH, cursp(), len); + push(); + return -1; } if (update) { if (val && len > 0) { @@ -1655,10 +1713,10 @@ gen_hash(codegen_scope *s, node *tree, int val, int limit) } static void -gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) +gen_call(codegen_scope *s, node *tree, int val, int safe) { - mrb_sym sym = name ? name : nsym(tree->cdr->car); - int skip = 0, n = 0, nk = 0, noop = 0, noself = 0, blk = 0, sp_save = cursp(); + mrb_sym sym = nsym(tree->cdr->car); + int skip = 0, n = 0, nk = 0, noop = no_optimize(s), noself = 0, blk = 0, sp_save = cursp(); if (!tree->car) { noself = noop = 1; @@ -1675,7 +1733,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) tree = tree->cdr->cdr->car; if (tree) { if (tree->car) { /* positional arguments */ - n = gen_values(s, tree->car, VAL, sp?1:0, 14); + n = gen_values(s, tree->car, VAL, 14); if (n < 0) { /* variable length */ noop = 1; /* not operator */ n = 15; @@ -1688,32 +1746,6 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) if (nk < 0) nk = 15; } } - 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_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 && tree->cdr->cdr) { codegen(s, tree->cdr->cdr, VAL); pop(); @@ -1773,11 +1805,44 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) } static void -gen_assignment(codegen_scope *s, node *tree, int sp, int val) +gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int val) { int idx; int type = nint(tree->car); + switch (type) { + case NODE_GVAR: + case NODE_ARG: + case NODE_LVAR: + case NODE_IVAR: + case NODE_CVAR: + case NODE_CONST: + case NODE_NIL: + case NODE_MASGN: + if (rhs) { + codegen(s, rhs, VAL); + pop(); + sp = cursp(); + } + break; + + case NODE_COLON2: + case NODE_COLON3: + case NODE_CALL: + case NODE_SCALL: + /* keep evaluation order */ + break; + + case NODE_NVAR: + /* never happens; should have already checked in the parser */ + codegen_error(s, "Can't assign to numbered parameter"); + break; + + default: + codegen_error(s, "unknown lhs"); + break; + } + tree = tree->cdr; switch (type) { case NODE_GVAR: @@ -1796,10 +1861,6 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) gen_setupvar(s, sp, nsym(tree)); } break; - case NODE_NVAR: - idx = nint(tree); - codegen_error(s, "Can't assign to numbered parameter"); - break; case NODE_IVAR: gen_setxv(s, OP_SETIV, sp, nsym(tree), val); break; @@ -1810,27 +1871,122 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) gen_setxv(s, OP_SETCONST, sp, nsym(tree), val); break; case NODE_COLON2: - gen_move(s, cursp(), sp, 0); + case NODE_COLON3: + if (sp) { + gen_move(s, cursp(), sp, 0); + } + sp = cursp(); push(); - codegen(s, tree->car, VAL); + if (type == NODE_COLON2) { + codegen(s, tree->car, VAL); + idx = new_sym(s, nsym(tree->cdr)); + } + else { /* NODE_COLON3 */ + genop_1(s, OP_OCLASS, cursp()); + push(); + idx = new_sym(s, nsym(tree)); + } + if (rhs) { + codegen(s, rhs, VAL); pop(); + gen_move(s, sp, cursp(), 0); + } pop_n(2); - idx = new_sym(s, nsym(tree->cdr)); genop_2(s, OP_SETMCNST, sp, idx); break; case NODE_CALL: case NODE_SCALL: - push(); - gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL, - type == NODE_SCALL); - pop(); - if (val && cursp() != sp) { - gen_move(s, cursp(), sp, 0); + { + int noself = 0, safe = (type == NODE_SCALL), skip = 0, top, call, n = 0; + mrb_sym mid = nsym(tree->cdr->car); + + top = cursp(); + if (val || sp == cursp()) { + push(); /* room for retval */ + } + call = cursp(); + if (!tree->car) { + noself = 1; + push(); + } + else { + codegen(s, tree->car, VAL); /* receiver */ + } + if (safe) { + int recv = cursp()-1; + gen_move(s, cursp(), recv, 1); + skip = genjmp2_0(s, OP_JMPNIL, cursp(), val); + } + tree = tree->cdr->cdr->car; + if (tree) { + if (tree->car) { /* positional arguments */ + n = gen_values(s, tree->car, VAL, (tree->cdr->car)?13:14); + if (n < 0) { /* variable length */ + n = 15; + push(); + } + } + if (tree->cdr->car) { /* keyword arguments */ + if (n == 13 || n == 14) { + pop_n(n); + genop_2(s, OP_ARRAY, cursp(), n); + push(); + n = 15; + } + gen_hash(s, tree->cdr->car->cdr, VAL, 0); + if (n < 14) { + n++; + } + else { + pop_n(2); + genop_2(s, OP_ARYPUSH, cursp(), 1); + } + push(); + } + } + if (rhs) { + codegen(s, rhs, VAL); + pop(); + } + else { + gen_move(s, cursp(), sp, 0); + } + if (val) { + gen_move(s, top, cursp(), 1); + } + if (n < 15) { + n++; + if (n == 15) { + pop_n(14); + genop_2(s, OP_ARRAY, cursp(), 15); + } + } + else { + pop(); + genop_2(s, OP_ARYPUSH, cursp(), 1); + } + push(); pop(); + s->sp = call; + if (mid == MRB_OPSYM_2(s->mrb, aref) && n == 2) { + push_n(4); pop_n(4); /* self + idx + value + (invisible block for OP_SEND) */ + genop_1(s, OP_SETIDX, cursp()); + } + else { + int st = 2 /* self + block */ + + (((n >> 0) & 0x0f) < 15 ? ((n >> 0) & 0x0f) : 1) + + (((n >> 4) & 0x0f) < 15 ? ((n >> 4) & 0x0f) * 2 : 1); + push_n(st); pop_n(st); + genop_3(s, noself ? OP_SSEND : OP_SEND, cursp(), new_sym(s, attrsym(s, mid)), n); + } + if (safe) { + dispatch(s, skip); + } + s->sp = top; } break; case NODE_MASGN: - gen_vmassignment(s, tree->car, sp, val); + gen_massignment(s, tree->car, sp, val); break; /* splat without assignment */ @@ -1845,7 +2001,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) } static void -gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) +gen_massignment(codegen_scope *s, node *tree, int rhs, int val) { int n = 0, post = 0; node *t, *p; @@ -1858,7 +2014,7 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) genop_3(s, OP_AREF, sp, rhs, n); push(); - gen_assignment(s, t->car, sp, NOVAL); + gen_assignment(s, t->car, NULL, sp, NOVAL); pop(); n++; t = t->cdr; @@ -1879,12 +2035,12 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) genop_3(s, OP_APOST, cursp(), n, post); n = 1; if (t->car && t->car != (node*)-1) { /* rest */ - gen_assignment(s, t->car, cursp(), NOVAL); + gen_assignment(s, t->car, NULL, cursp(), NOVAL); } if (t->cdr && t->cdr->car) { t = t->cdr->car; while (t) { - gen_assignment(s, t->car, cursp()+n, NOVAL); + gen_assignment(s, t->car, NULL, cursp()+n, NOVAL); t = t->cdr; n++; } @@ -1927,13 +2083,13 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) /* fall through */ case NODE_BEGIN: codegen(s, tree->car, VAL); - ++j; + j++; break; case NODE_LITERAL_DELIM: if (j > 0) { j = 0; - ++i; + i++; if (sym) gen_intern(s); } @@ -1961,7 +2117,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) tree = tree->cdr; } if (j > 0) { - ++i; + i++; if (sym) gen_intern(s); } @@ -1989,7 +2145,7 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) static void raise_error(codegen_scope *s, const char *msg) { - int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg)); + int idx = new_lit_cstr(s, msg); genop_1(s, OP_ERR, idx); } @@ -2046,7 +2202,7 @@ gen_retval(codegen_scope *s, node *tree) if (nint(tree->car) == NODE_SPLAT) { codegen(s, tree, VAL); pop(); - genop_1(s, OP_ARYDUP, cursp()); + genop_1(s, OP_ARYSPLAT, cursp()); } else { codegen(s, tree, VAL); @@ -2204,7 +2360,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); if (n3->cdr->car) { - gen_assignment(s, n3->cdr->car, exc, NOVAL); + gen_assignment(s, n3->cdr->car, NULL, exc, NOVAL); } if (n3->cdr->cdr->car) { codegen(s, n3->cdr->cdr->car, val); @@ -2467,7 +2623,7 @@ codegen(codegen_scope *s, node *tree, int val) else { pop(); } - tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, NOVAL); + tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, !head); pos2 = tmp; n = n->cdr; } @@ -2509,10 +2665,10 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_FCALL: case NODE_CALL: - gen_call(s, tree, 0, 0, val, 0); + gen_call(s, tree, val, 0); break; case NODE_SCALL: - gen_call(s, tree, 0, 0, val, 1); + gen_call(s, tree, val, 1); break; case NODE_DOT2: @@ -2560,7 +2716,7 @@ codegen(codegen_scope *s, node *tree, int val) { int n; - n = gen_values(s, tree, val, 0, 0); + n = gen_values(s, tree, val, 0); if (val) { if (n >= 0) { pop_n(n); @@ -2588,9 +2744,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_ASGN: - codegen(s, tree->cdr, VAL); - pop(); - gen_assignment(s, tree->car, cursp(), val); + gen_assignment(s, tree->car, tree->cdr, 0, val); break; case NODE_MASGN: @@ -2599,7 +2753,7 @@ codegen(codegen_scope *s, node *tree, int val) node *t = tree->cdr, *p; int rhs = cursp(); - if (nint(t->car) == NODE_ARRAY && t->cdr && nosplat(t->cdr)) { + if (!val && nint(t->car) == NODE_ARRAY && t->cdr && nosplat(t->cdr)) { /* fixed rhs */ t = t->cdr; while (t) { @@ -2613,12 +2767,12 @@ codegen(codegen_scope *s, node *tree, int val) n = 0; while (t) { if (n < len) { - gen_assignment(s, t->car, rhs+n, NOVAL); + gen_assignment(s, t->car, NULL, rhs+n, NOVAL); n++; } else { genop_1(s, OP_LOADNIL, rhs+n); - gen_assignment(s, t->car, rhs+n, NOVAL); + gen_assignment(s, t->car, NULL, rhs+n, NOVAL); } t = t->cdr; } @@ -2641,29 +2795,36 @@ codegen(codegen_scope *s, node *tree, int val) else { rn = len - post - n; } - genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn); - gen_assignment(s, t->car, cursp(), NOVAL); + if (cursp() == rhs+n) { + genop_2(s, OP_ARRAY, cursp(), rn); + } + else { + genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn); + } + gen_assignment(s, t->car, NULL, cursp(), NOVAL); n += rn; } if (t->cdr && t->cdr->car) { t = t->cdr->car; - while (ncar, rhs+n, NOVAL); + while (t) { + if (ncar, NULL, rhs+n, NOVAL); + } + else { + genop_1(s, OP_LOADNIL, cursp()); + gen_assignment(s, t->car, NULL, cursp(), NOVAL); + } t = t->cdr; n++; } } } pop_n(len); - if (val) { - genop_2(s, OP_ARRAY, rhs, len); - push(); - } } else { /* variable rhs */ codegen(s, t, VAL); - gen_vmassignment(s, tree->car, rhs, val); + gen_massignment(s, tree->car, rhs, val); if (!val) { pop(); } @@ -2713,7 +2874,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, 14); + nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 13); if (nargs >= 0) { callargs = nargs; } @@ -2769,7 +2930,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_3(s, OP_SEND, cursp(), idx, callargs); } else { - gen_assignment(s, tree->car, cursp(), val); + gen_assignment(s, tree->car, NULL, cursp(), val); } dispatch(s, pos); goto exit; @@ -2807,7 +2968,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_3(s, OP_SEND, cursp(), idx, 1); } if (callargs < 0) { - gen_assignment(s, tree->car, cursp(), val); + gen_assignment(s, tree->car, NULL, cursp(), val); } else { if (val && vsp >= 0) { @@ -2843,7 +3004,7 @@ codegen(codegen_scope *s, node *tree, int val) if (tree) { node *args = tree->car; if (args) { - st = n = gen_values(s, args, VAL, 0, 14); + st = n = gen_values(s, args, VAL, 14); if (n < 0) { st = 1; n = 15; push(); @@ -2884,7 +3045,7 @@ codegen(codegen_scope *s, node *tree, int val) { codegen_scope *s2 = s; int lv = 0; - size_t ainfo = 0; + uint16_t ainfo = 0; int n = CALL_MAXARGS; int sp = cursp(); @@ -2961,7 +3122,7 @@ codegen(codegen_scope *s, node *tree, int val) if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)"); push(); if (tree) { - n = gen_values(s, tree, VAL, 0, 14); + n = gen_values(s, tree, VAL, 14); if (n < 0) { n = sendv = 1; push(); @@ -3122,9 +3283,11 @@ codegen(codegen_scope *s, node *tree, int val) int idx = lv_idx(s, MRB_OPSYM_2(s->mrb, and)); if (idx == 0) { - codegen_error(s, "no anonymous block argument"); + gen_getupvar(s, cursp(), MRB_OPSYM_2(s->mrb, and)); + } + else { + gen_move(s, cursp(), idx, val); } - gen_move(s, cursp(), idx, val); if (val) push(); } else { @@ -3141,7 +3304,7 @@ codegen(codegen_scope *s, node *tree, int val) i = readint(s, p, base, FALSE, &overflow); if (overflow) { - int off = new_litbn(s, p, base, FALSE); + int off = new_litbint(s, p, base, FALSE); genop_2(s, OP_LOADL, cursp(), off); } else { @@ -3155,8 +3318,9 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_FLOAT: if (val) { char *p = (char*)tree; - mrb_float f = mrb_float_read(p, NULL); - int off = new_lit(s, mrb_float_value(s->mrb, f)); + double f; + mrb_read_float(p, NULL, &f); + int off = new_lit_float(s, (mrb_float)f); genop_2(s, OP_LOADL, cursp(), off); push(); @@ -3172,8 +3336,9 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_FLOAT: if (val) { char *p = (char*)tree->cdr; - mrb_float f = mrb_float_read(p, NULL); - int off = new_lit(s, mrb_float_value(s->mrb, -f)); + double f; + mrb_read_float(p, NULL, &f); + int off = new_lit_float(s, (mrb_float)-f); genop_2(s, OP_LOADL, cursp(), off); push(); @@ -3190,7 +3355,7 @@ codegen(codegen_scope *s, node *tree, int val) i = readint(s, p, base, TRUE, &overflow); if (overflow) { - int off = new_litbn(s, p, base, TRUE); + int off = new_litbint(s, p, base, TRUE); genop_2(s, OP_LOADL, cursp(), off); } else { @@ -3222,18 +3387,16 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_STR: if (val) { char *p = (char*)tree->car; - size_t len = (intptr_t)tree->cdr; - int ai = mrb_gc_arena_save(s->mrb); - int off = new_lit(s, mrb_str_new(s->mrb, p, len)); + mrb_int len = nint(tree->cdr); + int off = new_lit_str(s, p, len); - mrb_gc_arena_restore(s->mrb, ai); genop_2(s, OP_STRING, cursp(), off); push(); } break; case NODE_HEREDOC: - tree = ((struct mrb_parser_heredoc_info *)tree)->doc; + tree = ((struct mrb_parser_heredoc_info*)tree)->doc; /* fall through */ case NODE_DSTR: if (val) { @@ -3277,7 +3440,6 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_DXSTR: { node *n; - int ai = mrb_gc_arena_save(s->mrb); int sym = new_sym(s, MRB_SYM_2(s->mrb, Kernel)); genop_1(s, OP_LOADSELF, cursp()); @@ -3300,16 +3462,14 @@ codegen(codegen_scope *s, node *tree, int val) sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */ genop_3(s, OP_SEND, cursp(), sym, 1); if (val) push(); - mrb_gc_arena_restore(s->mrb, ai); } break; case NODE_XSTR: { char *p = (char*)tree->car; - size_t len = (intptr_t)tree->cdr; - int ai = mrb_gc_arena_save(s->mrb); - int off = new_lit(s, mrb_str_new(s->mrb, p, len)); + mrb_int len = nint(tree->cdr); + int off = new_lit_str(s, p, len); int sym; genop_1(s, OP_LOADSELF, cursp()); @@ -3320,7 +3480,6 @@ codegen(codegen_scope *s, node *tree, int val) sym = new_sym(s, MRB_OPSYM_2(s->mrb, tick)); /* ` */ genop_3(s, OP_SEND, cursp(), sym, 1); if (val) push(); - mrb_gc_arena_restore(s->mrb, ai); } break; @@ -3329,9 +3488,8 @@ codegen(codegen_scope *s, node *tree, int val) char *p1 = (char*)tree->car; char *p2 = (char*)tree->cdr->car; char *p3 = (char*)tree->cdr->cdr; - int ai = mrb_gc_arena_save(s->mrb); int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); - int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1)); + int off = new_lit_cstr(s, p1); int argc = 1; genop_1(s, OP_OCLASS, cursp()); @@ -3341,7 +3499,7 @@ codegen(codegen_scope *s, node *tree, int val) push(); if (p2 || p3) { if (p2) { /* opt */ - off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); + off = new_lit_cstr(s, p2); genop_2(s, OP_STRING, cursp(), off); } else { @@ -3350,7 +3508,7 @@ codegen(codegen_scope *s, node *tree, int val) push(); argc++; if (p3) { /* enc */ - off = new_lit(s, mrb_str_new(s->mrb, p3, 1)); + off = new_lit_str(s, p3, 1); genop_2(s, OP_STRING, cursp(), off); push(); argc++; @@ -3360,7 +3518,6 @@ codegen(codegen_scope *s, node *tree, int val) pop_n(argc+2); sym = new_sym(s, MRB_SYM_2(s->mrb, compile)); genop_3(s, OP_SEND, cursp(), sym, argc); - mrb_gc_arena_restore(s->mrb, ai); push(); } break; @@ -3368,7 +3525,6 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_DREGX: if (val) { node *n = tree->car; - int ai = mrb_gc_arena_save(s->mrb); int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS)); int argc = 1; int off; @@ -3389,7 +3545,7 @@ codegen(codegen_scope *s, node *tree, int val) n = tree->cdr->cdr; if (n->car) { /* tail */ p = (char*)n->car; - off = new_lit(s, mrb_str_new_cstr(s->mrb, p)); + off = new_lit_cstr(s, p); codegen(s, tree->car, VAL); genop_2(s, OP_STRING, cursp(), off); pop(); @@ -3398,14 +3554,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)); + off = new_lit_cstr(s, p2); 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)); + off = new_lit_cstr(s, p2); genop_2(s, OP_STRING, cursp(), off); push(); argc++; @@ -3414,7 +3570,6 @@ codegen(codegen_scope *s, node *tree, int val) pop_n(argc+2); sym = new_sym(s, MRB_SYM_2(s->mrb, compile)); genop_3(s, OP_SEND, cursp(), sym, argc); - mrb_gc_arena_restore(s->mrb, ai); push(); } else { @@ -3621,6 +3776,7 @@ codegen(codegen_scope *s, node *tree, int val) genop_1(s, OP_SCLASS, cursp()); push(); genop_2(s, OP_METHOD, cursp(), idx); + push(); pop(); pop(); genop_2(s, OP_DEF, cursp(), sym); if (val) push(); @@ -3668,7 +3824,7 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *nlv) { static const codegen_scope codegen_scope_zero = { 0 }; mrb_pool *pool = mrb_pool_open(mrb); - codegen_scope *s = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope)); + codegen_scope *s = (codegen_scope*)mrb_pool_alloc(pool, sizeof(codegen_scope)); if (!s) { if (prev) @@ -3747,10 +3903,10 @@ scope_finish(codegen_scope *s) irep->flags = 0; if (s->iseq) { size_t catchsize = sizeof(struct mrb_irep_catch_handler) * irep->clen; - irep->iseq = (const mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc + catchsize); + irep->iseq = (const mrb_code*)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc + catchsize); irep->ilen = s->pc; if (irep->clen > 0) { - memcpy((void *)(irep->iseq + irep->ilen), s->catch_table, catchsize); + memcpy((void*)(irep->iseq + irep->ilen), s->catch_table, catchsize); } } else { @@ -3780,7 +3936,7 @@ scope_finish(codegen_scope *s) static struct loopinfo* loop_push(codegen_scope *s, enum looptype t) { - struct loopinfo *p = (struct loopinfo *)codegen_palloc(s, sizeof(struct loopinfo)); + struct loopinfo *p = (struct loopinfo*)codegen_palloc(s, sizeof(struct loopinfo)); p->type = t; p->pc0 = p->pc1 = p->pc2 = JMPLINK_START; @@ -3865,8 +4021,8 @@ static int catch_handler_new(codegen_scope *s) { size_t newsize = sizeof(struct mrb_irep_catch_handler) * (s->irep->clen + 1); - s->catch_table = (struct mrb_irep_catch_handler *)codegen_realloc(s, (void *)s->catch_table, newsize); - return s->irep->clen ++; + s->catch_table = (struct mrb_irep_catch_handler*)codegen_realloc(s, (void*)s->catch_table, newsize); + return s->irep->clen++; } static void @@ -3937,7 +4093,7 @@ mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep) irep->lv = NULL; } if (!irep->reps) return; - for (i = 0; i < irep->rlen; ++i) { + for (i = 0; i < irep->rlen; i++) { mrb_irep_remove_lv(mrb, (mrb_irep*)irep->reps[i]); } } diff --git a/mruby/mrbgems/mruby-compiler/core/parse.y b/mruby/mrbgems/mruby-compiler/core/parse.y index 98b7cffb..20d86480 100644 --- a/mruby/mrbgems/mruby-compiler/core/parse.y +++ b/mruby/mrbgems/mruby-compiler/core/parse.y @@ -12,7 +12,6 @@ #define YYSTACK_USE_ALLOCA 1 #include -#include #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include #include #include "node.h" @@ -90,6 +90,15 @@ intern_gen(parser_state *p, const char *s, size_t len) #define intern_op(op) MRB_OPSYM_2(p->mrb, op) +static mrb_sym +intern_numparam_gen(parser_state *p, int num) +{ + char buf[3]; + buf[0] = '_'; buf[1] = '0'+num; buf[2] = '\0'; + return intern(buf, 2); +} +#define intern_numparam(n) intern_numparam_gen(p,(n)) + static void cons_free_gen(parser_state *p, node *cons) { @@ -109,6 +118,8 @@ parser_palloc(parser_state *p, size_t size) return m; } +#define parser_pfree(ptr) do { if (sizeof(node) <= sizeof(*(ptr))) cons_free((node*)ptr);} while (0) + static node* cons_gen(parser_state *p, node *car, node *cdr) { @@ -119,7 +130,7 @@ cons_gen(parser_state *p, node *car, node *cdr) p->cells = p->cells->cdr; } else { - c = (node *)parser_palloc(p, sizeof(mrb_ast_node)); + c = (node*)parser_palloc(p, sizeof(mrb_ast_node)); } c->car = car; @@ -195,7 +206,7 @@ append_gen(parser_state *p, node *a, node *b) static char* parser_strndup(parser_state *p, const char *s, size_t len) { - char *b = (char *)parser_palloc(p, len+1); + char *b = (char*)parser_palloc(p, len+1); memcpy(b, s, len); b[len] = '\0'; @@ -327,7 +338,7 @@ static void local_add_blk(parser_state *p, mrb_sym blk) { /* allocate register for block */ - local_add_f(p, blk ? blk : intern_op(and)); + local_add_f(p, blk ? blk : 0); } static void @@ -891,9 +902,9 @@ new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg) /* (:kw_rest_args . a) */ static node* -new_kw_rest_args(parser_state *p, node *a) +new_kw_rest_args(parser_state *p, mrb_sym sym) { - return cons((node*)NODE_KW_REST_ARGS, a); + return cons((node*)NODE_KW_REST_ARGS, nsym(sym)); } static node* @@ -904,7 +915,7 @@ new_args_dots(parser_state *p, node *m) mrb_sym b = intern_op(and); local_add_f(p, r); return new_args(p, m, 0, r, 0, - new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); + new_args_tail(p, 0, new_kw_rest_args(p, k), b)); } /* (:block_arg . a) */ @@ -994,13 +1005,13 @@ 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), - new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1); + new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), '.'); } 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), new_callargs(p, list1(rational), 0, 0), 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), '.'); } /* (:int . i) */ @@ -1180,7 +1191,7 @@ new_nth_ref(parser_state *p, int n) static node* new_heredoc(parser_state *p) { - parser_heredoc_info *inf = (parser_heredoc_info *)parser_palloc(p, sizeof(parser_heredoc_info)); + parser_heredoc_info *inf = (parser_heredoc_info*)parser_palloc(p, sizeof(parser_heredoc_info)); return cons((node*)NODE_HEREDOC, (node*)inf); } @@ -1216,14 +1227,14 @@ static node* call_uni_op(parser_state *p, node *recv, const char *m) { void_expr_error(p, recv); - return new_call(p, recv, intern_cstr(m), 0, 1); + return new_call(p, recv, intern_cstr(m), 0, '.'); } /* (:call a op b) */ static node* call_bin_op(parser_state *p, node *recv, const char *m, node *arg1) { - return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1); + return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), '.'); } static void @@ -1271,6 +1282,12 @@ call_with_block(parser_state *p, node *a, node *b) if (!n->car) n->car = new_callargs(p, 0, 0, b); else args_with_block(p, n->car, b); break; + case NODE_RETURN: + case NODE_BREAK: + case NODE_NEXT: + if (a->cdr == NULL) return; + call_with_block(p, a->cdr, b); + break; default: break; } @@ -1344,23 +1361,52 @@ label_reference(parser_state *p, mrb_sym sym) typedef enum mrb_string_type string_type; -static node* +typedef struct parser_lex_strterm { + int type; + int level; + int term; + int paren; + struct parser_lex_strterm *prev; +} parser_lex_strterm; + +static parser_lex_strterm* new_strterm(parser_state *p, string_type type, int term, int paren) { - return cons(nint(type), cons(nint(0), cons(nint(paren), nint(term)))); + parser_lex_strterm *lex = (parser_lex_strterm*)parser_palloc(p, sizeof(parser_lex_strterm)); + lex->type = type; + lex->level = 0; + lex->term = term; + lex->paren = paren; + lex->prev = p->lex_strterm; + return lex; } static void end_strterm(parser_state *p) { - cons_free(p->lex_strterm->cdr->cdr); - cons_free(p->lex_strterm->cdr); - cons_free(p->lex_strterm); + parser_lex_strterm *term = p->lex_strterm->prev; + parser_pfree(p->lex_strterm); + p->lex_strterm = term; +} + +static node* +push_strterm(parser_state *p) +{ + node *n = cons((node*)p->lex_strterm, p->parsing_heredoc); p->lex_strterm = NULL; + return n; +} + +static void +pop_strterm(parser_state *p, node *n) +{ + p->lex_strterm = (parser_lex_strterm*)n->car; + p->parsing_heredoc = n->cdr; + cons_free(n); } static parser_heredoc_info * -parsing_heredoc_inf(parser_state *p) +parsing_heredoc_info(parser_state *p) { node *nd = p->parsing_heredoc; if (nd == NULL) @@ -1372,45 +1418,12 @@ parsing_heredoc_inf(parser_state *p) static void heredoc_treat_nextline(parser_state *p) { - if (p->heredocs_from_nextline == NULL) - return; - if (p->parsing_heredoc == NULL) { - node *n; - p->parsing_heredoc = p->heredocs_from_nextline; - p->lex_strterm_before_heredoc = p->lex_strterm; - p->lex_strterm = new_strterm(p, parsing_heredoc_inf(p)->type, 0, 0); - n = p->all_heredocs; - if (n) { - while (n->cdr) - n = n->cdr; - n->cdr = p->parsing_heredoc; - } - else { - p->all_heredocs = p->parsing_heredoc; - } - } - else { - node *n, *m; - m = p->heredocs_from_nextline; - while (m->cdr) - m = m->cdr; - n = p->all_heredocs; - mrb_assert(n != NULL); - if (n == p->parsing_heredoc) { - m->cdr = n; - p->all_heredocs = p->heredocs_from_nextline; - p->parsing_heredoc = p->heredocs_from_nextline; - } - else { - while (n->cdr != p->parsing_heredoc) { - n = n->cdr; - mrb_assert(n != NULL); - } - m->cdr = n->cdr; - n->cdr = p->heredocs_from_nextline; - p->parsing_heredoc = p->heredocs_from_nextline; - } + if (p->heredocs_from_nextline == NULL) return; + if (p->parsing_heredoc && p->lex_strterm) { + append(p->heredocs_from_nextline, p->parsing_heredoc); } + p->parsing_heredoc = p->heredocs_from_nextline; + p->lex_strterm = new_strterm(p, parsing_heredoc_info(p)->type, 0, 0); p->heredocs_from_nextline = NULL; } @@ -1421,15 +1434,13 @@ heredoc_end(parser_state *p) if (p->parsing_heredoc == NULL) { p->lstate = EXPR_BEG; end_strterm(p); - p->lex_strterm = p->lex_strterm_before_heredoc; - p->lex_strterm_before_heredoc = NULL; } else { /* next heredoc */ - p->lex_strterm->car = nint(parsing_heredoc_inf(p)->type); + p->lex_strterm->type = parsing_heredoc_info(p)->type; } } -#define is_strterm_type(p,str_func) (intn((p)->lex_strterm->car) & (str_func)) +#define is_strterm_type(p,str_func) ((p)->lex_strterm->type & (str_func)) /* xxx ----------------------------- */ @@ -2626,6 +2637,10 @@ args : arg $$ = list1($1); NODE_LINENO($$, $1); } + | tSTAR + { + $$ = list1(new_splat(p, new_lvar(p, intern_op(mul)))); + } | tSTAR arg { $$ = list1(new_splat(p, $2)); @@ -2636,6 +2651,10 @@ args : arg void_expr_error(p, $3); $$ = push($1, $3); } + | args comma tSTAR + { + $$ = push($1, new_splat(p, new_lvar(p, intern_op(mul)))); + } | args comma tSTAR arg { $$ = push($1, new_splat(p, $4)); @@ -3358,13 +3377,12 @@ string_interp : tSTRING_MID } | tSTRING_PART { - $$ = p->lex_strterm; - p->lex_strterm = NULL; + $$ = push_strterm(p); } compstmt '}' { - p->lex_strterm = $2; + pop_strterm(p,$2); $$ = list2($1, $3); } | tLITERAL_DELIM @@ -3413,8 +3431,8 @@ heredoc_bodies : heredoc_body heredoc_body : tHEREDOC_END { - parser_heredoc_info * inf = parsing_heredoc_inf(p); - inf->doc = push(inf->doc, new_str(p, "", 0)); + parser_heredoc_info *info = parsing_heredoc_info(p); + info->doc = push(info->doc, new_str(p, "", 0)); heredoc_end(p); } | heredoc_string_rep tHEREDOC_END @@ -3429,21 +3447,20 @@ heredoc_string_rep : heredoc_string_interp heredoc_string_interp : tHD_STRING_MID { - parser_heredoc_info * inf = parsing_heredoc_inf(p); - inf->doc = push(inf->doc, $1); + parser_heredoc_info *info = parsing_heredoc_info(p); + info->doc = push(info->doc, $1); heredoc_treat_nextline(p); } | tHD_STRING_PART { - $$ = p->lex_strterm; - p->lex_strterm = NULL; + $$ = push_strterm(p); } compstmt '}' { - parser_heredoc_info * inf = parsing_heredoc_inf(p); - p->lex_strterm = $2; - inf->doc = push(push(inf->doc, $1), $3); + pop_strterm(p, $2); + parser_heredoc_info *info = parsing_heredoc_info(p); + info->doc = push(push(info->doc, $1), $3); } ; @@ -3667,6 +3684,10 @@ f_label : tIDENTIFIER tLABEL_TAG { local_nest(p); } + | tNUMPARAM tLABEL_TAG + { + local_nest(p); + } ; f_kw : f_label arg @@ -3721,7 +3742,7 @@ kwrest_mark : tPOW f_kwrest : kwrest_mark tIDENTIFIER { - $$ = new_kw_rest_args(p, nsym($2)); + $$ = new_kw_rest_args(p, $2); } | kwrest_mark { @@ -3815,7 +3836,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail } | /* none */ { - local_add_f(p, intern_op(and)); + local_add_f(p, 0); $$ = new_args(p, 0, 0, 0, 0, 0); } ; @@ -4031,6 +4052,16 @@ assoc : arg tASSOC arg { $$ = cons(new_sym(p, $1), label_reference(p, $1)); } + | tNUMPARAM tLABEL_TAG + { + mrb_sym sym = intern_numparam($1); + $$ = cons(new_sym(p, sym), label_reference(p, sym)); + } + | tNUMPARAM tLABEL_TAG arg + { + void_expr_error(p, $3); + $$ = cons(new_sym(p, intern_numparam($1)), $3); + } | string_fragment tLABEL_TAG arg { void_expr_error(p, $3); @@ -4046,6 +4077,10 @@ assoc : arg tASSOC arg void_expr_error(p, $2); $$ = cons(new_kw_rest_args(p, 0), $2); } + | tDSTAR + { + $$ = cons(new_kw_rest_args(p, 0), new_lvar(p, intern_op(pow))); + } ; operation : tIDENTIFIER @@ -4144,7 +4179,7 @@ yyerror(parser_state *p, const char *s) } else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) { n = strlen(s); - c = (char *)parser_palloc(p, n + 1); + c = (char*)parser_palloc(p, n + 1); memcpy(c, s, n + 1); p->error_buffer[p->nerr].message = c; p->error_buffer[p->nerr].lineno = p->lineno; @@ -4183,7 +4218,7 @@ yywarning(parser_state *p, const char *s) } else if (p->nwarn < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) { n = strlen(s); - c = (char *)parser_palloc(p, n + 1); + c = (char*)parser_palloc(p, n + 1); memcpy(c, s, n + 1); p->warn_buffer[p->nwarn].message = c; p->warn_buffer[p->nwarn].lineno = p->lineno; @@ -4218,7 +4253,7 @@ backref_error(parser_state *p, node *n) yyerror_c(p, "can't set variable $", (char)intn(n->cdr)); } else { - mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c); + yyerror(p, "Internal error in backref_error()"); } } @@ -4264,22 +4299,20 @@ static mrb_bool skips(parser_state *p, const char *s); static inline int nextc0(parser_state *p) { - int c; - if (p->s && p->s < p->send) { - c = (unsigned char)*p->s++; + return (unsigned char)*p->s++; } else { #ifndef MRB_NO_STDIO + int c; + if (p->f) { c = fgetc(p->f); - if (feof(p->f)) return -1; + if (!feof(p->f)) return c; } - else #endif - return -1; + return -1; } - return c; } static inline int @@ -4684,7 +4717,7 @@ read_escape(parser_state *p) c = read_escape_unicode(p, 4); if (c < 0) return 0; } - return -c; + return -c; case 'b':/* backspace */ return '\010'; @@ -4733,7 +4766,7 @@ read_escape(parser_state *p) } static void -heredoc_count_indent(parser_heredoc_info *hinf, const char *str, size_t len, size_t spaces, size_t *offset) +heredoc_count_indent(parser_heredoc_info *hinfo, const char *str, size_t len, size_t spaces, size_t *offset) { size_t indent = 0; *offset = 0; @@ -4748,7 +4781,7 @@ heredoc_count_indent(parser_heredoc_info *hinf, const char *str, size_t len, siz else break; size_t nindent = indent + size; - if (nindent > spaces || nindent > hinf->indent) + if (nindent > spaces || nindent > hinfo->indent) break; indent = nindent; *offset += 1; @@ -4756,14 +4789,14 @@ heredoc_count_indent(parser_heredoc_info *hinf, const char *str, size_t len, siz } static void -heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) +heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinfo) { - if (!hinf->remove_indent || hinf->indent == 0) + if (!hinfo->remove_indent || hinfo->indent == 0) return; node *indented, *n, *pair, *escaped, *nspaces; const char *str; size_t len, spaces, offset, start, end; - indented = hinf->indented; + indented = hinfo->indented; while (indented) { n = indented->car; pair = n->car; @@ -4780,7 +4813,7 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) if (end > len) end = len; spaces = (size_t)nspaces->car; size_t esclen = end - start; - heredoc_count_indent(hinf, str + start, esclen, spaces, &offset); + heredoc_count_indent(hinfo, str + start, esclen, spaces, &offset); esclen -= offset; memcpy(newstr + newlen, str + start + offset, esclen); newlen += esclen; @@ -4795,7 +4828,7 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) pair->cdr = (node*)newlen; } else { spaces = (size_t)nspaces->car; - heredoc_count_indent(hinf, str, len, spaces, &offset); + heredoc_count_indent(hinfo, str, len, spaces, &offset); pair->car = (node*)(str + offset); pair->cdr = (node*)(len - offset); } @@ -4804,13 +4837,13 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) } static void -heredoc_push_indented(parser_state *p, parser_heredoc_info *hinf, node *pair, node *escaped, node *nspaces, mrb_bool empty_line) +heredoc_push_indented(parser_state *p, parser_heredoc_info *hinfo, node *pair, node *escaped, node *nspaces, mrb_bool empty_line) { - hinf->indented = push(hinf->indented, cons(pair, cons(escaped, nspaces))); + hinfo->indented = push(hinfo->indented, cons(pair, cons(escaped, nspaces))); while (nspaces) { size_t tspaces = (size_t)nspaces->car; - if ((hinf->indent == ~0U || tspaces < hinf->indent) && !empty_line) - hinf->indent = tspaces; + if ((hinfo->indent == ~0U || tspaces < hinfo->indent) && !empty_line) + hinfo->indent = tspaces; nspaces = nspaces->cdr; } } @@ -4819,14 +4852,14 @@ static int parse_string(parser_state *p) { int c; - string_type type = (string_type)(intptr_t)p->lex_strterm->car; - int nest_level = intn(p->lex_strterm->cdr->car); - int beg = intn(p->lex_strterm->cdr->cdr->car); - int end = intn(p->lex_strterm->cdr->cdr->cdr); - parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL; - - mrb_bool unindent = hinf && hinf->remove_indent; - mrb_bool head = hinf && hinf->line_head; + string_type type = (string_type)p->lex_strterm->type; + int nest_level = p->lex_strterm->level; + int beg = p->lex_strterm->paren; + int end = p->lex_strterm->term; + parser_heredoc_info *hinfo = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_info(p) : NULL; + + mrb_bool unindent = hinfo && hinfo->remove_indent; + mrb_bool head = hinfo && hinfo->line_head; mrb_bool empty = TRUE; size_t spaces = 0; size_t pos = -1; @@ -4838,26 +4871,26 @@ parse_string(parser_state *p) newtok(p); while ((c = nextc(p)) != end || nest_level != 0) { pos++; - if (hinf && (c == '\n' || c < 0)) { + if (hinfo && (c == '\n' || c < 0)) { mrb_bool line_head; tokadd(p, '\n'); tokfix(p); p->lineno++; p->column = 0; - line_head = hinf->line_head; - hinf->line_head = TRUE; + line_head = hinfo->line_head; + hinfo->line_head = TRUE; if (line_head) { /* check whether end of heredoc */ const char *s = tok(p); int len = toklen(p); - if (hinf->allow_indent) { + if (hinfo->allow_indent) { while (ISSPACE(*s) && len > 0) { - ++s; - --len; + s++; + len--; } } - if (hinf->term_len > 0 && len-1 == hinf->term_len && strncmp(s, hinf->term, len-1) == 0) { - heredoc_remove_indent(p, hinf); + if (hinfo->term_len > 0 && len-1 == hinfo->term_len && strncmp(s, hinfo->term, len-1) == 0) { + heredoc_remove_indent(p, hinfo); return tHEREDOC_END; } } @@ -4866,11 +4899,11 @@ parse_string(parser_state *p) const char s1[] = "can't find heredoc delimiter \""; const char s2[] = "\" anywhere before EOF"; - if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) { + if (sizeof(s1)+sizeof(s2)+strlen(hinfo->term)+1 >= sizeof(buf)) { yyerror(p, "can't find heredoc delimiter anywhere before EOF"); } else { strcpy(buf, s1); - strcat(buf, hinf->term); + strcat(buf, hinfo->term); strcat(buf, s2); yyerror(p, buf); } @@ -4880,7 +4913,7 @@ parse_string(parser_state *p) pylval.nd = nd; if (unindent && head) { nspaces = push(nspaces, nint(spaces)); - heredoc_push_indented(p, hinf, nd->cdr, escaped, nspaces, empty && line_head); + heredoc_push_indented(p, hinfo, nd->cdr, escaped, nspaces, empty && line_head); } return tHD_STRING_MID; } @@ -4888,7 +4921,7 @@ parse_string(parser_state *p) if (c == '\t') spaces += 8; else if (ISSPACE(c)) - ++spaces; + spaces++; else empty = FALSE; } @@ -4898,11 +4931,11 @@ parse_string(parser_state *p) } else if (c == beg) { nest_level++; - p->lex_strterm->cdr->car = nint(nest_level); + p->lex_strterm->level = nest_level; } else if (c == end) { nest_level--; - p->lex_strterm->cdr->car = nint(nest_level); + p->lex_strterm->level = nest_level; } else if (c == '\\') { c = nextc(p); @@ -4939,14 +4972,14 @@ parse_string(parser_state *p) if (c < 0) break; tokadd(p, -c); } - if (hinf) - hinf->line_head = FALSE; + if (hinfo) + hinfo->line_head = FALSE; } else { pushback(p, c); tokadd(p, read_escape(p)); - if (hinf) - hinf->line_head = FALSE; + if (hinfo) + hinfo->line_head = FALSE; } } else { @@ -4971,12 +5004,12 @@ parse_string(parser_state *p) p->cmd_start = TRUE; node *nd = new_str(p, tok(p), toklen(p)); pylval.nd = nd; - if (hinf) { + if (hinfo) { if (unindent && head) { nspaces = push(nspaces, nint(spaces)); - heredoc_push_indented(p, hinf, nd->cdr, escaped, nspaces, FALSE); + heredoc_push_indented(p, hinfo, nd->cdr, escaped, nspaces, FALSE); } - hinf->line_head = FALSE; + hinfo->line_head = FALSE; return tHD_STRING_PART; } return tSTRING_PART; @@ -5943,17 +5976,10 @@ parser_yylex(parser_state *p) return tINTEGER; #else double d; - char *endp; - errno = 0; - d = mrb_float_read(tok(p), &endp); - if (d == 0 && endp == tok(p)) { + if (!mrb_read_float(tok(p), NULL, &d)) { yywarning_s(p, "corrupted float value", tok(p)); } - else if (errno == ERANGE) { - yywarning_s(p, "float out of range", tok(p)); - errno = 0; - } suffix = number_literal_suffix(p); if (seen_e && (suffix & NUM_SUFFIX_R)) { pushback(p, 'r'); @@ -6298,8 +6324,8 @@ parser_yylex(parser_state *p) if (last_state == EXPR_FNAME) goto gvar; tokfix(p); { - mrb_int n = mrb_int_read(tok(p), NULL, NULL); - if (n > INT32_MAX) { + mrb_int n; + if (!mrb_read_int(tok(p), NULL, NULL, &n)) { yywarning(p, "capture group index too big; always nil"); return keyword_nil; } @@ -6513,7 +6539,7 @@ parser_yylex(parser_state *p) return keyword_do_block; return keyword_do; } - if (state == EXPR_BEG || state == EXPR_VALUE) + if (state == EXPR_BEG || state == EXPR_VALUE || state == EXPR_CLASS) return kw->id[0]; else { if (kw->id[0] != kw->id[1]) @@ -6594,14 +6620,13 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt) i++; n = n->cdr; } - cxt->syms = (mrb_sym *)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym)); + cxt->syms = (mrb_sym*)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym)); cxt->slen = i; for (i=0, n=n0; n; i++,n=n->cdr) { cxt->syms[i] = sym(n->car); } } -void mrb_codedump_all(mrb_state*, struct RProc*); void mrb_parser_dump(mrb_state *mrb, node *tree, int offset); MRB_API void @@ -6652,7 +6677,7 @@ mrb_parser_new(mrb_state *mrb) pool = mrb_pool_open(mrb); if (!pool) return NULL; - p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state)); + p = (parser_state*)mrb_pool_alloc(pool, sizeof(parser_state)); if (!p) return NULL; *p = parser_state_zero; @@ -6677,8 +6702,6 @@ mrb_parser_new(mrb_state *mrb) p->tokbuf = p->buf; p->lex_strterm = NULL; - p->all_heredocs = p->parsing_heredoc = NULL; - p->lex_strterm_before_heredoc = NULL; p->current_filename_index = -1; p->filename_table = NULL; @@ -6698,7 +6721,7 @@ mrb_parser_free(parser_state *p) { MRB_API mrbc_context* mrbc_context_new(mrb_state *mrb) { - return (mrbc_context *)mrb_calloc(mrb, 1, sizeof(mrbc_context)); + return (mrbc_context*)mrb_calloc(mrb, 1, sizeof(mrbc_context)); } MRB_API void @@ -6714,7 +6737,7 @@ mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s) { if (s) { size_t len = strlen(s); - char *p = (char *)mrb_malloc(mrb, len + 1); + char *p = (char*)mrb_malloc(mrb, len + 1); memcpy(p, s, len + 1); if (c->filename) { @@ -6740,6 +6763,7 @@ mrbc_cleanup_local_variables(mrb_state *mrb, mrbc_context *c) c->syms = NULL; c->slen = 0; } + c->keep_lv = FALSE; } MRB_API void @@ -6753,7 +6777,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f) p->filename_sym = sym; p->lineno = (p->filename_table_length > 0)? 0 : 1; - for (i = 0; i < p->filename_table_length; ++i) { + for (i = 0; i < p->filename_table_length; i++) { if (p->filename_table[i] == sym) { p->current_filename_index = i; return; @@ -6791,8 +6815,8 @@ mrb_parse_file_continue(mrb_state *mrb, FILE *f, const void *prebuf, size_t preb p = mrb_parser_new(mrb); if (!p) return NULL; if (prebuf) { - p->s = (const char *)prebuf; - p->send = (const char *)prebuf + prebufsize; + p->s = (const char*)prebuf; + p->send = (const char*)prebuf + prebufsize; } else { p->s = p->send = NULL; @@ -6933,19 +6957,20 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c) return mrb_load_exec(mrb, mrb_parse_file_continue(mrb, fp, leading.b, bufsize, c), c); } else { - size_t binsize; + mrb_int binsize; uint8_t *bin; mrb_value bin_obj = mrb_nil_value(); /* temporary string object */ mrb_value result; binsize = bin_to_uint32(leading.h.binary_size); bin_obj = mrb_str_new(mrb, NULL, binsize); - bin = (uint8_t *)RSTRING_PTR(bin_obj); - memcpy(bin, leading.b, bufsize); - if (binsize > bufsize && - fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { - binsize = bufsize; - /* The error is reported by mrb_load_irep_buf_cxt() */ + bin = (uint8_t*)RSTRING_PTR(bin_obj); + if ((size_t)binsize > bufsize) { + memcpy(bin, leading.b, bufsize); + if (fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { + binsize = bufsize; + /* The error is reported by mrb_load_irep_buf_cxt() */ + } } result = mrb_load_irep_buf_cxt(mrb, bin, binsize, c); @@ -7417,12 +7442,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } } n2 = n2->cdr; - if (n2) { - if (n2->car) { - dump_prefix(n2, offset+2); - printf("post:\n"); - dump_recur(mrb, n2->car, offset+3); - } + if (n2 && n2->car) { + dump_prefix(n2, offset+2); + printf("post:\n"); + dump_recur(mrb, n2->car, offset+3); } } } @@ -7582,20 +7605,28 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_REGX: - printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr); + printf("NODE_REGX /%s/\n", (char*)tree->car); + if (tree->cdr->car) { + dump_prefix(tree, offset+1); + printf("opt: %s\n", (char*)tree->cdr->car); + } + if (tree->cdr->cdr) { + dump_prefix(tree, offset+1); + printf("enc: %s\n", (char*)tree->cdr->cdr); + } break; case NODE_DREGX: printf("NODE_DREGX:\n"); dump_recur(mrb, tree->car, offset+1); - dump_prefix(tree, offset); + dump_prefix(tree, offset+1); printf("tail: %s\n", (char*)tree->cdr->cdr->car); if (tree->cdr->cdr->cdr->car) { - dump_prefix(tree, offset); + dump_prefix(tree, offset+1); printf("opt: %s\n", (char*)tree->cdr->cdr->cdr->car); } if (tree->cdr->cdr->cdr->cdr) { - dump_prefix(tree, offset); + dump_prefix(tree, offset+1); printf("enc: %s\n", (char*)tree->cdr->cdr->cdr->cdr); } break; diff --git a/mruby/mrbgems/mruby-compiler/core/y.tab.c b/mruby/mrbgems/mruby-compiler/core/y.tab.c index 6c86c0ae..794b5cf9 100644 --- a/mruby/mrbgems/mruby-compiler/core/y.tab.c +++ b/mruby/mrbgems/mruby-compiler/core/y.tab.c @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.5.1. */ +/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -34,6 +34,10 @@ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. @@ -41,14 +45,11 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ -/* Undocumented macros, especially those whose name start with YY_, - are private implementation details. Do not rely on them. */ - -/* Identify Bison output. */ -#define YYBISON 1 +/* Identify Bison output, and Bison version. */ +#define YYBISON 30802 -/* Bison version. */ -#define YYBISON_VERSION "3.5.1" +/* Bison version string. */ +#define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -75,7 +76,6 @@ #define YYSTACK_USE_ALLOCA 1 #include -#include #include #include #include @@ -84,6 +84,7 @@ #include #include #include +#include #include #include "node.h" @@ -153,6 +154,15 @@ intern_gen(parser_state *p, const char *s, size_t len) #define intern_op(op) MRB_OPSYM_2(p->mrb, op) +static mrb_sym +intern_numparam_gen(parser_state *p, int num) +{ + char buf[3]; + buf[0] = '_'; buf[1] = '0'+num; buf[2] = '\0'; + return intern(buf, 2); +} +#define intern_numparam(n) intern_numparam_gen(p,(n)) + static void cons_free_gen(parser_state *p, node *cons) { @@ -172,6 +182,8 @@ parser_palloc(parser_state *p, size_t size) return m; } +#define parser_pfree(ptr) do { if (sizeof(node) <= sizeof(*(ptr))) cons_free((node*)ptr);} while (0) + static node* cons_gen(parser_state *p, node *car, node *cdr) { @@ -182,7 +194,7 @@ cons_gen(parser_state *p, node *car, node *cdr) p->cells = p->cells->cdr; } else { - c = (node *)parser_palloc(p, sizeof(mrb_ast_node)); + c = (node*)parser_palloc(p, sizeof(mrb_ast_node)); } c->car = car; @@ -258,7 +270,7 @@ append_gen(parser_state *p, node *a, node *b) static char* parser_strndup(parser_state *p, const char *s, size_t len) { - char *b = (char *)parser_palloc(p, len+1); + char *b = (char*)parser_palloc(p, len+1); memcpy(b, s, len); b[len] = '\0'; @@ -390,7 +402,7 @@ static void local_add_blk(parser_state *p, mrb_sym blk) { /* allocate register for block */ - local_add_f(p, blk ? blk : intern_op(and)); + local_add_f(p, blk ? blk : 0); } static void @@ -954,9 +966,9 @@ new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg) /* (:kw_rest_args . a) */ static node* -new_kw_rest_args(parser_state *p, node *a) +new_kw_rest_args(parser_state *p, mrb_sym sym) { - return cons((node*)NODE_KW_REST_ARGS, a); + return cons((node*)NODE_KW_REST_ARGS, nsym(sym)); } static node* @@ -967,7 +979,7 @@ new_args_dots(parser_state *p, node *m) mrb_sym b = intern_op(and); local_add_f(p, r); return new_args(p, m, 0, r, 0, - new_args_tail(p, 0, new_kw_rest_args(p, nsym(k)), b)); + new_args_tail(p, 0, new_kw_rest_args(p, k), b)); } /* (:block_arg . a) */ @@ -1057,13 +1069,13 @@ 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), - new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), 1); + new_callargs(p, list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary), 0, 0), '.'); } 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), new_callargs(p, list1(rational), 0, 0), 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), '.'); } /* (:int . i) */ @@ -1243,7 +1255,7 @@ new_nth_ref(parser_state *p, int n) static node* new_heredoc(parser_state *p) { - parser_heredoc_info *inf = (parser_heredoc_info *)parser_palloc(p, sizeof(parser_heredoc_info)); + parser_heredoc_info *inf = (parser_heredoc_info*)parser_palloc(p, sizeof(parser_heredoc_info)); return cons((node*)NODE_HEREDOC, (node*)inf); } @@ -1279,14 +1291,14 @@ static node* call_uni_op(parser_state *p, node *recv, const char *m) { void_expr_error(p, recv); - return new_call(p, recv, intern_cstr(m), 0, 1); + return new_call(p, recv, intern_cstr(m), 0, '.'); } /* (:call a op b) */ static node* call_bin_op(parser_state *p, node *recv, const char *m, node *arg1) { - return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), 1); + return new_call(p, recv, intern_cstr(m), new_callargs(p, list1(arg1), 0, 0), '.'); } static void @@ -1334,6 +1346,12 @@ call_with_block(parser_state *p, node *a, node *b) if (!n->car) n->car = new_callargs(p, 0, 0, b); else args_with_block(p, n->car, b); break; + case NODE_RETURN: + case NODE_BREAK: + case NODE_NEXT: + if (a->cdr == NULL) return; + call_with_block(p, a->cdr, b); + break; default: break; } @@ -1407,23 +1425,52 @@ label_reference(parser_state *p, mrb_sym sym) typedef enum mrb_string_type string_type; -static node* +typedef struct parser_lex_strterm { + int type; + int level; + int term; + int paren; + struct parser_lex_strterm *prev; +} parser_lex_strterm; + +static parser_lex_strterm* new_strterm(parser_state *p, string_type type, int term, int paren) { - return cons(nint(type), cons(nint(0), cons(nint(paren), nint(term)))); + parser_lex_strterm *lex = (parser_lex_strterm*)parser_palloc(p, sizeof(parser_lex_strterm)); + lex->type = type; + lex->level = 0; + lex->term = term; + lex->paren = paren; + lex->prev = p->lex_strterm; + return lex; } static void end_strterm(parser_state *p) { - cons_free(p->lex_strterm->cdr->cdr); - cons_free(p->lex_strterm->cdr); - cons_free(p->lex_strterm); + parser_lex_strterm *term = p->lex_strterm->prev; + parser_pfree(p->lex_strterm); + p->lex_strterm = term; +} + +static node* +push_strterm(parser_state *p) +{ + node *n = cons((node*)p->lex_strterm, p->parsing_heredoc); p->lex_strterm = NULL; + return n; +} + +static void +pop_strterm(parser_state *p, node *n) +{ + p->lex_strterm = (parser_lex_strterm*)n->car; + p->parsing_heredoc = n->cdr; + cons_free(n); } static parser_heredoc_info * -parsing_heredoc_inf(parser_state *p) +parsing_heredoc_info(parser_state *p) { node *nd = p->parsing_heredoc; if (nd == NULL) @@ -1435,45 +1482,12 @@ parsing_heredoc_inf(parser_state *p) static void heredoc_treat_nextline(parser_state *p) { - if (p->heredocs_from_nextline == NULL) - return; - if (p->parsing_heredoc == NULL) { - node *n; - p->parsing_heredoc = p->heredocs_from_nextline; - p->lex_strterm_before_heredoc = p->lex_strterm; - p->lex_strterm = new_strterm(p, parsing_heredoc_inf(p)->type, 0, 0); - n = p->all_heredocs; - if (n) { - while (n->cdr) - n = n->cdr; - n->cdr = p->parsing_heredoc; - } - else { - p->all_heredocs = p->parsing_heredoc; - } - } - else { - node *n, *m; - m = p->heredocs_from_nextline; - while (m->cdr) - m = m->cdr; - n = p->all_heredocs; - mrb_assert(n != NULL); - if (n == p->parsing_heredoc) { - m->cdr = n; - p->all_heredocs = p->heredocs_from_nextline; - p->parsing_heredoc = p->heredocs_from_nextline; - } - else { - while (n->cdr != p->parsing_heredoc) { - n = n->cdr; - mrb_assert(n != NULL); - } - m->cdr = n->cdr; - n->cdr = p->heredocs_from_nextline; - p->parsing_heredoc = p->heredocs_from_nextline; - } + if (p->heredocs_from_nextline == NULL) return; + if (p->parsing_heredoc && p->lex_strterm) { + append(p->heredocs_from_nextline, p->parsing_heredoc); } + p->parsing_heredoc = p->heredocs_from_nextline; + p->lex_strterm = new_strterm(p, parsing_heredoc_info(p)->type, 0, 0); p->heredocs_from_nextline = NULL; } @@ -1484,20 +1498,18 @@ heredoc_end(parser_state *p) if (p->parsing_heredoc == NULL) { p->lstate = EXPR_BEG; end_strterm(p); - p->lex_strterm = p->lex_strterm_before_heredoc; - p->lex_strterm_before_heredoc = NULL; } else { /* next heredoc */ - p->lex_strterm->car = nint(parsing_heredoc_inf(p)->type); + p->lex_strterm->type = parsing_heredoc_info(p)->type; } } -#define is_strterm_type(p,str_func) (intn((p)->lex_strterm->car) & (str_func)) +#define is_strterm_type(p,str_func) ((p)->lex_strterm->type & (str_func)) /* xxx ----------------------------- */ -#line 1501 "mrbgems/mruby-compiler/core/y.tab.c" +#line 1513 "mrbgems/mruby-compiler/core/y.tab.c" # ifndef YY_CAST # ifdef __cplusplus @@ -1520,14 +1532,6 @@ heredoc_end(parser_state *p) # endif # endif -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - /* Debug traces. */ #ifndef YYDEBUG @@ -1537,139 +1541,144 @@ heredoc_end(parser_state *p) extern int yydebug; #endif -/* Token type. */ +/* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { - keyword_class = 258, - keyword_module = 259, - keyword_def = 260, - keyword_begin = 261, - keyword_if = 262, - keyword_unless = 263, - keyword_while = 264, - keyword_until = 265, - keyword_for = 266, - keyword_undef = 267, - keyword_rescue = 268, - keyword_ensure = 269, - keyword_end = 270, - keyword_then = 271, - keyword_elsif = 272, - keyword_else = 273, - keyword_case = 274, - keyword_when = 275, - keyword_break = 276, - keyword_next = 277, - keyword_redo = 278, - keyword_retry = 279, - keyword_in = 280, - keyword_do = 281, - keyword_do_cond = 282, - keyword_do_block = 283, - keyword_do_LAMBDA = 284, - keyword_return = 285, - keyword_yield = 286, - keyword_super = 287, - keyword_self = 288, - keyword_nil = 289, - keyword_true = 290, - keyword_false = 291, - keyword_and = 292, - keyword_or = 293, - keyword_not = 294, - modifier_if = 295, - modifier_unless = 296, - modifier_while = 297, - modifier_until = 298, - modifier_rescue = 299, - keyword_alias = 300, - keyword_BEGIN = 301, - keyword_END = 302, - keyword__LINE__ = 303, - keyword__FILE__ = 304, - keyword__ENCODING__ = 305, - tIDENTIFIER = 306, - tFID = 307, - tGVAR = 308, - tIVAR = 309, - tCONSTANT = 310, - tCVAR = 311, - tLABEL_TAG = 312, - tINTEGER = 313, - tFLOAT = 314, - tCHAR = 315, - tXSTRING = 316, - tREGEXP = 317, - tSTRING = 318, - tSTRING_PART = 319, - tSTRING_MID = 320, - tNTH_REF = 321, - tBACK_REF = 322, - tREGEXP_END = 323, - tNUMPARAM = 324, - tUPLUS = 325, - tUMINUS = 326, - tCMP = 327, - tEQ = 328, - tEQQ = 329, - tNEQ = 330, - tGEQ = 331, - tLEQ = 332, - tANDOP = 333, - tOROP = 334, - tMATCH = 335, - tNMATCH = 336, - tDOT2 = 337, - tDOT3 = 338, - tBDOT2 = 339, - tBDOT3 = 340, - tAREF = 341, - tASET = 342, - tLSHFT = 343, - tRSHFT = 344, - tCOLON2 = 345, - tCOLON3 = 346, - tOP_ASGN = 347, - tASSOC = 348, - tLPAREN = 349, - tLPAREN_ARG = 350, - tRPAREN = 351, - tLBRACK = 352, - tLBRACE = 353, - tLBRACE_ARG = 354, - tSTAR = 355, - tPOW = 356, - tDSTAR = 357, - tAMPER = 358, - tLAMBDA = 359, - tANDDOT = 360, - tSYMBEG = 361, - tSTRING_BEG = 362, - tXSTRING_BEG = 363, - tSTRING_DVAR = 364, - tREGEXP_BEG = 365, - tWORDS_BEG = 366, - tSYMBOLS_BEG = 367, - tLAMBEG = 368, - tHEREDOC_BEG = 369, - tHEREDOC_END = 370, - tLITERAL_DELIM = 371, - tHD_LITERAL_DELIM = 372, - tHD_STRING_PART = 373, - tHD_STRING_MID = 374, - tLOWEST = 375, - tUMINUS_NUM = 376, - tLAST_TOKEN = 377 + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + keyword_class = 258, /* keyword_class */ + keyword_module = 259, /* keyword_module */ + keyword_def = 260, /* keyword_def */ + keyword_begin = 261, /* keyword_begin */ + keyword_if = 262, /* keyword_if */ + keyword_unless = 263, /* keyword_unless */ + keyword_while = 264, /* keyword_while */ + keyword_until = 265, /* keyword_until */ + keyword_for = 266, /* keyword_for */ + keyword_undef = 267, /* keyword_undef */ + keyword_rescue = 268, /* keyword_rescue */ + keyword_ensure = 269, /* keyword_ensure */ + keyword_end = 270, /* keyword_end */ + keyword_then = 271, /* keyword_then */ + keyword_elsif = 272, /* keyword_elsif */ + keyword_else = 273, /* keyword_else */ + keyword_case = 274, /* keyword_case */ + keyword_when = 275, /* keyword_when */ + keyword_break = 276, /* keyword_break */ + keyword_next = 277, /* keyword_next */ + keyword_redo = 278, /* keyword_redo */ + keyword_retry = 279, /* keyword_retry */ + keyword_in = 280, /* keyword_in */ + keyword_do = 281, /* keyword_do */ + keyword_do_cond = 282, /* keyword_do_cond */ + keyword_do_block = 283, /* keyword_do_block */ + keyword_do_LAMBDA = 284, /* keyword_do_LAMBDA */ + keyword_return = 285, /* keyword_return */ + keyword_yield = 286, /* keyword_yield */ + keyword_super = 287, /* keyword_super */ + keyword_self = 288, /* keyword_self */ + keyword_nil = 289, /* keyword_nil */ + keyword_true = 290, /* keyword_true */ + keyword_false = 291, /* keyword_false */ + keyword_and = 292, /* keyword_and */ + keyword_or = 293, /* keyword_or */ + keyword_not = 294, /* keyword_not */ + modifier_if = 295, /* modifier_if */ + modifier_unless = 296, /* modifier_unless */ + modifier_while = 297, /* modifier_while */ + modifier_until = 298, /* modifier_until */ + modifier_rescue = 299, /* modifier_rescue */ + keyword_alias = 300, /* keyword_alias */ + keyword_BEGIN = 301, /* keyword_BEGIN */ + keyword_END = 302, /* keyword_END */ + keyword__LINE__ = 303, /* keyword__LINE__ */ + keyword__FILE__ = 304, /* keyword__FILE__ */ + keyword__ENCODING__ = 305, /* keyword__ENCODING__ */ + tIDENTIFIER = 306, /* "local variable or method" */ + tFID = 307, /* "method" */ + tGVAR = 308, /* "global variable" */ + tIVAR = 309, /* "instance variable" */ + tCONSTANT = 310, /* "constant" */ + tCVAR = 311, /* "class variable" */ + tLABEL_TAG = 312, /* "label" */ + tINTEGER = 313, /* "integer literal" */ + tFLOAT = 314, /* "float literal" */ + tCHAR = 315, /* "character literal" */ + tXSTRING = 316, /* tXSTRING */ + tREGEXP = 317, /* tREGEXP */ + tSTRING = 318, /* tSTRING */ + tSTRING_PART = 319, /* tSTRING_PART */ + tSTRING_MID = 320, /* tSTRING_MID */ + tNTH_REF = 321, /* tNTH_REF */ + tBACK_REF = 322, /* tBACK_REF */ + tREGEXP_END = 323, /* tREGEXP_END */ + tNUMPARAM = 324, /* "numbered parameter" */ + tUPLUS = 325, /* "unary plus" */ + tUMINUS = 326, /* "unary minus" */ + tCMP = 327, /* "<=>" */ + tEQ = 328, /* "==" */ + tEQQ = 329, /* "===" */ + tNEQ = 330, /* "!=" */ + tGEQ = 331, /* ">=" */ + tLEQ = 332, /* "<=" */ + tANDOP = 333, /* "&&" */ + tOROP = 334, /* "||" */ + tMATCH = 335, /* "=~" */ + tNMATCH = 336, /* "!~" */ + tDOT2 = 337, /* ".." */ + tDOT3 = 338, /* "..." */ + tBDOT2 = 339, /* tBDOT2 */ + tBDOT3 = 340, /* tBDOT3 */ + tAREF = 341, /* tAREF */ + tASET = 342, /* tASET */ + tLSHFT = 343, /* "<<" */ + tRSHFT = 344, /* ">>" */ + tCOLON2 = 345, /* "::" */ + tCOLON3 = 346, /* tCOLON3 */ + tOP_ASGN = 347, /* tOP_ASGN */ + tASSOC = 348, /* "=>" */ + tLPAREN = 349, /* tLPAREN */ + tLPAREN_ARG = 350, /* "(" */ + tRPAREN = 351, /* ")" */ + tLBRACK = 352, /* "[" */ + tLBRACE = 353, /* tLBRACE */ + tLBRACE_ARG = 354, /* "{" */ + tSTAR = 355, /* "*" */ + tPOW = 356, /* tPOW */ + tDSTAR = 357, /* "**" */ + tAMPER = 358, /* "&" */ + tLAMBDA = 359, /* "->" */ + tANDDOT = 360, /* "&." */ + tSYMBEG = 361, /* "symbol" */ + tSTRING_BEG = 362, /* "string literal" */ + tXSTRING_BEG = 363, /* tXSTRING_BEG */ + tSTRING_DVAR = 364, /* tSTRING_DVAR */ + tREGEXP_BEG = 365, /* tREGEXP_BEG */ + tWORDS_BEG = 366, /* tWORDS_BEG */ + tSYMBOLS_BEG = 367, /* tSYMBOLS_BEG */ + tLAMBEG = 368, /* tLAMBEG */ + tHEREDOC_BEG = 369, /* "here document" */ + tHEREDOC_END = 370, /* tHEREDOC_END */ + tLITERAL_DELIM = 371, /* tLITERAL_DELIM */ + tHD_LITERAL_DELIM = 372, /* tHD_LITERAL_DELIM */ + tHD_STRING_PART = 373, /* tHD_STRING_PART */ + tHD_STRING_MID = 374, /* tHD_STRING_MID */ + tLOWEST = 375, /* tLOWEST */ + tUMINUS_NUM = 376, /* tUMINUS_NUM */ + tLAST_TOKEN = 377 /* tLAST_TOKEN */ }; + typedef enum yytokentype yytoken_kind_t; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 1443 "mrbgems/mruby-compiler/core/parse.y" +#line 1454 "mrbgems/mruby-compiler/core/parse.y" node *nd; mrb_sym id; @@ -1677,7 +1686,7 @@ union YYSTYPE stack_type stack; const struct vtable *vars; -#line 1681 "mrbgems/mruby-compiler/core/y.tab.c" +#line 1690 "mrbgems/mruby-compiler/core/y.tab.c" }; typedef union YYSTYPE YYSTYPE; @@ -1687,10 +1696,344 @@ typedef union YYSTYPE YYSTYPE; + int yyparse (parser_state *p); +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_keyword_class = 3, /* keyword_class */ + YYSYMBOL_keyword_module = 4, /* keyword_module */ + YYSYMBOL_keyword_def = 5, /* keyword_def */ + YYSYMBOL_keyword_begin = 6, /* keyword_begin */ + YYSYMBOL_keyword_if = 7, /* keyword_if */ + YYSYMBOL_keyword_unless = 8, /* keyword_unless */ + YYSYMBOL_keyword_while = 9, /* keyword_while */ + YYSYMBOL_keyword_until = 10, /* keyword_until */ + YYSYMBOL_keyword_for = 11, /* keyword_for */ + YYSYMBOL_keyword_undef = 12, /* keyword_undef */ + YYSYMBOL_keyword_rescue = 13, /* keyword_rescue */ + YYSYMBOL_keyword_ensure = 14, /* keyword_ensure */ + YYSYMBOL_keyword_end = 15, /* keyword_end */ + YYSYMBOL_keyword_then = 16, /* keyword_then */ + YYSYMBOL_keyword_elsif = 17, /* keyword_elsif */ + YYSYMBOL_keyword_else = 18, /* keyword_else */ + YYSYMBOL_keyword_case = 19, /* keyword_case */ + YYSYMBOL_keyword_when = 20, /* keyword_when */ + YYSYMBOL_keyword_break = 21, /* keyword_break */ + YYSYMBOL_keyword_next = 22, /* keyword_next */ + YYSYMBOL_keyword_redo = 23, /* keyword_redo */ + YYSYMBOL_keyword_retry = 24, /* keyword_retry */ + YYSYMBOL_keyword_in = 25, /* keyword_in */ + YYSYMBOL_keyword_do = 26, /* keyword_do */ + YYSYMBOL_keyword_do_cond = 27, /* keyword_do_cond */ + YYSYMBOL_keyword_do_block = 28, /* keyword_do_block */ + YYSYMBOL_keyword_do_LAMBDA = 29, /* keyword_do_LAMBDA */ + YYSYMBOL_keyword_return = 30, /* keyword_return */ + YYSYMBOL_keyword_yield = 31, /* keyword_yield */ + YYSYMBOL_keyword_super = 32, /* keyword_super */ + YYSYMBOL_keyword_self = 33, /* keyword_self */ + YYSYMBOL_keyword_nil = 34, /* keyword_nil */ + YYSYMBOL_keyword_true = 35, /* keyword_true */ + YYSYMBOL_keyword_false = 36, /* keyword_false */ + YYSYMBOL_keyword_and = 37, /* keyword_and */ + YYSYMBOL_keyword_or = 38, /* keyword_or */ + YYSYMBOL_keyword_not = 39, /* keyword_not */ + YYSYMBOL_modifier_if = 40, /* modifier_if */ + YYSYMBOL_modifier_unless = 41, /* modifier_unless */ + YYSYMBOL_modifier_while = 42, /* modifier_while */ + YYSYMBOL_modifier_until = 43, /* modifier_until */ + YYSYMBOL_modifier_rescue = 44, /* modifier_rescue */ + YYSYMBOL_keyword_alias = 45, /* keyword_alias */ + YYSYMBOL_keyword_BEGIN = 46, /* keyword_BEGIN */ + YYSYMBOL_keyword_END = 47, /* keyword_END */ + YYSYMBOL_keyword__LINE__ = 48, /* keyword__LINE__ */ + YYSYMBOL_keyword__FILE__ = 49, /* keyword__FILE__ */ + YYSYMBOL_keyword__ENCODING__ = 50, /* keyword__ENCODING__ */ + YYSYMBOL_tIDENTIFIER = 51, /* "local variable or method" */ + YYSYMBOL_tFID = 52, /* "method" */ + YYSYMBOL_tGVAR = 53, /* "global variable" */ + YYSYMBOL_tIVAR = 54, /* "instance variable" */ + YYSYMBOL_tCONSTANT = 55, /* "constant" */ + YYSYMBOL_tCVAR = 56, /* "class variable" */ + YYSYMBOL_tLABEL_TAG = 57, /* "label" */ + YYSYMBOL_tINTEGER = 58, /* "integer literal" */ + YYSYMBOL_tFLOAT = 59, /* "float literal" */ + YYSYMBOL_tCHAR = 60, /* "character literal" */ + YYSYMBOL_tXSTRING = 61, /* tXSTRING */ + YYSYMBOL_tREGEXP = 62, /* tREGEXP */ + YYSYMBOL_tSTRING = 63, /* tSTRING */ + YYSYMBOL_tSTRING_PART = 64, /* tSTRING_PART */ + YYSYMBOL_tSTRING_MID = 65, /* tSTRING_MID */ + YYSYMBOL_tNTH_REF = 66, /* tNTH_REF */ + YYSYMBOL_tBACK_REF = 67, /* tBACK_REF */ + YYSYMBOL_tREGEXP_END = 68, /* tREGEXP_END */ + YYSYMBOL_tNUMPARAM = 69, /* "numbered parameter" */ + YYSYMBOL_tUPLUS = 70, /* "unary plus" */ + YYSYMBOL_tUMINUS = 71, /* "unary minus" */ + YYSYMBOL_tCMP = 72, /* "<=>" */ + YYSYMBOL_tEQ = 73, /* "==" */ + YYSYMBOL_tEQQ = 74, /* "===" */ + YYSYMBOL_tNEQ = 75, /* "!=" */ + YYSYMBOL_tGEQ = 76, /* ">=" */ + YYSYMBOL_tLEQ = 77, /* "<=" */ + YYSYMBOL_tANDOP = 78, /* "&&" */ + YYSYMBOL_tOROP = 79, /* "||" */ + YYSYMBOL_tMATCH = 80, /* "=~" */ + YYSYMBOL_tNMATCH = 81, /* "!~" */ + YYSYMBOL_tDOT2 = 82, /* ".." */ + YYSYMBOL_tDOT3 = 83, /* "..." */ + YYSYMBOL_tBDOT2 = 84, /* tBDOT2 */ + YYSYMBOL_tBDOT3 = 85, /* tBDOT3 */ + YYSYMBOL_tAREF = 86, /* tAREF */ + YYSYMBOL_tASET = 87, /* tASET */ + YYSYMBOL_tLSHFT = 88, /* "<<" */ + YYSYMBOL_tRSHFT = 89, /* ">>" */ + YYSYMBOL_tCOLON2 = 90, /* "::" */ + YYSYMBOL_tCOLON3 = 91, /* tCOLON3 */ + YYSYMBOL_tOP_ASGN = 92, /* tOP_ASGN */ + YYSYMBOL_tASSOC = 93, /* "=>" */ + YYSYMBOL_tLPAREN = 94, /* tLPAREN */ + YYSYMBOL_tLPAREN_ARG = 95, /* "(" */ + YYSYMBOL_tRPAREN = 96, /* ")" */ + YYSYMBOL_tLBRACK = 97, /* "[" */ + YYSYMBOL_tLBRACE = 98, /* tLBRACE */ + YYSYMBOL_tLBRACE_ARG = 99, /* "{" */ + YYSYMBOL_tSTAR = 100, /* "*" */ + YYSYMBOL_tPOW = 101, /* tPOW */ + YYSYMBOL_tDSTAR = 102, /* "**" */ + YYSYMBOL_tAMPER = 103, /* "&" */ + YYSYMBOL_tLAMBDA = 104, /* "->" */ + YYSYMBOL_tANDDOT = 105, /* "&." */ + YYSYMBOL_tSYMBEG = 106, /* "symbol" */ + YYSYMBOL_tSTRING_BEG = 107, /* "string literal" */ + YYSYMBOL_tXSTRING_BEG = 108, /* tXSTRING_BEG */ + YYSYMBOL_tSTRING_DVAR = 109, /* tSTRING_DVAR */ + YYSYMBOL_tREGEXP_BEG = 110, /* tREGEXP_BEG */ + YYSYMBOL_tWORDS_BEG = 111, /* tWORDS_BEG */ + YYSYMBOL_tSYMBOLS_BEG = 112, /* tSYMBOLS_BEG */ + YYSYMBOL_tLAMBEG = 113, /* tLAMBEG */ + YYSYMBOL_tHEREDOC_BEG = 114, /* "here document" */ + YYSYMBOL_tHEREDOC_END = 115, /* tHEREDOC_END */ + YYSYMBOL_tLITERAL_DELIM = 116, /* tLITERAL_DELIM */ + YYSYMBOL_tHD_LITERAL_DELIM = 117, /* tHD_LITERAL_DELIM */ + YYSYMBOL_tHD_STRING_PART = 118, /* tHD_STRING_PART */ + YYSYMBOL_tHD_STRING_MID = 119, /* tHD_STRING_MID */ + YYSYMBOL_tLOWEST = 120, /* tLOWEST */ + YYSYMBOL_121_ = 121, /* '=' */ + YYSYMBOL_122_ = 122, /* '?' */ + YYSYMBOL_123_ = 123, /* ':' */ + YYSYMBOL_124_ = 124, /* '>' */ + YYSYMBOL_125_ = 125, /* '<' */ + YYSYMBOL_126_ = 126, /* '|' */ + YYSYMBOL_127_ = 127, /* '^' */ + YYSYMBOL_128_ = 128, /* '&' */ + YYSYMBOL_129_ = 129, /* '+' */ + YYSYMBOL_130_ = 130, /* '-' */ + YYSYMBOL_131_ = 131, /* '*' */ + YYSYMBOL_132_ = 132, /* '/' */ + YYSYMBOL_133_ = 133, /* '%' */ + YYSYMBOL_tUMINUS_NUM = 134, /* tUMINUS_NUM */ + YYSYMBOL_135_ = 135, /* '!' */ + YYSYMBOL_136_ = 136, /* '~' */ + YYSYMBOL_tLAST_TOKEN = 137, /* tLAST_TOKEN */ + YYSYMBOL_138_ = 138, /* '{' */ + YYSYMBOL_139_ = 139, /* '}' */ + YYSYMBOL_140_ = 140, /* '[' */ + YYSYMBOL_141_ = 141, /* ']' */ + YYSYMBOL_142_ = 142, /* ',' */ + YYSYMBOL_143_ = 143, /* '`' */ + YYSYMBOL_144_ = 144, /* '(' */ + YYSYMBOL_145_ = 145, /* ')' */ + YYSYMBOL_146_ = 146, /* ';' */ + YYSYMBOL_147_ = 147, /* '.' */ + YYSYMBOL_148_n_ = 148, /* '\n' */ + YYSYMBOL_YYACCEPT = 149, /* $accept */ + YYSYMBOL_program = 150, /* program */ + YYSYMBOL_151_1 = 151, /* $@1 */ + YYSYMBOL_top_compstmt = 152, /* top_compstmt */ + YYSYMBOL_top_stmts = 153, /* top_stmts */ + YYSYMBOL_top_stmt = 154, /* top_stmt */ + YYSYMBOL_155_2 = 155, /* @2 */ + YYSYMBOL_bodystmt = 156, /* bodystmt */ + YYSYMBOL_compstmt = 157, /* compstmt */ + YYSYMBOL_stmts = 158, /* stmts */ + YYSYMBOL_stmt = 159, /* stmt */ + YYSYMBOL_160_3 = 160, /* $@3 */ + YYSYMBOL_command_asgn = 161, /* command_asgn */ + YYSYMBOL_command_rhs = 162, /* command_rhs */ + YYSYMBOL_expr = 163, /* expr */ + YYSYMBOL_defn_head = 164, /* defn_head */ + YYSYMBOL_defs_head = 165, /* defs_head */ + YYSYMBOL_166_4 = 166, /* $@4 */ + YYSYMBOL_expr_value = 167, /* expr_value */ + YYSYMBOL_command_call = 168, /* command_call */ + YYSYMBOL_block_command = 169, /* block_command */ + YYSYMBOL_cmd_brace_block = 170, /* cmd_brace_block */ + YYSYMBOL_171_5 = 171, /* $@5 */ + YYSYMBOL_command = 172, /* command */ + YYSYMBOL_mlhs = 173, /* mlhs */ + YYSYMBOL_mlhs_inner = 174, /* mlhs_inner */ + YYSYMBOL_mlhs_basic = 175, /* mlhs_basic */ + YYSYMBOL_mlhs_item = 176, /* mlhs_item */ + YYSYMBOL_mlhs_list = 177, /* mlhs_list */ + YYSYMBOL_mlhs_post = 178, /* mlhs_post */ + YYSYMBOL_mlhs_node = 179, /* mlhs_node */ + YYSYMBOL_lhs = 180, /* lhs */ + YYSYMBOL_cname = 181, /* cname */ + YYSYMBOL_cpath = 182, /* cpath */ + YYSYMBOL_fname = 183, /* fname */ + YYSYMBOL_fsym = 184, /* fsym */ + YYSYMBOL_undef_list = 185, /* undef_list */ + YYSYMBOL_186_6 = 186, /* $@6 */ + YYSYMBOL_op = 187, /* op */ + YYSYMBOL_reswords = 188, /* reswords */ + YYSYMBOL_arg = 189, /* arg */ + YYSYMBOL_aref_args = 190, /* aref_args */ + YYSYMBOL_arg_rhs = 191, /* arg_rhs */ + YYSYMBOL_paren_args = 192, /* paren_args */ + YYSYMBOL_opt_paren_args = 193, /* opt_paren_args */ + YYSYMBOL_opt_call_args = 194, /* opt_call_args */ + YYSYMBOL_call_args = 195, /* call_args */ + YYSYMBOL_command_args = 196, /* command_args */ + YYSYMBOL_197_7 = 197, /* @7 */ + YYSYMBOL_block_arg = 198, /* block_arg */ + YYSYMBOL_opt_block_arg = 199, /* opt_block_arg */ + YYSYMBOL_comma = 200, /* comma */ + YYSYMBOL_args = 201, /* args */ + YYSYMBOL_mrhs = 202, /* mrhs */ + YYSYMBOL_primary = 203, /* primary */ + YYSYMBOL_204_8 = 204, /* @8 */ + YYSYMBOL_205_9 = 205, /* @9 */ + YYSYMBOL_206_10 = 206, /* $@10 */ + YYSYMBOL_207_11 = 207, /* $@11 */ + YYSYMBOL_208_12 = 208, /* @12 */ + YYSYMBOL_209_13 = 209, /* @13 */ + YYSYMBOL_210_14 = 210, /* $@14 */ + YYSYMBOL_211_15 = 211, /* $@15 */ + YYSYMBOL_212_16 = 212, /* $@16 */ + YYSYMBOL_213_17 = 213, /* $@17 */ + YYSYMBOL_214_18 = 214, /* $@18 */ + YYSYMBOL_215_19 = 215, /* $@19 */ + YYSYMBOL_216_20 = 216, /* @20 */ + YYSYMBOL_217_21 = 217, /* @21 */ + YYSYMBOL_218_22 = 218, /* @22 */ + YYSYMBOL_219_23 = 219, /* @23 */ + YYSYMBOL_primary_value = 220, /* primary_value */ + YYSYMBOL_then = 221, /* then */ + YYSYMBOL_do = 222, /* do */ + YYSYMBOL_if_tail = 223, /* if_tail */ + YYSYMBOL_opt_else = 224, /* opt_else */ + YYSYMBOL_for_var = 225, /* for_var */ + YYSYMBOL_f_margs = 226, /* f_margs */ + YYSYMBOL_227_24 = 227, /* $@24 */ + YYSYMBOL_block_args_tail = 228, /* block_args_tail */ + YYSYMBOL_opt_block_args_tail = 229, /* opt_block_args_tail */ + YYSYMBOL_block_param = 230, /* block_param */ + YYSYMBOL_opt_block_param = 231, /* opt_block_param */ + YYSYMBOL_block_param_def = 232, /* block_param_def */ + YYSYMBOL_233_25 = 233, /* $@25 */ + YYSYMBOL_opt_bv_decl = 234, /* opt_bv_decl */ + YYSYMBOL_bv_decls = 235, /* bv_decls */ + YYSYMBOL_bvar = 236, /* bvar */ + YYSYMBOL_f_larglist = 237, /* f_larglist */ + YYSYMBOL_lambda_body = 238, /* lambda_body */ + YYSYMBOL_do_block = 239, /* do_block */ + YYSYMBOL_240_26 = 240, /* $@26 */ + YYSYMBOL_block_call = 241, /* block_call */ + YYSYMBOL_method_call = 242, /* method_call */ + YYSYMBOL_brace_block = 243, /* brace_block */ + YYSYMBOL_244_27 = 244, /* @27 */ + YYSYMBOL_245_28 = 245, /* @28 */ + YYSYMBOL_case_body = 246, /* case_body */ + YYSYMBOL_cases = 247, /* cases */ + YYSYMBOL_opt_rescue = 248, /* opt_rescue */ + YYSYMBOL_exc_list = 249, /* exc_list */ + YYSYMBOL_exc_var = 250, /* exc_var */ + YYSYMBOL_opt_ensure = 251, /* opt_ensure */ + YYSYMBOL_literal = 252, /* literal */ + YYSYMBOL_string = 253, /* string */ + YYSYMBOL_string_fragment = 254, /* string_fragment */ + YYSYMBOL_string_rep = 255, /* string_rep */ + YYSYMBOL_string_interp = 256, /* string_interp */ + YYSYMBOL_257_29 = 257, /* @29 */ + YYSYMBOL_xstring = 258, /* xstring */ + YYSYMBOL_regexp = 259, /* regexp */ + YYSYMBOL_heredoc = 260, /* heredoc */ + YYSYMBOL_heredoc_bodies = 261, /* heredoc_bodies */ + YYSYMBOL_heredoc_body = 262, /* heredoc_body */ + YYSYMBOL_heredoc_string_rep = 263, /* heredoc_string_rep */ + YYSYMBOL_heredoc_string_interp = 264, /* heredoc_string_interp */ + YYSYMBOL_265_30 = 265, /* @30 */ + YYSYMBOL_words = 266, /* words */ + YYSYMBOL_symbol = 267, /* symbol */ + YYSYMBOL_basic_symbol = 268, /* basic_symbol */ + YYSYMBOL_sym = 269, /* sym */ + YYSYMBOL_symbols = 270, /* symbols */ + YYSYMBOL_numeric = 271, /* numeric */ + YYSYMBOL_variable = 272, /* variable */ + YYSYMBOL_var_lhs = 273, /* var_lhs */ + YYSYMBOL_var_ref = 274, /* var_ref */ + YYSYMBOL_backref = 275, /* backref */ + YYSYMBOL_superclass = 276, /* superclass */ + YYSYMBOL_277_31 = 277, /* $@31 */ + YYSYMBOL_f_opt_arglist_paren = 278, /* f_opt_arglist_paren */ + YYSYMBOL_f_arglist_paren = 279, /* f_arglist_paren */ + YYSYMBOL_f_arglist = 280, /* f_arglist */ + YYSYMBOL_f_label = 281, /* f_label */ + YYSYMBOL_f_kw = 282, /* f_kw */ + YYSYMBOL_f_block_kw = 283, /* f_block_kw */ + YYSYMBOL_f_block_kwarg = 284, /* f_block_kwarg */ + YYSYMBOL_f_kwarg = 285, /* f_kwarg */ + YYSYMBOL_kwrest_mark = 286, /* kwrest_mark */ + YYSYMBOL_f_kwrest = 287, /* f_kwrest */ + YYSYMBOL_args_tail = 288, /* args_tail */ + YYSYMBOL_opt_args_tail = 289, /* opt_args_tail */ + YYSYMBOL_f_args = 290, /* f_args */ + YYSYMBOL_f_bad_arg = 291, /* f_bad_arg */ + YYSYMBOL_f_norm_arg = 292, /* f_norm_arg */ + YYSYMBOL_f_arg_item = 293, /* f_arg_item */ + YYSYMBOL_294_32 = 294, /* @32 */ + YYSYMBOL_f_arg = 295, /* f_arg */ + YYSYMBOL_f_opt_asgn = 296, /* f_opt_asgn */ + YYSYMBOL_f_opt = 297, /* f_opt */ + YYSYMBOL_f_block_opt = 298, /* f_block_opt */ + YYSYMBOL_f_block_optarg = 299, /* f_block_optarg */ + YYSYMBOL_f_optarg = 300, /* f_optarg */ + YYSYMBOL_restarg_mark = 301, /* restarg_mark */ + YYSYMBOL_f_rest_arg = 302, /* f_rest_arg */ + YYSYMBOL_blkarg_mark = 303, /* blkarg_mark */ + YYSYMBOL_f_block_arg = 304, /* f_block_arg */ + YYSYMBOL_opt_f_block_arg = 305, /* opt_f_block_arg */ + YYSYMBOL_singleton = 306, /* singleton */ + YYSYMBOL_307_33 = 307, /* $@33 */ + YYSYMBOL_assoc_list = 308, /* assoc_list */ + YYSYMBOL_assocs = 309, /* assocs */ + YYSYMBOL_assoc = 310, /* assoc */ + YYSYMBOL_operation = 311, /* operation */ + YYSYMBOL_operation2 = 312, /* operation2 */ + YYSYMBOL_operation3 = 313, /* operation3 */ + YYSYMBOL_dot_or_colon = 314, /* dot_or_colon */ + YYSYMBOL_call_op = 315, /* call_op */ + YYSYMBOL_call_op2 = 316, /* call_op2 */ + YYSYMBOL_opt_terms = 317, /* opt_terms */ + YYSYMBOL_opt_nl = 318, /* opt_nl */ + YYSYMBOL_rparen = 319, /* rparen */ + YYSYMBOL_trailer = 320, /* trailer */ + YYSYMBOL_term = 321, /* term */ + YYSYMBOL_nl = 322, /* nl */ + YYSYMBOL_terms = 323, /* terms */ + YYSYMBOL_none = 324 /* none */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + #ifdef short @@ -1730,6 +2073,18 @@ typedef int_least16_t yytype_int16; typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ @@ -1789,6 +2144,7 @@ typedef int yytype_uint16; #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + /* Stored state numbers (used for stacks). */ typedef yytype_int16 yy_state_t; @@ -1807,6 +2163,7 @@ typedef int yy_state_fast_t; # endif #endif + #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) @@ -1825,17 +2182,23 @@ typedef int yy_state_fast_t; /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif -#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else @@ -1864,7 +2227,7 @@ typedef int yy_state_fast_t; #define YY_ASSERT(E) ((void) (0 && (E))) -#if ! defined yyoverflow || YYERROR_VERBOSE +#if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -1929,8 +2292,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - +#endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ @@ -1995,25 +2357,27 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 13387 +#define YYLAST 13092 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 149 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 176 /* YYNRULES -- Number of rules. */ -#define YYNRULES 613 +#define YYNRULES 619 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 1078 +#define YYNSTATES 1084 -#define YYUNDEFTOK 2 +/* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 377 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ @@ -2060,94 +2424,102 @@ static const yytype_uint8 yytranslate[] = }; #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 1614, 1614, 1614, 1625, 1631, 1635, 1640, 1644, 1650, - 1652, 1651, 1665, 1692, 1698, 1702, 1707, 1711, 1717, 1717, - 1721, 1725, 1729, 1733, 1737, 1741, 1745, 1750, 1751, 1755, - 1759, 1763, 1767, 1773, 1776, 1780, 1784, 1788, 1792, 1796, - 1801, 1805, 1814, 1823, 1832, 1841, 1848, 1849, 1853, 1857, - 1858, 1862, 1866, 1870, 1874, 1878, 1888, 1887, 1902, 1911, - 1912, 1915, 1916, 1923, 1922, 1937, 1941, 1946, 1950, 1955, - 1959, 1964, 1968, 1972, 1976, 1980, 1986, 1990, 1996, 1997, - 2003, 2007, 2011, 2015, 2019, 2023, 2027, 2031, 2035, 2039, - 2045, 2046, 2052, 2056, 2062, 2066, 2072, 2076, 2080, 2084, - 2088, 2092, 2098, 2104, 2111, 2115, 2119, 2123, 2127, 2131, - 2137, 2143, 2148, 2154, 2158, 2161, 2165, 2169, 2176, 2177, - 2178, 2179, 2184, 2191, 2192, 2195, 2199, 2199, 2205, 2206, - 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, - 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, - 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2237, 2237, - 2237, 2238, 2238, 2239, 2239, 2239, 2240, 2240, 2240, 2240, - 2241, 2241, 2241, 2242, 2242, 2242, 2243, 2243, 2243, 2243, - 2244, 2244, 2244, 2244, 2245, 2245, 2245, 2245, 2246, 2246, - 2246, 2246, 2247, 2247, 2247, 2247, 2248, 2248, 2251, 2255, - 2259, 2263, 2267, 2271, 2275, 2280, 2285, 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, - 2422, 2426, 2430, 2434, 2438, 2447, 2456, 2465, 2474, 2480, - 2481, 2486, 2490, 2497, 2501, 2508, 2512, 2521, 2538, 2539, - 2542, 2543, 2544, 2549, 2554, 2561, 2567, 2572, 2577, 2582, - 2589, 2589, 2600, 2604, 2610, 2614, 2620, 2623, 2629, 2634, - 2639, 2645, 2650, 2654, 2660, 2661, 2662, 2663, 2664, 2665, - 2666, 2667, 2671, 2676, 2675, 2687, 2691, 2686, 2696, 2696, - 2700, 2704, 2708, 2712, 2717, 2722, 2726, 2730, 2734, 2738, - 2742, 2743, 2749, 2756, 2748, 2769, 2777, 2785, 2785, 2785, - 2792, 2792, 2792, 2799, 2805, 2810, 2812, 2809, 2821, 2819, - 2837, 2842, 2835, 2859, 2857, 2873, 2883, 2894, 2898, 2902, - 2906, 2912, 2919, 2920, 2921, 2924, 2925, 2928, 2929, 2937, - 2938, 2944, 2948, 2951, 2955, 2959, 2963, 2968, 2972, 2976, - 2980, 2986, 2985, 2995, 2999, 3003, 3007, 3013, 3018, 3023, - 3027, 3031, 3035, 3039, 3043, 3047, 3051, 3055, 3059, 3063, - 3067, 3071, 3075, 3079, 3085, 3090, 3097, 3097, 3101, 3106, - 3113, 3117, 3123, 3124, 3127, 3132, 3135, 3139, 3145, 3149, - 3156, 3155, 3170, 3180, 3184, 3189, 3196, 3200, 3204, 3208, - 3212, 3216, 3220, 3224, 3228, 3235, 3234, 3249, 3248, 3264, - 3272, 3281, 3284, 3291, 3294, 3298, 3299, 3302, 3306, 3309, - 3313, 3316, 3317, 3318, 3319, 3322, 3323, 3329, 3330, 3331, - 3335, 3348, 3349, 3355, 3360, 3359, 3370, 3374, 3380, 3384, - 3397, 3401, 3407, 3410, 3411, 3414, 3420, 3426, 3427, 3430, - 3437, 3436, 3450, 3454, 3468, 3473, 3487, 3493, 3494, 3495, - 3496, 3497, 3501, 3507, 3511, 3521, 3522, 3523, 3527, 3533, - 3537, 3541, 3545, 3549, 3555, 3559, 3565, 3569, 3573, 3577, - 3581, 3585, 3593, 3600, 3606, 3607, 3611, 3615, 3614, 3631, - 3632, 3635, 3641, 3645, 3651, 3652, 3656, 3660, 3666, 3672, - 3678, 3685, 3691, 3698, 3702, 3708, 3712, 3718, 3719, 3722, - 3726, 3732, 3736, 3740, 3744, 3750, 3755, 3760, 3764, 3768, - 3772, 3776, 3780, 3784, 3788, 3792, 3796, 3800, 3804, 3808, - 3812, 3817, 3823, 3828, 3833, 3838, 3843, 3850, 3854, 3861, - 3866, 3865, 3877, 3881, 3887, 3895, 3903, 3911, 3915, 3921, - 3925, 3931, 3932, 3935, 3940, 3947, 3948, 3951, 3955, 3961, - 3965, 3971, 3976, 3976, 4001, 4002, 4008, 4013, 4019, 4025, - 4030, 4034, 4044, 4051, 4052, 4053, 4056, 4057, 4058, 4059, - 4062, 4063, 4064, 4067, 4068, 4071, 4075, 4081, 4082, 4088, - 4089, 4092, 4093, 4096, 4099, 4100, 4101, 4104, 4105, 4108, - 4113, 4116, 4117, 4121 + 0, 1625, 1625, 1625, 1636, 1642, 1646, 1651, 1655, 1661, + 1663, 1662, 1676, 1703, 1709, 1713, 1718, 1722, 1728, 1728, + 1732, 1736, 1740, 1744, 1748, 1752, 1756, 1761, 1762, 1766, + 1770, 1774, 1778, 1784, 1787, 1791, 1795, 1799, 1803, 1807, + 1812, 1816, 1825, 1834, 1843, 1852, 1859, 1860, 1864, 1868, + 1869, 1873, 1877, 1881, 1885, 1889, 1899, 1898, 1913, 1922, + 1923, 1926, 1927, 1934, 1933, 1948, 1952, 1957, 1961, 1966, + 1970, 1975, 1979, 1983, 1987, 1991, 1997, 2001, 2007, 2008, + 2014, 2018, 2022, 2026, 2030, 2034, 2038, 2042, 2046, 2050, + 2056, 2057, 2063, 2067, 2073, 2077, 2083, 2087, 2091, 2095, + 2099, 2103, 2109, 2115, 2122, 2126, 2130, 2134, 2138, 2142, + 2148, 2154, 2159, 2165, 2169, 2172, 2176, 2180, 2187, 2188, + 2189, 2190, 2195, 2202, 2203, 2206, 2210, 2210, 2216, 2217, + 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, + 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, + 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2248, 2248, + 2248, 2249, 2249, 2250, 2250, 2250, 2251, 2251, 2251, 2251, + 2252, 2252, 2252, 2253, 2253, 2253, 2254, 2254, 2254, 2254, + 2255, 2255, 2255, 2255, 2256, 2256, 2256, 2256, 2257, 2257, + 2257, 2257, 2258, 2258, 2258, 2258, 2259, 2259, 2262, 2266, + 2270, 2274, 2278, 2282, 2286, 2291, 2296, 2301, 2305, 2309, + 2313, 2317, 2321, 2325, 2329, 2333, 2337, 2341, 2345, 2349, + 2353, 2357, 2361, 2365, 2369, 2373, 2377, 2381, 2385, 2389, + 2393, 2397, 2401, 2405, 2409, 2413, 2417, 2421, 2425, 2429, + 2433, 2437, 2441, 2445, 2449, 2458, 2467, 2476, 2485, 2491, + 2492, 2497, 2501, 2508, 2512, 2519, 2523, 2532, 2549, 2550, + 2553, 2554, 2555, 2560, 2565, 2572, 2578, 2583, 2588, 2593, + 2600, 2600, 2611, 2615, 2621, 2625, 2631, 2634, 2640, 2644, + 2649, 2654, 2658, 2664, 2669, 2673, 2679, 2680, 2681, 2682, + 2683, 2684, 2685, 2686, 2690, 2695, 2694, 2706, 2710, 2705, + 2715, 2715, 2719, 2723, 2727, 2731, 2736, 2741, 2745, 2749, + 2753, 2757, 2761, 2762, 2768, 2775, 2767, 2788, 2796, 2804, + 2804, 2804, 2811, 2811, 2811, 2818, 2824, 2829, 2831, 2828, + 2840, 2838, 2856, 2861, 2854, 2878, 2876, 2892, 2902, 2913, + 2917, 2921, 2925, 2931, 2938, 2939, 2940, 2943, 2944, 2947, + 2948, 2956, 2957, 2963, 2967, 2970, 2974, 2978, 2982, 2987, + 2991, 2995, 2999, 3005, 3004, 3014, 3018, 3022, 3026, 3032, + 3037, 3042, 3046, 3050, 3054, 3058, 3062, 3066, 3070, 3074, + 3078, 3082, 3086, 3090, 3094, 3098, 3104, 3109, 3116, 3116, + 3120, 3125, 3132, 3136, 3142, 3143, 3146, 3151, 3154, 3158, + 3164, 3168, 3175, 3174, 3189, 3199, 3203, 3208, 3215, 3219, + 3223, 3227, 3231, 3235, 3239, 3243, 3247, 3254, 3253, 3268, + 3267, 3283, 3291, 3300, 3303, 3310, 3313, 3317, 3318, 3321, + 3325, 3328, 3332, 3335, 3336, 3337, 3338, 3341, 3342, 3348, + 3349, 3350, 3354, 3367, 3368, 3374, 3379, 3378, 3388, 3392, + 3398, 3402, 3415, 3419, 3425, 3428, 3429, 3432, 3438, 3444, + 3445, 3448, 3455, 3454, 3467, 3471, 3485, 3490, 3504, 3510, + 3511, 3512, 3513, 3514, 3518, 3524, 3528, 3538, 3539, 3540, + 3544, 3550, 3554, 3558, 3562, 3566, 3572, 3576, 3582, 3586, + 3590, 3594, 3598, 3602, 3610, 3617, 3623, 3624, 3628, 3632, + 3631, 3648, 3649, 3652, 3658, 3662, 3668, 3669, 3673, 3677, + 3683, 3687, 3693, 3699, 3706, 3712, 3719, 3723, 3729, 3733, + 3739, 3740, 3743, 3747, 3753, 3757, 3761, 3765, 3771, 3776, + 3781, 3785, 3789, 3793, 3797, 3801, 3805, 3809, 3813, 3817, + 3821, 3825, 3829, 3833, 3838, 3844, 3849, 3854, 3859, 3864, + 3871, 3875, 3882, 3887, 3886, 3898, 3902, 3908, 3916, 3924, + 3932, 3936, 3942, 3946, 3952, 3953, 3956, 3961, 3968, 3969, + 3972, 3976, 3982, 3986, 3992, 3997, 3997, 4022, 4023, 4029, + 4034, 4040, 4046, 4051, 4055, 4060, 4065, 4075, 4080, 4086, + 4087, 4088, 4091, 4092, 4093, 4094, 4097, 4098, 4099, 4102, + 4103, 4106, 4110, 4116, 4117, 4123, 4124, 4127, 4128, 4131, + 4134, 4135, 4136, 4139, 4140, 4143, 4148, 4151, 4152, 4156 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || 1 +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if 1 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "keyword_class", "keyword_module", - "keyword_def", "keyword_begin", "keyword_if", "keyword_unless", - "keyword_while", "keyword_until", "keyword_for", "keyword_undef", - "keyword_rescue", "keyword_ensure", "keyword_end", "keyword_then", - "keyword_elsif", "keyword_else", "keyword_case", "keyword_when", - "keyword_break", "keyword_next", "keyword_redo", "keyword_retry", - "keyword_in", "keyword_do", "keyword_do_cond", "keyword_do_block", - "keyword_do_LAMBDA", "keyword_return", "keyword_yield", "keyword_super", - "keyword_self", "keyword_nil", "keyword_true", "keyword_false", - "keyword_and", "keyword_or", "keyword_not", "modifier_if", - "modifier_unless", "modifier_while", "modifier_until", "modifier_rescue", - "keyword_alias", "keyword_BEGIN", "keyword_END", "keyword__LINE__", - "keyword__FILE__", "keyword__ENCODING__", "\"local variable or method\"", - "\"method\"", "\"global variable\"", "\"instance variable\"", - "\"constant\"", "\"class variable\"", "\"label\"", "\"integer literal\"", + "\"end of file\"", "error", "\"invalid token\"", "keyword_class", + "keyword_module", "keyword_def", "keyword_begin", "keyword_if", + "keyword_unless", "keyword_while", "keyword_until", "keyword_for", + "keyword_undef", "keyword_rescue", "keyword_ensure", "keyword_end", + "keyword_then", "keyword_elsif", "keyword_else", "keyword_case", + "keyword_when", "keyword_break", "keyword_next", "keyword_redo", + "keyword_retry", "keyword_in", "keyword_do", "keyword_do_cond", + "keyword_do_block", "keyword_do_LAMBDA", "keyword_return", + "keyword_yield", "keyword_super", "keyword_self", "keyword_nil", + "keyword_true", "keyword_false", "keyword_and", "keyword_or", + "keyword_not", "modifier_if", "modifier_unless", "modifier_while", + "modifier_until", "modifier_rescue", "keyword_alias", "keyword_BEGIN", + "keyword_END", "keyword__LINE__", "keyword__FILE__", + "keyword__ENCODING__", "\"local variable or method\"", "\"method\"", + "\"global variable\"", "\"instance variable\"", "\"constant\"", + "\"class variable\"", "\"label\"", "\"integer literal\"", "\"float literal\"", "\"character literal\"", "tXSTRING", "tREGEXP", "tSTRING", "tSTRING_PART", "tSTRING_MID", "tNTH_REF", "tBACK_REF", "tREGEXP_END", "\"numbered parameter\"", "\"unary plus\"", @@ -2195,827 +2567,838 @@ static const char *const yytname[] = "dot_or_colon", "call_op", "call_op2", "opt_terms", "opt_nl", "rparen", "trailer", "term", "nl", "terms", "none", YY_NULLPTR }; -#endif -# ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_int16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 61, 63, 58, 62, 60, 124, 94, 38, 43, - 45, 42, 47, 37, 376, 33, 126, 377, 123, 125, - 91, 93, 44, 96, 40, 41, 59, 46, 10 -}; -# endif +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + return yytname[yysymbol]; +} +#endif -#define YYPACT_NINF (-873) +#define YYPACT_NINF (-868) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-614) +#define YYTABLE_NINF (-620) #define yytable_value_is_error(Yyn) \ ((Yyn) == YYTABLE_NINF) - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ static const yytype_int16 yypact[] = { - -873, 124, 3686, -873, 8674, 10798, 11140, 6982, -873, 10444, - 10444, -873, -873, 10912, 8164, 6598, 8910, 8910, -873, -873, - 8910, 4343, 3935, -873, -873, -873, -873, -13, 8164, -873, - -4, -873, -873, -873, 7124, 3799, -873, -873, 7266, -873, - -873, -873, -873, -873, -873, -873, 45, 10562, 10562, 10562, - 10562, 89, 5857, 585, 9382, 9736, 8446, -873, 7882, 681, - 776, 904, 1227, 1252, -873, 288, 10680, 10562, -873, 448, - -873, 1256, -873, 328, 1307, 1307, -873, -873, 152, 44, - -873, 98, 11026, -873, 87, 13068, 318, 487, 56, 117, - -873, 466, -873, -873, -873, -873, -873, -873, -873, -873, - -873, 212, 123, -873, 291, 92, -873, -873, -873, -873, - -873, 106, 106, -13, 623, 777, -873, 10444, 364, 5976, - 355, 1435, 1435, -873, 139, -873, 669, -873, -873, 92, - -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, - -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, - -873, -873, -873, -873, -873, -873, -873, -873, 23, 46, - 60, 82, -873, -873, -873, -873, -873, -873, 127, 191, - 203, 204, -873, 229, -873, -873, -873, -873, -873, -873, - -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, - -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, - -873, -873, -873, -873, -873, -873, -873, -873, -873, 253, - 5035, 211, 328, 1307, 1307, 160, 193, 13192, 712, 118, - 248, 207, 160, 10444, 10444, 887, 312, -873, -873, 908, - 347, 58, 86, -873, -873, -873, -873, -873, -873, -873, - -873, -873, 8023, -873, -873, 240, -873, -873, -873, -873, - -873, -873, 448, -873, 632, -873, 369, -873, -873, 448, - 4071, 10562, 10562, 10562, 10562, -873, 13130, -873, -873, 292, - 373, 292, -873, -873, -873, 9028, -873, -873, -873, 8910, - -873, -873, -873, 6598, 6836, -873, 309, 6095, -873, 955, - 350, 13254, 13254, 299, 8792, 5857, 325, 448, 1256, 448, - 353, -873, 8792, 448, 352, 1511, 1511, -873, 13130, 344, - 1511, -873, 434, 11254, 358, 1013, 1040, 1057, 1610, -873, - -873, -873, -873, 1255, -873, -873, -873, -873, -873, -873, - 653, 1276, -873, -873, 825, -873, 1003, -873, 1314, -873, - 1348, 396, 414, -873, -873, -873, -873, 6360, 10444, 10444, - 10444, 10444, 8792, 10444, 10444, 48, -873, -873, -873, -873, - -873, 448, -873, -873, -873, -873, -873, -873, -873, 1963, - 399, 410, 5035, 10562, -873, 392, 486, 413, -873, 448, - -873, -873, -873, 419, 10562, -873, 430, 490, 441, 530, - -873, -873, 464, 5035, -873, -873, 9854, -873, 5857, 8560, - 458, 9854, 10562, 10562, 10562, 10562, 10562, 10562, 10562, 10562, - 10562, 10562, 10562, 10562, 10562, 10562, 553, 10562, 10562, 10562, - 10562, 10562, 10562, 10562, 10562, 10562, 10562, 10562, 10562, 2428, - -873, 8910, -873, 3143, -873, -873, 12650, -873, -873, -873, - -873, 10680, 10680, -873, 516, -873, 328, -873, 1068, -873, - -873, -873, -873, -873, -873, 11532, 8910, 11618, 5035, 10444, - -873, -873, -873, 606, 615, 215, 509, 510, -873, 5181, - 617, 10562, 11704, 8910, 11790, 10562, 10562, 5473, 101, 101, - 115, 11876, 8910, 11962, -873, 573, -873, 6095, 369, -873, - -873, 9972, 625, -873, 10562, 13192, 13192, 13192, 10562, -873, - -873, 9146, -873, 10562, -873, 9500, 6717, 506, 448, 292, - 292, -873, -873, 838, 511, -873, -873, -873, 8164, 5592, - 522, 11704, 11790, 10562, 1256, 448, -873, -873, 6479, 500, - 1256, -873, -873, 9618, -873, 448, 9736, -873, -873, -873, - 1068, 98, 11254, -873, 11254, 12048, 8910, 12134, 2259, -873, - -873, 526, -873, 1353, 6095, 653, -873, -873, -873, -873, - -873, -873, -873, 10562, 10562, -873, -873, -873, -873, -873, - -873, -873, -873, -873, -873, -873, 1454, 448, 448, 537, - 10680, 666, 13192, 335, -873, -873, -873, 54, -873, -873, - 2093, -873, 13192, 2259, -873, -873, 1038, -873, -873, 10680, - 672, 47, 10562, -873, 12784, 292, -873, 448, 11254, 559, - -873, -873, -873, 655, 581, 2039, -873, -873, 1078, 220, - 3042, 3042, 3042, 3042, 1617, 1617, 3376, 2927, 3042, 3042, - 13254, 13254, 1146, 1146, -873, 350, 13192, 1617, 1617, 1427, - 1427, 1442, 378, 378, 350, 350, 350, 4479, 7622, 4751, - 7740, -873, 106, -873, 568, 292, 461, -873, 501, -873, - -873, 4207, -873, -873, 1791, 47, 47, -873, 2539, -873, - -873, -873, -873, -873, 448, 10444, 5035, 906, 51, -873, - 106, 571, 106, 703, 838, 8305, -873, 10090, 706, -873, - 10562, 10562, 439, -873, 7384, 7503, 594, 256, 282, 706, - -873, -873, -873, -873, 55, 79, 598, 126, 129, 10444, - 8164, 621, 741, 13192, 639, -873, 13192, 13192, 852, 10562, - 13130, -873, 292, 13192, -873, -873, -873, -873, 9264, 9500, - -873, -873, -873, 637, -873, -873, 138, 1256, 448, 1511, - 458, -873, 906, 51, 636, 933, 934, -873, 91, 2259, - -873, 640, -873, 350, 350, -873, 276, 448, 620, -873, - -873, 2153, 720, 3255, -873, 721, -873, 413, -873, 448, - -873, -873, 644, 646, 647, -873, 651, 721, 647, 752, - 12722, -873, -873, 2259, 5035, -873, -873, 12855, 10208, -873, - -873, 11254, 8792, 10680, 10562, 12220, 8910, 12306, 167, 10680, - 10680, -873, 516, 577, 9146, 10680, 10680, -873, 516, 117, - 152, 5035, 6095, 47, -873, 448, 795, -873, -873, -873, - -873, 12784, -873, 719, -873, 5738, 801, -873, 10444, 803, - -873, 10562, 10562, 307, 10562, 10562, 807, 6241, 6241, 130, - 101, -873, -873, -873, 10326, 5327, 13192, -873, 6717, 292, - -873, -873, -873, 497, 678, 1326, 5035, 6095, -873, -873, - -873, 683, -873, 1671, 448, 10562, 10562, -873, -873, 2259, - -873, 1038, -873, 1038, -873, 1038, -873, -873, 10562, 10562, - -873, -873, -873, 11368, -873, 689, 413, 693, 11368, -873, - 696, 708, -873, 836, 10562, 12926, -873, -873, 13192, 4615, - 4887, 716, 324, 348, 10562, 10562, -873, -873, -873, -873, - -873, 10680, -873, -873, -873, -873, -873, -873, -873, 843, - 722, 6095, 5035, -873, -873, 11482, 160, -873, -873, 6241, - -873, -873, 160, -873, 10562, -873, 848, 854, -873, 13192, - 157, -873, 9500, -873, 849, 858, 735, 1330, 1330, 342, - -873, 13192, 13192, 647, 736, 647, 647, 13192, 13192, 755, - 761, 840, 1091, 335, -873, -873, 1746, -873, 1091, 2259, - -873, 1038, -873, -873, 12997, 412, 13192, 13192, -873, -873, - -873, -873, 759, 892, 857, -873, 1117, 1040, 1057, 5035, - -873, 5181, -873, -873, 6241, -873, -873, -873, -873, 778, - -873, -873, -873, -873, 780, 780, 1330, 781, -873, 1038, - -873, -873, -873, -873, -873, -873, 12392, -873, 413, 335, - -873, -873, 784, 785, 792, -873, 794, 792, -873, -873, - 1068, 12478, 8910, 12564, 615, 439, 931, 849, 852, 1330, - 780, 1330, 647, 804, 808, -873, 2259, -873, 1038, -873, - 1038, -873, 1038, -873, -873, 906, 51, 806, 592, 753, - -873, -873, -873, -873, 780, -873, 792, 812, 792, 792, - 497, -873, 1038, -873, -873, -873, 792, -873 + -868, 115, 3515, -868, 8231, 10355, 10697, 6539, -868, 10001, + 10001, -868, -868, 10469, 7721, 6155, 8467, 8467, -868, -868, + 8467, 4172, 3764, -868, -868, -868, -868, 18, 7721, -868, + 38, -868, -868, -868, 6681, 3628, -868, -868, 6823, -868, + -868, -868, -868, -868, -868, -868, 45, 10119, 10119, 10119, + 10119, 217, 5414, 792, 8939, 9293, 8003, -868, 7439, 1134, + 894, 67, 1139, 1203, -868, 94, 10237, 10119, -868, 780, + -868, 1204, -868, 529, 1741, 1741, -868, -868, 271, 173, + -868, 184, 10583, -868, 272, 12773, 579, 668, 228, 75, + -868, 381, -868, -868, -868, -868, -868, -868, -868, -868, + -868, 48, 278, -868, 300, 129, -868, -868, -868, -868, + -868, 243, 243, 18, 110, 646, -868, 10001, 360, 5533, + 517, 1837, 1837, -868, 279, -868, 756, -868, -868, 129, + -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, + -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, + -868, -868, -868, -868, -868, -868, -868, -868, 33, 89, + 108, 109, -868, -868, -868, -868, -868, -868, 117, 154, + 192, 199, -868, 208, -868, -868, -868, -868, -868, -868, + -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, + -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, + -868, -868, -868, -868, -868, -868, -868, -868, -868, 290, + 4592, 354, 529, 1741, 1741, 77, 305, 12897, 801, 159, + 347, 193, 77, 10001, 10001, 866, 397, -868, -868, 890, + 433, 78, 85, -868, -868, -868, -868, -868, -868, -868, + -868, -868, 7580, -868, -868, 320, -868, -868, -868, -868, + -868, -868, 780, -868, 944, -868, 444, -868, -868, 780, + 3900, 124, 10119, 10119, 10119, 10119, -868, 12835, -868, -868, + 324, 428, 324, -868, -868, -868, 8585, -868, -868, -868, + 8467, -868, -868, -868, 6155, 6393, -868, 367, 5652, -868, + 974, 391, 12959, 12959, 355, 8349, 5414, 378, 780, 1204, + 780, 416, -868, 8349, 780, 408, 714, 714, -868, 12835, + 423, 714, -868, 500, 10811, 429, 988, 999, 1035, 1982, + -868, -868, -868, -868, 1241, -868, -868, -868, -868, -868, + -868, 981, 1248, -868, -868, 1126, -868, 1051, -868, 1252, + -868, 1265, 480, 482, -868, -868, -868, -868, 5917, 10001, + 10001, 10001, 10001, 8349, 10001, 10001, 93, -868, -868, -868, + -868, 536, 780, -868, -868, -868, -868, -868, -868, -868, + 2113, 475, 479, 4592, 10119, -868, 463, 563, 476, -868, + 780, -868, -868, -868, 483, 10119, -868, 487, 576, 489, + 581, -868, -868, 521, 4592, -868, -868, 9411, -868, 5414, + 8117, 503, 9411, 10119, 10119, 10119, 10119, 10119, 10119, 10119, + 10119, 10119, 10119, 10119, 10119, 10119, 10119, 592, 10119, 10119, + 10119, 10119, 10119, 10119, 10119, 10119, 10119, 10119, 10119, 10119, + 3310, -868, 8467, -868, 11089, -868, -868, 12293, -868, -868, + -868, -868, 10237, 10237, -868, 550, -868, 529, -868, 1036, + -868, -868, -868, -868, -868, -868, 11175, 8467, 11261, 4592, + 10001, -868, -868, -868, 636, 642, 210, 538, 540, -868, + 4738, 659, 10119, 11347, 8467, 11433, 10119, 10119, 5030, 620, + 620, 134, 11519, 8467, 11605, -868, 616, -868, 5652, 444, + -868, -868, 9529, 665, -868, 10119, 10119, 12897, 12897, 12897, + 10119, -868, -868, 8703, -868, 10119, -868, 9057, 6274, 546, + 780, 324, 324, -868, -868, 313, 547, -868, -868, -868, + 7721, 5149, 557, 11347, 11433, 10119, 1204, 780, -868, -868, + 6036, 555, 1204, -868, -868, 9175, -868, 780, 9293, -868, + -868, -868, 1036, 184, 10811, -868, 10811, 11691, 8467, 11777, + 2314, -868, -868, 561, -868, 1290, 5652, 981, -868, -868, + -868, -868, -868, -868, -868, 10119, 10119, -868, -868, -868, + -868, -868, -868, -868, -868, -868, -868, -868, -868, 1428, + 780, 780, 564, 10237, 699, 12897, 266, -868, -868, -868, + 263, -868, -868, 2562, -868, 12897, 2314, -868, -868, 2042, + -868, -868, 10237, 701, 65, 10119, -868, 12489, 324, -868, + 780, 10811, 566, -868, -868, -868, 674, 591, 2410, -868, + -868, 1037, 220, 3100, 3100, 3100, 3100, 1377, 1377, 3375, + 2808, 3100, 3100, 12959, 12959, 1279, 1279, -868, 391, 12897, + 1377, 1377, 1483, 1483, 1288, 383, 383, 391, 391, 391, + 2930, 7179, 4308, 7297, -868, 243, -868, 584, 324, 452, + -868, 516, -868, -868, 4036, -868, -868, 1908, 65, 65, + -868, 3027, -868, -868, -868, -868, -868, 780, 10001, 4592, + 697, 530, -868, 243, 587, 243, 707, 313, 7862, -868, + 9647, 715, -868, 10119, 10119, 572, -868, 6941, 7060, 596, + 223, 285, 715, -868, -868, -868, -868, 116, 121, 603, + 135, 136, 10001, 7721, 609, 734, 12897, 206, -868, 12897, + 12897, 12897, 281, 10119, 12835, -868, 324, 12897, -868, -868, + -868, -868, 8821, 9057, -868, -868, -868, 611, -868, -868, + 211, 1204, 780, 714, 503, -868, 697, 530, 613, 860, + 904, -868, 36, 2314, -868, 618, -868, 391, 391, -868, + -868, 812, 780, 619, -868, -868, 2628, 711, 12365, -868, + 706, 536, -868, 476, -868, 780, -868, -868, 623, 627, + 628, -868, 630, 706, 628, 731, 12427, -868, -868, 2314, + 4592, -868, -868, 12560, 9765, -868, -868, 10811, 8349, 10237, + 10119, 11863, 8467, 11949, 413, 10237, 10237, -868, 550, 560, + 8703, 10237, 10237, -868, 550, 75, 271, 4592, 5652, 65, + -868, 780, 766, -868, -868, -868, -868, 12489, -868, 689, + -868, 5295, 771, -868, 10001, 774, -868, 10119, 10119, 333, + 10119, 10119, 776, 5798, 5798, 148, 620, -868, -868, -868, + 9883, 4884, 12897, -868, 6274, 324, -868, -868, -868, 88, + 647, 990, 4592, 5652, -868, -868, -868, 653, -868, 1554, + 780, 10119, 10119, -868, -868, 2314, -868, 2042, -868, 2042, + -868, 2042, -868, -868, 10119, 10119, -868, -868, -868, 10925, + -868, 655, 476, 657, 10925, -868, 661, 667, -868, 786, + 10119, 12631, -868, -868, 12897, 3179, 4444, 670, 406, 426, + 10119, 10119, -868, -868, -868, -868, -868, 10237, -868, -868, + -868, -868, -868, -868, -868, 803, 677, 5652, 4592, -868, + -868, 11039, 77, -868, -868, 5798, -868, -868, 77, -868, + 10119, -868, 808, 809, -868, 12897, 219, -868, 9057, -868, + 1629, 813, 682, 1445, 1445, 1019, -868, 12897, 12897, 628, + 694, 628, 628, 12897, 12897, 705, 712, 788, 1054, 266, + -868, -868, 1801, -868, 1054, 2314, -868, 2042, -868, -868, + 12702, 432, 12897, 12897, -868, -868, -868, -868, 718, 830, + 795, -868, 1083, 999, 1035, 4592, -868, 4738, -868, -868, + 5798, -868, -868, -868, -868, 722, -868, -868, -868, -868, + 727, 727, 1445, 733, -868, 2042, -868, -868, -868, -868, + -868, -868, 12035, -868, 476, 266, -868, -868, 736, 746, + 750, -868, 751, 750, -868, -868, 1036, 12121, 8467, 12207, + 642, 572, 879, 1629, 281, 1445, 727, 1445, 628, 757, + 761, -868, 2314, -868, 2042, -868, 2042, -868, 2042, -868, + -868, 697, 530, 772, 201, 467, -868, -868, -868, -868, + 727, -868, 750, 781, 750, 750, 88, -868, 2042, -868, + -868, -868, 750, -868 }; - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ static const yytype_int16 yydefact[] = { - 2, 0, 0, 1, 0, 0, 0, 0, 293, 0, - 0, 317, 320, 0, 0, 599, 337, 338, 339, 340, - 305, 270, 270, 488, 487, 489, 490, 601, 0, 10, - 0, 492, 491, 493, 479, 585, 481, 480, 483, 482, - 475, 476, 437, 438, 494, 495, 291, 0, 0, 0, - 0, 0, 0, 295, 613, 613, 88, 312, 0, 0, - 0, 0, 0, 0, 452, 0, 0, 0, 3, 599, - 6, 9, 27, 33, 541, 541, 49, 60, 59, 0, - 76, 0, 80, 90, 0, 54, 248, 0, 61, 310, - 284, 285, 435, 286, 287, 288, 433, 432, 464, 434, - 431, 486, 0, 289, 290, 270, 5, 8, 337, 338, - 305, 613, 413, 0, 113, 114, 291, 0, 0, 0, - 0, 541, 541, 116, 496, 341, 0, 486, 290, 0, - 333, 168, 178, 169, 165, 194, 195, 196, 197, 176, + 2, 0, 0, 1, 0, 0, 0, 0, 295, 0, + 0, 319, 322, 0, 0, 605, 339, 340, 341, 342, + 307, 270, 270, 490, 489, 491, 492, 607, 0, 10, + 0, 494, 493, 495, 481, 591, 483, 482, 485, 484, + 477, 478, 439, 440, 496, 497, 293, 0, 0, 0, + 0, 0, 0, 297, 619, 619, 88, 314, 0, 0, + 0, 0, 0, 0, 454, 0, 0, 0, 3, 605, + 6, 9, 27, 33, 544, 544, 49, 60, 59, 0, + 76, 0, 80, 90, 0, 54, 248, 0, 61, 312, + 286, 287, 437, 288, 289, 290, 435, 434, 466, 436, + 433, 488, 0, 291, 292, 270, 5, 8, 339, 340, + 307, 619, 415, 0, 113, 114, 293, 0, 0, 0, + 0, 544, 544, 116, 498, 343, 0, 488, 292, 0, + 335, 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, 572, 55, 121, 122, 571, 0, - 0, 0, 58, 541, 541, 0, 0, 54, 0, 486, - 0, 290, 0, 0, 0, 112, 0, 352, 351, 0, - 0, 486, 290, 187, 180, 190, 175, 158, 159, 160, - 118, 119, 0, 123, 125, 20, 124, 455, 460, 459, - 607, 609, 599, 610, 0, 457, 0, 611, 608, 600, - 583, 0, 0, 273, 0, 265, 277, 74, 269, 613, - 435, 613, 576, 75, 73, 613, 259, 306, 72, 0, - 258, 412, 71, 599, 0, 18, 0, 0, 221, 0, - 222, 209, 212, 302, 0, 0, 0, 599, 15, 599, - 78, 14, 0, 599, 0, 604, 604, 249, 0, 0, - 604, 574, 0, 0, 86, 0, 96, 103, 541, 469, - 468, 470, 471, 0, 467, 466, 439, 444, 443, 446, - 0, 0, 441, 448, 0, 450, 0, 462, 0, 473, - 0, 477, 478, 53, 236, 237, 4, 600, 0, 0, - 0, 0, 0, 0, 0, 548, 544, 543, 542, 545, - 546, 0, 550, 562, 517, 518, 566, 565, 561, 541, - 0, 504, 0, 510, 515, 613, 520, 613, 540, 0, - 547, 549, 552, 526, 0, 559, 526, 564, 526, 568, - 524, 500, 0, 0, 400, 402, 0, 92, 0, 84, - 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 208, 211, 0, 0, 0, 0, 0, 0, + 148, 151, 152, 157, 575, 55, 121, 122, 574, 0, + 0, 0, 58, 544, 544, 0, 0, 54, 0, 488, + 0, 292, 0, 0, 0, 112, 0, 354, 353, 0, + 0, 488, 292, 187, 180, 190, 175, 158, 159, 160, + 118, 119, 0, 123, 125, 20, 124, 457, 462, 461, + 613, 615, 605, 616, 0, 459, 0, 617, 614, 606, + 589, 293, 278, 588, 273, 0, 265, 277, 74, 269, + 619, 437, 619, 579, 75, 73, 619, 259, 308, 72, + 0, 258, 414, 71, 605, 0, 18, 0, 0, 221, + 0, 222, 209, 212, 304, 0, 0, 0, 605, 15, + 605, 78, 14, 0, 605, 0, 610, 610, 249, 0, + 0, 610, 577, 0, 0, 86, 0, 96, 103, 544, + 471, 470, 472, 473, 0, 469, 468, 441, 446, 445, + 448, 0, 0, 443, 450, 0, 452, 0, 464, 0, + 475, 0, 479, 480, 53, 236, 237, 4, 606, 0, + 0, 0, 0, 0, 0, 0, 551, 547, 546, 545, + 548, 549, 0, 553, 565, 520, 521, 569, 568, 564, + 544, 0, 506, 0, 513, 518, 619, 523, 619, 543, + 0, 550, 552, 555, 529, 0, 562, 529, 567, 529, + 571, 527, 502, 0, 0, 402, 404, 0, 92, 0, + 84, 81, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 208, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 596, 613, 595, 0, 598, 597, 0, 417, 415, 311, - 436, 0, 0, 406, 65, 309, 330, 113, 114, 115, - 477, 478, 504, 497, 328, 0, 613, 0, 0, 0, - 594, 593, 56, 0, 613, 302, 0, 0, 343, 0, - 342, 0, 0, 613, 0, 0, 0, 0, 0, 0, - 302, 0, 613, 0, 325, 0, 126, 0, 0, 456, - 458, 0, 0, 612, 580, 278, 582, 272, 0, 601, - 266, 0, 275, 0, 267, 0, 599, 0, 599, 613, - 613, 260, 271, 599, 0, 308, 52, 602, 0, 0, - 0, 0, 0, 0, 17, 599, 300, 13, 600, 77, - 296, 299, 303, 606, 250, 605, 606, 252, 304, 575, - 102, 94, 0, 89, 0, 0, 613, 0, 541, 313, - 397, 526, 472, 0, 0, 447, 453, 440, 442, 449, - 451, 463, 474, 0, 0, 7, 21, 22, 23, 24, - 25, 50, 51, 508, 554, 507, 0, 599, 599, 526, - 0, 0, 509, 0, 522, 570, 519, 0, 523, 505, - 0, 533, 555, 0, 536, 563, 0, 538, 567, 0, - 0, 613, 0, 28, 30, 0, 31, 599, 0, 82, - 93, 48, 34, 46, 0, 253, 198, 29, 0, 290, - 226, 231, 232, 233, 228, 230, 240, 241, 234, 235, - 207, 210, 238, 239, 32, 218, 601, 227, 229, 223, - 224, 225, 213, 214, 215, 216, 217, 586, 591, 587, - 592, 411, 270, 409, 0, 613, 586, 588, 587, 589, - 410, 270, 586, 587, 270, 613, 613, 35, 253, 199, - 45, 206, 63, 66, 0, 0, 0, 113, 114, 117, - 0, 0, 613, 0, 599, 0, 294, 613, 613, 423, - 0, 0, 613, 344, 590, 301, 0, 586, 587, 613, - 346, 318, 345, 321, 590, 301, 0, 586, 587, 0, - 0, 0, 0, 277, 0, 324, 579, 578, 276, 0, - 279, 274, 613, 581, 577, 257, 255, 261, 262, 264, - 307, 603, 19, 0, 26, 205, 79, 16, 599, 604, - 95, 87, 99, 101, 0, 98, 100, 601, 0, 0, - 465, 0, 454, 219, 220, 548, 360, 599, 353, 503, - 501, 0, 41, 244, 335, 0, 516, 613, 569, 0, - 525, 553, 526, 526, 526, 560, 526, 548, 526, 43, - 246, 336, 388, 386, 0, 385, 384, 283, 0, 91, - 85, 0, 0, 0, 0, 0, 613, 0, 0, 0, - 0, 408, 69, 414, 262, 0, 0, 407, 67, 403, - 62, 0, 0, 613, 331, 0, 0, 414, 334, 573, - 57, 424, 425, 613, 426, 0, 613, 349, 0, 0, - 347, 0, 0, 414, 0, 0, 0, 0, 0, 414, - 0, 127, 461, 323, 0, 0, 280, 268, 599, 613, - 11, 297, 251, 97, 0, 390, 0, 0, 314, 445, - 361, 358, 551, 0, 599, 0, 0, 521, 506, 0, - 529, 0, 531, 0, 537, 0, 534, 539, 0, 0, - 383, 601, 601, 512, 513, 613, 613, 368, 0, 557, - 368, 368, 366, 0, 0, 281, 83, 47, 254, 586, - 587, 0, 586, 587, 0, 0, 40, 203, 39, 204, - 70, 0, 37, 201, 38, 202, 68, 404, 405, 0, - 0, 0, 0, 498, 329, 0, 0, 428, 350, 0, - 12, 430, 0, 315, 0, 316, 0, 0, 326, 279, - 613, 256, 263, 396, 0, 0, 0, 0, 0, 356, - 502, 42, 245, 526, 526, 526, 526, 44, 247, 0, - 0, 0, 511, 0, 364, 365, 368, 376, 556, 0, - 379, 0, 381, 401, 282, 414, 243, 242, 36, 200, - 418, 416, 0, 0, 0, 427, 0, 104, 111, 0, - 429, 0, 319, 322, 0, 420, 421, 419, 394, 601, - 392, 395, 399, 398, 362, 359, 0, 354, 530, 0, - 527, 532, 535, 389, 387, 302, 0, 514, 613, 0, - 367, 374, 368, 368, 368, 558, 368, 368, 64, 332, - 110, 0, 613, 0, 613, 613, 0, 0, 391, 0, - 357, 0, 526, 590, 301, 363, 0, 371, 0, 373, - 0, 380, 0, 377, 382, 107, 109, 0, 586, 587, - 422, 348, 327, 393, 355, 528, 368, 368, 368, 368, - 105, 372, 0, 369, 375, 378, 368, 370 + 0, 602, 619, 601, 0, 604, 603, 0, 419, 417, + 313, 438, 0, 0, 408, 65, 311, 332, 113, 114, + 115, 479, 480, 506, 499, 330, 0, 619, 0, 0, + 0, 600, 599, 56, 0, 619, 304, 0, 0, 345, + 0, 344, 0, 0, 619, 0, 0, 0, 0, 0, + 0, 304, 0, 619, 0, 327, 0, 126, 0, 0, + 458, 460, 0, 0, 618, 583, 584, 279, 587, 272, + 0, 607, 266, 0, 275, 0, 267, 0, 605, 0, + 605, 619, 619, 260, 271, 605, 0, 310, 52, 608, + 0, 0, 0, 0, 0, 0, 17, 605, 302, 13, + 606, 77, 298, 301, 305, 612, 250, 611, 612, 252, + 306, 578, 102, 94, 0, 89, 0, 0, 619, 0, + 544, 315, 399, 529, 474, 0, 0, 449, 455, 442, + 444, 451, 453, 465, 476, 0, 0, 7, 21, 22, + 23, 24, 25, 50, 51, 510, 557, 511, 509, 0, + 605, 605, 529, 0, 0, 512, 0, 525, 573, 522, + 0, 526, 507, 0, 536, 558, 0, 539, 566, 0, + 541, 570, 0, 0, 619, 278, 28, 30, 0, 31, + 605, 0, 82, 93, 48, 34, 46, 0, 253, 198, + 29, 0, 292, 226, 231, 232, 233, 228, 230, 240, + 241, 234, 235, 207, 210, 238, 239, 32, 218, 607, + 227, 229, 223, 224, 225, 213, 214, 215, 216, 217, + 592, 597, 593, 598, 413, 270, 411, 0, 619, 592, + 594, 593, 595, 412, 270, 592, 593, 270, 619, 619, + 35, 253, 199, 45, 206, 63, 66, 0, 0, 0, + 113, 114, 117, 0, 0, 619, 0, 605, 0, 296, + 619, 619, 425, 0, 0, 619, 346, 596, 303, 0, + 592, 593, 619, 348, 320, 347, 323, 596, 303, 0, + 592, 593, 0, 0, 0, 0, 277, 0, 326, 582, + 585, 581, 276, 281, 280, 274, 619, 586, 580, 257, + 255, 261, 262, 264, 309, 609, 19, 0, 26, 205, + 79, 16, 605, 610, 95, 87, 99, 101, 0, 98, + 100, 607, 0, 0, 467, 0, 456, 219, 220, 551, + 549, 362, 605, 355, 505, 503, 0, 41, 244, 337, + 0, 0, 519, 619, 572, 0, 528, 556, 529, 529, + 529, 563, 529, 551, 529, 43, 246, 338, 390, 388, + 0, 387, 386, 285, 0, 91, 85, 0, 0, 0, + 0, 0, 619, 0, 0, 0, 0, 410, 69, 416, + 262, 0, 0, 409, 67, 405, 62, 0, 0, 619, + 333, 0, 0, 416, 336, 576, 57, 426, 427, 619, + 428, 0, 619, 351, 0, 0, 349, 0, 0, 416, + 0, 0, 0, 0, 0, 416, 0, 127, 463, 325, + 0, 0, 282, 268, 605, 619, 11, 299, 251, 97, + 0, 392, 0, 0, 316, 447, 363, 360, 554, 0, + 605, 0, 0, 524, 508, 0, 532, 0, 534, 0, + 540, 0, 537, 542, 0, 0, 385, 607, 607, 515, + 516, 619, 619, 370, 0, 560, 370, 370, 368, 0, + 281, 283, 83, 47, 254, 592, 593, 0, 592, 593, + 0, 0, 40, 203, 39, 204, 70, 0, 37, 201, + 38, 202, 68, 406, 407, 0, 0, 0, 0, 500, + 331, 0, 0, 430, 352, 0, 12, 432, 0, 317, + 0, 318, 0, 0, 328, 280, 619, 256, 263, 398, + 0, 0, 0, 0, 0, 358, 504, 42, 245, 529, + 529, 529, 529, 44, 247, 0, 0, 0, 514, 0, + 366, 367, 370, 378, 559, 0, 381, 0, 383, 403, + 284, 416, 243, 242, 36, 200, 420, 418, 0, 0, + 0, 429, 0, 104, 111, 0, 431, 0, 321, 324, + 0, 422, 423, 421, 396, 607, 394, 397, 401, 400, + 364, 361, 0, 356, 533, 0, 530, 535, 538, 391, + 389, 304, 0, 517, 619, 0, 369, 376, 370, 370, + 370, 561, 370, 370, 64, 334, 110, 0, 619, 0, + 619, 619, 0, 0, 393, 0, 359, 0, 529, 596, + 303, 365, 0, 373, 0, 375, 0, 382, 0, 379, + 384, 107, 109, 0, 592, 593, 424, 350, 329, 395, + 357, 531, 370, 370, 370, 370, 105, 374, 0, 371, + 377, 380, 370, 372 }; - /* YYPGOTO[NTERM-NUM]. */ +/* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -873, -873, -873, 436, -873, 34, -873, -233, 137, -873, - 40, -873, -188, -215, 560, 1421, 1889, -873, 20, -57, - -873, -640, -873, 30, 948, -211, -19, -50, -286, -475, - -11, 2634, -61, 957, 9, -17, -873, -873, 42, -873, - 1196, -873, 503, 73, -209, -365, 99, -7, -873, -440, - -240, -157, 147, -350, 97, -873, -873, -873, -873, -873, - -873, -873, -873, -873, -873, -873, -873, -873, -873, -873, - -873, 8, -200, -450, -71, -620, -873, -873, -873, 182, - 260, -873, -536, -873, -873, -302, -873, -65, -873, -873, - 163, -873, -873, -873, -88, -873, -873, -452, -873, -53, - -873, -873, -873, -873, -873, -14, 26, -148, -873, -873, - -873, -873, -873, -259, -873, 729, -873, -873, -873, 6, - -873, -873, -873, 2469, 2735, 980, 2054, -873, -873, 24, - 504, 0, 142, 405, 27, -873, -873, -873, 302, 84, - -126, -222, -843, -697, -438, -873, 301, -721, -545, -872, - 29, -527, -873, -448, -873, 208, -340, -873, -873, -873, - 38, -429, 656, -351, -873, -873, -80, -873, 66, -23, - 557, -267, 327, -258, -64, -2 + -868, -868, -868, 411, -868, 25, -868, -282, 693, -868, + 42, -868, -254, -213, 768, 1343, 1513, -868, 84, -59, + -868, -429, -868, -14, 916, -190, 4, -33, -271, -487, + -11, 1993, -84, 936, 29, -19, -868, -868, 19, -868, + 867, -868, -392, 46, -461, -327, 118, -7, -868, -446, + -233, -184, 15, -360, 57, -868, -868, -868, -868, -868, + -868, -868, -868, -868, -868, -868, -868, -868, -868, -868, + -868, 8, -211, -460, -94, -610, -868, -868, -868, 163, + 501, -868, -572, -868, -868, -276, -868, -90, -868, -868, + 145, -868, -868, -868, -81, -868, -868, -451, -868, -78, + -868, -868, -868, -868, -868, 147, 58, -167, -868, -868, + -868, -868, -868, -248, -868, 710, -868, -868, -868, 2, + -868, -868, -868, 2347, 2558, 960, 1777, -868, -868, -27, + 502, 20, -9, 396, 16, -868, -868, -868, 181, 485, + 249, -244, -839, -672, -556, -868, 180, -723, -541, -867, + 14, -513, -868, -388, -868, 675, -351, -868, -868, -868, + 62, -436, 624, -330, -868, -868, -47, -868, 7, -22, + 806, -253, 394, -284, -65, -2 }; - /* YYDEFGOTO[NTERM-NUM]. */ +/* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 1, 2, 68, 69, 70, 286, 463, 464, 297, - 298, 518, 72, 612, 73, 213, 214, 685, 215, 76, - 77, 673, 813, 78, 79, 299, 80, 81, 82, 543, - 83, 216, 123, 124, 243, 244, 245, 710, 650, 207, - 85, 304, 616, 651, 277, 507, 508, 278, 279, 268, - 500, 536, 655, 606, 86, 210, 302, 738, 303, 318, - 748, 223, 837, 224, 838, 709, 994, 676, 674, 922, - 458, 289, 469, 701, 829, 830, 230, 757, 947, 1020, - 967, 881, 784, 785, 882, 854, 999, 1000, 549, 858, - 395, 601, 88, 89, 445, 666, 665, 492, 997, 688, - 823, 926, 930, 90, 91, 92, 331, 332, 554, 93, - 94, 95, 555, 253, 254, 255, 487, 96, 97, 98, - 325, 99, 100, 219, 220, 103, 221, 454, 675, 370, - 371, 372, 373, 374, 884, 885, 375, 376, 377, 770, - 591, 379, 380, 381, 382, 576, 383, 384, 385, 889, - 890, 386, 387, 388, 389, 390, 584, 209, 459, 309, - 510, 272, 129, 680, 653, 462, 457, 436, 514, 855, - 515, 534, 257, 258, 259, 301 + 0, 1, 2, 68, 69, 70, 287, 464, 465, 298, + 299, 520, 72, 615, 73, 213, 214, 688, 215, 76, + 77, 676, 819, 78, 79, 300, 80, 81, 82, 545, + 83, 216, 123, 124, 243, 244, 245, 713, 653, 207, + 85, 305, 619, 654, 278, 509, 510, 279, 280, 269, + 502, 538, 658, 609, 86, 210, 303, 742, 304, 319, + 752, 223, 843, 224, 844, 712, 1000, 679, 677, 928, + 459, 290, 470, 704, 835, 836, 230, 762, 953, 1026, + 973, 887, 790, 791, 888, 860, 1005, 1006, 551, 864, + 396, 604, 88, 89, 446, 669, 668, 493, 1003, 691, + 829, 932, 936, 90, 91, 92, 332, 333, 556, 93, + 94, 95, 557, 253, 254, 255, 488, 96, 97, 98, + 326, 99, 100, 219, 220, 103, 221, 455, 678, 371, + 372, 373, 374, 375, 890, 891, 376, 377, 378, 776, + 594, 380, 381, 382, 383, 579, 384, 385, 386, 895, + 896, 387, 388, 389, 390, 391, 587, 209, 460, 310, + 512, 273, 129, 683, 656, 463, 458, 437, 516, 861, + 517, 536, 257, 258, 259, 302 }; - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 106, 439, 270, 270, 284, 347, 270, 433, 435, 343, - 87, 285, 87, 126, 126, 282, 205, 218, 218, 280, - 246, 229, 477, 218, 218, 218, 517, 542, 218, 703, - 222, 504, 400, 300, 246, 252, 712, 588, 107, 537, - 270, 270, 71, 539, 71, 314, 265, 265, 775, 206, - 265, 617, 307, 311, 271, 271, 206, 449, 271, 861, - 87, 721, 888, 772, 315, 721, 654, 324, 826, 741, - 206, 556, 391, 391, 218, 393, 724, 440, 652, 836, - -107, 256, 661, -104, 525, 664, 334, 336, 338, 340, - 315, 681, 306, 310, 276, 281, 550, 1025, 444, 392, - 206, 1001, 125, 125, -109, 573, 682, 724, 696, 280, - 125, -111, 501, -488, 505, 267, 273, 706, 437, 274, - 856, 652, 393, 661, 3, 218, 782, 87, 700, 811, - 812, 283, 682, 790, 287, 346, -487, -485, 474, 581, - -110, -301, 773, 437, 293, 776, 434, 578, 533, 483, - -489, -106, 771, 125, -108, -105, -301, 366, 378, 378, - 600, 430, 910, 269, 269, 396, -112, 269, 916, 574, - -488, 682, -490, 783, 1025, 825, 468, 491, 443, 125, - 394, 744, 367, 558, 276, 281, 558, 607, 558, 296, - 558, -301, 558, -487, 1001, -587, 682, -99, -301, -586, - -96, 305, 443, 432, 857, 378, 378, -489, 401, 522, - -484, 391, 391, 611, 393, 441, 247, -492, 87, 248, - 249, -101, 772, -587, 904, 683, 667, 670, -103, -490, - 438, 218, 218, 528, 772, 547, 275, 466, 467, -104, - 397, 535, 535, 478, 479, 888, 535, 250, 888, 251, - 275, 324, 1007, 611, 611, 438, 296, -102, 542, -77, - 594, 270, 597, 541, 453, 270, 465, 502, -98, 502, - 504, -100, -97, 511, -492, 247, 300, 921, 248, 249, - -91, -491, 247, 218, 206, 248, 249, 218, 721, 721, - 905, 218, 218, -493, -479, 87, 752, 378, 378, 476, - 724, 773, 87, 87, -484, 265, 250, 523, 251, 265, - 87, 771, 442, 773, 471, 251, 896, 271, 488, -483, - 995, 315, 542, 771, 775, 888, 747, 755, -111, 356, - 357, 358, 359, -104, 524, 891, -110, 822, -491, 603, - 475, -111, 530, 460, 613, 360, 341, 342, 834, 553, - -493, -479, 728, 729, -96, 87, 218, 218, 218, 218, - 87, 218, 218, 527, 721, 353, 354, 480, 566, 567, - 568, 569, 484, 585, 835, 585, -483, -106, 512, 300, - 87, 565, 486, 442, 613, 613, 765, 71, 609, 491, - 938, 523, 570, 755, 679, 356, 357, 358, 359, 934, - 461, 87, 378, -108, 218, 558, 87, 315, -341, 618, - 125, 360, -111, 450, 451, 447, 805, 270, 860, 448, - -110, 954, 509, -341, 520, 771, 269, 867, -105, 511, - 503, 901, 296, -103, 499, 771, 364, 365, 366, 218, - 806, -102, 270, 816, 652, -106, 661, 519, 788, 618, - 618, 417, 807, 378, 511, 809, 828, 825, -341, 270, - 517, 265, 689, 367, 218, -341, 87, 218, 270, -108, - 526, 511, 852, 807, -76, 659, 718, 87, 659, 417, - 511, 218, 847, 538, 1006, 87, 265, 270, 996, 540, - 218, 270, 740, 532, 541, 87, 125, 563, 804, 659, - 544, 732, 721, 265, 911, 542, 660, 502, 502, 426, - 427, 428, 265, 724, 845, 564, 659, 106, 1023, 270, - 580, 1026, 270, -414, 246, 659, 42, 87, 771, 43, - 660, -499, 270, -105, 583, 296, 87, 586, 797, 722, - 517, 595, 470, 605, 511, 964, 965, 660, 605, 470, - 315, 893, 315, 805, 218, 587, 660, 844, 541, 71, - 206, 590, 87, 247, 659, 505, 248, 249, 737, 212, - 212, 739, 593, 59, 727, 212, 265, 429, 919, 959, - 960, 598, -106, 596, 906, 599, 493, -414, 218, 659, - 912, 914, 430, 806, 250, 660, 251, 517, 1067, 786, - 610, 771, -414, -98, 634, 611, 692, 218, -106, 847, - 762, 611, 771, 798, 699, 672, 315, 611, 611, 551, - 660, 686, -108, 945, 711, 452, 452, 431, 687, 779, - 690, 691, 378, 693, 432, -414, 552, -414, 714, 125, - 715, 125, -91, -100, -414, 802, 870, 872, 874, -583, - 876, 726, 877, 502, 808, 468, 731, 810, 105, 280, - 105, 734, 280, 786, 786, 105, 105, 1057, 749, 911, - 579, 105, 105, 105, 493, 535, 105, 446, 1045, 761, - 280, 764, 682, 218, 87, 824, 827, 781, 575, 983, - 827, 751, 942, 841, 820, 815, 978, 827, -105, 792, - -298, 791, 793, -298, -298, 125, 589, -106, 105, 803, - -106, -106, 817, -479, 270, 270, 246, 218, 818, -97, - 502, 917, 105, 611, 825, 801, 989, 206, -479, 840, - -298, -298, 991, -298, 276, 833, 613, 276, -106, 839, - -106, 541, 613, 908, 326, 327, 328, 489, 613, 613, - 248, 249, 206, 801, 247, 276, 843, 248, 249, 455, - 842, -583, 863, -479, 865, 585, 849, -583, 247, -108, - -479, 248, 249, 105, 430, 105, 850, 853, 573, 859, - 517, 499, 270, 212, 212, 250, 869, 251, 871, 873, - 270, 768, 87, 875, 511, 768, 878, 329, 330, 315, - 87, 618, 472, -584, 218, 702, 702, 618, 218, 456, - 924, 786, 925, 618, 618, 929, 432, 430, 933, 87, - 87, 927, 935, 943, 931, 948, 265, 1008, 1010, 1011, - 1012, 963, 897, 87, 605, 966, 218, 333, 969, 659, - 327, 328, 849, 513, 516, 87, 87, 502, 932, 551, - 971, 973, 473, 87, 613, 493, 529, 975, 980, 432, - 531, 981, 493, 992, 87, 87, 105, -483, -108, 993, - 660, -108, -108, 1002, 1003, 353, 354, 758, 1009, 105, - 105, 1013, -483, 585, 585, 767, 559, 1014, 125, 327, - 328, 962, 329, 330, 774, 1015, 968, 778, 1028, -108, - 998, -108, 356, 357, 358, 359, 1033, 1029, 212, 212, - 212, 212, 1030, 571, 572, -584, 1065, -483, 360, 618, - 1037, -584, 1039, 1041, -483, 883, 1046, 1048, 270, 87, - 87, 105, -590, 986, 1050, 105, 1052, 87, 827, 105, - 105, 329, 330, 105, 669, 671, 1062, 1070, -586, 920, - 105, 105, -587, 247, 1072, 733, 248, 249, 105, -586, - -587, 227, 928, 130, 1061, 880, 335, 247, 327, 328, - 248, 249, 1063, 918, 936, 937, 1038, -291, 669, 671, - 125, 1060, 940, 490, 250, 125, 251, 208, 766, 0, - 1017, 892, -291, 0, 946, 1022, -590, 87, 481, 87, - 251, 814, 87, 105, 105, 105, 105, 105, 105, 105, - 105, -590, 0, 430, 0, 0, 585, 0, 270, 684, - 329, 330, 125, -586, -587, 0, 735, -291, 105, 0, - 511, 0, 689, 827, -291, 0, 0, 0, -586, -587, - 218, 470, 0, 0, -590, 521, -590, 0, 482, 105, - -586, 0, 105, -590, 105, 432, 0, 105, 982, 0, - 430, 0, 265, 725, 0, 560, 990, 327, 328, 0, - 730, -586, -587, -586, -587, 659, 0, -586, -587, 0, - -586, -587, 736, 0, 887, 886, 0, 105, 0, 777, - 0, 356, 357, 358, 359, 473, 868, 105, 105, 0, - 0, 0, 432, 545, 0, 883, 660, 360, 883, 0, - 0, 883, 105, 883, 105, 105, 0, 0, 430, 329, - 330, 0, 0, 0, 0, 105, 1034, 0, 1035, 105, - -486, 1036, 362, 105, 759, 760, 0, 0, 105, 364, - 365, 366, 923, 105, 0, -486, 0, -290, 0, 0, - 970, 972, 0, 546, 0, 0, 0, 0, -302, 0, - 432, 883, -290, 0, 789, 0, 367, 702, 795, 0, - 953, 768, 955, -302, 892, 105, 956, 892, 0, 892, - -486, 1016, 0, 430, 105, 0, 0, -486, 883, 0, - 883, 0, 883, 0, 883, 0, 430, -290, 0, 0, - 0, 0, 105, 0, -290, 217, 217, 1031, -302, 0, - 105, 217, 266, 266, 883, -302, 266, 0, 796, 0, - 0, 0, 430, 0, 0, 432, 1021, 892, 0, 0, - 0, 456, 0, 0, 0, 212, 105, 0, 432, 0, - 0, 819, 0, 288, 290, 291, 292, 417, 1004, 1005, - 266, 308, 0, 470, 892, 105, 892, 1032, 892, 470, - 892, 0, 344, 345, 432, 1018, 0, 0, 886, 212, - 1024, 886, 1027, 886, 0, 424, 425, 426, 427, 428, - 892, 0, 1047, 1049, 1051, 0, 1053, 1054, 0, 0, - 337, 327, 328, 0, 0, 851, 348, 349, 350, 351, - 352, 0, 907, 909, 0, 0, 0, 1040, 913, 915, - 1042, 0, 0, 217, 862, 339, 327, 328, 552, 327, - 328, 886, 0, 0, 0, 0, 1071, 1073, 1074, 1075, - 0, 105, 105, 0, 907, 909, 1077, 913, 915, 557, - 327, 328, 1064, 329, 330, 0, 0, 1066, 886, 1068, - 886, 0, 886, 1069, 886, 0, 0, 0, 355, 0, - 356, 357, 358, 359, 0, 105, 0, 0, 329, 330, - 0, 329, 330, 1076, 886, 0, 360, 561, 327, 328, - 0, 755, 0, 356, 357, 358, 359, 0, 212, 0, - 361, 0, 329, 330, 0, 0, 0, 0, 0, 360, - 0, 362, 0, 0, 0, 941, 0, 363, 364, 365, - 366, 562, 327, 328, 979, 0, 750, 327, 328, 217, - 217, 950, 0, 74, 362, 74, 121, 121, -613, 0, - 329, 330, 0, 0, 121, 367, 0, 979, 368, 0, - 105, 247, 0, 0, 248, 249, 0, 0, 105, 105, - 0, 369, 105, 0, 0, 105, 105, 495, 496, 497, - 344, 105, 105, 0, 329, 330, 0, 105, 105, 329, - 330, 266, 944, 74, 251, 266, 0, 121, 0, 217, - 217, 105, 0, 0, 105, 0, 355, 0, 356, 357, - 358, 359, 0, 105, 105, 0, 0, 0, 0, 0, - 0, 105, 0, 121, 360, 755, 0, 356, 357, 358, - 359, 0, 105, 105, 0, 414, 415, 0, 361, 0, - 0, 0, 0, 360, 0, 0, 0, 0, 417, 362, - 414, 415, 0, 0, 0, 363, 364, 365, 366, 0, - 74, 0, 0, 417, 217, 217, 217, 217, 362, 217, - 217, 0, 0, 0, 756, 423, 424, 425, 426, 427, - 428, 0, 0, 367, 0, 0, 368, 105, 0, 582, - 0, 424, 425, 426, 427, 428, 0, 105, 105, 369, - 592, 0, 0, 0, 0, 105, 0, 0, 0, 0, - 0, 0, 604, 0, 0, 0, 0, 615, 620, 621, - 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, - 632, 633, 0, 635, 636, 637, 638, 639, 640, 641, - 642, 643, 644, 645, 646, 0, 247, 266, 0, 248, - 249, 74, 0, 0, 0, 0, 0, 668, 668, 0, - 0, 0, 0, 0, 0, 105, 0, 105, 0, 0, - 105, 0, 266, 499, 0, 217, 0, 250, 0, 251, - 0, 355, 0, 356, 357, 358, 359, 668, 0, 266, - 0, 668, 668, 0, 0, 0, 0, 0, 266, 360, - 0, 0, 0, 0, 0, 0, 0, 713, 105, 0, - 716, 0, 0, 0, 717, 0, 0, 720, 0, 723, - 0, 308, 292, 0, 362, 414, 415, 0, 74, 0, - 363, 364, 365, 366, 0, 74, 74, 0, 417, 668, - 0, 0, 755, 74, 356, 357, 358, 359, 0, 720, - 0, 0, 308, 0, 121, 0, 0, 0, 367, 0, - 360, 368, 266, 421, 422, 423, 424, 425, 426, 427, - 428, 0, 0, 0, 548, 0, 0, 0, 0, 753, - 754, 0, 0, 0, 0, 362, 0, 0, 74, 0, - 0, 949, 0, 74, 0, 0, 763, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -613, 0, 74, 0, 780, 0, 355, 787, 356, - 357, 358, 359, 0, -613, -613, -613, -613, -613, -613, - 0, -613, 0, 0, 74, 360, 0, -613, -613, 74, - 121, 0, 74, 0, 0, 0, 0, 0, -613, -613, - 0, -613, -613, -613, -613, -613, 0, 0, 0, 0, - 362, 0, 0, 0, 0, 0, 363, 364, 365, 366, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 74, 0, 0, 0, 0, 0, 0, - 0, 217, 0, 0, 367, 0, 0, 368, 0, 74, - 0, -613, 0, 821, 0, 0, 763, 780, 1019, 0, - 74, 75, 0, 75, 122, 122, -613, 0, 74, 0, - 0, 0, 122, 0, 0, 217, -613, 0, 74, -613, - -613, 0, 0, 0, 0, 846, 0, 0, 0, 0, - 0, 0, 0, 0, 720, 308, 0, 0, 0, -613, - -613, 0, 0, 0, 0, 275, -613, -613, -613, -613, - 74, 75, 0, 0, 0, 122, 0, 0, 0, 74, + 106, 519, 266, 266, 348, 285, 266, 344, 440, 286, + 87, 478, 87, 126, 126, 283, 246, 218, 218, 281, + 706, 229, 256, 218, 218, 218, 206, 591, 218, 107, + 246, 270, 270, 206, 450, 270, 205, 777, 715, 506, + 434, 436, 620, 544, 71, 315, 71, 206, 393, 401, + 672, 674, 308, 312, 539, 781, 301, 725, 541, 745, + 87, 725, 125, 125, 316, 862, 894, 277, 282, 306, + 125, 728, 392, 392, 218, 552, 347, 206, 272, 272, + 778, 832, 272, 558, 672, 674, 503, 325, 507, 867, + 316, 584, 842, 469, 222, 394, 817, 818, 445, 252, + 655, 438, 728, -104, 664, 657, 527, 667, 1031, 281, + -111, 1007, 603, 125, -416, 3, 307, 311, 335, 337, + 339, 341, 535, -490, 796, 218, 581, 87, 685, 336, + 684, 328, 329, 739, 268, 274, -589, -487, 275, 125, + -486, -107, 394, 655, 788, 664, -109, 699, 614, 863, + 575, 444, 342, 343, 685, 438, 709, 277, 282, -110, + -106, -108, 284, 271, 271, 560, -112, 271, 560, -104, + 560, 475, 560, -105, 560, 444, 288, 686, -416, -489, + -490, 496, 484, 330, 331, 1031, 467, 468, 614, 614, + -96, 789, 247, -416, 685, 248, 249, 777, -491, -492, + -481, 271, 271, 813, 1007, 779, 815, -494, 782, 610, + 777, 392, 392, 439, 576, -481, -487, -106, 87, 685, + -96, 748, 469, 250, 813, 251, -416, -103, -416, 670, + 673, 218, 218, 530, 394, -416, -489, 831, 441, 492, + 778, 537, 537, 524, -493, -112, 537, 927, -589, 894, + -481, -486, 894, 778, -589, -491, -492, -481, -99, 489, + -592, 206, 266, -101, -494, -593, 266, 439, 504, 549, + 504, 325, 294, 276, 513, 544, -102, -98, -100, 506, + -104, 543, -495, 1013, 218, 477, 725, 725, 218, -481, + -97, 511, 218, 218, 397, 270, 87, 728, -485, 395, + 301, -493, 525, 87, 87, 529, 751, 479, 480, 756, + 902, 87, 443, 777, -111, 840, -106, 770, 435, -106, + -106, 247, 316, 777, 248, 249, 398, 732, 733, 894, + 828, -110, -77, 431, 781, 771, 1001, 526, 606, -495, + 544, -111, 272, 616, -106, 532, -481, -106, 501, -106, + 354, 355, 250, -91, 251, -485, 87, 218, 218, 218, + 218, 87, 218, 218, 725, 779, 367, 365, 366, 367, + 442, 125, 682, 567, 588, 433, 588, 841, 779, 916, + 461, 87, 555, 616, 616, 922, 944, 276, 560, 612, + 71, 368, 443, 402, 368, 572, 247, 822, 514, 248, + 249, 897, 87, 301, 454, 218, -108, 87, 316, 466, + 621, 448, 608, 913, 915, 449, 777, 608, 266, 919, + 921, -111, 873, 271, 794, 940, 472, 271, 247, 251, + 513, 248, 249, 568, 569, 570, 571, 462, 519, 476, + 218, 42, -103, 266, 43, 913, 915, 525, 919, 921, + 621, 621, 481, 662, -105, 513, 662, 125, 485, 250, + 266, 251, 487, 692, 492, 218, 501, 87, 218, 266, + 910, 655, 513, 664, 810, 907, -110, 662, 87, 722, + 663, 513, 218, -108, 418, 505, 87, 960, 59, 777, + 858, 218, 418, 853, 662, 1002, 87, -102, 811, 553, + 777, 736, 725, 662, 663, 521, 851, 717, 899, 504, + 504, 744, 728, 543, 427, 428, 429, 731, 812, 106, + 519, 663, 246, 528, 917, 985, 544, -106, 247, 87, + 663, 248, 249, 850, 266, 925, 911, -76, 87, 206, + 970, 971, 507, 662, 811, 614, 513, -108, 985, 534, + 582, 614, 316, -105, 316, 542, 218, 614, 614, 379, + 379, 251, 540, 71, 87, 726, 354, 355, 662, 767, + 663, 546, 741, -106, 803, 451, 452, 519, 543, 271, + 951, 565, -108, 566, 1029, -108, -108, 1032, 785, 834, + 831, 218, 912, 577, -98, 663, 583, 743, 918, 920, + -501, 125, 792, 125, 271, 586, 379, 379, 812, 471, + 218, 965, 966, -108, 589, -108, 471, 804, 590, 316, + -303, 271, 853, 453, 453, 593, 105, 598, 105, 596, + 271, 599, 601, 105, 105, -303, 597, -108, 600, 105, + 105, 105, 602, 637, 105, 613, 989, 703, 808, 675, + 271, 689, 917, 494, 271, 690, 504, 814, -100, 693, + 816, 694, 281, 614, 1073, 281, 792, 792, 125, -343, + -303, 948, -590, 1051, -593, 696, 105, -303, 537, 554, + 718, -105, 271, 281, -343, 271, 218, 87, 830, 833, + 105, 730, 735, 833, 847, 271, 738, -91, 379, 379, + 833, 807, -97, 753, 984, 608, 766, 206, 797, 685, + 277, 1063, 799, 277, 769, 246, 787, 826, 798, -343, + 218, 995, 824, -596, 504, 809, -343, 997, 823, 807, + 553, 277, 206, 831, 923, 247, -485, 839, 248, 249, + 616, 105, 494, 105, 845, 297, 616, 914, 848, 849, + 856, -485, 616, 616, 859, 871, 578, 865, 430, 763, + 519, 869, 821, 575, 543, 875, 250, 773, 251, 877, + 879, 588, 881, 431, 592, 884, 780, 212, 212, 784, + 889, 930, 931, 212, -590, 935, -485, -596, 266, 939, + -590, 941, 949, -485, 855, 954, 846, 969, 87, 972, + 513, 979, -596, 975, 379, 316, 87, 621, 432, 977, + 218, 981, 297, 621, 218, 433, 987, 792, 986, 621, + 621, 1009, 662, 998, 999, 87, 87, 933, 1008, 247, + 937, 1019, 248, 249, 105, -596, 1015, -596, 1020, 87, + 903, -592, 218, 1021, -596, 1035, 456, 105, 105, 663, + 1036, 87, 87, 504, 125, 379, 501, 1034, 616, 87, + 250, 431, 251, 759, 1043, 357, 358, 359, 360, 1045, + 87, 87, 855, 705, 705, 1047, 217, 217, 1052, 271, + 271, 760, 217, 267, 267, 447, -592, 267, 1054, 588, + 588, 473, 1056, 1058, 1068, 247, 457, 968, 248, 249, + 105, -592, 974, 433, 105, -593, 431, -300, 105, 105, + -300, -300, 105, 1076, 289, 291, 292, 293, 938, 105, + 105, 267, 309, 1078, 494, 621, 250, 105, 251, 227, + -593, 494, 737, 345, 346, 87, 87, -300, -300, 992, + -300, 474, 130, 87, 833, 1039, 125, 1067, 433, 271, + -592, 125, 886, 1069, 866, 334, -293, 271, 328, 329, + 889, 924, 1066, 889, 491, -592, 889, 208, 889, 893, + 892, -293, 105, 105, 105, 105, 105, 105, 105, 105, + 482, 522, 772, 1044, 217, 1023, 1028, 0, 125, 297, + 0, 212, 212, 0, -593, 431, 0, 105, -592, 0, + -592, 0, 0, 87, -592, 87, -293, -592, 87, -593, + 330, 331, 0, -293, 0, 0, 889, 0, 105, 0, + 0, 105, 588, 105, 266, 0, 105, 876, 878, 880, + 483, 882, 0, 883, 0, 379, 513, 433, 692, 833, + 0, 0, -593, 889, -593, 889, 218, 889, -593, 889, + 0, -593, 515, 518, 0, 959, 105, 961, 662, 490, + 0, 962, 248, 249, 523, 0, 105, 105, 0, 889, + 759, 820, 357, 358, 359, 360, 0, 0, 547, 431, + 0, 105, 0, 105, 105, 663, 0, 0, 760, -488, + 217, 217, 297, 431, 105, 271, 247, 0, 105, 248, + 249, 0, 105, 0, -488, 247, 531, 105, 248, 249, + 533, 471, 105, 562, 474, 328, 329, 212, 212, 212, + 212, 433, 573, 574, 0, -292, -304, 801, 548, 497, + 498, 499, 345, 1010, 1011, 433, 950, 0, 251, -488, + -292, -304, 431, 267, 1022, 105, -488, 267, 0, 0, + 1024, 217, 217, 892, 105, 1030, 892, 1033, 892, 431, + 0, 1012, 0, 695, 0, 0, 0, 330, 331, 874, + 0, 702, 105, 1037, 0, -292, -304, 802, 0, 0, + 105, 714, -292, -304, 433, 271, 0, 561, 431, 0, + 328, 329, 1046, 0, 457, 1048, 0, 327, 328, 329, + 0, 433, 338, 328, 329, 0, 892, 105, 1014, 1016, + 1017, 1018, 0, 0, 0, 929, 217, 217, 217, 217, + 0, 217, 217, 1038, 0, 0, 105, 1070, 687, 0, + 433, 0, 1072, 892, 1074, 892, 0, 892, 1075, 892, + 705, 585, 330, 331, 349, 350, 351, 352, 353, 755, + 330, 331, 595, 0, 0, 330, 331, 0, 1082, 892, + 0, 774, 0, 0, 607, 774, 340, 328, 329, 618, + 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, + 633, 634, 635, 636, 0, 638, 639, 640, 641, 642, + 643, 644, 645, 646, 647, 648, 649, 1071, 0, 267, + 0, 0, 105, 105, 554, 328, 329, 0, 0, 671, + 671, 559, 328, 329, 729, 563, 328, 329, 0, 330, + 331, 734, 0, 0, 267, 0, 471, 217, 564, 328, + 329, 0, 471, 740, 0, 0, 105, 0, 0, 671, + 0, 267, 0, 671, 671, 74, 0, 74, 121, 121, + 267, 0, 0, 754, 328, 329, 121, 330, 331, 716, + 0, 0, 719, 720, 330, 331, 0, 721, 330, 331, + 724, 0, 727, 0, 309, 293, 415, 416, 0, 0, + 418, 330, 331, 0, 0, 0, 764, 765, 0, 418, + 0, 0, 671, 0, 0, 74, 0, 976, 978, 121, + 0, 0, 724, 0, 0, 309, 330, 331, 425, 426, + 427, 428, 429, 0, 105, 267, 795, 425, 426, 427, + 428, 429, 105, 105, 0, 121, 105, 0, 0, 105, + 105, 0, 757, 758, 0, 105, 105, 0, 0, 0, + 0, 105, 105, 0, 0, 0, 212, 0, 0, 0, + 768, 0, 0, 0, 0, 105, 0, 0, 105, 0, + 0, 0, 74, 0, 898, 415, 416, 105, 105, 786, + 0, 0, 793, 1027, 0, 105, 0, 0, 418, 759, + 212, 357, 358, 359, 360, 0, 105, 105, 0, 0, + 0, 0, 0, 825, 0, 0, 759, 760, 357, 358, + 359, 360, 0, 422, 423, 424, 425, 426, 427, 428, + 429, 926, 0, 0, 760, 75, 0, 75, 122, 122, + 0, 0, 363, 0, 934, 0, 122, 0, 761, 1053, + 1055, 1057, 0, 1059, 1060, 0, 942, 943, 0, 363, + 0, 105, 0, 0, 946, 217, 0, 0, 857, 0, + 0, 105, 105, 74, 0, 0, 952, 827, 0, 105, + 768, 786, 0, 0, 0, 75, 0, 0, 868, 122, + 0, 415, 416, 1077, 1079, 1080, 1081, 0, 0, 217, + 0, 0, 0, 1083, 418, 0, 0, 0, 0, 0, + 852, 0, 0, 0, 0, 122, 0, 0, 0, 724, + 309, 0, 212, 0, 0, 759, 0, 357, 358, 359, + 360, 424, 425, 426, 427, 428, 429, 0, 0, 105, + 988, 105, 0, 760, 105, 0, 0, 0, 996, 0, + 0, 74, 75, 0, 0, 0, 0, 0, 74, 74, + 0, 0, 0, 0, 774, 0, 74, 898, 363, 0, + 898, 0, 898, 0, 955, 0, 0, 121, 0, 0, + 947, 901, 105, 0, 0, 0, 671, 904, 0, 267, + 0, 0, 671, 671, 0, 0, 956, 724, 671, 671, + 1004, 0, 357, 358, 359, 360, 0, 0, 1040, 0, + 1041, 74, 0, 1042, 0, 0, 74, 0, 760, 0, + 898, 217, 0, 0, 671, 671, 0, 671, 671, 0, + 0, 0, 0, 0, 0, 0, 74, 945, 0, 0, + 0, 293, 0, 75, 0, 0, 0, 898, 0, 898, + 0, 898, 0, 898, 0, 0, 0, 74, 957, 958, + 0, 0, 74, 121, 0, 74, 0, 0, 0, 0, + 0, 963, 964, 898, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 980, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 982, 983, 104, + 0, 104, 128, 128, 671, 74, 74, 0, 0, 0, + 232, 0, 356, 0, 357, 358, 359, 360, 0, 0, + 0, 75, 74, 0, 0, 0, 0, 671, 75, 75, + 361, 0, 0, 74, 0, 309, 75, 0, 0, 0, + 0, 74, 0, 0, 362, 0, 0, 122, 0, 104, + 0, 74, 0, 318, 0, 363, 0, 0, 0, 0, + 0, 364, 365, 366, 367, 0, 0, 0, 0, 0, + 0, 0, 356, 0, 357, 358, 359, 360, 0, 318, + 0, 75, -619, 0, 74, 0, 75, 0, 0, 368, + 361, 0, 369, 74, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 370, 75, 121, 356, 121, + 357, 358, 359, 360, 0, 363, 104, 0, 0, 74, + 0, 364, 365, 366, 367, 267, 361, 75, -619, 0, + 0, 0, 75, 122, 0, 75, 0, 0, 0, 0, + 362, -619, -619, -619, -619, -619, -619, 0, -619, 368, + 0, 363, 369, 0, -619, -619, 0, 364, 365, 366, + 367, 0, 0, 1025, 0, -619, -619, 0, -619, -619, + -619, -619, -619, 0, 121, 75, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 368, 0, 0, 369, 0, + 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 0, 370, 0, 75, 0, 0, 0, 104, 0, 0, + 0, 75, 0, 0, 0, 84, 0, 84, -619, 0, + 0, 75, 0, 0, 0, 0, 228, 0, 0, 0, + 0, 0, 0, -619, 0, 0, 0, 0, 0, 0, + 0, 0, 74, -619, 0, 0, -619, -619, 0, 0, + 0, 0, 0, 356, 75, 357, 358, 359, 360, 0, + 0, 0, 0, 75, 0, 84, -619, -619, 0, 0, + 0, 361, 276, -619, -619, -619, -619, 122, 0, 122, + 0, 0, 0, 0, 0, 104, 0, 0, 0, 75, + 0, 0, 104, 104, 0, 0, 363, 0, 0, 0, + 104, 0, 364, 365, 366, 367, 0, 0, 0, 0, + 0, 318, 0, 783, 0, 357, 358, 359, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 121, 0, 121, 0, 0, 0, 0, - 0, 122, 0, 0, 0, 74, 0, 0, 0, 0, - 0, 0, 0, 0, 895, 0, 0, 0, 0, 668, - 898, 0, 266, 0, 0, 668, 668, 0, 0, 0, - 720, 668, 668, 0, 0, 0, 0, 0, 75, 0, - 0, 0, 0, 0, 355, 0, 356, 357, 358, 359, - 0, 0, 0, 0, 217, 0, 0, 668, 668, 121, - 668, 668, 360, 0, 0, 0, 0, 0, 0, 0, - 939, 0, 0, 0, 292, 0, 0, 0, 577, 0, - 0, 0, 0, 0, 0, 0, 104, 362, 104, 128, - 128, 951, 952, 363, 364, 365, 366, 232, 0, 0, - 0, 0, 0, 0, 957, 958, 0, 0, 0, 0, - 0, 0, 0, 794, 0, 0, 0, 0, 0, 0, - 974, 367, 0, 0, 368, 0, 0, 74, 0, 75, - 976, 977, 0, 0, 0, 0, 104, 668, 0, 0, - 317, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, 0, 0, 0, 0, 414, 415, 0, - 668, 0, 0, 0, 0, 0, 317, 0, 308, 0, - 417, 0, 0, 0, 355, 0, 356, 357, 358, 359, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 418, 360, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 104, 0, 0, 75, 0, 769, 0, - 0, -277, 0, 75, 75, 0, 0, 362, 0, 0, - 0, 75, 0, 363, 364, 365, 366, 0, 0, 0, - 0, 0, 122, 0, 355, 74, 356, 357, 358, 359, - 0, 0, 121, 74, 74, 0, 0, 0, 0, 0, - 74, 367, 360, 0, 368, 0, 74, 74, 266, 0, - 0, 0, 74, 74, 0, 0, 75, 0, 864, 0, - 0, 75, 0, 0, 0, 0, 74, 362, 0, 0, - 0, 0, 0, 363, 364, 365, 366, 0, 74, 74, - 0, 75, 0, 0, 104, 0, 74, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 74, 74, 0, - 0, 367, 75, 0, 368, 0, 0, 75, 122, 0, - 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 121, 0, 0, 0, 0, 121, - 355, 0, 356, 357, 358, 359, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 360, 0, - 75, 75, 74, 0, 0, 0, 0, 0, 0, 0, - 0, 104, 74, 74, 0, 0, 121, 75, 104, 104, - 74, 0, 0, 362, 0, 0, 104, 0, 75, 363, - 364, 365, 366, 0, 0, 0, 75, 317, 0, 0, - 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 367, 0, 0, - 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 104, 0, 0, 0, 0, 104, 0, 75, 0, - 74, 0, 74, 0, 0, 74, 0, 75, 0, 0, - 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, - 0, 122, 0, 122, 0, 0, 0, 0, 0, 0, + 368, 361, 84, 369, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 122, 104, 550, 0, 0, 0, + 104, 0, 0, 74, 0, 0, 363, 0, 0, 0, + 121, 74, 74, 365, 366, 367, 0, 0, 74, 0, + 104, 0, 0, 0, 74, 74, 0, 0, 0, 0, + 74, 74, 0, 0, 356, 0, 357, 358, 359, 360, + 368, 104, 0, 0, 74, 0, 104, 318, 0, 622, + 0, 0, 361, 0, 0, 0, 74, 74, 0, 0, + 0, 0, 75, 0, 74, 0, 0, 0, 580, 0, + 0, 0, 0, 84, 0, 74, 74, 363, 0, 0, + 0, 0, 0, 364, 365, 366, 367, 0, 0, 622, + 622, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 121, 0, 0, 0, 104, 121, 0, 0, + 0, 368, 0, 0, 369, 0, 0, 104, 0, 0, + 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, + 74, 0, 0, 0, 0, 104, 0, 0, 0, 0, + 74, 74, 0, 0, 121, 0, 0, 0, 74, 0, + 0, 84, 0, 0, 0, 0, 0, 0, 84, 84, + 0, 0, 0, 0, 0, 0, 84, 0, 104, 0, 0, 0, 0, 75, 0, 0, 0, 104, 0, 0, - 0, 0, 104, 317, 0, 619, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 101, 0, 101, 127, 127, 127, 0, 0, 647, - 648, 0, 231, 649, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 619, 619, 122, 174, 175, - 176, 177, 178, 179, 180, 181, 0, 0, 182, 183, - 0, 0, 104, 0, 184, 185, 186, 187, 0, 0, - 0, 101, 0, 104, 0, 316, 0, 0, 188, 189, - 190, 104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 316, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 0, 201, 202, 75, 0, 0, 0, 0, - 0, 203, 275, 104, 0, 0, 0, 0, 0, 0, - 0, 0, 104, 794, 0, 0, 0, 0, 101, 0, - 0, 0, 0, 0, 0, 0, 317, 0, 317, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, - 0, 402, 403, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, 0, 0, 0, 0, 414, 415, 0, - 0, 0, 0, 0, 0, 0, 84, 0, 84, 0, - 417, 0, 0, 0, 0, 0, 0, 228, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 418, 317, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 75, 0, 0, 0, 0, 0, 101, - 122, 75, 75, 0, 0, 0, 84, 0, 75, 0, - 0, 0, 0, 0, 75, 75, 0, 0, 0, 0, - 75, 75, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 75, 75, 0, 0, - 104, 0, 0, 0, 75, 0, 0, 102, 0, 102, - 0, 0, 0, 0, 0, 75, 75, 0, 0, 0, + 122, 75, 75, 0, 0, 0, 0, 0, 75, 0, + 0, 318, 0, 318, 75, 75, 0, 0, 0, 0, + 75, 75, 0, 104, 0, 0, 0, 0, 74, 0, + 74, 84, 0, 74, 75, 0, 84, 0, 0, 101, + 0, 101, 127, 127, 127, 0, 75, 75, 0, 0, + 231, 0, 0, 0, 75, 356, 84, 357, 358, 359, + 360, 0, 0, 0, 0, 75, 75, 0, 0, 0, + 0, 0, 0, 361, 0, 0, 0, 84, 318, 0, + 0, 0, 84, 0, 0, 617, 0, 0, 0, 101, + 0, 0, 122, 317, 0, 0, 0, 122, 363, 0, + 0, 0, 0, 0, 364, 365, 366, 367, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, + 75, 0, 0, 0, 0, 617, 617, 0, 0, 0, + 75, 75, 368, 0, 122, 369, 0, 0, 75, 0, + 0, 0, 84, 0, 800, 0, 104, 0, 0, 0, 0, 0, 0, 84, 0, 0, 101, 0, 0, 0, - 0, 0, 0, 101, 101, 0, 0, 0, 0, 0, - 0, 101, 122, 0, 0, 0, 0, 122, 0, 0, - 0, 0, 316, 0, 0, 0, 0, 102, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 75, 75, 0, 0, 122, 0, 101, 0, 75, 0, - 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 415, 416, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, + 75, 418, 0, 75, 84, 0, 0, 0, 0, 0, + 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, + 0, 0, 419, 0, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 0, 0, 0, 0, 0, 84, + 0, 0, -277, 0, 0, 0, 0, 101, 0, 0, + 102, 0, 102, 0, 0, 0, 0, 104, 0, 0, + 0, 0, 0, 0, 318, 104, 622, 0, 0, 0, + 0, 0, 622, 0, 0, 0, 0, 0, 622, 622, + 0, 0, 0, 0, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, - 0, 101, 0, 0, 84, 317, 104, 619, 0, 0, - 0, 0, 0, 619, 102, 0, 0, 0, 0, 619, - 619, 0, 101, 0, 0, 104, 104, 101, 316, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 75, 104, - 75, 0, 0, 75, 0, 0, 0, 0, 0, 0, - 0, 104, 104, 0, 0, 0, 0, 0, 0, 104, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 84, 0, 0, 0, 0, 0, 101, 84, 84, - 0, 0, 0, 0, 0, 0, 84, 128, 101, 0, - 0, 0, 128, 0, 0, 102, 101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, - 0, 0, 0, 0, 0, 619, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 104, 104, 0, 0, 988, - 0, 84, 0, 104, 0, 0, 84, 0, 101, 0, - 0, 0, 0, 0, 0, 0, 0, 101, 0, 402, - 403, 404, 405, 406, 407, 408, 84, 410, 411, 0, - 0, 316, 0, 316, 0, 414, 415, 0, 0, 0, - 0, 0, 102, 101, 0, 0, 0, 84, 417, 102, - 102, 0, 84, 0, 0, 614, 0, 102, 0, 0, - 0, 0, 0, 104, 0, 104, 0, 0, 104, 0, - 0, 419, 420, 421, 422, 423, 424, 425, 426, 427, - 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 614, 614, 316, 0, 0, - 0, 0, 102, 0, 0, 0, 0, 102, 0, 0, - 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 84, 0, 0, 0, 102, 0, 0, - 0, 84, 0, 0, -614, -614, -614, -614, 406, 407, - 0, 84, -614, -614, 0, 0, 0, 0, 102, 0, - 414, 415, 0, 102, 0, 0, 102, 0, 0, 0, - 0, 0, 0, 417, 0, 101, 0, 0, 0, 0, + 102, 0, 0, 356, 0, 357, 358, 359, 360, 0, + 104, 104, 0, 0, 0, 0, 0, 0, 104, 0, + 0, 361, 0, 0, 0, 101, 0, 0, 0, 104, + 104, 0, 101, 101, 0, 0, 0, 775, 0, 0, + 101, 0, 0, 0, 0, 0, 363, 0, 0, 0, + 0, 317, 364, 365, 366, 367, 128, 0, 0, 0, + 0, 128, 84, 0, 0, 0, 0, 102, 0, 356, + 0, 357, 358, 359, 360, 0, 0, 0, 0, 0, + 368, 0, 0, 369, 622, 101, 0, 361, 0, 0, + 101, 0, 0, 0, 104, 104, 0, 0, 994, 0, + 0, 0, 104, 870, 0, 0, 0, 0, 0, 0, + 101, 0, 363, 0, 0, 0, 0, 0, 364, 365, + 366, 367, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 0, 0, 0, 101, 317, 0, 0, + 0, 0, 0, 0, 0, 0, 368, 0, 0, 369, + 0, 0, 0, 0, 0, 0, 0, 0, 102, 0, + 0, 0, 104, 0, 104, 0, 0, 104, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, - 0, 0, 84, 0, 0, 0, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 102, 102, 0, 0, + 0, 84, 617, 0, 0, 0, 0, 0, 617, 0, + 0, 0, 0, 0, 617, 617, 101, 0, 0, 0, + 84, 84, 0, 0, 0, 0, 0, 101, 0, 0, + 0, 0, 0, 0, 84, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 84, 84, 0, 0, + 0, 0, 0, 0, 84, 0, 102, 0, 0, 0, + 0, 0, 0, 102, 102, 84, 84, 0, 0, 0, + 0, 102, 0, 0, 0, 0, 0, 0, 101, 0, + 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, + 403, 404, 405, 406, 407, 408, 409, 0, 411, 412, + 0, 317, 0, 317, 0, 0, 415, 416, 0, 0, + 0, 0, 0, 101, 0, 0, 102, 0, 0, 418, + 617, 102, 0, 0, 0, 0, 0, 0, 0, 0, + 84, 84, 0, 0, 991, 0, 0, 0, 84, 0, + -596, 102, 420, 421, 422, 423, 424, 425, 426, 427, + 428, 429, 0, -596, -596, -596, 0, -596, -596, 0, + -596, 0, 102, 0, 0, 0, -596, 102, 317, 0, + 102, 0, 0, 0, 0, 0, 0, -596, -596, 0, + -596, -596, -596, -596, -596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, - 0, 0, 0, 102, 656, 657, 0, 0, 658, 0, - 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, - 0, 0, 102, 174, 175, 176, 177, 178, 179, 180, - 181, 0, 102, 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, 101, 102, 0, 0, 0, 0, 0, - 316, 101, 0, 102, 0, 0, 0, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 0, 201, 202, - 101, 101, 0, 0, 0, 0, 203, 275, 0, 102, - 0, 0, 0, 0, 101, 0, 0, 0, 0, 866, - 0, 0, 0, 0, 0, 0, 101, 101, 0, 0, - 84, 0, 0, 0, 101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 101, 101, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 0, - 0, 0, 0, 414, 415, 0, 0, 0, 0, 0, - 0, 0, 127, 0, 0, 0, 417, 127, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 418, 0, 419, - 420, 421, 422, 423, 424, 425, 426, 427, 428, 0, - 101, 101, 0, 0, 987, 0, 0, 0, 101, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 102, 0, 0, 0, 0, 0, 0, 84, 0, - 0, 0, 0, 0, 0, 0, 84, 614, 0, 0, - 0, 0, 0, 614, 0, 0, 0, 0, 0, 614, - 614, 0, 0, 0, 0, 84, 84, 0, 402, 403, - 404, 405, 406, 407, 0, 0, 410, 411, 101, 84, - 101, 0, 0, 101, 414, 415, 0, 0, 0, 0, - 0, 84, 84, 0, 0, 0, 0, 417, 0, 84, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 84, 84, 0, 0, 0, 0, 0, 0, 0, 0, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 0, 0, 0, 0, 0, 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, 614, 102, 102, 0, 0, - 0, 0, 0, 0, 0, 84, 84, 0, 0, 985, - 102, 0, 0, 84, 0, 0, 0, 0, 0, 0, - 0, 0, 102, 102, 0, 0, 0, 0, 0, 0, - 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 102, 102, 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, 0, 84, 0, 84, 0, 0, 84, 0, + 84, 0, 0, 84, 0, 0, 0, 0, 0, 0, + 102, 102, -596, -596, -596, -596, -596, -596, -596, -596, + -596, -596, -596, -596, 0, 0, 0, 102, -596, -596, + -596, 0, 805, -596, 0, 0, 101, 0, 102, 0, + 0, -596, 0, 0, 0, -596, 102, 0, 0, 0, + 0, 0, 0, 0, 0, -596, 102, 0, -596, -596, + 0, -107, -596, 0, -596, -596, -596, -596, -596, -596, + -596, -596, -596, -596, 0, 0, 0, 0, -596, -596, + -596, 800, -99, 0, 0, -596, -596, -596, -596, 102, + 0, 0, 0, 0, 0, 0, 0, 0, 102, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 0, 0, 0, 102, 415, 416, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, + 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, + 0, 0, 0, 0, 317, 101, 0, 0, 0, 419, + 0, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 0, 0, 0, 101, 101, 0, 0, 0, 0, + 0, 0, -620, -620, -620, -620, 407, 408, 101, -596, + -620, -620, 0, 0, 0, 0, 0, 0, 415, 416, + 101, 101, -596, -596, -596, 0, -596, -596, 101, -596, + 0, 418, 0, 0, 0, -596, 0, 0, 0, 101, + 101, 0, 0, 0, 0, 0, -596, -596, 0, -596, + -596, -596, -596, -596, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 0, 0, 127, 102, 0, 0, + 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -596, -596, -596, -596, -596, -596, -596, -596, -596, + -596, -596, -596, 0, 0, 0, 0, -596, -596, -596, + 0, 805, -596, 0, 101, 101, 0, 0, 993, 0, + -596, 0, 101, 0, -596, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -596, 0, 0, -596, -596, 0, + -107, -596, 0, -596, -596, -596, -596, -596, -596, -596, + -596, -596, -596, 0, 0, 0, 0, -596, -596, -596, + 0, -596, 0, 0, -596, -596, -596, -596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 102, 0, 0, 0, + 0, 0, 101, 0, 101, 0, 0, 101, 102, 0, 0, 0, 0, 0, 0, 0, 102, 102, 0, 0, - 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -613, 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, 650, 651, 102, 0, 652, 0, 0, 0, 102, + 102, 0, 0, 0, 0, 102, 102, 0, 0, 0, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 102, + 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, + 0, 102, 102, 0, 0, 0, 0, 0, 0, 102, + 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, + 102, 102, 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, 403, 404, 405, + 406, 407, 408, 203, 276, 411, 412, 0, 0, 0, + 0, 0, 0, 415, 416, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 102, 418, 0, 0, 0, + 0, 0, 0, 0, 0, 102, 102, 0, 0, 0, + 0, 0, 0, 102, 0, 0, 0, 0, 0, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 0, + 0, 0, 0, 0, 0, -619, 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, -294, 64, + -619, 0, 0, -619, -619, 0, 0, 0, 0, 0, + 0, -294, -294, -294, -294, -294, -294, 0, -294, 65, + 66, 67, 0, 0, 0, -294, -294, -294, 0, 0, + 0, -619, 0, -619, 0, -294, -294, 0, -294, -294, + -294, -294, -294, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -294, 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, -292, - 64, -613, 0, 0, -613, -613, 0, 0, 0, 0, - 0, 0, -292, -292, -292, -292, -292, -292, 0, -292, - 65, 66, 67, 0, 0, 0, -292, -292, -292, 0, - 0, 0, -613, 0, -613, 0, -292, -292, 0, -292, - -292, -292, -292, -292, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -292, 0, 0, 0, + -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, + -294, -294, 0, 0, 0, 0, -294, -294, -294, 0, + 0, -294, 0, 0, 0, 0, 0, -294, 0, -294, + 0, 0, 0, -294, 0, 0, 0, 0, 0, 0, + 0, -294, 0, -294, 0, 0, -294, -294, 0, 0, + -294, -294, -294, -294, -294, -294, -294, -294, -294, -294, + -294, -294, 0, 0, -415, 0, 0, -294, -294, -294, + -294, 0, 0, -294, -294, -294, -294, -415, -415, -415, + -415, -415, -415, 0, -415, 0, 0, 0, 0, 0, + -415, -415, -415, 0, 0, 0, 0, 0, 0, 0, + 0, -415, -415, 0, -415, -415, -415, -415, -415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -292, -292, -292, -292, -292, -292, -292, -292, -292, - -292, -292, -292, 0, 0, 0, 0, -292, -292, -292, - 0, 0, -292, 0, 0, 0, 0, 0, -292, 0, - -292, 0, 0, 0, -292, 0, 0, 0, 0, 0, - 0, 0, -292, 0, -292, 0, 0, -292, -292, 0, - 0, -292, -292, -292, -292, -292, -292, -292, -292, -292, - -292, -292, -292, 0, 0, -413, 0, 0, -292, -292, - -292, -292, 0, 0, -292, -292, -292, -292, -413, -413, - -413, -413, -413, -413, 0, -413, 0, 0, 0, 0, - 0, -413, -413, -413, 0, 0, 0, 0, 0, 0, - 0, 0, -413, -413, 0, -413, -413, -413, -413, -413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -415, -415, -415, -415, + -415, -415, -415, -415, -415, -415, -415, -415, 0, 0, + 0, 0, -415, -415, -415, 0, 0, -415, 0, 0, + 0, 0, 0, -415, 0, -415, 0, 0, 0, -415, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -415, + 0, 0, -415, -415, 0, 0, -415, 0, -415, -415, + -415, -415, -415, -415, -415, -415, -415, -415, 0, 0, + -481, 0, -415, -415, -415, -415, -415, 0, 276, -415, + -415, -415, -415, -481, -481, -481, -481, -481, -481, 0, + -481, 0, 0, 0, 0, 0, 0, -481, -481, 0, + 0, 0, 0, 0, 0, 0, 0, -481, -481, 0, + -481, -481, -481, -481, -481, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -413, -413, -413, - -413, -413, -413, -413, -413, -413, -413, -413, -413, 0, - 0, 0, 0, -413, -413, -413, 0, 0, -413, 0, - 0, 0, 0, 0, -413, 0, -413, 0, 0, 0, - -413, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -413, 0, 0, -413, -413, 0, 0, -413, 0, -413, - -413, -413, -413, -413, -413, -413, -413, -413, -413, 0, - 0, -479, 0, -413, -413, -413, -413, -413, 0, 275, - -413, -413, -413, -413, -479, -479, -479, -479, -479, -479, - 0, -479, 0, 0, 0, 0, 0, 0, -479, -479, - 0, 0, 0, 0, 0, 0, 0, 0, -479, -479, - 0, -479, -479, -479, -479, -479, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 494, 0, + 0, 0, -481, -481, -481, -481, -481, -481, -481, -481, + -481, -481, -481, -481, 0, 0, 0, 0, -481, -481, + -481, 0, -481, -481, 0, 0, 0, 0, 0, -481, + 0, -481, 0, 0, 0, -481, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -481, 0, 0, -481, -481, + 0, -481, -481, 0, -481, -481, -481, -481, -481, -481, + -481, -481, -481, -481, 0, 0, -619, 0, 0, -481, + -481, -481, -481, 0, 0, -481, -481, -481, -481, -619, + -619, -619, -619, -619, -619, 0, -619, 0, 0, 0, + 0, 0, -619, -619, -619, 0, 0, 0, 0, 0, + 0, 0, 0, -619, -619, 0, -619, -619, -619, -619, + -619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -479, -479, -479, -479, -479, -479, -479, - -479, -479, -479, -479, -479, 0, 0, 0, 0, -479, - -479, -479, 0, -479, -479, 0, 0, 0, 0, 0, - -479, 0, -479, 0, 0, 0, -479, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -479, 0, 0, -479, - -479, 0, -479, -479, 0, -479, -479, -479, -479, -479, - -479, -479, -479, -479, -479, 0, 0, -613, 0, 0, - -479, -479, -479, -479, 0, 0, -479, -479, -479, -479, - -613, -613, -613, -613, -613, -613, 0, -613, 0, 0, - 0, 0, 0, -613, -613, -613, 0, 0, 0, 0, - 0, 0, 0, 0, -613, -613, 0, -613, -613, -613, - -613, -613, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -619, -619, + -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, + 0, 0, 0, 0, -619, -619, -619, 0, 0, -619, + 0, 0, 0, 0, 0, -619, 0, -619, 0, 0, + 0, -619, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -619, 0, 0, -619, -619, 0, 0, -619, 0, + -619, -619, -619, -619, -619, -619, -619, -619, -619, -619, + 0, 0, -619, 0, -619, -619, -619, -619, -619, 0, + 276, -619, -619, -619, -619, -619, -619, -619, -619, -619, + -619, 0, -619, 0, 0, 0, 0, 0, 0, -619, + -619, 0, 0, 0, 0, 0, 0, 0, 0, -619, + -619, 0, -619, -619, -619, -619, -619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -613, - -613, -613, -613, -613, -613, -613, -613, -613, -613, -613, - -613, 0, 0, 0, 0, -613, -613, -613, 0, 0, - -613, 0, 0, 0, 0, 0, -613, 0, -613, 0, - 0, 0, -613, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -613, 0, 0, -613, -613, 0, 0, -613, - 0, -613, -613, -613, -613, -613, -613, -613, -613, -613, - -613, 0, 0, -613, 0, -613, -613, -613, -613, -613, - 0, 275, -613, -613, -613, -613, -613, -613, -613, -613, - -613, -613, 0, -613, 0, 0, 0, 0, 0, 0, - -613, -613, 0, 0, 0, 0, 0, 0, 0, 0, - -613, -613, 0, -613, -613, -613, -613, -613, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -619, -619, -619, -619, -619, -619, + -619, -619, -619, -619, -619, -619, 0, 0, 0, 0, + -619, -619, -619, 0, 0, -619, 0, 0, 0, 0, + 0, -619, 0, -619, 0, 0, 0, -619, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -619, 0, 0, + -619, -619, 0, 0, -619, 0, -619, -619, -619, -619, + -619, -619, -619, -619, -619, -619, 0, 0, -303, 0, + 0, -619, -619, -619, -619, 0, 276, -619, -619, -619, + -619, -303, -303, -303, 0, -303, -303, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -613, -613, -613, -613, -613, - -613, -613, -613, -613, -613, -613, -613, 0, 0, 0, - 0, -613, -613, -613, 0, 0, -613, 0, 0, 0, - 0, 0, -613, 0, -613, 0, 0, 0, -613, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -613, 0, - 0, -613, -613, 0, 0, -613, 0, -613, -613, -613, - -613, -613, -613, -613, -613, -613, -613, 0, 0, -590, - 0, 0, -613, -613, -613, -613, 0, 275, -613, -613, - -613, -613, -590, -590, -590, 0, -590, -590, 0, -590, - 0, 0, 0, 0, 0, -590, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -590, -590, 0, -590, - -590, -590, -590, -590, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -303, -303, 0, -303, -303, + -303, -303, -303, 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, -590, -590, -590, -590, -590, -590, -590, -590, -590, - -590, -590, -590, 0, 0, 0, 0, -590, -590, -590, - 0, 799, -590, 0, 0, 0, 0, 0, 0, 0, - -590, 0, 0, 0, -590, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -590, 0, 0, -590, -590, 0, - -107, -590, 0, -590, -590, -590, -590, -590, -590, -590, - -590, -590, -590, 0, 0, -590, 0, -590, -590, -590, - 0, -99, 0, 0, -590, -590, -590, -590, -590, -590, - -590, 0, -590, -590, 0, -590, 0, 0, 0, 0, - 0, -590, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -590, -590, 0, -590, -590, -590, -590, -590, + -303, -303, -303, -303, -303, -303, -303, -303, -303, -303, + -303, -303, 0, 0, 0, 0, -303, -303, -303, 0, + 806, -303, 0, 0, 0, 0, 0, 0, 0, -303, + 0, 0, 0, -303, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -303, 0, 0, -303, -303, 0, -109, + -303, 0, -303, -303, -303, -303, -303, -303, -303, -303, + -303, -303, 0, 0, -303, 0, 0, -303, -303, 0, + -101, 0, 0, -303, -303, -303, -303, -303, -303, -303, + 0, -303, -303, 0, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -303, -303, 0, -303, -303, -303, -303, -303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -590, -590, -590, - -590, -590, -590, -590, -590, -590, -590, -590, -590, 0, - 0, 0, 0, -590, -590, -590, 0, 799, -590, 0, - 0, 0, 0, 0, 0, 0, -590, 0, 0, 0, - -590, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -590, 0, 0, -590, -590, 0, -107, -590, 0, -590, - -590, -590, -590, -590, -590, -590, -590, -590, -590, 0, - 0, -301, 0, -590, -590, -590, 0, -590, 0, 0, - -590, -590, -590, -590, -301, -301, -301, 0, -301, -301, - 0, -301, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -301, -301, - 0, -301, -301, -301, -301, -301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -303, -303, -303, -303, + -303, -303, -303, -303, -303, -303, -303, -303, 0, 0, + 0, 0, -303, -303, -303, 0, 806, -303, 0, 0, + 0, 0, 0, 0, 0, -303, 0, 0, 0, -303, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -303, + 0, 0, -303, -303, 0, -109, -303, 0, -303, -303, + -303, -303, -303, -303, -303, -303, -303, -303, 0, 0, + 0, 0, 0, -303, -303, 0, -303, 0, 0, -303, + -303, -303, -303, 295, 0, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, -619, -619, -619, 0, 0, + -619, 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, -619, 0, 0, + -619, -619, 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, -619, 295, + -619, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 0, 0, -619, 0, -619, -619, 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, 0, -301, -301, -301, -301, -301, -301, -301, - -301, -301, -301, -301, -301, 0, 0, 0, 0, -301, - -301, -301, 0, 800, -301, 0, 0, 0, 0, 0, - 0, 0, -301, 0, 0, 0, -301, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -301, 0, 0, -301, - -301, 0, -109, -301, 0, -301, -301, -301, -301, -301, - -301, -301, -301, -301, -301, 0, 0, -301, 0, 0, - -301, -301, 0, -101, 0, 0, -301, -301, -301, -301, - -301, -301, -301, 0, -301, -301, 0, -301, 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, -619, 0, 0, -619, -619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -301, -301, 0, -301, -301, -301, - -301, -301, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 66, 67, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -619, 295, -619, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 0, 0, -619, + 0, 0, -619, 15, -619, 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, -619, + 0, 0, -619, -619, 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, + -619, 295, -619, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 0, 0, -619, 0, 0, -619, 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, -619, 0, 0, -619, -619, + 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, -619, 0, -619, 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, -619, 0, 0, -619, -619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -301, - -301, -301, -301, -301, -301, -301, -301, -301, -301, -301, - -301, 0, 0, 0, 0, -301, -301, -301, 0, 800, - -301, 0, 0, 0, 0, 0, 0, 0, -301, 0, - 0, 0, -301, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -301, 0, 0, -301, -301, 0, -109, -301, - 0, -301, -301, -301, -301, -301, -301, -301, -301, -301, - -301, 0, 0, 0, 0, 0, -301, -301, 0, -301, - 0, 0, -301, -301, -301, -301, 294, 0, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, -613, -613, - -613, 0, 0, -613, 15, 0, 16, 17, 18, 19, + 0, 0, 0, 65, 66, 67, 0, 0, -619, 0, + 0, 0, 0, 0, 0, -619, 295, -619, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 0, -619, + -619, 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, @@ -3025,42 +3408,22 @@ static const yytype_int16 yytable[] = 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, - -613, 0, 0, -613, -613, 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, -613, 294, -613, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 0, 0, -613, 0, -613, -613, - 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, -613, 0, 0, -613, - -613, 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, -613, 294, -613, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 0, 0, -613, 0, 0, -613, 15, -613, 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, -613, 0, 0, -613, -613, 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, -613, 294, -613, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 0, 0, -613, 0, - 0, -613, 15, 0, 16, 17, 18, 19, 0, 0, - 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, + -619, 0, 0, -619, -619, 295, 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, -619, 0, -619, 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, 296, 53, + 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, + 58, 59, 60, 0, 61, 62, 63, 0, 64, -619, + 0, 0, -619, -619, 295, 0, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 0, 0, 65, 66, + 67, 0, 15, 0, 16, 17, 18, 19, 0, -619, + -619, 0, -619, 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, @@ -3068,24 +3431,24 @@ static const yytype_int16 yytable[] = 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, -613, 0, - 0, -613, -613, 4, 0, 5, 6, 7, 8, 9, + 59, 60, 0, 61, 62, 63, 0, 64, -619, 0, + 0, -619, -619, 295, 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, -613, - 0, -613, 20, 21, 22, 23, 24, 25, 26, 0, - 0, 27, 0, 0, 0, 0, 0, 28, 29, 30, + 0, 15, 0, 16, 17, 18, 19, 0, -619, -619, + 0, -619, 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, -613, 0, 0, - -613, -613, 0, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 61, 62, 63, 0, 64, -619, 0, 0, + -619, -619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 66, 67, 0, - 0, -613, 0, 0, 0, 0, 0, 0, -613, 294, - -613, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 0, -613, -613, 0, 0, 0, 15, 0, 16, + 0, -619, 0, 0, 0, 0, 0, 0, -619, 295, + -619, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 0, 0, -619, 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, @@ -3095,22 +3458,22 @@ static const yytype_int16 yytable[] = 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, -613, 0, 0, -613, -613, 294, 0, + 63, 0, 64, -619, 0, 0, -619, -619, 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, -613, 0, -613, 20, 21, 22, + 18, 19, 0, 0, -619, 0, -619, 20, 21, 22, 23, 24, 25, 26, 0, 0, 27, 0, 0, 0, - 0, 0, 28, 0, 30, 31, 32, 33, 34, 35, + 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, 295, 53, 0, 54, 55, 0, 56, 0, 0, + 0, 52, 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, 0, 58, 59, 60, 0, 61, 62, 63, - 0, 64, -613, 0, 0, -613, -613, 294, 0, 5, + 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, -613, -613, 0, -613, 20, 21, 22, 23, + 19, 0, 0, 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, @@ -3119,48 +3482,229 @@ static const yytype_int16 yytable[] = 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, -613, 0, 0, -613, -613, 294, 0, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 0, 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, 16, 17, 18, 19, - 0, -613, -613, 0, -613, 20, 21, 22, 23, 24, + 0, 0, 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, + 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, 51, 0, 0, 52, - 53, 0, 54, 55, 0, 56, 0, 0, 0, 57, + 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, - -613, 0, 0, -613, -613, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, - 66, 67, 0, 0, -613, 0, 0, 0, 0, 0, - 0, -613, 294, -613, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 0, 0, -613, 0, 0, 0, - 15, 0, 16, 17, 18, 19, 0, 0, 0, 0, + 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, 265, + 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, 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, 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, -589, -589, -589, -589, -589, -589, + -589, -589, -589, 0, 0, 0, 0, 0, 0, 0, + -589, 0, -589, -589, -589, -589, 0, -589, 0, 0, + 0, -589, -589, -589, -589, -589, -589, -589, 0, 0, + -589, 0, 0, 0, 0, 0, 0, 0, 0, -589, + -589, -589, -589, -589, -589, -589, -589, -589, 0, -589, + -589, -589, 0, 0, -589, 0, 0, -589, -589, 0, + -589, -589, -589, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -589, -589, 0, 0, 0, + 0, 0, -589, 0, 0, -589, -589, 0, -589, -589, + 0, -589, 0, -589, -589, -589, 0, -589, -589, -589, + 0, -589, -589, -589, 0, -589, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -589, -589, -589, 0, -589, + 0, 0, 0, 0, 0, -589, -590, -590, -590, -590, + -590, -590, -590, -590, -590, 0, 0, 0, 0, 0, + 0, 0, -590, 0, -590, -590, -590, -590, 0, -590, + 0, 0, 0, -590, -590, -590, -590, -590, -590, -590, + 0, 0, -590, 0, 0, 0, 0, 0, 0, 0, + 0, -590, -590, -590, -590, -590, -590, -590, -590, -590, + 0, -590, -590, -590, 0, 0, -590, 0, 0, -590, + -590, 0, -590, -590, -590, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -590, -590, 0, + 0, 0, 0, 0, -590, 0, 0, -590, -590, 0, + -590, -590, 0, -590, 0, -590, -590, -590, 0, -590, + -590, -590, 0, -590, -590, -590, 0, -590, 0, 0, + 0, 0, 0, 0, -592, -592, -592, -592, -592, -592, + -592, -592, -592, 0, 0, 0, 0, -590, -590, -590, + -592, -590, -592, -592, -592, -592, 0, -590, 0, 0, + 0, -592, -592, -592, -592, -592, -592, -592, 0, 0, + -592, 0, 0, 0, 0, 0, 0, 0, 0, -592, + -592, -592, -592, -592, -592, -592, -592, -592, 0, -592, + -592, -592, 0, 0, -592, 0, 0, -592, -592, 0, + -592, -592, -592, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -592, -592, 0, 0, 0, + 0, 0, -592, 837, 0, -592, -592, 0, -592, -592, + 0, -592, 0, -592, -592, -592, 0, -592, -592, -592, + 0, -592, -592, -592, 0, -592, 0, 0, 0, 0, + 0, 0, -107, -593, -593, -593, -593, -593, -593, -593, + -593, -593, 0, 0, 0, -592, -592, -592, 0, -593, + 0, -593, -593, -593, -593, -592, 0, 0, 0, 0, + -593, -593, -593, -593, -593, -593, -593, 0, 0, -593, + 0, 0, 0, 0, 0, 0, 0, 0, -593, -593, + -593, -593, -593, -593, -593, -593, -593, 0, -593, -593, + -593, 0, 0, -593, 0, 0, -593, -593, 0, -593, + -593, -593, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -593, -593, 0, 0, 0, 0, + 0, -593, 838, 0, -593, -593, 0, -593, -593, 0, + -593, 0, -593, -593, -593, 0, -593, -593, -593, 0, + -593, -593, -593, 0, -593, 0, 0, 0, 0, 0, + 0, -109, -594, -594, -594, -594, -594, -594, -594, -594, + -594, 0, 0, 0, -593, -593, -593, 0, -594, 0, + -594, -594, -594, -594, -593, 0, 0, 0, 0, -594, + -594, -594, -594, -594, -594, -594, 0, 0, -594, 0, + 0, 0, 0, 0, 0, 0, 0, -594, -594, -594, + -594, -594, -594, -594, -594, -594, 0, -594, -594, -594, + 0, 0, -594, 0, 0, -594, -594, 0, -594, -594, + -594, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -594, -594, 0, 0, 0, 0, 0, + -594, 0, 0, -594, -594, 0, -594, -594, 0, -594, + 0, -594, -594, -594, 0, -594, -594, -594, 0, -594, + -594, -594, 0, -594, 0, 0, 0, 0, 0, 0, + -595, -595, -595, -595, -595, -595, -595, -595, -595, 0, + 0, 0, 0, -594, -594, -594, -595, 0, -595, -595, + -595, -595, 0, -594, 0, 0, 0, -595, -595, -595, + -595, -595, -595, -595, 0, 0, -595, 0, 0, 0, + 0, 0, 0, 0, 0, -595, -595, -595, -595, -595, + -595, -595, -595, -595, 0, -595, -595, -595, 0, 0, + -595, 0, 0, -595, -595, 0, -595, -595, -595, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -595, -595, 0, 0, 0, 0, 0, -595, 0, + 0, -595, -595, 0, -595, -595, 0, -595, 0, -595, + -595, -595, 0, -595, -595, -595, 0, -595, -595, -595, + 0, -595, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -595, -595, -595, 0, 0, 0, 0, 0, 0, + 0, -595, 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, 320, 321, 241, 322, 0, 0, 0, 0, + 0, 0, 323, 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, 324, 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, 320, 321, 241, 322, 0, 0, 0, + 0, 0, 0, 323, 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, 486, 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, 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, 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, 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, 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, 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, 313, 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, 314, 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, 313, 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, 611, 0, 20, 21, 22, 23, 24, 25, 26, 0, 0, - 27, 0, 0, 0, 0, 0, 28, 0, 30, 31, + 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, -613, 0, 0, -613, - -613, 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, -613, 0, -613, - 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, 247, 0, 0, 248, 249, + 0, 61, 62, 63, 0, 64, 0, 0, 0, 0, 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, 250, 0, 251, 20, + 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, 27, 0, 0, 0, 0, 0, 28, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 40, 41, 42, @@ -3169,1196 +3713,1006 @@ static const yytype_int16 yytable[] = 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, 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, 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, + 62, 63, 0, 64, 0, 0, 0, 0, 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, + 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, 34, 35, + 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, + 43, 0, 0, 44, 45, 0, 261, 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, 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, 119, 53, 0, 54, 55, 0, 262, 0, 263, + 264, 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, 265, 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, 260, 35, 36, 37, + 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, + 0, 44, 45, 0, 261, 47, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, + 508, 0, 0, 0, 0, 0, 211, 0, 0, 119, + 53, 0, 54, 55, 0, 262, 0, 263, 264, 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, + 265, 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, 260, 35, 36, 37, 38, 39, + 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, + 45, 0, 261, 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, 723, 0, 263, 264, 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, 265, 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, 260, 35, 36, 37, 38, 39, 0, 40, + 41, 42, 0, 0, 43, 0, 0, 44, 45, 0, + 261, 47, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 49, 854, 0, 0, 0, + 0, 0, 211, 0, 0, 119, 53, 0, 54, 55, + 0, 723, 0, 263, 264, 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, 265, 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, + 260, 35, 36, 37, 38, 39, 0, 40, 41, 42, + 0, 0, 43, 0, 0, 44, 45, 0, 261, 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, 262, + 0, 263, 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, 265, 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, 260, 35, + 36, 37, 38, 39, 0, 40, 41, 42, 0, 0, + 43, 0, 0, 44, 45, 0, 261, 47, 48, 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, - 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, -583, -583, -583, - -583, -583, -583, -583, -583, -583, 0, 0, 0, 0, - 0, 0, 0, -583, 0, -583, -583, -583, -583, 0, - -583, 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, 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, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -583, -583, - -583, 0, -583, 0, 0, 0, 0, 0, -583, -584, - -584, -584, -584, -584, -584, -584, -584, -584, 0, 0, - 0, 0, 0, 0, 0, -584, 0, -584, -584, -584, - -584, 0, -584, 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, 49, 50, 0, 0, 0, 0, 0, 211, 0, + 0, 119, 53, 0, 54, 55, 0, 0, 0, 263, + 264, 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, 265, 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, 260, 35, 36, 37, + 38, 39, 0, 40, 41, 42, 0, 0, 43, 0, + 0, 44, 45, 0, 261, 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, 723, 0, 263, 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, + 265, 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, 260, 35, 36, 37, 38, 39, + 0, 40, 41, 42, 0, 0, 43, 0, 0, 44, + 45, 0, 261, 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, 263, 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, 265, 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, 605, 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, 265, 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, 262, + 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, 265, 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, - -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, -586, -586, -586, - -586, -586, -586, -586, -586, -586, 0, 0, 0, 0, - -584, -584, -584, -586, -584, -586, -586, -586, -586, 0, - -584, 0, 0, 0, -586, -586, -586, -586, -586, -586, - -586, 0, 0, -586, 0, 0, 0, 0, 0, 0, - 0, 0, -586, -586, -586, -586, -586, -586, -586, -586, - -586, 0, -586, -586, -586, 0, 0, -586, 0, 0, - -586, -586, 0, -586, -586, -586, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -586, -586, - 0, 0, 0, 0, 0, -586, 831, 0, -586, -586, - 0, -586, -586, 0, -586, 0, -586, -586, -586, 0, - -586, -586, -586, 0, -586, -586, -586, 0, -586, 0, - 0, 0, 0, 0, 0, -107, -587, -587, -587, -587, - -587, -587, -587, -587, -587, 0, 0, 0, -586, -586, - -586, 0, -587, 0, -587, -587, -587, -587, -586, 0, - 0, 0, 0, -587, -587, -587, -587, -587, -587, -587, - 0, 0, -587, 0, 0, 0, 0, 0, 0, 0, - 0, -587, -587, -587, -587, -587, -587, -587, -587, -587, - 0, -587, -587, -587, 0, 0, -587, 0, 0, -587, - -587, 0, -587, -587, -587, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -587, -587, 0, - 0, 0, 0, 0, -587, 832, 0, -587, -587, 0, - -587, -587, 0, -587, 0, -587, -587, -587, 0, -587, - -587, -587, 0, -587, -587, -587, 0, -587, 0, 0, - 0, 0, 0, 0, -109, -588, -588, -588, -588, -588, - -588, -588, -588, -588, 0, 0, 0, -587, -587, -587, - 0, -588, 0, -588, -588, -588, -588, -587, 0, 0, - 0, 0, -588, -588, -588, -588, -588, -588, -588, 0, - 0, -588, 0, 0, 0, 0, 0, 0, 0, 0, - -588, -588, -588, -588, -588, -588, -588, -588, -588, 0, - -588, -588, -588, 0, 0, -588, 0, 0, -588, -588, - 0, -588, -588, -588, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -588, -588, 0, 0, - 0, 0, 0, -588, 0, 0, -588, -588, 0, -588, - -588, 0, -588, 0, -588, -588, -588, 0, -588, -588, - -588, 0, -588, -588, -588, 0, -588, 0, 0, 0, - 0, 0, 0, -589, -589, -589, -589, -589, -589, -589, - -589, -589, 0, 0, 0, 0, -588, -588, -588, -589, - 0, -589, -589, -589, -589, 0, -588, 0, 0, 0, - -589, -589, -589, -589, -589, -589, -589, 0, 0, -589, - 0, 0, 0, 0, 0, 0, 0, 0, -589, -589, - -589, -589, -589, -589, -589, -589, -589, 0, -589, -589, - -589, 0, 0, -589, 0, 0, -589, -589, 0, -589, - -589, -589, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -589, -589, 0, 0, 0, 0, - 0, -589, 0, 0, -589, -589, 0, -589, -589, 0, - -589, 0, -589, -589, -589, 0, -589, -589, -589, 0, - -589, -589, -589, 0, -589, 0, 0, 0, 0, 0, + 0, 49, 50, 0, 0, 0, 0, 0, 211, 0, + 0, 119, 53, 0, 54, 55, 0, 605, 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, 265, 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, 900, 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, + 265, 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, 723, 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, 265, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, + 0, 0, 0, 65, 265, 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, 0, 0, 0, -589, -589, -589, 0, 0, 0, - 0, 0, 0, 0, -589, 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, 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, 0, 0, 0, 0, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, + 0, 65, 265, 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, 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, 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, - 485, 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, 0, 0, 241, + 0, 0, 0, 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, + 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, 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, - 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, 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, 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, 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, + 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, 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, 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, 313, 0, 0, 399, 53, 0, + 54, 55, 0, 400, 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, 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, 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, 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, - 0, 0, 0, 15, 120, 16, 17, 18, 19, 0, - 0, 0, 608, 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, 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, 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, 0, 0, 0, - 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 0, 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, 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, - 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, 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, 260, - 35, 36, 37, 38, 39, 0, 40, 41, 42, 0, - 0, 43, 0, 0, 44, 45, 0, 46, 47, 48, + 0, 0, 313, 0, 0, 399, 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, 49, 506, 0, 0, 0, 0, 0, 211, - 0, 0, 119, 53, 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, 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, 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, 967, 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, - 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, - 119, 53, 0, 54, 55, 0, 719, 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, 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, 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, 848, - 0, 0, 0, 0, 0, 211, 0, 0, 119, 53, - 0, 54, 55, 0, 719, 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, 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, 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, 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, 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, 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, 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, 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, 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, 719, 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, 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, 260, 35, 36, - 37, 38, 39, 0, 40, 41, 42, 0, 0, 43, - 0, 0, 44, 45, 0, 46, 47, 48, 0, 0, + 990, 0, 0, 119, 53, 0, 54, 55, 0, 0, + 659, 660, 0, 57, 661, 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, - 49, 50, 0, 0, 0, 0, 0, 211, 0, 0, - 119, 53, 0, 54, 55, 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, 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, 602, 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, 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, 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, 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, - 602, 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, 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, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 0, 201, 202, 680, 651, 0, 0, + 681, 0, 203, 276, 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, 49, 50, 0, 0, 0, 0, 0, 211, - 0, 0, 119, 53, 0, 54, 55, 0, 894, 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, 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, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 0, + 201, 202, 665, 660, 0, 0, 666, 0, 203, 276, 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, 719, 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, 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, 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, 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, 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, 0, 0, 0, - 0, 0, 0, 5, 6, 7, 8, 9, 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, 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, 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, 114, - 35, 36, 37, 115, 39, 0, 40, 41, 42, 0, - 0, 43, 0, 0, 44, 45, 0, 116, 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, 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, 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, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 0, 201, 202, 697, 651, + 0, 0, 698, 0, 203, 276, 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, 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, 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, 312, 0, 0, - 398, 53, 0, 54, 55, 0, 399, 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, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 0, 201, 202, 700, 660, 0, 0, 701, 0, + 203, 276, 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, + 707, 651, 0, 0, 708, 0, 203, 276, 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, 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, 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, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 0, 201, 202, 710, 660, 0, 0, + 711, 0, 203, 276, 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, 312, 0, 0, 398, 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, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 0, + 201, 202, 746, 651, 0, 0, 747, 0, 203, 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 961, - 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, 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, 984, 0, 0, 119, 53, 0, 54, - 55, 0, 0, 677, 648, 0, 57, 678, 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, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 0, 201, 202, 749, 660, + 0, 0, 750, 0, 203, 276, 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, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 0, 201, 202, 662, - 657, 0, 0, 663, 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, 694, 648, 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, 0, 0, - 0, 0, 0, 0, 188, 189, 190, 0, 0, 0, + 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 0, 201, 202, 905, 651, 0, 0, 906, 0, + 203, 276, 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, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 0, 201, - 202, 697, 657, 0, 0, 698, 0, 203, 275, 0, + 0, 0, 0, 0, 0, 0, 0, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 0, 201, 202, + 908, 660, 0, 0, 909, 0, 203, 276, 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, - 174, 175, 176, 177, 178, 179, 180, 181, 0, 0, - 182, 183, 0, 0, 0, 0, 184, 185, 186, 187, + 0, 0, 0, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 0, 201, 202, 1049, 651, 0, 0, + 1050, 0, 203, 276, 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, - 188, 189, 190, 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, 1061, 651, 0, 0, 1062, 0, 203, 276, 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, 704, 648, 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, 0, 0, - 0, 0, 0, 0, 0, 0, 188, 189, 190, 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, 1064, 660, + 0, 0, 1065, 0, 203, 276, 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, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 0, 201, 202, 707, 657, 0, 0, 708, 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, 742, - 648, 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, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 188, 189, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 0, 201, 202, 665, 660, 0, 0, 666, 0, + 203, 276, 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, 872, + 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, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, 0, + 0, 0, 0, 415, 416, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 418, 0, 0, 0, + 0, 885, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 419, 0, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 0, 0, 0, 0, 415, 416, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 418, 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, 745, 657, 0, 0, 746, - 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, 419, + 0, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 0, 0, 0, 0, 415, 416, 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, 899, 648, 0, 0, 900, 0, 203, 275, 0, + 418, 0, 0, 0, 0, 0, 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, 419, 0, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429, 0, 0, 0, 0, 0, 0, 0, + 0, -277, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 0, 0, 0, 0, 415, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, + 0, 418, 0, 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, 902, 657, 0, - 0, 903, 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, 419, 0, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 0, 0, 0, 0, 0, 0, + 0, 0, -279, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 0, 0, 0, 0, 415, + 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 419, 0, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 0, 0, 0, 0, 0, + 0, 0, 0, -280, 403, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 0, 0, 0, 0, + 415, 416, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 418, 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, 648, 0, 0, 1044, 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, 419, 0, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 0, 0, 0, 0, + 0, 0, 0, 0, -282, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 0, 0, 0, + 0, 415, 416, 0, 0, 0, 417, 0, 0, 0, + 0, 0, 0, 0, 418, 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, 1055, - 648, 0, 0, 1056, 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, 419, 0, 420, 421, 422, + 423, 424, 425, 426, 427, 428, 429, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, 0, + 0, 0, 0, 415, 416, 0, 0, 0, 500, 0, + 0, 0, 0, 0, 0, 0, 418, 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, 1058, 657, 0, 0, 1059, - 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, 419, 0, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 0, 0, 0, 0, 415, 416, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 418, 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, 662, 657, 0, 0, 663, 0, 203, 275, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 419, + 0, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, -620, -620, 0, 0, 0, 0, 415, 416, 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, + 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 879, 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, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 0, 0, 0, 0, - 414, 415, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 418, 0, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 0, 0, - 0, 0, 414, 415, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 418, 0, 419, 420, - 421, 422, 423, 424, 425, 426, 427, 428, 0, 0, - 0, 0, 0, 0, 0, 0, -277, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 0, - 0, 0, 0, 414, 415, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 417, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 418, 0, 419, - 420, 421, 422, 423, 424, 425, 426, 427, 428, 0, - 0, 0, 0, 0, 0, 0, 0, -278, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 0, 0, 0, 0, 414, 415, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 0, 0, 0, 0, 0, 0, 0, 0, -279, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 0, 0, 0, 0, 414, 415, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 417, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, - 0, 419, 420, 421, 422, 423, 424, 425, 426, 427, - 428, 0, 0, 0, 0, 0, 0, 0, 0, -280, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 0, 0, 0, 0, 414, 415, 0, 0, - 0, 416, 0, 0, 0, 0, 0, 0, 0, 417, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 418, 0, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 0, 0, 0, 0, 414, 415, - 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, - 0, 417, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 418, 0, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 0, 0, 0, 0, - 414, 415, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 418, 0, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, -614, -614, 0, 0, - 0, 0, 414, 415, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 419, 420, - 421, 422, 423, 424, 425, 426, 427, 428 + 0, 0, 0, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429 }; static const yytype_int16 yycheck[] = { - 2, 89, 16, 17, 27, 69, 20, 87, 88, 66, - 2, 28, 4, 5, 6, 22, 7, 9, 10, 21, - 14, 13, 222, 15, 16, 17, 284, 313, 20, 479, - 10, 271, 82, 52, 28, 15, 488, 377, 4, 306, - 54, 55, 2, 310, 4, 56, 16, 17, 593, 7, - 20, 401, 54, 55, 16, 17, 14, 118, 20, 756, - 52, 501, 783, 590, 56, 505, 431, 58, 688, 544, - 28, 330, 74, 75, 66, 75, 505, 91, 429, 699, - 25, 15, 433, 25, 295, 436, 60, 61, 62, 63, - 82, 456, 54, 55, 21, 22, 318, 969, 105, 75, - 58, 944, 5, 6, 25, 57, 457, 536, 473, 111, - 13, 25, 269, 90, 271, 16, 17, 482, 26, 20, - 29, 472, 122, 474, 0, 117, 79, 119, 27, 665, - 666, 144, 483, 608, 138, 69, 90, 92, 218, 372, - 25, 90, 590, 26, 55, 593, 90, 369, 305, 229, - 90, 25, 590, 56, 25, 25, 105, 103, 74, 75, - 393, 105, 802, 16, 17, 121, 121, 20, 808, 121, - 147, 522, 90, 126, 1046, 18, 16, 20, 105, 82, - 28, 546, 128, 331, 111, 112, 334, 398, 336, 52, - 338, 140, 340, 147, 1037, 144, 547, 142, 147, 144, - 142, 54, 129, 147, 113, 121, 122, 147, 121, 289, - 92, 213, 214, 401, 214, 92, 115, 90, 210, 118, - 119, 142, 749, 144, 57, 458, 441, 442, 142, 147, - 138, 223, 224, 297, 761, 315, 144, 213, 214, 121, - 142, 305, 306, 223, 224, 966, 310, 146, 969, 148, - 144, 242, 949, 441, 442, 138, 119, 142, 544, 121, - 386, 275, 388, 313, 125, 279, 55, 269, 142, 271, - 510, 142, 142, 275, 147, 115, 295, 813, 118, 119, - 142, 90, 115, 275, 242, 118, 119, 279, 728, 729, - 123, 283, 284, 90, 90, 287, 555, 213, 214, 92, - 729, 749, 294, 295, 92, 275, 146, 92, 148, 279, - 302, 749, 92, 761, 121, 148, 791, 279, 252, 90, - 940, 313, 608, 761, 869, 1046, 548, 51, 121, 53, - 54, 55, 56, 121, 294, 783, 121, 687, 147, 396, - 92, 121, 302, 90, 401, 69, 58, 59, 92, 323, - 147, 147, 509, 510, 142, 347, 348, 349, 350, 351, - 352, 353, 354, 297, 804, 37, 38, 55, 348, 349, - 350, 351, 25, 375, 92, 377, 147, 121, 279, 398, - 372, 347, 142, 92, 441, 442, 51, 347, 399, 20, - 840, 92, 352, 51, 455, 53, 54, 55, 56, 92, - 147, 393, 318, 121, 396, 553, 398, 399, 90, 401, - 313, 69, 121, 58, 59, 51, 92, 431, 142, 55, - 121, 869, 275, 105, 287, 863, 279, 767, 121, 431, - 57, 796, 295, 142, 142, 873, 101, 102, 103, 431, - 92, 142, 456, 676, 795, 121, 797, 138, 605, 441, - 442, 101, 661, 369, 456, 664, 17, 18, 140, 473, - 718, 431, 464, 128, 456, 147, 458, 459, 482, 121, - 145, 473, 739, 682, 121, 433, 499, 469, 436, 101, - 482, 473, 722, 139, 142, 477, 456, 501, 940, 55, - 482, 505, 542, 141, 544, 487, 399, 101, 655, 457, - 142, 518, 942, 473, 92, 791, 433, 509, 510, 131, - 132, 133, 482, 942, 714, 101, 474, 519, 966, 533, - 121, 969, 536, 26, 518, 483, 60, 519, 966, 63, - 457, 121, 546, 121, 142, 398, 528, 51, 618, 501, - 798, 51, 215, 396, 546, 885, 886, 474, 401, 222, - 542, 784, 544, 92, 546, 142, 483, 714, 608, 519, - 518, 142, 554, 115, 522, 722, 118, 119, 528, 9, - 10, 533, 142, 107, 508, 15, 546, 90, 811, 881, - 882, 51, 121, 142, 799, 121, 259, 90, 580, 547, - 805, 806, 105, 92, 146, 522, 148, 855, 1046, 601, - 142, 1039, 105, 142, 51, 793, 469, 599, 16, 849, - 580, 799, 1050, 636, 477, 99, 608, 805, 806, 318, - 547, 15, 121, 856, 487, 121, 122, 140, 13, 599, - 121, 121, 548, 16, 147, 138, 63, 140, 491, 542, - 15, 544, 142, 142, 147, 652, 772, 773, 774, 26, - 776, 145, 778, 655, 661, 16, 145, 664, 2, 661, - 4, 139, 664, 665, 666, 9, 10, 1032, 142, 92, - 369, 15, 16, 17, 347, 739, 20, 117, 1018, 142, - 682, 15, 1033, 675, 676, 687, 688, 15, 361, 922, - 692, 554, 849, 710, 685, 675, 911, 699, 121, 44, - 115, 142, 121, 118, 119, 608, 379, 115, 52, 141, - 118, 119, 141, 90, 728, 729, 710, 709, 15, 142, - 722, 809, 66, 911, 18, 652, 926, 685, 105, 709, - 145, 146, 932, 148, 661, 141, 793, 664, 146, 141, - 148, 791, 799, 800, 63, 64, 65, 115, 805, 806, - 118, 119, 710, 680, 115, 682, 15, 118, 119, 90, - 139, 138, 142, 140, 44, 767, 728, 144, 115, 16, - 147, 118, 119, 117, 105, 119, 139, 141, 57, 139, - 1038, 142, 796, 223, 224, 146, 142, 148, 142, 142, - 804, 583, 784, 142, 796, 587, 44, 116, 117, 791, - 792, 793, 90, 26, 796, 478, 479, 799, 800, 140, - 15, 813, 93, 805, 806, 14, 147, 105, 15, 811, - 812, 823, 15, 145, 826, 142, 796, 953, 954, 955, - 956, 142, 792, 825, 687, 142, 828, 61, 142, 797, - 64, 65, 804, 283, 284, 837, 838, 849, 828, 548, - 142, 15, 140, 845, 911, 528, 299, 141, 15, 147, - 303, 139, 535, 15, 856, 857, 210, 90, 115, 15, - 797, 118, 119, 15, 139, 37, 38, 576, 142, 223, - 224, 126, 105, 885, 886, 583, 61, 126, 791, 64, - 65, 883, 116, 117, 593, 55, 888, 596, 139, 146, - 51, 148, 53, 54, 55, 56, 986, 15, 348, 349, - 350, 351, 55, 353, 354, 138, 1042, 140, 69, 911, - 142, 144, 142, 142, 147, 783, 142, 142, 942, 921, - 922, 275, 26, 925, 142, 279, 142, 929, 940, 283, - 284, 116, 117, 287, 441, 442, 15, 141, 144, 812, - 294, 295, 144, 115, 142, 519, 118, 119, 302, 26, - 26, 13, 825, 6, 1035, 783, 62, 115, 64, 65, - 118, 119, 1037, 810, 837, 838, 999, 90, 475, 476, - 883, 1034, 845, 254, 146, 888, 148, 7, 583, -1, - 963, 783, 105, -1, 857, 966, 90, 989, 90, 991, - 148, 674, 994, 347, 348, 349, 350, 351, 352, 353, - 354, 105, -1, 105, -1, -1, 1018, -1, 1032, 459, - 116, 117, 925, 90, 90, -1, 523, 140, 372, -1, - 1032, -1, 1034, 1035, 147, -1, -1, -1, 105, 105, - 1032, 714, -1, -1, 138, 90, 140, -1, 140, 393, - 144, -1, 396, 147, 398, 147, -1, 401, 921, -1, - 105, -1, 1032, 506, -1, 62, 929, 64, 65, -1, - 513, 138, 138, 140, 140, 1033, -1, 144, 144, -1, - 147, 147, 525, -1, 783, 783, -1, 431, -1, 51, - -1, 53, 54, 55, 56, 140, 769, 441, 442, -1, - -1, -1, 147, 90, -1, 963, 1033, 69, 966, -1, - -1, 969, 456, 971, 458, 459, -1, -1, 105, 116, - 117, -1, -1, -1, -1, 469, 989, -1, 991, 473, - 90, 994, 94, 477, 577, 578, -1, -1, 482, 101, - 102, 103, 815, 487, -1, 105, -1, 90, -1, -1, - 890, 891, -1, 140, -1, -1, -1, -1, 90, -1, - 147, 1019, 105, -1, 607, -1, 128, 840, 90, -1, - 869, 963, 871, 105, 966, 519, 875, 969, -1, 971, - 140, 90, -1, 105, 528, -1, -1, 147, 1046, -1, - 1048, -1, 1050, -1, 1052, -1, 105, 140, -1, -1, - -1, -1, 546, -1, 147, 9, 10, 90, 140, -1, - 554, 15, 16, 17, 1072, 147, 20, -1, 140, -1, - -1, -1, 105, -1, -1, 147, 966, 1019, -1, -1, - -1, 140, -1, -1, -1, 675, 580, -1, 147, -1, - -1, 684, -1, 47, 48, 49, 50, 101, 947, 948, - 54, 55, -1, 926, 1046, 599, 1048, 140, 1050, 932, - 1052, -1, 66, 67, 147, 963, -1, -1, 966, 709, - 969, 969, 971, 971, -1, 129, 130, 131, 132, 133, - 1072, -1, 1022, 1023, 1024, -1, 1026, 1027, -1, -1, - 63, 64, 65, -1, -1, 738, 40, 41, 42, 43, - 44, -1, 799, 800, -1, -1, -1, 1006, 805, 806, - 1009, -1, -1, 117, 757, 63, 64, 65, 63, 64, - 65, 1019, -1, -1, -1, -1, 1066, 1067, 1068, 1069, - -1, 675, 676, -1, 831, 832, 1076, 834, 835, 63, - 64, 65, 1041, 116, 117, -1, -1, 1046, 1046, 1048, - 1048, -1, 1050, 1052, 1052, -1, -1, -1, 51, -1, - 53, 54, 55, 56, -1, 709, -1, -1, 116, 117, - -1, 116, 117, 1072, 1072, -1, 69, 63, 64, 65, - -1, 51, -1, 53, 54, 55, 56, -1, 828, -1, - 83, -1, 116, 117, -1, -1, -1, -1, -1, 69, - -1, 94, -1, -1, -1, 848, -1, 100, 101, 102, - 103, 63, 64, 65, 911, -1, 63, 64, 65, 223, - 224, 864, -1, 2, 94, 4, 5, 6, 121, -1, - 116, 117, -1, -1, 13, 128, -1, 934, 131, -1, - 784, 115, -1, -1, 118, 119, -1, -1, 792, 793, - -1, 144, 796, -1, -1, 799, 800, 261, 262, 263, - 264, 805, 806, -1, 116, 117, -1, 811, 812, 116, - 117, 275, 146, 52, 148, 279, -1, 56, -1, 283, - 284, 825, -1, -1, 828, -1, 51, -1, 53, 54, - 55, 56, -1, 837, 838, -1, -1, -1, -1, -1, - -1, 845, -1, 82, 69, 51, -1, 53, 54, 55, - 56, -1, 856, 857, -1, 88, 89, -1, 83, -1, - -1, -1, -1, 69, -1, -1, -1, -1, 101, 94, - 88, 89, -1, -1, -1, 100, 101, 102, 103, -1, - 119, -1, -1, 101, 348, 349, 350, 351, 94, 353, - 354, -1, -1, -1, 100, 128, 129, 130, 131, 132, - 133, -1, -1, 128, -1, -1, 131, 911, -1, 373, - -1, 129, 130, 131, 132, 133, -1, 921, 922, 144, - 384, -1, -1, -1, -1, 929, -1, -1, -1, -1, - -1, -1, 396, -1, -1, -1, -1, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, -1, 417, 418, 419, 420, 421, 422, 423, - 424, 425, 426, 427, 428, -1, 115, 431, -1, 118, - 119, 210, -1, -1, -1, -1, -1, 441, 442, -1, - -1, -1, -1, -1, -1, 989, -1, 991, -1, -1, - 994, -1, 456, 142, -1, 459, -1, 146, -1, 148, - -1, 51, -1, 53, 54, 55, 56, 471, -1, 473, - -1, 475, 476, -1, -1, -1, -1, -1, 482, 69, - -1, -1, -1, -1, -1, -1, -1, 491, 1032, -1, - 494, -1, -1, -1, 498, -1, -1, 501, -1, 503, - -1, 505, 506, -1, 94, 88, 89, -1, 287, -1, - 100, 101, 102, 103, -1, 294, 295, -1, 101, 523, - -1, -1, 51, 302, 53, 54, 55, 56, -1, 533, - -1, -1, 536, -1, 313, -1, -1, -1, 128, -1, - 69, 131, 546, 126, 127, 128, 129, 130, 131, 132, - 133, -1, -1, -1, 144, -1, -1, -1, -1, 563, - 564, -1, -1, -1, -1, 94, -1, -1, 347, -1, - -1, 100, -1, 352, -1, -1, 580, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 0, -1, 372, -1, 599, -1, 51, 602, 53, - 54, 55, 56, -1, 13, 14, 15, 16, 17, 18, - -1, 20, -1, -1, 393, 69, -1, 26, 27, 398, - 399, -1, 401, -1, -1, -1, -1, -1, 37, 38, - -1, 40, 41, 42, 43, 44, -1, -1, -1, -1, - 94, -1, -1, -1, -1, -1, 100, 101, 102, 103, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 441, 442, -1, -1, -1, -1, -1, -1, - -1, 675, -1, -1, 128, -1, -1, 131, -1, 458, - -1, 90, -1, 687, -1, -1, 690, 691, 142, -1, - 469, 2, -1, 4, 5, 6, 105, -1, 477, -1, - -1, -1, 13, -1, -1, 709, 115, -1, 487, 118, - 119, -1, -1, -1, -1, 719, -1, -1, -1, -1, - -1, -1, -1, -1, 728, 729, -1, -1, -1, 138, - 139, -1, -1, -1, -1, 144, 145, 146, 147, 148, - 519, 52, -1, -1, -1, 56, -1, -1, -1, 528, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 542, -1, 544, -1, -1, -1, -1, - -1, 82, -1, -1, -1, 554, -1, -1, -1, -1, - -1, -1, -1, -1, 788, -1, -1, -1, -1, 793, - 794, -1, 796, -1, -1, 799, 800, -1, -1, -1, - 804, 805, 806, -1, -1, -1, -1, -1, 119, -1, - -1, -1, -1, -1, 51, -1, 53, 54, 55, 56, - -1, -1, -1, -1, 828, -1, -1, 831, 832, 608, - 834, 835, 69, -1, -1, -1, -1, -1, -1, -1, - 844, -1, -1, -1, 848, -1, -1, -1, 85, -1, - -1, -1, -1, -1, -1, -1, 2, 94, 4, 5, - 6, 865, 866, 100, 101, 102, 103, 13, -1, -1, - -1, -1, -1, -1, 878, 879, -1, -1, -1, -1, - -1, -1, -1, 44, -1, -1, -1, -1, -1, -1, - 894, 128, -1, -1, 131, -1, -1, 676, -1, 210, - 904, 905, -1, -1, -1, -1, 52, 911, -1, -1, - 56, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, -1, -1, -1, -1, 88, 89, -1, - 934, -1, -1, -1, -1, -1, 82, -1, 942, -1, - 101, -1, -1, -1, 51, -1, 53, 54, 55, 56, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 122, 69, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 119, -1, -1, 287, -1, 85, -1, - -1, 142, -1, 294, 295, -1, -1, 94, -1, -1, - -1, 302, -1, 100, 101, 102, 103, -1, -1, -1, - -1, -1, 313, -1, 51, 784, 53, 54, 55, 56, - -1, -1, 791, 792, 793, -1, -1, -1, -1, -1, - 799, 128, 69, -1, 131, -1, 805, 806, 1032, -1, - -1, -1, 811, 812, -1, -1, 347, -1, 85, -1, - -1, 352, -1, -1, -1, -1, 825, 94, -1, -1, - -1, -1, -1, 100, 101, 102, 103, -1, 837, 838, - -1, 372, -1, -1, 210, -1, 845, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 856, 857, -1, - -1, 128, 393, -1, 131, -1, -1, 398, 399, -1, - 401, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 883, -1, -1, -1, -1, 888, - 51, -1, 53, 54, 55, 56, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 69, -1, - 441, 442, 911, -1, -1, -1, -1, -1, -1, -1, - -1, 287, 921, 922, -1, -1, 925, 458, 294, 295, - 929, -1, -1, 94, -1, -1, 302, -1, 469, 100, - 101, 102, 103, -1, -1, -1, 477, 313, -1, -1, - -1, -1, -1, -1, -1, -1, 487, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 128, -1, -1, - 131, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 347, -1, -1, -1, -1, 352, -1, 519, -1, - 989, -1, 991, -1, -1, 994, -1, 528, -1, -1, - -1, -1, -1, -1, -1, -1, 372, -1, -1, -1, - -1, 542, -1, 544, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 554, -1, -1, -1, 393, -1, -1, - -1, -1, 398, 399, -1, 401, -1, -1, -1, -1, + 2, 285, 16, 17, 69, 27, 20, 66, 89, 28, + 2, 222, 4, 5, 6, 22, 14, 9, 10, 21, + 480, 13, 15, 15, 16, 17, 7, 378, 20, 4, + 28, 16, 17, 14, 118, 20, 7, 593, 489, 272, + 87, 88, 402, 314, 2, 56, 4, 28, 75, 82, + 442, 443, 54, 55, 307, 596, 52, 503, 311, 546, + 52, 507, 5, 6, 56, 29, 789, 21, 22, 54, + 13, 507, 74, 75, 66, 319, 69, 58, 16, 17, + 593, 691, 20, 331, 476, 477, 270, 58, 272, 761, + 82, 373, 702, 16, 10, 75, 668, 669, 105, 15, + 430, 26, 538, 25, 434, 432, 296, 437, 975, 111, + 25, 950, 394, 56, 26, 0, 54, 55, 60, 61, + 62, 63, 306, 90, 611, 117, 370, 119, 458, 62, + 457, 64, 65, 525, 16, 17, 26, 92, 20, 82, + 92, 25, 122, 473, 79, 475, 25, 474, 402, 113, + 57, 105, 58, 59, 484, 26, 483, 111, 112, 25, + 25, 25, 144, 16, 17, 332, 121, 20, 335, 121, + 337, 218, 339, 25, 341, 129, 138, 459, 90, 90, + 147, 57, 229, 116, 117, 1052, 213, 214, 442, 443, + 142, 126, 115, 105, 524, 118, 119, 753, 90, 90, + 90, 54, 55, 664, 1043, 593, 667, 90, 596, 399, + 766, 213, 214, 138, 121, 105, 92, 16, 210, 549, + 142, 548, 16, 146, 685, 148, 138, 142, 140, 442, + 443, 223, 224, 298, 214, 147, 147, 18, 91, 20, + 753, 306, 307, 290, 90, 121, 311, 819, 138, 972, + 140, 92, 975, 766, 144, 147, 147, 147, 142, 252, + 144, 242, 276, 142, 147, 144, 280, 138, 270, 316, + 272, 242, 55, 144, 276, 546, 142, 142, 142, 512, + 121, 314, 90, 955, 276, 92, 732, 733, 280, 90, + 142, 276, 284, 285, 121, 280, 288, 733, 90, 28, + 296, 147, 92, 295, 296, 298, 550, 223, 224, 557, + 797, 303, 92, 869, 121, 92, 115, 51, 90, 118, + 119, 115, 314, 879, 118, 119, 142, 511, 512, 1052, + 690, 121, 121, 105, 875, 69, 946, 295, 397, 147, + 611, 121, 280, 402, 121, 303, 147, 146, 142, 148, + 37, 38, 146, 142, 148, 147, 348, 349, 350, 351, + 352, 353, 354, 355, 810, 753, 103, 101, 102, 103, + 92, 314, 456, 348, 376, 147, 378, 92, 766, 808, + 90, 373, 324, 442, 443, 814, 846, 144, 555, 400, + 348, 128, 92, 121, 128, 353, 115, 679, 280, 118, + 119, 789, 394, 399, 125, 397, 121, 399, 400, 55, + 402, 51, 397, 805, 806, 55, 972, 402, 432, 811, + 812, 121, 773, 276, 608, 92, 121, 280, 115, 148, + 432, 118, 119, 349, 350, 351, 352, 147, 722, 92, + 432, 60, 142, 457, 63, 837, 838, 92, 840, 841, + 442, 443, 55, 434, 121, 457, 437, 400, 25, 146, + 474, 148, 142, 465, 20, 457, 142, 459, 460, 483, + 57, 801, 474, 803, 658, 802, 121, 458, 470, 501, + 434, 483, 474, 16, 101, 57, 478, 875, 107, 1045, + 743, 483, 101, 726, 475, 946, 488, 142, 92, 319, + 1056, 520, 948, 484, 458, 138, 717, 492, 790, 511, + 512, 544, 948, 546, 131, 132, 133, 510, 92, 521, + 804, 475, 520, 145, 92, 917, 797, 121, 115, 521, + 484, 118, 119, 717, 548, 817, 123, 121, 530, 520, + 891, 892, 726, 524, 92, 799, 548, 121, 940, 141, + 370, 805, 544, 121, 546, 55, 548, 811, 812, 74, + 75, 148, 139, 521, 556, 503, 37, 38, 549, 583, + 524, 142, 530, 121, 621, 58, 59, 861, 611, 432, + 862, 101, 115, 101, 972, 118, 119, 975, 602, 17, + 18, 583, 805, 57, 142, 549, 121, 535, 811, 812, + 121, 544, 604, 546, 457, 142, 121, 122, 92, 215, + 602, 887, 888, 146, 51, 148, 222, 639, 142, 611, + 90, 474, 855, 121, 122, 142, 2, 51, 4, 142, + 483, 142, 51, 9, 10, 105, 387, 121, 389, 15, + 16, 17, 121, 51, 20, 142, 928, 27, 655, 99, + 503, 15, 92, 259, 507, 13, 658, 664, 142, 121, + 667, 121, 664, 917, 1052, 667, 668, 669, 611, 90, + 140, 855, 26, 1024, 144, 16, 52, 147, 743, 63, + 15, 121, 535, 685, 105, 538, 678, 679, 690, 691, + 66, 145, 145, 695, 713, 548, 139, 142, 213, 214, + 702, 655, 142, 142, 917, 690, 142, 688, 142, 1039, + 664, 1038, 121, 667, 15, 713, 15, 688, 44, 140, + 712, 932, 15, 26, 726, 141, 147, 938, 141, 683, + 550, 685, 713, 18, 815, 115, 90, 141, 118, 119, + 799, 117, 348, 119, 141, 52, 805, 806, 139, 15, + 139, 105, 811, 812, 141, 44, 362, 139, 90, 579, + 1044, 142, 678, 57, 797, 142, 146, 586, 148, 142, + 142, 773, 142, 105, 380, 44, 596, 9, 10, 599, + 789, 15, 93, 15, 138, 14, 140, 90, 802, 15, + 144, 15, 145, 147, 732, 142, 712, 142, 790, 142, + 802, 15, 105, 142, 319, 797, 798, 799, 140, 142, + 802, 141, 119, 805, 806, 147, 139, 819, 15, 811, + 812, 139, 803, 15, 15, 817, 818, 829, 15, 115, + 832, 126, 118, 119, 210, 138, 142, 140, 126, 831, + 798, 144, 834, 55, 147, 15, 90, 223, 224, 803, + 55, 843, 844, 855, 797, 370, 142, 139, 917, 851, + 146, 105, 148, 51, 142, 53, 54, 55, 56, 142, + 862, 863, 810, 479, 480, 142, 9, 10, 142, 732, + 733, 69, 15, 16, 17, 117, 26, 20, 142, 891, + 892, 90, 142, 142, 15, 115, 140, 889, 118, 119, + 276, 144, 894, 147, 280, 144, 105, 115, 284, 285, + 118, 119, 288, 141, 47, 48, 49, 50, 834, 295, + 296, 54, 55, 142, 530, 917, 146, 303, 148, 13, + 26, 537, 521, 66, 67, 927, 928, 145, 146, 931, + 148, 140, 6, 935, 946, 992, 889, 1041, 147, 802, + 90, 894, 789, 1043, 142, 61, 90, 810, 64, 65, + 969, 816, 1040, 972, 254, 105, 975, 7, 977, 789, + 789, 105, 348, 349, 350, 351, 352, 353, 354, 355, + 90, 288, 586, 1005, 117, 969, 972, -1, 931, 296, + -1, 223, 224, -1, 90, 105, -1, 373, 138, -1, + 140, -1, -1, 995, 144, 997, 140, 147, 1000, 105, + 116, 117, -1, 147, -1, -1, 1025, -1, 394, -1, + -1, 397, 1024, 399, 1038, -1, 402, 778, 779, 780, + 140, 782, -1, 784, -1, 550, 1038, 147, 1040, 1041, + -1, -1, 138, 1052, 140, 1054, 1038, 1056, 144, 1058, + -1, 147, 284, 285, -1, 875, 432, 877, 1039, 115, + -1, 881, 118, 119, 90, -1, 442, 443, -1, 1078, + 51, 677, 53, 54, 55, 56, -1, -1, 90, 105, + -1, 457, -1, 459, 460, 1039, -1, -1, 69, 90, + 223, 224, 399, 105, 470, 948, 115, -1, 474, 118, + 119, -1, 478, -1, 105, 115, 300, 483, 118, 119, + 304, 717, 488, 62, 140, 64, 65, 349, 350, 351, + 352, 147, 354, 355, -1, 90, 90, 90, 140, 262, + 263, 264, 265, 953, 954, 147, 146, -1, 148, 140, + 105, 105, 105, 276, 90, 521, 147, 280, -1, -1, + 969, 284, 285, 972, 530, 975, 975, 977, 977, 105, + -1, 142, -1, 470, -1, -1, -1, 116, 117, 775, + -1, 478, 548, 90, -1, 140, 140, 140, -1, -1, + 556, 488, 147, 147, 147, 1038, -1, 61, 105, -1, + 64, 65, 1012, -1, 140, 1015, -1, 63, 64, 65, + -1, 147, 63, 64, 65, -1, 1025, 583, 959, 960, + 961, 962, -1, -1, -1, 821, 349, 350, 351, 352, + -1, 354, 355, 140, -1, -1, 602, 1047, 460, -1, + 147, -1, 1052, 1052, 1054, 1054, -1, 1056, 1058, 1058, + 846, 374, 116, 117, 40, 41, 42, 43, 44, 556, + 116, 117, 385, -1, -1, 116, 117, -1, 1078, 1078, + -1, 586, -1, -1, 397, 590, 63, 64, 65, 402, + 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, + 413, 414, 415, 416, -1, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 428, 429, 1048, -1, 432, + -1, -1, 678, 679, 63, 64, 65, -1, -1, 442, + 443, 63, 64, 65, 508, 63, 64, 65, -1, 116, + 117, 515, -1, -1, 457, -1, 932, 460, 63, 64, + 65, -1, 938, 527, -1, -1, 712, -1, -1, 472, + -1, 474, -1, 476, 477, 2, -1, 4, 5, 6, + 483, -1, -1, 63, 64, 65, 13, 116, 117, 492, + -1, -1, 495, 496, 116, 117, -1, 500, 116, 117, + 503, -1, 505, -1, 507, 508, 88, 89, -1, -1, + 101, 116, 117, -1, -1, -1, 580, 581, -1, 101, + -1, -1, 525, -1, -1, 52, -1, 896, 897, 56, + -1, -1, 535, -1, -1, 538, 116, 117, 129, 130, + 131, 132, 133, -1, 790, 548, 610, 129, 130, 131, + 132, 133, 798, 799, -1, 82, 802, -1, -1, 805, + 806, -1, 565, 566, -1, 811, 812, -1, -1, -1, + -1, 817, 818, -1, -1, -1, 678, -1, -1, -1, + 583, -1, -1, -1, -1, 831, -1, -1, 834, -1, + -1, -1, 119, -1, 789, 88, 89, 843, 844, 602, + -1, -1, 605, 972, -1, 851, -1, -1, 101, 51, + 712, 53, 54, 55, 56, -1, 862, 863, -1, -1, + -1, -1, -1, 687, -1, -1, 51, 69, 53, 54, + 55, 56, -1, 126, 127, 128, 129, 130, 131, 132, + 133, 818, -1, -1, 69, 2, -1, 4, 5, 6, + -1, -1, 94, -1, 831, -1, 13, -1, 100, 1028, + 1029, 1030, -1, 1032, 1033, -1, 843, 844, -1, 94, + -1, 917, -1, -1, 851, 678, -1, -1, 742, -1, + -1, 927, 928, 210, -1, -1, 863, 690, -1, 935, + 693, 694, -1, -1, -1, 52, -1, -1, 762, 56, + -1, 88, 89, 1072, 1073, 1074, 1075, -1, -1, 712, + -1, -1, -1, 1082, 101, -1, -1, -1, -1, -1, + 723, -1, -1, -1, -1, 82, -1, -1, -1, 732, + 733, -1, 834, -1, -1, 51, -1, 53, 54, 55, + 56, 128, 129, 130, 131, 132, 133, -1, -1, 995, + 927, 997, -1, 69, 1000, -1, -1, -1, 935, -1, + -1, 288, 119, -1, -1, -1, -1, -1, 295, 296, + -1, -1, -1, -1, 969, -1, 303, 972, 94, -1, + 975, -1, 977, -1, 100, -1, -1, 314, -1, -1, + 854, 794, 1038, -1, -1, -1, 799, 800, -1, 802, + -1, -1, 805, 806, -1, -1, 870, 810, 811, 812, + 51, -1, 53, 54, 55, 56, -1, -1, 995, -1, + 997, 348, -1, 1000, -1, -1, 353, -1, 69, -1, + 1025, 834, -1, -1, 837, 838, -1, 840, 841, -1, + -1, -1, -1, -1, -1, -1, 373, 850, -1, -1, + -1, 854, -1, 210, -1, -1, -1, 1052, -1, 1054, + -1, 1056, -1, 1058, -1, -1, -1, 394, 871, 872, + -1, -1, 399, 400, -1, 402, -1, -1, -1, -1, + -1, 884, 885, 1078, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 900, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 910, 911, 2, + -1, 4, 5, 6, 917, 442, 443, -1, -1, -1, + 13, -1, 51, -1, 53, 54, 55, 56, -1, -1, + -1, 288, 459, -1, -1, -1, -1, 940, 295, 296, + 69, -1, -1, 470, -1, 948, 303, -1, -1, -1, + -1, 478, -1, -1, 83, -1, -1, 314, -1, 52, + -1, 488, -1, 56, -1, 94, -1, -1, -1, -1, + -1, 100, 101, 102, 103, -1, -1, -1, -1, -1, + -1, -1, 51, -1, 53, 54, 55, 56, -1, 82, + -1, 348, 121, -1, 521, -1, 353, -1, -1, 128, + 69, -1, 131, 530, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 144, 373, 544, 51, 546, + 53, 54, 55, 56, -1, 94, 119, -1, -1, 556, + -1, 100, 101, 102, 103, 1038, 69, 394, 0, -1, + -1, -1, 399, 400, -1, 402, -1, -1, -1, -1, + 83, 13, 14, 15, 16, 17, 18, -1, 20, 128, + -1, 94, 131, -1, 26, 27, -1, 100, 101, 102, + 103, -1, -1, 142, -1, 37, 38, -1, 40, 41, + 42, 43, 44, -1, 611, 442, 443, -1, -1, -1, + -1, -1, -1, -1, -1, 128, -1, -1, 131, -1, + -1, -1, 459, -1, -1, -1, -1, -1, -1, -1, + -1, 144, -1, 470, -1, -1, -1, 210, -1, -1, + -1, 478, -1, -1, -1, 2, -1, 4, 90, -1, + -1, 488, -1, -1, -1, -1, 13, -1, -1, -1, + -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, + -1, -1, 679, 115, -1, -1, 118, 119, -1, -1, + -1, -1, -1, 51, 521, 53, 54, 55, 56, -1, + -1, -1, -1, 530, -1, 52, 138, 139, -1, -1, + -1, 69, 144, 145, 146, 147, 148, 544, -1, 546, + -1, -1, -1, -1, -1, 288, -1, -1, -1, 556, + -1, -1, 295, 296, -1, -1, 94, -1, -1, -1, + 303, -1, 100, 101, 102, 103, -1, -1, -1, -1, + -1, 314, -1, 51, -1, 53, 54, 55, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2, -1, 4, 5, 6, 7, -1, -1, 51, - 52, -1, 13, 55, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 441, 442, 608, 70, 71, - 72, 73, 74, 75, 76, 77, -1, -1, 80, 81, - -1, -1, 458, -1, 86, 87, 88, 89, -1, -1, - -1, 52, -1, 469, -1, 56, -1, -1, 100, 101, - 102, 477, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 487, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 82, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, -1, 135, 136, 676, -1, -1, -1, -1, - -1, 143, 144, 519, -1, -1, -1, -1, -1, -1, - -1, -1, 528, 44, -1, -1, -1, -1, 119, -1, - -1, -1, -1, -1, -1, -1, 542, -1, 544, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 554, -1, + 128, 69, 119, 131, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 611, 348, 144, -1, -1, -1, + 353, -1, -1, 790, -1, -1, 94, -1, -1, -1, + 797, 798, 799, 101, 102, 103, -1, -1, 805, -1, + 373, -1, -1, -1, 811, 812, -1, -1, -1, -1, + 817, 818, -1, -1, 51, -1, 53, 54, 55, 56, + 128, 394, -1, -1, 831, -1, 399, 400, -1, 402, + -1, -1, 69, -1, -1, -1, 843, 844, -1, -1, + -1, -1, 679, -1, 851, -1, -1, -1, 85, -1, + -1, -1, -1, 210, -1, 862, 863, 94, -1, -1, + -1, -1, -1, 100, 101, 102, 103, -1, -1, 442, + 443, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 889, -1, -1, -1, 459, 894, -1, -1, + -1, 128, -1, -1, 131, -1, -1, 470, -1, -1, + -1, -1, -1, -1, -1, 478, -1, -1, -1, -1, + 917, -1, -1, -1, -1, 488, -1, -1, -1, -1, + 927, 928, -1, -1, 931, -1, -1, -1, 935, -1, + -1, 288, -1, -1, -1, -1, -1, -1, 295, 296, + -1, -1, -1, -1, -1, -1, 303, -1, 521, -1, + -1, -1, -1, 790, -1, -1, -1, 530, -1, -1, + 797, 798, 799, -1, -1, -1, -1, -1, 805, -1, + -1, 544, -1, 546, 811, 812, -1, -1, -1, -1, + 817, 818, -1, 556, -1, -1, -1, -1, 995, -1, + 997, 348, -1, 1000, 831, -1, 353, -1, -1, 2, + -1, 4, 5, 6, 7, -1, 843, 844, -1, -1, + 13, -1, -1, -1, 851, 51, 373, 53, 54, 55, + 56, -1, -1, -1, -1, 862, 863, -1, -1, -1, + -1, -1, -1, 69, -1, -1, -1, 394, 611, -1, + -1, -1, 399, -1, -1, 402, -1, -1, -1, 52, + -1, -1, 889, 56, -1, -1, -1, 894, 94, -1, + -1, -1, -1, -1, 100, 101, 102, 103, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, + 917, -1, -1, -1, -1, 442, 443, -1, -1, -1, + 927, 928, 128, -1, 931, 131, -1, -1, 935, -1, + -1, -1, 459, -1, 44, -1, 679, -1, -1, -1, + -1, -1, -1, 470, -1, -1, 119, -1, -1, -1, + -1, 478, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 488, 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, 995, -1, + 997, 101, -1, 1000, 521, -1, -1, -1, -1, -1, + -1, -1, -1, 530, -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, 556, + -1, -1, 142, -1, -1, -1, -1, 210, -1, -1, + 2, -1, 4, -1, -1, -1, -1, 790, -1, -1, + -1, -1, -1, -1, 797, 798, 799, -1, -1, -1, + -1, -1, 805, -1, -1, -1, -1, -1, 811, 812, + -1, -1, -1, -1, 817, 818, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 831, -1, + 52, -1, -1, 51, -1, 53, 54, 55, 56, -1, + 843, 844, -1, -1, -1, -1, -1, -1, 851, -1, + -1, 69, -1, -1, -1, 288, -1, -1, -1, 862, + 863, -1, 295, 296, -1, -1, -1, 85, -1, -1, + 303, -1, -1, -1, -1, -1, 94, -1, -1, -1, + -1, 314, 100, 101, 102, 103, 889, -1, -1, -1, + -1, 894, 679, -1, -1, -1, -1, 119, -1, 51, + -1, 53, 54, 55, 56, -1, -1, -1, -1, -1, + 128, -1, -1, 131, 917, 348, -1, 69, -1, -1, + 353, -1, -1, -1, 927, 928, -1, -1, 931, -1, + -1, -1, 935, 85, -1, -1, -1, -1, -1, -1, + 373, -1, 94, -1, -1, -1, -1, -1, 100, 101, + 102, 103, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 394, -1, -1, -1, -1, 399, 400, -1, -1, + -1, -1, -1, -1, -1, -1, 128, -1, -1, 131, + -1, -1, -1, -1, -1, -1, -1, -1, 210, -1, + -1, -1, 995, -1, 997, -1, -1, 1000, -1, -1, + -1, -1, -1, 790, -1, -1, -1, -1, -1, -1, + -1, 798, 799, -1, -1, -1, -1, -1, 805, -1, + -1, -1, -1, -1, 811, 812, 459, -1, -1, -1, + 817, 818, -1, -1, -1, -1, -1, 470, -1, -1, + -1, -1, -1, -1, 831, 478, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 488, 843, 844, -1, -1, + -1, -1, -1, -1, 851, -1, 288, -1, -1, -1, + -1, -1, -1, 295, 296, 862, 863, -1, -1, -1, + -1, 303, -1, -1, -1, -1, -1, -1, 521, -1, + -1, -1, -1, -1, -1, -1, -1, 530, -1, -1, + 72, 73, 74, 75, 76, 77, 78, -1, 80, 81, + -1, 544, -1, 546, -1, -1, 88, 89, -1, -1, + -1, -1, -1, 556, -1, -1, 348, -1, -1, 101, + 917, 353, -1, -1, -1, -1, -1, -1, -1, -1, + 927, 928, -1, -1, 931, -1, -1, -1, 935, -1, + 0, 373, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, -1, 13, 14, 15, -1, 17, 18, -1, + 20, -1, 394, -1, -1, -1, 26, 399, 611, -1, + 402, -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, 995, -1, + 997, -1, -1, 1000, -1, -1, -1, -1, -1, -1, + 442, 443, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, -1, -1, -1, 459, 88, 89, + 90, -1, 92, 93, -1, -1, 679, -1, 470, -1, + -1, 101, -1, -1, -1, 105, 478, -1, -1, -1, + -1, -1, -1, -1, -1, 115, 488, -1, 118, 119, + -1, 121, 122, -1, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, -1, -1, -1, -1, 138, 139, + 140, 44, 142, -1, -1, 145, 146, 147, 148, 521, + -1, -1, -1, -1, -1, -1, -1, -1, 530, -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, 556, 88, 89, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 101, -1, + -1, -1, -1, -1, -1, -1, -1, 790, -1, -1, + -1, -1, -1, -1, 797, 798, -1, -1, -1, 122, + -1, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, -1, -1, -1, 817, 818, -1, -1, -1, -1, + -1, -1, 72, 73, 74, 75, 76, 77, 831, 0, + 80, 81, -1, -1, -1, -1, -1, -1, 88, 89, + 843, 844, 13, 14, 15, -1, 17, 18, 851, 20, + -1, 101, -1, -1, -1, 26, -1, -1, -1, 862, + 863, -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, 889, 679, -1, -1, + -1, 894, -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, -1, - -1, -1, -1, -1, -1, -1, 2, -1, 4, -1, - 101, -1, -1, -1, -1, -1, -1, 13, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 122, 608, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 784, -1, -1, -1, -1, -1, 210, - 791, 792, 793, -1, -1, -1, 52, -1, 799, -1, - -1, -1, -1, -1, 805, 806, -1, -1, -1, -1, - 811, 812, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 825, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 837, 838, -1, -1, - 676, -1, -1, -1, 845, -1, -1, 2, -1, 4, - -1, -1, -1, -1, -1, 856, 857, -1, -1, -1, - -1, -1, -1, 119, -1, -1, 287, -1, -1, -1, - -1, -1, -1, 294, 295, -1, -1, -1, -1, -1, - -1, 302, 883, -1, -1, -1, -1, 888, -1, -1, - -1, -1, 313, -1, -1, -1, -1, 52, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 911, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 921, 922, -1, -1, 925, -1, 347, -1, 929, -1, - -1, 352, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 784, -1, - -1, 372, -1, -1, 210, 791, 792, 793, -1, -1, - -1, -1, -1, 799, 119, -1, -1, -1, -1, 805, - 806, -1, 393, -1, -1, 811, 812, 398, 399, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 989, 825, - 991, -1, -1, 994, -1, -1, -1, -1, -1, -1, - -1, 837, 838, -1, -1, -1, -1, -1, -1, 845, + 81, 82, 83, -1, -1, -1, -1, 88, 89, 90, + -1, 92, 93, -1, 927, 928, -1, -1, 931, -1, + 101, -1, 935, -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, 138, 139, 140, + -1, 142, -1, -1, 145, 146, 147, 148, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 856, 857, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 287, -1, -1, -1, -1, -1, 458, 294, 295, - -1, -1, -1, -1, -1, -1, 302, 883, 469, -1, - -1, -1, 888, -1, -1, 210, 477, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 487, -1, -1, -1, - -1, -1, -1, -1, -1, 911, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 921, 922, -1, -1, 925, - -1, 347, -1, 929, -1, -1, 352, -1, 519, -1, - -1, -1, -1, -1, -1, -1, -1, 528, -1, 72, - 73, 74, 75, 76, 77, 78, 372, 80, 81, -1, - -1, 542, -1, 544, -1, 88, 89, -1, -1, -1, - -1, -1, 287, 554, -1, -1, -1, 393, 101, 294, - 295, -1, 398, -1, -1, 401, -1, 302, -1, -1, - -1, -1, -1, 989, -1, 991, -1, -1, 994, -1, - -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, 441, 442, 608, -1, -1, - -1, -1, 347, -1, -1, -1, -1, 352, -1, -1, - -1, -1, 458, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 469, -1, -1, -1, 372, -1, -1, - -1, 477, -1, -1, 72, 73, 74, 75, 76, 77, - -1, 487, 80, 81, -1, -1, -1, -1, 393, -1, - 88, 89, -1, 398, -1, -1, 401, -1, -1, -1, - -1, -1, -1, 101, -1, 676, -1, -1, -1, -1, - -1, -1, -1, 519, -1, -1, -1, -1, -1, -1, - -1, -1, 528, -1, -1, -1, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 441, 442, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 554, -1, - -1, -1, -1, 458, 51, 52, -1, -1, 55, -1, - -1, -1, -1, -1, 469, -1, -1, -1, -1, -1, - -1, -1, 477, 70, 71, 72, 73, 74, 75, 76, - 77, -1, 487, 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, 784, 519, -1, -1, -1, -1, -1, - 791, 792, -1, 528, -1, -1, -1, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, -1, 135, 136, - 811, 812, -1, -1, -1, -1, 143, 144, -1, 554, - -1, -1, -1, -1, 825, -1, -1, -1, -1, 44, - -1, -1, -1, -1, -1, -1, 837, 838, -1, -1, - 676, -1, -1, -1, 845, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 856, 857, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, -1, + -1, -1, 995, -1, 997, -1, -1, 1000, 790, -1, + -1, -1, -1, -1, -1, -1, 798, 799, -1, -1, + -1, 51, 52, 805, -1, 55, -1, -1, -1, 811, + 812, -1, -1, -1, -1, 817, 818, -1, -1, -1, + 70, 71, 72, 73, 74, 75, 76, 77, -1, 831, + 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, + -1, 843, 844, -1, -1, -1, -1, -1, -1, 851, + 100, 101, 102, -1, -1, -1, -1, -1, -1, -1, + 862, 863, -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, 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, 883, -1, -1, -1, 101, 888, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 122, -1, 124, + -1, -1, -1, -1, -1, 917, 101, -1, -1, -1, + -1, -1, -1, -1, -1, 927, 928, -1, -1, -1, + -1, -1, -1, 935, -1, -1, -1, -1, -1, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, -1, - 921, 922, -1, -1, 925, -1, -1, -1, 929, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 676, -1, -1, -1, -1, -1, -1, 784, -1, - -1, -1, -1, -1, -1, -1, 792, 793, -1, -1, - -1, -1, -1, 799, -1, -1, -1, -1, -1, 805, - 806, -1, -1, -1, -1, 811, 812, -1, 72, 73, - 74, 75, 76, 77, -1, -1, 80, 81, 989, 825, - 991, -1, -1, 994, 88, 89, -1, -1, -1, -1, - -1, 837, 838, -1, -1, -1, -1, 101, -1, 845, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 856, 857, -1, -1, -1, -1, -1, -1, -1, -1, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 784, - -1, -1, -1, -1, -1, -1, -1, 792, 793, -1, - -1, -1, -1, -1, 799, -1, -1, -1, -1, -1, - 805, 806, -1, -1, -1, 911, 811, 812, -1, -1, - -1, -1, -1, -1, -1, 921, 922, -1, -1, 925, - 825, -1, -1, 929, -1, -1, -1, -1, -1, -1, - -1, -1, 837, 838, -1, -1, -1, -1, -1, -1, - 845, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 856, 857, -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, 989, -1, 991, -1, -1, 994, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 911, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 921, 922, -1, -1, - -1, -1, -1, -1, 929, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -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, 989, 39, 991, -1, -1, 994, - -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, 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, 995, 39, 997, -1, -1, 1000, -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, -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, - 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, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 57, -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, -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, -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, -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, 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, -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, -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, 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, 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, -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, 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, -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, + 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, -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, + -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, -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, -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, 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, -1, 37, 38, -1, 40, 41, 42, - 43, 44, -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, 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, 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, -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, 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, @@ -4368,42 +4722,22 @@ static const yytype_int16 yycheck[] = 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, 15, -1, - -1, 18, 19, -1, 21, 22, 23, 24, -1, -1, - -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, + 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, + -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, 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, @@ -4414,9 +4748,9 @@ static const yytype_int16 yycheck[] = 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, 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, 46, 47, + -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, @@ -4428,7 +4762,7 @@ static const yytype_int16 yycheck[] = -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, + 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, @@ -4438,22 +4772,22 @@ static const yytype_int16 yycheck[] = -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, + 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, -1, 39, -1, -1, -1, - -1, -1, 45, -1, 47, 48, 49, 50, 51, 52, + -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, -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, + -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, + 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, 59, 60, -1, -1, 63, @@ -4462,101 +4796,183 @@ static const yytype_int16 yycheck[] = 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, + 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, 145, 146, -1, 148, 30, 31, 32, 33, 34, + -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, + -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, -1, -1, 104, + 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, 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, + 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, 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, 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, -1, -1, -1, -1, -1, + -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, 45, -1, 47, 48, + 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, -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, + -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, -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, 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, 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, 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, + -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, 32, 33, 34, 35, 36, -1, -1, 39, -1, - -1, -1, -1, -1, 45, -1, 47, 48, 49, 50, + -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, -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, 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, + -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, 134, 135, 136, -1, 19, -1, 21, 22, - 23, 24, -1, -1, 146, -1, 148, 30, 31, 32, + -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, -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, 60, -1, -1, 63, - -1, -1, 66, 67, -1, 69, 70, 71, -1, -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, - 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, -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, -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, - 134, 135, 136, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 148, 3, 4, 5, 6, 7, + -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, + 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, @@ -4565,637 +4981,520 @@ static const yytype_int16 yycheck[] = -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, 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, -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, 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, - 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, 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, -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, 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, -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, 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, 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, -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, 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, -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, 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, -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, 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, + -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, 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, -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, - -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, -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, 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, 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, -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, 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, 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, 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, 70, 71, -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, 84, 85, -1, -1, -1, -1, -1, 91, -1, + -1, 94, 95, -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, 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, 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, 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, 24, -1, -1, -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, -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, 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, -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, 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, 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, -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, - 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, -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, 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, -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, 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, -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, 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, -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, 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, 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, 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, - 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, 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, 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, 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, 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, - 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, 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, 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, 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, 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, -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, 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, -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, - 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, -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, 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, -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, 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, -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, 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, -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, 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, -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, - 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, -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, 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, 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, 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, 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, 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, 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, -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, 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, -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, 70, 71, -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, 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, 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, -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, 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, + -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, 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, -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, 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, -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, 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, -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, 70, 71, -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, - 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, 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, -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, 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, 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, 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, -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, + 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, 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, -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, 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, 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, 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, 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, -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, 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, 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, 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, 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, + 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, - 100, 101, 102, -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, 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, 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, - 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, 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, 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, -1, -1, - 86, 87, 88, 89, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 100, 101, 102, -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, -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, 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, - 70, 71, 72, 73, 74, 75, 76, 77, -1, -1, - 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, + -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, - 100, 101, 102, -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, -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, 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, -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, - 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, -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, 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, -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, 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, 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, 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, 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, - 70, 71, 72, 73, 74, 75, 76, 77, -1, -1, - 80, 81, -1, -1, -1, -1, 86, 87, 88, 89, + -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, - 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, -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, 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, -1, -1, - -1, -1, -1, -1, -1, -1, 142, 72, 73, 74, + -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, 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, -1, -1, -1, -1, -1, -1, -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, -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, -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, + 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, -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, + 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, - 122, -1, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 72, 73, 74, 75, 76, 77, 78, 79, + -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, -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, + 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, + -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, -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, + 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, - -1, -1, -1, -1, -1, -1, -1, -1, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133 + 101, -1, -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 }; - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ static const yytype_int16 yystos[] = { 0, 150, 151, 0, 1, 3, 4, 5, 6, 7, @@ -5224,91 +5523,92 @@ static const yytype_int16 yystos[] = 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, 83, 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, 295, 63, 255, 257, 261, 262, 63, 256, 61, - 62, 63, 63, 101, 101, 154, 167, 167, 167, 167, - 159, 163, 163, 57, 121, 321, 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, + 51, 69, 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, 83, 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, 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, 295, 63, 255, 257, 261, 262, 63, + 256, 61, 62, 63, 63, 101, 101, 154, 167, 167, + 167, 167, 159, 163, 163, 57, 121, 57, 321, 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, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 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, 142, - 63, 157, 262, 189, 189, 51, 100, 226, 295, 319, - 319, 142, 172, 189, 15, 51, 282, 287, 304, 85, - 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, 321, 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 + 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, 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, 142, 63, 157, 262, 189, 189, 51, + 69, 100, 226, 295, 319, 319, 142, 172, 189, 15, + 51, 69, 282, 287, 304, 85, 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, 321, 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. */ +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int16 yyr1[] = { 0, 149, 151, 150, 152, 153, 153, 153, 153, 154, @@ -5339,43 +5639,43 @@ static const yytype_int16 yyr1[] = 190, 190, 190, 191, 191, 192, 192, 192, 193, 193, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 197, 196, 198, 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, 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, 280, 280, 281, 282, - 282, 283, 283, 284, 284, 285, 285, 286, 286, 287, - 287, 288, 288, 288, 288, 289, 289, 290, 290, 290, + 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, 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, 280, 280, + 281, 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, 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, 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 + 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, 304, 305, 305, 306, 307, 306, 308, 308, 309, + 309, 310, 310, 310, 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. */ +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 0, 2, 2, 1, 1, 3, 2, 1, @@ -5405,52 +5705,53 @@ static const yytype_int8 yyr2[] = 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, 1, 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, + 0, 2, 2, 1, 2, 1, 2, 1, 1, 2, + 3, 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, 1, 1, 1, 0, 0, + 4, 1, 1, 3, 5, 3, 1, 2, 4, 2, + 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, 1, 2, 1, 1, 0, 4, 1, 2, 1, + 3, 3, 3, 2, 2, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 0, 4, 1, - 1, 3, 5, 3, 1, 2, 4, 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, 1, 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, 1, 1, 0, - 1, 0, 2, 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 }; +enum { YYENOMEM = -2 }; + #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) @@ -5472,10 +5773,9 @@ static const yytype_int8 yyr2[] = } \ while (0) -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF /* Enable debugging if requested. */ @@ -5492,19 +5792,16 @@ do { \ YYFPRINTF Args; \ } while (0) -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ - Type, Value, p); \ + Kind, Value, p); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) @@ -5515,19 +5812,16 @@ do { \ `-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_state *p) +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, parser_state *p) { FILE *yyoutput = yyo; - YYUSE (yyoutput); - YYUSE (p); + YY_USE (yyoutput); + YY_USE (p); if (!yyvaluep) return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyo, yytoknum[yytype], *yyvaluep); -# endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -5537,12 +5831,13 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, pa `---------------------------*/ static void -yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, parser_state *p) +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, parser_state *p) { YYFPRINTF (yyo, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - yy_symbol_value_print (yyo, yytype, yyvaluep, p); + yy_symbol_value_print (yyo, yykind, yyvaluep, p); YYFPRINTF (yyo, ")"); } @@ -5575,7 +5870,8 @@ do { \ `------------------------------------------------*/ static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule, parser_state *p) +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, + int yyrule, parser_state *p) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; @@ -5587,9 +5883,8 @@ yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule, parser_state *p) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, - yystos[+yyssp[yyi + 1 - yynrhs]], - &yyvsp[(yyi + 1) - (yynrhs)] - , p); + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)], p); YYFPRINTF (stderr, "\n"); } } @@ -5604,8 +5899,8 @@ do { \ multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ @@ -5628,12 +5923,60 @@ int yydebug; #endif -#if YYERROR_VERBOSE +/* Context of a parse error. */ +typedef struct +{ + yy_state_t *yyssp; + yysymbol_kind_t yytoken; +} yypcontext_t; -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) -# else +/* Put in YYARG at most YYARGN of the expected tokens given the + current YYCTX, and return the number of tokens stored in YYARG. If + YYARG is null, return the number of expected tokens (guaranteed to + be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. + Return 0 if there are more than YYARGN expected tokens, yet fill + YYARG up to YYARGN. */ +static int +yypcontext_expected_tokens (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + int yyn = yypact[+*yyctx->yyssp]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (!yyarg) + ++yycount; + else if (yycount == yyargn) + return 0; + else + yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); + } + } + if (yyarg && yycount == 0 && 0 < yyargn) + yyarg[0] = YYSYMBOL_YYEMPTY; + return yycount; +} + + + + +#ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) +# else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) @@ -5643,13 +5986,13 @@ yystrlen (const char *yystr) continue; return yylen; } -# endif # endif +#endif -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else +#ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * @@ -5663,10 +6006,10 @@ yystpcpy (char *yydest, const char *yysrc) return yyd - 1; } -# endif # endif +#endif -# ifndef yytnamerr +#ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string @@ -5681,7 +6024,6 @@ yytnamerr (char *yyres, const char *yystr) { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; - for (;;) switch (*++yyp) { @@ -5715,31 +6057,15 @@ yytnamerr (char *yyres, const char *yystr) else return yystrlen (yystr); } -# endif +#endif -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ static int -yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, - yy_state_t *yyssp, int yytoken) +yy_syntax_error_arguments (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) { - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat: reported tokens (one for the "unexpected", - one per "expected"). */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Actual size of YYARG. */ int yycount = 0; - /* Cumulated lengths of YYARG. */ - YYPTRDIFF_T yysize = 0; - /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action @@ -5763,52 +6089,54 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ - if (yytoken != YYEMPTY) + if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { - int yyn = yypact[+*yyssp]; - YYPTRDIFF_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - yysize = yysize0; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYPTRDIFF_T yysize1 - = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return 2; - } - } - } + int yyn; + if (yyarg) + yyarg[yycount] = yyctx->yytoken; + ++yycount; + yyn = yypcontext_expected_tokens (yyctx, + yyarg ? yyarg + 1 : yyarg, yyargn - 1); + if (yyn == YYENOMEM) + return YYENOMEM; + else + yycount += yyn; } + return yycount; +} + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + const yypcontext_t *yyctx) +{ + enum { YYARGS_MAX = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + yysymbol_kind_t yyarg[YYARGS_MAX]; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; + + /* Actual size of YYARG. */ + int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); + if (yycount == YYENOMEM) + return YYENOMEM; switch (yycount) { -# define YYCASE_(N, S) \ +#define YYCASE_(N, S) \ case N: \ yyformat = S; \ - break + break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); @@ -5816,17 +6144,23 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ +#undef YYCASE_ } + /* Compute error message size. Don't count the "%s"s, but reserve + room for the terminator. */ + yysize = yystrlen (yyformat) - 2 * yycount + 1; { - /* Don't count the "%s"s in the final size, but reserve room for - the terminator. */ - YYPTRDIFF_T yysize1 = yysize + (yystrlen (yyformat) - 2 * yycount) + 1; - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return 2; + int yyi; + for (yyi = 0; yyi < yycount; ++yyi) + { + YYPTRDIFF_T yysize1 + = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return YYENOMEM; + } } if (*yymsg_alloc < yysize) @@ -5835,7 +6169,7 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; + return -1; } /* Avoid sprintf, as that infringes on the user's name space. @@ -5847,7 +6181,7 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { - yyp += yytnamerr (yyp, yyarg[yyi++]); + yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else @@ -5858,29 +6192,32 @@ yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, } return 0; } -#endif /* YYERROR_VERBOSE */ + /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_state *p) +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep, parser_state *p) { - YYUSE (yyvaluep); - YYUSE (p); + YY_USE (yyvaluep); + YY_USE (p); if (!yymsg) yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } + + /*----------. | yyparse. | `----------*/ @@ -5888,7 +6225,7 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_state *p) int yyparse (parser_state *p) { -/* The lookahead symbol. */ +/* Lookahead token kind. */ int yychar; @@ -5899,45 +6236,41 @@ YY_INITIAL_VALUE (static YYSTYPE yyval_default;) YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Number of syntax errors so far. */ - int yynerrs; + int yynerrs = 0; - yy_state_fast_t yystate; + yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. + int yyerrstatus = 0; - Refer to the stacks through separate pointers, to allow yyoverflow + /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ - /* The state stack. */ + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; + + /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss; - yy_state_t *yyssp; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; - /* The semantic value stack. */ + /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYPTRDIFF_T yystacksize; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; int yyn; + /* The return value of yyparse. */ int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; -#if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; -#endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) @@ -5945,16 +6278,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); Keep to zero when no symbol should be popped. */ int yylen = 0; - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; @@ -5976,10 +6303,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE - goto yyexhaustedlab; + YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ @@ -6007,7 +6335,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; @@ -6018,10 +6346,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) - goto yyexhaustedlab; + YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } @@ -6040,6 +6368,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + if (yystate == YYFINAL) YYACCEPT; @@ -6060,18 +6389,29 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (&yylval, p); } if (yychar <= YYEOF) { - yychar = yytoken = YYEOF; + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + goto yyerrlab1; + } else { yytoken = YYTRANSLATE (yychar); @@ -6140,87 +6480,87 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); YY_REDUCE_PRINT (yyn); switch (yyn) { - case 2: -#line 1614 "mrbgems/mruby-compiler/core/parse.y" + case 2: /* $@1: %empty */ +#line 1625 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; if (!p->locals) p->locals = cons(0,0); } -#line 6150 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6490 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 3: -#line 1619 "mrbgems/mruby-compiler/core/parse.y" + case 3: /* program: $@1 top_compstmt */ +#line 1630 "mrbgems/mruby-compiler/core/parse.y" { p->tree = new_scope(p, (yyvsp[0].nd)); NODE_LINENO(p->tree, (yyvsp[0].nd)); } -#line 6159 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6499 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 4: -#line 1626 "mrbgems/mruby-compiler/core/parse.y" + case 4: /* top_compstmt: top_stmts opt_terms */ +#line 1637 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6167 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6507 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 5: -#line 1632 "mrbgems/mruby-compiler/core/parse.y" + case 5: /* top_stmts: none */ +#line 1643 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 6175 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6515 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 6: -#line 1636 "mrbgems/mruby-compiler/core/parse.y" + case 6: /* top_stmts: top_stmt */ +#line 1647 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6184 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6524 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 7: -#line 1641 "mrbgems/mruby-compiler/core/parse.y" + case 7: /* top_stmts: top_stmts terms top_stmt */ +#line 1652 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6192 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6532 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 8: -#line 1645 "mrbgems/mruby-compiler/core/parse.y" + case 8: /* top_stmts: error top_stmt */ +#line 1656 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 6200 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6540 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 10: -#line 1652 "mrbgems/mruby-compiler/core/parse.y" + case 10: /* @2: %empty */ +#line 1663 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); nvars_block(p); } -#line 6209 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6549 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 11: -#line 1657 "mrbgems/mruby-compiler/core/parse.y" + case 11: /* top_stmt: keyword_BEGIN @2 '{' top_compstmt '}' */ +#line 1668 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "BEGIN not supported"); local_resume(p, (yyvsp[-3].nd)); nvars_unnest(p); (yyval.nd) = 0; } -#line 6220 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6560 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 12: -#line 1669 "mrbgems/mruby-compiler/core/parse.y" + case 12: /* bodystmt: compstmt opt_rescue opt_else opt_ensure */ +#line 1680 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-2].nd)) { (yyval.nd) = new_rescue(p, (yyvsp[-3].nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); @@ -6242,222 +6582,222 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } } } -#line 6246 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6586 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 13: -#line 1693 "mrbgems/mruby-compiler/core/parse.y" + case 13: /* compstmt: stmts opt_terms */ +#line 1704 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6254 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6594 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 14: -#line 1699 "mrbgems/mruby-compiler/core/parse.y" + case 14: /* stmts: none */ +#line 1710 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, 0); } -#line 6262 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6602 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 15: -#line 1703 "mrbgems/mruby-compiler/core/parse.y" + case 15: /* stmts: stmt */ +#line 1714 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6271 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6611 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 16: -#line 1708 "mrbgems/mruby-compiler/core/parse.y" + case 16: /* stmts: stmts terms stmt */ +#line 1719 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6279 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6619 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 17: -#line 1712 "mrbgems/mruby-compiler/core/parse.y" + case 17: /* stmts: error stmt */ +#line 1723 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); } -#line 6287 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6627 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 18: -#line 1717 "mrbgems/mruby-compiler/core/parse.y" + case 18: /* $@3: %empty */ +#line 1728 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 6293 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6633 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 19: -#line 1718 "mrbgems/mruby-compiler/core/parse.y" + case 19: /* stmt: keyword_alias fsym $@3 fsym */ +#line 1729 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_alias(p, (yyvsp[-2].id), (yyvsp[0].id)); } -#line 6301 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6641 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 20: -#line 1722 "mrbgems/mruby-compiler/core/parse.y" + case 20: /* stmt: keyword_undef undef_list */ +#line 1733 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6309 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6649 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 21: -#line 1726 "mrbgems/mruby-compiler/core/parse.y" + case 21: /* stmt: stmt modifier_if expr_value */ +#line 1737 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6317 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6657 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 22: -#line 1730 "mrbgems/mruby-compiler/core/parse.y" + case 22: /* stmt: stmt modifier_unless expr_value */ +#line 1741 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_unless(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6325 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6665 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 23: -#line 1734 "mrbgems/mruby-compiler/core/parse.y" + case 23: /* stmt: stmt modifier_while expr_value */ +#line 1745 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_while(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6333 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6673 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 24: -#line 1738 "mrbgems/mruby-compiler/core/parse.y" + case 24: /* stmt: stmt modifier_until expr_value */ +#line 1749 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_until(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6681 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 25: -#line 1742 "mrbgems/mruby-compiler/core/parse.y" + case 25: /* stmt: stmt modifier_rescue stmt */ +#line 1753 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6349 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6689 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 26: -#line 1746 "mrbgems/mruby-compiler/core/parse.y" + case 26: /* stmt: keyword_END '{' compstmt '}' */ +#line 1757 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "END not supported"); (yyval.nd) = new_postexe(p, (yyvsp[-1].nd)); } -#line 6358 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6698 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 28: -#line 1752 "mrbgems/mruby-compiler/core/parse.y" + case 28: /* stmt: mlhs '=' command_call */ +#line 1763 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6366 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6706 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 29: -#line 1756 "mrbgems/mruby-compiler/core/parse.y" + case 29: /* stmt: lhs '=' mrhs */ +#line 1767 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6374 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6714 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 30: -#line 1760 "mrbgems/mruby-compiler/core/parse.y" + case 30: /* stmt: mlhs '=' arg */ +#line 1771 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6382 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6722 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 31: -#line 1764 "mrbgems/mruby-compiler/core/parse.y" + case 31: /* stmt: mlhs '=' mrhs */ +#line 1775 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6390 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6730 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 32: -#line 1768 "mrbgems/mruby-compiler/core/parse.y" + case 32: /* stmt: arg "=>" "local variable or method" */ +#line 1779 "mrbgems/mruby-compiler/core/parse.y" { node *lhs = new_lvar(p, (yyvsp[0].id)); assignable(p, lhs); (yyval.nd) = new_asgn(p, lhs, (yyvsp[-2].nd)); } -#line 6400 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6740 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 34: -#line 1777 "mrbgems/mruby-compiler/core/parse.y" + case 34: /* command_asgn: lhs '=' command_rhs */ +#line 1788 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6408 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6748 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 35: -#line 1781 "mrbgems/mruby-compiler/core/parse.y" + case 35: /* command_asgn: var_lhs tOP_ASGN command_rhs */ +#line 1792 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6416 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6756 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 36: -#line 1785 "mrbgems/mruby-compiler/core/parse.y" + case 36: /* command_asgn: primary_value '[' opt_call_args ']' tOP_ASGN command_rhs */ +#line 1796 "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 6424 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6764 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 37: -#line 1789 "mrbgems/mruby-compiler/core/parse.y" + case 37: /* command_asgn: primary_value call_op "local variable or method" tOP_ASGN command_rhs */ +#line 1800 "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 6432 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6772 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 38: -#line 1793 "mrbgems/mruby-compiler/core/parse.y" + case 38: /* command_asgn: primary_value call_op "constant" tOP_ASGN command_rhs */ +#line 1804 "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 6440 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6780 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 39: -#line 1797 "mrbgems/mruby-compiler/core/parse.y" + case 39: /* command_asgn: primary_value "::" "constant" tOP_ASGN command_call */ +#line 1808 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = 0; } -#line 6449 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6789 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 40: -#line 1802 "mrbgems/mruby-compiler/core/parse.y" + case 40: /* command_asgn: primary_value "::" "local variable or method" tOP_ASGN command_rhs */ +#line 1813 "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 6457 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6797 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 41: -#line 1806 "mrbgems/mruby-compiler/core/parse.y" + case 41: /* command_asgn: defn_head f_opt_arglist_paren '=' command */ +#line 1817 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); endless_method_name(p, (yyvsp[-3].nd)); @@ -6466,11 +6806,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 6470 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6810 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 42: -#line 1815 "mrbgems/mruby-compiler/core/parse.y" + case 42: /* command_asgn: defn_head f_opt_arglist_paren '=' command modifier_rescue arg */ +#line 1826 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); endless_method_name(p, (yyvsp[-5].nd)); @@ -6479,11 +6819,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 6483 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6823 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 43: -#line 1824 "mrbgems/mruby-compiler/core/parse.y" + case 43: /* command_asgn: defs_head f_opt_arglist_paren '=' command */ +#line 1835 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); void_expr_error(p, (yyvsp[0].nd)); @@ -6492,11 +6832,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 6496 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6836 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 44: -#line 1833 "mrbgems/mruby-compiler/core/parse.y" + case 44: /* command_asgn: defs_head f_opt_arglist_paren '=' command modifier_rescue arg */ +#line 1844 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); void_expr_error(p, (yyvsp[-2].nd)); @@ -6505,79 +6845,79 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 6509 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6849 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 45: -#line 1842 "mrbgems/mruby-compiler/core/parse.y" + case 45: /* command_asgn: backref tOP_ASGN command_rhs */ +#line 1853 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 6518 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6858 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 47: -#line 1850 "mrbgems/mruby-compiler/core/parse.y" + case 47: /* command_rhs: command_call modifier_rescue stmt */ +#line 1861 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6526 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6866 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 50: -#line 1859 "mrbgems/mruby-compiler/core/parse.y" + case 50: /* expr: expr keyword_and expr */ +#line 1870 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6534 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6874 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 51: -#line 1863 "mrbgems/mruby-compiler/core/parse.y" + case 51: /* expr: expr keyword_or expr */ +#line 1874 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6542 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6882 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 52: -#line 1867 "mrbgems/mruby-compiler/core/parse.y" + case 52: /* expr: keyword_not opt_nl expr */ +#line 1878 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6550 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6890 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 53: -#line 1871 "mrbgems/mruby-compiler/core/parse.y" + case 53: /* expr: '!' command_call */ +#line 1882 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6558 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6898 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 55: -#line 1879 "mrbgems/mruby-compiler/core/parse.y" + case 55: /* defn_head: keyword_def fname */ +#line 1890 "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 6569 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6909 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 56: -#line 1888 "mrbgems/mruby-compiler/core/parse.y" + case 56: /* $@4: %empty */ +#line 1899 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_FNAME; } -#line 6577 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6917 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 57: -#line 1892 "mrbgems/mruby-compiler/core/parse.y" + case 57: /* defs_head: keyword_def singleton dot_or_colon $@4 fname */ +#line 1903 "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; @@ -6586,1054 +6926,1054 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_block(p); p->lstate = EXPR_ENDFN; /* force for args */ } -#line 6590 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6930 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 58: -#line 1903 "mrbgems/mruby-compiler/core/parse.y" + case 58: /* expr_value: expr */ +#line 1914 "mrbgems/mruby-compiler/core/parse.y" { if (!(yyvsp[0].nd)) (yyval.nd) = new_nil(p); else { (yyval.nd) = (yyvsp[0].nd); } } -#line 6601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6941 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 62: -#line 1917 "mrbgems/mruby-compiler/core/parse.y" + case 62: /* block_command: block_call call_op2 operation2 command_args */ +#line 1928 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6609 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6949 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 63: -#line 1923 "mrbgems/mruby-compiler/core/parse.y" + case 63: /* $@5: %empty */ +#line 1934 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); } -#line 6618 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6958 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 64: -#line 1930 "mrbgems/mruby-compiler/core/parse.y" + case 64: /* cmd_brace_block: "{" $@5 opt_block_param compstmt '}' */ +#line 1941 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p, (yyvsp[-2].nd), (yyvsp[-1].nd)); local_unnest(p); nvars_unnest(p); } -#line 6628 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6968 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 65: -#line 1938 "mrbgems/mruby-compiler/core/parse.y" + case 65: /* command: operation command_args */ +#line 1949 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6636 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6976 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 66: -#line 1942 "mrbgems/mruby-compiler/core/parse.y" + case 66: /* command: operation command_args cmd_brace_block */ +#line 1953 "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 6645 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6985 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 67: -#line 1947 "mrbgems/mruby-compiler/core/parse.y" + case 67: /* command: primary_value call_op operation2 command_args */ +#line 1958 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6653 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6993 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 68: -#line 1951 "mrbgems/mruby-compiler/core/parse.y" + case 68: /* command: primary_value call_op operation2 command_args cmd_brace_block */ +#line 1962 "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 6662 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7002 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 69: -#line 1956 "mrbgems/mruby-compiler/core/parse.y" + case 69: /* command: primary_value "::" operation2 command_args */ +#line 1967 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 6670 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7010 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 70: -#line 1960 "mrbgems/mruby-compiler/core/parse.y" + case 70: /* command: primary_value "::" operation2 command_args cmd_brace_block */ +#line 1971 "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 6679 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7019 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 71: -#line 1965 "mrbgems/mruby-compiler/core/parse.y" + case 71: /* command: keyword_super command_args */ +#line 1976 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 6687 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7027 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 72: -#line 1969 "mrbgems/mruby-compiler/core/parse.y" + case 72: /* command: keyword_yield command_args */ +#line 1980 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 6695 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7035 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 73: -#line 1973 "mrbgems/mruby-compiler/core/parse.y" + case 73: /* command: keyword_return call_args */ +#line 1984 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, ret_args(p, (yyvsp[0].nd))); } -#line 6703 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7043 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 74: -#line 1977 "mrbgems/mruby-compiler/core/parse.y" + case 74: /* command: keyword_break call_args */ +#line 1988 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, ret_args(p, (yyvsp[0].nd))); } -#line 6711 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7051 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 75: -#line 1981 "mrbgems/mruby-compiler/core/parse.y" + case 75: /* command: keyword_next call_args */ +#line 1992 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, ret_args(p, (yyvsp[0].nd))); } -#line 6719 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7059 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 76: -#line 1987 "mrbgems/mruby-compiler/core/parse.y" + case 76: /* mlhs: mlhs_basic */ +#line 1998 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6727 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7067 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 77: -#line 1991 "mrbgems/mruby-compiler/core/parse.y" + case 77: /* mlhs: tLPAREN mlhs_inner rparen */ +#line 2002 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6735 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7075 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 79: -#line 1998 "mrbgems/mruby-compiler/core/parse.y" + case 79: /* mlhs_inner: tLPAREN mlhs_inner rparen */ +#line 2009 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 6743 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7083 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 80: -#line 2004 "mrbgems/mruby-compiler/core/parse.y" + case 80: /* mlhs_basic: mlhs_list */ +#line 2015 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 6751 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7091 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 81: -#line 2008 "mrbgems/mruby-compiler/core/parse.y" + case 81: /* mlhs_basic: mlhs_list mlhs_item */ +#line 2019 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(push((yyvsp[-1].nd),(yyvsp[0].nd))); } -#line 6759 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7099 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 82: -#line 2012 "mrbgems/mruby-compiler/core/parse.y" + case 82: /* mlhs_basic: mlhs_list "*" mlhs_node */ +#line 2023 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6767 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7107 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 83: -#line 2016 "mrbgems/mruby-compiler/core/parse.y" + case 83: /* mlhs_basic: mlhs_list "*" mlhs_node ',' mlhs_post */ +#line 2027 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-4].nd), (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6775 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7115 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 84: -#line 2020 "mrbgems/mruby-compiler/core/parse.y" + case 84: /* mlhs_basic: mlhs_list "*" */ +#line 2031 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2((yyvsp[-1].nd), new_nil(p)); } -#line 6783 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7123 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 85: -#line 2024 "mrbgems/mruby-compiler/core/parse.y" + case 85: /* mlhs_basic: mlhs_list "*" ',' mlhs_post */ +#line 2035 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-3].nd), new_nil(p), (yyvsp[0].nd)); } -#line 6791 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7131 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 86: -#line 2028 "mrbgems/mruby-compiler/core/parse.y" + case 86: /* mlhs_basic: "*" mlhs_node */ +#line 2039 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2(0, (yyvsp[0].nd)); } -#line 6799 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7139 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 87: -#line 2032 "mrbgems/mruby-compiler/core/parse.y" + case 87: /* mlhs_basic: "*" mlhs_node ',' mlhs_post */ +#line 2043 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6807 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7147 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 88: -#line 2036 "mrbgems/mruby-compiler/core/parse.y" + case 88: /* mlhs_basic: "*" */ +#line 2047 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list2(0, new_nil(p)); } -#line 6815 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7155 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 89: -#line 2040 "mrbgems/mruby-compiler/core/parse.y" + case 89: /* mlhs_basic: "*" ',' mlhs_post */ +#line 2051 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_nil(p), (yyvsp[0].nd)); } -#line 6823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7163 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 91: -#line 2047 "mrbgems/mruby-compiler/core/parse.y" + case 91: /* mlhs_item: tLPAREN mlhs_inner rparen */ +#line 2058 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_masgn(p, (yyvsp[-1].nd), NULL); } -#line 6831 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7171 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 92: -#line 2053 "mrbgems/mruby-compiler/core/parse.y" + case 92: /* mlhs_list: mlhs_item ',' */ +#line 2064 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[-1].nd)); } -#line 6839 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7179 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 93: -#line 2057 "mrbgems/mruby-compiler/core/parse.y" + case 93: /* mlhs_list: mlhs_list mlhs_item ',' */ +#line 2068 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[-1].nd)); } -#line 6847 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7187 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 94: -#line 2063 "mrbgems/mruby-compiler/core/parse.y" + case 94: /* mlhs_post: mlhs_item */ +#line 2074 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 6855 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7195 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 95: -#line 2067 "mrbgems/mruby-compiler/core/parse.y" + case 95: /* mlhs_post: mlhs_list mlhs_item */ +#line 2078 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 6863 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7203 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 96: -#line 2073 "mrbgems/mruby-compiler/core/parse.y" + case 96: /* mlhs_node: variable */ +#line 2084 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 6871 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7211 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 97: -#line 2077 "mrbgems/mruby-compiler/core/parse.y" + case 97: /* mlhs_node: primary_value '[' opt_call_args ']' */ +#line 2088 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 6879 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7219 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 98: -#line 2081 "mrbgems/mruby-compiler/core/parse.y" + case 98: /* mlhs_node: primary_value call_op "local variable or method" */ +#line 2092 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6887 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7227 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 99: -#line 2085 "mrbgems/mruby-compiler/core/parse.y" + case 99: /* mlhs_node: primary_value "::" "local variable or method" */ +#line 2096 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 6895 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7235 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 100: -#line 2089 "mrbgems/mruby-compiler/core/parse.y" + case 100: /* mlhs_node: primary_value call_op "constant" */ +#line 2100 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6903 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7243 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 101: -#line 2093 "mrbgems/mruby-compiler/core/parse.y" + case 101: /* mlhs_node: primary_value "::" "constant" */ +#line 2104 "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 6913 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7253 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 102: -#line 2099 "mrbgems/mruby-compiler/core/parse.y" + case 102: /* mlhs_node: tCOLON3 "constant" */ +#line 2110 "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 6923 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7263 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 103: -#line 2105 "mrbgems/mruby-compiler/core/parse.y" + case 103: /* mlhs_node: backref */ +#line 2116 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 6932 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7272 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 104: -#line 2112 "mrbgems/mruby-compiler/core/parse.y" + case 104: /* lhs: variable */ +#line 2123 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 6940 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7280 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 105: -#line 2116 "mrbgems/mruby-compiler/core/parse.y" + case 105: /* lhs: primary_value '[' opt_call_args ']' */ +#line 2127 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 6948 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7288 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 106: -#line 2120 "mrbgems/mruby-compiler/core/parse.y" + case 106: /* lhs: primary_value call_op "local variable or method" */ +#line 2131 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6956 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7296 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 107: -#line 2124 "mrbgems/mruby-compiler/core/parse.y" + case 107: /* lhs: primary_value "::" "local variable or method" */ +#line 2135 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 6964 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7304 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 108: -#line 2128 "mrbgems/mruby-compiler/core/parse.y" + case 108: /* lhs: primary_value call_op "constant" */ +#line 2139 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 6972 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7312 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 109: -#line 2132 "mrbgems/mruby-compiler/core/parse.y" + case 109: /* lhs: primary_value "::" "constant" */ +#line 2143 "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 6982 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7322 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 110: -#line 2138 "mrbgems/mruby-compiler/core/parse.y" + case 110: /* lhs: tCOLON3 "constant" */ +#line 2149 "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 6992 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7332 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 111: -#line 2144 "mrbgems/mruby-compiler/core/parse.y" + case 111: /* lhs: backref */ +#line 2155 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 7001 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7341 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 112: -#line 2149 "mrbgems/mruby-compiler/core/parse.y" + case 112: /* lhs: "numbered parameter" */ +#line 2160 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 7009 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7349 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 113: -#line 2155 "mrbgems/mruby-compiler/core/parse.y" + case 113: /* cname: "local variable or method" */ +#line 2166 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "class/module name must be CONSTANT"); } -#line 7017 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7357 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 115: -#line 2162 "mrbgems/mruby-compiler/core/parse.y" + case 115: /* cpath: tCOLON3 cname */ +#line 2173 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(nint(1), nsym((yyvsp[0].id))); } -#line 7025 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7365 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 116: -#line 2166 "mrbgems/mruby-compiler/core/parse.y" + case 116: /* cpath: cname */ +#line 2177 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(nint(0), nsym((yyvsp[0].id))); } -#line 7033 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7373 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 117: -#line 2170 "mrbgems/mruby-compiler/core/parse.y" + case 117: /* cpath: primary_value "::" cname */ +#line 2181 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = cons((yyvsp[-2].nd), nsym((yyvsp[0].id))); } -#line 7042 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7382 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 121: -#line 2180 "mrbgems/mruby-compiler/core/parse.y" + case 121: /* fname: op */ +#line 2191 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7051 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7391 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 122: -#line 2185 "mrbgems/mruby-compiler/core/parse.y" + case 122: /* fname: reswords */ +#line 2196 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7060 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7400 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 125: -#line 2196 "mrbgems/mruby-compiler/core/parse.y" + case 125: /* undef_list: fsym */ +#line 2207 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_undef(p, (yyvsp[0].id)); } -#line 7068 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7408 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 126: -#line 2199 "mrbgems/mruby-compiler/core/parse.y" + case 126: /* $@6: %empty */ +#line 2210 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 7074 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7414 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 127: -#line 2200 "mrbgems/mruby-compiler/core/parse.y" + case 127: /* undef_list: undef_list ',' $@6 fsym */ +#line 2211 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), nsym((yyvsp[0].id))); } -#line 7082 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7422 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 128: -#line 2205 "mrbgems/mruby-compiler/core/parse.y" + case 128: /* op: '|' */ +#line 2216 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(or); } -#line 7088 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7428 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 129: -#line 2206 "mrbgems/mruby-compiler/core/parse.y" + case 129: /* op: '^' */ +#line 2217 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(xor); } -#line 7094 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7434 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 130: -#line 2207 "mrbgems/mruby-compiler/core/parse.y" + case 130: /* op: '&' */ +#line 2218 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 7100 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7440 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 131: -#line 2208 "mrbgems/mruby-compiler/core/parse.y" + case 131: /* op: "<=>" */ +#line 2219 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(cmp); } -#line 7106 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7446 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 132: -#line 2209 "mrbgems/mruby-compiler/core/parse.y" + case 132: /* op: "==" */ +#line 2220 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eq); } -#line 7112 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7452 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 133: -#line 2210 "mrbgems/mruby-compiler/core/parse.y" + case 133: /* op: "===" */ +#line 2221 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eqq); } -#line 7118 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7458 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 134: -#line 2211 "mrbgems/mruby-compiler/core/parse.y" + case 134: /* op: "=~" */ +#line 2222 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(match); } -#line 7124 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7464 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 135: -#line 2212 "mrbgems/mruby-compiler/core/parse.y" + case 135: /* op: "!~" */ +#line 2223 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(nmatch); } -#line 7130 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7470 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 136: -#line 2213 "mrbgems/mruby-compiler/core/parse.y" + case 136: /* op: '>' */ +#line 2224 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(gt); } -#line 7136 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7476 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 137: -#line 2214 "mrbgems/mruby-compiler/core/parse.y" + case 137: /* op: ">=" */ +#line 2225 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(ge); } -#line 7142 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7482 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 138: -#line 2215 "mrbgems/mruby-compiler/core/parse.y" + case 138: /* op: '<' */ +#line 2226 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lt); } -#line 7148 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7488 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 139: -#line 2216 "mrbgems/mruby-compiler/core/parse.y" + case 139: /* op: "<=" */ +#line 2227 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(le); } -#line 7154 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7494 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 140: -#line 2217 "mrbgems/mruby-compiler/core/parse.y" + case 140: /* op: "!=" */ +#line 2228 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neq); } -#line 7160 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7500 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 141: -#line 2218 "mrbgems/mruby-compiler/core/parse.y" + case 141: /* op: "<<" */ +#line 2229 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lshift); } -#line 7166 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7506 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 142: -#line 2219 "mrbgems/mruby-compiler/core/parse.y" + case 142: /* op: ">>" */ +#line 2230 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(rshift); } -#line 7172 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7512 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 143: -#line 2220 "mrbgems/mruby-compiler/core/parse.y" + case 143: /* op: '+' */ +#line 2231 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(add); } -#line 7178 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7518 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 144: -#line 2221 "mrbgems/mruby-compiler/core/parse.y" + case 144: /* op: '-' */ +#line 2232 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(sub); } -#line 7184 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7524 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 145: -#line 2222 "mrbgems/mruby-compiler/core/parse.y" + case 145: /* op: '*' */ +#line 2233 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7190 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7530 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 146: -#line 2223 "mrbgems/mruby-compiler/core/parse.y" + case 146: /* op: "*" */ +#line 2234 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7196 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7536 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 147: -#line 2224 "mrbgems/mruby-compiler/core/parse.y" + case 147: /* op: '/' */ +#line 2235 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(div); } -#line 7202 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7542 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 148: -#line 2225 "mrbgems/mruby-compiler/core/parse.y" + case 148: /* op: '%' */ +#line 2236 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mod); } -#line 7208 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7548 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 149: -#line 2226 "mrbgems/mruby-compiler/core/parse.y" + case 149: /* op: tPOW */ +#line 2237 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7214 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7554 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 150: -#line 2227 "mrbgems/mruby-compiler/core/parse.y" + case 150: /* op: "**" */ +#line 2238 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7220 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7560 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 151: -#line 2228 "mrbgems/mruby-compiler/core/parse.y" + case 151: /* op: '!' */ +#line 2239 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(not); } -#line 7226 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7566 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 152: -#line 2229 "mrbgems/mruby-compiler/core/parse.y" + case 152: /* op: '~' */ +#line 2240 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neg); } -#line 7232 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7572 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 153: -#line 2230 "mrbgems/mruby-compiler/core/parse.y" + case 153: /* op: "unary plus" */ +#line 2241 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(plus); } -#line 7238 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7578 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 154: -#line 2231 "mrbgems/mruby-compiler/core/parse.y" + case 154: /* op: "unary minus" */ +#line 2242 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(minus); } -#line 7244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7584 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 155: -#line 2232 "mrbgems/mruby-compiler/core/parse.y" + case 155: /* op: tAREF */ +#line 2243 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aref); } -#line 7250 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7590 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 156: -#line 2233 "mrbgems/mruby-compiler/core/parse.y" + case 156: /* op: tASET */ +#line 2244 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aset); } -#line 7256 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7596 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 157: -#line 2234 "mrbgems/mruby-compiler/core/parse.y" + case 157: /* op: '`' */ +#line 2245 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(tick); } -#line 7262 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7602 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 198: -#line 2252 "mrbgems/mruby-compiler/core/parse.y" + case 198: /* arg: lhs '=' arg_rhs */ +#line 2263 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7270 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7610 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 199: -#line 2256 "mrbgems/mruby-compiler/core/parse.y" + case 199: /* arg: var_lhs tOP_ASGN arg_rhs */ +#line 2267 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7278 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7618 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 200: -#line 2260 "mrbgems/mruby-compiler/core/parse.y" + case 200: /* arg: primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs */ +#line 2271 "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 7286 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7626 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 201: -#line 2264 "mrbgems/mruby-compiler/core/parse.y" + case 201: /* arg: primary_value call_op "local variable or method" tOP_ASGN arg_rhs */ +#line 2275 "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 7294 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7634 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 202: -#line 2268 "mrbgems/mruby-compiler/core/parse.y" + case 202: /* arg: primary_value call_op "constant" tOP_ASGN arg_rhs */ +#line 2279 "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 7302 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7642 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 203: -#line 2272 "mrbgems/mruby-compiler/core/parse.y" + case 203: /* arg: primary_value "::" "local variable or method" tOP_ASGN arg_rhs */ +#line 2283 "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 7310 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7650 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 204: -#line 2276 "mrbgems/mruby-compiler/core/parse.y" + case 204: /* arg: primary_value "::" "constant" tOP_ASGN arg_rhs */ +#line 2287 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7319 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7659 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 205: -#line 2281 "mrbgems/mruby-compiler/core/parse.y" + case 205: /* arg: tCOLON3 "constant" tOP_ASGN arg_rhs */ +#line 2292 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7328 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7668 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 206: -#line 2286 "mrbgems/mruby-compiler/core/parse.y" + case 206: /* arg: backref tOP_ASGN arg_rhs */ +#line 2297 "mrbgems/mruby-compiler/core/parse.y" { backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 7337 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7677 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 207: -#line 2291 "mrbgems/mruby-compiler/core/parse.y" + case 207: /* arg: arg ".." arg */ +#line 2302 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7345 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7685 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 208: -#line 2295 "mrbgems/mruby-compiler/core/parse.y" + case 208: /* arg: arg ".." */ +#line 2306 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7353 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7693 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 209: -#line 2299 "mrbgems/mruby-compiler/core/parse.y" + case 209: /* arg: tBDOT2 arg */ +#line 2310 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot2(p, new_nil(p), (yyvsp[0].nd)); } -#line 7361 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7701 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 210: -#line 2303 "mrbgems/mruby-compiler/core/parse.y" + case 210: /* arg: arg "..." arg */ +#line 2314 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7369 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7709 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 211: -#line 2307 "mrbgems/mruby-compiler/core/parse.y" + case 211: /* arg: arg "..." */ +#line 2318 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7377 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7717 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 212: -#line 2311 "mrbgems/mruby-compiler/core/parse.y" + case 212: /* arg: tBDOT3 arg */ +#line 2322 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dot3(p, new_nil(p), (yyvsp[0].nd)); } -#line 7385 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7725 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 213: -#line 2315 "mrbgems/mruby-compiler/core/parse.y" + case 213: /* arg: arg '+' arg */ +#line 2326 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "+", (yyvsp[0].nd)); } -#line 7393 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7733 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 214: -#line 2319 "mrbgems/mruby-compiler/core/parse.y" + case 214: /* arg: arg '-' arg */ +#line 2330 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "-", (yyvsp[0].nd)); } -#line 7401 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7741 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 215: -#line 2323 "mrbgems/mruby-compiler/core/parse.y" + case 215: /* arg: arg '*' arg */ +#line 2334 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "*", (yyvsp[0].nd)); } -#line 7409 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7749 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 216: -#line 2327 "mrbgems/mruby-compiler/core/parse.y" + case 216: /* arg: arg '/' arg */ +#line 2338 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "/", (yyvsp[0].nd)); } -#line 7417 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7757 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 217: -#line 2331 "mrbgems/mruby-compiler/core/parse.y" + case 217: /* arg: arg '%' arg */ +#line 2342 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "%", (yyvsp[0].nd)); } -#line 7425 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7765 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 218: -#line 2335 "mrbgems/mruby-compiler/core/parse.y" + case 218: /* arg: arg tPOW arg */ +#line 2346 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)); } -#line 7433 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7773 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 219: -#line 2339 "mrbgems/mruby-compiler/core/parse.y" + case 219: /* arg: tUMINUS_NUM "integer literal" tPOW arg */ +#line 2350 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7441 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7781 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 220: -#line 2343 "mrbgems/mruby-compiler/core/parse.y" + case 220: /* arg: tUMINUS_NUM "float literal" tPOW arg */ +#line 2354 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7449 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7789 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 221: -#line 2347 "mrbgems/mruby-compiler/core/parse.y" + case 221: /* arg: "unary plus" arg */ +#line 2358 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "+@"); } -#line 7457 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7797 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 222: -#line 2351 "mrbgems/mruby-compiler/core/parse.y" + case 222: /* arg: "unary minus" arg */ +#line 2362 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 7465 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7805 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 223: -#line 2355 "mrbgems/mruby-compiler/core/parse.y" + case 223: /* arg: arg '|' arg */ +#line 2366 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "|", (yyvsp[0].nd)); } -#line 7473 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7813 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 224: -#line 2359 "mrbgems/mruby-compiler/core/parse.y" + case 224: /* arg: arg '^' arg */ +#line 2370 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "^", (yyvsp[0].nd)); } -#line 7481 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7821 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 225: -#line 2363 "mrbgems/mruby-compiler/core/parse.y" + case 225: /* arg: arg '&' arg */ +#line 2374 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "&", (yyvsp[0].nd)); } -#line 7489 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7829 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 226: -#line 2367 "mrbgems/mruby-compiler/core/parse.y" + case 226: /* arg: arg "<=>" arg */ +#line 2378 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=>", (yyvsp[0].nd)); } -#line 7497 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7837 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 227: -#line 2371 "mrbgems/mruby-compiler/core/parse.y" + case 227: /* arg: arg '>' arg */ +#line 2382 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">", (yyvsp[0].nd)); } -#line 7505 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7845 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 228: -#line 2375 "mrbgems/mruby-compiler/core/parse.y" + case 228: /* arg: arg ">=" arg */ +#line 2386 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">=", (yyvsp[0].nd)); } -#line 7513 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7853 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 229: -#line 2379 "mrbgems/mruby-compiler/core/parse.y" + case 229: /* arg: arg '<' arg */ +#line 2390 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<", (yyvsp[0].nd)); } -#line 7521 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7861 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 230: -#line 2383 "mrbgems/mruby-compiler/core/parse.y" + case 230: /* arg: arg "<=" arg */ +#line 2394 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=", (yyvsp[0].nd)); } -#line 7529 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7869 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 231: -#line 2387 "mrbgems/mruby-compiler/core/parse.y" + case 231: /* arg: arg "==" arg */ +#line 2398 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "==", (yyvsp[0].nd)); } -#line 7537 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7877 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 232: -#line 2391 "mrbgems/mruby-compiler/core/parse.y" + case 232: /* arg: arg "===" arg */ +#line 2402 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "===", (yyvsp[0].nd)); } -#line 7545 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7885 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 233: -#line 2395 "mrbgems/mruby-compiler/core/parse.y" + case 233: /* arg: arg "!=" arg */ +#line 2406 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!=", (yyvsp[0].nd)); } -#line 7553 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7893 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 234: -#line 2399 "mrbgems/mruby-compiler/core/parse.y" + case 234: /* arg: arg "=~" arg */ +#line 2410 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "=~", (yyvsp[0].nd)); } -#line 7561 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7901 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 235: -#line 2403 "mrbgems/mruby-compiler/core/parse.y" + case 235: /* arg: arg "!~" arg */ +#line 2414 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!~", (yyvsp[0].nd)); } -#line 7569 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7909 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 236: -#line 2407 "mrbgems/mruby-compiler/core/parse.y" + case 236: /* arg: '!' arg */ +#line 2418 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 7577 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7917 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 237: -#line 2411 "mrbgems/mruby-compiler/core/parse.y" + case 237: /* arg: '~' arg */ +#line 2422 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "~"); } -#line 7585 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7925 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 238: -#line 2415 "mrbgems/mruby-compiler/core/parse.y" + case 238: /* arg: arg "<<" arg */ +#line 2426 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<<", (yyvsp[0].nd)); } -#line 7593 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7933 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 239: -#line 2419 "mrbgems/mruby-compiler/core/parse.y" + case 239: /* arg: arg ">>" arg */ +#line 2430 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">>", (yyvsp[0].nd)); } -#line 7601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7941 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 240: -#line 2423 "mrbgems/mruby-compiler/core/parse.y" + case 240: /* arg: arg "&&" arg */ +#line 2434 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7609 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7949 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 241: -#line 2427 "mrbgems/mruby-compiler/core/parse.y" + case 241: /* arg: arg "||" arg */ +#line 2438 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7617 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7957 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 242: -#line 2431 "mrbgems/mruby-compiler/core/parse.y" + case 242: /* arg: arg '?' arg opt_nl ':' arg */ +#line 2442 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7625 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7965 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 243: -#line 2435 "mrbgems/mruby-compiler/core/parse.y" + case 243: /* arg: arg '?' arg opt_nl "label" arg */ +#line 2446 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7633 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7973 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 244: -#line 2439 "mrbgems/mruby-compiler/core/parse.y" + case 244: /* arg: defn_head f_opt_arglist_paren '=' arg */ +#line 2450 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); endless_method_name(p, (yyvsp[-3].nd)); @@ -7642,11 +7982,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 7646 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7986 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 245: -#line 2448 "mrbgems/mruby-compiler/core/parse.y" + case 245: /* arg: defn_head f_opt_arglist_paren '=' arg modifier_rescue arg */ +#line 2459 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); endless_method_name(p, (yyvsp[-5].nd)); @@ -7655,11 +7995,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 7659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7999 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 246: -#line 2457 "mrbgems/mruby-compiler/core/parse.y" + case 246: /* arg: defs_head f_opt_arglist_paren '=' arg */ +#line 2468 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); void_expr_error(p, (yyvsp[0].nd)); @@ -7668,11 +8008,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 7672 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8012 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 247: -#line 2466 "mrbgems/mruby-compiler/core/parse.y" + case 247: /* arg: defs_head f_opt_arglist_paren '=' arg modifier_rescue arg */ +#line 2477 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); void_expr_error(p, (yyvsp[-2].nd)); @@ -7681,70 +8021,70 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 7685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8025 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 248: -#line 2475 "mrbgems/mruby-compiler/core/parse.y" + case 248: /* arg: primary */ +#line 2486 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7693 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8033 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 250: -#line 2482 "mrbgems/mruby-compiler/core/parse.y" + case 250: /* aref_args: args trailer */ +#line 2493 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7702 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8042 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 251: -#line 2487 "mrbgems/mruby-compiler/core/parse.y" + case 251: /* aref_args: args comma assocs trailer */ +#line 2498 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), new_hash(p, (yyvsp[-1].nd))); } -#line 7710 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8050 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 252: -#line 2491 "mrbgems/mruby-compiler/core/parse.y" + case 252: /* aref_args: assocs trailer */ +#line 2502 "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 7719 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8059 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 253: -#line 2498 "mrbgems/mruby-compiler/core/parse.y" + case 253: /* arg_rhs: arg */ +#line 2509 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7727 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8067 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 254: -#line 2502 "mrbgems/mruby-compiler/core/parse.y" + case 254: /* arg_rhs: arg modifier_rescue arg */ +#line 2513 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7736 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8076 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 255: -#line 2509 "mrbgems/mruby-compiler/core/parse.y" + case 255: /* paren_args: '(' opt_call_args ')' */ +#line 2520 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 7744 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8084 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 256: -#line 2513 "mrbgems/mruby-compiler/core/parse.y" + case 256: /* paren_args: '(' args comma tBDOT3 rparen */ +#line 2524 "mrbgems/mruby-compiler/core/parse.y" { mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); @@ -7753,11 +8093,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 7757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8097 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 257: -#line 2522 "mrbgems/mruby-compiler/core/parse.y" + case 257: /* paren_args: '(' tBDOT3 rparen */ +#line 2533 "mrbgems/mruby-compiler/core/parse.y" { mrb_sym r = intern_op(mul); mrb_sym k = intern_op(pow); @@ -7772,378 +8112,394 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = 0; } } -#line 7776 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8116 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 262: -#line 2545 "mrbgems/mruby-compiler/core/parse.y" + case 262: /* opt_call_args: args comma */ +#line 2556 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p,(yyvsp[-1].nd),0,0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7785 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8125 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 263: -#line 2550 "mrbgems/mruby-compiler/core/parse.y" + case 263: /* opt_call_args: args comma assocs comma */ +#line 2561 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p,(yyvsp[-3].nd),new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } -#line 7794 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8134 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 264: -#line 2555 "mrbgems/mruby-compiler/core/parse.y" + case 264: /* opt_call_args: assocs comma */ +#line 2566 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p,0,new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7803 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8143 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 265: -#line 2562 "mrbgems/mruby-compiler/core/parse.y" + case 265: /* call_args: command */ +#line 2573 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = new_callargs(p, list1((yyvsp[0].nd)), 0, 0); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7813 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8153 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 266: -#line 2568 "mrbgems/mruby-compiler/core/parse.y" + case 266: /* call_args: args opt_block_arg */ +#line 2579 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p, (yyvsp[-1].nd), 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7822 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8162 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 267: -#line 2573 "mrbgems/mruby-compiler/core/parse.y" + case 267: /* call_args: assocs opt_block_arg */ +#line 2584 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p, 0, new_kw_hash(p, (yyvsp[-1].nd)), (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 7831 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8171 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 268: -#line 2578 "mrbgems/mruby-compiler/core/parse.y" + case 268: /* call_args: args comma assocs opt_block_arg */ +#line 2589 "mrbgems/mruby-compiler/core/parse.y" { (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 7840 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8180 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 269: -#line 2583 "mrbgems/mruby-compiler/core/parse.y" + case 269: /* call_args: block_arg */ +#line 2594 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_callargs(p, 0, 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7849 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8189 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 270: -#line 2589 "mrbgems/mruby-compiler/core/parse.y" + case 270: /* @7: %empty */ +#line 2600 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; CMDARG_PUSH(1); } -#line 7858 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8198 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 271: -#line 2594 "mrbgems/mruby-compiler/core/parse.y" + case 271: /* command_args: @7 call_args */ +#line 2605 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-1].stack); (yyval.nd) = (yyvsp[0].nd); } -#line 7867 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8207 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 272: -#line 2601 "mrbgems/mruby-compiler/core/parse.y" + case 272: /* block_arg: "&" arg */ +#line 2612 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block_arg(p, (yyvsp[0].nd)); } -#line 7875 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8215 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 273: -#line 2605 "mrbgems/mruby-compiler/core/parse.y" + case 273: /* block_arg: "&" */ +#line 2616 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block_arg(p, 0); } -#line 7883 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8223 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 274: -#line 2611 "mrbgems/mruby-compiler/core/parse.y" + case 274: /* opt_block_arg: comma block_arg */ +#line 2622 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 7891 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8231 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 275: -#line 2615 "mrbgems/mruby-compiler/core/parse.y" + case 275: /* opt_block_arg: none */ +#line 2626 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 7899 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8239 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 277: -#line 2624 "mrbgems/mruby-compiler/core/parse.y" + case 277: /* args: arg */ +#line 2635 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8249 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 278: /* args: "*" */ +#line 2641 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = list1(new_splat(p, new_lvar(p, intern_op(mul)))); + } +#line 8257 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 278: -#line 2630 "mrbgems/mruby-compiler/core/parse.y" + case 279: /* args: "*" arg */ +#line 2645 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 7918 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8266 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 279: -#line 2635 "mrbgems/mruby-compiler/core/parse.y" + case 280: /* args: args comma arg */ +#line 2650 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7927 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8275 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 281: /* args: args comma "*" */ +#line 2655 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = push((yyvsp[-2].nd), new_splat(p, new_lvar(p, intern_op(mul)))); + } +#line 8283 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 280: -#line 2640 "mrbgems/mruby-compiler/core/parse.y" + case 282: /* args: args comma "*" arg */ +#line 2659 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 7935 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8291 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 281: -#line 2646 "mrbgems/mruby-compiler/core/parse.y" + case 283: /* mrhs: args comma arg */ +#line 2665 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7944 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8300 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 282: -#line 2651 "mrbgems/mruby-compiler/core/parse.y" + case 284: /* mrhs: args comma "*" arg */ +#line 2670 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 7952 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8308 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 283: -#line 2655 "mrbgems/mruby-compiler/core/parse.y" + case 285: /* mrhs: "*" arg */ +#line 2674 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); } -#line 7960 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8316 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 291: -#line 2668 "mrbgems/mruby-compiler/core/parse.y" + case 293: /* primary: "numbered parameter" */ +#line 2687 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nvar(p, (yyvsp[0].num)); } -#line 7968 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8324 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 292: -#line 2672 "mrbgems/mruby-compiler/core/parse.y" + case 294: /* primary: "method" */ +#line 2691 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[0].id), 0); } -#line 7976 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8332 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 293: -#line 2676 "mrbgems/mruby-compiler/core/parse.y" + case 295: /* @8: %empty */ +#line 2695 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 7985 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8341 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 294: -#line 2682 "mrbgems/mruby-compiler/core/parse.y" + case 296: /* primary: keyword_begin @8 bodystmt keyword_end */ +#line 2701 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-2].stack); (yyval.nd) = (yyvsp[-1].nd); } -#line 7994 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8350 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 295: -#line 2687 "mrbgems/mruby-compiler/core/parse.y" + case 297: /* @9: %empty */ +#line 2706 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8003 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8359 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 296: -#line 2691 "mrbgems/mruby-compiler/core/parse.y" + case 298: /* $@10: %empty */ +#line 2710 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8009 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8365 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 297: -#line 2692 "mrbgems/mruby-compiler/core/parse.y" + case 299: /* primary: "(" @9 stmt $@10 rparen */ +#line 2711 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-3].stack); (yyval.nd) = (yyvsp[-2].nd); } -#line 8018 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8374 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 298: -#line 2696 "mrbgems/mruby-compiler/core/parse.y" + case 300: /* $@11: %empty */ +#line 2715 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8024 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8380 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 299: -#line 2697 "mrbgems/mruby-compiler/core/parse.y" + case 301: /* primary: "(" $@11 rparen */ +#line 2716 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 8032 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8388 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 300: -#line 2701 "mrbgems/mruby-compiler/core/parse.y" + case 302: /* primary: tLPAREN compstmt ')' */ +#line 2720 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8040 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8396 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 301: -#line 2705 "mrbgems/mruby-compiler/core/parse.y" + case 303: /* primary: primary_value "::" "constant" */ +#line 2724 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 8048 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8404 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 302: -#line 2709 "mrbgems/mruby-compiler/core/parse.y" + case 304: /* primary: tCOLON3 "constant" */ +#line 2728 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 8056 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8412 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 303: -#line 2713 "mrbgems/mruby-compiler/core/parse.y" + case 305: /* primary: "[" aref_args ']' */ +#line 2732 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_array(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8065 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8421 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 304: -#line 2718 "mrbgems/mruby-compiler/core/parse.y" + case 306: /* primary: tLBRACE assoc_list '}' */ +#line 2737 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_hash(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8074 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8430 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 305: -#line 2723 "mrbgems/mruby-compiler/core/parse.y" + case 307: /* primary: keyword_return */ +#line 2742 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, 0); } -#line 8082 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8438 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 306: -#line 2727 "mrbgems/mruby-compiler/core/parse.y" + case 308: /* primary: keyword_yield opt_paren_args */ +#line 2746 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 8090 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8446 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 307: -#line 2731 "mrbgems/mruby-compiler/core/parse.y" + case 309: /* primary: keyword_not '(' expr rparen */ +#line 2750 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[-1].nd)), "!"); } -#line 8098 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8454 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 308: -#line 2735 "mrbgems/mruby-compiler/core/parse.y" + case 310: /* primary: keyword_not '(' rparen */ +#line 2754 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, new_nil(p), "!"); } -#line 8106 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8462 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 309: -#line 2739 "mrbgems/mruby-compiler/core/parse.y" + case 311: /* primary: operation brace_block */ +#line 2758 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), new_callargs(p, 0, 0, (yyvsp[0].nd))); } -#line 8114 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8470 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 311: -#line 2744 "mrbgems/mruby-compiler/core/parse.y" + case 313: /* primary: method_call brace_block */ +#line 2763 "mrbgems/mruby-compiler/core/parse.y" { call_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = (yyvsp[-1].nd); } -#line 8123 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8479 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 312: -#line 2749 "mrbgems/mruby-compiler/core/parse.y" + case 314: /* @12: %empty */ +#line 2768 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lpar_beg; p->lpar_beg = ++p->paren_nest; } -#line 8134 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8490 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 313: -#line 2756 "mrbgems/mruby-compiler/core/parse.y" + case 315: /* @13: %empty */ +#line 2775 "mrbgems/mruby-compiler/core/parse.y" { (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8143 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8499 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 314: -#line 2761 "mrbgems/mruby-compiler/core/parse.y" + case 316: /* primary: "->" @12 f_larglist @13 lambda_body */ +#line 2780 "mrbgems/mruby-compiler/core/parse.y" { p->lpar_beg = (yyvsp[-3].num); (yyval.nd) = new_lambda(p, (yyvsp[-2].nd), (yyvsp[0].nd)); @@ -8152,149 +8508,149 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmdarg_stack = (yyvsp[-1].stack); CMDARG_LEXPOP(); } -#line 8156 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8512 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 315: -#line 2773 "mrbgems/mruby-compiler/core/parse.y" + case 317: /* primary: keyword_if expr_value then compstmt if_tail keyword_end */ +#line 2792 "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 8165 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8521 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 316: -#line 2781 "mrbgems/mruby-compiler/core/parse.y" + case 318: /* primary: keyword_unless expr_value then compstmt opt_else keyword_end */ +#line 2800 "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 8174 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8530 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 317: -#line 2785 "mrbgems/mruby-compiler/core/parse.y" + case 319: /* $@14: %empty */ +#line 2804 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8180 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8536 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 318: -#line 2785 "mrbgems/mruby-compiler/core/parse.y" + case 320: /* $@15: %empty */ +#line 2804 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8186 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8542 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 319: -#line 2788 "mrbgems/mruby-compiler/core/parse.y" + case 321: /* primary: keyword_while $@14 expr_value do $@15 compstmt keyword_end */ +#line 2807 "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 8195 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8551 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 320: -#line 2792 "mrbgems/mruby-compiler/core/parse.y" + case 322: /* $@16: %empty */ +#line 2811 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8201 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8557 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 321: -#line 2792 "mrbgems/mruby-compiler/core/parse.y" + case 323: /* $@17: %empty */ +#line 2811 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8207 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8563 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 322: -#line 2795 "mrbgems/mruby-compiler/core/parse.y" + case 324: /* primary: keyword_until $@16 expr_value do $@17 compstmt keyword_end */ +#line 2814 "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 8216 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8572 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 323: -#line 2802 "mrbgems/mruby-compiler/core/parse.y" + case 325: /* primary: keyword_case expr_value opt_terms case_body keyword_end */ +#line 2821 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 8224 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8580 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 324: -#line 2806 "mrbgems/mruby-compiler/core/parse.y" + case 326: /* primary: keyword_case opt_terms case_body keyword_end */ +#line 2825 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, 0, (yyvsp[-1].nd)); } -#line 8232 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8588 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 325: -#line 2810 "mrbgems/mruby-compiler/core/parse.y" + case 327: /* $@18: %empty */ +#line 2829 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8238 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8594 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 326: -#line 2812 "mrbgems/mruby-compiler/core/parse.y" + case 328: /* $@19: %empty */ +#line 2831 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8600 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 327: -#line 2815 "mrbgems/mruby-compiler/core/parse.y" + case 329: /* primary: keyword_for for_var keyword_in $@18 expr_value do $@19 compstmt keyword_end */ +#line 2834 "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 8253 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8609 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 328: -#line 2821 "mrbgems/mruby-compiler/core/parse.y" + case 330: /* @20: %empty */ +#line 2840 "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 8264 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8620 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 329: -#line 2829 "mrbgems/mruby-compiler/core/parse.y" + case 331: /* primary: keyword_class cpath superclass @20 bodystmt keyword_end */ +#line 2848 "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 8275 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8631 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 330: -#line 2837 "mrbgems/mruby-compiler/core/parse.y" + case 332: /* @21: %empty */ +#line 2856 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = p->in_def; p->in_def = 0; } -#line 8284 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8640 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 331: -#line 2842 "mrbgems/mruby-compiler/core/parse.y" + case 333: /* @22: %empty */ +#line 2861 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(local_switch(p), nint(p->in_single)); nvars_block(p); p->in_single = 0; } -#line 8294 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8650 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 332: -#line 2849 "mrbgems/mruby-compiler/core/parse.y" + case 334: /* primary: keyword_class "<<" expr @21 term @22 bodystmt keyword_end */ +#line 2868 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sclass(p, (yyvsp[-5].nd), (yyvsp[-1].nd)); SET_LINENO((yyval.nd), (yyvsp[-7].num)); @@ -8303,44 +8659,44 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def = (yyvsp[-4].num); p->in_single = intn((yyvsp[-2].nd)->cdr); } -#line 8307 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8663 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 333: -#line 2859 "mrbgems/mruby-compiler/core/parse.y" + case 335: /* @23: %empty */ +#line 2878 "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 8318 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8674 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 334: -#line 2867 "mrbgems/mruby-compiler/core/parse.y" + case 336: /* primary: keyword_module cpath @23 bodystmt keyword_end */ +#line 2886 "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 8329 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8685 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 335: -#line 2877 "mrbgems/mruby-compiler/core/parse.y" + case 337: /* primary: defn_head f_arglist bodystmt keyword_end */ +#line 2896 "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 8340 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8696 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 336: -#line 2887 "mrbgems/mruby-compiler/core/parse.y" + case 338: /* primary: defs_head f_arglist bodystmt keyword_end */ +#line 2906 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); defs_setup(p, (yyval.nd), (yyvsp[-2].nd), (yyvsp[-1].nd)); @@ -8348,451 +8704,451 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 8352 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8708 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 337: -#line 2895 "mrbgems/mruby-compiler/core/parse.y" + case 339: /* primary: keyword_break */ +#line 2914 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, 0); } -#line 8360 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8716 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 338: -#line 2899 "mrbgems/mruby-compiler/core/parse.y" + case 340: /* primary: keyword_next */ +#line 2918 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, 0); } -#line 8368 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8724 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 339: -#line 2903 "mrbgems/mruby-compiler/core/parse.y" + case 341: /* primary: keyword_redo */ +#line 2922 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_redo(p); } -#line 8376 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8732 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 340: -#line 2907 "mrbgems/mruby-compiler/core/parse.y" + case 342: /* primary: keyword_retry */ +#line 2926 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_retry(p); } -#line 8384 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8740 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 341: -#line 2913 "mrbgems/mruby-compiler/core/parse.y" + case 343: /* primary_value: primary */ +#line 2932 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 8393 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8749 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 348: -#line 2932 "mrbgems/mruby-compiler/core/parse.y" + case 350: /* if_tail: keyword_elsif expr_value then compstmt if_tail */ +#line 2951 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-3].nd)), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8401 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8757 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 350: -#line 2939 "mrbgems/mruby-compiler/core/parse.y" + case 352: /* opt_else: keyword_else compstmt */ +#line 2958 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8409 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8765 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 351: -#line 2945 "mrbgems/mruby-compiler/core/parse.y" + case 353: /* for_var: lhs */ +#line 2964 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(list1((yyvsp[0].nd))); } -#line 8417 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8773 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 353: -#line 2952 "mrbgems/mruby-compiler/core/parse.y" + case 355: /* f_margs: f_arg */ +#line 2971 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[0].nd),0,0); } -#line 8425 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8781 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 354: -#line 2956 "mrbgems/mruby-compiler/core/parse.y" + case 356: /* f_margs: f_arg ',' "*" f_norm_arg */ +#line 2975 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-3].nd), new_arg(p, (yyvsp[0].id)), 0); } -#line 8433 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8789 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 355: -#line 2960 "mrbgems/mruby-compiler/core/parse.y" + case 357: /* f_margs: f_arg ',' "*" f_norm_arg ',' f_arg */ +#line 2979 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-5].nd), new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8441 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8797 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 356: -#line 2964 "mrbgems/mruby-compiler/core/parse.y" + case 358: /* f_margs: f_arg ',' "*" */ +#line 2983 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(mul)); (yyval.nd) = list3((yyvsp[-2].nd), nint(-1), 0); } -#line 8450 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8806 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 357: -#line 2969 "mrbgems/mruby-compiler/core/parse.y" + case 359: /* f_margs: f_arg ',' "*" ',' f_arg */ +#line 2988 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3((yyvsp[-4].nd), nint(-1), (yyvsp[0].nd)); } -#line 8458 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8814 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 358: -#line 2973 "mrbgems/mruby-compiler/core/parse.y" + case 360: /* f_margs: "*" f_norm_arg */ +#line 2992 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_arg(p, (yyvsp[0].id)), 0); } -#line 8466 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8822 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 359: -#line 2977 "mrbgems/mruby-compiler/core/parse.y" + case 361: /* f_margs: "*" f_norm_arg ',' f_arg */ +#line 2996 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8474 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8830 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 360: -#line 2981 "mrbgems/mruby-compiler/core/parse.y" + case 362: /* f_margs: "*" */ +#line 3000 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(mul)); (yyval.nd) = list3(0, nint(-1), 0); } -#line 8483 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8839 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 361: -#line 2986 "mrbgems/mruby-compiler/core/parse.y" + case 363: /* $@24: %empty */ +#line 3005 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, intern_op(mul)); } -#line 8491 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8847 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 362: -#line 2990 "mrbgems/mruby-compiler/core/parse.y" + case 364: /* f_margs: "*" ',' $@24 f_arg */ +#line 3009 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list3(0, nint(-1), (yyvsp[0].nd)); } -#line 8499 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8855 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 363: -#line 2996 "mrbgems/mruby-compiler/core/parse.y" + case 365: /* block_args_tail: f_block_kwarg ',' f_kwrest opt_f_block_arg */ +#line 3015 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8507 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8863 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 364: -#line 3000 "mrbgems/mruby-compiler/core/parse.y" + case 366: /* block_args_tail: f_block_kwarg opt_f_block_arg */ +#line 3019 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 8515 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8871 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 365: -#line 3004 "mrbgems/mruby-compiler/core/parse.y" + case 367: /* block_args_tail: f_kwrest opt_f_block_arg */ +#line 3023 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8523 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8879 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 366: -#line 3008 "mrbgems/mruby-compiler/core/parse.y" + case 368: /* block_args_tail: f_block_arg */ +#line 3027 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 8531 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8887 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 367: -#line 3014 "mrbgems/mruby-compiler/core/parse.y" + case 369: /* opt_block_args_tail: ',' block_args_tail */ +#line 3033 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8539 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8895 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 368: -#line 3018 "mrbgems/mruby-compiler/core/parse.y" + case 370: /* opt_block_args_tail: %empty */ +#line 3037 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 8547 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8903 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 369: -#line 3024 "mrbgems/mruby-compiler/core/parse.y" + case 371: /* block_param: f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail */ +#line 3043 "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 8555 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8911 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 370: -#line 3028 "mrbgems/mruby-compiler/core/parse.y" + case 372: /* block_param: f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail */ +#line 3047 "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 8563 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8919 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 371: -#line 3032 "mrbgems/mruby-compiler/core/parse.y" + case 373: /* block_param: f_arg ',' f_block_optarg opt_block_args_tail */ +#line 3051 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8571 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8927 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 372: -#line 3036 "mrbgems/mruby-compiler/core/parse.y" + case 374: /* block_param: f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail */ +#line 3055 "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 8579 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8935 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 373: -#line 3040 "mrbgems/mruby-compiler/core/parse.y" + case 375: /* block_param: f_arg ',' f_rest_arg opt_block_args_tail */ +#line 3059 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8587 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8943 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 374: -#line 3044 "mrbgems/mruby-compiler/core/parse.y" + case 376: /* block_param: f_arg ',' opt_block_args_tail */ +#line 3063 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-2].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8595 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8951 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 375: -#line 3048 "mrbgems/mruby-compiler/core/parse.y" + case 377: /* block_param: f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail */ +#line 3067 "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 8603 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8959 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 376: -#line 3052 "mrbgems/mruby-compiler/core/parse.y" + case 378: /* block_param: f_arg opt_block_args_tail */ +#line 3071 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8967 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 377: -#line 3056 "mrbgems/mruby-compiler/core/parse.y" + case 379: /* block_param: f_block_optarg ',' f_rest_arg opt_block_args_tail */ +#line 3075 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8975 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 378: -#line 3060 "mrbgems/mruby-compiler/core/parse.y" + case 380: /* block_param: f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail */ +#line 3079 "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 8627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8983 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 379: -#line 3064 "mrbgems/mruby-compiler/core/parse.y" + case 381: /* block_param: f_block_optarg opt_block_args_tail */ +#line 3083 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8635 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8991 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 380: -#line 3068 "mrbgems/mruby-compiler/core/parse.y" + case 382: /* block_param: f_block_optarg ',' f_arg opt_block_args_tail */ +#line 3087 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8643 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8999 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 381: -#line 3072 "mrbgems/mruby-compiler/core/parse.y" + case 383: /* block_param: f_rest_arg opt_block_args_tail */ +#line 3091 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8651 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9007 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 382: -#line 3076 "mrbgems/mruby-compiler/core/parse.y" + case 384: /* block_param: f_rest_arg ',' f_arg opt_block_args_tail */ +#line 3095 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9015 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 383: -#line 3080 "mrbgems/mruby-compiler/core/parse.y" + case 385: /* block_param: block_args_tail */ +#line 3099 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 8667 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9023 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 384: -#line 3086 "mrbgems/mruby-compiler/core/parse.y" + case 386: /* opt_block_param: none */ +#line 3105 "mrbgems/mruby-compiler/core/parse.y" { local_add_blk(p, 0); (yyval.nd) = 0; } -#line 8676 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9032 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 385: -#line 3091 "mrbgems/mruby-compiler/core/parse.y" + case 387: /* opt_block_param: block_param_def */ +#line 3110 "mrbgems/mruby-compiler/core/parse.y" { p->cmd_start = TRUE; (yyval.nd) = (yyvsp[0].nd); } -#line 8685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9041 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 386: -#line 3097 "mrbgems/mruby-compiler/core/parse.y" + case 388: /* $@25: %empty */ +#line 3116 "mrbgems/mruby-compiler/core/parse.y" {local_add_blk(p, 0);} -#line 8691 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9047 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 387: -#line 3098 "mrbgems/mruby-compiler/core/parse.y" + case 389: /* block_param_def: '|' $@25 opt_bv_decl '|' */ +#line 3117 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8699 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9055 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 388: -#line 3102 "mrbgems/mruby-compiler/core/parse.y" + case 390: /* block_param_def: "||" */ +#line 3121 "mrbgems/mruby-compiler/core/parse.y" { local_add_blk(p, 0); (yyval.nd) = 0; } -#line 8708 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9064 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 389: -#line 3107 "mrbgems/mruby-compiler/core/parse.y" + case 391: /* block_param_def: '|' block_param opt_bv_decl '|' */ +#line 3126 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-2].nd); } -#line 8716 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9072 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 390: -#line 3114 "mrbgems/mruby-compiler/core/parse.y" + case 392: /* opt_bv_decl: opt_nl */ +#line 3133 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8724 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9080 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 391: -#line 3118 "mrbgems/mruby-compiler/core/parse.y" + case 393: /* opt_bv_decl: opt_nl ';' bv_decls opt_nl */ +#line 3137 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 8732 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9088 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 394: -#line 3128 "mrbgems/mruby-compiler/core/parse.y" + case 396: /* bvar: "local variable or method" */ +#line 3147 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); new_bv(p, (yyvsp[0].id)); } -#line 8741 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9097 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 396: -#line 3136 "mrbgems/mruby-compiler/core/parse.y" + case 398: /* f_larglist: '(' f_args opt_bv_decl ')' */ +#line 3155 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-2].nd); } -#line 8749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9105 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 397: -#line 3140 "mrbgems/mruby-compiler/core/parse.y" + case 399: /* f_larglist: f_args */ +#line 3159 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9113 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 398: -#line 3146 "mrbgems/mruby-compiler/core/parse.y" + case 400: /* lambda_body: tLAMBEG compstmt '}' */ +#line 3165 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8765 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9121 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 399: -#line 3150 "mrbgems/mruby-compiler/core/parse.y" + case 401: /* lambda_body: keyword_do_LAMBDA bodystmt keyword_end */ +#line 3169 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 8773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9129 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 400: -#line 3156 "mrbgems/mruby-compiler/core/parse.y" + case 402: /* $@26: %empty */ +#line 3175 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); } -#line 8782 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9138 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 401: -#line 3163 "mrbgems/mruby-compiler/core/parse.y" + case 403: /* do_block: keyword_do_block $@26 opt_block_param bodystmt keyword_end */ +#line 3182 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_block(p,(yyvsp[-2].nd),(yyvsp[-1].nd)); local_unnest(p); nvars_unnest(p); } -#line 8792 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9148 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 402: -#line 3171 "mrbgems/mruby-compiler/core/parse.y" + case 404: /* block_call: command do_block */ +#line 3190 "mrbgems/mruby-compiler/core/parse.y" { if (typen((yyvsp[-1].nd)->car) == NODE_YIELD) { yyerror(p, "block given to yield"); @@ -8802,159 +9158,159 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = (yyvsp[-1].nd); } -#line 8806 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9162 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 403: -#line 3181 "mrbgems/mruby-compiler/core/parse.y" + case 405: /* block_call: block_call call_op2 operation2 opt_paren_args */ +#line 3200 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 8814 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9170 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 404: -#line 3185 "mrbgems/mruby-compiler/core/parse.y" + case 406: /* block_call: block_call call_op2 operation2 opt_paren_args brace_block */ +#line 3204 "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 8823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9179 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 405: -#line 3190 "mrbgems/mruby-compiler/core/parse.y" + case 407: /* block_call: block_call call_op2 operation2 command_args do_block */ +#line 3209 "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 8832 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9188 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 406: -#line 3197 "mrbgems/mruby-compiler/core/parse.y" + case 408: /* method_call: operation paren_args */ +#line 3216 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 8840 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9196 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 407: -#line 3201 "mrbgems/mruby-compiler/core/parse.y" + case 409: /* method_call: primary_value call_op operation2 opt_paren_args */ +#line 3220 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 8848 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9204 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 408: -#line 3205 "mrbgems/mruby-compiler/core/parse.y" + case 410: /* method_call: primary_value "::" operation2 paren_args */ +#line 3224 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 8856 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9212 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 409: -#line 3209 "mrbgems/mruby-compiler/core/parse.y" + case 411: /* method_call: primary_value "::" operation3 */ +#line 3228 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 8864 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9220 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 410: -#line 3213 "mrbgems/mruby-compiler/core/parse.y" + case 412: /* method_call: primary_value call_op paren_args */ +#line 3232 "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 8872 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9228 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 411: -#line 3217 "mrbgems/mruby-compiler/core/parse.y" + case 413: /* method_call: primary_value "::" paren_args */ +#line 3236 "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 8880 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9236 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 412: -#line 3221 "mrbgems/mruby-compiler/core/parse.y" + case 414: /* method_call: keyword_super paren_args */ +#line 3240 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 8888 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9244 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 413: -#line 3225 "mrbgems/mruby-compiler/core/parse.y" + case 415: /* method_call: keyword_super */ +#line 3244 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_zsuper(p); } -#line 8896 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9252 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 414: -#line 3229 "mrbgems/mruby-compiler/core/parse.y" + case 416: /* method_call: primary_value '[' opt_call_args ']' */ +#line 3248 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 8904 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9260 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 415: -#line 3235 "mrbgems/mruby-compiler/core/parse.y" + case 417: /* @27: %empty */ +#line 3254 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 8914 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9270 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 416: -#line 3242 "mrbgems/mruby-compiler/core/parse.y" + case 418: /* brace_block: '{' @27 opt_block_param compstmt '}' */ +#line 3261 "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 8925 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9281 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 417: -#line 3249 "mrbgems/mruby-compiler/core/parse.y" + case 419: /* @28: %empty */ +#line 3268 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 8935 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9291 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 418: -#line 3256 "mrbgems/mruby-compiler/core/parse.y" + case 420: /* brace_block: keyword_do @28 opt_block_param bodystmt keyword_end */ +#line 3275 "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 8946 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9302 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 419: -#line 3267 "mrbgems/mruby-compiler/core/parse.y" + case 421: /* case_body: keyword_when args then compstmt cases */ +#line 3286 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(cons((yyvsp[-3].nd), (yyvsp[-1].nd)), (yyvsp[0].nd)); } -#line 8954 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9310 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 420: -#line 3273 "mrbgems/mruby-compiler/core/parse.y" + case 422: /* cases: opt_else */ +#line 3292 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[0].nd)) { (yyval.nd) = cons(cons(0, (yyvsp[0].nd)), 0); @@ -8963,60 +9319,60 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = 0; } } -#line 8967 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9323 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 422: -#line 3287 "mrbgems/mruby-compiler/core/parse.y" + case 424: /* opt_rescue: keyword_rescue exc_list exc_var then compstmt opt_rescue */ +#line 3306 "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 8976 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9332 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 424: -#line 3295 "mrbgems/mruby-compiler/core/parse.y" + case 426: /* exc_list: arg */ +#line 3314 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 8984 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9340 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 427: -#line 3303 "mrbgems/mruby-compiler/core/parse.y" + case 429: /* exc_var: "=>" lhs */ +#line 3322 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8992 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9348 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 429: -#line 3310 "mrbgems/mruby-compiler/core/parse.y" + case 431: /* opt_ensure: keyword_ensure compstmt */ +#line 3329 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9000 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9356 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 436: -#line 3324 "mrbgems/mruby-compiler/core/parse.y" + case 438: /* string: string string_fragment */ +#line 3343 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = concat_string(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9008 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9364 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 439: -#line 3332 "mrbgems/mruby-compiler/core/parse.y" + case 441: /* string_fragment: "string literal" tSTRING */ +#line 3351 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9016 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9372 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 440: -#line 3336 "mrbgems/mruby-compiler/core/parse.y" + case 442: /* string_fragment: "string literal" string_rep tSTRING */ +#line 3355 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9027,69 +9383,68 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dstr(p, n); } -#line 9031 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9387 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 442: -#line 3350 "mrbgems/mruby-compiler/core/parse.y" + case 444: /* string_rep: string_rep string_interp */ +#line 3369 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = append((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9039 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9395 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 443: -#line 3356 "mrbgems/mruby-compiler/core/parse.y" + case 445: /* string_interp: tSTRING_MID */ +#line 3375 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9047 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9403 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 444: -#line 3360 "mrbgems/mruby-compiler/core/parse.y" + case 446: /* @29: %empty */ +#line 3379 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = p->lex_strterm; - p->lex_strterm = NULL; + (yyval.nd) = push_strterm(p); } -#line 9056 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9411 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 445: -#line 3366 "mrbgems/mruby-compiler/core/parse.y" + case 447: /* string_interp: tSTRING_PART @29 compstmt '}' */ +#line 3384 "mrbgems/mruby-compiler/core/parse.y" { - p->lex_strterm = (yyvsp[-2].nd); + pop_strterm(p,(yyvsp[-2].nd)); (yyval.nd) = list2((yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 9065 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9420 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 446: -#line 3371 "mrbgems/mruby-compiler/core/parse.y" + case 448: /* string_interp: tLITERAL_DELIM */ +#line 3389 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9073 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9428 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 447: -#line 3375 "mrbgems/mruby-compiler/core/parse.y" + case 449: /* string_interp: tHD_LITERAL_DELIM heredoc_bodies */ +#line 3393 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9081 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9436 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 448: -#line 3381 "mrbgems/mruby-compiler/core/parse.y" + case 450: /* xstring: tXSTRING_BEG tXSTRING */ +#line 3399 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9089 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9444 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 449: -#line 3385 "mrbgems/mruby-compiler/core/parse.y" + case 451: /* xstring: tXSTRING_BEG string_rep tXSTRING */ +#line 3403 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9100,82 +9455,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dxstr(p, n); } -#line 9104 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9459 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 450: -#line 3398 "mrbgems/mruby-compiler/core/parse.y" + case 452: /* regexp: tREGEXP_BEG tREGEXP */ +#line 3416 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9112 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9467 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 451: -#line 3402 "mrbgems/mruby-compiler/core/parse.y" + case 453: /* regexp: tREGEXP_BEG string_rep tREGEXP */ +#line 3420 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dregx(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9120 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9475 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 455: -#line 3415 "mrbgems/mruby-compiler/core/parse.y" + case 457: /* heredoc_body: tHEREDOC_END */ +#line 3433 "mrbgems/mruby-compiler/core/parse.y" { - parser_heredoc_info * inf = parsing_heredoc_inf(p); - inf->doc = push(inf->doc, new_str(p, "", 0)); + parser_heredoc_info *info = parsing_heredoc_info(p); + info->doc = push(info->doc, new_str(p, "", 0)); heredoc_end(p); } -#line 9130 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9485 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 456: -#line 3421 "mrbgems/mruby-compiler/core/parse.y" + case 458: /* heredoc_body: heredoc_string_rep tHEREDOC_END */ +#line 3439 "mrbgems/mruby-compiler/core/parse.y" { heredoc_end(p); } -#line 9138 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9493 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 459: -#line 3431 "mrbgems/mruby-compiler/core/parse.y" + case 461: /* heredoc_string_interp: tHD_STRING_MID */ +#line 3449 "mrbgems/mruby-compiler/core/parse.y" { - parser_heredoc_info * inf = parsing_heredoc_inf(p); - inf->doc = push(inf->doc, (yyvsp[0].nd)); + parser_heredoc_info *info = parsing_heredoc_info(p); + info->doc = push(info->doc, (yyvsp[0].nd)); heredoc_treat_nextline(p); } -#line 9148 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9503 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 460: -#line 3437 "mrbgems/mruby-compiler/core/parse.y" + case 462: /* @30: %empty */ +#line 3455 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = p->lex_strterm; - p->lex_strterm = NULL; + (yyval.nd) = push_strterm(p); } -#line 9157 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9511 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 461: -#line 3443 "mrbgems/mruby-compiler/core/parse.y" + case 463: /* heredoc_string_interp: tHD_STRING_PART @30 compstmt '}' */ +#line 3460 "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)); + pop_strterm(p, (yyvsp[-2].nd)); + parser_heredoc_info *info = parsing_heredoc_info(p); + info->doc = push(push(info->doc, (yyvsp[-3].nd)), (yyvsp[-1].nd)); } -#line 9167 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9521 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 462: -#line 3451 "mrbgems/mruby-compiler/core/parse.y" + case 464: /* words: tWORDS_BEG tSTRING */ +#line 3468 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_words(p, list1((yyvsp[0].nd))); } -#line 9175 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9529 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 463: -#line 3455 "mrbgems/mruby-compiler/core/parse.y" + case 465: /* words: tWORDS_BEG string_rep tSTRING */ +#line 3472 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9186,20 +9540,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_words(p, n); } -#line 9190 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9544 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 464: -#line 3469 "mrbgems/mruby-compiler/core/parse.y" + case 466: /* symbol: basic_symbol */ +#line 3486 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDARG; (yyval.nd) = new_sym(p, (yyvsp[0].id)); } -#line 9199 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9553 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 465: -#line 3474 "mrbgems/mruby-compiler/core/parse.y" + case 467: /* symbol: "symbol" "string literal" string_rep tSTRING */ +#line 3491 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); p->lstate = EXPR_ENDARG; @@ -9211,43 +9565,43 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dsym(p, new_dstr(p, n)); } -#line 9215 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9569 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 466: -#line 3488 "mrbgems/mruby-compiler/core/parse.y" + case 468: /* basic_symbol: "symbol" sym */ +#line 3505 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9223 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9577 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 471: -#line 3498 "mrbgems/mruby-compiler/core/parse.y" + case 473: /* sym: tSTRING */ +#line 3515 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9231 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9585 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 472: -#line 3502 "mrbgems/mruby-compiler/core/parse.y" + case 474: /* sym: "string literal" tSTRING */ +#line 3519 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9239 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9593 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 473: -#line 3508 "mrbgems/mruby-compiler/core/parse.y" + case 475: /* symbols: tSYMBOLS_BEG tSTRING */ +#line 3525 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_symbols(p, list1((yyvsp[0].nd))); } -#line 9247 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9601 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 474: -#line 3512 "mrbgems/mruby-compiler/core/parse.y" + case 476: /* symbols: tSYMBOLS_BEG string_rep tSTRING */ +#line 3529 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9255,123 +9609,123 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_symbols(p, n); } -#line 9259 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9613 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 477: -#line 3524 "mrbgems/mruby-compiler/core/parse.y" + case 479: /* numeric: tUMINUS_NUM "integer literal" */ +#line 3541 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9267 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9621 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 478: -#line 3528 "mrbgems/mruby-compiler/core/parse.y" + case 480: /* numeric: tUMINUS_NUM "float literal" */ +#line 3545 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9275 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9629 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 479: -#line 3534 "mrbgems/mruby-compiler/core/parse.y" + case 481: /* variable: "local variable or method" */ +#line 3551 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_lvar(p, (yyvsp[0].id)); } -#line 9283 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9637 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 480: -#line 3538 "mrbgems/mruby-compiler/core/parse.y" + case 482: /* variable: "instance variable" */ +#line 3555 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_ivar(p, (yyvsp[0].id)); } -#line 9291 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9645 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 481: -#line 3542 "mrbgems/mruby-compiler/core/parse.y" + case 483: /* variable: "global variable" */ +#line 3559 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_gvar(p, (yyvsp[0].id)); } -#line 9299 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9653 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 482: -#line 3546 "mrbgems/mruby-compiler/core/parse.y" + case 484: /* variable: "class variable" */ +#line 3563 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_cvar(p, (yyvsp[0].id)); } -#line 9307 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9661 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 483: -#line 3550 "mrbgems/mruby-compiler/core/parse.y" + case 485: /* variable: "constant" */ +#line 3567 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_const(p, (yyvsp[0].id)); } -#line 9315 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9669 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 484: -#line 3556 "mrbgems/mruby-compiler/core/parse.y" + case 486: /* var_lhs: variable */ +#line 3573 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 9323 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9677 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 485: -#line 3560 "mrbgems/mruby-compiler/core/parse.y" + case 487: /* var_lhs: "numbered parameter" */ +#line 3577 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 9331 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9685 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 486: -#line 3566 "mrbgems/mruby-compiler/core/parse.y" + case 488: /* var_ref: variable */ +#line 3583 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = var_reference(p, (yyvsp[0].nd)); } -#line 9339 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9693 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 487: -#line 3570 "mrbgems/mruby-compiler/core/parse.y" + case 489: /* var_ref: keyword_nil */ +#line 3587 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 9347 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9701 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 488: -#line 3574 "mrbgems/mruby-compiler/core/parse.y" + case 490: /* var_ref: keyword_self */ +#line 3591 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_self(p); } -#line 9355 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9709 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 489: -#line 3578 "mrbgems/mruby-compiler/core/parse.y" + case 491: /* var_ref: keyword_true */ +#line 3595 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_true(p); } -#line 9363 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9717 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 490: -#line 3582 "mrbgems/mruby-compiler/core/parse.y" + case 492: /* var_ref: keyword_false */ +#line 3599 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_false(p); } -#line 9371 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9725 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 491: -#line 3586 "mrbgems/mruby-compiler/core/parse.y" + case 493: /* var_ref: keyword__FILE__ */ +#line 3603 "mrbgems/mruby-compiler/core/parse.y" { const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); if (!fn) { @@ -9379,599 +9733,607 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_str(p, fn, strlen(fn)); } -#line 9383 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9737 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 492: -#line 3594 "mrbgems/mruby-compiler/core/parse.y" + case 494: /* var_ref: keyword__LINE__ */ +#line 3611 "mrbgems/mruby-compiler/core/parse.y" { char buf[16]; dump_int(p->lineno, buf); (yyval.nd) = new_int(p, buf, 10, 0); } -#line 9394 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9748 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 493: -#line 3601 "mrbgems/mruby-compiler/core/parse.y" + case 495: /* var_ref: keyword__ENCODING__ */ +#line 3618 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, MRB_SYM_2(p->mrb, __ENCODING__), 0); } -#line 9402 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9756 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 496: -#line 3611 "mrbgems/mruby-compiler/core/parse.y" + case 498: /* superclass: %empty */ +#line 3628 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 9410 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9764 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 497: -#line 3615 "mrbgems/mruby-compiler/core/parse.y" + case 499: /* $@31: %empty */ +#line 3632 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9419 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9773 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 498: -#line 3620 "mrbgems/mruby-compiler/core/parse.y" + case 500: /* superclass: '<' $@31 expr_value term */ +#line 3637 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9427 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9781 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 501: -#line 3636 "mrbgems/mruby-compiler/core/parse.y" + case 503: /* f_arglist_paren: '(' f_args rparen */ +#line 3653 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9437 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9791 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 502: -#line 3642 "mrbgems/mruby-compiler/core/parse.y" + case 504: /* f_arglist_paren: '(' f_arg ',' tBDOT3 rparen */ +#line 3659 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9445 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9799 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 503: -#line 3646 "mrbgems/mruby-compiler/core/parse.y" + case 505: /* f_arglist_paren: '(' tBDOT3 rparen */ +#line 3663 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9453 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9807 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 505: -#line 3653 "mrbgems/mruby-compiler/core/parse.y" + case 507: /* f_arglist: f_args term */ +#line 3670 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9461 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9815 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 506: -#line 3657 "mrbgems/mruby-compiler/core/parse.y" + case 508: /* f_arglist: f_arg ',' tBDOT3 term */ +#line 3674 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9469 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9823 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 507: -#line 3661 "mrbgems/mruby-compiler/core/parse.y" + case 509: /* f_arglist: "..." term */ +#line 3678 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9477 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9831 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 508: -#line 3667 "mrbgems/mruby-compiler/core/parse.y" + case 510: /* f_label: "local variable or method" "label" */ +#line 3684 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); } -#line 9485 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9839 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 511: /* f_label: "numbered parameter" "label" */ +#line 3688 "mrbgems/mruby-compiler/core/parse.y" + { + local_nest(p); + } +#line 9847 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 509: -#line 3673 "mrbgems/mruby-compiler/core/parse.y" + case 512: /* f_kw: f_label arg */ +#line 3694 "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 9495 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9857 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 510: -#line 3679 "mrbgems/mruby-compiler/core/parse.y" + case 513: /* f_kw: f_label */ +#line 3700 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9504 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9866 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 511: -#line 3686 "mrbgems/mruby-compiler/core/parse.y" + case 514: /* f_block_kw: f_label primary_value */ +#line 3707 "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 9514 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9876 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 512: -#line 3692 "mrbgems/mruby-compiler/core/parse.y" + case 515: /* f_block_kw: f_label */ +#line 3713 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9523 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9885 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 513: -#line 3699 "mrbgems/mruby-compiler/core/parse.y" + case 516: /* f_block_kwarg: f_block_kw */ +#line 3720 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9531 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9893 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 514: -#line 3703 "mrbgems/mruby-compiler/core/parse.y" + case 517: /* f_block_kwarg: f_block_kwarg ',' f_block_kw */ +#line 3724 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9539 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9901 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 515: -#line 3709 "mrbgems/mruby-compiler/core/parse.y" + case 518: /* f_kwarg: f_kw */ +#line 3730 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9547 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9909 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 516: -#line 3713 "mrbgems/mruby-compiler/core/parse.y" + case 519: /* f_kwarg: f_kwarg ',' f_kw */ +#line 3734 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9555 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9917 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 519: -#line 3723 "mrbgems/mruby-compiler/core/parse.y" + case 522: /* f_kwrest: kwrest_mark "local variable or method" */ +#line 3744 "mrbgems/mruby-compiler/core/parse.y" { - (yyval.nd) = new_kw_rest_args(p, nsym((yyvsp[0].id))); + (yyval.nd) = new_kw_rest_args(p, (yyvsp[0].id)); } -#line 9563 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9925 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 520: -#line 3727 "mrbgems/mruby-compiler/core/parse.y" + case 523: /* f_kwrest: kwrest_mark */ +#line 3748 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, 0); } -#line 9571 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9933 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 521: -#line 3733 "mrbgems/mruby-compiler/core/parse.y" + case 524: /* args_tail: f_kwarg ',' f_kwrest opt_f_block_arg */ +#line 3754 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9579 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9941 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 522: -#line 3737 "mrbgems/mruby-compiler/core/parse.y" + case 525: /* args_tail: f_kwarg opt_f_block_arg */ +#line 3758 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 9587 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9949 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 523: -#line 3741 "mrbgems/mruby-compiler/core/parse.y" + case 526: /* args_tail: f_kwrest opt_f_block_arg */ +#line 3762 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9595 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9957 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 524: -#line 3745 "mrbgems/mruby-compiler/core/parse.y" + case 527: /* args_tail: f_block_arg */ +#line 3766 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 9603 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9965 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 525: -#line 3751 "mrbgems/mruby-compiler/core/parse.y" + case 528: /* opt_args_tail: ',' args_tail */ +#line 3772 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9973 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 526: -#line 3755 "mrbgems/mruby-compiler/core/parse.y" + case 529: /* opt_args_tail: %empty */ +#line 3776 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 9619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9981 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 527: -#line 3761 "mrbgems/mruby-compiler/core/parse.y" + case 530: /* f_args: f_arg ',' f_optarg ',' f_rest_arg opt_args_tail */ +#line 3782 "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 9627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9989 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 528: -#line 3765 "mrbgems/mruby-compiler/core/parse.y" + case 531: /* f_args: f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail */ +#line 3786 "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 9635 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9997 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 529: -#line 3769 "mrbgems/mruby-compiler/core/parse.y" + case 532: /* f_args: f_arg ',' f_optarg opt_args_tail */ +#line 3790 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 9643 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10005 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 530: -#line 3773 "mrbgems/mruby-compiler/core/parse.y" + case 533: /* f_args: f_arg ',' f_optarg ',' f_arg opt_args_tail */ +#line 3794 "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 9651 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10013 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 531: -#line 3777 "mrbgems/mruby-compiler/core/parse.y" + case 534: /* f_args: f_arg ',' f_rest_arg opt_args_tail */ +#line 3798 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10021 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 532: -#line 3781 "mrbgems/mruby-compiler/core/parse.y" + case 535: /* f_args: f_arg ',' f_rest_arg ',' f_arg opt_args_tail */ +#line 3802 "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 9667 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10029 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 533: -#line 3785 "mrbgems/mruby-compiler/core/parse.y" + case 536: /* f_args: f_arg opt_args_tail */ +#line 3806 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 9675 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10037 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 534: -#line 3789 "mrbgems/mruby-compiler/core/parse.y" + case 537: /* f_args: f_optarg ',' f_rest_arg opt_args_tail */ +#line 3810 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9683 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10045 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 535: -#line 3793 "mrbgems/mruby-compiler/core/parse.y" + case 538: /* f_args: f_optarg ',' f_rest_arg ',' f_arg opt_args_tail */ +#line 3814 "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 9691 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10053 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 536: -#line 3797 "mrbgems/mruby-compiler/core/parse.y" + case 539: /* f_args: f_optarg opt_args_tail */ +#line 3818 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 9699 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10061 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 537: -#line 3801 "mrbgems/mruby-compiler/core/parse.y" + case 540: /* f_args: f_optarg ',' f_arg opt_args_tail */ +#line 3822 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9707 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10069 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 538: -#line 3805 "mrbgems/mruby-compiler/core/parse.y" + case 541: /* f_args: f_rest_arg opt_args_tail */ +#line 3826 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9715 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10077 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 539: -#line 3809 "mrbgems/mruby-compiler/core/parse.y" + case 542: /* f_args: f_rest_arg ',' f_arg opt_args_tail */ +#line 3830 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9723 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10085 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 540: -#line 3813 "mrbgems/mruby-compiler/core/parse.y" + case 543: /* f_args: args_tail */ +#line 3834 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 9731 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10093 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 541: -#line 3817 "mrbgems/mruby-compiler/core/parse.y" + case 544: /* f_args: %empty */ +#line 3838 "mrbgems/mruby-compiler/core/parse.y" { - local_add_f(p, intern_op(and)); + local_add_f(p, 0); (yyval.nd) = new_args(p, 0, 0, 0, 0, 0); } -#line 9740 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10102 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 542: -#line 3824 "mrbgems/mruby-compiler/core/parse.y" + case 545: /* f_bad_arg: "constant" */ +#line 3845 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a constant"); (yyval.nd) = 0; } -#line 9749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10111 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 543: -#line 3829 "mrbgems/mruby-compiler/core/parse.y" + case 546: /* f_bad_arg: "instance variable" */ +#line 3850 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be an instance variable"); (yyval.nd) = 0; } -#line 9758 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10120 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 544: -#line 3834 "mrbgems/mruby-compiler/core/parse.y" + case 547: /* f_bad_arg: "global variable" */ +#line 3855 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a global variable"); (yyval.nd) = 0; } -#line 9767 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10129 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 545: -#line 3839 "mrbgems/mruby-compiler/core/parse.y" + case 548: /* f_bad_arg: "class variable" */ +#line 3860 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a class variable"); (yyval.nd) = 0; } -#line 9776 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10138 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 546: -#line 3844 "mrbgems/mruby-compiler/core/parse.y" + case 549: /* f_bad_arg: "numbered parameter" */ +#line 3865 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a numbered parameter"); (yyval.nd) = 0; } -#line 9785 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10147 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 547: -#line 3851 "mrbgems/mruby-compiler/core/parse.y" + case 550: /* f_norm_arg: f_bad_arg */ +#line 3872 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 9793 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10155 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 548: -#line 3855 "mrbgems/mruby-compiler/core/parse.y" + case 551: /* f_norm_arg: "local variable or method" */ +#line 3876 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 9802 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10164 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 549: -#line 3862 "mrbgems/mruby-compiler/core/parse.y" + case 552: /* f_arg_item: f_norm_arg */ +#line 3883 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_arg(p, (yyvsp[0].id)); } -#line 9810 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10172 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 550: -#line 3866 "mrbgems/mruby-compiler/core/parse.y" + case 553: /* @32: %empty */ +#line 3887 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); } -#line 9818 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10180 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 551: -#line 3870 "mrbgems/mruby-compiler/core/parse.y" + case 554: /* f_arg_item: tLPAREN @32 f_margs rparen */ +#line 3891 "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 9828 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10190 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 552: -#line 3878 "mrbgems/mruby-compiler/core/parse.y" + case 555: /* f_arg: f_arg_item */ +#line 3899 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9836 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10198 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 553: -#line 3882 "mrbgems/mruby-compiler/core/parse.y" + case 556: /* f_arg: f_arg ',' f_arg_item */ +#line 3903 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9844 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10206 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 554: -#line 3888 "mrbgems/mruby-compiler/core/parse.y" + case 557: /* f_opt_asgn: "local variable or method" '=' */ +#line 3909 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[-1].id)); local_nest(p); (yyval.id) = (yyvsp[-1].id); } -#line 9854 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10216 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 555: -#line 3896 "mrbgems/mruby-compiler/core/parse.y" + case 558: /* f_opt: f_opt_asgn arg */ +#line 3917 "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 9864 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10226 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 556: -#line 3904 "mrbgems/mruby-compiler/core/parse.y" + case 559: /* f_block_opt: f_opt_asgn primary_value */ +#line 3925 "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 9874 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10236 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 557: -#line 3912 "mrbgems/mruby-compiler/core/parse.y" + case 560: /* f_block_optarg: f_block_opt */ +#line 3933 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9882 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10244 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 558: -#line 3916 "mrbgems/mruby-compiler/core/parse.y" + case 561: /* f_block_optarg: f_block_optarg ',' f_block_opt */ +#line 3937 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9890 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10252 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 559: -#line 3922 "mrbgems/mruby-compiler/core/parse.y" + case 562: /* f_optarg: f_opt */ +#line 3943 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9898 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10260 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 560: -#line 3926 "mrbgems/mruby-compiler/core/parse.y" + case 563: /* f_optarg: f_optarg ',' f_opt */ +#line 3947 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9906 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10268 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 563: -#line 3936 "mrbgems/mruby-compiler/core/parse.y" + case 566: /* f_rest_arg: restarg_mark "local variable or method" */ +#line 3957 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 9915 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10277 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 564: -#line 3941 "mrbgems/mruby-compiler/core/parse.y" + case 567: /* f_rest_arg: restarg_mark */ +#line 3962 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); local_add_f(p, (yyval.id)); } -#line 9924 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10286 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 567: -#line 3952 "mrbgems/mruby-compiler/core/parse.y" + case 570: /* f_block_arg: blkarg_mark "local variable or method" */ +#line 3973 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9932 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10294 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 568: -#line 3956 "mrbgems/mruby-compiler/core/parse.y" + case 571: /* f_block_arg: blkarg_mark */ +#line 3977 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 9940 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10302 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 569: -#line 3962 "mrbgems/mruby-compiler/core/parse.y" + case 572: /* opt_f_block_arg: ',' f_block_arg */ +#line 3983 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9948 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10310 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 570: -#line 3966 "mrbgems/mruby-compiler/core/parse.y" + case 573: /* opt_f_block_arg: none */ +#line 3987 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 9956 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10318 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 571: -#line 3972 "mrbgems/mruby-compiler/core/parse.y" + case 574: /* singleton: var_ref */ +#line 3993 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 9965 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10327 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 572: -#line 3976 "mrbgems/mruby-compiler/core/parse.y" + case 575: /* $@33: %empty */ +#line 3997 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_BEG;} -#line 9971 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10333 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 573: -#line 3977 "mrbgems/mruby-compiler/core/parse.y" + case 576: /* singleton: '(' $@33 expr rparen */ +#line 3998 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-1].nd) == 0) { yyerror(p, "can't define singleton method for ()."); @@ -9994,63 +10356,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = (yyvsp[-1].nd); } -#line 9998 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10360 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 575: -#line 4003 "mrbgems/mruby-compiler/core/parse.y" + case 578: /* assoc_list: assocs trailer */ +#line 4024 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 10006 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10368 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 576: -#line 4009 "mrbgems/mruby-compiler/core/parse.y" + case 579: /* assocs: assoc */ +#line 4030 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 10015 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10377 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 577: -#line 4014 "mrbgems/mruby-compiler/core/parse.y" + case 580: /* assocs: assocs comma assoc */ +#line 4035 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10023 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10385 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 578: -#line 4020 "mrbgems/mruby-compiler/core/parse.y" + case 581: /* assoc: arg "=>" arg */ +#line 4041 "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 10033 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10395 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 579: -#line 4026 "mrbgems/mruby-compiler/core/parse.y" + case 582: /* assoc: "local variable or method" "label" arg */ +#line 4047 "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 10042 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10404 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 580: -#line 4031 "mrbgems/mruby-compiler/core/parse.y" + case 583: /* assoc: "local variable or method" "label" */ +#line 4052 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_sym(p, (yyvsp[-1].id)), label_reference(p, (yyvsp[-1].id))); } -#line 10050 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10412 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 581: -#line 4035 "mrbgems/mruby-compiler/core/parse.y" + case 584: /* assoc: "numbered parameter" "label" */ +#line 4056 "mrbgems/mruby-compiler/core/parse.y" + { + mrb_sym sym = intern_numparam((yyvsp[-1].num)); + (yyval.nd) = cons(new_sym(p, sym), label_reference(p, sym)); + } +#line 10421 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 585: /* assoc: "numbered parameter" "label" arg */ +#line 4061 "mrbgems/mruby-compiler/core/parse.y" + { + void_expr_error(p, (yyvsp[0].nd)); + (yyval.nd) = cons(new_sym(p, intern_numparam((yyvsp[-2].num))), (yyvsp[0].nd)); + } +#line 10430 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 586: /* assoc: string_fragment "label" arg */ +#line 4066 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); if (typen((yyvsp[-2].nd)->car) == NODE_DSTR) { @@ -10060,67 +10440,75 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = cons(new_sym(p, new_strsym(p, (yyvsp[-2].nd))), (yyvsp[0].nd)); } } -#line 10064 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10444 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 582: -#line 4045 "mrbgems/mruby-compiler/core/parse.y" + case 587: /* assoc: "**" arg */ +#line 4076 "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 10073 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10453 "mrbgems/mruby-compiler/core/y.tab.c" + break; + + case 588: /* assoc: "**" */ +#line 4081 "mrbgems/mruby-compiler/core/parse.y" + { + (yyval.nd) = cons(new_kw_rest_args(p, 0), new_lvar(p, intern_op(pow))); + } +#line 10461 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 595: -#line 4072 "mrbgems/mruby-compiler/core/parse.y" + case 601: /* call_op: '.' */ +#line 4107 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = '.'; } -#line 10081 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10469 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 596: -#line 4076 "mrbgems/mruby-compiler/core/parse.y" + case 602: /* call_op: "&." */ +#line 4111 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = 0; } -#line 10089 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10477 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 598: -#line 4083 "mrbgems/mruby-compiler/core/parse.y" + case 604: /* call_op2: "::" */ +#line 4118 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = tCOLON2; } -#line 10097 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10485 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 607: -#line 4104 "mrbgems/mruby-compiler/core/parse.y" + case 613: /* term: ';' */ +#line 4139 "mrbgems/mruby-compiler/core/parse.y" {yyerrok;} -#line 10103 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10491 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 609: -#line 4109 "mrbgems/mruby-compiler/core/parse.y" + case 615: /* nl: '\n' */ +#line 4144 "mrbgems/mruby-compiler/core/parse.y" { p->lineno += (yyvsp[0].num); p->column = 0; } -#line 10112 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10500 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 613: -#line 4121 "mrbgems/mruby-compiler/core/parse.y" + case 619: /* none: %empty */ +#line 4156 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 10120 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10508 "mrbgems/mruby-compiler/core/y.tab.c" break; -#line 10124 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10512 "mrbgems/mruby-compiler/core/y.tab.c" default: break; } @@ -10135,11 +10523,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; - YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; @@ -10163,50 +10550,44 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (p, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) { + yypcontext_t yyctx + = {yyssp, yytoken}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; + yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; - else if (yysyntax_error_status == 1) + else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); - yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); - if (!yymsg) + yymsg = YY_CAST (char *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); + if (yymsg) { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; + yysyntax_error_status + = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + yymsgp = yymsg; } else { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = YYENOMEM; } } yyerror (p, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; + if (yysyntax_error_status == YYENOMEM) + YYNOMEM; } -# undef YYSYNTAX_ERROR -#endif } - - if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an @@ -10239,6 +10620,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; + ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -10255,13 +10637,14 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ + /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) @@ -10275,7 +10658,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yydestruct ("Error: popping", - yystos[yystate], yyvsp, p); + YY_ACCESSING_SYMBOL (yystate), yyvsp, p); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -10287,7 +10670,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; @@ -10298,7 +10681,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); `-------------------------------------*/ yyacceptlab: yyresult = 0; - goto yyreturn; + goto yyreturnlab; /*-----------------------------------. @@ -10306,24 +10689,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); `-----------------------------------*/ yyabortlab: yyresult = 1; - goto yyreturn; + goto yyreturnlab; -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ yyexhaustedlab: yyerror (p, YY_("memory exhausted")); yyresult = 2; - /* Fall through. */ -#endif + goto yyreturnlab; -/*-----------------------------------------------------. -| yyreturn -- parsing is finished, return the result. | -`-----------------------------------------------------*/ -yyreturn: +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at @@ -10339,20 +10720,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[+*yyssp], yyvsp, p); + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, p); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif -#if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); -#endif return yyresult; } -#line 4125 "mrbgems/mruby-compiler/core/parse.y" + +#line 4160 "mrbgems/mruby-compiler/core/parse.y" #define pylval (*((YYSTYPE*)(p->ylval))) @@ -10375,7 +10755,7 @@ yyerror(parser_state *p, const char *s) } else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) { n = strlen(s); - c = (char *)parser_palloc(p, n + 1); + c = (char*)parser_palloc(p, n + 1); memcpy(c, s, n + 1); p->error_buffer[p->nerr].message = c; p->error_buffer[p->nerr].lineno = p->lineno; @@ -10414,7 +10794,7 @@ yywarning(parser_state *p, const char *s) } else if (p->nwarn < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) { n = strlen(s); - c = (char *)parser_palloc(p, n + 1); + c = (char*)parser_palloc(p, n + 1); memcpy(c, s, n + 1); p->warn_buffer[p->nwarn].message = c; p->warn_buffer[p->nwarn].lineno = p->lineno; @@ -10449,7 +10829,7 @@ backref_error(parser_state *p, node *n) yyerror_c(p, "can't set variable $", (char)intn(n->cdr)); } else { - mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c); + yyerror(p, "Internal error in backref_error()"); } } @@ -10495,22 +10875,20 @@ static mrb_bool skips(parser_state *p, const char *s); static inline int nextc0(parser_state *p) { - int c; - if (p->s && p->s < p->send) { - c = (unsigned char)*p->s++; + return (unsigned char)*p->s++; } else { #ifndef MRB_NO_STDIO + int c; + if (p->f) { c = fgetc(p->f); - if (feof(p->f)) return -1; + if (!feof(p->f)) return c; } - else #endif - return -1; + return -1; } - return c; } static inline int @@ -10915,7 +11293,7 @@ read_escape(parser_state *p) c = read_escape_unicode(p, 4); if (c < 0) return 0; } - return -c; + return -c; case 'b':/* backspace */ return '\010'; @@ -10964,7 +11342,7 @@ read_escape(parser_state *p) } static void -heredoc_count_indent(parser_heredoc_info *hinf, const char *str, size_t len, size_t spaces, size_t *offset) +heredoc_count_indent(parser_heredoc_info *hinfo, const char *str, size_t len, size_t spaces, size_t *offset) { size_t indent = 0; *offset = 0; @@ -10979,7 +11357,7 @@ heredoc_count_indent(parser_heredoc_info *hinf, const char *str, size_t len, siz else break; size_t nindent = indent + size; - if (nindent > spaces || nindent > hinf->indent) + if (nindent > spaces || nindent > hinfo->indent) break; indent = nindent; *offset += 1; @@ -10987,14 +11365,14 @@ heredoc_count_indent(parser_heredoc_info *hinf, const char *str, size_t len, siz } static void -heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) +heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinfo) { - if (!hinf->remove_indent || hinf->indent == 0) + if (!hinfo->remove_indent || hinfo->indent == 0) return; node *indented, *n, *pair, *escaped, *nspaces; const char *str; size_t len, spaces, offset, start, end; - indented = hinf->indented; + indented = hinfo->indented; while (indented) { n = indented->car; pair = n->car; @@ -11011,7 +11389,7 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) if (end > len) end = len; spaces = (size_t)nspaces->car; size_t esclen = end - start; - heredoc_count_indent(hinf, str + start, esclen, spaces, &offset); + heredoc_count_indent(hinfo, str + start, esclen, spaces, &offset); esclen -= offset; memcpy(newstr + newlen, str + start + offset, esclen); newlen += esclen; @@ -11026,7 +11404,7 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) pair->cdr = (node*)newlen; } else { spaces = (size_t)nspaces->car; - heredoc_count_indent(hinf, str, len, spaces, &offset); + heredoc_count_indent(hinfo, str, len, spaces, &offset); pair->car = (node*)(str + offset); pair->cdr = (node*)(len - offset); } @@ -11035,13 +11413,13 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinf) } static void -heredoc_push_indented(parser_state *p, parser_heredoc_info *hinf, node *pair, node *escaped, node *nspaces, mrb_bool empty_line) +heredoc_push_indented(parser_state *p, parser_heredoc_info *hinfo, node *pair, node *escaped, node *nspaces, mrb_bool empty_line) { - hinf->indented = push(hinf->indented, cons(pair, cons(escaped, nspaces))); + hinfo->indented = push(hinfo->indented, cons(pair, cons(escaped, nspaces))); while (nspaces) { size_t tspaces = (size_t)nspaces->car; - if ((hinf->indent == ~0U || tspaces < hinf->indent) && !empty_line) - hinf->indent = tspaces; + if ((hinfo->indent == ~0U || tspaces < hinfo->indent) && !empty_line) + hinfo->indent = tspaces; nspaces = nspaces->cdr; } } @@ -11050,14 +11428,14 @@ static int parse_string(parser_state *p) { int c; - string_type type = (string_type)(intptr_t)p->lex_strterm->car; - int nest_level = intn(p->lex_strterm->cdr->car); - int beg = intn(p->lex_strterm->cdr->cdr->car); - int end = intn(p->lex_strterm->cdr->cdr->cdr); - parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL; - - mrb_bool unindent = hinf && hinf->remove_indent; - mrb_bool head = hinf && hinf->line_head; + string_type type = (string_type)p->lex_strterm->type; + int nest_level = p->lex_strterm->level; + int beg = p->lex_strterm->paren; + int end = p->lex_strterm->term; + parser_heredoc_info *hinfo = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_info(p) : NULL; + + mrb_bool unindent = hinfo && hinfo->remove_indent; + mrb_bool head = hinfo && hinfo->line_head; mrb_bool empty = TRUE; size_t spaces = 0; size_t pos = -1; @@ -11069,26 +11447,26 @@ parse_string(parser_state *p) newtok(p); while ((c = nextc(p)) != end || nest_level != 0) { pos++; - if (hinf && (c == '\n' || c < 0)) { + if (hinfo && (c == '\n' || c < 0)) { mrb_bool line_head; tokadd(p, '\n'); tokfix(p); p->lineno++; p->column = 0; - line_head = hinf->line_head; - hinf->line_head = TRUE; + line_head = hinfo->line_head; + hinfo->line_head = TRUE; if (line_head) { /* check whether end of heredoc */ const char *s = tok(p); int len = toklen(p); - if (hinf->allow_indent) { + if (hinfo->allow_indent) { while (ISSPACE(*s) && len > 0) { - ++s; - --len; + s++; + len--; } } - if (hinf->term_len > 0 && len-1 == hinf->term_len && strncmp(s, hinf->term, len-1) == 0) { - heredoc_remove_indent(p, hinf); + if (hinfo->term_len > 0 && len-1 == hinfo->term_len && strncmp(s, hinfo->term, len-1) == 0) { + heredoc_remove_indent(p, hinfo); return tHEREDOC_END; } } @@ -11097,11 +11475,11 @@ parse_string(parser_state *p) const char s1[] = "can't find heredoc delimiter \""; const char s2[] = "\" anywhere before EOF"; - if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) { + if (sizeof(s1)+sizeof(s2)+strlen(hinfo->term)+1 >= sizeof(buf)) { yyerror(p, "can't find heredoc delimiter anywhere before EOF"); } else { strcpy(buf, s1); - strcat(buf, hinf->term); + strcat(buf, hinfo->term); strcat(buf, s2); yyerror(p, buf); } @@ -11111,7 +11489,7 @@ parse_string(parser_state *p) pylval.nd = nd; if (unindent && head) { nspaces = push(nspaces, nint(spaces)); - heredoc_push_indented(p, hinf, nd->cdr, escaped, nspaces, empty && line_head); + heredoc_push_indented(p, hinfo, nd->cdr, escaped, nspaces, empty && line_head); } return tHD_STRING_MID; } @@ -11119,7 +11497,7 @@ parse_string(parser_state *p) if (c == '\t') spaces += 8; else if (ISSPACE(c)) - ++spaces; + spaces++; else empty = FALSE; } @@ -11129,11 +11507,11 @@ parse_string(parser_state *p) } else if (c == beg) { nest_level++; - p->lex_strterm->cdr->car = nint(nest_level); + p->lex_strterm->level = nest_level; } else if (c == end) { nest_level--; - p->lex_strterm->cdr->car = nint(nest_level); + p->lex_strterm->level = nest_level; } else if (c == '\\') { c = nextc(p); @@ -11170,14 +11548,14 @@ parse_string(parser_state *p) if (c < 0) break; tokadd(p, -c); } - if (hinf) - hinf->line_head = FALSE; + if (hinfo) + hinfo->line_head = FALSE; } else { pushback(p, c); tokadd(p, read_escape(p)); - if (hinf) - hinf->line_head = FALSE; + if (hinfo) + hinfo->line_head = FALSE; } } else { @@ -11202,12 +11580,12 @@ parse_string(parser_state *p) p->cmd_start = TRUE; node *nd = new_str(p, tok(p), toklen(p)); pylval.nd = nd; - if (hinf) { + if (hinfo) { if (unindent && head) { nspaces = push(nspaces, nint(spaces)); - heredoc_push_indented(p, hinf, nd->cdr, escaped, nspaces, FALSE); + heredoc_push_indented(p, hinfo, nd->cdr, escaped, nspaces, FALSE); } - hinf->line_head = FALSE; + hinfo->line_head = FALSE; return tHD_STRING_PART; } return tSTRING_PART; @@ -12174,17 +12552,10 @@ parser_yylex(parser_state *p) return tINTEGER; #else double d; - char *endp; - errno = 0; - d = mrb_float_read(tok(p), &endp); - if (d == 0 && endp == tok(p)) { + if (!mrb_read_float(tok(p), NULL, &d)) { yywarning_s(p, "corrupted float value", tok(p)); } - else if (errno == ERANGE) { - yywarning_s(p, "float out of range", tok(p)); - errno = 0; - } suffix = number_literal_suffix(p); if (seen_e && (suffix & NUM_SUFFIX_R)) { pushback(p, 'r'); @@ -12529,8 +12900,8 @@ parser_yylex(parser_state *p) if (last_state == EXPR_FNAME) goto gvar; tokfix(p); { - mrb_int n = mrb_int_read(tok(p), NULL, NULL); - if (n > INT32_MAX) { + mrb_int n; + if (!mrb_read_int(tok(p), NULL, NULL, &n)) { yywarning(p, "capture group index too big; always nil"); return keyword_nil; } @@ -12660,16 +13031,17 @@ parser_yylex(parser_state *p) nvars = nvars->cdr; } nvar = intn(p->nvars->car); - if (nvar == -1) { - yywarning(p, "numbered parameter used in inner block"); - } - else { - int nvars = intn(p->nvars->car); - p->nvars->car = nint(nvars > n ? nvars : n); + if (nvar != -2) { /* numbered parameters never appear on toplevel */ + if (nvar == -1) { + yywarning(p, "numbered parameter used in inner block"); + } + else { + p->nvars->car = nint(nvar > n ? nvar : n); + } + pylval.num = n; + p->lstate = EXPR_END; + return tNUMPARAM; } - pylval.num = n; - p->lstate = EXPR_END; - return tNUMPARAM; } } /* fall through */ @@ -12743,7 +13115,7 @@ parser_yylex(parser_state *p) return keyword_do_block; return keyword_do; } - if (state == EXPR_BEG || state == EXPR_VALUE) + if (state == EXPR_BEG || state == EXPR_VALUE || state == EXPR_CLASS) return kw->id[0]; else { if (kw->id[0] != kw->id[1]) @@ -12824,14 +13196,13 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt) i++; n = n->cdr; } - cxt->syms = (mrb_sym *)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym)); + cxt->syms = (mrb_sym*)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym)); cxt->slen = i; for (i=0, n=n0; n; i++,n=n->cdr) { cxt->syms[i] = sym(n->car); } } -void mrb_codedump_all(mrb_state*, struct RProc*); void mrb_parser_dump(mrb_state *mrb, node *tree, int offset); MRB_API void @@ -12882,7 +13253,7 @@ mrb_parser_new(mrb_state *mrb) pool = mrb_pool_open(mrb); if (!pool) return NULL; - p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state)); + p = (parser_state*)mrb_pool_alloc(pool, sizeof(parser_state)); if (!p) return NULL; *p = parser_state_zero; @@ -12907,8 +13278,6 @@ mrb_parser_new(mrb_state *mrb) p->tokbuf = p->buf; p->lex_strterm = NULL; - p->all_heredocs = p->parsing_heredoc = NULL; - p->lex_strterm_before_heredoc = NULL; p->current_filename_index = -1; p->filename_table = NULL; @@ -12928,7 +13297,7 @@ mrb_parser_free(parser_state *p) { MRB_API mrbc_context* mrbc_context_new(mrb_state *mrb) { - return (mrbc_context *)mrb_calloc(mrb, 1, sizeof(mrbc_context)); + return (mrbc_context*)mrb_calloc(mrb, 1, sizeof(mrbc_context)); } MRB_API void @@ -12944,7 +13313,7 @@ mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s) { if (s) { size_t len = strlen(s); - char *p = (char *)mrb_malloc(mrb, len + 1); + char *p = (char*)mrb_malloc(mrb, len + 1); memcpy(p, s, len + 1); if (c->filename) { @@ -12970,6 +13339,7 @@ mrbc_cleanup_local_variables(mrb_state *mrb, mrbc_context *c) c->syms = NULL; c->slen = 0; } + c->keep_lv = FALSE; } MRB_API void @@ -12983,7 +13353,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f) p->filename_sym = sym; p->lineno = (p->filename_table_length > 0)? 0 : 1; - for (i = 0; i < p->filename_table_length; ++i) { + for (i = 0; i < p->filename_table_length; i++) { if (p->filename_table[i] == sym) { p->current_filename_index = i; return; @@ -13021,8 +13391,8 @@ mrb_parse_file_continue(mrb_state *mrb, FILE *f, const void *prebuf, size_t preb p = mrb_parser_new(mrb); if (!p) return NULL; if (prebuf) { - p->s = (const char *)prebuf; - p->send = (const char *)prebuf + prebufsize; + p->s = (const char*)prebuf; + p->send = (const char*)prebuf + prebufsize; } else { p->s = p->send = NULL; @@ -13163,19 +13533,20 @@ mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c) return mrb_load_exec(mrb, mrb_parse_file_continue(mrb, fp, leading.b, bufsize, c), c); } else { - size_t binsize; + mrb_int binsize; uint8_t *bin; mrb_value bin_obj = mrb_nil_value(); /* temporary string object */ mrb_value result; binsize = bin_to_uint32(leading.h.binary_size); bin_obj = mrb_str_new(mrb, NULL, binsize); - bin = (uint8_t *)RSTRING_PTR(bin_obj); - memcpy(bin, leading.b, bufsize); - if (binsize > bufsize && - fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { - binsize = bufsize; - /* The error is reported by mrb_load_irep_buf_cxt() */ + bin = (uint8_t*)RSTRING_PTR(bin_obj); + if ((size_t)binsize > bufsize) { + memcpy(bin, leading.b, bufsize); + if (fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { + binsize = bufsize; + /* The error is reported by mrb_load_irep_buf_cxt() */ + } } result = mrb_load_irep_buf_cxt(mrb, bin, binsize, c); @@ -13647,12 +14018,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } } n2 = n2->cdr; - if (n2) { - if (n2->car) { - dump_prefix(n2, offset+2); - printf("post:\n"); - dump_recur(mrb, n2->car, offset+3); - } + if (n2 && n2->car) { + dump_prefix(n2, offset+2); + printf("post:\n"); + dump_recur(mrb, n2->car, offset+3); } } } @@ -13812,20 +14181,28 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_REGX: - printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr); + printf("NODE_REGX /%s/\n", (char*)tree->car); + if (tree->cdr->car) { + dump_prefix(tree, offset+1); + printf("opt: %s\n", (char*)tree->cdr->car); + } + if (tree->cdr->cdr) { + dump_prefix(tree, offset+1); + printf("enc: %s\n", (char*)tree->cdr->cdr); + } break; case NODE_DREGX: printf("NODE_DREGX:\n"); dump_recur(mrb, tree->car, offset+1); - dump_prefix(tree, offset); + dump_prefix(tree, offset+1); printf("tail: %s\n", (char*)tree->cdr->cdr->car); if (tree->cdr->cdr->cdr->car) { - dump_prefix(tree, offset); + dump_prefix(tree, offset+1); printf("opt: %s\n", (char*)tree->cdr->cdr->cdr->car); } if (tree->cdr->cdr->cdr->cdr) { - dump_prefix(tree, offset); + dump_prefix(tree, offset+1); printf("enc: %s\n", (char*)tree->cdr->cdr->cdr->cdr); } break; diff --git a/mruby/mrbgems/mruby-complex/mrblib/complex.rb b/mruby/mrbgems/mruby-complex/mrblib/complex.rb index 4c36179c..e341efc5 100644 --- a/mruby/mrbgems/mruby-complex/mrblib/complex.rb +++ b/mruby/mrbgems/mruby-complex/mrblib/complex.rb @@ -74,3 +74,9 @@ def i end undef i end + +class Numeric + def to_c + Complex(self, 0) + end +end diff --git a/mruby/mrbgems/mruby-complex/src/complex.c b/mruby/mrbgems/mruby-complex/src/complex.c index 6a02b1e9..ad88a67e 100644 --- a/mruby/mrbgems/mruby-complex/src/complex.c +++ b/mruby/mrbgems/mruby-complex/src/complex.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #ifdef MRB_NO_FLOAT @@ -45,6 +46,8 @@ struct RComplex { #define complex_ptr(mrb, v) (&((struct RComplex*)mrb_obj_ptr(v))->r) #endif +mrb_static_assert_object_size(struct RComplex); + static struct RBasic* complex_alloc(mrb_state *mrb, struct RClass *c, struct mrb_complex **p) { @@ -82,6 +85,15 @@ mrb_complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary) #define complex_new(mrb, real, imag) mrb_complex_new(mrb, real, imag) +void +mrb_complex_copy(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct mrb_complex *p1 = complex_ptr(mrb, x); + struct mrb_complex *p2 = complex_ptr(mrb, y); + p1->real = p2->real; + p1->imaginary = p2->imaginary; +} + static mrb_value complex_real(mrb_state *mrb, mrb_value self) { @@ -122,9 +134,18 @@ mrb_complex_to_i(mrb_state *mrb, mrb_value self) { struct mrb_complex *p = complex_ptr(mrb, self); +#ifdef MRB_USE_BIGINT if (p->imaginary != 0) { mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Integer", self); } + if (!FIXABLE_FLOAT(p->real)) { + return mrb_bint_new_float(mrb, p->real); + } +#else + if (p->imaginary != 0 || !FIXABLE_FLOAT(p->real)) { + mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %v into Integer", self); + } +#endif return mrb_int_value(mrb, (mrb_int)p->real); } @@ -168,10 +189,9 @@ complex_eq(mrb_state *mrb, mrb_value x) return mrb_bool_value(mrb_complex_eq(mrb, x, y)); } -static mrb_value -complex_add(mrb_state *mrb, mrb_value x) +mrb_value +mrb_complex_add(mrb_state *mrb, mrb_value x, mrb_value y) { - mrb_value y = mrb_get_arg1(mrb); struct mrb_complex *p1 = complex_ptr(mrb, x); switch (mrb_type(y)) { @@ -190,9 +210,15 @@ complex_add(mrb_state *mrb, mrb_value x) } static mrb_value -complex_sub(mrb_state *mrb, mrb_value x) +complex_add(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); + return mrb_complex_add(mrb, x, y); +} + +mrb_value +mrb_complex_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ struct mrb_complex *p1 = complex_ptr(mrb, x); switch (mrb_type(y)) { @@ -211,9 +237,15 @@ complex_sub(mrb_state *mrb, mrb_value x) } static mrb_value -complex_mul(mrb_state *mrb, mrb_value x) +complex_sub(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); + return mrb_complex_sub(mrb, x, y); +} + +mrb_value +mrb_complex_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ struct mrb_complex *p1 = complex_ptr(mrb, x); switch (mrb_type(y)) { @@ -232,6 +264,13 @@ complex_mul(mrb_state *mrb, mrb_value x) } } +static mrb_value +complex_mul(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + return mrb_complex_mul(mrb, x, y); +} + /* Arithmetic on (significand, exponent) pairs avoids premature overflow in complex division */ struct float_pair { @@ -272,14 +311,16 @@ div_pair(struct float_pair *q, struct float_pair const *a, q->x = a->x - b->x; } -static mrb_value -complex_div(mrb_state *mrb, mrb_value self) +mrb_value +mrb_complex_div(mrb_state *mrb, mrb_value self, mrb_value rhs) { struct mrb_complex *a, *b; - mrb_value rhs = mrb_get_arg1(mrb); a = complex_ptr(mrb, self); if (mrb_type(rhs) != MRB_TT_COMPLEX) { + if (mrb_integer_p(rhs) && mrb_integer(rhs) == 0) { + mrb_int_zerodiv(mrb); + } mrb_float f = mrb_as_float(mrb, rhs); return complex_new(mrb, mrb_div_float(a->real, f), mrb_div_float(a->imaginary, f)); } @@ -324,88 +365,32 @@ complex_div(mrb_state *mrb, mrb_value self) return complex_new(mrb, F(ldexp)(zr.s, zr.x), F(ldexp)(zi.s, zi.x)); } -mrb_int mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y); -mrb_value mrb_rational_new(mrb_state *mrb, mrb_int n, mrb_int d); -mrb_value mrb_rational_div(mrb_state *mrb, mrb_value x); - -/* 15.2.8.3.4 */ -/* - * redefine Integer#/ - */ static mrb_value -cpx_int_div(mrb_state *mrb, mrb_value x) +complex_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); - return mrb_int_value(mrb, div); - } - switch (mrb_type(y)) { -#ifdef MRB_USE_RATIONAL - case MRB_TT_RATIONAL: - return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1)); -#endif - case MRB_TT_COMPLEX: - x = complex_new(mrb, (mrb_float)a, 0); - return complex_div(mrb, x); - default: - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); - } + return mrb_complex_div(mrb, x, y); } -/* 15.2.9.3.19(x) */ -/* - * redefine Integer#quo - */ - static mrb_value -cpx_int_quo(mrb_state *mrb, mrb_value x) +complex_hash(mrb_state *mrb, mrb_value cpx) { - mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - switch (mrb_type(y)) { -#ifdef MRB_USE_RATIONAL - case MRB_TT_RATIONAL: - x = mrb_rational_new(mrb, a, 1); - return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); -#endif - case MRB_TT_COMPLEX: - x = complex_new(mrb, (mrb_float)a, 0); - return complex_div(mrb, x); - default: - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); - } + struct mrb_complex *c = complex_ptr(mrb, cpx); + uint32_t hash = mrb_byte_hash((uint8_t*)&c->real, sizeof(mrb_float)); + hash = mrb_byte_hash_step((uint8_t*)&c->imaginary, sizeof(mrb_float), hash); + return mrb_int_value(mrb, hash); } static mrb_value -cpx_flo_div(mrb_state *mrb, mrb_value x) +nil_to_c(mrb_state *mrb, mrb_value self) { - mrb_float a = mrb_float(x); - mrb_value y = mrb_get_arg1(mrb); - - switch(mrb_type(y)) { - case MRB_TT_COMPLEX: - return complex_div(mrb, complex_new(mrb, a, 0)); - case MRB_TT_FLOAT: - a = mrb_div_float(a, mrb_float(y)); - return mrb_float_value(mrb, a); - default: - a = mrb_div_float(a, mrb_as_float(mrb, y)); - return mrb_float_value(mrb, a); - } + return complex_new(mrb, 0, 0); } void mrb_mruby_complex_gem_init(mrb_state *mrb) { struct RClass *comp; -#ifdef COMPLEX_INLINE - mrb_assert(sizeof(struct mrb_complex) < sizeof(void*)*3); -#endif - comp = mrb_define_class_id(mrb, MRB_SYM(Complex), mrb_class_get_id(mrb, MRB_SYM(Numeric))); MRB_SET_INSTANCE_TT(comp, MRB_TT_COMPLEX); @@ -424,10 +409,8 @@ 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)); /* 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 */ + mrb_define_method(mrb, comp, "hash", complex_hash, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->nil_class, "to_c", nil_to_c, MRB_ARGS_NONE()); } void diff --git a/mruby/mrbgems/mruby-data/mrbgem.rake b/mruby/mrbgems/mruby-data/mrbgem.rake new file mode 100644 index 00000000..ea897920 --- /dev/null +++ b/mruby/mrbgems/mruby-data/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-data') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'standard Data class' +end diff --git a/mruby/mrbgems/mruby-data/src/data.c b/mruby/mrbgems/mruby-data/src/data.c new file mode 100644 index 00000000..91bc55a0 --- /dev/null +++ b/mruby/mrbgems/mruby-data/src/data.c @@ -0,0 +1,462 @@ +/* +** data.c - Data class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RDATA_LEN(st) RARRAY_LEN(st) +#define RDATA_PTR(st) RARRAY_PTR(st) + +#define data_p(o) (mrb_type(o) == MRB_TT_STRUCT) + +static struct RClass * +data_class(mrb_state *mrb) +{ + return mrb_class_get_id(mrb, MRB_SYM(Data)); +} + +static void +data_corrupted(mrb_state *mrb) +{ + mrb_raise(mrb, E_TYPE_ERROR, "corrupted data"); +} + +static mrb_value +data_s_members(mrb_state *mrb, struct RClass *c) +{ + struct RClass* sclass = data_class(mrb); + mrb_value mem; + + for (;;) { + mem = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__members__)); + if (!mrb_nil_p(mem)) { + if (!mrb_array_p(mem)) { + data_corrupted(mrb); + } + return mem; + } + c = c->super; + if (c == sclass || c == 0) { + mrb_raise(mrb, E_TYPE_ERROR, "uninitialized data"); + } + } +} + +static mrb_value +data_members(mrb_state *mrb, mrb_value obj) +{ + if (!data_p(obj) || RDATA_LEN(obj) == 0) { + data_corrupted(mrb); + } + mrb_value members = data_s_members(mrb, mrb_obj_class(mrb, obj)); + if (RDATA_LEN(obj) != RARRAY_LEN(members)) { + mrb_raisef(mrb, E_TYPE_ERROR, + "data size differs (%i required %i given)", + RARRAY_LEN(members), RDATA_LEN(obj)); + } + return members; +} + +static mrb_value +mrb_data_s_members(mrb_state *mrb, mrb_value klass) +{ + mrb_value members = data_s_members(mrb, mrb_class_ptr(klass)); + return mrb_ary_new_from_values(mrb, RARRAY_LEN(members), RARRAY_PTR(members)); +} + +/* + * call-seq: + * data.members -> array + * + * Returns an array of strings representing the names of the instance + * variables. + * + * Customer = Data.define(:name, :address, :zip) + * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * joe.members #=> [:name, :address, :zip] + */ + +static mrb_value +mrb_data_members(mrb_state *mrb, mrb_value obj) +{ + return mrb_data_s_members(mrb, mrb_obj_value(mrb_obj_class(mrb, obj))); +} + +static mrb_value +mrb_data_ref(mrb_state *mrb, mrb_value obj) +{ + mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); + mrb_value *ptr = RDATA_PTR(obj); + + if (!ptr) return mrb_nil_value(); + return ptr[i]; +} + +static void +make_data_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) +{ + const mrb_value *ptr_members = RARRAY_PTR(members); + mrb_int len = RARRAY_LEN(members); + int ai = mrb_gc_arena_save(mrb); + + for (mrb_int i=0; ic->ci->nk > 0) { + mrb_value tmp = mrb_str_new(mrb, NULL, sizeof(mrb_sym)*n); + mrb_sym *knames = (mrb_sym*)RSTRING_PTR(tmp); + mrb_value m = mrb_ary_new_capa(mrb, n); + vals = RARRAY_PTR(m); + for (mrb_int i=0; ibasic.c->super = c->c; */ + make_data_define_accessors(mrb, members, c); + return data; +} + +/* + * call-seq: + * DataClass.new(arg, ...) -> obj + * + * Data::define returns a new Class object, + * which can then be used to create specific instances of the new + * data structure. The number of actual parameters must be + * equal to the number of attributes defined for this class. + * Passing too many or too less parameters will raise an + * ArgumentError. + * + * The remaining methods listed in this section (class and instance) + * are defined for this generated class. + * + * # Create a structure named by its constant + * Customer = Data.define(:name, :address) #=> Customer + * Customer.new("Dave", "123 Main") #=> # + */ +static mrb_value +mrb_data_s_def(mrb_state *mrb, mrb_value klass) +{ + mrb_value rest; + mrb_value b, data; + mrb_sym id; + const mrb_value *argv; + mrb_int argc; + + mrb_get_args(mrb, "*&", &argv, &argc, &b); + if (argc == 0) { /* special case to avoid crash */ + mrb_argnum_error(mrb, argc, 1, -1); + } + else { + rest = mrb_ary_new_from_values(mrb, argc, argv); + for (mrb_int i=0; i true or false + * + * Equality---Returns true if other_data is + * equal to this one: they must be of the same class as generated by + * Data::define, and all values of must be equal + * (according to Object#==). + * + * Customer = Data.define(:name, :address, :zip) + * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * joe2 = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) + * jane = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345) + * joe == joe2 #=> true + * joe == jane #=> false + */ + +static mrb_value +mrb_data_equal(mrb_state *mrb, mrb_value s) +{ + mrb_value s2 = mrb_get_arg1(mrb); + mrb_value *ptr, *ptr2; + mrb_int len; + + if (mrb_obj_equal(mrb, s, s2)) { + return mrb_true_value(); + } + if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) { + return mrb_false_value(); + } + if (RDATA_LEN(s) != RDATA_LEN(s2)) { + return mrb_false_value(); + } + ptr = RDATA_PTR(s); + ptr2 = RDATA_PTR(s2); + len = RDATA_LEN(s); + for (mrb_int i=0; i true or false + * + * Two structures are equal if they are the same object, or if all their + * fields are equal (using Object#eql?). + */ +static mrb_value +mrb_data_eql(mrb_state *mrb, mrb_value s) +{ + mrb_value s2 = mrb_get_arg1(mrb); + mrb_value *ptr, *ptr2; + mrb_int len; + + if (mrb_obj_equal(mrb, s, s2)) { + return mrb_true_value(); + } + if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) { + return mrb_false_value(); + } + if (RDATA_LEN(s) != RDATA_LEN(s2)) { + return mrb_false_value(); + } + ptr = RDATA_PTR(s); + ptr2 = RDATA_PTR(s2); + len = RDATA_LEN(s); + for (mrb_int i=0; i hash + * + * Create a hash from member names and values. + */ +static mrb_value +mrb_data_to_h(mrb_state *mrb, mrb_value self) +{ + mrb_value members, ret; + mrb_value *mems, *vals; + + members = data_members(mrb, self); + mems = RARRAY_PTR(members); + vals = RDATA_PTR(self); + + ret = mrb_hash_new_capa(mrb, RARRAY_LEN(members)); + mrb_int len = RARRAY_LEN(members); + for (mrb_int i=0; i string + * data.inspect -> string + * + * Returns a string representation of Data + */ +static mrb_value +mrb_data_to_s(mrb_state *mrb, mrb_value self) +{ + mrb_value members, ret, cname; + mrb_value *mems, *vals; + mrb_int mlen; + + members = data_members(mrb, self); + mlen = RARRAY_LEN(members); + mems = RARRAY_PTR(members); + vals = RDATA_PTR(self); + ret = mrb_str_new_lit(mrb, "#0) mrb_str_cat_lit(mrb, ret, ", "); + mrb_str_cat(mrb, ret, name, len); + mrb_str_cat_lit(mrb, ret, "="); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, vals[i])); + mrb_gc_arena_restore(mrb, ai); + } + mrb_str_cat_lit(mrb, ret, ">"); + + return ret; +} + +/* + * A Data is a convenient way to bundle a number of + * attributes together, using accessor methods, without having to write + * an explicit class. + * + * The Data class is a generator of specific classes, + * each one of which is defined to hold a set of variables and their + * accessors. In these examples, we'll call the generated class + * "CustomerClass," and we'll show an example instance of that + * class as "CustomerInst." + * + * In the descriptions that follow, the parameter symbol refers + * to a symbol (such as :name). + */ +void +mrb_mruby_data_gem_init(mrb_state* mrb) +{ + struct RClass *d; + d = mrb_define_class(mrb, "Data", mrb->object_class); + MRB_SET_INSTANCE_TT(d, MRB_TT_STRUCT); + + mrb_undef_class_method(mrb, d, "new"); + mrb_define_class_method(mrb, d, "define", mrb_data_s_def, MRB_ARGS_ANY()); + + mrb_define_method(mrb, d, "==", mrb_data_equal, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, d, "members", mrb_data_members, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "initialize", mrb_data_initialize, MRB_ARGS_ANY()); + mrb_define_method(mrb, d, "initialize_copy", mrb_data_init_copy, MRB_ARGS_ANY()); + mrb_define_method(mrb, d, "eql?", mrb_data_eql, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, d, "to_h", mrb_data_to_h, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "to_s", mrb_data_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "inspect", mrb_data_to_s, MRB_ARGS_NONE()); +} + +void +mrb_mruby_data_gem_final(mrb_state* mrb) +{ +} diff --git a/mruby/mrbgems/mruby-data/test/data.rb b/mruby/mrbgems/mruby-data/test/data.rb new file mode 100644 index 00000000..e54be06c --- /dev/null +++ b/mruby/mrbgems/mruby-data/test/data.rb @@ -0,0 +1,76 @@ +## +# Struct ISO Test + +assert('Data') do + assert_equal Class, Data.class +end + +assert('Data.define') do + c = Data.define(:m1, :m2) + assert_equal Data, c.superclass + assert_equal [:m1, :m2], c.members +end + +assert('Data#==') do + c = Data.define(:m1, :m2) + cc1 = c.new(1,2) + cc2 = c.new(1,2) + assert_true cc1 == cc2 +end + +assert('Data#members') do + c = Data.define(:m1, :m2) + assert_equal [:m1, :m2], c.new(1,2).members +end + +assert('wrong struct arg count') do + c = Data.define(:m1) + assert_raise ArgumentError do + cc = c.new(1,2,3) + end +end + +assert('data dup') do + c = Data.define(:m1, :m2, :m3, :m4, :m5) + cc = c.new(1,2,3,4,5) + assert_nothing_raised { + assert_equal(cc, cc.dup) + } +end + +assert('Data inspect') do + c = Data.define(:m1, :m2, :m3, :m4, :m5) + cc = c.new(1,2,3,4,5) + assert_equal "#", cc.inspect +end + +assert('Data#to_h') do + s = Data.define(:white, :red, :green).new('ruuko', 'yuzuki', 'hitoe') + assert_equal({:white => 'ruuko', :red => 'yuzuki', :green => 'hitoe'}) { s.to_h } +end + +assert("Data.define does not allow array") do + assert_raise(TypeError) do + Data.define("Test", [:a]) + end +end + +assert("Data.define generates subclass of Data") do + begin + original_struct = Data + Data = String + assert_equal original_struct, original_struct.define(:foo).superclass + ensure + Data = original_struct + end +end + +assert 'Data#freeze' do + c = Data.define(:m) + + o = c.new(:test) + assert_equal :test, o.m + assert_nothing_raised { + o.freeze + } +end diff --git a/mruby/mrbgems/mruby-dir/README.md b/mruby/mrbgems/mruby-dir/README.md new file mode 100644 index 00000000..2be9d03c --- /dev/null +++ b/mruby/mrbgems/mruby-dir/README.md @@ -0,0 +1,53 @@ +# mruby-dir + +Dir class for mruby. Supported methods are: + +`.chdir` +`.delete` +`.entries` +`.exist?` +`.foreach` +`.getwd` +`.mkdir` +`.open` +`#close` +`#each` +`#read` +`#rewind` +`#seek` +`#tell` + +## License + +Copyright (c) 2012 Internet Initiative Japan Inc. + +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. + +### On Windows platforms, you must agree on additional license too: + +Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose is hereby granted without fee, provided +that this copyright and permissions notice appear in all copies and +derivatives. + +This software is supplied "as is" without express or implied warranty. + +But that said, if there are any problems please get in touch. diff --git a/mruby/mrbgems/mruby-dir/mrbgem.rake b/mruby/mrbgems/mruby-dir/mrbgem.rake new file mode 100644 index 00000000..6951c49d --- /dev/null +++ b/mruby/mrbgems/mruby-dir/mrbgem.rake @@ -0,0 +1,4 @@ +MRuby::Gem::Specification.new('mruby-dir') do |spec| + spec.license = 'MIT and MIT-like license' + spec.authors = [ 'Internet Initiative Japan Inc.', 'Kevlin Henney'] +end diff --git a/mruby/mrbgems/mruby-dir/mrblib/dir.rb b/mruby/mrbgems/mruby-dir/mrblib/dir.rb new file mode 100644 index 00000000..5f4742be --- /dev/null +++ b/mruby/mrbgems/mruby-dir/mrblib/dir.rb @@ -0,0 +1,68 @@ +class Dir + include Enumerable + + def each(&block) + while s = self.read + block.call(s) + end + self + end + + alias each_child each + alias pos tell + alias pos= seek + + class << self + def entries(path) + a = [] + self.open(path) do |d| + while s = d.read + a << s + end + end + a + end + alias children entries + + def foreach(path, &block) + self.open(path) do |d| + d.each(&block) + end + end + + def open(path, &block) + if block + d = self.new(path) + begin + block.call(d) + ensure + begin + d.close + rescue IOError + end + end + else + self.new(path) + end + end + + def chdir(path, &block) + if block + wd = self.getwd + begin + self._chdir(path) + block.call(path) + ensure + self._chdir(wd) + end + else + self._chdir(path) + end + end + + alias exists? exist? + alias pwd getwd + alias rmdir delete + alias unlink delete + end +end diff --git a/mruby/mrbgems/mruby-dir/src/Win/dirent.c b/mruby/mrbgems/mruby-dir/src/Win/dirent.c new file mode 100644 index 00000000..1b43a992 --- /dev/null +++ b/mruby/mrbgems/mruby-dir/src/Win/dirent.c @@ -0,0 +1,154 @@ +/* + + Implementation of POSIX directory browsing functions and types for Win32. + + Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) + History: Created March 1997. Updated June 2003 and July 2012. + Rights: See end of file. + +*/ + +#include +#include /* _findfirst and _findnext set errno iff they return -1 */ +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */ + +struct dirent +{ + char *d_name; +}; + +struct DIR +{ + handle_type handle; /* -1 for failed rewind */ + struct _finddata_t info; + struct dirent result; /* d_name null iff first time */ + char *name; /* null-terminated char string */ +}; + +typedef struct DIR DIR; + +DIR *opendir(const char *name) +{ + DIR *dir = 0; + + if(name && name[0]) + { + size_t base_length = strlen(name); + const char *all = /* search pattern must end with suitable wildcard */ + strchr("/\\", name[base_length - 1]) ? "*" : "/*"; + + if((dir = (DIR *) malloc(sizeof *dir)) != 0 && + (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) + { + strcat(strcpy(dir->name, name), all); + + if((dir->handle = + (handle_type) _findfirst(dir->name, &dir->info)) != -1) + { + dir->result.d_name = 0; + } + else /* rollback */ + { + free(dir->name); + free(dir); + dir = 0; + } + } + else /* rollback */ + { + free(dir); + dir = 0; + errno = ENOMEM; + } + } + else + { + errno = EINVAL; + } + + return dir; +} + +int closedir(DIR *dir) +{ + int result = -1; + + if(dir) + { + if(dir->handle != -1) + { + result = _findclose(dir->handle); + } + + free(dir->name); + free(dir); + } + + if(result == -1) /* map all errors to EBADF */ + { + errno = EBADF; + } + + return result; +} + +struct dirent *readdir(DIR *dir) +{ + struct dirent *result = 0; + + if(dir && dir->handle != -1) + { + if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) + { + result = &dir->result; + result->d_name = dir->info.name; + } + } + else + { + errno = EBADF; + } + + return result; +} + +void rewinddir(DIR *dir) +{ + if(dir && dir->handle != -1) + { + _findclose(dir->handle); + dir->handle = (handle_type) _findfirst(dir->name, &dir->info); + dir->result.d_name = 0; + } + else + { + errno = EBADF; + } +} + +#ifdef __cplusplus +} +#endif + +/* + + Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose is hereby granted without fee, provided + that this copyright and permissions notice appear in all copies and + derivatives. + + This software is supplied "as is" without express or implied warranty. + + But that said, if there are any problems please get in touch. + +*/ diff --git a/mruby/mrbgems/mruby-dir/src/dir.c b/mruby/mrbgems/mruby-dir/src/dir.c new file mode 100644 index 00000000..455c17bd --- /dev/null +++ b/mruby/mrbgems/mruby-dir/src/dir.c @@ -0,0 +1,321 @@ +/* +** dir.c - Dir +** +** See Copyright Notice in mruby.h +*/ + +#include "mruby.h" +#include "mruby/class.h" +#include "mruby/data.h" +#include "mruby/error.h" +#include "mruby/string.h" +#include "mruby/presym.h" +#include +#if defined(_WIN32) || defined(_WIN64) + #define MAXPATHLEN 1024 + #if !defined(PATH_MAX) + #define PATH_MAX MAX_PATH + #endif + #define S_ISDIR(B) ((B)&_S_IFDIR) + #include "Win/dirent.c" + #include + #define rmdir(path) _rmdir(path) + #define getcwd(path,len) _getcwd(path,len) + #define mkdir(path,mode) _mkdir(path) + #define chdir(path) _chdir(path) +#else + #include + #include + #include +#endif +#include +#include +#include +#include +#include +#include + +#define E_IO_ERROR mrb_exc_get_id(mrb, MRB_SYM(IOError)) + +struct mrb_dir { + DIR *dir; +}; + +static void +mrb_dir_free(mrb_state *mrb, void *ptr) +{ + struct mrb_dir *mdir = (struct mrb_dir*)ptr; + + if (mdir->dir) { + closedir(mdir->dir); + mdir->dir = NULL; + } + mrb_free(mrb, mdir); +} + +static struct mrb_data_type mrb_dir_type = { "DIR", mrb_dir_free }; + +static mrb_value +mrb_dir_close(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + mdir = (struct mrb_dir*)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + if (closedir(mdir->dir) == -1) { + mrb_sys_fail(mrb, "closedir"); + } + mdir->dir = NULL; + return mrb_nil_value(); +} + +static mrb_value +mrb_dir_init(mrb_state *mrb, mrb_value self) +{ + DIR *dir; + struct mrb_dir *mdir; + const char *path; + + mdir = (struct mrb_dir*)DATA_PTR(self); + if (mdir) { + mrb_dir_free(mrb, mdir); + } + DATA_TYPE(self) = &mrb_dir_type; + DATA_PTR(self) = NULL; + + mdir = (struct mrb_dir*)mrb_malloc(mrb, sizeof(*mdir)); + mdir->dir = NULL; + DATA_PTR(self) = mdir; + + mrb_get_args(mrb, "z", &path); + if ((dir = opendir(path)) == NULL) { + mrb_sys_fail(mrb, path); + } + mdir->dir = dir; + return self; +} + +static mrb_value +mrb_dir_delete(mrb_state *mrb, mrb_value klass) +{ + const char *path; + + mrb_get_args(mrb, "z", &path); + if (rmdir(path) == -1) { + mrb_sys_fail(mrb, path); + } + return mrb_fixnum_value(0); +} + +static mrb_value +mrb_dir_existp(mrb_state *mrb, mrb_value klass) +{ + struct stat sb; + const char *path; + + mrb_get_args(mrb, "z", &path); + if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { + return mrb_true_value(); + } + else { + return mrb_false_value(); + } +} + +static mrb_value +mrb_dir_getwd(mrb_state *mrb, mrb_value klass) +{ + mrb_value path; + + path = mrb_str_buf_new(mrb, MAXPATHLEN); + if (getcwd(RSTRING_PTR(path), MAXPATHLEN) == NULL) { + mrb_sys_fail(mrb, "getcwd(2)"); + } + mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); + return path; +} + +static mrb_value +mrb_dir_mkdir(mrb_state *mrb, mrb_value klass) +{ + mrb_int mode; + const char *path; + + mode = 0777; + mrb_get_args(mrb, "z|i", &path, &mode); + if (mkdir(path, mode) == -1) { + mrb_sys_fail(mrb, path); + } + return mrb_fixnum_value(0); +} + +static mrb_value +mrb_dir_chdir(mrb_state *mrb, mrb_value klass) +{ + const char *path; + + mrb_get_args(mrb, "z", &path); + if (chdir(path) == -1) { + mrb_sys_fail(mrb, path); + } + return mrb_fixnum_value(0); +} + +static mrb_value +mrb_dir_chroot(mrb_state *mrb, mrb_value self) +{ +#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__) + mrb_raise(mrb, E_NOTIMP_ERROR, "chroot() unreliable on your system"); + return mrb_fixnum_value(0); +#else + const char *path; + int res; + + mrb_get_args(mrb, "z", &path); + res = chroot(path); + if (res == -1) { + mrb_sys_fail(mrb, path); + } + + return mrb_fixnum_value(res); +#endif +} + +static mrb_bool +skip_name_p(const char *name) +{ + if (name[0] != '.') return FALSE; + if (name[1] == '\0') return TRUE; + if (name[1] != '.') return FALSE; + if (name[2] == '\0') return TRUE; + return FALSE; +} + +static mrb_value +mrb_dir_empty(mrb_state *mrb, mrb_value self) +{ + DIR *dir; + struct dirent *dp; + const char *path; + mrb_value result = mrb_true_value(); + + mrb_get_args(mrb, "z", &path); + if ((dir = opendir(path)) == NULL) { + mrb_sys_fail(mrb, path); + } + while ((dp = readdir(dir))) { + if (!skip_name_p(dp->d_name)) { + result = mrb_false_value(); + break; + } + } + closedir(dir); + return result; +} + +static mrb_value +mrb_dir_read(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + struct dirent *dp; + + mdir = (struct mrb_dir*)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + dp = readdir(mdir->dir); + if (dp != NULL) { + return mrb_str_new_cstr(mrb, dp->d_name); + } + else { + return mrb_nil_value(); + } +} + +static mrb_value +mrb_dir_rewind(mrb_state *mrb, mrb_value self) +{ + struct mrb_dir *mdir; + + mdir = (struct mrb_dir*)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + rewinddir(mdir->dir); + return self; +} + +static mrb_value +mrb_dir_seek(mrb_state *mrb, mrb_value self) +{ + #if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__) + mrb_raise(mrb, E_NOTIMP_ERROR, "dirseek() unreliable on your system"); + return self; + #else + struct mrb_dir *mdir; + mrb_int pos; + + mdir = (struct mrb_dir*)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + mrb_get_args(mrb, "i", &pos); + seekdir(mdir->dir, (long)pos); + return self; + #endif +} + +static mrb_value +mrb_dir_tell(mrb_state *mrb, mrb_value self) +{ +#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__) + mrb_raise(mrb, E_NOTIMP_ERROR, "dirtell() unreliable on your system"); + return mrb_fixnum_value(0); +#else + struct mrb_dir *mdir; + mrb_int pos; + + mdir = (struct mrb_dir*)mrb_get_datatype(mrb, self, &mrb_dir_type); + if (!mdir) return mrb_nil_value(); + if (!mdir->dir) { + mrb_raise(mrb, E_IO_ERROR, "closed directory"); + } + pos = (mrb_int)telldir(mdir->dir); + return mrb_fixnum_value(pos); +#endif +} + +void +mrb_mruby_dir_gem_init(mrb_state *mrb) +{ + struct RClass *d; + + d = mrb_define_class(mrb, "Dir", mrb->object_class); + MRB_SET_INSTANCE_TT(d, MRB_TT_DATA); + mrb_define_class_method(mrb, d, "delete", mrb_dir_delete, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "exist?", mrb_dir_existp, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "getwd", mrb_dir_getwd, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, d, "mkdir", mrb_dir_mkdir, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_class_method(mrb, d, "_chdir", mrb_dir_chdir, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "chroot", mrb_dir_chroot, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, d, "empty?", mrb_dir_empty, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, d, "close", mrb_dir_close, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "initialize", mrb_dir_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, d, "read", mrb_dir_read, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "rewind", mrb_dir_rewind, MRB_ARGS_NONE()); + mrb_define_method(mrb, d, "seek", mrb_dir_seek, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, d, "tell", mrb_dir_tell, MRB_ARGS_NONE()); + + mrb_define_class(mrb, "IOError", mrb->eStandardError_class); +} + +void +mrb_mruby_dir_gem_final(mrb_state *mrb) +{ +} diff --git a/mruby/mrbgems/mruby-dir/test/dir.rb b/mruby/mrbgems/mruby-dir/test/dir.rb new file mode 100644 index 00000000..7dbb4d3a --- /dev/null +++ b/mruby/mrbgems/mruby-dir/test/dir.rb @@ -0,0 +1,137 @@ +assert('Dir') do + assert_equal(Class, Dir.class) +end + +assert('DirTest.setup') do + assert_nothing_raised{DirTest.setup} +end + +assert('Dir.chdir') do + assert_equal 0, Dir.chdir(DirTest.sandbox) +end + +assert('Dir.entries') do + a = Dir.entries(DirTest.sandbox) + assert_true a.include?("a") + assert_true a.include?("b") +end + +assert('Dir.exist?') do + assert_true Dir.exist?(DirTest.sandbox) + assert_false Dir.exist?(DirTest.sandbox + "/nosuchdir") +end + +assert('Dir.foreach') do + a = [] + Dir.foreach(DirTest.sandbox) { |s| a << s } + assert_true a.include?("a") + assert_true a.include?("b") +end + +assert('Dir.getwd') do + s = Dir.getwd + assert_true s.kind_of? String +end + +assert('Dir.mkdir') do + m1 = DirTest.sandbox + "/mkdir1" + m2 = DirTest.sandbox + "/mkdir2" + assert_equal 0, Dir.mkdir(m1) + assert_equal 0, Dir.mkdir(m2, 0765) +end + +assert('Dir.delete') do + s = DirTest.sandbox + "/delete" + Dir.mkdir(s) + assert_true Dir.exist?(s) + + Dir.delete(s) + assert_false Dir.exist?(s) +end + +assert('Dir.open') do + a = [] + Dir.open(DirTest.sandbox) { |d| + d.each_child { |s| a << s } + } + assert_true a.include?("a") + assert_true a.include?("b") +end + +assert('Dir#initialize and Dir#close') do + d = Dir.new(".") + assert_true d.instance_of?(Dir) + assert_nil d.close +end + +assert('Dir#close') do + d = Dir.new(".") + assert_nothing_raised{d.close} +end + +assert('Dir#each_child') do + a = [] + d = Dir.open(DirTest.sandbox) + d.each_child { |s| a << s } + d.close + assert_true a.include?("a") + assert_true a.include?("b") +end + +assert('Dir#read') do + a = [] + d = Dir.open(DirTest.sandbox) + while s = d.read + a << s + end + d.close + assert_true a.include?("a") + assert_true a.include?("b") +end + +assert('Dir#rewind') do + d = Dir.open(DirTest.sandbox) + while d.read; end + + assert_equal d, d.rewind + + a = [] + while s = d.read + a << s + end + d.close + assert_true a.include? "a" + assert_true a.include? "b" +end + +# Note: behaviors of seekdir(3) and telldir(3) are so platform-dependent +# that we cannot write portable tests here. + +assert('Dir#tell') do + n = nil + begin + Dir.open(DirTest.sandbox) { |d| + n = d.tell + } + assert_true n.is_a? Integer + rescue NotImplementedError => e + skip e.message + end +end + +assert('Dir#seek') do + d1 = Dir.open(DirTest.sandbox) + d1.read + begin + n = d1.tell + d1.read + d2 = d1.seek(n) + assert_equal d1, d2 + rescue NotImplementedError => e + skip e.message + end +end + +assert('DirTest.teardown') do + assert_nothing_raised{DirTest.teardown} +end diff --git a/mruby/mrbgems/mruby-dir/test/dirtest.c b/mruby/mrbgems/mruby-dir/test/dirtest.c new file mode 100644 index 00000000..34ef3476 --- /dev/null +++ b/mruby/mrbgems/mruby-dir/test/dirtest.c @@ -0,0 +1,142 @@ +#include +#include + +#include +#include +#include + +#if defined(_WIN32) || defined(_WIN64) +#ifdef __cplusplus +extern "C" { +#endif +typedef struct DIR DIR; +struct dirent +{ + char *d_name; +}; +DIR *opendir(const char *name); +struct dirent *readdir(DIR *dir); +int closedir(DIR *dir); +#ifdef __cplusplus +} +#endif +#include +#include +#define rmdir(path) _rmdir(path) +#define getcwd(path,len) _getcwd(path,len) +#define mkdir(path,mode) _mkdir(path) +#define chdir(path) _chdir(path) +#else +#include +#include +#endif + +#include "mruby.h" +#include "mruby/string.h" +#include "mruby/variable.h" + +static void +make_dir(mrb_state *mrb, const char *name, const char *up) +{ + if (mkdir(name, 0) == -1) { + if (chdir("..") == 0) { + rmdir(up); + } + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdir(%s) failed", mrb_str_new_cstr(mrb, name)); + } +} + +mrb_value +mrb_dirtest_setup(mrb_state *mrb, mrb_value klass) +{ + char buf[1024]; + const char *aname = "a"; + const char *bname = "b"; + + /* save current working directory */ + if (getcwd(buf, sizeof(buf)) == NULL) { + mrb_raise(mrb, E_RUNTIME_ERROR, "getcwd() failed"); + } + mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "pwd"), mrb_str_new_cstr(mrb, buf)); + + /* create sandbox */ +#if defined(_WIN32) || defined(_WIN64) + snprintf(buf, sizeof(buf), "%s\\mruby-dir-test.XXXXXX", _getcwd(NULL,0)); + if ((_mktemp(buf) == NULL) || mkdir(buf,0) != 0) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdtemp(%s) failed", buf); + } +#else + snprintf(buf, sizeof(buf), "%s/mruby-dir-test.XXXXXX", P_tmpdir); + if (mkdtemp(buf) == NULL) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "mkdtemp(%s) failed", buf); + } +#endif + mrb_cv_set(mrb, klass, mrb_intern_cstr(mrb, "sandbox"), mrb_str_new_cstr(mrb, buf)); + + /* go to sandbox */ + if (chdir(buf) == -1) { + rmdir(buf); + mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%s) failed", buf); + } + + /* make some directories in the sandbox */ + make_dir(mrb, aname, buf); + make_dir(mrb, bname, buf); + + return mrb_true_value(); +} + +mrb_value +mrb_dirtest_teardown(mrb_state *mrb, mrb_value klass) +{ + mrb_value d, sandbox; + DIR *dirp; + struct dirent *dp; + const char *path; + + /* cleanup sandbox */ + sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); + path = mrb_str_to_cstr(mrb, sandbox); + + dirp = opendir(path); + while ((dp = readdir(dirp)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) + continue; + if (rmdir(dp->d_name) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%s) failed", dp->d_name); + } + } + closedir(dirp); + + /* back to original pwd */ + d = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "pwd")); + path = mrb_str_to_cstr(mrb, d); + if (chdir(path) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "chdir(%s) failed", path); + } + + /* remove sandbox directory */ + sandbox = mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); + path = mrb_str_to_cstr(mrb, sandbox); + if (rmdir(path) == -1) { + mrb_raisef(mrb, E_RUNTIME_ERROR, "rmdir(%s) failed", path); + } + + return mrb_true_value(); +} + +mrb_value +mrb_dirtest_sandbox(mrb_state *mrb, mrb_value klass) +{ + return mrb_cv_get(mrb, klass, mrb_intern_cstr(mrb, "sandbox")); +} + +void +mrb_mruby_dir_gem_test(mrb_state *mrb) +{ + struct RClass *c = mrb_define_module(mrb, "DirTest"); + + mrb_define_class_method(mrb, c, "sandbox", mrb_dirtest_sandbox, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, c, "setup", mrb_dirtest_setup, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, c, "teardown", mrb_dirtest_teardown, MRB_ARGS_NONE()); +} diff --git a/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb index 5f39235e..2c9e8d3a 100644 --- a/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -244,7 +244,7 @@ def first(*args) # # Returns the number of items in +enum+ through enumeration. # If an argument is given, the number of items in +enum+ that - # are equal to +item+ are counted. If a block is given, it + # are equal to +item+ are counted. If a block is given, it # counts the number of elements yielding a true value. def count(v=NONE, &block) count = 0 @@ -368,7 +368,7 @@ def min_by(&block) # enum.minmax { |a, b| block } -> [min, max] # # Returns two elements array which contains the minimum and the - # maximum value in the enumerable. The first form assumes all + # maximum value in the enumerable. The first form assumes all # objects implement Comparable; the second uses the # block to return a <=> b. # @@ -647,8 +647,8 @@ def reverse_each(&block) # enum.cycle(n=nil) -> an_enumerator # # Calls block for each element of enum repeatedly _n_ - # times or forever if none or +nil+ is given. If a non-positive - # number is given or the collection is empty, does nothing. Returns + # times or forever if none or +nil+ is given. If a non-positive + # number is given or the collection is empty, does nothing. Returns # +nil+ if the loop has finished without getting interrupted. # # Enumerable#cycle saves elements in an internal array so changes @@ -696,7 +696,7 @@ def cycle(nv = nil, &block) # enum.find_index -> an_enumerator # # Compares each entry in enum with value or passes - # to block. Returns the index for the first for which the + # to block. Returns the index for the first for which the # evaluated value is non-false. If no object matches, returns # nil # @@ -731,10 +731,10 @@ def find_index(val=NONE, &block) # enum.zip(arg, ...) { |arr| block } -> nil # # Takes one element from enum and merges corresponding - # elements from each args. This generates a sequence of + # elements from each args. This generates a sequence of # n-element arrays, where n is one more than the - # count of arguments. The length of the resulting sequence will be - # enum#size. If the size of any argument is less than + # count of arguments. The length of the resulting sequence will be + # enum#size. If the size of any argument is less than # enum#size, nil values are supplied. If # a block is given, it is invoked for each output array, otherwise # an array of arrays is returned. @@ -844,7 +844,7 @@ def filter_map(&blk) # call-seq: # enum.tally -> a_hash # - # Tallys the collection. Returns a hash where the keys are the + # Tallys the collection. Returns a hash where the keys are the # elements and the values are numbers of elements in the collection # that correspond to the key. # @@ -856,4 +856,28 @@ def tally end hash end + + ## + # call-seq: + # enum.sum(count=1) -> numeric + # enum.sum(count=1){...} -> numeric + # + # Returns the sum of elements. For example, [e1, e2, e3].sum + # returns e1 + e2 + e3. If a block is given, each element is + # processed by the block, e.g [e1, e2, e3].sum{_1.m} gives + # e1.m + e2.m + e3.m. + # + def sum(init=0,&block) + result=init + if block + self.each do |e| + result += block.call(e) + end + else + self.each do |e| + result += e + end + end + result + end end diff --git a/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb index 58efceb1..65cddbda 100644 --- a/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ b/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -36,7 +36,7 @@ # # foo: two # # foo: three # -# This allows you to chain Enumerators together. For example, you +# This allows you to chain Enumerators together. For example, you # can map a list's elements to strings containing the index # and the element as a string via: # @@ -112,7 +112,7 @@ class Enumerator # given object using the given method with the given arguments passed. This # form is left only for internal use. # - # Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum + # Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum # instead. def initialize(obj=NONE, meth=:each, *args, **kwd, &block) if block @@ -154,7 +154,7 @@ def initialize_copy(obj) # e.with_index(offset = 0) # # Iterates the given block for each element with an index, which - # starts from +offset+. If no block is given, returns a new Enumerator + # starts from +offset+. If no block is given, returns a new Enumerator # that includes the index, starting from +offset+ # # +offset+:: the starting index to use @@ -297,7 +297,7 @@ def enumerator_block_call(&block) # e.next -> object # # Returns the next object in the enumerator, and move the internal position - # forward. When the position reached at the end, StopIteration is raised. + # forward. When the position reached at the end, StopIteration is raised. # # === Example # @@ -321,7 +321,7 @@ def next # e.next_values -> array # # Returns the next object as an array in the enumerator, and move the - # internal position forward. When the position reached at the end, + # internal position forward. When the position reached at the end, # StopIteration is raised. # # This method can be used to distinguish yield and yield @@ -405,7 +405,7 @@ def next_values # e.peek -> object # # Returns the next object in the enumerator, but doesn't move the internal - # position forward. If the position is already at the end, StopIteration + # position forward. If the position is already at the end, StopIteration # is raised. # # === Example @@ -429,7 +429,7 @@ def peek # e.peek_values -> array # # Returns the next object as an array, similar to Enumerator#next_values, but - # doesn't move the internal position forward. If the position is already at + # doesn't move the internal position forward. If the position is already at # the end, StopIteration is raised. # # === Example @@ -564,7 +564,7 @@ def << *args # Enumerator.produce(initial = nil) { |val| } -> enumerator # # Creates an infinite enumerator from any block, just called over and - # over. Result of the previous iteration is passed to the next one. + # over. Result of the previous iteration is passed to the next one. # If +initial+ is provided, it is passed to the first iteration, and # becomes the first element of the enumerator; if it is not provided, # first iteration receives +nil+, and its result becomes first diff --git a/mruby/mrbgems/mruby-errno/README.md b/mruby/mrbgems/mruby-errno/README.md new file mode 100644 index 00000000..aa9a782b --- /dev/null +++ b/mruby/mrbgems/mruby-errno/README.md @@ -0,0 +1,25 @@ +# mruby-errno + +Errno module for mruby + +## License + +Copyright (c) 2013 Internet Initiative Japan Inc. + +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. diff --git a/mruby/mrbgems/mruby-errno/mrbgem.rake b/mruby/mrbgems/mruby-errno/mrbgem.rake new file mode 100644 index 00000000..9bf6c27a --- /dev/null +++ b/mruby/mrbgems/mruby-errno/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-errno') do |spec| + spec.license = 'MIT' + spec.authors = 'Internet Initiative Japan Inc.' + spec.summary = 'Errno module and SystemCallError class' +end diff --git a/mruby/mrbgems/mruby-errno/mrblib/errno.rb b/mruby/mrbgems/mruby-errno/mrblib/errno.rb new file mode 100644 index 00000000..52899396 --- /dev/null +++ b/mruby/mrbgems/mruby-errno/mrblib/errno.rb @@ -0,0 +1,15 @@ +module Errno + def Errno.const_defined?(name) + __errno_defined?(name) or super + end + + def Errno.const_missing(name) + __errno_define(name) or super + end + + # Module#constants is defined in mruby-metaprog + # So, it may be raised NoMethodError + def Errno.constants + __errno_list(super) + end +end diff --git a/mruby/mrbgems/mruby-errno/src/errno.c b/mruby/mrbgems/mruby-errno/src/errno.c new file mode 100644 index 00000000..97132b4b --- /dev/null +++ b/mruby/mrbgems/mruby-errno/src/errno.c @@ -0,0 +1,324 @@ +#include "mruby.h" +#include "mruby/array.h" +#include "mruby/class.h" +#include "mruby/error.h" +#include "mruby/hash.h" +#include "mruby/numeric.h" +#include "mruby/string.h" +#include "mruby/variable.h" +#include "mruby/internal.h" +#include +#include +#include + +static const struct { +#ifdef MRB_NO_PRESYM +#define itsdefined(name, sym) { #name, name }, + const char *name; +#else +#define itsdefined(name, sym) { sym, name }, + mrb_sym sym; +#endif + int eno; +} e2c[] = { +#define itsnotdefined(name, sym) +#include "known_errors_def.cstub" +#undef itsdefined +#undef itsnotdefined +}; + +static const struct { +#ifdef MRB_NO_PRESYM +#define itsnotdefined(name, sym) { #name }, + const char *name; +#else +#define itsnotdefined(name, sym) { sym }, + mrb_sym sym; +#endif +} noe2c[] = { +#define itsdefined(name, sym) +#include "known_errors_def.cstub" +#undef itsdefined +#undef itsnotdefined +}; + +#ifdef MRB_NO_PRESYM +#define ENTRY_SYM(e) mrb_intern_static(mrb, (e).name, strlen((e).name)) +#else +#define ENTRY_SYM(e) (e).sym +#endif + +#define E2C_LEN (sizeof(e2c) / sizeof(e2c[0])) +#define NOE2C_LEN (sizeof(noe2c) / sizeof(noe2c[0])) + +static struct RClass* +mrb_errno_define_exxx(mrb_state *mrb, mrb_sym name, int eno) +{ + struct RClass *errno_module = mrb_module_get_id(mrb, MRB_SYM(Errno)); + + if (mrb_const_defined_at(mrb, mrb_obj_value(errno_module), name)) { + mrb_value v = mrb_const_get(mrb, mrb_obj_value(errno_module), name); + + if (mrb_class_p(v)) { + return mrb_class_ptr(v); + } + } + + struct RClass *sce_class = mrb_exc_get_id(mrb, MRB_SYM(SystemCallError)); + struct RClass *e = mrb_define_class_under_id(mrb, errno_module, name, sce_class); + mrb_define_const_id(mrb, e, MRB_SYM(Errno), mrb_fixnum_value(eno)); + + return e; +} + +#ifndef MRB_NO_PRESYM +typedef mrb_sym sym_ref; +#define sym_ref_init(mrb, id) (id) +#define errno_name_matched_p(errentry, ref) ((errentry).sym == *(ref)) + +#else +typedef struct { + const char *name; + size_t len; +} sym_ref; + +static sym_ref +sym_ref_init(mrb_state *mrb, mrb_sym id) +{ + mrb_int len = 0; + const char *name = mrb_sym_name_len(mrb, id, &len); + sym_ref ename = { name, (size_t)len }; + return ename; +} + +#define errno_name_matched_p(errentry, ref) errno_name_matched_p_0((errentry).name, (ref)) +static mrb_bool +errno_name_matched_p_0(const char *name, const sym_ref *ref) +{ + if (ref->len == strlen(name) && memcmp(ref->name, name, ref->len) == 0) { + return TRUE; + } + else { + return FALSE; + } +} +#endif // MRB_NO_PRESYM + +static mrb_bool +ary_included_in_head(mrb_state *mrb, mrb_value ary, mrb_value obj, mrb_ssize head) +{ + const mrb_value *p = RARRAY_PTR(ary); + + for (; head > 0; head--, p++) { + if (mrb_obj_eq(mrb, obj, *p)) { + return TRUE; + } + } + + return FALSE; +} + +static mrb_value +mrb_errno_defined_p(mrb_state *mrb, mrb_value self) +{ + mrb_sym name; + mrb_get_args(mrb, "n", &name); + const sym_ref ref = sym_ref_init(mrb, name); + + for (size_t i = 0; i < E2C_LEN; i++) { + if (errno_name_matched_p(e2c[i], &ref)) { + return mrb_true_value(); + } + } + + for (size_t i = 0; i < NOE2C_LEN; i++) { + if (errno_name_matched_p(noe2c[i], &ref)) { + return mrb_true_value(); + } + } + + return mrb_false_value(); +} + +static mrb_value +mrb_errno_define(mrb_state *mrb, mrb_value self) +{ + mrb_sym name; + mrb_get_args(mrb, "n", &name); + const sym_ref ref = sym_ref_init(mrb, name); + + for (size_t i = 0; i < E2C_LEN; i++) { + if (errno_name_matched_p(e2c[i], &ref)) { + return mrb_obj_value(mrb_errno_define_exxx(mrb, name, e2c[i].eno)); + } + } + + for (size_t i = 0; i < NOE2C_LEN; i++) { + if (errno_name_matched_p(noe2c[i], &ref)) { + struct RClass *errno_module = mrb_module_get_id(mrb, MRB_SYM(Errno)); + return mrb_obj_value(mrb_class_get_under_id(mrb, errno_module, MRB_SYM(NOERROR))); + } + } + + return mrb_nil_value(); +} + +static mrb_value +mrb_errno_list(mrb_state *mrb, mrb_value self) +{ + mrb_value list; + mrb_get_args(mrb, "A", &list); + + mrb_ary_modify(mrb, mrb_ary_ptr(list)); + mrb_ssize head = RARRAY_LEN(list); + + for (size_t i = 0; i < E2C_LEN; i++) { + mrb_value id = mrb_symbol_value(ENTRY_SYM(e2c[i])); + if (!ary_included_in_head(mrb, list, id, head)) { + mrb_ary_push(mrb, list, id); + } + } + + for (size_t i = 0; i < NOE2C_LEN; i++) { + mrb_value id = mrb_symbol_value(ENTRY_SYM(noe2c[i])); + if (!ary_included_in_head(mrb, list, id, head)) { + mrb_ary_push(mrb, list, id); + } + } + + return list; +} + +static void +mrb_sce_init(mrb_state *mrb, mrb_value self, mrb_value m, mrb_value no) +{ + mrb_value str; + char buf[20]; + + if (!mrb_nil_p(no)) { + size_t i; + int n = (int)mrb_as_int(mrb, no); + + for (i=0; i < E2C_LEN; i++) { + if (e2c[i].eno == n) { + mrb_basic_ptr(self)->c = mrb_errno_define_exxx(mrb, ENTRY_SYM(e2c[i]), e2c[i].eno); + str = mrb_str_new_cstr(mrb, strerror(n)); + break; + } + } + if (i == E2C_LEN) { + mrb_iv_set(mrb, self, MRB_SYM(errno), mrb_fixnum_value(n)); + str = mrb_str_new_cstr(mrb, "Unknown error: "); + char *bp = mrb_int_to_cstr(buf, sizeof(buf), n, 10); + mrb_str_cat2(mrb, str, bp); + } + } + else { + str = mrb_str_new_cstr(mrb, "unknown error"); + } + if (!mrb_nil_p(m)) { + mrb_str_cat2(mrb, str, " - "); + mrb_str_append(mrb, str, m); + } + mrb_exc_mesg_set(mrb, mrb_exc_ptr(self), str); +} + +static mrb_value +mrb_exxx_init(mrb_state *mrb, mrb_value self) +{ + mrb_value m = mrb_nil_value(); + + mrb_get_args(mrb, "|S", &m); + mrb_sce_init(mrb, self, m, mrb_nil_value()); + return self; +} + +static mrb_value +mrb_sce_init_m(mrb_state *mrb, mrb_value self) +{ + if (mrb_class(mrb, self) != mrb_exc_get_id(mrb, MRB_SYM(SystemCallError))) { + return mrb_exxx_init(mrb, self); + } + + mrb_value m, n; + + if (mrb_get_args(mrb, "o|o", &m, &n) == 1) { + if (mrb_fixnum_p(m)) { + n = m; + m = mrb_nil_value(); + } + else { + n = mrb_nil_value(); + } + } + mrb_sce_init(mrb, self, m, n); + return self; +} + +static mrb_value +mrb_sce_errno(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + mrb_sym sym; + + c = mrb_class(mrb, self); + sym = MRB_SYM(Errno); + if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) { + return mrb_const_get(mrb, mrb_obj_value(c), sym); + } else { + sym = MRB_SYM(errno); + return mrb_attr_get(mrb, self, sym); + } +} + +static mrb_value +mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) +{ + struct RClass *sce; + mrb_value msg, no; + mrb_int argc; + + mrb->c->ci->mid = 0; + sce = mrb_class_ptr(cls); + argc = mrb_get_args(mrb, "o|S", &no, &msg); + + struct RBasic* e = mrb_obj_alloc(mrb, MRB_TT_EXCEPTION, sce); + mrb_value exc = mrb_obj_value(e); + if (argc == 1) { + msg = mrb_nil_value(); + } + exc = mrb_obj_value(e); + mrb_sce_init(mrb, exc, msg, no); + mrb_exc_raise(mrb, exc); + return mrb_nil_value(); /* NOTREACHED */ +} + +void +mrb_mruby_errno_gem_init(mrb_state *mrb) +{ + struct RClass *e, *eno, *sce, *ste; + + ste = mrb->eStandardError_class; + + sce = mrb_define_class(mrb, "SystemCallError", ste); + mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE()); + mrb_define_method(mrb, sce, "initialize", mrb_sce_init_m, MRB_ARGS_ARG(1, 1)); + + eno = mrb_define_module_id(mrb, MRB_SYM(Errno)); + mrb_define_class_method(mrb, eno, "__errno_defined?", mrb_errno_defined_p, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, eno, "__errno_define", mrb_errno_define, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, eno, "__errno_list", mrb_errno_list, MRB_ARGS_REQ(1)); + + e = mrb_define_class_under_id(mrb, eno, MRB_SYM(NOERROR), sce); + mrb_define_const_id(mrb, e, MRB_SYM(Errno), mrb_fixnum_value(0)); + //mrb_define_method(mrb, e, "===", mrb_exxx_cmp, MRB_ARGS_REQ(1)); + + // Pre-allocation for Errno::ENOMEM only + mrb_errno_define_exxx(mrb, MRB_SYM(ENOMEM), ENOMEM); +} + +void +mrb_mruby_errno_gem_final(mrb_state *mrb) +{ +} diff --git a/mruby/mrbgems/mruby-errno/src/gen.rb b/mruby/mrbgems/mruby-errno/src/gen.rb new file mode 100755 index 00000000..a9a6c8ee --- /dev/null +++ b/mruby/mrbgems/mruby-errno/src/gen.rb @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname($0)) + +d = File.open("known_errors_def.cstub", "w") + +IO.readlines("known_errors.def").each { |name| + next if name =~ /^#/ + name.strip! + + d.write < #include #include - -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_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*); +#include 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) @@ -34,14 +29,14 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi mrb_obj_class(mrb, binding)); } scope_obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); - mrb_assert(mrb_proc_p(scope_obj)); + mrb_check_type(mrb, scope_obj, MRB_TT_PROC); scope = mrb_proc_ptr(scope_obj); if (MRB_PROC_CFUNC_P(scope)) { e = NULL; } else { mrb_value env = mrb_iv_get(mrb, binding, MRB_SYM(env)); - mrb_assert(mrb_env_p(env)); + mrb_check_type(mrb, env, MRB_TT_ENV); e = (struct REnv *)mrb_obj_ptr(env); mrb_assert(e != NULL); } @@ -179,15 +174,15 @@ f_instance_eval(mrb_state *mrb, mrb_value self) mrb_int len; const char *file = NULL; mrb_int line = 1; - mrb_value cv; + struct RClass *c; struct RProc *proc; mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); - cv = mrb_singleton_class(mrb, self); + c = mrb_singleton_class_ptr(mrb, self); proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); - MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv)); + MRB_PROC_SET_TARGET_CLASS(proc, c); mrb_assert(!MRB_PROC_CFUNC_P(proc)); - mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(cv)); + mrb_vm_ci_target_class_set(mrb->c->ci, c); return exec_irep(mrb, self, proc); } else { diff --git a/mruby/mrbgems/mruby-exit/src/mruby-exit.c b/mruby/mrbgems/mruby-exit/src/mruby-exit.c index 4ff2f932..658d188e 100644 --- a/mruby/mrbgems/mruby-exit/src/mruby-exit.c +++ b/mruby/mrbgems/mruby-exit/src/mruby-exit.c @@ -1,26 +1,80 @@ #include #include +#include +#include +#include -static mrb_value -f_exit(mrb_state *mrb, mrb_value self) +#ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif + +#ifndef EXIT_FAILURE +# define EXIT_FAILURE 1 +#endif + +static int +get_status(mrb_state *mrb) { mrb_value status = mrb_true_value(); - int istatus; mrb_get_args(mrb, "|o", &status); - istatus = mrb_true_p(status) ? EXIT_SUCCESS : - mrb_false_p(status) ? EXIT_FAILURE : - (int)mrb_int(mrb, status); - exit(istatus); + if (mrb_true_p(status)) return EXIT_SUCCESS; + if (mrb_false_p(status)) return EXIT_FAILURE; + return (int)mrb_as_int(mrb, status); +} +/* + * call-seq: + * exit(status=true) + * + * Initiates the termination of the Ruby script by raising the + * SystemExit exception. This exception may be caught. The + * optional parameter is used to return a status code to the invoking + * environment. + * + * +true+ and +false+ of _status_ means success and failure + * respectively. The interpretation of other integer values are + * system dependent. + * + * exit(0) + */ +static mrb_value +f_exit(mrb_state *mrb, mrb_value self) +{ + int status = get_status(mrb); + mrb_value exc = mrb_obj_new(mrb, mrb_exc_get_id(mrb, MRB_SYM(SystemExit)), 0, NULL); + struct RException *e = mrb_exc_ptr(exc); + e->flags |= MRB_EXC_EXIT; + mrb_iv_set(mrb, exc, MRB_SYM(status), mrb_int_value(mrb, (mrb_int)status)); + mrb_exc_raise(mrb, exc); + /* not reached */ + return mrb_nil_value(); +} + +/* + * call-seq: + * exit!(status=true) + * + * Exits the process immediately. No exit handlers are run. + * status is returned to the underlying system as the + * exit status. + * + * exit!(0) + */ +static mrb_value +f_exit_bang(mrb_state *mrb, mrb_value self) +{ + exit(get_status(mrb)); /* not reached */ - return status; + return mrb_nil_value(); } void mrb_mruby_exit_gem_init(mrb_state* mrb) { - mrb_define_method(mrb, mrb->kernel_module, "exit", f_exit, MRB_ARGS_OPT(1)); + mrb_define_class_id(mrb, MRB_SYM(SystemExit), mrb->eException_class); + mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM(exit), f_exit, MRB_ARGS_OPT(1)); + mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM_B(exit), f_exit_bang, MRB_ARGS_OPT(1)); } void diff --git a/mruby/mrbgems/mruby-fiber/src/fiber.c b/mruby/mrbgems/mruby-fiber/src/fiber.c index 322ed36e..33913c10 100644 --- a/mruby/mrbgems/mruby-fiber/src/fiber.c +++ b/mruby/mrbgems/mruby-fiber/src/fiber.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #define fiber_ptr(o) ((struct RFiber*)mrb_ptr(o)) @@ -14,7 +15,7 @@ * call-seq: * Fiber.new{...} -> obj * - * Creates a fiber, whose execution is suspend until it is explicitly + * Creates a fiber, whose execution is suspended until it is explicitly * resumed using Fiber#resume method. * The code running inside the fiber can give up control by calling * Fiber.yield in which case it yields control back to caller @@ -173,6 +174,26 @@ fiber_switch_context(mrb_state *mrb, struct mrb_context *c) mrb->c = c; } +/* + * Argument mesg is limited to a string literal or "static const" string. + * Also, it must be called as `return fiber_error(...)`. + */ +static mrb_value +fiber_error(mrb_state *mrb, const char *mesg) +{ + mrb_value str = mrb_str_new_static(mrb, mesg, strlen(mesg)); + mrb_value exc = mrb_exc_new_str(mrb, E_FIBER_ERROR, str); + + if (mrb->jmp) { + mrb_exc_raise(mrb, exc); + } + + mrb->exc = mrb_obj_ptr(exc); + + return exc; +} + +/* This function must be called as `return fiber_switch(...)` */ static mrb_value fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mrb_bool resume, mrb_bool vmexec) { @@ -181,32 +202,43 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr enum mrb_fiber_state status; mrb_value value; + if (resume && c == mrb->c) { + return fiber_error(mrb, "attempt to resume the current fiber"); + } + fiber_check_cfunc(mrb, c); status = c->status; switch (status) { case MRB_FIBER_TRANSFERRED: if (resume) { - mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber"); + return fiber_error(mrb, "resuming transferred fiber"); } break; case MRB_FIBER_RUNNING: case MRB_FIBER_RESUMED: - mrb_raise(mrb, E_FIBER_ERROR, "double resume"); + return fiber_error(mrb, "double resume"); break; case MRB_FIBER_TERMINATED: - mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber"); + return fiber_error(mrb, "resuming dead fiber"); break; default: break; } - old_c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED; - c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c); + if (resume) { + old_c->status = MRB_FIBER_RESUMED; + c->prev = mrb->c; + } + else { + old_c->status = MRB_FIBER_TRANSFERRED; + // c->prev = mrb->root_c; + c->prev = NULL; + } fiber_switch_context(mrb, c); if (status == MRB_FIBER_CREATED) { mrb_value *b, *e; if (!c->ci->proc) { - mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)"); + return fiber_error(mrb, "double resume (current)"); } if (vmexec) { c->ci--; /* pop dummy callinfo */ @@ -224,7 +256,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr *b++ = *a++; } } - c->cibase->n = len; + c->cibase->n = (uint8_t)len; value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; } else { @@ -259,6 +291,9 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr * to the next Fiber.yield statement inside the fiber's block * or to the block value if it runs to completion without any * Fiber.yield + * + * This method cannot be called from C using mrb_funcall(). + * Use mrb_fiber_resume() function instead. */ static mrb_value fiber_resume(mrb_state *mrb, mrb_value self) @@ -267,6 +302,7 @@ fiber_resume(mrb_state *mrb, mrb_value self) mrb_int len; mrb_bool vmexec = FALSE; + fiber_check_cfunc(mrb, mrb->c); mrb_get_args(mrb, "*!", &a, &len); if (mrb->c->ci->cci > 0) { vmexec = TRUE; @@ -274,7 +310,6 @@ fiber_resume(mrb_state *mrb, mrb_value self) return fiber_switch(mrb, self, len, a, TRUE, vmexec); } -/* resume thread with given arguments */ MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int len, const mrb_value *a) { @@ -329,6 +364,10 @@ fiber_transfer(mrb_state *mrb, mrb_value self) fiber_check_cfunc(mrb, mrb->c); mrb_get_args(mrb, "*!", &a, &len); + if (c->status == MRB_FIBER_RESUMED) { + mrb_raise(mrb, E_FIBER_ERROR, "attempt to transfer to a resuming fiber"); + } + if (c == mrb->root_c) { mrb->c->status = MRB_FIBER_TRANSFERRED; fiber_switch_context(mrb, c); @@ -343,19 +382,22 @@ fiber_transfer(mrb_state *mrb, mrb_value self) return fiber_switch(mrb, self, len, a, FALSE, FALSE); } -/* yield values to the caller fiber */ -/* mrb_fiber_yield() must be called as `return mrb_fiber_yield(...)` */ MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a) { struct mrb_context *c = mrb->c; if (!c->prev) { - mrb_raise(mrb, E_FIBER_ERROR, "can't yield from root fiber"); + return fiber_error(mrb, "attempt to yield on a not resumed fiber"); + } + if (c == mrb->root_c) { + return fiber_error(mrb, "can't yield from root fiber"); + } + if (c->prev->status == MRB_FIBER_TRANSFERRED) { + return fiber_error(mrb, "attempt to yield on a not resumed fiber"); } fiber_check_cfunc(mrb, c); - c->prev->status = MRB_FIBER_RUNNING; c->status = MRB_FIBER_SUSPENDED; fiber_switch_context(mrb, c->prev); c->prev = NULL; @@ -379,6 +421,9 @@ mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a) * * mruby limitation: Fiber resume/yield cannot cross C function boundary. * thus you cannot yield from #initialize which is called by mrb_funcall(). + * + * This method cannot be called from C using mrb_funcall(). + * Use mrb_fiber_yield() function instead. */ static mrb_value fiber_yield(mrb_state *mrb, mrb_value self) diff --git a/mruby/mrbgems/mruby-fiber/test/fiber.rb b/mruby/mrbgems/mruby-fiber/test/fiber.rb index b6ecb798..64b9d817 100644 --- a/mruby/mrbgems/mruby-fiber/test/fiber.rb +++ b/mruby/mrbgems/mruby-fiber/test/fiber.rb @@ -9,24 +9,19 @@ end assert('Fiber#transfer') do + ary = [] f2 = nil - f1 = Fiber.new do |v| - Fiber.yield v - f2.transfer - end - f2 = Fiber.new do - f1.transfer(1) - f1.transfer(1) - Fiber.yield 2 - end - assert_equal 1, f2.resume - assert_raise(FiberError) { f2.resume } - assert_equal 2, f2.transfer - assert_raise(FiberError) { f1.resume } - f1.transfer - f2.resume + f1 = Fiber.new{ + ary << f2.transfer(:foo) + :ok + } + f2 = Fiber.new{ + ary << f1.transfer(:baz) + :ng + } + assert_equal(:ok, f1.transfer) + assert_equal([:baz], ary) assert_false f1.alive? - assert_false f2.alive? end assert('Fiber#alive?') do @@ -139,12 +134,12 @@ assert('Transfer to self.') do result = [] - f = Fiber.new { result << :start; f.transfer; result << :end } + f = Fiber.new { result << :start; f.transfer; result << :end } f.transfer assert_equal [:start, :end], result result = [] - f = Fiber.new { result << :start; f.transfer; result << :end } + f = Fiber.new { result << :start; f.transfer; result << :end } f.resume assert_equal [:start, :end], result end @@ -163,7 +158,7 @@ result = :ok root.transfer } - f.resume + f.transfer assert_true f.alive? assert_equal :ok, result end @@ -174,7 +169,7 @@ result = nil f2 = nil f1 = Fiber.new { - Fiber.yield f2.resume + root.transfer(f2.transfer) result = :f1 } f2 = Fiber.new { @@ -182,12 +177,13 @@ root.transfer :from_f2 result = :f2 } - assert_equal :from_f2, f1.resume + assert_equal :from_f2, f1.transfer assert_equal :to_root, result assert_equal :f2, f2.transfer assert_equal :f2, result assert_false f2.alive? - assert_equal :f1, f1.resume + assert_equal nil, f1.transfer + assert_equal :f1, f1.transfer assert_equal :f1, result assert_false f1.alive? end diff --git a/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb index 5775913c..5a8b5377 100644 --- a/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -1,6 +1,6 @@ class Hash - # ISO does not define Hash#each_pair, so each_pair is defined in gem. + # ISO does not define Hash#each_pair, so each_pair is defined in gem. alias each_pair each ## @@ -62,10 +62,10 @@ def self.[](*object) ## # call-seq: - # hsh.merge!(other_hash) -> hsh - # hsh.merge!(other_hash){|key, oldval, newval| block} -> hsh + # hsh.merge!(other_hash..) -> hsh + # hsh.merge!(other_hash..){|key, oldval, newval| block} -> hsh # - # Adds the contents of _other_hash_ to _hsh_. If no block is specified, + # Adds the contents of _other_hash_ to _hsh_. If no block is specified, # entries with duplicate keys are overwritten with the values from # _other_hash_, otherwise the value of each duplicate key is determined by # calling the block with the key, its value in _hsh_ and its value in @@ -81,14 +81,20 @@ def self.[](*object) # #=> {"a"=>100, "b"=>200, "c"=>300} # - def merge!(other, &block) - raise TypeError, "Hash required (#{other.class} given)" unless Hash === other - if block - other.each_key{|k| - self[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k] - } - else - other.each_key{|k| self[k] = other[k]} + def merge!(*others, &block) + i = 0; len=others.size + return self.__merge(*others) unless block + while ilevel argument determines the level of recursion to flatten. # # a = {1=> "one", 2 => [2,"two"], 3 => "three"} @@ -422,12 +428,8 @@ def transform_keys(&block) # def transform_keys!(&block) return to_enum :transform_keys! unless block - self.keys.each do |k| - value = self[k] - self.__delete(k) - k = block.call(k) if block - self[k] = value - end + hash = self.transform_keys(&block) + self.replace(hash) self end ## diff --git a/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c b/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c index 9c85858f..b634373f 100644 --- a/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c +++ b/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c @@ -29,6 +29,7 @@ hash_values_at(mrb_state *mrb, mrb_value hash) mrb_get_args(mrb, "*", &argv, &argc); result = mrb_ary_new_capa(mrb, argc); + if (argc == 0) return result; ai = mrb_gc_arena_save(mrb); for (i = 0; i < argc; i++) { mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i])); diff --git a/mruby/mrbgems/mruby-hash-ext/test/hash.rb b/mruby/mrbgems/mruby-hash-ext/test/hash.rb index 78e8b3a3..a705af65 100644 --- a/mruby/mrbgems/mruby-hash-ext/test/hash.rb +++ b/mruby/mrbgems/mruby-hash-ext/test/hash.rb @@ -47,7 +47,7 @@ assert('Hash#merge!') do a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' } - b = { 'cba_key' => 'XXX', 'xyz_key' => 'xyz_value' } + b = { 'cba_key' => 'XXX', 'xyz_key' => 'xyz_value' } result_1 = a.merge! b @@ -64,6 +64,9 @@ assert_raise(TypeError) do { 'abc_key' => 'abc_value' }.merge! "a" end + + # multiple arguments + assert_equal({a:1,b:2,c:3}, {a:1}.merge!({b:2},{c:3})) end assert('Hash#values_at') do diff --git a/mruby/mrbgems/mruby-io/README.md b/mruby/mrbgems/mruby-io/README.md index c07a6e89..525785fa 100644 --- a/mruby/mrbgems/mruby-io/README.md +++ b/mruby/mrbgems/mruby-io/README.md @@ -14,160 +14,160 @@ Add the line below to your build configuration. ### IO -* - -| method | mruby-io | memo | -| ------------------------- | -------- | ---- | -| IO.binread | | | -| IO.binwrite | | | -| IO.copy_stream | | | -| IO.new, IO.for_fd, IO.open | o | | -| IO.foreach | | | -| IO.pipe | o | | -| IO.popen | o | | -| IO.read | o | | -| IO.readlines | | | -| IO.select | o | | -| IO.sysopen | o | | -| IO.try_convert | | | -| IO.write | | | -| IO#<< | | | -| IO#advise | | | -| IO#autoclose= | | | -| IO#autoclose? | | | -| IO#binmode | | | -| IO#binmode? | | | +- + +| method | mruby-io | memo | +|----------------------------|----------|----------| +| IO.binread | | | +| IO.binwrite | | | +| IO.copy_stream | | | +| IO.new, IO.for_fd, IO.open | o | | +| IO.foreach | | | +| IO.pipe | o | | +| IO.popen | o | | +| IO.read | o | | +| IO.readlines | | | +| IO.select | o | | +| IO.sysopen | o | | +| IO.try_convert | | | +| IO.write | | | +| IO#<< | | | +| IO#advise | | | +| IO#autoclose= | | | +| IO#autoclose? | | | +| IO#binmode | | | +| IO#binmode? | | | | IO#bytes | | obsolete | | IO#chars | | obsolete | -| IO#clone, IO#dup | o | | -| IO#close | o | | -| IO#close_on_exec= | o | | -| IO#close_on_exec? | o | | -| IO#close_read | | | -| IO#close_write | | | -| IO#closed? | o | | +| IO#clone, IO#dup | o | | +| IO#close | o | | +| IO#close_on_exec= | o | | +| IO#close_on_exec? | o | | +| IO#close_read | | | +| IO#close_write | | | +| IO#closed? | o | | | IO#codepoints | | obsolete | -| IO#each_byte | o | | -| IO#each_char | o | | -| IO#each_codepoint | | | -| IO#each_line | o | | -| IO#eof, IO#eof? | o | | -| IO#external_encoding | | | -| IO#fcntl | | | -| IO#fdatasync | | | -| IO#fileno, IO#to_i | o | | -| IO#flush | o | | -| IO#fsync | | | -| IO#getbyte | o | | -| IO#getc | o | | -| IO#gets | o | | -| IO#internal_encoding | | | -| IO#ioctl | | | -| IO#isatty, IO#tty? | o | | -| IO#lineno | | | -| IO#lineno= | | | +| IO#each_byte | o | | +| IO#each_char | o | | +| IO#each_codepoint | | | +| IO#each_line | o | | +| IO#eof, IO#eof? | o | | +| IO#external_encoding | | | +| IO#fcntl | | | +| IO#fdatasync | | | +| IO#fileno, IO#to_i | o | | +| IO#flush | o | | +| IO#fsync | | | +| IO#getbyte | o | | +| IO#getc | o | | +| IO#gets | o | | +| IO#internal_encoding | | | +| IO#ioctl | | | +| IO#isatty, IO#tty? | o | | +| IO#lineno | | | +| IO#lineno= | | | | IO#lines | | obsolete | -| IO#pid | o | | -| IO#pos, IO#tell | o | | -| IO#pos= | o | | -| IO#print | o | | -| IO#printf | o | | -| IO#putc | | | -| IO#puts | o | | -| IO#read | o | | -| IO#read_nonblock | | | -| IO#readbyte | o | | -| IO#readchar | o | | -| IO#readline | o | | -| IO#readlines | o | | -| IO#readpartial | | | -| IO#reopen | | | -| IO#rewind | | | -| IO#seek | o | | -| IO#set_encoding | | | -| IO#stat | | | -| IO#sync | o | | -| IO#sync= | o | | -| IO#sysread | o | | -| IO#sysseek | o | | -| IO#syswrite | o | | -| IO#to_io | | | -| IO#ungetbyte | o | | -| IO#ungetc | o | | -| IO#write | o | | -| IO#write_nonblock | | | +| IO#pid | o | | +| IO#pos, IO#tell | o | | +| IO#pos= | o | | +| IO#print | o | | +| IO#printf | o | | +| IO#putc | | | +| IO#puts | o | | +| IO#read | o | | +| IO#read_nonblock | | | +| IO#readbyte | o | | +| IO#readchar | o | | +| IO#readline | o | | +| IO#readlines | o | | +| IO#readpartial | | | +| IO#reopen | | | +| IO#rewind | | | +| IO#seek | o | | +| IO#set_encoding | | | +| IO#stat | | | +| IO#sync | o | | +| IO#sync= | o | | +| IO#sysread | o | | +| IO#sysseek | o | | +| IO#syswrite | o | | +| IO#to_io | | | +| IO#ungetbyte | o | | +| IO#ungetc | o | | +| IO#write | o | | +| IO#write_nonblock | | | ### File -* +- -| method | mruby-io | memo | -| --------------------------- | -------- | ---- | -| File.absolute_path | | | -| File.atime | | | -| File.basename | o | | +| method | mruby-io | memo | +|-----------------------------|----------|----------| +| File.absolute_path | | | +| File.atime | | | +| File.basename | o | | | File.blockdev? | | FileTest | | File.chardev? | | FileTest | -| File.chmod | o | | -| File.chown | | | -| File.ctime | | | -| File.delete, File.unlink | o | | -| File.directory? | o | FileTest | -| File.dirname | o | | +| File.chmod | o | | +| File.chown | | | +| File.ctime | | | +| File.delete, File.unlink | o | | +| File.directory? | o | FileTest | +| File.dirname | o | | | File.executable? | | FileTest | | File.executable_real? | | FileTest | -| File.exist?, exists? | o | FileTest | -| File.expand_path | o | | -| File.extname | o | | -| File.file? | o | FileTest | -| File.fnmatch, File.fnmatch? | | | -| File.ftype | | | +| File.exist?, exists? | o | FileTest | +| File.expand_path | o | | +| File.extname | o | | +| File.file? | o | FileTest | +| File.fnmatch, File.fnmatch? | | | +| File.ftype | | | | File.grpowned? | | FileTest | | File.identical? | | FileTest | -| File.join | o | | -| File.lchmod | | | -| File.lchown | | | -| File.link | | | -| File.lstat | | | -| File.mtime | | | -| File.new, File.open | o | | +| File.join | o | | +| File.lchmod | | | +| File.lchown | | | +| File.link | | | +| File.lstat | | | +| File.mtime | | | +| File.new, File.open | o | | | File.owned? | | FileTest | -| File.path | | | -| File.pipe? | o | FileTest | +| File.path | | | +| File.pipe? | o | FileTest | | File.readable? | | FileTest | | File.readable_real? | | FileTest | -| File.readlink | o | | -| File.realdirpath | | | -| File.realpath | o | | -| File.rename | o | | +| File.readlink | o | | +| File.realdirpath | | | +| File.realpath | o | | +| File.rename | o | | | File.setgid? | | FileTest | | File.setuid? | | FileTest | -| File.size | o | | -| File.size? | o | FileTest | -| File.socket? | o | FileTest | -| File.split | | | -| File.stat | | | +| File.size | o | | +| File.size? | o | FileTest | +| File.socket? | o | FileTest | +| File.split | | | +| File.stat | | | | File.sticky? | | FileTest | -| File.symlink | | | -| File.symlink? | o | FileTest | -| File.truncate | | | -| File.umask | o | | -| File.utime | | | -| File.world_readable? | | | -| File.world_writable? | | | +| File.symlink | | | +| File.symlink? | o | FileTest | +| File.truncate | | | +| File.umask | o | | +| File.utime | | | +| File.world_readable? | | | +| File.world_writable? | | | | File.writable? | | FileTest | | File.writable_real? | | FileTest | -| File.zero? | o | FileTest | -| File#atime | | | -| File#chmod | | | -| File#chown | | | -| File#ctime | | | -| File#flock | o | | -| File#lstat | | | -| File#mtime | | | -| File#path, File#to_path | o | | -| File#size | | | -| File#truncate | | | +| File.zero? | o | FileTest | +| File#atime | | | +| File#chmod | | | +| File#chown | | | +| File#ctime | | | +| File#flock | o | | +| File#lstat | | | +| File#mtime | | | +| File#path, File#to_path | o | | +| File#size | | | +| File#truncate | | | ## License diff --git a/mruby/mrbgems/mruby-io/include/mruby/ext/io.h b/mruby/mrbgems/mruby-io/include/mruby/ext/io.h index 714f58fd..13da769c 100644 --- a/mruby/mrbgems/mruby-io/include/mruby/ext/io.h +++ b/mruby/mrbgems/mruby-io/include/mruby/ext/io.h @@ -23,12 +23,22 @@ extern "C" { # endif #endif +#define MRB_IO_BUF_SIZE 4096 + +struct mrb_io_buf { + short start; + short len; + char mem[MRB_IO_BUF_SIZE]; +}; + struct mrb_io { int fd; /* file descriptor, or -1 */ int fd2; /* file descriptor to write if it's different from fd, or -1 */ int pid; /* child's pid (for pipes) */ + struct mrb_io_buf *buf; unsigned int readable:1, writable:1, + eof:1, sync:1, is_socket:1; }; @@ -53,12 +63,6 @@ struct mrb_io { #define MRB_O_DSYNC 0x00008000 #define MRB_O_RSYNC 0x00010000 -#define MRB_O_RDONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDONLY)) -#define MRB_O_WRONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_WRONLY)) -#define MRB_O_RDWR_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDWR)) -#define MRB_O_READABLE_P(f) ((mrb_bool)((((f) & MRB_O_ACCMODE) | 2) == 2)) -#define MRB_O_WRITABLE_P(f) ((mrb_bool)(((((f) & MRB_O_ACCMODE) + 1) & 2) == 2)) - #define E_IO_ERROR (mrb_exc_get(mrb, "IOError")) #define E_EOF_ERROR (mrb_exc_get(mrb, "EOFError")) diff --git a/mruby/mrbgems/mruby-io/mrbgem.rake b/mruby/mrbgems/mruby-io/mrbgem.rake index b2fc8826..3bb3febd 100644 --- a/mruby/mrbgems/mruby-io/mrbgem.rake +++ b/mruby/mrbgems/mruby-io/mrbgem.rake @@ -3,8 +3,6 @@ MRuby::Gem::Specification.new('mruby-io') do |spec| spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers'] spec.summary = 'IO and File class' - spec.cc.include_paths << "#{build.root}/src" - if spec.for_windows? spec.linker.libraries << "ws2_32" end diff --git a/mruby/mrbgems/mruby-io/mrblib/io.rb b/mruby/mrbgems/mruby-io/mrblib/io.rb index 9192d7bf..dc787c4f 100644 --- a/mruby/mrbgems/mruby-io/mrblib/io.rb +++ b/mruby/mrbgems/mruby-io/mrblib/io.rb @@ -1,16 +1,12 @@ ## # IO +# +# ISO 15.2.20 class IOError < StandardError; end class EOFError < IOError; end class IO - SEEK_SET = 0 - SEEK_CUR = 1 - SEEK_END = 2 - - BUF_SIZE = 4096 - def self.open(*args, &block) io = self.new(*args) @@ -66,12 +62,8 @@ def self.read(path, length=nil, offset=0, mode: "r") fd = -1 io = nil begin - if path[0] == "|" - io = IO.popen(path[1..-1], mode) - else - fd = IO.sysopen(path, mode) - io = IO.open(fd, mode) - end + fd = IO.sysopen(path, mode) + io = IO.open(fd, mode) io.seek(offset) if offset > 0 str = io.read(length) ensure @@ -84,49 +76,18 @@ def self.read(path, length=nil, offset=0, mode: "r") str end - def flush - # mruby-io always writes immediately (no output buffer). - raise IOError, "closed stream" if self.closed? - self - end - def hash # We must define IO#hash here because IO includes Enumerable and - # Enumerable#hash will call IO#read... + # Enumerable#hash will call IO#read() otherwise self.__id__ end - def write(string) - str = string.is_a?(String) ? string : string.to_s - return 0 if str.empty? - unless @buf.empty? - # reset real pos ignore buf - seek(pos, SEEK_SET) - end - len = syswrite(str) - len - end - def <<(str) write(str) self end - def eof? - _check_readable - begin - _read_buf - return @buf.empty? - rescue EOFError - return true - end - end alias_method :eof, :eof? - - def pos - raise IOError if closed? - sysseek(0, SEEK_CUR) - @buf.bytesize - end alias_method :tell, :pos def pos=(i) @@ -137,28 +98,6 @@ def rewind seek(0, SEEK_SET) end - def seek(i, whence = SEEK_SET) - raise IOError if closed? - sysseek(i, whence) - @buf = '' - 0 - end - - def _read_buf - return @buf if @buf && @buf.bytesize > 0 - sysread(BUF_SIZE, @buf) - end - - def ungetc(substr) - raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String) - if @buf.empty? - @buf.replace(substr) - else - @buf[0,0] = substr - end - nil - end - def ungetbyte(c) if c.is_a? String c = c.getbyte(0) @@ -170,127 +109,6 @@ def ungetbyte(c) ungetc s end - def read(length = nil, outbuf = "") - unless length.nil? - unless length.is_a? Integer - raise TypeError.new "can't convert #{length.class} into Integer" - end - if length < 0 - raise ArgumentError.new "negative length: #{length} given" - end - if length == 0 - return "" # easy case - end - end - - array = [] - while true - begin - _read_buf - rescue EOFError - array = nil if array.empty? and (not length.nil?) and length != 0 - break - end - - if length - consume = (length <= @buf.bytesize) ? length : @buf.bytesize - array.push IO._bufread(@buf, consume) - length -= consume - break if length == 0 - else - array.push @buf - @buf = '' - end - end - - if array.nil? - outbuf.replace("") - nil - else - outbuf.replace(array.join) - end - end - - def readline(arg = "\n", limit = nil) - case arg - when String - rs = arg - when Integer - rs = "\n" - limit = arg - else - raise ArgumentError - end - - if rs.nil? - return read - end - - if rs == "" - rs = "\n\n" - end - - array = [] - while true - begin - _read_buf - rescue EOFError - array = nil if array.empty? - break - end - - if limit && limit <= @buf.size - array.push @buf[0, limit] - @buf[0, limit] = "" - break - elsif idx = @buf.index(rs) - len = idx + rs.size - array.push @buf[0, len] - @buf[0, len] = "" - break - else - array.push @buf - @buf = '' - end - end - - raise EOFError.new "end of file reached" if array.nil? - - array.join - end - - def gets(*args) - begin - readline(*args) - rescue EOFError - nil - end - end - - def readchar - _read_buf - _readchar(@buf) - end - - def getc - begin - readchar - rescue EOFError - nil - end - end - - def readbyte - _read_buf - IO._bufread(@buf, 1).getbyte(0) - end - - def getbyte - readbyte - rescue EOFError - nil - end - # 15.2.20.5.3 def each(&block) return to_enum unless block @@ -323,14 +141,6 @@ def each_char(&block) self end - def readlines - ary = [] - while (line = gets) - ary << line - end - ary - end - def puts(*args) i = 0 len = args.size diff --git a/mruby/mrbgems/mruby-io/src/file.c b/mruby/mrbgems/mruby-io/src/file.c index fe786179..e0957ffa 100644 --- a/mruby/mrbgems/mruby-io/src/file.c +++ b/mruby/mrbgems/mruby-io/src/file.c @@ -261,7 +261,7 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass) result = mrb_str_new_capa(mrb, PATH_MAX); if (realpath(cpath, RSTRING_PTR(result)) == NULL) { mrb_locale_free(cpath); - mrb_sys_fail(mrb, cpath); + mrb_sys_fail(mrb, RSTRING_CSTR(mrb, pathname)); return result; /* not reached */ } mrb_locale_free(cpath); @@ -594,7 +594,7 @@ mrb_init_file(mrb_state *mrb) io = mrb_class_get_id(mrb, MRB_SYM(IO)); file = mrb_define_class(mrb, "File", io); - MRB_SET_INSTANCE_TT(file, MRB_TT_DATA); + MRB_SET_INSTANCE_TT(file, MRB_TT_CDATA); mrb_define_class_method(mrb, file, "umask", mrb_file_s_umask, MRB_ARGS_OPT(1)); mrb_define_class_method(mrb, file, "delete", mrb_file_s_unlink, MRB_ARGS_ANY()); mrb_define_class_method(mrb, file, "unlink", mrb_file_s_unlink, MRB_ARGS_ANY()); diff --git a/mruby/mrbgems/mruby-io/src/io.c b/mruby/mrbgems/mruby-io/src/io.c index 765dc905..ebe19930 100644 --- a/mruby/mrbgems/mruby-io/src/io.c +++ b/mruby/mrbgems/mruby-io/src/io.c @@ -11,6 +11,7 @@ #include "mruby/variable.h" #include "mruby/ext/io.h" #include "mruby/error.h" +#include "mruby/internal.h" #include "mruby/presym.h" #include @@ -33,7 +34,7 @@ typedef long ftime_t; typedef long fsuseconds_t; typedef int fmode_t; - typedef int mrb_io_read_write_size; + typedef int fssize_t; #ifndef O_TMPFILE #define O_TMPFILE O_TEMPORARY @@ -47,7 +48,7 @@ typedef time_t ftime_t; typedef suseconds_t fsuseconds_t; typedef mode_t fmode_t; - typedef ssize_t mrb_io_read_write_size; + typedef ssize_t fssize_t; #endif #ifdef _MSC_VER @@ -66,21 +67,20 @@ typedef mrb_int pid_t; #define OPEN_READABLE_P(f) ((mrb_bool)(OPEN_RDONLY_P(f) || OPEN_RDWR_P(f))) #define OPEN_WRITABLE_P(f) ((mrb_bool)(OPEN_WRONLY_P(f) || OPEN_RDWR_P(f))) -static void mrb_io_free(mrb_state *mrb, void *ptr); -struct mrb_data_type mrb_io_type = { "IO", mrb_io_free }; +static void io_free(mrb_state *mrb, void *ptr); +struct mrb_data_type mrb_io_type = { "IO", io_free }; -static struct mrb_io *io_get_open_fptr(mrb_state *mrb, mrb_value self); -static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr); -static int mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode); +static int io_modestr_to_flags(mrb_state *mrb, const char *modestr); +static int io_mode_to_flags(mrb_state *mrb, mrb_value mode); static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet); -static struct mrb_io * -io_get_open_fptr(mrb_state *mrb, mrb_value self) +static struct mrb_io* +io_get_open_fptr(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; - fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, self, &mrb_io_type); + fptr = (struct mrb_io*)mrb_data_get_ptr(mrb, io, &mrb_io_type); if (fptr == NULL) { mrb_raise(mrb, E_IO_ERROR, "uninitialized stream"); } @@ -90,6 +90,11 @@ io_get_open_fptr(mrb_state *mrb, mrb_value self) return fptr; } +#if !defined(MRB_NO_IO_POPEN) && defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +# define MRB_NO_IO_POPEN 1 +#endif + +#ifndef MRB_NO_IO_POEPN static void io_set_process_status(mrb_state *mrb, pid_t pid, int status) { @@ -110,9 +115,10 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status) } mrb_gv_set(mrb, mrb_intern_lit(mrb, "$?"), v); } +#endif static int -mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) +io_modestr_to_flags(mrb_state *mrb, const char *mode) { int flags; const char *m = mode; @@ -153,13 +159,13 @@ mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) } static int -mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode) +io_mode_to_flags(mrb_state *mrb, mrb_value mode) { if (mrb_nil_p(mode)) { - return mrb_io_modestr_to_flags(mrb, "r"); + return O_RDONLY; } else if (mrb_string_p(mode)) { - return mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); + return io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode)); } else { int flags = 0; @@ -222,14 +228,14 @@ mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode) } static void -mrb_fd_cloexec(mrb_state *mrb, int fd) +io_fd_cloexec(mrb_state *mrb, int fd) { #if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) int flags, flags2; flags = fcntl(fd, F_GETFD); - if (flags == -1) { - mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%d, F_GETFD) failed: %d", fd, errno); + if (flags < 0) { + mrb_sys_fail(mrb, "cloexec GETFD"); } if (fd <= 2) { flags2 = flags & ~FD_CLOEXEC; /* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */ @@ -238,8 +244,8 @@ mrb_fd_cloexec(mrb_state *mrb, int fd) flags2 = flags | FD_CLOEXEC; /* Set CLOEXEC for non-standard file descriptors: 3, 4, 5, ... */ } if (flags != flags2) { - if (fcntl(fd, F_SETFD, flags2) == -1) { - mrb_bug(mrb, "mrb_fd_cloexec: fcntl(%d, F_SETFD, %d) failed: %d", fd, flags2, errno); + if (fcntl(fd, F_SETFD, flags2) < 0) { + mrb_sys_fail(mrb, "cloexec SETFD"); } } #endif @@ -247,33 +253,33 @@ mrb_fd_cloexec(mrb_state *mrb, int fd) #if !defined(_WIN32) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) static int -mrb_cloexec_pipe(mrb_state *mrb, int fildes[2]) +io_cloexec_pipe(mrb_state *mrb, int fildes[2]) { int ret; ret = pipe(fildes); if (ret == -1) return -1; - mrb_fd_cloexec(mrb, fildes[0]); - mrb_fd_cloexec(mrb, fildes[1]); + io_fd_cloexec(mrb, fildes[0]); + io_fd_cloexec(mrb, fildes[1]); return ret; } static int -mrb_pipe(mrb_state *mrb, int pipes[2]) +io_pipe(mrb_state *mrb, int pipes[2]) { int ret; - ret = mrb_cloexec_pipe(mrb, pipes); + ret = io_cloexec_pipe(mrb, pipes); if (ret == -1) { if (errno == EMFILE || errno == ENFILE) { mrb_garbage_collect(mrb); - ret = mrb_cloexec_pipe(mrb, pipes); + ret = io_cloexec_pipe(mrb, pipes); } } return ret; } static int -mrb_proc_exec(const char *pname) +io_process_exec(const char *pname) { const char *s; s = pname; @@ -286,33 +292,45 @@ mrb_proc_exec(const char *pname) return -1; } - execl("/bin/sh", "sh", "-c", pname, (char *)NULL); + execl("/bin/sh", "sh", "-c", pname, (char*)NULL); return -1; } #endif static void -mrb_io_free(mrb_state *mrb, void *ptr) +io_free(mrb_state *mrb, void *ptr) { - struct mrb_io *io = (struct mrb_io *)ptr; + struct mrb_io *io = (struct mrb_io*)ptr; if (io != NULL) { fptr_finalize(mrb, io, TRUE); mrb_free(mrb, io); } } +static void +io_buf_init(mrb_state *mrb, struct mrb_io *fptr) +{ + if (fptr->readable) { + fptr->buf = (struct mrb_io_buf*)mrb_malloc(mrb, sizeof(struct mrb_io_buf)); + fptr->buf->start = 0; + fptr->buf->len = 0; + } +} + static struct mrb_io * -mrb_io_alloc(mrb_state *mrb) +io_alloc(mrb_state *mrb) { struct mrb_io *fptr; - fptr = (struct mrb_io *)mrb_malloc(mrb, sizeof(struct mrb_io)); + fptr = (struct mrb_io*)mrb_malloc(mrb, sizeof(struct mrb_io)); fptr->fd = -1; fptr->fd2 = -1; fptr->pid = 0; + fptr->buf = 0; fptr->readable = 0; fptr->writable = 0; fptr->sync = 0; + fptr->eof = 0; fptr->is_socket = 0; return fptr; } @@ -321,8 +339,8 @@ mrb_io_alloc(mrb_state *mrb) #define NOFILE 64 #endif -#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE -# define mrb_io_s_popen mrb_notimplement_m +#ifdef MRB_NO_IO_POPEN +# define io_s_popen mrb_notimplement_m #else static int option_to_fd(mrb_state *mrb, mrb_value v) @@ -331,7 +349,7 @@ option_to_fd(mrb_state *mrb, mrb_value v) if (mrb_nil_p(v)) return -1; switch (mrb_type(v)) { - case MRB_TT_DATA: /* IO */ + case MRB_TT_CDATA: /* IO */ return mrb_io_fileno(mrb, v); case MRB_TT_INTEGER: return (int)mrb_integer(v); @@ -343,7 +361,7 @@ option_to_fd(mrb_state *mrb, mrb_value v) } static mrb_value -mrb_io_s_popen_args(mrb_state *mrb, mrb_value klass, +io_s_popen_args(mrb_state *mrb, mrb_value klass, const char **cmd, int *flags, int *doexec, int *opt_in, int *opt_out, int *opt_err) { @@ -359,7 +377,7 @@ mrb_io_s_popen_args(mrb_state *mrb, mrb_value klass, mrb_get_args(mrb, "zo:", cmd, &mode, &kw); - *flags = mrb_io_mode_to_flags(mrb, mode); + *flags = io_mode_to_flags(mrb, mode); *doexec = (strcmp("-", *cmd) != 0); *opt_in = option_to_fd(mrb, kv.opt_in); *opt_out = option_to_fd(mrb, kv.opt_out); @@ -370,7 +388,7 @@ mrb_io_s_popen_args(mrb_state *mrb, mrb_value klass, #ifdef _WIN32 static mrb_value -mrb_io_s_popen(mrb_state *mrb, mrb_value klass) +io_s_popen(mrb_state *mrb, mrb_value klass) { mrb_value io; int doexec; @@ -392,8 +410,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) 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); + io = io_s_popen_args(mrb, klass, &cmd, &flags, &doexec, + &opt_in, &opt_out, &opt_err); saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; @@ -442,15 +460,13 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) pid = pi.dwProcessId; } - mrb_iv_set(mrb, io, mrb_intern_lit(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); - - fptr = mrb_io_alloc(mrb); + fptr = io_alloc(mrb); fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0); fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0); fptr->pid = pid; fptr->readable = OPEN_READABLE_P(flags); fptr->writable = OPEN_WRITABLE_P(flags); - fptr->sync = 0; + io_buf_init(mrb, fptr); DATA_TYPE(io) = &mrb_io_type; DATA_PTR(io) = fptr; @@ -458,7 +474,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) } #else static mrb_value -mrb_io_s_popen(mrb_state *mrb, mrb_value klass) +io_s_popen(mrb_state *mrb, mrb_value klass) { mrb_value io, result; int doexec; @@ -472,15 +488,15 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) 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); + io = io_s_popen_args(mrb, klass, &cmd, &flags, &doexec, + &opt_in, &opt_out, &opt_err); if (OPEN_READABLE_P(flags)) { if (pipe(pr) == -1) { mrb_sys_fail(mrb, "pipe"); } - mrb_fd_cloexec(mrb, pr[0]); - mrb_fd_cloexec(mrb, pr[1]); + io_fd_cloexec(mrb, pr[0]); + io_fd_cloexec(mrb, pr[1]); } if (OPEN_WRITABLE_P(flags)) { @@ -489,8 +505,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) if (pr[1] != -1) close(pr[1]); mrb_sys_fail(mrb, "pipe"); } - mrb_fd_cloexec(mrb, pw[0]); - mrb_fd_cloexec(mrb, pw[1]); + io_fd_cloexec(mrb, pw[0]); + io_fd_cloexec(mrb, pw[1]); } if (!doexec) { @@ -530,7 +546,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) for (fd = 3; fd < NOFILE; fd++) { close(fd); } - mrb_proc_exec(cmd); + io_process_exec(cmd); mrb_raisef(mrb, E_IO_ERROR, "command not found: %s", cmd); _exit(127); } @@ -551,15 +567,13 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) fd = pw[1]; } - mrb_iv_set(mrb, io, mrb_intern_lit(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); - - fptr = mrb_io_alloc(mrb); + fptr = io_alloc(mrb); fptr->fd = fd; fptr->fd2 = write_fd; fptr->pid = pid; fptr->readable = OPEN_READABLE_P(flags); fptr->writable = OPEN_WRITABLE_P(flags); - fptr->sync = 0; + io_buf_init(mrb, fptr); DATA_TYPE(io) = &mrb_io_type; DATA_PTR(io) = fptr; @@ -586,7 +600,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) #endif /* TARGET_OS_IPHONE */ static int -mrb_dup(mrb_state *mrb, int fd, mrb_bool *failed) +symdup(mrb_state *mrb, int fd, mrb_bool *failed) { int new_fd; @@ -600,42 +614,39 @@ mrb_dup(mrb_state *mrb, int fd, mrb_bool *failed) } static mrb_value -mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy) +io_init_copy(mrb_state *mrb, mrb_value copy) { mrb_value orig = mrb_get_arg1(mrb); - mrb_value buf; struct mrb_io *fptr_copy; struct mrb_io *fptr_orig; mrb_bool failed = TRUE; fptr_orig = io_get_open_fptr(mrb, orig); - fptr_copy = (struct mrb_io *)DATA_PTR(copy); + fptr_copy = (struct mrb_io*)DATA_PTR(copy); if (fptr_orig == fptr_copy) return copy; if (fptr_copy != NULL) { fptr_finalize(mrb, fptr_copy, FALSE); mrb_free(mrb, fptr_copy); } - fptr_copy = (struct mrb_io *)mrb_io_alloc(mrb); + fptr_copy = (struct mrb_io*)io_alloc(mrb); DATA_TYPE(copy) = &mrb_io_type; DATA_PTR(copy) = fptr_copy; + io_buf_init(mrb, fptr_copy); - buf = mrb_iv_get(mrb, orig, mrb_intern_lit(mrb, "@buf")); - mrb_iv_set(mrb, copy, mrb_intern_lit(mrb, "@buf"), buf); - - fptr_copy->fd = mrb_dup(mrb, fptr_orig->fd, &failed); + fptr_copy->fd = symdup(mrb, fptr_orig->fd, &failed); if (failed) { mrb_sys_fail(mrb, 0); } - mrb_fd_cloexec(mrb, fptr_copy->fd); + io_fd_cloexec(mrb, fptr_copy->fd); if (fptr_orig->fd2 != -1) { - fptr_copy->fd2 = mrb_dup(mrb, fptr_orig->fd2, &failed); + fptr_copy->fd2 = symdup(mrb, fptr_orig->fd2, &failed); if (failed) { close(fptr_copy->fd); mrb_sys_fail(mrb, 0); } - mrb_fd_cloexec(mrb, fptr_copy->fd2); + io_fd_cloexec(mrb, fptr_copy->fd2); } fptr_copy->pid = fptr_orig->pid; @@ -685,16 +696,16 @@ check_file_descriptor(mrb_state *mrb, mrb_int fd) } static mrb_value -mrb_io_initialize(mrb_state *mrb, mrb_value io) +io_init(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; mrb_int fd; - mrb_value mode, opt; + mrb_value mode, opt; /* opt (Hash) will be ignored */ int flags; mode = opt = mrb_nil_value(); - mrb_get_args(mrb, "i|oo", &fd, &mode, &opt); + mrb_get_args(mrb, "i|oH", &fd, &mode, &opt); switch (fd) { case 0: /* STDIN_FILENO */ case 1: /* STDOUT_FILENO */ @@ -704,23 +715,14 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) check_file_descriptor(mrb, fd); break; } - if (mrb_nil_p(mode)) { - mode = mrb_str_new_cstr(mrb, "r"); - } - if (mrb_nil_p(opt)) { - opt = mrb_hash_new(mrb); - } - - flags = mrb_io_mode_to_flags(mrb, mode); + flags = io_mode_to_flags(mrb, mode); - mrb_iv_set(mrb, io, mrb_intern_lit(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); - - fptr = (struct mrb_io *)DATA_PTR(io); + fptr = (struct mrb_io*)DATA_PTR(io); if (fptr != NULL) { fptr_finalize(mrb, fptr, TRUE); mrb_free(mrb, fptr); } - fptr = mrb_io_alloc(mrb); + fptr = io_alloc(mrb); DATA_TYPE(io) = &mrb_io_type; DATA_PTR(io) = fptr; @@ -728,7 +730,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) fptr->fd = (int)fd; fptr->readable = OPEN_READABLE_P(flags); fptr->writable = OPEN_WRITABLE_P(flags); - fptr->sync = 0; + io_buf_init(mrb, fptr); return io; } @@ -736,12 +738,13 @@ static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet) { int saved_errno = 0; + int limit = quiet ? 3 : 0; if (fptr == NULL) { return; } - if (fptr->fd > 2) { + if (fptr->fd >= limit) { #ifdef _WIN32 if (fptr->is_socket) { if (closesocket(fptr->fd) != 0) { @@ -758,7 +761,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet) fptr->fd = -1; } - if (fptr->fd2 > 2) { + if (fptr->fd2 >= limit) { if (close(fptr->fd2) == -1) { if (saved_errno == 0) { saved_errno = errno; @@ -767,6 +770,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet) fptr->fd2 = -1; } +#ifndef MRB_NO_IO_POPEN if (fptr->pid != 0) { #if !defined(_WIN32) && !defined(_WIN64) pid_t pid; @@ -788,6 +792,12 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet) fptr->pid = 0; /* Note: we don't raise an exception when waitpid(3) fails */ } +#endif + + if (fptr->buf) { + mrb_free(mrb, fptr->buf); + fptr->buf = NULL; + } if (!quiet && saved_errno != 0) { errno = saved_errno; @@ -795,29 +805,50 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet) } } -static mrb_value -mrb_io_check_readable(mrb_state *mrb, mrb_value self) +static struct mrb_io* +io_get_read_fptr(mrb_state *mrb, mrb_value io) { - struct mrb_io *fptr = io_get_open_fptr(mrb, self); - if (! fptr->readable) { + struct mrb_io *fptr = io_get_open_fptr(mrb, io); + if (!fptr->readable) { mrb_raise(mrb, E_IO_ERROR, "not opened for reading"); } - return mrb_nil_value(); + return fptr; +} + +static struct mrb_io* +io_get_write_fptr(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr = io_get_open_fptr(mrb, io); + if (!fptr->writable) { + mrb_raise(mrb, E_IO_ERROR, "not opened for writing"); + } + return fptr; +} + +static int +io_get_write_fd(struct mrb_io *fptr) +{ + if (fptr->fd2 == -1) { + return fptr->fd; + } + else { + return fptr->fd2; + } } static mrb_value -mrb_io_isatty(mrb_state *mrb, mrb_value self) +io_isatty(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; - fptr = io_get_open_fptr(mrb, self); + fptr = io_get_open_fptr(mrb, io); if (isatty(fptr->fd) == 0) return mrb_false_value(); return mrb_true_value(); } static mrb_value -mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass) +io_s_for_fd(mrb_state *mrb, mrb_value klass) { struct RClass *c = mrb_class_ptr(klass); enum mrb_vtype ttype = MRB_INSTANCE_TT(c); @@ -826,11 +857,11 @@ mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass) /* copied from mrb_instance_alloc() */ if (ttype == 0) ttype = MRB_TT_OBJECT; obj = mrb_obj_value((struct RObject*)mrb_obj_alloc(mrb, ttype, c)); - return mrb_io_initialize(mrb, obj); + return io_init(mrb, obj); } static mrb_value -mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass) +io_s_sysclose(mrb_state *mrb, mrb_value klass) { mrb_int fd; mrb->c->ci->mid = 0; @@ -842,7 +873,7 @@ mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass) } static int -mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode) +io_cloexec_open(mrb_state *mrb, const char *pathname, int flags, fmode_t mode) { int fd, retry = FALSE; char* fname = mrb_locale_from_utf8(pathname, -1); @@ -854,7 +885,7 @@ mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mo flags |= O_NOINHERIT; #endif reopen: - fd = open(fname, (int)flags, (fmode_t)mode); + fd = open(fname, flags, mode); if (fd == -1) { if (!retry) { switch (errno) { @@ -871,13 +902,13 @@ mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mo mrb_locale_free(fname); if (fd <= 2) { - mrb_fd_cloexec(mrb, fd); + io_fd_cloexec(mrb, fd); } return fd; } static mrb_value -mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) +io_s_sysopen(mrb_state *mrb, mrb_value klass) { mrb_value path = mrb_nil_value(); mrb_value mode = mrb_nil_value(); @@ -891,38 +922,22 @@ mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) } pat = RSTRING_CSTR(mrb, path); - flags = mrb_io_mode_to_flags(mrb, mode); - fd = mrb_cloexec_open(mrb, pat, flags, perm); + flags = io_mode_to_flags(mrb, mode); + fd = io_cloexec_open(mrb, pat, flags, (fmode_t)perm); return mrb_fixnum_value(fd); } -static mrb_value mrb_io_sysread_common(mrb_state *mrb, - mrb_io_read_write_size (*readfunc)(int, void *, fsize_t, off_t), - mrb_value io, mrb_value buf, mrb_int maxlen, off_t offset); - -static mrb_io_read_write_size -mrb_sysread_dummy(int fd, void *buf, fsize_t nbytes, off_t offset) -{ - return (mrb_io_read_write_size)read(fd, buf, nbytes); -} - -static mrb_value -mrb_io_sysread(mrb_state *mrb, mrb_value io) +static void +eof_error(mrb_state *mrb) { - mrb_value buf = mrb_nil_value(); - mrb_int maxlen; - - mrb_get_args(mrb, "i|S", &maxlen, &buf); - - return mrb_io_sysread_common(mrb, mrb_sysread_dummy, io, buf, maxlen, 0); + mrb_raise(mrb, E_EOF_ERROR, "end of file reached"); } static mrb_value -mrb_io_sysread_common(mrb_state *mrb, - mrb_io_read_write_size (*readfunc)(int, void *, fsize_t, off_t), +io_read_common(mrb_state *mrb, + fssize_t (*readfunc)(int, void*, fsize_t, off_t), mrb_value io, mrb_value buf, mrb_int maxlen, off_t offset) { - struct mrb_io *fptr; int ret; if (maxlen < 0) { @@ -943,10 +958,7 @@ mrb_io_sysread_common(mrb_state *mrb, mrb_str_modify(mrb, RSTRING(buf)); } - fptr = (struct mrb_io *)io_get_open_fptr(mrb, io); - if (!fptr->readable) { - mrb_raise(mrb, E_IO_ERROR, "not opened for reading"); - } + struct mrb_io *fptr = io_get_read_fptr(mrb, io); ret = readfunc(fptr->fd, RSTRING_PTR(buf), (fsize_t)maxlen, offset); if (ret < 0) { mrb_sys_fail(mrb, "sysread failed"); @@ -955,13 +967,31 @@ mrb_io_sysread_common(mrb_state *mrb, buf = mrb_str_resize(mrb, buf, ret); } if (ret == 0 && maxlen > 0) { - mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File"); + fptr->eof = 1; + eof_error(mrb); } return buf; } +static fssize_t +sysread(int fd, void *buf, fsize_t nbytes, off_t offset) +{ + return (fssize_t)read(fd, buf, nbytes); +} + +static mrb_value +io_sysread(mrb_state *mrb, mrb_value io) +{ + mrb_value buf = mrb_nil_value(); + mrb_int maxlen; + + mrb_get_args(mrb, "i|S", &maxlen, &buf); + + return io_read_common(mrb, sysread, io, buf, maxlen, 0); +} + static mrb_value -mrb_io_sysseek(mrb_state *mrb, mrb_value io) +io_sysseek(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; off_t pos; @@ -977,73 +1007,130 @@ mrb_io_sysseek(mrb_state *mrb, mrb_value io) if (pos == -1) { mrb_sys_fail(mrb, "sysseek"); } - if (pos > MRB_INT_MAX) { -#ifndef MRB_NO_FLOAT - return mrb_float_value(mrb, (mrb_float)pos); -#else - mrb_raise(mrb, E_IO_ERROR, "sysseek reached too far for MRB_NO_FLOAT"); -#endif - } else { - return mrb_int_value(mrb, pos); + fptr->eof = 0; + if (sizeof(off_t) > sizeof(mrb_int) && pos > (off_t)MRB_INT_MAX) { + mrb_raise(mrb, E_IO_ERROR, "sysseek reached too far for mrb_int"); } + return mrb_int_value(mrb, (mrb_int)pos); } static mrb_value -mrb_io_syswrite_common(mrb_state *mrb, - mrb_io_read_write_size (*writefunc)(int, const void *, fsize_t, off_t), - mrb_value io, mrb_value buf, off_t offset) +io_seek(mrb_state *mrb, mrb_value io) { - struct mrb_io *fptr; - int fd, length; - - fptr = io_get_open_fptr(mrb, io); - if (! fptr->writable) { - mrb_raise(mrb, E_IO_ERROR, "not opened for writing"); + mrb_value pos = io_sysseek(mrb, io); + struct mrb_io *fptr = io_get_open_fptr(mrb, io); + if (fptr->buf) { + fptr->buf->start = 0; + fptr->buf->len = 0; } + return pos; +} - if (fptr->fd2 == -1) { - fd = fptr->fd; - } else { - fd = fptr->fd2; - } - length = writefunc(fd, RSTRING_PTR(buf), (fsize_t)RSTRING_LEN(buf), offset); +static mrb_value +io_write_common(mrb_state *mrb, + fssize_t (*writefunc)(int, const void*, fsize_t, off_t), + struct mrb_io *fptr, const void *buf, fsize_t blen, off_t offset) +{ + int fd; + fssize_t length; + + fd = io_get_write_fd(fptr); + length = writefunc(fd, buf, blen, offset); if (length == -1) { - mrb_sys_fail(mrb, 0); + mrb_sys_fail(mrb, "syswrite"); } - return mrb_int_value(mrb, (mrb_int)length); } -static mrb_io_read_write_size -mrb_syswrite_dummy(int fd, const void *buf, fsize_t nbytes, off_t offset) +static fssize_t +syswrite(int fd, const void *buf, fsize_t nbytes, off_t offset) { - return (mrb_io_read_write_size)write(fd, buf, nbytes); + return (fssize_t)write(fd, buf, nbytes); } static mrb_value -mrb_io_syswrite(mrb_state *mrb, mrb_value io) +io_syswrite(mrb_state *mrb, mrb_value io) { mrb_value buf; mrb_get_args(mrb, "S", &buf); - return mrb_io_syswrite_common(mrb, mrb_syswrite_dummy, io, buf, 0); + return io_write_common(mrb, syswrite, io_get_write_fptr(mrb, io), RSTRING_PTR(buf), RSTRING_LEN(buf), 0); +} + + /* def write(string) */ + /* str = string.is_a?(String) ? string : string.to_s */ + /* return 0 if str.empty? */ + /* len = syswrite(str) */ + /* len */ + /* end */ + +static mrb_int +fd_write(mrb_state *mrb, int fd, mrb_value str) +{ + fssize_t len, sum, n; + + str = mrb_obj_as_string(mrb, str); + len = (fssize_t)RSTRING_LEN(str); + if (len == 0)return 0; + + for (sum=0; sumbuf && fptr->buf->len > 0) { + off_t n; + + /* get current position */ + n = lseek(fd, 0, SEEK_CUR); + if (n == -1) mrb_sys_fail(mrb, "lseek"); + /* move cursor */ + n = lseek(fd, n - fptr->buf->len, SEEK_SET); + if (n == -1) mrb_sys_fail(mrb, "lseek(2)"); + fptr->buf->start = fptr->buf->len = 0; + } + + if (mrb_get_argc(mrb) == 1) { + len = fd_write(mrb, fd, mrb_get_arg1(mrb)); + } + else { + mrb_value *argv; + mrb_int argc; + + mrb_get_args(mrb, "*", &argv, &argc); + while (argc--) { + len += fd_write(mrb, fd, *argv++); + } + } + return mrb_int_value(mrb, len); +} + +static mrb_value +io_close(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; - fptr = io_get_open_fptr(mrb, self); + fptr = io_get_open_fptr(mrb, io); fptr_finalize(mrb, fptr, FALSE); return mrb_nil_value(); } static mrb_value -mrb_io_close_write(mrb_state *mrb, mrb_value self) +io_close_write(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; - fptr = io_get_open_fptr(mrb, self); + fptr = io_get_open_fptr(mrb, io); if (close((int)fptr->fd2) == -1) { mrb_sys_fail(mrb, "close"); } @@ -1051,10 +1138,10 @@ mrb_io_close_write(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_io_closed(mrb_state *mrb, mrb_value io) +io_closed(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; - fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, io, &mrb_io_type); + fptr = (struct mrb_io*)mrb_data_get_ptr(mrb, io, &mrb_io_type); if (fptr == NULL || fptr->fd >= 0) { return mrb_false_value(); } @@ -1063,7 +1150,22 @@ mrb_io_closed(mrb_state *mrb, mrb_value io) } static mrb_value -mrb_io_pid(mrb_state *mrb, mrb_value io) +io_pos(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr = io_get_open_fptr(mrb, io); + off_t pos = lseek(fptr->fd, 0, SEEK_CUR); + if (pos == -1) mrb_sys_fail(mrb, 0); + + if (fptr->buf) { + return mrb_int_value(mrb, pos - fptr->buf->len); + } + else { + return mrb_int_value(mrb, pos); + } +} + +static mrb_value +io_pid(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; fptr = io_get_open_fptr(mrb, io); @@ -1100,19 +1202,9 @@ time2timeval(mrb_state *mrb, mrb_value time) return t; } -static int -mrb_io_read_data_pending(mrb_state *mrb, mrb_value io) -{ - mrb_value buf = mrb_iv_get(mrb, io, mrb_intern_lit(mrb, "@buf")); - if (mrb_string_p(buf) && RSTRING_LEN(buf) > 0) { - return 1; - } - return 0; -} - #if !defined(_WIN32) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) static mrb_value -mrb_io_s_pipe(mrb_state *mrb, mrb_value klass) +io_s_pipe(mrb_state *mrb, mrb_value klass) { mrb_value r = mrb_nil_value(); mrb_value w = mrb_nil_value(); @@ -1120,25 +1212,21 @@ mrb_io_s_pipe(mrb_state *mrb, mrb_value klass) struct mrb_io *fptr_w; int pipes[2]; - if (mrb_pipe(mrb, pipes) == -1) { + if (io_pipe(mrb, pipes) == -1) { mrb_sys_fail(mrb, "pipe"); } r = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); - mrb_iv_set(mrb, r, mrb_intern_lit(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); - fptr_r = mrb_io_alloc(mrb); + fptr_r = io_alloc(mrb); fptr_r->fd = pipes[0]; fptr_r->readable = 1; - fptr_r->writable = 0; - fptr_r->sync = 0; DATA_TYPE(r) = &mrb_io_type; DATA_PTR(r) = fptr_r; + io_buf_init(mrb, fptr_r); w = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); - mrb_iv_set(mrb, w, mrb_intern_lit(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); - fptr_w = mrb_io_alloc(mrb); + fptr_w = io_alloc(mrb); fptr_w->fd = pipes[1]; - fptr_w->readable = 0; fptr_w->writable = 1; fptr_w->sync = 1; DATA_TYPE(w) = &mrb_io_type; @@ -1148,8 +1236,15 @@ mrb_io_s_pipe(mrb_state *mrb, mrb_value klass) } #endif +static int +mrb_io_read_data_pending(mrb_state *mrb, struct mrb_io *fptr) +{ + if (fptr->buf && fptr->buf->len > 0) return 1; + return 0; +} + static mrb_value -mrb_io_s_select(mrb_state *mrb, mrb_value klass) +io_s_select(mrb_state *mrb, mrb_value klass) { const mrb_value *argv; mrb_int argc; @@ -1198,7 +1293,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass) fptr = io_get_open_fptr(mrb, read_io); if (fptr->fd >= FD_SETSIZE) continue; FD_SET(fptr->fd, rp); - if (mrb_io_read_data_pending(mrb, read_io)) { + if (mrb_io_read_data_pending(mrb, fptr)) { pending++; FD_SET(fptr->fd, &pset); } @@ -1258,8 +1353,14 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass) retry: n = select(max, rp, wp, ep, tp); if (n < 0) { +#ifdef _WIN32 + errno = WSAGetLastError(); + if (errno != WSAEINTR) + mrb_sys_fail(mrb, "select failed"); +#else if (errno != EINTR) mrb_sys_fail(mrb, "select failed"); +#endif if (tp == NULL) goto retry; interrupt_flag = 1; @@ -1322,7 +1423,7 @@ mrb_io_fileno(mrb_state *mrb, mrb_value io) } static mrb_value -mrb_io_fileno_m(mrb_state *mrb, mrb_value io) +io_fileno(mrb_state *mrb, mrb_value io) { int fd = mrb_io_fileno(mrb, io); return mrb_fixnum_value(fd); @@ -1330,12 +1431,12 @@ mrb_io_fileno_m(mrb_state *mrb, mrb_value io) #if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) static mrb_value -mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self) +io_close_on_exec_p(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; int ret; - fptr = io_get_open_fptr(mrb, self); + fptr = io_get_open_fptr(mrb, io); if (fptr->fd2 >= 0) { if ((ret = fcntl(fptr->fd2, F_GETFD)) == -1) mrb_sys_fail(mrb, "F_GETFD failed"); @@ -1347,18 +1448,18 @@ mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self) return mrb_true_value(); } #else -# define mrb_io_close_on_exec_p mrb_notimplement_m +# define io_close_on_exec_p mrb_notimplement_m #endif #if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) static mrb_value -mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self) +io_set_close_on_exec(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; int flag, ret; mrb_bool b; - fptr = io_get_open_fptr(mrb, self); + fptr = io_get_open_fptr(mrb, io); mrb_get_args(mrb, "b", &b); flag = b ? FD_CLOEXEC : 0; @@ -1382,32 +1483,32 @@ mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self) return mrb_bool_value(b); } #else -# define mrb_io_set_close_on_exec mrb_notimplement_m +# define io_set_close_on_exec mrb_notimplement_m #endif static mrb_value -mrb_io_set_sync(mrb_state *mrb, mrb_value self) +io_set_sync(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; mrb_bool b; - fptr = io_get_open_fptr(mrb, self); + fptr = io_get_open_fptr(mrb, io); mrb_get_args(mrb, "b", &b); fptr->sync = b; return mrb_bool_value(b); } static mrb_value -mrb_io_sync(mrb_state *mrb, mrb_value self) +io_sync(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; - fptr = io_get_open_fptr(mrb, self); + fptr = io_get_open_fptr(mrb, io); return mrb_bool_value(fptr->sync); } #ifndef MRB_WITH_IO_PREAD_PWRITE -# define mrb_io_pread mrb_notimplement_m -# define mrb_io_pwrite mrb_notimplement_m +# define io_pread mrb_notimplement_m +# define io_pwrite mrb_notimplement_m #else static off_t value2off(mrb_state *mrb, mrb_value offv) @@ -1420,7 +1521,7 @@ value2off(mrb_state *mrb, mrb_value offv) * pread(maxlen, offset, outbuf = "") -> outbuf */ static mrb_value -mrb_io_pread(mrb_state *mrb, mrb_value io) +io_pread(mrb_state *mrb, mrb_value io) { mrb_value buf = mrb_nil_value(); mrb_value off; @@ -1428,7 +1529,7 @@ mrb_io_pread(mrb_state *mrb, mrb_value io) mrb_get_args(mrb, "io|S!", &maxlen, &off, &buf); - return mrb_io_sysread_common(mrb, pread, io, buf, maxlen, value2off(mrb, off)); + return io_read_common(mrb, pread, io, buf, maxlen, value2off(mrb, off)); } /* @@ -1436,87 +1537,366 @@ mrb_io_pread(mrb_state *mrb, mrb_value io) * pwrite(buffer, offset) -> wrote_bytes */ static mrb_value -mrb_io_pwrite(mrb_state *mrb, mrb_value io) +io_pwrite(mrb_state *mrb, mrb_value io) { mrb_value buf, off; mrb_get_args(mrb, "So", &buf, &off); - return mrb_io_syswrite_common(mrb, pwrite, io, buf, value2off(mrb, off)); + return io_write_common(mrb, pwrite, io_get_write_fptr(mrb, io), RSTRING_PTR(buf), RSTRING_LEN(buf), value2off(mrb, off)); } #endif /* MRB_WITH_IO_PREAD_PWRITE */ static mrb_value -io_bufread(mrb_state *mrb, mrb_value str, mrb_int len) +io_ungetc(mrb_state *mrb, mrb_value io) { - mrb_value str2; - mrb_int newlen; - struct RString *s; - char *p; + struct mrb_io *fptr = io_get_read_fptr(mrb, io); + struct mrb_io_buf *buf = fptr->buf; + mrb_value str; + mrb_int len; + + mrb_get_args(mrb, "S", &str); + len = RSTRING_LEN(str); + if (len > MRB_IO_BUF_SIZE - buf->len) { + fptr->buf = (struct mrb_io_buf*)mrb_realloc(mrb, buf, sizeof(struct mrb_io_buf)+buf->len+len-MRB_IO_BUF_SIZE); + buf = fptr->buf; + } + memmove(buf->mem+len, buf->mem+buf->start, buf->len); + memcpy(buf->mem, RSTRING_PTR(str), len); + buf->start = 0; + buf->len += len; + return mrb_nil_value(); +} + +static void +io_buf_reset(struct mrb_io *fptr) +{ + struct mrb_io_buf *buf = fptr->buf; - s = RSTRING(str); - mrb_str_modify(mrb, s); - p = RSTR_PTR(s); - str2 = mrb_str_new(mrb, p, len); - newlen = RSTR_LEN(s)-len; - memmove(p, p+len, newlen); - p[newlen] = '\0'; - RSTR_SET_LEN(s, newlen); + buf->start = 0; + buf->len = 0; +} - return str2; +static void +io_buf_shift(struct mrb_io *fptr, mrb_int n) +{ + struct mrb_io_buf *buf = fptr->buf; + + buf->start += n; + buf->len -= n; +} + +#ifdef MRB_UTF8_STRING +static void +io_buf_fill_comp(mrb_state *mrb, struct mrb_io *fptr) +{ + struct mrb_io_buf *buf = fptr->buf; + int keep = buf->len; + + memmove(buf->mem, buf->mem+buf->start, keep); + int n = read(fptr->fd, buf->mem+keep, MRB_IO_BUF_SIZE-keep); + if (n < 0) mrb_sys_fail(mrb, 0); + if (n == 0) fptr->eof = 1; + buf->start = 0; + buf->len += (short)n; +} +#endif + +static void +io_buf_fill(mrb_state *mrb, struct mrb_io *fptr) +{ + struct mrb_io_buf *buf = fptr->buf; + + if (buf->len > 0) return; + + int n = read(fptr->fd, buf->mem, MRB_IO_BUF_SIZE); + if (n < 0) mrb_sys_fail(mrb, 0); + if (n == 0) fptr->eof = 1; + buf->start = 0; + buf->len = (short)n; } static mrb_value -mrb_io_bufread(mrb_state *mrb, mrb_value self) +io_eof(mrb_state *mrb, mrb_value io) { - mrb_value str; - mrb_int len; + struct mrb_io *fptr = io_get_read_fptr(mrb, io); - mrb->c->ci->mid = 0; - mrb_get_args(mrb, "Si", &str, &len); - mrb_assert(RSTRING_LEN(str) > 0); - mrb_assert(RSTRING_PTR(str) != NULL); - mrb_str_modify(mrb, RSTRING(str)); - return io_bufread(mrb, str, len); + io_buf_fill(mrb, fptr); + if (fptr->buf->len > 0) return mrb_false_value(); + return mrb_bool_value(fptr->eof); +} + +static void +io_buf_cat(mrb_state *mrb, mrb_value outbuf, struct mrb_io *fptr, mrb_int n) +{ + struct mrb_io_buf *buf = fptr->buf; + + mrb_assert(n <= buf->len); + mrb_str_cat(mrb, outbuf, buf->mem+buf->start, n); + io_buf_shift(fptr, n); +} + +static void +io_buf_cat_all(mrb_state *mrb, mrb_value outbuf, struct mrb_io *fptr) +{ + struct mrb_io_buf *buf = fptr->buf; + + mrb_str_cat(mrb, outbuf, buf->mem+buf->start, buf->len); + io_buf_reset(fptr); } static mrb_value -mrb_io_readchar(mrb_state *mrb, mrb_value self) +io_read_all(mrb_state *mrb, struct mrb_io *fptr, mrb_value outbuf) { - mrb_value buf; - mrb_int len = 1; -#ifdef MRB_UTF8_STRING - unsigned char c; -#endif + for (;;) { + io_buf_fill(mrb, fptr); + if (fptr->eof) { + return outbuf; + } + io_buf_cat_all(mrb, outbuf, fptr); + } +} - mrb->c->ci->mid = 0; - mrb_get_args(mrb, "S", &buf); - mrb_assert(RSTRING_LEN(buf) > 0); - mrb_assert(RSTRING_PTR(buf) != NULL); - mrb_str_modify(mrb, RSTRING(buf)); -#ifdef MRB_UTF8_STRING - c = RSTRING_PTR(buf)[0]; - if (c & 0x80) { - len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf)); - if (len == 1 && RSTRING_LEN(buf) < 4) { /* partial UTF-8 */ - mrb_int blen = RSTRING_LEN(buf); - ssize_t n; +static mrb_value +io_read(mrb_state *mrb, mrb_value io) +{ + mrb_value outbuf = mrb_nil_value(); + mrb_value len; + mrb_int length = 0; + mrb_bool length_given; + struct mrb_io *fptr = io_get_read_fptr(mrb, io); + + mrb_get_args(mrb, "|o?S", &len, &length_given, &outbuf); + if (length_given) { + if (mrb_nil_p(len)) { + length_given = FALSE; + } + else { + length = mrb_as_int(mrb, len); + if (length < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative length %d given", length); + } + if (length == 0) { + return mrb_str_new(mrb, NULL, 0); + } + } + } - struct mrb_io *fptr = (struct mrb_io*)io_get_open_fptr(mrb, self); + if (mrb_nil_p(outbuf)) { + outbuf = mrb_str_new_capa(mrb, MRB_IO_BUF_SIZE); + } + if (!length_given) { /* read as much as possible */ + return io_read_all(mrb, fptr, outbuf); + } + for (;;) { + io_buf_fill(mrb, fptr); + if (fptr->eof || length == 0) { + if (RSTRING_LEN(outbuf) == 0) + return mrb_nil_value(); + return outbuf; + } + if (fptr->buf->len < length) { + length -= fptr->buf->len; + io_buf_cat_all(mrb, outbuf, fptr); + } + else { + io_buf_cat(mrb, outbuf, fptr, length); + return outbuf; + } + } +} + +static mrb_int +io_find_index(struct mrb_io *fptr, const char *rs, mrb_int rslen) +{ + struct mrb_io_buf *buf = fptr->buf; + + mrb_assert(rslen > 0); + const char c = rs[0]; + const mrb_int limit = buf->len - rslen; + const char *p = buf->mem+buf->start; + for (mrb_int i=0; ireadable) { - mrb_raise(mrb, E_IO_ERROR, "not opened for reading"); +static mrb_value +io_gets(mrb_state *mrb, mrb_value io) +{ + mrb_value rs = mrb_nil_value(); + mrb_int limit; + mrb_bool rs_given = FALSE; /* newline break */ + mrb_bool limit_given = FALSE; /* no limit */ + mrb_value outbuf; + struct mrb_io *fptr = io_get_read_fptr(mrb, io); + struct mrb_io_buf *buf = fptr->buf; + + mrb_get_args(mrb, "|o?i?", &rs, &rs_given, &limit, &limit_given); + + if (limit_given == FALSE) { + if (rs_given) { + if (mrb_nil_p(rs)) { + rs_given = FALSE; + } + else if (mrb_integer_p(rs)) { + limit = mrb_integer(rs); + limit_given = TRUE; + rs = mrb_nil_value(); + } + else if (!mrb_string_p(rs)) { + mrb_ensure_int_type(mrb, rs); + } + } + } + if (rs_given) { + if (mrb_nil_p(rs)) { + rs_given = FALSE; + } + else { + mrb_ensure_string_type(mrb, rs); + if (RSTRING_LEN(rs) == 0) { /* paragraph mode */ + rs = mrb_str_new_lit(mrb, "\n\n"); + } + } + } + else { + rs = mrb_str_new_lit(mrb, "\n"); + rs_given = TRUE; + } + + /* from now on rs_given==FALSE means no RS */ + if (mrb_nil_p(rs) && !limit_given) { + return io_read_all(mrb, fptr, mrb_str_new_capa(mrb, MRB_IO_BUF_SIZE)); + } + + io_buf_fill(mrb, fptr); + if (fptr->eof) return mrb_nil_value(); + + if (limit_given) { + if (limit == 0) return mrb_str_new(mrb, NULL, 0); + outbuf = mrb_str_new_capa(mrb, limit); + } + else { + outbuf = mrb_str_new(mrb, NULL, 0); + } + + for (;;) { + if (rs_given) { /* with RS */ + int rslen = RSTRING_LEN(rs); + mrb_int idx = io_find_index(fptr, RSTRING_PTR(rs), rslen); + if (idx >= 0) { /* found */ + mrb_int n = idx+rslen; + if (limit_given && limit < n) { + n = limit; + } + io_buf_cat(mrb, outbuf, fptr, n); + return outbuf; } - /* refill the buffer */ - mrb_str_resize(mrb, buf, 4096); - n = read(fptr->fd, RSTRING_PTR(buf)+blen, 4096-blen); - if (n < 0) mrb_sys_fail(mrb, "sysread failed"); - mrb_str_resize(mrb, buf, blen+n); } - len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf)); + if (limit_given) { + if (limit <= buf->len) { + io_buf_cat(mrb, outbuf, fptr, limit); + return outbuf; + } + limit -= buf->len; + } + io_buf_cat_all(mrb, outbuf, fptr); + io_buf_fill(mrb, fptr); + if (fptr->eof) { + if (RSTRING_LEN(outbuf) == 0) return mrb_nil_value(); + return outbuf; + } + } +} + +static mrb_value +io_readline(mrb_state *mrb, mrb_value io) +{ + mrb_value result = io_gets(mrb, io); + if (mrb_nil_p(result)) { + eof_error(mrb); + } + return result; +} + +static mrb_value +io_readlines(mrb_state *mrb, mrb_value io) +{ + mrb_value ary = mrb_ary_new(mrb); + for (;;) { + mrb_value line = io_gets(mrb, io); + + if (mrb_nil_p(line)) return ary; + mrb_ary_push(mrb, ary, line); + } +} + +static mrb_value +io_getc(mrb_state *mrb, mrb_value io) +{ + mrb_int len = 1; + struct mrb_io *fptr = io_get_read_fptr(mrb, io); + + io_buf_fill(mrb, fptr); + if (fptr->eof) return mrb_nil_value(); +#ifdef MRB_UTF8_STRING + struct mrb_io_buf *buf = fptr->buf; + const char *p = &buf->mem[buf->start]; + if ((*p) & 0x80) { + len = mrb_utf8len(p, p+buf->len); + if (len == 1 && buf->len < 4) { /* partial UTF-8 */ + io_buf_fill_comp(mrb, fptr); + p = &buf->mem[buf->start]; + len = mrb_utf8len(p, p+buf->len); + } } #endif - return io_bufread(mrb, buf, len); + mrb_value str = mrb_str_new(mrb, fptr->buf->mem+fptr->buf->start, len); + io_buf_shift(fptr, len); + return str; +} + +static mrb_value +io_readchar(mrb_state *mrb, mrb_value io) +{ + mrb_value result = io_getc(mrb, io); + if (mrb_nil_p(result)) { + eof_error(mrb); + } + return result; +} + +static mrb_value +io_getbyte(mrb_state *mrb, mrb_value io) +{ + struct mrb_io *fptr = io_get_read_fptr(mrb, io); + + io_buf_fill(mrb, fptr); + if (fptr->eof) return mrb_nil_value(); + + unsigned char c = fptr->buf->mem[fptr->buf->start]; + io_buf_shift(fptr, 1); + return mrb_int_value(mrb, (mrb_int)c); +} + +static mrb_value +io_readbyte(mrb_state *mrb, mrb_value io) +{ + mrb_value result = io_getbyte(mrb, io); + if (mrb_nil_p(result)) { + eof_error(mrb); + } + return result; +} + +static mrb_value +io_flush(mrb_state *mrb, mrb_value io) +{ + io_get_open_fptr(mrb, io); + return io; } void @@ -1525,37 +1905,51 @@ mrb_init_io(mrb_state *mrb) struct RClass *io; io = mrb_define_class(mrb, "IO", mrb->object_class); - MRB_SET_INSTANCE_TT(io, MRB_TT_DATA); + MRB_SET_INSTANCE_TT(io, MRB_TT_CDATA); mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */ - mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ARG(1,2)); - mrb_define_class_method(mrb, io, "_sysclose", mrb_io_s_sysclose, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_ARG(1,2)); - mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ARG(1,3)); - mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ARG(1,2)); + mrb_define_class_method(mrb, io, "_popen", io_s_popen, MRB_ARGS_ARG(1,2)); + mrb_define_class_method(mrb, io, "_sysclose", io_s_sysclose, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, io, "for_fd", io_s_for_fd, MRB_ARGS_ARG(1,2)); + mrb_define_class_method(mrb, io, "select", io_s_select, MRB_ARGS_ARG(1,3)); + mrb_define_class_method(mrb, io, "sysopen", io_s_sysopen, MRB_ARGS_ARG(1,2)); #if !defined(_WIN32) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) - mrb_define_class_method(mrb, io, "_pipe", mrb_io_s_pipe, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, io, "_pipe", io_s_pipe, MRB_ARGS_NONE()); #endif - mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ARG(1,2)); /* 15.2.20.5.21 (x)*/ - mrb_define_method(mrb, io, "initialize_copy", mrb_io_initialize_copy, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, io, "_check_readable", mrb_io_check_readable, MRB_ARGS_NONE()); - mrb_define_method(mrb, io, "isatty", mrb_io_isatty, MRB_ARGS_NONE()); - mrb_define_method(mrb, io, "sync", mrb_io_sync, MRB_ARGS_NONE()); - mrb_define_method(mrb, io, "sync=", mrb_io_set_sync, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, io, "sysread", mrb_io_sysread, MRB_ARGS_ARG(1,1)); - mrb_define_method(mrb, io, "sysseek", mrb_io_sysseek, MRB_ARGS_ARG(1,1)); - mrb_define_method(mrb, io, "syswrite", mrb_io_syswrite, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, io, "close", mrb_io_close, MRB_ARGS_NONE()); /* 15.2.20.5.1 */ - mrb_define_method(mrb, io, "close_write", mrb_io_close_write, MRB_ARGS_NONE()); - mrb_define_method(mrb, io, "close_on_exec=", mrb_io_set_close_on_exec, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, io, "close_on_exec?", mrb_io_close_on_exec_p, MRB_ARGS_NONE()); - mrb_define_method(mrb, io, "closed?", mrb_io_closed, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ - mrb_define_method(mrb, io, "pid", mrb_io_pid, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ - mrb_define_method(mrb, io, "fileno", mrb_io_fileno_m, MRB_ARGS_NONE()); - mrb_define_method(mrb, io, "pread", mrb_io_pread, MRB_ARGS_ANY()); /* ruby 2.5 feature */ - mrb_define_method(mrb, io, "pwrite", mrb_io_pwrite, MRB_ARGS_ANY()); /* ruby 2.5 feature */ - - mrb_define_method(mrb, io, "_readchar", mrb_io_readchar, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, io, "_bufread", mrb_io_bufread, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, io, "initialize", io_init, MRB_ARGS_ARG(1,2)); + mrb_define_method(mrb, io, "initialize_copy", io_init_copy, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "isatty", io_isatty, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "eof?", io_eof, MRB_ARGS_NONE()); /* 15.2.20.5.6 */ + mrb_define_method(mrb, io, "getc", io_getc, MRB_ARGS_NONE()); /* 15.2.20.5.8 */ + mrb_define_method(mrb, io, "gets", io_gets, MRB_ARGS_OPT(2)); /* 15.2.20.5.9 */ + mrb_define_method(mrb, io, "read", io_read, MRB_ARGS_OPT(2)); /* 15.2.20.5.14 */ + mrb_define_method(mrb, io, "readchar", io_readchar, MRB_ARGS_NONE()); /* 15.2.20.5.15 */ + mrb_define_method(mrb, io, "readline", io_readline, MRB_ARGS_OPT(2)); /* 15.2.20.5.16 */ + mrb_define_method(mrb, io, "readlines", io_readlines, MRB_ARGS_OPT(2)); /* 15.2.20.5.17 */ + mrb_define_method(mrb, io, "sync", io_sync, MRB_ARGS_NONE()); /* 15.2.20.5.18 */ + mrb_define_method(mrb, io, "sync=", io_set_sync, MRB_ARGS_REQ(1)); /* 15.2.20.5.19 */ + mrb_define_method(mrb, io, "sysread", io_sysread, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, io, "sysseek", io_sysseek, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, io, "syswrite", io_syswrite, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "seek", io_seek, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, io, "close", io_close, MRB_ARGS_NONE()); /* 15.2.20.5.1 */ + mrb_define_method(mrb, io, "close_write", io_close_write, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "close_on_exec=", io_set_close_on_exec, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "close_on_exec?", io_close_on_exec_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "closed?", io_closed, MRB_ARGS_NONE()); /* 15.2.20.5.2 */ + mrb_define_method(mrb, io, "flush", io_flush, MRB_ARGS_NONE()); /* 15.2.20.5.7 */ + mrb_define_method(mrb, io, "ungetc", io_ungetc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, io, "pos", io_pos, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "pid", io_pid, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "fileno", io_fileno, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "write", io_write, MRB_ARGS_ANY()); /* 15.2.20.5.20 */ + mrb_define_method(mrb, io, "pread", io_pread, MRB_ARGS_ANY()); /* ruby 2.5 feature */ + mrb_define_method(mrb, io, "pwrite", io_pwrite, MRB_ARGS_ANY()); /* ruby 2.5 feature */ + mrb_define_method(mrb, io, "getbyte", io_getbyte, MRB_ARGS_NONE()); + mrb_define_method(mrb, io, "readbyte", io_readbyte, MRB_ARGS_NONE()); + + mrb_define_const_id(mrb, io, MRB_SYM(SEEK_SET), mrb_fixnum_value(SEEK_SET)); + mrb_define_const_id(mrb, io, MRB_SYM(SEEK_CUR), mrb_fixnum_value(SEEK_CUR)); + mrb_define_const_id(mrb, io, MRB_SYM(SEEK_END), mrb_fixnum_value(SEEK_END)); } diff --git a/mruby/mrbgems/mruby-io/test/file.rb b/mruby/mrbgems/mruby-io/test/file.rb index c1385060..5a8a8dfa 100644 --- a/mruby/mrbgems/mruby-io/test/file.rb +++ b/mruby/mrbgems/mruby-io/test/file.rb @@ -46,7 +46,7 @@ assert('File.extname') do assert_equal '.txt', File.extname('foo/foo.txt') - assert_equal '.gz', File.extname('foo/foo.tar.gz') + assert_equal '.gz', File.extname('foo/foo.tar.gz') assert_equal '', File.extname('foo/bar') assert_equal '', File.extname('foo/.bar') assert_equal '', File.extname('foo.txt/bar') diff --git a/mruby/mrbgems/mruby-io/test/io.rb b/mruby/mrbgems/mruby-io/test/io.rb index 88a89fee..024a71ac 100644 --- a/mruby/mrbgems/mruby-io/test/io.rb +++ b/mruby/mrbgems/mruby-io/test/io.rb @@ -140,9 +140,10 @@ def assert_io_open(meth) end assert "IO#read(n) with n > IO::BUF_SIZE" do + buf_size = 4096 # copied from io.c skip "pipe is not supported on this platform" if MRubyIOTestUtil.win? IO.pipe do |r,w| - n = IO::BUF_SIZE+1 + n = buf_size+1 w.write 'a'*n assert_equal 'a'*n, r.read(n) end @@ -186,8 +187,8 @@ def assert_io_open(meth) end assert('IO#write', '15.2.20.5.20') do - io = IO.open(IO.sysopen($mrbtest_io_wfname)) - assert_equal 0, io.write("") + io = IO.open(IO.sysopen($mrbtest_io_wfname, "w"), "w") + assert_equal 1, io.write("a") io.close io = IO.open(IO.sysopen($mrbtest_io_wfname, "r+"), "r+") @@ -201,9 +202,9 @@ def assert_io_open(meth) end assert('IO#<<') do - io = IO.open(IO.sysopen($mrbtest_io_wfname)) - io << "" << "" - assert_equal 0, io.pos + io = IO.open(IO.sysopen($mrbtest_io_wfname, "w"), "w") + io << "a" << "b" + assert_equal 2, io.pos io.close end @@ -303,26 +304,11 @@ def assert_io_open(meth) io.close end -assert('IO#_read_buf') do - fd = IO.sysopen $mrbtest_io_rfname - io = IO.new fd - def io._buf - @buf - end - msg_len = $mrbtest_io_msg.size - assert_equal '', io._buf - assert_equal $mrbtest_io_msg, io._read_buf - assert_equal $mrbtest_io_msg, io._buf - assert_equal 'mruby', io.read(5) - assert_equal 5, io.pos - assert_equal msg_len - 5, io._buf.size - assert_equal $mrbtest_io_msg[5,100], io.read - assert_equal 0, io._buf.size - assert_raise EOFError do - io._read_buf - end - assert_equal true, io.eof - assert_equal true, io.eof? +assert('IO#ungetc') do + io = IO.new(IO.sysopen($mrbtest_io_rfname)) + assert_equal 'm', io.getc + assert_nothing_raised{io.ungetc("M")} + assert_equal 'M', io.getc io.close end @@ -383,6 +369,7 @@ def io._buf # gets with rs io.pos = 0 assert_equal $mrbtest_io_msg[0, 6], io.gets(' '), "gets with rs" + assert_equal $mrbtest_io_msg[6, 3], io.gets(' '), "gets with rs(2)" # gets with rs, limit io.pos = 0 diff --git a/mruby/mrbgems/mruby-kernel-ext/src/kernel.c b/mruby/mrbgems/mruby-kernel-ext/src/kernel.c index 976615f6..89116f63 100644 --- a/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mruby/mrbgems/mruby-kernel-ext/src/kernel.c @@ -6,6 +6,7 @@ #include #include #include +#include #include static mrb_value @@ -78,7 +79,7 @@ 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) + if (ci->proc && ci->proc->e.env && 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); @@ -166,7 +167,7 @@ mrb_f_integer(mrb_state *mrb, mrb_value self) mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); } /* to raise TypeError */ - return mrb_to_integer(mrb, val); + return mrb_ensure_integer_type(mrb, val); } #ifndef MRB_NO_FLOAT @@ -190,7 +191,7 @@ mrb_f_float(mrb_state *mrb, mrb_value self) if (mrb_string_p(arg)) { return mrb_float_value(mrb, mrb_str_to_dbl(mrb, arg, TRUE)); } - return mrb_to_float(mrb, arg); + return mrb_ensure_float_type(mrb, arg); } #endif diff --git a/mruby/mrbgems/mruby-math/src/math.c b/mruby/mrbgems/mruby-math/src/math.c index 79fdb7c6..1f6f88e8 100644 --- a/mruby/mrbgems/mruby-math/src/math.c +++ b/mruby/mrbgems/mruby-math/src/math.c @@ -94,8 +94,7 @@ cbrt(double x) } /* Declaration of complementary Error function */ -double -erfc(double x); +double erfc(double x); /* ** Implementations of error functions @@ -117,10 +116,10 @@ erf(double x) do { term *= xsqr/j; sum -= term/(2*j+1); - ++j; + j++; term *= xsqr/j; sum += term/(2*j+1); - ++j; + j++; if (sum == 0) break; } while (fabs(term/sum) > DBL_EPSILON); return two_sqrtpi*sum; @@ -324,8 +323,6 @@ math_atan2(mrb_state *mrb, mrb_value obj) return mrb_float_value(mrb, x); } - - /* HYPERBOLIC TRIG FUNCTIONS */ diff --git a/mruby/mrbgems/mruby-metaprog/src/metaprog.c b/mruby/mrbgems/mruby-metaprog/src/metaprog.c index 4bf31cbe..67da9cd9 100644 --- a/mruby/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mruby/mrbgems/mruby-metaprog/src/metaprog.c @@ -5,6 +5,7 @@ #include "mruby/proc.h" #include "mruby/class.h" #include "mruby/string.h" +#include #include "mruby/presym.h" typedef enum { @@ -575,6 +576,39 @@ mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod) return mrb_class_instance_method_list(mrb, recur, c); } +static int +undefined_method_i(mrb_state *mrb, mrb_sym mid, mrb_method_t m, void *p) +{ + mrb_value ary = *(mrb_value*)p; + + if (MRB_METHOD_UNDEF_P(m)) { + mrb_ary_push(mrb, ary, mrb_symbol_value(mid)); + } + return 0; +} + +/* + * call-seq: + * mod.undefined_methods() -> array + * + * Returns an array containing the names of the undefined methods of the module/class. + */ +static mrb_value +mrb_mod_undefined_methods(mrb_state *mrb, mrb_value mod) +{ + struct RClass *m = mrb_class_ptr(mod); + mrb_get_args(mrb, ""); /* no argument */ + + mrb_value ary = mrb_ary_new(mrb); + + if (m->flags & MRB_FL_CLASS_IS_PREPENDED) { + MRB_CLASS_ORIGIN(m); + } + mrb_mt_foreach(mrb, m, undefined_method_i, (void*)&ary); + + return ary; +} + /* 15.2.2.4.41 */ /* * call-seq: @@ -631,9 +665,6 @@ mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod) return ary; } -/* implementation of #send method */ -mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); - void mrb_mruby_metaprog_gem_init(mrb_state* mrb) { @@ -663,6 +694,7 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb) mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */ mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */ mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */ + mrb_define_method(mrb, mod, "undefined_instance_methods", mrb_mod_undefined_methods, MRB_ARGS_NONE()); mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ mrb_define_method(mrb, mod, "method_removed", mrb_f_nil, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */ diff --git a/mruby/mrbgems/mruby-metaprog/test/metaprog.rb b/mruby/mrbgems/mruby-metaprog/test/metaprog.rb index 4d265170..d55c0555 100644 --- a/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +++ b/mruby/mrbgems/mruby-metaprog/test/metaprog.rb @@ -56,7 +56,7 @@ end ivars = o.instance_variables - assert_equal Array, ivars.class, + assert_equal Array, ivars.class assert_equal(2, ivars.size) assert_true ivars.include?(:@a) assert_true ivars.include?(:@b) @@ -272,13 +272,13 @@ module Test4includedModules2 assert('Module#instance_methods', '15.2.2.4.33') do module Test4InstanceMethodsA - def method1() end + def method1() end end class Test4InstanceMethodsB - def method2() end + def method2() end end class Test4InstanceMethodsC < Test4InstanceMethodsB - def method3() end + def method3() end end r = Test4InstanceMethodsC.instance_methods(true) diff --git a/mruby/mrbgems/mruby-method/README.md b/mruby/mrbgems/mruby-method/README.md index 41130bb8..1da2055c 100644 --- a/mruby/mrbgems/mruby-method/README.md +++ b/mruby/mrbgems/mruby-method/README.md @@ -22,38 +22,38 @@ end ## Kernel -* `Kernel#method` -* `Kernel#singleton_method` +- `Kernel#method` +- `Kernel#singleton_method` ## Module -* `Module#instance_method` +- `Module#instance_method` ## Method class -* `Method#name` -* `Method#call` -* `Method#super_method` -* `Method#arity` -* `Method#unbind` -* `Method#[]` -* `Method#owner` -* `Method#receiver` -* `Method#parameters` -* `Method#source_location` -* `Method#to_proc` +- `Method#name` +- `Method#call` +- `Method#super_method` +- `Method#arity` +- `Method#unbind` +- `Method#[]` +- `Method#owner` +- `Method#receiver` +- `Method#parameters` +- `Method#source_location` +- `Method#to_proc` ## UnboundMethod class -* `UnboundMethod#name` -* `UnboundMethod#bind` -* `UnboundMethod#super_method` -* `UnboundMethod#arity` -* `UnboundMethod#owner` -* `UnboundMethod#parameters` -* `UnboundMethod#source_location` +- `UnboundMethod#name` +- `UnboundMethod#bind` +- `UnboundMethod#super_method` +- `UnboundMethod#arity` +- `UnboundMethod#owner` +- `UnboundMethod#parameters` +- `UnboundMethod#source_location` # See also -* -* +- +- diff --git a/mruby/mrbgems/mruby-method/src/method.c b/mruby/mrbgems/mruby-method/src/method.c index 85e8872e..b2eb4ef0 100644 --- a/mruby/mrbgems/mruby-method/src/method.c +++ b/mruby/mrbgems/mruby-method/src/method.c @@ -4,11 +4,9 @@ #include "mruby/variable.h" #include "mruby/proc.h" #include "mruby/string.h" +#include "mruby/internal.h" #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); - // Defined by mruby-proc-ext on which mruby-method depends mrb_value mrb_proc_parameters(mrb_state *mrb, mrb_value proc); mrb_value mrb_proc_source_location(mrb_state *mrb, struct RProc *p); @@ -189,7 +187,7 @@ method_eql(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); mrb_value receiver, orig_proc, other_proc; - struct RClass *owner, *klass; + struct RClass *owner; struct RProc *orig_rproc, *other_rproc; if (!mrb_obj_is_instance_of(mrb, other, mrb_class(mrb, self))) @@ -198,10 +196,6 @@ method_eql(mrb_state *mrb, mrb_value self) if (mrb_class(mrb, self) != mrb_class(mrb, other)) return mrb_false_value(); - klass = mrb_class_ptr(IV_GET(self, MRB_SYM(_klass))); - if (klass != mrb_class_ptr(IV_GET(other, MRB_SYM(_klass)))) - return mrb_false_value(); - owner = mrb_class_ptr(IV_GET(self, MRB_SYM(_owner))); if (owner != mrb_class_ptr(IV_GET(other, MRB_SYM(_owner)))) return mrb_false_value(); @@ -219,10 +213,8 @@ method_eql(mrb_state *mrb, mrb_value self) return mrb_false_value(); } - if (mrb_nil_p(orig_proc)) - return mrb_false_value(); - if (mrb_nil_p(other_proc)) - return mrb_false_value(); + if (mrb_nil_p(orig_proc)) return mrb_false_value(); + if (mrb_nil_p(other_proc)) return mrb_false_value(); orig_rproc = mrb_proc_ptr(orig_proc); other_rproc = mrb_proc_ptr(other_proc); @@ -327,25 +319,25 @@ method_super_method(mrb_state *mrb, mrb_value self) struct RProc *proc; struct RObject *me; - switch (mrb_type(klass)) { - case MRB_TT_SCLASS: - super = mrb_class_ptr(klass)->super->super; - break; - case MRB_TT_ICLASS: - super = mrb_class_ptr(klass)->super; - break; - default: - super = mrb_class_ptr(owner)->super; - break; + if (mrb_type(owner) == MRB_TT_MODULE) { + struct RClass *m = mrb_class_ptr(owner); + rklass = mrb_class_ptr(klass)->super; + while (rklass && rklass->c != m) { + rklass = rklass->super; + } + if (!rklass) return mrb_nil_value(); + super = rklass->super; + } + else { + super = mrb_class_ptr(owner)->super; } proc = method_search_vm(mrb, &super, mrb_symbol(name)); - if (!proc) - return mrb_nil_value(); + if (!proc) return mrb_nil_value(); rklass = super; - while (super->tt == MRB_TT_ICLASS) - super = super->c; + super = mrb_class_real(super); + if (!super) return mrb_nil_value(); me = method_object_alloc(mrb, mrb_obj_class(mrb, self)); mrb_obj_iv_set(mrb, me, MRB_SYM(_owner), mrb_obj_value(super)); @@ -401,6 +393,16 @@ method_to_s(mrb_state *mrb, mrb_value self) mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, self)); mrb_str_cat_lit(mrb, str, ": "); + if (mrb_type(owner) == MRB_TT_SCLASS) { + mrb_value recv = mrb_iv_get(mrb, self, MRB_SYM(_recv)); + if (!mrb_nil_p(recv)) { + mrb_str_concat(mrb, str, recv); + mrb_str_cat_lit(mrb, str, "."); + mrb_str_concat(mrb, str, name); + goto finish; + } + } + rklass = mrb_class_ptr(klass); if (mrb_class_ptr(owner) == rklass) { mrb_str_concat(mrb, str, owner); @@ -408,12 +410,21 @@ method_to_s(mrb_state *mrb, mrb_value self) mrb_str_concat(mrb, str, name); } else { - mrb_str_cat_cstr(mrb, str, mrb_class_name(mrb, rklass)); + rklass = mrb_class_real(rklass); /* skip internal class */ + mrb_str_concat(mrb, str, mrb_obj_value(rklass)); mrb_str_cat_lit(mrb, str, "("); mrb_str_concat(mrb, str, owner); mrb_str_cat_lit(mrb, str, ")#"); mrb_str_concat(mrb, str, name); } + finish:; + mrb_value loc = method_source_location(mrb, self); + if (mrb_array_p(loc) && RARRAY_LEN(loc) == 2) { + mrb_str_cat_lit(mrb, str, " "); + mrb_str_concat(mrb, str, RARRAY_PTR(loc)[0]); + mrb_str_cat_lit(mrb, str, ":"); + mrb_str_concat(mrb, str, RARRAY_PTR(loc)[1]); + } mrb_str_cat_lit(mrb, str, ">"); return str; } diff --git a/mruby/mrbgems/mruby-method/test/method.rb b/mruby/mrbgems/mruby-method/test/method.rb index 9089c96d..8966ee08 100644 --- a/mruby/mrbgems/mruby-method/test/method.rb +++ b/mruby/mrbgems/mruby-method/test/method.rb @@ -230,14 +230,14 @@ def o.baz(x, y, z, *w, u:, v:, **opts, &blk) o = Object.new def o.foo; end m = o.method(:foo) - assert_equal("#", m.unbind.inspect) + assert_match("#", m.unbind.inspect) c = Class.new c.class_eval { def foo; end; } m = c.new.method(:foo) - assert_equal("#", m.inspect) + assert_match("#", m.inspect) m = c.instance_method(:foo) - assert_equal("#", m.inspect) + assert_match("#", m.inspect) end assert 'owner' do diff --git a/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb b/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb index 576605cb..ee205b85 100644 --- a/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb +++ b/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb @@ -1,8 +1,24 @@ class Numeric + ## + # call-seq: + # zero? -> true or false + # + # Returns +true+ if +zero+ has a zero value, +false+ otherwise. + # + # Of the Core and Standard Library classes, + # only Rational and Complex use this implementation. + # def zero? self == 0 end + ## + # call-seq: + # nonzero? -> self or nil + # + # Returns +self+ if +self+ is not a zero value, +nil+ otherwise; + # uses method zero? for the evaluation. + # def nonzero? if self == 0 nil @@ -11,11 +27,73 @@ def nonzero? end end + ## + # call-seq: + # positive? -> true or false + # + # Returns +true+ if +self+ is greater than 0, +false+ otherwise. + # def positive? self > 0 end + ## + # call-seq: + # negative? -> true or false + # + # Returns +true+ if +self+ is less than 0, +false+ otherwise. + # def negative? self < 0 end + + ## + # call-seq: + # int.allbits?(mask) -> true or false + # + # Returns +true+ if all bits of +int+ & +mask+ are 1. + # + def allbits?(mask) + (self & mask) == mask + end + + ## + # call-seq: + # int.anybits?(mask) -> true or false + # + # Returns +true+ if any bits of +int+ & +mask+ are 1. + # + def anybits?(mask) + (self & mask) != 0 + end + + ## + # call-seq: + # int.nobits?(mask) -> true or false + # + # Returns +true+ if no bits of +int+ & +mask+ are 1. + # + def nobits?(mask) + (self & mask) == 0 + end +end + +class Integer + # call-seq: + # ceildiv(other) -> integer + # + # Returns the result of division +self+ by +other+. The + # result is rounded up to the nearest integer. + # + # 3.ceildiv(3) # => 1 + # 4.ceildiv(3) # => 2 + # + # 4.ceildiv(-3) # => -1 + # -4.ceildiv(3) # => -1 + # -4.ceildiv(-3) # => 2 + # + # 3.ceildiv(1.2) # => 3 + def ceildiv(other) + -div(-other) + end end diff --git a/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 2f2a6c75..5fa4e5fb 100644 --- a/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -1,91 +1,197 @@ #include #include +#include +#include #include -/* - * call-seq: - * int.allbits?(mask) -> true or false - * - * Returns +true+ if all bits of +int+ & +mask+ are 1. - */ -static mrb_value -int_allbits(mrb_state *mrb, mrb_value self) -{ - mrb_int n, m; - - mrb_get_args(mrb, "i", &m); - n = mrb_integer(self); - return mrb_bool_value((n & m) == m); -} +#ifndef MRB_NO_FLOAT +static mrb_value flo_remainder(mrb_state *mrb, mrb_value self); +#endif /* * call-seq: - * int.anybits?(mask) -> true or false + * num.remainder(numeric) -> real * - * Returns +true+ if any bits of +int+ & +mask+ are 1. + * x.remainder(y) means x-y*(x/y).truncate. + * + * See Numeric#divmod. */ static mrb_value -int_anybits(mrb_state *mrb, mrb_value self) +int_remainder(mrb_state *mrb, mrb_value x) { - mrb_int n, m; + mrb_value y = mrb_get_arg1(mrb); + mrb_int a, b; - mrb_get_args(mrb, "i", &m); - n = mrb_integer(self); - return mrb_bool_value((n & m) != 0); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + if (mrb_integer_p(y) || mrb_bigint_p(y)) { + return mrb_bint_rem(mrb, x, y); + } + return flo_remainder(mrb, mrb_float_value(mrb, mrb_as_float(mrb, x))); + } +#endif + a = mrb_integer(x); + if (mrb_integer_p(y)) { + b = mrb_integer(y); + if (b == 0) mrb_int_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 + return flo_remainder(mrb, mrb_float_value(mrb, mrb_as_float(mrb, x))); +#endif } +mrb_value mrb_int_pow(mrb_state *mrb, mrb_value x, mrb_value y); + /* - * call-seq: - * int.nobits?(mask) -> true or false + * call-seq: + * integer.pow(numeric) -> numeric + * integer.pow(integer, integer) -> integer + * + * Returns (modular) exponentiation as: * - * Returns +true+ if no bits of +int+ & +mask+ are 1. + * a.pow(b) #=> same as a**b + * a.pow(b, m) #=> same as (a**b) % m, but avoids huge temporary values */ static mrb_value -int_nobits(mrb_state *mrb, mrb_value self) +int_powm(mrb_state *mrb, mrb_value x) { - mrb_int n, m; + mrb_value m; + mrb_int e, exp, mod, result = 1; - mrb_get_args(mrb, "i", &m); - 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"); + if (mrb_get_argc(mrb) == 1) { + return mrb_int_pow(mrb, x, mrb_get_arg1(mrb)); + } + mrb_get_args(mrb, "io", &e, &m); + if (e < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_powm(mrb, x, e, m); + } + if (mrb_bigint_p(m)) { + return mrb_bint_powm(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), e, m); + } +#endif + if (!mrb_integer_p(m)) mrb_raise(mrb, E_TYPE_ERROR, "int.pow(n,m): m must be integer"); + mod = mrb_integer(m); + if (mod < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): m must be positive when 2nd argument specified"); + if (mod == 0) mrb_int_zerodiv(mrb); + if (mod == 1) return mrb_fixnum_value(0); + mrb_int base = mrb_integer(x); + exp = e; + for (;;) { + mrb_int tmp; + if (exp & 1) { + if (mrb_int_mul_overflow(result, base, &tmp)) { + result %= mod; base %= mod; + if (mrb_int_mul_overflow(result, base, &tmp)) { +#ifdef MRB_USE_BIGINT + return mrb_bint_powm(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), e, m); +#else + mrb_int_overflow(mrb, "pow"); +#endif + } + } + result = tmp % mod; + } + exp >>= 1; + if (exp == 0) break; + if (mrb_int_mul_overflow(base, base, &tmp)) { + base %= mod; + if (mrb_int_mul_overflow(base, base, &tmp)) { +#ifdef MRB_USE_BIGINT + return mrb_bint_powm(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), e, m); +#else + mrb_int_overflow(mrb, "pow"); +#endif + } + } + base = tmp % mod; + } + return mrb_int_value(mrb, result); } /* * call-seq: - * num.remainder(numeric) -> real + * digits(base = 10) -> array_of_integers * - * x.remainder(y) means x-y*(x/y).truncate. + * Returns an array of integers representing the +base+-radix + * digits of +self+; + * the first element of the array represents the least significant digit: + * + * 12345.digits # => [5, 4, 3, 2, 1] + * 12345.digits(7) # => [4, 6, 6, 0, 5] + * 12345.digits(100) # => [45, 23, 1] + * + * Raises an exception if +self+ is negative or +base+ is less than 2. * - * See Numeric#divmod. */ + static mrb_value -int_remainder(mrb_state *mrb, mrb_value x) +int_digits(mrb_state *mrb, mrb_value self) { - mrb_value y = mrb_get_arg1(mrb); - mrb_int a, b; + mrb_int base = 10; - 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); + mrb_get_args(mrb, "|i", &base); + if (base < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative radix"); + } + else if (base < 2) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); + } +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + mrb_value x = self; + mrb_value zero = mrb_fixnum_value(0); + mrb_value bv = mrb_int_value(mrb, base); + if (mrb_bint_cmp(mrb, x, zero) < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "number should be positive"); + } + mrb_value digits = mrb_ary_new(mrb); + + while (mrb_bint_cmp(mrb, x, zero) == 0) { + mrb_ary_push(mrb, digits, zero); + return digits; + } + + while (mrb_bint_cmp(mrb, x, zero) > 0) { + mrb_value q = mrb_bint_mod(mrb, x, bv); + mrb_ary_push(mrb, digits, q); + x = mrb_bint_div(mrb, x, bv); + if (!mrb_bigint_p(x)) { + mrb_int n = mrb_integer(x); + while (n > 0) { + mrb_int q = n % base; + mrb_ary_push(mrb, digits, mrb_int_value(mrb, q)); + n /= base; + } + break; + } + } + return digits; } -#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 + mrb_int n = mrb_integer(self); + if (n < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "number should be positive"); + } + + mrb_value digits = mrb_ary_new(mrb); + + if (n == 0) { + mrb_ary_push(mrb, digits, mrb_fixnum_value(0)); + return digits; + } + + while (n > 0) { + mrb_int q = n % base; + mrb_ary_push(mrb, digits, mrb_int_value(mrb, q)); + n /= base; + } + return digits; } #ifndef MRB_NO_FLOAT @@ -96,7 +202,7 @@ flo_remainder(mrb_state *mrb, mrb_value self) a = mrb_float(self); mrb_get_args(mrb, "f", &b); - if (b == 0) zerodiv(mrb); + if (b == 0) mrb_int_zerodiv(mrb); if (isinf(b)) return mrb_float_value(mrb, a); return mrb_float_value(mrb, a-b*trunc(a/b)); } @@ -105,17 +211,16 @@ flo_remainder(mrb_state *mrb, mrb_value self) void mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) { - struct RClass *i = mrb_class_get(mrb, "Integer"); - - 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)); + struct RClass *i = mrb->integer_class; mrb_define_alias(mrb, i, "modulo", "%"); mrb_define_method(mrb, i, "remainder", int_remainder, MRB_ARGS_REQ(1)); + mrb_define_method_id(mrb, i, MRB_SYM(pow), int_powm, MRB_ARGS_ARG(1,1)); + mrb_define_method_id(mrb, i, MRB_SYM(digits), int_digits, MRB_ARGS_OPT(1)); + #ifndef MRB_NO_FLOAT - struct RClass *f = mrb_class_get(mrb, "Float"); + struct RClass *f = mrb->float_class; mrb_define_alias(mrb, f, "modulo", "%"); mrb_define_method(mrb, f, "remainder", flo_remainder, MRB_ARGS_REQ(1)); diff --git a/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb b/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb index efdf25a3..0da071f2 100644 --- a/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +++ b/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb @@ -19,3 +19,33 @@ assert_equal nil, 0.nonzero? assert_equal 1000, 1000.nonzero? end + +assert('Integer#pow') do + assert_equal(8, 2.pow(3)) + assert_equal(-8, (-2).pow(3)) + assert_equal(361, 9.pow(1024,1000)) +end + +assert('Integer#ceildiv') do + assert_equal(0, 0.ceildiv(3)) + assert_equal(1, 1.ceildiv(3)) + assert_equal(1, 3.ceildiv(3)) + assert_equal(2, 4.ceildiv(3)) + + assert_equal(-1, 4.ceildiv(-3)) + assert_equal(-1, -4.ceildiv(3)) + assert_equal(2, -4.ceildiv(-3)) + + if Object.const_defined?(:Float) + assert_equal(3, 3.ceildiv(1.2)) + end + if Object.const_defined?(:Rational) + assert_equal(3, 3.ceildiv(6/5r)) + end + +# assert_equal(10, (10**100-11).ceildiv(10**99-1)) +# assert_equal(11, (10**100-9).ceildiv(10**99-1)) + assert_equal(8, 2.pow(3)) + assert_equal(-8, (-2).pow(3)) +# assert_equal(361, 9.pow(1024,1000)) +end diff --git a/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c index 929a6180..4c770811 100644 --- a/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -78,7 +78,7 @@ os_count_objects(mrb_state *mrb, mrb_value self) for (i = MRB_TT_FALSE; i < MRB_TT_MAXDEFINE; i++) { mrb_value type; switch (i) { -#define COUNT_TYPE(t) case (MRB_T ## t): type = mrb_symbol_value(mrb_intern_lit(mrb, #t)); break; +#define COUNT_TYPE(t) case (MRB_T ## t): type = mrb_symbol_value(MRB_SYM(t)); break; COUNT_TYPE(T_INTEGER); COUNT_TYPE(T_FLOAT); COUNT_TYPE(T_CPTR); @@ -96,9 +96,12 @@ os_count_objects(mrb_state *mrb, mrb_value self) COUNT_TYPE(T_ENV); COUNT_TYPE(T_DATA); COUNT_TYPE(T_FIBER); + COUNT_TYPE(T_STRUCT); COUNT_TYPE(T_ISTRUCT); + COUNT_TYPE(T_BREAK); COUNT_TYPE(T_COMPLEX); COUNT_TYPE(T_RATIONAL); + COUNT_TYPE(T_BIGINT); #undef COUNT_TYPE default: type = mrb_fixnum_value(i); break; diff --git a/mruby/mrbgems/mruby-os-memsize/mrbgem.rake b/mruby/mrbgems/mruby-os-memsize/mrbgem.rake index b5c163bb..8bd04d95 100644 --- a/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +++ b/mruby/mrbgems/mruby-os-memsize/mrbgem.rake @@ -3,8 +3,8 @@ MRuby::Gem::Specification.new('mruby-os-memsize') do |spec| spec.author = 'mruby developers' spec.summary = 'ObjectSpace memsize_of method' - spec.add_dependency('mruby-objectspace') - spec.add_test_dependency('mruby-metaprog') - spec.add_test_dependency('mruby-method') - spec.add_test_dependency('mruby-fiber') + spec.add_dependency('mruby-objectspace', :core => 'mruby-objectspace') + spec.add_test_dependency('mruby-metaprog', :core => 'mruby-metaprog') + spec.add_test_dependency('mruby-method', :core => 'mruby-method') + spec.add_test_dependency('mruby-fiber', :core => 'mruby-fiber') end diff --git a/mruby/mrbgems/mruby-os-memsize/src/memsize.c b/mruby/mrbgems/mruby-os-memsize/src/memsize.c index b6a25a20..b95515cc 100644 --- a/mruby/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mruby/mrbgems/mruby-os-memsize/src/memsize.c @@ -10,6 +10,7 @@ #include #include #include +#include static size_t os_memsize_of_irep(mrb_state* state, const struct mrb_irep *irep) @@ -127,24 +128,29 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) case MRB_TT_INTEGER: if (mrb_immediate_p(obj)) break; - case MRB_TT_RATIONAL: + case MRB_TT_RATIONAL: #if defined(MRB_USE_RATIONAL) #if defined(MRB_INT64) && defined(MRB_32BIT) - size += sizeof(mrb_int)*2; + size += sizeof(mrb_int)*2; #endif - size += mrb_objspace_page_slot_size(); + size += mrb_objspace_page_slot_size(); #endif - break; + break; - case MRB_TT_COMPLEX: + case MRB_TT_COMPLEX: #if defined(MRB_USE_COMPLEX) #if defined(MRB_32BIT) && !defined(MRB_USE_FLOAT32) - size += sizeof(mrb_float)*2; + size += sizeof(mrb_float)*2; +#endif + size += mrb_objspace_page_slot_size(); #endif - size += mrb_objspace_page_slot_size(); + break; + case MRB_TT_BIGINT: +#if defined(MRB_USE_BIGINT) + size += mrb_bint_memsize(obj); + /* fall through */ #endif - break; - case MRB_TT_DATA: + case MRB_TT_CDATA: case MRB_TT_ISTRUCT: size += mrb_objspace_page_slot_size(); break; diff --git a/mruby/mrbgems/mruby-pack/mrbgem.rake b/mruby/mrbgems/mruby-pack/mrbgem.rake index f1c0306b..97da0c88 100644 --- a/mruby/mrbgems/mruby-pack/mrbgem.rake +++ b/mruby/mrbgems/mruby-pack/mrbgem.rake @@ -2,6 +2,4 @@ MRuby::Gem::Specification.new('mruby-pack') do |spec| spec.license = 'MIT' spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers'] spec.summary = 'Array#pack and String#unpack method' - - spec.cc.include_paths << "#{build.root}/src" end diff --git a/mruby/mrbgems/mruby-pack/src/pack.c b/mruby/mrbgems/mruby-pack/src/pack.c index 1edaac93..b5ecdc64 100644 --- a/mruby/mrbgems/mruby-pack/src/pack.c +++ b/mruby/mrbgems/mruby-pack/src/pack.c @@ -12,7 +12,6 @@ #include "mruby/endian.h" #include -#include #include #define INT_OVERFLOW_P(n) ((n) < MRB_INT_MIN || (n) > MRB_INT_MAX) @@ -72,9 +71,17 @@ enum pack_type { const static unsigned char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static unsigned char base64_dec_tab[128]; +const static unsigned char base64_dec_tab[] = + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3e\xff\xff\xff\x3f" + "\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\xff\xff\xff\xfe\xff\xff" + "\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e" + "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\xff\xff\xff\xff\xff" + "\xff\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28" + "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\xff\xff\xff\xff\xff"; -static unsigned int +static int hex2int(unsigned char ch) { if (ch >= '0' && ch <= '9') @@ -87,22 +94,6 @@ hex2int(unsigned char ch) return -1; } -static void -make_base64_dec_tab(void) -{ - int i; - memset(base64_dec_tab, PACK_BASE64_IGNORE, sizeof(base64_dec_tab)); - for (i = 0; i < 26; i++) - base64_dec_tab['A' + i] = i; - for (i = 0; i < 26; i++) - base64_dec_tab['a' + i] = i + 26; - for (i = 0; i < 10; i++) - base64_dec_tab['0' + i] = i + 52; - base64_dec_tab['+'+0] = 62; - base64_dec_tab['/'+0] = 63; - base64_dec_tab['='+0] = PACK_BASE64_PADDING; -} - static mrb_value str_len_ensure(mrb_state *mrb, mrb_value str, mrb_int len) { @@ -205,18 +196,18 @@ u32tostr(char *buf, size_t len, uint32_t n) return; } - *p -- = '\0'; - len --; + *p-- = '\0'; + len--; if (n > 0) { for (; len > 0 && n > 0; len --, n /= 10) { *p -- = '0' + (n % 10); } - p ++; + p++; } else if (len > 0) { *p = '0'; - len --; + len--; } memmove(buf, p, bufend - p); @@ -301,18 +292,18 @@ u64tostr(char *buf, size_t len, uint64_t n) return; } - *p -- = '\0'; - len --; + *p-- = '\0'; + len--; if (n > 0) { - for (; len > 0 && n > 0; len --, n /= 10) { - *p -- = '0' + (n % 10); + for (; len > 0 && n > 0; len--, n /= 10) { + *p-- = '0' + (n % 10); } - p ++; + p++; } else if (len > 0) { *p = '0'; - len --; + len--; } memmove(buf, p, bufend - p); @@ -331,8 +322,8 @@ i64tostr(char *buf, size_t len, int64_t n) } if (n < 0) { - *buf ++ = '-'; - len --; + *buf++ = '-'; + len--; n = -n; } @@ -387,13 +378,13 @@ 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; + int i; char *p; if (n < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "can't compress negative numbers"); } - for (i=1; i (MRB_INT_MAX>>7)) { mrb_raise(mrb, E_RANGE_ERROR, "BER unpacking 'w' overflow"); @@ -441,13 +434,13 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i memcpy(RSTRING_PTR(str) + sidx, buffer, 8); } else { - for (i = 0; i < 8; ++i) { + for (i = 0; i < 8; i++) { RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; } } } else { if (littleendian) { - for (i = 0; i < 8; ++i) { + for (i = 0; i < 8; i++) { RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; } } @@ -471,13 +464,13 @@ unpack_double(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value a memcpy(buffer, src, 8); } else { - for (i = 0; i < 8; ++i) { + for (i = 0; i < 8; i++) { buffer[8 - i - 1] = src[i]; } } } else { if (littleendian) { - for (i = 0; i < 8; ++i) { + for (i = 0; i < 8; i++) { buffer[8 - i - 1] = src[i]; } } @@ -504,13 +497,13 @@ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in memcpy(RSTRING_PTR(str) + sidx, buffer, 4); } else { - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; } } } else { if (littleendian) { - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; } } @@ -534,13 +527,13 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar memcpy(buffer, src, 4); } else { - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { buffer[4 - i - 1] = src[i]; } } } else { if (littleendian) { - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { buffer[4 - i - 1] = src[i]; } } @@ -620,6 +613,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp) } if (!(uv & 0x40)) { *lenp = 1; + malformed: mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character"); } @@ -630,7 +624,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp) else if (!(uv & 0x02)) { n = 6; uv &= 0x01; } else { *lenp = 1; - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character"); + goto malformed; } if (n > *lenp) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %d bytes, given %d bytes)", @@ -642,7 +636,7 @@ utf8_to_uv(mrb_state *mrb, const char *p, long *lenp) c = *p++ & 0xff; if ((c & 0xc0) != 0x80) { *lenp -= n + 1; - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character"); + goto malformed; } else { c &= 0x3f; @@ -709,9 +703,18 @@ pack_str(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, return (int)(dptr - dptr0); } +#define CHECK_UNPACK_LEN(mrb, slen, ary) do {\ + if ((slen) <= 0) {\ + mrb_ary_push(mrb, ary, mrb_str_new(mrb, 0, 0));\ + return 0;\ + }\ +} while (0) + static int unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) { + CHECK_UNPACK_LEN(mrb, slen, ary); + mrb_value dst; const char *cp, *sptr; int copylen; @@ -746,7 +749,8 @@ unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, static int 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; + int a, b; + unsigned int ashift, bshift; long slen; char *dptr, *dptr0, *sptr; @@ -792,6 +796,8 @@ pack_hex(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, static int unpack_hex(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) { + CHECK_UNPACK_LEN(mrb, slen, ary); + mrb_value dst; int a, ashift, b, bshift; const char *sptr, *sptr0; @@ -905,6 +911,8 @@ pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int coun static int unpack_base64(mrb_state *mrb, const void *src, int slen, mrb_value ary) { + CHECK_UNPACK_LEN(mrb, slen, ary); + mrb_value dst; int dlen; unsigned long l; @@ -1022,6 +1030,8 @@ pack_qenc(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count) static int unpack_qenc(mrb_state *mrb, const void *src, int slen, mrb_value ary) { + CHECK_UNPACK_LEN(mrb, slen, ary); + mrb_value buf = mrb_str_new(mrb, 0, slen); const char *s = (const char*)src, *ss = s; const char *send = s + slen; @@ -1295,12 +1305,12 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type ch = tptr[tmpl->idx]; if (ISDIGIT(ch)) { char *e; - mrb_int n = mrb_int_read(tptr+tmpl->idx, tptr+tlen, &e); - if (e == NULL || n > INT_MAX) { + mrb_int n; + if (!mrb_read_int(tptr+tmpl->idx, tptr+tlen, &e, &n) || INT_MAX < n) { mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length"); } count = (int)n; - tmpl->idx = e - tptr; + tmpl->idx = (int)(e - tptr); continue; } else if (ch == '*') { if (type == PACK_TYPE_NONE) @@ -1387,13 +1397,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_integer(mrb, o); + o = mrb_ensure_int_type(mrb, o); } #ifndef MRB_NO_FLOAT else if (type == PACK_TYPE_FLOAT) { if (!mrb_float_p(o)) { - mrb_float f = mrb_as_float(mrb, o); - o = mrb_float_value(mrb, f); + o = mrb_ensure_float_type(mrb, o); } } #endif @@ -1516,7 +1525,6 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) 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; @@ -1524,7 +1532,7 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) break; } - while (count != 0) { + while (count != 0 && srcidx < srclen) { if (srclen - srcidx < size) { while (count-- > 0) { mrb_ary_push(mrb, result, mrb_nil_value()); @@ -1567,14 +1575,12 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) count--; } } - if (single) break; - } - - if (single) { - if (RARRAY_LEN(result) > 0) { - return RARRAY_PTR(result)[0]; + if (single) { + if (RARRAY_LEN(result) > 0) { + return RARRAY_PTR(result)[0]; + } + return mrb_nil_value(); } - return mrb_nil_value(); } return result; } @@ -1594,8 +1600,6 @@ mrb_pack_unpack1(mrb_state *mrb, mrb_value str) void mrb_mruby_pack_gem_init(mrb_state *mrb) { - make_base64_dec_tab(); - mrb_define_method(mrb, mrb->array_class, "pack", mrb_pack_pack, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->string_class, "unpack", mrb_pack_unpack, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->string_class, "unpack1", mrb_pack_unpack1, MRB_ARGS_REQ(1)); diff --git a/mruby/mrbgems/mruby-pack/test/pack.rb b/mruby/mrbgems/mruby-pack/test/pack.rb index 16db6607..4dd7f4a9 100644 --- a/mruby/mrbgems/mruby-pack/test/pack.rb +++ b/mruby/mrbgems/mruby-pack/test/pack.rb @@ -1,4 +1,3 @@ -# coding: utf-8 PACK_IS_LITTLE_ENDIAN = "\x01\00".unpack('S')[0] == 0x01 def assert_pack tmpl, packed, unpacked diff --git a/mruby/mrbgems/mruby-print/mrblib/print.rb b/mruby/mrbgems/mruby-print/mrblib/print.rb index 96ee71fe..a8a23ea9 100644 --- a/mruby/mrbgems/mruby-print/mrblib/print.rb +++ b/mruby/mrbgems/mruby-print/mrblib/print.rb @@ -47,11 +47,9 @@ def puts(*args) i += 1 end __printstr__ "\n" if len == 0 - nil end def printf(*args) __printstr__(sprintf(*args)) - nil end end diff --git a/mruby/mrbgems/mruby-print/src/print.c b/mruby/mrbgems/mruby-print/src/print.c index 789808de..f6d6d46f 100644 --- a/mruby/mrbgems/mruby-print/src/print.c +++ b/mruby/mrbgems/mruby-print/src/print.c @@ -15,43 +15,41 @@ #endif #endif -static void -printstr(mrb_state *mrb, const char *p, mrb_int len) -{ -#if defined(_WIN32) - if (isatty(fileno(stdout))) { - DWORD written; - int wlen = MultiByteToWideChar(CP_UTF8, 0, p, (int)len, NULL, 0); - wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t)); - if (MultiByteToWideChar(CP_UTF8, 0, p, (int)len, utf16, wlen) > 0) { - utf16[wlen] = 0; - WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), - utf16, (DWORD)wlen, &written, NULL); - } - mrb_free(mrb, utf16); - } else -#endif - fwrite(p, (size_t)len, 1, stdout); - fflush(stdout); -} - static mrb_value mrb_printstr(mrb_state *mrb, mrb_value self) { mrb_value s = mrb_get_arg1(mrb); if (mrb_string_p(s)) { - printstr(mrb, RSTRING_PTR(s), RSTRING_LEN(s)); + const char *p = RSTRING_PTR(s); + mrb_int len = RSTRING_LEN(s); + +#if defined(_WIN32) + if (isatty(fileno(stdout))) { + DWORD written; + int wlen = MultiByteToWideChar(CP_UTF8, 0, p, (int)len, NULL, 0); + wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t)); + if (MultiByteToWideChar(CP_UTF8, 0, p, (int)len, utf16, wlen) > 0) { + utf16[wlen] = 0; + WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), + utf16, (DWORD)wlen, &written, NULL); + } + mrb_free(mrb, utf16); + } + else +#endif + { + fwrite(p, (size_t)len, 1, stdout); + } + fflush(stdout); } - return s; + return mrb_nil_value(); } void mrb_mruby_print_gem_init(mrb_state* mrb) { - struct RClass *krn; - krn = mrb->kernel_module; - mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1)); } void diff --git a/mruby/mrbgems/mruby-proc-binding/mrbgem.rake b/mruby/mrbgems/mruby-proc-binding/mrbgem.rake index 425aac84..4aa88297 100644 --- a/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +++ b/mruby/mrbgems/mruby-proc-binding/mrbgem.rake @@ -4,6 +4,7 @@ MRuby::Gem::Specification.new('mruby-proc-binding') do |spec| spec.summary = 'Proc#binding method' spec.add_dependency('mruby-binding-core', :core => 'mruby-binding-core') + spec.add_dependency('mruby-proc-ext', :core => 'mruby-proc-ext') spec.add_test_dependency('mruby-binding', :core => 'mruby-binding') spec.add_test_dependency('mruby-compiler', :core => 'mruby-compiler') end diff --git a/mruby/mrbgems/mruby-proc-ext/src/proc.c b/mruby/mrbgems/mruby-proc-ext/src/proc.c index ac89db19..4e90371c 100644 --- a/mruby/mrbgems/mruby-proc-ext/src/proc.c +++ b/mruby/mrbgems/mruby-proc-ext/src/proc.c @@ -49,7 +49,7 @@ mrb_proc_inspect(mrb_state *mrb, mrb_value self) const mrb_irep *irep = p->body.irep; const char *filename; int32_t line; - mrb_str_cat_lit(mrb, str, "@"); + mrb_str_cat_lit(mrb, str, " "); filename = mrb_debug_get_filename(mrb, irep, 0); mrb_str_cat_cstr(mrb, str, filename ? filename : "-"); @@ -99,13 +99,13 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self) mrb_sym name; int size; } *p, parameters_list [] = { - {MRB_SYM(req), 0}, - {MRB_SYM(opt), 0}, - {MRB_SYM(rest), 0}, - {MRB_SYM(req), 0}, - {MRB_SYM(keyrest), 0}, - {MRB_SYM(block), 0}, - {MRB_SYM(key), 0}, + {MRB_SYM(req), 0}, + {MRB_SYM(opt), 0}, + {MRB_SYM(rest), 0}, + {MRB_SYM(req), 0}, + {MRB_SYM(keyrest),0}, + {MRB_SYM(block), 0}, + {MRB_SYM(key), 0}, {0, 0} }; const struct RProc *proc = mrb_proc_ptr(self); @@ -115,20 +115,14 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self) mrb_value krest = mrb_nil_value(); mrb_value block = mrb_nil_value(); int i, j; - int max = -1; + int max = 0; if (MRB_PROC_CFUNC_P(proc)) { // TODO cfunc aspec is not implemented yet return mrb_ary_new(mrb); } irep = proc->body.irep; - if (!irep) { - return mrb_ary_new(mrb); - } - if (!irep->lv) { - return mrb_ary_new(mrb); - } - if (*irep->iseq != OP_ENTER) { + if (!irep || !irep->lv || *irep->iseq != OP_ENTER) { return mrb_ary_new(mrb); } @@ -146,9 +140,11 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self) parameters_list[5].size = MRB_ASPEC_BLOCK(aspec); parameters_list[6].size = MRB_ASPEC_KEY(aspec); - parameters = mrb_ary_new_capa(mrb, irep->nlocals-1); + for (i = 0; parameters_list[i].name; i++) { + max += parameters_list[i].size; + } + parameters = mrb_ary_new_capa(mrb, max); - max = irep->nlocals-1; for (i = 0, p = parameters_list; p->name; p++) { mrb_value sname = mrb_symbol_value(p->name); @@ -158,15 +154,7 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self) a = mrb_ary_new(mrb); mrb_ary_push(mrb, a, sname); if (i < max && irep->lv[i]) { - mrb_sym sym = irep->lv[i]; - const char *name = mrb_sym_name(mrb, sym); - switch (name[0]) { - case '*': case '&': - break; - default: - mrb_ary_push(mrb, a, mrb_symbol_value(sym)); - break; - } + mrb_ary_push(mrb, a, mrb_symbol_value(irep->lv[i])); } if (p->name == MRB_SYM(block)) { block = a; continue; @@ -176,6 +164,8 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self) } mrb_ary_push(mrb, parameters, a); } + /* need to skip empty block slot */ + if (p->size == 0 && p->name == MRB_SYM(block)) i++; } if (!mrb_nil_p(krest)) mrb_ary_push(mrb, parameters, krest); if (!mrb_nil_p(block)) mrb_ary_push(mrb, parameters, block); diff --git a/mruby/mrbgems/mruby-proc-ext/test/proc.rb b/mruby/mrbgems/mruby-proc-ext/test/proc.rb index 06365b7d..7ac50840 100644 --- a/mruby/mrbgems/mruby-proc-ext/test/proc.rb +++ b/mruby/mrbgems/mruby-proc-ext/test/proc.rb @@ -30,7 +30,7 @@ def enable_debug_info? else file = line = "-" end - assert_match "#", ins + assert_match "#", ins end assert('Proc#parameters') do @@ -78,7 +78,7 @@ def enable_debug_info? assert_equal([[:req, :a]], lambda {|a|}.parameters) assert_equal([[:opt, :a]], lambda {|a=nil|}.parameters) assert_equal([[:req, :a]], ->(a){}.parameters) - assert_equal([[:rest]], lambda { |*| }.parameters) + assert_equal([[:rest, :*]], lambda { |*| }.parameters) assert_equal([[:rest, :a]], Proc.new {|*a|}.parameters) assert_equal([[:opt, :a], [:opt, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:opt, :f], [:opt, :g], [:block, :h]], Proc.new {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) assert_equal([[:req, :a], [:req, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:req, :f], [:req, :g], [:block, :h]], lambda {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters) diff --git a/mruby/mrbgems/mruby-random/src/random.c b/mruby/mrbgems/mruby-random/src/random.c index ae917d33..d16ef332 100644 --- a/mruby/mrbgems/mruby-random/src/random.c +++ b/mruby/mrbgems/mruby-random/src/random.c @@ -137,7 +137,7 @@ random_rand(mrb_state *mrb, rand_state *t, mrb_int max) } static mrb_int -random_rand_i(mrb_state *mrb, rand_state *t, mrb_int max) +rand_i(rand_state *t, mrb_int max) { return rand_uint32(t) % max; } @@ -155,12 +155,15 @@ get_opt(mrb_state* mrb) return arg; } +#define ID_RANDOM MRB_SYM(mruby_Random) + static mrb_value -random_default(mrb_state *mrb) { - struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); - mrb_value d = mrb_const_get(mrb, mrb_obj_value(c), MRB_SYM(DEFAULT)); +random_default(mrb_state *mrb) +{ + struct RClass *c = mrb_class_get_id(mrb, ID_RANDOM); + mrb_value d = mrb_iv_get(mrb, mrb_obj_value(c), ID_RANDOM); if (!mrb_obj_is_kind_of(mrb, d, c)) { - mrb_raise(mrb, E_TYPE_ERROR, "Random::DEFAULT replaced"); + mrb_raise(mrb, E_RUNTIME_ERROR, "[BUG] default Random replaced"); } return d; } @@ -204,7 +207,7 @@ random_m_srand(mrb_state *mrb, mrb_value self) rand_state *t = random_ptr(self); if (mrb_get_args(mrb, "|i", &i) == 0) { - seed = (uint32_t)time(NULL) + rand_uint32(t); + seed = (uint32_t)time(NULL) ^ rand_uint32(t) ^ (uint32_t)(uintptr_t)t; } else { seed = (uint32_t)i; @@ -231,6 +234,23 @@ random_m_bytes(mrb_state *mrb, mrb_value self) return bytes; } +static rand_state* +check_random_arg(mrb_state *mrb, mrb_value r) +{ + struct RClass *c = mrb_class_get_id(mrb, ID_RANDOM); + rand_state *random; + + if (mrb_undef_p(r)) { + random = random_default_state(mrb); + } + else if (mrb_istruct_p(r) && mrb_obj_is_kind_of(mrb, r, c)){ + random = (rand_state*)mrb_istruct_ptr(r); + } + else { + mrb_raise(mrb, E_TYPE_ERROR, "Random object required"); + } + return random; +} /* * call-seq: * ary.shuffle! -> ary @@ -241,14 +261,15 @@ random_m_bytes(mrb_state *mrb, mrb_value self) static mrb_value mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) { - mrb_int i, max; - rand_state *random; - if (RARRAY_LEN(ary) > 1) { - 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); - } + mrb_int i, max; + rand_state *random; + mrb_sym kname = MRB_SYM(random); + mrb_value r; + const mrb_kwargs kw = {1, 0, &kname, &r, NULL}; + + mrb_get_args(mrb, ":", &kw); + random = check_random_arg(mrb, r); mrb_ary_modify(mrb, mrb_ary_ptr(ary)); max = RARRAY_LEN(ary); for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { @@ -256,7 +277,7 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) mrb_value *ptr = RARRAY_PTR(ary); mrb_value tmp; - j = random_rand_i(mrb, random, max); + j = rand_i(random, max); tmp = ptr[i]; ptr[i] = ptr[j]; @@ -305,11 +326,12 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) mrb_bool given; rand_state *random; mrb_int len; - struct RClass *c = mrb_class_get_id(mrb, MRB_SYM(Random)); + mrb_sym kname = MRB_SYM(random); + mrb_value r; + const mrb_kwargs kw = {1, 0, &kname, &r, NULL}; - if (mrb_get_args(mrb, "|i?I", &n, &given, &random, c) < 2) { - random = random_default_state(mrb); - } + mrb_get_args(mrb, "|i?:", &n, &given, &kw); + random = check_random_arg(mrb, r); len = RARRAY_LEN(ary); if (!given) { /* pick one element */ switch (len) { @@ -318,7 +340,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) case 1: return RARRAY_PTR(ary)[0]; default: - return RARRAY_PTR(ary)[rand_uint32(random) % len]; + return RARRAY_PTR(ary)[rand_i(random, len)]; } } else { @@ -333,7 +355,7 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) for (;;) { retry: - r = (mrb_int)(rand_uint32(random) % len); + r = rand_i(random, len); for (j=0; jkernel_module, "srand", random_f_srand, MRB_ARGS_OPT(1)); random = mrb_define_class(mrb, "Random", mrb->object_class); + mrb_const_set(mrb, mrb_obj_value(mrb->object_class), ID_RANDOM, mrb_obj_value(random)); // for class check 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)); @@ -400,8 +423,12 @@ void mrb_mruby_random_gem_init(mrb_state *mrb) mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1)); mrb_define_method(mrb, array, "sample", mrb_ary_sample, MRB_ARGS_OPT(2)); - mrb_const_set(mrb, mrb_obj_value(random), MRB_SYM(DEFAULT), - mrb_obj_new(mrb, random, 0, NULL)); + mrb_value d = mrb_obj_new(mrb, random, 0, NULL); + rand_state *t = random_ptr(d); + mrb_iv_set(mrb, mrb_obj_value(random), ID_RANDOM, d); + + uint32_t seed = (uint32_t)time(NULL); + rand_seed(t, seed ^ (uint32_t)(uintptr_t)t); } void mrb_mruby_random_gem_final(mrb_state *mrb) diff --git a/mruby/mrbgems/mruby-random/test/random.rb b/mruby/mrbgems/mruby-random/test/random.rb index 4a2f0826..7426aad2 100644 --- a/mruby/mrbgems/mruby-random/test/random.rb +++ b/mruby/mrbgems/mruby-random/test/random.rb @@ -73,14 +73,14 @@ assert("Array#shuffle(random)") do assert_raise(TypeError) do # this will cause an exception due to the wrong argument - [1, 2].shuffle "Not a Random instance" + [1, 2].shuffle(random: "Not a Random instance") end # verify that the same seed causes the same results ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - shuffled1 = ary.shuffle Random.new 345 - shuffled2 = ary.shuffle Random.new 345 - shuffled3 = ary.shuffle Random.new 346 + shuffled1 = ary.shuffle(random: Random.new(345)) + shuffled2 = ary.shuffle(random: Random.new(345)) + shuffled3 = ary.shuffle(random: Random.new(346)) assert_equal(shuffled1, shuffled2) assert_not_equal(shuffled1, shuffled3) end @@ -88,16 +88,16 @@ assert('Array#shuffle!(random)') do assert_raise(TypeError) do # this will cause an exception due to the wrong argument - [1, 2].shuffle! "Not a Random instance" + [1, 2].shuffle!(random: "Not a Random instance") end # verify that the same seed causes the same results ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ary1.shuffle! Random.new 345 + ary1.shuffle!(random: Random.new(345)) ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ary2.shuffle! Random.new 345 + ary2.shuffle!(random: Random.new(345)) ary3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ary3.shuffle! Random.new 346 + ary3.shuffle!(random: Random.new(346)) assert_equal(ary1, ary2) assert_not_equal(ary1, ary3) end @@ -123,15 +123,15 @@ assert('Array#sample(random)') do assert_raise(TypeError) do # this will cause an exception due to the wrong argument - [1, 2].sample(2, "Not a Random instance") + [1, 2].sample(2, random: "Not a Random instance") end # verify that the same seed causes the same results ary = (1..10).to_a srand(15) samples1 = ary.sample(4) - samples2 = ary.sample(4, Random.new(15)) - samples3 = ary.sample(4, Random.new(16)) + samples2 = ary.sample(4, random: Random.new(15)) + samples3 = ary.sample(4, random: Random.new(16)) assert_equal(samples1, samples2) assert_not_equal(samples1, samples3) end diff --git a/mruby/mrbgems/mruby-range-ext/src/range.c b/mruby/mrbgems/mruby-range-ext/src/range.c index 633c97b7..9aaeac81 100644 --- a/mruby/mrbgems/mruby-range-ext/src/range.c +++ b/mruby/mrbgems/mruby-range-ext/src/range.c @@ -2,29 +2,33 @@ #include static mrb_bool -r_le(mrb_state *mrb, mrb_value a, mrb_value b) +r_less(mrb_state *mrb, mrb_value a, mrb_value b, mrb_bool excl) { - mrb_int n = mrb_cmp(mrb, a, b); - - if (n == 0 || n == -1) return TRUE; - return FALSE; -} - -static mrb_bool -r_lt(mrb_state *mrb, mrb_value a, mrb_value b) -{ - return mrb_cmp(mrb, a, b) == -1; + switch (mrb_cmp(mrb, a, b)) { + case -2: /* failure */ + case 1: + return FALSE; + case 0: + return !excl; + case -1: + default: /* just in case */ + return TRUE; + } } /* * call-seq: * rng.cover?(obj) -> true or false + * rng.cover?(range) -> true or false + * + * Returns +true+ if the given argument is within +self+, +false+ otherwise. + * + * With non-range argument +object+, evaluates with <= and <. * - * Returns true if +obj+ is between the begin and end of - * the range. + * For range +self+ with included end value (#exclude_end? == false), + * evaluates thus: * - * This tests begin <= obj <= end when #exclude_end? is +false+ - * and begin <= obj < end when #exclude_end? is +true+. + * self.begin <= object <= self.end * * ("a".."z").cover?("c") #=> true * ("a".."z").cover?("5") #=> false @@ -40,20 +44,53 @@ range_cover(mrb_state *mrb, mrb_value range) beg = RANGE_BEG(r); end = RANGE_END(r); - if (r_le(mrb, beg, val)) { - if (mrb_nil_p(end)) { + if (mrb_nil_p(beg) && mrb_nil_p(end)) return mrb_true_value(); + + if (mrb_range_p(val)) { + struct RRange *r2 = mrb_range_ptr(mrb, val); + mrb_value beg2 = RANGE_BEG(r2); + mrb_value end2 = RANGE_END(r2); + + /* range.cover?(nil..nil) => true */ + if (mrb_nil_p(beg2) && mrb_nil_p(end2)) return mrb_true_value(); + + /* (a..b).cover?(c..d) */ + if (mrb_nil_p(end)) { /* a.. */ + /* (a..).cover?(c..) => true */ + if (mrb_nil_p(end2)) return mrb_bool_value(mrb_cmp(mrb, beg, beg2) != -2); + /* (a..).cover?(c..d) where d false */ + if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value(); return mrb_true_value(); } - if (RANGE_EXCL(r)) { - if (r_lt(mrb, val, end)) - return mrb_true_value(); + else if (mrb_nil_p(beg)) { /* ..b */ + /* (..b).cover?(..d) => true */ + if (mrb_nil_p(beg2)) return mrb_bool_value(mrb_cmp(mrb, end, end2) != -2); + /* (..b).cover?(c..d) where b false */ + if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value(); + return mrb_true_value(); } - else { - if (r_le(mrb, val, end)) - return mrb_true_value(); + else { /* a..b */ + /* (a..b).cover?(c..) => (c (a false */ + if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value(); + /* (a..b).cover?(c..d) where (d false */ + if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value(); + return mrb_true_value(); } } + if (mrb_nil_p(beg) || r_less(mrb, beg, val, FALSE)) { + if (mrb_nil_p(end)) { + return mrb_true_value(); + } + if (r_less(mrb, val, end, RANGE_EXCL(r))) + return mrb_true_value(); + } return mrb_false_value(); } @@ -155,7 +192,7 @@ range_size(mrb_state *mrb, mrb_value range) void mrb_mruby_range_ext_gem_init(mrb_state* mrb) { - struct RClass * s = mrb_class_get(mrb, "Range"); + struct RClass * s = mrb->range_class; mrb_define_method(mrb, s, "cover?", range_cover, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "size", range_size, MRB_ARGS_NONE()); diff --git a/mruby/mrbgems/mruby-range-ext/test/range.rb b/mruby/mrbgems/mruby-range-ext/test/range.rb index 863c619c..4ae57566 100644 --- a/mruby/mrbgems/mruby-range-ext/test/range.rb +++ b/mruby/mrbgems/mruby-range-ext/test/range.rb @@ -3,11 +3,25 @@ assert('Range#cover?') do assert_true ("a".."z").cover?("c") - assert_true !("a".."z").cover?("5") + assert_false ("a".."z").cover?("5") assert_true ("a".."z").cover?("cc") + assert_false ("a".."z").cover?(nil) assert_true ("a"..).cover?("c") assert_false ("a"..).cover?("5") assert_true ("a"..).cover?("cc") + assert_true (.."z").cover?("a") + assert_false (..."z").cover?("z") + assert_true (.."z").cover?("z") + assert_true (nil..nil).cover?(nil) + + assert_true ("a".."c").cover?("b".."d") + assert_true ("a"..).cover?("b"..) + assert_false ("a"..).cover?(1..) + assert_false ("d"..).cover?(.."b") + assert_true (.."c").cover?("b".."d") + assert_true (.."c").cover?(.."d") + assert_false (.."c").cover?(..2) + assert_false (.."c").cover?("d"..) end assert('Range#first') do diff --git a/mruby/mrbgems/mruby-rational/mrbgem.rake b/mruby/mrbgems/mruby-rational/mrbgem.rake index 53411486..2cd4816f 100644 --- a/mruby/mrbgems/mruby-rational/mrbgem.rake +++ b/mruby/mrbgems/mruby-rational/mrbgem.rake @@ -3,5 +3,5 @@ MRuby::Gem::Specification.new('mruby-rational') do |spec| spec.author = 'mruby developers' spec.summary = 'Rational class' spec.build.defines << "MRB_USE_RATIONAL" - spec.add_test_dependency('mruby-complex') + spec.add_test_dependency('mruby-complex', :core => 'mruby-complex') end diff --git a/mruby/mrbgems/mruby-rational/src/rational.c b/mruby/mrbgems/mruby-rational/src/rational.c index e6604654..3b13fb57 100644 --- a/mruby/mrbgems/mruby-rational/src/rational.c +++ b/mruby/mrbgems/mruby-rational/src/rational.c @@ -1,8 +1,19 @@ #include #include #include +#include #include +#ifndef MRB_NO_FLOAT +#include +mrb_value mrb_complex_new(mrb_state *, mrb_float, mrb_float); +#endif +mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_add(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_sub(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_mul(mrb_state *mrb, mrb_value, mrb_value); +mrb_value mrb_complex_div(mrb_state *mrb, mrb_value, mrb_value); + struct mrb_rational { mrb_int numerator; mrb_int denominator; @@ -33,6 +44,8 @@ struct RRational { #define rational_ptr(mrb, v) (&((struct RRational*)mrb_obj_ptr(v))->r) #endif +mrb_static_assert_object_size(struct RRational); + static struct RBasic* rational_alloc(mrb_state *mrb, struct RClass *c, struct mrb_rational **p) { @@ -98,6 +111,15 @@ mrb_rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator) #define rational_new(mrb,n,d) mrb_rational_new(mrb, n, d) +void +mrb_rational_copy(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct mrb_rational *p1 = rational_ptr(mrb, x); + struct mrb_rational *p2 = rational_ptr(mrb, y); + p1->numerator = p2->numerator; + p1->denominator = p2->denominator; +} + inline static mrb_int i_gcd(mrb_int x, mrb_int y) { @@ -116,7 +138,7 @@ i_gcd(mrb_int x, mrb_int y) u = (mrb_uint)x; v = (mrb_uint)y; - for (shift = 0; ((u | v) & 1) == 0; ++shift) { + for (shift = 0; ((u | v) & 1) == 0; shift++) { u >>= 1; v >>= 1; } @@ -325,12 +347,26 @@ rational_negative_p(mrb_state *mrb, mrb_value self) return mrb_false_value(); } +#ifndef MRB_NO_FLOAT +static mrb_value +float_to_r(mrb_state *mrb, mrb_value self) +{ + return rational_new_f(mrb, mrb_float(self)); +} +#endif + static mrb_value fix_to_r(mrb_state *mrb, mrb_value self) { return rational_new(mrb, mrb_integer(self), 1); } +static mrb_value +nil_to_r(mrb_state *mrb, mrb_value self) +{ + return rational_new(mrb, 0, 1); +} + static mrb_value rational_m(mrb_state *mrb, mrb_value self) { @@ -393,7 +429,6 @@ rational_eq(mrb_state *mrb, mrb_value x) #ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: { - mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value, mrb_value); result = mrb_complex_eq(mrb, y, mrb_rational_to_f(mrb, x)); break; } @@ -405,10 +440,6 @@ rational_eq(mrb_state *mrb, mrb_value x) return mrb_bool_value(result); } -#ifndef MRB_NO_FLOAT -mrb_value mrb_complex_new(mrb_state *, mrb_float, mrb_float); -#endif - static mrb_value rational_cmp(mrb_state *mrb, mrb_value x) { @@ -454,11 +485,6 @@ rational_cmp(mrb_state *mrb, mrb_value x) return mrb_fixnum_value(-1); return mrb_fixnum_value(0); } -#endif -#ifdef MRB_USE_COMPLEX - case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_float(p1), 0); - return mrb_funcall_id(mrb, x, MRB_OPSYM(cmp), 1, y); #endif default: x = mrb_funcall_id(mrb, y, MRB_OPSYM(cmp), 1, x); @@ -479,11 +505,10 @@ rational_minus(mrb_state *mrb, mrb_value x) return rational_new(mrb, -n, p->denominator); } -static mrb_value -rational_add(mrb_state *mrb, mrb_value x) +mrb_value +mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y) { struct mrb_rational *p1 = rational_ptr(mrb, x); - mrb_value y = mrb_get_arg1(mrb); switch (mrb_type(y)) { case MRB_TT_INTEGER: @@ -513,16 +538,27 @@ rational_add(mrb_state *mrb, mrb_value x) } #endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_add(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); +#endif + default: return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); } } static mrb_value -rational_sub(mrb_state *mrb, mrb_value x) +rational_add(mrb_state *mrb, mrb_value x) { - struct mrb_rational *p1 = rational_ptr(mrb, x); mrb_value y = mrb_get_arg1(mrb); + return mrb_rational_add(mrb, x, y); +} + +mrb_value +mrb_rational_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct mrb_rational *p1 = rational_ptr(mrb, x); switch (mrb_type(y)) { case MRB_TT_INTEGER: @@ -546,8 +582,7 @@ rational_sub(mrb_state *mrb, mrb_value x) #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - x = mrb_complex_new(mrb, rat_float(p1), 0); - return mrb_funcall_id(mrb, x, MRB_OPSYM(sub), 1, y); + return mrb_complex_sub(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); #endif #ifndef MRB_NO_FLOAT @@ -565,10 +600,16 @@ rational_sub(mrb_state *mrb, mrb_value x) } static mrb_value -rational_mul(mrb_state *mrb, mrb_value x) +rational_sub(mrb_state *mrb, mrb_value x) { - struct mrb_rational *p1 = rational_ptr(mrb, x); mrb_value y = mrb_get_arg1(mrb); + return mrb_rational_sub(mrb, x, y); +} + +mrb_value +mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ + struct mrb_rational *p1 = rational_ptr(mrb, x); switch (mrb_type(y)) { case MRB_TT_INTEGER: @@ -595,21 +636,33 @@ rational_mul(mrb_state *mrb, mrb_value x) } #endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_mul(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); +#endif + default: return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); } } +static mrb_value +rational_mul(mrb_state *mrb, mrb_value x) +{ + mrb_value y = mrb_get_arg1(mrb); + return mrb_rational_mul(mrb, x, y); +} + mrb_value -mrb_rational_div(mrb_state *mrb, mrb_value x) +mrb_rational_div(mrb_state *mrb, mrb_value x, mrb_value y) { struct mrb_rational *p1 = rational_ptr(mrb, x); - mrb_value y = mrb_get_arg1(mrb); switch (mrb_type(y)) { case MRB_TT_INTEGER: { mrb_int z = mrb_integer(y); + if (z == 0) mrb_int_zerodiv(mrb); if (mrb_int_mul_overflow(p1->denominator, z, &z)) rat_overflow(mrb); return rational_new_i(mrb, p1->numerator, z); } @@ -625,8 +678,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_float(p1), 0); - return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); + return mrb_complex_div(mrb, mrb_complex_new(mrb, rat_float(p1), 0), y); #endif default: @@ -642,64 +694,75 @@ mrb_rational_div(mrb_state *mrb, mrb_value x) } } -#define rational_div mrb_rational_div -mrb_int mrb_div_int(mrb_state *, mrb_int, mrb_int); - -#ifndef MRB_USE_COMPLEX -/* 15.2.8.3.4 */ -/* - * redefine Integer#/ - */ static mrb_value -rational_int_div(mrb_state *mrb, mrb_value x) +rational_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); - - if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); - return mrb_int_value(mrb, div); - } - switch (mrb_type(y)) { - case MRB_TT_RATIONAL: - return rational_div(mrb, rational_new(mrb, a, 1)); - default: -#ifdef MRB_NO_FLOAT - case MRB_TT_FLOAT: - mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); -#endif - } + return mrb_rational_div(mrb, x, y); } -/* 15.2.9.3.19(x) */ -/* - * redefine Integer#quo - */ - static mrb_value -rational_int_quo(mrb_state *mrb, mrb_value x) +rational_pow(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); + struct mrb_rational *p1 = rational_ptr(mrb, x); +#ifndef MRB_NO_FLOAT + double d1, d2; - if (mrb_integer_p(y)) { - return rational_new(mrb, a, mrb_integer(y)); - } switch (mrb_type(y)) { case MRB_TT_RATIONAL: - x = rational_new(mrb, a, 1); - return mrb_funcall_id(mrb, x, MRB_OPSYM(div), 1, y); + { + struct mrb_rational *p2 = rational_ptr(mrb, y); + if (p2->numerator == 0) { + return mrb_rational_new(mrb, 1, 1); + } + if (p2->numerator == p2->denominator) { + return x; + } + if (p2->denominator == 1) { + return rational_new_i(mrb, (mrb_int)pow((mrb_float)p1->numerator, (mrb_float)p2->numerator), + (mrb_int)pow((mrb_float)p1->denominator, (mrb_float)p2->numerator)); + } + d1 = rat_float(p1); + d2 = rat_float(p2); + } + break; + case MRB_TT_FLOAT: + { + d1 = rat_float(p1); + d2 = mrb_float(y); + } + break; + case MRB_TT_INTEGER: + { + mrb_int i = mrb_integer(y); + if (i == 0) { + return mrb_rational_new(mrb, 1, 1); + } + if (i == 1) { + return x; + } + return rational_new_i(mrb, (mrb_int)pow((mrb_float)p1->numerator, (mrb_float)i), + (mrb_int)pow((mrb_float)p1->denominator, (mrb_float)i)); + } + break; default: -#ifdef MRB_NO_FLOAT - mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); + mrb_raisef(mrb, E_TYPE_ERROR, "%T cannot be converted to Rational", y); + } + return mrb_float_value(mrb, pow(d1, d2)); #else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); + mrb_raisef(mrb, E_NOTIMP_ERROR, "Rational#** not implemented with MRB_NO_FLOAT"); #endif - } } -#endif /* !MRB_USE_COMPLEX */ + +static mrb_value +rational_hash(mrb_state *mrb, mrb_value rat) +{ + struct mrb_rational *r = rational_ptr(mrb, rat); + uint32_t hash = mrb_byte_hash((uint8_t*)&r->numerator, sizeof(mrb_int)); + hash = mrb_byte_hash_step((uint8_t*)&r->denominator, sizeof(mrb_int), hash); + return mrb_int_value(mrb, hash); +} void mrb_mruby_rational_gem_init(mrb_state *mrb) { @@ -725,11 +788,13 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) mrb_define_method(mrb, rat, "*", rational_mul, MRB_ARGS_REQ(1)); mrb_define_method(mrb, rat, "/", rational_div, MRB_ARGS_REQ(1)); 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, "/", rational_int_div, MRB_ARGS_REQ(1)); /* override */ - mrb_define_method(mrb, mrb->integer_class, "quo", rational_int_quo, MRB_ARGS_REQ(1)); /* override */ + mrb_define_method(mrb, rat, "**", rational_pow, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, rat, "hash", rational_hash, MRB_ARGS_NONE()); +#ifndef MRB_NO_FLOAT + mrb_define_method(mrb, mrb->float_class, "to_r", float_to_r, MRB_ARGS_NONE()); #endif + mrb_define_method(mrb, mrb->integer_class, "to_r", fix_to_r, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->nil_class, "to_r", nil_to_r, MRB_ARGS_NONE()); mrb_define_method(mrb, mrb->kernel_module, "Rational", rational_m, MRB_ARGS_ARG(1,1)); } diff --git a/mruby/mrbgems/mruby-rational/test/rational.rb b/mruby/mrbgems/mruby-rational/test/rational.rb index b807ef83..0038f141 100644 --- a/mruby/mrbgems/mruby-rational/test/rational.rb +++ b/mruby/mrbgems/mruby-rational/test/rational.rb @@ -331,3 +331,18 @@ def assert_complex(real, imag) assert_predicate(Rational(2,3), :frozen?) assert_predicate(4/5r, :frozen?) end + +assert 'Rational#**' do + assert_rational(1r, (14/2r)**0) + assert_rational(14/2r, (14/2r)**1) + assert_rational(49r, (14/2r)**2) + assert_rational(27r, (6/2r)**3) + assert_float(2.0, (4r)**(1/2r)) + assert_rational(4r, (4r)**(2/2r)) + assert_rational(16r, (4r)**(4/2r)) + assert_float(1.0, (4r)**(0.0)) + assert_float(2.0, (4r)**(0.5)) + assert_float(4.0, (4r)**(1.0)) + assert_float(16.0, (4r)**(2.0)) + assert_float(3.5**1.5, (7/2r)**(1.5)) +end diff --git a/mruby/mrbgems/mruby-set/LICENSE b/mruby/mrbgems/mruby-set/LICENSE new file mode 100644 index 00000000..d892b29f --- /dev/null +++ b/mruby/mrbgems/mruby-set/LICENSE @@ -0,0 +1,24 @@ +mruby-set + +Copyright (c) yui-knk 2016 + +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. + +[ MIT license: http://www.opensource.org/licenses/mit-license.php ] diff --git a/mruby/mrbgems/mruby-set/README.md b/mruby/mrbgems/mruby-set/README.md new file mode 100644 index 00000000..9ddb0256 --- /dev/null +++ b/mruby/mrbgems/mruby-set/README.md @@ -0,0 +1,34 @@ +# mruby-set + +Set class + +## Example + +```ruby +set1 = Set.new([1,2]) +set2 = Set[1,2,3] +set3 = Set[4] + +set1 + set3 +#=> # +set2 - set1 +#=> # +set2 & set1 +#=> # +set1 ^ set2 +#=> # +``` + +## Limitations + +These methods are not implemented yet: + +- freeze +- to_set +- divide(Set#divide with 2 arity block is not implemented.) + +## License + +Under the MIT License: + +- see [LICENSE](LICENSE) file diff --git a/mruby/mrbgems/mruby-set/mrbgem.rake b/mruby/mrbgems/mruby-set/mrbgem.rake new file mode 100644 index 00000000..c5930570 --- /dev/null +++ b/mruby/mrbgems/mruby-set/mrbgem.rake @@ -0,0 +1,7 @@ +MRuby::Gem::Specification.new('mruby-set') do |spec| + spec.license = 'MIT' + spec.authors = 'yui-knk' + + spec.add_dependency "mruby-hash-ext", :core => "mruby-hash-ext" + spec.add_dependency "mruby-enumerator", :core => "mruby-enumerator" +end diff --git a/mruby/mrbgems/mruby-set/mrblib/set.rb b/mruby/mrbgems/mruby-set/mrblib/set.rb new file mode 100644 index 00000000..0116e187 --- /dev/null +++ b/mruby/mrbgems/mruby-set/mrblib/set.rb @@ -0,0 +1,329 @@ +class Set + include Enumerable + + # internal method + def __do_with_enum(enum, &block) + if enum.respond_to?(:each) + enum.each(&block) + else + raise ArgumentError, "value must be enumerable" + end + end + + # internal method to get internal hash + def __get_hash + @hash + end + + def self.[](*ary) + new(ary) + end + + def initialize(enum = nil, &block) + @hash ||= Hash.new + + enum.nil? and return + + if block_given? + __do_with_enum(enum) { |o| add(block.call(o)) } + else + merge(enum) + end + end + + def initialize_copy(orig) + super + @hash = orig.__get_hash.dup + end + + # def freeze + # @hash.freeze + # super + # end + + def size + @hash.size + end + alias length size + + def empty? + @hash.empty? + end + + def clear + @hash.clear + self + end + + def replace(enum) + clear + merge(enum) + end + + def to_a + @hash.keys + end + +# def to_set +# end +# + def flatten_merge(set, seen = Set.new) + seen.add(set.object_id) + set.each { |e| + if e.is_a?(Set) + if seen.include?(e_id = e.object_id) + raise ArgumentError, "tried to flatten recursive Set" + end + + flatten_merge(e, seen) + else + add(e) + end + } + seen.delete(set.object_id) + + self + end + + def flatten + self.class.new.flatten_merge(self) + end + + def flatten! + if detect { |e| e.is_a?(Set) } + replace(flatten()) + else + nil + end + end + + def include?(o) + @hash.include?(o) + end + alias member? include? + alias === include? + + def superset?(set) + raise ArgumentError, "value must be a set" unless set.is_a?(Set) + return false if size < set.size + set.all? { |o| include?(o) } + end + alias >= superset? + + def proper_superset?(set) + raise ArgumentError, "value must be a set" unless set.is_a?(Set) + return false if size <= set.size + set.all? { |o| include?(o) } + end + alias > proper_superset? + + def subset?(set) + raise ArgumentError, "value must be a set" unless set.is_a?(Set) + return false if set.size < size + all? { |o| set.include?(o) } + end + alias <= subset? + + def proper_subset?(set) + raise ArgumentError, "value must be a set" unless set.is_a?(Set) + return false if set.size <= size + all? { |o| set.include?(o) } + end + alias < proper_subset? + + def intersect?(set) + raise ArgumentError, "value must be a set" unless set.is_a?(Set) + if size < set.size + any? { |o| set.include?(o) } + else + set.any? { |o| include?(o) } + end + end + + def disjoint?(set) + !intersect?(set) + end + + def each(&block) + return to_enum :each unless block_given? + @hash.each_key(&block) + self + end + + def add(o) + @hash[o] = true + self + end + alias << add + + def add?(o) + if include?(o) + nil + else + add(o) + end + end + + def delete(o) + @hash.delete(o) + self + end + + def delete?(o) + if include?(o) + delete(o) + else + nil + end + end + + def delete_if + return to_enum :delete_if unless block_given? + select { |o| yield o }.each { |o| @hash.delete(o) } + self + end + + def keep_if + return to_enum :keep_if unless block_given? + reject { |o| yield o }.each { |o| @hash.delete(o) } + self + end + + def collect! + return to_enum :collect! unless block_given? + set = self.class.new + each { |o| set << yield(o) } + replace(set) + end + alias map! collect! + + def reject!(&block) + return to_enum :reject! unless block_given? + n = size + delete_if(&block) + size == n ? nil : self + end + + def select!(&block) + return to_enum :select! unless block_given? + n = size + keep_if(&block) + size == n ? nil : self + end + alias filter! select! + + def merge(enum) + if enum.instance_of?(self.class) + @hash.merge!(enum.__get_hash) + else + __do_with_enum(enum) { |o| add(o) } + end + + self + end + + def subtract(enum) + __do_with_enum(enum) { |o| delete(o) } + self + end + + def |(enum) + dup.merge(enum) + end + alias + | + alias union | + + def -(enum) + dup.subtract(enum) + end + alias difference - + + def &(enum) + n = Set.new + __do_with_enum(enum) { |o| n.add(o) if include?(o) } + n + end + alias intersection & + + def ^(enum) + (self | Set.new(enum)) - (self & Set.new(enum)) + end + + def ==(other) + if self.equal?(other) + true + elsif other.instance_of?(self.class) && self.size == other.size + @hash == other.__get_hash + elsif other.is_a?(self.class) && self.size == other.size + other.all? { |o| include?(o) } + else + false + end + end + + def <=>(set) + return unless set.is_a?(Set) + + case size <=> set.size + when -1 then -1 if proper_subset?(set) + when +1 then +1 if proper_superset?(set) + else 0 if self.==(set) + end + end + + def hash + @hash.hash + end + + def eql?(o) + return false unless o.is_a?(Set) + @hash.eql?(o.__get_hash) + end + + def classify + return to_enum :classify unless block_given? + h = {} + + each { |i| + x = yield(i) + (h[x] ||= self.class.new).add(i) + } + + h + end + + def divide(&func) + return to_enum :divide unless block_given? + + if func.arity == 2 + raise NotImplementedError, "Set#divide with 2 arity block is not implemented." + end + + Set.new(classify(&func).values) + end + + def join(separator = nil) + to_a.join(separator) + end + + def _inspect(recur_list) + return "#<#{self.class}: {}>" if empty? + return "#<#{self.class}: {...}>" if recur_list[self.object_id] + recur_list[self.object_id] = true + ary = map { |o| o._inspect(recur_list) } + "#<#{self.class}: {#{ary.join(", ")}}>" + end + + def inspect + _inspect({}) + end + alias to_s inspect + + def reset + if frozen? + raise FrozenError, "can't modify frozen Set" + else + @hash.rehash + end + end +end diff --git a/mruby/mrbgems/mruby-set/mruby-set.gem b/mruby/mrbgems/mruby-set/mruby-set.gem new file mode 100644 index 00000000..84a4afb4 --- /dev/null +++ b/mruby/mrbgems/mruby-set/mruby-set.gem @@ -0,0 +1,6 @@ +name: mruby-set +description: Set class +author: yui-knk +website: https://github.com/yui-knk/mruby-set +protocol: git +repository: https://github.com/yui-knk/mruby-set.git diff --git a/mruby/mrbgems/mruby-set/test/set.rb b/mruby/mrbgems/mruby-set/test/set.rb new file mode 100644 index 00000000..72049b15 --- /dev/null +++ b/mruby/mrbgems/mruby-set/test/set.rb @@ -0,0 +1,632 @@ +## +## Set Test +## + +assert("Set.new") do + assert_nothing_raised { + Set.new() + Set.new(nil) + Set.new([]) + Set.new([1,2]) + Set.new(1..3) + } + assert_raise(ArgumentError) { Set.new(false) } + assert_raise(ArgumentError) { Set.new(1) } + assert_raise(ArgumentError) { Set.new(1,2) } + + ary = [2,4,6,4] + set = Set.new(ary) + ary.clear + assert_false set.empty? + assert_equal(3, set.size) + + ary = [1,2,3] + + s = Set.new(ary) { |o| o * 2 } + assert_equal([2,4,6], s.sort) +end + +assert("Set.[]") do + assert_nothing_raised { + Set[] + Set[nil] + Set[[]] + Set[[1,2]] + Set['a'..'c'] + Set[false] + Set[1] + Set[1,2] + } + + ary = [2,4,6,4] + set = Set[ary] + ary.clear + assert_false set.empty? + assert_equal([[]], set.to_a) +end + +assert("Set#clone") do + set1 = Set.new + set2 = set1.clone + + assert_false set1.equal?(set2) # assert_not_same + + assert_equal(set1, set2) + + set1 << 'abc' + + assert_equal(Set.new, set2) +end + +assert("Set#dup") do + set1 = Set[1,2] + set2 = set1.dup + + assert_false set1.equal?(set2) # assert_not_same + + assert_equal(set1, set2) + + set1 << 'abc' + + assert_equal(Set[1,2], set2) +end + +assert("Set#size") do + assert_equal(0, Set[].size) + assert_equal(1, Set[nil].size) + assert_equal(1, Set[[]].size) + assert_equal(1, Set[[nil]].size) +end + +assert("Set#empty?") do + assert_true Set[].empty? + assert_false Set[1,2].empty? +end + +assert("Set#clear") do + set = Set[1,2] + ret = set.clear + + assert_true set.equal?(ret) # assert_same + assert_true set.empty? +end + +assert("Set#replace") do + set = Set[1,2] + ret = set.replace(['a','b','c']) + + assert_true set.equal?(ret) # assert_same + assert_equal(Set['a','b','c'], set) + + + set = Set[1,2] + ret = set.replace(Set['a','b','c']) + + assert_true set.equal?(ret) # assert_same + assert_equal(Set['a','b','c'], set) +end + +assert("Set#to_a") do + set = Set[1,2,3,2] + ary = set.to_a + + assert_equal([1,2,3], ary.sort) +end + +assert("Set#flatten") do + # test1 + set1 = Set[ + 1, + Set[ + 5, + Set[7, + Set[0] + ], + Set[6,2], + 1 + ], + 3, + Set[3,4] + ] + + set2 = set1.flatten + set3 = Set.new(0..7) + + assert_false set1.equal?(set2) # assert_not_same + assert_equal(set3, set2) + + + # test2; multiple occurrences of a set in an set + set1 = Set[1, 2] + set2 = Set[set1, Set[set1, 4], 3] + + assert_nothing_raised { + set3 = set2.flatten + } + + assert_equal(Set.new(1..4), set3) + + + # test3; recursion + set2 = Set[] + set1 = Set[1, set2] + set2.add(set1) + + assert_raise(ArgumentError) { + set1.flatten + } + + # test4; miscellaneous + empty = Set[] + set = Set[Set[empty, "a"], Set[empty, "b"]] + + assert_nothing_raised { + set.flatten + } +end + +assert("Set#flatten!") do + # test1 + set1 = Set[ + 1, + Set[ + 5, + Set[7, + Set[0] + ], + Set[6,2], + 1 + ], + 3, + Set[3,4] + ] + + set3 = Set.new(0..7) + orig_set1 = set1 + set1.flatten! + + assert_true orig_set1.equal?(set1) # assert_same + assert_equal(set3, set1) + + + # test2; multiple occurrences of a set in an set + set1 = Set[1, 2] + set2 = Set[set1, Set[set1, 4], 3] + + assert_nothing_raised { + set2.flatten! + } + + assert_equal(Set.new(1..4), set2) + + + # test3; recursion + set2 = Set[] + set1 = Set[1, set2] + set2.add(set1) + + assert_raise(ArgumentError) { + set1.flatten! + } + + # test4; miscellaneous + assert_nil(Set.new(0..31).flatten!) + + x = Set[Set[],Set[1,2]].flatten! + y = Set[1,2] + + assert_equal(x, y) +end + +assert("Set#include?") do + set = Set[1,2,3] + + assert_true set.include?(1) + assert_true set.include?(2) + assert_true set.include?(3) + assert_false set.include?(0) + assert_false set.include?(nil) + + set = Set["1",nil,"2",nil,"0","1",false] + assert_true set.include?(nil) + assert_true set.include?(false) + assert_true set.include?("1") + assert_false set.include?(0) + assert_false set.include?(true) + assert_false set.include?(2) +end + +assert("Set#superset?") do + set = Set[1,2,3] + + assert_raise(ArgumentError) { set.superset?(nil) } + assert_raise(ArgumentError) { set.superset?(2) } + assert_raise(ArgumentError) { set.superset?([2]) } + + assert_true set.superset?(Set[]) + assert_true set.superset?(Set[1,2]) + assert_true set.superset?(Set[1,2,3]) + assert_false set.superset?(Set[1,2,3,4]) + assert_false set.superset?(Set[1,4]) + + assert_true set >= Set[1,2] + assert_true set >= Set[1,2,3] + + assert_true Set[].superset?(Set[]) +end + +assert("Set#proper_superset?") do + set = Set[1,2,3] + + assert_raise(ArgumentError) { set.proper_superset?(nil) } + assert_raise(ArgumentError) { set.proper_superset?(2) } + assert_raise(ArgumentError) { set.proper_superset?([2]) } + + assert_true set.proper_superset?(Set[]) + assert_true set.proper_superset?(Set[1,2]) + assert_false set.proper_superset?(Set[1,2,3]) + assert_false set.proper_superset?(Set[1,2,3,4]) + assert_false set.proper_superset?(Set[1,4]) + + assert_true set > Set[1,2] + assert_false set > Set[1,2,3] + + assert_false Set[].proper_superset?(Set[]) +end + +assert("Set#subset?") do + set = Set[1,2,3] + + assert_raise(ArgumentError) { set.subset?(nil) } + assert_raise(ArgumentError) { set.subset?(2) } + assert_raise(ArgumentError) { set.subset?([2]) } + + assert_true set.subset?(Set[1,2,3,4]) + assert_true set.subset?(Set[1,2,3]) + assert_false set.subset?(Set[1,2]) + assert_false set.subset?(Set[]) + + assert_true set <= Set[1,2,3] + assert_false set <= Set[1,2] + + assert_true Set[].subset?(Set[1]) + assert_true Set[].subset?(Set[]) +end + +assert("Set#proper_subset?") do + set = Set[1,2,3] + + assert_raise(ArgumentError) { set.proper_subset?(nil) } + assert_raise(ArgumentError) { set.proper_subset?(2) } + assert_raise(ArgumentError) { set.proper_subset?([2]) } + + assert_true set.proper_subset?(Set[1,2,3,4]) + assert_false set.proper_subset?(Set[1,2,3]) + assert_false set.proper_subset?(Set[1,2]) + assert_false set.proper_subset?(Set[]) + + assert_true set < Set[1,2,3,4] + assert_false set < Set[1,2,3] + + assert_true Set[].proper_subset?(Set[1]) + assert_false Set[].proper_subset?(Set[]) +end + +assert("Set#intersect?") do + set = Set[3,4,5] + + assert_raise(ArgumentError) { set.intersect?(3) } + assert_raise(ArgumentError) { set.intersect?([2,4,6]) } + + assert_true set.intersect?(set) + assert_true set.intersect?(Set[2,4]) + assert_true set.intersect?(Set[5,6,7]) + assert_true set.intersect?(Set[1,2,6,8,4]) + + assert_false(set.intersect?(Set[])) + assert_false(set.intersect?(Set[0,2])) + assert_false(set.intersect?(Set[0,2,6])) + assert_false(set.intersect?(Set[0,2,6,8,10])) + + # Make sure set hasn't changed + assert_equal(Set[3,4,5], set) +end + +assert("Set#disjoint?") do + set = Set[3,4,5] + + assert_raise(ArgumentError) { set.disjoint?(3) } + assert_raise(ArgumentError) { set.disjoint?([2,4,6]) } + + assert_true(set.disjoint?(Set[])) + assert_true(set.disjoint?(Set[0,2])) + assert_true(set.disjoint?(Set[0,2,6])) + assert_true(set.disjoint?(Set[0,2,6,8,10])) + + assert_false set.disjoint?(set) + assert_false set.disjoint?(Set[2,4]) + assert_false set.disjoint?(Set[5,6,7]) + assert_false set.disjoint?(Set[1,2,6,8,4]) + + # Make sure set hasn't changed + assert_equal(Set[3,4,5], set) +end + +assert("Set#each") do + ary = [1,3,5,7,10,20] + set = Set.new(ary) + + ret = set.each { |o| } + assert_true set.equal?(ret) # assert_same + + e = set.each + assert_true e.instance_of?(Enumerator) + + assert_nothing_raised { + set.each { |o| + ary.delete(o) or raise "unexpected element: #{o}" + } + ary.empty? or raise "forgotten elements: #{ary.join(', ')}" + } +end + +assert("Set#add") do + set = Set[1,2,3] + + ret = set.add(2) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,3], set) + + ret = set.add(4) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,3,4], set) +end + +assert("Set#add?") do + set = Set[1,2,3] + + ret = set.add?(2) + assert_nil ret + assert_equal(Set[1,2,3], set) + + ret = set.add?(4) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,3,4], set) +end + +assert("Set#delete") do + set = Set[1,2,3] + + ret = set.delete(4) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,3], set) + + ret = set.delete(2) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,3], set) +end + +assert("Set#delete?") do + set = Set[1,2,3] + + ret = set.delete?(4) + assert_nil ret + assert_equal(Set[1,2,3], set) + + ret = set.delete?(1) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[2,3], set) +end + +assert("Set#delete_if") do + set = Set.new(1..10) + ret = set.delete_if { |i| i > 10 } + assert_true set.equal?(ret) # assert_same + assert_equal(Set.new(1..10), set) + + set = Set.new(1..10) + ret = set.delete_if { |i| i % 3 == 0 } + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,4,5,7,8,10], set) +end + +assert("Set#keep_if") do + set = Set.new(1..10) + ret = set.keep_if { |i| i <= 10 } + assert_true set.equal?(ret) # assert_same + assert_equal(Set.new(1..10), set) + + set = Set.new(1..10) + ret = set.keep_if { |i| i % 3 != 0 } + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,4,5,7,8,10], set) +end + +assert("Set#collect!") do + set = Set[1,2,3,'a','b','c',-1..1,2..4] + + ret = set.collect! { |i| + case i + when Numeric + i * 2 + when String + i.upcase + else + nil + end + } + + assert_true set.equal?(ret) # assert_same + assert_equal(Set[2,4,6,"A","B","C",nil], set) +end + +assert("Set#reject!") do + set = Set.new(1..10) + + ret = set.reject! { |i| i > 10 } + assert_nil(ret) + assert_equal(Set.new(1..10), set) + + ret = set.reject! { |i| i % 3 == 0 } + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,4,5,7,8,10], set) +end + +# this test is not in CRuby +assert("Set#select!") do + set = Set.new(1..10) + + ret = set.select! { |i| i <= 10 } + assert_nil(ret) + assert_equal(Set.new(1..10), set) + + ret = set.select! { |i| i % 3 != 0 } + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,4,5,7,8,10], set) +end + +assert("Set#merge") do + set = Set[1,2,3] + + ret = set.merge([2,4,6]) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,2,3,4,6], set) +end + +assert("Set#subtract") do + set = Set[1,2,3] + + ret = set.subtract([2,4,6]) + assert_true set.equal?(ret) # assert_same + assert_equal(Set[1,3], set) +end + +assert("Set#+") do + set = Set[1,2,3] + + ret = set + [2,4,6] + assert_false set.equal?(ret) # assert_not_same + assert_equal(Set[1,2,3,4,6], ret) +end + +assert("Set#-") do + set = Set[1,2,3] + + ret = set - [2,4,6] + assert_false set.equal?(ret) # assert_not_same + assert_equal(Set[1,3], ret) +end + +assert("Set#&") do + set = Set[1,2,3,4] + + ret = set & [2,4,6] + assert_false set.equal?(ret) # assert_not_same + assert_equal(Set[2,4], ret) +end + +assert("Set#^") do + set = Set[1,2,3,4] + + ret = set ^ [2,4,5,5] + assert_false set.equal?(ret) # assert_not_same + assert_equal(Set[1,3,5], ret) +end + +assert("Set#==") do + set1 = Set[2,3,1] + set2 = Set[1,2,3] + + assert_equal(set1, set1) + assert_equal(set1, set2) + assert_not_equal(Set[1], [1]) + + set1 = Class.new(Set)["a", "b"] + set2 = Set["a", "b", set1] + set1 = set1.add(set1.clone) + + assert_equal(set2, set2.clone) + assert_equal(set1.clone, set1) +end + +assert("Set#classify") do + set = Set.new(1..10) + ret = set.classify { |i| i % 3 } + + assert_equal(3, ret.size) + assert_equal(Hash, ret.class) + ret.each_value { |v| assert_equal(Set, v.class) } + assert_equal(Set[3,6,9], ret[0]) + assert_equal(Set[1,4,7,10], ret[1]) + assert_equal(Set[2,5,8], ret[2]) +end + +assert("Set#divide") do + # arity is 1 + set = Set.new(1..10) + ret = set.divide { |i| i % 3 } + + assert_equal(3, ret.size) + n = 0 + ret.each { |s| n += s.size } + assert_equal(set.size, n) + assert_equal(set, ret.flatten) + + assert_equal(Set, ret.class) + assert_true(ret.include?(Set[3,6,9])) + assert_true(ret.include?(Set[1,4,7,10])) + assert_true(ret.include?(Set[2,5,8])) + + + # arity is 2 + set = Set[7,10,5,11,1,3,4,9,0] + assert_raise(NotImplementedError) { + ret = set.divide { |a, b| (a - b).abs == 1 } + } + + # assert_equal(4, ret.size) + # n = 0 + # ret.each { |s| n += s.size } + # assert_equal(set.size, n) + # assert_equal(set, ret.flatten) + + # assert_equal(Set, ret.class) +end + +# freeze is not implemented yet +#assert("freeze") do +# orig = set = Set[1,2,3] +# assert_equal false, set.frozen? +# set << 4 +# assert_same orig, set.freeze +# assert_equal true, set.frozen? +# assert_raise(RuntimeError) { +# set << 5 +# } +# assert_equal 4, set.size +#end +# assert("freeze_dup") do +# set1 = Set[1,2,3] +# set1.freeze +# set2 = set1.dup +# +# assert_not_predicate set2, :frozen? +# assert_nothing_raised { +# set2.add 4 +# } +# end +# assert("reeze_clone") do +# set1 = Set[1,2,3] +# set1.freeze +# set2 = set1.clone +# +# assert_predicate set2, :frozen? +# assert_raise(RuntimeError) { +# set2.add 5 +# } +# end +# +assert("Set#inspect") do + set = Set[1,2,3] + assert_equal("#", set.inspect) +end diff --git a/mruby/mrbgems/mruby-sleep/README.md b/mruby/mrbgems/mruby-sleep/README.md index ed9c2730..ff24a20f 100644 --- a/mruby/mrbgems/mruby-sleep/README.md +++ b/mruby/mrbgems/mruby-sleep/README.md @@ -4,7 +4,7 @@ mruby sleep module ## Install by mrbgems -* add `conf.gem` line to your build configuration. +- add `conf.gem` line to your build configuration. ```ruby MRuby::Build.new do |conf| @@ -26,4 +26,4 @@ usleep(10000) under the MIT License: -* +- diff --git a/mruby/mrbgems/mruby-sleep/src/sleep.c b/mruby/mrbgems/mruby-sleep/src/sleep.c index 79a5af65..d05bc194 100644 --- a/mruby/mrbgems/mruby-sleep/src/sleep.c +++ b/mruby/mrbgems/mruby-sleep/src/sleep.c @@ -95,7 +95,7 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self) if (usec >= 0) { usleep(usec); } else { - mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative integer"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative"); } #ifdef _WIN32 diff --git a/mruby/mrbgems/mruby-socket/README.md b/mruby/mrbgems/mruby-socket/README.md index 8084cdb7..f88ae350 100644 --- a/mruby/mrbgems/mruby-socket/README.md +++ b/mruby/mrbgems/mruby-socket/README.md @@ -20,17 +20,17 @@ Date: Tue, 21 May 2013 04:31:30 GMT ## Requirement -* [mruby-io](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-io) mrbgem -* [iij/mruby-mtest](https://github.com/iij/mruby-mtest) mrgbem to run tests -* system must have RFC3493 basic socket interface -* and some POSIX API... +- [mruby-io](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-io) mrbgem +- [iij/mruby-mtest](https://github.com/iij/mruby-mtest) mrgbem to run tests +- system must have RFC3493 basic socket interface +- and some POSIX API... ## TODO -* add missing methods -* write more tests -* fix possible descriptor leakage (see XXX comments) -* `UNIXSocket#recv_io` `UNIXSocket#send_io` +- add missing methods +- write more tests +- fix possible descriptor leakage (see XXX comments) +- `UNIXSocket#recv_io` `UNIXSocket#send_io` ## License diff --git a/mruby/mrbgems/mruby-socket/mrbgem.rake b/mruby/mrbgems/mruby-socket/mrbgem.rake index e5876135..dba00c64 100644 --- a/mruby/mrbgems/mruby-socket/mrbgem.rake +++ b/mruby/mrbgems/mruby-socket/mrbgem.rake @@ -3,7 +3,6 @@ MRuby::Gem::Specification.new('mruby-socket') do |spec| spec.authors = ['Internet Initiative Japan', 'mruby developers'] spec.summary = 'standard socket class' - spec.cc.include_paths << "#{build.root}/src" #spec.cc.defines << "HAVE_SA_LEN=0" # If Windows, use winsock diff --git a/mruby/mrbgems/mruby-socket/src/const.cstub b/mruby/mrbgems/mruby-socket/src/const.cstub index f176513b..592fe517 100644 --- a/mruby/mrbgems/mruby-socket/src/const.cstub +++ b/mruby/mrbgems/mruby-socket/src/const.cstub @@ -385,6 +385,21 @@ #if defined(SO_TYPE) define_const(SO_TYPE); #endif +#if defined(SO_INCOMING_CPU) + define_const(SO_INCOMING_CPU); +#endif +#if defined(SO_INCOMING_NAPI_ID) + define_const(SO_INCOMING_NAPI_ID); +#endif +#if defined(SO_RTABLE) + define_const(SO_RTABLE); +#endif +#if defined(SO_SETFIB) + define_const(SO_SETFIB); +#endif +#if defined(SO_USER_COOKIE) + define_const(SO_USER_COOKIE); +#endif #if defined(SOCK_DGRAM) define_const(SOCK_DGRAM); #endif @@ -457,3 +472,9 @@ #if defined(TCP_WINDOW_CLAMP) define_const(TCP_WINDOW_CLAMP); #endif +#if defined(TCP_KEEPALIVE) + define_const(TCP_KEEPALIVE); +#endif +#if defined(TCP_CONNECTION_INFO) + define_const(TCP_CONNECTION_INFO); +#endif diff --git a/mruby/mrbgems/mruby-socket/src/const.def b/mruby/mrbgems/mruby-socket/src/const.def index b54bb841..4275ed99 100644 --- a/mruby/mrbgems/mruby-socket/src/const.def +++ b/mruby/mrbgems/mruby-socket/src/const.def @@ -136,6 +136,11 @@ SO_SNDTIMEO SO_SPLICE SO_TIMESTAMP SO_TYPE +SO_INCOMING_CPU +SO_INCOMING_NAPI_ID +SO_RTABLE +SO_SETFIB +SO_USER_COOKIE SOCK_DGRAM SOCK_RAW @@ -163,3 +168,5 @@ TCP_QUICKACK TCP_SACK_ENABLE TCP_SYNCNT TCP_WINDOW_CLAMP +TCP_KEEPALIVE +TCP_CONNECTION_INFO diff --git a/mruby/mrbgems/mruby-socket/src/socket.c b/mruby/mrbgems/mruby-socket/src/socket.c index f0213ad3..a9ce33d2 100644 --- a/mruby/mrbgems/mruby-socket/src/socket.c +++ b/mruby/mrbgems/mruby-socket/src/socket.c @@ -38,6 +38,7 @@ #include "mruby/string.h" #include "mruby/variable.h" #include "mruby/error.h" +#include "mruby/internal.h" #include "mruby/presym.h" #include "mruby/ext/io.h" @@ -52,12 +53,6 @@ #define E_SOCKET_ERROR mrb_class_get_id(mrb, MRB_SYM(SocketError)) -#if !defined(mrb_cptr) -#define mrb_cptr_value(m,p) mrb_voidp_value((m),(p)) -#define mrb_cptr(o) mrb_voidp(o) -#define mrb_cptr_p(o) mrb_voidp_p(o) -#endif - #ifdef _WIN32 static const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { @@ -262,10 +257,12 @@ sa2addrlist(mrb_state *mrb, const struct sockaddr *sa, socklen_t salen) return ary; } +int mrb_io_fileno(mrb_state *mrb, mrb_value io); + static int socket_fd(mrb_state *mrb, mrb_value sock) { - return (int)mrb_integer(mrb_funcall_id(mrb, sock, MRB_SYM(fileno), 0)); + return mrb_io_fileno(mrb, sock); } static int @@ -468,9 +465,10 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self) } else if (argc == 1) { if (strcmp(mrb_obj_classname(mrb, so), "Socket::Option") != 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "not an instance of Socket::Option"); - level = mrb_integer(mrb_funcall_id(mrb, so, MRB_SYM(level), 0)); - optname = mrb_integer(mrb_funcall_id(mrb, so, MRB_SYM(optname), 0)); + level = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(level), 0)); + optname = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(optname), 0)); optval = mrb_funcall_id(mrb, so, MRB_SYM(data), 0); + mrb_ensure_string_type(mrb, optval); } else { mrb_argnum_error(mrb, argc, 3, 3); } @@ -515,9 +513,8 @@ mrb_ipsocket_ntop(mrb_state *mrb, mrb_value klass) char buf[50]; mrb_get_args(mrb, "is", &af, &addr, &n); - if ((af == AF_INET && n != 4) || (af == AF_INET6 && n != 16)) - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); - if (inet_ntop((int)af, addr, buf, sizeof(buf)) == NULL) + if ((af == AF_INET && n != 4) || (af == AF_INET6 && n != 16) || + inet_ntop((int)af, addr, buf, sizeof(buf)) == NULL) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); return mrb_str_new_cstr(mrb, buf); } @@ -530,8 +527,7 @@ mrb_ipsocket_pton(mrb_state *mrb, mrb_value klass) char buf[50]; mrb_get_args(mrb, "is", &af, &bp, &n); - if ((size_t)n > sizeof(buf) - 1) - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); + if ((size_t)n > sizeof(buf) - 1) goto invalid; memcpy(buf, bp, n); buf[n] = '\0'; @@ -623,7 +619,7 @@ mrb_socket_accept2(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "i", &s0); socklen = sizeof(struct sockaddr_storage); - sastr = mrb_str_new_capa(mrb, socklen); + sastr = mrb_str_new_capa(mrb, (mrb_int)socklen); s1 = (int)accept(s0, (struct sockaddr *)RSTRING_PTR(sastr), &socklen); if (s1 == -1) { mrb_sys_fail(mrb, "accept"); diff --git a/mruby/mrbgems/mruby-sprintf/src/sprintf.c b/mruby/mrbgems/mruby-sprintf/src/sprintf.c index 8de3a454..71a3e90d 100644 --- a/mruby/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mruby/mrbgems/mruby-sprintf/src/sprintf.c @@ -110,7 +110,7 @@ mrb_uint_to_cstr(char *buf, size_t len, mrb_int num, int base) #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) +fmt_float(char *buf, size_t buf_size, char fmt, int flags, int width, int prec, mrb_float f) { char sign = '\0'; int left_align = 0; @@ -153,12 +153,14 @@ fmt_float(char *buf, size_t buf_size, char fmt, int flags, mrb_int width, int pr } #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;\ +#define CHECK(l) do { \ + if (blen+(l) >= bsiz) {\ + while (blen+(l) >= bsiz) {\ + if (bsiz > MRB_INT_MAX/2) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier");\ + bsiz*=2;\ + }\ + mrb_str_resize(mrb, result, bsiz);\ }\ - mrb_str_resize(mrb, result, bsiz);\ buf = RSTRING_PTR(result);\ } while (0) @@ -235,7 +237,7 @@ check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len) #define GETNUM(n, val) do { \ if (!(p = get_num(mrb, p, end, &(n)))) \ - mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big 1"); \ + mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \ } while(0) #define GETASTER(num) do { \ @@ -249,15 +251,17 @@ check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len) tmp_v = GETNEXTARG(); \ p = t; \ } \ - num = mrb_as_int(mrb, tmp_v); \ + num = (int)mrb_as_int(mrb, tmp_v); \ } while (0) -static const char * +static const char* get_num(mrb_state *mrb, const char *p, const char *end, int *valp) { char *e; - mrb_int n = mrb_int_read(p, end, &e); - if (e == NULL || n > INT_MAX) return NULL; + mrb_int n; + if (!mrb_read_int(p, end, &e, &n) || INT_MAX < n) { + return NULL; + } *valp = (int)n; return e; } @@ -584,8 +588,8 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm mrb_raise(mrb, E_ARGUMENT_ERROR, "flag after precision"); \ } - ++argc; - --argv; + argc++; + argv--; mrb_ensure_string_type(mrb, fmt); p = RSTRING_PTR(fmt); end = p + RSTRING_LEN(fmt); @@ -601,7 +605,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm int flags = FNONE; for (t = p; t < end && *t != '%'; t++) ; - if (t + 1 == end) ++t; + if (t + 1 == end) t++; PUSH(p, t - p); if (t >= end) goto sprint_exit; /* end of fmt string */ @@ -766,7 +770,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); } c = RSTRING_PTR(tmp); - n = RSTRING_LEN(tmp); + n = (int)RSTRING_LEN(tmp); if (!(flags & FWIDTH)) { PUSH(c, n); } @@ -842,7 +846,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm char sc = 0; mrb_int v = 0; int base; - mrb_int len; + int len; if (flags & FSHARP) { switch (*p) { @@ -920,7 +924,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm size_t size; size = strlen(s); /* PARANOID: assert(size <= MRB_INT_MAX) */ - len = (mrb_int)size; + len = (int)size; } if (*p == 'X') { @@ -953,7 +957,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm size = strlen(prefix); /* PARANOID: assert(size <= MRB_INT_MAX). * this check is absolutely paranoid. */ - width -= (mrb_int)size; + width -= (int)size; } if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) { @@ -1002,12 +1006,14 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm } break; -#ifndef MRB_NO_FLOAT case 'f': case 'g': case 'G': case 'e': case 'E': { +#ifdef MRB_NO_FLOAT + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%%%c not supported with MRB_NO_FLOAT defined", *p); +#else mrb_value val = GETARG(); double fval; mrb_int need = 6; @@ -1015,7 +1021,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm fval = mrb_as_float(mrb, val); if (!isfinite(fval)) { const char *expr; - const mrb_int elen = 3; + const int elen = 3; char sign = '\0'; if (isnan(fval)) { @@ -1030,7 +1036,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm else if (flags & (FPLUS|FSPACE)) sign = (flags & FPLUS) ? '+' : ' '; if (sign) - ++need; + need++; if ((flags & FWIDTH) && need < width) need = width; @@ -1046,7 +1052,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm else { if (sign) buf[blen - elen - 1] = sign; - memcpy(&buf[blen - elen], expr, elen); + memcpy(&buf[blen - elen], expr, (size_t)elen); } break; } @@ -1066,7 +1072,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm need += (flags&FPREC) ? prec : 6; if ((flags&FWIDTH) && need < width) need = width; - if (need > MRB_INT_MAX - 20) { + if ((mrb_int)need > MRB_INT_MAX - 20) { goto too_big_width_prec; } need += 20; @@ -1077,9 +1083,9 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); } blen += n; +#endif } break; -#endif } flags = FNONE; } @@ -1091,7 +1097,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm if (posarg >= 0 && nextarg < argc) { const char *mesg = "too many arguments for format string"; if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg); - if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%s", mesg); + if (mrb_test(ruby_verbose)) mrb_warn(mrb, mesg); } #endif mrb_str_resize(mrb, result, blen); diff --git a/mruby/mrbgems/mruby-string-ext/mrblib/string.rb b/mruby/mrbgems/mruby-string-ext/mrblib/string.rb index d8fd120a..87f8ab9a 100644 --- a/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mruby/mrbgems/mruby-string-ext/mrblib/string.rb @@ -273,7 +273,7 @@ def rjust(idx, padstr = ' ') # call-seq: # str.center(width, padstr=' ') -> new_str # - # Centers +str+ in +width+. If +width+ is greater than the length of +str+, + # Centers +str+ in +width+. If +width+ is greater than the length of +str+, # returns a new String of length +width+ with +str+ centered and padded with # +padstr+; otherwise, returns +str+. # @@ -334,8 +334,12 @@ def codepoints(&block) # a = "world" # a.prepend("hello ") #=> "hello world" # a #=> "hello world" - def prepend(arg) - self[0, 0] = arg + def prepend(*args) + len = args.size + while len > 0 + len -= 1 + self[0, 0] = args[len] + end self end @@ -368,7 +372,7 @@ def lines(&blk) # Iterates through successive values, starting at str and # ending at other_str inclusive, passing each value in turn to # the block. The String#succ method is used to generate - # each value. If optional second argument exclusive is omitted or is false, + # each value. If optional second argument exclusive is omitted or is false, # the last value will be included; otherwise it will be excluded. # # If no block is given, an enumerator is returned instead. diff --git a/mruby/mrbgems/mruby-string-ext/src/string.c b/mruby/mrbgems/mruby-string-ext/src/string.c index 8360a051..881409ad 100644 --- a/mruby/mrbgems/mruby-string-ext/src/string.c +++ b/mruby/mrbgems/mruby-string-ext/src/string.c @@ -4,6 +4,7 @@ #include #include #include +#include #define ENC_ASCII_8BIT "ASCII-8BIT" #define ENC_BINARY "BINARY" @@ -12,10 +13,6 @@ #define ENC_COMP_P(enc, enc_lit) \ str_casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1) -#ifdef MRB_NO_FLOAT -# define mrb_float_p(o) FALSE -#endif - static mrb_bool str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) { @@ -26,8 +23,8 @@ str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) e2 = s2 + len2; while (s1 < e1 && s2 < e2) { if (*s1 != *s2 && TOUPPER(*s1) != TOUPPER(*s2)) return FALSE; - ++s1; - ++s2; + s1++; + s2++; } return TRUE; } @@ -145,27 +142,9 @@ mrb_str_swapcase(mrb_state *mrb, mrb_value self) return str; } -/* - * call-seq: - * str << integer -> str - * str.concat(integer) -> str - * str << obj -> str - * str.concat(obj) -> str - * - * Append---Concatenates the given object to str. If the object is a - * Integer, it is considered as a codepoint, and is converted - * to a character before concatenation - * (equivalent to str.concat(integer.chr(__ENCODING__))). - * - * a = "hello " - * a << "world" #=> "hello world" - * a.concat(33) #=> "hello world!" - */ -static mrb_value -mrb_str_concat_m(mrb_state *mrb, mrb_value self) +static void +str_concat(mrb_state *mrb, mrb_value self, mrb_value str) { - mrb_value str = mrb_get_arg1(mrb); - if (mrb_integer_p(str) || mrb_float_p(str)) #ifdef MRB_UTF8_STRING str = int_chr_utf8(mrb, str); @@ -175,6 +154,39 @@ mrb_str_concat_m(mrb_state *mrb, mrb_value self) else mrb_ensure_string_type(mrb, str); mrb_str_cat_str(mrb, self, str); +} + +/* + * call-seq: + * str << obj -> str + * str.concat(*obj) -> str + * + * s = 'foo' + * s.concat('bar', 'baz') # => "foobarbaz" + * s # => "foobarbaz" + * + * For each given object +object+ that is an \Integer, + * the value is considered a codepoint and converted to a character before concatenation: + * + * s = 'foo' + * s.concat(32, 'bar', 32, 'baz') # => "foo bar baz" + * + */ +static mrb_value +mrb_str_concat_m(mrb_state *mrb, mrb_value self) +{ + if (mrb_get_argc(mrb) == 1) { + str_concat(mrb, self, mrb_get_arg1(mrb)); + return self; + } + + mrb_value *args; + mrb_int alen; + + mrb_get_args(mrb, "*", &args, &alen); + for (mrb_int i=0; i 1 && (p[1] & 0xc0) == 0x80) { + len = mrb_utf8len_table[p[0]>>3]; + if (len <= limit && len > 1 && (p[1] & 0xc0) == 0x80) { if (len == 2) return ((p[0] & 0x1f) << 6) + (p[1] & 0x3f); if ((p[2] & 0xc0) == 0x80) { @@ -1020,20 +1022,10 @@ utf8code(unsigned char* p) if (len == 4) return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12) + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f); - if ((p[4] & 0xc0) == 0x80) { - if (len == 5) - return ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18) - + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6) - + (p[4] & 0x3f); - if ((p[5] & 0xc0) == 0x80 && len == 6) - return ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24) - + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12) - + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f); - } } } } - return p[0]; + return -1; } static mrb_value @@ -1041,7 +1033,9 @@ mrb_str_ord(mrb_state* mrb, mrb_value str) { if (RSTRING_LEN(str) == 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string"); - return mrb_fixnum_value(utf8code((unsigned char*) RSTRING_PTR(str))); + mrb_int c = utf8code((unsigned char*)RSTRING_PTR(str), RSTRING_LEN(str)); + if (c < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid UTF-8 byte sequence"); + return mrb_fixnum_value(c); } #else static mrb_value @@ -1245,6 +1239,45 @@ mrb_str_lines(mrb_state *mrb, mrb_value self) return result; } +/* + * call-seq: + * +string -> new_string or self + * + * Returns +self+ if +self+ is not frozen. + * + * Otherwise returns self.dup, which is not frozen. + */ +static mrb_value +mrb_str_uplus(mrb_state *mrb, mrb_value str) +{ + if (mrb_frozen_p(mrb_obj_ptr(str))) { + return mrb_str_dup(mrb, str); + } + else { + return str; + } +} + +/* + * call-seq: + * -string -> frozen_string + * + * Returns a frozen, possibly pre-existing copy of the string. + * + * The returned \String will be deduplicated as long as it does not have + * any instance variables set on it and is not a String subclass. + * + * String#dedup is an alias for String#-@. + */ +static mrb_value +mrb_str_uminus(mrb_state *mrb, mrb_value str) +{ + if (mrb_frozen_p(mrb_obj_ptr(str))) { + return str; + } + return mrb_obj_freeze(mrb, mrb_str_dup(mrb, str)); +} + void mrb_mruby_string_ext_gem_init(mrb_state* mrb) { @@ -1280,10 +1313,12 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) 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, "+@", mrb_str_uplus, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "-@", mrb_str_uminus, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "__lines", mrb_str_lines, MRB_ARGS_NONE()); - mrb_define_method(mrb, mrb_class_get(mrb, "Integer"), "chr", mrb_int_chr, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, mrb->integer_class, "chr", mrb_int_chr, MRB_ARGS_OPT(1)); } void diff --git a/mruby/mrbgems/mruby-string-ext/test/numeric.rb b/mruby/mrbgems/mruby-string-ext/test/numeric.rb index dfcb9ebf..f79235de 100644 --- a/mruby/mrbgems/mruby-string-ext/test/numeric.rb +++ b/mruby/mrbgems/mruby-string-ext/test/numeric.rb @@ -1,5 +1,3 @@ -# coding: utf-8 - assert('Integer#chr') do assert_equal("A", 65.chr) assert_equal("B", 0x42.chr) diff --git a/mruby/mrbgems/mruby-string-ext/test/string.rb b/mruby/mrbgems/mruby-string-ext/test/string.rb index 7be673aa..0400a8da 100644 --- a/mruby/mrbgems/mruby-string-ext/test/string.rb +++ b/mruby/mrbgems/mruby-string-ext/test/string.rb @@ -1,4 +1,3 @@ -# coding: utf-8 ## # String(Ext) Test @@ -713,3 +712,17 @@ def assert_upto(exp, receiver, *args) assert_equal "he", "hello".delete_suffix!("llo") assert_nil "hello".delete_suffix!("he") end + +assert('String#+@') do + a = +"abc" + assert_false(a.frozen?) + a = +(a.freeze) + assert_false(a.frozen?) +end + +assert('String#-@') do + a = -"abc" + assert_true(a.frozen?) + a = -(a.freeze) + assert_true(a.frozen?) +end diff --git a/mruby/mrbgems/mruby-struct/mrblib/struct.rb b/mruby/mrbgems/mruby-struct/mrblib/struct.rb index 2439e2a3..f80c5451 100644 --- a/mruby/mrbgems/mruby-struct/mrblib/struct.rb +++ b/mruby/mrbgems/mruby-struct/mrblib/struct.rb @@ -3,6 +3,7 @@ # # ISO 15.2.18 class Struct + include Enumerable ## # Calls the given block for each element of +self+ diff --git a/mruby/mrbgems/mruby-struct/src/struct.c b/mruby/mrbgems/mruby-struct/src/struct.c index 2d864bda..6dc0b5b0 100644 --- a/mruby/mrbgems/mruby-struct/src/struct.c +++ b/mruby/mrbgems/mruby-struct/src/struct.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define RSTRUCT_LEN(st) RARRAY_LEN(st) @@ -26,32 +27,30 @@ struct_class(mrb_state *mrb) return mrb_class_get_id(mrb, MRB_SYM(Struct)); } -static inline mrb_value -struct_ivar_get(mrb_state *mrb, mrb_value cls, mrb_sym id) +static void +struct_corrupted(mrb_state *mrb) { - struct RClass* c = mrb_class_ptr(cls); - struct RClass* sclass = struct_class(mrb); - mrb_value ans; - - for (;;) { - ans = mrb_iv_get(mrb, mrb_obj_value(c), id); - if (!mrb_nil_p(ans)) return ans; - c = c->super; - if (c == sclass || c == 0) - return mrb_nil_value(); - } + mrb_raise(mrb, E_TYPE_ERROR, "corrupted data"); } static mrb_value -struct_s_members(mrb_state *mrb, struct RClass *klass) +struct_s_members(mrb_state *mrb, struct RClass *c) { - mrb_value members = struct_ivar_get(mrb, mrb_obj_value(klass), MRB_SYM(__members__)); + struct RClass* sclass = struct_class(mrb); + mrb_value members; - if (mrb_nil_p(members)) { - mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct"); - } - if (!mrb_array_p(members)) { - mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); + for (;;) { + members = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__members__)); + if (!mrb_nil_p(members)) { + if (!mrb_array_p(members)) { + struct_corrupted(mrb); + } + break; + } + c = c->super; + if (c == sclass || c == 0) { + mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct"); + } } return members; } @@ -59,10 +58,10 @@ struct_s_members(mrb_state *mrb, struct RClass *klass) 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_struct_p(s) || RSTRUCT_LEN(s) == 0) { - mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); + struct_corrupted(mrb); } + mrb_value members = struct_s_members(mrb, mrb_obj_class(mrb, s)); if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%i required %i given)", @@ -82,12 +81,7 @@ mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass) return ary; } -static void -mrb_struct_modify(mrb_state *mrb, mrb_value strct) -{ - mrb_check_frozen(mrb, mrb_basic_ptr(strct)); - mrb_write_barrier(mrb, mrb_basic_ptr(strct)); -} +#define mrb_struct_modify(mrb,s) mrb_check_frozen((mrb), mrb_basic_ptr(s)) /* 15.2.18.4.6 */ /* @@ -161,6 +155,7 @@ mrb_struct_set_m(mrb_state *mrb, mrb_value obj) } else { ptr[i] = val; + mrb_field_write_barrier_value(mrb, mrb_basic_ptr(obj), val); } return val; } @@ -208,15 +203,14 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl mrb_warn(mrb, "redefining constant Struct::%v", name); mrb_const_remove(mrb, mrb_obj_value(klass), id); } - c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass); + c = mrb_define_class_under_id(mrb, klass, id, klass); } - MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT); nstr = mrb_obj_value(c); mrb_iv_set(mrb, nstr, MRB_SYM(__members__), members); - mrb_define_class_method(mrb, c, "new", mrb_instance_new, MRB_ARGS_ANY()); - mrb_define_class_method(mrb, c, "[]", mrb_instance_new, MRB_ARGS_ANY()); - mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, MRB_ARGS_NONE()); + mrb_define_class_method_id(mrb, c, MRB_SYM(new), mrb_instance_new, MRB_ARGS_ANY()); + mrb_define_class_method_id(mrb, c, MRB_OPSYM(aref), mrb_instance_new, MRB_ARGS_ANY()); + mrb_define_class_method_id(mrb, c, MRB_SYM(members), mrb_struct_s_members_m, MRB_ARGS_NONE()); /* RSTRUCT(nstr)->basic.c->super = c->c; */ make_struct_define_accessors(mrb, members, c); return nstr; @@ -306,12 +300,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass) static mrb_int num_members(mrb_state *mrb, struct RClass *klass) { - mrb_value members; - - members = struct_ivar_get(mrb, mrb_obj_value(klass), MRB_SYM(__members__)); - if (!mrb_array_p(members)) { - mrb_raise(mrb, E_TYPE_ERROR, "broken members"); - } + mrb_value members = struct_s_members(mrb, klass); return RARRAY_LEN(members); } @@ -360,7 +349,7 @@ mrb_struct_init_copy(mrb_state *mrb, mrb_value copy) mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } if (!mrb_struct_p(s)) { - mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); + struct_corrupted(mrb); } mrb_ary_replace(mrb, copy, s); return copy; @@ -387,17 +376,24 @@ struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id) return mrb_nil_value(); /* not reached */ } -static mrb_value -struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i) +static mrb_int +struct_index(mrb_state *mrb, mrb_int i, mrb_int len) { - mrb_int idx = i < 0 ? RSTRUCT_LEN(s) + i : i; + mrb_int idx = i < 0 ? len + i : i; if (idx < 0) mrb_raisef(mrb, E_INDEX_ERROR, - "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s)); - if (RSTRUCT_LEN(s) <= idx) + "offset %i too small for struct(size:%i)", i, len); + if (len <= idx) mrb_raisef(mrb, E_INDEX_ERROR, - "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s)); + "offset %i too large for struct(size:%i)", i, len); + return idx; +} + +static mrb_value +struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i) +{ + mrb_int idx = struct_index(mrb, i, RSTRUCT_LEN(s)); return RSTRUCT_PTR(s)[idx]; } @@ -450,6 +446,7 @@ mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) if (mrb_symbol(ptr_members[i]) == id) { mrb_struct_modify(mrb, s); ptr[i] = val; + mrb_field_write_barrier_value(mrb, mrb_basic_ptr(s), val); return val; } } @@ -496,17 +493,9 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) return mrb_struct_aset_sym(mrb, s, mrb_symbol(idx), val); } - i = mrb_as_int(mrb, idx); - if (i < 0) i = RSTRUCT_LEN(s) + i; - if (i < 0) { - mrb_raisef(mrb, E_INDEX_ERROR, - "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s)); - } - if (RSTRUCT_LEN(s) <= i) { - mrb_raisef(mrb, E_INDEX_ERROR, - "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s)); - } + i = struct_index(mrb, mrb_as_int(mrb, idx), RSTRUCT_LEN(s)); mrb_struct_modify(mrb, s); + mrb_field_write_barrier_value(mrb, mrb_basic_ptr(s), val); return RSTRUCT_PTR(s)[i] = val; } @@ -541,9 +530,7 @@ mrb_struct_equal(mrb_state *mrb, mrb_value s) if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) { return mrb_false_value(); } - if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) { - mrb_bug(mrb, "inconsistent struct"); /* should never happen */ - } + mrb_assert(RSTRUCT_LEN(s) == RSTRUCT_LEN(s2)); ptr = RSTRUCT_PTR(s); ptr2 = RSTRUCT_PTR(s2); len = RSTRUCT_LEN(s); @@ -558,7 +545,7 @@ mrb_struct_equal(mrb_state *mrb, mrb_value s) /* 15.2.18.4.12(x) */ /* - * code-seq: + * call-seq: * struct.eql?(other) -> true or false * * Two structures are equal if they are the same object, or if all their @@ -577,9 +564,7 @@ mrb_struct_eql(mrb_state *mrb, mrb_value s) if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) { return mrb_false_value(); } - if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) { - mrb_bug(mrb, "inconsistent struct"); /* should never happen */ - } + mrb_assert(RSTRUCT_LEN(s) == RSTRUCT_LEN(s2)); ptr = RSTRUCT_PTR(s); ptr2 = RSTRUCT_PTR(s2); len = RSTRUCT_LEN(s); @@ -633,7 +618,7 @@ mrb_struct_to_h(mrb_state *mrb, mrb_value self) members = struct_members(mrb, self); ret = mrb_hash_new_capa(mrb, RARRAY_LEN(members)); - for (i = 0; i < RARRAY_LEN(members); ++i) { + for (i = 0; i < RARRAY_LEN(members); i++) { mrb_hash_set(mrb, ret, RARRAY_PTR(members)[i], RSTRUCT_PTR(self)[i]); } @@ -671,7 +656,7 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) { struct RClass *st; st = mrb_define_class(mrb, "Struct", mrb->object_class); - MRB_SET_INSTANCE_TT(st, MRB_TT_ARRAY); + MRB_SET_INSTANCE_TT(st, MRB_TT_STRUCT); mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ @@ -683,12 +668,12 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) mrb_define_method(mrb, st, "initialize_copy", mrb_struct_init_copy, MRB_ARGS_REQ(1)); /* 15.2.18.4.9 */ mrb_define_method(mrb, st, "eql?", mrb_struct_eql, MRB_ARGS_REQ(1)); /* 15.2.18.4.12(x) */ - mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE()); - mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE()); - mrb_define_method(mrb, st, "to_a", mrb_struct_to_a, MRB_ARGS_NONE()); - mrb_define_method(mrb, st, "values", mrb_struct_to_a, MRB_ARGS_NONE()); - mrb_define_method(mrb, st, "to_h", mrb_struct_to_h, MRB_ARGS_NONE()); - mrb_define_method(mrb, st, "values_at", mrb_struct_values_at, MRB_ARGS_ANY()); + mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "to_a", mrb_struct_to_a, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "values", mrb_struct_to_a, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "to_h", mrb_struct_to_h, MRB_ARGS_NONE()); + mrb_define_method(mrb, st, "values_at", mrb_struct_values_at, MRB_ARGS_ANY()); } void diff --git a/mruby/mrbgems/mruby-symbol-ext/src/symbol.c b/mruby/mrbgems/mruby-symbol-ext/src/symbol.c index 460d2531..4340d74a 100644 --- a/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +++ b/mruby/mrbgems/mruby-symbol-ext/src/symbol.c @@ -1,6 +1,7 @@ #include #include #include +#include #ifdef MRB_USE_ALL_SYMBOLS # include #endif diff --git a/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb b/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb index a4fb2773..239f8c27 100644 --- a/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +++ b/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb @@ -1,4 +1,3 @@ -# coding: utf-8 ## # Symbol(Ext) Test diff --git a/mruby/mrbgems/mruby-test-inline-struct/test/inline.c b/mruby/mrbgems/mruby-test-inline-struct/test/inline.c index 7537bffc..a54bf2b0 100644 --- a/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +++ b/mruby/mrbgems/mruby-test-inline-struct/test/inline.c @@ -56,10 +56,18 @@ istruct_test_test_receive(mrb_state *mrb, mrb_value self) static mrb_value istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self) { - char *ptr; + mrb_value is; struct RClass *klass = mrb_class_get(mrb, "InlineStructTest"); - mrb_get_args(mrb, "I", &ptr, klass); - return mrb_bool_value(ptr[0] == 's'); + mrb_get_args(mrb, "o", &is); + /* if you need to protect istruct retrieval from untrusted code, + you need to care about class replacing. + See mrbgem/mruby-random/src/random.c for detail */ + if (mrb_istruct_p(is) && mrb_obj_is_kind_of(mrb, is, klass)) { + char *ptr = (char*)mrb_istruct_ptr(is); + return mrb_bool_value(ptr[0] == 's'); + } + mrb_raise(mrb, E_TYPE_ERROR, "InlineStructTest"); + return mrb_false_value(); } static mrb_value diff --git a/mruby/mrbgems/mruby-test/README.md b/mruby/mrbgems/mruby-test/README.md index 86b1ce05..7c6647dd 100644 --- a/mruby/mrbgems/mruby-test/README.md +++ b/mruby/mrbgems/mruby-test/README.md @@ -1,5 +1,4 @@ -Running Tests -============= +# Running Tests To run the tests, execute the following from the project's root directory. diff --git a/mruby/mrbgems/mruby-test/driver.c b/mruby/mrbgems/mruby-test/driver.c index 21e27253..0ccba9ea 100644 --- a/mruby/mrbgems/mruby-test/driver.c +++ b/mruby/mrbgems/mruby-test/driver.c @@ -55,7 +55,7 @@ t_print(mrb_state *mrb, mrb_value self) mrb_int i; mrb_get_args(mrb, "*!", &argv, &argc); - for (i = 0; i < argc; ++i) { + for (i = 0; i < argc; i++) { mrb_value s = mrb_obj_as_string(mrb, argv[i]); fwrite(RSTRING_PTR(s), RSTRING_LEN(s), 1, stdout); } @@ -76,7 +76,7 @@ str_match_bracket(const char *p, const char *pat_end, if (p == pat_end) return NULL; if (*p == '!' || *p == '^') { negated = TRUE; - ++p; + p++; } while (*p != ']') { @@ -109,7 +109,7 @@ str_match_no_brace_p(const char *pat, mrb_int pat_len, if (p == pat_end) return s == str_end; switch (*p) { case '*': - do { ++p; } while (p != pat_end && *p == '*'); + do { p++; } while (p != pat_end && *p == '*'); if (UNESCAPE(p, pat_end) == pat_end) return TRUE; if (s == str_end) return FALSE; p_tmp = p; @@ -117,15 +117,15 @@ str_match_no_brace_p(const char *pat, mrb_int pat_len, continue; case '?': if (s == str_end) return FALSE; - ++p; - ++s; + p++; + s++; continue; case '[': { const char *t; if (s == str_end) return FALSE; if ((t = str_match_bracket(p+1, pat_end, s, str_end))) { p = t; - ++s; + s++; continue; } goto L_failed; @@ -164,7 +164,7 @@ str_match_p(mrb_state *mrb, int nest = 0; mrb_bool ret = FALSE; - for (; p != pat_end; ++p) { + for (; p != pat_end; p++) { if (*p == '{' && nest++ == 0) lbrace = p; else if (*p == '}' && lbrace && --nest == 0) { rbrace = p; break; } else if (*p == '\\' && ++p == pat_end) break; @@ -180,9 +180,9 @@ str_match_p(mrb_state *mrb, while (p < rbrace) { char *orig_ex_p = ex_p; const char *t = ++p; - for (nest = 0; p < rbrace && !(*p == ',' && nest == 0); ++p) { - if (*p == '{') ++nest; - else if (*p == '}') --nest; + for (nest = 0; p < rbrace && !(*p == ',' && nest == 0); p++) { + if (*p == '{') nest++; + else if (*p == '}') nest--; else if (*p == '\\' && ++p == rbrace) break; } COPY_AND_INC(ex_p, t, p-t); @@ -271,8 +271,9 @@ mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src) if (mrb_array_p(res_src)) { mrb_int i; mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$asserts")); - for (i = 0; i < RARRAY_LEN(res_src); ++i) { + for (i = 0; i < RARRAY_LEN(res_src); i++) { mrb_value val_src = RARRAY_PTR(res_src)[i]; + mrb_ensure_string_type(mrb_dst, val_src); mrb_ary_push(mrb_dst, res_dst, mrb_str_new(mrb_dst, RSTRING_PTR(val_src), RSTRING_LEN(val_src))); } } @@ -290,7 +291,7 @@ main(int argc, char **argv) /* new interpreter instance */ mrb = mrb_open(); if (mrb == NULL) { - fprintf(stderr, "Invalid mrb_state, exiting test driver"); + fputs("Invalid mrb_state, exiting test driver", stderr); return EXIT_FAILURE; } diff --git a/mruby/mrbgems/mruby-time/src/time.c b/mruby/mrbgems/mruby-time/src/time.c index 6b9762ac..63a9d252 100644 --- a/mruby/mrbgems/mruby-time/src/time.c +++ b/mruby/mrbgems/mruby-time/src/time.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #ifdef MRB_NO_STDIO @@ -459,7 +460,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, #define OUTINT(x) 0 #endif - if (OUTINT(ayear-1900) || + if (ayear < 1900 || OUTINT(ayear-1900) || amonth < 1 || amonth > 12 || aday < 1 || aday > 31 || ahour < 0 || ahour > 24 || @@ -476,14 +477,21 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, nowtime.tm_sec = (int)asec; nowtime.tm_isdst = -1; + time_t (*mk)(struct tm*); if (timezone == MRB_TIMEZONE_UTC) { - nowsecs = timegm(&nowtime); + mk = timegm; } else { - nowsecs = mktime(&nowtime); + mk = mktime; } + nowsecs = (*mk)(&nowtime); if (nowsecs == (time_t)-1) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time"); + nowtime.tm_sec += 1; /* maybe Epoch-1 sec */ + nowsecs = (*mk)(&nowtime); + if (nowsecs != 0) { /* check if Epoch */ + mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time"); + } + nowsecs = (time_t)-1; /* valid Epoch-1 */ } return time_alloc_time(mrb, nowsecs, ausec, timezone); @@ -997,13 +1005,23 @@ mrb_time_to_s(mrb_state *mrb, mrb_value self) return str; } +static mrb_value +mrb_time_hash(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm = time_get_ptr(mrb, self); + uint32_t hash = mrb_byte_hash((uint8_t*)&tm->sec, sizeof(time_t)); + hash = mrb_byte_hash_step((uint8_t*)&tm->usec, sizeof(time_t), hash); + hash = mrb_byte_hash_step((uint8_t*)&tm->timezone, sizeof(tm->timezone), hash); + return mrb_int_value(mrb, hash); +} + void mrb_mruby_time_gem_init(mrb_state* mrb) { struct RClass *tc; /* ISO 15.2.19.2 */ tc = mrb_define_class(mrb, "Time", mrb->object_class); - MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); + MRB_SET_INSTANCE_TT(tc, MRB_TT_CDATA); mrb_include_module(mrb, tc, mrb_module_get(mrb, "Comparable")); mrb_define_class_method(mrb, tc, "at", mrb_time_at_m, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */ mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */ @@ -1012,6 +1030,8 @@ mrb_mruby_time_gem_init(mrb_state* mrb) mrb_define_class_method(mrb, tc, "now", mrb_time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */ mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */ + mrb_define_method(mrb, tc, "hash" , mrb_time_hash , MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "eql?" , mrb_time_eq , MRB_ARGS_REQ(1)); mrb_define_method(mrb, tc, "==" , mrb_time_eq , MRB_ARGS_REQ(1)); mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */ mrb_define_method(mrb, tc, "+" , mrb_time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */ diff --git a/mruby/mrbgems/mruby-time/test/time.rb b/mruby/mrbgems/mruby-time/test/time.rb index e239dec2..2c3a354f 100644 --- a/mruby/mrbgems/mruby-time/test/time.rb +++ b/mruby/mrbgems/mruby-time/test/time.rb @@ -267,7 +267,3 @@ end assert_equal(0, t.usec) end - -assert('Time.gm with Dec 31 23:59:59 1969 raise ArgumentError') do - assert_raise(ArgumentError) {Time.gm(1969, 12, 31, 23, 59, 59)} -end diff --git a/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb b/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb index 664008d1..52d1809f 100644 --- a/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +++ b/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb @@ -1,4 +1,3 @@ - def self.include(*modules) self.class.include(*modules) end diff --git a/mruby/mrbgems/stdlib-ext.gembox b/mruby/mrbgems/stdlib-ext.gembox index 2177dca3..29157dc6 100644 --- a/mruby/mrbgems/stdlib-ext.gembox +++ b/mruby/mrbgems/stdlib-ext.gembox @@ -13,6 +13,9 @@ MRuby::GemBox.new do |conf| # Use standard Struct class conf.gem :core => "mruby-struct" + # Use standard Data class + conf.gem :core => "mruby-data" + # Use Random class conf.gem :core => "mruby-random" end diff --git a/mruby/mrbgems/stdlib-io.gembox b/mruby/mrbgems/stdlib-io.gembox index cd1c2049..38449216 100644 --- a/mruby/mrbgems/stdlib-io.gembox +++ b/mruby/mrbgems/stdlib-io.gembox @@ -9,4 +9,10 @@ MRuby::GemBox.new do |conf| # Use standard print/puts/p conf.gem :core => "mruby-print" + + # Use errno extension for a good mruby-io/mruby-socket experience + conf.gem :core => "mruby-errno" + + # Use Dir class + conf.gem :core => "mruby-dir" end diff --git a/mruby/mrbgems/stdlib.gembox b/mruby/mrbgems/stdlib.gembox index 72fb9e34..a4d01af1 100644 --- a/mruby/mrbgems/stdlib.gembox +++ b/mruby/mrbgems/stdlib.gembox @@ -34,6 +34,9 @@ MRuby::GemBox.new do |conf| # Use ObjectSpace class conf.gem :core => "mruby-objectspace" + # Use Set class + conf.gem :core => "mruby-set" + # Use Fiber class conf.gem :core => "mruby-fiber" diff --git a/mruby/mrblib/00class.rb b/mruby/mrblib/00class.rb index d7a718ba..5bef3f12 100644 --- a/mruby/mrblib/00class.rb +++ b/mruby/mrblib/00class.rb @@ -22,7 +22,8 @@ def attr_accessor(*names) # 15.2.2.4.27 def include(*args) - args.reverse.each do |m| + args.reverse! + args.each do |m| m.append_features(self) m.included(self) end @@ -30,7 +31,8 @@ def include(*args) end def prepend(*args) - args.reverse.each do |m| + args.reverse! + args.each do |m| m.prepend_features(self) m.prepended(self) end diff --git a/mruby/mrblib/00kernel.rb b/mruby/mrblib/00kernel.rb new file mode 100644 index 00000000..02f3a998 --- /dev/null +++ b/mruby/mrblib/00kernel.rb @@ -0,0 +1,35 @@ +module Kernel + ## + # call-seq: + # obj.extend(module, ...) -> obj + # + # Adds to _obj_ the instance methods from each module given as a + # parameter. + # + # module Mod + # def hello + # "Hello from Mod.\n" + # end + # end + # + # class Klass + # def hello + # "Hello from Klass.\n" + # end + # end + # + # k = Klass.new + # k.hello #=> "Hello from Klass.\n" + # k.extend(Mod) #=> # + # k.hello #=> "Hello from Mod.\n" + # + # ISO 15.3.1.3.13 + def extend(*args) + args.reverse! + args.each do |m| + m.extend_object(self) + m.extended(self) + end + self + end +end diff --git a/mruby/mrblib/10error.rb b/mruby/mrblib/10error.rb index aa9da91b..431f7780 100644 --- a/mruby/mrblib/10error.rb +++ b/mruby/mrblib/10error.rb @@ -1,3 +1,16 @@ +class Exception + ## + # call-seq: + # exception.message -> string + # + # Returns the result of invoking exception.to_s. + # Normally this returns the exception's message or name. + # + def message + to_s + end +end + # ISO 15.2.24 class ArgumentError < StandardError end diff --git a/mruby/mrblib/array.rb b/mruby/mrblib/array.rb index 6b4f74b9..af3c17cb 100644 --- a/mruby/mrblib/array.rb +++ b/mruby/mrblib/array.rb @@ -1,10 +1,13 @@ -# coding: utf-8 ## # Array # # ISO 15.2.12 class Array ## + # call-seq: + # array.each {|element| ... } -> self + # array.each -> Enumerator + # # Calls the given block for each element of +self+ # and pass the respective element. # @@ -21,6 +24,10 @@ def each(&block) end ## + # call-seq: + # array.each_index {|index| ... } -> self + # array.each_index -> Enumerator + # # Calls the given block for each element of +self+ # and pass the index of the respective element. # @@ -37,6 +44,10 @@ def each_index(&block) end ## + # call-seq: + # array.collect! {|element| ... } -> self + # array.collect! -> new_enumerator + # # Calls the given block for each element of +self+ # and pass the respective element. Each element will # be replaced by the resulting values. @@ -55,6 +66,10 @@ def collect!(&block) end ## + # call-seq: + # array.map! {|element| ... } -> self + # array.map! -> new_enumerator + # # Alias for collect! # # ISO 15.2.12.5.20 @@ -102,19 +117,19 @@ def _inspect(recur_list) ## # Return the contents of this array as a string. # - # ISO 15.2.12.5.31 (x) def inspect self._inspect({}) end - # ISO 15.2.12.5.32 (x) alias to_s inspect ## + # call-seq: + # array == other -> true or false + # # Equality---Two arrays are equal if they contain the same number # of elements and if each element is equal to (according to # Object.==) the corresponding element in the other array. # - # ISO 15.2.12.5.33 (x) def ==(other) other = self.__ary_eq(other) return false if other == false @@ -129,10 +144,12 @@ def ==(other) end ## + # call-seq: + # array.eql? other_array -> true or false + # # Returns true if +self+ and _other_ are the same object, # or are both arrays with the same content. # - # ISO 15.2.12.5.34 (x) def eql?(other) other = self.__ary_eq(other) return false if other == false @@ -147,17 +164,19 @@ def eql?(other) end ## + # call-seq: + # array <=> other_array -> -1, 0, or 1 + # # Comparison---Returns an integer (-1, 0, or +1) # if this array is less than, equal to, or greater than other_ary. # Each object in each array is compared (using <=>). If any value isn't # equal, then that inequality is the return value. If all the # values found are equal, then the return is based on a - # comparison of the array lengths. Thus, two arrays are + # comparison of the array lengths. Thus, two arrays are # "equal" according to Array#<=> if and only if they have # the same length and the value of each element is equal to the # value of the corresponding element in the other array. # - # ISO 15.2.12.5.36 (x) def <=>(other) other = self.__ary_cmp(other) return 0 if 0 == other @@ -167,10 +186,14 @@ def <=>(other) n = other.size len = n if len > n i = 0 - while i < len - n = (self[i] <=> other[i]) - return n if n.nil? || n != 0 - i += 1 + begin + while i < len + n = (self[i] <=> other[i]) + return n if n.nil? || n != 0 + i += 1 + end + rescue NoMethodError + return nil end len = self.size - other.size if len == 0 @@ -183,6 +206,10 @@ def <=>(other) end ## + # call-seq: + # array.delete(obj) -> deleted_object + # array.delete(obj) {|nosuch| ... } -> deleted_object or block_return + # # Delete element with index +key+ def delete(key, &block) while i = self.index(key) @@ -194,6 +221,10 @@ def delete(key, &block) end ## + # call-seq: + # array.sort! -> self + # array.sort! {|a, b| ... } -> self + # # Sort all elements and replace +self+ with these # elements. def sort!(&block) @@ -227,7 +258,7 @@ def sort!(&block) lsize = lary.size # The entity sharing between lary and self may cause a large memory - # copy operation in the merge loop below. This harmless operation + # copy operation in the merge loop below. This harmless operation # cancels the sharing and provides a huge performance gain. lary[0] = lary[0] @@ -261,10 +292,21 @@ def sort!(&block) self end + ## + # call-seq: + # array.sort -> new_array + # array.sort {|a, b| ... } -> new_array + # + # Returns a new Array whose elements are those from +self+, sorted. def sort(&block) self.dup.sort!(&block) end + ## + # call-seq: + # array.to_a -> self + # + # Returns self, no need to convert. def to_a self end diff --git a/mruby/mrblib/compar.rb b/mruby/mrblib/compar.rb index 84b96259..b39d619f 100644 --- a/mruby/mrblib/compar.rb +++ b/mruby/mrblib/compar.rb @@ -5,6 +5,9 @@ module Comparable ## + # call-seq: + # obj < other -> true or false + # # Return true if +self+ is less # than +other+. Otherwise return # false. @@ -19,6 +22,9 @@ def < other end ## + # call-seq: + # obj <= other -> true or false + # # Return true if +self+ is less # than or equal to +other+. # Otherwise return false. @@ -33,6 +39,9 @@ def <= other end ## + # call-seq: + # obj == other -> true or false + # # Return true if +self+ is equal # to +other+. Otherwise return # false. @@ -44,6 +53,9 @@ def == other end ## + # call-seq: + # obj > other -> true or false + # # Return true if +self+ is greater # than +other+. Otherwise return # false. @@ -58,6 +70,9 @@ def > other end ## + # call-seq: + # obj >= other -> true or false + # # Return true if +self+ is greater # than or equal to +other+. # Otherwise return false. @@ -72,6 +87,9 @@ def >= other end ## + # call-seq: + # obj.between?(min,max) -> true or false + # # Return true if +self+ is greater # than or equal to +min+ and # less than or equal to +max+. diff --git a/mruby/mrblib/hash.rb b/mruby/mrblib/hash.rb index ac70f4c7..bfec4c2a 100644 --- a/mruby/mrblib/hash.rb +++ b/mruby/mrblib/hash.rb @@ -10,6 +10,9 @@ class Hash include Enumerable ## + # call-seq: + # hash == object -> true or false + # # 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 # Object#==) the corresponding elements in the other @@ -30,10 +33,12 @@ def ==(hash) end ## + # call-seq: + # hash.eql? object -> true or false + # # Returns true if hash and other are # both hashes with the same content compared by eql?. # - # ISO 15.2.13.4.32 (x) def eql?(hash) return true if self.equal?(hash) unless Hash === hash @@ -48,6 +53,10 @@ def eql?(hash) end ## + # call-seq: + # hash.delete(key) -> value or nil + # hash.delete(key) {|key| ... } -> object + # # Delete the element with the key +key+. # Return the value of the element if +key+ # was found. Return nil if nothing was @@ -63,15 +72,14 @@ def delete(key, &block) end ## - # Calls the given block for each element of +self+ - # and pass the key and value of each element. - # # call-seq: # hsh.each {| key, value | block } -> hsh # hsh.each_pair {| key, value | block } -> hsh # hsh.each -> an_enumerator # hsh.each_pair -> an_enumerator # + # Calls the given block for each element of +self+ + # and pass the key and value of each element. # # If no block is given, an enumerator is returned instead. # @@ -99,13 +107,13 @@ def each(&block) end ## - # Calls the given block for each element of +self+ - # and pass the key of each element. - # # call-seq: # hsh.each_key {| key | block } -> hsh # hsh.each_key -> an_enumerator # + # Calls the given block for each element of +self+ + # and pass the key of each element. + # # If no block is given, an enumerator is returned instead. # # h = { "a" => 100, "b" => 200 } @@ -125,13 +133,12 @@ def each_key(&block) end ## - # Calls the given block for each element of +self+ - # and pass the value of each element. - # # call-seq: - # hsh.each_value {| value | block } -> hsh + # hsh.each_value {| value | block } -> self # hsh.each_value -> an_enumerator # + # Calls the given block with each value; returns +self+: + # # If no block is given, an enumerator is returned instead. # # h = { "a" => 100, "b" => 200 } @@ -151,22 +158,39 @@ def each_value(&block) end ## - # Return a hash which contains the content of - # +self+ and +other+. If a block is given - # it will be called for each element with - # a duplicate key. The value of the block - # will be the final value of this element. + # call-seq: + # hsh.merge(other_hash..) -> hsh + # hsh.merge(other_hash..){|key, oldval, newval| block} -> hsh + # + # Returns the new \Hash formed by merging each of +other_hashes+ + # into a copy of +self+. + # + # Each argument in +other_hashes+ must be a \Hash. + # Adds the contents of _other_hash_ to _hsh_. If no block is specified, + # entries with duplicate keys are overwritten with the values from + # _other_hash_, otherwise the value of each duplicate key is determined by + # calling the block with the key, its value in _hsh_ and its value in + # _other_hash_. + # + # Example: + # h = {foo: 0, bar: 1, baz: 2} + # h1 = {bat: 3, bar: 4} + # h2 = {bam: 5, bat:6} + # h3 = h.merge(h1, h2) { |key, old_value, new_value| old_value + new_value } + # h3 # => {:foo=>0, :bar=>5, :baz=>2, :bat=>9, :bam=>5} # # ISO 15.2.13.4.22 - def merge(other, &block) - raise TypeError, "Hash required (#{other.class} given)" unless Hash === other + def merge(*others, &block) + i=0; len=others.size h = self.dup - if block + return h.__merge(*others) unless block + while i 0) { - int i = x.elements_size(); - m_output << "["; - for (auto &e : x.elements()) { - i--; - if (i == 0) { - visit(e); - } else { - visit(e); - m_output << ", "; - } - } - m_output << "]"; - } else { - m_output << "[1]"; - } + if (x.elements_size() > 0) { + int i = x.elements_size(); + m_output << "["; + for (auto &e : x.elements()) { + i--; + if (i == 0) { + visit(e); + } else { + visit(e); + m_output << ", "; + } + } + m_output << "]"; + } else { + m_output << "[1]"; + } } void protoConverter::visit(Array const& x) { - switch (x.arr_func()) { - case Array::FLATTEN: - visit(x.arr_arg()); - m_output << ".flatten"; - break; - case Array::COMPACT: - visit(x.arr_arg()); - m_output << ".compact"; - break; - case Array::FETCH: - visit(x.arr_arg()); - m_output << ".fetch"; - break; - case Array::FILL: - visit(x.arr_arg()); - m_output << ".fill"; - break; - case Array::ROTATE: - visit(x.arr_arg()); - m_output << ".rotate"; - break; - case Array::ROTATE_E: - visit(x.arr_arg()); - m_output << ".rotate!"; - break; - case Array::DELETEIF: - visit(x.arr_arg()); - m_output << ".delete_if"; - break; - case Array::INSERT: - visit(x.arr_arg()); - m_output << ".insert"; - break; - case Array::BSEARCH: - visit(x.arr_arg()); - m_output << ".bsearch"; - break; - case Array::KEEPIF: - visit(x.arr_arg()); - m_output << ".keep_if"; - break; - case Array::SELECT: - visit(x.arr_arg()); - m_output << ".select"; - break; - case Array::VALUES_AT: - visit(x.arr_arg()); - m_output << ".values_at"; - break; - case Array::BLOCK: - visit(x.arr_arg()); - m_output << ".index"; - break; - case Array::DIG: - visit(x.arr_arg()); - m_output << ".dig"; - break; - case Array::SLICE: - visit(x.arr_arg()); - m_output << ".slice"; - break; - case Array::PERM: - visit(x.arr_arg()); - m_output << ".permutation"; - break; - case Array::COMB: - visit(x.arr_arg()); - m_output << ".combination"; - break; - case Array::ASSOC: - visit(x.arr_arg()); - m_output << ".assoc"; - break; - case Array::RASSOC: - visit(x.arr_arg()); - m_output << ".rassoc"; - break; - } - m_output << "("; - visit(x.val_arg()); - m_output << ")"; + switch (x.arr_func()) { + case Array::FLATTEN: + visit(x.arr_arg()); + m_output << ".flatten"; + break; + case Array::COMPACT: + visit(x.arr_arg()); + m_output << ".compact"; + break; + case Array::FETCH: + visit(x.arr_arg()); + m_output << ".fetch"; + break; + case Array::FILL: + visit(x.arr_arg()); + m_output << ".fill"; + break; + case Array::ROTATE: + visit(x.arr_arg()); + m_output << ".rotate"; + break; + case Array::ROTATE_E: + visit(x.arr_arg()); + m_output << ".rotate!"; + break; + case Array::DELETEIF: + visit(x.arr_arg()); + m_output << ".delete_if"; + break; + case Array::INSERT: + visit(x.arr_arg()); + m_output << ".insert"; + break; + case Array::BSEARCH: + visit(x.arr_arg()); + m_output << ".bsearch"; + break; + case Array::KEEPIF: + visit(x.arr_arg()); + m_output << ".keep_if"; + break; + case Array::SELECT: + visit(x.arr_arg()); + m_output << ".select"; + break; + case Array::VALUES_AT: + visit(x.arr_arg()); + m_output << ".values_at"; + break; + case Array::BLOCK: + visit(x.arr_arg()); + m_output << ".index"; + break; + case Array::DIG: + visit(x.arr_arg()); + m_output << ".dig"; + break; + case Array::SLICE: + visit(x.arr_arg()); + m_output << ".slice"; + break; + case Array::PERM: + visit(x.arr_arg()); + m_output << ".permutation"; + break; + case Array::COMB: + visit(x.arr_arg()); + m_output << ".combination"; + break; + case Array::ASSOC: + visit(x.arr_arg()); + m_output << ".assoc"; + break; + case Array::RASSOC: + visit(x.arr_arg()); + m_output << ".rassoc"; + break; + } + m_output << "("; + visit(x.val_arg()); + m_output << ")"; } void protoConverter::visit(AssignmentStatement const& x) { - m_output << "var_" << m_numLiveVars << " = "; - visit(x.rvalue()); - m_numVarsPerScope.top()++; - m_numLiveVars++; - m_output << "\n"; + m_output << "var_" << m_numLiveVars << " = "; + visit(x.rvalue()); + m_numVarsPerScope.top()++; + m_numLiveVars++; + m_output << "\n"; } void protoConverter::visit(BinaryOp const& x) { - m_output << "("; - visit(x.left()); - switch (x.op()) { - case BinaryOp::ADD: m_output << " + "; break; - case BinaryOp::SUB: m_output << " - "; break; - case BinaryOp::MUL: m_output << " * "; break; - case BinaryOp::DIV: m_output << " / "; break; - case BinaryOp::MOD: m_output << " % "; break; - case BinaryOp::XOR: m_output << " ^ "; break; - case BinaryOp::AND: m_output << " and "; break; - case BinaryOp::OR: m_output << " or "; break; - case BinaryOp::EQ: m_output << " == "; break; - case BinaryOp::NE: m_output << " != "; break; - case BinaryOp::LE: m_output << " <= "; break; - case BinaryOp::GE: m_output << " >= "; break; - case BinaryOp::LT: m_output << " < "; break; - case BinaryOp::GT: m_output << " > "; break; - case BinaryOp::RS: m_output << " >> "; break; - } - visit(x.right()); - m_output << ")"; + m_output << "("; + visit(x.left()); + switch (x.op()) { + case BinaryOp::ADD: m_output << " + "; break; + case BinaryOp::SUB: m_output << " - "; break; + case BinaryOp::MUL: m_output << " * "; break; + case BinaryOp::DIV: m_output << " / "; break; + case BinaryOp::MOD: m_output << " % "; break; + case BinaryOp::XOR: m_output << " ^ "; break; + case BinaryOp::AND: m_output << " and "; break; + case BinaryOp::OR: m_output << " or "; break; + case BinaryOp::EQ: m_output << " == "; break; + case BinaryOp::NE: m_output << " != "; break; + case BinaryOp::LE: m_output << " <= "; break; + case BinaryOp::GE: m_output << " >= "; break; + case BinaryOp::LT: m_output << " < "; break; + case BinaryOp::GT: m_output << " > "; break; + case BinaryOp::RS: m_output << " >> "; break; + } + visit(x.right()); + m_output << ")"; } void protoConverter::visit(BuiltinFuncs const& x) { - switch (x.bifunc_oneof_case()) { - case BuiltinFuncs::kOs: - visit(x.os()); - break; - case BuiltinFuncs::kTime: - visit(x.time()); - break; - case BuiltinFuncs::kArr: - visit(x.arr()); - break; - case BuiltinFuncs::kMops: - visit(x.mops()); - break; - case BuiltinFuncs::BIFUNC_ONEOF_NOT_SET: - m_output << "1"; - break; - } - m_output << "\n"; + switch (x.bifunc_oneof_case()) { + case BuiltinFuncs::kOs: + visit(x.os()); + break; + case BuiltinFuncs::kTime: + visit(x.time()); + break; + case BuiltinFuncs::kArr: + visit(x.arr()); + break; + case BuiltinFuncs::kMops: + visit(x.mops()); + break; + case BuiltinFuncs::BIFUNC_ONEOF_NOT_SET: + m_output << "1"; + break; + } + m_output << "\n"; } void protoConverter::visit(Const const& x) { - switch (x.const_oneof_case()) { - case Const::kIntLit: - m_output << "(" << (x.int_lit() % 13) << ")"; - break; - case Const::kBoolVal: - m_output << "(" << x.bool_val() << ")"; - break; - case Const::CONST_ONEOF_NOT_SET: - m_output << "1"; - break; - } + switch (x.const_oneof_case()) { + case Const::kIntLit: + m_output << "(" << (x.int_lit() % 13) << ")"; + break; + case Const::kBoolVal: + m_output << "(" << x.bool_val() << ")"; + break; + case Const::CONST_ONEOF_NOT_SET: + m_output << "1"; + break; + } } void protoConverter::visit(Function const& x) { - m_output << "def foo()\nvar_0 = 1\n"; - visit(x.statements()); - m_output << "end\n"; - m_output << "foo\n"; + m_output << "def foo()\nvar_0 = 1\n"; + visit(x.statements()); + m_output << "end\n"; + m_output << "foo\n"; } void protoConverter::visit(HashType const& x) { - if (x.keyval_size() > 0) { - int i = x.keyval_size(); - m_output << "{"; - for (auto &e : x.keyval()) { - i--; - if (i == 0) { - visit(e); - } - else { - visit(e); - m_output << ", "; - } - } - m_output << "}"; - } + if (x.keyval_size() > 0) { + int i = x.keyval_size(); + m_output << "{"; + for (auto &e : x.keyval()) { + i--; + if (i == 0) { + visit(e); + } + else { + visit(e); + m_output << ", "; + } + } + m_output << "}"; + } } void protoConverter::visit(IfElse const& x) { - m_output << "if "; - visit(x.cond()); - m_output << "\n"; - visit(x.if_body()); - m_output << "\nelse\n"; - visit(x.else_body()); - m_output << "\nend\n"; + m_output << "if "; + visit(x.cond()); + m_output << "\n"; + visit(x.if_body()); + m_output << "\nelse\n"; + visit(x.else_body()); + m_output << "\nend\n"; } void protoConverter::visit(KVPair const& x) { - m_output << "\"" << removeSpecial(x.key()) << "\""; - m_output << " => "; - m_output << "\"" << removeSpecial(x.val()) << "\""; + m_output << "\"" << removeSpecial(x.key()) << "\""; + m_output << " => "; + m_output << "\"" << removeSpecial(x.val()) << "\""; } void protoConverter::visit(MathConst const& x) { - switch (x.math_const()) { - case MathConst::PI: - m_output << "Math::PI"; - break; - case MathConst::E: - m_output << "Math::E"; - break; - } + switch (x.math_const()) { + case MathConst::PI: + m_output << "Math::PI"; + break; + case MathConst::E: + m_output << "Math::E"; + break; + } } void protoConverter::visit(MathOps const& x) { - switch (x.math_op()) { - case MathOps::CBRT: - m_output << "Math.cbrt("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::COS: - m_output << "Math.cos("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::ERF: - m_output << "Math.erf("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::ERFC: - m_output << "Math.erfc("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::LOG: - m_output << "Math.log("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::LOG10: - m_output << "Math.log10("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::LOG2: - m_output << "Math.log2("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::SIN: - m_output << "Math.sin("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::SQRT: - m_output << "Math.sqrt("; - visit(x.math_arg()); - m_output << ")"; - break; - case MathOps::TAN: - m_output << "Math.tan("; - visit(x.math_arg()); - m_output << ")"; - break; - } + switch (x.math_op()) { + case MathOps::CBRT: + m_output << "Math.cbrt("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::COS: + m_output << "Math.cos("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::ERF: + m_output << "Math.erf("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::ERFC: + m_output << "Math.erfc("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::LOG: + m_output << "Math.log("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::LOG10: + m_output << "Math.log10("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::LOG2: + m_output << "Math.log2("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::SIN: + m_output << "Math.sin("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::SQRT: + m_output << "Math.sqrt("; + visit(x.math_arg()); + m_output << ")"; + break; + case MathOps::TAN: + m_output << "Math.tan("; + visit(x.math_arg()); + m_output << ")"; + break; + } } void protoConverter::visit(MathType const& x) { - switch (x.math_arg_oneof_case()) { - case MathType::kMathRval: - visit(x.math_rval()); - break; - case MathType::kMathConst: - visit(x.math_const()); - break; - case MathType::MATH_ARG_ONEOF_NOT_SET: - m_output << "1"; - break; - } + switch (x.math_arg_oneof_case()) { + case MathType::kMathRval: + visit(x.math_rval()); + break; + case MathType::kMathConst: + visit(x.math_const()); + break; + case MathType::MATH_ARG_ONEOF_NOT_SET: + m_output << "1"; + break; + } } void protoConverter::visit(ObjectSpace const& x) { - switch (x.os_func()) { - case ObjectSpace::COUNT: - m_output << "ObjectSpace.count_objects"; - break; - } - m_output << "("; - visit(x.os_arg()); - m_output << ")" << "\n"; + switch (x.os_func()) { + case ObjectSpace::COUNT: + m_output << "ObjectSpace.count_objects"; + break; + } + m_output << "("; + visit(x.os_arg()); + m_output << ")" << "\n"; } void protoConverter::visit(Rvalue const& x) { - switch (x.rvalue_oneof_case()) { - case Rvalue::kVarref: - visit(x.varref()); - break; - case Rvalue::kCons: - visit(x.cons()); - break; - case Rvalue::kBinop: - visit(x.binop()); - break; - case Rvalue::RVALUE_ONEOF_NOT_SET: - m_output << "1"; - break; - } + switch (x.rvalue_oneof_case()) { + case Rvalue::kVarref: + visit(x.varref()); + break; + case Rvalue::kCons: + visit(x.cons()); + break; + case Rvalue::kBinop: + visit(x.binop()); + break; + case Rvalue::RVALUE_ONEOF_NOT_SET: + m_output << "1"; + break; + } } void protoConverter::visit(Statement const& x) { - switch (x.stmt_oneof_case()) { - case Statement::kAssignment: - visit(x.assignment()); - break; - case Statement::kIfelse: - visit(x.ifelse()); - break; - case Statement::kTernaryStmt: - visit(x.ternary_stmt()); - break; - case Statement::kBuiltins: - visit(x.builtins()); - break; - case Statement::kBlockstmt: - visit(x.blockstmt()); - break; - case Statement::STMT_ONEOF_NOT_SET: - break; - } - m_output << "\n"; + switch (x.stmt_oneof_case()) { + case Statement::kAssignment: + visit(x.assignment()); + break; + case Statement::kIfelse: + visit(x.ifelse()); + break; + case Statement::kTernaryStmt: + visit(x.ternary_stmt()); + break; + case Statement::kBuiltins: + visit(x.builtins()); + break; + case Statement::kBlockstmt: + visit(x.blockstmt()); + break; + case Statement::STMT_ONEOF_NOT_SET: + break; + } + m_output << "\n"; } void protoConverter::visit(StatementSeq const& x) { - if (x.statements_size() > 0) { - m_numVarsPerScope.push(0); - m_output << "@scope ||= begin\n"; - for (auto &st : x.statements()) - visit(st); - m_output << "end\n"; - m_numLiveVars -= m_numVarsPerScope.top(); - m_numVarsPerScope.pop(); - } + if (x.statements_size() > 0) { + m_numVarsPerScope.push(0); + m_output << "@scope ||= begin\n"; + for (auto &st : x.statements()) + visit(st); + m_output << "end\n"; + m_numLiveVars -= m_numVarsPerScope.top(); + m_numVarsPerScope.pop(); + } } void protoConverter::visit(StringExtNoArg const& x) { - m_output << "\"" << removeSpecial(x.str_arg()) << "\""; - switch (x.str_op()) { - case StringExtNoArg::DUMP: - m_output << ".dump"; - break; - case StringExtNoArg::STRIP: - m_output << ".strip"; - break; - case StringExtNoArg::LSTRIP: - m_output << ".lstrip"; - break; - case StringExtNoArg::RSTRIP: - m_output << ".rstrip"; - break; - case StringExtNoArg::STRIPE: - m_output << ".strip!"; - break; - case StringExtNoArg::LSTRIPE: - m_output << ".lstrip!"; - break; - case StringExtNoArg::RSTRIPE: - m_output << ".rstrip!"; - break; - case StringExtNoArg::SWAPCASE: - m_output << ".swapcase"; - break; - case StringExtNoArg::SWAPCASEE: - m_output << ".swapcase!"; - break; - case StringExtNoArg::SQUEEZE: - m_output << ".squeeze"; - break; - } + m_output << "\"" << removeSpecial(x.str_arg()) << "\""; + switch (x.str_op()) { + case StringExtNoArg::DUMP: + m_output << ".dump"; + break; + case StringExtNoArg::STRIP: + m_output << ".strip"; + break; + case StringExtNoArg::LSTRIP: + m_output << ".lstrip"; + break; + case StringExtNoArg::RSTRIP: + m_output << ".rstrip"; + break; + case StringExtNoArg::STRIPE: + m_output << ".strip!"; + break; + case StringExtNoArg::LSTRIPE: + m_output << ".lstrip!"; + break; + case StringExtNoArg::RSTRIPE: + m_output << ".rstrip!"; + break; + case StringExtNoArg::SWAPCASE: + m_output << ".swapcase"; + break; + case StringExtNoArg::SWAPCASEE: + m_output << ".swapcase!"; + break; + case StringExtNoArg::SQUEEZE: + m_output << ".squeeze"; + break; + } } void protoConverter::visit(Ternary const& x) { - m_output << "("; - visit(x.tern_cond()); - m_output << " ? "; - visit(x.t_branch()); - m_output << " : "; - visit(x.f_branch()); - m_output << ")\n"; + m_output << "("; + visit(x.tern_cond()); + m_output << " ? "; + visit(x.t_branch()); + m_output << " : "; + visit(x.f_branch()); + m_output << ")\n"; } void protoConverter::visit(Time const& x) { - switch (x.t_func()) { - case Time::AT: - m_output << "Time.at"; - break; - case Time::GM: - m_output << "Time.gm"; - break; - } - m_output << "(" << (x.t_arg()% 13) << ")" << "\n"; + switch (x.t_func()) { + case Time::AT: + m_output << "Time.at"; + break; + case Time::GM: + m_output << "Time.gm"; + break; + } + m_output << "(" << (x.t_arg()% 13) << ")" << "\n"; } void protoConverter::visit(VarRef const& x) { - m_output << "var_" << (static_cast(x.varnum()) % m_numLiveVars); + m_output << "var_" << (static_cast(x.varnum()) % m_numLiveVars); } std::string protoConverter::FunctionToString(Function const& input) { - visit(input); - return m_output.str(); + visit(input); + return m_output.str(); } diff --git a/mruby/oss-fuzz/proto_to_ruby.h b/mruby/oss-fuzz/proto_to_ruby.h index 355c4283..e91c78f0 100644 --- a/mruby/oss-fuzz/proto_to_ruby.h +++ b/mruby/oss-fuzz/proto_to_ruby.h @@ -7,49 +7,49 @@ #include namespace ruby_fuzzer { - class protoConverter - { - public: - protoConverter() { - m_numLiveVars = 1; - m_numVarsPerScope.push(m_numLiveVars); - } - protoConverter(protoConverter const& x) { - m_numLiveVars = x.m_numLiveVars; - m_numVarsPerScope = x.m_numVarsPerScope; - } - ~protoConverter() {} - std::string FunctionToString(Function const& _input); + class protoConverter + { + public: + protoConverter() { + m_numLiveVars = 1; + m_numVarsPerScope.push(m_numLiveVars); + } + protoConverter(protoConverter const& x) { + m_numLiveVars = x.m_numLiveVars; + m_numVarsPerScope = x.m_numVarsPerScope; + } + ~protoConverter() {} + std::string FunctionToString(Function const& _input); - private: - void visit(ArrType const&); - void visit(Array const&); - void visit(AssignmentStatement const&); - void visit(BinaryOp const&); - void visit(BuiltinFuncs const&); - void visit(Const const&); - void visit(Function const&); - void visit(HashType const&); - void visit(IfElse const&); - void visit(KVPair const&); - void visit(MathConst const&); - void visit(MathOps const&); - void visit(MathType const&); - void visit(ObjectSpace const&); - void visit(Rvalue const&); - void visit(Statement const&); - void visit(StatementSeq const&); - void visit(StringExtNoArg const&); - void visit(Ternary const&); - void visit(Time const&); - void visit(VarRef const&); - template - void visit(google::protobuf::RepeatedPtrField const& _repeated_field); + private: + void visit(ArrType const&); + void visit(Array const&); + void visit(AssignmentStatement const&); + void visit(BinaryOp const&); + void visit(BuiltinFuncs const&); + void visit(Const const&); + void visit(Function const&); + void visit(HashType const&); + void visit(IfElse const&); + void visit(KVPair const&); + void visit(MathConst const&); + void visit(MathOps const&); + void visit(MathType const&); + void visit(ObjectSpace const&); + void visit(Rvalue const&); + void visit(Statement const&); + void visit(StatementSeq const&); + void visit(StringExtNoArg const&); + void visit(Ternary const&); + void visit(Time const&); + void visit(VarRef const&); + template + void visit(google::protobuf::RepeatedPtrField const& _repeated_field); - std::string removeSpecial(const std::string &x); + std::string removeSpecial(const std::string &x); - std::ostringstream m_output; - std::stack m_numVarsPerScope; - int32_t m_numLiveVars; - }; + std::ostringstream m_output; + std::stack m_numVarsPerScope; + int32_t m_numLiveVars; + }; } diff --git a/mruby/src/array.c b/mruby/src/array.c index 1a95b75c..d841a994 100644 --- a/mruby/src/array.c +++ b/mruby/src/array.c @@ -10,23 +10,42 @@ #include #include #include +#include #include #include "value_array.h" #define ARY_DEFAULT_LEN 4 #define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ #define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) +#ifndef MRB_ARY_LENGTH_MAX +#define MRB_ARY_LENGTH_MAX 131072 +#endif #define ARY_MAX_SIZE ((mrb_int)((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? ARY_C_MAX_SIZE : MRB_INT_MAX-1)) +static void +ary_too_big(mrb_state *mrb) +{ + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); +} + +static inline void +ary_check_too_big(mrb_state *mrb, mrb_int a, mrb_int b) +{ + if (a > ARY_MAX_SIZE - b || a < 0) + ary_too_big(mrb); +#if MRB_ARY_LENGTH_MAX != 0 + if (a > MRB_ARY_LENGTH_MAX - b || a < 0) + ary_too_big(mrb); +#endif +} + static struct RArray* ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a; size_t blen; - if (capa > ARY_MAX_SIZE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } + ary_check_too_big(mrb, capa, 0); blen = capa * sizeof(mrb_value); a = MRB_OBJ_ALLOC(mrb, MRB_TT_ARRAY, mrb->array_class); @@ -100,10 +119,12 @@ MRB_API mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr) { struct RArray *a; + mrb_value *p; a = ary_new_capa(mrb, 2); - ARY_PTR(a)[0] = car; - ARY_PTR(a)[1] = cdr; + p = ARY_PTR(a); + p[0] = car; + p[1] = cdr; ARY_SET_LEN(a, 2); return mrb_obj_value(a); } @@ -118,11 +139,7 @@ ary_fill_with_nil(mrb_value *ptr, mrb_int size) } } -static void -ary_modify_check(mrb_state *mrb, struct RArray *a) -{ - mrb_check_frozen(mrb, a); -} +#define ary_modify_check(mrb, a) mrb_check_frozen((mrb), (a)) static void ary_modify(mrb_state *mrb, struct RArray *a) @@ -188,11 +205,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) { mrb_int capa = ARY_CAPA(a); - if (len > ARY_MAX_SIZE || len < 0) { - size_error: - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } - + ary_check_too_big(mrb, len, 0); if (capa < ARY_DEFAULT_LEN) { capa = ARY_DEFAULT_LEN; } @@ -205,7 +218,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) } } if (capa < len || capa > ARY_MAX_SIZE) { - goto size_error; + ary_too_big(mrb); } if (ARY_EMBED_P(a)) { @@ -302,9 +315,7 @@ ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2) ary_replace(mrb, a, a2); return; } - if (ARY_LEN(a2) > ARY_MAX_SIZE - ARY_LEN(a)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } + ary_check_too_big(mrb, ARY_LEN(a2), ARY_LEN(a)); len = ARY_LEN(a) + ARY_LEN(a2); ary_modify(mrb, a); @@ -324,13 +335,29 @@ mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other) ary_concat(mrb, mrb_ary_ptr(self), a2); } +/* + * call-seq: + * array.concat(*other_arrays) -> self + * + * Adds to +array+ all elements from each \Array in +other_arrays+; returns +self+: + * + * a = [0, 1] + * a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5] + */ + static mrb_value mrb_ary_concat_m(mrb_state *mrb, mrb_value self) { - mrb_value ary; + mrb_value *args; + mrb_int len; - mrb_get_args(mrb, "A", &ary); - mrb_ary_concat(mrb, self, ary); + mrb_get_args(mrb, "*!", &args, &len); + for (int i=0; i self + * + * Prepends the given +objects+ to +self+: + * + * a = [:foo, 'bar', 2] + * a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2] + * + * Array#prepend is an alias for Array#unshift. + * + * Related: #push, #pop, #shift. + */ + static mrb_value mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) { @@ -662,14 +707,15 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) mrb_value *ptr; mrb_int alen, len; - mrb_get_args(mrb, "*!", &vals, &alen); + alen = mrb_get_argc(mrb); + vals = mrb_get_argv(mrb); if (alen == 0) { ary_modify_check(mrb, a); return self; } len = ARY_LEN(a); if (alen > ARY_MAX_SIZE - len) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + ary_too_big(mrb); } if (ARY_SHARED_P(a) && a->as.heap.aux.shared->refcnt == 1 /* shared only referenced from this array */ @@ -710,6 +756,9 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of array", n - len); } } + if (n >= ARY_MAX_SIZE) { + mrb_raise(mrb, E_INDEX_ERROR, "index too big"); + } if (len <= n) { if (ARY_CAPA(a) <= n) ary_expand_capa(mrb, a, n + 1); @@ -834,7 +883,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 = 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; @@ -1003,7 +1052,7 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) return v3; } -static mrb_value +mrb_value mrb_ary_delete_at(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); @@ -1025,7 +1074,7 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self) len = alen - index; while (--len) { *ptr = *(ptr+1); - ++ptr; + ptr++; } ARY_SET_LEN(a, alen-1); diff --git a/mruby/src/backtrace.c b/mruby/src/backtrace.c index d6648cc4..4a0fdc11 100644 --- a/mruby/src/backtrace.c +++ b/mruby/src/backtrace.c @@ -14,6 +14,7 @@ #include #include #include +#include #include struct backtrace_location { @@ -26,8 +27,7 @@ typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location* static const mrb_data_type bt_type = { "Backtrace", mrb_free }; -mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); -mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); +struct RObject *mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace); static void each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) @@ -97,29 +97,41 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * #ifndef MRB_NO_STDIO static void -print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) +print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) { mrb_int i; - mrb_int n = RARRAY_LEN(backtrace); + mrb_int n = (backtrace ? ARY_LEN(backtrace) : 0); mrb_value *loc, mesg; if (n != 0) { if (n > 1) { - fprintf(stderr, "trace (most recent call last):\n"); + fputs("trace (most recent call last):\n", stderr); } - for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) { + for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { if (mrb_string_p(*loc)) { - fprintf(stderr, "\t[%d] %.*s\n", - (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); + fprintf(stderr, "\t[%d] ", (int)i); + fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + fputc('\n', stderr); } } if (mrb_string_p(*loc)) { - fprintf(stderr, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc)); + fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + fputs(": ", stderr); } } - mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); - fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); - fputc('\n', stderr); + else { + fputs("(unknown):0: ", stderr); + } + + if (exc == mrb->nomem_err) { + static const char nomem[] = "Out of memory (NoMemoryError)\n"; + fwrite(nomem, sizeof(nomem)-1, 1, stderr); + } + else { + mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); + fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); + fputc('\n', stderr); + } } /* mrb_print_backtrace @@ -130,16 +142,13 @@ print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace) MRB_API void mrb_print_backtrace(mrb_state *mrb) { - mrb_value backtrace; - - if (!mrb->exc) { + if (!mrb->exc || mrb->exc->tt != MRB_TT_EXCEPTION) { return; } - backtrace = mrb_obj_iv_get(mrb, mrb->exc, MRB_SYM(backtrace)); - if (mrb_nil_p(backtrace)) return; - if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace); - print_backtrace(mrb, mrb->exc, backtrace); + struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace; + if (backtrace && backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); + print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace); } #else @@ -172,7 +181,7 @@ pack_backtrace_i(mrb_state *mrb, *pptr = ptr+1; } -static mrb_value +static struct RObject* packed_backtrace(mrb_state *mrb) { struct RData *backtrace; @@ -183,44 +192,51 @@ packed_backtrace(mrb_state *mrb) each_backtrace(mrb, ciidx, count_backtrace_i, &len); size = len * sizeof(struct backtrace_location); + backtrace = mrb_data_object_alloc(mrb, NULL, NULL, &bt_type); ptr = mrb_malloc(mrb, size); - backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); + backtrace->data = ptr; backtrace->flags = (uint32_t)len; each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); - return mrb_obj_value(backtrace); + return (struct RObject*)backtrace; +} + +static void +store_backtrace(mrb_state *mrb, mrb_value exc, struct RObject *backtrace) +{ + struct RException *e = mrb_exc_ptr(exc); + e->backtrace = backtrace; + mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)backtrace); } void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) { - mrb_sym sym = MRB_SYM(backtrace); - mrb_value backtrace; int ai; - if (mrb_iv_defined(mrb, exc, sym)) return; + if (mrb_exc_ptr(exc)->backtrace) return; ai = mrb_gc_arena_save(mrb); - backtrace = packed_backtrace(mrb); - mrb_iv_set(mrb, exc, sym, backtrace); + struct RObject *backtrace = packed_backtrace(mrb); + store_backtrace(mrb, exc, backtrace); mrb_gc_arena_restore(mrb, ai); } -mrb_value -mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) +struct RObject* +mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) { const struct backtrace_location *bt; mrb_int n, i; int ai; - if (mrb_nil_p(backtrace)) { + if (backtrace == NULL) { empty_backtrace: - return mrb_ary_new_capa(mrb, 0); + return mrb_obj_ptr(mrb_ary_new_capa(mrb, 0)); } - if (mrb_array_p(backtrace)) return backtrace; - bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type); + if (backtrace->tt == MRB_TT_ARRAY) return backtrace; + bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, mrb_obj_value(backtrace), &bt_type); if (bt == NULL) goto empty_backtrace; - n = (mrb_int)RDATA(backtrace)->flags; + n = (mrb_int)backtrace->flags; if (n == 0) goto empty_backtrace; - backtrace = mrb_ary_new_capa(mrb, n); + backtrace = mrb_obj_ptr(mrb_ary_new_capa(mrb, n)); ai = mrb_gc_arena_save(mrb); for (i = 0; i < n; i++) { const struct backtrace_location *entry = &bt[i]; @@ -236,7 +252,7 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) mrb_str_cat_lit(mrb, btline, ":in "); mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id)); } - mrb_ary_push(mrb, backtrace, btline); + mrb_ary_push(mrb, mrb_obj_value(backtrace), btline); mrb_gc_arena_restore(mrb, ai); } @@ -246,20 +262,21 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc) { - mrb_value backtrace; - - backtrace = mrb_iv_get(mrb, exc, MRB_SYM(backtrace)); - if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) { - return backtrace; + struct RObject *backtrace = mrb_exc_ptr(exc)->backtrace; + if (backtrace == NULL) { + return mrb_nil_value(); + } + if (backtrace->tt == MRB_TT_ARRAY) { + return mrb_obj_value(backtrace); } /* unpack packed-backtrace */ backtrace = mrb_unpack_backtrace(mrb, backtrace); - mrb_iv_set(mrb, exc, MRB_SYM(backtrace), backtrace); - return backtrace; + store_backtrace(mrb, exc, backtrace); + return mrb_obj_value(backtrace); } mrb_value mrb_get_backtrace(mrb_state *mrb) { - return mrb_unpack_backtrace(mrb, packed_backtrace(mrb)); + return mrb_obj_value(mrb_unpack_backtrace(mrb, packed_backtrace(mrb))); } diff --git a/mruby/src/cdump.c b/mruby/src/cdump.c index b4dfc4e8..251b3984 100644 --- a/mruby/src/cdump.c +++ b/mruby/src/cdump.c @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -39,12 +40,7 @@ cdump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp) 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); - } + fprintf(fp, "{IREP_TT_FLOAT, {.f=" MRB_FLOAT_FMT "}},\n", p->u.f); #endif break; case IREP_TT_BIGINT: @@ -171,7 +167,7 @@ sym_operator_name(const char *sym_name, mrb_int len) } if (0 < cmp) { start = ++idx; - --table_size; + table_size--; } } return NULL; @@ -193,7 +189,10 @@ sym_var_name(mrb_state *mrb, const char *initname, const char *key, int n) 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; + if (sym == 0) { + fputs("0,", fp); + return MRB_DUMP_OK; + } mrb_int len; const char *name = mrb_sym_name_len(mrb, sym, &len), *op_name; @@ -302,7 +301,7 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, 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; ifiles[0]->lines.flat_map[i]; + const 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); @@ -310,8 +309,8 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, 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; + fprintf(fp, "static const char %s_debug_lines_%d[] = \"", name, n); + const uint8_t *pmap = info->files[0]->lines.packed_map; for (i=0; i #include #include +#include #include union mt_ptr { @@ -42,8 +43,8 @@ typedef struct mt_tbl { } mt_tbl; #ifdef MRB_USE_INLINE_METHOD_CACHE -#define MT_CACHE_SIZE 256 -static uint8_t mt_cache[MT_CACHE_SIZE]; +#define MT_INLINE_CACHE_SIZE 256 +static uint8_t mt_cache[MT_INLINE_CACHE_SIZE]; #endif /* Creates the method table. */ @@ -72,9 +73,9 @@ mt_rehash(mrb_state *mrb, mt_tbl *t) khash_power2(new_alloc); if (old_alloc == new_alloc) return; + t->ptr = (union mt_ptr*)mrb_calloc(mrb, sizeof(union mt_ptr)+sizeof(mrb_sym), new_alloc); t->alloc = new_alloc; t->size = 0; - t->ptr = (union mt_ptr*)mrb_calloc(mrb, sizeof(union mt_ptr)+sizeof(mrb_sym), new_alloc); if (old_alloc == 0) return; mrb_sym *keys = (mrb_sym*)&old_ptr[old_alloc]; @@ -149,10 +150,16 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp) union mt_ptr *vals = t->ptr; hash = kh_int_hash_func(mrb, sym); #ifdef MRB_USE_INLINE_METHOD_CACHE - int cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE; + int cpos = (hash^(uintptr_t)t) % MT_INLINE_CACHE_SIZE; pos = mt_cache[cpos]; - if (cpos < t->alloc && t->table[cpos].key == sym) { - return &t->table[cpos]; + if (pos < t->alloc) { + mrb_sym key = keys[pos]; + if (key) { + if (MT_KEY_SYM(key) == sym) { + *pp = vals[pos]; + return key; + } + } } #endif start = pos = hash & (t->alloc-1); @@ -161,7 +168,7 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp) if (MT_KEY_SYM(key) == sym) { *pp = vals[pos]; #ifdef MRB_USE_INLINE_METHOD_CACHE - if (pos < 0xff) { + if (pos < 0x100) { mt_cache[cpos] = pos; } #endif @@ -237,6 +244,23 @@ mt_free(mrb_state *mrb, mt_tbl *t) mrb_free(mrb, t); } +static inline mrb_method_t +create_method_value(mrb_state *mrb, mrb_sym key, union mt_ptr val) +{ + mrb_method_t m; + + if (key & MT_FUNC_P) { + MRB_METHOD_FROM_FUNC(m, val.func); + } + else { + MRB_METHOD_FROM_PROC(m, val.proc); + } + if (key & MT_NOARG_P) { + MRB_METHOD_NOARG_SET(m); + } + return m; +} + MRB_API void mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p) { @@ -252,19 +276,7 @@ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void * for (i=0; ialloc; i++) { mrb_sym key = keys[i]; if (MT_KEY_SYM(key)) { - mrb_method_t m; - - if (key & MT_FUNC_P) { - MRB_METHOD_FROM_FUNC(m, vals[i].func); - } - else { - MRB_METHOD_FROM_PROC(m, vals[i].proc); - } - if (key & MT_NOARG_P) { - MRB_METHOD_NOARG_SET(m); - } - - if (fn(mrb, MT_KEY_SYM(key), m, p) != 0) + if (fn(mrb, MT_KEY_SYM(key), create_method_value(mrb, key, vals[i]), p) != 0) return; } } @@ -385,7 +397,6 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o) } o->c = sc; mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc); - mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o); mrb_obj_iv_set(mrb, (struct RObject*)sc, MRB_SYM(__attached__), mrb_obj_value(o)); sc->flags |= o->flags & MRB_FL_OBJ_IS_FROZEN; } @@ -545,11 +556,13 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super); } -static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value); +static mrb_value mrb_do_nothing(mrb_state *mrb, mrb_value); #ifndef MRB_NO_METHOD_CACHE static void mc_clear(mrb_state *mrb); +static void mc_clear_by_id(mrb_state *mrb, mrb_sym mid); #else #define mc_clear(mrb) +#define mc_clear_by_id(mrb,mid) #endif static void @@ -562,9 +575,8 @@ mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass) super = mrb->object_class; super->flags |= MRB_FL_CLASS_IS_INHERITED; s = mrb_obj_value(super); - mrb_mc_clear_by_class(mrb, klass); mid = MRB_SYM(inherited); - if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) { + if (!mrb_func_basic_p(mrb, s, mid, mrb_do_nothing)) { mrb_value c = mrb_obj_value(klass); mrb_funcall_argv(mrb, s, mid, 1, &c); } @@ -772,7 +784,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_ ptr.func = MRB_METHOD_FUNC(m); } mt_put(mrb, h, mid, MT_FLAGS(MRB_METHOD_FUNC_P(m), MRB_METHOD_NOARG_P(m)), ptr); - mc_clear(mrb); + mc_clear_by_id(mrb, mid); } MRB_API void @@ -877,8 +889,6 @@ mrb_get_arg1(mrb_state *mrb) return array_argv[0]; } -mrb_int mrb_ci_bidx(mrb_callinfo *ci); - MRB_API mrb_bool mrb_block_given_p(mrb_state *mrb) { @@ -888,54 +898,16 @@ mrb_block_given_p(mrb_state *mrb) return !mrb_nil_p(b); } -/* - retrieve arguments from mrb_state. - - mrb_get_args(mrb, format, ...) - - returns number of arguments parsed. - - format specifiers: - - string mruby type C type note - ---------------------------------------------------------------------------------------------- - o: Object [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! 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*,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: +#define GET_ARG(_type) (ptr ? ((_type)(*ptr++)) : va_arg((*ap), _type)) - 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, ...) +static mrb_int +get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) { const char *fmt = format; char c; - int i = 0; - va_list ap; + mrb_int i = 0; mrb_callinfo *ci = mrb->c->ci; - int argc = ci->n; + mrb_int argc = ci->n; const mrb_value *argv = ci->stack+1; mrb_bool argv_on_stack; mrb_bool opt = FALSE; @@ -945,8 +917,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_bool reqkarg = FALSE; int argc_min = 0, argc_max = 0; - va_start(ap, format); - while ((c = *fmt++)) { switch (c) { case '|': @@ -1070,7 +1040,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { mrb_value *p; - p = va_arg(ap, mrb_value*); + p = GET_ARG(mrb_value*); if (pickarg) { if (!(altmode && mrb_nil_p(*pickarg))) { switch (c) { @@ -1088,7 +1058,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { struct RClass **p; - p = va_arg(ap, struct RClass**); + p = GET_ARG(struct RClass**); if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { *p = NULL; @@ -1105,8 +1075,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) const char **ps = 0; mrb_int *pl = 0; - ps = va_arg(ap, const char**); - pl = va_arg(ap, mrb_int*); + ps = GET_ARG(const char**); + pl = GET_ARG(mrb_int*); if (needmodify) goto bad_needmodify; if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { @@ -1125,7 +1095,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { const char **ps; - ps = va_arg(ap, const char**); + ps = GET_ARG(const char**); if (needmodify) goto bad_needmodify; if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { @@ -1144,8 +1114,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) const mrb_value **pb; mrb_int *pl; - pb = va_arg(ap, const mrb_value**); - pl = va_arg(ap, mrb_int*); + pb = GET_ARG(const mrb_value**); + pl = GET_ARG(mrb_int*); if (needmodify) goto bad_needmodify; if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { @@ -1161,35 +1131,12 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } break; - case 'I': - { - void* *p; - struct RClass *klass; - - p = va_arg(ap, void**); - 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); - } - } - } - break; #ifndef MRB_NO_FLOAT case 'f': { mrb_float *p; - p = va_arg(ap, mrb_float*); + p = GET_ARG(mrb_float*); if (pickarg) { *p = mrb_as_float(mrb, *pickarg); } @@ -1200,7 +1147,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { mrb_int *p; - p = va_arg(ap, mrb_int*); + p = GET_ARG(mrb_int*); if (pickarg) { *p = mrb_as_int(mrb, *pickarg); } @@ -1208,7 +1155,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) break; case 'b': { - mrb_bool *boolp = va_arg(ap, mrb_bool*); + mrb_bool *boolp = GET_ARG(mrb_bool*); if (pickarg) { *boolp = mrb_test(*pickarg); @@ -1219,7 +1166,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { mrb_sym *symp; - symp = va_arg(ap, mrb_sym*); + symp = GET_ARG(mrb_sym*); if (pickarg) { *symp = to_sym(mrb, *pickarg); } @@ -1230,8 +1177,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) void** datap; struct mrb_data_type const* type; - datap = va_arg(ap, void**); - type = va_arg(ap, struct mrb_data_type const*); + datap = GET_ARG(void**); + type = GET_ARG(struct mrb_data_type const*); if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { *datap = 0; @@ -1247,7 +1194,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { mrb_value *p, *bp; - p = va_arg(ap, mrb_value*); + p = GET_ARG(mrb_value*); bp = ci->stack + mrb_ci_bidx(ci); if (altmode && mrb_nil_p(*bp)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); @@ -1263,7 +1210,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) { mrb_bool *p; - p = va_arg(ap, mrb_bool*); + p = GET_ARG(mrb_bool*); *p = pickarg ? TRUE : FALSE; } break; @@ -1274,8 +1221,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_int *pl; mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE; - var = va_arg(ap, const mrb_value**); - pl = va_arg(ap, mrb_int*); + var = GET_ARG(const mrb_value**); + pl = GET_ARG(mrb_int*); if (argc > i) { *pl = argc-i; if (*pl > 0) { @@ -1300,20 +1247,22 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) case ':': { mrb_value ksrc = mrb_hash_p(kdict) ? mrb_hash_dup(mrb, kdict) : mrb_hash_new(mrb); - const mrb_kwargs *kwargs = va_arg(ap, const mrb_kwargs*); + const mrb_kwargs *kwargs = GET_ARG(const mrb_kwargs*); mrb_value *rest; if (kwargs == NULL) { rest = NULL; } else { - uint32_t kwnum = kwargs->num; - uint32_t required = kwargs->required; + mrb_int kwnum = kwargs->num; + mrb_int required = kwargs->required; const mrb_sym *kname = kwargs->table; mrb_value *values = kwargs->values; - uint32_t j; + mrb_int j; const uint32_t keyword_max = 40; + mrb_assert(kwnum >= 0); + mrb_assert(required >= 0); if (kwnum > keyword_max || required > kwnum) { mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large"); } @@ -1363,10 +1312,63 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } finish: - va_end(ap); return i; } +/* + retrieve arguments from mrb_state. + + mrb_get_args(mrb, format, ...) + + returns number of arguments parsed. + + format specifiers: + + string mruby type C type note + ---------------------------------------------------------------------------------------------- + o: Object [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! 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 + &: 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, mrb_args_format format, ...) +{ + va_list ap; + va_start(ap, format); + mrb_int rc = get_args_v(mrb, format, NULL, &ap); + va_end(ap); + return rc; +} + +MRB_API mrb_int +mrb_get_args_a(mrb_state *mrb, mrb_args_format format, void **args) +{ + return get_args_v(mrb, format, args, NULL); +} + static struct RClass* boot_defclass(mrb_state *mrb, struct RClass *super) { @@ -1376,6 +1378,7 @@ boot_defclass(mrb_state *mrb, struct RClass *super) if (super) { c->super = super; mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); + c->flags |= MRB_FL_CLASS_IS_INHERITED; } else { c->super = mrb->object_class; @@ -1649,17 +1652,12 @@ mrb_mod_initialize(mrb_state *mrb, mrb_value mod) return mod; } -/* implementation of module_eval/class_eval */ -mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); - static mrb_value mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod) { return mod; } -/* returns mrb_class_ptr(mrb_singleton_class()) */ -/* except that it return NULL for immediate values */ MRB_API struct RClass* mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v) { @@ -1739,6 +1737,7 @@ mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, m } #ifndef MRB_NO_METHOD_CACHE +/* clear whole method cache table */ static void mc_clear(mrb_state *mrb) { @@ -1749,27 +1748,32 @@ mc_clear(mrb_state *mrb) } } +/* clear method cache for a class */ void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c) { struct mrb_cache_entry *mc = mrb->cache; - int i; - if (c->flags & MRB_FL_CLASS_IS_INHERITED) { - mc_clear(mrb); - return; + for (int i=0; ic == c || mc->c0 == c) mc->c = 0; } - for (i=0; icache; + + for (int i=0; imid == id) mc->c = 0; } } #endif -MRB_API mrb_method_t -mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) +mrb_method_t +mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid) { mrb_method_t m; - struct RClass *c = *cp; #ifndef MRB_NO_METHOD_CACHE struct RClass *oc = c; int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1); @@ -1790,15 +1794,7 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) if (ret) { if (ptr.proc == 0) break; *cp = c; - if (ret & MT_FUNC_P) { - MRB_METHOD_FROM_FUNC(m, ptr.func); - } - else { - MRB_METHOD_FROM_PROC(m, ptr.proc); - } - if (ret & MT_NOARG_P) { - MRB_METHOD_NOARG_SET(m); - } + m = create_method_value(mrb, ret, ptr); #ifndef MRB_NO_METHOD_CACHE mc->c = oc; mc->c0 = c; @@ -1814,6 +1810,12 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) return m; /* no method */ } +MRB_API mrb_method_t +mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) +{ + return mrb_vm_find_method(mrb, *cp, cp, mid); +} + MRB_API mrb_method_t mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) { @@ -1939,7 +1941,12 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv) if (c->tt == MRB_TT_SCLASS) mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class"); - if (ttype == 0) ttype = MRB_TT_OBJECT; + if (c == mrb->nil_class || c == mrb->false_class) { + mrb_assert(ttype == 0); + } + else if (ttype == 0) { + ttype = MRB_TT_OBJECT; + } if (ttype <= MRB_TT_CPTR) { mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv); } @@ -1970,7 +1977,7 @@ mrb_instance_new(mrb_state *mrb, mrb_value cv) mrb_get_args(mrb, "*!&", &argv, &argc, &blk); obj = mrb_instance_alloc(mrb, cv); init = MRB_SYM(initialize); - if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) { + if (!mrb_func_basic_p(mrb, obj, init, mrb_do_nothing)) { mrb_funcall_with_block(mrb, obj, init, argc, argv, blk); } return obj; @@ -1984,7 +1991,7 @@ mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *arg obj = mrb_instance_alloc(mrb, mrb_obj_value(c)); mid = MRB_SYM(initialize); - if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) { + if (!mrb_func_basic_p(mrb, obj, mid, mrb_do_nothing)) { mrb_funcall_argv(mrb, obj, mid, argc, argv); } return obj; @@ -2041,7 +2048,7 @@ mrb_class_superclass(mrb_state *mrb, mrb_value klass) } static mrb_value -mrb_bob_init(mrb_state *mrb, mrb_value cv) +mrb_do_nothing(mrb_state *mrb, mrb_value cv) { return mrb_nil_value(); } @@ -2305,8 +2312,6 @@ 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) { @@ -2363,7 +2368,10 @@ mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym mid) MRB_CLASS_ORIGIN(c); h = c->mt; - if (h && mt_del(mrb, h, mid)) return; + if (h && mt_del(mrb, h, mid)) { + mc_clear_by_id(mrb, mid); + return; + } mrb_name_error(mrb, mid, "method '%n' not defined in %C", mid, c); } @@ -2743,13 +2751,28 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) case MRB_TT_OBJECT: case MRB_TT_SCLASS: case MRB_TT_HASH: - case MRB_TT_DATA: + case MRB_TT_CDATA: case MRB_TT_EXCEPTION: mrb_iv_copy(mrb, dest, obj); break; case MRB_TT_ISTRUCT: mrb_istruct_copy(dest, obj); break; +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + mrb_bint_copy(mrb, dest, obj); + break; +#endif +#ifdef MRB_USE_RATIONAL + case MRB_TT_RATIONAL: + mrb_rational_copy(mrb, dest, obj); + break; +#endif +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: + mrb_complex_copy(mrb, dest, obj); + break; +#endif default: break; @@ -2847,8 +2870,59 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj) /* implementation of __id__ */ mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self); -/* implementation of instance_eval */ -mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value); + +mrb_noreturn void +mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) +{ + mrb_no_method_error(mrb, name, args, "undefined method '%n'", name); +} + +/* 15.3.1.3.30 */ +/* + * call-seq: + * obj.method_missing(symbol [, *args] ) -> result + * + * Invoked by Ruby when obj is sent a message it cannot handle. + * symbol is the symbol for the method called, and args + * are any arguments that were passed to it. By default, the interpreter + * raises an error when this method is called. However, it is possible + * to override the method to provide more dynamic behavior. + * If it is decided that a particular method should not be handled, then + * super should be called, so that ancestors can pick up the + * missing method. + * The example below creates + * a class Roman, which responds to methods with names + * consisting of roman numerals, returning the corresponding integer + * values. + * + * class Roman + * def romanToInt(str) + * # ... + * end + * def method_missing(methId) + * str = methId.to_s + * romanToInt(str) + * end + * end + * + * r = Roman.new + * r.iv #=> 4 + * r.xxiii #=> 23 + * r.mm #=> 2000 + */ +mrb_value +mrb_obj_missing(mrb_state *mrb, mrb_value mod) +{ + mrb_sym name; + 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 */ + return mrb_nil_value(); +} static mrb_value inspect_main(mrb_state *mrb, mrb_value mod) @@ -2871,7 +2945,7 @@ static const mrb_code new_iseq[] = { MRB_PRESYM_DEFINE_VAR_AND_INITER(new_syms, 2, MRB_SYM(allocate), MRB_SYM(initialize)) static const mrb_irep new_irep = { - 4, 5, 0, MRB_IREP_STATIC, + 4, 6, 0, MRB_IREP_STATIC, new_iseq, NULL, new_syms, NULL, NULL, NULL, sizeof(new_iseq), 0, 2, 0, 0, }; @@ -2891,9 +2965,6 @@ init_class_new(mrb_state *mrb, struct RClass *cls) mrb_define_method_raw(mrb, cls, MRB_SYM(new), m); } -/* implementation of #send method */ -mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); - void mrb_init_class(mrb_state *mrb) { @@ -2930,32 +3001,33 @@ mrb_init_class(mrb_state *mrb) MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS); - mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE()); + mrb_define_method(mrb, bob, "initialize", mrb_do_nothing, MRB_ARGS_NONE()); mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE()); mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */ mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.4 */ 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_method(mrb, bob, "singleton_method_added", mrb_do_nothing, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, bob, "method_missing", mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */ 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()); mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */ mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */ - mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, cls, "inherited", mrb_do_nothing, MRB_ARGS_REQ(1)); init_class_new(mrb, cls); MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE); mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */ - mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ - mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mod, "extended", mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ + mrb_define_method(mrb, mod, "prepended", mrb_do_nothing, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */ mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */ mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */ - mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ + mrb_define_method(mrb, mod, "included", mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */ mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */ mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY()); @@ -2978,7 +3050,7 @@ 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_define_method(mrb, mod, "method_added", mrb_do_nothing, MRB_ARGS_REQ(1)); mrb_undef_method(mrb, cls, "append_features"); mrb_undef_method(mrb, cls, "prepend_features"); diff --git a/mruby/src/codedump.c b/mruby/src/codedump.c index 5d763fa3..1d19354f 100644 --- a/mruby/src/codedump.c +++ b/mruby/src/codedump.c @@ -5,86 +5,89 @@ #include #include #include +#include #ifndef MRB_NO_STDIO static void -print_r(mrb_state *mrb, const mrb_irep *irep, size_t n) +print_r(mrb_state *mrb, const mrb_irep *irep, size_t n, FILE *out) { if (n == 0) return; if (n >= irep->nlocals) return; if (!irep->lv[n-1]) return; - printf(" R%d:%s", (int)n, mrb_sym_dump(mrb, irep->lv[n-1])); + fprintf(out, " R%d:%s", (int)n, mrb_sym_dump(mrb, irep->lv[n-1])); } static void -print_lv_a(mrb_state *mrb, const mrb_irep *irep, uint16_t a) +print_lv_a(mrb_state *mrb, const mrb_irep *irep, uint16_t a, FILE *out) { if (!irep->lv || a >= irep->nlocals || a == 0) { - printf("\n"); + fprintf(out, "\n"); return; } - printf("\t;"); - print_r(mrb, irep, a); - printf("\n"); + fprintf(out, "\t;"); + print_r(mrb, irep, a, out); + fprintf(out, "\n"); } static void -print_lv_ab(mrb_state *mrb, const mrb_irep *irep, uint16_t a, uint16_t b) +print_lv_ab(mrb_state *mrb, const mrb_irep *irep, uint16_t a, uint16_t b, FILE *out) { if (!irep->lv || (a >= irep->nlocals && b >= irep->nlocals) || a+b == 0) { - printf("\n"); + fprintf(out, "\n"); return; } - printf("\t;"); - if (a > 0) print_r(mrb, irep, a); - if (b > 0) print_r(mrb, irep, b); - printf("\n"); + fprintf(out, "\t;"); + if (a > 0) print_r(mrb, irep, a, out); + if (b > 0) print_r(mrb, irep, b, out); + fprintf(out, "\n"); } static void -print_header(mrb_state *mrb, const mrb_irep *irep, uint32_t i) +print_header(mrb_state *mrb, const mrb_irep *irep, ptrdiff_t i, FILE *out) { int32_t line; - line = mrb_debug_get_line(mrb, irep, i); + mrb_assert(i <= UINT32_MAX); + line = mrb_debug_get_line(mrb, irep, (uint32_t)i); if (line < 0) { - printf(" "); + fprintf(out, " "); } else { - printf("%5d ", line); + fprintf(out, "%5d ", line); } - printf("%03d ", (int)i); + fprintf(out, "%03d ", (int)i); } static void -print_args(uint8_t i) +print_args(uint16_t i, FILE *out) { + mrb_assert(i <= 255); uint8_t n = i&0xf; uint8_t nk = (i>>4)&0xf; if (n == 15) { - printf("n=*"); + fprintf(out, "n=*"); } else { - printf("n=%d", n); + fprintf(out, "n=%d", n); } if (nk > 0) { - printf("|"); + fprintf(out, "|"); if (nk == 15) { - printf("nk=*"); + fprintf(out, "nk=*"); } else { - printf("nk=%d", nk); + fprintf(out, "nk=%d", nk); } } - printf(" (0x%02x)\n", i); + fprintf(out, "\n"); } #define CASE(insn,ops) case insn: FETCH_ ## ops (); L_ ## insn static void -codedump(mrb_state *mrb, const mrb_irep *irep) +codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) { int ai; const mrb_code *pc, *pcend; @@ -92,16 +95,22 @@ 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 ilen=%d\n", (void*)irep, - irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen); + fprintf(out, "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) { int i; + int head = FALSE; - printf("local variable names:\n"); - for (i = 1; i < irep->nlocals; ++i) { + for (i = 1; i < irep->nlocals; i++) { char const *s = mrb_sym_dump(mrb, irep->lv[i - 1]); - printf(" R%d:%s\n", i, s ? s : ""); + if (s) { + if (!head) { + head = TRUE; + fprintf(out, "local variable names:\n"); + } + fprintf(out, " R%d:%s\n", i, s); + } } } @@ -109,7 +118,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep) int i = irep->clen; const struct mrb_irep_catch_handler *e = mrb_irep_catch_handler_table(irep); - for (; i > 0; i --, e ++) { + for (; i > 0; i--,e++) { uint32_t begin = mrb_irep_catch_handler_unpack(e->begin); uint32_t end = mrb_irep_catch_handler_unpack(e->end); uint32_t target = mrb_irep_catch_handler_unpack(e->target); @@ -129,7 +138,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep) type = buf; break; } - printf("catch type: %-8s begin: %04" PRIu32 " end: %04" PRIu32 " target: %04" PRIu32 "\n", type, begin, end, target); + fprintf(out, "catch type: %-8s begin: %04" PRIu32 " end: %04" PRIu32 " target: %04" PRIu32 "\n", type, begin, end, target); } } @@ -146,60 +155,60 @@ codedump(mrb_state *mrb, const mrb_irep *irep) i = pc - irep->iseq; next_file = mrb_debug_get_filename(mrb, irep, (uint32_t)i); if (next_file && file != next_file) { - printf("file: %s\n", next_file); + fprintf(out, "file: %s\n", next_file); file = next_file; } - print_header(mrb, irep, (uint32_t)i); + print_header(mrb, irep, i, out); ins = READ_B(); switch (ins) { CASE(OP_NOP, Z): - printf("NOP\n"); + fprintf(out, "NOP\n"); break; CASE(OP_MOVE, BB): - printf("MOVE\t\tR%d\tR%d\t", a, b); - print_lv_ab(mrb, irep, a, b); + fprintf(out, "MOVE\t\tR%d\tR%d\t", a, b); + print_lv_ab(mrb, irep, a, b, out); break; CASE(OP_LOADL, BB): switch (irep->pool[b].tt) { #ifndef MRB_NO_FLOAT case IREP_TT_FLOAT: - printf("LOADL\t\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f); + fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f); break; #endif case IREP_TT_INT32: - printf("LOADL\t\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32); + fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32); break; #ifdef MRB_64BIT case IREP_TT_INT64: - printf("LOADL\t\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64); + fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64); break; #endif default: - printf("LOADL\t\tR%d\tL(%d)\t", a, b); + fprintf(out, "LOADL\t\tR%d\tL(%d)\t", a, b); break; } - print_lv_a(mrb, irep, a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADI, BB): - printf("LOADI\t\tR%d\t%d\t", a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADI\t\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADINEG, BB): - printf("LOADI\tR%d\t-%d\t", a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADINEG\tR%d\t-%d\t", a, b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADI16, BS): - printf("LOADI16\tR%d\t%d\t", a, (int)(int16_t)b); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADI16\tR%d\t%d\t", a, (int)(int16_t)b); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "LOADI32\tR%d\t%d\t", a, (int32_t)(((uint32_t)b<<16)+c)); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADI__1, B): - printf("LOADI__1\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADI__1\tR%d\t(-1)\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADI_0, B): goto L_LOADI; CASE(OP_LOADI_1, B): goto L_LOADI; @@ -210,371 +219,367 @@ codedump(mrb_state *mrb, const mrb_irep *irep) CASE(OP_LOADI_6, B): goto L_LOADI; CASE(OP_LOADI_7, B): L_LOADI: - printf("LOADI_%d\tR%d\t\t", ins-(int)OP_LOADI_0, a); - print_lv_a(mrb, irep, a); + b = ins-(int)OP_LOADI_0; + fprintf(out, "LOADI_%d\tR%d\t(%d)\t", b, a, b); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "LOADSYM\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADNIL, B): - printf("LOADNIL\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADNIL\tR%d\t(nil)\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADSELF, B): - printf("LOADSELF\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADSELF\tR%d\t(R0)\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADT, B): - printf("LOADT\t\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADT\t\tR%d\t(true)\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LOADF, B): - printf("LOADF\t\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "LOADF\t\tR%d\t(false)\t", a); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "GETGV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "SETGV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "GETSV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "SETSV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "GETCONST\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "SETCONST\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "GETMCNST\tR%d\tR%d::%s\t", a, a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "SETMCNST\tR%d::%s\tR%d\t", a+1, mrb_sym_dump(mrb, irep->syms[b]), a); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "GETIV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "SETIV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_GETUPVAR, BBB): - printf("GETUPVAR\tR%d\t%d\t%d\t", a, b, c); - print_lv_a(mrb, irep, a); + fprintf(out, "GETUPVAR\tR%d\t%d\t%d\t", a, b, c); + print_lv_a(mrb, irep, a, out); break; CASE(OP_SETUPVAR, BBB): - printf("SETUPVAR\tR%d\t%d\t%d\t", a, b, c); - print_lv_a(mrb, irep, a); + fprintf(out, "SETUPVAR\tR%d\t%d\t%d\t", a, b, c); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "GETCV\t\tR%d\t%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "SETCV\t\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_GETIDX, B): - printf("GETIDX\tR%d\tR%d\n", a, a+1); + fprintf(out, "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); + fprintf(out, "SETIDX\tR%d\tR%d\tR%d\n", a, a+1, a+2); break; CASE(OP_JMP, S): i = pc - irep->iseq; - printf("JMP\t\t%03d\n", (int)i+(int16_t)a); + fprintf(out, "JMP\t\t%03d\n", (int)i+(int16_t)a); break; CASE(OP_JMPUW, S): i = pc - irep->iseq; - printf("JMPUW\t\t%03d\n", (int)i+(int16_t)a); + fprintf(out, "JMPUW\t\t%03d\n", (int)i+(int16_t)a); break; CASE(OP_JMPIF, BS): i = pc - irep->iseq; - printf("JMPIF\t\tR%d\t%03d\t", a, (int)i+(int16_t)b); - print_lv_a(mrb, irep, a); + fprintf(out, "JMPIF\t\tR%d\t%03d\t", a, (int)i+(int16_t)b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_JMPNOT, BS): i = pc - irep->iseq; - printf("JMPNOT\tR%d\t%03d\t", a, (int)i+(int16_t)b); - print_lv_a(mrb, irep, a); + fprintf(out, "JMPNOT\tR%d\t%03d\t", a, (int)i+(int16_t)b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_JMPNIL, BS): i = pc - irep->iseq; - printf("JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b); - print_lv_a(mrb, irep, a); + fprintf(out, "JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_SSEND, BBB): - printf("SSEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); - print_args(c); + fprintf(out, "SSEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c, out); break; CASE(OP_SSENDB, BBB): - printf("SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); - print_args(c); + fprintf(out, "SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c, out); break; CASE(OP_SEND, BBB): - printf("SEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); - print_args(c); + fprintf(out, "SEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c, out); break; CASE(OP_SENDB, BBB): - printf("SENDB\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); - print_args(c); + fprintf(out, "SENDB\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c, out); break; CASE(OP_CALL, Z): - printf("CALL\n"); + fprintf(out, "CALL\n"); break; CASE(OP_SUPER, BB): - printf("SUPER\t\tR%d\t", a); - print_args(b); + fprintf(out, "SUPER\t\tR%d\t", a); + print_args(b, out); break; CASE(OP_ARGARY, BS): - printf("ARGARY\tR%d\t%d:%d:%d:%d (%d)\t", a, + fprintf(out, "ARGARY\tR%d\t%d:%d:%d:%d (%d)\t", a, (b>>11)&0x3f, (b>>10)&0x1, (b>>5)&0x1f, (b>>4)&0x1, (b>>0)&0xf); - print_lv_a(mrb, irep, a); + print_lv_a(mrb, irep, a, out); break; 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), a); + fprintf(out, "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), a); break; 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); + fprintf(out, "KEY_P\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; CASE(OP_KEYEND, Z): - printf("KEYEND\n"); + fprintf(out, "KEYEND\n"); break; 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); + fprintf(out, "KARG\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; CASE(OP_RETURN, B): - printf("RETURN\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "RETURN\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_RETURN_BLK, B): - printf("RETURN_BLK\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "RETURN_BLK\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_BREAK, B): - printf("BREAK\t\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "BREAK\t\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_BLKPUSH, BS): - printf("BLKPUSH\tR%d\t%d:%d:%d:%d (%d)\t", a, + fprintf(out, "BLKPUSH\tR%d\t%d:%d:%d:%d (%d)\t", a, (b>>11)&0x3f, (b>>10)&0x1, (b>>5)&0x1f, (b>>4)&0x1, (b>>0)&0xf); - print_lv_a(mrb, irep, a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_LAMBDA, BB): - printf("LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); break; CASE(OP_BLOCK, BB): - printf("BLOCK\t\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "BLOCK\t\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); break; CASE(OP_METHOD, BB): - printf("METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); break; CASE(OP_RANGE_INC, B): - printf("RANGE_INC\tR%d\n", a); + fprintf(out, "RANGE_INC\tR%d\n", a); break; CASE(OP_RANGE_EXC, B): - printf("RANGE_EXC\tR%d\n", a); + fprintf(out, "RANGE_EXC\tR%d\n", a); break; CASE(OP_DEF, BB): - printf("DEF\t\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); + fprintf(out, "DEF\t\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); break; CASE(OP_UNDEF, B): - printf("UNDEF\t\t:%s\n", mrb_sym_dump(mrb, irep->syms[a])); + fprintf(out, "UNDEF\t\t:%s\n", mrb_sym_dump(mrb, irep->syms[a])); break; 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])); + fprintf(out, "ALIAS\t\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b])); break; CASE(OP_ADD, B): - printf("ADD\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "ADD\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_ADDI, BB): - printf("ADDI\t\tR%d\t%d\t", a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "ADDI\t\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_SUB, B): - printf("SUB\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "SUB\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_SUBI, BB): - printf("SUBI\t\tR%d\t%d\t", a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "SUBI\t\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_MUL, B): - printf("MUL\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "MUL\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_DIV, B): - printf("DIV\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "DIV\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_LT, B): - printf("LT\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "LT\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_LE, B): - printf("LE\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "LE\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_GT, B): - printf("GT\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "GT\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_GE, B): - printf("GE\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "GE\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_EQ, B): - printf("EQ\t\tR%d\tR%d\n", a, a+1); + fprintf(out, "EQ\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_ARRAY, BB): - printf("ARRAY\t\tR%d\tR%d\t%d", a, a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "ARRAY\t\tR%d\tR%d\t%d", a, a, b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_ARRAY2, BBB): - printf("ARRAY\t\tR%d\tR%d\t%d", a, b, c); - print_lv_ab(mrb, irep, a, b); + fprintf(out, "ARRAY\t\tR%d\tR%d\t%d", a, b, c); + print_lv_ab(mrb, irep, a, b, out); break; CASE(OP_ARYCAT, B): - printf("ARYCAT\tR%d\tR%d\t", a, a+1); - print_lv_a(mrb, irep, a); + fprintf(out, "ARYCAT\tR%d\tR%d\t", a, a+1); + print_lv_a(mrb, irep, a, out); break; CASE(OP_ARYPUSH, BB): - printf("ARYPUSH\tR%d\t%d\t", a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "ARYPUSH\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a, out); break; - CASE(OP_ARYDUP, B): - printf("ARYDUP\tR%d\t", a); - print_lv_a(mrb, irep, a); + CASE(OP_ARYSPLAT, B): + fprintf(out, "ARYSPLAT\tR%d\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_AREF, BBB): - printf("AREF\t\tR%d\tR%d\t%d", a, b, c); - print_lv_ab(mrb, irep, a, b); + fprintf(out, "AREF\t\tR%d\tR%d\t%d", a, b, c); + print_lv_ab(mrb, irep, a, b, out); break; CASE(OP_ASET, BBB): - printf("ASET\t\tR%d\tR%d\t%d", a, b, c); - print_lv_ab(mrb, irep, a, b); + fprintf(out, "ASET\t\tR%d\tR%d\t%d", a, b, c); + print_lv_ab(mrb, irep, a, b, out); break; CASE(OP_APOST, BBB): - printf("APOST\t\tR%d\t%d\t%d", a, b, c); - print_lv_a(mrb, irep, a); + fprintf(out, "APOST\t\tR%d\t%d\t%d", a, b, c); + print_lv_a(mrb, irep, a, out); break; CASE(OP_INTERN, B): - printf("INTERN\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "INTERN\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "SYMBOL\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + print_lv_a(mrb, irep, a, out); break; CASE(OP_STRING, BB): mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); - if ((irep->pool[b].tt & IREP_TT_NFLAG) == 0) { - printf("STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); - } - else { - printf("STRING\tR%d\tL(%d)\t", a, b); - } - print_lv_a(mrb, irep, a); + fprintf(out, "STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + print_lv_a(mrb, irep, a, out); break; CASE(OP_STRCAT, B): - printf("STRCAT\tR%d\tR%d", a, a+1); - print_lv_a(mrb, irep, a); + fprintf(out, "STRCAT\tR%d\tR%d\t", a, a+1); + print_lv_a(mrb, irep, a, out); break; CASE(OP_HASH, BB): - printf("HASH\t\tR%d\t%d\t", a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "HASH\t\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_HASHADD, BB): - printf("HASHADD\tR%d\t%d\t", a, b); - print_lv_a(mrb, irep, a); + fprintf(out, "HASHADD\tR%d\t%d\t", a, b); + print_lv_a(mrb, irep, a, out); break; CASE(OP_HASHCAT, B): - printf("HASHCAT\tR%d\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "HASHCAT\tR%d\tR%d\t", a, a+1); + print_lv_a(mrb, irep, a, out); break; CASE(OP_OCLASS, B): - printf("OCLASS\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "OCLASS\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; 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); + fprintf(out, "CLASS\t\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; CASE(OP_MODULE, BB): - printf("MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); - print_lv_a(mrb, irep, a); + fprintf(out, "MODULE\tR%d\t:%s", a, mrb_sym_dump(mrb, irep->syms[b])); + print_lv_a(mrb, irep, a, out); break; CASE(OP_EXEC, BB): - printf("EXEC\t\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]); - print_lv_a(mrb, irep, a); + fprintf(out, "EXEC\t\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]); + print_lv_a(mrb, irep, a, out); break; CASE(OP_SCLASS, B): - printf("SCLASS\t\tR%d\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "SCLASS\t\tR%d\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_TCLASS, B): - printf("TCLASS\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "TCLASS\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_ERR, B): if ((irep->pool[a].tt & IREP_TT_NFLAG) == 0) { - printf("ERR\t\t%s\n", irep->pool[a].u.str); + fprintf(out, "ERR\t\t%s\n", irep->pool[a].u.str); } else { - printf("ERR\tL(%d)\n", a); + fprintf(out, "ERR\tL(%d)\n", a); } break; CASE(OP_EXCEPT, B): - printf("EXCEPT\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "EXCEPT\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_RESCUE, BB): - printf("RESCUE\tR%d\tR%d", a, b); - print_lv_ab(mrb, irep, a, b); + fprintf(out, "RESCUE\tR%d\tR%d", a, b); + print_lv_ab(mrb, irep, a, b, out); break; CASE(OP_RAISEIF, B): - printf("RAISEIF\tR%d\t\t", a); - print_lv_a(mrb, irep, a); + fprintf(out, "RAISEIF\tR%d\t\t", a); + print_lv_a(mrb, irep, a, out); break; CASE(OP_DEBUG, BBB): - printf("DEBUG\t\t%d\t%d\t%d\n", a, b, c); + fprintf(out, "DEBUG\t\t%d\t%d\t%d\n", a, b, c); break; CASE(OP_STOP, Z): - printf("STOP\n"); + fprintf(out, "STOP\n"); break; CASE(OP_EXT1, Z): - printf("EXT1\n"); - print_header(mrb, irep, pc-irep->iseq); + fprintf(out, "EXT1\n"); + print_header(mrb, irep, pc-irep->iseq, out); ins = READ_B(); switch (ins) { #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); goto L_OP_ ## i; @@ -583,8 +588,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep) } break; CASE(OP_EXT2, Z): - printf("EXT2\n"); - print_header(mrb, irep, pc-irep->iseq); + fprintf(out, "EXT2\n"); + print_header(mrb, irep, pc-irep->iseq, out); ins = READ_B(); switch (ins) { #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); goto L_OP_ ## i; @@ -593,8 +598,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep) } break; CASE(OP_EXT3, Z): - printf("EXT3\n"); - print_header(mrb, irep, pc-irep->iseq); + fprintf(out, "EXT3\n"); + print_header(mrb, irep, pc-irep->iseq, out); ins = READ_B(); switch (ins) { #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); goto L_OP_ ## i; @@ -604,32 +609,39 @@ codedump(mrb_state *mrb, const mrb_irep *irep) break; default: - printf("unknown_op (0x%x)\n", ins); + fprintf(out, "unknown_op (0x%x)\n", ins); break; } mrb_gc_arena_restore(mrb, ai); } - printf("\n"); + fprintf(out, "\n"); } static void -codedump_recur(mrb_state *mrb, const mrb_irep *irep) +codedump_recur(mrb_state *mrb, const mrb_irep *irep, FILE *out) { int i; - codedump(mrb, irep); + codedump(mrb, irep, out); if (irep->reps) { for (i=0; irlen; i++) { - codedump_recur(mrb, irep->reps[i]); + codedump_recur(mrb, irep->reps[i], out); } } } + +void +mrb_codedump_all_file(mrb_state *mrb, struct RProc *proc, FILE *out) +{ + codedump_recur(mrb, proc->body.irep, out); +} + #endif void mrb_codedump_all(mrb_state *mrb, struct RProc *proc) { #ifndef MRB_NO_STDIO - codedump_recur(mrb, proc->body.irep); + mrb_codedump_all_file(mrb, proc, stdout); #endif } diff --git a/mruby/src/debug.c b/mruby/src/debug.c index e570e806..11af6fcf 100644 --- a/mruby/src/debug.c +++ b/mruby/src/debug.c @@ -63,7 +63,7 @@ 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) +mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos) { size_t i = 0, shift = 0; uint32_t n = 0; @@ -106,11 +106,11 @@ mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) case mrb_debug_line_flat_map: { /* get upper bound */ - mrb_irep_debug_info_line *ret = f->lines.flat_map; + const mrb_irep_debug_info_line *ret = f->lines.flat_map; uint32_t count = f->line_entry_count; while (count > 0) { int32_t step = count / 2; - mrb_irep_debug_info_line *it = ret + step; + const mrb_irep_debug_info_line *it = ret + step; if (!(pc < it->start_pos)) { ret = it + 1; count -= step + 1; @@ -131,8 +131,8 @@ mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) } case mrb_debug_line_packed_map: { - uint8_t *p = f->lines.packed_map; - uint8_t *pend = p + f->line_entry_count; + const uint8_t *p = f->lines.packed_map; + const 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); @@ -202,17 +202,17 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, size_t packed_size = 0; uint8_t *p, *pend; - for (i = 0; i < file_pc_count; ++i) { + 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); + f->lines.packed_map = p = (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) { + 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; @@ -232,7 +232,7 @@ mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d) if (!d) { return; } if (d->files) { - for (i = 0; i < d->flen; ++i) { + for (i = 0; i < d->flen; i++) { if (d->files[i]) { mrb_free(mrb, d->files[i]->lines.ptr); mrb_free(mrb, d->files[i]); diff --git a/mruby/src/dump.c b/mruby/src/dump.c index 3841e12a..c0ad4b68 100644 --- a/mruby/src/dump.c +++ b/mruby/src/dump.c @@ -110,7 +110,7 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep) switch (irep->pool[pool_no].tt) { case IREP_TT_INT64: -#ifdef MRB_64BIT +#if defined(MRB_64BIT) || defined(MRB_INT64) { int64_t i = irep->pool[pool_no].u.i64; @@ -131,7 +131,6 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep) { mrb_int len = irep->pool[pool_no].u.str[0]; mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); - size += sizeof(uint8_t); size += (size_t)len+2; } break; @@ -173,8 +172,8 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) int ai = mrb_gc_arena_save(mrb); switch (irep->pool[pool_no].tt) { -#ifdef MRB_64BIT case IREP_TT_INT64: +#if defined(MRB_64BIT) || defined(MRB_INT64) { int64_t i = irep->pool[pool_no].u.i64; if (i < INT32_MIN || INT32_MAX < i) { @@ -199,7 +198,6 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) len = irep->pool[pool_no].u.str[0]; memcpy(cur, irep->pool[pool_no].u.str, (size_t)len+2); cur += len+2; - *cur++ = '\0'; break; case IREP_TT_FLOAT: diff --git a/mruby/src/error.c b/mruby/src/error.c index 5fa872c9..a0e23fad 100644 --- a/mruby/src/error.c +++ b/mruby/src/error.c @@ -15,36 +15,24 @@ #include #include #include +#include #include -static void -exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) +void +mrb_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); - } + if (!mrb_string_p(mesg)) { + mesg = mrb_obj_as_string(mrb, mesg); } + exc->mesg = mrb_obj_ptr(mesg); + mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, mesg); } -static mrb_value -exc_mesg_get(mrb_state *mrb, struct RException *exc) +mrb_value +mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc) { - 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)); - } + if (exc->mesg == NULL) return mrb_nil_value(); + return mrb_obj_value(exc->mesg); } MRB_API mrb_value @@ -52,14 +40,14 @@ mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) { mrb_ensure_string_type(mrb, str); - struct RBasic* e = mrb_obj_alloc(mrb, MRB_TT_EXCEPTION, c); + struct RException *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); + mrb_exc_mesg_set(mrb, e, str); return exc; } MRB_API mrb_value -mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len) +mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, mrb_int len) { return mrb_exc_new_str(mrb, c, mrb_str_new(mrb, ptr, len)); } @@ -78,7 +66,7 @@ exc_initialize(mrb_state *mrb, mrb_value exc) mrb_value mesg; if (mrb_get_args(mrb, "|o", &mesg) == 1) { - exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); + mrb_exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); } return exc; } @@ -107,7 +95,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); - exc_mesg_set(mrb, mrb_exc_ptr(exc), a); + mrb_exc_mesg_set(mrb, mrb_exc_ptr(exc), a); return exc; } @@ -123,7 +111,7 @@ exc_exception(mrb_state *mrb, mrb_value self) static mrb_value exc_to_s(mrb_state *mrb, mrb_value exc) { - mrb_value mesg = exc_mesg_get(mrb, mrb_exc_ptr(exc)); + mrb_value mesg = mrb_exc_mesg_get(mrb, mrb_exc_ptr(exc)); struct RObject *p; if (!mrb_string_p(mesg)) { @@ -136,20 +124,6 @@ exc_to_s(mrb_state *mrb, mrb_value exc) return mesg; } -/* - * call-seq: - * exception.message -> string - * - * Returns the result of invoking exception.to_s. - * Normally this returns the exception's message or name. - */ - -static mrb_value -exc_message(mrb_state *mrb, mrb_value exc) -{ - return mrb_funcall_id(mrb, exc, MRB_SYM(to_s), 0); -} - /* * call-seq: * exception.inspect -> string @@ -163,10 +137,9 @@ exc_message(mrb_state *mrb, mrb_value exc) mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc) { - 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); + mrb_value mesg = mrb_exc_mesg_get(mrb, mrb_exc_ptr(exc)); /* string or nil */ + return (mrb_nil_p(mesg)||RSTRING_LEN(mesg)==0) ? cname : mrb_format(mrb, "%v (%v)", mesg, cname); } void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc); @@ -187,7 +160,8 @@ set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace) p++; } } - mrb_iv_set(mrb, exc, MRB_SYM(backtrace), backtrace); + mrb_exc_ptr(exc)->backtrace = mrb_obj_ptr(backtrace); + mrb_field_write_barrier_value(mrb, mrb_basic_ptr(exc), backtrace); } static mrb_value @@ -221,7 +195,7 @@ static mrb_noreturn void exc_throw(mrb_state *mrb, mrb_value exc) { if (!mrb->jmp) { - mrb_p(mrb, exc); + mrb_print_error(mrb); abort(); } MRB_THROW(mrb->jmp); @@ -304,7 +278,7 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap) if (c == '%') { if (*p == '!') { inspect = TRUE; - ++p; + p++; } if (!*p) break; switch (*p) { @@ -534,25 +508,24 @@ mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv) return mesg; } -MRB_API void +MRB_API mrb_noreturn void mrb_sys_fail(mrb_state *mrb, const char *mesg) { struct RClass *sce; mrb_int no; no = (mrb_int)errno; - if (mrb_class_defined(mrb, "SystemCallError")) { - sce = mrb_class_get(mrb, "SystemCallError"); + if (mrb_class_defined_id(mrb, MRB_SYM(SystemCallError))) { + sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError)); if (mesg != NULL) { - mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); + mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); } else { - mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no)); + mrb_funcall_id(mrb, mrb_obj_value(sce), MRB_SYM(_sys_fail), 1, mrb_fixnum_value(no)); } } - else { - mrb_raise(mrb, E_RUNTIME_ERROR, mesg); - } + + mrb_raise(mrb, E_RUNTIME_ERROR, mesg); } MRB_API mrb_noreturn void @@ -603,7 +576,7 @@ mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *o err = 0; } MRB_CATCH(&c_jmp) { if (mrb->exc) { - mrb_p(mrb, mrb_obj_value(mrb->exc)); + mrb_print_error(mrb); mrb->exc = NULL; } else { @@ -656,6 +629,26 @@ mrb_raise_nomemory(mrb_state *mrb) } } +MRB_API void +mrb_print_error(mrb_state *mrb) +{ +#ifndef MRB_NO_STDIO + if (mrb->jmp == NULL) { + struct mrb_jmpbuf c_jmp; + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + mrb_print_backtrace(mrb); + } MRB_CATCH(&c_jmp) { + /* ignore exception during print_backtrace() */ + } MRB_END_EXC(&c_jmp); + mrb->jmp = NULL; + } + else { + mrb_print_backtrace(mrb); + } +#endif +} + void mrb_init_exception(mrb_state *mrb) { @@ -667,7 +660,6 @@ mrb_init_exception(mrb_state *mrb) mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_OPT(1)); mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_OPT(1)); mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "inspect", mrb_exc_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE()); mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); diff --git a/mruby/src/etc.c b/mruby/src/etc.c index 28abbbeb..83419223 100644 --- a/mruby/src/etc.c +++ b/mruby/src/etc.c @@ -9,13 +9,14 @@ #include #include #include +#include MRB_API struct RData* mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb_data_type *type) { struct RData *data; - data = MRB_OBJ_ALLOC(mrb, MRB_TT_DATA, klass); + data = MRB_OBJ_ALLOC(mrb, MRB_TT_CDATA, klass); data->data = ptr; data->type = type; @@ -26,7 +27,7 @@ MRB_API void mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) { if (!mrb_data_p(obj)) { - mrb_check_type(mrb, obj, MRB_TT_DATA); + mrb_check_type(mrb, obj, MRB_TT_CDATA); } if (DATA_TYPE(obj) != type) { const mrb_data_type *t2 = DATA_TYPE(obj); @@ -70,33 +71,13 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name) return 0; /* not reached */ } -static mrb_int -make_num_id(const char *p, size_t len) -{ - uint32_t id = 0; - - while (len--) { - id = id*65599 + *p; - p++; - } - id = id + (id>>5); - - return (mrb_int)id; -} - -MRB_API mrb_int -mrb_int_id(mrb_int n) -{ - return make_num_id((const char*)&n, sizeof(n)); -} - #ifndef MRB_NO_FLOAT -MRB_API mrb_int +static mrb_int mrb_float_id(mrb_float f) { /* normalize -0.0 to 0.0 */ if (f == 0) f = 0.0; - return make_num_id((const char*)&f, sizeof(f)); + return (mrb_int)mrb_byte_hash((uint8_t*)&f, sizeof(f)); } #endif @@ -140,7 +121,7 @@ mrb_obj_id(mrb_value obj) case MRB_TT_SYMBOL: return MakeID(mrb_symbol(obj), tt); case MRB_TT_INTEGER: - return MakeID(mrb_int_id(mrb_integer(obj)), tt); + return MakeID(mrb_integer(obj), tt); #ifndef MRB_NO_FLOAT case MRB_TT_FLOAT: return MakeID(mrb_float_id(mrb_float(obj)), tt); @@ -156,7 +137,7 @@ mrb_obj_id(mrb_value obj) case MRB_TT_HASH: case MRB_TT_RANGE: case MRB_TT_EXCEPTION: - case MRB_TT_DATA: + case MRB_TT_CDATA: case MRB_TT_ISTRUCT: default: return MakeID(mrb_ptr(obj), tt); @@ -178,7 +159,7 @@ mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f) #elif defined(MRB_64BIT) && defined(MRB_USE_FLOAT32) v.w = 0; v.f = f; - v.w = ((v.w<<2) & ~3) | 2; + v.w = (v.w<<2) | 2; #else v.f = f; v.w = (v.w & ~3) | 2; @@ -193,9 +174,10 @@ 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; +#else + u.w &= ~3; #endif return u.f; } diff --git a/mruby/src/fmt_fp.c b/mruby/src/fmt_fp.c index bcb9ccc2..7c5b01a9 100644 --- a/mruby/src/fmt_fp.c +++ b/mruby/src/fmt_fp.c @@ -5,7 +5,7 @@ /*********************************************************************** Routine for converting a single-precision - floating point number into a string. + floating-point number into a string. 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 @@ -78,7 +78,7 @@ static const mrb_float g_neg_pow[] = { 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 buf_remaining = (int)buf_size - 1; int alt_form = 0; if ((uint8_t)fmt & 0x80) { @@ -103,7 +103,7 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch } else if (sign) { *s++ = sign; } - buf_remaining -= (s - buf); // Adjust for sign + buf_remaining -= (int)(s - buf); // Adjust for sign { char uc = fmt & 0x20; @@ -118,7 +118,7 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch *s++ = 'N' ^ uc; ret: *s = '\0'; - return s - buf; + return (int)(s - buf); } } @@ -254,7 +254,7 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch prec = 0; } - // We now have f as a floating point number between >= 1 and < 10 + // 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. @@ -275,7 +275,7 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch } // Print the digits of the mantissa - for (int i = 0; i < num_digits; ++i, --dec) { + 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)) { @@ -358,6 +358,6 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch } *s = '\0'; - return s - buf; + return (int)(s - buf); } #endif diff --git a/mruby/src/gc.c b/mruby/src/gc.c index a6ff0c58..f1b50ad7 100644 --- a/mruby/src/gc.c +++ b/mruby/src/gc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #ifdef MRB_GC_STRESS @@ -192,7 +193,7 @@ gettimeofday_time(void) #define GC_STEP_SIZE 1024 -/* white: 001 or 010, black: 100, gray: 000 */ +/* white: 001 or 010, black: 100, gray: 000, red:111 */ #define GC_GRAY 0 #define GC_WHITE_A 1 #define GC_WHITE_B (1 << 1) @@ -214,7 +215,11 @@ mrb_static_assert(MRB_GC_RED <= GC_COLOR_MASK); #define other_white_part(s) ((s)->current_white_part ^ GC_WHITES) #define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE) -#define objects(p) ((RVALUE *)p->objects) +/* We have removed `objects[]` from `mrb_heap_page` since it was not C++ + * compatible. Using array index to get pointer after structure instead. */ + +/* #define objects(p) ((RVALUE *)p->objects) */ +#define objects(p) ((RVALUE *)&p[1]) mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); @@ -223,6 +228,9 @@ mrb_realloc_simple(mrb_state *mrb, void *p, size_t len) { void *p2; +#if defined(MRB_GC_STRESS) && defined(MRB_DEBUG) + mrb_full_gc(mrb); +#endif p2 = (mrb->allocf)(mrb, p, len, mrb->allocf_ud); if (!p2 && len > 0 && mrb->gc.heaps) { mrb_full_gc(mrb); @@ -292,7 +300,7 @@ MRB_API void* mrb_alloca(mrb_state *mrb, size_t size) { struct RString *s; - s = MRB_OBJ_ALLOC(mrb, MRB_TT_STRING, mrb->string_class); + s = MRB_OBJ_ALLOC(mrb, MRB_TT_STRING, NULL); return s->as.heap.ptr = (char*)mrb_malloc(mrb, size); } @@ -306,7 +314,7 @@ heap_p(mrb_gc *gc, struct RBasic *object) RVALUE *p; p = objects(page); - if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) { + if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE - 1].as.basic) { return TRUE; } page = page->next; @@ -315,7 +323,8 @@ heap_p(mrb_gc *gc, struct RBasic *object) } MRB_API mrb_bool -mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) { +mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) +{ mrb_gc *gc = &mrb->gc; if (!heap_p(gc, object)) return TRUE; return is_dead(gc, object); @@ -457,8 +466,9 @@ gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) #else if (gc->arena_idx >= gc->arena_capa) { /* extend arena */ - gc->arena_capa = (int)(gc->arena_capa * 3 / 2); - gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa); + int newcapa = gc->arena_capa * 3 / 2; + gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*newcapa); + gc->arena_capa = newcapa; } #endif gc->arena[gc->arena_idx++] = p; @@ -469,7 +479,9 @@ MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj) { if (mrb_immediate_p(obj)) return; - gc_protect(mrb, &mrb->gc, mrb_basic_ptr(obj)); + struct RBasic *p = mrb_basic_ptr(obj); + if (is_red(p)) return; + gc_protect(mrb, &mrb->gc, p); } #define GC_ROOT_SYM MRB_SYM(_gc_root_) @@ -553,6 +565,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) ttype != MRB_TT_SCLASS && ttype != MRB_TT_ICLASS && ttype != MRB_TT_ENV && + ttype != MRB_TT_BIGINT && ttype != tt) { mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls); } @@ -599,8 +612,6 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) gc->gray_list = obj; } -mrb_int mrb_ci_nregs(mrb_callinfo *ci); - static void mark_context_stack(mrb_state *mrb, struct mrb_context *c) { @@ -685,7 +696,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) /* fall through */ case MRB_TT_OBJECT: - case MRB_TT_DATA: + case MRB_TT_CDATA: mrb_gc_mark_iv(mrb, (struct RObject*)obj); break; @@ -760,9 +771,10 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_EXCEPTION: mrb_gc_mark_iv(mrb, (struct RObject*)obj); - if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + if (((struct RException*)obj)->mesg) { mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->mesg); } + mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->backtrace); break; default: @@ -834,7 +846,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) struct REnv *e = ci->u.env; if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) { - mrb_env_unshare(mrb, e); + mrb_env_unshare(mrb, e, TRUE); } ci--; } @@ -879,7 +891,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) mrb_gc_free_range(mrb, ((struct RRange*)obj)); break; - case MRB_TT_DATA: + case MRB_TT_CDATA: { struct RData *d = (struct RData*)obj; if (d->type && d->type->dfree) { @@ -907,9 +919,19 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) break; #endif +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + mrb_gc_free_bint(mrb, obj); + break; +#endif + default: break; } +#if defined(MRB_GC_STRESS) && defined(MRB_DEBUG) + memset(obj, -1, sizeof(RVALUE)); + paint_white(obj); +#endif obj->tt = MRB_TT_FREE; } @@ -957,12 +979,6 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc) mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self); /* mark exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); - /* mark pre-allocated exception */ - mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err); - mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err); -#ifdef MRB_GC_FIXED_ARENA - mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); -#endif mark_context(mrb, mrb->c); if (mrb->root_c != mrb->c) { @@ -994,7 +1010,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) break; case MRB_TT_OBJECT: - case MRB_TT_DATA: + case MRB_TT_CDATA: children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); break; @@ -1009,13 +1025,11 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) mrb_callinfo *ci; if (!c || c->status == MRB_FIBER_TERMINATED) break; + if (!c->ci) break; /* mark stack */ i = c->ci->stack - c->stbase; - - if (c->ci) { - i += mrb_ci_nregs(c->ci); - } + i += mrb_ci_nregs(c->ci); if (c->stbase + i > c->stend) i = c->stend - c->stbase; children += i; @@ -1049,7 +1063,10 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_EXCEPTION: children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj); - if ((obj->flags & MRB_EXC_MESG_STRING_FLAG) != 0) { + if (((struct RException*)obj)->mesg) { + children++; + } + if (((struct RException*)obj)->backtrace) { children++; } break; @@ -1060,7 +1077,6 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) return children; } - static void gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) { while (gc->gray_list) { @@ -1070,7 +1086,6 @@ gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) { } } - static size_t incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) { @@ -1086,6 +1101,20 @@ incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) return tried_marks; } +static void +clear_error_object(mrb_state *mrb, struct RObject *obj) +{ + if (obj == 0) return; + if (!is_white(obj)) return; + paint_black(obj); + mrb_gc_mark(mrb, (struct RBasic*)obj->c); + mrb_gc_free_iv(mrb, obj); + struct RException *err = (struct RException*)obj; + err->iv = NULL; + err->mesg = NULL; + err->backtrace = NULL; +} + static void final_marking_phase(mrb_state *mrb, mrb_gc *gc) { @@ -1101,6 +1130,14 @@ final_marking_phase(mrb_state *mrb, mrb_gc *gc) mark_context(mrb, mrb->root_c); } mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); + + /* mark pre-allocated exception */ + clear_error_object(mrb, mrb->nomem_err); + clear_error_object(mrb, mrb->stack_err); +#ifdef MRB_GC_FIXED_ARENA + clear_error_object(mrb, mrb->arena_err); +#endif + gc_mark_gray_list(mrb, gc); mrb_assert(gc->gray_list == NULL); gc->gray_list = gc->atomic_gray_list; @@ -1112,6 +1149,8 @@ final_marking_phase(mrb_state *mrb, mrb_gc *gc) static void prepare_incremental_sweep(mrb_state *mrb, mrb_gc *gc) { + // mrb_assert(gc->atomic_gray_list == NULL); + // mrb_assert(gc->gray_list == NULL); gc->state = MRB_GC_STATE_SWEEP; gc->sweeps = gc->heaps; gc->live_after_mark = gc->live; @@ -1217,11 +1256,11 @@ incremental_gc(mrb_state *mrb, mrb_gc *gc, size_t limit) } static void -incremental_gc_until(mrb_state *mrb, mrb_gc *gc, mrb_gc_state to_state) +incremental_gc_finish(mrb_state *mrb, mrb_gc *gc) { do { incremental_gc(mrb, gc, SIZE_MAX); - } while (gc->state != to_state); + } while (gc->state != MRB_GC_STATE_ROOT); } static void @@ -1246,14 +1285,15 @@ clear_all_old(mrb_state *mrb, mrb_gc *gc) mrb_assert(is_generational(gc)); if (is_major_gc(gc)) { /* finish the half baked GC */ - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + incremental_gc_finish(mrb, gc); + } + else { + /* Sweep the dead objects, then reset all the live objects + * (including all the old objects, of course) to white. */ + gc->generational = FALSE; + prepare_incremental_sweep(mrb, gc); + incremental_gc_finish(mrb, gc); } - - /* Sweep the dead objects, then reset all the live objects - * (including all the old objects, of course) to white. */ - gc->generational = FALSE; - prepare_incremental_sweep(mrb, gc); - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); gc->generational = origin_mode; /* The gray objects have already been painted as white */ @@ -1271,7 +1311,7 @@ mrb_incremental_gc(mrb_state *mrb) GC_TIME_START; if (is_minor_gc(gc)) { - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + incremental_gc_finish(mrb, gc); } else { incremental_gc_step(mrb, gc); @@ -1327,10 +1367,10 @@ mrb_full_gc(mrb_state *mrb) } else if (gc->state != MRB_GC_STATE_ROOT) { /* finish half baked GC cycle */ - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + incremental_gc_finish(mrb, gc); } - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + incremental_gc_finish(mrb, gc); gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio; if (is_generational(gc)) { @@ -1360,8 +1400,10 @@ mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value { mrb_gc *gc = &mrb->gc; + if (!value) return; if (!is_black(obj)) return; if (!is_white(value)) return; + if (is_red(value)) return; mrb_assert(gc->state == MRB_GC_STATE_MARK || (!is_dead(gc, value) && !is_dead(gc, obj))); mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); @@ -1537,7 +1579,7 @@ change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable) gc->full = FALSE; } else if (!is_generational(gc) && enable) { - incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT); + incremental_gc_finish(mrb, gc); gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; gc->full = FALSE; } @@ -1637,8 +1679,7 @@ mrb_init_gc(mrb_state *mrb) { struct RClass *gc; - mrb_static_assert(sizeof(RVALUE) <= sizeof(void*) * 6, - "RVALUE size must be within 6 words"); + mrb_static_assert_object_size(RVALUE); gc = mrb_define_module(mrb, "GC"); diff --git a/mruby/src/hash.c b/mruby/src/hash.c index fc6b6fa6..40cfacf6 100644 --- a/mruby/src/hash.c +++ b/mruby/src/hash.c @@ -11,6 +11,7 @@ #include #include #include +#include #include /* @@ -169,7 +170,7 @@ DEFINE_SWITCHER(ht, HT) #define ea_each_used(ea, n_used, entry_var, code) do { \ hash_entry *entry_var = ea, *ea_end__ = entry_var + (n_used); \ - for (; entry_var < ea_end__; ++entry_var) { \ + for (; entry_var < ea_end__; entry_var++) { \ code; \ } \ } while (0) @@ -177,7 +178,7 @@ DEFINE_SWITCHER(ht, HT) #define ea_each(ea, size, entry_var, code) do { \ hash_entry *entry_var = ea; \ uint32_t size__ = size; \ - for (; 0 < size__; ++entry_var) { \ + for (; 0 < size__; entry_var++) { \ if (entry_deleted_p(entry_var)) continue; \ --size__; \ code; \ @@ -293,6 +294,7 @@ static uint32_t ib_bit_to_capa(uint32_t bit); static void ht_init( mrb_state *mrb, struct RHash *h, uint32_t size, hash_entry *ea, uint32_t ea_capa, hash_table *ht, uint32_t ib_bit); +static void ht_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val); static void ht_set_without_ib_adjustment( mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val); @@ -308,7 +310,7 @@ next_power2(uint32_t v) v |= v >> 4; v |= v >> 8; v |= v >> 16; - ++v; + v++; return v; #endif } @@ -424,7 +426,7 @@ ea_compress(hash_entry *ea, uint32_t n_used) ea_each_used(ea, n_used, r_entry, { if (entry_deleted_p(r_entry)) continue; if (r_entry != w_entry) *w_entry = *r_entry; - ++w_entry; + w_entry++; }); } @@ -530,9 +532,8 @@ ar_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val) if (ea_capa == ea_n_used) { if (size == ea_n_used) { if (size == AR_MAX_SIZE) { - hash_entry *ea = ea_adjust(mrb, ar_ea(h), &ea_capa, EA_MAX_CAPA); - ea_set(ea, ea_n_used, key, val); - ht_init(mrb, h, ++size, ea, ea_capa, NULL, IB_INIT_BIT); + ht_init(mrb, h, size, ar_ea(h), ea_capa, NULL, IB_INIT_BIT); + ht_set(mrb, h, key, val); return; } else { @@ -591,7 +592,7 @@ ar_rehash(mrb_state *mrb, struct RHash *h) ea_set(ea, w_size, r_entry->key, r_entry->val); entry_delete(r_entry); } - ++w_size; + w_size++; } }); mrb_assert(size == w_size); @@ -783,8 +784,9 @@ ht_init(mrb_state *mrb, struct RHash *h, uint32_t size, { size_t ib_byte_size = ib_byte_size_for(ib_bit); size_t ht_byte_size = sizeof(hash_table) + ib_byte_size; + ht = (hash_table*)mrb_realloc(mrb, ht, ht_byte_size); h_ht_on(h); - h_set_ht(h, (hash_table*)mrb_realloc(mrb, ht, ht_byte_size)); + h_set_ht(h, ht); ht_set_size(h, size); ht_set_ea(h, ea); ht_set_ea_capa(h, ea_capa); @@ -1745,6 +1747,19 @@ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2) }); } +static mrb_value +mrb_hash_merge_m(mrb_state *mrb, mrb_value hash) +{ + mrb_int argc; + mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + while (argc--) { + mrb_hash_merge(mrb, hash, *argv++); + } + return hash; +} + /* * call-seq: * hsh.rehash -> hsh @@ -1805,4 +1820,5 @@ mrb_init_hash(mrb_state *mrb) mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */ mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */ mrb_define_method(mrb, h, "rehash", mrb_hash_rehash, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "__merge", mrb_hash_merge_m, MRB_ARGS_REQ(1)); } diff --git a/mruby/src/kernel.c b/mruby/src/kernel.c index 7a261560..250f01d2 100644 --- a/mruby/src/kernel.c +++ b/mruby/src/kernel.c @@ -13,6 +13,7 @@ #include #include #include +#include #include MRB_API mrb_bool @@ -77,6 +78,16 @@ mrb_equal_m(mrb_state *mrb, mrb_value self) return mrb_bool_value(mrb_equal(mrb, self, arg)); } +static mrb_value +mrb_cmp_m(mrb_state *mrb, mrb_value self) +{ + mrb_value arg = mrb_get_arg1(mrb); + + if (mrb_equal(mrb, self, arg)) + return mrb_fixnum_value(0); + return mrb_nil_value(); +} + /* 15.3.1.3.3 */ /* 15.3.1.3.33 */ /* @@ -215,59 +226,6 @@ mrb_obj_class_m(mrb_state *mrb, mrb_value self) return mrb_obj_value(mrb_obj_class(mrb, self)); } -static mrb_value -mrb_obj_extend(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value obj) -{ - mrb_int i; - - if (argc == 0) { - mrb_argnum_error(mrb, argc, 1, -1); - } - for (i = 0; i < argc; i++) { - mrb_check_type(mrb, argv[i], MRB_TT_MODULE); - } - while (argc--) { - mrb_funcall_id(mrb, argv[argc], MRB_SYM(extend_object), 1, obj); - mrb_funcall_id(mrb, argv[argc], MRB_SYM(extended), 1, obj); - } - return obj; -} - -/* 15.3.1.3.13 */ -/* - * call-seq: - * obj.extend(module, ...) -> obj - * - * Adds to _obj_ the instance methods from each module given as a - * parameter. - * - * module Mod - * def hello - * "Hello from Mod.\n" - * end - * end - * - * class Klass - * def hello - * "Hello from Klass.\n" - * end - * end - * - * k = Klass.new - * k.hello #=> "Hello from Klass.\n" - * k.extend(Mod) #=> # - * k.hello #=> "Hello from Mod.\n" - */ -static mrb_value -mrb_obj_extend_m(mrb_state *mrb, mrb_value self) -{ - const mrb_value *argv; - mrb_int argc; - - mrb_get_args(mrb, "*", &argv, &argc); - return mrb_obj_extend(mrb, argc, argv, self); -} - MRB_API mrb_value mrb_obj_freeze(mrb_state *mrb, mrb_value self) { @@ -301,6 +259,11 @@ mrb_obj_frozen(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_hash(mrb_state *mrb, mrb_value self) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_hash(mrb, self); + } +#endif return mrb_int_value(mrb, mrb_obj_id(self)); } @@ -478,59 +441,6 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) return val; } -void -mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) -{ - mrb_no_method_error(mrb, name, args, "undefined method '%n'", name); -} - -/* 15.3.1.3.30 */ -/* - * call-seq: - * obj.method_missing(symbol [, *args] ) -> result - * - * Invoked by Ruby when obj is sent a message it cannot handle. - * symbol is the symbol for the method called, and args - * are any arguments that were passed to it. By default, the interpreter - * raises an error when this method is called. However, it is possible - * to override the method to provide more dynamic behavior. - * If it is decided that a particular method should not be handled, then - * super should be called, so that ancestors can pick up the - * missing method. - * The example below creates - * a class Roman, which responds to methods with names - * consisting of roman numerals, returning the corresponding integer - * values. - * - * class Roman - * def romanToInt(str) - * # ... - * end - * def method_missing(methId) - * str = methId.to_s - * romanToInt(str) - * end - * end - * - * r = Roman.new - * r.iv #=> 4 - * r.xxiii #=> 23 - * r.mm #=> 2000 - */ -mrb_value -mrb_obj_missing(mrb_state *mrb, mrb_value mod) -{ - mrb_sym name; - 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 */ - return mrb_nil_value(); -} - static inline mrb_bool basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) { @@ -589,13 +499,13 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) else if (mrb_nil_p(self)) { return mrb_false_value(); } - else if (!mrb_respond_to(mrb, self, mrb_intern_lit(mrb, "to_a"))) { + else if (!mrb_respond_to(mrb, self, MRB_SYM(to_a))) { mrb_value c = mrb_funcall_argv(mrb, self, eqq, 1, &v); if (mrb_test(c)) return mrb_true_value(); return mrb_false_value(); } else { - ary = mrb_funcall(mrb, self, "to_a", 0); + ary = mrb_funcall_id(mrb, self, MRB_SYM(to_a), 0); if (mrb_nil_p(ary)) { return mrb_funcall_argv(mrb, self, eqq, 1, &v); } @@ -630,17 +540,16 @@ mrb_init_kernel(mrb_state *mrb) mrb->kernel_module = krn = mrb_define_module(mrb, "Kernel"); /* 15.3.1 */ mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.2 */ mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.5 */ -; /* 15.3.1.2.11 */ mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_OPT(2)); /* 15.3.1.2.12 */ mrb_define_method(mrb, krn, "===", mrb_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */ + mrb_define_method(mrb, krn, "<=>", mrb_cmp_m, MRB_ARGS_REQ(1)); mrb_define_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.6 */ mrb_define_method(mrb, krn, "class", mrb_obj_class_m, MRB_ARGS_NONE()); /* 15.3.1.3.7 */ mrb_define_method(mrb, krn, "clone", mrb_obj_clone, MRB_ARGS_NONE()); /* 15.3.1.3.8 */ mrb_define_method(mrb, krn, "dup", mrb_obj_dup, MRB_ARGS_NONE()); /* 15.3.1.3.9 */ mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */ - mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, MRB_ARGS_ANY()); /* 15.3.1.3.13 */ mrb_define_method(mrb, krn, "freeze", mrb_obj_freeze, MRB_ARGS_NONE()); mrb_define_method(mrb, krn, "frozen?", mrb_obj_frozen, MRB_ARGS_NONE()); mrb_define_method(mrb, krn, "hash", mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */ @@ -651,7 +560,6 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.24 */ mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.25 */ mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.26 */ - mrb_define_method(mrb, krn, "method_missing", mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */ mrb_define_method(mrb, krn, "nil?", mrb_false, MRB_ARGS_NONE()); /* 15.3.1.3.32 */ mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.33 */ mrb_define_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_ANY()); /* 15.3.1.3.40 */ diff --git a/mruby/src/load.c b/mruby/src/load.c index bb22a613..52cb154b 100644 --- a/mruby/src/load.c +++ b/mruby/src/load.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #if SIZE_MAX < UINT32_MAX @@ -162,17 +163,16 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ #endif case IREP_TT_BIGINT: - pool_data_len = bin_to_uint8(src); /* pool data length */ - src += sizeof(uint8_t); + pool_data_len = bin_to_uint8(src) + 2; /* pool data length */ if (src + pool_data_len > end) return FALSE; - { + else { char *p; pool[i].tt = IREP_TT_BIGINT; - p = (char*)mrb_malloc(mrb, pool_data_len+2); - memcpy(p, src, pool_data_len+2); + p = (char*)mrb_malloc(mrb, pool_data_len); + memcpy(p, src, pool_data_len); pool[i].u.str = (const char*)p; } - src += pool_data_len + 2; + src += pool_data_len; break; case IREP_TT_FLOAT: @@ -326,7 +326,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ if (bin > end) return MRB_DUMP_GENERAL_FAILURE; debug->files = (mrb_irep_debug_info_file**)mrb_calloc(mrb, irep->debug_info->flen, sizeof(mrb_irep_debug_info*)); - for (f_idx = 0; f_idx < debug->flen; ++f_idx) { + for (f_idx = 0; f_idx < debug->flen; f_idx++) { mrb_irep_debug_info_file *file; uint16_t filename_idx; @@ -352,11 +352,12 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ size_t l = sizeof(uint16_t) * (size_t)file->line_entry_count; if (bin + l > end) return MRB_DUMP_GENERAL_FAILURE; - file->lines.ary = (uint16_t *)mrb_malloc(mrb, l); - for (l = 0; l < file->line_entry_count; ++l) { - file->lines.ary[l] = bin_to_uint16(bin); + uint16_t *ary = (uint16_t *)mrb_malloc(mrb, l); + for (l = 0; l < file->line_entry_count; l++) { + ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); } + file->lines.ary = ary; } break; case mrb_debug_line_flat_map: { @@ -364,21 +365,23 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ size_t n = sizeof(mrb_irep_debug_info_line); if (bin + c*n > end) return MRB_DUMP_GENERAL_FAILURE; - file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_calloc(mrb, c, n); - for (size_t l = 0; l < file->line_entry_count; ++l) { - file->lines.flat_map[l].start_pos = bin_to_uint32(bin); + mrb_irep_debug_info_line *flat_map = (mrb_irep_debug_info_line*)mrb_calloc(mrb, c, n); + for (size_t l = 0; l < file->line_entry_count; l++) { + flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); - file->lines.flat_map[l].line = bin_to_uint16(bin); + flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t); } + file->lines.flat_map = flat_map; } break; case mrb_debug_line_packed_map: { size_t l = (size_t)file->line_entry_count; if (bin + l > end) return MRB_DUMP_GENERAL_FAILURE; - file->lines.packed_map = (uint8_t*)mrb_calloc(mrb, 1, l); - memcpy(file->lines.packed_map, bin, file->line_entry_count); + uint8_t *packed_map = (uint8_t*)mrb_malloc(mrb, l); + memcpy(packed_map, bin, file->line_entry_count); + file->lines.packed_map = packed_map; bin += file->line_entry_count; } break; @@ -432,7 +435,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep * if (bin > end) return MRB_DUMP_GENERAL_FAILURE; filenames_obj = mrb_str_new(mrb, NULL, sizeof(mrb_sym) * (size_t)filenames_len); filenames = (mrb_sym*)RSTRING_PTR(filenames_obj); - for (i = 0; i < filenames_len; ++i) { + for (i = 0; i < filenames_len; i++) { uint16_t f_len = bin_to_uint16(bin); bin += sizeof(uint16_t); if (bin + f_len > end) { @@ -474,7 +477,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec if (irep->nlocals == 0) return MRB_DUMP_GENERAL_FAILURE; irep->lv = lv = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (irep->nlocals - 1)); - for (i = 0; i + 1 < irep->nlocals; ++i) { + for (i = 0; i + 1 < irep->nlocals; i++) { uint16_t const sym_idx = bin_to_uint16(bin); bin += sizeof(uint16_t); if (sym_idx == RITE_LV_NULL_MARK) { @@ -488,7 +491,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec } } - for (i = 0; i < irep->rlen; ++i) { + for (i = 0; i < irep->rlen; i++) { size_t len; int ret; @@ -529,7 +532,7 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep *ire if (bin > end) return MRB_DUMP_READ_FAULT; syms_obj = mrb_str_new(mrb, NULL, sizeof(mrb_sym) * (size_t)syms_len); syms = (mrb_sym*)RSTRING_PTR(syms_obj); - for (i = 0; i < syms_len; ++i) { + for (i = 0; i < syms_len; i++) { uint16_t const str_len = bin_to_uint16(bin); bin += sizeof(uint16_t); if (bin > end) return MRB_DUMP_READ_FAULT; @@ -666,8 +669,6 @@ irep_error(mrb_state *mrb) mrb_exc_set(mrb, mrb_exc_new_lit(mrb, E_SCRIPT_ERROR, "irep load error")); } -void mrb_codedump_all(mrb_state*, struct RProc*); - static mrb_value load_irep(mrb_state *mrb, struct RProc *proc, mrbc_context *c) { diff --git a/mruby/src/numeric.c b/mruby/src/numeric.c index fb3c0e48..a671eeba 100644 --- a/mruby/src/numeric.c +++ b/mruby/src/numeric.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -20,37 +21,42 @@ #endif #endif -static void -int_overflow(mrb_state *mrb, const char *reason) +mrb_noreturn void +mrb_int_overflow(mrb_state *mrb, const char *reason) { mrb_raisef(mrb, E_RANGE_ERROR, "integer overflow in %s", reason); } -static void -int_zerodiv(mrb_state *mrb) +mrb_noreturn void +mrb_int_zerodiv(mrb_state *mrb) { mrb_raise(mrb, E_ZERODIV_ERROR, "divided by 0"); } -/* - * call-seq: - * - * num ** other -> num - * - * Raises num the other power. - * - * 2.0**3 #=> 8.0 - */ -static mrb_value -int_pow(mrb_state *mrb, mrb_value x) +static mrb_noreturn void +mrb_int_noconv(mrb_state *mrb, mrb_value y) +{ + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into Integer", y); +} + +mrb_value +mrb_int_pow(mrb_state *mrb, mrb_value x, mrb_value y) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + return mrb_float_value(mrb, pow(mrb_bint_as_float(mrb, x), mrb_float(y))); + } +#endif + return mrb_bint_pow(mrb, x, y); + } +#endif mrb_int base = mrb_integer(x); mrb_int result = 1; mrb_int exp; #ifndef MRB_NO_FLOAT - mrb_value y = mrb_get_arg1(mrb); - if (mrb_float_p(y)) { return mrb_float_value(mrb, pow((double)base, mrb_float(y))); } @@ -66,50 +72,78 @@ int_pow(mrb_state *mrb, mrb_value x) #ifndef MRB_NO_FLOAT return mrb_float_value(mrb, pow((double)base, (double)exp)); #else - int_overflow(mrb, "negative power"); + mrb_int_overflow(mrb, "negative power"); #endif } for (;;) { if (exp & 1) { if (mrb_int_mul_overflow(result, base, &result)) { - int_overflow(mrb, "power"); +#ifdef MRB_USE_BIGINT + return mrb_bint_pow(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), y); +#else + mrb_int_overflow(mrb, "power"); +#endif } } exp >>= 1; if (exp == 0) break; if (mrb_int_mul_overflow(base, base, &base)) { - int_overflow(mrb, "power"); +#ifdef MRB_USE_BIGINT + return mrb_bint_pow(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), y); +#else + mrb_int_overflow(mrb, "power"); +#endif } } return mrb_int_value(mrb, result); } +/* + * call-seq: + * + * num ** other -> num + * + * Raises num the other power. + * + * 2.0**3 #=> 8.0 + */ +static mrb_value +int_pow(mrb_state *mrb, mrb_value x) +{ + return mrb_int_pow(mrb, x, mrb_get_arg1(mrb)); +} + mrb_int -mrb_div_int(mrb_state *mrb, mrb_int x, mrb_int y) +mrb_div_int(mrb_int x, mrb_int y) +{ + mrb_int div = x / y; + + if ((x ^ y) < 0 && x != div * y) { + div -= 1; + } + return div; +} + +mrb_value +mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y) { if (y == 0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); } else if(x == MRB_INT_MIN && y == -1) { - int_overflow(mrb, "division"); - } - else { - mrb_int div = x / y; - - if ((x ^ y) < 0 && x != div * y) { - div -= 1; - } - return div; +#ifdef MRB_USE_BIGINT + return mrb_bint_mul_ii(mrb, x, y); +#else + mrb_int_overflow(mrb, "division"); +#endif } - /* not reached */ - return 0; + return mrb_int_value(mrb, mrb_div_int(x, y)); } -/* 15.2.8.3.4 */ -/* 15.2.9.3.4 */ +/* 15.2.8.3.6 */ /* * call-seq: - * int / other -> num + * int / num -> num * * Performs division: the class of the resulting object depends on * the class of num and on the magnitude of the @@ -119,17 +153,37 @@ static mrb_value int_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - mrb_int a = mrb_integer(x); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_div(mrb, x, y); + } +#endif + mrb_int a = mrb_integer(x); if (mrb_integer_p(y)) { - mrb_int div = mrb_div_int(mrb, a, mrb_integer(y)); - return mrb_int_value(mrb, div); + return mrb_div_int_value(mrb, a, mrb_integer(y)); } -#ifdef MRB_NO_FLOAT - mrb_raise(mrb, E_TYPE_ERROR, "non integer division"); -#else - return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); + switch (mrb_type(y)) { +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bint_div(mrb, mrb_bint_new_int(mrb, a), y); +#endif +#ifdef MRB_USE_RATIONAL + case MRB_TT_RATIONAL: + return mrb_rational_div(mrb, mrb_rational_new(mrb, a, 1), y); +#endif +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: + x = mrb_complex_new(mrb, (mrb_float)a, 0); + return mrb_complex_div(mrb, x, y); #endif +#ifndef MRB_NO_FLOAT + case MRB_TT_FLOAT: + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); +#endif + default: + mrb_int_noconv(mrb, y); + } } /* 15.2.9.3.19(x) */ @@ -149,28 +203,55 @@ int_div(mrb_state *mrb, mrb_value x) static mrb_value int_idiv(mrb_state *mrb, mrb_value x) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_div(mrb, x, mrb_get_arg1(mrb)); + } +#endif mrb_int y; mrb_get_args(mrb, "i", &y); - if (y == 0) { - int_zerodiv(mrb); - } - return mrb_int_value(mrb, mrb_integer(x) / y); + return mrb_div_int_value(mrb, mrb_integer(x), y); } static mrb_value -int_quo(mrb_state *mrb, mrb_value xv) +int_quo(mrb_state *mrb, mrb_value x) { +#ifndef MRB_USE_RATIONAL #ifdef MRB_NO_FLOAT - return int_idiv(mrb, xv); + return int_idiv(mrb, x); #else mrb_float y; mrb_get_args(mrb, "f", &y); if (y == 0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); + } +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_float_value(mrb, mrb_bint_as_float(mrb, x) / y); + } +#endif + return mrb_float_value(mrb, mrb_integer(x) / y); +#endif +#else + mrb_int a = mrb_integer(x); + mrb_value y = mrb_get_arg1(mrb); + if (mrb_integer_p(y) && mrb_class_defined_id(mrb, MRB_SYM(Rational))) { + return mrb_rational_new(mrb, a, mrb_integer(y)); + } + switch (mrb_type(y)) { + case MRB_TT_RATIONAL: + x = mrb_rational_new(mrb, a, 1); + return mrb_rational_div(mrb, x, y); + default: +#ifndef MRB_NO_FLOAT + return mrb_float_value(mrb, mrb_div_float((mrb_float)a, mrb_as_float(mrb, y))); +#else + mrb_int_noconv(mrb, y); + break; +#endif } - return mrb_float_value(mrb, mrb_integer(xv) / y); #endif } @@ -184,7 +265,7 @@ coerce_step_counter(mrb_state *mrb, mrb_value self) #ifndef MRB_NO_FLOAT mrb->c->ci->mid = 0; if (mrb_float_p(num) || mrb_float_p(step)) { - return mrb_to_float(mrb, self); + return mrb_ensure_float_type(mrb, self); } #endif @@ -212,11 +293,10 @@ flo_pow(mrb_state *mrb, mrb_value x) static mrb_value flo_idiv(mrb_state *mrb, mrb_value xv) { - mrb_int y, div; + mrb_int y; mrb_get_args(mrb, "i", &y); - div = mrb_div_int(mrb, (mrb_int)mrb_float(xv), y); - return mrb_int_value(mrb, (mrb_int)div); + return mrb_div_int_value(mrb, (mrb_int)mrb_float(xv), y); } mrb_float @@ -233,17 +313,30 @@ mrb_div_float(mrb_float x, mrb_float y) } } +/* 15.2.9.3.6 */ +/* + * call-seq: + * float / num -> float + * + * Returns a new Float which is the result of dividing float by num. + */ static mrb_value flo_div(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); mrb_float a = mrb_float(x); - if (mrb_float_p(y)) { + switch(mrb_type(y)) { +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: + return mrb_complex_div(mrb, mrb_complex_new(mrb, a, 0), y); +#endif + case MRB_TT_FLOAT: a = mrb_div_float(a, mrb_float(y)); - } - else { + return mrb_float_value(mrb, a); + default: a = mrb_div_float(a, mrb_as_float(mrb, y)); + return mrb_float_value(mrb, a); } return mrb_float_value(mrb, a); } @@ -309,7 +402,7 @@ flo_to_s(mrb_state *mrb, mrb_value flt) return str; } -/* 15.2.9.3.1 */ +/* 15.2.9.3.3 */ /* * call-seq: * float + other -> float @@ -328,14 +421,14 @@ flo_add(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, a + mrb_float(y)); #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); + return mrb_complex_add(mrb, y, x); #endif default: return mrb_float_value(mrb, a + mrb_as_float(mrb, y)); } } -/* 15.2.9.3.2 */ +/* 15.2.9.3.4 */ /* * call-seq: * float - other -> float @@ -355,15 +448,14 @@ flo_sub(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, a - mrb_float(y)); #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - x = mrb_funcall_id(mrb, y, MRB_OPSYM(sub), 1, x); - return mrb_funcall_id(mrb, x, MRB_OPSYM(minus), 0); + return mrb_complex_sub(mrb, mrb_complex_new(mrb, a, 0), y); #endif default: return mrb_float_value(mrb, a - mrb_as_float(mrb, y)); } } -/* 15.2.9.3.3 */ +/* 15.2.9.3.5 */ /* * call-seq: * float * other -> float @@ -383,7 +475,7 @@ flo_mul(mrb_state *mrb, mrb_value x) return mrb_float_value(mrb, a * mrb_float(y)); #if defined(MRB_USE_COMPLEX) case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); + return mrb_complex_mul(mrb, y, x); #endif default: return mrb_float_value(mrb, a * mrb_as_float(mrb, y)); @@ -401,7 +493,7 @@ flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp) goto exit; } if (y == 0.0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); } if (isinf(y) && !isinf(x)) { mod = x; @@ -427,7 +519,7 @@ flodivmod(mrb_state *mrb, double x, double y, mrb_float *divp, mrb_float *modp) if (divp) *divp = div; } -/* 15.2.9.3.5 */ +/* 15.2.9.3.5 */ /* * call-seq: * flt % other -> float @@ -463,25 +555,30 @@ flo_mod(mrb_state *mrb, mrb_value x) * (1.0).eql?(1.0) #=> true */ static mrb_value -int_eql(mrb_state *mrb, mrb_value x) +num_eql(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - if (!mrb_integer_p(y)) return mrb_false_value(); - return mrb_bool_value(mrb_integer(x) == mrb_integer(y)); -} - +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bool_value(mrb_bint_cmp(mrb, x, y) == 0); + } +#endif #ifndef MRB_NO_FLOAT -static mrb_value -flo_eql(mrb_state *mrb, mrb_value x) -{ - mrb_value y = mrb_get_arg1(mrb); - - if (!mrb_float_p(y)) return mrb_false_value(); - return mrb_bool_value(mrb_float(x) == mrb_float(y)); + if (mrb_float_p(x)) { + if (!mrb_float_p(y)) return mrb_false_value(); + return mrb_bool_value(mrb_float(x) == mrb_float(y)); + } +#endif + if (mrb_integer_p(x)) { + if (!mrb_integer_p(y)) return mrb_false_value(); + return mrb_bool_value(mrb_integer(x) == mrb_integer(y)); + } + return mrb_bool_value(mrb_equal(mrb, x, y)); } -/* 15.2.9.3.7 */ +#ifndef MRB_NO_FLOAT +/* 15.2.9.3.7 */ /* * call-seq: * flt == obj -> true or false @@ -542,7 +639,7 @@ static mrb_value int64_value(mrb_state *mrb, int64_t v) { if (!TYPED_FIXABLE(v,int64_t)) { - int_overflow(mrb, "bit operation"); + mrb_int_overflow(mrb, "bit operation"); } return mrb_fixnum_value((mrb_int)v); } @@ -688,7 +785,7 @@ flo_infinite_p(mrb_state *mrb, mrb_value num) return mrb_nil_value(); } -/* 15.2.9.3.9 */ +/* 15.2.9.3.9 */ /* * call-seq: * flt.finite? -> true or false @@ -705,6 +802,20 @@ flo_finite_p(mrb_state *mrb, mrb_value num) return mrb_bool_value(isfinite(mrb_float(num))); } +/* + * Document-class: FloatDomainError + * + * Raised when attempting to convert special float values + * (in particular infinite or NaN) + * to numerical classes which don't support them. + * + * Float::INFINITY.to_i + * + * raises the exception: + * + * FloatDomainError: Infinity + */ +/* ------------------------------------------------------------------------*/ void mrb_check_num_exact(mrb_state *mrb, mrb_float num) { @@ -717,7 +828,20 @@ 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)) +flo_rounding_int(mrb_state *mrb, mrb_float f) +{ + if (!FIXABLE_FLOAT(f)) { +#ifdef MRB_USE_BIGINT + return mrb_bint_new_float(mrb, f); +#else + mrb_int_overflow(mrb, "rounding"); +#endif + } + return mrb_int_value(mrb, (mrb_int)f); +} + +static mrb_value +flo_rounding(mrb_state *mrb, mrb_value num, double (*func)(double)) { mrb_float f = mrb_float(num); mrb_int ndigits = 0; @@ -733,19 +857,20 @@ flo_ceil_floor(mrb_state *mrb, mrb_value num, double (*func)(double)) } if (ndigits > 0) { if (ndigits > fprec) return num; - mrb_float d = pow(10, ndigits); + mrb_float d = pow(10, (double)ndigits); f = func(f * d) / d; + mrb_check_num_exact(mrb, f); return mrb_float_value(mrb, f); } if (ndigits < 0) { - mrb_float d = pow(10, -ndigits); + mrb_float d = pow(10, -(double)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); + return flo_rounding_int(mrb, f); } /* 15.2.9.3.10 */ @@ -759,7 +884,7 @@ flo_ceil_floor(mrb_state *mrb, mrb_value num, double (*func)(double)) * When the precision is negative, the returned value is an integer * with at least ndigits.abs trailing zeros. * - * Returns a floating point number when +ndigits+ is positive, + * Returns a floating-point number when +ndigits+ is positive, * otherwise returns an integer. * * 1.2.floor #=> 1 @@ -782,7 +907,7 @@ flo_ceil_floor(mrb_state *mrb, mrb_value num, double (*func)(double)) * 34567.89.floor(2) #=> 34567.89 * 34567.89.floor(3) #=> 34567.89 * - * Note that the limited precision of floating point arithmetic + * Note that the limited precision of floating-point arithmetic * might lead to surprising results: * * (0.3 / 0.1).floor #=> 2 (!) @@ -790,10 +915,10 @@ flo_ceil_floor(mrb_state *mrb, mrb_value num, double (*func)(double)) static mrb_value flo_floor(mrb_state *mrb, mrb_value num) { - return flo_ceil_floor(mrb, num, floor); + return flo_rounding(mrb, num, floor); } -/* 15.2.9.3.8 */ +/* 15.2.9.3.8 */ /* * call-seq: * float.ceil([ndigits]) -> integer or float @@ -804,7 +929,7 @@ flo_floor(mrb_state *mrb, mrb_value num) * When the precision is negative, the returned value is an integer * with at least ndigits.abs trailing zeros. * - * Returns a floating point number when +ndigits+ is positive, + * Returns a floating-point number when +ndigits+ is positive, * otherwise returns an integer. * * 1.2.ceil #=> 2 @@ -827,7 +952,7 @@ flo_floor(mrb_state *mrb, mrb_value num) * 34567.89.ceil(2) #=> 34567.89 * 34567.89.ceil(3) #=> 34567.89 * - * Note that the limited precision of floating point arithmetic + * Note that the limited precision of floating-point arithmetic * might lead to surprising results: * * (2.1 / 0.7).ceil #=> 4 (!) @@ -836,7 +961,7 @@ flo_floor(mrb_state *mrb, mrb_value num) static mrb_value flo_ceil(mrb_state *mrb, mrb_value num) { - return flo_ceil_floor(mrb, num, ceil); + return flo_rounding(mrb, num, ceil); } /* 15.2.9.3.12 */ @@ -930,10 +1055,17 @@ flo_to_i(mrb_state *mrb, mrb_value num) { mrb_float f = mrb_float(num); + mrb_check_num_exact(mrb, f); + if (!FIXABLE_FLOAT(f)) { +#ifdef MRB_USE_BIGINT + return mrb_bint_new_float(mrb, f); +#else + mrb_int_overflow(mrb, "to_f"); +#endif + } 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); } @@ -976,7 +1108,7 @@ flo_abs(mrb_state *mrb, mrb_value num) * */ - +/* 15.2.9.3.24 */ /* * call-seq: * int.to_i -> integer @@ -991,8 +1123,8 @@ int_to_i(mrb_state *mrb, mrb_value num) return num; } -static mrb_value -fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_value +mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; @@ -1001,52 +1133,49 @@ fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) mrb_int b, c; if (a == 0) return x; + if (a == 1) return y; b = mrb_integer(y); + if (b == 0) return y; + if (b == 1) return x; if (mrb_int_mul_overflow(a, b, &c)) { - int_overflow(mrb, "multiplication"); +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_mul(mrb, x, y); +#else + mrb_int_overflow(mrb, "multiplication"); +#endif } return mrb_int_value(mrb, c); } switch (mrb_type(y)) { -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + if (a == 0) return x; + if (a == 1) return y; + return mrb_bint_mul(mrb, y, x); +#endif +#ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: - case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); + if (a == 0) return x; + if (a == 1) return y; + return mrb_rational_mul(mrb, y, x); #endif - default: -#ifdef MRB_NO_FLOAT - mrb_raise(mrb, E_TYPE_ERROR, "non integer multiplication"); -#else - return mrb_float_value(mrb, (mrb_float)a * mrb_as_float(mrb, y)); +#ifdef MRB_USE_COMPLEX + case MRB_TT_COMPLEX: + if (a == 0) return x; + if (a == 1) return y; + return mrb_complex_mul(mrb, y, x); #endif - } -} - -MRB_API mrb_value -mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) -{ - if (mrb_integer_p(x)) { - return fixnum_mul(mrb, x, y); - } #ifndef MRB_NO_FLOAT - if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) * mrb_as_float(mrb, y)); - } + case MRB_TT_FLOAT: + return mrb_float_value(mrb, (mrb_float)a * mrb_as_float(mrb, y)); #endif -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) - switch (mrb_type(x)) { - case MRB_TT_RATIONAL: - case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, x, MRB_OPSYM(mul), 1, y); default: - break; + mrb_int_noconv(mrb, y); } -#endif - mrb_raise(mrb, E_TYPE_ERROR, "no number multiply"); - return mrb_nil_value(); /* not reached */ } -/* 15.2.8.3.3 */ +/* 15.2.8.3.5 */ /* * call-seq: * int * numeric -> numeric_result @@ -1061,17 +1190,22 @@ int_mul(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); - return fixnum_mul(mrb, x, y); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_mul(mrb, x, y); + } +#endif + return mrb_int_mul(mrb, x, y); } static void intdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) { if (y == 0) { - int_zerodiv(mrb); + mrb_int_zerodiv(mrb); } else if(x == MRB_INT_MIN && y == -1) { - int_overflow(mrb, "division"); + mrb_int_overflow(mrb, "division"); } else { mrb_int div = x / y; @@ -1086,10 +1220,10 @@ intdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) } } -/* 15.2.8.3.5 */ +/* 15.2.8.3.7 */ /* * call-seq: - * int % other -> real + * int % num -> num * * Returns int modulo other. * See numeric.divmod for more information. @@ -1101,10 +1235,16 @@ int_mod(mrb_state *mrb, mrb_value x) mrb_value y = mrb_get_arg1(mrb); mrb_int a, b; +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_mod(mrb, x, y); + } +#endif a = mrb_integer(x); + if (a == 0) return x; if (mrb_integer_p(y)) { b = mrb_integer(y); - if (b == 0) int_zerodiv(mrb); + if (b == 0) mrb_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) { @@ -1122,6 +1262,10 @@ int_mod(mrb_state *mrb, mrb_value x) #endif } +#ifndef MRB_NO_FLOAT +static mrb_value flo_divmod(mrb_state *mrb, mrb_value x); +#endif + /* * call-seq: * int.divmod(numeric) -> array @@ -1133,6 +1277,17 @@ int_divmod(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { +#ifndef MRB_NO_FLOAT + if (mrb_float_p(y)) { + mrb_float f = mrb_bint_as_float(mrb, x); + return flo_divmod(mrb, mrb_float_value(mrb, f)); + } +#endif + return mrb_bint_divmod(mrb, x, y); + } +#endif if (mrb_integer_p(y)) { mrb_int div, mod; @@ -1142,15 +1297,7 @@ int_divmod(mrb_state *mrb, mrb_value x) #ifdef MRB_NO_FLOAT mrb_raise(mrb, E_TYPE_ERROR, "non integer divmod"); #else - else { - mrb_float div, mod; - mrb_value a, b; - - 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); - } + return flo_divmod(mrb, x); #endif } @@ -1172,7 +1319,7 @@ flo_divmod(mrb_state *mrb, mrb_value x) } #endif -/* 15.2.8.3.7 */ +/* 15.2.8.3.2 */ /* * call-seq: * int == other -> true or false @@ -1196,6 +1343,10 @@ int_equal(mrb_state *mrb, mrb_value x) case MRB_TT_FLOAT: return mrb_bool_value((mrb_float)mrb_integer(x) == mrb_float(y)); #endif +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bool_value(mrb_bint_cmp(mrb, y, x) == 0); +#endif #ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: return mrb_bool_value(mrb_equal(mrb, y, x)); @@ -1209,7 +1360,7 @@ int_equal(mrb_state *mrb, mrb_value x) } } -/* 15.2.8.3.8 */ +/* 15.2.8.3.8 */ /* * call-seq: * ~int -> integer @@ -1225,6 +1376,11 @@ int_rev(mrb_state *mrb, mrb_value num) { mrb_int val = mrb_integer(num); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(num)) { + mrb_bint_rev(mrb, num); + } +#endif return mrb_int_value(mrb, ~val); } @@ -1242,7 +1398,7 @@ static mrb_value flo_xor(mrb_state *mrb, mrb_value x); } while(0) #endif -/* 15.2.8.3.9 */ +/* 15.2.8.3.9 */ /* * call-seq: * int & integer -> integer_result @@ -1255,6 +1411,14 @@ int_and(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_and(mrb, x, y); + } + if (mrb_bigint_p(y)) { + return mrb_bint_and(mrb, mrb_as_bint(mrb, x), y); + } +#endif bit_op(x, y, and, &); } @@ -1271,6 +1435,14 @@ int_or(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_or(mrb, x, y); + } + if (mrb_bigint_p(y)) { + return mrb_bint_or(mrb, mrb_as_bint(mrb, x), y); + } +#endif bit_op(x, y, or, |); } @@ -1287,6 +1459,14 @@ int_xor(mrb_state *mrb, mrb_value x) { mrb_value y = mrb_get_arg1(mrb); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_xor(mrb, x, y); + } + if (mrb_bigint_p(y)) { + return mrb_bint_xor(mrb, mrb_as_bint(mrb, x), y); + } +#endif bit_op(x, y, or, ^); } @@ -1345,10 +1525,20 @@ int_lshift(mrb_state *mrb, mrb_value x) if (width == 0) { return x; } + if (width == MRB_INT_MIN) mrb_int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_lshift(mrb, x, width); + } +#endif val = mrb_integer(x); if (val == 0) return x; if (!mrb_num_shift(mrb, val, width, &val)) { - int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + return mrb_bint_lshift(mrb, mrb_bint_new_int(mrb, val), width); +#else + mrb_int_overflow(mrb, "bit shift"); +#endif } return mrb_int_value(mrb, val); } @@ -1370,70 +1560,223 @@ int_rshift(mrb_state *mrb, mrb_value x) if (width == 0) { return x; } + if (width == MRB_INT_MIN) mrb_int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_rshift(mrb, x, width); + } +#endif val = mrb_integer(x); if (val == 0) return x; - if (width == MRB_INT_MIN) int_overflow(mrb, "bit shift"); if (!mrb_num_shift(mrb, val, -width, &val)) { - int_overflow(mrb, "bit shift"); +#ifdef MRB_USE_BIGINT + return mrb_bint_rshift(mrb, mrb_bint_new_int(mrb, val), width); +#else + mrb_int_overflow(mrb, "bit shift"); +#endif } return mrb_int_value(mrb, val); } -/* 15.2.8.3.23 */ +static mrb_value +prepare_int_rounding(mrb_state *mrb, mrb_value x) +{ + mrb_int nd = 0; + size_t bytes; + + mrb_get_args(mrb, "|i", &nd); + if (nd >= 0) { + return mrb_nil_value(); + } +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + bytes = mrb_bint_memsize(x); + } + else +#endif + bytes = sizeof(mrb_int); + if (-0.415241 * nd - 0.125 > bytes) { + return mrb_undef_value(); + } + return mrb_int_pow(mrb, mrb_fixnum_value(10), mrb_fixnum_value(-nd)); +} + +/* 15.2.8.3.14 Integer#ceil */ /* * call-seq: - * int.to_f -> float + * int.ceil -> int + * int.ceil(ndigits) -> int * - * Converts int to a Float. + * Returns self. * + * When the precision (ndigits) is negative, the returned value is an integer + * with at least ndigits.abs trailing zeros. */ +static mrb_value +int_ceil(mrb_state *mrb, mrb_value x) +{ + mrb_value f = prepare_int_rounding(mrb, x); + if (mrb_undef_p(f)) return mrb_fixnum_value(0); + if (mrb_nil_p(f)) return x; +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f))); + } +#endif + mrb_int a = mrb_integer(x); + mrb_int b = mrb_integer(f); + int neg = a < 0; + if (neg) a = -a; + else a += b - 1; + a = a / b * b; + if (neg) a = -a; + return mrb_int_value(mrb, a); +} -#ifndef MRB_NO_FLOAT +/* 15.2.8.3.17 Integer#floor */ +/* + * call-seq: + * int.floor -> int + * int.floor(ndigits) -> int + * + * Returns self. + * + * When the precision (ndigits) is negative, the returned value is an integer + * with at least ndigits.abs trailing zeros. + */ static mrb_value -int_to_f(mrb_state *mrb, mrb_value num) +int_floor(mrb_state *mrb, mrb_value x) { - return mrb_float_value(mrb, (mrb_float)mrb_integer(num)); + mrb_value f = prepare_int_rounding(mrb, x); + if (mrb_undef_p(f)) return mrb_fixnum_value(0); + if (mrb_nil_p(f)) return x; +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f)); + } +#endif + mrb_int a = mrb_integer(x); + mrb_int b = mrb_integer(f); + int neg = a < 0; + if (neg) a = -a + b - 1; + a = a / b * b; + if (neg) a = -a; + return mrb_int_value(mrb, a); } +/* 15.2.8.3.20 Integer#round */ /* - * Document-class: FloatDomainError + * call-seq: + * int.round -> int + * int.round(ndigits) -> int * - * Raised when attempting to convert special float values - * (in particular infinite or NaN) - * to numerical classes which don't support them. + * Returns self. * - * Float::INFINITY.to_i + * When the precision (ndigits) is negative, the returned value is an integer + * with at least ndigits.abs trailing zeros. + */ +static mrb_value +int_round(mrb_state *mrb, mrb_value x) +{ + mrb_value f = prepare_int_rounding(mrb, x); + if (mrb_undef_p(f)) return mrb_fixnum_value(0); + if (mrb_nil_p(f)) return x; +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + mrb_value r = mrb_bint_mod(mrb, x, f); + mrb_value n = mrb_bint_sub(mrb, x, r); + mrb_value h = mrb_bigint_p(f) ? mrb_bint_rshift(mrb, f, 1) : mrb_int_value(mrb, mrb_integer(f)>>1); + mrb_int cmp = mrb_bigint_p(r) ? mrb_bint_cmp(mrb, r, h) : (mrb_integer(r) - mrb_integer(h)); + if ((cmp > 0) || (cmp == 0 && mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) > 0)) { + n = mrb_as_bint(mrb, n); + n = mrb_bint_add(mrb, n, f); + } + return n; + } +#endif + mrb_int a = mrb_integer(x); + mrb_int b = mrb_integer(f); + int neg = a < 0; + if (neg) a = -a; + a = (a + b / 2) / b * b; + if (neg) a = -a; + return mrb_int_value(mrb, a); +} + +/* 15.2.8.3.26 Integer#truncate */ +/* + * call-seq: + * int.truncate -> int + * int.truncate(ndigits) -> int * - * raises the exception: + * Returns self. * - * FloatDomainError: Infinity + * When the precision (ndigits) is negative, the returned value is an integer + * with at least ndigits.abs trailing zeros. */ -/* ------------------------------------------------------------------------*/ +static mrb_value +int_truncate(mrb_state *mrb, mrb_value x) +{ + mrb_value f = prepare_int_rounding(mrb, x); + if (mrb_undef_p(f)) return mrb_fixnum_value(0); + if (mrb_nil_p(f)) return x; +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + mrb_value m = mrb_bint_mod(mrb, x, f); + if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) < 0) { + return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, m)); + } + else { + return mrb_bint_sub(mrb, x, m); + } + } +#endif + mrb_int a = mrb_integer(x); + mrb_int b = mrb_integer(f); + int neg = a < 0; + if (neg) a = -a; + a = a / b * b; + if (neg) a = -a; + return mrb_int_value(mrb, a); +} + +/* 15.2.8.3.23 */ +/* + * call-seq: + * int.to_f -> float + * + * Converts int to a Float. + * + */ + +#ifndef MRB_NO_FLOAT +static mrb_value +int_to_f(mrb_state *mrb, mrb_value num) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(num)) { + return mrb_float_value(mrb, mrb_bint_as_float(mrb, num)); + } +#endif + return mrb_float_value(mrb, (mrb_float)mrb_integer(num)); +} + MRB_API mrb_value 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"); } - else { - mrb_float d = mrb_float(x); - - mrb_check_num_exact(mrb, d); - if (FIXABLE_FLOAT(d)) { - z = (mrb_int)d; - } - else { - mrb_raisef(mrb, E_RANGE_ERROR, "number (%v) too big for integer", x); - } + mrb_float f = mrb_float(x); + if (isinf(f) || isnan(f)) { + mrb_raisef(mrb, E_RANGE_ERROR, "float %f out of range", f); } - return mrb_int_value(mrb, z); + return flo_to_i(mrb, x); } #endif -static mrb_value -int_plus(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_value +mrb_int_add(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; @@ -1443,16 +1786,29 @@ int_plus(mrb_state *mrb, mrb_value x, mrb_value y) if (a == 0) return y; b = mrb_integer(y); + if (b == 0) return x; if (mrb_int_add_overflow(a, b, &c)) { - int_overflow(mrb, "addition"); +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_add(mrb, x, y); +#else + mrb_int_overflow(mrb, "addition"); +#endif } return mrb_int_value(mrb, c); } switch (mrb_type(y)) { -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bint_add(mrb, y, x); +#endif +#ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: + return mrb_rational_add(mrb, y, x); +#endif +#ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); + return mrb_complex_add(mrb, y, x); #endif default: #ifdef MRB_NO_FLOAT @@ -1463,31 +1819,7 @@ int_plus(mrb_state *mrb, mrb_value x, mrb_value y) } } -MRB_API mrb_value -mrb_num_plus(mrb_state *mrb, mrb_value x, mrb_value y) -{ - if (mrb_integer_p(x)) { - return int_plus(mrb, x, y); - } -#ifndef MRB_NO_FLOAT - if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) + mrb_as_float(mrb, y)); - } -#endif -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) - switch (mrb_type(x)) { - case MRB_TT_RATIONAL: - case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, x, MRB_OPSYM(add), 1, y); - default: - break; - } -#endif - mrb_raise(mrb, E_TYPE_ERROR, "no number addition"); - return mrb_nil_value(); /* not reached */ -} - -/* 15.2.8.3.1 */ +/* 15.2.8.3.3 */ /* * call-seq: * int + numeric -> numeric_result @@ -1501,11 +1833,16 @@ int_add(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); - return int_plus(mrb, self, other); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_add(mrb, self, other); + } +#endif + return mrb_int_add(mrb, self, other); } -static mrb_value -int_minus(mrb_state *mrb, mrb_value x, mrb_value y) +mrb_value +mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; @@ -1515,16 +1852,27 @@ int_minus(mrb_state *mrb, mrb_value x, mrb_value y) b = mrb_integer(y); if (mrb_int_sub_overflow(a, b, &c)) { - int_overflow(mrb, "subtraction"); +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_sub(mrb, x, y); +#else + mrb_int_overflow(mrb, "subtraction"); +#endif } return mrb_int_value(mrb, c); } switch (mrb_type(y)) { -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_bint_sub(mrb, mrb_bint_new_int(mrb, a), y); +#endif +#ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: + return mrb_rational_sub(mrb, mrb_rational_new(mrb, a, 1), y); +#endif +#ifdef MRB_USE_COMPLEX case MRB_TT_COMPLEX: - x = mrb_funcall_id(mrb, y, MRB_OPSYM(sub), 1, x); - return mrb_funcall_id(mrb, x, MRB_OPSYM(minus), 0); + return mrb_complex_sub(mrb, mrb_complex_new(mrb, (mrb_float)a, 0), y); #endif default: #ifdef MRB_NO_FLOAT @@ -1535,35 +1883,10 @@ int_minus(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) -{ - if (mrb_integer_p(x)) { - return int_minus(mrb, x, y); - } -#ifndef MRB_NO_FLOAT - if (mrb_float_p(x)) { - return mrb_float_value(mrb, mrb_float(x) - mrb_as_float(mrb, y)); - } -#endif -#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) - switch (mrb_type(x)) { - case MRB_TT_RATIONAL: - case MRB_TT_COMPLEX: - return mrb_funcall_id(mrb, x, MRB_OPSYM(sub), 1, y); - default: - break; - } -#endif - mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction"); - return mrb_nil_value(); /* not reached */ -} - -/* 15.2.8.3.2 */ -/* 15.2.8.3.16 */ +/* 15.2.8.3.4 */ /* * call-seq: - * int - numeric -> numeric_result + * int - numeric -> numeric * * Performs subtraction: the class of the resulting object depends on * the class of numeric and on the magnitude of the @@ -1574,7 +1897,12 @@ int_sub(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); - return int_minus(mrb, self, other); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_sub(mrb, self, other); + } +#endif + return mrb_int_sub(mrb, self, other); } MRB_API char* @@ -1619,6 +1947,11 @@ mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base) if (base < 2 || 36 < base) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); } +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_to_s(mrb, x, base); + } +#endif 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); @@ -1655,6 +1988,12 @@ int_to_s(mrb_state *mrb, mrb_value self) static mrb_int cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) { +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(v1)) { + return mrb_bint_cmp(mrb, v1, v2); + } +#endif + #ifdef MRB_NO_FLOAT mrb_int x, y; #else @@ -1696,7 +2035,20 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) } } -/* 15.2.9.3.6 */ +static mrb_value +int_hash(mrb_state *mrb, mrb_value self) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(self)) { + return mrb_bint_hash(mrb, self); + } +#endif + mrb_int n = mrb_integer(self); + return mrb_int_value(mrb, mrb_byte_hash((uint8_t*)&n, sizeof(n))); +} + +/* 15.2.8.3.1 */ +/* 15.2.9.3.1 */ /* * call-seq: * self.f <=> other.f => -1, 0, +1, or nil @@ -1781,12 +2133,14 @@ mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2) switch (mrb_type(obj1)) { case MRB_TT_INTEGER: case MRB_TT_FLOAT: + case MRB_TT_BIGINT: return cmpnum(mrb, obj1, obj2); case MRB_TT_STRING: if (!mrb_string_p(obj2)) return -2; return mrb_str_cmp(mrb, obj1, obj2); default: + if (!mrb_respond_to(mrb, obj1, MRB_OPSYM(cmp))) return -2; v = mrb_funcall_id(mrb, obj1, MRB_OPSYM(cmp), 1, obj2); if (mrb_nil_p(v) || !mrb_integer_p(v)) return -2; @@ -1806,6 +2160,17 @@ num_infinite_p(mrb_state *mrb, mrb_value self) return mrb_false_value(); } +#ifndef MRB_NO_FLOAT +static mrb_value +flo_hash(mrb_state *mrb, mrb_value flo) +{ + mrb_float f = mrb_float(flo); + /* normalize -0.0 to 0.0 */ + if (f == 0) f = 0.0; + return mrb_int_value(mrb, (mrb_int)mrb_byte_hash((uint8_t*)&f, sizeof(f))); +} +#endif + /* ------------------------------------------------------------------------*/ void mrb_init_numeric(mrb_state *mrb) @@ -1819,6 +2184,7 @@ mrb_init_numeric(mrb_state *mrb) numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */ mrb_define_method(mrb, numeric, "finite?", num_finite_p, MRB_ARGS_NONE()); mrb_define_method(mrb, numeric, "infinite?",num_infinite_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, numeric, "eql?", num_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ /* Integer Class */ mrb->integer_class = integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */ @@ -1838,8 +2204,8 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, integer, "-", int_sub, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */ mrb_define_method(mrb, integer, "*", int_mul, MRB_ARGS_REQ(1)); /* 15.2.8.3.3 */ mrb_define_method(mrb, integer, "%", int_mod, MRB_ARGS_REQ(1)); /* 15.2.8.3.5 */ - mrb_define_method(mrb, integer, "/", int_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.6 */ - mrb_define_method(mrb, integer, "quo", int_quo, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ + mrb_define_method(mrb, integer, "/", int_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.6 */ + mrb_define_method(mrb, integer, "quo", int_quo, MRB_ARGS_REQ(1)); /* 15.2.7.4.5(x) */ mrb_define_method(mrb, integer, "div", int_idiv, MRB_ARGS_REQ(1)); mrb_define_method(mrb, integer, "==", int_equal, MRB_ARGS_REQ(1)); /* 15.2.8.3.7 */ mrb_define_method(mrb, integer, "~", int_rev, MRB_ARGS_NONE()); /* 15.2.8.3.8 */ @@ -1848,13 +2214,17 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, integer, "^", int_xor, MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */ mrb_define_method(mrb, integer, "<<", int_lshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */ mrb_define_method(mrb, integer, ">>", int_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */ - mrb_define_method(mrb, integer, "eql?", int_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ + mrb_define_method(mrb, integer, "ceil", int_ceil, MRB_ARGS_OPT(1)); /* 15.2.8.3.14 */ + mrb_define_method(mrb, integer, "floor", int_floor, MRB_ARGS_OPT(1)); /* 15.2.8.3.17 */ + mrb_define_method(mrb, integer, "round", int_round, MRB_ARGS_OPT(1)); /* 15.2.8.3.20 */ + mrb_define_method(mrb, integer, "truncate", int_truncate, MRB_ARGS_OPT(1)); /* 15.2.8.3.26 */ + mrb_define_method(mrb, integer, "hash", int_hash, MRB_ARGS_NONE()); /* 15.2.8.3.18 */ #ifndef MRB_NO_FLOAT mrb_define_method(mrb, integer, "to_f", int_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */ #endif mrb_define_method(mrb, integer, "to_s", int_to_s, MRB_ARGS_OPT(1)); /* 15.2.8.3.25 */ mrb_define_method(mrb, integer, "inspect", int_to_s, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, integer, "divmod", int_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ + mrb_define_method(mrb, integer, "divmod", int_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30(x) */ mrb_define_method(mrb, integer, "__coerce_step_counter", coerce_step_counter, MRB_ARGS_REQ(2)); /* Fixnum Class for compatibility */ @@ -1866,19 +2236,19 @@ mrb_init_numeric(mrb_state *mrb) MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); mrb_undef_class_method(mrb, fl, "new"); mrb_define_method(mrb, fl, "**", flo_pow, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "/", flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ - mrb_define_method(mrb, fl, "quo", flo_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */ + mrb_define_method(mrb, fl, "/", flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ + mrb_define_method(mrb, fl, "quo", flo_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5(x) */ mrb_define_method(mrb, fl, "div", flo_idiv, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "+", flo_add, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */ - mrb_define_method(mrb, fl, "-", flo_sub, MRB_ARGS_REQ(1)); /* 15.2.9.3.4 */ - mrb_define_method(mrb, fl, "*", flo_mul, MRB_ARGS_REQ(1)); /* 15.2.9.3.5 */ - mrb_define_method(mrb, fl, "%", flo_mod, MRB_ARGS_REQ(1)); /* 15.2.9.3.7 */ - mrb_define_method(mrb, fl, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */ + mrb_define_method(mrb, fl, "+", flo_add, MRB_ARGS_REQ(1)); /* 15.2.9.3.3 */ + mrb_define_method(mrb, fl, "-", flo_sub, MRB_ARGS_REQ(1)); /* 15.2.9.3.4 */ + mrb_define_method(mrb, fl, "*", flo_mul, MRB_ARGS_REQ(1)); /* 15.2.9.3.5 */ + mrb_define_method(mrb, fl, "%", flo_mod, MRB_ARGS_REQ(1)); /* 15.2.9.3.7 */ + mrb_define_method(mrb, fl, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */ mrb_define_method(mrb, fl, "<", num_lt, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "<=", num_le, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, ">", num_gt, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, ">=", num_ge, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "==", flo_eq, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */ + mrb_define_method(mrb, fl, "==", flo_eq, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */ mrb_define_method(mrb, fl, "~", flo_rev, MRB_ARGS_NONE()); mrb_define_method(mrb, fl, "&", flo_and, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1)); @@ -1894,12 +2264,12 @@ mrb_init_numeric(mrb_state *mrb) 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 */ + mrb_define_method(mrb, fl, "hash", flo_hash, MRB_ARGS_NONE()); #ifdef INFINITY mrb_define_const_id(mrb, fl, MRB_SYM(INFINITY), mrb_float_value(mrb, INFINITY)); diff --git a/mruby/src/numops.c b/mruby/src/numops.c new file mode 100644 index 00000000..ff8adc2d --- /dev/null +++ b/mruby/src/numops.c @@ -0,0 +1,112 @@ +/* +** numeric.c - Numeric, Integer, Float class +** +** See Copyright Notice in mruby.h +*/ + +#include +#include +#include +#include + +MRB_API mrb_value +mrb_num_add(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_add(mrb, x, y); + } +#endif + if (mrb_integer_p(x)) { + return mrb_int_add(mrb, x, y); + } +#ifndef MRB_NO_FLOAT + if (mrb_float_p(x)) { + return mrb_float_value(mrb, mrb_float(x) + mrb_as_float(mrb, y)); + } +#endif +#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) + switch (mrb_type(x)) { +#if defined(MRB_USE_RATIONAL) + case MRB_TT_RATIONAL: + return mrb_rational_add(mrb, x, y); +#endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_add(mrb, x, y); +#endif + default: + break; + } +#endif + mrb_raise(mrb, E_TYPE_ERROR, "no number addition"); + return mrb_nil_value(); /* not reached */ +} + +MRB_API mrb_value +mrb_num_sub(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_sub(mrb, x, y); + } +#endif + if (mrb_integer_p(x)) { + return mrb_int_sub(mrb, x, y); + } +#ifndef MRB_NO_FLOAT + if (mrb_float_p(x)) { + return mrb_float_value(mrb, mrb_float(x) - mrb_as_float(mrb, y)); + } +#endif +#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) + switch (mrb_type(x)) { +#if defined(MRB_USE_RATIONAL) + case MRB_TT_RATIONAL: + return mrb_rational_sub(mrb, x, y); +#endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_sub(mrb, x, y); +#endif + default: + break; + } +#endif + mrb_raise(mrb, E_TYPE_ERROR, "no number subtraction"); + return mrb_nil_value(); /* not reached */ +} + +MRB_API mrb_value +mrb_num_mul(mrb_state *mrb, mrb_value x, mrb_value y) +{ +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(x)) { + return mrb_bint_mul(mrb, x, y); + } +#endif + if (mrb_integer_p(x)) { + return mrb_int_mul(mrb, x, y); + } +#ifndef MRB_NO_FLOAT + if (mrb_float_p(x)) { + return mrb_float_value(mrb, mrb_float(x) * mrb_as_float(mrb, y)); + } +#endif +#if defined(MRB_USE_RATIONAL) || defined(MRB_USE_COMPLEX) + switch (mrb_type(x)) { +#if defined(MRB_USE_RATIONAL) + case MRB_TT_RATIONAL: + return mrb_rational_mul(mrb, x, y); +#endif +#if defined(MRB_USE_COMPLEX) + case MRB_TT_COMPLEX: + return mrb_complex_mul(mrb, x, y); +#endif + default: + break; + } +#endif + mrb_raise(mrb, E_TYPE_ERROR, "no number multiply"); + return mrb_nil_value(); /* not reached */ +} diff --git a/mruby/src/object.c b/mruby/src/object.c index a4229301..cc7ec644 100644 --- a/mruby/src/object.c +++ b/mruby/src/object.c @@ -9,6 +9,7 @@ #include #include #include +#include #include MRB_API mrb_bool @@ -57,13 +58,23 @@ mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2) if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; #ifndef MRB_NO_FLOAT /* value mixing with integer and float */ - if (mrb_integer_p(obj1)) { - if (mrb_float_p(obj2) && (mrb_float)mrb_integer(obj1) == mrb_float(obj2)) + if (mrb_integer_p(obj1) && mrb_float_p(obj2)) { + if ((mrb_float)mrb_integer(obj1) == mrb_float(obj2)) return TRUE; + return FALSE; } - else if (mrb_float_p(obj1)) { - if (mrb_integer_p(obj2) && mrb_float(obj1) == (mrb_float)mrb_integer(obj2)) + else if (mrb_float_p(obj1) && mrb_integer_p(obj2)) { + if (mrb_float(obj1) == (mrb_float)mrb_integer(obj2)) return TRUE; + return FALSE; + } +#endif +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(obj1) && + (mrb_integer_p(obj2) || mrb_bigint_p(obj2) || mrb_float_p(obj2))) { + if (mrb_bint_cmp(mrb, obj1, obj2) == 0) + return TRUE; + return FALSE; } #endif result = mrb_funcall_id(mrb, obj1, MRB_OPSYM(eq), 1, obj2); @@ -368,7 +379,7 @@ mrb_type_convert_check(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_s { mrb_value v; - if (mrb_type(val) == type && type != MRB_TT_DATA && type != MRB_TT_ISTRUCT) return val; + if (mrb_type(val) == type && type != MRB_TT_CDATA && type != MRB_TT_ISTRUCT) return val; v = convert_type(mrb, val, type_name(type), method, FALSE); if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value(); return v; @@ -496,7 +507,7 @@ mrb_value mrb_complex_to_i(mrb_state *mrb, mrb_value comp); #endif MRB_API mrb_value -mrb_ensure_int_type(mrb_state *mrb, mrb_value val) +mrb_ensure_integer_type(mrb_state *mrb, mrb_value val) { if (!mrb_integer_p(val)) { #ifndef MRB_NO_FLOAT @@ -505,6 +516,10 @@ mrb_ensure_int_type(mrb_state *mrb, mrb_value val) } else { switch (mrb_type(val)) { +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return val; +#endif #ifdef MRB_USE_RATIONAL case MRB_TT_RATIONAL: return mrb_rational_to_i(mrb, val); @@ -523,6 +538,18 @@ mrb_ensure_int_type(mrb_state *mrb, mrb_value val) return val; } +MRB_API mrb_value +mrb_ensure_int_type(mrb_state *mrb, mrb_value val) +{ + val = mrb_ensure_integer_type(mrb, val); +#ifdef MRB_USE_BIGINT + if (mrb_bigint_p(val)) { + return mrb_int_value(mrb, mrb_bint_as_int(mrb, val)); + } +#endif + return val; +} + #ifndef MRB_NO_FLOAT MRB_API mrb_value mrb_ensure_float_type(mrb_state *mrb, mrb_value val) @@ -547,6 +574,11 @@ mrb_ensure_float_type(mrb_state *mrb, mrb_value val) return mrb_complex_to_f(mrb, val); #endif +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + return mrb_float_value(mrb, mrb_bint_as_float(mrb, val)); +#endif + default: mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Float", val); /* not reached */ @@ -606,7 +638,11 @@ mrb_check_hash_type(mrb_state *mrb, mrb_value hash) MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj) { - return mrb_obj_as_string(mrb, mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0)); + mrb_value v = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0); + if (!mrb_string_p(v)) { + v = mrb_obj_as_string(mrb, obj); + } + return v; } MRB_API mrb_bool diff --git a/mruby/src/print.c b/mruby/src/print.c index 4af871b4..c6cb6464 100644 --- a/mruby/src/print.c +++ b/mruby/src/print.c @@ -49,12 +49,6 @@ mrb_p(mrb_state *mrb, mrb_value obj) } -MRB_API void -mrb_print_error(mrb_state *mrb) -{ - mrb_print_backtrace(mrb); -} - MRB_API void mrb_show_version(mrb_state *mrb) { @@ -78,11 +72,6 @@ mrb_p(mrb_state *mrb, mrb_value obj) { } -MRB_API void -mrb_print_error(mrb_state *mrb) -{ -} - MRB_API void mrb_show_version(mrb_state *mrb) { diff --git a/mruby/src/proc.c b/mruby/src/proc.c index abace39d..c27e6ea7 100644 --- a/mruby/src/proc.c +++ b/mruby/src/proc.c @@ -9,9 +9,10 @@ #include #include #include -#include #include #include +#include +#include static const mrb_code call_iseq[] = { OP_CALL, @@ -51,15 +52,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep) struct RClass *tc = NULL; if (ci->proc) { - if (ci->proc->color != MRB_GC_RED) { - tc = MRB_PROC_TARGET_CLASS(ci->proc); - } - else { - tc = mrb_vm_ci_target_class(ci); - if (tc && tc->tt == MRB_TT_ICLASS) { - tc = tc->c; - } - } + tc = MRB_PROC_TARGET_CLASS(ci->proc); } if (tc == NULL) { tc = mrb_vm_ci_target_class(ci); @@ -161,12 +154,12 @@ mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const MRB_ENV_SET_LEN(e, argc); if (argv) { - for (i = 0; i < argc; ++i) { + for (i = 0; i < argc; i++) { e->stack[i] = argv[i]; } } else { - for (i = 0; i < argc; ++i) { + for (i = 0; i < argc; i++) { SET_NIL_VALUE(e->stack[i]); } } @@ -237,14 +230,20 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) return proc; } +static void +check_proc(mrb_state *mrb, mrb_value proc) +{ + if (!mrb_proc_p(proc)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); + } +} + static mrb_value mrb_proc_init_copy(mrb_state *mrb, mrb_value self) { mrb_value proc = mrb_get_arg1(mrb); - if (!mrb_proc_p(proc)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); - } + check_proc(mrb, proc); mrb_proc_copy(mrb, mrb_proc_ptr(self), mrb_proc_ptr(proc)); return self; } @@ -275,9 +274,7 @@ proc_lambda(mrb_state *mrb, mrb_value self) if (mrb_nil_p(blk)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); } - if (!mrb_proc_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); - } + check_proc(mrb, blk); p = mrb_proc_ptr(blk); if (!MRB_PROC_STRICT_P(p)) { struct RProc *p2 = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, p->c); @@ -337,7 +334,7 @@ mrb_proc_local_variables(mrb_state *mrb, const struct RProc *proc) if (MRB_PROC_CFUNC_P(proc)) break; irep = proc->body.irep; if (irep->lv) { - for (i = 0; i + 1 < irep->nlocals; ++i) { + for (i = 0; i + 1 < irep->nlocals; i++) { if (irep->lv[i]) { mrb_sym sym = irep->lv[i]; const char *name = mrb_sym_name(mrb, sym); diff --git a/mruby/src/range.c b/mruby/src/range.c index 7507173b..a81bcd42 100644 --- a/mruby/src/range.c +++ b/mruby/src/range.c @@ -362,9 +362,13 @@ range_num_to_a(mrb_state *mrb, mrb_value range) mrb_int len; if (mrb_int_sub_overflow(b, a, &len)) { + too_long: mrb_raise(mrb, E_RANGE_ERROR, "integer range too long"); } - if (!RANGE_EXCL(r)) len++; + if (!RANGE_EXCL(r)) { + if (len == MRB_INT_MAX) goto too_long; + len++; + } ary = mrb_ary_new_capa(mrb, len); for (mrb_int i=0; i `mrb_float_read` + * renamed the function `vim_strtod` -> `mrb_read_float` * simplified the code + * changed the API My modifications in this file are also placed in the public domain. @@ -22,10 +23,9 @@ Matz (Yukihiro Matsumoto) #include #include -#include -MRB_API double -mrb_float_read(const char *str, char **end) +MRB_API mrb_bool +mrb_read_float(const char *str, char **endp, double *fp) { double d = 0.0; int sign; @@ -34,24 +34,26 @@ mrb_float_read(const char *str, char **end) a = p = str; while (ISSPACE(*p)) - ++p; + p++; /* decimal part */ sign = 1; if (*p == '-') { sign = -1; - ++p; - } else if (*p == '+') - ++p; + 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; + p++; + n++; } a = p; - } else if (*p != '.') + } + else if (*p != '.') goto done; d *= sign; @@ -59,17 +61,16 @@ mrb_float_read(const char *str, char **end) 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; - } + p++; + + if (ISDIGIT(*p)) { + while (*p && ISDIGIT(*p)) { + f += base * (*p - '0') ; + base /= 10.0; + p++; + n++; } + } d += f * sign; a = p; } @@ -77,18 +78,19 @@ mrb_float_read(const char *str, char **end) /* exponential part */ if ((*p == 'E') || (*p == 'e')) { int e = 0; - ++p; + p++; sign = 1; if (*p == '-') { sign = -1; - ++p; - } else if (*p == '+') - ++p; + p++; + } + else if (*p == '+') + p++; if (ISDIGIT(*p)) { while (*p == '0') - ++p; + p++; if (*p == '\0') --p; e = (int)(*p++ - '0'); for (; *p && ISDIGIT(*p); p++) { @@ -98,22 +100,21 @@ mrb_float_read(const char *str, char **end) e *= sign; } else if (!ISDIGIT(*(a-1))) { - a = str; - goto done; + return FALSE; } else if (*p == 0) goto done; - d *= pow(10.0, (double) e); + 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; + *fp = d; + if (endp) *endp = (char*)a; + if (str == a) return FALSE; + return TRUE; } #endif diff --git a/mruby/src/readint.c b/mruby/src/readint.c index 5fae222c..ad7c048e 100644 --- a/mruby/src/readint.c +++ b/mruby/src/readint.c @@ -1,16 +1,15 @@ #include #include -#include -/* mrb_int_read(): read mrb_int from a string (base 10 only) */ +/* mrb_read_int(): 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 *np - variable to save the result */ +/* returns TRUE if read succeeded */ +/* if integer overflows, returns FALSE */ +MRB_API mrb_bool +mrb_read_int(const char *p, const char *e, char **endp, mrb_int *np) { mrb_int n = 0; int ch; @@ -19,12 +18,11 @@ mrb_int_read(const char *p, const char *e, char **endp) 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; + return FALSE; } p++; } if (endp) *endp = (char*)p; - return n; + *np = n; + return TRUE; } diff --git a/mruby/src/readnum.c b/mruby/src/readnum.c new file mode 100644 index 00000000..3c459d06 --- /dev/null +++ b/mruby/src/readnum.c @@ -0,0 +1,43 @@ +/* this file defines obsolete functions: mrb_int_read() and mrb_float_read() */ +/* use mrb_read_int() and mrb_read_float() instead */ + +#include +#include +#include + +/* 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; + + if (!mrb_read_int(p, e, endp, &n)) { + if (endp) *endp = NULL; + errno = ERANGE; + return MRB_INT_MAX; + } + if (endp) *endp = (char*)p; + return n; +} + +#ifndef MRB_NO_FLOAT +//#include +//#include + +MRB_API double +mrb_float_read(const char *str, char **endp) +{ + double d; + + if (!mrb_read_float(str, endp, &d)) { + errno = ERANGE; + } + return d; +} +#endif diff --git a/mruby/src/state.c b/mruby/src/state.c index 4dafc964..a1065a20 100644 --- a/mruby/src/state.c +++ b/mruby/src/state.c @@ -12,6 +12,7 @@ #include #include #include +#include void mrb_init_core(mrb_state*); void mrb_init_mrbgems(mrb_state*); @@ -137,6 +138,7 @@ mrb_irep_cutref(mrb_state *mrb, mrb_irep *irep) if (irep->flags & MRB_IREP_NO_FREE) return; reps = (mrb_irep**)irep->reps; + if (!reps) return; for (i=0; irlen; i++) { mrb_irep *tmp = reps[i]; reps[i] = NULL; @@ -185,7 +187,7 @@ mrb_free_context(mrb_state *mrb, struct mrb_context *c) void mrb_protect_atexit(mrb_state *mrb); - MRB_API void +MRB_API void mrb_close(mrb_state *mrb) { if (!mrb) return; diff --git a/mruby/src/string.c b/mruby/src/string.c index 332c4e77..3e82b1ca 100644 --- a/mruby/src/string.c +++ b/mruby/src/string.c @@ -14,12 +14,13 @@ #include #include #include +#include #include #include typedef struct mrb_shared_string { int refcnt; - mrb_ssize capa; + mrb_int capa; char *ptr; } mrb_shared_string; @@ -27,29 +28,48 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #define mrb_obj_alloc_string(mrb) MRB_OBJ_ALLOC((mrb), MRB_TT_STRING, (mrb)->string_class) +#ifndef MRB_STR_LENGTH_MAX +#define MRB_STR_LENGTH_MAX 1048576 +#endif + +static void +str_check_too_big(mrb_state *mrb, mrb_int len) +{ + if (len < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "[BUG] negative string length"); + } +#if MRB_STR_LENGTH_MAX != 0 + if (len > MRB_STR_LENGTH_MAX-1) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "string too long (len=%i max=" MRB_STRINGIZE(MRB_STR_LENGTH_MAX) ")", len); + } +#endif +} + static struct RString* str_init_normal_capa(mrb_state *mrb, struct RString *s, - const char *p, size_t len, size_t capa) + const char *p, mrb_int len, mrb_int capa) { + str_check_too_big(mrb, capa); char *dst = (char *)mrb_malloc(mrb, capa + 1); if (p) memcpy(dst, p, len); dst[len] = '\0'; s->as.heap.ptr = dst; - s->as.heap.len = (mrb_ssize)len; - s->as.heap.aux.capa = (mrb_ssize)capa; + s->as.heap.len = len; + s->as.heap.aux.capa = capa; RSTR_UNSET_TYPE_FLAG(s); return s; } static struct RString* -str_init_normal(mrb_state *mrb, struct RString *s, const char *p, size_t len) +str_init_normal(mrb_state *mrb, struct RString *s, const char *p, mrb_int len) { return str_init_normal_capa(mrb, s, p, len, len); } static struct RString* -str_init_embed(struct RString *s, const char *p, size_t len) +str_init_embed(struct RString *s, const char *p, mrb_int len) { + mrb_assert(len >= 0); if (p) memcpy(RSTR_EMBED_PTR(s), p, len); RSTR_EMBED_PTR(s)[len] = '\0'; RSTR_SET_TYPE_FLAG(s, EMBED); @@ -58,10 +78,10 @@ str_init_embed(struct RString *s, const char *p, size_t len) } static struct RString* -str_init_nofree(struct RString *s, const char *p, size_t len) +str_init_nofree(struct RString *s, const char *p, mrb_int len) { s->as.heap.ptr = (char *)p; - s->as.heap.len = (mrb_ssize)len; + s->as.heap.len = len; s->as.heap.aux.capa = 0; /* nofree */ RSTR_SET_TYPE_FLAG(s, NOFREE); return s; @@ -97,37 +117,29 @@ str_init_fshared(const struct RString *orig, struct RString *s, struct RString * } static struct RString* -str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, size_t len) +str_init_modifiable(mrb_state *mrb, struct RString *s, const char *p, mrb_int len) { if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(s, p, len); } - else { - return str_init_normal(mrb, s, p, len); - } + return str_init_normal(mrb, s, p, len); } static struct RString* -str_new_static(mrb_state *mrb, const char *p, size_t len) +str_new_static(mrb_state *mrb, const char *p, mrb_int len) { if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } - if (len >= MRB_SSIZE_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); } static struct RString* -str_new(mrb_state *mrb, const char *p, size_t len) +str_new(mrb_state *mrb, const char *p, mrb_int len) { if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } - if (len >= MRB_SSIZE_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); - } if (p && mrb_ro_data_p(p)) { return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); } @@ -135,44 +147,36 @@ str_new(mrb_state *mrb, const char *p, size_t len) } MRB_API mrb_value -mrb_str_new_capa(mrb_state *mrb, size_t capa) +mrb_str_new_capa(mrb_state *mrb, mrb_int capa) { - struct RString *s; + struct RString *s = mrb_obj_alloc_string(mrb); if (RSTR_EMBEDDABLE_P(capa)) { - s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0); - } - else if (capa >= MRB_SSIZE_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); - /* not reached */ - s = NULL; + s = str_init_embed(s, NULL, 0); } else { - s = str_init_normal_capa(mrb, mrb_obj_alloc_string(mrb), NULL, 0, capa); + s = str_init_normal_capa(mrb, s, NULL, 0, capa); } - return mrb_obj_value(s); } static void -resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) +resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity) { -#if SIZE_MAX > MRB_SSIZE_MAX - mrb_assert(capacity < MRB_SSIZE_MAX); -#endif if (RSTR_EMBED_P(s)) { if (!RSTR_EMBEDDABLE_P(capacity)) { str_init_normal_capa(mrb, s, RSTR_EMBED_PTR(s), RSTR_EMBED_LEN(s), capacity); } } else { + str_check_too_big(mrb, capacity); s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); s->as.heap.aux.capa = (mrb_ssize)capacity; } } MRB_API mrb_value -mrb_str_new(mrb_state *mrb, const char *p, size_t len) +mrb_str_new(mrb_state *mrb, const char *p, mrb_int len) { return mrb_obj_value(str_new(mrb, p, len)); } @@ -181,7 +185,7 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state *mrb, const char *p) { struct RString *s; - size_t len; + mrb_int len; if (p) { len = strlen(p); @@ -196,7 +200,7 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p) } MRB_API mrb_value -mrb_str_new_static(mrb_state *mrb, const char *p, size_t len) +mrb_str_new_static(mrb_state *mrb, const char *p, mrb_int len) { struct RString *s = str_new_static(mrb, p, len); return mrb_obj_value(s); @@ -225,20 +229,19 @@ str_modify_keep_ascii(mrb_state *mrb, struct RString *s) mrb_free(mrb, shared); } else { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_init_modifiable(mrb, s, s->as.heap.ptr, s->as.heap.len); str_decref(mrb, shared); } } else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_init_modifiable(mrb, s, s->as.heap.ptr, s->as.heap.len); } } static void -check_null_byte(mrb_state *mrb, mrb_value str) +check_null_byte(mrb_state *mrb, struct RString *str) { - mrb_ensure_string_type(mrb, str); - if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) { + if (memchr(RSTR_PTR(str), '\0', RSTR_LEN(str))) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); } } @@ -255,33 +258,29 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str) } #ifdef MRB_UTF8_STRING -static const char utf8len_codepage[256] = -{ - 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,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,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,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1, -}; - #define utf8_islead(c) ((unsigned char)((c)&0xc0) != 0x80) +extern const char mrb_utf8len_table[]; +const char mrb_utf8len_table[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0 +}; + mrb_int mrb_utf8len(const char* p, const char* e) { - mrb_int len; - mrb_int i; - - if ((unsigned char)*p < 0x80) return 1; - len = utf8len_codepage[(unsigned char)*p]; - if (len == 1) return 1; + mrb_int len = mrb_utf8len_table[(unsigned char)p[0] >> 3]; if (len > e - p) return 1; - for (i = 1; i < len; ++i) - if (utf8_islead(p[i])) - return 1; + switch (len) { + case 1: + return 1; + case 4: + if (utf8_islead(p[3])) return 1; + case 3: + if (utf8_islead(p[2])) return 1; + case 2: + if (utf8_islead(p[1])) return 1; + } return len; } @@ -291,10 +290,9 @@ mrb_utf8_strlen(const char *str, mrb_int byte_len) mrb_int len = 0; const char *p = str; const char *e = p + byte_len; - while (p < e) { - p += mrb_utf8len(p, e); - len++; + if (utf8_islead(*p)) len++; + p++; } return len; } @@ -346,60 +344,32 @@ bytes2chars(char *p, mrb_int len, mrb_int bi) const char *pivot = p + bi; mrb_int i; - for (i = 0; p < pivot; i ++) { + for (i = 0; p < pivot; i++) { p += mrb_utf8len(p, e); } if (p != pivot) return -1; return i; } -static const char * +static const char* char_adjust(const char *beg, const char *end, const char *ptr) { - if ((ptr > beg || ptr < end) && (*ptr & 0xc0) == 0x80) { - const int utf8_adjust_max = 3; - const char *p; - - if (ptr - beg > utf8_adjust_max) { - beg = ptr - utf8_adjust_max; - } - - p = ptr; - while (p > beg) { - p --; - if ((*p & 0xc0) != 0x80) { - int clen = mrb_utf8len(p, end); - if (clen > ptr - p) return p; - break; - } - } - } - + ptrdiff_t len = end - ptr; + if (len < 1 || utf8_islead(ptr[0])) return ptr; + if (len > 1 && utf8_islead(ptr[1])) return ptr+1; + if (len > 2 && utf8_islead(ptr[2])) return ptr+2; + if (len > 3 && utf8_islead(ptr[3])) return ptr+3; return ptr; } -static const char * +static const char* char_backtrack(const char *ptr, const char *end) { - if (ptr < end) { - const int utf8_bytelen_max = 4; - const char *p; - - if (end - ptr > utf8_bytelen_max) { - ptr = end - utf8_bytelen_max; - } - - p = end; - while (p > ptr) { - p --; - if ((*p & 0xc0) != 0x80) { - int clen = utf8len_codepage[(unsigned char)*p]; - if (clen == end - p) { return p; } - break; - } - } - } - + ptrdiff_t len = end - ptr; + if (len < 1 || utf8_islead(end[-1])) return end-1; + if (len > 1 && utf8_islead(end[-2])) return end-2; + if (len > 2 && utf8_islead(end[-3])) return end-3; + if (len > 3 && utf8_islead(end[-4])) return end-4; return end - 1; } @@ -414,10 +384,10 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co { mrb_int i; - for (i = 0; i < 1 << CHAR_BIT; i ++) { + for (i = 0; i < 1 << CHAR_BIT; i++) { qstable[i] = slen; } - for (i = 0; i < slen; i ++) { + for (i = 0; i < slen; i++) { qstable[(unsigned char)s[i]] = slen - (i + 1); } } @@ -435,7 +405,7 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co do { p += mrb_utf8len(p, pend); - off ++; + off++; } while (p < pivot); } @@ -500,9 +470,9 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr ptrdiff_t qstable[256]; /* Preprocessing */ - for (i = 0; i < 256; ++i) + for (i = 0; i < 256; i++) qstable[i] = m + 1; - for (; x < xe; ++x) + for (; x < xe; x++) qstable[*x] = xe - x; /* Searching */ for (; y + m <= ys + n; y += *(qstable + y[m])) { @@ -687,23 +657,25 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) static mrb_int str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) { - const char *s, *sbeg, *t; + const char *s, *sbeg, *send, *t; struct RString *ps = mrb_str_ptr(str); mrb_int len = RSTRING_LEN(sub); + mrb_int slen = RSTR_LEN(ps); /* substring longer than string */ - if (RSTR_LEN(ps) < len) return -1; - if (RSTR_LEN(ps) - pos < len) { - pos = RSTR_LEN(ps) - len; + if (slen < len) return -1; + if (slen - pos < len) { + pos = slen - len; } sbeg = RSTR_PTR(ps); - s = RSTR_PTR(ps) + pos; + send = sbeg + slen; + s = sbeg + pos; t = RSTRING_PTR(sub); if (len) { - s = char_adjust(sbeg, sbeg + RSTR_LEN(ps), s); + s = char_adjust(sbeg, send, s); while (sbeg <= s) { - if (memcmp(s, t, len) == 0) { - return (mrb_int)(s - RSTR_PTR(ps)); + if ((mrb_int)(send - s) >= len && memcmp(s, t, len) == 0) { + return (mrb_int)(s - sbeg); } s = char_backtrack(sbeg, s); } @@ -714,21 +686,6 @@ str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) } } -MRB_API mrb_int -mrb_str_strlen(mrb_state *mrb, struct RString *s) -{ - mrb_int i, max = RSTR_LEN(s); - char *p = RSTR_PTR(s); - - if (!p) return 0; - for (i=0; i @@ -833,14 +790,9 @@ 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); - 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); - } + mrb_int len = RSTRING_LEN(str0); + check_null_byte(mrb, RSTRING(str0)); + s = str_init_modifiable(mrb, mrb_obj_alloc_string(mrb), p, len); return RSTR_PTR(s); } @@ -857,10 +809,15 @@ mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b) struct RString *s = mrb_str_ptr(a); struct RString *s2 = mrb_str_ptr(b); struct RString *t; + mrb_int slen = RSTR_LEN(s); + mrb_int s2len = RSTR_LEN(s2); + const char *p = RSTR_PTR(s); + const char *p2 = RSTR_PTR(s2); - t = str_new(mrb, 0, RSTR_LEN(s) + RSTR_LEN(s2)); - memcpy(RSTR_PTR(t), RSTR_PTR(s), RSTR_LEN(s)); - memcpy(RSTR_PTR(t) + RSTR_LEN(s), RSTR_PTR(s2), RSTR_LEN(s2)); + t = str_new(mrb, 0, slen + s2len); + char *pt = RSTR_PTR(t); + memcpy(pt, p, slen); + memcpy(pt + slen, p2, s2len); return mrb_obj_value(t); } @@ -920,7 +877,7 @@ mrb_str_bytesize(mrb_state *mrb, mrb_value self) static mrb_value mrb_str_times(mrb_state *mrb, mrb_value self) { - mrb_int n,len,times; + mrb_int n, len, times; struct RString *str2; char *p; @@ -928,11 +885,9 @@ mrb_str_times(mrb_state *mrb, mrb_value self) if (times < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } - if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) { + if (mrb_int_mul_overflow(RSTRING_LEN(self), times, &len)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big"); } - - len = RSTRING_LEN(self)*times; str2 = str_new(mrb, 0, len); p = RSTR_PTR(str2); if (len > 0) { @@ -964,16 +919,18 @@ mrb_str_times(mrb_state *mrb, mrb_value self) MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2) { - mrb_int len; + mrb_int len, len1, len2; mrb_int retval; struct RString *s1 = mrb_str_ptr(str1); struct RString *s2 = mrb_str_ptr(str2); - len = lesser(RSTR_LEN(s1), RSTR_LEN(s2)); + len1 = RSTR_LEN(s1); + len2 = RSTR_LEN(s2); + len = lesser(len1, len2); retval = memcmp(RSTR_PTR(s1), RSTR_PTR(s2), len); if (retval == 0) { - if (RSTR_LEN(s1) == RSTR_LEN(s2)) return 0; - if (RSTR_LEN(s1) > RSTR_LEN(s2)) return 1; + if (len1 == len2) return 0; + if (len1 > len2) return 1; return -1; } if (retval > 0) return 1; @@ -1059,22 +1016,6 @@ mrb_str_equal_m(mrb_state *mrb, mrb_value str1) } /* ---------------------------------- */ -/* obslete: use RSTRING_PTR() */ -MRB_API const char* -mrb_string_value_ptr(mrb_state *mrb, mrb_value str) -{ - str = mrb_obj_as_string(mrb, str); - return RSTRING_PTR(str); -} - -/* obslete: use RSTRING_LEN() */ -MRB_API mrb_int -mrb_string_value_len(mrb_state *mrb, mrb_value ptr) -{ - mrb_ensure_string_type(mrb, ptr); - return RSTRING_LEN(ptr); -} - MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str) { @@ -1234,7 +1175,7 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb } replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep)); - if (mrb_int_add_overflow(replen, len - (end - pos), &newlen) || newlen >= MRB_SSIZE_MAX) { + if (mrb_int_add_overflow(replen, len - (end - pos), &newlen)) { mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big"); } @@ -1279,12 +1220,7 @@ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) if (inspect) { mrb_int clen = mrb_utf8len(p, pend); if (clen > 1) { - mrb_int i; - - for (i=0; i integer or nil + * + * Returns the \Integer byte-based index of the first occurrence of the given +substring+, + * or +nil+ if none found: + * + * 'foo'.byteindex('f') # => 0 + * 'foo'.byteindex('oo') # => 1 + * 'foo'.byteindex('ooo') # => nil + */ +static mrb_value +mrb_str_byteindex_m(mrb_state *mrb, mrb_value str) +{ + mrb_value sub; + mrb_int pos; + + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + pos = 0; + } + else if (pos < 0) { + pos += RSTRING_LEN(str); + if (pos < 0) { + return mrb_nil_value(); + } + } + pos = str_index_str(mrb, str, sub, pos); + + if (pos == -1) return mrb_nil_value(); + return mrb_int_value(mrb, pos); +} + /* 15.2.10.5.22 */ /* * call-seq: @@ -1808,9 +1787,14 @@ mrb_str_include(mrb_state *mrb, mrb_value self) * "hello".index('a') #=> nil * "hello".index('l', -2) #=> 3 */ +#ifdef MRB_UTF8_STRING static mrb_value mrb_str_index_m(mrb_state *mrb, mrb_value str) { + if (RSTR_ASCII_P(mrb_str_ptr(str))) { + return mrb_str_byteindex_m(mrb, str); + } + mrb_value sub; mrb_int pos; @@ -1827,9 +1811,11 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) pos = str_index_str_by_char(mrb, str, sub, pos); if (pos == -1) return mrb_nil_value(); - BYTES_ALIGN_CHECK(pos); return mrb_int_value(mrb, pos); } +#else +#define mrb_str_index_m mrb_str_byteindex_m +#endif /* 15.2.10.5.24 */ /* 15.2.10.5.28 */ @@ -2019,6 +2005,44 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str) return str2; } +/* + * call-seq: + * byterindex(substring, offset = self.bytesize) -> integer or nil + * + * Returns the \Integer byte-based index of the _last_ occurrence of the given +substring+, + * or +nil+ if none found: + * + * 'foo'.byterindex('f') # => 0 + * 'foo'.byterindex('o') # => 2 + * 'foo'.byterindex('oo') # => 1 + * 'foo'.byterindex('ooo') # => nil + */ +static mrb_value +mrb_str_byterindex_m(mrb_state *mrb, mrb_value str) +{ + mrb_value sub; + mrb_int pos; + mrb_int len = RSTRING_LEN(str); + + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + pos = len; + } + else { + if (pos < 0) { + pos += len; + if (pos < 0) { + return mrb_nil_value(); + } + } + if (pos > len) pos = len; + } + pos = str_rindex(mrb, str, sub, pos); + if (pos < 0) { + return mrb_nil_value(); + } + return mrb_int_value(mrb, pos); +} + /* 15.2.10.5.31 */ /* * call-seq: @@ -2034,27 +2058,33 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str) * "hello".rindex('a') #=> nil * "hello".rindex('l', 2) #=> 2 */ +#ifdef MRB_UTF8_STRING static mrb_value -mrb_str_rindex(mrb_state *mrb, mrb_value str) +mrb_str_rindex_m(mrb_state *mrb, mrb_value str) { + if (RSTR_ASCII_P(mrb_str_ptr(str))) { + return mrb_str_byterindex_m(mrb, str); + } + mrb_value sub; mrb_int pos; - int argc = mrb_get_args(mrb, "S|i", &sub, &pos); - mrb_int len = RSTRING_CHAR_LEN(str); - if (argc == 1) { - pos = len; + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + pos = RSTRING_CHAR_LEN(str); + pos = chars2bytes(str, 0, pos); + } + else if (pos >= 0) { + pos = chars2bytes(str, 0, pos); } else { - if (pos < 0) { - pos += len; - if (pos < 0) { - return mrb_nil_value(); - } + const char *p = RSTRING_PTR(str); + const char *e = RSTRING_END(str); + while (pos++ < 0 && p < e) { + e = char_backtrack(p, e); } - if (pos > len) pos = len; + if (p == e) return mrb_nil_value(); + pos = (mrb_int)(e - p); } - pos = chars2bytes(str, 0, pos); pos = str_rindex(mrb, str, sub, pos); if (pos >= 0) { pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); @@ -2063,6 +2093,9 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) } return mrb_nil_value(); } +#else +#define mrb_str_rindex_m mrb_str_byterindex_m +#endif /* 15.2.10.5.35 */ @@ -2158,7 +2191,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) mrb_gc_arena_restore(mrb, ai); skip = TRUE; beg = idx; - if (lim_p) ++i; + if (lim_p) i++; } else { end = idx; @@ -2205,11 +2238,24 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) return result; } +static mrb_bool +trailingbad(const char *str, const char *p, const char *pend) +{ + if (p == str) return TRUE; /* no number */ + if (*(p - 1) == '_') return TRUE; /* trailing '_' */ + while (p= base) { @@ -2347,22 +2396,27 @@ mrb_str_len_to_integer(mrb_state *mrb, const char *str, size_t len, mrb_int base break; } overflow: +#ifdef MRB_USE_BIGINT + ; + const char *p3 = p2; + while (p3 < pend) { + char c = TOLOWER(*p3); + const char *p4 = strchr(mrb_digitmap, c); + if (p4 == NULL && c != '_') break; + if (p4 - mrb_digitmap >= base) break; + p3++; + } + if (badcheck && trailingbad(str, p, pend)) goto bad; + return mrb_bint_new_str(mrb, p2, (mrb_int)(p3-p2), sign ? base : -base); +#else mrb_raisef(mrb, E_RANGE_ERROR, "string (%l) too big for integer", str, pend-str); +#endif } n += c; } val = (mrb_int)n; - if (badcheck) { - if (p == str) goto bad; /* no number */ - if (*(p - 1) == '_') goto bad; /* trailing '_' */ - while (p= MRB_SSIZE_MAX) { + if (mrb_int_add_overflow(RSTR_LEN(s), len, &total)) { size_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } if (capa <= total) { if (capa == 0) capa = 1; while (capa <= total) { - if (capa <= MRB_SSIZE_MAX / 2) { - capa *= 2; - } - else { - capa = total+1; - } - } - if (capa <= total || capa > MRB_SSIZE_MAX) { - goto size_error; + if (mrb_int_mul_overflow(capa, 2, &capa)) goto size_error; } resize_capa(mrb, s, capa); } @@ -2681,7 +2726,6 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len) ptr = RSTR_PTR(s) + off; } memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len); - mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX); RSTR_SET_LEN(s, total); RSTR_PTR(s)[total] = '\0'; /* sentinel */ return str; @@ -2798,8 +2842,8 @@ mrb_str_setbyte(mrb_state *mrb, mrb_value str) /* * call-seq: * str.byteslice(integer) -> new_str or nil - * str.byteslice(integer, integer) -> new_str or nil - * str.byteslice(range) -> new_str or nil + * str.byteslice(integer, integer) -> new_str or nil + * str.byteslice(range) -> new_str or nil * * Byte Reference---If passed a single Integer, returns a * substring of one byte at that position. If passed two Integer @@ -2877,13 +2921,13 @@ sub_replace(mrb_state *mrb, mrb_value self) mrb_str_cat(mrb, result, "\\", 1); break; case '`': - mrb_str_cat(mrb, result, RSTRING_PTR(self), chars2bytes(self, 0, found)); + mrb_str_cat(mrb, result, RSTRING_PTR(self), found); break; case '&': case '0': mrb_str_cat(mrb, result, match, mlen); break; case '\'': - offset = chars2bytes(self, 0, found) + mlen; + offset = found + mlen; if (RSTRING_LEN(self) > offset) { mrb_str_cat(mrb, result, RSTRING_PTR(self)+offset, RSTRING_LEN(self)-offset); } @@ -2942,7 +2986,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "replace", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.28 */ mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE()); /* 15.2.10.5.29 */ mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE()); /* 15.2.10.5.30 */ - mrb_define_method(mrb, s, "rindex", mrb_str_rindex, MRB_ARGS_ANY()); /* 15.2.10.5.31 */ + mrb_define_method(mrb, s, "rindex", mrb_str_rindex_m, MRB_ARGS_ANY()); /* 15.2.10.5.31 */ mrb_define_method(mrb, s, "size", mrb_str_size, MRB_ARGS_NONE()); /* 15.2.10.5.33 */ mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */ mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */ @@ -2961,6 +3005,8 @@ 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, "byteindex", mrb_str_byteindex_m, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, s, "byterindex", mrb_str_byterindex_m, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, s, "__sub_replace", sub_replace, MRB_ARGS_REQ(3)); /* internal */ diff --git a/mruby/src/symbol.c b/mruby/src/symbol.c index cc8986ea..c707a9d9 100644 --- a/mruby/src/symbol.c +++ b/mruby/src/symbol.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #ifndef MRB_NO_PRESYM @@ -110,7 +111,7 @@ sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp) for (i=0; i<5; i++) { uint32_t bits = sym>>(24-i*6) & 0x3f; if (bits == 0) break; - buf[i] = pack_table[bits-1];; + buf[i] = pack_table[bits-1]; } buf[i] = '\0'; if (lenp) *lenp = i; @@ -118,26 +119,6 @@ sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp) } #endif -static uint8_t -symhash(const char *key, size_t len) -{ - uint32_t hash, i; - - for(hash = i = 0; i < len; ++i) { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - 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)) @@ -154,7 +135,7 @@ sym_check(mrb_state *mrb, const char *name, size_t len, mrb_sym i) } else { /* length in BER */ - symlen = mrb_packed_int_decode((uint8_t*)symname, (uint8_t**)&symname); + symlen = mrb_packed_int_decode((const uint8_t*)symname, (const uint8_t**)&symname); } if (len == symlen && memcmp(symname, name, len) == 0) { return TRUE; @@ -178,7 +159,7 @@ find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) i = sym_inline_pack(name, len); if (i > 0) return i; - hash = symhash(name, len); + hash = mrb_byte_hash((const uint8_t*)name, len); if (hashp) *hashp = hash; i = mrb->symhash[hash]; @@ -220,7 +201,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) size_t symcapa = mrb->symcapa; if (symcapa == 0) symcapa = 100; else symcapa = (size_t)(symcapa * 6 / 5); - mrb->symtbl = (const char**)mrb_realloc(mrb, mrb->symtbl, sizeof(char*)*symcapa); + mrb->symtbl = (const char**)mrb_realloc(mrb, (void*)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); @@ -232,9 +213,10 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) mrb->symtbl[sym] = name; } else { - int ilen = mrb_packed_int_len(len); + uint32_t ulen = (uint32_t)len; + size_t ilen = mrb_packed_int_len(ulen); char *p = (char *)mrb_malloc(mrb, len+ilen+1); - mrb_packed_int_encode(len, (uint8_t*)p, (uint8_t*)p+ilen); + mrb_packed_int_encode(ulen, (uint8_t*)p, (uint8_t*)p+ilen); memcpy(p+ilen, name, len); p[ilen+len] = 0; mrb->symtbl[sym] = p; @@ -347,7 +329,7 @@ sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp) 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); + uint32_t len = mrb_packed_int_decode((const uint8_t*)symname, (const uint8_t**)&symname); if (lenp) *lenp = (mrb_int)len; } else if (lenp) { @@ -376,9 +358,9 @@ mrb_free_symtbl(mrb_state *mrb) mrb_free(mrb, (char*)mrb->symtbl[i]); } } - mrb_free(mrb, mrb->symtbl); - mrb_free(mrb, mrb->symlink); - mrb_free(mrb, mrb->symflags); + mrb_free(mrb, (void*)mrb->symtbl); + mrb_free(mrb, (void*)mrb->symlink); + mrb_free(mrb, (void*)mrb->symflags); } void diff --git a/mruby/src/variable.c b/mruby/src/variable.c index 53b760d0..be27f0ed 100644 --- a/mruby/src/variable.c +++ b/mruby/src/variable.c @@ -10,6 +10,7 @@ #include #include #include +#include #include /* Instance variable table structure */ @@ -48,9 +49,9 @@ iv_rehash(mrb_state *mrb, iv_tbl *t) khash_power2(new_alloc); if (old_alloc == new_alloc) return; + t->ptr = (mrb_value*)mrb_calloc(mrb, sizeof(mrb_value)+sizeof(mrb_sym), new_alloc); t->size = 0; t->alloc = new_alloc; - t->ptr = (mrb_value*)mrb_calloc(mrb, sizeof(mrb_value)+sizeof(mrb_sym), new_alloc); if (old_alloc == 0) return; mrb_sym *keys = (mrb_sym*)&old_ptr[old_alloc]; @@ -299,7 +300,7 @@ obj_iv_p(mrb_value obj) case MRB_TT_MODULE: case MRB_TT_SCLASS: case MRB_TT_HASH: - case MRB_TT_DATA: + case MRB_TT_CDATA: case MRB_TT_EXCEPTION: return TRUE; default: @@ -485,7 +486,7 @@ mrb_value mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) { iv_tbl *t = obj->iv; - int len = iv_size(mrb, t); + size_t len = iv_size(mrb, t); if (len > 0) { const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj)); @@ -773,6 +774,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym, mrb_bool skip) mrb_bool retry = FALSE; mrb_value name; + /* if skip then skip the current class (already searched) */ if (skip) c = c->super; L_RETRY: while (c) { @@ -781,6 +783,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym, mrb_bool skip) return v; } c = c->super; + if (!skip && c == mrb->object_class) break; } if (!retry && base->tt == MRB_TT_MODULE) { c = mrb->object_class; @@ -825,6 +828,7 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) proc = proc->upper; while (proc) { c2 = MRB_PROC_TARGET_CLASS(proc); + if (!c2) c2 = mrb->object_class; if (c2 && iv_get(mrb, c2->iv, sym, &v)) { return v; } @@ -985,7 +989,7 @@ mrb_f_global_variables(mrb_state *mrb, mrb_value self) } static mrb_bool -mrb_const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb_bool recurse) +const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb_bool recurse) { struct RClass *klass = mrb_class_ptr(mod); struct RClass *tmp; @@ -1011,13 +1015,13 @@ mrb_const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, MRB_API mrb_bool mrb_const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id) { - return mrb_const_defined_0(mrb, mod, id, TRUE, TRUE); + return const_defined_0(mrb, mod, id, TRUE, TRUE); } MRB_API mrb_bool mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id) { - return mrb_const_defined_0(mrb, mod, id, TRUE, FALSE); + return const_defined_0(mrb, mod, id, TRUE, FALSE); } MRB_API mrb_value @@ -1104,8 +1108,8 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c) if (outer == NULL) return mrb_nil_value(); name = find_class_sym(mrb, outer, c); if (name == 0) return mrb_nil_value(); - str = mrb_class_name(mrb, outer); path = mrb_str_new_capa(mrb, 40); + str = mrb_class_name(mrb, outer); mrb_str_cat_cstr(mrb, path, str); mrb_str_cat_cstr(mrb, path, "::"); diff --git a/mruby/src/vm.c b/mruby/src/vm.c index 3501abf5..475f02ab 100644 --- a/mruby/src/vm.c +++ b/mruby/src/vm.c @@ -19,6 +19,7 @@ #include "value_array.h" #include #include +#include #include #ifdef MRB_NO_STDIO @@ -27,7 +28,7 @@ extern "C" { #endif void abort(void); #if defined(__cplusplus) -} /* extern "C" { */ +} /* extern "C" */ #endif #endif @@ -83,8 +84,6 @@ mrb_gc_arena_shrink(mrb_state *mrb, int idx) #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) { @@ -97,6 +96,7 @@ stack_clear(mrb_value *from, size_t count) static inline void stack_copy(mrb_value *dst, const mrb_value *src, size_t size) { + if (!src) return; memcpy(dst, src, sizeof(mrb_value)*size); } @@ -177,10 +177,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) size += room; #endif - newstack = (mrb_value *)mrb_realloc_simple(mrb, mrb->c->stbase, sizeof(mrb_value) * size); - if (newstack == NULL) { - mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); - } + newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); stack_clear(&(newstack[oldsize]), size - oldsize); envadjust(mrb, oldbase, newstack, oldsize); mrb->c->stbase = newstack; @@ -201,6 +198,21 @@ mrb_stack_extend(mrb_state *mrb, mrb_int room) } } +static void +stack_extend_adjust(mrb_state *mrb, mrb_int room, const mrb_value **argp) +{ + const struct mrb_context *c = mrb->c; + ptrdiff_t voff = *argp - c->stbase; + + if (voff < 0 || voff >= c->stend - c->stbase) { + mrb_stack_extend(mrb, room); + } + else { + mrb_stack_extend(mrb, room); + *argp = c->stbase + voff; + } +} + static inline struct REnv* uvenv(mrb_state *mrb, mrb_int up) { @@ -238,14 +250,80 @@ top_proc(mrb_state *mrb, const struct RProc *proc) return proc; } +#define CI_PROC_SET(ci, p) do {\ + ci->proc = p;\ + ci->pc = (p && !MRB_PROC_CFUNC_P(p)) ? p->body.irep->iseq : NULL;\ +} while (0) + +void +mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p) +{ + CI_PROC_SET(ci, p); +} + +#define CI_TARGET_CLASS(ci) (((ci)->u.env && (ci)->u.env->tt == MRB_TT_ENV)? (ci)->u.env->c : (ci)->u.target_class) + +struct RClass* +mrb_vm_ci_target_class(const mrb_callinfo *ci) +{ + return CI_TARGET_CLASS(ci); +} + +void +mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc) +{ + struct REnv *e = ci->u.env; + if (e && e->tt == MRB_TT_ENV) { + e->c = tc; + } + else { + ci->u.target_class = tc; + } +} + +#define CI_ENV(ci) (((ci)->u.env && (ci)->u.env->tt == MRB_TT_ENV)? (ci)->u.env : NULL) + +struct REnv* +mrb_vm_ci_env(const mrb_callinfo *ci) +{ + return CI_ENV(ci); +} + +void +mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +{ + if (ci->u.env) { + if (ci->u.env->tt == MRB_TT_ENV) { + if (e) { + e->c = ci->u.env->c; + ci->u.env = e; + } + else { + ci->u.target_class = ci->u.env->c; + } + } + else { + if (e) { + e->c = ci->u.target_class; + ci->u.env = e; + } + } + } + else { + ci->u.env = e; + } +} + #define CINFO_NONE 0 #define CINFO_SKIP 1 #define CINFO_DIRECT 2 #define CINFO_RESUMED 3 +#define BLK_PTR(b) ((mrb_proc_p(b)) ? mrb_proc_ptr(b) : NULL) + static inline mrb_callinfo* -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) +cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, struct RClass *target_class, + const struct RProc *proc, struct RProc *blk, mrb_sym mid, uint16_t argc) { struct mrb_context *c = mrb->c; mrb_callinfo *ci = c->ci; @@ -262,7 +340,8 @@ cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, } ci = ++c->ci; ci->mid = mid; - mrb_vm_ci_proc_set(ci, proc); + CI_PROC_SET(ci, proc); + ci->blk = blk; ci->stack = ci[-1].stack + push_stacks; ci->n = argc & 0xf; ci->nk = (argc>>4) & 0xf; @@ -272,24 +351,45 @@ cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, return ci; } -void -mrb_env_unshare(mrb_state *mrb, struct REnv *e) +mrb_bool +mrb_env_unshare(mrb_state *mrb, struct REnv *e, mrb_bool noraise) { - if (e == NULL) return; - else { - size_t len = (size_t)MRB_ENV_LEN(e); - mrb_value *p; + if (e == NULL) return TRUE; + if (!MRB_ENV_ONSTACK_P(e)) return TRUE; + if (e->cxt != mrb->c) return TRUE; + if (e == CI_ENV(mrb->c->cibase)) return TRUE; /* for mirb */ + + size_t len = (size_t)MRB_ENV_LEN(e); + if (len == 0) { + e->stack = NULL; + MRB_ENV_CLOSE(e); + return TRUE; + } - if (!MRB_ENV_ONSTACK_P(e)) return; - if (e->cxt != mrb->c) return; - if (e == mrb_vm_ci_env(mrb->c->cibase)) return; /* for mirb */ - p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); - if (len > 0) { - stack_copy(p, e->stack, len); - } + size_t live = mrb->gc.live; + mrb_value *p = (mrb_value *)mrb_malloc_simple(mrb, sizeof(mrb_value)*len); + if (live != mrb->gc.live && mrb_object_dead_p(mrb, (struct RBasic *)e)) { + // The e object is now subject to GC inside mrb_malloc_simple(). + // Moreover, if NULL is returned due to mrb_malloc_simple() failure, simply ignore it. + mrb_free(mrb, p); + return TRUE; + } + else if (p) { + stack_copy(p, e->stack, len); e->stack = p; MRB_ENV_CLOSE(e); mrb_write_barrier(mrb, (struct RBasic *)e); + return TRUE; + } + else { + e->stack = NULL; + MRB_ENV_CLOSE(e); + MRB_ENV_SET_LEN(e, 0); + MRB_ENV_SET_BIDX(e, 0); + if (!noraise) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); + } + return FALSE; } } @@ -297,10 +397,20 @@ static inline mrb_callinfo* cipop(mrb_state *mrb) { struct mrb_context *c = mrb->c; - struct REnv *env = mrb_vm_ci_env(c->ci); + mrb_callinfo *ci = c->ci; + struct REnv *env = CI_ENV(ci); + mrb_vm_ci_env_set(ci, NULL); // make possible to free by GC if env is not needed + struct RProc *b = ci->blk; + if (b && !mrb_object_dead_p(mrb, (struct RBasic*)b) && b->tt == MRB_TT_PROC && + !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&ci[-1])) { + b->flags |= MRB_PROC_ORPHAN; + } + if (env && !mrb_env_unshare(mrb, env, TRUE)) { + c->ci--; // exceptions are handled at the method caller; see #3087 + mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); + } c->ci--; - if (env) mrb_env_unshare(mrb, env); return c->ci; } @@ -396,14 +506,13 @@ mrb_funcall_id(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, ...) static mrb_int mrb_ci_kidx(const mrb_callinfo *ci) { + if (ci->nk == 0) return -1; return (ci->n == CALL_MAXARGS) ? 2 : ci->n + 1; } -static mrb_int -mrb_bidx(uint16_t c) +static inline mrb_int +mrb_bidx(uint8_t n, uint8_t k) { - 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; @@ -413,7 +522,7 @@ mrb_bidx(uint16_t c) mrb_int mrb_ci_bidx(mrb_callinfo *ci) { - return mrb_bidx(ci->n|(ci->nk<<4)); + return mrb_bidx(ci->n, ci->nk); } mrb_int @@ -422,7 +531,7 @@ mrb_ci_nregs(mrb_callinfo *ci) const struct RProc *p; if (!ci) return 4; - uint8_t nregs = mrb_ci_bidx(ci) + 1; /* self + args + kargs + blk */ + mrb_int nregs = mrb_ci_bidx(ci) + 1; /* self + args + kargs + blk */ p = ci->proc; if (p && !MRB_PROC_CFUNC_P(p) && p->body.irep && p->body.irep->nregs > nregs) { return p->body.irep->nregs; @@ -433,20 +542,16 @@ mrb_ci_nregs(mrb_callinfo *ci) mrb_value mrb_obj_missing(mrb_state *mrb, mrb_value mod); 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) +prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, mrb_value blk, mrb_bool 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 *argv = &ci->stack[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 (ci->n == 15) args = argv[0]; + else args = mrb_ary_new_from_values(mrb, ci->n, argv); if (mrb_func_basic_p(mrb, recv, missing, mrb_obj_missing)) { method_missing: @@ -455,27 +560,67 @@ prepare_missing(mrb_state *mrb, mrb_value recv, mrb_sym mid, struct RClass **cls /* not reached */ } if (mid != missing) { - *clsp = mrb_class(mrb, recv); + ci->u.target_class = mrb_class(mrb, recv); } - m = mrb_method_search_vm(mrb, clsp, missing); + m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, missing); if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */ - mrb_stack_extend(mrb, a+4); + mrb_stack_extend(mrb, 4); - argv = &ci->stack[a+1]; /* maybe reallocated */ + argv = &ci->stack[1]; /* maybe reallocated */ argv[0] = args; - if (nk == 0) { + if (ci->nk == 0) { argv[1] = blk; } else { - mrb_assert(nk == 15); - argv[1] = argv[n]; + mrb_assert(ci->nk == 15); + argv[1] = argv[ci->n]; argv[2] = blk; } - *c = 15 | (nk<<4); + ci->n = CALL_MAXARGS; + /* ci->nk is already set to zero or CALL_MAXARGS */ mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); + ci->mid = missing; return m; } +static void +funcall_args_capture(mrb_state *mrb, int stoff, mrb_int argc, const mrb_value *argv, mrb_value block, mrb_callinfo *ci) +{ + if (argc < 0 || argc > INT32_MAX) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative or too big argc for funcall (%i)", argc); + } + + ci->nk = 0; /* funcall does not support keyword arguments */ + if (argc < CALL_MAXARGS) { + mrb_int extends = stoff + argc + 2 /* self + block */; + stack_extend_adjust(mrb, extends, &argv); + + mrb_value *args = mrb->c->ci->stack + stoff + 1 /* self */; + stack_copy(args, argv, argc); + args[argc] = block; + ci->n = (uint8_t)argc; + } + else { + int extends = stoff + 3 /* self + splat + block */; + stack_extend_adjust(mrb, extends, &argv); + + mrb_value *args = mrb->c->ci->stack + stoff + 1 /* self */; + args[0] = mrb_ary_new_from_values(mrb, argc, argv); + args[1] = block; + ci->n = CALL_MAXARGS; + } +} + +static mrb_value +ensure_block(mrb_state *mrb, mrb_value blk) +{ + 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 */ + } + return blk; +} + MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) { @@ -504,10 +649,8 @@ 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->c->ci; mrb_int n = mrb_ci_nregs(ci); - ptrdiff_t voff = -1; if (!mrb->c->stbase) { stack_init(mrb); @@ -515,55 +658,27 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc 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 (argc >= 15) { - ci->stack[n+1] = mrb_ary_new_from_values(mrb, argc, argv); - argc = 15; - } + blk = ensure_block(mrb, blk); + ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, BLK_PTR(blk), 0, 0); + funcall_args_capture(mrb, 0, argc, argv, blk, ci); + ci->u.target_class = mrb_class(mrb, self); + m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, mid); if (MRB_METHOD_UNDEF_P(m)) { - uint16_t ac = (uint16_t)argc; - m = prepare_missing(mrb, self, mid, &c, n, &ac, mrb_nil_value(), 0); - argc = (mrb_int)ac; - mid = MRB_SYM(method_missing); - } - ci = cipush(mrb, n, 0, c, NULL, mid, argc); - if (MRB_METHOD_PROC_P(m)) { - struct RProc *p = MRB_METHOD_PROC(m); - - mrb_vm_ci_proc_set(ci, p); - if (!MRB_PROC_CFUNC_P(p)) { - mrb_stack_extend(mrb, p->body.irep->nregs + argc); - } - } - if (voff >= 0) { - argv = mrb->c->stbase + voff; - } - ci->stack[0] = self; - if (argc < 15) { - if (argc > 0) - stack_copy(ci->stack+1, argv, argc); - ci->stack[argc+1] = blk; + m = prepare_missing(mrb, ci, self, mid, mrb_nil_value(), FALSE); } else { - ci->stack[2] = blk; + ci->mid = mid; } + ci->proc = MRB_METHOD_PROC_P(m) ? MRB_METHOD_PROC(m) : NULL; if (MRB_METHOD_CFUNC_P(m)) { - ci->cci = CINFO_DIRECT; + ci->stack[0] = self; val = MRB_METHOD_CFUNC(m)(mrb, self); cipop(mrb); } else { ci->cci = CINFO_SKIP; - val = mrb_run(mrb, MRB_METHOD_PROC(m), self); + val = mrb_run(mrb, ci->proc, self); } } mrb_gc_arena_restore(mrb, ai); @@ -580,7 +695,7 @@ mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, cons static void check_method_noarg(mrb_state *mrb, const mrb_callinfo *ci) { - int argc = ci->n == CALL_MAXARGS ? RARRAY_LEN(ci->stack[1]) : ci->n; + mrb_int argc = ci->n == CALL_MAXARGS ? RARRAY_LEN(ci->stack[1]) : ci->n; if (ci->nk > 0) { mrb_value kdict = ci->stack[mrb_ci_kidx(ci)]; if (!(mrb_hash_p(kdict) && mrb_hash_empty_p(mrb, kdict))) { @@ -596,10 +711,10 @@ static mrb_value exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) { mrb_callinfo *ci = mrb->c->ci; - int keep, nregs; + mrb_int keep, nregs; ci->stack[0] = self; - mrb_vm_ci_proc_set(ci, p); + CI_PROC_SET(ci, p); if (MRB_PROC_CFUNC_P(p)) { if (MRB_PROC_NOARG_P(p)) { check_method_noarg(mrb, ci); @@ -616,7 +731,7 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) stack_clear(ci->stack+keep, nregs-keep); } - cipush(mrb, 0, 0, NULL, NULL, 0, 0); + cipush(mrb, 0, 0, NULL, NULL, NULL, 0, 0); return self; } @@ -634,12 +749,12 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) if (MRB_PROC_NOARG_P(p)) { check_method_noarg(mrb, ci); } - cipush(mrb, 0, CINFO_DIRECT, mrb_vm_ci_target_class(ci), p, ci->mid, ci->n|(ci->nk<<4)); + cipush(mrb, 0, CINFO_DIRECT, CI_TARGET_CLASS(ci), p, NULL, ci->mid, ci->n|(ci->nk<<4)); ret = MRB_PROC_CFUNC(p)(mrb, self); cipop(mrb); } else { - int keep = mrb_ci_bidx(ci) + 1; /* receiver + block */ + mrb_int keep = mrb_ci_bidx(ci) + 1; /* receiver + block */ ret = mrb_top_run(mrb, p, self, keep); } if (mrb->exc && mrb->jmp) { @@ -701,7 +816,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) } c = mrb_class(mrb, self); - m = mrb_method_search_vm(mrb, &c, name); + m = mrb_vm_find_method(mrb, c, &c, name); if (MRB_METHOD_UNDEF_P(m)) { /* call method_mising */ goto funcall; } @@ -729,13 +844,25 @@ mrb_f_send(mrb_state *mrb, mrb_value self) } if (MRB_METHOD_PROC_P(m)) { - mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m)); + const struct RProc *p = MRB_METHOD_PROC(m); + CI_PROC_SET(ci, p); } return MRB_METHOD_CFUNC(m)(mrb, self); } return exec_irep(mrb, self, MRB_METHOD_PROC(m)); } +static void +check_block(mrb_state *mrb, mrb_value blk) +{ + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + if (!mrb_proc_p(blk)) { + mrb_raise(mrb, E_TYPE_ERROR, "not a block"); + } +} + static mrb_value eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) { @@ -743,16 +870,14 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb_callinfo *ci; int nregs; - if (mrb_nil_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } + check_block(mrb, blk); ci = mrb->c->ci; 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_PROC_SET(ci, p); ci->n = 1; ci->nk = 0; ci->mid = ci[-1].mid; @@ -769,7 +894,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; stack_clear(mrb->c->ci->stack+2, nregs-2); - ci = cipush(mrb, 0, 0, NULL, NULL, 0, 0); + ci = cipush(mrb, 0, 0, NULL, NULL, NULL, 0, 0); return self; } @@ -836,39 +961,23 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value mrb_value val; mrb_int n; - if (mrb_nil_p(b)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } + check_block(mrb, b); ci = mrb->c->ci; n = mrb_ci_nregs(ci); p = mrb_proc_ptr(b); - ci = cipush(mrb, n, CINFO_SKIP, c, p, mid, 0 /* dummy */); - ci->nk = 0; - if (argc >= CALL_MAXARGS) { - ci->n = 15; - n = 3; - } - else { - ci->n = argc; - n = argc + 2; - } - mrb_stack_extend(mrb, n); - mrb->c->ci->stack[0] = self; - 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(); /* clear blk */ + ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, NULL, 0, 0); + funcall_args_capture(mrb, 0, argc, argv, mrb_nil_value(), ci); + ci->u.target_class = c; + ci->mid = mid; + ci->proc = p; if (MRB_PROC_CFUNC_P(p)) { - ci->cci = CINFO_DIRECT; + ci->stack[0] = self; val = MRB_PROC_CFUNC(p)(mrb, self); cipop(mrb); } else { + ci->cci = CINFO_SKIP; val = mrb_run(mrb, p, self); } return val; @@ -896,17 +1005,11 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const struct RProc *p; mrb_callinfo *ci; - if (mrb_nil_p(b)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - if (!mrb_proc_p(b)) { - mrb_raise(mrb, E_TYPE_ERROR, "not a block"); - } - + check_block(mrb, b); p = mrb_proc_ptr(b); ci = mrb->c->ci; - mrb_stack_extend(mrb, 4); + stack_extend_adjust(mrb, 4, &argv); mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); mrb->c->ci->stack[2] = mrb_nil_value(); mrb->c->ci->stack[3] = mrb_nil_value(); @@ -915,6 +1018,39 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const return exec_irep(mrb, self, p); } +#define RBREAK_TAG_FOREACH(f) \ + f(RBREAK_TAG_BREAK, 0) \ + f(RBREAK_TAG_BREAK_UPPER, 1) \ + f(RBREAK_TAG_BREAK_INTARGET, 2) \ + f(RBREAK_TAG_RETURN_BLOCK, 3) \ + f(RBREAK_TAG_RETURN, 4) \ + f(RBREAK_TAG_RETURN_TOPLEVEL, 5) \ + f(RBREAK_TAG_JUMP, 6) \ + f(RBREAK_TAG_STOP, 7) + +#define RBREAK_TAG_DEFINE(tag, i) tag = i, +enum { + RBREAK_TAG_FOREACH(RBREAK_TAG_DEFINE) +}; +#undef RBREAK_TAG_DEFINE + +#define RBREAK_TAG_BIT 3 +#define RBREAK_TAG_BIT_OFF 8 +#define RBREAK_TAG_MASK (~(~UINT32_C(0) << RBREAK_TAG_BIT)) + +static inline uint32_t +mrb_break_tag_get(struct RBreak *brk) +{ + return (brk->flags >> RBREAK_TAG_BIT_OFF) & RBREAK_TAG_MASK; +} + +static inline void +mrb_break_tag_set(struct RBreak *brk, uint32_t tag) +{ + brk->flags &= ~(RBREAK_TAG_MASK << RBREAK_TAG_BIT_OFF); + brk->flags |= (tag & RBREAK_TAG_MASK) << RBREAK_TAG_BIT_OFF; +} + static struct RBreak* break_new(mrb_state *mrb, uint32_t tag, const struct RProc *p, mrb_value val) { @@ -988,6 +1124,15 @@ localjump_error(mrb_state *mrb, localjump_error_kind kind) mrb_exc_set(mrb, exc); } +#define RAISE_EXC(mrb, exc) do { \ + mrb_value exc_value = (exc); \ + mrb_exc_set(mrb, exc_value); \ + goto L_RAISE; \ +} while (0) + +#define RAISE_LIT(mrb, c, str) RAISE_EXC(mrb, mrb_exc_new_lit(mrb, c, str)) +#define RAISE_FORMAT(mrb, c, fmt, ...) RAISE_EXC(mrb, mrb_exc_new_str(mrb, c, mrb_format(mrb, fmt, __VA_ARGS__))) + static void argnum_error(mrb_state *mrb, mrb_int num) { @@ -1124,6 +1269,13 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta } if (stack_keep > nregs) nregs = stack_keep; + else { + struct REnv *e = CI_ENV(mrb->c->ci); + if (stack_keep == 0 || (e && irep->nlocals < MRB_ENV_LEN(e))) { + mrb_vm_ci_env_set(mrb->c->ci, NULL); + mrb_env_unshare(mrb, e, FALSE); + } + } mrb_stack_extend(mrb, nregs); stack_clear(c->ci->stack + stack_keep, nregs - stack_keep); c->ci->stack[0] = self; @@ -1143,27 +1295,36 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta static struct RClass* check_target_class(mrb_state *mrb) { - struct RClass *target = mrb_vm_ci_target_class(mrb->c->ci); + struct RClass *target = 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); + mrb_raise(mrb, E_TYPE_ERROR, "no class/module to add method"); } return target; } +#define regs (mrb->c->ci->stack) + static mrb_value -hash_new_from_values(mrb_state *mrb, mrb_int argc, mrb_value *regs) +hash_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) { mrb_value hash = mrb_hash_new_capa(mrb, argc); while (argc--) { - mrb_hash_set(mrb, hash, regs[0], regs[1]); - regs += 2; + mrb_hash_set(mrb, hash, regs[idx+0], regs[idx+1]); + idx += 2; } return hash; } -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); +static mrb_value +ary_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) +{ + mrb_value ary = mrb_ary_new_capa(mrb, argc); + while (argc--) { + mrb_ary_push(mrb, ary, regs[idx]); + idx++; + } + return ary; +} MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) @@ -1203,9 +1364,8 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) goto L_RAISE; } mrb->jmp = &c_jmp; - mrb_vm_ci_proc_set(mrb->c->ci, proc); + CI_PROC_SET(mrb->c->ci, proc); -#define regs (mrb->c->ci->stack) INIT_DISPATCH { CASE(OP_NOP, Z) { /* do nothing */ @@ -1236,7 +1396,15 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) goto L_INT_OVERFLOW; #endif case IREP_TT_BIGINT: +#ifdef MRB_USE_BIGINT + { + const char *s = pool[b].u.str; + regs[a] = mrb_bint_new_str(mrb, s+2, (uint8_t)s[0], s[1]); + } + break; +#else goto L_INT_OVERFLOW; +#endif #ifndef MRB_NO_FLOAT case IREP_TT_FLOAT: regs[a] = mrb_float_value(mrb, pool[b].u.f); @@ -1523,14 +1691,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) case MRB_TT_MODULE: break; default: - { - mrb_value exc; - - exc = mrb_exc_new_lit(mrb, E_TYPE_ERROR, - "class or module required for rescue clause"); - mrb_exc_set(mrb, exc); - goto L_RAISE; - } + RAISE_LIT(mrb, E_TYPE_ERROR, "class or module required for rescue clause"); } ec = mrb_class_ptr(e); regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec)); @@ -1575,56 +1736,53 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mid = syms[b]; L_SENDB_SYM: { + mrb_callinfo *ci; + mrb_method_t m; + mrb_value recv, blk; 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_value recv; + mrb_int bidx = a + mrb_bidx(n,nk); - if (0 < nk && nk < 15) { /* pack keyword arguments */ - mrb_int kidx = a+(n==15?1:n)+1; - mrb_value kdict = hash_new_from_values(mrb, nk, regs+kidx); + if (nk == CALL_MAXARGS) { + mrb_ensure_hash_type(mrb, regs[a+(n==CALL_MAXARGS?1:n)+1]); + } + else if (nk > 0) { /* pack keyword arguments */ + mrb_int kidx = a+(n==CALL_MAXARGS?1:n)+1; + mrb_value kdict = hash_new_from_regs(mrb, nk, kidx); regs[kidx] = kdict; - nk = 15; + nk = CALL_MAXARGS; c = n | (nk<<4); } - mrb_assert(bidx < irep->nregs+a); - mrb_value blk; - mrb_int new_bidx = a+mrb_bidx(c); + mrb_assert(bidx < irep->nregs); + mrb_int new_bidx = a+mrb_bidx(n, nk); 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 */ - } + blk = ensure_block(mrb, regs[bidx]); regs[new_bidx] = blk; } - recv = regs[a]; - cls = mrb_class(mrb, recv); - m = mrb_method_search_vm(mrb, &cls, mid); + ci = cipush(mrb, a, CINFO_DIRECT, NULL, NULL, BLK_PTR(blk), 0, c); + recv = regs[0]; + ci->u.target_class = (insn == OP_SUPER) ? CI_TARGET_CLASS(ci - 1)->super : mrb_class(mrb, recv); + m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, mid); if (MRB_METHOD_UNDEF_P(m)) { - m = prepare_missing(mrb, recv, mid, &cls, a, &c, blk, 0); - mid = MRB_SYM(method_missing); + m = prepare_missing(mrb, ci, recv, mid, blk, (insn == OP_SUPER)); } - - /* push callinfo */ - ci = cipush(mrb, a, 0, cls, NULL, mid, c); + else { + ci->mid = mid; + } + ci->cci = CINFO_NONE; + if (!mrb_nil_p(blk)) ci->blk = mrb_proc_ptr(blk); if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); - - mrb_vm_ci_proc_set(ci, p); + CI_PROC_SET(ci, p); recv = p->body.func(mrb, recv); } else { @@ -1636,12 +1794,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; ci = mrb->c->ci; - if (mrb_proc_p(blk)) { - struct RProc *p = mrb_proc_ptr(blk); - if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) { - p->flags |= MRB_PROC_ORPHAN; - } - } if (!ci->u.target_class) { /* return from context modifying method (resume/yield) */ if (ci->cci == CINFO_RESUMED) { mrb->jmp = prev_jmp; @@ -1662,7 +1814,8 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } else { /* setup environment for calling method */ - mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m))); + proc = MRB_METHOD_PROC(m); + CI_PROC_SET(ci, proc); irep = proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1679,7 +1832,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) /* replace callinfo */ ci->u.target_class = MRB_PROC_TARGET_CLASS(m); - mrb_vm_ci_proc_set(ci, m); + CI_PROC_SET(ci, m); if (MRB_PROC_ENV_P(m)) { ci->mid = MRB_PROC_ENV(m)->mid; } @@ -1721,110 +1874,31 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_SUPER, BB) { - mrb_method_t m; - struct RClass *cls; mrb_callinfo *ci = mrb->c->ci; - mrb_int bidx = mrb_bidx(b)+a; - mrb_value recv, blk; + mrb_value recv; const struct RProc *p = ci->proc; - mrb_sym mid = ci->mid; - struct RClass* target_class = MRB_PROC_TARGET_CLASS(p); + struct RClass* target_class = CI_TARGET_CLASS(ci); + mid = ci->mid; if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */ mid = p->e.env->mid; /* restore old mid */ } - mrb_assert(bidx < irep->nregs); - - blk = regs[bidx]; - uint8_t nk = (b >> 4) & 0x0f; - if (nk > 0 && nk < CALL_MAXARGS) { /* pack keyword arguments */ - uint8_t n = b & 0x0f; - mrb_int kidx = a+(n==15?1:n)+1; - mrb_value kdict = hash_new_from_values(mrb, nk, regs+kidx); - regs[kidx] = kdict; - nk = 15; - b = n | (nk<<4); - bidx = kidx + 1; - regs[bidx] = blk; - } if (mid == 0 || !target_class) { - mrb_value exc = mrb_exc_new_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); - mrb_exc_set(mrb, exc); - goto L_RAISE; + RAISE_LIT(mrb, E_NOMETHOD_ERROR, "super called outside of method"); } if ((target_class->flags & MRB_FL_CLASS_IS_PREPENDED) || target_class->tt == MRB_TT_MODULE) { - target_class = mrb_vm_ci_target_class(ci); - if (!target_class || target_class->tt != MRB_TT_ICLASS) { - goto super_typeerror; - } + 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); - goto L_RAISE; - } - if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { - blk = mrb_type_convert(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc)); - /* The stack or ci stack might have been reallocated during - mrb_type_convert(), see #3622 and #3784 */ - regs[bidx] = blk; - ci = mrb->c->ci; - } - cls = target_class->super; - m = mrb_method_search_vm(mrb, &cls, mid); - if (MRB_METHOD_UNDEF_P(m)) { - m = prepare_missing(mrb, recv, mid, &cls, a, &b, blk, 1); - mid = MRB_SYM(method_missing); + super_typeerror: + RAISE_LIT(mrb, E_TYPE_ERROR, "self has wrong type to call super in this context"); } - /* push callinfo */ - ci = cipush(mrb, a, 0, cls, NULL, mid, b); - - /* prepare stack */ - ci->stack[0] = recv; - - if (MRB_METHOD_CFUNC_P(m)) { - mrb_value v; - - if (MRB_METHOD_PROC_P(m)) { - mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m)); - } - v = MRB_METHOD_CFUNC(m)(mrb, recv); - mrb_gc_arena_restore(mrb, ai); - if (mrb->exc) goto L_RAISE; - 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->cci == CINFO_RESUMED) { - mrb->jmp = prev_jmp; - return v; - } - else { - mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc)); - proc = ci[-1].proc; - irep = proc->body.irep; - pool = irep->pool; - syms = irep->syms; - } - } - mrb->c->ci->stack[0] = v; - ci = cipop(mrb); - pc = ci->pc; - } - else { - /* 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, (irep->nregs < 4) ? 4 : irep->nregs); - pc = irep->iseq; - } - JUMP; + c = b; // arg info + regs[a] = recv; + goto L_SENDB_SYM; } CASE(OP_ARGARY, BS) { @@ -1835,13 +1909,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_int lv = (b>>0)&0xf; mrb_value *stack; - if (mrb->c->ci->mid == 0 || mrb_vm_ci_target_class(mrb->c->ci) == NULL) { - mrb_value exc; - + if (mrb->c->ci->mid == 0 || CI_TARGET_CLASS(mrb->c->ci) == NULL) { L_NOSUPER: - exc = mrb_exc_new_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); - mrb_exc_set(mrb, exc); - goto L_RAISE; + RAISE_LIT(mrb, E_NOMETHOD_ERROR, "super called outside of method"); } if (lv == 0) stack = regs + 1; else { @@ -1890,7 +1960,26 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_ENTER, W) { + mrb_callinfo *ci = mrb->c->ci; + mrb_int argc = ci->n; + mrb_value *argv = regs+1; + mrb_int m1 = MRB_ASPEC_REQ(a); + + /* no other args */ + if ((a & ~0x7c0001) == 0 && argc < 15 && MRB_PROC_STRICT_P(proc)) { + if (argc != m1) { + argnum_error(mrb, m1); + goto L_RAISE; + } + /* clear local (but non-argument) variables */ + mrb_int pos = m1+2; /* self+m1+blk */ + if (irep->nlocals-pos > 0) { + stack_clear(®s[pos], irep->nlocals-pos); + } + NEXT; + } + mrb_int o = MRB_ASPEC_OPT(a); mrb_int r = MRB_ASPEC_REST(a); mrb_int m2 = MRB_ASPEC_POST(a); @@ -1900,41 +1989,34 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) */ 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 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(); /* 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]); + if (ci->nk == 15) { + kdict = regs[mrb_ci_kidx(ci)]; + } + if (!kd) { + if (!mrb_nil_p(kdict) && mrb_hash_size(mrb, kdict) > 0) { + if (argc < 14) { + ci->n++; + argc++; /* include kdict in normal arguments */ + } + else if (argc == 14) { + /* pack arguments and kdict */ + regs[1] = ary_new_from_regs(mrb, argc+1, 1); + argc = ci->n = 15; + } + else {/* argc == 15 */ + /* push kdict to packed arguments */ + mrb_ary_push(mrb, regs[1], kdict); + } } + kdict = mrb_nil_value(); ci->nk = 0; } - if (kd && MRB_ASPEC_KEY(a) > 0 && mrb_hash_p(kdict)) { + else if (MRB_ASPEC_KEY(a) > 0 && !mrb_nil_p(kdict)) { kdict = mrb_hash_dup(mrb, kdict); } @@ -1944,6 +2026,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) argv = ARY_PTR(ary); argc = (int)ARY_LEN(ary); mrb_gc_protect(mrb, regs[1]); + if (kd && !mrb_nil_p(kdict)) mrb_gc_protect(mrb, kdict); } /* strict argument check */ @@ -2008,15 +2091,18 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } /* need to be update blk first to protect blk from GC */ + mrb_int const kw_pos = len + kd; /* where kwhash should be */ + mrb_int const blk_pos = kw_pos + 1; /* where block should be */ 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 */ + ci->nk = 15; } /* format arguments for generated code */ - mrb->c->ci->n = len; + mrb->c->ci->n = (uint8_t)len; /* clear local (but non-argument) variables */ if (irep->nlocals-blk_pos-1 > 0) { @@ -2031,9 +2117,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_value kdict, v; 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; + RAISE_FORMAT(mrb, E_ARGUMENT_ERROR, "missing keyword: %v", k); } v = mrb_hash_get(mrb, kdict, k); regs[a] = v; @@ -2061,9 +2145,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) 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); - mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); - goto L_RAISE; + RAISE_FORMAT(mrb, E_ARGUMENT_ERROR, "unknown keyword: %v", key1); } NEXT; } @@ -2083,55 +2165,33 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_callinfo *ci; ci = mrb->c->ci; - if (ci->mid) { - mrb_value blk = regs[mrb_ci_bidx(ci)]; - - if (mrb_proc_p(blk)) { - struct RProc *p = mrb_proc_ptr(blk); - - if (!MRB_PROC_STRICT_P(p) && - ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) { - p->flags |= MRB_PROC_ORPHAN; - } - } - } - if (mrb->exc) { L_RAISE: ci = mrb->c->ci; - if (ci == mrb->c->cibase) { - ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL); - if (ch == NULL) goto L_FTOP; - goto L_CATCH; - } while ((ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL)) == NULL) { - ci = cipop(mrb); - if (ci[1].cci == CINFO_SKIP && prev_jmp) { - mrb->jmp = prev_jmp; - MRB_THROW(prev_jmp); + if (ci != mrb->c->cibase) { + ci = cipop(mrb); + if (ci[1].cci == CINFO_SKIP && prev_jmp) { + mrb->jmp = prev_jmp; + MRB_THROW(prev_jmp); + } + pc = ci[0].pc; } - pc = ci[0].pc; - if (ci == mrb->c->cibase) { - ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL); - if (ch == NULL) { - L_FTOP: /* fiber top */ - if (mrb->c == mrb->root_c) { - mrb->c->ci->stack = mrb->c->stbase; - goto L_STOP; - } - else { - struct mrb_context *c = mrb->c; + else if (mrb->c == mrb->root_c) { + mrb->c->ci->stack = mrb->c->stbase; + goto L_STOP; + } + else { + struct mrb_context *c = mrb->c; - c->status = MRB_FIBER_TERMINATED; - mrb->c = c->prev; - c->prev = NULL; - goto L_RAISE; - } - } - break; + c->status = MRB_FIBER_TERMINATED; + mrb->c = c->prev; + if (!mrb->c) mrb->c = mrb->root_c; + else c->prev = NULL; + goto L_RAISE; } } - L_CATCH: + if (ch == NULL) goto L_STOP; if (FALSE) { L_CATCH_TAGGED_BREAK: /* from THROW_TAGGED_BREAK() or UNWIND_ENSURE() */ @@ -2204,14 +2264,18 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) struct mrb_context *c; c = mrb->c; - if (!c->prev) { /* toplevel return */ - regs[irep->nlocals] = v; - goto CHECKPOINT_LABEL_MAKE(RBREAK_TAG_STOP); + if (!c->prev) { + if (c != mrb->root_c) { + /* fiber termination should transfer to root */ + c->prev = mrb->root_c; + } + else { /* toplevel return */ + regs[irep->nlocals] = v; + goto CHECKPOINT_LABEL_MAKE(RBREAK_TAG_STOP); + } } - if (!c->vmexec && c->prev->ci == c->prev->cibase) { - mrb_value exc = mrb_exc_new_lit(mrb, E_FIBER_ERROR, "double resume"); - mrb_exc_set(mrb, exc); - goto L_RAISE; + else if (!c->vmexec && c->prev->ci == c->prev->cibase) { + RAISE_LIT(mrb, E_FIBER_ERROR, "double resume"); } CHECKPOINT_RESTORE(RBREAK_TAG_RETURN_TOPLEVEL) { c = mrb->c; @@ -2245,13 +2309,8 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) case OP_R_BREAK: if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; if (MRB_PROC_ORPHAN_P(proc)) { - mrb_value exc; - L_BREAK_ERROR: - exc = mrb_exc_new_lit(mrb, E_LOCALJUMP_ERROR, - "break from proc-closure"); - mrb_exc_set(mrb, exc); - goto L_RAISE; + RAISE_LIT(mrb, E_LOCALJUMP_ERROR, "break from proc-closure"); } if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_ONSTACK_P(MRB_PROC_ENV(proc))) { goto L_BREAK_ERROR; @@ -2280,9 +2339,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } if (ci->cci > CINFO_NONE) { ci = cipop(mrb); + mrb->exc = (struct RObject*)break_new(mrb, RBREAK_TAG_BREAK, proc, v); mrb_gc_arena_restore(mrb, ai); mrb->c->vmexec = FALSE; - mrb->exc = (struct RObject*)break_new(mrb, RBREAK_TAG_BREAK, proc, v); mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } @@ -2336,7 +2395,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_assert(ci == mrb->c->ci); mrb_assert(mrb->exc == NULL); - if (mrb->c->vmexec && !mrb_vm_ci_target_class(ci)) { + if (mrb->c->vmexec && !CI_TARGET_CLASS(ci)) { mrb_gc_arena_restore(mrb, ai); mrb->c->vmexec = FALSE; mrb->jmp = prev_jmp; @@ -2388,12 +2447,10 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) NEXT; } +#if !defined(MRB_USE_BIGINT) || defined(MRB_INT32) L_INT_OVERFLOW: - { - mrb_value exc = mrb_exc_new_lit(mrb, E_RANGE_ERROR, "integer overflow"); - mrb_exc_set(mrb, exc); - } - goto L_RAISE; + RAISE_LIT(mrb, E_RANGE_ERROR, "integer overflow"); +#endif #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) #define OP_MATH(op_name) \ @@ -2413,8 +2470,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) case TYPES2(MRB_TT_INTEGER, MRB_TT_INTEGER): \ { \ mrb_int x = mrb_integer(regs[a]), y = mrb_integer(regs[a+1]), z; \ - if (mrb_int_##op_name##_overflow(x, y, &z)) \ - OP_MATH_OVERFLOW_INT(); \ + if (mrb_int_##op_name##_overflow(x, y, &z)) { \ + OP_MATH_OVERFLOW_INT(op_name,x,y); \ + } \ else \ SET_INT_VALUE(mrb,regs[a], z); \ } \ @@ -2430,7 +2488,11 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } \ break #endif -#define OP_MATH_OVERFLOW_INT() goto L_INT_OVERFLOW +#ifdef MRB_USE_BIGINT +#define OP_MATH_OVERFLOW_INT(op,x,y) regs[a] = mrb_bint_##op##_ii(mrb,x,y) +#else +#define OP_MATH_OVERFLOW_INT(op,x,y) goto L_INT_OVERFLOW +#endif #define OP_MATH_CASE_STRING_add() \ case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \ regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \ @@ -2467,8 +2529,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) { mrb_int x = mrb_integer(regs[a]); mrb_int y = mrb_integer(regs[a+1]); - mrb_int div = mrb_div_int(mrb, x, y); - SET_INT_VALUE(mrb, regs[a], div); + regs[a] = mrb_div_int_value(mrb, x, y); } NEXT; #ifndef MRB_NO_FLOAT @@ -2512,8 +2573,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) case MRB_TT_INTEGER: \ { \ mrb_int x = mrb_integer(regs[a]), y = (mrb_int)b, z; \ - if (mrb_int_##op_name##_overflow(x, y, &z)) \ - OP_MATH_OVERFLOW_INT(); \ + if (mrb_int_##op_name##_overflow(x, y, &z)) { \ + OP_MATH_OVERFLOW_INT(op_name,x,y); \ + } \ else \ SET_INT_VALUE(mrb,regs[a], z); \ } \ @@ -2620,12 +2682,12 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_ARRAY, BB) { - regs[a] = mrb_ary_new_from_values(mrb, b, ®s[a]); + regs[a] = ary_new_from_regs(mrb, b, a); mrb_gc_arena_restore(mrb, ai); NEXT; } CASE(OP_ARRAY2, BBB) { - regs[a] = mrb_ary_new_from_values(mrb, c, ®s[b]); + regs[a] = ary_new_from_regs(mrb, c, b); mrb_gc_arena_restore(mrb, ai); NEXT; } @@ -2636,7 +2698,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) regs[a] = splat; } else { - mrb_assert(mrb_type(regs[a]) == MRB_TT_ARRAY); + mrb_assert(mrb_array_p(regs[a])); mrb_ary_concat(mrb, regs[a], splat); } mrb_gc_arena_restore(mrb, ai); @@ -2644,22 +2706,17 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_ARYPUSH, BB) { - mrb_assert(mrb_type(regs[a]) == MRB_TT_ARRAY); + mrb_assert(mrb_array_p(regs[a])); for (mrb_int i=0; i> 2; @@ -2760,6 +2817,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_STRCAT, B) { + mrb_assert(mrb_string_p(regs[a])); mrb_str_concat(mrb, regs[a], regs[a+1]); NEXT; } @@ -2793,7 +2851,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) CASE(OP_HASHCAT, B) { mrb_value hash = regs[a]; - mrb_ensure_hash_type(mrb, hash); + mrb_assert(mrb_hash_p(hash)); mrb_hash_merge(mrb, hash, regs[a+1]); mrb_gc_arena_restore(mrb, ai); NEXT; @@ -2895,7 +2953,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) p->flags |= MRB_PROC_SCOPE; /* prepare call stack */ - cipush(mrb, a, 0, mrb_class_ptr(recv), p, 0, 0); + cipush(mrb, a, 0, mrb_class_ptr(recv), p, NULL, 0, 0); irep = p->body.irep; pool = irep->pool; @@ -2969,8 +3027,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_assert((pool[a].tt&IREP_TT_NFLAG)==0); exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, pool[a].u.str, len); - mrb_exc_set(mrb, exc); - goto L_RAISE; + RAISE_EXC(mrb, exc); } CASE(OP_EXT1, Z) { @@ -2994,7 +3051,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) NEXT; } CASE(OP_EXT3, Z) { - uint8_t insn = READ_B(); + 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" @@ -3052,21 +3109,14 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st return mrb_vm_run(mrb, proc, self, stack_keep); } if (mrb->c->ci == mrb->c->cibase) { - mrb_vm_ci_env_set(mrb->c->ci, NULL); return mrb_vm_run(mrb, proc, self, stack_keep); } - cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, 0, 0); + cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, NULL, 0, 0); v = mrb_vm_run(mrb, proc, self, stack_keep); return v; } #if defined(MRB_USE_CXX_EXCEPTION) && defined(__cplusplus) -# if !defined(MRB_USE_CXX_ABI) -} /* end of extern "C" */ -# endif -mrb_int mrb_jmpbuf::jmpbuf_id = 0; -# if !defined(MRB_USE_CXX_ABI) -extern "C" { -# endif +mrb_int mrb_jmpbuf_id = 0; #endif diff --git a/mruby/tasks/benchmark.rake b/mruby/tasks/benchmark.rake index 12e0d460..9b40f9b1 100644 --- a/mruby/tasks/benchmark.rake +++ b/mruby/tasks/benchmark.rake @@ -9,11 +9,8 @@ def bm_files end def build_config_name - if !ENV['MRUBY_CONFIG'].to_s.empty? - File.basename(ENV['MRUBY_CONFIG'], '.rb').gsub('build_config_', '') - else - "bm" - end + path = MRuby::Build.mruby_config_path + File.basename(path, '.rb').gsub('build_config_', '') end def plot_file @@ -21,6 +18,8 @@ def plot_file end def plot + raise "no build target to benchmark against" if $dat_files.empty? + opts_file = "#{MRUBY_ROOT}/benchmark/plot.gpl" opts = File.read(opts_file).each_line.to_a.map(&:strip).join(';') @@ -46,11 +45,13 @@ def plot p.puts "e" end end + + puts "Benchmark results output to #{plot_file}" end MRuby.each_target do |target| - next if target.name == 'host' || target.internal? + next if !target.benchmark_enabled? || target.internal? mruby_bin = "#{target.build_dir}/bin/mruby" bm_files.each do |bm_file| @@ -86,6 +87,7 @@ file plot_file => $dat_files do plot end +desc "run benchmark tests" task :benchmark => plot_file do plot end diff --git a/mruby/tasks/doc.rake b/mruby/tasks/doc.rake index 8a9108f1..50dc3618 100644 --- a/mruby/tasks/doc.rake +++ b/mruby/tasks/doc.rake @@ -1,3 +1,5 @@ +MRuby.autoload :Documentation, 'mruby/doc' + desc 'generate document' task :doc => %w[doc:api doc:capi] @@ -9,6 +11,9 @@ namespace :doc do rescue puts "ERROR: To generate yard documentation, you should install yard-mruby gem." puts " $ gem install yard-mruby yard-coderay" + puts "https://yardoc.org/" + puts "https://rubygems.org/gems/yard-mruby" + puts "https://rubygems.org/gems/yard-coderay" end end @@ -17,11 +22,15 @@ namespace :doc do begin sh "doxygen Doxyfile" rescue - puts "ERROR: To generate C API documents, you need Doxygen." + puts "ERROR: To generate C API documents, you need Doxygen and Graphviz." puts "On Debian-based systems:" - puts " $ sudo apt-get install doxygen" + puts " $ sudo apt-get install doxygen graphviz" puts "On RHEL-based systems:" - puts " $ sudo dnf install doxygen" + puts " $ sudo dnf install doxygen graphviz" + puts "On macOS-based systems:" + puts " $ brew install doxygen graphviz" + puts "https://www.doxygen.nl/" + puts "https://graphviz.org/" end end @@ -43,14 +52,34 @@ namespace :doc do namespace :view do desc 'open yard docs' task :api do - sh 'xdg-open doc/api/index.html' + if RUBY_PLATFORM.include?('darwin') + sh 'open doc/api/index.html' + else + sh 'xdg-open doc/api/index.html' + end end desc 'open doxygen docs' task :capi do - sh 'xdg-open doc/capi/html/index.html' + if RUBY_PLATFORM.include?('darwin') + sh 'open doc/capi/html/index.html' + else + sh 'xdg-open doc/capi/html/index.html' + end end end + + desc 'update doc/internal/opcode.md' + task 'update-opcode.md' do + unless system(*%W(git --git-dir #{MRUBY_ROOT}/.git --work-tree #{MRUBY_ROOT} diff --quiet @ -- doc/internal/opcode.md)) + abort <<~'ERRMESG' + The file "doc/internal/opcode.md" has been modified but not committed. + To avoid loss of your edits, the automatic update process has been aborted. + ERRMESG + end + + MRuby::Documentation.update_opcode_md + end end # deprecated diff --git a/mruby/tasks/mrbgems.rake b/mruby/tasks/mrbgems.rake index 4f24cfd9..1e6b0319 100644 --- a/mruby/tasks/mrbgems.rake +++ b/mruby/tasks/mrbgems.rake @@ -54,6 +54,7 @@ MRuby.each_target do end file active_gems_txt => :generate_active_gems_txt + desc "generate the active gems text files" task :generate_active_gems_txt do |t| def t.timestamp; Time.at(0) end active_gems = gems.sort_by(&:name).inject(""){|s, g| s << "#{g.name}\n"} diff --git a/mruby/tasks/toolchains/android.rake b/mruby/tasks/toolchains/android.rake index 48526bc4..6e4648e6 100644 --- a/mruby/tasks/toolchains/android.rake +++ b/mruby/tasks/toolchains/android.rake @@ -1,3 +1,5 @@ +require "json" + class MRuby::Toolchain::Android DEFAULT_ARCH = 'armeabi' # TODO : Revise if arch should have a default @@ -32,28 +34,6 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter end end - class PlatformDirNotFound < StandardError - def message - <<-EOM -Couldn't find Android NDK platform directories. -Set ANDROID_PLATFORM environment variable or set :platform parameter - EOM - end - end - - class SysrootNotReady < StandardError - def message - <<-EOM -Couldn't find standard header files -Please Move/Copy important file inside - /sysroot/usr/include/ -to - /platforms///usr/include/ -Higher NDK version will be use. - EOM - end - end - attr_reader :params def initialize(params) @@ -92,7 +72,7 @@ Higher NDK version will be use. next nil unless path[-1] == "*" dirs = Dir.glob(path).collect do |d| m = d.match(/(\d+)\.(\d+)\.(\d+)$/) - m ? [m[1], m[2], m[3]].collect { |v| v.to_i } : nil + m ? [m[1], m[2], m[3]].collect(&:to_i) : nil end dirs.compact! dirs.sort! do |before, after| @@ -178,54 +158,6 @@ Higher NDK version will be use. @arch ||= (params[:arch] || ENV['ANDROID_ARCH'] || DEFAULT_ARCH).to_s end - def sysroot - return @sysroot if @sysroot - sysroot_path = home_path.join('platforms', platform, - case arch - when /armeabi/ then 'arch-arm' - when /arm64-v8a/ then 'arch-arm64' - when /x86_64/ then 'arch-x86_64' - when /x86/ then 'arch-x86' - when /mips64/ then 'arch-mips64' - when /mips/ then 'arch-mips' - end - ).to_s - if Dir.exist?(File.join(sysroot_path, "usr", "include")) - return @sysroot = sysroot_path - else - raise(SysrootNotReady) - end - end - - def platform - if @platform === nil then - @platform = params[:platform] || ENV['ANDROID_PLATFORM'] || nil - if @platform === nil - Dir.glob(home_path.join('platforms/android-*').to_s){ |item| - next if File.file?(item) - if @platform === nil - @platform = Integer(item.rpartition('-')[2]) - else - platform = Integer(item.rpartition('-')[2]) - @platform = platform > @platform ? platform : @platform - end - } - if @platform === nil - raise(PlatformDirNotFound) - else - @platform = "android-#{@platform}" - end - end - end - if Integer(@platform.rpartition('-')[2]) < 21 - case arch - when /arm64-v8a/, /x86_64/, /mips64/ - raise NotImplementedError, "Platform (#{@platform}) has no implementation for architecture (#{arch})" - end - end - @platform - end - def armeabi_v7a_mfpu @armeabi_v7a_mfpu ||= (params[:mfpu] || 'vfpv3-d16').to_s end @@ -234,6 +166,19 @@ Higher NDK version will be use. @armeabi_v7a_mfloat_abi ||= (params[:mfloat_abi] || 'softfp').to_s end + def sdk_version + @sdk_version ||= params[:sdk_version] + if !@sdk_version then + # Higher SDK version will be used. + json = nil + File.open(home_path + "meta/platforms.json") do |f| + json = JSON.load(f) + end + @sdk_version = json["max"] + end + @sdk_version + end + def no_warn_mismatch if %W(soft softfp).include? armeabi_v7a_mfloat_abi '' @@ -259,6 +204,7 @@ Higher NDK version will be use. def ctarget flags = [] + v = sdk_version case toolchain when :gcc case arch @@ -272,13 +218,13 @@ Higher NDK version will be use. end when :clang case arch - when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi) - when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi) - when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android) - when /x86_64/ then flags += %W(-target x86_64-none-linux-android) - when /x86/ then flags += %W(-target i686-none-linux-android) - when /mips64/ then flags += %W(-target mips64el-none-linux-android) - when /mips/ then flags += %W(-target mipsel-none-linux-android) + when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi#{v}) + when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi#{v}) + when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android#{v}) + when /x86_64/ then flags += %W(-target x86_64-none-linux-android#{v}) + when /x86/ then flags += %W(-target i686-none-linux-android#{v}) + when /mips64/ then flags += %W(-target mips64el-none-linux-android#{v}) + when /mips/ then flags += %W(-target mipsel-none-linux-android#{v}) end end @@ -304,7 +250,7 @@ Higher NDK version will be use. flags += %W(-U_WIN32 -U_WIN64) end - flags += %W(-MMD -MP -D__android__ -DANDROID --sysroot="#{sysroot}") + flags += %W(-MMD -MP -D__android__ -DANDROID) flags += ctarget case toolchain when :gcc @@ -319,14 +265,13 @@ Higher NDK version will be use. def ldflags flags = [] - flags += %W(--sysroot="#{sysroot}") - flags end def ldflags_before_libraries flags = [] + v = sdk_version case toolchain when :gcc case arch @@ -335,13 +280,13 @@ Higher NDK version will be use. when :clang flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}") case arch - when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi -Wl,--fix-cortex-a8#{no_warn_mismatch}) - when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi) - when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android) - when /x86_64/ then flags += %W(-target x86_64-none-linux-android) - when /x86/ then flags += %W(-target i686-none-linux-android) - when /mips64/ then flags += %W(-target mips64el-none-linux-android) - when /mips/ then flags += %W(-target mipsel-none-linux-android) + when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi#{v} -Wl,--fix-cortex-a8#{no_warn_mismatch}) + when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi#{v}) + when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android#{v}) + when /x86_64/ then flags += %W(-target x86_64-none-linux-android#{v}) + when /x86/ then flags += %W(-target i686-none-linux-android#{v}) + when /mips64/ then flags += %W(-target mips64el-none-linux-android#{v}) + when /mips/ then flags += %W(-target mipsel-none-linux-android#{v}) end end flags += %W(-no-canonical-prefixes) diff --git a/mruby/tasks/toolchains/gcc.rake b/mruby/tasks/toolchains/gcc.rake index 51bda651..aa1cf777 100644 --- a/mruby/tasks/toolchains/gcc.rake +++ b/mruby/tasks/toolchains/gcc.rake @@ -25,7 +25,11 @@ MRuby::Toolchain.new(:gcc) do |conf, params| conf.linker do |linker| linker.command = ENV['LD'] || ENV['CXX'] || ENV['CC'] || default_command linker.flags = [ENV['LDFLAGS'] || %w()] - linker.libraries = %w(m) + if ENV['OS'] == 'Windows_NT' + linker.libraries = [] + else + linker.libraries = %w(m) + end linker.library_paths = [] linker.option_library = '-l%s' linker.option_library_path = '-L%s' diff --git a/mruby/test/assert.rb b/mruby/test/assert.rb index 8cd2b375..7563099e 100644 --- a/mruby/test/assert.rb +++ b/mruby/test/assert.rb @@ -4,7 +4,7 @@ $kill_test = 0 $warning_test = 0 $skip_test = 0 -$asserts = [] +$asserts = [] $test_start = Time.now if Object.const_defined?(:Time) # For bintest on Ruby @@ -257,7 +257,7 @@ def _assert_operator(affirmed, obj1, op, obj2 = $undefined, msg = nil) # Matches any one character. # # [_SET_], [^_SET_] ([!_SET_]) :: -# Matches any one character in _SET_. Behaves like character sets in +# Matches any one character in _SET_. Behaves like character sets in # Regexp, including set negation ([^a-z]). # # {_A_,_B_} :: diff --git a/mruby/test/bintest.rb b/mruby/test/bintest.rb index 773d61ed..5d995ff8 100644 --- a/mruby/test/bintest.rb +++ b/mruby/test/bintest.rb @@ -19,11 +19,11 @@ def cmd_list(s) end def cmd(s) - return cmd_list(s).join(' ') + cmd_list(s).join(' ') end def cmd_bin(s) - return cmd_list(s).pop + cmd_list(s).pop end def shellquote(s) @@ -44,7 +44,7 @@ def shellquote(s) case RbConfig::CONFIG['host_os'] when /mswin(?!ce)|mingw|bccwin/ - gem = gem.gsub('\\', '/') + gem = gem.tr('\\', '/') end Dir["#{gem}/bintest/**/*.rb"].each do |file| diff --git a/mruby/test/t/array.rb b/mruby/test/t/array.rb index 5f26259f..eccb435e 100644 --- a/mruby/test/t/array.rb +++ b/mruby/test/t/array.rb @@ -32,6 +32,8 @@ class SubArray < Array end assert_equal([1, 1, 1], [1].*(3)) assert_equal([], [1].*(0)) + assert_equal('abc', ['a', 'b', 'c'].*('')) + assert_equal('0, 0, 1, {:foo=>0}', [0, [0, 1], {foo: 0}].*(', ')) end assert('Array#<<', '15.2.12.5.3') do diff --git a/mruby/test/t/bs_block.rb b/mruby/test/t/bs_block.rb index f4e4da37..c37d1b53 100644 --- a/mruby/test/t/bs_block.rb +++ b/mruby/test/t/bs_block.rb @@ -374,7 +374,7 @@ def m end assert('BS Block [ruby-dev:31160]') do - def m() + def m yield end assert_nil m {|(v,(*))|} @@ -389,7 +389,7 @@ def m(a, *b) end assert('BS Block 31') do - def m() + def m yield end assert_nil m {|((*))|} diff --git a/mruby/test/t/comparable.rb b/mruby/test/t/comparable.rb index 2ee28de7..08d1f308 100644 --- a/mruby/test/t/comparable.rb +++ b/mruby/test/t/comparable.rb @@ -1,4 +1,3 @@ - assert('Comparable#<', '15.3.3.2.1') do class Foo include Comparable diff --git a/mruby/test/t/hash.rb b/mruby/test/t/hash.rb index 1b4db056..9ff066b8 100644 --- a/mruby/test/t/hash.rb +++ b/mruby/test/t/hash.rb @@ -676,6 +676,11 @@ def h.default(k); self[k] = 1; end h1, h2 = entries1.hash_for, entries2.hash_for k2.callback = ->(name, *){h2.clear if name == :hash} assert_nothing_crashed{h1.merge(h2)} + + # single arguments + assert_equal({a:1,b:2}, {a:1}.merge({b:2})) + # multiple arguments + assert_equal({a:1,b:2,c:3}, {a:1}.merge({b:2},{c:3})) end end diff --git a/mruby/test/t/integer.rb b/mruby/test/t/integer.rb index d4076f38..64028638 100644 --- a/mruby/test/t/integer.rb +++ b/mruby/test/t/integer.rb @@ -40,15 +40,26 @@ assert_equal 2, a a = 5/2 assert_equal 2, a + b = -1/2 + assert_equal(-1, b) + b = 1/-2 + assert_equal(-1, b) skip unless Object.const_defined?(:Float) b = 2/1.0 assert_equal 2.0, b end -assert('Integer#quo') do - a = 6.quo(5) - assert_equal 1.2, a -end if Object.const_defined?(:Float) +if Object.const_defined?(:Rational) + assert('Integer#quo') do + a = 6.quo(5) + assert_equal 5/6r, a + end +elsif Object.const_defined?(:Float) + assert('Integer#quo') do + a = 6.quo(5) + assert_equal 1.2, a + end +end assert('Integer#%', '15.2.8.3.5') do a = 1%1 @@ -57,7 +68,7 @@ d = 2%-5 e = -2%5 f = -2%-5 - g = 2%-2 + g = 2%-2 h = -2%2 i = -2%-2 diff --git a/mruby/test/t/lang.rb b/mruby/test/t/lang.rb index 4ed1b3da..1f83bafe 100755 --- a/mruby/test/t/lang.rb +++ b/mruby/test/t/lang.rb @@ -1,4 +1,4 @@ -# The aim of these tests is to detect pitfall for optimized VM. +# The aim of these tests is to detect pitfall for optimized VM. # Test for or/and # diff --git a/mruby/test/t/module.rb b/mruby/test/t/module.rb index 9aa01828..c18276a9 100644 --- a/mruby/test/t/module.rb +++ b/mruby/test/t/module.rb @@ -356,16 +356,16 @@ module Test4Included2 assert('Module#method_defined?', '15.2.2.4.34') do module Test4MethodDefined module A - def method1() end + def method1() end end class B - def method2() end + def method2() end end class C < B include A - def method3() end + def method3() end end end @@ -686,7 +686,7 @@ class << self # assert_nothing_raised(SystemStackError, bug10847) do # 0.3.numerator # end - # end; + # end #end assert 'Module#prepend to frozen class' do @@ -729,14 +729,14 @@ module Test4to_sModules assert('Issue 1467') do module M1 - def initialize() + def initialize super() end end class C1 include M1 - def initialize() + def initialize super() end end diff --git a/mruby/test/t/string.rb b/mruby/test/t/string.rb index 44749322..11b5cae0 100644 --- a/mruby/test/t/string.rb +++ b/mruby/test/t/string.rb @@ -1,4 +1,3 @@ -# coding: utf-8 ## # String ISO Test @@ -507,8 +506,8 @@ b = 'abc' * 10 c = ('cba' * 10).dup - b.replace(c); - c.replace(b); + b.replace(c) + c.replace(b) assert_equal c, b # shared string diff --git a/mruby/test/t/syntax.rb b/mruby/test/t/syntax.rb index 87edfb27..7de86113 100644 --- a/mruby/test/t/syntax.rb +++ b/mruby/test/t/syntax.rb @@ -531,9 +531,9 @@ def m(a = b = 1, &c) [a, b, c ? true : nil] end this is a comment that has extra after =begin and =end with spaces after it =end line = __LINE__ -=begin this is a comment +=begin this is a comment this is a comment that has extra after =begin and =end with tabs after it -=end xxxxxxxxxxxxxxxxxxxxxxxxxx +=end xxxxxxxxxxxxxxxxxxxxxxxxxx assert_equal(line + 4, __LINE__) end From db210dd617c9bc394e9a9ec8b615ded695b50d47 Mon Sep 17 00:00:00 2001 From: pyama Date: Wed, 20 Sep 2023 13:35:26 +0900 Subject: [PATCH 2/7] some methods move to internal.h --- src/http/ngx_http_mruby_async.c | 1 + src/http/ngx_http_mruby_core.c | 1 + src/stream/ngx_stream_mruby_async.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/http/ngx_http_mruby_async.c b/src/http/ngx_http_mruby_async.c index e2bcbb6d..e895f30d 100644 --- a/src/http/ngx_http_mruby_async.c +++ b/src/http/ngx_http_mruby_async.c @@ -21,6 +21,7 @@ #include #include #include +#include typedef struct { mrb_state *mrb; diff --git a/src/http/ngx_http_mruby_core.c b/src/http/ngx_http_mruby_core.c index aae5f410..0c007078 100644 --- a/src/http/ngx_http_mruby_core.c +++ b/src/http/ngx_http_mruby_core.c @@ -12,6 +12,7 @@ #include "mruby/array.h" #include "mruby/string.h" #include "mruby/variable.h" +#include "mruby/internal.h" #if (NGX_DEBUG) static void ngx_mrb_log_backtrace(mrb_state *mrb, mrb_value obj, ngx_log_t *log) diff --git a/src/stream/ngx_stream_mruby_async.c b/src/stream/ngx_stream_mruby_async.c index 457a5ad2..83162dc9 100644 --- a/src/stream/ngx_stream_mruby_async.c +++ b/src/stream/ngx_stream_mruby_async.c @@ -12,6 +12,7 @@ #include #include #include +#include "mruby/internal.h" typedef struct { mrb_state *mrb; From abb1f618c8c0a06c2e2c7052f46849f8a9e64222 Mon Sep 17 00:00:00 2001 From: pyama Date: Wed, 20 Sep 2023 13:36:03 +0900 Subject: [PATCH 3/7] rename --- src/http/ngx_http_mruby_async.c | 2 +- src/stream/ngx_stream_mruby_async.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/http/ngx_http_mruby_async.c b/src/http/ngx_http_mruby_async.c index e895f30d..3daf942c 100644 --- a/src/http/ngx_http_mruby_async.c +++ b/src/http/ngx_http_mruby_async.c @@ -77,7 +77,7 @@ mrb_value ngx_mrb_run_fiber(mrb_state *mrb, mrb_value *fiber_proc, mrb_value *re } if (!mrb_array_p(resume_result)) { - mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit( + mrb->exc = mrb_obj_ptr(mrb_exc_new_lit( mrb, E_RUNTIME_ERROR, "_ngx_mrb_prepare_fiber proc must return array included handler_return and fiber alive status")); return mrb_false_value(); diff --git a/src/stream/ngx_stream_mruby_async.c b/src/stream/ngx_stream_mruby_async.c index 83162dc9..14289eb3 100644 --- a/src/stream/ngx_stream_mruby_async.c +++ b/src/stream/ngx_stream_mruby_async.c @@ -41,7 +41,7 @@ static mrb_value ngx_stream_mrb_run_fiber(mrb_state *mrb, mrb_value *fiber_proc, } if (!mrb_array_p(resume_result)) { - mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit( + mrb->exc = mrb_obj_ptr(mrb_exc_new_lit( mrb, E_RUNTIME_ERROR, "_ngx_mrb_prepare_fiber proc must return array included handler_return and fiber alive status")); return mrb_false_value(); From 2c97f0d909dec444751d278e1d3a7c4476d48df4 Mon Sep 17 00:00:00 2001 From: pyama Date: Mon, 25 Sep 2023 01:23:18 +0900 Subject: [PATCH 4/7] Fiber workaround does not work in mruby 3.2 ref: https://github.com/mruby/mruby/issues/6060 --- mruby/mrbgems/mruby-fiber/src/fiber.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mruby/mrbgems/mruby-fiber/src/fiber.c b/mruby/mrbgems/mruby-fiber/src/fiber.c index 33913c10..75ffa906 100644 --- a/mruby/mrbgems/mruby-fiber/src/fiber.c +++ b/mruby/mrbgems/mruby-fiber/src/fiber.c @@ -302,7 +302,6 @@ fiber_resume(mrb_state *mrb, mrb_value self) mrb_int len; mrb_bool vmexec = FALSE; - fiber_check_cfunc(mrb, mrb->c); mrb_get_args(mrb, "*!", &a, &len); if (mrb->c->ci->cci > 0) { vmexec = TRUE; From 1215ad238158a80d5d19f2f0170abee9a6c1174d Mon Sep 17 00:00:00 2001 From: pyama Date: Mon, 25 Sep 2023 01:41:40 +0900 Subject: [PATCH 5/7] string length limit change to 10MB(from 1MB) --- build_config.rb | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/build_config.rb b/build_config.rb index ebc9eb7f..790dbc4d 100644 --- a/build_config.rb +++ b/build_config.rb @@ -1,9 +1,9 @@ MRuby::Build.new('host') do |conf| - toolchain :gcc + conf.defines << 'MRB_STR_LENGTH_MAX=10485760' conf.gembox 'full-core' - + enable_debug conf.cc do |cc| cc.flags << ENV['NGX_MRUBY_CFLAGS'] if ENV['NGX_MRUBY_CFLAGS'] end @@ -16,19 +16,19 @@ # # Recommended for ngx_mruby # - conf.gem :github => 'iij/mruby-env' - conf.gem :github => 'iij/mruby-dir' - conf.gem :github => 'iij/mruby-digest' - conf.gem :github => 'iij/mruby-process' - conf.gem :github => 'mattn/mruby-json' - conf.gem :github => 'mattn/mruby-onig-regexp' - conf.gem :github => 'matsumotory/mruby-redis' - conf.gem :github => 'matsumotory/mruby-vedis' - conf.gem :github => 'matsumotory/mruby-userdata' - conf.gem :github => 'matsumotory/mruby-uname' - conf.gem :github => 'matsumotory/mruby-mutex' - conf.gem :github => 'matsumotory/mruby-localmemcache' - conf.gem :mgem => 'mruby-secure-random' + conf.gem github: 'iij/mruby-env' + conf.gem github: 'iij/mruby-dir' + conf.gem github: 'iij/mruby-digest' + conf.gem github: 'iij/mruby-process' + conf.gem github: 'mattn/mruby-json' + conf.gem github: 'mattn/mruby-onig-regexp' + conf.gem github: 'matsumotory/mruby-redis' + conf.gem github: 'matsumotory/mruby-vedis' + conf.gem github: 'matsumotory/mruby-userdata' + conf.gem github: 'matsumotory/mruby-uname' + conf.gem github: 'matsumotory/mruby-mutex' + conf.gem github: 'matsumotory/mruby-localmemcache' + conf.gem mgem: 'mruby-secure-random' # ngx_mruby extended class conf.gem './mrbgems/ngx_mruby_mrblib' @@ -45,7 +45,7 @@ # conf.gem :github => 'matsumotory/mruby-discount' # use mysql on ngx_mruby - #conf.gem :github => 'mattn/mruby-mysql' + # conf.gem :github => 'mattn/mruby-mysql' # have GeoIPCity.dat # conf.gem :github => 'matsumotory/mruby-geoip' @@ -53,12 +53,12 @@ # Linux only for ngx_mruby # conf.gem :github => 'matsumotory/mruby-capability' # conf.gem :github => 'matsumotory/mruby-cgroup' - end MRuby::Build.new('test') do |conf| # load specific toolchain settings + conf.defines << 'MRB_STR_LENGTH_MAX=10485760' # Gets set by the VS command prompts. if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR'] toolchain :visualcpp @@ -68,13 +68,13 @@ enable_debug - conf.gem :github => 'matsumotory/mruby-simplehttp' - conf.gem :github => 'matsumotory/mruby-httprequest' - conf.gem :github => 'matsumotory/mruby-uname' - conf.gem :github => 'matsumotory/mruby-simpletest' - conf.gem :github => 'mattn/mruby-http' - conf.gem :github => 'mattn/mruby-json' - conf.gem :github => 'iij/mruby-env' + conf.gem github: 'matsumotory/mruby-simplehttp' + conf.gem github: 'matsumotory/mruby-httprequest' + conf.gem github: 'matsumotory/mruby-uname' + conf.gem github: 'matsumotory/mruby-simpletest' + conf.gem github: 'mattn/mruby-http' + conf.gem github: 'mattn/mruby-json' + conf.gem github: 'iij/mruby-env' # include the default GEMs conf.gembox 'full-core' From 2de908b475dd2fa425c02c9dbe69439850fb0e51 Mon Sep 17 00:00:00 2001 From: pyama Date: Mon, 25 Sep 2023 18:06:21 +0900 Subject: [PATCH 6/7] disable GC --- build_config.rb | 2 +- mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build_config.rb b/build_config.rb index 790dbc4d..ae9f5037 100644 --- a/build_config.rb +++ b/build_config.rb @@ -3,7 +3,7 @@ conf.defines << 'MRB_STR_LENGTH_MAX=10485760' conf.gembox 'full-core' - enable_debug + conf.cc do |cc| cc.flags << ENV['NGX_MRUBY_CFLAGS'] if ENV['NGX_MRUBY_CFLAGS'] end diff --git a/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb b/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb index b32b3f8c..3ee0f4a4 100644 --- a/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb +++ b/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb @@ -132,8 +132,10 @@ def _ngx_mrb_prepare_fiber(nginx_handler) fiber_handler = Fiber.new { nginx_handler.call } lambda do + GC.disable # BUG?: return nginx_handler directly from fiber, not proc in any case. result = fiber_handler.resume + GC.enable [fiber_handler.alive?, result] end end From 863a06340537795c38722f9281a81ad6ae9cbf17 Mon Sep 17 00:00:00 2001 From: pyama Date: Mon, 25 Sep 2023 22:44:12 +0900 Subject: [PATCH 7/7] use mruby master --- mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb | 50 +- mruby/.dockerignore | 14 + mruby/.editorconfig | 26 +- mruby/.gitattributes | 4 + mruby/.github/dependabot.yml | 7 +- mruby/.github/labeler.yml | 29 + mruby/.github/linters/.markdown-lint.yml | 6 + mruby/.github/workflows/build.yml | 6 +- mruby/.github/workflows/codeql-analysis.yml | 53 - mruby/.github/workflows/labeler.yml | 15 + mruby/.github/workflows/lint.yml | 15 +- mruby/.github/workflows/oss-fuzz.yml | 1 + mruby/.github/workflows/super-linter.yml | 7 +- mruby/.gitignore | 24 +- mruby/.pre-commit-config.yaml | 19 +- mruby/AUTHORS | 21 +- mruby/CONTRIBUTING.md | 84 +- mruby/Dockerfile | 17 + mruby/Doxyfile | 965 ++++++--- mruby/Gemfile | 8 + mruby/Gemfile.lock | 27 + mruby/Makefile | 12 + mruby/NEWS | 1 - mruby/README.md | 63 +- mruby/Rakefile | 50 +- mruby/appveyor.yml | 5 +- mruby/benchmark/bm_ao_render.rb | 7 +- mruby/build_config/android_arm64_v8a.rb | 4 +- mruby/build_config/android_armeabi.rb | 11 - .../android_armeabi_v7a_neon_hard.rb | 4 +- mruby/build_config/dreamcast_shelf.rb | 1 - mruby/build_config/i586-pc-msdosdjgpp.rb | 77 + mruby/codespell.txt | 10 +- mruby/doc/guides/compile.md | 58 +- mruby/doc/guides/debugger.md | 2 +- mruby/doc/guides/gc-arena-howto.md | 7 +- mruby/doc/guides/link.md | 4 +- mruby/doc/guides/mrbconf.md | 8 +- mruby/doc/guides/mrbgems.md | 27 +- mruby/doc/limitations.md | 34 +- mruby/doc/mruby3.0.md | 2 +- mruby/doc/mruby3.2.md | 7 +- mruby/docker-compose.yml | 13 + .../cdata_extension_example/src/example.c | 4 +- .../mrbgems/mruby-YOUR-bigint/TODO-HINT.md | 12 +- mruby/include/mrbconf.h | 4 +- mruby/include/mruby.h | 43 +- mruby/include/mruby/class.h | 22 +- mruby/include/mruby/common.h | 2 +- mruby/include/mruby/compile.h | 2 +- mruby/include/mruby/data.h | 4 +- mruby/include/mruby/debug.h | 10 +- mruby/include/mruby/endian.h | 2 +- mruby/include/mruby/error.h | 15 +- mruby/include/mruby/gc.h | 51 +- mruby/include/mruby/internal.h | 36 +- mruby/include/mruby/khash.h | 8 +- mruby/include/mruby/proc.h | 35 + mruby/include/mruby/value.h | 6 +- mruby/lib/mruby/build.rb | 67 +- mruby/lib/mruby/build/command.rb | 16 +- mruby/lib/mruby/core_ext.rb | 21 + mruby/lib/mruby/gem.rb | 31 +- mruby/lib/mruby/presym.rb | 40 +- mruby/mrbgems/default.gembox | 3 + mruby/mrbgems/mruby-array-ext/src/array.c | 39 +- mruby/mrbgems/mruby-bigint/core/bigint.c | 229 ++- mruby/mrbgems/mruby-bin-config/mrbgem.rake | 18 +- mruby/mrbgems/mruby-bin-config/mruby-config | 16 +- .../mrbgems/mruby-bin-config/mruby-config.bat | 52 +- mruby/mrbgems/mruby-bin-debugger/mrbgem.rake | 2 +- .../mruby-bin-debugger/tools/mrdb/apibreak.c | 14 +- .../mruby-bin-debugger/tools/mrdb/apibreak.h | 26 +- .../mruby-bin-debugger/tools/mrdb/apilist.c | 2 +- .../mruby-bin-debugger/tools/mrdb/apilist.h | 4 +- .../mruby-bin-debugger/tools/mrdb/apiprint.c | 6 +- .../mruby-bin-debugger/tools/mrdb/cmdbreak.c | 12 +- .../mruby-bin-debugger/tools/mrdb/cmdmisc.c | 12 +- .../mruby-bin-debugger/tools/mrdb/cmdrun.c | 2 +- .../mruby-bin-debugger/tools/mrdb/mrdb.c | 22 +- .../mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 9 +- .../mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c | 7 +- .../mruby-bin-mruby/tools/mruby/mruby.c | 8 +- mruby/mrbgems/mruby-bin-strip/mrbgem.rake | 1 + mruby/mrbgems/mruby-binding-core/mrbgem.rake | 7 - .../mruby-binding-core/src/binding-core.c | 309 --- .../mruby-binding-core/test/binding-core.rb | 40 - mruby/mrbgems/mruby-binding/mrbgem.rake | 6 +- mruby/mrbgems/mruby-binding/src/binding.c | 475 +++-- mruby/mrbgems/mruby-binding/test/binding.rb | 66 +- mruby/mrbgems/mruby-catch/src/catch.c | 45 +- mruby/mrbgems/mruby-class-ext/src/class.c | 22 +- mruby/mrbgems/mruby-cmath/src/cmath.c | 6 +- .../mrbgems/mruby-compar-ext/mrblib/compar.rb | 11 +- mruby/mrbgems/mruby-compiler/core/codegen.c | 2 +- mruby/mrbgems/mruby-compiler/core/parse.y | 113 +- mruby/mrbgems/mruby-compiler/core/y.tab.c | 1764 +++++++++-------- mruby/mrbgems/mruby-complex/src/complex.c | 11 +- mruby/mrbgems/mruby-data/src/data.c | 120 +- mruby/mrbgems/mruby-dir/README.md | 2 +- mruby/mrbgems/mruby-dir/mrbgem.rake | 2 +- mruby/mrbgems/mruby-dir/src/Win/dirent.c | 44 +- mruby/mrbgems/mruby-dir/src/dir.c | 17 +- .../mruby-enumerator/mrblib/enumerator.rb | 2 +- mruby/mrbgems/mruby-errno/src/errno.c | 9 +- mruby/mrbgems/mruby-eval/mrbgem.rake | 3 + mruby/mrbgems/mruby-eval/src/eval.c | 148 +- mruby/mrbgems/mruby-eval/test/binding.rb | 64 + mruby/mrbgems/mruby-exit/src/mruby-exit.c | 2 +- mruby/mrbgems/mruby-fiber/src/fiber.c | 21 +- mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb | 19 +- mruby/mrbgems/mruby-hash-ext/test/hash.rb | 4 +- mruby/mrbgems/mruby-io/README.md | 8 +- mruby/mrbgems/mruby-io/mrblib/file.rb | 16 +- mruby/mrbgems/mruby-io/src/file.c | 70 +- mruby/mrbgems/mruby-io/src/file_test.c | 7 +- mruby/mrbgems/mruby-io/src/io.c | 60 +- mruby/mrbgems/mruby-io/test/file.rb | 26 + mruby/mrbgems/mruby-io/test/io.rb | 13 +- mruby/mrbgems/mruby-io/test/mruby_io_test.c | 5 +- mruby/mrbgems/mruby-math/src/math.c | 101 +- mruby/mrbgems/mruby-metaprog/src/metaprog.c | 9 +- mruby/mrbgems/mruby-method/mrblib/kernel.rb | 10 - mruby/mrbgems/mruby-method/src/method.c | 144 +- .../mruby-numeric-ext/src/numeric_ext.c | 59 +- mruby/mrbgems/mruby-object-ext/src/object.c | 8 +- mruby/mrbgems/mruby-os-memsize/src/memsize.c | 35 +- mruby/mrbgems/mruby-pack/README.md | 4 + mruby/mrbgems/mruby-pack/src/pack.c | 264 ++- mruby/mrbgems/mruby-pack/test/pack.rb | 10 + mruby/mrbgems/mruby-print/mrblib/print.rb | 30 +- mruby/mrbgems/mruby-print/src/print.c | 32 +- mruby/mrbgems/mruby-proc-binding/mrbgem.rake | 4 +- .../mruby-proc-binding/src/proc-binding.c | 11 +- mruby/mrbgems/mruby-proc-ext/src/proc.c | 43 +- mruby/mrbgems/mruby-proc-ext/test/proc.rb | 4 +- mruby/mrbgems/mruby-random/src/random.c | 3 +- mruby/mrbgems/mruby-range-ext/mrblib/range.rb | 8 + mruby/mrbgems/mruby-range-ext/test/range.rb | 34 + mruby/mrbgems/mruby-rational/src/rational.c | 10 +- mruby/mrbgems/mruby-set/mrblib/set.rb | 10 +- mruby/mrbgems/mruby-sleep/src/sleep.c | 14 +- mruby/mrbgems/mruby-socket/README.md | 4 +- mruby/mrbgems/mruby-socket/mrbgem.rake | 4 +- mruby/mrbgems/mruby-socket/mrblib/socket.rb | 57 +- mruby/mrbgems/mruby-socket/src/socket.c | 376 +++- mruby/mrbgems/mruby-sprintf/src/sprintf.c | 11 +- .../mrbgems/mruby-string-ext/mrblib/string.rb | 7 +- mruby/mrbgems/mruby-string-ext/src/string.c | 196 +- mruby/mrbgems/mruby-struct/mrblib/struct.rb | 29 - mruby/mrbgems/mruby-struct/src/struct.c | 193 +- mruby/mrbgems/mruby-struct/test/struct.rb | 2 +- .../mruby-test-inline-struct/test/inline.c | 3 +- mruby/mrbgems/mruby-test/driver.c | 2 +- mruby/mrbgems/mruby-test/mrbgem.rake | 74 +- mruby/mrbgems/mruby-time/mrblib/time.rb | 9 - mruby/mrbgems/mruby-time/src/time.c | 370 ++-- mruby/mrblib/array.rb | 21 - mruby/mrblib/compar.rb | 2 +- mruby/mrblib/hash.rb | 26 +- mruby/mrblib/kernel.rb | 5 - mruby/mrblib/numeric.rb | 2 +- mruby/oss-fuzz/mruby_proto_fuzzer.cpp | 2 +- mruby/src/array.c | 81 +- mruby/src/backtrace.c | 221 +-- mruby/src/cdump.c | 16 +- mruby/src/class.c | 135 +- mruby/src/codedump.c | 35 +- mruby/src/debug.c | 119 +- mruby/src/dump.c | 20 +- mruby/src/error.c | 125 +- mruby/src/etc.c | 2 +- mruby/src/fmt_fp.c | 39 +- mruby/src/gc.c | 247 +-- mruby/src/hash.c | 92 +- mruby/src/kernel.c | 83 +- mruby/src/load.c | 24 +- mruby/src/numeric.c | 140 +- mruby/src/object.c | 19 +- mruby/src/pool.c | 4 +- mruby/src/proc.c | 64 +- mruby/src/range.c | 18 +- mruby/src/readfloat.c | 2 +- mruby/src/state.c | 6 +- mruby/src/string.c | 131 +- mruby/src/symbol.c | 12 +- mruby/src/variable.c | 107 +- mruby/src/vm.c | 256 +-- mruby/super-linter.report/.keep | 0 mruby/tasks/doc.rake | 2 +- mruby/tasks/install.rake | 33 + mruby/tasks/libmruby.rake | 77 +- mruby/tasks/mrbgems.rake | 71 +- mruby/tasks/toolchains/android.rake | 104 +- mruby/tasks/toolchains/gcc.rake | 4 + mruby/test/t/bs_block.rb | 2 +- mruby/test/t/class.rb | 2 +- mruby/test/t/codegen.rb | 11 +- mruby/test/t/float.rb | 2 +- mruby/test/t/hash.rb | 11 - mruby/test/t/string.rb | 69 + mruby/test/t/syntax.rb | 1 + 202 files changed, 6421 insertions(+), 4467 deletions(-) create mode 100644 mruby/.dockerignore create mode 100644 mruby/.gitattributes create mode 100644 mruby/.github/labeler.yml delete mode 100644 mruby/.github/workflows/codeql-analysis.yml create mode 100644 mruby/.github/workflows/labeler.yml create mode 100644 mruby/Dockerfile create mode 100644 mruby/Gemfile create mode 100644 mruby/Gemfile.lock delete mode 100644 mruby/build_config/android_armeabi.rb create mode 100644 mruby/build_config/i586-pc-msdosdjgpp.rb create mode 100644 mruby/docker-compose.yml delete mode 100644 mruby/mrbgems/mruby-binding-core/mrbgem.rake delete mode 100644 mruby/mrbgems/mruby-binding-core/src/binding-core.c delete mode 100644 mruby/mrbgems/mruby-binding-core/test/binding-core.rb create mode 100644 mruby/mrbgems/mruby-eval/test/binding.rb delete mode 100644 mruby/mrbgems/mruby-method/mrblib/kernel.rb delete mode 100644 mruby/mrbgems/mruby-time/mrblib/time.rb delete mode 100644 mruby/super-linter.report/.keep create mode 100644 mruby/tasks/install.rake diff --git a/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb b/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb index 3ee0f4a4..c0f8156a 100644 --- a/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb +++ b/mrbgems/ngx_mruby_mrblib/mrblib/mrb_nginx.rb @@ -1,7 +1,7 @@ class Nginx class Request def scheme - self.var.scheme + var.scheme end def document_root @@ -14,32 +14,33 @@ def read_body end def body - self.get_body + get_body end def uri_args - args_to_hash(self.args) + args_to_hash(args) end def uri_args=(params) raise ArgumentError unless params.is_a?(Hash) - self.args = params.map{|k,v| "#{k}=#{v}"}.join("&") + + self.args = params.map { |k, v| "#{k}=#{v}" }.join('&') end def post_args - args_to_hash(self.body) + args_to_hash(body) end private def args_to_hash(args) - Hash[*args.split("&").map{|arg| arg.split("=", 2)}.flatten] + Hash[*args.split('&').map { |arg| arg.split('=', 2) }.flatten] end end class Headers_in def user_agent - self["User-Agent"] + self['User-Agent'] end end @@ -50,32 +51,32 @@ def self.var class Utils class << self def encode_parameters(params, delimiter = '&', quote = nil) - if params.is_a?(Hash) - params = params.map do |key, value| - sprintf("%s=%s%s%s", escape(key), quote, escape(value), quote) - end - else - params = params.map { |value| escape(value) } - end + params = if params.is_a?(Hash) + params.map do |key, value| + format('%s=%s%s%s', escape(key), quote, escape(value), quote) + end + else + params.map { |value| escape(value) } + end delimiter ? params.join(delimiter) : params end def escape(str) reserved_str = [ - "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "n", "m", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "-", ".", "_", "~" + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '-', '.', '_', '~' ] tmp = '' str = str.to_s str.size.times do |idx| chr = str[idx] - if reserved_str.include?(chr) - tmp += chr - else - tmp += "%" + chr.unpack("H*").first.upcase - end + tmp += if reserved_str.include?(chr) + chr + else + '%' + chr.unpack1('H*').upcase + end end tmp end @@ -122,7 +123,6 @@ class Response end end - module Kernel def get_server_class Nginx @@ -132,10 +132,8 @@ def _ngx_mrb_prepare_fiber(nginx_handler) fiber_handler = Fiber.new { nginx_handler.call } lambda do - GC.disable # BUG?: return nginx_handler directly from fiber, not proc in any case. result = fiber_handler.resume - GC.enable [fiber_handler.alive?, result] end end diff --git a/mruby/.dockerignore b/mruby/.dockerignore new file mode 100644 index 00000000..627d921e --- /dev/null +++ b/mruby/.dockerignore @@ -0,0 +1,14 @@ +.DS_Store +.idea +.vscode +*.bak +*.iml +*.ipr +*.swp +*.tmp + +/.yardoc +/bin +/build +/doc/api +/doc/capi diff --git a/mruby/.editorconfig b/mruby/.editorconfig index f966739f..a5145bad 100644 --- a/mruby/.editorconfig +++ b/mruby/.editorconfig @@ -8,37 +8,27 @@ root = true [*] charset = utf-8 end_of_line = lf -indent_size = 8 -indent_style = tab +indent_size = 2 +indent_style = space insert_final_newline = true tab_width = 8 +trim_trailing_whitespace = true [{Makefile,Makefile.*,makefile,*.mk}] -trim_trailing_whitespace = true +indent_style = tab #max_line_length = 80 -[*.{c,cc,C,cxx,cpp,h,hh,H,hxx,hpp,inc,y}] -indent_size = 2 -indent_style = space -trim_trailing_whitespace = true +#[*.{c,cc,C,cxx,cpp,h,hh,H,hxx,hpp,inc,y}] #max_line_length = 120 -[{*.rb,Rakefile,rakefile,*.rake,*.gemspec,*.gembox}] -indent_size = 2 -indent_style = space -trim_trailing_whitespace = true +#[{*.rb,Rakefile,rakefile,*.rake,*.gemspec,*.gembox}] #max_line_length = 120 # limitation to US-ASCII [*.bat] end_of_line = crlf -indent_style = space #max_line_length = 80 -[*.{yaml,yml}] -indent_size = 2 -indent_style = space +#[*.{yaml,yml}] -[*.md] -indent_size = 2 -indent_style = space +#[*.md] diff --git a/mruby/.gitattributes b/mruby/.gitattributes new file mode 100644 index 00000000..0f776312 --- /dev/null +++ b/mruby/.gitattributes @@ -0,0 +1,4 @@ +* text=auto eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.png binary diff --git a/mruby/.github/dependabot.yml b/mruby/.github/dependabot.yml index dac4cac3..ff902ec0 100644 --- a/mruby/.github/dependabot.yml +++ b/mruby/.github/dependabot.yml @@ -1,8 +1,11 @@ # Basic set up - version: 2 updates: - + # Maintain dependencies for Ruby + - package-ecosystem: "bundler" + directory: "/" + schedule: + interval: "daily" # Maintain dependencies for GitHub Actions - package-ecosystem: "github-actions" directory: "/" diff --git a/mruby/.github/labeler.yml b/mruby/.github/labeler.yml new file mode 100644 index 00000000..b4f73b78 --- /dev/null +++ b/mruby/.github/labeler.yml @@ -0,0 +1,29 @@ +benchmark: + - benchmark/**/* +build: + - Makefile + - Rakefile + - build_config/**/* + - lib/**/* + - tasks/**/* +core: + - include/**/* + - mrblib/**/* + - src/**/* + - test/**/* +doc: + - CONTRIBUTING.md + - LEGAL + - LICENSE + - NEWS + - README.md + - SECURITY.md + - TODO.md + - doc/**/* + - examples/**/* +github: + - .github/**/* +mrbgems: + - mrbgems/**/* +oss-fuzz: + - oss-fuzz/**/* diff --git a/mruby/.github/linters/.markdown-lint.yml b/mruby/.github/linters/.markdown-lint.yml index 5c6cbec4..f6c3cdd2 100644 --- a/mruby/.github/linters/.markdown-lint.yml +++ b/mruby/.github/linters/.markdown-lint.yml @@ -19,5 +19,11 @@ MD025: false # MD026 no-trailing-punctuation - Trailing punctuation in heading MD026: false +# MD033/no-inline-html - Inline HTML +MD033: false + # MD040 fenced-code-language - Fenced code blocks should have a language specified MD040: false + +# MD041 first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: false diff --git a/mruby/.github/workflows/build.yml b/mruby/.github/workflows/build.yml index ec82c0de..c0a7024e 100644 --- a/mruby/.github/workflows/build.yml +++ b/mruby/.github/workflows/build.yml @@ -27,7 +27,8 @@ jobs: CXX: ${{ matrix.cxx }} LD: ${{ matrix.cc }} steps: - - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 - name: Ruby version run: ruby -v - name: Compiler version @@ -41,7 +42,8 @@ jobs: env: MRUBY_CONFIG: ci/msvc steps: - - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 - name: Ruby version run: ruby -v - name: Build and test diff --git a/mruby/.github/workflows/codeql-analysis.yml b/mruby/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 10117d54..00000000 --- a/mruby/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Code scanning - action - -on: - push: - branches-ignore: - - dependabot/** - pull_request: - schedule: - - cron: '0 19 * * 4' - -permissions: - contents: read - -jobs: - CodeQL-Build: - permissions: - actions: read # for github/codeql-action/init to get workflow details - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/autobuild to send a status report - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - # Override language selection by uncommenting this and choosing your languages - # with: - # languages: go, javascript, csharp, python, cpp, java - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - # - run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/mruby/.github/workflows/labeler.yml b/mruby/.github/workflows/labeler.yml new file mode 100644 index 00000000..f85abb12 --- /dev/null +++ b/mruby/.github/workflows/labeler.yml @@ -0,0 +1,15 @@ +# https://github.com/actions/labeler +name: Pull Request Labeler +on: + - pull_request_target +jobs: + triage: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + sync-labels: true diff --git a/mruby/.github/workflows/lint.yml b/mruby/.github/workflows/lint.yml index c31b7411..b95005f2 100644 --- a/mruby/.github/workflows/lint.yml +++ b/mruby/.github/workflows/lint.yml @@ -1,3 +1,4 @@ +# https://pre-commit.com/ name: Lint on: [pull_request] @@ -6,22 +7,12 @@ permissions: contents: read jobs: - misspell: - name: Check spelling with misspell - runs-on: ubuntu-latest - steps: - - name: Check Out - uses: actions/checkout@v3 - - name: Install - run: wget -O - -q https://git.io/misspell | sh -s -- -b . - - name: Run misspell - run: git ls-files --empty-directory | xargs ./misspell -error pre-commit: name: Run pre-commit runs-on: ubuntu-latest steps: - - name: Check Out - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 - name: Install run: | python -m pip install --upgrade pip diff --git a/mruby/.github/workflows/oss-fuzz.yml b/mruby/.github/workflows/oss-fuzz.yml index 414c750e..72d40cf9 100644 --- a/mruby/.github/workflows/oss-fuzz.yml +++ b/mruby/.github/workflows/oss-fuzz.yml @@ -1,3 +1,4 @@ +# https://github.com/google/oss-fuzz name: CIFuzz on: [pull_request] permissions: diff --git a/mruby/.github/workflows/super-linter.yml b/mruby/.github/workflows/super-linter.yml index 538ccf07..fd577722 100644 --- a/mruby/.github/workflows/super-linter.yml +++ b/mruby/.github/workflows/super-linter.yml @@ -1,3 +1,4 @@ +# https://github.com/super-linter/super-linter name: Super-Linter on: [pull_request] @@ -13,13 +14,13 @@ jobs: name: Lint Code Base runs-on: ubuntu-latest steps: - - name: Checkout Code - uses: actions/checkout@v3 + - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" + uses: actions/checkout@v4 with: # Full git history is needed to get a proper list of changed files within `super-linter` fetch-depth: 0 - name: Lint Code Base - uses: github/super-linter/slim@v4.10.1 + uses: super-linter/super-linter/slim@v5.3.1 env: ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true diff --git a/mruby/.gitignore b/mruby/.gitignore index 6a0e7e46..eb5b5ddf 100644 --- a/mruby/.gitignore +++ b/mruby/.gitignore @@ -1,8 +1,8 @@ -*.lock *.bak *.bc *.d *.i +*.lock *.o *.orig *.pdb @@ -13,25 +13,23 @@ *.tmp *~ .DS_Store +.ccls* .ccmalloc .svn .vscode .yardoc -.ccls* -compile_flags.txt -compile_commands.json -cscope.files -cscope.out -tags - /.git -/bin -/build -/mruby-source-*.gem - /benchmark/**/*.dat /benchmark/*.pdf /benchmark/*.png - +/bin +/build /doc/api /doc/capi +/mruby-source-*.gem +compile_commands.json +compile_flags.txt +cscope.files +cscope.out +tags +!Gemfile.lock diff --git a/mruby/.pre-commit-config.yaml b/mruby/.pre-commit-config.yaml index 4c7bc52e..48e353b7 100644 --- a/mruby/.pre-commit-config.yaml +++ b/mruby/.pre-commit-config.yaml @@ -23,12 +23,14 @@ repos: - id: detect-private-key - id: end-of-file-fixer - id: file-contents-sorter + args: [--unique] files: ^codespell\.txt$ - id: fix-byte-order-marker + - id: forbid-submodules - id: mixed-line-ending - id: trailing-whitespace - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.3.1 + rev: v1.5.1 hooks: - id: forbid-tabs exclude: Makefile$|Makefile\..+$|makefile$|\.mk$ @@ -36,7 +38,7 @@ repos: args: [--whitespaces-count, '2'] exclude: Makefile$|Makefile\..+$|makefile$|\.mk$ - repo: https://github.com/codespell-project/codespell - rev: v2.2.2 + rev: v2.2.5 hooks: - id: codespell name: Run codespell @@ -49,7 +51,7 @@ repos: name: Local policy is to exclude extension from all shell files types: [shell] - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.33.0 + rev: v0.35.0 hooks: - id: markdownlint name: Run markdownlint @@ -57,8 +59,17 @@ repos: entry: markdownlint -c .github/linters/.markdown-lint.yml . types: [markdown] files: \.(md|mdown|markdown)$ + - repo: https://github.com/tcort/markdown-link-check + rev: v3.11.2 + hooks: + - id: markdown-link-check + name: Run markdown-link-check + description: Checks hyperlinks in Markdown files + args: [-q] + types: [markdown] + files: \.(md|mdown|markdown)$ - repo: https://github.com/adrienverge/yamllint - rev: v1.28.0 + rev: v1.32.0 hooks: - id: yamllint name: Run yamllint diff --git a/mruby/AUTHORS b/mruby/AUTHORS index fce97efc..6483ddc5 100644 --- a/mruby/AUTHORS +++ b/mruby/AUTHORS @@ -1,10 +1,10 @@ # Authors of mruby (mruby developers) -## The List of Contributors sorted by number of commits (as of 2022-01-08 4462e3d) +## The List of Contributors sorted by number of commits (as of 2023-08-26 b85b682) - 8860 Yukihiro "Matz" Matsumoto (@matz)* + 9287 Yukihiro "Matz" Matsumoto (@matz)* 586 KOBAYASHI Shuji (@shuujii) - 441 dearblue (@dearblue)* + 494 dearblue (@dearblue)* 378 Daniel Bovensiepen (@bovi)* 346 Takeshi Watanabe (@take-cheeze)* 334 Masaki Muranaka (@monaka) @@ -12,15 +12,15 @@ 234 Jun Hiroe (@suzukaze) 220 Cremno (@cremno)* 209 Yuki Kurihara (@ksss)+ + 159 John Bampton (@jbampton) 151 Yasuhiro Matsumoto (@mattn)* 113 Carson McDonald (@carsonmcdonald) - 113 John Bampton (@jbampton) 103 Tomasz Dąbrowski (@dabroz)* 84 Akira Yumiyama (@akiray03)* 84 skandhas (@skandhas) + 81 Hiroshi Mimaki (@mimaki)* 80 Masamitsu MURASE (@masamitsu-murase) 74 Yuichiro MASUI (@masuidrive) - 73 Hiroshi Mimaki (@mimaki)* 71 Tatsuhiko Kubo (@cubicdaiya)* 65 Yuichiro Kaneko (@yui-knk)+ 64 Paolo Bosetti (@pbosetti)* @@ -63,6 +63,7 @@ 12 Kouki Ooyatsu (kaishuu0123)* 12 NAKAMURA Usaku (@unak)* 12 RIZAL Reckordp (@Reckordp)+ + 12 Ray Chason (@chasonr)* 12 Takashi Sawanaka (@sdottaka)* 12 Ukrainskiy Sergey (@ukrainskiysergey) 12 Xuejie "Rafael" Xiao (@xxuejie)* @@ -73,7 +74,6 @@ 11 takkaw (@takkaw) 10 Miura Hideki (@miura1729) 10 Narihiro Nakamura (@authorNari) - 10 Ray Chason (@chasonr)* 10 Yuichi Nishiwaki (@nyuichi) 9 Akira Mitsui (@murasesyuka)* 9 Frank Celler (@fceller) @@ -96,6 +96,7 @@ 6 Kenji Okimoto (@okkez)+ 6 Selman ULUG (@selman) 6 Yusuke Endoh (@mame)* + 6 masahino (@masahino) 5 Chris Reuter (@suetanvil) 5 Davide D'Agostino (@DAddYE) 5 Eric Hodel (@drbrain) @@ -109,7 +110,6 @@ 5 TOMITA Masahiro (@tmtm) 5 Yurie Yamane (@yurie)+ 5 dreamedge (@dreamedge) - 5 masahino (@masahino) 5 nkshigeru (@nkshigeru) 5 xuejianqing (@joans321) 4 Dante Catalfamo (@dantecatalfamo) @@ -137,10 +137,12 @@ 3 Jan Berdajs (@mrbrdo) 3 Jonas Minnberg (@sasq64) 3 Joseph McCullough (@joequery) + 3 Lanza (@LanzaSchneider) 3 Mark McCurry (@fundamental) 3 Nobuhiro Iwamatsu (@iwamatsu) 3 Per Lundberg (@perlun)* 3 Rob Fors (@robfors)* + 3 Robert Rowe (@CaptainJet) 3 Sebastián Katzer (@katzer)* 3 Shouji Kuboyama (@Shokuji)* 3 Shuta Kimura (@kimushu)+ @@ -173,7 +175,6 @@ 2 Kazuhiko Yamashita (@pyama86)+ 2 Kazuhiro Sera (@seratch) 2 Kuroda Daisuke (@dycoon)+ - 2 Lanza (@LanzaSchneider) 2 Lothar Scholz (@llothar) 2 Lukas Joeressen (@kext) 2 Masahiro Wakame (@vvkame)+ @@ -196,11 +197,13 @@ 1 A-Sat (@asatou)+ 1 Abinoam Praxedes Marques Junior (@abinoam) 1 Alex Wang (@nanamiwang)+ + 1 AlexDenisov (@AlexDenisov) 1 Andrew Nordman (@cadwallion) 1 Ashish Kurmi (@boahc077) 1 Atsushi Morimoto (@mynz) 1 Ben A Morgan (@BenMorganIO) 1 Benoit Daloze (@eregon) + 1 Colin MacKenzie IV (@sinisterchipmunk) 1 Daehyub Kim (@lateau) 1 Daniel Varga (@vargad) 1 Edgar Boda-Majer (@eboda) @@ -257,7 +260,6 @@ 1 Prayag Verma (@pra85) 1 Ranmocy (@ranmocy) 1 Robert McNally (@wolfmcnally) - 1 Robert Rowe (@CaptainJet) 1 Ryan Scott Lewis (@RyanScottLewis) 1 Ryo Okubo (@syucream) 1 SAkira a.k.a. Akira Suzuki (@sakisakira) @@ -285,6 +287,7 @@ 1 Yurii Nakonechnyi (@inobelar) 1 Yusuke Suzuki (@Constellation)+ 1 Yusuke Tanaka (@csouls) + 1 alpha.netzilla (@alpha-netzilla) 1 arton (@arton) 1 duangsuse (@duangsuse) 1 fl0l0u (@fl0l0u) diff --git a/mruby/CONTRIBUTING.md b/mruby/CONTRIBUTING.md index 61d67312..a797b137 100644 --- a/mruby/CONTRIBUTING.md +++ b/mruby/CONTRIBUTING.md @@ -26,8 +26,8 @@ A framework for managing and maintaining multi-language `pre-commit` hooks. 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). -Use `pre-commit run --all-files` to check all files. +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 ` @@ -37,12 +37,16 @@ Sometimes you might need to skip one or more hooks which can be done with the `S `$ SKIP=yamllint git commit -m "foo"` -For convenience, we have added `pre-commit run --all-files` and `pre-commit autoupdate` +For convenience, we have added `pre-commit run --all-files`, `pre-commit install` and `pre-commit autoupdate` to both the Makefile and the Rakefile. Run them with: - `make check` or `rake check` +- `make checkinstall` or `rake checkinstall` - `make checkupdate` or `rake checkupdate` +To configure `pre-commit` you can modify the config file [.pre-commit-config.yaml](.pre-commit-config.yaml). +We use [GitHub Actions](.github/workflows/lint.yml) to run `pre-commit` on every pull request. + ### pre-commit quick links - [Quick start](https://pre-commit.com/#quick-start) @@ -50,21 +54,73 @@ to both the Makefile and the Rakefile. Run them with: - [pre-commit autoupdate](https://pre-commit.com/#pre-commit-autoupdate) - [Temporarily disabling hooks](https://pre-commit.com/#temporarily-disabling-hooks) -## Spell Checking +## Docker + +We have both a `Dockerfile` and `docker-compose.yml` files in the repository root. +You can run these with the command line or use +[Docker Desktop](https://www.docker.com/products/docker-desktop/). + +The Docker image is running Debian bullseye with Ruby and Python installed. +You can build the Docker image with: + +`$ docker-compose build test` + +So far we just have one service: `test`. Running the default `docker-compose` +command will create the Docker image, spin up a container and then build and +run all mruby tests. -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: +The default `docker-compose` command is: -```bash -find . -type f | xargs ./misspell -error +`$ docker-compose -p mruby run test` + +You can also use Make or Rake to run the default `docker-compose` +command from above: + +- `make composetest` +- `rake composetest` + +List your Docker images with: + +```console +$ docker images +REPOSITORY TAG IMAGE ID CREATED SIZE +mruby-test latest ec60f9536948 29 seconds ago 1.29GB ``` -Notable `misspell` help options or flags are: +You can also run any custom `docker-compose` command which will override +the default. For example to run `pre-commit run --all-files` type: + +`$ docker-compose -p mruby run test pre-commit run --all-files` + +For convenience, you can also run `pre-commit` with: + +- `make composecheck` +- `rake composecheck` + +The bonus of running `pre-commit` with `docker-compose` is that you won't need +to install `pre-commit` and the hooks on your local machine. And that also +means you won't need to install `brew`, `conda` or `pip`. + +Note limitation: currently running `pre-commit` with `docker-compose` we +skip the `check-executables-have-shebangs` hook. + +Two more examples of custom `docker-compose` commands are: + +- `$ docker-compose -p mruby run test ls` +- `$ docker-compose -p mruby run test rake doc:api` + +If you want to test using a different `docker-compose` YAML config file you +can use the `-f` flag: + +`$ docker-compose -p mruby -f docker-compose.test.yml run test` + +- +- + +## Spell Checking -- `-i` string: ignore the following corrections, comma separated -- `-w`: Overwrite file with corrections (default is just to display) +We are using `pre-commit` to run [codespell](https://github.com/codespell-project/codespell) +to check code for common misspellings. We have a small custom dictionary file [codespell.txt](codespell.txt). ## Coding conventions @@ -120,7 +176,7 @@ unless there's a clear reason, e.g. the latest Ruby has changed behavior from IS ### mruby API - [YARD](https://yardoc.org/) - YARD is a documentation generation tool for the Ruby programming language -- [yard-mruby](https://rubygems.org/gems/yard-mruby) - Document MRuby sources with YARD +- [yard-mruby](https://rubygems.org/gems/yard-mruby) - Document mruby sources with YARD - [yard-coderay](https://rubygems.org/gems/yard-coderay) - Adds coderay syntax highlighting to YARD docs ### C API diff --git a/mruby/Dockerfile b/mruby/Dockerfile new file mode 100644 index 00000000..f6699562 --- /dev/null +++ b/mruby/Dockerfile @@ -0,0 +1,17 @@ +FROM ruby:3.2.2-bullseye + +RUN apt-get update && apt-get install --no-install-recommends -y python3-pip shellcheck \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY Gemfile . + +COPY Gemfile.lock . + +COPY .pre-commit-config.yaml . + +RUN bundle install && pip3 install pre-commit && git init . && pre-commit install-hooks + +COPY . . diff --git a/mruby/Doxyfile b/mruby/Doxyfile index ece327c8..3a66c141 100644 --- a/mruby/Doxyfile +++ b/mruby/Doxyfile @@ -1,82 +1,97 @@ -# Doxyfile 1.8.13 +# Doxyfile 1.9.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "mruby" -PROJECT_NUMBER = 3.1.0 - -PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language" - -PROJECT_LOGO = doc/mruby_logo_red_icon.png - -OUTPUT_DIRECTORY = doc/capi +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. -USE_MDFILE_AS_MAINPAGE = README.md +DOXYFILE_ENCODING = UTF-8 -INPUT = CONTRIBUTING.md \ - README.md \ - SECURITY.md \ - TODO.md \ - src \ - include \ - include/mruby \ - mrblib \ - doc \ - doc/guides \ - doc/internal \ - LEGAL \ - LICENSE \ - NEWS +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. -# Red for Ruby -HTML_COLORSTYLE_HUE = 359 +PROJECT_NAME = mruby -# The following expansions -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = NO +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. -# This tells doxygen to search the places that make sense -SEARCH_INCLUDES = YES -INCLUDE_PATH = include include/mruby -INCLUDE_FILE_PATTERNS = *.h +PROJECT_NUMBER = 3.2.0 -CLANG_ASSISTED_PARSING = NO -CLANG_OPTIONS = -I./include +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. -# This thing creates documentation elements for everything, even when its not documented. Its a little ugly to do it right now because huge swathes of code aren't documented. -EXTRACT_ALL = NO +PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language" -# Document MRB_INLINE functions -EXTRACT_STATIC = YES +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. -JAVADOC_AUTOBRIEF = YES -QT_AUTOBRIEF = NO +PROJECT_LOGO = doc/mruby_logo_red_icon.png -QUIET = YES -WARN_IF_UNDOCUMENTED = NO +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. -#=========================================================================== -# BELOW THIS LINE IS CRUFT GENERATED BY doxygen -g -# If you edit anything below this, bring it up here so its easier to read. -#=========================================================================== +OUTPUT_DIRECTORY = doc/capi -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -88,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -187,6 +202,32 @@ STRIP_FROM_INC_PATH = SHORT_NAMES = NO +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as @@ -200,6 +241,14 @@ SHORT_NAMES = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -223,20 +272,19 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -265,28 +313,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = no_extension=md # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. +# documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -298,7 +358,7 @@ MARKDOWN_SUPPORT = YES # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. +# Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 @@ -328,7 +388,7 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. @@ -414,6 +474,19 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -426,6 +499,7 @@ LOOKUP_CACHE_SIZE = 0 # normally produced when WARNINGS is set to YES. # The default value is: NO. +EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. @@ -433,6 +507,12 @@ LOOKUP_CACHE_SIZE = 0 EXTRACT_PRIVATE = NO +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -443,6 +523,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, @@ -469,6 +550,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -480,14 +568,15 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO @@ -506,12 +595,20 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = YES @@ -529,6 +626,12 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -686,7 +789,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -697,7 +801,7 @@ LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. @@ -708,6 +812,12 @@ CITE_BIB_FILES = # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES @@ -718,25 +828,51 @@ CITE_BIB_FILES = WARNINGS = YES +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = NO # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. # The default value is: NO. WARN_AS_ERROR = NO @@ -747,13 +883,27 @@ WARN_AS_ERROR = NO # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = @@ -767,16 +917,41 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. +INPUT = CONTRIBUTING.md \ + README.md \ + SECURITY.md \ + TODO.md \ + src \ + include \ + include/mruby \ + mrblib \ + doc \ + doc/guides \ + doc/internal \ + LEGAL \ + LICENSE \ + NEWS # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -785,11 +960,15 @@ INPUT_ENCODING = UTF-8 # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -871,7 +1050,7 @@ EXCLUDE_PATTERNS = # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test +# ANamespace::AClass, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* @@ -919,6 +1098,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -953,6 +1137,22 @@ FILTER_SOURCE_FILES = NO FILTER_SOURCE_PATTERNS = +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = README.md + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -980,7 +1180,7 @@ INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. +# entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO @@ -1012,12 +1212,12 @@ SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version +# (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -1039,23 +1239,6 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse-libclang=ON option for CMake. -# The default value is: NO. - - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - - #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1067,17 +1250,11 @@ VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1156,7 +1333,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1171,8 +1353,32 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 359 + # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1199,6 +1405,17 @@ HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = NO +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. @@ -1222,13 +1439,14 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1242,6 +1460,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1267,8 +1492,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1298,7 +1527,7 @@ CHM_FILE = HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). +# (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1343,7 +1572,8 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1351,8 +1581,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1360,30 +1590,30 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @@ -1426,16 +1656,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1460,6 +1702,24 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1469,19 +1729,14 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1491,11 +1746,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1508,22 +1781,29 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1551,7 +1831,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1570,7 +1850,8 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). +# Xapian (see: +# https://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1583,8 +1864,9 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). See the section "External Indexing and -# Searching" for details. +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = @@ -1635,21 +1917,35 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1679,29 +1975,31 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1734,9 +2032,11 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1744,8 +2044,7 @@ USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode # command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# if errors occur, instead of asking the user for help. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1758,19 +2057,9 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1784,6 +2073,14 @@ LATEX_BIB_STYLE = plain LATEX_TIMESTAMP = NO +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1823,9 +2120,9 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. @@ -1834,22 +2131,12 @@ RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -1921,6 +2208,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -1939,23 +2233,14 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sf.net) file that captures the -# structure of the code including all documentation. Note that this feature is -# still experimental and incomplete at the moment. +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -2006,6 +2291,16 @@ PERLMOD_MAKEVAR_PREFIX = # C-preprocessor directives found in the sources and include files. # The default value is: YES. +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -2013,7 +2308,31 @@ PERLMOD_MAKEVAR_PREFIX = # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. +INCLUDE_PATH = include \ + include/mruby + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = *.h # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. @@ -2023,6 +2342,7 @@ PERLMOD_MAKEVAR_PREFIX = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2031,6 +2351,7 @@ PERLMOD_MAKEVAR_PREFIX = # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have @@ -2040,6 +2361,7 @@ PERLMOD_MAKEVAR_PREFIX = # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. +SKIP_FUNCTION_MACROS = NO #--------------------------------------------------------------------------- # Configuration options related to external references @@ -2087,34 +2409,10 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. @@ -2133,7 +2431,7 @@ HIDE_UNDOC_RELATIONS = YES # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO -# The default value is: YES. +# The default value is: NO. HAVE_DOT = YES @@ -2147,35 +2445,50 @@ HAVE_DOT = YES DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" + +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a +# graph for each documented class showing the direct and indirect inheritance +# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, +# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set +# to TEXT the direct and indirect inheritance relations will be shown as texts / +# links. +# Possible values are: NO, YES, TEXT and GRAPH. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES @@ -2189,7 +2502,8 @@ CLASS_GRAPH = YES COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. See also the chapter Grouping +# in the manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2212,10 +2526,32 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. +# This tag requires that the tag UML_LOOK is set to YES. UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2282,6 +2618,13 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: @@ -2289,9 +2632,7 @@ DIRECTORY_GRAPH = YES # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, -# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, -# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, # png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and # png:gdiplus:gdiplus. # The default value is: png. @@ -2337,10 +2678,10 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = @@ -2378,18 +2719,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2402,14 +2731,18 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES diff --git a/mruby/Gemfile b/mruby/Gemfile new file mode 100644 index 00000000..497e42ff --- /dev/null +++ b/mruby/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gem 'rake' +gem 'yard' +gem 'yard-coderay' +gem 'yard-mruby' diff --git a/mruby/Gemfile.lock b/mruby/Gemfile.lock new file mode 100644 index 00000000..37e5d651 --- /dev/null +++ b/mruby/Gemfile.lock @@ -0,0 +1,27 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.3) + rake (13.0.6) + webrick (1.7.0) + yard (0.9.28) + webrick (~> 1.7.0) + yard-coderay (0.1.0) + coderay + yard + yard-mruby (0.3.0) + yard (~> 0.9.0) + +PLATFORMS + ruby + x86_64-darwin-21 + x86_64-linux + +DEPENDENCIES + rake + yard + yard-coderay + yard-mruby + +BUNDLED WITH + 2.4.10 diff --git a/mruby/Makefile b/mruby/Makefile index 4e70a8e6..a62a126e 100644 --- a/mruby/Makefile +++ b/mruby/Makefile @@ -18,6 +18,18 @@ check : pre-commit run --all-files .PHONY : check +checkinstall : + pre-commit install +.PHONY : checkinstall + checkupdate : pre-commit autoupdate .PHONY : checkupdate + +composecheck : + docker-compose -p mruby run test pre-commit run --all-files +.PHONY : composecheck + +composetest : + docker-compose -p mruby run test +.PHONY : composetest diff --git a/mruby/NEWS b/mruby/NEWS index 34cf8452..36f955eb 100644 --- a/mruby/NEWS +++ b/mruby/NEWS @@ -46,7 +46,6 @@ Following CVEs are fixed. - [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080) - [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240) - [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326) -- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) - [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481) - [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525) - [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570) diff --git a/mruby/README.md b/mruby/README.md index cf310e01..ed3d9302 100644 --- a/mruby/README.md +++ b/mruby/README.md @@ -1,6 +1,16 @@ -# mruby - -[![GitHub Super-Linter](https://github.com/mruby/mruby/workflows/Lint%20Code%20Base/badge.svg)](https://github.com/marketplace/actions/super-linter) +
+

+ + The mruby programming language + +

+

mruby

+ + GitHub Super-Linter + +
## What is mruby @@ -8,18 +18,22 @@ mruby is the lightweight implementation of the Ruby language complying to (part of) the [ISO standard][ISO-standard] with more recent features provided by Ruby 3.x. Also, its syntax is Ruby 3.x compatible except for pattern matching. -mruby can be linked and embedded within your application. We provide the -interpreter program "mruby", and the interactive mruby shell "mirb" as examples. -You can also compile Ruby programs into compiled byte code using the mruby -compiler "mrbc". All those tools reside in the "bin" directory. "mrbc" is -also able to generate compiled byte code in a C source file, see the "mrbtest" -program under the "test" directory for an example. +You can link and embed mruby within your application. The "mruby" interpreter +program and the interactive "mirb" shell are provided as examples. You can also +compile Ruby programs into compiled byte code using the "mrbc" compiler. All +these tools are located in the "bin" directory. "mrbc" can also generate +compiled byte code in a C source file. See the "mrbtest" program under the +"test" directory for an example. This achievement was sponsored by the Regional Innovation Creation R&D Programs of the Ministry of Economy, Trade and Industry of Japan. ## How to get mruby +To get mruby, you can download the stable version 3.2.0 from the official mruby +GitHub repository or clone the trunk of the mruby source tree with the "git +clone" command. You can also install and compile mruby using [ruby-install](https://github.com/postmodern/ruby-install), [ruby-build](https://github.com/rbenv/ruby-build) or [rvm](https://github.com/rvm/rvm). + The stable version 3.2.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/3.2.0.zip](https://github.com/mruby/mruby/archive/3.2.0.zip) The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master) @@ -27,15 +41,13 @@ The latest development version of mruby can be downloaded via the following URL: The trunk of the mruby source tree can be checked out with the following command: -``` +```console $ git clone https://github.com/mruby/mruby.git ``` -You can also install and compile mruby using [ruby-install](https://github.com/postmodern/ruby-install), [ruby-build](https://github.com/rbenv/ruby-build) or [rvm](https://github.com/rvm/rvm). - -## mruby home-page +## mruby homepage -The URL of the mruby home-page is: . +The URL of the mruby homepage is: . ## Mailing list @@ -45,7 +57,7 @@ We don't have a mailing list, but you can use [GitHub issues](https://github.com For the simplest case, type -``` +```console rake all test ``` @@ -53,27 +65,27 @@ See the [compile.md](doc/guides/compile.md) file for the detail. ## Building documentation -There are two sets of documentation in mruby: the mruby API (generated by yard) and C API (Doxygen and Graphviz) +There are two sets of documentation in mruby: the mruby API (generated by YARD) and C API (Doxygen and Graphviz) To build both of them, simply go -``` +```console rake doc ``` You can also view them in your browser -``` +```console rake view_api rake view_capi ``` ## How to customize mruby (mrbgems) -mruby contains a package manager called *mrbgems*. To create extensions -in C and/or Ruby you should create a *GEM*. For a documentation of how to -use mrbgems consult the file [mrbgems.md](doc/guides/mrbgems.md). -For example code of how to use mrbgems look into the folder [examples/mrbgems/](examples/mrbgems). +mruby contains a package manager called "mrbgems" that you can use to create +extensions in C and/or Ruby. For a guide on how to use mrbgems, consult the +[mrbgems.md](doc/guides/mrbgems.md) file, and for example code, refer to the +[examples/mrbgems/](examples/mrbgems) folder. ## License @@ -98,9 +110,8 @@ Please ask us if you want to distribute your code under another license. ## How to Contribute -See the [contribution guidelines][contribution-guidelines], and then send a pull -request to . We consider you have granted -non-exclusive right to your contributed code under MIT license. +To contribute to mruby, please refer to the [contribution guidelines][contribution-guidelines] and send a pull request to the [mruby GitHub repository](https://github.com/mruby/mruby). +By contributing, you grant non-exclusive rights to your code under the MIT License. [ISO-standard]: https://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579 -[contribution-guidelines]: https://github.com/mruby/mruby/blob/master/CONTRIBUTING.md +[contribution-guidelines]: CONTRIBUTING.md diff --git a/mruby/Rakefile b/mruby/Rakefile index 5a8fbdb5..79ec84f6 100644 --- a/mruby/Rakefile +++ b/mruby/Rakefile @@ -31,6 +31,7 @@ load "#{MRUBY_ROOT}/tasks/presym.rake" load "#{MRUBY_ROOT}/tasks/test.rake" load "#{MRUBY_ROOT}/tasks/benchmark.rake" load "#{MRUBY_ROOT}/tasks/doc.rake" +load "#{MRUBY_ROOT}/tasks/install.rake" ############################## # generic build targets, rules @@ -56,7 +57,7 @@ task :clean do rm_rf build.build_dir rm_f build.products end - puts "Cleaned up target build folder" + puts "Cleaned up target build directory" end desc "clean everything!" @@ -64,35 +65,9 @@ task :deep_clean => %w[clean doc:clean] do MRuby.each_target do |build| rm_rf build.gem_clone_dir end - puts "Cleaned up mrbgems build folder" -end - -PREFIX = ENV['PREFIX'] || ENV['INSTALL_PREFIX'] || '/usr/local' - -desc "install compiled products" -task :install => :install_bin do - if host = MRuby.targets['host'] - install_D host.libmruby_static, File.join(PREFIX, "lib", File.basename(host.libmruby_static)) - # install mruby.h and mrbconf.h - Dir.glob(File.join(MRUBY_ROOT, "include", "*.h")) do |src| - install_D src, File.join(PREFIX, "include", File.basename(src)) - end - Dir.glob(File.join(MRUBY_ROOT, "include", "mruby", "*.h")) do |src| - install_D src, File.join(PREFIX, "include", "mruby", File.basename(src)) - end - Dir.glob(File.join(File.join(MRUBY_ROOT, "build", "host", "include", "mruby", "presym", "*.h"))) do |src| - install_D src, File.join(PREFIX, "include", "mruby", "presym", File.basename(src)) - end - end -end - -desc "install compiled executable (on host)" -task :install_bin => :all do - if host = MRuby.targets['host'] - Dir.glob(File.join(MRUBY_ROOT, "bin", "*")) do |src| - install_D src, File.join(PREFIX, "bin", File.basename(src)) - end - end + rm_rf "#{MRUBY_ROOT}/bin" + rm_rf "#{MRUBY_ROOT}/build" + puts "Cleaned up mrbgems build directory" end desc "run all pre-commit hooks against all files" @@ -100,7 +75,22 @@ task :check do sh "pre-commit run --all-files" end +desc "install the pre-commit hooks" +task :checkinstall do + sh "pre-commit install" +end + desc "check the pre-commit hooks for updates" task :checkupdate do sh "pre-commit autoupdate" end + +desc "run all pre-commit hooks against all files with docker-compose" +task :composecheck do + sh "docker-compose -p mruby run test pre-commit run --all-files" +end + +desc "build and run all mruby tests with docker-compose" +task :composetest do + sh "docker-compose -p mruby run test" +end diff --git a/mruby/appveyor.yml b/mruby/appveyor.yml index 8782f59a..3a063dd7 100644 --- a/mruby/appveyor.yml +++ b/mruby/appveyor.yml @@ -4,6 +4,10 @@ shallow_clone: true environment: matrix: + - job_name: Visual Studio 2022 64bit + visualcpp: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat + appveyor_build_worker_image: Visual Studio 2022 + - job_name: Visual Studio 2019 64bit visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat appveyor_build_worker_image: Visual Studio 2019 @@ -38,7 +42,6 @@ init: - set PATH=C:\Ruby26-x64\bin;%PATH% - ruby --version - build_script: - set MRUBY_CONFIG=ci/msvc - rake -m test:build diff --git a/mruby/benchmark/bm_ao_render.rb b/mruby/benchmark/bm_ao_render.rb index 91e2d341..ddb42d5c 100644 --- a/mruby/benchmark/bm_ao_render.rb +++ b/mruby/benchmark/bm_ao_render.rb @@ -253,6 +253,7 @@ def ambient_occlusion(isect) def render(w, h, nsubsamples) nsf = nsubsamples.to_f + nsfs = nsf * nsf h.times do |y| w.times do |x| rad = Vec.new(0.0, 0.0, 0.0) @@ -288,9 +289,9 @@ def render(w, h, nsubsamples) end end - r = rad.x / (nsf * nsf) - g = rad.y / (nsf * nsf) - b = rad.z / (nsf * nsf) + r = rad.x / nsfs + g = rad.y / nsfs + b = rad.z / nsfs printf("%c", clamp(r)) printf("%c", clamp(g)) printf("%c", clamp(b)) diff --git a/mruby/build_config/android_arm64_v8a.rb b/mruby/build_config/android_arm64_v8a.rb index 8763b008..6dda612d 100644 --- a/mruby/build_config/android_arm64_v8a.rb +++ b/mruby/build_config/android_arm64_v8a.rb @@ -2,8 +2,8 @@ MRuby::CrossBuild.new('android-arm64-v8a') do |conf| params = { :arch => 'arm64-v8a', - :sdk_version => 26, - :toolchain => :clang, + :sdk_version => 33, + :toolchain => :clang } toolchain :android, params diff --git a/mruby/build_config/android_armeabi.rb b/mruby/build_config/android_armeabi.rb deleted file mode 100644 index cef0e3ad..00000000 --- a/mruby/build_config/android_armeabi.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Requires Android NDK r13 or later. -MRuby::CrossBuild.new('android-armeabi') do |conf| - params = { - :arch => 'armeabi', - :sdk_version => 26, - :toolchain => :clang, - } - toolchain :android, params - - conf.gembox 'default' -end diff --git a/mruby/build_config/android_armeabi_v7a_neon_hard.rb b/mruby/build_config/android_armeabi_v7a_neon_hard.rb index 150d1d20..3dae2418 100644 --- a/mruby/build_config/android_armeabi_v7a_neon_hard.rb +++ b/mruby/build_config/android_armeabi_v7a_neon_hard.rb @@ -4,8 +4,8 @@ :arch => 'armeabi-v7a', :mfpu => 'neon', :mfloat_abi => 'hard', - :sdk_version => 26, - :toolchain => :clang, + :sdk_version => 33, + :toolchain => :clang } toolchain :android, params diff --git a/mruby/build_config/dreamcast_shelf.rb b/mruby/build_config/dreamcast_shelf.rb index 092fde0d..53adad2a 100644 --- a/mruby/build_config/dreamcast_shelf.rb +++ b/mruby/build_config/dreamcast_shelf.rb @@ -73,7 +73,6 @@ # Some Gems are incompatible and were disabled. conf.gem :core => "mruby-array-ext" - conf.gem :core => "mruby-binding" conf.gem :core => "mruby-catch" conf.gem :core => "mruby-class-ext" conf.gem :core => "mruby-cmath" diff --git a/mruby/build_config/i586-pc-msdosdjgpp.rb b/mruby/build_config/i586-pc-msdosdjgpp.rb new file mode 100644 index 00000000..4275423c --- /dev/null +++ b/mruby/build_config/i586-pc-msdosdjgpp.rb @@ -0,0 +1,77 @@ +# Cross Compiling configuration for MS-DOS +# +# Requires DJGPP cross-compiler, see +# https://github.com/andrewwutw/build-djgpp/releases + +MRuby::CrossBuild.new("i586-pc-msdosdjgpp") do |conf| + toolchain :gcc + + # If DJGPP is not in the PATH, set this to the bin directory + DJGPP_PATH = nil + + GCC = 'i586-pc-msdosdjgpp-gcc' + GXX = 'i586-pc-msdosdjgpp-g++' + AR = 'i586-pc-msdosdjgpp-ar' + + conf.cc do |cc| + cc.command = DJGPP_PATH ? File.join(DJGPP_PATH, GCC) : GCC + cc.defines << 'MRB_WITHOUT_IO_PREAD_PWRITE' + cc.defines << 'MRB_UTF8_STRING' + end + + conf.cxx do |cxx| + cxx.command = DJGPP_PATH ? File.join(DJGPP_PATH, GXX) : GXX + cxx.defines << 'MRB_WITHOUT_IO_PREAD_PWRITE' + cxx.defines << 'MRB_UTF8_STRING' + end + + conf.linker do |linker| + linker.command = DJGPP_PATH ? File.join(DJGPP_PATH, GXX) : GXX + linker.libraries = %w(m) + end + + conf.archiver do |archiver| + archiver.command = DJGPP_PATH ? File.join(DJGPP_PATH, AR) : AR + end + + # All provided gems that can be reasonably made to compile: + # default.gembox, minus mruby-socket and replacing mruby-cmath with mruby-cmath-alt + conf.gembox "stdlib" + conf.gembox "stdlib-ext" + + conf.gem :core => 'mruby-io' # stdlib-io.gembox <- default.gembox +# No socket support in DJGPP +# conf.gem :core => 'mruby-socket' # stdlib-io.gembox <- default.gembox + conf.gem :core => 'mruby-print' # stdlib-io.gembox <- default.gembox + conf.gem :core => 'mruby-errno' # stdlib-io.gembox <- default.gembox + conf.gem :core => 'mruby-dir' # stdlib-io.gembox <- default.gembox + + conf.gem :core => 'mruby-bigint' # math.gembox <- default.gembox + conf.gem :core => 'mruby-complex' # math.gembox <- default.gembox + conf.gem :core => 'mruby-math' # math.gembox <- default.gembox + conf.gem :core => 'mruby-rational' # math.gembox <- default.gembox + # Alternative implementation of cmath, not requiring +# conf.gem :github => 'chasonr/mruby-cmath-alt' # math.gembox <- default.gembox + + conf.gembox "metaprog" + + conf.gem :core => 'mruby-bin-mrbc' # default.gembox + conf.gem :core => 'mruby-bin-debugger' # default.gembox + conf.gem :core => 'mruby-bin-mirb' # default.gembox + conf.gem :core => 'mruby-bin-mruby' # default.gembox + conf.gem :core => 'mruby-bin-strip' # default.gembox + conf.gem :core => 'mruby-bin-config' # default.gembox + + # Other compilable gems + conf.gem :core => 'mruby-binding' + conf.gem :core => 'mruby-catch' + conf.gem :core => 'mruby-enum-chain' + conf.gem :core => 'mruby-error' + conf.gem :core => 'mruby-exit' + conf.gem :core => 'mruby-os-memsize' + conf.gem :core => 'mruby-proc-binding' + conf.gem :core => 'mruby-sleep' + + # For Onigmo regular expression support + conf.gem :github => 'mattn/mruby-onig-regexp' +end diff --git a/mruby/codespell.txt b/mruby/codespell.txt index d6d80b07..9a4d7548 100644 --- a/mruby/codespell.txt +++ b/mruby/codespell.txt @@ -1,20 +1,16 @@ ans -ba +celler clen -creat delet disabl -falsy filetest fo hel -hist ist -methid nd quitt remore -ro runn sting -upto +strin +wronly diff --git a/mruby/doc/guides/compile.md b/mruby/doc/guides/compile.md index 4302d136..579a49d7 100644 --- a/mruby/doc/guides/compile.md +++ b/mruby/doc/guides/compile.md @@ -177,7 +177,7 @@ conf.linker do |linker| linker.flags_before_libraries = ... linker.libraries = ... linker.flags_after_libraries = ... - linker.library_paths = .... + linker.library_paths = ... linker.option_library = ... linker.option_library_path = ... linker.link_options = ... @@ -265,7 +265,7 @@ There is a `RubyGem` (gem for CRuby) named `mgem` that help you to manage `mrbgems`. Try `gem install mgem`. `mgem` can show you the list of registered `mrbgems`. -See doc/mrbgems/README.md for more option about mrbgems. +See [doc/guides/mrbgems.md](mrbgems.md) for more option about mrbgems. ### Mrbtest @@ -376,7 +376,7 @@ end ## Build process -During the build process the directory `build` will be created in the +During the build process the `build` directory will be created in the root directory. The structure of this directory will look like this: ``` @@ -527,7 +527,7 @@ After the build, you will get `libmruby.a`. You can link it to your application. For compiler options and library path, you can use `mruby-config` command for convenience. `mruby-config` command prints the configuration used for `libmruby.a`. -``` +```console $ mruby-config --help Usage: mruby-config [switches] switches: @@ -557,6 +557,56 @@ LDFLAGS = `$(MRB_CONFIG) --ldflags` LIBS = `$(MRB_CONFIG) --libs` ``` +## Install + +To install the files in the `bin`, `include` and `lib` directories generated by the "host" build target into a system directory, do the following: + +```console +$ rake install +``` + +If there are multiple build targets in the build configuration file, to install the products of all build targets, do the following: + +```console +$ rake install:full +``` + +To install only one of several build targets, e.g., the "its-mine" build target, do the following: + +```console +$ rake install:full:its-mine +``` + +To install only the executable files, do the following: + +```console +$ rake install_bin # only "host" build target +$ rake install:bin # all build targets +$ rake install:bin:its-mine # only "its-mine" build target +``` + +### Installation Directory + +The installation directory is `/usr/local` for the "host" build target and `/usr/local/mruby/` for the others. +To change them, you can set the environment variable `PREFIX` or use `MRuby::Build#install_prefix = dir` in your build configuration file. + +The `PREFIX` environment variable affects all build targets and changes the `/usr/local` part. + +The `MRuby::Build#install_prefix` can be set for each individual build target. +In this case, the environment variable `PREFIX` is ignored. + +Also, if the environment variable `DESTDIR` is set, it will prepend to the path obtained by `install_prefix` to determine the final write directory. +This is intended for temporary file expansion by the user's package work. + +--- + +To summarize: + +- The default value of the environment variable `PREFIX` is `/usr/local`. +- For the "host" build target, the default value of `MRuby::Build#install_prefix` is ``. +- For a build target other than "host", the default value of `MRuby::Build#install_prefix` is `/mruby/`. +- If the environment variable `DESTDIR` is set, the actual write directory is `/`. + ## Tips - If you see compilation troubles, try `rake clean` first. diff --git a/mruby/doc/guides/debugger.md b/mruby/doc/guides/debugger.md index ef48005a..40afb507 100644 --- a/mruby/doc/guides/debugger.md +++ b/mruby/doc/guides/debugger.md @@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option: ```bash $ mrdb --version -mruby 3.1.0 (2022-05-12) +mruby 3.2.0 (2023-02-24) ``` ## 2.2 Basic Operation diff --git a/mruby/doc/guides/gc-arena-howto.md b/mruby/doc/guides/gc-arena-howto.md index 22cd4ef1..31bee93f 100644 --- a/mruby/doc/guides/gc-arena-howto.md +++ b/mruby/doc/guides/gc-arena-howto.md @@ -3,6 +3,7 @@ _This is an English translation of [Matz's blog post][matz blog post] written in Japanese._ _Some parts are updated to reflect recent changes._ + [matz blog post]: When you are extending mruby using C language, you may encounter @@ -62,7 +63,7 @@ memory leak. As of this writing, mruby automatically extend arena to remember objects (See `MRB_GC_FIXED_ARENA` and `MRB_GC_ARENA_SIZE` in -doc/guides/mrbconf.md). +[doc/guides/mrbconf.md](mrbconf.md)). If you create many objects in C functions, memory usage will increase, since GC never kicks in. This memory usage may look like memory leaks, but will also @@ -106,7 +107,7 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) char tail[] = { ']' }; /* check recursive */ - for(i=0; i 0) { diff --git a/mruby/doc/guides/link.md b/mruby/doc/guides/link.md index 861f7136..491efc41 100644 --- a/mruby/doc/guides/link.md +++ b/mruby/doc/guides/link.md @@ -54,7 +54,7 @@ command with following options: - `--cc` compiler name - `--cflags` options passed to compiler -``` +```console $ mruby-config --cflags -std=gnu99 -g -O3 -Wall -DMRB_GC_FIXED_ARENA -I/home/matz/work/mruby/include -I/home/matz/work/mruby/build/host/include ``` @@ -71,7 +71,7 @@ To retrieve linker options, you can use `mruby-config` with following options: - `--ldflags-before-libs` options passed to linker before linked libraries - `--libs` linked libraries -``` +```console $ mruby-config --ldflags -L/home/matz/work/mruby/build/host/lib diff --git a/mruby/doc/guides/mrbconf.md b/mruby/doc/guides/mrbconf.md index 771922a4..dc153850 100644 --- a/mruby/doc/guides/mrbconf.md +++ b/mruby/doc/guides/mrbconf.md @@ -18,10 +18,10 @@ This is the same for `MRuby::CrossBuild`. # build_config.rb MRuby::Build.new do |conf| - ..... + ... conf.defines << 'MRB_GC_FIXED_ARENA' conf.defines << 'MRB_NO_METHOD_CACHE' - ..... + ... end ``` @@ -247,6 +247,6 @@ largest value of required alignment. - Make it available `Symbol.all_symbols` in `mrbgems/mruby-symbol-ext` - Increase heap memory usage. -`MRB_NO_DIRECT_THREADING` +`MRB_USE_VM_SWITCH_DISPATCH` -- Turn off direct threading optimization in VM loop +- Turn on switch dispatch in VM loop diff --git a/mruby/doc/guides/mrbgems.md b/mruby/doc/guides/mrbgems.md index e81a30ac..999629d4 100644 --- a/mruby/doc/guides/mrbgems.md +++ b/mruby/doc/guides/mrbgems.md @@ -1,6 +1,6 @@ # mrbgems -mrbgems is a library manager to integrate C and Ruby extension in an easy and +mrbgems is a library manager to integrate C and Ruby extensions in an easy and standardised way into mruby. Conventionally, each mrbgem name is prefixed by `mruby-`, e.g. `mruby-time` for a gem that provides `Time` class functionality. @@ -92,6 +92,21 @@ end However, it should be used with caution, as it may deviate from the intent of the gem's author. +### Gem Testing + +If you enable unit tests in your build with `enable_test`, tests will be +generated for all gems and their dependencies by default. If necessary, it is +possible to suppress tests for a specific gem like so: + +```ruby +conf.gem 'mruby-noisygem' do |g| + g.skip_test = true +end +``` + +However, it is considered best practice to leave all tests enabled whenever +possible. A warning message will be generated for each gem with disabled tests. + ## GemBox There are instances when you wish to add a collection of mrbgems into mruby at @@ -160,9 +175,9 @@ The maximal GEM structure looks like this: +- test/ <- Test code (Ruby) ``` -The folder `mrblib` contains pure Ruby files to extend mruby. The folder `src` -contains C/C++ files to extend mruby. The folder `include` contains C/C++ header -files. The folder `test` contains C/C++ and pure Ruby files for testing purposes +The `mrblib` directory contains pure Ruby files to extend mruby. The `src` directory +contains C/C++ files to extend mruby. The `include` directory contains C/C++ header +files. The `test` directory contains C/C++ and pure Ruby files for testing purposes which will be used by `mrbtest`. `mrbgem.rake` contains the specification to compile C and Ruby files. `README.md` is a short description of your GEM. @@ -349,7 +364,7 @@ mrb_c_extension_example_gem_final(mrb_state* mrb) { mruby can be extended with pure Ruby. It is possible to override existing classes or add new ones in this way. Put all Ruby files into the `mrblib` -folder. +directory. ### Pre-Conditions @@ -377,7 +392,7 @@ none mruby can be extended with C and Ruby at the same time. It is possible to override existing classes or add new ones in this way. Put all Ruby files -into the `mrblib` folder and all C files into the `src` folder. +into the `mrblib` directory and all C files into the `src` directory. mruby codes under `mrblib` directory would be executed after gem init C function is called. Make sure *mruby script* depends on *C code* and diff --git a/mruby/doc/limitations.md b/mruby/doc/limitations.md index ae09ecf3..3c65f76e 100644 --- a/mruby/doc/limitations.md +++ b/mruby/doc/limitations.md @@ -64,7 +64,7 @@ p Liste.new "foobar" #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] -` [] ` +`[]` #### mruby [3.1.0 (2022-05-12)] @@ -114,7 +114,7 @@ The declaration form of following visibility methods are not implemented. Especially, `module_function` method is not dummy, but no declaration form. -``` +```ruby module TestModule module_function def test_func @@ -170,7 +170,7 @@ alias $a $__a__ #### Ruby [ruby 2.0.0p645 (2015-04-13 revision 50299)] -` nil ` +`nil` #### mruby [3.1.0 (2022-05-12)] @@ -196,7 +196,7 @@ The re-defined `+` operator does not accept any arguments. #### mruby [3.1.0 (2022-05-12)] -` 'ab' ` +`'ab'` Behavior of the operator wasn't changed. ## `Kernel#binding` is not supported until [3.0.0 (2021-03-05)] @@ -205,26 +205,11 @@ Behavior of the operator wasn't changed. #### Ruby [ruby 2.5.1p57 (2018-03-29 revision 63029)] -``` +```shell $ ruby -e 'puts Proc.new {}.binding' # ``` -#### mruby [3.0.0 (2021-03-05)] - -``` -$ ./bin/mruby -e 'puts Proc.new {}.binding' -trace (most recent call last): - [0] -e:1 --e:1: undefined method 'binding' (NoMethodError) -``` - -#### mruby [3.1.0 (2022-05-12)] - -`binding` has been supported since 3.1.0. - -See also [mrbgems/mruby-binding](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-binding) and [mrbgems/mruby-binding-core](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-binding-core). - ## `nil?` redefinition in conditional expressions Redefinition of `nil?` is ignored in conditional expressions. @@ -259,3 +244,12 @@ f(1,[2,3]) ``` CRuby gives `[1,2,3,nil]`. mruby raises `NoMethodError` for `b`. + +Keyword argument expansion has similar restrictions. The following example, gives `[1, 1]` for CRuby, mruby raises `NoMethodError` for `b`. + +```ruby +def g(a: 1, b: a) + p [a,b] +end +g(a:1) +``` diff --git a/mruby/doc/mruby3.0.md b/mruby/doc/mruby3.0.md index c1acb5ec..3f7418c4 100644 --- a/mruby/doc/mruby3.0.md +++ b/mruby/doc/mruby3.0.md @@ -159,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](https://github.com/mruby/mruby/blob/master/doc/guides/symbol.md). +See [Symbols](guides/symbol.md). diff --git a/mruby/doc/mruby3.2.md b/mruby/doc/mruby3.2.md index 1ca18d6b..59bd1e2e 100644 --- a/mruby/doc/mruby3.2.md +++ b/mruby/doc/mruby3.2.md @@ -32,9 +32,9 @@ ## New bundled gems -- mruby-errno from [https://github.com/iij/mruby-errno.git] -- mruby-set from [https://github.com/yui-knk/mruby-set.git] -- mruby-dir from [https://github.com/iij/mruby-dir.git] +- mruby-errno from +- mruby-set from +- mruby-dir from - mruby-data # Breaking Changes @@ -62,7 +62,6 @@ Following CVEs are fixed. - [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080) - [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240) - [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326) -- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) - [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481) - [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525) - [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570) diff --git a/mruby/docker-compose.yml b/mruby/docker-compose.yml new file mode 100644 index 00000000..223e85af --- /dev/null +++ b/mruby/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' +services: + test: + build: + context: . + command: sh -c 'rake deep_clean && rake -m test:build && rake test:run' + environment: + - MRUBY_CONFIG=ci/gcc-clang + - CC=gcc + - CXX=g++ + - LD=gcc + - SKIP=check-executables-have-shebangs + working_dir: /app diff --git a/mruby/examples/mrbgems/cdata_extension_example/src/example.c b/mruby/examples/mrbgems/cdata_extension_example/src/example.c index ac5593e7..4be26489 100644 --- a/mruby/examples/mrbgems/cdata_extension_example/src/example.c +++ b/mruby/examples/mrbgems/cdata_extension_example/src/example.c @@ -35,7 +35,7 @@ mrb_foo_get_bar(mrb_state *mrb, mrb_value self) struct Foo *f; f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type); - if(f == NULL) { + if (f == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data"); } @@ -49,7 +49,7 @@ mrb_foo_set_bar(mrb_state *mrb, mrb_value self) int v; f = (struct Foo*)mrb_data_get_ptr(mrb, self, &mrb_foo_type); - if(f == NULL) { + if (f == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "uninitialized data"); } diff --git a/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md b/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md index 4027df96..d1877f51 100644 --- a/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md +++ b/mruby/examples/mrbgems/mruby-YOUR-bigint/TODO-HINT.md @@ -10,7 +10,7 @@ The file structure in this example is as follows: +- mruby-YOUR-bigint/ <- Make this directory public if necessary. | Change the name of copied directory. | - +- TODO-HINT.md <- This file is currently viewing by you. + +- TODO-HINT.md <- You are currently viewing this file. | Remove this from copied directory. | +- core/ @@ -21,19 +21,19 @@ The file structure in this example is as follows: May be depended on by other GEMs. ``` -Implementors of own bigints should copy below this directory to another directory and do the following: +Implementors of their own bigints should copy below this directory to another directory and do the following: - Rewrite `spec.author`, `spec.license`, `spec.homepage` and `spec.summary` in `/mrbgem.rake` file to those of your own implementors. - Implement the respective functions in `/core/bigint.c`. - Define and use an object structure for `MRB_TT_BIGINT` type-tag. - It is recommended to use `mrb_static_assert_object_size()` to ensure that the size of the object structure is within 6 words. + It is recommended to use `mrb_static_assert_object_size()` to ensure that the size of the object structure is within six words. - Delete this file from the destination of the copy. If you wish to use it as an alternative to the `mruby-bigint` provided by mruby, please leave the GEM name in `/mrbgem.rake` as it is. This is an important factor when it is depended from other GEMs with `spec.add_dependency 'mruby-bigint'`. -The name of the top directory of GEM can be changed arbitrarily. -The name of the git repository can also be changed arbitrarily. +The name of the top directory of the GEM can be changed arbitrarily. +The name of the Git repository can also be changed arbitrarily. -Note that there is no need for an initialization function as there is in normal GEM. +Note that there is no need for an initialization function as there is in a normal GEM. If you need it, create a file `/src/bigint.c` for example, and implement the `mrb_mruby_bigint_gem_init()` function. diff --git a/mruby/include/mrbconf.h b/mruby/include/mrbconf.h index 1629a5c4..122eb2b0 100644 --- a/mruby/include/mrbconf.h +++ b/mruby/include/mrbconf.h @@ -176,8 +176,8 @@ #if defined(DISABLE_STDIO) || defined(MRB_DISABLE_STDIO) # define MRB_NO_STDIO #endif -#ifdef MRB_DISABLE_DIRECT_THREADING -# define MRB_NO_DIRECT_THREADING +#if defined(MRB_DISABLE_DIRECT_THREADING) || defined(MRB_NO_DIRECT_THREADING) +# define MRB_USE_VM_SWITCH_DISPATCH #endif #if defined(ENABLE_DEBUG) || defined(MRB_ENABLE_DEBUG_HOOK) # define MRB_USE_DEBUG_HOOK diff --git a/mruby/include/mruby.h b/mruby/include/mruby.h index 2d96b25e..5feb8d63 100644 --- a/mruby/include/mruby.h +++ b/mruby/include/mruby.h @@ -139,7 +139,7 @@ #endif /** - * MRuby C API entry point + * mruby C API entry point */ MRB_BEGIN_DECL @@ -420,7 +420,7 @@ MRB_API void mrb_prepend_module(mrb_state *mrb, struct RClass *cla, struct RClas * mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE()); * } * - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla The class pointer where the method will be defined. * @param name The name of the method being defined. * @param func The function pointer to the method definition. @@ -448,7 +448,7 @@ MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, * foo = mrb_define_class(mrb, "Foo", mrb->object_class); * mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); * } - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla The class where the class method will be defined. * @param name The name of the class method being defined. * @param fun The function pointer to the class method definition. @@ -484,7 +484,7 @@ MRB_API void mrb_define_singleton_method_id(mrb_state *mrb, struct RObject *cla, * foo = mrb_define_module(mrb, "Foo"); * mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); * } - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla The module where the module function will be defined. * @param name The name of the module function being defined. * @param fun The function pointer to the module function definition. @@ -514,7 +514,7 @@ MRB_API void mrb_define_module_function_id(mrb_state *mrb, struct RClass *cla, m * mrb_value * mrb_example_gem_final(mrb_state* mrb){ * } - * @param mrb The MRuby state reference. + * @param mrb The mruby state reference. * @param cla A class or module the constant is defined in. * @param name The name of the constant being defined. * @param val The value for the constant. @@ -1017,7 +1017,7 @@ struct mrb_kwargs /** * Retrieve arguments from mrb_state. * - * @param mrb The current MRuby state. + * @param mrb The current mruby state. * @param format is a list of format specifiers * @param ... The passing variadic arguments must be a pointer of retrieving type. * @return the number of arguments retrieved. @@ -1248,7 +1248,7 @@ MRB_API mrb_state* mrb_open(void); MRB_API mrb_state* mrb_open_allocf(mrb_allocf f, void *ud); /** - * Create new mrb_state with just the MRuby core + * Create new mrb_state with just the mruby core * * @param f * Reference to the allocation function. @@ -1303,26 +1303,17 @@ MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); /* mrb_cmp(mrb, obj1, obj2): 1:0:-1; -2 for error */ MRB_API mrb_int mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2); -MRB_INLINE int -mrb_gc_arena_save(mrb_state *mrb) -{ - return mrb->gc.arena_idx; -} - -MRB_INLINE void -mrb_gc_arena_restore(mrb_state *mrb, int idx) -{ - mrb->gc.arena_idx = idx; -} +#define mrb_gc_arena_save(mrb) ((mrb)->gc.arena_idx) +#define mrb_gc_arena_restore(mrb, idx) ((mrb)->gc.arena_idx = (idx)) MRB_API void mrb_garbage_collect(mrb_state*); MRB_API void mrb_full_gc(mrb_state*); -MRB_API void mrb_incremental_gc(mrb_state *); +MRB_API void mrb_incremental_gc(mrb_state*); MRB_API void mrb_gc_mark(mrb_state*,struct RBasic*); #define mrb_gc_mark_value(mrb,val) do {\ if (!mrb_immediate_p(val)) mrb_gc_mark((mrb), mrb_basic_ptr(val)); \ } while (0) -MRB_API void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*); +MRB_API void mrb_field_write_barrier(mrb_state*, struct RBasic*, struct RBasic*); #define mrb_field_write_barrier_value(mrb, obj, val) do{\ if (!mrb_immediate_p(val)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val)); \ } while (0) @@ -1366,7 +1357,7 @@ MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj); MRB_API mrb_noreturn void mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max); MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...); -MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...); +MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *mesg); MRB_API void mrb_print_backtrace(mrb_state *mrb); MRB_API void mrb_print_error(mrb_state *mrb); /* function for `raisef` formatting */ @@ -1378,6 +1369,8 @@ MRB_API mrb_value mrb_vformat(mrb_state *mrb, const char *format, va_list ap); + exception objects obtained from those macros are local to mrb */ #define MRB_ERROR_SYM(sym) mrb_intern_lit(mrb, #sym) +#define E_EXCEPTION mrb->eException_class +#define E_STANDARD_ERROR mrb->eStandardError_class #define E_RUNTIME_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(RuntimeError)) #define E_TYPE_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(TypeError)) #define E_ZERODIV_ERROR mrb_exc_get_id(mrb, MRB_ERROR_SYM(ZeroDivisionError)) @@ -1436,12 +1429,8 @@ MRB_API mrb_value mrb_ensure_int_type(mrb_state *mrb, mrb_value val); /* string type checking (contrary to the name, it doesn't convert) */ 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) -{ - if (mrb_frozen_p((struct RBasic*)o)) mrb_frozen_error(mrb, o); -} - +MRB_API void mrb_check_frozen(mrb_state *mrb, void *); +MRB_API void mrb_check_frozen_value(mrb_state *mrb, mrb_value v); MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *c, const char *a, const char *b); MRB_API void mrb_define_alias_id(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b); MRB_API const char *mrb_class_name(mrb_state *mrb, struct RClass* klass); diff --git a/mruby/include/mruby/class.h b/mruby/include/mruby/class.h index ff16f1ac..a3e1c0d1 100644 --- a/mruby/include/mruby/class.h +++ b/mruby/include/mruby/class.h @@ -26,6 +26,10 @@ struct RClass { MRB_INLINE struct RClass* mrb_class(mrb_state *mrb, mrb_value v) { + if (!mrb_immediate_p(v)) { + return mrb_obj_ptr(v)->c; + } + switch (mrb_type(v)) { case MRB_TT_FALSE: if (mrb_fixnum(v)) @@ -43,20 +47,18 @@ mrb_class(mrb_state *mrb, mrb_value v) #endif case MRB_TT_CPTR: return mrb->object_class; - case MRB_TT_ENV: - return NULL; default: - return mrb_obj_ptr(v)->c; + return NULL; } } /* flags: - 20: frozen - 19: is_prepended - 18: is_origin - 17: is_inherited (used by method cache) - 16: unused - 0-15: instance type + 20: frozen + 19: is_prepended + 18: is_origin + 17: is_inherited (used by method cache) + 6-16: unused + 0-5: instance type */ #define MRB_FL_CLASS_IS_PREPENDED (1 << 19) #define MRB_FL_CLASS_IS_ORIGIN (1 << 18) @@ -69,7 +71,7 @@ mrb_class(mrb_state *mrb, mrb_value v) }\ } while (0) #define MRB_FL_CLASS_IS_INHERITED (1 << 17) -#define MRB_INSTANCE_TT_MASK (0xFF) +#define MRB_INSTANCE_TT_MASK (0x1F) #define MRB_SET_INSTANCE_TT(c, tt) ((c)->flags = (((c)->flags & ~MRB_INSTANCE_TT_MASK) | (char)(tt))) #define MRB_INSTANCE_TT(c) (enum mrb_vtype)((c)->flags & MRB_INSTANCE_TT_MASK) diff --git a/mruby/include/mruby/common.h b/mruby/include/mruby/common.h index 59214d3c..fd5c1102 100644 --- a/mruby/include/mruby/common.h +++ b/mruby/include/mruby/common.h @@ -67,7 +67,7 @@ MRB_BEGIN_DECL #endif #define MRB_INLINE static inline -/** Declare a public MRuby API function. */ +/** Declare a public mruby API function. */ #ifndef MRB_API #if defined(MRB_BUILD_AS_DLL) #if defined(MRB_CORE) || defined(MRB_LIB) diff --git a/mruby/include/mruby/compile.h b/mruby/include/mruby/compile.h index 70cf9a93..84f09e3e 100644 --- a/mruby/include/mruby/compile.h +++ b/mruby/include/mruby/compile.h @@ -10,7 +10,7 @@ #include "common.h" /** - * MRuby Compiler + * mruby Compiler */ MRB_BEGIN_DECL diff --git a/mruby/include/mruby/data.h b/mruby/include/mruby/data.h index 7bdf1c34..a64301a5 100644 --- a/mruby/include/mruby/data.h +++ b/mruby/include/mruby/data.h @@ -41,12 +41,12 @@ MRB_API struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass #define Data_Make_Struct(mrb,klass,strct,type,sval,data_obj) do { \ (data_obj) = Data_Wrap_Struct(mrb,klass,type,NULL);\ - (sval) = (strct *)mrb_malloc(mrb, sizeof(strct)); \ + (sval) = (strct*)mrb_malloc(mrb, sizeof(strct)); \ { static const strct zero = { 0 }; *(sval) = zero; };\ (data_obj)->data = (sval);\ } while (0) -#define RDATA(obj) ((struct RData *)(mrb_ptr(obj))) +#define RDATA(obj) ((struct RData*)(mrb_ptr(obj))) #define DATA_PTR(d) (RDATA(d)->data) #define DATA_TYPE(d) (RDATA(d)->type) MRB_API void mrb_data_check_type(mrb_state *mrb, mrb_value, const mrb_data_type*); diff --git a/mruby/include/mruby/debug.h b/mruby/include/mruby/debug.h index 4a62cce4..f0409351 100644 --- a/mruby/include/mruby/debug.h +++ b/mruby/include/mruby/debug.h @@ -10,7 +10,7 @@ #include "common.h" /** - * MRuby Debugging. + * mruby Debugging. */ MRB_BEGIN_DECL @@ -46,7 +46,7 @@ typedef struct mrb_irep_debug_info { } mrb_irep_debug_info; /* - * get line from irep's debug info and program counter + * get filename from irep's debug info and program counter * @return returns NULL if not found */ MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, uint32_t pc); @@ -57,6 +57,12 @@ MRB_API const char *mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, */ MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc); +/* + * get line and filename from irep's debug info and program counter + * @return returns FALSE if not found + */ +MRB_API mrb_bool mrb_debug_get_position(mrb_state *mrb, const mrb_irep *irep, uint32_t pc, int32_t *lp, const char **fp); + MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep); MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file( mrb_state *mrb, mrb_irep_debug_info *info, diff --git a/mruby/include/mruby/endian.h b/mruby/include/mruby/endian.h index 477f3bc9..940c47ea 100644 --- a/mruby/include/mruby/endian.h +++ b/mruby/include/mruby/endian.h @@ -34,7 +34,7 @@ static inline int check_little_endian(void) { unsigned int n = 1; - return (*(unsigned char *)&n == 1); + return (*(unsigned char*)&n == 1); } # define littleendian check_little_endian() #endif diff --git a/mruby/include/mruby/error.h b/mruby/include/mruby/error.h index ccf2cdb6..5f7ec43b 100644 --- a/mruby/include/mruby/error.h +++ b/mruby/include/mruby/error.h @@ -10,7 +10,7 @@ #include "common.h" /** - * MRuby error handling. + * mruby error handling. */ MRB_BEGIN_DECL @@ -34,12 +34,8 @@ struct RException { MRB_API mrb_noreturn 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); #define mrb_exc_new_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit)) -MRB_API mrb_value mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv); MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...); -/* declaration for `fail` method */ -MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); - #if defined(MRB_64BIT) || defined(MRB_USE_FLOAT32) || defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING) struct RBreak { MRB_OBJECT_HEADER; @@ -74,6 +70,15 @@ mrb_break_value_set(struct RBreak *brk, mrb_value val) #define mrb_break_proc_get(brk) ((brk)->proc) #define mrb_break_proc_set(brk, p) ((brk)->proc = p) +/** + * Error check + * + */ +/* clear error status in the mrb_state structure */ +MRB_API void mrb_clear_error(mrb_state *mrb); +/* returns TRUE if error in the previous call; internally calls mrb_clear_error() */ +MRB_API mrb_bool mrb_check_error(mrb_state *mrb); + /** * Protect * diff --git a/mruby/include/mruby/gc.h b/mruby/include/mruby/gc.h index ba56cefd..ab50e08a 100644 --- a/mruby/include/mruby/gc.h +++ b/mruby/include/mruby/gc.h @@ -41,48 +41,37 @@ typedef enum { #pragma warning(disable : 4200) #endif -typedef struct mrb_heap_page { - struct RBasic *freelist; - struct mrb_heap_page *prev; - struct mrb_heap_page *next; - struct mrb_heap_page *free_next; - struct mrb_heap_page *free_prev; - mrb_bool old:1; - /* Flexible array members area a C99 feature, not C++ compatible */ - /* void* objects[]; */ -} mrb_heap_page; - #ifdef _MSC_VER #pragma warning(pop) #endif typedef struct mrb_gc { - mrb_heap_page *heaps; /* heaps for GC */ - mrb_heap_page *sweeps; - mrb_heap_page *free_heaps; - size_t live; /* count of live objects */ + struct mrb_heap_page *heaps; /* all heaps pages */ + struct mrb_heap_page *free_heaps;/* heaps for allocation */ + struct mrb_heap_page *sweeps; /* page where sweep starts */ + struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */ + struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */ + size_t live; /* count of live objects */ + size_t live_after_mark; /* old generation objects */ + size_t threshold; /* threshold to start GC */ + size_t oldgen_threshold; /* threshold to kick major GC */ + mrb_gc_state state; /* current state of gc */ + int interval_ratio; + int step_ratio; + int current_white_part :2; /* make white object by white_part */ + mrb_bool iterating :1; /* currently iterating over objects */ + mrb_bool disabled :1; /* GC disabled */ + mrb_bool generational :1; /* generational GC mode */ + mrb_bool full :1; /* major GC mode */ + mrb_bool out_of_memory :1; /* out-of-memory error occurred */ + #ifdef MRB_GC_FIXED_ARENA struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */ #else struct RBasic **arena; /* GC protection array */ - int arena_capa; + int arena_capa; /* size of protection array */ #endif int arena_idx; - - mrb_gc_state state; /* state of gc */ - int current_white_part; /* make white object by white_part */ - struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */ - struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */ - size_t live_after_mark; - size_t threshold; - int interval_ratio; - int step_ratio; - mrb_bool iterating :1; - mrb_bool disabled :1; - mrb_bool full :1; - mrb_bool generational :1; - mrb_bool out_of_memory :1; - size_t majorgc_old_threshold; } mrb_gc; MRB_API mrb_bool mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object); diff --git a/mruby/include/mruby/internal.h b/mruby/include/mruby/internal.h index db64fd38..37c6fa1f 100644 --- a/mruby/include/mruby/internal.h +++ b/mruby/include/mruby/internal.h @@ -12,6 +12,8 @@ void mrb_ary_decref(mrb_state*, mrb_shared_array*); mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len); #endif +mrb_bool mrb_inspect_recursive_p(mrb_state *mrb, mrb_value self); + #ifdef MRUBY_CLASS_H struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym); struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym); @@ -23,11 +25,16 @@ mrb_value mrb_mod_to_s(mrb_state *, mrb_value); void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); mrb_method_t mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid); +mrb_value mrb_mod_const_missing(mrb_state *mrb, mrb_value mod); +mrb_value mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym); +size_t mrb_class_mt_memsize(mrb_state*, struct RClass*); #endif +mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); + /* debug */ size_t mrb_packed_int_len(uint32_t num); -size_t mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend); +size_t mrb_packed_int_encode(uint32_t num, uint8_t *p); uint32_t mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos); /* dump */ @@ -51,6 +58,8 @@ mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); mrb_value mrb_get_backtrace(mrb_state *mrb); void mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg); mrb_value mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc); +mrb_value mrb_f_raise(mrb_state*, mrb_value); +mrb_value mrb_make_exception(mrb_state *mrb, mrb_value exc, mrb_value mesg); /* gc */ void mrb_gc_mark_mt(mrb_state*, struct RClass*); @@ -89,6 +98,9 @@ mrb_value mrb_int_sub(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y); mrb_noreturn void mrb_int_zerodiv(mrb_state *mrb); mrb_noreturn void mrb_int_overflow(mrb_state *mrb, const char *reason); +#ifndef MRB_NO_FLOAT +void mrb_check_num_exact(mrb_state *mrb, mrb_float num); +#endif #ifdef MRB_USE_COMPLEX mrb_value mrb_complex_new(mrb_state *mrb, mrb_float x, mrb_float y); @@ -112,6 +124,11 @@ struct RProc *mrb_closure_new(mrb_state*, const mrb_irep*); void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b); mrb_int mrb_proc_arity(const struct RProc *p); struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc); +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_proc_local_variables(mrb_state *mrb, const struct RProc *proc); +const struct RProc *mrb_proc_get_caller(mrb_state *mrb, struct REnv **env); +mrb_value mrb_proc_get_self(mrb_state *mrb, struct RProc *p, struct RClass **target_class_p); +mrb_bool mrb_proc_eql(mrb_state *mrb, mrb_value self, mrb_value other); #endif /* range */ @@ -171,21 +188,28 @@ mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); #ifdef MRB_USE_BIGINT mrb_value mrb_bint_new_int(mrb_state *mrb, mrb_int x); +#ifdef MRB_INT64 +#define mrb_bint_new_int64(mrb,x) mrb_bint_new_int((mrb),(mrb_int)(x)) +#else +mrb_value mrb_bint_new_int64(mrb_state *mrb, int64_t x); +#endif +mrb_value mrb_bint_new_uint64(mrb_state *mrb, uint64_t x); mrb_value mrb_bint_new_str(mrb_state *mrb, const char *x, mrb_int len, mrb_int base); mrb_value mrb_as_bint(mrb_state *mrb, mrb_value x); mrb_value mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_add_d(mrb_state *mrb, mrb_value x, mrb_value y); +mrb_value mrb_bint_sub_d(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_mul(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_div(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_divmod(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_add_ii(mrb_state *mrb, mrb_int x, mrb_int y); mrb_value mrb_bint_sub_ii(mrb_state *mrb, mrb_int x, mrb_int y); mrb_value mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y); -mrb_value mrb_bint_div_ii(mrb_state *mrb, mrb_int x, mrb_int y); mrb_value mrb_bint_mod(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_rem(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_pow(mrb_state *mrb, mrb_value x, mrb_value y); -mrb_value mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_int y, mrb_value z); +mrb_value mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_value y, mrb_value z); mrb_value mrb_bint_and(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_or(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_bint_xor(mrb_state *mrb, mrb_value x, mrb_value y); @@ -198,6 +222,12 @@ mrb_value mrb_bint_new_float(mrb_state *mrb, mrb_float x); mrb_float mrb_bint_as_float(mrb_state *mrb, mrb_value x); #endif mrb_int mrb_bint_as_int(mrb_state *mrb, mrb_value x); +#ifdef MRB_INT64 +#define mrb_bint_as_int64(mrb, x) mrb_bint_as_int((mrb), (x)) +#else +int64_t mrb_bint_as_int64(mrb_state *mrb, mrb_value x); +#endif +uint64_t mrb_bint_as_uint64(mrb_state *mrb, mrb_value x); mrb_int mrb_bint_cmp(mrb_state *mrb, mrb_value x, mrb_value y); void mrb_gc_free_bint(mrb_state *mrb, struct RBasic *x); void mrb_bint_copy(mrb_state *mrb, mrb_value x, mrb_value y); diff --git a/mruby/include/mruby/khash.h b/mruby/include/mruby/khash.h index 1fb6eecb..c413ebbb 100644 --- a/mruby/include/mruby/khash.h +++ b/mruby/include/mruby/khash.h @@ -102,8 +102,8 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \ if (!p) { return 1; } \ h->size = 0; \ - h->keys = (khkey_t *)p; \ - h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \ + h->keys = (khkey_t*)p; \ + h->vals = kh_is_map ? (khval_t*)(p+sizeof(khkey_t)*sz) : NULL; \ h->ed_flags = p+len*sz; \ kh_fill_flags(h->ed_flags, 0xaa, sz/4); \ return 0; \ @@ -171,7 +171,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) hh.n_buckets = new_n_buckets; \ kh_alloc_##name(mrb, &hh); \ /* relocate */ \ - for (i=0 ; ic->cibase`. + * + * #include + * #include + * #include + * + * int + * main(int argc, char **argv) + * { + * mrb_state *mrb; + * mrbc_context *cxt; + * mrb_value blk, ret; + * + * mrb = mrb_open(); + * cxt = mrbc_context_new(mrb); + * blk = mrb_load_string_cxt(mrb, "x, y, z = 1, 2, 3; proc { [x, y, z] }", cxt); + * mrb_vm_ci_env_clear(mrb, mrb->c->cibase); + * mrb_load_string_cxt(mrb, "x, y, z = 4, 5, 6", cxt); + * ret = mrb_funcall(mrb, blk, "call", 0); + * mrb_p(mrb, ret); // => [1, 2, 3] + * // => [4, 5, 6] if `mrb_vm_ci_env_clear()` is commented out + * mrbc_context_free(mrb, cxt); + * mrb_close(mrb); + * + * return 0; + * } + * + * The top-level local variable names stored in `mrbc_context` are retained. + * Use also `mrbc_cleanup_local_variables()` at the same time, if necessary. + */ +MRB_API void mrb_vm_ci_env_clear(mrb_state *mrb, mrb_callinfo *ci); + void mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p); struct RClass * mrb_vm_ci_target_class(const mrb_callinfo *ci); void mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc); diff --git a/mruby/include/mruby/value.h b/mruby/include/mruby/value.h index 6666a9c1..71cdaca3 100644 --- a/mruby/include/mruby/value.h +++ b/mruby/include/mruby/value.h @@ -10,7 +10,7 @@ #include "common.h" /* - * MRuby Value definition functions and macros. + * mruby Value definition functions and macros. */ MRB_BEGIN_DECL @@ -125,7 +125,7 @@ MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...); # define isinf(n) (!_finite(n) && !_isnan(n)) # define signbit(n) (_copysign(1.0, (n)) < 0.0) static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; -# define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE) +# define INFINITY (*(float*)&IEEE754_INFINITY_BITS_SINGLE) # define NAN ((float)(INFINITY - INFINITY)) # endif #endif @@ -186,7 +186,7 @@ MRB_VTYPE_FOREACH(MRB_VTYPE_TYPEDEF) /** * @abstract - * MRuby value boxing. + * mruby value boxing. * * Actual implementation depends on configured boxing type. * diff --git a/mruby/lib/mruby/build.rb b/mruby/lib/mruby/build.rb index 4925cee3..9dff12cf 100644 --- a/mruby/lib/mruby/build.rb +++ b/mruby/lib/mruby/build.rb @@ -1,12 +1,16 @@ require "mruby/core_ext" require "mruby/build/load_gems" require "mruby/build/command" +autoload :Find, "find" module MRuby autoload :Gem, "mruby/gem" autoload :Lockfile, "mruby/lockfile" autoload :Presym, "mruby/presym" + INSTALL_PREFIX = ENV['PREFIX'] || ENV['INSTALL_PREFIX'] || '/usr/local' + INSTALL_DESTDIR = ENV['DESTDIR'] || '' + class << self def targets @targets ||= {} @@ -97,6 +101,7 @@ def initialize(name='host', build_dir=nil, internal: false, &block) @file_separator = '/' @build_dir = "#{build_dir}/#{@name}" @gem_clone_dir = "#{build_dir}/repos/#{@name}" + @install_prefix = nil @defines = [] @cc = Command::Compiler.new(self, %w(.c), label: "CC") @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp), label: "CXX") @@ -162,9 +167,7 @@ def debug_enabled? def enable_debug compilers.each do |c| c.defines += %w(MRB_DEBUG) - if toolchains.any? { |toolchain| toolchain == "gcc" } - c.flags += %w(-g3 -O0) - end + c.setup_debug(self) end @mrbc.compile_options += ' -g' @@ -370,14 +373,35 @@ def define_rules end end - def define_installer(src) - dst = "#{self.class.install_dir}/#{File.basename(src)}" + def define_installer_outline(src, dst) file dst => src do - install_D src, dst + _pp "GEN", src.relative_path, dst.relative_path + mkdir_p(File.dirname(dst)) + yield dst end dst end + if ENV['OS'] == 'Windows_NT' + def define_installer(src) + dst = "#{self.class.install_dir}/#{File.basename(src)}".pathmap("%X.bat") + define_installer_outline(src, dst) do + File.write dst, <<~BATCHFILE + @echo off + call "#{File.expand_path(src)}" %* + BATCHFILE + end + end + else + def define_installer(src) + dst = "#{self.class.install_dir}/#{File.basename(src)}" + define_installer_outline(src, dst) do + File.unlink(dst) rescue nil + File.symlink(File.expand_path(src), dst) + end + end + end + def define_installer_if_needed(bin) exe = exefile("#{build_dir}/bin/#{bin}") host? ? define_installer(exe) : exe @@ -440,10 +464,10 @@ def run_test 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 env = {"BUILD_DIR" => @build_dir, "MRBCFILE" => mrbc} - sh env, "ruby test/bintest.rb#{verbose_flag} #{targets.join ' '}" + bintest = File.join(MRUBY_ROOT, "test/bintest.rb") + sh env, "ruby #{bintest}#{verbose_flag} #{targets.join ' '}" end def print_build_summary @@ -485,6 +509,29 @@ def internal? @internal end + def each_header_files(&block) + return to_enum(__method__) unless block + + basedir = File.join(MRUBY_ROOT, "include") + Find.find(basedir) do |d| + next unless File.file? d + yield d + end + + @gems.each { |g| g.each_header_files(&block) } + + self + end + + def install_prefix + @install_prefix || (self.name == "host" ? MRuby::INSTALL_PREFIX : + File.join(MRuby::INSTALL_PREFIX, "mruby/#{self.name}")) + end + + def install_prefix=(dir) + @install_prefix = dir&.to_s + end + protected attr_writer :presym @@ -554,7 +601,6 @@ def run_test 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 @@ -565,7 +611,8 @@ def run_bintest "MRBCFILE" => mrbc, "EMULATOR" => @test_runner.emulator, } - sh env, "ruby test/bintest.rb#{verbose_flag} #{targets.join ' '}" + bintest = File.join(MRUBY_ROOT, "test/bintest.rb") + sh env, "ruby #{bintest}#{verbose_flag} #{targets.join ' '}" end protected diff --git a/mruby/lib/mruby/build/command.rb b/mruby/lib/mruby/build/command.rb index c8a3037e..e40b1553 100644 --- a/mruby/lib/mruby/build/command.rb +++ b/mruby/lib/mruby/build/command.rb @@ -99,12 +99,16 @@ def define_rules(build_dir, source_dir='', out_ext=build.exts.object) gemrake = File.join(source_dir, "mrbgem.rake") rakedep = File.exist?(gemrake) ? [ gemrake ] : [] - if build_dir.include? "mrbgems/" + bd = build_dir + if bd.start_with?(MRUBY_ROOT) + bd = bd.sub(MRUBY_ROOT, '') + end + if bd.include? "mrbgems/" generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(?!mrbc/)(.*)#{Regexp.escape out_ext}$") else generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(?!mrbc/|mrbgems/.+/)(.*)#{Regexp.escape out_ext}$") end - source_exts.each do |ext, compile| + source_exts.each do |ext| rule generated_file_matcher => [ proc { |file| file.sub(generated_file_matcher, "#{source_dir}/\\1#{ext}") @@ -129,6 +133,12 @@ def define_rules(build_dir, source_dir='', out_ext=build.exts.object) end end + # This method can be redefined as a singleton method where appropriate. + # Manipulate `flags`, `include_paths` and/or more if necessary. + def setup_debug(conf) + nil + end + private # @@ -335,7 +345,7 @@ def run(out, infiles, funcname, cdump: true, static: false) opt << " -s" if static cmd = %["#{filename @command}" #{opt} #{filename(infiles).map{|f| %["#{f}"]}.join(' ')}] puts cmd if Rake.verbose - IO.popen(cmd, 'r+') do |io| + IO.popen(cmd, 'r') do |io| out.puts io.read end # if mrbc execution fail, drop the file diff --git a/mruby/lib/mruby/core_ext.rb b/mruby/lib/mruby/core_ext.rb index 1ad528c2..ac273764 100644 --- a/mruby/lib/mruby/core_ext.rb +++ b/mruby/lib/mruby/core_ext.rb @@ -22,6 +22,27 @@ def relative_path def remove_leading_parents Pathname.new(".#{Pathname.new("/#{self}").cleanpath}").cleanpath.to_s end + + def replace_prefix_by(dirmap) + [self].replace_prefix_by(dirmap)[0] + end +end + +class Array + # Replace the prefix of each string that is a file path that contains in its own array. + # + # dirmap is a hash whose elements are `{ "path/to/old-prefix" => "path/to/new-prefix", ... }`. + # If it does not match any element of dirmap, the file path is not replaced. + def replace_prefix_by(dirmap) + dirmap = dirmap.map { |older, newer| [File.join(older, "/"), File.join(newer, "/")] } + dirmap.sort! + dirmap.reverse! + self.flatten.map do |e| + map = dirmap.find { |older, newer| e.start_with?(older) } + e = e.sub(map[0], map[1]) if map + e + end + end end def install_D(src, dst) diff --git a/mruby/lib/mruby/gem.rb b/mruby/lib/mruby/gem.rb index 64c6f3de..35aa2bd5 100644 --- a/mruby/lib/mruby/gem.rb +++ b/mruby/lib/mruby/gem.rb @@ -36,6 +36,7 @@ class Specification attr_accessor :export_include_paths attr_reader :generate_functions + attr_writer :skip_test attr_block MRuby::Build::COMMANDS @@ -62,6 +63,7 @@ def setup @test_preload = nil # 'test/assert.rb' @test_args = {} + @skip_test = false @bins = [] @cdump = true @@ -87,6 +89,10 @@ def setup build.locks[repo_url]['version'] = version if repo_url end + def skip_test? + @skip_test + end + def setup_compilers (core? ? [@cc, *(@cxx if build.cxx_exception_enabled?)] : compilers).each do |compiler| compiler.define_rules build_dir, @dir, @build.exts.presym_preprocessed if build.presym_enabled? @@ -209,7 +215,6 @@ def generate_gem_init(fname) f.puts %Q[void mrb_#{funcname}_gem_final(mrb_state *mrb);] f.puts %Q[] f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {] - f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] f.puts %Q[ gem_mrblib_#{funcname}_proc_init_syms(mrb);] if !rbfiles.empty? && cdump? f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")] unless rbfiles.empty? @@ -218,16 +223,7 @@ def generate_gem_init(fname) else f.puts %Q[ mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});] end - f.puts %Q[ if (mrb->exc) {] - f.puts %Q[ mrb_print_error(mrb);] - f.puts %Q[ mrb_close(mrb);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - f.puts %Q[ struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);] - f.puts %Q[ mrb_vm_ci_env_set(mrb->c->cibase, NULL);] - f.puts %Q[ mrb_env_unshare(mrb, e, FALSE);] end - f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] f.puts %Q[}] f.puts %Q[] f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_final(mrb_state *mrb) {] @@ -241,6 +237,8 @@ def print_gem_comment(f) f.puts %Q[ * This file is loading the irep] f.puts %Q[ * Ruby GEM code.] f.puts %Q[ *] + f.puts %Q[ * This file was generated by mruby/#{__FILE__.relative_path_from(MRUBY_ROOT)}.] + f.puts %Q[ *] f.puts %Q[ * IMPORTANT:] f.puts %Q[ * This file was generated!] f.puts %Q[ * All manual changes will get lost.] @@ -292,6 +290,19 @@ def version_ok?(req_versions) end end.all? end + + def each_header_files(&block) + return to_enum(__method__) unless block + + self.export_include_paths.flatten.uniq.compact.each do |dir| + Find.find(dir) do |d| + next unless File.file? d + yield d + end + end + + self + end end # Specification class Version diff --git a/mruby/lib/mruby/presym.rb b/mruby/lib/mruby/presym.rb index 7f74569f..8ade2480 100644 --- a/mruby/lib/mruby/presym.rb +++ b/mruby/lib/mruby/presym.rb @@ -46,6 +46,18 @@ class Presym C_STR_LITERAL_RE = /"(?:[^\\\"]|\\.)*"/ + ESCAPE_SEQUENCE_MAP = { + "a" => "\a", + "b" => "\b", + "e" => "\e", + "f" => "\f", + "n" => "\n", + "r" => "\r", + "t" => "\t", + "v" => "\v", + } + ESCAPE_SEQUENCE_MAP.keys.each { |k| ESCAPE_SEQUENCE_MAP[ESCAPE_SEQUENCE_MAP[k]] = k } + def initialize(build) @build = build end @@ -93,7 +105,18 @@ def write_table_header(presyms) f.puts "};" f.puts f.puts "static const char * const presym_name_table[] = {" - presyms.each{|sym| f.puts %| "#{sym}",|} + presyms.each do |sym| + sym = sym.gsub(/([\x01-\x1f\x7f-\xff])|("|\\)/n) { + case + when $1 + e = ESCAPE_SEQUENCE_MAP[$1] + e ? "\\#{e}" : '\\x%02x""' % $1.ord + when $2 + "\\#$2" + end + } + f.puts %| "#{sym}",| + end f.puts "};" end end @@ -119,7 +142,20 @@ def table_header_path def read_preprocessed(presym_hash, path) File.binread(path).scan(/<@! (.*?) !@>/) do |part,| literals = part.scan(C_STR_LITERAL_RE) - presym_hash[literals.map{|l| l[1..-2]}.join] = true unless literals.empty? + unless literals.empty? + literals = literals.map{|l| l[1..-2]} + literals.each do |e| + e.gsub!(/\\x([0-9A-Fa-f]{1,2})|\\(0[0-7]{,3})|\\([abefnrtv])|\\(.)/) do + case + when $1; $1.hex.chr(Encoding::BINARY) + when $2; $2.oct.chr(Encoding::BINARY) + when $3; ESCAPE_SEQUENCE_MAP[$3] + when $4; $4 + end + end + end + presym_hash[literals.join] = true + end end end diff --git a/mruby/mrbgems/default.gembox b/mruby/mrbgems/default.gembox index ae2de2ac..1143b198 100644 --- a/mruby/mrbgems/default.gembox +++ b/mruby/mrbgems/default.gembox @@ -8,6 +8,9 @@ MRuby::GemBox.new do |conf| # Generate mrbc command conf.gem :core => "mruby-bin-mrbc" + # Generate mrdb command + conf.gem :core => "mruby-bin-debugger" + # Generate mirb command conf.gem :core => "mruby-bin-mirb" diff --git a/mruby/mrbgems/mruby-array-ext/src/array.c b/mruby/mrbgems/mruby-array-ext/src/array.c index 385ad511..02e7834b 100644 --- a/mruby/mrbgems/mruby-array-ext/src/array.c +++ b/mruby/mrbgems/mruby-array-ext/src/array.c @@ -27,7 +27,7 @@ */ static mrb_value -mrb_ary_assoc(mrb_state *mrb, mrb_value ary) +ary_assoc(mrb_state *mrb, mrb_value ary) { mrb_int i; mrb_value v; @@ -57,7 +57,7 @@ mrb_ary_assoc(mrb_state *mrb, mrb_value ary) */ static mrb_value -mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) +ary_rassoc(mrb_state *mrb, mrb_value ary) { mrb_int i; mrb_value v; @@ -87,10 +87,9 @@ mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) */ static mrb_value -mrb_ary_at(mrb_state *mrb, mrb_value ary) +ary_at(mrb_state *mrb, mrb_value ary) { - mrb_int pos; - mrb_get_args(mrb, "i", &pos); + mrb_int pos = mrb_as_int(mrb, mrb_get_arg1(mrb)); return mrb_ary_entry(ary, pos); } @@ -102,7 +101,7 @@ ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) } static mrb_value -mrb_ary_values_at(mrb_state *mrb, mrb_value self) +ary_values_at(mrb_state *mrb, mrb_value self) { mrb_int argc = mrb_get_argc(mrb); const mrb_value *argv = mrb_get_argv(mrb); @@ -134,7 +133,7 @@ mrb_value mrb_ary_delete_at(mrb_state *mrb, mrb_value self); */ static mrb_value -mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) +ary_slice_bang(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); mrb_int i, j, len, alen; @@ -187,7 +186,7 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) */ static mrb_value -mrb_ary_compact(mrb_state *mrb, mrb_value self) +ary_compact(mrb_state *mrb, mrb_value self) { mrb_value ary = mrb_ary_new(mrb); mrb_int len = RARRAY_LEN(self); @@ -213,7 +212,7 @@ mrb_ary_compact(mrb_state *mrb, mrb_value self) * [ "a", "b", "c" ].compact! #=> nil */ static mrb_value -mrb_ary_compact_bang(mrb_state *mrb, mrb_value self) +ary_compact_bang(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); mrb_int i, j = 0; @@ -250,7 +249,7 @@ mrb_ary_compact_bang(mrb_state *mrb, mrb_value self) * a.rotate(-3) #=> ["b", "c", "d", "a"] */ static mrb_value -mrb_ary_rotate(mrb_state *mrb, mrb_value self) +ary_rotate(mrb_state *mrb, mrb_value self) { mrb_int count=1; mrb_get_args(mrb, "|i", &count); @@ -301,7 +300,7 @@ rev(mrb_value *p, mrb_int beg, mrb_int end) * a.rotate!(-3) #=> ["a", "b", "c", "d"] */ static mrb_value -mrb_ary_rotate_bang(mrb_state *mrb, mrb_value self) +ary_rotate_bang(mrb_state *mrb, mrb_value self) { mrb_int count=1; mrb_get_args(mrb, "|i", &count); @@ -347,15 +346,15 @@ mrb_mruby_array_ext_gem_init(mrb_state* mrb) { struct RClass * a = mrb->array_class; - mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, MRB_ARGS_REQ(1)); - 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, "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)); + mrb_define_method(mrb, a, "assoc", ary_assoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "at", ary_at, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "rassoc", ary_rassoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "values_at", ary_values_at, MRB_ARGS_ANY()); + mrb_define_method(mrb, a, "slice!", ary_slice_bang, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, a, "compact", ary_compact, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "compact!", ary_compact_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "rotate", ary_rotate, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, a, "rotate!", ary_rotate_bang, MRB_ARGS_OPT(1)); } void diff --git a/mruby/mrbgems/mruby-bigint/core/bigint.c b/mruby/mrbgems/mruby-bigint/core/bigint.c index 5c757729..97f54547 100644 --- a/mruby/mrbgems/mruby-bigint/core/bigint.c +++ b/mruby/mrbgems/mruby-bigint/core/bigint.c @@ -78,7 +78,7 @@ mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) y->sn = 1; u = v; } - if (v < 0) { + else /* if (v < 0) */ { y->sn = -1; if (v == MRB_INT_MIN) u = v; else u = -v; @@ -97,6 +97,39 @@ mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) } } +static void +mpz_set_uint64(mrb_state *mrb, mpz_t *y, uint64_t u) +{ + const size_t len = sizeof(uint64_t) / sizeof(mp_limb); + + y->sn = (u != 0); + mpz_realloc(mrb, y, len); + for (size_t i=0; ip[i++] = (mp_limb)LOW(u); + u >>= DIG_SIZE; + } +} + +#ifdef MRB_INT32 +static void +mpz_set_int64(mrb_state *mrb, mpz_t *y, int64_t v) +{ + uint64_t u; + + if (v < 0) { + if (v == INT64_MIN) u = v; + else u = -v; + } + else { + u = v; + } + mpz_set_uint64(mrb, y, u); + if (v < 0) { + y->sn = -1; + } +} +#endif + static void mpz_init_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) { @@ -131,7 +164,7 @@ digits(mpz_t *x) size_t i; if (x->sz == 0) return 0; - for (i = x->sz - 1; x->p[i] == 0 ; i--) + for (i = x->sz - 1; x->p[i] == 0; i--) if (i == 0) break; return i+1; } @@ -362,7 +395,7 @@ lzb(mp_limb x) int j=0; - for (mp_limb i = ((mp_limb)1 << (DIG_SIZE-1)); i && !(x&i) ; j++,i>>=1) + for (mp_limb i = ((mp_limb)1 << (DIG_SIZE-1)); i && !(x&i); j++,i>>=1) ; return j; } @@ -909,7 +942,41 @@ mpz_pow(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int e) } static void -mpz_powm(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int ex, mpz_t *n) +mpz_powm(mrb_state *mrb, mpz_t *zz, mpz_t *x, mpz_t *ex, mpz_t *n) +{ + mpz_t t, b; + + if (uzero(ex)) { + mpz_set_int(mrb, zz, 1); + return; + } + + if (ex->sn < 0) { + return; + } + + mpz_init_set_int(mrb, &t, 1); + mpz_init_set(mrb, &b, x); + + size_t len = digits(ex); + for (size_t i=0; ip[i]; + for (size_t j=0; j>= 1; + mpz_mul(mrb, &b, &b, &b); + mpz_mod(mrb, &b, &b, n); + } + } + mpz_move(mrb, zz, &t); + mpz_clear(mrb, &b); +} + +static void +mpz_powm_i(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int ex, mpz_t *n) { mpz_t t, b; @@ -956,16 +1023,29 @@ bint_new_int(mrb_state *mrb, mrb_int x) } mrb_value -mrb_bint_new(mrb_state *mrb) +mrb_bint_new_int(mrb_state *mrb, mrb_int x) +{ + struct RBigint *b = bint_new_int(mrb, x); + return mrb_obj_value(b); +} + +#ifdef MRB_INT32 +mrb_value +mrb_bint_new_int64(mrb_state *mrb, int64_t x) { struct RBigint *b = bint_new(mrb); + mpz_init(mrb, &b->mp); + mpz_set_int64(mrb, &b->mp, x); return mrb_obj_value(b); } +#endif mrb_value -mrb_bint_new_int(mrb_state *mrb, mrb_int x) +mrb_bint_new_uint64(mrb_state *mrb, uint64_t x) { - struct RBigint *b = bint_new_int(mrb, x); + struct RBigint *b = bint_new(mrb); + mpz_init(mrb, &b->mp); + mpz_set_uint64(mrb, &b->mp, x); return mrb_obj_value(b); } @@ -1086,6 +1166,61 @@ mrb_bint_as_int(mrb_state *mrb, mrb_value x) return i; } +#ifdef MRB_INT32 +int64_t +mrb_bint_as_int64(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + mpz_t *m = &b->mp; + uint64_t u = 0; + size_t len = digits(m); + + if (len*sizeof(mp_limb) > sizeof(uint64_t)) { + out_of_range: + mrb_raise(mrb, E_RANGE_ERROR, "integer out of range"); + } + for (size_t i=len-1; ; i--) { + u <<= DIG_SIZE; + u |= m->p[i]; + if (i==0) break; + } + if (u > INT64_MAX) goto out_of_range; + if (m->sn < 0) return -(int64_t)u; + return (int64_t)u; +} +#endif + +uint64_t +mrb_bint_as_uint64(mrb_state *mrb, mrb_value x) +{ + struct RBigint *b = RBIGINT(x); + mpz_t *m = &b->mp; + uint64_t u = 0; + size_t len = digits(m); + + if (m->sn < 0 || len*sizeof(mp_limb) > sizeof(uint64_t)) { + mrb_raise(mrb, E_RANGE_ERROR, "integer out of range"); + } + for (size_t i=len-1; ; i--) { + u <<= DIG_SIZE; + u |= m->p[i]; + if (i==0) break; + } + return u; +} + +/* unnormalize version of mrb_bint_add */ +mrb_value +mrb_bint_add_d(mrb_state *mrb, mrb_value x, mrb_value y) +{ + y = mrb_as_bint(mrb, y); + struct RBigint *b = RBIGINT(x); + struct RBigint *b2 = RBIGINT(y); + struct RBigint *b3 = bint_new(mrb); + mpz_add(mrb, &b3->mp, &b->mp, &b2->mp); + return mrb_obj_value(b3); +} + mrb_value mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) { @@ -1096,12 +1231,20 @@ mrb_bint_add(mrb_state *mrb, mrb_value x, mrb_value y) return mrb_float_value(mrb,v1+v2); } #endif + x = mrb_bint_add_d(mrb, x, y); + return bint_norm(mrb, RBIGINT(x)); +} + +/* unnormalize version of mrb_bint_sub */ +mrb_value +mrb_bint_sub_d(mrb_state *mrb, mrb_value x, mrb_value y) +{ y = mrb_as_bint(mrb, y); struct RBigint *b = RBIGINT(x); struct RBigint *b2 = RBIGINT(y); struct RBigint *b3 = bint_new(mrb); - mpz_add(mrb, &b3->mp, &b->mp, &b2->mp); - return bint_norm(mrb, b3); + mpz_sub(mrb, &b3->mp, &b->mp, &b2->mp); + return mrb_obj_value(b3); } mrb_value @@ -1114,12 +1257,8 @@ mrb_bint_sub(mrb_state *mrb, mrb_value x, mrb_value y) return mrb_float_value(mrb,v1-v2); } #endif - y = mrb_as_bint(mrb, y); - struct RBigint *b = RBIGINT(x); - struct RBigint *b2 = RBIGINT(y); - struct RBigint *b3 = bint_new(mrb); - mpz_sub(mrb, &b3->mp, &b->mp, &b2->mp); - return bint_norm(mrb, b3); + x = mrb_bint_sub_d(mrb, x, y); + return bint_norm(mrb, RBIGINT(x)); } mrb_value @@ -1206,20 +1345,6 @@ mrb_bint_mul_ii(mrb_state *mrb, mrb_int x, mrb_int y) return bint_norm(mrb, b); } -mrb_value -mrb_bint_div_ii(mrb_state *mrb, mrb_int x, mrb_int y) -{ - struct RBigint *b = bint_new(mrb); - mpz_t z1, z2; - - mpz_init_set_int(mrb, &z1, x); - mpz_init_set_int(mrb, &z2, y); - mpz_mdiv(mrb, &b->mp, &z1, &z2); - mpz_clear(mrb, &z1); - mpz_clear(mrb, &z2); - return bint_norm(mrb, b); -} - mrb_value mrb_bint_mod(mrb_state *mrb, mrb_value x, mrb_value y) { @@ -1334,32 +1459,36 @@ mrb_bint_pow(mrb_state *mrb, mrb_value x, mrb_value y) } mrb_value -mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_int exp, mrb_value mod) +mrb_bint_powm(mrb_state *mrb, mrb_value x, mrb_value exp, mrb_value mod) { struct RBigint *b = RBIGINT(x); - switch (mrb_type(mod)) { - case MRB_TT_INTEGER: - { - mrb_int m = mrb_integer(mod); - if (m == 0) mrb_int_zerodiv(mrb); - struct RBigint *b2 = bint_new_int(mrb, m); - struct RBigint *b3 = bint_new(mrb); - mpz_powm(mrb, &b3->mp, &b->mp, exp, &b2->mp); - return bint_norm(mrb, b3); + struct RBigint *b2, *b3; + + if (mrb_bigint_p(mod)) { + b2 = RBIGINT(mod); + if (uzero(&b2->mp)) mrb_int_zerodiv(mrb); + } + else { + mrb_int m = mrb_integer(mod); + if (m == 0) mrb_int_zerodiv(mrb); + b2 = bint_new_int(mrb, m); + } + b3 = bint_new(mrb); + if (mrb_bigint_p(exp)) { + struct RBigint *be = RBIGINT(exp); + if (be->mp.sn < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); } - case MRB_TT_BIGINT: - { - struct RBigint *b2 = RBIGINT(mod); - struct RBigint *b3 = bint_new(mrb); - if (uzero(&b2->mp)) mrb_int_zerodiv(mrb); - mpz_powm(mrb, &b3->mp, &b->mp, exp, &b2->mp); - return bint_norm(mrb, b3); + mpz_powm(mrb, &b3->mp, &b->mp, &be->mp, &b2->mp); + } + else { + mrb_int e = mrb_integer(exp); + if (e < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); } - mrb_raise(mrb, E_TYPE_ERROR, "too big power"); - default: - mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be convert to integer", mod); + mpz_powm_i(mrb, &b3->mp, &b->mp, e, &b2->mp); } - return mrb_nil_value(); + return bint_norm(mrb, b3); } mrb_value diff --git a/mruby/mrbgems/mruby-bin-config/mrbgem.rake b/mruby/mrbgems/mruby-bin-config/mrbgem.rake index b4c43764..8a484d69 100644 --- a/mruby/mrbgems/mruby-bin-config/mrbgem.rake +++ b/mruby/mrbgems/mruby-bin-config/mrbgem.rake @@ -11,7 +11,16 @@ MRuby::Gem::Specification.new('mruby-bin-config') do |spec| else mruby_config_dir = "#{build.build_dir}/bin" end - mruby_config = name + (ENV['OS'] == 'Windows_NT' ? '.bat' : '') + + if ENV['OS'] == 'Windows_NT' + suffix = '.bat' + refvar = '%\\1%' + else + suffix = '' + refvar = '${\\1}' + end + + mruby_config = name + suffix mruby_config_path = "#{mruby_config_dir}/#{mruby_config}" make_cfg = "#{build.build_dir}/lib/libmruby.flags.mak" tmplt_path = "#{__dir__}/#{mruby_config}" @@ -24,11 +33,16 @@ MRuby::Gem::Specification.new('mruby-bin-config') do |spec| directory mruby_config_dir - file mruby_config_path => [mruby_config_dir, make_cfg, tmplt_path] do |t| + file mruby_config_path => [__FILE__, mruby_config_dir, make_cfg, tmplt_path] do |t| config = Hash[File.readlines(make_cfg).map!(&:chomp).map! {|l| + l.gsub!(/\$\((\w+)\)/, refvar) l.gsub('\\"', '"').split(' = ', 2).map! {|s| s.sub(/^(?=.)/, 'echo ')} }] tmplt = File.read(tmplt_path) + tmplt.sub!(%r((?<=\A#!/bin/sh\n\n)), <<~SETDIR) + MRUBY_PACKAGE_DIR=$(dirname "$(dirname "$(readlink -f "$0")")") + + SETDIR File.write(t.name, tmplt.gsub(/(#{Regexp.union(*config.keys)})\b/, config)) chmod(0755, t.name) end diff --git a/mruby/mrbgems/mruby-bin-config/mruby-config b/mruby/mrbgems/mruby-bin-config/mruby-config index 3adda9e1..27365e65 100755 --- a/mruby/mrbgems/mruby-bin-config/mruby-config +++ b/mruby/mrbgems/mruby-bin-config/mruby-config @@ -4,8 +4,14 @@ print_help() { echo "Usage: mruby-config [switches]" echo " switches:" - echo " --cc print compiler name" - echo " --cflags print flags passed to compiler" + echo " --cc print C compiler name" + echo " --cflags print flags passed to C compiler" + echo " --cxx print C++ compiler name" + echo " --cxxflags print flags passed to C++ compiler" + echo " --as print assembler name" + echo " --asflags print flags passed to assembler" + echo " --objc print Objective C compiler name" + echo " --objcflags print flags passed to Objective C compiler" echo " --ld print linker name" echo " --ldflags print flags passed to linker" echo " --ldflags-before-libs print flags passed to linker before linked libraries" @@ -23,6 +29,12 @@ while [ $# -gt 0 ]; do case $1 in --cc) echo MRUBY_CC;; --cflags) echo MRUBY_CFLAGS;; + --cxx) echo MRUBY_CXX;; + --cxxflags) echo MRUBY_CXXFLAGS;; + --as) echo MRUBY_AS;; + --asflags) echo MRUBY_ASFLAGS;; + --objc) echo MRUBY_OBJC;; + --objcflags) echo MRUBY_OBJCFLAGS;; --ld) echo MRUBY_LD;; --ldflags) echo MRUBY_LDFLAGS;; --ldflags-before-libs) echo MRUBY_LDFLAGS_BEFORE_LIBS;; diff --git a/mruby/mrbgems/mruby-bin-config/mruby-config.bat b/mruby/mrbgems/mruby-bin-config/mruby-config.bat index 949fea06..fa7ad2a6 100644 --- a/mruby/mrbgems/mruby-bin-config/mruby-config.bat +++ b/mruby/mrbgems/mruby-bin-config/mruby-config.bat @@ -1,10 +1,28 @@ @echo off +call :init "%~dp0." +goto top + +:init +rem call init2 for treatments last directory separator +call :init2 "%~dp1." +goto :eof + +:init2 +set MRUBY_PACKAGE_DIR=%~f1 +goto :eof + :top shift if "%0" equ "" goto :eof if "%0" equ "--cc" goto cc if "%0" equ "--cflags" goto cflags +if "%0" equ "--cxx" goto cxx +if "%0" equ "--cxxflags" goto cxxflags +if "%0" equ "--as" goto as +if "%0" equ "--asflags" goto asflags +if "%0" equ "--objc" goto objc +if "%0" equ "--objcflags" goto objcflags if "%0" equ "--ld" goto ld if "%0" equ "--ldflags" goto ldflags if "%0" equ "--ldflags-before-libs" goto ldflagsbeforelibs @@ -22,6 +40,30 @@ goto top echo MRUBY_CFLAGS goto top +:cxx +echo MRUBY_CXX +goto top + +:cxxflags +echo MRUBY_CXXFLAGS +goto top + +:as +echo MRUBY_AS +goto top + +:asflags +echo MRUBY_ASFLAGS +goto top + +:objc +echo MRUBY_OBJC +goto top + +:objcflags +echo MRUBY_OBJCFLAGS +goto top + :ld echo MRUBY_LD goto top @@ -45,8 +87,14 @@ goto top :showhelp echo Usage: mruby-config [switches] echo switches: -echo --cc print compiler name -echo --cflags print flags passed to compiler +echo --cc print C compiler name +echo --cflags print flags passed to C compiler +echo --cxx print C++ compiler name +echo --cxxflags print flags passed to C++ compiler +echo --as print assembler name +echo --asflags print flags passed to assembler +echo --objc print Objective C compiler name +echo --objcflags print flags passed to Objective C compiler echo --ld print linker name echo --ldflags print flags passed to linker echo --ldflags-before-libs print flags passed to linker before linked libraries diff --git a/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake b/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake index 091851dd..f51c9a3d 100644 --- a/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake +++ b/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake @@ -2,7 +2,7 @@ MRuby::Gem::Specification.new('mruby-bin-debugger') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'mruby debugger command' - spec.build.defines |= %w(MRB_USE_DEBUG_HOOK) + spec.build.defines << "MRB_USE_DEBUG_HOOK" spec.add_dependency('mruby-eval', :core => 'mruby-eval') spec.bins = %w(mrdb) diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index a69d65dd..e3e0e666 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -68,7 +68,7 @@ get_break_index(mrb_debug_context *dbg, uint32_t bpno) int32_t index; char hit = FALSE; - for(i = 0 ; i < dbg->bpnum; i++) { + for (i = 0; i < dbg->bpnum; i++) { if (dbg->bp[i].bpno == bpno) { hit = TRUE; index = i; @@ -341,7 +341,7 @@ mrb_debug_delete_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno) free_breakpoint(mrb, &dbg->bp[index]); - for(i = index ; i < dbg->bpnum; i++) { + for (i = index; i < dbg->bpnum; i++) { if ((i + 1) == dbg->bpnum) { dbg->bp[i] = (mrb_debug_breakpoint){0}; } @@ -364,7 +364,7 @@ mrb_debug_delete_break_all(mrb_state *mrb, mrb_debug_context *dbg) return MRB_DEBUG_INVALID_ARGUMENT; } - for(i = 0 ; i < dbg->bpnum ; i++) { + for (i = 0; i < dbg->bpnum; i++) { free_breakpoint(mrb, &dbg->bp[i]); } @@ -401,7 +401,7 @@ mrb_debug_enable_break_all(mrb_state *mrb, mrb_debug_context *dbg) return MRB_DEBUG_INVALID_ARGUMENT; } - for(i = 0 ; i < dbg->bpnum; i++) { + for (i = 0; i < dbg->bpnum; i++) { dbg->bp[i].enable = TRUE; } @@ -436,7 +436,7 @@ mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg) return MRB_DEBUG_INVALID_ARGUMENT; } - for(i = 0 ; i < dbg->bpnum; i++) { + for (i = 0; i < dbg->bpnum; i++) { dbg->bp[i].enable = FALSE; } @@ -470,7 +470,7 @@ mrb_debug_check_breakpoint_line(mrb_state *mrb, mrb_debug_context *dbg, const ch } bp = dbg->bp; - for(i=0; ibpnum; i++) { + for (i=0; ibpnum; i++) { switch (bp->type) { case MRB_DEBUG_BPTYPE_LINE: if (bp->enable == TRUE) { @@ -504,7 +504,7 @@ mrb_debug_check_breakpoint_method(mrb_state *mrb, mrb_debug_context *dbg, struct } bp = dbg->bp; - for(i=0; ibpnum; i++) { + for (i=0; ibpnum; i++) { if (bp->type == MRB_DEBUG_BPTYPE_METHOD) { if (bp->enable == TRUE) { bpno = compare_break_method(mrb, bp, class_obj, method_sym, isCfunc); diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h index 08f1d808..cc272cbe 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h @@ -9,18 +9,18 @@ #include #include "mrdb.h" -int32_t mrb_debug_set_break_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); -int32_t mrb_debug_set_break_method(mrb_state *, mrb_debug_context *, const char *, const char *); -int32_t mrb_debug_get_breaknum(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_get_break_all(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint bp[]); -int32_t mrb_debug_get_break(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint *); -int32_t mrb_debug_delete_break(mrb_state *, mrb_debug_context *, uint32_t); -int32_t mrb_debug_delete_break_all(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_enable_break(mrb_state *, mrb_debug_context *, uint32_t); -int32_t mrb_debug_enable_break_all(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_disable_break(mrb_state *, mrb_debug_context *, uint32_t); -int32_t mrb_debug_disable_break_all(mrb_state *, mrb_debug_context *); -int32_t mrb_debug_check_breakpoint_line(mrb_state *, mrb_debug_context *, const char *, uint16_t); -int32_t mrb_debug_check_breakpoint_method(mrb_state *, mrb_debug_context *, struct RClass *, mrb_sym, mrb_bool*); +int32_t mrb_debug_set_break_line(mrb_state*, mrb_debug_context*, const char*, uint16_t); +int32_t mrb_debug_set_break_method(mrb_state*, mrb_debug_context*, const char*, const char*); +int32_t mrb_debug_get_breaknum(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_get_break_all(mrb_state*, mrb_debug_context*, uint32_t, mrb_debug_breakpoint bp[]); +int32_t mrb_debug_get_break(mrb_state*, mrb_debug_context*, uint32_t, mrb_debug_breakpoint*); +int32_t mrb_debug_delete_break(mrb_state*, mrb_debug_context*, uint32_t); +int32_t mrb_debug_delete_break_all(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_enable_break(mrb_state*, mrb_debug_context*, uint32_t); +int32_t mrb_debug_enable_break_all(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_disable_break(mrb_state*, mrb_debug_context*, uint32_t); +int32_t mrb_debug_disable_break_all(mrb_state*, mrb_debug_context*); +int32_t mrb_debug_check_breakpoint_line(mrb_state*, mrb_debug_context*, const char*, uint16_t); +int32_t mrb_debug_check_breakpoint_method(mrb_state*, mrb_debug_context*, struct RClass*, mrb_sym, mrb_bool*); #endif /* APIBREAK_H_ */ diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c index 27db02b4..0fc087bd 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c @@ -200,7 +200,7 @@ mrb_debug_get_source(mrb_state *mrb, mrdb_state *mrdb, const char *srcpath, cons break; } - mrb_free(mrb, (void *)search_path[1]); + mrb_free(mrb, (void*)search_path[1]); return path; } diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h index 6c410788..542fda10 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h @@ -8,7 +8,7 @@ #include #include "mrdb.h" -int32_t mrb_debug_list(mrb_state *, mrb_debug_context *, char *, uint16_t, uint16_t); -char* mrb_debug_get_source(mrb_state *, mrdb_state *, const char *, const char *); +int32_t mrb_debug_list(mrb_state*, mrb_debug_context*, char*, uint16_t, uint16_t); +char* mrb_debug_get_source(mrb_state*, mrdb_state*, const char*, const char *); #endif /* APILIST_H_ */ diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c index 9093a4f0..8b3f30ff 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c @@ -34,7 +34,7 @@ mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size mrb_value mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval) { - void (*tmp)(struct mrb_state *, const struct mrb_irep *, const mrb_code *, mrb_value *); + void (*tmp)(struct mrb_state*, const struct mrb_irep*, const mrb_code*, mrb_value*); mrb_value ruby_code; mrb_value s; mrb_value v; @@ -68,11 +68,11 @@ mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t recv = dbg->regs[0]; - v = mrb_funcall_id(mrb, recv, MRB_SYM(instance_eval), 1, ruby_code); + v = mrb_funcall_argv(mrb, recv, MRB_SYM(instance_eval), 1, &ruby_code); } if (exc) { - *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class); + *exc = mrb_obj_is_kind_of(mrb, v, E_EXCEPTION); } s = mrb_inspect(mrb, v); diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c index bc9937e9..621bb452 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c @@ -42,8 +42,8 @@ #define LINENO_MAX_DIGIT 6 #define BPNO_LETTER_NUM 9 -typedef int32_t (*all_command_func)(mrb_state *, mrb_debug_context *); -typedef int32_t (*select_command_func)(mrb_state *, mrb_debug_context *, uint32_t); +typedef int32_t (*all_command_func)(mrb_state*, mrb_debug_context*); +typedef int32_t (*select_command_func)(mrb_state*, mrb_debug_context*, uint32_t); static void print_api_common_error(int32_t error) @@ -61,7 +61,7 @@ print_api_common_error(int32_t error) #define STRTOUL(ul,s) { \ int i; \ ul = 0; \ - for(i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0'); \ + for (i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0'); \ } static int32_t @@ -106,7 +106,7 @@ exe_set_command_select(mrb_state *mrb, mrdb_state *mrdb, select_command_func fun int32_t bpno = 0; int32_t i; - for(i=1; iwcnt; i++) { + for (i=1; iwcnt; i++) { ps = mrdb->words[i]; bpno = parse_breakpoint_no(ps); if (bpno == 0) { @@ -199,7 +199,7 @@ info_break_all(mrb_state *mrb, mrdb_state *mrdb) return; } puts(BREAK_INFO_MSG_HEADER); - for(i = 0 ; i < bpnum ; i++) { + for (i = 0; i < bpnum; i++) { print_breakpoint(&bp_list[i]); } @@ -216,7 +216,7 @@ info_break_select(mrb_state *mrb, mrdb_state *mrdb) mrb_bool isFirst = TRUE; int32_t i; - for(i=2; iwcnt; i++) { + for (i=2; iwcnt; i++) { ps = mrdb->words[i]; bpno = parse_breakpoint_no(ps); if (bpno == 0) { diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c index 0714f3f2..4cf635b4 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c @@ -167,7 +167,8 @@ parse_uint(char **sp, uint16_t *n) return FALSE; } - for (p = *sp; *p != '\0' && ISDIGIT(*p); p++) ; + for (p = *sp; *p != '\0' && ISDIGIT(*p); p++) + ; if (p != *sp && (i = atoi(*sp)) >= 0) { *n = (uint16_t)i; @@ -350,9 +351,9 @@ check_cmd_pattern(const char *pattern, const char *cmd) } p = lbracket + 1; - q = (char *)cmd + (lbracket - pattern); + q = (char*)cmd + (lbracket - pattern); - for ( ; p < rbracket && *q != '\0'; p++, q++) { + for (; p < rbracket && *q != '\0'; p++, q++) { if (*p != *q) { break; } @@ -479,7 +480,8 @@ dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb) break; } c = buf; - while (buf != '\n' && (buf = getchar()) != EOF) ; + while (buf != '\n' && (buf = getchar()) != EOF) + ; if (c == 'y' || c == 'Y') { mrdb->dbg->xm = DBG_QUIT; @@ -500,7 +502,7 @@ dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb) if (mrdb->dbg->xm == DBG_QUIT) { struct RClass *exc; - exc = mrb_define_class(mrb, "DebuggerExit", mrb->eException_class); + exc = mrb_define_class(mrb, "DebuggerExit", E_EXCEPTION); mrb_raise(mrb, exc, "Exit mrdb"); } return DBGST_PROMPT; diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c index fe8cf0aa..1cd463eb 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c @@ -19,7 +19,7 @@ dbgcmd_run(mrb_state *mrb, mrdb_state *mrdb) if (dbg->xphase == DBG_PHASE_RUNNING){ struct RClass *exc; puts("Start it from the beginning"); - exc = mrb_define_class(mrb, "DebuggerRestart", mrb->eException_class); + exc = mrb_define_class(mrb, "DebuggerRestart", E_EXCEPTION); mrb_raise(mrb, exc, "Restart mrdb"); } } diff --git a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index 340a57b5..e0e3a96f 100644 --- a/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -20,7 +20,7 @@ #include "apibreak.h" #include "apilist.h" -void mrdb_state_free(mrb_state *); +void mrdb_state_free(mrb_state*); static mrb_debug_context *_debug_context = NULL; static mrdb_state *_mrdb_state = NULL; @@ -113,7 +113,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) char *buf; buflen = strlen(item) + 1; - buf = (char *)mrb_malloc(mrb, buflen); + buf = (char*)mrb_malloc(mrb, buflen); memcpy(buf, item, buflen); args->srcpath = buf; } @@ -123,8 +123,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) srcpathlen = strlen(args->srcpath); itemlen = strlen(item); - args->srcpath = - (char *)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2); + args->srcpath = (char*)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2); args->srcpath[srcpathlen] = '\n'; memcpy(args->srcpath + srcpathlen + 1, item, itemlen + 1); } @@ -280,7 +279,7 @@ get_command(mrb_state *mrb, mrdb_state *mrdb) } if (i == MAX_COMMAND_LINE) { - for ( ; (c=getchar()) != EOF && c !='\n'; i++) ; + for (; (c=getchar()) != EOF && c !='\n'; i++) ; } if (i > MAX_COMMAND_LINE) { @@ -297,7 +296,8 @@ pick_out_word(mrb_state *mrb, char **pp) { char *ps; - for (ps=*pp; ISBLANK(*ps); ps++) ; + for (ps=*pp; ISBLANK(*ps); ps++) + ; if (*ps == '\0') { return NULL; } @@ -336,7 +336,8 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) } mrdb->wcnt = 1; /* set remain parameter */ - for ( ; *p && ISBLANK(*p); p++) ; + for (; *p && ISBLANK(*p); p++) + ; if (*p) { mrdb->words[mrdb->wcnt++] = p; } @@ -356,7 +357,8 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) mrdb->words[1] = pick_out_word(mrb, &p); if (mrdb->words[1]) { /* update remain parameter */ - for ( ; *p && ISBLANK(*p); p++) ; + for (; *p && ISBLANK(*p); p++) + ; if (*p) { mrdb->words[mrdb->wcnt++] = p; } @@ -364,7 +366,7 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) } /* check word #1,#2 */ - for ( ; cmd->cmd1; cmd++) { + for (; cmd->cmd1; cmd++) { wlen = strlen(mrdb->words[0]); if (wlen < cmd->len1 || strncmp(mrdb->words[0], cmd->cmd1, wlen)) { @@ -386,7 +388,7 @@ parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) /* divide remain parameters */ if (cmd->cmd1 && cmd->div) { p = mrdb->words[--mrdb->wcnt]; - for ( ; mrdb->wcntwcnt++) { + for (; mrdb->wcntwcnt++) { mrdb->words[mrdb->wcnt] = pick_out_word(mrb, &p); if (!mrdb->words[mrdb->wcnt]) { break; diff --git a/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 78c3ed40..d4cea8d5 100644 --- a/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -95,7 +95,7 @@ get_history_path(mrb_state *mrb) int len = snprintf(NULL, 0, "%s/%s", home, history_file_name); if (len >= 0) { size_t size = len + 1; - path = (char *)mrb_malloc_simple(mrb, size); + path = (char*)mrb_malloc_simple(mrb, size); if (path != NULL) { int n = snprintf(path, size, "%s/%s", home, history_file_name); if (n != len) { @@ -117,7 +117,7 @@ p(mrb_state *mrb, mrb_value obj, int prompt) mrb_value val; char* msg; - val = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0); + val = mrb_funcall_argv(mrb, obj, MRB_SYM(inspect), 0, NULL); if (prompt) { if (!mrb->exc) { fputs(" => ", stdout); @@ -508,7 +508,6 @@ main(int argc, char **argv) /* Load libraries */ for (i = 0; i < args.libc; i++) { - struct REnv *e; FILE *lfp = fopen(args.libv[i], "r"); if (lfp == NULL) { printf("Cannot open library file. (%s)\n", args.libv[i]); @@ -517,9 +516,7 @@ main(int argc, char **argv) } mrb_load_file_cxt(mrb, lfp, cxt); fclose(lfp); - e = mrb_vm_ci_env(mrb->c->cibase); - mrb_vm_ci_env_set(mrb->c->cibase, NULL); - mrb_env_unshare(mrb, e, FALSE); + mrb_vm_ci_env_clear(mrb, mrb->c->cibase); mrbc_cleanup_local_variables(mrb, cxt); } diff --git a/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index 505d4509..88cb51ca 100644 --- a/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -199,7 +199,7 @@ static int partial_hook(struct mrb_parser_state *p) { mrbc_context *c = p->cxt; - struct mrbc_args *args = (struct mrbc_args *)c->partial_data; + struct mrbc_args *args = (struct mrbc_args*)c->partial_data; const char *fn; if (p->f) fclose(p->f); @@ -368,9 +368,4 @@ void mrb_init_mrbgems(mrb_state *mrb) { } - -void -mrb_final_mrbgems(mrb_state *mrb) -{ -} #endif diff --git a/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 3faaaccd..ad8373b9 100644 --- a/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -172,8 +172,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) cmdlinelen = strlen(args->cmdline); itemlen = strlen(item); - args->cmdline = - (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2); + args->cmdline = (char*)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2); args->cmdline[cmdlinelen] = '\n'; memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1); } @@ -326,7 +325,6 @@ main(int argc, char **argv) /* Load libraries */ for (i = 0; i < args.libc; i++) { - struct REnv *e; FILE *lfp = fopen(args.libv[i], "rb"); if (lfp == NULL) { fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]); @@ -342,9 +340,7 @@ main(int argc, char **argv) v = mrb_load_detect_file_cxt(mrb, lfp, c); } fclose(lfp); - e = mrb_vm_ci_env(mrb->c->cibase); - mrb_vm_ci_env_set(mrb->c->cibase, NULL); - mrb_env_unshare(mrb, e, FALSE); + mrb_vm_ci_env_clear(mrb, mrb->c->cibase); mrbc_cleanup_local_variables(mrb, c); } diff --git a/mruby/mrbgems/mruby-bin-strip/mrbgem.rake b/mruby/mrbgems/mruby-bin-strip/mrbgem.rake index 2abd25ee..b98fbafc 100644 --- a/mruby/mrbgems/mruby-bin-strip/mrbgem.rake +++ b/mruby/mrbgems/mruby-bin-strip/mrbgem.rake @@ -2,5 +2,6 @@ MRuby::Gem::Specification.new('mruby-bin-strip') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'irep dump debug section remover command' + spec.add_dependency 'mruby-compiler', :core => 'mruby-compiler' spec.bins = %w(mruby-strip) end diff --git a/mruby/mrbgems/mruby-binding-core/mrbgem.rake b/mruby/mrbgems/mruby-binding-core/mrbgem.rake deleted file mode 100644 index c0ba4820..00000000 --- a/mruby/mrbgems/mruby-binding-core/mrbgem.rake +++ /dev/null @@ -1,7 +0,0 @@ -MRuby::Gem::Specification.new('mruby-binding-core') do |spec| - spec.license = 'MIT' - spec.author = 'mruby developers' - spec.summary = 'Binding class (core features only)' - - spec.add_test_dependency('mruby-proc-ext', :core => 'mruby-proc-ext') -end diff --git a/mruby/mrbgems/mruby-binding-core/src/binding-core.c b/mruby/mrbgems/mruby-binding-core/src/binding-core.c deleted file mode 100644 index 47ec34f8..00000000 --- a/mruby/mrbgems/mruby-binding-core/src/binding-core.c +++ /dev/null @@ -1,309 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -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_proc_local_variables(mrb_state *mrb, const struct RProc *proc); -const struct RProc *mrb_proc_get_caller(mrb_state *mrb, struct REnv **env); - -static mrb_int -binding_extract_pc(mrb_state *mrb, mrb_value binding) -{ - mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(pc)); - if (mrb_nil_p(obj)) { - return -1; - } - else { - mrb_check_type(mrb, obj, MRB_TT_INTEGER); - return mrb_int(mrb, obj); - } -} - -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); -} - -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)) { - return NULL; - } - else { - mrb_check_type(mrb, obj, MRB_TT_ENV); - return (struct REnv *)mrb_obj_ptr(obj); - } -} - -static void -binding_local_variable_name_check(mrb_state *mrb, mrb_sym id) -{ - if (id == 0) { - badname: - mrb_raisef(mrb, E_NAME_ERROR, "wrong local variable name %!n for binding", id); - } - - mrb_int len; - const char *name = mrb_sym_name_len(mrb, id, &len); - if (len == 0) { - goto badname; - } - - if (ISASCII(*name) && !(*name == '_' || ISLOWER(*name))) { - goto badname; - } - len--; - name++; - - for (; len > 0; len--, name++) { - if (ISASCII(*name) && !(*name == '_' || ISALNUM(*name))) { - goto badname; - } - } -} - -static mrb_value * -binding_local_variable_search(mrb_state *mrb, const struct RProc *proc, struct REnv *env, mrb_sym varname) -{ - binding_local_variable_name_check(mrb, varname); - - while (proc) { - if (MRB_PROC_CFUNC_P(proc)) break; - - const mrb_irep *irep = proc->body.irep; - const mrb_sym *lv; - if (irep && (lv = irep->lv)) { - for (int i = 0; i + 1 < irep->nlocals; i++, lv++) { - if (varname == *lv) { - return (env && MRB_ENV_LEN(env) > i) ? &env->stack[i + 1] : NULL; - } - } - } - - if (MRB_PROC_SCOPE_P(proc)) break; - env = MRB_PROC_ENV(proc); - proc = proc->upper; - } - - return NULL; -} - -/* - * call-seq: - * local_variable_defined?(symbol) -> bool - */ -static mrb_value -binding_local_variable_defined_p(mrb_state *mrb, mrb_value self) -{ - mrb_sym varname; - mrb_get_args(mrb, "n", &varname); - - 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(); - } - else { - return mrb_false_value(); - } -} - -/* - * call-seq: - * local_variable_get(symbol) -> object - */ -static mrb_value -binding_local_variable_get(mrb_state *mrb, mrb_value self) -{ - mrb_sym varname; - mrb_get_args(mrb, "n", &varname); - - 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); - } - - return *e; -} - -static mrb_value -binding_local_variable_set(mrb_state *mrb, mrb_value self) -{ - mrb_sym varname; - mrb_value obj; - mrb_get_args(mrb, "no", &varname, &obj); - - 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); - } - - return obj; -} - -static mrb_value -binding_local_variables(mrb_state *mrb, mrb_value self) -{ - const struct RProc *proc = mrb_proc_ptr(mrb_iv_get(mrb, self, MRB_SYM(proc))); - return mrb_proc_local_variables(mrb, proc); -} - -static mrb_value -binding_receiver(mrb_state *mrb, mrb_value self) -{ - return mrb_iv_get(mrb, self, MRB_SYM(recv)); -} - -/* - * call-seq: - * source_location -> [String, Integer] - */ -static mrb_value -binding_source_location(mrb_state *mrb, mrb_value self) -{ - if (mrb_iv_defined(mrb, self, MRB_SYM(source_location))) { - return mrb_iv_get(mrb, self, MRB_SYM(source_location)); - } - - mrb_value srcloc; - 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(); - } - else { - const mrb_irep *irep = proc->upper->body.irep; - mrb_int pc = binding_extract_pc(mrb, self); - if (pc < 0) { - srcloc = mrb_nil_value(); - } - else { - const char *fname = mrb_debug_get_filename(mrb, irep, (uint32_t)pc); - mrb_int fline = mrb_debug_get_line(mrb, irep, (uint32_t)pc); - - if (fname && fline >= 0) { - srcloc = mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, fname), mrb_fixnum_value(fline)); - } - else { - srcloc = mrb_nil_value(); - } - } - } - - if (!mrb_frozen_p(mrb_obj_ptr(self))) { - mrb_iv_set(mrb, self, MRB_SYM(source_location), srcloc); - } - return srcloc; -} - -mrb_value -mrb_binding_alloc(mrb_state *mrb) -{ - struct RObject *obj = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb_class_get_id(mrb, MRB_SYM(Binding))); - return mrb_obj_value(obj); -} - -struct RProc* -mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv **envp) -{ - /* - * local variable space: It is a space to hold the top-level variable of - * binding.eval and binding.local_variable_set. - */ - - static const mrb_code iseq_dummy[] = { OP_RETURN, 0 }; - - 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; - irep->ilen = sizeof(iseq_dummy) / sizeof(iseq_dummy[0]); - irep->lv = (mrb_sym*)mrb_calloc(mrb, 1, sizeof(mrb_sym)); /* initial allocation for dummy */ - irep->nlocals = 1; - irep->nregs = 1; - lvspace->body.irep = irep; - lvspace->upper = proc; - if (*envp) { - lvspace->e.env = *envp; - lvspace->flags |= MRB_PROC_ENVSET; - } - - *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; - (*envp)->mid = 0; - (*envp)->flags = MRB_ENV_CLOSED; - MRB_ENV_SET_LEN(*envp, 1); - - return lvspace; -} - -static mrb_value -mrb_f_binding(mrb_state *mrb, mrb_value self) -{ - mrb_value binding; - struct RProc *proc; - struct REnv *env; - - binding = mrb_binding_alloc(mrb); - proc = (struct RProc*)mrb_proc_get_caller(mrb, &env); - if (!env || MRB_PROC_CFUNC_P(proc)) { - proc = NULL; - env = NULL; - } - - if (proc && !MRB_PROC_CFUNC_P(proc)) { - const mrb_irep *irep = proc->body.irep; - mrb_iv_set(mrb, binding, MRB_SYM(pc), mrb_fixnum_value(mrb->c->ci[-1].pc - irep->iseq - 1 /* step back */)); - } - proc = mrb_binding_wrap_lvspace(mrb, proc, &env); - mrb_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value(proc)); - mrb_iv_set(mrb, binding, MRB_SYM(recv), self); - mrb_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); - return binding; -} - -void -mrb_mruby_binding_core_gem_init(mrb_state *mrb) -{ - struct RClass *binding = mrb_define_class(mrb, "Binding", mrb->object_class); - mrb_undef_class_method(mrb, binding, "new"); - mrb_undef_class_method(mrb, binding, "allocate"); - - mrb_define_method(mrb, mrb->kernel_module, "binding", mrb_f_binding, MRB_ARGS_NONE()); - - mrb_define_method(mrb, binding, "local_variable_defined?", binding_local_variable_defined_p, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, binding, "local_variable_get", binding_local_variable_get, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, binding, "local_variable_set", binding_local_variable_set, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, binding, "local_variables", binding_local_variables, MRB_ARGS_NONE()); - mrb_define_method(mrb, binding, "receiver", binding_receiver, MRB_ARGS_NONE()); - mrb_define_method(mrb, binding, "source_location", binding_source_location, MRB_ARGS_NONE()); - mrb_define_method(mrb, binding, "inspect", mrb_any_to_s, MRB_ARGS_NONE()); -} - -void -mrb_mruby_binding_core_gem_final(mrb_state *mrb) -{ -} diff --git a/mruby/mrbgems/mruby-binding-core/test/binding-core.rb b/mruby/mrbgems/mruby-binding-core/test/binding-core.rb deleted file mode 100644 index 066e79b1..00000000 --- a/mruby/mrbgems/mruby-binding-core/test/binding-core.rb +++ /dev/null @@ -1,40 +0,0 @@ -assert("Kernel.#binding") do - assert_kind_of Binding, binding -end - -assert("Binding#local_variables") do - block = Proc.new do |a| - b = 1 - binding - end - assert_equal [:a, :b, :block], block.call(0).local_variables.sort -end - -assert("Binding#local_variable_set") do - bind = binding - 1.times { - assert_equal(9, bind.local_variable_set(:x, 9)) - assert_raise(NameError) { x } - assert_equal([:bind, :x], bind.local_variables.sort) - } -end - -assert("Binding#local_variable_get") do - bind = binding - x = 1 - 1.times { - y = 2 - assert_equal(1, bind.local_variable_get(:x)) - x = 10 - assert_equal(10, bind.local_variable_get(:x)) - assert_raise(NameError) { bind.local_variable_get(:y) } - assert_equal([:bind, :x], bind.local_variables.sort) - } -end - -assert("Binding#source_location") do - skip unless -> {}.source_location - - bind, source_location = binding, [__FILE__, __LINE__] - assert_equal source_location, bind.source_location -end diff --git a/mruby/mrbgems/mruby-binding/mrbgem.rake b/mruby/mrbgems/mruby-binding/mrbgem.rake index 4ad5638e..fe48f3ad 100644 --- a/mruby/mrbgems/mruby-binding/mrbgem.rake +++ b/mruby/mrbgems/mruby-binding/mrbgem.rake @@ -1,11 +1,7 @@ MRuby::Gem::Specification.new('mruby-binding') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'Binding class' + spec.summary = 'Binding class (core features only)' - spec.add_dependency('mruby-binding-core', :core => 'mruby-binding-core') - spec.add_dependency('mruby-eval', :core => 'mruby-eval') - spec.add_test_dependency('mruby-metaprog', :core => 'mruby-metaprog') - spec.add_test_dependency('mruby-method', :core => 'mruby-method') spec.add_test_dependency('mruby-proc-ext', :core => 'mruby-proc-ext') end diff --git a/mruby/mrbgems/mruby-binding/src/binding.c b/mruby/mrbgems/mruby-binding/src/binding.c index de3147f6..7a0a577f 100644 --- a/mruby/mrbgems/mruby-binding/src/binding.c +++ b/mruby/mrbgems/mruby-binding/src/binding.c @@ -1,166 +1,417 @@ #include #include #include -#include -#include +#include #include -#include -#include +#include #include +#include +#include +#include -void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); -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); +#define BINDING_UPPER_DEFAULT 20 +#define BINDING_UPPER_MINIMUM 10 +#define BINDING_UPPER_MAXIMUM 100 -static void -binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char *file) +#ifndef MRB_BINDING_UPPER_MAX +# define BINDING_UPPER_MAX BINDING_UPPER_DEFAULT +#else +# if (MRB_BINDING_UPPER_MAX) > BINDING_UPPER_MAXIMUM +# define BINDING_UPPER_MAX BINDING_UPPER_MAXIMUM +# elif (MRB_BINDING_UPPER_MAX) < BINDING_UPPER_MINIMUM +# define BINDING_UPPER_MAX BINDING_UPPER_MINIMUM +# else +# define BINDING_UPPER_MAX MRB_BINDING_UPPER_MAX +# endif +#endif + +static mrb_int +binding_extract_pc(mrb_state *mrb, mrb_value binding) +{ + mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(pc)); + if (mrb_nil_p(obj)) { + return -1; + } + else { + mrb_check_type(mrb, obj, MRB_TT_INTEGER); + return mrb_int(mrb, obj); + } +} + +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); +} + +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)) { + return NULL; + } + else { + mrb_check_type(mrb, obj, MRB_TT_ENV); + return (struct REnv*)mrb_obj_ptr(obj); + } +} + +static mrb_irep * +binding_irep_new_lvspace(mrb_state *mrb) +{ + static const mrb_code iseq_dummy[] = { OP_RETURN, 0 }; + + mrb_irep *irep = mrb_add_irep(mrb); + irep->flags = MRB_ISEQ_NO_FREE; + irep->iseq = iseq_dummy; + irep->ilen = sizeof(iseq_dummy) / sizeof(iseq_dummy[0]); + irep->lv = (mrb_sym*)mrb_calloc(mrb, 1, sizeof(mrb_sym)); /* initial allocation for dummy */ + irep->nlocals = 1; + irep->nregs = 1; + return irep; +} + +static struct RProc * +binding_proc_new_lvspace(mrb_state *mrb, const struct RProc *upper, struct REnv *env) { - if (!p) { - mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state (out of memory)"); + struct RProc *lvspace = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class); + lvspace->body.irep = binding_irep_new_lvspace(mrb); + lvspace->upper = upper; + if (env && env->tt == MRB_TT_ENV) { + lvspace->e.env = env; + lvspace->flags |= MRB_PROC_ENVSET; } + return lvspace; +} - if (0 < p->nerr) { - mrb_value str; +static struct REnv * +binding_env_new_lvspace(mrb_state *mrb, const struct REnv *e) +{ + struct REnv *env = MRB_OBJ_ALLOC(mrb, MRB_TT_ENV, NULL); + mrb_value *stacks = (mrb_value*)mrb_calloc(mrb, 1, sizeof(mrb_value)); + env->cxt = e ? e->cxt : mrb->c; + env->mid = 0; + env->stack = stacks; + if (e && e->stack && MRB_ENV_LEN(e) > 0) { + env->stack[0] = e->stack[0]; + } + else { + env->stack[0] = mrb_nil_value(); + } + env->flags = MRB_ENV_CLOSED; + MRB_ENV_SET_LEN(env, 1); + return env; +} - if (file) { - str = mrb_format(mrb, "file %s line %d: %s", - file, - p->error_buffer[0].lineno, - p->error_buffer[0].message); +static size_t +binding_proc_upper_count(const struct RProc *proc) +{ + size_t count = 0; + for (; proc && !MRB_PROC_CFUNC_P(proc); proc = proc->upper) { + count++; + if (MRB_PROC_SCOPE_P(proc)) break; + } + return count; +} + +mrb_bool +mrb_binding_p(mrb_state *mrb, mrb_value obj) +{ + if (!mrb_obj_is_kind_of(mrb, obj, mrb_class_get_id(mrb, MRB_SYM(Binding)))) return FALSE; + if (mrb_type(obj) != MRB_TT_OBJECT) return FALSE; + if (!mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), MRB_SYM(proc))) return FALSE; + if (!mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), MRB_SYM(recv))) return FALSE; + if (!mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), MRB_SYM(env))) return FALSE; + return TRUE; +} + +static void +binding_type_ensure(mrb_state *mrb, mrb_value obj) +{ + if (mrb_binding_p(mrb, obj)) return; + mrb_raise(mrb, E_TYPE_ERROR, "not a binding"); +} + +static struct RProc* +binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv **envp) +{ + /* + * local variable space: It is a space to hold the top-level variable of + * binding.eval and binding.local_variable_set. + */ + + struct RProc *lvspace = binding_proc_new_lvspace(mrb, proc, *envp); + *envp = binding_env_new_lvspace(mrb, *envp); + return lvspace; +} + +static mrb_value +binding_initialize_copy(mrb_state *mrb, mrb_value binding) +{ + mrb_value src = mrb_get_arg1(mrb); + binding_type_ensure(mrb, src); + const struct RProc *src_proc = mrb_binding_extract_proc(mrb, src); + struct REnv *src_env = mrb_binding_extract_env(mrb, src); + + mrb_check_frozen(mrb, mrb_obj_ptr(binding)); + + struct RProc *lvspace; + struct REnv *env; + if (MRB_ENV_LEN(src_env) < 2) { + /* when local variables of src are self only */ + env = src_proc->e.env; + lvspace = binding_wrap_lvspace(mrb, src_proc->upper, &env); + } + else { + if (binding_proc_upper_count(src_proc) > BINDING_UPPER_MAX) { + mrb_raise(mrb, E_RUNTIME_ERROR, + "too many upper procs for local variables (mruby limitation; maximum is " MRB_STRINGIZE(BINDING_UPPER_MAX) ")"); } - else { - str = mrb_format(mrb, "line %d: %s", - p->error_buffer[0].lineno, - p->error_buffer[0].message); + + env = src_env; + lvspace = binding_wrap_lvspace(mrb, src_proc, &env); + + // The reason for using the mrb_obj_iv_set_force() function is to allow local + // variables to be modified even if src is frozen. This behavior is CRuby imitation. + src_proc = binding_wrap_lvspace(mrb, src_proc, &src_env); + struct RObject *o = mrb_obj_ptr(src); + mrb_obj_iv_set_force(mrb, o, MRB_SYM(proc), mrb_obj_value((struct RProc*)src_proc)); + mrb_obj_iv_set_force(mrb, o, MRB_SYM(env), mrb_obj_value(src_env)); + } + mrb_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value(lvspace)); + mrb_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); + + return binding; +} + +static void +binding_local_variable_name_check(mrb_state *mrb, mrb_sym id) +{ + if (id == 0) { + badname: + mrb_raisef(mrb, E_NAME_ERROR, "wrong local variable name %!n for binding", id); + } + + mrb_int len; + const char *name = mrb_sym_name_len(mrb, id, &len); + if (len == 0) { + goto badname; + } + + if (ISASCII(*name) && !(*name == '_' || ISLOWER(*name))) { + goto badname; + } + len--; + name++; + + for (; len > 0; len--, name++) { + if (ISASCII(*name) && !(*name == '_' || ISALNUM(*name))) { + goto badname; } - mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); } } -#define LV_BUFFERS 8 +static mrb_value * +binding_local_variable_search(mrb_state *mrb, const struct RProc *proc, struct REnv *env, mrb_sym varname) +{ + binding_local_variable_name_check(mrb, varname); -struct expand_lvspace { - mrb_irep *irep; - struct REnv *env; - int 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; + while (proc) { + if (MRB_PROC_CFUNC_P(proc)) break; + + const mrb_irep *irep = proc->body.irep; + const mrb_sym *lv; + if (irep && (lv = irep->lv)) { + for (int i = 0; i + 1 < irep->nlocals; i++, lv++) { + if (varname == *lv) { + return (env && MRB_ENV_LEN(env) > i) ? &env->stack[i + 1] : NULL; + } } } + + if (MRB_PROC_SCOPE_P(proc)) break; + env = MRB_PROC_ENV(proc); + proc = proc->upper; } - return TRUE; + return NULL; } -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; -}; +/* + * call-seq: + * local_variable_defined?(symbol) -> bool + */ +static mrb_value +binding_local_variable_defined_p(mrb_state *mrb, mrb_value self) +{ + mrb_sym varname; + mrb_get_args(mrb, "n", &varname); + + 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(); + } + else { + return mrb_false_value(); + } +} +/* + * call-seq: + * local_variable_get(symbol) -> object + */ static mrb_value -binding_eval_prepare_body(mrb_state *mrb, void *opaque) +binding_local_variable_get(mrb_state *mrb, mrb_value self) { - struct binding_eval_prepare_body *p = (struct binding_eval_prepare_body*)opaque; + mrb_sym varname; + mrb_get_args(mrb, "n", &varname); - const struct RProc *proc = mrb_binding_extract_proc(mrb, p->binding); - mrb_assert(!MRB_PROC_CFUNC_P(proc)); + 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); + } - 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); + return *e; +} - 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); +static mrb_value +binding_local_variable_set(mrb_state *mrb, mrb_value self) +{ + mrb_sym varname; + mrb_value obj; + mrb_get_args(mrb, "no", &varname, &obj); + + 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); } - return mrb_nil_value(); + return obj; } -static void -binding_eval_prepare(mrb_state *mrb, mrb_value binding) +static mrb_value +binding_local_variables(mrb_state *mrb, mrb_value self) { - 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); + const struct RProc *proc = mrb_proc_ptr(mrb_iv_get(mrb, self, MRB_SYM(proc))); + return mrb_proc_local_variables(mrb, proc); +} - /* `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 +binding_receiver(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(recv)); } +/* + * call-seq: + * source_location -> [String, Integer] + */ static mrb_value -mrb_binding_eval(mrb_state *mrb, mrb_value binding) +binding_source_location(mrb_state *mrb, mrb_value self) { - binding_eval_prepare(mrb, binding); + if (mrb_iv_defined(mrb, self, MRB_SYM(source_location))) { + return mrb_iv_get(mrb, self, MRB_SYM(source_location)); + } - 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; + mrb_value srcloc; + 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(); + } + else { + const mrb_irep *irep = proc->upper->body.irep; + mrb_int pc = binding_extract_pc(mrb, self); + if (pc < 0) { + srcloc = mrb_nil_value(); + } + else { + const char *fname; + int32_t line; - if (argc < 15) { - argv[0] = mrb_ary_new_from_values(mrb, argc, argv); - argv[1] = argv[argc]; /* copy block */ - ci->n = 15; + if (!mrb_debug_get_position(mrb, irep, (uint32_t)pc, &line, &fname)) { + srcloc = mrb_nil_value(); + } + else { + srcloc = mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, fname), mrb_fixnum_value(line)); + } + } } - if (MRB_METHOD_UNDEF_P(m)) { - mrb_method_missing(mrb, MRB_SYM(eval), binding, argv[0]); + + if (!mrb_frozen_p(mrb_obj_ptr(self))) { + mrb_iv_set(mrb, self, MRB_SYM(source_location), srcloc); } + return srcloc; +} - 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); +mrb_value +mrb_binding_new(mrb_state *mrb, const struct RProc *proc, mrb_value recv, struct REnv *env) +{ + struct RObject *binding = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb_class_get_id(mrb, MRB_SYM(Binding))); + + if (proc && !MRB_PROC_CFUNC_P(proc)) { + const mrb_irep *irep = proc->body.irep; + mrb_obj_iv_set(mrb, binding, MRB_SYM(pc), mrb_fixnum_value(mrb->c->ci[-1].pc - irep->iseq - 1 /* step back */)); } - else { - proc = MRB_METHOD_PROC(m); + proc = binding_wrap_lvspace(mrb, proc, &env); + + mrb_obj_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value((void*)proc)); + mrb_obj_iv_set(mrb, binding, MRB_SYM(recv), recv); + mrb_obj_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); + + return mrb_obj_value(binding); +} + +static mrb_value +mrb_f_binding(mrb_state *mrb, mrb_value self) +{ + struct RProc *proc; + struct REnv *env; + + if (mrb->c->ci->cci != 0) { + caller_err: + mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot create Binding object for non-Ruby caller"); } - ci->u.target_class = c; - return mrb_exec_irep(mrb, binding, proc); + proc = (struct RProc*)mrb_proc_get_caller(mrb, &env); + if (!env || MRB_PROC_CFUNC_P(proc)) { + goto caller_err; + } + return mrb_binding_new(mrb, proc, self, env); } 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()); + struct RClass *binding = mrb_define_class(mrb, "Binding", mrb->object_class); + MRB_SET_INSTANCE_TT(binding, MRB_TT_UNDEF); + mrb_undef_class_method(mrb, binding, "new"); + mrb_undef_class_method(mrb, binding, "allocate"); + + mrb_define_method(mrb, mrb->kernel_module, "binding", mrb_f_binding, MRB_ARGS_NONE()); + + mrb_define_method(mrb, binding, "initialize_copy", binding_initialize_copy, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, binding, "local_variable_defined?", binding_local_variable_defined_p, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, binding, "local_variable_get", binding_local_variable_get, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, binding, "local_variable_set", binding_local_variable_set, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, binding, "local_variables", binding_local_variables, MRB_ARGS_NONE()); + mrb_define_method(mrb, binding, "receiver", binding_receiver, MRB_ARGS_NONE()); + mrb_define_method(mrb, binding, "source_location", binding_source_location, MRB_ARGS_NONE()); + mrb_define_method(mrb, binding, "inspect", mrb_any_to_s, MRB_ARGS_NONE()); } void diff --git a/mruby/mrbgems/mruby-binding/test/binding.rb b/mruby/mrbgems/mruby-binding/test/binding.rb index bfae84c5..1f76b29f 100644 --- a/mruby/mrbgems/mruby-binding/test/binding.rb +++ b/mruby/mrbgems/mruby-binding/test/binding.rb @@ -1,9 +1,5 @@ -assert("Binding#eval") do - b = nil - 1.times { x, y, z = 1, 2, 3; [x,y,z]; b = binding } - assert_equal([1, 2, 3], b.eval("[x, y, z]")) - here = self - assert_equal(here, b.eval("self")) +assert("Kernel.#binding") do + assert_kind_of Binding, binding end assert("Binding#local_variables") do @@ -11,18 +7,15 @@ b = 1 binding end - bind = block.call(0) - assert_equal [:a, :b, :bind, :block], bind.local_variables.sort - bind.eval("x = 2") - assert_equal [:a, :b, :bind, :block, :x], bind.local_variables.sort + assert_equal [:a, :b, :block], block.call(0).local_variables.sort end assert("Binding#local_variable_set") do bind = binding 1.times { assert_equal(9, bind.local_variable_set(:x, 9)) - assert_equal(9, bind.eval("x")) - assert_equal([:bind, :x], bind.eval("local_variables.sort")) + assert_raise(NameError) { x } + assert_equal([:bind, :x], bind.local_variables.sort) } end @@ -35,36 +28,37 @@ x = 10 assert_equal(10, bind.local_variable_get(:x)) assert_raise(NameError) { bind.local_variable_get(:y) } - bind.eval("z = 3") - assert_equal(3, bind.local_variable_get(:z)) - bind.eval("y = 5") - assert_equal(5, bind.local_variable_get(:y)) - assert_equal(2, y) + assert_equal([:bind, :x], bind.local_variables.sort) } end -assert "Kernel#binding and .eval from C" do - bind = binding_in_c - assert_equal 5, bind.eval("2 + 3") - assert_nothing_raised { bind.eval("self") } -end +assert("Binding#source_location") do + skip unless -> {}.source_location -assert "Binding#eval with Binding.new via UnboundMethod" do - assert_raise(NoMethodError) { Class.instance_method(:new).bind_call(Binding) } + bind, source_location = binding, [__FILE__, __LINE__] + assert_equal source_location, bind.source_location end -assert "Binding#eval with Binding.new via Method" do - # The following test is OK if SIGSEGV does not occur - cx = Class.new(Binding) - cx.define_singleton_method(:allocate, &Object.method(:allocate)) - Class.instance_method(:new).bind_call(cx).eval("") - - assert_true true +assert("Binding#dup") do + x = 5 + bind1 = binding + bind1.local_variable_set(:y, 10) + bind2 = bind1.dup + assert_equal 5, bind2.local_variable_get(:x) + assert_equal 10, bind2.local_variable_get(:y) + x = 50 + assert_equal 50, bind1.local_variable_get(:x) + assert_equal 50, bind2.local_variable_get(:x) + bind1.local_variable_set(:y, 20) + assert_equal 20, bind1.local_variable_get(:y) + assert_equal 20, bind2.local_variable_get(:y) + bind1.local_variable_set(:z, 30) + assert_raise(NameError) { bind2.local_variable_get(:z) } + bind2.local_variable_set(:z, 40) + assert_equal 30, bind1.local_variable_get(:z) + assert_equal 40, bind2.local_variable_get(:z) 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 +assert "Kernel#binding and .eval from C" do + assert_raise(RuntimeError) { binding_in_c } end diff --git a/mruby/mrbgems/mruby-catch/src/catch.c b/mruby/mrbgems/mruby-catch/src/catch.c index 048a4473..44852c6b 100644 --- a/mruby/mrbgems/mruby-catch/src/catch.c +++ b/mruby/mrbgems/mruby-catch/src/catch.c @@ -6,14 +6,14 @@ #include #include - MRB_PRESYM_DEFINE_VAR_AND_INITER(catch_syms_3, 1, MRB_SYM(call)) static const mrb_code catch_iseq_3[18] = { - OP_ENTER, 0x00, 0x00, 0x00, - OP_GETUPVAR, 0x02, 0x02, 0x01, - OP_GETUPVAR, 0x03, 0x01, 0x01, - OP_SEND, 0x02, 0x00, 0x01, - OP_RETURN, 0x02,}; + OP_ENTER, 0x00, 0x00, 0x00, // 000 ENTER 0:0:0:0:0:0:0 (0x0) + OP_GETUPVAR, 0x02, 0x02, 0x01, // 004 GETUPVAR R2 2 1 + OP_GETUPVAR, 0x03, 0x01, 0x01, // 008 GETUPVAR R3 1 1 + OP_SEND, 0x02, 0x00, 0x01, // 012 SEND R2 :call n=1 + OP_RETURN, 0x02, // 016 RETURN R2 +}; static const mrb_irep catch_irep_3 = { 2,5,0, MRB_IREP_STATIC,catch_iseq_3, @@ -26,10 +26,11 @@ static const mrb_irep *catch_reps_2[1] = { &catch_irep_3, }; static const mrb_code catch_iseq_2[13] = { - OP_ENTER, 0x00, 0x00, 0x00, - OP_LAMBDA, 0x02, 0x00, - OP_SEND, 0x02, 0x00, 0x00, - OP_RETURN, 0x02,}; + OP_ENTER, 0x00, 0x00, 0x00, // 000 ENTER 0:0:0:0:0:0:0 (0x0) + OP_LAMBDA, 0x02, 0x00, // 004 LAMBDA R2 I[0] + OP_SEND, 0x02, 0x00, 0x00, // 007 SEND R2 :call n=0 + OP_RETURN, 0x02, // 011 RETURN R2 +}; static const mrb_irep catch_irep_2 = { 2,4,0, MRB_IREP_STATIC,catch_iseq_2, @@ -43,15 +44,16 @@ static const mrb_irep *catch_reps_1[1] = { }; MRB_PRESYM_DEFINE_VAR_AND_INITER(catch_syms_1, 3, MRB_SYM(Object), MRB_SYM(new), MRB_SYM(call)) static const mrb_code catch_iseq_1[29] = { - OP_ENTER, 0x00, 0x20, 0x01, - OP_JMP, 0x00, 0x03, - OP_JMP, 0x00, 0x0a, - OP_GETCONST, 0x03, 0x00, - OP_SEND, 0x03, 0x01, 0x00, - OP_MOVE, 0x01, 0x03, - OP_LAMBDA, 0x03, 0x00, - OP_SEND, 0x03, 0x02, 0x00, - OP_RETURN, 0x03,}; + OP_ENTER, 0x00, 0x20, 0x01, // 000 ENTER 0:1:0:0:0:0:1 (0x2001) + OP_JMP, 0x00, 0x03, // 004 JMP 010 + OP_JMP, 0x00, 0x0a, // 007 JMP 020 + OP_GETCONST, 0x03, 0x00, // 010 GETCONST R3 Object + OP_SEND, 0x03, 0x01, 0x00, // 013 SEND R3 :new n=0 + OP_MOVE, 0x01, 0x03, // 017 MOVE R1 R3 + OP_LAMBDA, 0x03, 0x00, // 020 LAMBDA R3 I[0] + OP_SEND, 0x03, 0x02, 0x00, // 023 SEND R3 :call n=0 + OP_RETURN, 0x03, // 027 RETURN R3 +}; static const mrb_irep catch_irep = { 3,5,0, MRB_IREP_STATIC,catch_iseq_1, @@ -60,7 +62,6 @@ static const mrb_irep catch_irep = { NULL, 29,0,3,1,0 }; - static const struct RProc catch_proc = { NULL, NULL, MRB_TT_PROC, MRB_GC_RED, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT, { &catch_irep }, NULL, { NULL } @@ -83,7 +84,7 @@ find_catcher(mrb_state *mrb, mrb_value tag) } static mrb_value -mrb_f_throw(mrb_state *mrb, mrb_value self) +throw_m(mrb_state *mrb, mrb_value self) { mrb_value tag, obj; if (mrb_get_args(mrb, "o|o", &tag, &obj) == 1) { @@ -115,7 +116,7 @@ mrb_mruby_catch_gem_init(mrb_state *mrb) MRB_METHOD_FROM_PROC(m, &catch_proc); mrb_define_method_raw(mrb, mrb->kernel_module, MRB_SYM(catch), m); - mrb_define_method(mrb, mrb->kernel_module, "throw", mrb_f_throw, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, mrb->kernel_module, "throw", throw_m, MRB_ARGS_ARG(1,1)); } void diff --git a/mruby/mrbgems/mruby-class-ext/src/class.c b/mruby/mrbgems/mruby-class-ext/src/class.c index dbe06152..0fa0a4af 100644 --- a/mruby/mrbgems/mruby-class-ext/src/class.c +++ b/mruby/mrbgems/mruby-class-ext/src/class.c @@ -7,7 +7,7 @@ #include "mruby/presym.h" static mrb_value -mrb_mod_name(mrb_state *mrb, mrb_value self) +mod_name(mrb_state *mrb, mrb_value self) { mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self)); if (mrb_string_p(name)) { @@ -17,7 +17,7 @@ mrb_mod_name(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) +mod_singleton_class_p(mrb_state *mrb, mrb_value self) { return mrb_bool_value(mrb_sclass_p(self)); } @@ -42,7 +42,7 @@ mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) */ static mrb_value -mrb_mod_module_exec(mrb_state *mrb, mrb_value self) +mod_module_exec(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc; @@ -95,7 +95,7 @@ add_subclasses(mrb_state *mrb, struct RBasic *obj, void *data) * C.subclasses #=> [] */ static mrb_value -mrb_class_subclasses(mrb_state *mrb, mrb_value self) +class_subclasses(mrb_state *mrb, mrb_value self) { struct RClass *c; mrb_value ary; @@ -126,7 +126,7 @@ mrb_class_subclasses(mrb_state *mrb, mrb_value self) * NilClass.attached_object #=> TypeError: not a singleton class */ static mrb_value -mrb_class_attached_object(mrb_state *mrb, mrb_value self) +class_attached_object(mrb_state *mrb, mrb_value self) { struct RClass *c; @@ -142,14 +142,14 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb) { struct RClass *mod = mrb->module_class; - mrb_define_method(mrb, mod, "name", mrb_mod_name, MRB_ARGS_NONE()); - mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE()); - mrb_define_method(mrb, mod, "module_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); - mrb_define_method(mrb, mod, "class_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mod, "name", mod_name, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "singleton_class?", mod_singleton_class_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "module_exec", mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mod, "class_exec", mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); struct RClass *cls = mrb->class_class; - mrb_define_method(mrb, cls, "subclasses", mrb_class_subclasses, MRB_ARGS_NONE()); - mrb_define_method(mrb, cls, "attached_object", mrb_class_attached_object, MRB_ARGS_NONE()); + mrb_define_method(mrb, cls, "subclasses", class_subclasses, MRB_ARGS_NONE()); + mrb_define_method(mrb, cls, "attached_object", class_attached_object, MRB_ARGS_NONE()); } void diff --git a/mruby/mrbgems/mruby-cmath/src/cmath.c b/mruby/mrbgems/mruby-cmath/src/cmath.c index de59adf9..b0b8d5f1 100644 --- a/mruby/mrbgems/mruby-cmath/src/cmath.c +++ b/mruby/mrbgems/mruby-cmath/src/cmath.c @@ -33,7 +33,7 @@ cmath_get_complex(mrb_state *mrb, mrb_value c, mrb_float *r, mrb_float *i) *i = 0; return FALSE; } - else if (mrb_obj_is_kind_of(mrb, c, mrb_class_get(mrb, "Complex"))) { + else if (mrb_type(c) == MRB_TT_COMPLEX) { mrb_complex_get(mrb, c, r, i); return TRUE; } @@ -76,13 +76,13 @@ CXDIVc(mrb_complex a, mrb_complex b) if ((abi = cimag(b)) < 0) abi = - abi; if (abr <= abi) { - ratio = creal(b) / cimag(b) ; + ratio = creal(b) / cimag(b); den = cimag(a) * (1 + ratio*ratio); cr = (creal(a)*ratio + cimag(a)) / den; ci = (cimag(a)*ratio - creal(a)) / den; } else { - ratio = cimag(b) / creal(b) ; + ratio = cimag(b) / creal(b); den = creal(a) * (1 + ratio*ratio); cr = (creal(a) + cimag(a)*ratio) / den; ci = (cimag(a) - creal(a)*ratio) / den; diff --git a/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb b/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb index 18bba791..cc40223d 100644 --- a/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +++ b/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb @@ -53,8 +53,17 @@ def clamp(min, max=nil) if min.nil? min = self end + elsif min.nil? or min < self + return self else - raise TypeError, "wrong argument type #{min.class}" + return min + end + end + if min.nil? + if self < max + return self + else + return max end end c = min <=> max diff --git a/mruby/mrbgems/mruby-compiler/core/codegen.c b/mruby/mrbgems/mruby-compiler/core/codegen.c index 41e269e6..7315832b 100644 --- a/mruby/mrbgems/mruby-compiler/core/codegen.c +++ b/mruby/mrbgems/mruby-compiler/core/codegen.c @@ -771,7 +771,7 @@ get_int_operand(codegen_scope *s, struct mrb_insn_data *data, mrb_int *n) return TRUE; case OP_LOADI32: - *n = (mrb_int)((uint32_t)data->b<<16)+data->c; + *n = (int32_t)((uint32_t)data->b<<16)+data->c; return TRUE; case OP_LOADL: diff --git a/mruby/mrbgems/mruby-compiler/core/parse.y b/mruby/mrbgems/mruby-compiler/core/parse.y index 20d86480..d8760550 100644 --- a/mruby/mrbgems/mruby-compiler/core/parse.y +++ b/mruby/mrbgems/mruby-compiler/core/parse.y @@ -139,7 +139,7 @@ cons_gen(parser_state *p, node *car, node *cdr) c->filename_index = p->current_filename_index; /* beginning of next partial file; need to point the previous file */ if (p->lineno == 0 && p->current_filename_index > 0) { - c->filename_index-- ; + c->filename_index--; } return c; } @@ -1101,8 +1101,8 @@ concat_string(parser_state *p, node *a, node *b) } else { node *c; /* last node of a */ - for (c = a; c->cdr != NULL; c = c->cdr) ; - + for (c = a; c->cdr != NULL; c = c->cdr) + ; if (string_node_p(b)) { /* a == NODE_DSTR && b == NODE_STR */ if (string_node_p(c->car)) { @@ -1460,56 +1460,56 @@ heredoc_end(parser_state *p) } %token - keyword_class - keyword_module - keyword_def - keyword_begin - keyword_if - keyword_unless - keyword_while - keyword_until - keyword_for + keyword_class "'class'" + keyword_module "'module'" + keyword_def "'def'" + keyword_begin "'begin'" + keyword_if "'if'" + keyword_unless "'unless'" + keyword_while "'while'" + keyword_until "'until'" + keyword_for "'for'" %token - keyword_undef - keyword_rescue - keyword_ensure - keyword_end - keyword_then - keyword_elsif - keyword_else - keyword_case - keyword_when - keyword_break - keyword_next - keyword_redo - keyword_retry - keyword_in - keyword_do - keyword_do_cond - keyword_do_block - keyword_do_LAMBDA - keyword_return - keyword_yield - keyword_super - keyword_self - keyword_nil - keyword_true - keyword_false - keyword_and - keyword_or - keyword_not - modifier_if - modifier_unless - modifier_while - modifier_until - modifier_rescue - keyword_alias - keyword_BEGIN - keyword_END - keyword__LINE__ - keyword__FILE__ - keyword__ENCODING__ + keyword_undef "'undef'" + keyword_rescue "'rescue'" + keyword_ensure "'ensure'" + keyword_end "'end'" + keyword_then "'then'" + keyword_elsif "'elsif'" + keyword_else "'else'" + keyword_case "'case'" + keyword_when "'when'" + keyword_break "'break'" + keyword_next "'next'" + keyword_redo "'redo'" + keyword_retry "'retry'" + keyword_in "'in'" + keyword_do "'do'" + keyword_do_cond "'do' for condition" + keyword_do_block "'do' for block" + keyword_do_LAMBDA "'do' for lambda" + keyword_return "'return'" + keyword_yield "'yield'" + keyword_super "'super'" + keyword_self "'self'" + keyword_nil "'nil'" + keyword_true "'true'" + keyword_false "'false'" + keyword_and "'and'" + keyword_or "'or'" + keyword_not "'not'" + modifier_if "'if' modifier" + modifier_unless "'unless' modifier" + modifier_while "'while' modifier" + modifier_until "'until' modifier" + modifier_rescue "'rescue' modifier" + keyword_alias "'alis'" + keyword_BEGIN "'BEGIN'" + keyword_END "'END'" + keyword__LINE__ "'__LINE__'" + keyword__FILE__ "'__FILE__'" + keyword__ENCODING__ "'__ENCODING__'" %token tIDENTIFIER "local variable or method" %token tFID "method" @@ -3175,12 +3175,14 @@ do_block : keyword_do_block { local_nest(p); nvars_nest(p); + $$ = p->lineno; } opt_block_param bodystmt keyword_end { $$ = new_block(p,$3,$4); + SET_LINENO($$, $2); local_unnest(p); nvars_unnest(p); } @@ -4826,7 +4828,8 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinfo) newstr[newlen] = '\0'; pair->car = (node*)newstr; pair->cdr = (node*)newlen; - } else { + } + else { spaces = (size_t)nspaces->car; heredoc_count_indent(hinfo, str, len, spaces, &offset); pair->car = (node*)(str + offset); @@ -4901,7 +4904,8 @@ parse_string(parser_state *p) if (sizeof(s1)+sizeof(s2)+strlen(hinfo->term)+1 >= sizeof(buf)) { yyerror(p, "can't find heredoc delimiter anywhere before EOF"); - } else { + } + else { strcpy(buf, s1); strcat(buf, hinfo->term); strcat(buf, s2); @@ -6737,8 +6741,9 @@ mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s) { if (s) { size_t len = strlen(s); - char *p = (char*)mrb_malloc(mrb, len + 1); + char *p = (char*)mrb_malloc_simple(mrb, len + 1); + if (p == NULL) return NULL; memcpy(p, s, len + 1); if (c->filename) { mrb_free(mrb, c->filename); diff --git a/mruby/mrbgems/mruby-compiler/core/y.tab.c b/mruby/mrbgems/mruby-compiler/core/y.tab.c index 794b5cf9..2ab6fbc5 100644 --- a/mruby/mrbgems/mruby-compiler/core/y.tab.c +++ b/mruby/mrbgems/mruby-compiler/core/y.tab.c @@ -203,7 +203,7 @@ cons_gen(parser_state *p, node *car, node *cdr) c->filename_index = p->current_filename_index; /* beginning of next partial file; need to point the previous file */ if (p->lineno == 0 && p->current_filename_index > 0) { - c->filename_index-- ; + c->filename_index--; } return c; } @@ -1165,8 +1165,8 @@ concat_string(parser_state *p, node *a, node *b) } else { node *c; /* last node of a */ - for (c = a; c->cdr != NULL; c = c->cdr) ; - + for (c = a; c->cdr != NULL; c = c->cdr) + ; if (string_node_p(b)) { /* a == NODE_DSTR && b == NODE_STR */ if (string_node_p(c->car)) { @@ -1550,54 +1550,54 @@ extern int yydebug; YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ - keyword_class = 258, /* keyword_class */ - keyword_module = 259, /* keyword_module */ - keyword_def = 260, /* keyword_def */ - keyword_begin = 261, /* keyword_begin */ - keyword_if = 262, /* keyword_if */ - keyword_unless = 263, /* keyword_unless */ - keyword_while = 264, /* keyword_while */ - keyword_until = 265, /* keyword_until */ - keyword_for = 266, /* keyword_for */ - keyword_undef = 267, /* keyword_undef */ - keyword_rescue = 268, /* keyword_rescue */ - keyword_ensure = 269, /* keyword_ensure */ - keyword_end = 270, /* keyword_end */ - keyword_then = 271, /* keyword_then */ - keyword_elsif = 272, /* keyword_elsif */ - keyword_else = 273, /* keyword_else */ - keyword_case = 274, /* keyword_case */ - keyword_when = 275, /* keyword_when */ - keyword_break = 276, /* keyword_break */ - keyword_next = 277, /* keyword_next */ - keyword_redo = 278, /* keyword_redo */ - keyword_retry = 279, /* keyword_retry */ - keyword_in = 280, /* keyword_in */ - keyword_do = 281, /* keyword_do */ - keyword_do_cond = 282, /* keyword_do_cond */ - keyword_do_block = 283, /* keyword_do_block */ - keyword_do_LAMBDA = 284, /* keyword_do_LAMBDA */ - keyword_return = 285, /* keyword_return */ - keyword_yield = 286, /* keyword_yield */ - keyword_super = 287, /* keyword_super */ - keyword_self = 288, /* keyword_self */ - keyword_nil = 289, /* keyword_nil */ - keyword_true = 290, /* keyword_true */ - keyword_false = 291, /* keyword_false */ - keyword_and = 292, /* keyword_and */ - keyword_or = 293, /* keyword_or */ - keyword_not = 294, /* keyword_not */ - modifier_if = 295, /* modifier_if */ - modifier_unless = 296, /* modifier_unless */ - modifier_while = 297, /* modifier_while */ - modifier_until = 298, /* modifier_until */ - modifier_rescue = 299, /* modifier_rescue */ - keyword_alias = 300, /* keyword_alias */ - keyword_BEGIN = 301, /* keyword_BEGIN */ - keyword_END = 302, /* keyword_END */ - keyword__LINE__ = 303, /* keyword__LINE__ */ - keyword__FILE__ = 304, /* keyword__FILE__ */ - keyword__ENCODING__ = 305, /* keyword__ENCODING__ */ + keyword_class = 258, /* "'class'" */ + keyword_module = 259, /* "'module'" */ + keyword_def = 260, /* "'def'" */ + keyword_begin = 261, /* "'begin'" */ + keyword_if = 262, /* "'if'" */ + keyword_unless = 263, /* "'unless'" */ + keyword_while = 264, /* "'while'" */ + keyword_until = 265, /* "'until'" */ + keyword_for = 266, /* "'for'" */ + keyword_undef = 267, /* "'undef'" */ + keyword_rescue = 268, /* "'rescue'" */ + keyword_ensure = 269, /* "'ensure'" */ + keyword_end = 270, /* "'end'" */ + keyword_then = 271, /* "'then'" */ + keyword_elsif = 272, /* "'elsif'" */ + keyword_else = 273, /* "'else'" */ + keyword_case = 274, /* "'case'" */ + keyword_when = 275, /* "'when'" */ + keyword_break = 276, /* "'break'" */ + keyword_next = 277, /* "'next'" */ + keyword_redo = 278, /* "'redo'" */ + keyword_retry = 279, /* "'retry'" */ + keyword_in = 280, /* "'in'" */ + keyword_do = 281, /* "'do'" */ + keyword_do_cond = 282, /* "'do' for condition" */ + keyword_do_block = 283, /* "'do' for block" */ + keyword_do_LAMBDA = 284, /* "'do' for lambda" */ + keyword_return = 285, /* "'return'" */ + keyword_yield = 286, /* "'yield'" */ + keyword_super = 287, /* "'super'" */ + keyword_self = 288, /* "'self'" */ + keyword_nil = 289, /* "'nil'" */ + keyword_true = 290, /* "'true'" */ + keyword_false = 291, /* "'false'" */ + keyword_and = 292, /* "'and'" */ + keyword_or = 293, /* "'or'" */ + keyword_not = 294, /* "'not'" */ + modifier_if = 295, /* "'if' modifier" */ + modifier_unless = 296, /* "'unless' modifier" */ + modifier_while = 297, /* "'while' modifier" */ + modifier_until = 298, /* "'until' modifier" */ + modifier_rescue = 299, /* "'rescue' modifier" */ + keyword_alias = 300, /* "'alis'" */ + keyword_BEGIN = 301, /* "'BEGIN'" */ + keyword_END = 302, /* "'END'" */ + keyword__LINE__ = 303, /* "'__LINE__'" */ + keyword__FILE__ = 304, /* "'__FILE__'" */ + keyword__ENCODING__ = 305, /* "'__ENCODING__'" */ tIDENTIFIER = 306, /* "local variable or method" */ tFID = 307, /* "method" */ tGVAR = 308, /* "global variable" */ @@ -1708,54 +1708,54 @@ enum yysymbol_kind_t YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_keyword_class = 3, /* keyword_class */ - YYSYMBOL_keyword_module = 4, /* keyword_module */ - YYSYMBOL_keyword_def = 5, /* keyword_def */ - YYSYMBOL_keyword_begin = 6, /* keyword_begin */ - YYSYMBOL_keyword_if = 7, /* keyword_if */ - YYSYMBOL_keyword_unless = 8, /* keyword_unless */ - YYSYMBOL_keyword_while = 9, /* keyword_while */ - YYSYMBOL_keyword_until = 10, /* keyword_until */ - YYSYMBOL_keyword_for = 11, /* keyword_for */ - YYSYMBOL_keyword_undef = 12, /* keyword_undef */ - YYSYMBOL_keyword_rescue = 13, /* keyword_rescue */ - YYSYMBOL_keyword_ensure = 14, /* keyword_ensure */ - YYSYMBOL_keyword_end = 15, /* keyword_end */ - YYSYMBOL_keyword_then = 16, /* keyword_then */ - YYSYMBOL_keyword_elsif = 17, /* keyword_elsif */ - YYSYMBOL_keyword_else = 18, /* keyword_else */ - YYSYMBOL_keyword_case = 19, /* keyword_case */ - YYSYMBOL_keyword_when = 20, /* keyword_when */ - YYSYMBOL_keyword_break = 21, /* keyword_break */ - YYSYMBOL_keyword_next = 22, /* keyword_next */ - YYSYMBOL_keyword_redo = 23, /* keyword_redo */ - YYSYMBOL_keyword_retry = 24, /* keyword_retry */ - YYSYMBOL_keyword_in = 25, /* keyword_in */ - YYSYMBOL_keyword_do = 26, /* keyword_do */ - YYSYMBOL_keyword_do_cond = 27, /* keyword_do_cond */ - YYSYMBOL_keyword_do_block = 28, /* keyword_do_block */ - YYSYMBOL_keyword_do_LAMBDA = 29, /* keyword_do_LAMBDA */ - YYSYMBOL_keyword_return = 30, /* keyword_return */ - YYSYMBOL_keyword_yield = 31, /* keyword_yield */ - YYSYMBOL_keyword_super = 32, /* keyword_super */ - YYSYMBOL_keyword_self = 33, /* keyword_self */ - YYSYMBOL_keyword_nil = 34, /* keyword_nil */ - YYSYMBOL_keyword_true = 35, /* keyword_true */ - YYSYMBOL_keyword_false = 36, /* keyword_false */ - YYSYMBOL_keyword_and = 37, /* keyword_and */ - YYSYMBOL_keyword_or = 38, /* keyword_or */ - YYSYMBOL_keyword_not = 39, /* keyword_not */ - YYSYMBOL_modifier_if = 40, /* modifier_if */ - YYSYMBOL_modifier_unless = 41, /* modifier_unless */ - YYSYMBOL_modifier_while = 42, /* modifier_while */ - YYSYMBOL_modifier_until = 43, /* modifier_until */ - YYSYMBOL_modifier_rescue = 44, /* modifier_rescue */ - YYSYMBOL_keyword_alias = 45, /* keyword_alias */ - YYSYMBOL_keyword_BEGIN = 46, /* keyword_BEGIN */ - YYSYMBOL_keyword_END = 47, /* keyword_END */ - YYSYMBOL_keyword__LINE__ = 48, /* keyword__LINE__ */ - YYSYMBOL_keyword__FILE__ = 49, /* keyword__FILE__ */ - YYSYMBOL_keyword__ENCODING__ = 50, /* keyword__ENCODING__ */ + YYSYMBOL_keyword_class = 3, /* "'class'" */ + YYSYMBOL_keyword_module = 4, /* "'module'" */ + YYSYMBOL_keyword_def = 5, /* "'def'" */ + YYSYMBOL_keyword_begin = 6, /* "'begin'" */ + YYSYMBOL_keyword_if = 7, /* "'if'" */ + YYSYMBOL_keyword_unless = 8, /* "'unless'" */ + YYSYMBOL_keyword_while = 9, /* "'while'" */ + YYSYMBOL_keyword_until = 10, /* "'until'" */ + YYSYMBOL_keyword_for = 11, /* "'for'" */ + YYSYMBOL_keyword_undef = 12, /* "'undef'" */ + YYSYMBOL_keyword_rescue = 13, /* "'rescue'" */ + YYSYMBOL_keyword_ensure = 14, /* "'ensure'" */ + YYSYMBOL_keyword_end = 15, /* "'end'" */ + YYSYMBOL_keyword_then = 16, /* "'then'" */ + YYSYMBOL_keyword_elsif = 17, /* "'elsif'" */ + YYSYMBOL_keyword_else = 18, /* "'else'" */ + YYSYMBOL_keyword_case = 19, /* "'case'" */ + YYSYMBOL_keyword_when = 20, /* "'when'" */ + YYSYMBOL_keyword_break = 21, /* "'break'" */ + YYSYMBOL_keyword_next = 22, /* "'next'" */ + YYSYMBOL_keyword_redo = 23, /* "'redo'" */ + YYSYMBOL_keyword_retry = 24, /* "'retry'" */ + YYSYMBOL_keyword_in = 25, /* "'in'" */ + YYSYMBOL_keyword_do = 26, /* "'do'" */ + YYSYMBOL_keyword_do_cond = 27, /* "'do' for condition" */ + YYSYMBOL_keyword_do_block = 28, /* "'do' for block" */ + YYSYMBOL_keyword_do_LAMBDA = 29, /* "'do' for lambda" */ + YYSYMBOL_keyword_return = 30, /* "'return'" */ + YYSYMBOL_keyword_yield = 31, /* "'yield'" */ + YYSYMBOL_keyword_super = 32, /* "'super'" */ + YYSYMBOL_keyword_self = 33, /* "'self'" */ + YYSYMBOL_keyword_nil = 34, /* "'nil'" */ + YYSYMBOL_keyword_true = 35, /* "'true'" */ + YYSYMBOL_keyword_false = 36, /* "'false'" */ + YYSYMBOL_keyword_and = 37, /* "'and'" */ + YYSYMBOL_keyword_or = 38, /* "'or'" */ + YYSYMBOL_keyword_not = 39, /* "'not'" */ + YYSYMBOL_modifier_if = 40, /* "'if' modifier" */ + YYSYMBOL_modifier_unless = 41, /* "'unless' modifier" */ + YYSYMBOL_modifier_while = 42, /* "'while' modifier" */ + YYSYMBOL_modifier_until = 43, /* "'until' modifier" */ + YYSYMBOL_modifier_rescue = 44, /* "'rescue' modifier" */ + YYSYMBOL_keyword_alias = 45, /* "'alis'" */ + YYSYMBOL_keyword_BEGIN = 46, /* "'BEGIN'" */ + YYSYMBOL_keyword_END = 47, /* "'END'" */ + YYSYMBOL_keyword__LINE__ = 48, /* "'__LINE__'" */ + YYSYMBOL_keyword__FILE__ = 49, /* "'__FILE__'" */ + YYSYMBOL_keyword__ENCODING__ = 50, /* "'__ENCODING__'" */ YYSYMBOL_tIDENTIFIER = 51, /* "local variable or method" */ YYSYMBOL_tFID = 52, /* "method" */ YYSYMBOL_tGVAR = 53, /* "global variable" */ @@ -1945,7 +1945,7 @@ enum yysymbol_kind_t YYSYMBOL_f_larglist = 237, /* f_larglist */ YYSYMBOL_lambda_body = 238, /* lambda_body */ YYSYMBOL_do_block = 239, /* do_block */ - YYSYMBOL_240_26 = 240, /* $@26 */ + YYSYMBOL_240_26 = 240, /* @26 */ YYSYMBOL_block_call = 241, /* block_call */ YYSYMBOL_method_call = 242, /* method_call */ YYSYMBOL_brace_block = 243, /* brace_block */ @@ -2467,28 +2467,28 @@ static const yytype_int16 yyrline[] = 3037, 3042, 3046, 3050, 3054, 3058, 3062, 3066, 3070, 3074, 3078, 3082, 3086, 3090, 3094, 3098, 3104, 3109, 3116, 3116, 3120, 3125, 3132, 3136, 3142, 3143, 3146, 3151, 3154, 3158, - 3164, 3168, 3175, 3174, 3189, 3199, 3203, 3208, 3215, 3219, - 3223, 3227, 3231, 3235, 3239, 3243, 3247, 3254, 3253, 3268, - 3267, 3283, 3291, 3300, 3303, 3310, 3313, 3317, 3318, 3321, - 3325, 3328, 3332, 3335, 3336, 3337, 3338, 3341, 3342, 3348, - 3349, 3350, 3354, 3367, 3368, 3374, 3379, 3378, 3388, 3392, - 3398, 3402, 3415, 3419, 3425, 3428, 3429, 3432, 3438, 3444, - 3445, 3448, 3455, 3454, 3467, 3471, 3485, 3490, 3504, 3510, - 3511, 3512, 3513, 3514, 3518, 3524, 3528, 3538, 3539, 3540, - 3544, 3550, 3554, 3558, 3562, 3566, 3572, 3576, 3582, 3586, - 3590, 3594, 3598, 3602, 3610, 3617, 3623, 3624, 3628, 3632, - 3631, 3648, 3649, 3652, 3658, 3662, 3668, 3669, 3673, 3677, - 3683, 3687, 3693, 3699, 3706, 3712, 3719, 3723, 3729, 3733, - 3739, 3740, 3743, 3747, 3753, 3757, 3761, 3765, 3771, 3776, - 3781, 3785, 3789, 3793, 3797, 3801, 3805, 3809, 3813, 3817, - 3821, 3825, 3829, 3833, 3838, 3844, 3849, 3854, 3859, 3864, - 3871, 3875, 3882, 3887, 3886, 3898, 3902, 3908, 3916, 3924, - 3932, 3936, 3942, 3946, 3952, 3953, 3956, 3961, 3968, 3969, - 3972, 3976, 3982, 3986, 3992, 3997, 3997, 4022, 4023, 4029, - 4034, 4040, 4046, 4051, 4055, 4060, 4065, 4075, 4080, 4086, - 4087, 4088, 4091, 4092, 4093, 4094, 4097, 4098, 4099, 4102, - 4103, 4106, 4110, 4116, 4117, 4123, 4124, 4127, 4128, 4131, - 4134, 4135, 4136, 4139, 4140, 4143, 4148, 4151, 4152, 4156 + 3164, 3168, 3175, 3174, 3191, 3201, 3205, 3210, 3217, 3221, + 3225, 3229, 3233, 3237, 3241, 3245, 3249, 3256, 3255, 3270, + 3269, 3285, 3293, 3302, 3305, 3312, 3315, 3319, 3320, 3323, + 3327, 3330, 3334, 3337, 3338, 3339, 3340, 3343, 3344, 3350, + 3351, 3352, 3356, 3369, 3370, 3376, 3381, 3380, 3390, 3394, + 3400, 3404, 3417, 3421, 3427, 3430, 3431, 3434, 3440, 3446, + 3447, 3450, 3457, 3456, 3469, 3473, 3487, 3492, 3506, 3512, + 3513, 3514, 3515, 3516, 3520, 3526, 3530, 3540, 3541, 3542, + 3546, 3552, 3556, 3560, 3564, 3568, 3574, 3578, 3584, 3588, + 3592, 3596, 3600, 3604, 3612, 3619, 3625, 3626, 3630, 3634, + 3633, 3650, 3651, 3654, 3660, 3664, 3670, 3671, 3675, 3679, + 3685, 3689, 3695, 3701, 3708, 3714, 3721, 3725, 3731, 3735, + 3741, 3742, 3745, 3749, 3755, 3759, 3763, 3767, 3773, 3778, + 3783, 3787, 3791, 3795, 3799, 3803, 3807, 3811, 3815, 3819, + 3823, 3827, 3831, 3835, 3840, 3846, 3851, 3856, 3861, 3866, + 3873, 3877, 3884, 3889, 3888, 3900, 3904, 3910, 3918, 3926, + 3934, 3938, 3944, 3948, 3954, 3955, 3958, 3963, 3970, 3971, + 3974, 3978, 3984, 3988, 3994, 3999, 3999, 4024, 4025, 4031, + 4036, 4042, 4048, 4053, 4057, 4062, 4067, 4077, 4082, 4088, + 4089, 4090, 4093, 4094, 4095, 4096, 4099, 4100, 4101, 4104, + 4105, 4108, 4112, 4118, 4119, 4125, 4126, 4129, 4130, 4133, + 4136, 4137, 4138, 4141, 4142, 4145, 4150, 4153, 4154, 4158 }; #endif @@ -2504,68 +2504,67 @@ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "\"end of file\"", "error", "\"invalid token\"", "keyword_class", - "keyword_module", "keyword_def", "keyword_begin", "keyword_if", - "keyword_unless", "keyword_while", "keyword_until", "keyword_for", - "keyword_undef", "keyword_rescue", "keyword_ensure", "keyword_end", - "keyword_then", "keyword_elsif", "keyword_else", "keyword_case", - "keyword_when", "keyword_break", "keyword_next", "keyword_redo", - "keyword_retry", "keyword_in", "keyword_do", "keyword_do_cond", - "keyword_do_block", "keyword_do_LAMBDA", "keyword_return", - "keyword_yield", "keyword_super", "keyword_self", "keyword_nil", - "keyword_true", "keyword_false", "keyword_and", "keyword_or", - "keyword_not", "modifier_if", "modifier_unless", "modifier_while", - "modifier_until", "modifier_rescue", "keyword_alias", "keyword_BEGIN", - "keyword_END", "keyword__LINE__", "keyword__FILE__", - "keyword__ENCODING__", "\"local variable or method\"", "\"method\"", - "\"global variable\"", "\"instance variable\"", "\"constant\"", - "\"class variable\"", "\"label\"", "\"integer literal\"", - "\"float literal\"", "\"character literal\"", "tXSTRING", "tREGEXP", - "tSTRING", "tSTRING_PART", "tSTRING_MID", "tNTH_REF", "tBACK_REF", - "tREGEXP_END", "\"numbered parameter\"", "\"unary plus\"", - "\"unary minus\"", "\"<=>\"", "\"==\"", "\"===\"", "\"!=\"", "\">=\"", - "\"<=\"", "\"&&\"", "\"||\"", "\"=~\"", "\"!~\"", "\"..\"", "\"...\"", - "tBDOT2", "tBDOT3", "tAREF", "tASET", "\"<<\"", "\">>\"", "\"::\"", - "tCOLON3", "tOP_ASGN", "\"=>\"", "tLPAREN", "\"(\"", "\")\"", "\"[\"", - "tLBRACE", "\"{\"", "\"*\"", "tPOW", "\"**\"", "\"&\"", "\"->\"", - "\"&.\"", "\"symbol\"", "\"string literal\"", "tXSTRING_BEG", - "tSTRING_DVAR", "tREGEXP_BEG", "tWORDS_BEG", "tSYMBOLS_BEG", "tLAMBEG", - "\"here document\"", "tHEREDOC_END", "tLITERAL_DELIM", - "tHD_LITERAL_DELIM", "tHD_STRING_PART", "tHD_STRING_MID", "tLOWEST", - "'='", "'?'", "':'", "'>'", "'<'", "'|'", "'^'", "'&'", "'+'", "'-'", - "'*'", "'/'", "'%'", "tUMINUS_NUM", "'!'", "'~'", "tLAST_TOKEN", "'{'", - "'}'", "'['", "']'", "','", "'`'", "'('", "')'", "';'", "'.'", "'\\n'", - "$accept", "program", "$@1", "top_compstmt", "top_stmts", "top_stmt", - "@2", "bodystmt", "compstmt", "stmts", "stmt", "$@3", "command_asgn", - "command_rhs", "expr", "defn_head", "defs_head", "$@4", "expr_value", - "command_call", "block_command", "cmd_brace_block", "$@5", "command", - "mlhs", "mlhs_inner", "mlhs_basic", "mlhs_item", "mlhs_list", - "mlhs_post", "mlhs_node", "lhs", "cname", "cpath", "fname", "fsym", - "undef_list", "$@6", "op", "reswords", "arg", "aref_args", "arg_rhs", - "paren_args", "opt_paren_args", "opt_call_args", "call_args", - "command_args", "@7", "block_arg", "opt_block_arg", "comma", "args", - "mrhs", "primary", "@8", "@9", "$@10", "$@11", "@12", "@13", "$@14", - "$@15", "$@16", "$@17", "$@18", "$@19", "@20", "@21", "@22", "@23", - "primary_value", "then", "do", "if_tail", "opt_else", "for_var", - "f_margs", "$@24", "block_args_tail", "opt_block_args_tail", - "block_param", "opt_block_param", "block_param_def", "$@25", - "opt_bv_decl", "bv_decls", "bvar", "f_larglist", "lambda_body", - "do_block", "$@26", "block_call", "method_call", "brace_block", "@27", - "@28", "case_body", "cases", "opt_rescue", "exc_list", "exc_var", - "opt_ensure", "literal", "string", "string_fragment", "string_rep", - "string_interp", "@29", "xstring", "regexp", "heredoc", "heredoc_bodies", - "heredoc_body", "heredoc_string_rep", "heredoc_string_interp", "@30", - "words", "symbol", "basic_symbol", "sym", "symbols", "numeric", - "variable", "var_lhs", "var_ref", "backref", "superclass", "$@31", - "f_opt_arglist_paren", "f_arglist_paren", "f_arglist", "f_label", "f_kw", - "f_block_kw", "f_block_kwarg", "f_kwarg", "kwrest_mark", "f_kwrest", - "args_tail", "opt_args_tail", "f_args", "f_bad_arg", "f_norm_arg", - "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", "assoc", "operation", "operation2", "operation3", - "dot_or_colon", "call_op", "call_op2", "opt_terms", "opt_nl", "rparen", - "trailer", "term", "nl", "terms", "none", YY_NULLPTR + "\"end of file\"", "error", "\"invalid token\"", "\"'class'\"", + "\"'module'\"", "\"'def'\"", "\"'begin'\"", "\"'if'\"", "\"'unless'\"", + "\"'while'\"", "\"'until'\"", "\"'for'\"", "\"'undef'\"", "\"'rescue'\"", + "\"'ensure'\"", "\"'end'\"", "\"'then'\"", "\"'elsif'\"", "\"'else'\"", + "\"'case'\"", "\"'when'\"", "\"'break'\"", "\"'next'\"", "\"'redo'\"", + "\"'retry'\"", "\"'in'\"", "\"'do'\"", "\"'do' for condition\"", + "\"'do' for block\"", "\"'do' for lambda\"", "\"'return'\"", + "\"'yield'\"", "\"'super'\"", "\"'self'\"", "\"'nil'\"", "\"'true'\"", + "\"'false'\"", "\"'and'\"", "\"'or'\"", "\"'not'\"", "\"'if' modifier\"", + "\"'unless' modifier\"", "\"'while' modifier\"", "\"'until' modifier\"", + "\"'rescue' modifier\"", "\"'alis'\"", "\"'BEGIN'\"", "\"'END'\"", + "\"'__LINE__'\"", "\"'__FILE__'\"", "\"'__ENCODING__'\"", + "\"local variable or method\"", "\"method\"", "\"global variable\"", + "\"instance variable\"", "\"constant\"", "\"class variable\"", + "\"label\"", "\"integer literal\"", "\"float literal\"", + "\"character literal\"", "tXSTRING", "tREGEXP", "tSTRING", + "tSTRING_PART", "tSTRING_MID", "tNTH_REF", "tBACK_REF", "tREGEXP_END", + "\"numbered parameter\"", "\"unary plus\"", "\"unary minus\"", "\"<=>\"", + "\"==\"", "\"===\"", "\"!=\"", "\">=\"", "\"<=\"", "\"&&\"", "\"||\"", + "\"=~\"", "\"!~\"", "\"..\"", "\"...\"", "tBDOT2", "tBDOT3", "tAREF", + "tASET", "\"<<\"", "\">>\"", "\"::\"", "tCOLON3", "tOP_ASGN", "\"=>\"", + "tLPAREN", "\"(\"", "\")\"", "\"[\"", "tLBRACE", "\"{\"", "\"*\"", + "tPOW", "\"**\"", "\"&\"", "\"->\"", "\"&.\"", "\"symbol\"", + "\"string literal\"", "tXSTRING_BEG", "tSTRING_DVAR", "tREGEXP_BEG", + "tWORDS_BEG", "tSYMBOLS_BEG", "tLAMBEG", "\"here document\"", + "tHEREDOC_END", "tLITERAL_DELIM", "tHD_LITERAL_DELIM", "tHD_STRING_PART", + "tHD_STRING_MID", "tLOWEST", "'='", "'?'", "':'", "'>'", "'<'", "'|'", + "'^'", "'&'", "'+'", "'-'", "'*'", "'/'", "'%'", "tUMINUS_NUM", "'!'", + "'~'", "tLAST_TOKEN", "'{'", "'}'", "'['", "']'", "','", "'`'", "'('", + "')'", "';'", "'.'", "'\\n'", "$accept", "program", "$@1", + "top_compstmt", "top_stmts", "top_stmt", "@2", "bodystmt", "compstmt", + "stmts", "stmt", "$@3", "command_asgn", "command_rhs", "expr", + "defn_head", "defs_head", "$@4", "expr_value", "command_call", + "block_command", "cmd_brace_block", "$@5", "command", "mlhs", + "mlhs_inner", "mlhs_basic", "mlhs_item", "mlhs_list", "mlhs_post", + "mlhs_node", "lhs", "cname", "cpath", "fname", "fsym", "undef_list", + "$@6", "op", "reswords", "arg", "aref_args", "arg_rhs", "paren_args", + "opt_paren_args", "opt_call_args", "call_args", "command_args", "@7", + "block_arg", "opt_block_arg", "comma", "args", "mrhs", "primary", "@8", + "@9", "$@10", "$@11", "@12", "@13", "$@14", "$@15", "$@16", "$@17", + "$@18", "$@19", "@20", "@21", "@22", "@23", "primary_value", "then", + "do", "if_tail", "opt_else", "for_var", "f_margs", "$@24", + "block_args_tail", "opt_block_args_tail", "block_param", + "opt_block_param", "block_param_def", "$@25", "opt_bv_decl", "bv_decls", + "bvar", "f_larglist", "lambda_body", "do_block", "@26", "block_call", + "method_call", "brace_block", "@27", "@28", "case_body", "cases", + "opt_rescue", "exc_list", "exc_var", "opt_ensure", "literal", "string", + "string_fragment", "string_rep", "string_interp", "@29", "xstring", + "regexp", "heredoc", "heredoc_bodies", "heredoc_body", + "heredoc_string_rep", "heredoc_string_interp", "@30", "words", "symbol", + "basic_symbol", "sym", "symbols", "numeric", "variable", "var_lhs", + "var_ref", "backref", "superclass", "$@31", "f_opt_arglist_paren", + "f_arglist_paren", "f_arglist", "f_label", "f_kw", "f_block_kw", + "f_block_kwarg", "f_kwarg", "kwrest_mark", "f_kwrest", "args_tail", + "opt_args_tail", "f_args", "f_bad_arg", "f_norm_arg", "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", "assoc", + "operation", "operation2", "operation3", "dot_or_colon", "call_op", + "call_op2", "opt_terms", "opt_nl", "rparen", "trailer", "term", "nl", + "terms", "none", YY_NULLPTR }; static const char * @@ -6486,7 +6485,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->lstate = EXPR_BEG; if (!p->locals) p->locals = cons(0,0); } -#line 6490 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6489 "mrbgems/mruby-compiler/core/y.tab.c" break; case 3: /* program: $@1 top_compstmt */ @@ -6495,7 +6494,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->tree = new_scope(p, (yyvsp[0].nd)); NODE_LINENO(p->tree, (yyvsp[0].nd)); } -#line 6499 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6498 "mrbgems/mruby-compiler/core/y.tab.c" break; case 4: /* top_compstmt: top_stmts opt_terms */ @@ -6503,7 +6502,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 6507 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6506 "mrbgems/mruby-compiler/core/y.tab.c" break; case 5: /* top_stmts: none */ @@ -6511,7 +6510,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, 0); } -#line 6515 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6514 "mrbgems/mruby-compiler/core/y.tab.c" break; case 6: /* top_stmts: top_stmt */ @@ -6520,7 +6519,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6524 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6523 "mrbgems/mruby-compiler/core/y.tab.c" break; case 7: /* top_stmts: top_stmts terms top_stmt */ @@ -6528,7 +6527,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6532 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6531 "mrbgems/mruby-compiler/core/y.tab.c" break; case 8: /* top_stmts: error top_stmt */ @@ -6536,7 +6535,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, 0); } -#line 6540 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6539 "mrbgems/mruby-compiler/core/y.tab.c" break; case 10: /* @2: %empty */ @@ -6545,10 +6544,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 6549 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6548 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 11: /* top_stmt: keyword_BEGIN @2 '{' top_compstmt '}' */ + case 11: /* top_stmt: "'BEGIN'" @2 '{' top_compstmt '}' */ #line 1668 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "BEGIN not supported"); @@ -6556,7 +6555,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); (yyval.nd) = 0; } -#line 6560 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6559 "mrbgems/mruby-compiler/core/y.tab.c" break; case 12: /* bodystmt: compstmt opt_rescue opt_else opt_ensure */ @@ -6582,7 +6581,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } } } -#line 6586 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6585 "mrbgems/mruby-compiler/core/y.tab.c" break; case 13: /* compstmt: stmts opt_terms */ @@ -6590,7 +6589,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 6594 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6593 "mrbgems/mruby-compiler/core/y.tab.c" break; case 14: /* stmts: none */ @@ -6598,7 +6597,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, 0); } -#line 6602 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6601 "mrbgems/mruby-compiler/core/y.tab.c" break; case 15: /* stmts: stmt */ @@ -6607,7 +6606,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_begin(p, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 6611 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6610 "mrbgems/mruby-compiler/core/y.tab.c" break; case 16: /* stmts: stmts terms stmt */ @@ -6615,7 +6614,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), newline_node((yyvsp[0].nd))); } -#line 6619 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6618 "mrbgems/mruby-compiler/core/y.tab.c" break; case 17: /* stmts: error stmt */ @@ -6623,78 +6622,78 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_begin(p, (yyvsp[0].nd)); } -#line 6627 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6626 "mrbgems/mruby-compiler/core/y.tab.c" break; case 18: /* $@3: %empty */ #line 1728 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 6633 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6632 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 19: /* stmt: keyword_alias fsym $@3 fsym */ + case 19: /* stmt: "'alis'" fsym $@3 fsym */ #line 1729 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_alias(p, (yyvsp[-2].id), (yyvsp[0].id)); } -#line 6641 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6640 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 20: /* stmt: keyword_undef undef_list */ + case 20: /* stmt: "'undef'" undef_list */ #line 1733 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 6649 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6648 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 21: /* stmt: stmt modifier_if expr_value */ + case 21: /* stmt: stmt "'if' modifier" expr_value */ #line 1737 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6657 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6656 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 22: /* stmt: stmt modifier_unless expr_value */ + case 22: /* stmt: stmt "'unless' modifier" expr_value */ #line 1741 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_unless(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd), 0); } -#line 6665 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6664 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 23: /* stmt: stmt modifier_while expr_value */ + case 23: /* stmt: stmt "'while' modifier" expr_value */ #line 1745 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_while(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6673 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6672 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 24: /* stmt: stmt modifier_until expr_value */ + case 24: /* stmt: stmt "'until' modifier" expr_value */ #line 1749 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_until(p, cond((yyvsp[0].nd)), (yyvsp[-2].nd)); } -#line 6681 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6680 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 25: /* stmt: stmt modifier_rescue stmt */ + case 25: /* stmt: stmt "'rescue' modifier" stmt */ #line 1753 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6689 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6688 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 26: /* stmt: keyword_END '{' compstmt '}' */ + case 26: /* stmt: "'END'" '{' compstmt '}' */ #line 1757 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "END not supported"); (yyval.nd) = new_postexe(p, (yyvsp[-1].nd)); } -#line 6698 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6697 "mrbgems/mruby-compiler/core/y.tab.c" break; case 28: /* stmt: mlhs '=' command_call */ @@ -6702,7 +6701,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6706 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6705 "mrbgems/mruby-compiler/core/y.tab.c" break; case 29: /* stmt: lhs '=' mrhs */ @@ -6710,7 +6709,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6714 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6713 "mrbgems/mruby-compiler/core/y.tab.c" break; case 30: /* stmt: mlhs '=' arg */ @@ -6718,7 +6717,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6722 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6721 "mrbgems/mruby-compiler/core/y.tab.c" break; case 31: /* stmt: mlhs '=' mrhs */ @@ -6726,7 +6725,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-2].nd), new_array(p, (yyvsp[0].nd))); } -#line 6730 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6729 "mrbgems/mruby-compiler/core/y.tab.c" break; case 32: /* stmt: arg "=>" "local variable or method" */ @@ -6736,7 +6735,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); assignable(p, lhs); (yyval.nd) = new_asgn(p, lhs, (yyvsp[-2].nd)); } -#line 6740 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6739 "mrbgems/mruby-compiler/core/y.tab.c" break; case 34: /* command_asgn: lhs '=' command_rhs */ @@ -6744,7 +6743,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6748 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6747 "mrbgems/mruby-compiler/core/y.tab.c" break; case 35: /* command_asgn: var_lhs tOP_ASGN command_rhs */ @@ -6752,7 +6751,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6756 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6755 "mrbgems/mruby-compiler/core/y.tab.c" break; case 36: /* command_asgn: primary_value '[' opt_call_args ']' tOP_ASGN command_rhs */ @@ -6760,7 +6759,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 6764 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6763 "mrbgems/mruby-compiler/core/y.tab.c" break; case 37: /* command_asgn: primary_value call_op "local variable or method" tOP_ASGN command_rhs */ @@ -6768,7 +6767,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 6772 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6771 "mrbgems/mruby-compiler/core/y.tab.c" break; case 38: /* command_asgn: primary_value call_op "constant" tOP_ASGN command_rhs */ @@ -6776,7 +6775,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 6780 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6779 "mrbgems/mruby-compiler/core/y.tab.c" break; case 39: /* command_asgn: primary_value "::" "constant" tOP_ASGN command_call */ @@ -6785,7 +6784,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "constant re-assignment"); (yyval.nd) = 0; } -#line 6789 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6788 "mrbgems/mruby-compiler/core/y.tab.c" break; case 40: /* command_asgn: primary_value "::" "local variable or method" tOP_ASGN command_rhs */ @@ -6793,7 +6792,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6797 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6796 "mrbgems/mruby-compiler/core/y.tab.c" break; case 41: /* command_asgn: defn_head f_opt_arglist_paren '=' command */ @@ -6806,10 +6805,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 6810 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6809 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 42: /* command_asgn: defn_head f_opt_arglist_paren '=' command modifier_rescue arg */ + case 42: /* command_asgn: defn_head f_opt_arglist_paren '=' command "'rescue' modifier" arg */ #line 1826 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -6819,7 +6818,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 6823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6822 "mrbgems/mruby-compiler/core/y.tab.c" break; case 43: /* command_asgn: defs_head f_opt_arglist_paren '=' command */ @@ -6832,10 +6831,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 6836 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6835 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 44: /* command_asgn: defs_head f_opt_arglist_paren '=' command modifier_rescue arg */ + case 44: /* command_asgn: defs_head f_opt_arglist_paren '=' command "'rescue' modifier" arg */ #line 1844 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -6845,7 +6844,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 6849 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6848 "mrbgems/mruby-compiler/core/y.tab.c" break; case 45: /* command_asgn: backref tOP_ASGN command_rhs */ @@ -6854,39 +6853,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 6858 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6857 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 47: /* command_rhs: command_call modifier_rescue stmt */ + case 47: /* command_rhs: command_call "'rescue' modifier" stmt */ #line 1861 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6866 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6865 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 50: /* expr: expr keyword_and expr */ + case 50: /* expr: expr "'and'" expr */ #line 1870 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6874 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6873 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 51: /* expr: expr keyword_or expr */ + case 51: /* expr: expr "'or'" expr */ #line 1874 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 6882 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6881 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 52: /* expr: keyword_not opt_nl expr */ + case 52: /* expr: "'not'" opt_nl expr */ #line 1878 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6890 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6889 "mrbgems/mruby-compiler/core/y.tab.c" break; case 53: /* expr: '!' command_call */ @@ -6894,10 +6893,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 6898 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6897 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 55: /* defn_head: keyword_def fname */ + case 55: /* defn_head: "'def'" fname */ #line 1890 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_def(p, (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); @@ -6905,7 +6904,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def++; nvars_block(p); } -#line 6909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6908 "mrbgems/mruby-compiler/core/y.tab.c" break; case 56: /* $@4: %empty */ @@ -6913,10 +6912,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { p->lstate = EXPR_FNAME; } -#line 6917 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6916 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 57: /* defs_head: keyword_def singleton dot_or_colon $@4 fname */ + case 57: /* defs_head: "'def'" singleton dot_or_colon $@4 fname */ #line 1903 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sdef(p, (yyvsp[-3].nd), (yyvsp[0].id), nint(p->cmdarg_stack), local_switch(p)); @@ -6926,7 +6925,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_block(p); p->lstate = EXPR_ENDFN; /* force for args */ } -#line 6930 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6929 "mrbgems/mruby-compiler/core/y.tab.c" break; case 58: /* expr_value: expr */ @@ -6937,7 +6936,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = (yyvsp[0].nd); } } -#line 6941 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6940 "mrbgems/mruby-compiler/core/y.tab.c" break; case 62: /* block_command: block_call call_op2 operation2 command_args */ @@ -6945,7 +6944,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6949 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6948 "mrbgems/mruby-compiler/core/y.tab.c" break; case 63: /* $@5: %empty */ @@ -6954,7 +6953,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_nest(p); nvars_nest(p); } -#line 6958 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6957 "mrbgems/mruby-compiler/core/y.tab.c" break; case 64: /* cmd_brace_block: "{" $@5 opt_block_param compstmt '}' */ @@ -6964,7 +6963,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_unnest(p); nvars_unnest(p); } -#line 6968 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6967 "mrbgems/mruby-compiler/core/y.tab.c" break; case 65: /* command: operation command_args */ @@ -6972,7 +6971,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 6976 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6975 "mrbgems/mruby-compiler/core/y.tab.c" break; case 66: /* command: operation command_args cmd_brace_block */ @@ -6981,7 +6980,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); args_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = new_fcall(p, (yyvsp[-2].id), (yyvsp[-1].nd)); } -#line 6985 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6984 "mrbgems/mruby-compiler/core/y.tab.c" break; case 67: /* command: primary_value call_op operation2 command_args */ @@ -6989,7 +6988,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 6993 "mrbgems/mruby-compiler/core/y.tab.c" +#line 6992 "mrbgems/mruby-compiler/core/y.tab.c" break; case 68: /* command: primary_value call_op operation2 command_args cmd_brace_block */ @@ -6998,7 +6997,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 7002 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7001 "mrbgems/mruby-compiler/core/y.tab.c" break; case 69: /* command: primary_value "::" operation2 command_args */ @@ -7006,7 +7005,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 7010 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7009 "mrbgems/mruby-compiler/core/y.tab.c" break; case 70: /* command: primary_value "::" operation2 command_args cmd_brace_block */ @@ -7015,47 +7014,47 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 7019 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7018 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 71: /* command: keyword_super command_args */ + case 71: /* command: "'super'" command_args */ #line 1976 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 7027 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7026 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 72: /* command: keyword_yield command_args */ + case 72: /* command: "'yield'" command_args */ #line 1980 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 7035 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7034 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 73: /* command: keyword_return call_args */ + case 73: /* command: "'return'" call_args */ #line 1984 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, ret_args(p, (yyvsp[0].nd))); } -#line 7043 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7042 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 74: /* command: keyword_break call_args */ + case 74: /* command: "'break'" call_args */ #line 1988 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, ret_args(p, (yyvsp[0].nd))); } -#line 7051 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7050 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 75: /* command: keyword_next call_args */ + case 75: /* command: "'next'" call_args */ #line 1992 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, ret_args(p, (yyvsp[0].nd))); } -#line 7059 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7058 "mrbgems/mruby-compiler/core/y.tab.c" break; case 76: /* mlhs: mlhs_basic */ @@ -7063,7 +7062,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 7067 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7066 "mrbgems/mruby-compiler/core/y.tab.c" break; case 77: /* mlhs: tLPAREN mlhs_inner rparen */ @@ -7071,7 +7070,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 7075 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7074 "mrbgems/mruby-compiler/core/y.tab.c" break; case 79: /* mlhs_inner: tLPAREN mlhs_inner rparen */ @@ -7079,7 +7078,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 7083 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7082 "mrbgems/mruby-compiler/core/y.tab.c" break; case 80: /* mlhs_basic: mlhs_list */ @@ -7087,7 +7086,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 7091 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7090 "mrbgems/mruby-compiler/core/y.tab.c" break; case 81: /* mlhs_basic: mlhs_list mlhs_item */ @@ -7095,7 +7094,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(push((yyvsp[-1].nd),(yyvsp[0].nd))); } -#line 7099 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7098 "mrbgems/mruby-compiler/core/y.tab.c" break; case 82: /* mlhs_basic: mlhs_list "*" mlhs_node */ @@ -7103,7 +7102,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7107 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7106 "mrbgems/mruby-compiler/core/y.tab.c" break; case 83: /* mlhs_basic: mlhs_list "*" mlhs_node ',' mlhs_post */ @@ -7111,7 +7110,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-4].nd), (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7115 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7114 "mrbgems/mruby-compiler/core/y.tab.c" break; case 84: /* mlhs_basic: mlhs_list "*" */ @@ -7119,7 +7118,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2((yyvsp[-1].nd), new_nil(p)); } -#line 7123 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7122 "mrbgems/mruby-compiler/core/y.tab.c" break; case 85: /* mlhs_basic: mlhs_list "*" ',' mlhs_post */ @@ -7127,7 +7126,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-3].nd), new_nil(p), (yyvsp[0].nd)); } -#line 7131 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7130 "mrbgems/mruby-compiler/core/y.tab.c" break; case 86: /* mlhs_basic: "*" mlhs_node */ @@ -7135,7 +7134,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2(0, (yyvsp[0].nd)); } -#line 7139 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7138 "mrbgems/mruby-compiler/core/y.tab.c" break; case 87: /* mlhs_basic: "*" mlhs_node ',' mlhs_post */ @@ -7143,7 +7142,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7147 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7146 "mrbgems/mruby-compiler/core/y.tab.c" break; case 88: /* mlhs_basic: "*" */ @@ -7151,7 +7150,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list2(0, new_nil(p)); } -#line 7155 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7154 "mrbgems/mruby-compiler/core/y.tab.c" break; case 89: /* mlhs_basic: "*" ',' mlhs_post */ @@ -7159,7 +7158,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, new_nil(p), (yyvsp[0].nd)); } -#line 7163 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7162 "mrbgems/mruby-compiler/core/y.tab.c" break; case 91: /* mlhs_item: tLPAREN mlhs_inner rparen */ @@ -7167,7 +7166,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_masgn(p, (yyvsp[-1].nd), NULL); } -#line 7171 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7170 "mrbgems/mruby-compiler/core/y.tab.c" break; case 92: /* mlhs_list: mlhs_item ',' */ @@ -7175,7 +7174,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1((yyvsp[-1].nd)); } -#line 7179 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7178 "mrbgems/mruby-compiler/core/y.tab.c" break; case 93: /* mlhs_list: mlhs_list mlhs_item ',' */ @@ -7183,7 +7182,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[-1].nd)); } -#line 7187 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7186 "mrbgems/mruby-compiler/core/y.tab.c" break; case 94: /* mlhs_post: mlhs_item */ @@ -7191,7 +7190,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 7195 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7194 "mrbgems/mruby-compiler/core/y.tab.c" break; case 95: /* mlhs_post: mlhs_list mlhs_item */ @@ -7199,7 +7198,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 7203 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7202 "mrbgems/mruby-compiler/core/y.tab.c" break; case 96: /* mlhs_node: variable */ @@ -7207,7 +7206,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { assignable(p, (yyvsp[0].nd)); } -#line 7211 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7210 "mrbgems/mruby-compiler/core/y.tab.c" break; case 97: /* mlhs_node: primary_value '[' opt_call_args ']' */ @@ -7215,7 +7214,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 7219 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7218 "mrbgems/mruby-compiler/core/y.tab.c" break; case 98: /* mlhs_node: primary_value call_op "local variable or method" */ @@ -7223,7 +7222,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7227 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7226 "mrbgems/mruby-compiler/core/y.tab.c" break; case 99: /* mlhs_node: primary_value "::" "local variable or method" */ @@ -7231,7 +7230,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 7235 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7234 "mrbgems/mruby-compiler/core/y.tab.c" break; case 100: /* mlhs_node: primary_value call_op "constant" */ @@ -7239,7 +7238,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7243 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7242 "mrbgems/mruby-compiler/core/y.tab.c" break; case 101: /* mlhs_node: primary_value "::" "constant" */ @@ -7249,7 +7248,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 7253 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7252 "mrbgems/mruby-compiler/core/y.tab.c" break; case 102: /* mlhs_node: tCOLON3 "constant" */ @@ -7259,7 +7258,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 7263 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7262 "mrbgems/mruby-compiler/core/y.tab.c" break; case 103: /* mlhs_node: backref */ @@ -7268,7 +7267,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 7272 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7271 "mrbgems/mruby-compiler/core/y.tab.c" break; case 104: /* lhs: variable */ @@ -7276,7 +7275,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { assignable(p, (yyvsp[0].nd)); } -#line 7280 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7279 "mrbgems/mruby-compiler/core/y.tab.c" break; case 105: /* lhs: primary_value '[' opt_call_args ']' */ @@ -7284,7 +7283,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 7288 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7287 "mrbgems/mruby-compiler/core/y.tab.c" break; case 106: /* lhs: primary_value call_op "local variable or method" */ @@ -7292,7 +7291,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7296 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7295 "mrbgems/mruby-compiler/core/y.tab.c" break; case 107: /* lhs: primary_value "::" "local variable or method" */ @@ -7300,7 +7299,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 7304 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7303 "mrbgems/mruby-compiler/core/y.tab.c" break; case 108: /* lhs: primary_value call_op "constant" */ @@ -7308,7 +7307,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, (yyvsp[-1].num)); } -#line 7312 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7311 "mrbgems/mruby-compiler/core/y.tab.c" break; case 109: /* lhs: primary_value "::" "constant" */ @@ -7318,7 +7317,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 7322 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7321 "mrbgems/mruby-compiler/core/y.tab.c" break; case 110: /* lhs: tCOLON3 "constant" */ @@ -7328,7 +7327,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "dynamic constant assignment"); (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 7332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7331 "mrbgems/mruby-compiler/core/y.tab.c" break; case 111: /* lhs: backref */ @@ -7337,7 +7336,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[0].nd)); (yyval.nd) = 0; } -#line 7341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7340 "mrbgems/mruby-compiler/core/y.tab.c" break; case 112: /* lhs: "numbered parameter" */ @@ -7345,7 +7344,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { yyerror(p, "can't assign to numbered parameter"); } -#line 7349 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7348 "mrbgems/mruby-compiler/core/y.tab.c" break; case 113: /* cname: "local variable or method" */ @@ -7353,7 +7352,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { yyerror(p, "class/module name must be CONSTANT"); } -#line 7357 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7356 "mrbgems/mruby-compiler/core/y.tab.c" break; case 115: /* cpath: tCOLON3 cname */ @@ -7361,7 +7360,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = cons(nint(1), nsym((yyvsp[0].id))); } -#line 7365 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7364 "mrbgems/mruby-compiler/core/y.tab.c" break; case 116: /* cpath: cname */ @@ -7369,7 +7368,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = cons(nint(0), nsym((yyvsp[0].id))); } -#line 7373 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7372 "mrbgems/mruby-compiler/core/y.tab.c" break; case 117: /* cpath: primary_value "::" cname */ @@ -7378,7 +7377,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = cons((yyvsp[-2].nd), nsym((yyvsp[0].id))); } -#line 7382 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7381 "mrbgems/mruby-compiler/core/y.tab.c" break; case 121: /* fname: op */ @@ -7387,7 +7386,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7391 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7390 "mrbgems/mruby-compiler/core/y.tab.c" break; case 122: /* fname: reswords */ @@ -7396,7 +7395,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->lstate = EXPR_ENDFN; (yyval.id) = (yyvsp[0].id); } -#line 7400 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7399 "mrbgems/mruby-compiler/core/y.tab.c" break; case 125: /* undef_list: fsym */ @@ -7404,13 +7403,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_undef(p, (yyvsp[0].id)); } -#line 7408 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7407 "mrbgems/mruby-compiler/core/y.tab.c" break; case 126: /* $@6: %empty */ #line 2210 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_FNAME;} -#line 7414 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7413 "mrbgems/mruby-compiler/core/y.tab.c" break; case 127: /* undef_list: undef_list ',' $@6 fsym */ @@ -7418,187 +7417,187 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), nsym((yyvsp[0].id))); } -#line 7422 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7421 "mrbgems/mruby-compiler/core/y.tab.c" break; case 128: /* op: '|' */ #line 2216 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(or); } -#line 7428 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7427 "mrbgems/mruby-compiler/core/y.tab.c" break; case 129: /* op: '^' */ #line 2217 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(xor); } -#line 7434 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7433 "mrbgems/mruby-compiler/core/y.tab.c" break; case 130: /* op: '&' */ #line 2218 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 7440 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7439 "mrbgems/mruby-compiler/core/y.tab.c" break; case 131: /* op: "<=>" */ #line 2219 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(cmp); } -#line 7446 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7445 "mrbgems/mruby-compiler/core/y.tab.c" break; case 132: /* op: "==" */ #line 2220 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eq); } -#line 7452 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7451 "mrbgems/mruby-compiler/core/y.tab.c" break; case 133: /* op: "===" */ #line 2221 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(eqq); } -#line 7458 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7457 "mrbgems/mruby-compiler/core/y.tab.c" break; case 134: /* op: "=~" */ #line 2222 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(match); } -#line 7464 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7463 "mrbgems/mruby-compiler/core/y.tab.c" break; case 135: /* op: "!~" */ #line 2223 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(nmatch); } -#line 7470 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7469 "mrbgems/mruby-compiler/core/y.tab.c" break; case 136: /* op: '>' */ #line 2224 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(gt); } -#line 7476 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7475 "mrbgems/mruby-compiler/core/y.tab.c" break; case 137: /* op: ">=" */ #line 2225 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(ge); } -#line 7482 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7481 "mrbgems/mruby-compiler/core/y.tab.c" break; case 138: /* op: '<' */ #line 2226 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lt); } -#line 7488 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7487 "mrbgems/mruby-compiler/core/y.tab.c" break; case 139: /* op: "<=" */ #line 2227 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(le); } -#line 7494 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7493 "mrbgems/mruby-compiler/core/y.tab.c" break; case 140: /* op: "!=" */ #line 2228 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neq); } -#line 7500 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7499 "mrbgems/mruby-compiler/core/y.tab.c" break; case 141: /* op: "<<" */ #line 2229 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(lshift); } -#line 7506 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7505 "mrbgems/mruby-compiler/core/y.tab.c" break; case 142: /* op: ">>" */ #line 2230 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(rshift); } -#line 7512 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7511 "mrbgems/mruby-compiler/core/y.tab.c" break; case 143: /* op: '+' */ #line 2231 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(add); } -#line 7518 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7517 "mrbgems/mruby-compiler/core/y.tab.c" break; case 144: /* op: '-' */ #line 2232 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(sub); } -#line 7524 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7523 "mrbgems/mruby-compiler/core/y.tab.c" break; case 145: /* op: '*' */ #line 2233 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7530 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7529 "mrbgems/mruby-compiler/core/y.tab.c" break; case 146: /* op: "*" */ #line 2234 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); } -#line 7536 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7535 "mrbgems/mruby-compiler/core/y.tab.c" break; case 147: /* op: '/' */ #line 2235 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(div); } -#line 7542 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7541 "mrbgems/mruby-compiler/core/y.tab.c" break; case 148: /* op: '%' */ #line 2236 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mod); } -#line 7548 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7547 "mrbgems/mruby-compiler/core/y.tab.c" break; case 149: /* op: tPOW */ #line 2237 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7554 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7553 "mrbgems/mruby-compiler/core/y.tab.c" break; case 150: /* op: "**" */ #line 2238 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(pow); } -#line 7560 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7559 "mrbgems/mruby-compiler/core/y.tab.c" break; case 151: /* op: '!' */ #line 2239 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(not); } -#line 7566 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7565 "mrbgems/mruby-compiler/core/y.tab.c" break; case 152: /* op: '~' */ #line 2240 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(neg); } -#line 7572 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7571 "mrbgems/mruby-compiler/core/y.tab.c" break; case 153: /* op: "unary plus" */ #line 2241 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(plus); } -#line 7578 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7577 "mrbgems/mruby-compiler/core/y.tab.c" break; case 154: /* op: "unary minus" */ #line 2242 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(minus); } -#line 7584 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7583 "mrbgems/mruby-compiler/core/y.tab.c" break; case 155: /* op: tAREF */ #line 2243 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aref); } -#line 7590 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7589 "mrbgems/mruby-compiler/core/y.tab.c" break; case 156: /* op: tASET */ #line 2244 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(aset); } -#line 7596 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7595 "mrbgems/mruby-compiler/core/y.tab.c" break; case 157: /* op: '`' */ #line 2245 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(tick); } -#line 7602 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7601 "mrbgems/mruby-compiler/core/y.tab.c" break; case 198: /* arg: lhs '=' arg_rhs */ @@ -7606,7 +7605,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_asgn(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7610 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7609 "mrbgems/mruby-compiler/core/y.tab.c" break; case 199: /* arg: var_lhs tOP_ASGN arg_rhs */ @@ -7614,7 +7613,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, (yyvsp[-2].nd), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7618 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7617 "mrbgems/mruby-compiler/core/y.tab.c" break; case 200: /* arg: primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs */ @@ -7622,7 +7621,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 7626 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7625 "mrbgems/mruby-compiler/core/y.tab.c" break; case 201: /* arg: primary_value call_op "local variable or method" tOP_ASGN arg_rhs */ @@ -7630,7 +7629,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 7634 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7633 "mrbgems/mruby-compiler/core/y.tab.c" break; case 202: /* arg: primary_value call_op "constant" tOP_ASGN arg_rhs */ @@ -7638,7 +7637,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (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 7642 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7641 "mrbgems/mruby-compiler/core/y.tab.c" break; case 203: /* arg: primary_value "::" "local variable or method" tOP_ASGN arg_rhs */ @@ -7646,7 +7645,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_op_asgn(p, new_call(p, (yyvsp[-4].nd), (yyvsp[-2].id), 0, tCOLON2), (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 7650 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7649 "mrbgems/mruby-compiler/core/y.tab.c" break; case 204: /* arg: primary_value "::" "constant" tOP_ASGN arg_rhs */ @@ -7655,7 +7654,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7659 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7658 "mrbgems/mruby-compiler/core/y.tab.c" break; case 205: /* arg: tCOLON3 "constant" tOP_ASGN arg_rhs */ @@ -7664,7 +7663,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yyerror(p, "constant re-assignment"); (yyval.nd) = new_begin(p, 0); } -#line 7668 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7667 "mrbgems/mruby-compiler/core/y.tab.c" break; case 206: /* arg: backref tOP_ASGN arg_rhs */ @@ -7673,7 +7672,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); backref_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_begin(p, 0); } -#line 7677 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7676 "mrbgems/mruby-compiler/core/y.tab.c" break; case 207: /* arg: arg ".." arg */ @@ -7681,7 +7680,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot2(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7684 "mrbgems/mruby-compiler/core/y.tab.c" break; case 208: /* arg: arg ".." */ @@ -7689,7 +7688,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot2(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7693 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7692 "mrbgems/mruby-compiler/core/y.tab.c" break; case 209: /* arg: tBDOT2 arg */ @@ -7697,7 +7696,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot2(p, new_nil(p), (yyvsp[0].nd)); } -#line 7701 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7700 "mrbgems/mruby-compiler/core/y.tab.c" break; case 210: /* arg: arg "..." arg */ @@ -7705,7 +7704,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot3(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7709 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7708 "mrbgems/mruby-compiler/core/y.tab.c" break; case 211: /* arg: arg "..." */ @@ -7713,7 +7712,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot3(p, (yyvsp[-1].nd), new_nil(p)); } -#line 7717 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7716 "mrbgems/mruby-compiler/core/y.tab.c" break; case 212: /* arg: tBDOT3 arg */ @@ -7721,7 +7720,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_dot3(p, new_nil(p), (yyvsp[0].nd)); } -#line 7725 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7724 "mrbgems/mruby-compiler/core/y.tab.c" break; case 213: /* arg: arg '+' arg */ @@ -7729,7 +7728,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "+", (yyvsp[0].nd)); } -#line 7733 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7732 "mrbgems/mruby-compiler/core/y.tab.c" break; case 214: /* arg: arg '-' arg */ @@ -7737,7 +7736,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "-", (yyvsp[0].nd)); } -#line 7741 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7740 "mrbgems/mruby-compiler/core/y.tab.c" break; case 215: /* arg: arg '*' arg */ @@ -7745,7 +7744,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "*", (yyvsp[0].nd)); } -#line 7749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7748 "mrbgems/mruby-compiler/core/y.tab.c" break; case 216: /* arg: arg '/' arg */ @@ -7753,7 +7752,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "/", (yyvsp[0].nd)); } -#line 7757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7756 "mrbgems/mruby-compiler/core/y.tab.c" break; case 217: /* arg: arg '%' arg */ @@ -7761,7 +7760,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "%", (yyvsp[0].nd)); } -#line 7765 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7764 "mrbgems/mruby-compiler/core/y.tab.c" break; case 218: /* arg: arg tPOW arg */ @@ -7769,7 +7768,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)); } -#line 7773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7772 "mrbgems/mruby-compiler/core/y.tab.c" break; case 219: /* arg: tUMINUS_NUM "integer literal" tPOW arg */ @@ -7777,7 +7776,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7781 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7780 "mrbgems/mruby-compiler/core/y.tab.c" break; case 220: /* arg: tUMINUS_NUM "float literal" tPOW arg */ @@ -7785,7 +7784,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd))); } -#line 7789 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7788 "mrbgems/mruby-compiler/core/y.tab.c" break; case 221: /* arg: "unary plus" arg */ @@ -7793,7 +7792,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "+@"); } -#line 7797 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7796 "mrbgems/mruby-compiler/core/y.tab.c" break; case 222: /* arg: "unary minus" arg */ @@ -7801,7 +7800,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 7805 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7804 "mrbgems/mruby-compiler/core/y.tab.c" break; case 223: /* arg: arg '|' arg */ @@ -7809,7 +7808,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "|", (yyvsp[0].nd)); } -#line 7813 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7812 "mrbgems/mruby-compiler/core/y.tab.c" break; case 224: /* arg: arg '^' arg */ @@ -7817,7 +7816,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "^", (yyvsp[0].nd)); } -#line 7821 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7820 "mrbgems/mruby-compiler/core/y.tab.c" break; case 225: /* arg: arg '&' arg */ @@ -7825,7 +7824,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "&", (yyvsp[0].nd)); } -#line 7829 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7828 "mrbgems/mruby-compiler/core/y.tab.c" break; case 226: /* arg: arg "<=>" arg */ @@ -7833,7 +7832,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=>", (yyvsp[0].nd)); } -#line 7837 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7836 "mrbgems/mruby-compiler/core/y.tab.c" break; case 227: /* arg: arg '>' arg */ @@ -7841,7 +7840,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">", (yyvsp[0].nd)); } -#line 7845 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7844 "mrbgems/mruby-compiler/core/y.tab.c" break; case 228: /* arg: arg ">=" arg */ @@ -7849,7 +7848,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">=", (yyvsp[0].nd)); } -#line 7853 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7852 "mrbgems/mruby-compiler/core/y.tab.c" break; case 229: /* arg: arg '<' arg */ @@ -7857,7 +7856,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<", (yyvsp[0].nd)); } -#line 7861 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7860 "mrbgems/mruby-compiler/core/y.tab.c" break; case 230: /* arg: arg "<=" arg */ @@ -7865,7 +7864,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<=", (yyvsp[0].nd)); } -#line 7869 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7868 "mrbgems/mruby-compiler/core/y.tab.c" break; case 231: /* arg: arg "==" arg */ @@ -7873,7 +7872,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "==", (yyvsp[0].nd)); } -#line 7877 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7876 "mrbgems/mruby-compiler/core/y.tab.c" break; case 232: /* arg: arg "===" arg */ @@ -7881,7 +7880,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "===", (yyvsp[0].nd)); } -#line 7885 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7884 "mrbgems/mruby-compiler/core/y.tab.c" break; case 233: /* arg: arg "!=" arg */ @@ -7889,7 +7888,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!=", (yyvsp[0].nd)); } -#line 7893 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7892 "mrbgems/mruby-compiler/core/y.tab.c" break; case 234: /* arg: arg "=~" arg */ @@ -7897,7 +7896,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "=~", (yyvsp[0].nd)); } -#line 7901 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7900 "mrbgems/mruby-compiler/core/y.tab.c" break; case 235: /* arg: arg "!~" arg */ @@ -7905,7 +7904,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "!~", (yyvsp[0].nd)); } -#line 7909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7908 "mrbgems/mruby-compiler/core/y.tab.c" break; case 236: /* arg: '!' arg */ @@ -7913,7 +7912,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "!"); } -#line 7917 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7916 "mrbgems/mruby-compiler/core/y.tab.c" break; case 237: /* arg: '~' arg */ @@ -7921,7 +7920,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_uni_op(p, cond((yyvsp[0].nd)), "~"); } -#line 7925 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7924 "mrbgems/mruby-compiler/core/y.tab.c" break; case 238: /* arg: arg "<<" arg */ @@ -7929,7 +7928,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), "<<", (yyvsp[0].nd)); } -#line 7933 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7932 "mrbgems/mruby-compiler/core/y.tab.c" break; case 239: /* arg: arg ">>" arg */ @@ -7937,7 +7936,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = call_bin_op(p, (yyvsp[-2].nd), ">>", (yyvsp[0].nd)); } -#line 7941 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7940 "mrbgems/mruby-compiler/core/y.tab.c" break; case 240: /* arg: arg "&&" arg */ @@ -7945,7 +7944,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_and(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7949 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7948 "mrbgems/mruby-compiler/core/y.tab.c" break; case 241: /* arg: arg "||" arg */ @@ -7953,7 +7952,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_or(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 7957 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7956 "mrbgems/mruby-compiler/core/y.tab.c" break; case 242: /* arg: arg '?' arg opt_nl ':' arg */ @@ -7961,7 +7960,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7965 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7964 "mrbgems/mruby-compiler/core/y.tab.c" break; case 243: /* arg: arg '?' arg opt_nl "label" arg */ @@ -7969,7 +7968,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_if(p, cond((yyvsp[-5].nd)), (yyvsp[-3].nd), (yyvsp[0].nd)); } -#line 7973 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7972 "mrbgems/mruby-compiler/core/y.tab.c" break; case 244: /* arg: defn_head f_opt_arglist_paren '=' arg */ @@ -7982,10 +7981,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 7986 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7985 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 245: /* arg: defn_head f_opt_arglist_paren '=' arg modifier_rescue arg */ + case 245: /* arg: defn_head f_opt_arglist_paren '=' arg "'rescue' modifier" arg */ #line 2459 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -7995,7 +7994,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 7999 "mrbgems/mruby-compiler/core/y.tab.c" +#line 7998 "mrbgems/mruby-compiler/core/y.tab.c" break; case 246: /* arg: defs_head f_opt_arglist_paren '=' arg */ @@ -8008,10 +8007,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 8012 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8011 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 247: /* arg: defs_head f_opt_arglist_paren '=' arg modifier_rescue arg */ + case 247: /* arg: defs_head f_opt_arglist_paren '=' arg "'rescue' modifier" arg */ #line 2477 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-5].nd); @@ -8021,7 +8020,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 8025 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8024 "mrbgems/mruby-compiler/core/y.tab.c" break; case 248: /* arg: primary */ @@ -8029,7 +8028,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8033 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8032 "mrbgems/mruby-compiler/core/y.tab.c" break; case 250: /* aref_args: args trailer */ @@ -8038,7 +8037,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = (yyvsp[-1].nd); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8042 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8041 "mrbgems/mruby-compiler/core/y.tab.c" break; case 251: /* aref_args: args comma assocs trailer */ @@ -8046,7 +8045,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), new_hash(p, (yyvsp[-1].nd))); } -#line 8050 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8049 "mrbgems/mruby-compiler/core/y.tab.c" break; case 252: /* aref_args: assocs trailer */ @@ -8055,7 +8054,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = cons(new_kw_hash(p, (yyvsp[-1].nd)), 0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8059 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8058 "mrbgems/mruby-compiler/core/y.tab.c" break; case 253: /* arg_rhs: arg */ @@ -8063,16 +8062,16 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8067 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8066 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 254: /* arg_rhs: arg modifier_rescue arg */ + case 254: /* arg_rhs: arg "'rescue' modifier" arg */ #line 2513 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[-2].nd)); (yyval.nd) = new_mod_rescue(p, (yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 8076 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8075 "mrbgems/mruby-compiler/core/y.tab.c" break; case 255: /* paren_args: '(' opt_call_args ')' */ @@ -8080,7 +8079,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 8084 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8083 "mrbgems/mruby-compiler/core/y.tab.c" break; case 256: /* paren_args: '(' args comma tBDOT3 rparen */ @@ -8093,7 +8092,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 8097 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8096 "mrbgems/mruby-compiler/core/y.tab.c" break; case 257: /* paren_args: '(' tBDOT3 rparen */ @@ -8112,7 +8111,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = 0; } } -#line 8116 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8115 "mrbgems/mruby-compiler/core/y.tab.c" break; case 262: /* opt_call_args: args comma */ @@ -8121,7 +8120,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p,(yyvsp[-1].nd),0,0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8125 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8124 "mrbgems/mruby-compiler/core/y.tab.c" break; case 263: /* opt_call_args: args comma assocs comma */ @@ -8130,7 +8129,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p,(yyvsp[-3].nd),new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-3].nd)); } -#line 8134 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8133 "mrbgems/mruby-compiler/core/y.tab.c" break; case 264: /* opt_call_args: assocs comma */ @@ -8139,7 +8138,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p,0,new_kw_hash(p,(yyvsp[-1].nd)),0); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8143 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8142 "mrbgems/mruby-compiler/core/y.tab.c" break; case 265: /* call_args: command */ @@ -8149,7 +8148,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, list1((yyvsp[0].nd)), 0, 0); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8153 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8152 "mrbgems/mruby-compiler/core/y.tab.c" break; case 266: /* call_args: args opt_block_arg */ @@ -8158,7 +8157,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, (yyvsp[-1].nd), 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8162 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8161 "mrbgems/mruby-compiler/core/y.tab.c" break; case 267: /* call_args: assocs opt_block_arg */ @@ -8167,7 +8166,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, 0, new_kw_hash(p, (yyvsp[-1].nd)), (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8171 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8170 "mrbgems/mruby-compiler/core/y.tab.c" break; case 268: /* call_args: args comma assocs opt_block_arg */ @@ -8176,7 +8175,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (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 8180 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8179 "mrbgems/mruby-compiler/core/y.tab.c" break; case 269: /* call_args: block_arg */ @@ -8185,7 +8184,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_callargs(p, 0, 0, (yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8189 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8188 "mrbgems/mruby-compiler/core/y.tab.c" break; case 270: /* @7: %empty */ @@ -8194,7 +8193,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; CMDARG_PUSH(1); } -#line 8198 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8197 "mrbgems/mruby-compiler/core/y.tab.c" break; case 271: /* command_args: @7 call_args */ @@ -8203,7 +8202,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmdarg_stack = (yyvsp[-1].stack); (yyval.nd) = (yyvsp[0].nd); } -#line 8207 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8206 "mrbgems/mruby-compiler/core/y.tab.c" break; case 272: /* block_arg: "&" arg */ @@ -8211,7 +8210,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_block_arg(p, (yyvsp[0].nd)); } -#line 8215 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8214 "mrbgems/mruby-compiler/core/y.tab.c" break; case 273: /* block_arg: "&" */ @@ -8219,7 +8218,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_block_arg(p, 0); } -#line 8223 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8222 "mrbgems/mruby-compiler/core/y.tab.c" break; case 274: /* opt_block_arg: comma block_arg */ @@ -8227,7 +8226,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8231 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8230 "mrbgems/mruby-compiler/core/y.tab.c" break; case 275: /* opt_block_arg: none */ @@ -8235,7 +8234,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 8239 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8238 "mrbgems/mruby-compiler/core/y.tab.c" break; case 277: /* args: arg */ @@ -8245,7 +8244,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8249 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8248 "mrbgems/mruby-compiler/core/y.tab.c" break; case 278: /* args: "*" */ @@ -8253,7 +8252,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(new_splat(p, new_lvar(p, intern_op(mul)))); } -#line 8257 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8256 "mrbgems/mruby-compiler/core/y.tab.c" break; case 279: /* args: "*" arg */ @@ -8262,7 +8261,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 8266 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8265 "mrbgems/mruby-compiler/core/y.tab.c" break; case 280: /* args: args comma arg */ @@ -8271,7 +8270,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 8275 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8274 "mrbgems/mruby-compiler/core/y.tab.c" break; case 281: /* args: args comma "*" */ @@ -8279,7 +8278,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-2].nd), new_splat(p, new_lvar(p, intern_op(mul)))); } -#line 8283 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8282 "mrbgems/mruby-compiler/core/y.tab.c" break; case 282: /* args: args comma "*" arg */ @@ -8287,7 +8286,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 8291 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8290 "mrbgems/mruby-compiler/core/y.tab.c" break; case 283: /* mrhs: args comma arg */ @@ -8296,7 +8295,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 8300 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8299 "mrbgems/mruby-compiler/core/y.tab.c" break; case 284: /* mrhs: args comma "*" arg */ @@ -8304,7 +8303,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = push((yyvsp[-3].nd), new_splat(p, (yyvsp[0].nd))); } -#line 8308 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8307 "mrbgems/mruby-compiler/core/y.tab.c" break; case 285: /* mrhs: "*" arg */ @@ -8312,7 +8311,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(new_splat(p, (yyvsp[0].nd))); } -#line 8316 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8315 "mrbgems/mruby-compiler/core/y.tab.c" break; case 293: /* primary: "numbered parameter" */ @@ -8320,7 +8319,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_nvar(p, (yyvsp[0].num)); } -#line 8324 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8323 "mrbgems/mruby-compiler/core/y.tab.c" break; case 294: /* primary: "method" */ @@ -8328,7 +8327,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_fcall(p, (yyvsp[0].id), 0); } -#line 8332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8331 "mrbgems/mruby-compiler/core/y.tab.c" break; case 295: /* @8: %empty */ @@ -8337,16 +8336,16 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8341 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8340 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 296: /* primary: keyword_begin @8 bodystmt keyword_end */ + case 296: /* primary: "'begin'" @8 bodystmt "'end'" */ #line 2701 "mrbgems/mruby-compiler/core/parse.y" { p->cmdarg_stack = (yyvsp[-2].stack); (yyval.nd) = (yyvsp[-1].nd); } -#line 8350 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8349 "mrbgems/mruby-compiler/core/y.tab.c" break; case 297: /* @9: %empty */ @@ -8355,13 +8354,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8359 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8358 "mrbgems/mruby-compiler/core/y.tab.c" break; case 298: /* $@10: %empty */ #line 2710 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8365 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8364 "mrbgems/mruby-compiler/core/y.tab.c" break; case 299: /* primary: "(" @9 stmt $@10 rparen */ @@ -8370,13 +8369,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmdarg_stack = (yyvsp[-3].stack); (yyval.nd) = (yyvsp[-2].nd); } -#line 8374 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8373 "mrbgems/mruby-compiler/core/y.tab.c" break; case 300: /* $@11: %empty */ #line 2715 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_ENDARG;} -#line 8380 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8379 "mrbgems/mruby-compiler/core/y.tab.c" break; case 301: /* primary: "(" $@11 rparen */ @@ -8384,7 +8383,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_nil(p); } -#line 8388 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8387 "mrbgems/mruby-compiler/core/y.tab.c" break; case 302: /* primary: tLPAREN compstmt ')' */ @@ -8392,7 +8391,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 8396 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8395 "mrbgems/mruby-compiler/core/y.tab.c" break; case 303: /* primary: primary_value "::" "constant" */ @@ -8400,7 +8399,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_colon2(p, (yyvsp[-2].nd), (yyvsp[0].id)); } -#line 8404 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8403 "mrbgems/mruby-compiler/core/y.tab.c" break; case 304: /* primary: tCOLON3 "constant" */ @@ -8408,7 +8407,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_colon3(p, (yyvsp[0].id)); } -#line 8412 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8411 "mrbgems/mruby-compiler/core/y.tab.c" break; case 305: /* primary: "[" aref_args ']' */ @@ -8417,7 +8416,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_array(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8421 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8420 "mrbgems/mruby-compiler/core/y.tab.c" break; case 306: /* primary: tLBRACE assoc_list '}' */ @@ -8426,39 +8425,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = new_hash(p, (yyvsp[-1].nd)); NODE_LINENO((yyval.nd), (yyvsp[-1].nd)); } -#line 8430 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8429 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 307: /* primary: keyword_return */ + case 307: /* primary: "'return'" */ #line 2742 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_return(p, 0); } -#line 8438 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8437 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 308: /* primary: keyword_yield opt_paren_args */ + case 308: /* primary: "'yield'" opt_paren_args */ #line 2746 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_yield(p, (yyvsp[0].nd)); } -#line 8446 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8445 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 309: /* primary: keyword_not '(' expr rparen */ + case 309: /* primary: "'not'" '(' expr rparen */ #line 2750 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, cond((yyvsp[-1].nd)), "!"); } -#line 8454 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8453 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 310: /* primary: keyword_not '(' rparen */ + case 310: /* primary: "'not'" '(' rparen */ #line 2754 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = call_uni_op(p, new_nil(p), "!"); } -#line 8462 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8461 "mrbgems/mruby-compiler/core/y.tab.c" break; case 311: /* primary: operation brace_block */ @@ -8466,7 +8465,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), new_callargs(p, 0, 0, (yyvsp[0].nd))); } -#line 8470 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8469 "mrbgems/mruby-compiler/core/y.tab.c" break; case 313: /* primary: method_call brace_block */ @@ -8475,7 +8474,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); call_with_block(p, (yyvsp[-1].nd), (yyvsp[0].nd)); (yyval.nd) = (yyvsp[-1].nd); } -#line 8479 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8478 "mrbgems/mruby-compiler/core/y.tab.c" break; case 314: /* @12: %empty */ @@ -8486,7 +8485,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.num) = p->lpar_beg; p->lpar_beg = ++p->paren_nest; } -#line 8490 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8489 "mrbgems/mruby-compiler/core/y.tab.c" break; case 315: /* @13: %empty */ @@ -8495,7 +8494,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.stack) = p->cmdarg_stack; p->cmdarg_stack = 0; } -#line 8499 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8498 "mrbgems/mruby-compiler/core/y.tab.c" break; case 316: /* primary: "->" @12 f_larglist @13 lambda_body */ @@ -8508,104 +8507,104 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmdarg_stack = (yyvsp[-1].stack); CMDARG_LEXPOP(); } -#line 8512 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8511 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 317: /* primary: keyword_if expr_value then compstmt if_tail keyword_end */ + case 317: /* primary: "'if'" expr_value then compstmt if_tail "'end'" */ #line 2792 "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 8521 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8520 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 318: /* primary: keyword_unless expr_value then compstmt opt_else keyword_end */ + case 318: /* primary: "'unless'" expr_value then compstmt opt_else "'end'" */ #line 2800 "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 8530 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8529 "mrbgems/mruby-compiler/core/y.tab.c" break; case 319: /* $@14: %empty */ #line 2804 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8536 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8535 "mrbgems/mruby-compiler/core/y.tab.c" break; case 320: /* $@15: %empty */ #line 2804 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8542 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8541 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 321: /* primary: keyword_while $@14 expr_value do $@15 compstmt keyword_end */ + case 321: /* primary: "'while'" $@14 expr_value do $@15 compstmt "'end'" */ #line 2807 "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 8551 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8550 "mrbgems/mruby-compiler/core/y.tab.c" break; case 322: /* $@16: %empty */ #line 2811 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8557 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8556 "mrbgems/mruby-compiler/core/y.tab.c" break; case 323: /* $@17: %empty */ #line 2811 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8563 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8562 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 324: /* primary: keyword_until $@16 expr_value do $@17 compstmt keyword_end */ + case 324: /* primary: "'until'" $@16 expr_value do $@17 compstmt "'end'" */ #line 2814 "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 8572 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8571 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 325: /* primary: keyword_case expr_value opt_terms case_body keyword_end */ + case 325: /* primary: "'case'" expr_value opt_terms case_body "'end'" */ #line 2821 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 8580 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8579 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 326: /* primary: keyword_case opt_terms case_body keyword_end */ + case 326: /* primary: "'case'" opt_terms case_body "'end'" */ #line 2825 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_case(p, 0, (yyvsp[-1].nd)); } -#line 8588 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8587 "mrbgems/mruby-compiler/core/y.tab.c" break; case 327: /* $@18: %empty */ #line 2829 "mrbgems/mruby-compiler/core/parse.y" {COND_PUSH(1);} -#line 8594 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8593 "mrbgems/mruby-compiler/core/y.tab.c" break; case 328: /* $@19: %empty */ #line 2831 "mrbgems/mruby-compiler/core/parse.y" {COND_POP();} -#line 8600 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8599 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 329: /* primary: keyword_for for_var keyword_in $@18 expr_value do $@19 compstmt keyword_end */ + case 329: /* primary: "'for'" for_var "'in'" $@18 expr_value do $@19 compstmt "'end'" */ #line 2834 "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 8609 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8608 "mrbgems/mruby-compiler/core/y.tab.c" break; case 330: /* @20: %empty */ @@ -8616,10 +8615,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8620 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8619 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 331: /* primary: keyword_class cpath superclass @20 bodystmt keyword_end */ + case 331: /* primary: "'class'" cpath superclass @20 bodystmt "'end'" */ #line 2848 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_class(p, (yyvsp[-4].nd), (yyvsp[-3].nd), (yyvsp[-1].nd)); @@ -8627,7 +8626,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8631 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8630 "mrbgems/mruby-compiler/core/y.tab.c" break; case 332: /* @21: %empty */ @@ -8636,7 +8635,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.num) = p->in_def; p->in_def = 0; } -#line 8640 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8639 "mrbgems/mruby-compiler/core/y.tab.c" break; case 333: /* @22: %empty */ @@ -8646,10 +8645,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_block(p); p->in_single = 0; } -#line 8650 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8649 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 334: /* primary: keyword_class "<<" expr @21 term @22 bodystmt keyword_end */ + case 334: /* primary: "'class'" "<<" expr @21 term @22 bodystmt "'end'" */ #line 2868 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_sclass(p, (yyvsp[-5].nd), (yyvsp[-1].nd)); @@ -8659,7 +8658,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def = (yyvsp[-4].num); p->in_single = intn((yyvsp[-2].nd)->cdr); } -#line 8663 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8662 "mrbgems/mruby-compiler/core/y.tab.c" break; case 335: /* @23: %empty */ @@ -8670,10 +8669,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = local_switch(p); nvars_block(p); } -#line 8674 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8673 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 336: /* primary: keyword_module cpath @23 bodystmt keyword_end */ + case 336: /* primary: "'module'" cpath @23 bodystmt "'end'" */ #line 2886 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_module(p, (yyvsp[-3].nd), (yyvsp[-1].nd)); @@ -8681,10 +8680,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_resume(p, (yyvsp[-2].nd)); nvars_unnest(p); } -#line 8685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8684 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 337: /* primary: defn_head f_arglist bodystmt keyword_end */ + case 337: /* primary: defn_head f_arglist bodystmt "'end'" */ #line 2896 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); @@ -8692,10 +8691,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); nvars_unnest(p); p->in_def--; } -#line 8696 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8695 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 338: /* primary: defs_head f_arglist bodystmt keyword_end */ + case 338: /* primary: defs_head f_arglist bodystmt "'end'" */ #line 2906 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-3].nd); @@ -8704,39 +8703,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->in_def--; p->in_single--; } -#line 8708 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8707 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 339: /* primary: keyword_break */ + case 339: /* primary: "'break'" */ #line 2914 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_break(p, 0); } -#line 8716 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8715 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 340: /* primary: keyword_next */ + case 340: /* primary: "'next'" */ #line 2918 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_next(p, 0); } -#line 8724 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8723 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 341: /* primary: keyword_redo */ + case 341: /* primary: "'redo'" */ #line 2922 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_redo(p); } -#line 8732 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8731 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 342: /* primary: keyword_retry */ + case 342: /* primary: "'retry'" */ #line 2926 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_retry(p); } -#line 8740 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8739 "mrbgems/mruby-compiler/core/y.tab.c" break; case 343: /* primary_value: primary */ @@ -8745,23 +8744,23 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 8749 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8748 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 350: /* if_tail: keyword_elsif expr_value then compstmt if_tail */ + case 350: /* if_tail: "'elsif'" expr_value then compstmt if_tail */ #line 2951 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_if(p, cond((yyvsp[-3].nd)), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8757 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8756 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 352: /* opt_else: keyword_else compstmt */ + case 352: /* opt_else: "'else'" compstmt */ #line 2958 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 8765 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8764 "mrbgems/mruby-compiler/core/y.tab.c" break; case 353: /* for_var: lhs */ @@ -8769,7 +8768,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list1(list1((yyvsp[0].nd))); } -#line 8773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8772 "mrbgems/mruby-compiler/core/y.tab.c" break; case 355: /* f_margs: f_arg */ @@ -8777,7 +8776,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[0].nd),0,0); } -#line 8781 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8780 "mrbgems/mruby-compiler/core/y.tab.c" break; case 356: /* f_margs: f_arg ',' "*" f_norm_arg */ @@ -8785,7 +8784,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-3].nd), new_arg(p, (yyvsp[0].id)), 0); } -#line 8789 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8788 "mrbgems/mruby-compiler/core/y.tab.c" break; case 357: /* f_margs: f_arg ',' "*" f_norm_arg ',' f_arg */ @@ -8793,7 +8792,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-5].nd), new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8797 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8796 "mrbgems/mruby-compiler/core/y.tab.c" break; case 358: /* f_margs: f_arg ',' "*" */ @@ -8802,7 +8801,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_f(p, intern_op(mul)); (yyval.nd) = list3((yyvsp[-2].nd), nint(-1), 0); } -#line 8806 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8805 "mrbgems/mruby-compiler/core/y.tab.c" break; case 359: /* f_margs: f_arg ',' "*" ',' f_arg */ @@ -8810,7 +8809,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3((yyvsp[-4].nd), nint(-1), (yyvsp[0].nd)); } -#line 8814 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8813 "mrbgems/mruby-compiler/core/y.tab.c" break; case 360: /* f_margs: "*" f_norm_arg */ @@ -8818,7 +8817,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, new_arg(p, (yyvsp[0].id)), 0); } -#line 8822 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8821 "mrbgems/mruby-compiler/core/y.tab.c" break; case 361: /* f_margs: "*" f_norm_arg ',' f_arg */ @@ -8826,7 +8825,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, new_arg(p, (yyvsp[-2].id)), (yyvsp[0].nd)); } -#line 8830 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8829 "mrbgems/mruby-compiler/core/y.tab.c" break; case 362: /* f_margs: "*" */ @@ -8835,7 +8834,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_f(p, intern_op(mul)); (yyval.nd) = list3(0, nint(-1), 0); } -#line 8839 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8838 "mrbgems/mruby-compiler/core/y.tab.c" break; case 363: /* $@24: %empty */ @@ -8843,7 +8842,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { local_add_f(p, intern_op(mul)); } -#line 8847 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8846 "mrbgems/mruby-compiler/core/y.tab.c" break; case 364: /* f_margs: "*" ',' $@24 f_arg */ @@ -8851,7 +8850,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = list3(0, nint(-1), (yyvsp[0].nd)); } -#line 8855 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8854 "mrbgems/mruby-compiler/core/y.tab.c" break; case 365: /* block_args_tail: f_block_kwarg ',' f_kwrest opt_f_block_arg */ @@ -8859,7 +8858,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8863 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8862 "mrbgems/mruby-compiler/core/y.tab.c" break; case 366: /* block_args_tail: f_block_kwarg opt_f_block_arg */ @@ -8867,7 +8866,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 8871 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8870 "mrbgems/mruby-compiler/core/y.tab.c" break; case 367: /* block_args_tail: f_kwrest opt_f_block_arg */ @@ -8875,7 +8874,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 8879 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8878 "mrbgems/mruby-compiler/core/y.tab.c" break; case 368: /* block_args_tail: f_block_arg */ @@ -8883,7 +8882,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 8887 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8886 "mrbgems/mruby-compiler/core/y.tab.c" break; case 369: /* opt_block_args_tail: ',' block_args_tail */ @@ -8891,7 +8890,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 8895 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8894 "mrbgems/mruby-compiler/core/y.tab.c" break; case 370: /* opt_block_args_tail: %empty */ @@ -8899,7 +8898,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 8903 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8902 "mrbgems/mruby-compiler/core/y.tab.c" break; case 371: /* block_param: f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail */ @@ -8907,7 +8906,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8911 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8910 "mrbgems/mruby-compiler/core/y.tab.c" break; case 372: /* block_param: f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail */ @@ -8915,7 +8914,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-7].nd), (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8919 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8918 "mrbgems/mruby-compiler/core/y.tab.c" break; case 373: /* block_param: f_arg ',' f_block_optarg opt_block_args_tail */ @@ -8923,7 +8922,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8927 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8926 "mrbgems/mruby-compiler/core/y.tab.c" break; case 374: /* block_param: f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail */ @@ -8931,7 +8930,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-5].nd), (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8935 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8934 "mrbgems/mruby-compiler/core/y.tab.c" break; case 375: /* block_param: f_arg ',' f_rest_arg opt_block_args_tail */ @@ -8939,7 +8938,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8943 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8942 "mrbgems/mruby-compiler/core/y.tab.c" break; case 376: /* block_param: f_arg ',' opt_block_args_tail */ @@ -8947,7 +8946,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-2].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8951 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8950 "mrbgems/mruby-compiler/core/y.tab.c" break; case 377: /* block_param: f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail */ @@ -8955,7 +8954,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-5].nd), 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8959 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8958 "mrbgems/mruby-compiler/core/y.tab.c" break; case 378: /* block_param: f_arg opt_block_args_tail */ @@ -8963,7 +8962,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 8967 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8966 "mrbgems/mruby-compiler/core/y.tab.c" break; case 379: /* block_param: f_block_optarg ',' f_rest_arg opt_block_args_tail */ @@ -8971,7 +8970,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 8975 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8974 "mrbgems/mruby-compiler/core/y.tab.c" break; case 380: /* block_param: f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail */ @@ -8979,7 +8978,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-5].nd), (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8983 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8982 "mrbgems/mruby-compiler/core/y.tab.c" break; case 381: /* block_param: f_block_optarg opt_block_args_tail */ @@ -8987,7 +8986,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 8991 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8990 "mrbgems/mruby-compiler/core/y.tab.c" break; case 382: /* block_param: f_block_optarg ',' f_arg opt_block_args_tail */ @@ -8995,7 +8994,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 8999 "mrbgems/mruby-compiler/core/y.tab.c" +#line 8998 "mrbgems/mruby-compiler/core/y.tab.c" break; case 383: /* block_param: f_rest_arg opt_block_args_tail */ @@ -9003,7 +9002,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 9007 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9006 "mrbgems/mruby-compiler/core/y.tab.c" break; case 384: /* block_param: f_rest_arg ',' f_arg opt_block_args_tail */ @@ -9011,7 +9010,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9015 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9014 "mrbgems/mruby-compiler/core/y.tab.c" break; case 385: /* block_param: block_args_tail */ @@ -9019,7 +9018,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 9023 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9022 "mrbgems/mruby-compiler/core/y.tab.c" break; case 386: /* opt_block_param: none */ @@ -9028,7 +9027,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_blk(p, 0); (yyval.nd) = 0; } -#line 9032 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9031 "mrbgems/mruby-compiler/core/y.tab.c" break; case 387: /* opt_block_param: block_param_def */ @@ -9037,13 +9036,13 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); p->cmd_start = TRUE; (yyval.nd) = (yyvsp[0].nd); } -#line 9041 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9040 "mrbgems/mruby-compiler/core/y.tab.c" break; case 388: /* $@25: %empty */ #line 3116 "mrbgems/mruby-compiler/core/parse.y" {local_add_blk(p, 0);} -#line 9047 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9046 "mrbgems/mruby-compiler/core/y.tab.c" break; case 389: /* block_param_def: '|' $@25 opt_bv_decl '|' */ @@ -9051,7 +9050,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 9055 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9054 "mrbgems/mruby-compiler/core/y.tab.c" break; case 390: /* block_param_def: "||" */ @@ -9060,7 +9059,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_blk(p, 0); (yyval.nd) = 0; } -#line 9064 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9063 "mrbgems/mruby-compiler/core/y.tab.c" break; case 391: /* block_param_def: '|' block_param opt_bv_decl '|' */ @@ -9068,7 +9067,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-2].nd); } -#line 9072 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9071 "mrbgems/mruby-compiler/core/y.tab.c" break; case 392: /* opt_bv_decl: opt_nl */ @@ -9076,7 +9075,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 9080 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9079 "mrbgems/mruby-compiler/core/y.tab.c" break; case 393: /* opt_bv_decl: opt_nl ';' bv_decls opt_nl */ @@ -9084,7 +9083,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = 0; } -#line 9088 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9087 "mrbgems/mruby-compiler/core/y.tab.c" break; case 396: /* bvar: "local variable or method" */ @@ -9093,7 +9092,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); local_add_f(p, (yyvsp[0].id)); new_bv(p, (yyvsp[0].id)); } -#line 9097 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9096 "mrbgems/mruby-compiler/core/y.tab.c" break; case 398: /* f_larglist: '(' f_args opt_bv_decl ')' */ @@ -9101,7 +9100,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-2].nd); } -#line 9105 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9104 "mrbgems/mruby-compiler/core/y.tab.c" break; case 399: /* f_larglist: f_args */ @@ -9109,7 +9108,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[0].nd); } -#line 9113 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9112 "mrbgems/mruby-compiler/core/y.tab.c" break; case 400: /* lambda_body: tLAMBEG compstmt '}' */ @@ -9117,38 +9116,40 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); { (yyval.nd) = (yyvsp[-1].nd); } -#line 9121 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9120 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 401: /* lambda_body: keyword_do_LAMBDA bodystmt keyword_end */ + case 401: /* lambda_body: "'do' for lambda" bodystmt "'end'" */ #line 3169 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9129 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9128 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 402: /* $@26: %empty */ + case 402: /* @26: %empty */ #line 3175 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); + (yyval.num) = p->lineno; } #line 9138 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 403: /* do_block: keyword_do_block $@26 opt_block_param bodystmt keyword_end */ -#line 3182 "mrbgems/mruby-compiler/core/parse.y" + case 403: /* do_block: "'do' for block" @26 opt_block_param bodystmt "'end'" */ +#line 3183 "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 9148 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9149 "mrbgems/mruby-compiler/core/y.tab.c" break; case 404: /* block_call: command do_block */ -#line 3190 "mrbgems/mruby-compiler/core/parse.y" +#line 3192 "mrbgems/mruby-compiler/core/parse.y" { if (typen((yyvsp[-1].nd)->car) == NODE_YIELD) { yyerror(p, "block given to yield"); @@ -9158,159 +9159,159 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = (yyvsp[-1].nd); } -#line 9162 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9163 "mrbgems/mruby-compiler/core/y.tab.c" break; case 405: /* block_call: block_call call_op2 operation2 opt_paren_args */ -#line 3200 "mrbgems/mruby-compiler/core/parse.y" +#line 3202 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 9170 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9171 "mrbgems/mruby-compiler/core/y.tab.c" break; case 406: /* block_call: block_call call_op2 operation2 opt_paren_args brace_block */ -#line 3204 "mrbgems/mruby-compiler/core/parse.y" +#line 3206 "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 9179 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9180 "mrbgems/mruby-compiler/core/y.tab.c" break; case 407: /* block_call: block_call call_op2 operation2 command_args do_block */ -#line 3209 "mrbgems/mruby-compiler/core/parse.y" +#line 3211 "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 9188 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9189 "mrbgems/mruby-compiler/core/y.tab.c" break; case 408: /* method_call: operation paren_args */ -#line 3216 "mrbgems/mruby-compiler/core/parse.y" +#line 3218 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, (yyvsp[-1].id), (yyvsp[0].nd)); } -#line 9196 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9197 "mrbgems/mruby-compiler/core/y.tab.c" break; case 409: /* method_call: primary_value call_op operation2 opt_paren_args */ -#line 3220 "mrbgems/mruby-compiler/core/parse.y" +#line 3222 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), (yyvsp[-2].num)); } -#line 9204 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9205 "mrbgems/mruby-compiler/core/y.tab.c" break; case 410: /* method_call: primary_value "::" operation2 paren_args */ -#line 3224 "mrbgems/mruby-compiler/core/parse.y" +#line 3226 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), (yyvsp[-1].id), (yyvsp[0].nd), tCOLON2); } -#line 9212 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9213 "mrbgems/mruby-compiler/core/y.tab.c" break; case 411: /* method_call: primary_value "::" operation3 */ -#line 3228 "mrbgems/mruby-compiler/core/parse.y" +#line 3230 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-2].nd), (yyvsp[0].id), 0, tCOLON2); } -#line 9220 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9221 "mrbgems/mruby-compiler/core/y.tab.c" break; case 412: /* method_call: primary_value call_op paren_args */ -#line 3232 "mrbgems/mruby-compiler/core/parse.y" +#line 3234 "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 9228 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9229 "mrbgems/mruby-compiler/core/y.tab.c" break; case 413: /* method_call: primary_value "::" paren_args */ -#line 3236 "mrbgems/mruby-compiler/core/parse.y" +#line 3238 "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 9236 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9237 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 414: /* method_call: keyword_super paren_args */ -#line 3240 "mrbgems/mruby-compiler/core/parse.y" + case 414: /* method_call: "'super'" paren_args */ +#line 3242 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_super(p, (yyvsp[0].nd)); } -#line 9244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9245 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 415: /* method_call: keyword_super */ -#line 3244 "mrbgems/mruby-compiler/core/parse.y" + case 415: /* method_call: "'super'" */ +#line 3246 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_zsuper(p); } -#line 9252 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9253 "mrbgems/mruby-compiler/core/y.tab.c" break; case 416: /* method_call: primary_value '[' opt_call_args ']' */ -#line 3248 "mrbgems/mruby-compiler/core/parse.y" +#line 3250 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_call(p, (yyvsp[-3].nd), intern_op(aref), (yyvsp[-1].nd), '.'); } -#line 9260 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9261 "mrbgems/mruby-compiler/core/y.tab.c" break; case 417: /* @27: %empty */ -#line 3254 "mrbgems/mruby-compiler/core/parse.y" +#line 3256 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 9270 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9271 "mrbgems/mruby-compiler/core/y.tab.c" break; case 418: /* brace_block: '{' @27 opt_block_param compstmt '}' */ -#line 3261 "mrbgems/mruby-compiler/core/parse.y" +#line 3263 "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 9281 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9282 "mrbgems/mruby-compiler/core/y.tab.c" break; case 419: /* @28: %empty */ -#line 3268 "mrbgems/mruby-compiler/core/parse.y" +#line 3270 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); nvars_nest(p); (yyval.num) = p->lineno; } -#line 9291 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9292 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 420: /* brace_block: keyword_do @28 opt_block_param bodystmt keyword_end */ -#line 3275 "mrbgems/mruby-compiler/core/parse.y" + case 420: /* brace_block: "'do'" @28 opt_block_param bodystmt "'end'" */ +#line 3277 "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 9302 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9303 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 421: /* case_body: keyword_when args then compstmt cases */ -#line 3286 "mrbgems/mruby-compiler/core/parse.y" + case 421: /* case_body: "'when'" args then compstmt cases */ +#line 3288 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(cons((yyvsp[-3].nd), (yyvsp[-1].nd)), (yyvsp[0].nd)); } -#line 9310 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9311 "mrbgems/mruby-compiler/core/y.tab.c" break; case 422: /* cases: opt_else */ -#line 3292 "mrbgems/mruby-compiler/core/parse.y" +#line 3294 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[0].nd)) { (yyval.nd) = cons(cons(0, (yyvsp[0].nd)), 0); @@ -9319,60 +9320,60 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = 0; } } -#line 9323 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9324 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 424: /* opt_rescue: keyword_rescue exc_list exc_var then compstmt opt_rescue */ -#line 3306 "mrbgems/mruby-compiler/core/parse.y" + case 424: /* opt_rescue: "'rescue'" exc_list exc_var then compstmt opt_rescue */ +#line 3308 "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 9332 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9333 "mrbgems/mruby-compiler/core/y.tab.c" break; case 426: /* exc_list: arg */ -#line 3314 "mrbgems/mruby-compiler/core/parse.y" +#line 3316 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9340 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9341 "mrbgems/mruby-compiler/core/y.tab.c" break; case 429: /* exc_var: "=>" lhs */ -#line 3322 "mrbgems/mruby-compiler/core/parse.y" +#line 3324 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9348 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9349 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 431: /* opt_ensure: keyword_ensure compstmt */ -#line 3329 "mrbgems/mruby-compiler/core/parse.y" + case 431: /* opt_ensure: "'ensure'" compstmt */ +#line 3331 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9356 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9357 "mrbgems/mruby-compiler/core/y.tab.c" break; case 438: /* string: string string_fragment */ -#line 3343 "mrbgems/mruby-compiler/core/parse.y" +#line 3345 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = concat_string(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9364 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9365 "mrbgems/mruby-compiler/core/y.tab.c" break; case 441: /* string_fragment: "string literal" tSTRING */ -#line 3351 "mrbgems/mruby-compiler/core/parse.y" +#line 3353 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9372 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9373 "mrbgems/mruby-compiler/core/y.tab.c" break; case 442: /* string_fragment: "string literal" string_rep tSTRING */ -#line 3355 "mrbgems/mruby-compiler/core/parse.y" +#line 3357 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9383,68 +9384,68 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dstr(p, n); } -#line 9387 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9388 "mrbgems/mruby-compiler/core/y.tab.c" break; case 444: /* string_rep: string_rep string_interp */ -#line 3369 "mrbgems/mruby-compiler/core/parse.y" +#line 3371 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = append((yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9395 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9396 "mrbgems/mruby-compiler/core/y.tab.c" break; case 445: /* string_interp: tSTRING_MID */ -#line 3375 "mrbgems/mruby-compiler/core/parse.y" +#line 3377 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9403 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9404 "mrbgems/mruby-compiler/core/y.tab.c" break; case 446: /* @29: %empty */ -#line 3379 "mrbgems/mruby-compiler/core/parse.y" +#line 3381 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push_strterm(p); } -#line 9411 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9412 "mrbgems/mruby-compiler/core/y.tab.c" break; case 447: /* string_interp: tSTRING_PART @29 compstmt '}' */ -#line 3384 "mrbgems/mruby-compiler/core/parse.y" +#line 3386 "mrbgems/mruby-compiler/core/parse.y" { pop_strterm(p,(yyvsp[-2].nd)); (yyval.nd) = list2((yyvsp[-3].nd), (yyvsp[-1].nd)); } -#line 9420 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9421 "mrbgems/mruby-compiler/core/y.tab.c" break; case 448: /* string_interp: tLITERAL_DELIM */ -#line 3389 "mrbgems/mruby-compiler/core/parse.y" +#line 3391 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9428 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9429 "mrbgems/mruby-compiler/core/y.tab.c" break; case 449: /* string_interp: tHD_LITERAL_DELIM heredoc_bodies */ -#line 3393 "mrbgems/mruby-compiler/core/parse.y" +#line 3395 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1(new_literal_delim(p)); } -#line 9436 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9437 "mrbgems/mruby-compiler/core/y.tab.c" break; case 450: /* xstring: tXSTRING_BEG tXSTRING */ -#line 3399 "mrbgems/mruby-compiler/core/parse.y" +#line 3401 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9444 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9445 "mrbgems/mruby-compiler/core/y.tab.c" break; case 451: /* xstring: tXSTRING_BEG string_rep tXSTRING */ -#line 3403 "mrbgems/mruby-compiler/core/parse.y" +#line 3405 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9455,81 +9456,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dxstr(p, n); } -#line 9459 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9460 "mrbgems/mruby-compiler/core/y.tab.c" break; case 452: /* regexp: tREGEXP_BEG tREGEXP */ -#line 3416 "mrbgems/mruby-compiler/core/parse.y" +#line 3418 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9467 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9468 "mrbgems/mruby-compiler/core/y.tab.c" break; case 453: /* regexp: tREGEXP_BEG string_rep tREGEXP */ -#line 3420 "mrbgems/mruby-compiler/core/parse.y" +#line 3422 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_dregx(p, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 9475 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9476 "mrbgems/mruby-compiler/core/y.tab.c" break; case 457: /* heredoc_body: tHEREDOC_END */ -#line 3433 "mrbgems/mruby-compiler/core/parse.y" +#line 3435 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info *info = parsing_heredoc_info(p); info->doc = push(info->doc, new_str(p, "", 0)); heredoc_end(p); } -#line 9485 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9486 "mrbgems/mruby-compiler/core/y.tab.c" break; case 458: /* heredoc_body: heredoc_string_rep tHEREDOC_END */ -#line 3439 "mrbgems/mruby-compiler/core/parse.y" +#line 3441 "mrbgems/mruby-compiler/core/parse.y" { heredoc_end(p); } -#line 9493 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9494 "mrbgems/mruby-compiler/core/y.tab.c" break; case 461: /* heredoc_string_interp: tHD_STRING_MID */ -#line 3449 "mrbgems/mruby-compiler/core/parse.y" +#line 3451 "mrbgems/mruby-compiler/core/parse.y" { parser_heredoc_info *info = parsing_heredoc_info(p); info->doc = push(info->doc, (yyvsp[0].nd)); heredoc_treat_nextline(p); } -#line 9503 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9504 "mrbgems/mruby-compiler/core/y.tab.c" break; case 462: /* @30: %empty */ -#line 3455 "mrbgems/mruby-compiler/core/parse.y" +#line 3457 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push_strterm(p); } -#line 9511 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9512 "mrbgems/mruby-compiler/core/y.tab.c" break; case 463: /* heredoc_string_interp: tHD_STRING_PART @30 compstmt '}' */ -#line 3460 "mrbgems/mruby-compiler/core/parse.y" +#line 3462 "mrbgems/mruby-compiler/core/parse.y" { pop_strterm(p, (yyvsp[-2].nd)); parser_heredoc_info *info = parsing_heredoc_info(p); info->doc = push(push(info->doc, (yyvsp[-3].nd)), (yyvsp[-1].nd)); } -#line 9521 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9522 "mrbgems/mruby-compiler/core/y.tab.c" break; case 464: /* words: tWORDS_BEG tSTRING */ -#line 3468 "mrbgems/mruby-compiler/core/parse.y" +#line 3470 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_words(p, list1((yyvsp[0].nd))); } -#line 9529 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9530 "mrbgems/mruby-compiler/core/y.tab.c" break; case 465: /* words: tWORDS_BEG string_rep tSTRING */ -#line 3472 "mrbgems/mruby-compiler/core/parse.y" +#line 3474 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9540,20 +9541,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_words(p, n); } -#line 9544 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9545 "mrbgems/mruby-compiler/core/y.tab.c" break; case 466: /* symbol: basic_symbol */ -#line 3486 "mrbgems/mruby-compiler/core/parse.y" +#line 3488 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_ENDARG; (yyval.nd) = new_sym(p, (yyvsp[0].id)); } -#line 9553 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9554 "mrbgems/mruby-compiler/core/y.tab.c" break; case 467: /* symbol: "symbol" "string literal" string_rep tSTRING */ -#line 3491 "mrbgems/mruby-compiler/core/parse.y" +#line 3493 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); p->lstate = EXPR_ENDARG; @@ -9565,43 +9566,43 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_dsym(p, new_dstr(p, n)); } -#line 9569 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9570 "mrbgems/mruby-compiler/core/y.tab.c" break; case 468: /* basic_symbol: "symbol" sym */ -#line 3505 "mrbgems/mruby-compiler/core/parse.y" +#line 3507 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 9577 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9578 "mrbgems/mruby-compiler/core/y.tab.c" break; case 473: /* sym: tSTRING */ -#line 3515 "mrbgems/mruby-compiler/core/parse.y" +#line 3517 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9585 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9586 "mrbgems/mruby-compiler/core/y.tab.c" break; case 474: /* sym: "string literal" tSTRING */ -#line 3519 "mrbgems/mruby-compiler/core/parse.y" +#line 3521 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = new_strsym(p, (yyvsp[0].nd)); } -#line 9593 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9594 "mrbgems/mruby-compiler/core/y.tab.c" break; case 475: /* symbols: tSYMBOLS_BEG tSTRING */ -#line 3525 "mrbgems/mruby-compiler/core/parse.y" +#line 3527 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_symbols(p, list1((yyvsp[0].nd))); } -#line 9601 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9602 "mrbgems/mruby-compiler/core/y.tab.c" break; case 476: /* symbols: tSYMBOLS_BEG string_rep tSTRING */ -#line 3529 "mrbgems/mruby-compiler/core/parse.y" +#line 3531 "mrbgems/mruby-compiler/core/parse.y" { node *n = (yyvsp[-1].nd); if (intn((yyvsp[0].nd)->cdr->cdr) > 0) { @@ -9609,123 +9610,123 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_symbols(p, n); } -#line 9613 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9614 "mrbgems/mruby-compiler/core/y.tab.c" break; case 479: /* numeric: tUMINUS_NUM "integer literal" */ -#line 3541 "mrbgems/mruby-compiler/core/parse.y" +#line 3543 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9621 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9622 "mrbgems/mruby-compiler/core/y.tab.c" break; case 480: /* numeric: tUMINUS_NUM "float literal" */ -#line 3545 "mrbgems/mruby-compiler/core/parse.y" +#line 3547 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_negate(p, (yyvsp[0].nd)); } -#line 9629 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9630 "mrbgems/mruby-compiler/core/y.tab.c" break; case 481: /* variable: "local variable or method" */ -#line 3551 "mrbgems/mruby-compiler/core/parse.y" +#line 3553 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_lvar(p, (yyvsp[0].id)); } -#line 9637 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9638 "mrbgems/mruby-compiler/core/y.tab.c" break; case 482: /* variable: "instance variable" */ -#line 3555 "mrbgems/mruby-compiler/core/parse.y" +#line 3557 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_ivar(p, (yyvsp[0].id)); } -#line 9645 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9646 "mrbgems/mruby-compiler/core/y.tab.c" break; case 483: /* variable: "global variable" */ -#line 3559 "mrbgems/mruby-compiler/core/parse.y" +#line 3561 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_gvar(p, (yyvsp[0].id)); } -#line 9653 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9654 "mrbgems/mruby-compiler/core/y.tab.c" break; case 484: /* variable: "class variable" */ -#line 3563 "mrbgems/mruby-compiler/core/parse.y" +#line 3565 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_cvar(p, (yyvsp[0].id)); } -#line 9661 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9662 "mrbgems/mruby-compiler/core/y.tab.c" break; case 485: /* variable: "constant" */ -#line 3567 "mrbgems/mruby-compiler/core/parse.y" +#line 3569 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_const(p, (yyvsp[0].id)); } -#line 9669 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9670 "mrbgems/mruby-compiler/core/y.tab.c" break; case 486: /* var_lhs: variable */ -#line 3573 "mrbgems/mruby-compiler/core/parse.y" +#line 3575 "mrbgems/mruby-compiler/core/parse.y" { assignable(p, (yyvsp[0].nd)); } -#line 9677 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9678 "mrbgems/mruby-compiler/core/y.tab.c" break; case 487: /* var_lhs: "numbered parameter" */ -#line 3577 "mrbgems/mruby-compiler/core/parse.y" +#line 3579 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "can't assign to numbered parameter"); } -#line 9685 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9686 "mrbgems/mruby-compiler/core/y.tab.c" break; case 488: /* var_ref: variable */ -#line 3583 "mrbgems/mruby-compiler/core/parse.y" +#line 3585 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = var_reference(p, (yyvsp[0].nd)); } -#line 9693 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9694 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 489: /* var_ref: keyword_nil */ -#line 3587 "mrbgems/mruby-compiler/core/parse.y" + case 489: /* var_ref: "'nil'" */ +#line 3589 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_nil(p); } -#line 9701 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9702 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 490: /* var_ref: keyword_self */ -#line 3591 "mrbgems/mruby-compiler/core/parse.y" + case 490: /* var_ref: "'self'" */ +#line 3593 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_self(p); } -#line 9709 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9710 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 491: /* var_ref: keyword_true */ -#line 3595 "mrbgems/mruby-compiler/core/parse.y" + case 491: /* var_ref: "'true'" */ +#line 3597 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_true(p); } -#line 9717 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9718 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 492: /* var_ref: keyword_false */ -#line 3599 "mrbgems/mruby-compiler/core/parse.y" + case 492: /* var_ref: "'false'" */ +#line 3601 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_false(p); } -#line 9725 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9726 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 493: /* var_ref: keyword__FILE__ */ -#line 3603 "mrbgems/mruby-compiler/core/parse.y" + case 493: /* var_ref: "'__FILE__'" */ +#line 3605 "mrbgems/mruby-compiler/core/parse.y" { const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); if (!fn) { @@ -9733,607 +9734,607 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = new_str(p, fn, strlen(fn)); } -#line 9737 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9738 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 494: /* var_ref: keyword__LINE__ */ -#line 3611 "mrbgems/mruby-compiler/core/parse.y" + case 494: /* var_ref: "'__LINE__'" */ +#line 3613 "mrbgems/mruby-compiler/core/parse.y" { char buf[16]; dump_int(p->lineno, buf); (yyval.nd) = new_int(p, buf, 10, 0); } -#line 9748 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9749 "mrbgems/mruby-compiler/core/y.tab.c" break; - case 495: /* var_ref: keyword__ENCODING__ */ -#line 3618 "mrbgems/mruby-compiler/core/parse.y" + case 495: /* var_ref: "'__ENCODING__'" */ +#line 3620 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_fcall(p, MRB_SYM_2(p->mrb, __ENCODING__), 0); } -#line 9756 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9757 "mrbgems/mruby-compiler/core/y.tab.c" break; case 498: /* superclass: %empty */ -#line 3628 "mrbgems/mruby-compiler/core/parse.y" +#line 3630 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 9764 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9765 "mrbgems/mruby-compiler/core/y.tab.c" break; case 499: /* $@31: %empty */ -#line 3632 "mrbgems/mruby-compiler/core/parse.y" +#line 3634 "mrbgems/mruby-compiler/core/parse.y" { p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9773 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9774 "mrbgems/mruby-compiler/core/y.tab.c" break; case 500: /* superclass: '<' $@31 expr_value term */ -#line 3637 "mrbgems/mruby-compiler/core/parse.y" +#line 3639 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9781 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9782 "mrbgems/mruby-compiler/core/y.tab.c" break; case 503: /* f_arglist_paren: '(' f_args rparen */ -#line 3653 "mrbgems/mruby-compiler/core/parse.y" +#line 3655 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); p->lstate = EXPR_BEG; p->cmd_start = TRUE; } -#line 9791 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9792 "mrbgems/mruby-compiler/core/y.tab.c" break; case 504: /* f_arglist_paren: '(' f_arg ',' tBDOT3 rparen */ -#line 3659 "mrbgems/mruby-compiler/core/parse.y" +#line 3661 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9799 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9800 "mrbgems/mruby-compiler/core/y.tab.c" break; case 505: /* f_arglist_paren: '(' tBDOT3 rparen */ -#line 3663 "mrbgems/mruby-compiler/core/parse.y" +#line 3665 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9807 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9808 "mrbgems/mruby-compiler/core/y.tab.c" break; case 507: /* f_arglist: f_args term */ -#line 3670 "mrbgems/mruby-compiler/core/parse.y" +#line 3672 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 9815 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9816 "mrbgems/mruby-compiler/core/y.tab.c" break; case 508: /* f_arglist: f_arg ',' tBDOT3 term */ -#line 3674 "mrbgems/mruby-compiler/core/parse.y" +#line 3676 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, (yyvsp[-3].nd)); } -#line 9823 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9824 "mrbgems/mruby-compiler/core/y.tab.c" break; case 509: /* f_arglist: "..." term */ -#line 3678 "mrbgems/mruby-compiler/core/parse.y" +#line 3680 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_dots(p, 0); } -#line 9831 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9832 "mrbgems/mruby-compiler/core/y.tab.c" break; case 510: /* f_label: "local variable or method" "label" */ -#line 3684 "mrbgems/mruby-compiler/core/parse.y" +#line 3686 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); } -#line 9839 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9840 "mrbgems/mruby-compiler/core/y.tab.c" break; case 511: /* f_label: "numbered parameter" "label" */ -#line 3688 "mrbgems/mruby-compiler/core/parse.y" +#line 3690 "mrbgems/mruby-compiler/core/parse.y" { local_nest(p); } -#line 9847 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9848 "mrbgems/mruby-compiler/core/y.tab.c" break; case 512: /* f_kw: f_label arg */ -#line 3694 "mrbgems/mruby-compiler/core/parse.y" +#line 3696 "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 9857 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9858 "mrbgems/mruby-compiler/core/y.tab.c" break; case 513: /* f_kw: f_label */ -#line 3700 "mrbgems/mruby-compiler/core/parse.y" +#line 3702 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9866 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9867 "mrbgems/mruby-compiler/core/y.tab.c" break; case 514: /* f_block_kw: f_label primary_value */ -#line 3707 "mrbgems/mruby-compiler/core/parse.y" +#line 3709 "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 9876 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9877 "mrbgems/mruby-compiler/core/y.tab.c" break; case 515: /* f_block_kw: f_label */ -#line 3713 "mrbgems/mruby-compiler/core/parse.y" +#line 3715 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_arg(p, (yyvsp[0].id), 0); local_unnest(p); } -#line 9885 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9886 "mrbgems/mruby-compiler/core/y.tab.c" break; case 516: /* f_block_kwarg: f_block_kw */ -#line 3720 "mrbgems/mruby-compiler/core/parse.y" +#line 3722 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9893 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9894 "mrbgems/mruby-compiler/core/y.tab.c" break; case 517: /* f_block_kwarg: f_block_kwarg ',' f_block_kw */ -#line 3724 "mrbgems/mruby-compiler/core/parse.y" +#line 3726 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9901 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9902 "mrbgems/mruby-compiler/core/y.tab.c" break; case 518: /* f_kwarg: f_kw */ -#line 3730 "mrbgems/mruby-compiler/core/parse.y" +#line 3732 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 9909 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9910 "mrbgems/mruby-compiler/core/y.tab.c" break; case 519: /* f_kwarg: f_kwarg ',' f_kw */ -#line 3734 "mrbgems/mruby-compiler/core/parse.y" +#line 3736 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 9917 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9918 "mrbgems/mruby-compiler/core/y.tab.c" break; case 522: /* f_kwrest: kwrest_mark "local variable or method" */ -#line 3744 "mrbgems/mruby-compiler/core/parse.y" +#line 3746 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, (yyvsp[0].id)); } -#line 9925 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9926 "mrbgems/mruby-compiler/core/y.tab.c" break; case 523: /* f_kwrest: kwrest_mark */ -#line 3748 "mrbgems/mruby-compiler/core/parse.y" +#line 3750 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_kw_rest_args(p, 0); } -#line 9933 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9934 "mrbgems/mruby-compiler/core/y.tab.c" break; case 524: /* args_tail: f_kwarg ',' f_kwrest opt_f_block_arg */ -#line 3754 "mrbgems/mruby-compiler/core/parse.y" +#line 3756 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-3].nd), (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9941 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9942 "mrbgems/mruby-compiler/core/y.tab.c" break; case 525: /* args_tail: f_kwarg opt_f_block_arg */ -#line 3758 "mrbgems/mruby-compiler/core/parse.y" +#line 3760 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, (yyvsp[-1].nd), 0, (yyvsp[0].id)); } -#line 9949 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9950 "mrbgems/mruby-compiler/core/y.tab.c" break; case 526: /* args_tail: f_kwrest opt_f_block_arg */ -#line 3762 "mrbgems/mruby-compiler/core/parse.y" +#line 3764 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, (yyvsp[-1].nd), (yyvsp[0].id)); } -#line 9957 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9958 "mrbgems/mruby-compiler/core/y.tab.c" break; case 527: /* args_tail: f_block_arg */ -#line 3766 "mrbgems/mruby-compiler/core/parse.y" +#line 3768 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, (yyvsp[0].id)); } -#line 9965 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9966 "mrbgems/mruby-compiler/core/y.tab.c" break; case 528: /* opt_args_tail: ',' args_tail */ -#line 3772 "mrbgems/mruby-compiler/core/parse.y" +#line 3774 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); } -#line 9973 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9974 "mrbgems/mruby-compiler/core/y.tab.c" break; case 529: /* opt_args_tail: %empty */ -#line 3776 "mrbgems/mruby-compiler/core/parse.y" +#line 3778 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args_tail(p, 0, 0, 0); } -#line 9981 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9982 "mrbgems/mruby-compiler/core/y.tab.c" break; case 530: /* f_args: f_arg ',' f_optarg ',' f_rest_arg opt_args_tail */ -#line 3782 "mrbgems/mruby-compiler/core/parse.y" +#line 3784 "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 9989 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9990 "mrbgems/mruby-compiler/core/y.tab.c" break; case 531: /* f_args: f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail */ -#line 3786 "mrbgems/mruby-compiler/core/parse.y" +#line 3788 "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 9997 "mrbgems/mruby-compiler/core/y.tab.c" +#line 9998 "mrbgems/mruby-compiler/core/y.tab.c" break; case 532: /* f_args: f_arg ',' f_optarg opt_args_tail */ -#line 3790 "mrbgems/mruby-compiler/core/parse.y" +#line 3792 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 10005 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10006 "mrbgems/mruby-compiler/core/y.tab.c" break; case 533: /* f_args: f_arg ',' f_optarg ',' f_arg opt_args_tail */ -#line 3794 "mrbgems/mruby-compiler/core/parse.y" +#line 3796 "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 10013 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10014 "mrbgems/mruby-compiler/core/y.tab.c" break; case 534: /* f_args: f_arg ',' f_rest_arg opt_args_tail */ -#line 3798 "mrbgems/mruby-compiler/core/parse.y" +#line 3800 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-3].nd), 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 10021 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10022 "mrbgems/mruby-compiler/core/y.tab.c" break; case 535: /* f_args: f_arg ',' f_rest_arg ',' f_arg opt_args_tail */ -#line 3802 "mrbgems/mruby-compiler/core/parse.y" +#line 3804 "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 10029 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10030 "mrbgems/mruby-compiler/core/y.tab.c" break; case 536: /* f_args: f_arg opt_args_tail */ -#line 3806 "mrbgems/mruby-compiler/core/parse.y" +#line 3808 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, (yyvsp[-1].nd), 0, 0, 0, (yyvsp[0].nd)); } -#line 10037 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10038 "mrbgems/mruby-compiler/core/y.tab.c" break; case 537: /* f_args: f_optarg ',' f_rest_arg opt_args_tail */ -#line 3810 "mrbgems/mruby-compiler/core/parse.y" +#line 3812 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 10045 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10046 "mrbgems/mruby-compiler/core/y.tab.c" break; case 538: /* f_args: f_optarg ',' f_rest_arg ',' f_arg opt_args_tail */ -#line 3814 "mrbgems/mruby-compiler/core/parse.y" +#line 3816 "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 10053 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10054 "mrbgems/mruby-compiler/core/y.tab.c" break; case 539: /* f_args: f_optarg opt_args_tail */ -#line 3818 "mrbgems/mruby-compiler/core/parse.y" +#line 3820 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-1].nd), 0, 0, (yyvsp[0].nd)); } -#line 10061 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10062 "mrbgems/mruby-compiler/core/y.tab.c" break; case 540: /* f_args: f_optarg ',' f_arg opt_args_tail */ -#line 3822 "mrbgems/mruby-compiler/core/parse.y" +#line 3824 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, (yyvsp[-3].nd), 0, (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 10069 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10070 "mrbgems/mruby-compiler/core/y.tab.c" break; case 541: /* f_args: f_rest_arg opt_args_tail */ -#line 3826 "mrbgems/mruby-compiler/core/parse.y" +#line 3828 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-1].id), 0, (yyvsp[0].nd)); } -#line 10077 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10078 "mrbgems/mruby-compiler/core/y.tab.c" break; case 542: /* f_args: f_rest_arg ',' f_arg opt_args_tail */ -#line 3830 "mrbgems/mruby-compiler/core/parse.y" +#line 3832 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, (yyvsp[-3].id), (yyvsp[-1].nd), (yyvsp[0].nd)); } -#line 10085 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10086 "mrbgems/mruby-compiler/core/y.tab.c" break; case 543: /* f_args: args_tail */ -#line 3834 "mrbgems/mruby-compiler/core/parse.y" +#line 3836 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_args(p, 0, 0, 0, 0, (yyvsp[0].nd)); } -#line 10093 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10094 "mrbgems/mruby-compiler/core/y.tab.c" break; case 544: /* f_args: %empty */ -#line 3838 "mrbgems/mruby-compiler/core/parse.y" +#line 3840 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, 0); (yyval.nd) = new_args(p, 0, 0, 0, 0, 0); } -#line 10102 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10103 "mrbgems/mruby-compiler/core/y.tab.c" break; case 545: /* f_bad_arg: "constant" */ -#line 3845 "mrbgems/mruby-compiler/core/parse.y" +#line 3847 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a constant"); (yyval.nd) = 0; } -#line 10111 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10112 "mrbgems/mruby-compiler/core/y.tab.c" break; case 546: /* f_bad_arg: "instance variable" */ -#line 3850 "mrbgems/mruby-compiler/core/parse.y" +#line 3852 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be an instance variable"); (yyval.nd) = 0; } -#line 10120 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10121 "mrbgems/mruby-compiler/core/y.tab.c" break; case 547: /* f_bad_arg: "global variable" */ -#line 3855 "mrbgems/mruby-compiler/core/parse.y" +#line 3857 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a global variable"); (yyval.nd) = 0; } -#line 10129 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10130 "mrbgems/mruby-compiler/core/y.tab.c" break; case 548: /* f_bad_arg: "class variable" */ -#line 3860 "mrbgems/mruby-compiler/core/parse.y" +#line 3862 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a class variable"); (yyval.nd) = 0; } -#line 10138 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10139 "mrbgems/mruby-compiler/core/y.tab.c" break; case 549: /* f_bad_arg: "numbered parameter" */ -#line 3865 "mrbgems/mruby-compiler/core/parse.y" +#line 3867 "mrbgems/mruby-compiler/core/parse.y" { yyerror(p, "formal argument cannot be a numbered parameter"); (yyval.nd) = 0; } -#line 10147 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10148 "mrbgems/mruby-compiler/core/y.tab.c" break; case 550: /* f_norm_arg: f_bad_arg */ -#line 3872 "mrbgems/mruby-compiler/core/parse.y" +#line 3874 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 10155 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10156 "mrbgems/mruby-compiler/core/y.tab.c" break; case 551: /* f_norm_arg: "local variable or method" */ -#line 3876 "mrbgems/mruby-compiler/core/parse.y" +#line 3878 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 10164 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10165 "mrbgems/mruby-compiler/core/y.tab.c" break; case 552: /* f_arg_item: f_norm_arg */ -#line 3883 "mrbgems/mruby-compiler/core/parse.y" +#line 3885 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = new_arg(p, (yyvsp[0].id)); } -#line 10172 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10173 "mrbgems/mruby-compiler/core/y.tab.c" break; case 553: /* @32: %empty */ -#line 3887 "mrbgems/mruby-compiler/core/parse.y" +#line 3889 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = local_switch(p); } -#line 10180 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10181 "mrbgems/mruby-compiler/core/y.tab.c" break; case 554: /* f_arg_item: tLPAREN @32 f_margs rparen */ -#line 3891 "mrbgems/mruby-compiler/core/parse.y" +#line 3893 "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 10190 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10191 "mrbgems/mruby-compiler/core/y.tab.c" break; case 555: /* f_arg: f_arg_item */ -#line 3899 "mrbgems/mruby-compiler/core/parse.y" +#line 3901 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 10198 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10199 "mrbgems/mruby-compiler/core/y.tab.c" break; case 556: /* f_arg: f_arg ',' f_arg_item */ -#line 3903 "mrbgems/mruby-compiler/core/parse.y" +#line 3905 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10206 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10207 "mrbgems/mruby-compiler/core/y.tab.c" break; case 557: /* f_opt_asgn: "local variable or method" '=' */ -#line 3909 "mrbgems/mruby-compiler/core/parse.y" +#line 3911 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[-1].id)); local_nest(p); (yyval.id) = (yyvsp[-1].id); } -#line 10216 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10217 "mrbgems/mruby-compiler/core/y.tab.c" break; case 558: /* f_opt: f_opt_asgn arg */ -#line 3917 "mrbgems/mruby-compiler/core/parse.y" +#line 3919 "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 10226 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10227 "mrbgems/mruby-compiler/core/y.tab.c" break; case 559: /* f_block_opt: f_opt_asgn primary_value */ -#line 3925 "mrbgems/mruby-compiler/core/parse.y" +#line 3927 "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 10236 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10237 "mrbgems/mruby-compiler/core/y.tab.c" break; case 560: /* f_block_optarg: f_block_opt */ -#line 3933 "mrbgems/mruby-compiler/core/parse.y" +#line 3935 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 10244 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10245 "mrbgems/mruby-compiler/core/y.tab.c" break; case 561: /* f_block_optarg: f_block_optarg ',' f_block_opt */ -#line 3937 "mrbgems/mruby-compiler/core/parse.y" +#line 3939 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10252 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10253 "mrbgems/mruby-compiler/core/y.tab.c" break; case 562: /* f_optarg: f_opt */ -#line 3943 "mrbgems/mruby-compiler/core/parse.y" +#line 3945 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); } -#line 10260 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10261 "mrbgems/mruby-compiler/core/y.tab.c" break; case 563: /* f_optarg: f_optarg ',' f_opt */ -#line 3947 "mrbgems/mruby-compiler/core/parse.y" +#line 3949 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10268 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10269 "mrbgems/mruby-compiler/core/y.tab.c" break; case 566: /* f_rest_arg: restarg_mark "local variable or method" */ -#line 3957 "mrbgems/mruby-compiler/core/parse.y" +#line 3959 "mrbgems/mruby-compiler/core/parse.y" { local_add_f(p, (yyvsp[0].id)); (yyval.id) = (yyvsp[0].id); } -#line 10277 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10278 "mrbgems/mruby-compiler/core/y.tab.c" break; case 567: /* f_rest_arg: restarg_mark */ -#line 3962 "mrbgems/mruby-compiler/core/parse.y" +#line 3964 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(mul); local_add_f(p, (yyval.id)); } -#line 10286 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10287 "mrbgems/mruby-compiler/core/y.tab.c" break; case 570: /* f_block_arg: blkarg_mark "local variable or method" */ -#line 3973 "mrbgems/mruby-compiler/core/parse.y" +#line 3975 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 10294 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10295 "mrbgems/mruby-compiler/core/y.tab.c" break; case 571: /* f_block_arg: blkarg_mark */ -#line 3977 "mrbgems/mruby-compiler/core/parse.y" +#line 3979 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = intern_op(and); } -#line 10302 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10303 "mrbgems/mruby-compiler/core/y.tab.c" break; case 572: /* opt_f_block_arg: ',' f_block_arg */ -#line 3983 "mrbgems/mruby-compiler/core/parse.y" +#line 3985 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = (yyvsp[0].id); } -#line 10310 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10311 "mrbgems/mruby-compiler/core/y.tab.c" break; case 573: /* opt_f_block_arg: none */ -#line 3987 "mrbgems/mruby-compiler/core/parse.y" +#line 3989 "mrbgems/mruby-compiler/core/parse.y" { (yyval.id) = 0; } -#line 10318 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10319 "mrbgems/mruby-compiler/core/y.tab.c" break; case 574: /* singleton: var_ref */ -#line 3993 "mrbgems/mruby-compiler/core/parse.y" +#line 3995 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[0].nd); if (!(yyval.nd)) (yyval.nd) = new_nil(p); } -#line 10327 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10328 "mrbgems/mruby-compiler/core/y.tab.c" break; case 575: /* $@33: %empty */ -#line 3997 "mrbgems/mruby-compiler/core/parse.y" +#line 3999 "mrbgems/mruby-compiler/core/parse.y" {p->lstate = EXPR_BEG;} -#line 10333 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10334 "mrbgems/mruby-compiler/core/y.tab.c" break; case 576: /* singleton: '(' $@33 expr rparen */ -#line 3998 "mrbgems/mruby-compiler/core/parse.y" +#line 4000 "mrbgems/mruby-compiler/core/parse.y" { if ((yyvsp[-1].nd) == 0) { yyerror(p, "can't define singleton method for ()."); @@ -10356,81 +10357,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } (yyval.nd) = (yyvsp[-1].nd); } -#line 10360 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10361 "mrbgems/mruby-compiler/core/y.tab.c" break; case 578: /* assoc_list: assocs trailer */ -#line 4024 "mrbgems/mruby-compiler/core/parse.y" +#line 4026 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = (yyvsp[-1].nd); } -#line 10368 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10369 "mrbgems/mruby-compiler/core/y.tab.c" break; case 579: /* assocs: assoc */ -#line 4030 "mrbgems/mruby-compiler/core/parse.y" +#line 4032 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = list1((yyvsp[0].nd)); NODE_LINENO((yyval.nd), (yyvsp[0].nd)); } -#line 10377 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10378 "mrbgems/mruby-compiler/core/y.tab.c" break; case 580: /* assocs: assocs comma assoc */ -#line 4035 "mrbgems/mruby-compiler/core/parse.y" +#line 4037 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = push((yyvsp[-2].nd), (yyvsp[0].nd)); } -#line 10385 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10386 "mrbgems/mruby-compiler/core/y.tab.c" break; case 581: /* assoc: arg "=>" arg */ -#line 4041 "mrbgems/mruby-compiler/core/parse.y" +#line 4043 "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 10395 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10396 "mrbgems/mruby-compiler/core/y.tab.c" break; case 582: /* assoc: "local variable or method" "label" arg */ -#line 4047 "mrbgems/mruby-compiler/core/parse.y" +#line 4049 "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 10404 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10405 "mrbgems/mruby-compiler/core/y.tab.c" break; case 583: /* assoc: "local variable or method" "label" */ -#line 4052 "mrbgems/mruby-compiler/core/parse.y" +#line 4054 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_sym(p, (yyvsp[-1].id)), label_reference(p, (yyvsp[-1].id))); } -#line 10412 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10413 "mrbgems/mruby-compiler/core/y.tab.c" break; case 584: /* assoc: "numbered parameter" "label" */ -#line 4056 "mrbgems/mruby-compiler/core/parse.y" +#line 4058 "mrbgems/mruby-compiler/core/parse.y" { mrb_sym sym = intern_numparam((yyvsp[-1].num)); (yyval.nd) = cons(new_sym(p, sym), label_reference(p, sym)); } -#line 10421 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10422 "mrbgems/mruby-compiler/core/y.tab.c" break; case 585: /* assoc: "numbered parameter" "label" arg */ -#line 4061 "mrbgems/mruby-compiler/core/parse.y" +#line 4063 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); (yyval.nd) = cons(new_sym(p, intern_numparam((yyvsp[-2].num))), (yyvsp[0].nd)); } -#line 10430 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10431 "mrbgems/mruby-compiler/core/y.tab.c" break; case 586: /* assoc: string_fragment "label" arg */ -#line 4066 "mrbgems/mruby-compiler/core/parse.y" +#line 4068 "mrbgems/mruby-compiler/core/parse.y" { void_expr_error(p, (yyvsp[0].nd)); if (typen((yyvsp[-2].nd)->car) == NODE_DSTR) { @@ -10440,75 +10441,75 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.nd) = cons(new_sym(p, new_strsym(p, (yyvsp[-2].nd))), (yyvsp[0].nd)); } } -#line 10444 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10445 "mrbgems/mruby-compiler/core/y.tab.c" break; case 587: /* assoc: "**" arg */ -#line 4076 "mrbgems/mruby-compiler/core/parse.y" +#line 4078 "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 10453 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10454 "mrbgems/mruby-compiler/core/y.tab.c" break; case 588: /* assoc: "**" */ -#line 4081 "mrbgems/mruby-compiler/core/parse.y" +#line 4083 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = cons(new_kw_rest_args(p, 0), new_lvar(p, intern_op(pow))); } -#line 10461 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10462 "mrbgems/mruby-compiler/core/y.tab.c" break; case 601: /* call_op: '.' */ -#line 4107 "mrbgems/mruby-compiler/core/parse.y" +#line 4109 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = '.'; } -#line 10469 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10470 "mrbgems/mruby-compiler/core/y.tab.c" break; case 602: /* call_op: "&." */ -#line 4111 "mrbgems/mruby-compiler/core/parse.y" +#line 4113 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = 0; } -#line 10477 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10478 "mrbgems/mruby-compiler/core/y.tab.c" break; case 604: /* call_op2: "::" */ -#line 4118 "mrbgems/mruby-compiler/core/parse.y" +#line 4120 "mrbgems/mruby-compiler/core/parse.y" { (yyval.num) = tCOLON2; } -#line 10485 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10486 "mrbgems/mruby-compiler/core/y.tab.c" break; case 613: /* term: ';' */ -#line 4139 "mrbgems/mruby-compiler/core/parse.y" +#line 4141 "mrbgems/mruby-compiler/core/parse.y" {yyerrok;} -#line 10491 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10492 "mrbgems/mruby-compiler/core/y.tab.c" break; case 615: /* nl: '\n' */ -#line 4144 "mrbgems/mruby-compiler/core/parse.y" +#line 4146 "mrbgems/mruby-compiler/core/parse.y" { p->lineno += (yyvsp[0].num); p->column = 0; } -#line 10500 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10501 "mrbgems/mruby-compiler/core/y.tab.c" break; case 619: /* none: %empty */ -#line 4156 "mrbgems/mruby-compiler/core/parse.y" +#line 4158 "mrbgems/mruby-compiler/core/parse.y" { (yyval.nd) = 0; } -#line 10508 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10509 "mrbgems/mruby-compiler/core/y.tab.c" break; -#line 10512 "mrbgems/mruby-compiler/core/y.tab.c" +#line 10513 "mrbgems/mruby-compiler/core/y.tab.c" default: break; } @@ -10732,7 +10733,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); return yyresult; } -#line 4160 "mrbgems/mruby-compiler/core/parse.y" +#line 4162 "mrbgems/mruby-compiler/core/parse.y" #define pylval (*((YYSTYPE*)(p->ylval))) @@ -11402,7 +11403,8 @@ heredoc_remove_indent(parser_state *p, parser_heredoc_info *hinfo) newstr[newlen] = '\0'; pair->car = (node*)newstr; pair->cdr = (node*)newlen; - } else { + } + else { spaces = (size_t)nspaces->car; heredoc_count_indent(hinfo, str, len, spaces, &offset); pair->car = (node*)(str + offset); @@ -11477,7 +11479,8 @@ parse_string(parser_state *p) if (sizeof(s1)+sizeof(s2)+strlen(hinfo->term)+1 >= sizeof(buf)) { yyerror(p, "can't find heredoc delimiter anywhere before EOF"); - } else { + } + else { strcpy(buf, s1); strcat(buf, hinfo->term); strcat(buf, s2); @@ -13313,8 +13316,9 @@ mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s) { if (s) { size_t len = strlen(s); - char *p = (char*)mrb_malloc(mrb, len + 1); + char *p = (char*)mrb_malloc_simple(mrb, len + 1); + if (p == NULL) return NULL; memcpy(p, s, len + 1); if (c->filename) { mrb_free(mrb, c->filename); diff --git a/mruby/mrbgems/mruby-complex/src/complex.c b/mruby/mrbgems/mruby-complex/src/complex.c index ad88a67e..f0e5829d 100644 --- a/mruby/mrbgems/mruby-complex/src/complex.c +++ b/mruby/mrbgems/mruby-complex/src/complex.c @@ -284,12 +284,15 @@ add_pair(struct float_pair *s, struct float_pair const *a, { if (b->s == 0.0F) { *s = *a; - } else if (a->s == 0.0F) { + } + else if (a->s == 0.0F) { *s = *b; - } else if (a->x >= b->x) { + } + else if (a->x >= b->x) { s->s = a->s + F(ldexp)(b->s, b->x - a->x); s->x = a->x; - } else { + } + else { s->s = F(ldexp)(a->s, a->x - b->x) + b->s; s->x = b->x; } @@ -392,7 +395,7 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) struct RClass *comp; comp = mrb_define_class_id(mrb, MRB_SYM(Complex), mrb_class_get_id(mrb, MRB_SYM(Numeric))); - MRB_SET_INSTANCE_TT(comp, MRB_TT_COMPLEX); + MRB_SET_INSTANCE_TT(comp, MRB_TT_UNDEF); mrb_undef_class_method(mrb, comp, "new"); mrb_define_class_method(mrb, comp, "rectangular", complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); diff --git a/mruby/mrbgems/mruby-data/src/data.c b/mruby/mrbgems/mruby-data/src/data.c index 91bc55a0..dd077619 100644 --- a/mruby/mrbgems/mruby-data/src/data.c +++ b/mruby/mrbgems/mruby-data/src/data.c @@ -94,15 +94,60 @@ mrb_data_members(mrb_state *mrb, mrb_value obj) } static mrb_value -mrb_data_ref(mrb_state *mrb, mrb_value obj) +data_ref(mrb_state *mrb, mrb_value obj, mrb_int i) { - mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); + mrb_int len = RDATA_LEN(obj); mrb_value *ptr = RDATA_PTR(obj); - if (!ptr) return mrb_nil_value(); + if (!ptr || len <= i) + return mrb_nil_value(); return ptr[i]; } +static mrb_value +mrb_data_ref(mrb_state *mrb, mrb_value obj) +{ + mrb_int argc = mrb_get_argc(mrb); + if (argc != 0) { + mrb_argnum_error(mrb, argc, 0, 0); + } + mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); + return data_ref(mrb, obj, i); +} + +static mrb_value +data_ref_0(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 0); +} + +static mrb_value +data_ref_1(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 1); +} + +static mrb_value +data_ref_2(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 2); +} + +static mrb_value +data_ref_3(mrb_state *mrb, mrb_value obj) +{ + return data_ref(mrb, obj, 3); +} + +#define DATA_DIRECT_REF_MAX 4 + +static mrb_func_t aref[DATA_DIRECT_REF_MAX] = { + data_ref_0, + data_ref_1, + data_ref_2, + data_ref_3, +}; + static void make_data_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) { @@ -112,12 +157,18 @@ make_data_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) for (mrb_int i=0; i0) mrb_str_cat_lit(mrb, ret, ", "); mrb_str_cat(mrb, ret, name, len); mrb_str_cat_lit(mrb, ret, "="); - mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, vals[i])); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, RARRAY_PTR(self)[i])); mrb_gc_arena_restore(mrb, ai); } mrb_str_cat_lit(mrb, ret, ">"); @@ -440,7 +492,7 @@ mrb_mruby_data_gem_init(mrb_state* mrb) { struct RClass *d; d = mrb_define_class(mrb, "Data", mrb->object_class); - MRB_SET_INSTANCE_TT(d, MRB_TT_STRUCT); + MRB_SET_INSTANCE_TT(d, MRB_TT_UNDEF); mrb_undef_class_method(mrb, d, "new"); mrb_define_class_method(mrb, d, "define", mrb_data_s_def, MRB_ARGS_ANY()); diff --git a/mruby/mrbgems/mruby-dir/README.md b/mruby/mrbgems/mruby-dir/README.md index 2be9d03c..7cd9fcc3 100644 --- a/mruby/mrbgems/mruby-dir/README.md +++ b/mruby/mrbgems/mruby-dir/README.md @@ -1,6 +1,6 @@ # mruby-dir -Dir class for mruby. Supported methods are: +Dir class for mruby. Supported methods are: `.chdir` `.delete` diff --git a/mruby/mrbgems/mruby-dir/mrbgem.rake b/mruby/mrbgems/mruby-dir/mrbgem.rake index 6951c49d..ed05e14d 100644 --- a/mruby/mrbgems/mruby-dir/mrbgem.rake +++ b/mruby/mrbgems/mruby-dir/mrbgem.rake @@ -1,4 +1,4 @@ MRuby::Gem::Specification.new('mruby-dir') do |spec| spec.license = 'MIT and MIT-like license' - spec.authors = [ 'Internet Initiative Japan Inc.', 'Kevlin Henney'] + spec.authors = ['Internet Initiative Japan Inc.', 'Kevlin Henney'] end diff --git a/mruby/mrbgems/mruby-dir/src/Win/dirent.c b/mruby/mrbgems/mruby-dir/src/Win/dirent.c index 1b43a992..086aaf97 100644 --- a/mruby/mrbgems/mruby-dir/src/Win/dirent.c +++ b/mruby/mrbgems/mruby-dir/src/Win/dirent.c @@ -39,38 +39,31 @@ DIR *opendir(const char *name) { DIR *dir = 0; - if(name && name[0]) - { + if (name && name[0]) { size_t base_length = strlen(name); const char *all = /* search pattern must end with suitable wildcard */ strchr("/\\", name[base_length - 1]) ? "*" : "/*"; - if((dir = (DIR *) malloc(sizeof *dir)) != 0 && - (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) - { + if ((dir = (DIR *) malloc(sizeof *dir)) != 0 && + (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) { strcat(strcpy(dir->name, name), all); - if((dir->handle = - (handle_type) _findfirst(dir->name, &dir->info)) != -1) - { + if ((dir->handle = (handle_type) _findfirst(dir->name, &dir->info)) != -1) { dir->result.d_name = 0; } - else /* rollback */ - { + else { /* rollback */ free(dir->name); free(dir); dir = 0; } } - else /* rollback */ - { + else { /* rollback */ free(dir); dir = 0; errno = ENOMEM; } } - else - { + else { errno = EINVAL; } @@ -81,9 +74,8 @@ int closedir(DIR *dir) { int result = -1; - if(dir) - { - if(dir->handle != -1) + if (dir) { + if (dir->handle != -1) { result = _findclose(dir->handle); } @@ -92,8 +84,7 @@ int closedir(DIR *dir) free(dir); } - if(result == -1) /* map all errors to EBADF */ - { + if (result == -1) { /* map all errors to EBADF */ errno = EBADF; } @@ -104,16 +95,13 @@ struct dirent *readdir(DIR *dir) { struct dirent *result = 0; - if(dir && dir->handle != -1) - { - if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) - { + if (dir && dir->handle != -1) { + if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { result = &dir->result; result->d_name = dir->info.name; } } - else - { + else { errno = EBADF; } @@ -122,14 +110,12 @@ struct dirent *readdir(DIR *dir) void rewinddir(DIR *dir) { - if(dir && dir->handle != -1) - { + if (dir && dir->handle != -1) { _findclose(dir->handle); dir->handle = (handle_type) _findfirst(dir->name, &dir->info); dir->result.d_name = 0; } - else - { + else { errno = EBADF; } } diff --git a/mruby/mrbgems/mruby-dir/src/dir.c b/mruby/mrbgems/mruby-dir/src/dir.c index 455c17bd..52d100f2 100644 --- a/mruby/mrbgems/mruby-dir/src/dir.c +++ b/mruby/mrbgems/mruby-dir/src/dir.c @@ -34,6 +34,7 @@ #include #include #include +#include #define E_IO_ERROR mrb_exc_get_id(mrb, MRB_SYM(IOError)) @@ -128,10 +129,16 @@ static mrb_value mrb_dir_getwd(mrb_state *mrb, mrb_value klass) { mrb_value path; + mrb_int size = 64; - path = mrb_str_buf_new(mrb, MAXPATHLEN); - if (getcwd(RSTRING_PTR(path), MAXPATHLEN) == NULL) { - mrb_sys_fail(mrb, "getcwd(2)"); + path = mrb_str_buf_new(mrb, size); + while (getcwd(RSTRING_PTR(path), size) == NULL) { + int e = errno; + if (e != ERANGE) { + mrb_sys_fail(mrb, "getcwd(2)"); + } + size *= 2; + mrb_str_resize(mrb, path, size); } mrb_str_resize(mrb, path, strlen(RSTRING_PTR(path))); return path; @@ -166,7 +173,7 @@ mrb_dir_chdir(mrb_state *mrb, mrb_value klass) static mrb_value mrb_dir_chroot(mrb_state *mrb, mrb_value self) { -#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__) +#if defined(_WIN32) || defined(_WIN64) || defined(__ANDROID__) || defined(__MSDOS__) mrb_raise(mrb, E_NOTIMP_ERROR, "chroot() unreliable on your system"); return mrb_fixnum_value(0); #else @@ -312,7 +319,7 @@ mrb_mruby_dir_gem_init(mrb_state *mrb) mrb_define_method(mrb, d, "seek", mrb_dir_seek, MRB_ARGS_REQ(1)); mrb_define_method(mrb, d, "tell", mrb_dir_tell, MRB_ARGS_NONE()); - mrb_define_class(mrb, "IOError", mrb->eStandardError_class); + mrb_define_class(mrb, "IOError", E_STANDARD_ERROR); } void diff --git a/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb index 65cddbda..4cc18efd 100644 --- a/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ b/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -574,7 +574,7 @@ def << *args # # Examples of usage: # - # Enumerator.produce(1, &:succ) # => enumerator of 1, 2, 3, 4, .... + # Enumerator.produce(1, &:succ) # => enumerator of 1, 2, 3, 4, ... # # Enumerator.produce { rand(10) } # => infinite random number sequence # diff --git a/mruby/mrbgems/mruby-errno/src/errno.c b/mruby/mrbgems/mruby-errno/src/errno.c index 97132b4b..b2059f46 100644 --- a/mruby/mrbgems/mruby-errno/src/errno.c +++ b/mruby/mrbgems/mruby-errno/src/errno.c @@ -265,7 +265,8 @@ mrb_sce_errno(mrb_state *mrb, mrb_value self) sym = MRB_SYM(Errno); if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) { return mrb_const_get(mrb, mrb_obj_value(c), sym); - } else { + } + else { sym = MRB_SYM(errno); return mrb_attr_get(mrb, self, sym); } @@ -296,11 +297,9 @@ mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) void mrb_mruby_errno_gem_init(mrb_state *mrb) { - struct RClass *e, *eno, *sce, *ste; - - ste = mrb->eStandardError_class; + struct RClass *e, *eno, *sce; - sce = mrb_define_class(mrb, "SystemCallError", ste); + sce = mrb_define_class(mrb, "SystemCallError", E_STANDARD_ERROR); mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1)); mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE()); mrb_define_method(mrb, sce, "initialize", mrb_sce_init_m, MRB_ARGS_ARG(1, 1)); diff --git a/mruby/mrbgems/mruby-eval/mrbgem.rake b/mruby/mrbgems/mruby-eval/mrbgem.rake index cb8835b3..d2986fd3 100644 --- a/mruby/mrbgems/mruby-eval/mrbgem.rake +++ b/mruby/mrbgems/mruby-eval/mrbgem.rake @@ -4,4 +4,7 @@ MRuby::Gem::Specification.new('mruby-eval') do |spec| spec.summary = 'standard Kernel#eval method' add_dependency 'mruby-compiler', :core => 'mruby-compiler' + add_dependency 'mruby-binding', :core => 'mruby-binding' + spec.add_test_dependency('mruby-metaprog', :core => 'mruby-metaprog') + spec.add_test_dependency('mruby-method', :core => 'mruby-method') end diff --git a/mruby/mrbgems/mruby-eval/src/eval.c b/mruby/mrbgems/mruby-eval/src/eval.c index ff65b0fa..5b843216 100644 --- a/mruby/mrbgems/mruby-eval/src/eval.c +++ b/mruby/mrbgems/mruby-eval/src/eval.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -9,6 +10,15 @@ #include #include +/* provided by mruby-binding */ +mrb_bool mrb_binding_p(mrb_state *mrb, mrb_value binding); +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); + +/* provided by mruby-compiler */ +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 struct RProc* create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) { @@ -22,22 +32,16 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi struct mrb_context *c = mrb->c; if (!mrb_nil_p(binding)) { - mrb_value scope_obj; - if (!mrb_class_defined_id(mrb, MRB_SYM(Binding)) - || !mrb_obj_is_kind_of(mrb, binding, mrb_class_get_id(mrb, MRB_SYM(Binding)))) { + if (!mrb_binding_p(mrb, binding)) { mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %C (expected binding)", - mrb_obj_class(mrb, binding)); + mrb_obj_class(mrb, binding)); } - scope_obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); - mrb_check_type(mrb, scope_obj, MRB_TT_PROC); - scope = mrb_proc_ptr(scope_obj); + scope = mrb_binding_extract_proc(mrb, binding); if (MRB_PROC_CFUNC_P(scope)) { e = NULL; } else { - mrb_value env = mrb_iv_get(mrb, binding, MRB_SYM(env)); - mrb_check_type(mrb, env, MRB_TT_ENV); - e = (struct REnv *)mrb_obj_ptr(env); + e = mrb_binding_extract_env(mrb, binding); mrb_assert(e != NULL); } } @@ -146,6 +150,108 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) return mrb_exec_irep(mrb, self, proc); } +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; + int 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; + 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->upper = proc; + 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, const char *expr, mrb_int exprlen, const char *file) +{ + struct binding_eval_prepare_body d = { binding }; + + d.mrbc = mrbc_context_new(mrb); + d.file = mrbc_filename(mrb, d.mrbc, file ? file : "(eval)"); + d.mrbc->capture_errors = TRUE; + d.pstate = mrb_parse_nstring(mrb, expr, exprlen, d.mrbc); + + 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 f_eval(mrb_state *mrb, mrb_value self) { @@ -158,6 +264,9 @@ f_eval(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line); + if (!mrb_nil_p(binding)) { + binding_eval_prepare(mrb, binding, s, len, file); + } 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)); @@ -214,6 +323,22 @@ f_class_eval(mrb_state *mrb, mrb_value self) } } +static mrb_value +mrb_binding_eval(mrb_state *mrb, mrb_value binding) +{ + mrb_callinfo *ci = mrb->c->ci; + int argc = ci->n; + mrb_value *argv = ci->stack + 1; + + if (argc < 15) { + argv[0] = mrb_ary_new_from_values(mrb, argc, argv); + argv[1] = argv[argc]; /* copy block */ + ci->n = 15; + } + mrb_ary_splice(mrb, argv[0], 1, 0, binding); /* insert binding as 2nd argument */ + return f_eval(mrb, binding); +} + void mrb_mruby_eval_gem_init(mrb_state* mrb) { @@ -221,6 +346,9 @@ mrb_mruby_eval_gem_init(mrb_state* mrb) 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()); + + struct RClass *binding = mrb_class_get_id(mrb, MRB_SYM(Binding)); + mrb_define_method(mrb, binding, "eval", mrb_binding_eval, MRB_ARGS_ANY()); } void diff --git a/mruby/mrbgems/mruby-eval/test/binding.rb b/mruby/mrbgems/mruby-eval/test/binding.rb new file mode 100644 index 00000000..1266690e --- /dev/null +++ b/mruby/mrbgems/mruby-eval/test/binding.rb @@ -0,0 +1,64 @@ +assert("Binding#eval") do + b = nil + 1.times { x, y, z = 1, 2, 3; [x,y,z]; b = binding } + assert_equal([1, 2, 3], b.eval("[x, y, z]")) + here = self + assert_equal(here, b.eval("self")) +end + +assert("Binding#local_variables") do + block = Proc.new do |a| + b = 1 + binding + end + bind = block.call(0) + assert_equal [:a, :b, :bind, :block], bind.local_variables.sort + bind.eval("x = 2") + assert_equal [:a, :b, :bind, :block, :x], bind.local_variables.sort +end + +assert("Binding#local_variable_set") do + bind = binding + 1.times { + assert_equal(9, bind.local_variable_set(:x, 9)) + assert_equal(9, bind.eval("x")) + assert_equal([:bind, :x], bind.eval("local_variables.sort")) + } +end + +assert("Binding#local_variable_get") do + bind = binding + x = 1 + 1.times { + y = 2 + assert_equal(1, bind.local_variable_get(:x)) + x = 10 + assert_equal(10, bind.local_variable_get(:x)) + assert_raise(NameError) { bind.local_variable_get(:y) } + bind.eval("z = 3") + assert_equal(3, bind.local_variable_get(:z)) + bind.eval("y = 5") + assert_equal(5, bind.local_variable_get(:y)) + assert_equal(2, y) + } +end + +assert "Binding#eval with Binding.new via UnboundMethod" do + assert_raise(NoMethodError) { Class.instance_method(:new).bind_call(Binding) } +end + +assert "Binding#eval with Binding.new via Method" do + # The following test is OK if SIGSEGV does not occur + cx = Class.new(Binding) + cx.define_singleton_method(:allocate, &Object.method(:allocate)) + Class.instance_method(:new).bind_call(cx).eval("") + + 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/mruby/mrbgems/mruby-exit/src/mruby-exit.c b/mruby/mrbgems/mruby-exit/src/mruby-exit.c index 658d188e..24311f12 100644 --- a/mruby/mrbgems/mruby-exit/src/mruby-exit.c +++ b/mruby/mrbgems/mruby-exit/src/mruby-exit.c @@ -72,7 +72,7 @@ f_exit_bang(mrb_state *mrb, mrb_value self) void mrb_mruby_exit_gem_init(mrb_state* mrb) { - mrb_define_class_id(mrb, MRB_SYM(SystemExit), mrb->eException_class); + mrb_define_class_id(mrb, MRB_SYM(SystemExit), E_EXCEPTION); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM(exit), f_exit, MRB_ARGS_OPT(1)); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM_B(exit), f_exit_bang, MRB_ARGS_OPT(1)); } diff --git a/mruby/mrbgems/mruby-fiber/src/fiber.c b/mruby/mrbgems/mruby-fiber/src/fiber.c index 75ffa906..05baac96 100644 --- a/mruby/mrbgems/mruby-fiber/src/fiber.c +++ b/mruby/mrbgems/mruby-fiber/src/fiber.c @@ -93,7 +93,7 @@ fiber_init(mrb_state *mrb, mrb_value self) if (p->body.irep->nregs > slen) { slen += p->body.irep->nregs; } - c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value)); + c->stbase = (mrb_value*)mrb_malloc(mrb, slen*sizeof(mrb_value)); c->stend = c->stbase + slen; { @@ -110,7 +110,7 @@ fiber_init(mrb_state *mrb, mrb_value self) c->stbase[0] = mrb->c->ci->stack[0]; /* initialize callinfo stack */ - c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo)); + c->cibase = (mrb_callinfo*)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + FIBER_CI_INIT_SIZE; c->ci = c->cibase; @@ -257,7 +257,14 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr } } c->cibase->n = (uint8_t)len; - value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; + struct REnv *env = MRB_PROC_ENV(c->cibase->proc); + if (env && env->stack) { + value = env->stack[0]; + } + else { + value = mrb_top_self(mrb); + } + c->stbase[0] = value; } else { value = fiber_result(mrb, a, len); @@ -300,13 +307,9 @@ fiber_resume(mrb_state *mrb, mrb_value self) { const mrb_value *a; mrb_int len; - mrb_bool vmexec = FALSE; mrb_get_args(mrb, "*!", &a, &len); - if (mrb->c->ci->cci > 0) { - vmexec = TRUE; - } - return fiber_switch(mrb, self, len, a, TRUE, vmexec); + return fiber_switch(mrb, self, len, a, TRUE, FALSE); } MRB_API mrb_value @@ -470,7 +473,7 @@ mrb_mruby_fiber_gem_init(mrb_state* mrb) mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY()); mrb_define_class_method(mrb, c, "current", fiber_current, MRB_ARGS_NONE()); - mrb_define_class(mrb, "FiberError", mrb->eStandardError_class); + mrb_define_class(mrb, "FiberError", E_STANDARD_ERROR); } void diff --git a/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb index 5a8b5377..11537093 100644 --- a/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -113,16 +113,7 @@ def merge!(*others, &block) # def compact! - keys = self.keys - nk = keys.select{|k| - self[k] != nil - } - return nil if (keys.size == nk.size) - h = {} - nk.each {|k| - h[k] = self[k] - } - self.replace(h) + self.__compact end ## @@ -136,12 +127,8 @@ def compact! # h #=> { a: 1, b: false, c: nil } # def compact - h = {} - self.keys.select{|k| - self[k] != nil - }.each {|k| - h[k] = self[k] - } + h=self.dup + h.__compact h end diff --git a/mruby/mrbgems/mruby-hash-ext/test/hash.rb b/mruby/mrbgems/mruby-hash-ext/test/hash.rb index a705af65..60a2123e 100644 --- a/mruby/mrbgems/mruby-hash-ext/test/hash.rb +++ b/mruby/mrbgems/mruby-hash-ext/test/hash.rb @@ -89,8 +89,8 @@ assert('Hash#compact!') do h = { "cat" => "feline", "dog" => nil, "cow" => false } - h.compact! - assert_equal({ "cat" => "feline", "cow" => false }, h) + assert_equal({ "cat" => "feline", "cow" => false }, h.compact!) + assert_nil(h.compact!) end assert('Hash#fetch') do diff --git a/mruby/mrbgems/mruby-io/README.md b/mruby/mrbgems/mruby-io/README.md index 525785fa..21138ace 100644 --- a/mruby/mrbgems/mruby-io/README.md +++ b/mruby/mrbgems/mruby-io/README.md @@ -158,14 +158,14 @@ Add the line below to your build configuration. | File.writable? | | FileTest | | File.writable_real? | | FileTest | | File.zero? | o | FileTest | -| File#atime | | | +| File#atime | o | | | File#chmod | | | | File#chown | | | -| File#ctime | | | +| File#ctime | o | | | File#flock | o | | | File#lstat | | | -| File#mtime | | | -| File#path, File#to_path | o | | +| File#mtime | o | | +| File#path | o | | | File#size | | | | File#truncate | | | diff --git a/mruby/mrbgems/mruby-io/mrblib/file.rb b/mruby/mrbgems/mruby-io/mrblib/file.rb index 9398acef..719f4e62 100644 --- a/mruby/mrbgems/mruby-io/mrblib/file.rb +++ b/mruby/mrbgems/mruby-io/mrblib/file.rb @@ -11,11 +11,25 @@ def initialize(fd_or_path, mode = "r", perm = 0666) end end + def atime + t = self._atime + t && Time.at(t) + end + + def ctime + t = self._ctime + t && Time.at(t) + end + def mtime t = self._mtime t && Time.at(t) end + def inspect + "<#{self.class}:#{@path}>" + end + def self.join(*names) return "" if names.empty? @@ -199,8 +213,6 @@ def self.extname(filename) def self.path(filename) if filename.kind_of?(String) filename - elsif filename.respond_to?(:to_path) - filename.to_path else raise TypeError, "no implicit conversion of #{filename.class} into String" end diff --git a/mruby/mrbgems/mruby-io/src/file.c b/mruby/mrbgems/mruby-io/src/file.c index e0957ffa..2bfef303 100644 --- a/mruby/mrbgems/mruby-io/src/file.c +++ b/mruby/mrbgems/mruby-io/src/file.c @@ -38,7 +38,9 @@ #define GETCWD getcwd #define CHMOD(a, b) chmod(a,b) #include +#ifndef __DJGPP__ #include +#endif #include #include #endif @@ -105,7 +107,8 @@ mrb_file_s_umask(mrb_state *mrb, mrb_value klass) if (mrb_get_args(mrb, "|i", &mask) == 0) { omask = umask(0); umask(omask); - } else { + } + else { omask = umask(mask); } return mrb_fixnum_value(omask); @@ -179,7 +182,8 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass) ridx = strlen(buffer); if (ridx == 0) { strncpy(buffer, ".", 2); /* null terminated */ - } else if (ridx > 1) { + } + else if (ridx > 1) { ridx--; while (ridx > 0 && (buffer[ridx] == '/' || buffer[ridx] == '\\')) { buffer[ridx] = '\0'; /* remove last char */ @@ -275,6 +279,7 @@ mrb_file__getwd(mrb_state *mrb, mrb_value klass) mrb_value path; char buf[MAXPATHLEN], *utf8; + mrb->c->ci->mid = 0; if (GETCWD(buf, MAXPATHLEN) == NULL) { mrb_sys_fail(mrb, "getcwd(2)"); } @@ -344,6 +349,7 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) char *home; mrb_value path; + mrb->c->ci->mid = 0; #ifndef _WIN32 mrb_value username; @@ -356,7 +362,8 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) if (!mrb_file_is_absolute_path(home)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home"); } - } else { + } + else { const char *cuser = RSTRING_CSTR(mrb, username); struct passwd *pwd = getpwnam(cuser); if (pwd == NULL) { @@ -381,7 +388,8 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) if (!mrb_file_is_absolute_path(home)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home"); } - } else { + } + else { return mrb_nil_value(); } home = mrb_locale_from_utf8(home, -1); @@ -391,14 +399,60 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass) #endif } +#define TIME_OVERFLOW_P(a) (sizeof(time_t) >= sizeof(mrb_int) && ((a) > MRB_INT_MAX || (a) < MRB_INT_MIN)) +#define TIME_T_UINT (~(time_t)0 > 0) +#if defined(MRB_USE_BITINT) +#define TIME_BIGTIME(mrb, a) \ + return (TIME_T_UINT ? mrb_bint_new_uint64((mrb), (uint64_t)(a)) \ + : mrb_bint_new_int64(mrb, (int64_t)(a))) +#elif !defined(MRB_NO_FLOAT) +#define TIME_BIGTIME(mrb,a) return mrb_float_value((mrb), (mrb_float)(a)) +#else +#define TIME_BIGTIME(mrb, a) mrb_raise(mrb, E_IO_ERROR, #a " overflow") +#endif + +static mrb_value +mrb_file_atime(mrb_state *mrb, mrb_value self) +{ + int fd = mrb_io_fileno(mrb, self); + mrb_stat st; + + mrb->c->ci->mid = 0; + if (mrb_fstat(fd, &st) == -1) + mrb_sys_fail(mrb, "atime"); + if (TIME_OVERFLOW_P(st.st_atime)) { + TIME_BIGTIME(mrb, st.st_atime); + } + return mrb_int_value(mrb, (mrb_int)st.st_atime); +} + +static mrb_value +mrb_file_ctime(mrb_state *mrb, mrb_value self) +{ + int fd = mrb_io_fileno(mrb, self); + mrb_stat st; + + mrb->c->ci->mid = 0; + if (mrb_fstat(fd, &st) == -1) + mrb_sys_fail(mrb, "ctime"); + if (TIME_OVERFLOW_P(st.st_ctime)) { + TIME_BIGTIME(mrb, st. st_ctime); + } + return mrb_int_value(mrb, (mrb_int)st.st_ctime); +} + static mrb_value mrb_file_mtime(mrb_state *mrb, mrb_value self) { int fd = mrb_io_fileno(mrb, self); mrb_stat st; + mrb->c->ci->mid = 0; if (mrb_fstat(fd, &st) == -1) - return mrb_false_value(); + mrb_sys_fail(mrb, "mtime"); + if (TIME_OVERFLOW_P(st.st_mtime)) { + TIME_BIGTIME(mrb, st. st_mtime); + } return mrb_int_value(mrb, (mrb_int)st.st_mtime); } @@ -567,10 +621,10 @@ mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) { mrb_get_args(mrb, "z", &path); tmp = mrb_locale_from_utf8(path, -1); - buf = (char *)mrb_malloc(mrb, bufsize); + buf = (char*)mrb_malloc(mrb, bufsize); while ((rc = readlink(tmp, buf, bufsize)) == (ssize_t)bufsize && rc != -1) { bufsize *= 2; - buf = (char *)mrb_realloc(mrb, buf, bufsize); + buf = (char*)mrb_realloc(mrb, buf, bufsize); } mrb_locale_free(tmp); if (rc == -1) { @@ -610,6 +664,8 @@ mrb_init_file(mrb_state *mrb) mrb_define_class_method(mrb, file, "_gethome", mrb_file__gethome, MRB_ARGS_OPT(1)); mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, file, "_atime", mrb_file_atime, MRB_ARGS_NONE()); + mrb_define_method(mrb, file, "_ctime", mrb_file_ctime, MRB_ARGS_NONE()); mrb_define_method(mrb, file, "_mtime", mrb_file_mtime, MRB_ARGS_NONE()); mrb_define_method(mrb, file, "size", mrb_file_size, MRB_ARGS_NONE()); mrb_define_method(mrb, file, "truncate", mrb_file_truncate, MRB_ARGS_REQ(1)); diff --git a/mruby/mrbgems/mruby-io/src/file_test.c b/mruby/mrbgems/mruby-io/src/file_test.c index f1762369..1d7aa564 100644 --- a/mruby/mrbgems/mruby-io/src/file_test.c +++ b/mruby/mrbgems/mruby-io/src/file_test.c @@ -20,7 +20,9 @@ #include #include #include +#ifndef __DJGPP__ #include +#endif #include #include #endif @@ -38,7 +40,7 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) { if (mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "IO"))) { struct mrb_io *fptr; - fptr = (struct mrb_io *)mrb_data_get_ptr(mrb, obj, &mrb_io_type); + fptr = (struct mrb_io*)mrb_data_get_ptr(mrb, obj, &mrb_io_type); if (fptr && fptr->fd >= 0) { return fstat(fptr->fd, st); @@ -52,7 +54,8 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat) int ret; if (do_lstat) { ret = LSTAT(path, st); - } else { + } + else { ret = stat(path, st); } mrb_locale_free(path); diff --git a/mruby/mrbgems/mruby-io/src/io.c b/mruby/mrbgems/mruby-io/src/io.c index ebe19930..560acde6 100644 --- a/mruby/mrbgems/mruby-io/src/io.c +++ b/mruby/mrbgems/mruby-io/src/io.c @@ -46,7 +46,11 @@ #include typedef size_t fsize_t; typedef time_t ftime_t; +#ifdef __DJGPP__ + typedef long fsuseconds_t; +#else typedef suseconds_t fsuseconds_t; +#endif typedef mode_t fmode_t; typedef ssize_t fssize_t; #endif @@ -94,7 +98,7 @@ io_get_open_fptr(mrb_state *mrb, mrb_value io) # define MRB_NO_IO_POPEN 1 #endif -#ifndef MRB_NO_IO_POEPN +#ifndef MRB_NO_IO_POPEN static void io_set_process_status(mrb_state *mrb, pid_t pid, int status) { @@ -110,7 +114,8 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status) } if (c_status != NULL) { v = mrb_funcall_id(mrb, mrb_obj_value(c_status), MRB_SYM(new), 2, mrb_fixnum_value(pid), mrb_fixnum_value(status)); - } else { + } + else { v = mrb_fixnum_value(WEXITSTATUS(status)); } mrb_gv_set(mrb, mrb_intern_lit(mrb, "$?"), v); @@ -559,10 +564,12 @@ io_s_popen(mrb_state *mrb, mrb_value klass) fd = pr[0]; close(pw[0]); write_fd = pw[1]; - } else if (OPEN_RDONLY_P(flags)) { + } + else if (OPEN_RDONLY_P(flags)) { close(pr[1]); fd = pr[0]; - } else { + } + else { close(pw[0]); fd = pw[1]; } @@ -629,10 +636,16 @@ io_init_copy(mrb_state *mrb, mrb_value copy) mrb_free(mrb, fptr_copy); } fptr_copy = (struct mrb_io*)io_alloc(mrb); + fptr_copy->pid = fptr_orig->pid; + fptr_copy->readable = fptr_orig->readable; + fptr_copy->writable = fptr_orig->writable; + fptr_copy->sync = fptr_orig->sync; + fptr_copy->is_socket = fptr_orig->is_socket; + + io_buf_init(mrb, fptr_copy); DATA_TYPE(copy) = &mrb_io_type; DATA_PTR(copy) = fptr_copy; - io_buf_init(mrb, fptr_copy); fptr_copy->fd = symdup(mrb, fptr_orig->fd, &failed); if (failed) { @@ -649,12 +662,6 @@ io_init_copy(mrb_state *mrb, mrb_value copy) io_fd_cloexec(mrb, fptr_copy->fd2); } - fptr_copy->pid = fptr_orig->pid; - fptr_copy->readable = fptr_orig->readable; - fptr_copy->writable = fptr_orig->writable; - fptr_copy->sync = fptr_orig->sync; - fptr_copy->is_socket = fptr_orig->is_socket; - return copy; } @@ -685,10 +692,8 @@ check_file_descriptor(mrb_state *mrb, mrb_int fd) } #endif /* _WIN32 */ - if (fstat(fdi, &sb) != 0) { - goto badfd; - } - + if (fstat(fdi, &sb) == 0) return; + if (errno == EBADF) goto badfd; return; badfd: @@ -705,6 +710,9 @@ io_init(mrb_state *mrb, mrb_value io) mode = opt = mrb_nil_value(); + if (mrb_block_given_p(mrb)) { + mrb_warn(mrb, "File.new() does not take block; use File.open() instead"); + } mrb_get_args(mrb, "i|oH", &fd, &mode, &opt); switch (fd) { case 0: /* STDIN_FILENO */ @@ -1278,7 +1286,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) if (mrb_nil_p(timeout)) { tp = NULL; - } else { + } + else { timerec = time2timeval(mrb, timeout); tp = &timerec; } @@ -1304,7 +1313,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) timerec.tv_sec = timerec.tv_usec = 0; tp = &timerec; } - } else { + } + else { rp = NULL; } @@ -1324,7 +1334,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) max = fptr->fd2; } } - } else { + } + else { wp = NULL; } @@ -1344,7 +1355,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) max = fptr->fd2; } } - } else { + } + else { ep = NULL; } @@ -1392,7 +1404,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]); if (FD_ISSET(fptr->fd, wp)) { mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); - } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, wp)) { + } + else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, wp)) { mrb_ary_push(mrb, list, RARRAY_PTR(write)[i]); } } @@ -1404,7 +1417,8 @@ io_s_select(mrb_state *mrb, mrb_value klass) fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]); if (FD_ISSET(fptr->fd, ep)) { mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); - } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, ep)) { + } + else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, ep)) { mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]); } } @@ -1713,7 +1727,7 @@ io_find_index(struct mrb_io *fptr, const char *rs, mrb_int rslen) mrb_assert(rslen > 0); const char c = rs[0]; - const mrb_int limit = buf->len - rslen; + const mrb_int limit = buf->len - rslen + 1; const char *p = buf->mem+buf->start; for (mrb_int i=0; i 0) { mrb_str_cat_cstr(mrb, fname, tmpdir); if (*(RSTRING_END(fname)-1) != '/') mrb_str_cat_lit(mrb, fname, "/"); - } else { + } + else { mrb_str_cat_lit(mrb, fname, "/tmp/"); } #endif @@ -142,7 +143,7 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self) sun0.sun_family = AF_UNIX; strncpy(sun0.sun_path, fnames[IDX_SOCKET], sizeof(sun0.sun_path)-1); sun0.sun_path[sizeof(sun0.sun_path)-1] = 0; - if (bind(fds[IDX_SOCKET], (struct sockaddr *)&sun0, sizeof(sun0)) == -1) { + if (bind(fds[IDX_SOCKET], (struct sockaddr*)&sun0, sizeof(sun0)) == -1) { mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d", sun0.sun_path, errno); diff --git a/mruby/mrbgems/mruby-math/src/math.c b/mruby/mrbgems/mruby-math/src/math.c index 1f6f88e8..75f0a220 100644 --- a/mruby/mrbgems/mruby-math/src/math.c +++ b/mruby/mrbgems/mruby-math/src/math.c @@ -174,6 +174,8 @@ log2(double x) #endif +#define get_float_arg(mrb) mrb_as_float((mrb), mrb_get_arg1(mrb)) + /* TRIGONOMETRIC FUNCTIONS */ @@ -188,11 +190,7 @@ log2(double x) static mrb_value math_sin(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = sin(x); - + mrb_float x = sin(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -206,11 +204,7 @@ math_sin(mrb_state *mrb, mrb_value obj) static mrb_value math_cos(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = cos(x); - + mrb_float x = cos(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -223,11 +217,7 @@ math_cos(mrb_state *mrb, mrb_value obj) static mrb_value math_tan(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = tan(x); - + mrb_float x = tan(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -245,9 +235,8 @@ math_tan(mrb_state *mrb, mrb_value obj) static mrb_value math_asin(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < -1.0 || x > 1.0) { domain_error(mrb, "asin"); } @@ -265,9 +254,8 @@ math_asin(mrb_state *mrb, mrb_value obj) static mrb_value math_acos(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < -1.0 || x > 1.0) { domain_error(mrb, "acos"); } @@ -285,11 +273,7 @@ math_acos(mrb_state *mrb, mrb_value obj) static mrb_value math_atan(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = atan(x); - + mrb_float x = atan(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -336,11 +320,7 @@ math_atan2(mrb_state *mrb, mrb_value obj) static mrb_value math_sinh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = sinh(x); - + mrb_float x = sinh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -353,11 +333,7 @@ math_sinh(mrb_state *mrb, mrb_value obj) static mrb_value math_cosh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = cosh(x); - + mrb_float x = cosh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -371,11 +347,7 @@ math_cosh(mrb_state *mrb, mrb_value obj) static mrb_value math_tanh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = tanh(x); - + mrb_float x = tanh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -393,12 +365,7 @@ math_tanh(mrb_state *mrb, mrb_value obj) static mrb_value math_asinh(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - - x = asinh(x); - + mrb_float x = asinh(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -411,9 +378,8 @@ math_asinh(mrb_state *mrb, mrb_value obj) static mrb_value math_acosh(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 1.0) { domain_error(mrb, "acosh"); } @@ -431,9 +397,8 @@ math_acosh(mrb_state *mrb, mrb_value obj) static mrb_value math_atanh(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < -1.0 || x > 1.0) { domain_error(mrb, "atanh"); } @@ -460,11 +425,7 @@ math_atanh(mrb_state *mrb, mrb_value obj) static mrb_value math_exp(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = exp(x); - + mrb_float x = exp(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -518,9 +479,8 @@ math_log(mrb_state *mrb, mrb_value obj) static mrb_value math_log2(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "log2"); } @@ -543,9 +503,8 @@ math_log2(mrb_state *mrb, mrb_value obj) static mrb_value math_log10(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "log10"); } @@ -564,9 +523,8 @@ math_log10(mrb_state *mrb, mrb_value obj) static mrb_value math_sqrt(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); - mrb_get_args(mrb, "f", &x); if (x < 0.0) { domain_error(mrb, "sqrt"); } @@ -610,11 +568,7 @@ math_sqrt(mrb_state *mrb, mrb_value obj) static mrb_value math_cbrt(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = cbrt(x); - + mrb_float x = cbrt(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -633,10 +587,9 @@ math_cbrt(mrb_state *mrb, mrb_value obj) static mrb_value math_frexp(mrb_state *mrb, mrb_value obj) { - mrb_float x; + mrb_float x = get_float_arg(mrb); int exp; - mrb_get_args(mrb, "f", &x); x = frexp(x, &exp); return mrb_assoc_new(mrb, mrb_float_value(mrb, x), mrb_fixnum_value(exp)); @@ -692,11 +645,7 @@ math_hypot(mrb_state *mrb, mrb_value obj) static mrb_value math_erf(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = erf(x); - + mrb_float x = erf(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -710,11 +659,7 @@ math_erf(mrb_state *mrb, mrb_value obj) static mrb_value math_erfc(mrb_state *mrb, mrb_value obj) { - mrb_float x; - - mrb_get_args(mrb, "f", &x); - x = erfc(x); - + mrb_float x = erfc(get_float_arg(mrb)); return mrb_float_value(mrb, x); } @@ -725,7 +670,7 @@ mrb_mruby_math_gem_init(mrb_state* mrb) struct RClass *mrb_math; mrb_math = mrb_define_module(mrb, "Math"); - mrb_define_class_under_id(mrb, mrb_math, MRB_SYM(DomainError), mrb->eStandardError_class); + mrb_define_class_under_id(mrb, mrb_math, MRB_SYM(DomainError), E_STANDARD_ERROR); #ifdef M_PI mrb_define_const_id(mrb, mrb_math, MRB_SYM(PI), mrb_float_value(mrb, M_PI)); diff --git a/mruby/mrbgems/mruby-metaprog/src/metaprog.c b/mruby/mrbgems/mruby-metaprog/src/metaprog.c index 67da9cd9..3b93574c 100644 --- a/mruby/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mruby/mrbgems/mruby-metaprog/src/metaprog.c @@ -22,8 +22,6 @@ typedef enum { NOEX_RESPONDS = 0x80 } mrb_method_flag_t; -mrb_value mrb_proc_local_variables(mrb_state *mrb, const struct RProc *proc); - static mrb_value mrb_f_nil(mrb_state *mrb, mrb_value cv) { @@ -296,7 +294,6 @@ mrb_obj_public_methods(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) { - khint_t i; mrb_value ary; struct RClass *klass; khash_t(st) *set = kh_init(st, mrb); @@ -316,7 +313,7 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) } ary = mrb_ary_new(mrb); - for (i=0;ibody.func != other_rproc->body.func) - return mrb_false_value(); + if (mrb_nil_p(orig_proc) && mrb_nil_p(other_proc) && + mrb_symbol(IV_GET(self, MRB_SYM(_name))) == mrb_symbol(IV_GET(other, MRB_SYM(_name)))) { + return mrb_true_value(); } - else { - if (MRB_PROC_CFUNC_P(other_rproc)) - return mrb_false_value(); - if (orig_rproc->body.irep != other_rproc->body.irep) - return mrb_false_value(); + if (mrb_nil_p(orig_proc) || mrb_nil_p(other_proc)) { + return mrb_false_value(); } - - return mrb_true_value(); + return mrb_bool_value(mrb_proc_eql(mrb, orig_proc, other_proc)); } #undef IV_GET @@ -429,8 +420,8 @@ method_to_s(mrb_state *mrb, mrb_value self) return str; } -static void -mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound) +static mrb_bool +search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound) { mrb_value ret; @@ -438,14 +429,14 @@ mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym *proc = method_search_vm(mrb, owner, name); if (!*proc) { if (unbound) { - goto name_error; + return FALSE; } if (!mrb_respond_to(mrb, obj, MRB_SYM_Q(respond_to_missing))) { - goto name_error; + return FALSE; } ret = mrb_funcall_id(mrb, obj, MRB_SYM_Q(respond_to_missing), 2, mrb_symbol_value(name), mrb_true_value()); if (!mrb_test(ret)) { - goto name_error; + return FALSE; } *owner = c; } @@ -453,54 +444,74 @@ mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym while ((*owner)->tt == MRB_TT_ICLASS) *owner = (*owner)->c; - return; + return TRUE; +} -name_error: - mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%n' for class '%C'", name, c); +static mrb_noreturn void +singleton_method_error(mrb_state *mrb, mrb_sym name, mrb_value obj) +{ + mrb_raisef(mrb, E_NAME_ERROR, "undefined singleton method '%n' for '%!v'", name, obj); } static mrb_value -mrb_kernel_method(mrb_state *mrb, mrb_value self) +method_alloc(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, mrb_bool unbound, mrb_bool singleton) { struct RClass *owner; struct RProc *proc; struct RObject *me; - mrb_sym name; - mrb_get_args(mrb, "n", &name); - - mrb_search_method_owner(mrb, mrb_class(mrb, self), self, name, &owner, &proc, FALSE); - - me = method_object_alloc(mrb, mrb_class_get_id(mrb, MRB_SYM(Method))); + if (!search_method_owner(mrb, c, obj, name, &owner, &proc, unbound)) { + if (singleton) { + singleton_method_error(mrb, name, obj); + } + else { + mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%n' for class '%C'", name, c); + } + } + if (singleton && owner != c) { + singleton_method_error(mrb, name, obj); + } + me = method_object_alloc(mrb, mrb_class_get_id(mrb, unbound ? MRB_SYM(UnboundMethod) : MRB_SYM(Method))); mrb_obj_iv_set(mrb, me, MRB_SYM(_owner), mrb_obj_value(owner)); - mrb_obj_iv_set(mrb, me, MRB_SYM(_recv), self); + mrb_obj_iv_set(mrb, me, MRB_SYM(_recv), unbound ? mrb_nil_value() : obj); mrb_obj_iv_set(mrb, me, MRB_SYM(_name), mrb_symbol_value(name)); mrb_obj_iv_set(mrb, me, MRB_SYM(_proc), proc ? mrb_obj_value(proc) : mrb_nil_value()); - mrb_obj_iv_set(mrb, me, MRB_SYM(_klass), mrb_obj_value(mrb_class(mrb, self))); + mrb_obj_iv_set(mrb, me, MRB_SYM(_klass), mrb_obj_value(c)); return mrb_obj_value(me); } static mrb_value -mrb_module_instance_method(mrb_state *mrb, mrb_value self) +mrb_kernel_method(mrb_state *mrb, mrb_value self) { - struct RClass *owner; - struct RProc *proc; - struct RObject *ume; mrb_sym name; mrb_get_args(mrb, "n", &name); + return method_alloc(mrb, mrb_class(mrb, self), self, name, FALSE, FALSE); +} - mrb_search_method_owner(mrb, mrb_class_ptr(self), self, name, &owner, &proc, TRUE); +static mrb_value +mrb_kernel_singleton_method(mrb_state *mrb, mrb_value self) +{ + struct RClass *c; + mrb_sym name; - ume = method_object_alloc(mrb, mrb_class_get_id(mrb, MRB_SYM(UnboundMethod))); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_owner), mrb_obj_value(owner)); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_recv), mrb_nil_value()); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_name), mrb_symbol_value(name)); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_proc), proc ? mrb_obj_value(proc) : mrb_nil_value()); - mrb_obj_iv_set(mrb, ume, MRB_SYM(_klass), self); + mrb_get_args(mrb, "n", &name); - return mrb_obj_value(ume); + c = mrb_class(mrb, self); + if (c->tt != MRB_TT_SCLASS) { + singleton_method_error(mrb, name, self); + } + return method_alloc(mrb, c, self, name, FALSE, TRUE); +} + +static mrb_value +mrb_module_instance_method(mrb_state *mrb, mrb_value self) +{ + mrb_sym name; + + mrb_get_args(mrb, "n", &name); + return method_alloc(mrb, mrb_class_ptr(self), self, name, TRUE, FALSE); } static mrb_value @@ -527,6 +538,7 @@ mrb_mruby_method_gem_init(mrb_state* mrb) struct RClass *unbound_method = mrb_define_class_id(mrb, MRB_SYM(UnboundMethod), mrb->object_class); struct RClass *method = mrb_define_class_id(mrb, MRB_SYM(Method), mrb->object_class); + MRB_SET_INSTANCE_TT(unbound_method, MRB_TT_UNDEF); mrb_undef_class_method(mrb, unbound_method, "new"); mrb_define_method(mrb, unbound_method, "bind", unbound_method_bind, MRB_ARGS_REQ(1)); mrb_define_method(mrb, unbound_method, "super_method", method_super_method, MRB_ARGS_NONE()); @@ -541,6 +553,7 @@ mrb_mruby_method_gem_init(mrb_state* mrb) mrb_define_method(mrb, unbound_method, "owner", method_owner, MRB_ARGS_NONE()); mrb_define_method(mrb, unbound_method, "name", method_name, MRB_ARGS_NONE()); + MRB_SET_INSTANCE_TT(method, MRB_TT_UNDEF); mrb_undef_class_method(mrb, method, "new"); mrb_define_method(mrb, method, "==", method_eql, MRB_ARGS_REQ(1)); mrb_define_method(mrb, method, "eql?", method_eql, MRB_ARGS_REQ(1)); @@ -558,6 +571,7 @@ mrb_mruby_method_gem_init(mrb_state* mrb) mrb_define_method(mrb, method, "name", method_name, MRB_ARGS_NONE()); mrb_define_method(mrb, mrb->kernel_module, "method", mrb_kernel_method, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "singleton_method", mrb_kernel_singleton_method, MRB_ARGS_REQ(1)); mrb_define_method(mrb, mrb->module_class, "instance_method", mrb_module_instance_method, MRB_ARGS_REQ(1)); } diff --git a/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 5fa4e5fb..4833f05f 100644 --- a/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -59,29 +59,36 @@ mrb_value mrb_int_pow(mrb_state *mrb, mrb_value x, mrb_value y); static mrb_value int_powm(mrb_state *mrb, mrb_value x) { - mrb_value m; - mrb_int e, exp, mod, result = 1; + mrb_value m, e; + mrb_int exp, mod, result = 1; if (mrb_get_argc(mrb) == 1) { return mrb_int_pow(mrb, x, mrb_get_arg1(mrb)); } - mrb_get_args(mrb, "io", &e, &m); - if (e < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); + mrb_get_args(mrb, "oo", &e, &m); + if (!mrb_integer_p(e) +#ifdef MRB_USE_BIGINT + && !mrb_bigint_p(e) +#endif + ) { + mrb_raise(mrb, E_TYPE_ERROR, "int.pow(n,m): 2nd argument not allowed unless 1st argument is an integer"); + } #ifdef MRB_USE_BIGINT if (mrb_bigint_p(x)) { return mrb_bint_powm(mrb, x, e, m); } - if (mrb_bigint_p(m)) { + if (mrb_bigint_p(e) || mrb_bigint_p(m)) { return mrb_bint_powm(mrb, mrb_bint_new_int(mrb, mrb_integer(x)), e, m); } #endif + exp = mrb_integer(e); + if (exp < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): n must be positive"); if (!mrb_integer_p(m)) mrb_raise(mrb, E_TYPE_ERROR, "int.pow(n,m): m must be integer"); mod = mrb_integer(m); if (mod < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "int.pow(n,m): m must be positive when 2nd argument specified"); if (mod == 0) mrb_int_zerodiv(mrb); if (mod == 1) return mrb_fixnum_value(0); mrb_int base = mrb_integer(x); - exp = e; for (;;) { mrb_int tmp; if (exp & 1) { @@ -211,30 +218,30 @@ flo_remainder(mrb_state *mrb, mrb_value self) void mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) { - struct RClass *i = mrb->integer_class; + struct RClass *ic = mrb->integer_class; - mrb_define_alias(mrb, i, "modulo", "%"); - mrb_define_method(mrb, i, "remainder", int_remainder, MRB_ARGS_REQ(1)); + mrb_define_alias(mrb, ic, "modulo", "%"); + mrb_define_method(mrb, ic, "remainder", int_remainder, MRB_ARGS_REQ(1)); - mrb_define_method_id(mrb, i, MRB_SYM(pow), int_powm, MRB_ARGS_ARG(1,1)); - mrb_define_method_id(mrb, i, MRB_SYM(digits), int_digits, MRB_ARGS_OPT(1)); + mrb_define_method_id(mrb, ic, MRB_SYM(pow), int_powm, MRB_ARGS_ARG(1,1)); + mrb_define_method_id(mrb, ic, MRB_SYM(digits), int_digits, MRB_ARGS_OPT(1)); #ifndef MRB_NO_FLOAT - struct RClass *f = mrb->float_class; - - 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)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(DIG), mrb_fixnum_value(MRB_FLT_DIG)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MIN_EXP), mrb_fixnum_value(MRB_FLT_MIN_EXP)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MIN), mrb_float_value(mrb, MRB_FLT_MIN)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MIN_10_EXP), mrb_fixnum_value(MRB_FLT_MIN_10_EXP)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MAX_EXP), mrb_fixnum_value(MRB_FLT_MAX_EXP)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MAX), mrb_float_value(mrb, MRB_FLT_MAX)); - mrb_define_const_id(mrb, mrb->float_class, MRB_SYM(MAX_10_EXP), mrb_fixnum_value(MRB_FLT_MAX_10_EXP)); + struct RClass *fc = mrb->float_class; + + mrb_define_alias(mrb, fc, "modulo", "%"); + mrb_define_method(mrb, fc, "remainder", flo_remainder, MRB_ARGS_REQ(1)); + + mrb_define_const_id(mrb, fc, MRB_SYM(RADIX), mrb_fixnum_value(MRB_FLT_RADIX)); + mrb_define_const_id(mrb, fc, MRB_SYM(MANT_DIG), mrb_fixnum_value(MRB_FLT_MANT_DIG)); + mrb_define_const_id(mrb, fc, MRB_SYM(EPSILON), mrb_float_value(mrb, MRB_FLT_EPSILON)); + mrb_define_const_id(mrb, fc, MRB_SYM(DIG), mrb_fixnum_value(MRB_FLT_DIG)); + mrb_define_const_id(mrb, fc, MRB_SYM(MIN_EXP), mrb_fixnum_value(MRB_FLT_MIN_EXP)); + mrb_define_const_id(mrb, fc, MRB_SYM(MIN), mrb_float_value(mrb, MRB_FLT_MIN)); + mrb_define_const_id(mrb, fc, MRB_SYM(MIN_10_EXP), mrb_fixnum_value(MRB_FLT_MIN_10_EXP)); + mrb_define_const_id(mrb, fc, MRB_SYM(MAX_EXP), mrb_fixnum_value(MRB_FLT_MAX_EXP)); + mrb_define_const_id(mrb, fc, MRB_SYM(MAX), mrb_float_value(mrb, MRB_FLT_MAX)); + mrb_define_const_id(mrb, fc, MRB_SYM(MAX_10_EXP), mrb_fixnum_value(MRB_FLT_MAX_10_EXP)); #endif /* MRB_NO_FLOAT */ } diff --git a/mruby/mrbgems/mruby-object-ext/src/object.c b/mruby/mrbgems/mruby-object-ext/src/object.c index 69f1763c..f0b50bf1 100644 --- a/mruby/mrbgems/mruby-object-ext/src/object.c +++ b/mruby/mrbgems/mruby-object-ext/src/object.c @@ -70,7 +70,7 @@ nil_to_i(mrb_state *mrb, mrb_value obj) * */ static mrb_value -mrb_f_itself(mrb_state *mrb, mrb_value self) +f_itself(mrb_state *mrb, mrb_value self) { return self; } @@ -94,7 +94,7 @@ mrb_f_itself(mrb_state *mrb, mrb_value self) */ static mrb_value -mrb_obj_instance_exec(mrb_state *mrb, mrb_value self) +obj_instance_exec(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc; @@ -122,9 +122,9 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, n, "to_h", nil_to_h, MRB_ARGS_NONE()); mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE()); - mrb_define_method(mrb, mrb->kernel_module, "itself", mrb_f_itself, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->kernel_module, "itself", f_itself, MRB_ARGS_NONE()); - mrb_define_method(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), "instance_exec", obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); } void diff --git a/mruby/mrbgems/mruby-os-memsize/src/memsize.c b/mruby/mrbgems/mruby-os-memsize/src/memsize.c index b95515cc..10f77bee 100644 --- a/mruby/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mruby/mrbgems/mruby-os-memsize/src/memsize.c @@ -16,13 +16,24 @@ static size_t os_memsize_of_irep(mrb_state* state, const struct mrb_irep *irep) { size_t size; - int i; size = (irep->slen * sizeof(mrb_sym)) + - (irep->plen * sizeof(mrb_code)) + - (irep->ilen * sizeof(mrb_code)); + (irep->plen * sizeof(mrb_pool_value)) + + (irep->ilen * sizeof(mrb_code)) + + (irep->rlen * sizeof(struct mrb_irep*)); - for(i = 0; i < irep->rlen; i++) { + for (int i = 0; i < irep->plen; i++) { + const mrb_pool_value *p = &irep->pool[i]; + if ((p->tt & IREP_TT_NFLAG) == 0) { /* string pool value */ + size += (p->tt>>2); + } + else if (p->tt == IREP_TT_BIGINT) { /* bigint pool value */ + size += p->u.str[0]; + } + } + + for (int i = 0; i < irep->rlen; i++) { + size += sizeof(struct mrb_irep); /* size of irep structure */ size += os_memsize_of_irep(state, irep->reps[i]); } return size; @@ -72,7 +83,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) case MRB_TT_MODULE: case MRB_TT_SCLASS: case MRB_TT_ICLASS: - size += mrb_gc_mark_mt_size(mrb, mrb_class_ptr(obj)) * sizeof(mrb_method_t); + size += mrb_class_mt_memsize(mrb, mrb_class_ptr(obj)); /* fall through */ case MRB_TT_EXCEPTION: case MRB_TT_OBJECT: { @@ -95,14 +106,16 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) /* Arrays that do not fit within an RArray perform a heap allocation * storing an array of pointers to the original objects*/ size += mrb_objspace_page_slot_size(); - if(len > MRB_ARY_EMBED_LEN_MAX) size += sizeof(mrb_value *) * len; + if (len > MRB_ARY_EMBED_LEN_MAX) + size += sizeof(mrb_value*) * len; break; } case MRB_TT_PROC: { struct RProc* proc = mrb_proc_ptr(obj); size += mrb_objspace_page_slot_size(); size += MRB_ENV_LEN(proc->e.env) * sizeof(mrb_value); - if(!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep); + if (!MRB_PROC_CFUNC_P(proc)) + size += os_memsize_of_irep(mrb, proc->body.irep); break; } case MRB_TT_RANGE: @@ -112,7 +125,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) #endif break; case MRB_TT_FIBER: { - struct RFiber* f = (struct RFiber *)mrb_ptr(obj); + struct RFiber* f = (struct RFiber*)mrb_ptr(obj); ptrdiff_t stack_size = f->cxt->stend - f->cxt->stbase; ptrdiff_t ci_size = f->cxt->ciend - f->cxt->cibase; @@ -192,9 +205,7 @@ static mrb_value os_memsize_of(mrb_state *mrb, mrb_value self) { size_t total; - mrb_value obj; - - mrb_get_args(mrb, "o", &obj); + mrb_value obj = mrb_get_arg1(mrb); total = os_memsize_of_object(mrb, obj); return mrb_fixnum_value((mrb_int)total); @@ -208,7 +219,7 @@ struct os_memsize_of_all_cb_data { static int os_memsize_of_all_cb(mrb_state *mrb, struct RBasic *obj, void *d) { - struct os_memsize_of_all_cb_data *data = (struct os_memsize_of_all_cb_data *)d; + struct os_memsize_of_all_cb_data *data = (struct os_memsize_of_all_cb_data*)d; switch (obj->tt) { case MRB_TT_FREE: case MRB_TT_ENV: case MRB_TT_BREAK: case MRB_TT_ICLASS: diff --git a/mruby/mrbgems/mruby-pack/README.md b/mruby/mrbgems/mruby-pack/README.md index 712cf8e1..10a53809 100644 --- a/mruby/mrbgems/mruby-pack/README.md +++ b/mruby/mrbgems/mruby-pack/README.md @@ -16,6 +16,8 @@ There is no dependency on other mrbgems. - A : arbitrary binary string (space padded, count is width) - a : arbitrary binary string (null padded, count is width) +- B : bit string (descending) +- b : bit string (ascending) - C : 8-bit unsigned (unsigned char) - c : 8-bit signed (signed char) - D, d: 64-bit float, native format @@ -28,6 +30,8 @@ There is no dependency on other mrbgems. - h : hex string (low nibble first) - I : unsigned integer, native endian (`unsigned int` in C) - i : signed integer, native endian (`int` in C) +- J : unsigned integer, native endian (`uintptr_t` in C) +- j : signed integer, native endian (`intptr_t` 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) diff --git a/mruby/mrbgems/mruby-pack/src/pack.c b/mruby/mrbgems/mruby-pack/src/pack.c index b5ecdc64..26c2890b 100644 --- a/mruby/mrbgems/mruby-pack/src/pack.c +++ b/mruby/mrbgems/mruby-pack/src/pack.c @@ -35,17 +35,17 @@ enum pack_dir { //PACK_DIR_VAX, PACK_DIR_BER, /* w */ PACK_DIR_UTF8, /* U */ - //PACK_DIR_BER, PACK_DIR_DOUBLE, /* E */ PACK_DIR_FLOAT, /* f */ PACK_DIR_STR, /* A */ PACK_DIR_HEX, /* h */ + PACK_DIR_BSTR, /* b */ PACK_DIR_BASE64, /* m */ PACK_DIR_QENC, /* M */ PACK_DIR_NUL, /* x */ PACK_DIR_BACK, /* X */ PACK_DIR_ABS, /* @ */ - PACK_DIR_INVALID + PACK_DIR_NONE, /* - */ }; enum pack_type { @@ -123,9 +123,9 @@ static int 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)); + mrb_ary_push(mrb, ary, mrb_fixnum_value(*(signed char*)src)); else - mrb_ary_push(mrb, ary, mrb_fixnum_value(*(unsigned char *)src)); + mrb_ary_push(mrb, ary, mrb_fixnum_value(*(unsigned char*)src)); return 1; } @@ -139,7 +139,8 @@ pack_short(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in if (flags & PACK_FLAG_LITTLEENDIAN) { RSTRING_PTR(str)[sidx+0] = n % 256; RSTRING_PTR(str)[sidx+1] = n / 256; - } else { + } + else { RSTRING_PTR(str)[sidx+0] = n / 256; RSTRING_PTR(str)[sidx+1] = n % 256; } @@ -153,7 +154,8 @@ unpack_short(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary if (flags & PACK_FLAG_LITTLEENDIAN) { n = src[1] * 256 + src[0]; - } else { + } + else { n = src[0] * 256 + src[1]; } if ((flags & PACK_FLAG_SIGNED) && (n >= 0x8000)) { @@ -175,7 +177,8 @@ pack_long(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int RSTRING_PTR(str)[sidx+1] = (char)(n >> 8); RSTRING_PTR(str)[sidx+2] = (char)(n >> 16); RSTRING_PTR(str)[sidx+3] = (char)(n >> 24); - } else { + } + else { RSTRING_PTR(str)[sidx+0] = (char)(n >> 24); RSTRING_PTR(str)[sidx+1] = (char)(n >> 16); RSTRING_PTR(str)[sidx+2] = (char)(n >> 8); @@ -231,7 +234,8 @@ unpack_long(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, ul += (uint32_t)src[2] *256*256; ul += (uint32_t)src[1] *256; ul += (uint32_t)src[0]; - } else { + } + else { ul = (uint32_t)src[0] * 256*256*256; ul += (uint32_t)src[1] *256*256; ul += (uint32_t)src[2] *256; @@ -239,7 +243,8 @@ unpack_long(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, } if (flags & PACK_FLAG_SIGNED) { n = (int32_t)ul; - } else { + } + else { #ifndef MRB_INT64 if (UINT_OVERFLOW_P(ul)) { u32tostr(msg, sizeof(msg), ul); @@ -268,7 +273,8 @@ pack_quad(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned int RSTRING_PTR(str)[sidx+5] = (char)(n >> 40); RSTRING_PTR(str)[sidx+6] = (char)(n >> 48); RSTRING_PTR(str)[sidx+7] = (char)(n >> 56); - } else { + } + else { RSTRING_PTR(str)[sidx+0] = (char)(n >> 56); RSTRING_PTR(str)[sidx+1] = (char)(n >> 48); RSTRING_PTR(str)[sidx+2] = (char)(n >> 40); @@ -345,7 +351,8 @@ unpack_quad(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, if (flags & PACK_FLAG_LITTLEENDIAN) { pos = 7; step = -1; - } else { + } + else { pos = 0; step = 1; } @@ -363,7 +370,8 @@ unpack_quad(mrb_state *mrb, const unsigned char *src, int srclen, mrb_value ary, } #endif n = (mrb_int)sll; - } else { + } + else { if (UINT_OVERFLOW_P(ull)) { u64tostr(msg, sizeof(msg), ull); mrb_raisef(mrb, E_RANGE_ERROR, "cannot unpack to Integer: %s", msg); @@ -425,7 +433,7 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i { int i; double d; - uint8_t *buffer = (uint8_t *)&d; + uint8_t *buffer = (uint8_t*)&d; str = str_len_ensure(mrb, str, sidx + 8); d = mrb_float(o); @@ -438,7 +446,8 @@ pack_double(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned i RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 8; i++) { RSTRING_PTR(str)[sidx + i] = buffer[8 - i - 1]; @@ -457,7 +466,7 @@ unpack_double(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value a { int i; double d; - uint8_t *buffer = (uint8_t *)&d; + uint8_t *buffer = (uint8_t*)&d; if (flags & PACK_FLAG_LITTLEENDIAN) { if (littleendian) { @@ -468,7 +477,8 @@ unpack_double(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value a buffer[8 - i - 1] = src[i]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 8; i++) { buffer[8 - i - 1] = src[i]; @@ -488,7 +498,7 @@ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in { int i; float f; - uint8_t *buffer = (uint8_t *)&f; + uint8_t *buffer = (uint8_t*)&f; str = str_len_ensure(mrb, str, sidx + 4); f = (float)mrb_float(o); @@ -501,7 +511,8 @@ pack_float(mrb_state *mrb, mrb_value o, mrb_value str, mrb_int sidx, unsigned in RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 4; i++) { RSTRING_PTR(str)[sidx + i] = buffer[4 - i - 1]; @@ -520,7 +531,7 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar { int i; float f; - uint8_t *buffer = (uint8_t *)&f; + uint8_t *buffer = (uint8_t*)&f; if (flags & PACK_FLAG_LITTLEENDIAN) { if (littleendian) { @@ -531,7 +542,8 @@ unpack_float(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ar buffer[4 - i - 1] = src[i]; } } - } else { + } + else { if (littleendian) { for (i = 0; i < 4; i++) { buffer[4 - i - 1] = src[i]; @@ -660,7 +672,7 @@ unpack_utf8(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary if (srclen == 0) { return 1; } - uv = utf8_to_uv(mrb, (const char *)src, &lenp); + uv = utf8_to_uv(mrb, (const char*)src, &lenp); mrb_ary_push(mrb, ary, mrb_fixnum_value((mrb_int)uv)); return (int)lenp; } @@ -681,13 +693,16 @@ pack_str(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, if (count == 0) { return 0; - } else if (count == -1) { + } + else if (count == -1) { copylen = slen; padlen = (flags & PACK_FLAG_Z) ? 1 : 0; - } else if (count < slen) { + } + else if (count < slen) { copylen = count; padlen = 0; - } else { + } + else { copylen = slen; padlen = count - slen; } @@ -719,14 +734,14 @@ unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, const char *cp, *sptr; int copylen; - sptr = (const char *)src; + sptr = (const char*)src; if (count != -1 && count < slen) { slen = count; } copylen = slen; if (slen >= 0 && flags & PACK_FLAG_Z) { /* "Z" */ - if ((cp = (const char *)memchr(sptr, '\0', slen)) != NULL) { + if ((cp = (const char*)memchr(sptr, '\0', slen)) != NULL) { copylen = (int)(cp - sptr); if (count == -1) { slen = copylen + 1; @@ -760,14 +775,16 @@ pack_hex(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, if (flags & PACK_FLAG_LSB) { ashift = 0; bshift = 4; - } else { + } + else { ashift = 4; bshift = 0; } if (count == -1) { count = slen; - } else if (slen > count) { + } + else if (slen > count) { slen = count; } @@ -807,12 +824,13 @@ unpack_hex(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, if (flags & PACK_FLAG_LSB) { ashift = 0; bshift = 4; - } else { + } + else { ashift = 4; bshift = 0; } - sptr = (const char *)src; + sptr = (const char*)src; if (count == -1) count = slen * 2; @@ -842,6 +860,92 @@ unpack_hex(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, return (int)(sptr - sptr0); } +static int +pack_bstr(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags) +{ + const char *sptr = RSTRING_PTR(src); + int slen = (int)RSTRING_LEN(src); + + if (count == -1) { + count = slen; + } + else if (slen > count) { + slen = count; + } + + dst = str_len_ensure(mrb, dst, didx + count); + char *dptr = RSTRING_PTR(dst) + didx; + char *dptr0 = dptr; + + unsigned int byte = 0; + for (int i=0; i++ < slen; sptr++) { + if (flags & PACK_FLAG_LSB) { + if (*sptr & 1) + byte |= 128; + if (i & 7) + byte >>= 1; + else { + char c = (char)(byte&0xff); + *dptr++ = c; + byte = 0; + } + } + else { + byte |= *sptr & 1; + if (i & 7) + byte <<= 1; + else { + char c = (char)(byte&0xff); + *dptr++ = c; + byte = 0; + } + } + } + if (slen & 7) { + if (flags & PACK_FLAG_LSB) { + byte >>= 7 - (slen & 7); + } + else { + byte <<= 7 - (slen & 7); + } + char c = (char)(byte&0xff); + *dptr++ = c; + } + return (int)(dptr - dptr0); +} + +static int +unpack_bstr(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, unsigned int flags) +{ + CHECK_UNPACK_LEN(mrb, slen, ary); + + const char *sptr0 = (const char*)src; + const char *sptr = sptr0; + if (count == -1) + count = slen * 8; + + mrb_value dst = mrb_str_new(mrb, NULL, count); + char *dptr = RSTRING_PTR(dst); + const char *dptr0 = dptr; + int bits = 0; + + for (int i=0; i>= 1; + else bits = (unsigned char)*sptr++; + *dptr++ = (bits & 1) ? '1' : '0'; + } + else { + if (i & 7) bits <<= 1; + else bits = (unsigned char)*sptr++; + *dptr++ = (bits & 128) ? '1' : '0'; + } + } + dst = mrb_str_resize(mrb, dst, (mrb_int)(dptr - dptr0)); + mrb_ary_push(mrb, ary, dst); + return (int)(sptr - sptr0); +} + static int pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count) { @@ -858,7 +962,8 @@ pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int coun if (count != 0 && count < 3) { /* -1, 1 or 2 */ count = 45; - } else if (count >= 3) { + } + else if (count >= 3) { count -= count % 3; } @@ -892,7 +997,8 @@ pack_base64(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int coun *dstptr++ = '='; *dstptr++ = '='; column += 3; - } else if (srclen == 2) { + } + else if (srclen == 2) { l = (unsigned char)*srcptr++ << 16; l += (unsigned char)*srcptr++ << 8; *dstptr++ = base64chars[(l >> 18) & 0x3f]; @@ -921,7 +1027,7 @@ unpack_base64(mrb_state *mrb, const void *src, int slen, mrb_value ary) const char *sptr, *sptr0; char *dptr, *dptr0; - sptr0 = sptr = (const char *)src; + sptr0 = sptr = (const char*)src; dlen = slen / 4 * 3; /* an estimated value - may be shorter */ dst = mrb_str_new(mrb, NULL, dlen); @@ -950,11 +1056,13 @@ unpack_base64(mrb_state *mrb, const void *src, int slen, mrb_value ary) *dptr++ = (l >> 16) & 0xff; *dptr++ = (l >> 8) & 0xff; *dptr++ = l & 0xff; - } else if (padding == 1) { + } + else if (padding == 1) { *dptr++ = (l >> 16) & 0xff; *dptr++ = (l >> 8) & 0xff; break; - } else { + } + else { *dptr++ = (l >> 16) & 0xff; break; } @@ -1095,8 +1203,8 @@ has_tmpl(const struct tmpl *tmpl) return (tmpl->idx < RSTRING_LEN(tmpl->str)); } -static void -read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type *typep, int *sizep, int *countp, unsigned int *flagsp) +static enum pack_dir +read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_type *typep, int *sizep, int *countp, unsigned int *flagsp) { mrb_int t, tlen; int ch, size = 0; @@ -1109,8 +1217,10 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type tptr = RSTRING_PTR(tmpl->str); tlen = RSTRING_LEN(tmpl->str); + restart: + if (tmpl->idx >= tlen) return PACK_DIR_NONE; t = tptr[tmpl->idx++]; -alias: + alias: switch (t) { case 'A': dir = PACK_DIR_STR; @@ -1179,6 +1289,16 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type type = PACK_TYPE_STRING; flags |= PACK_FLAG_COUNT2 | PACK_FLAG_LSB; break; + case 'B': + dir = PACK_DIR_BSTR; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_COUNT2; + break; + case 'b': + dir = PACK_DIR_BSTR; + type = PACK_TYPE_STRING; + flags |= PACK_FLAG_COUNT2 | PACK_FLAG_LSB; + break; case 'I': switch (sizeof(int)) { case 2: t = 'S'; goto alias; @@ -1197,6 +1317,22 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(int) == %d", (int)sizeof(int)); } break; + case 'J': + switch (sizeof(intptr_t)) { + case 4: t = 'L'; goto alias; + case 8: t = 'Q'; goto alias; + default: + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(uintptr_t) == %d", (int)sizeof(uintptr_t)); + } + break; + case 'j': + switch (sizeof(intptr_t)) { + case 4: t = 'l'; goto alias; + case 8: t = 'q'; goto alias; + default: + mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-pack does not support sizeof(intptr_t) == %d", (int)sizeof(intptr_t)); + } + break; case 'L': dir = PACK_DIR_LONG; type = PACK_TYPE_INTEGER; @@ -1290,14 +1426,22 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type type = PACK_TYPE_STRING; flags |= PACK_FLAG_WIDTH | PACK_FLAG_COUNT2 | PACK_FLAG_Z; break; + case '#': + while (++tmpl->idx < tlen && tptr[tmpl->idx] != '\n') + ; + goto restart; + 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; - break; + if (!ISSPACE((char)t)) { + char c = (char)t; + mrb_value s = mrb_str_new(mrb, &c, 1); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown unpack directive %!v", s); + } + goto restart; } /* read suffix [0-9*_!<>] */ @@ -1312,20 +1456,24 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type count = (int)n; tmpl->idx = (int)(e - tptr); continue; - } else if (ch == '*') { + } + else if (ch == '*') { if (type == PACK_TYPE_NONE) count = 0; else count = -1; - } else if (ch == '_' || ch == '!' || ch == '<' || ch == '>') { + } + 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); } if (ch == '_' || ch == '!') { flags |= PACK_FLAG_s; - } else if (ch == '<') { + } + else if (ch == '<') { flags |= PACK_FLAG_LT; - } else if (ch == '>') { + } + else if (ch == '>') { flags |= PACK_FLAG_GT; } } @@ -1339,11 +1487,11 @@ read_tmpl(mrb_state *mrb, struct tmpl *tmpl, enum pack_dir *dirp, enum pack_type flags |= PACK_FLAG_LITTLEENDIAN; } - *dirp = dir; *typep = type; *sizep = size; *countp = count; *flagsp = flags; + return dir; } static mrb_value @@ -1364,11 +1512,10 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) aidx = 0; ridx = 0; while (has_tmpl(&tmpl)) { - read_tmpl(mrb, &tmpl, &dir, &type, &size, &count, &flags); + dir = read_tmpl(mrb, &tmpl, &type, &size, &count, &flags); - if (dir == PACK_DIR_INVALID) - continue; - else if (dir == PACK_DIR_NUL) { + if (dir == PACK_DIR_NONE) break; + if (dir == PACK_DIR_NUL) { grow: if (ridx > INT_MAX - count) goto overflow; ridx += pack_nul(mrb, result, ridx, count); @@ -1395,7 +1542,7 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) if (count == 0 && !(flags & PACK_FLAG_WIDTH)) break; - o = mrb_ary_ref(mrb, ary, aidx); + o = RARRAY_PTR(ary)[aidx]; if (type == PACK_TYPE_INTEGER) { o = mrb_ensure_int_type(mrb, o); } @@ -1437,6 +1584,9 @@ mrb_pack_pack(mrb_state *mrb, mrb_value ary) case PACK_DIR_HEX: ridx += pack_hex(mrb, o, result, ridx, count, flags); break; + case PACK_DIR_BSTR: + ridx += pack_bstr(mrb, o, result, ridx, count, flags); + break; case PACK_DIR_STR: ridx += pack_str(mrb, o, result, ridx, count, flags); break; @@ -1493,11 +1643,10 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) result = mrb_ary_new(mrb); while (has_tmpl(&tmpl)) { - read_tmpl(mrb, &tmpl, &dir, &type, &size, &count, &flags); + dir = read_tmpl(mrb, &tmpl, &type, &size, &count, &flags); - if (dir == PACK_DIR_INVALID) - continue; - else if (dir == PACK_DIR_NUL) { + if (dir == PACK_DIR_NONE) break; + if (dir == PACK_DIR_NUL) { check_x(mrb, srclen-srcidx, count, 'x'); srcidx += count; continue; @@ -1514,11 +1663,14 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) } /* PACK_FLAG_COUNT2 directions */ - sptr = (const unsigned char *)RSTRING_PTR(str) + srcidx; + 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_BSTR: + srcidx += unpack_bstr(mrb, sptr, srclen - srcidx, result, count, flags); + continue; case PACK_DIR_STR: srcidx += unpack_str(mrb, sptr, srclen - srcidx, result, count, flags); continue; diff --git a/mruby/mrbgems/mruby-pack/test/pack.rb b/mruby/mrbgems/mruby-pack/test/pack.rb index 4dd7f4a9..6045f788 100644 --- a/mruby/mrbgems/mruby-pack/test/pack.rb +++ b/mruby/mrbgems/mruby-pack/test/pack.rb @@ -38,6 +38,16 @@ def assert_pack tmpl, packed, unpacked assert_equal ["あ"], "=E3=81=82=\n".unpack("M") end +# pack & unpack 'B'/'b' +assert('pack("B/b")') do + assert_pack "b*", "\xFF\x00", ["1111111100000000"] + assert_pack "b*", "\x01\x02", ["1000000001000000"] + assert_pack "b3", "\x01", ["100"] + + assert_pack "B*", "\xFF\x00", ["1111111100000000"] + assert_pack "B*", "\x01\x02", ["0000000100000010"] +end + # pack & unpack 'H' assert('pack("H")') do assert_pack "H*", "01", ["3031"] diff --git a/mruby/mrbgems/mruby-print/mrblib/print.rb b/mruby/mrbgems/mruby-print/mrblib/print.rb index a8a23ea9..9047f5e8 100644 --- a/mruby/mrbgems/mruby-print/mrblib/print.rb +++ b/mruby/mrbgems/mruby-print/mrblib/print.rb @@ -6,32 +6,20 @@ module Kernel ## # Print human readable object description # - # ISO 15.3.1.2.9 - # ISO 15.3.1.3.34 + # ISO 15.3.1.2.9 Kernel.p + # ISO 15.3.1.3.34 Kernel#p def p(*args) i = 0 len = args.size while i < len - __printstr__ args[i].inspect - __printstr__ "\n" + print args[i].inspect, "\n" i += 1 end args.__svalue end - # 15.3.1.2.10 - # 15.3.1.3.35 - def print(*args) - i = 0 - len = args.size - while i < len - __printstr__ args[i].to_s - i += 1 - end - end - - # 15.3.1.2.11 - # 15.3.1.3.39 + # ISO 15.3.1.2.11 Kernel.puts + # ISO 15.3.1.3.39 Kernel#puts def puts(*args) i = 0 len = args.size @@ -41,15 +29,15 @@ def puts(*args) puts(*s) else s = s.to_s - __printstr__ s - __printstr__ "\n" if (s[-1] != "\n") + print s + print "\n" if (s[-1] != "\n") end i += 1 end - __printstr__ "\n" if len == 0 + print "\n" if len == 0 end def printf(*args) - __printstr__(sprintf(*args)) + print(sprintf(*args)) end end diff --git a/mruby/mrbgems/mruby-print/src/print.c b/mruby/mrbgems/mruby-print/src/print.c index f6d6d46f..94cab36e 100644 --- a/mruby/mrbgems/mruby-print/src/print.c +++ b/mruby/mrbgems/mruby-print/src/print.c @@ -13,13 +13,13 @@ # define isatty(x) _isatty(x) # define fileno(x) _fileno(x) #endif +#else +# include #endif -static mrb_value -mrb_printstr(mrb_state *mrb, mrb_value self) +static void +printstr(mrb_state *mrb, mrb_value s) { - mrb_value s = mrb_get_arg1(mrb); - if (mrb_string_p(s)) { const char *p = RSTRING_PTR(s); mrb_int len = RSTRING_LEN(s); @@ -35,21 +35,33 @@ mrb_printstr(mrb_state *mrb, mrb_value self) utf16, (DWORD)wlen, &written, NULL); } mrb_free(mrb, utf16); + return; } - else #endif - { - fwrite(p, (size_t)len, 1, stdout); - } - fflush(stdout); + fwrite(p, (size_t)len, 1, stdout); + } +} + +// ISO 15.3.1.2.10 Kernel.print +// ISO 15.3.1.3.35 Kernel#print +static mrb_value +mrb_print(mrb_state *mrb, mrb_value self) +{ + mrb_int argc = mrb_get_argc(mrb); + const mrb_value *argv = mrb_get_argv(mrb); + + for (mrb_int i=0; ikernel_module, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "print", mrb_print, MRB_ARGS_ANY()); /* 15.3.1.3.35 */ } void diff --git a/mruby/mrbgems/mruby-proc-binding/mrbgem.rake b/mruby/mrbgems/mruby-proc-binding/mrbgem.rake index 4aa88297..53e6faae 100644 --- a/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +++ b/mruby/mrbgems/mruby-proc-binding/mrbgem.rake @@ -3,8 +3,8 @@ MRuby::Gem::Specification.new('mruby-proc-binding') do |spec| spec.author = 'mruby developers' spec.summary = 'Proc#binding method' - spec.add_dependency('mruby-binding-core', :core => 'mruby-binding-core') + spec.add_dependency('mruby-binding', :core => 'mruby-binding') spec.add_dependency('mruby-proc-ext', :core => 'mruby-proc-ext') - spec.add_test_dependency('mruby-binding', :core => 'mruby-binding') + spec.add_test_dependency('mruby-eval', :core => 'mruby-eval') spec.add_test_dependency('mruby-compiler', :core => 'mruby-compiler') end diff --git a/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c b/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c index d176034d..f513dafd 100644 --- a/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c +++ b/mruby/mrbgems/mruby-proc-binding/src/proc-binding.c @@ -6,14 +6,12 @@ /* provided by mruby-proc-ext */ mrb_value mrb_proc_source_location(mrb_state *mrb, struct RProc *p); -/* provided by mruby-binding-core */ -mrb_value mrb_binding_alloc(mrb_state *mrb); -struct RProc *mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv **envp); +/* provided by mruby-binding */ +mrb_value mrb_binding_new(mrb_state *mrb, const struct RProc *proc, mrb_value recv, struct REnv *env); static mrb_value mrb_proc_binding(mrb_state *mrb, mrb_value procval) { - mrb_value binding = mrb_binding_alloc(mrb); const struct RProc *proc = mrb_proc_ptr(procval); struct REnv *env; @@ -30,10 +28,7 @@ mrb_proc_binding(mrb_state *mrb, mrb_value procval) receiver = MRB_ENV_LEN(env) > 0 ? env->stack[0] : mrb_nil_value(); } - proc = mrb_binding_wrap_lvspace(mrb, proc, &env); - mrb_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value((void *)proc)); - mrb_iv_set(mrb, binding, MRB_SYM(recv), receiver); - mrb_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); + mrb_value binding = mrb_binding_new(mrb, proc, receiver, env); mrb_iv_set(mrb, binding, MRB_SYM(source_location), mrb_proc_source_location(mrb, mrb_proc_ptr(procval))); return binding; } diff --git a/mruby/mrbgems/mruby-proc-ext/src/proc.c b/mruby/mrbgems/mruby-proc-ext/src/proc.c index 4e90371c..8713e8bb 100644 --- a/mruby/mrbgems/mruby-proc-ext/src/proc.c +++ b/mruby/mrbgems/mruby-proc-ext/src/proc.c @@ -7,7 +7,7 @@ #include static mrb_value -mrb_proc_lambda_p(mrb_state *mrb, mrb_value self) +proc_lambda_p(mrb_state *mrb, mrb_value self) { struct RProc *p = mrb_proc_ptr(self); return mrb_bool_value(MRB_PROC_STRICT_P(p)); @@ -24,22 +24,21 @@ mrb_proc_source_location(mrb_state *mrb, struct RProc *p) int32_t line; const char *filename; - filename = mrb_debug_get_filename(mrb, irep, 0); - line = mrb_debug_get_line(mrb, irep, 0); - - return (!filename && line == -1)? mrb_nil_value() - : mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line)); + if (!mrb_debug_get_position(mrb, irep, 0, &line, &filename)) { + return mrb_nil_value(); + } + return mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line)); } } static mrb_value -mrb_proc_source_location_m(mrb_state *mrb, mrb_value self) +proc_source_location(mrb_state *mrb, mrb_value self) { return mrb_proc_source_location(mrb, mrb_proc_ptr(self)); } static mrb_value -mrb_proc_inspect(mrb_state *mrb, mrb_value self) +proc_inspect(mrb_state *mrb, mrb_value self) { struct RProc *p = mrb_proc_ptr(self); mrb_value str = mrb_str_new_lit(mrb, "#proc_class; - mrb_define_method(mrb, p, "lambda?", mrb_proc_lambda_p, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "source_location", mrb_proc_source_location_m, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "to_s", mrb_proc_inspect, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "inspect", mrb_proc_inspect, MRB_ARGS_NONE()); - mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); - - mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); - mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, p, "lambda?", proc_lambda_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "source_location", proc_source_location, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "to_s", proc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "inspect", proc_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); + + mrb_define_method(mrb, mrb->kernel_module, "proc", kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); } void diff --git a/mruby/mrbgems/mruby-proc-ext/test/proc.rb b/mruby/mrbgems/mruby-proc-ext/test/proc.rb index 7ac50840..13e7058f 100644 --- a/mruby/mrbgems/mruby-proc-ext/test/proc.rb +++ b/mruby/mrbgems/mruby-proc-ext/test/proc.rb @@ -7,8 +7,8 @@ def enable_debug_info? raise rescue => e @enable_debug_info = !e.backtrace.empty? - if(@enable_debug_info && e.backtrace[0].include?("(unknown)")) - @enable_debug_info = false + if @enable_debug_info && e.backtrace[0].include?("(unknown)") + @enable_debug_info = false end return @enable_debug_info end diff --git a/mruby/mrbgems/mruby-random/src/random.c b/mruby/mrbgems/mruby-random/src/random.c index d16ef332..c47702e9 100644 --- a/mruby/mrbgems/mruby-random/src/random.c +++ b/mruby/mrbgems/mruby-random/src/random.c @@ -222,8 +222,7 @@ 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_int i = mrb_as_int(mrb, mrb_get_arg1(mrb)); mrb_value bytes = mrb_str_new(mrb, NULL, i); uint8_t *p = (uint8_t*)RSTRING_PTR(bytes); diff --git a/mruby/mrbgems/mruby-range-ext/mrblib/range.rb b/mruby/mrbgems/mruby-range-ext/mrblib/range.rb index 8b670afe..e229c918 100644 --- a/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +++ b/mruby/mrbgems/mruby-range-ext/mrblib/range.rb @@ -96,4 +96,12 @@ def min(&block) # delegate to Enumerable super() end + + # Compare two ranges and see if they overlap each other + # (1..5).overlap?(4..6) # => true + # (1..5).overlap?(7..9) # => false + def overlap?(other) + raise TypeError, "argument must be a range" unless other.kind_of?(Range) + other.begin == self.begin || self.cover?(other.begin) || other.cover?(self.begin) + end end diff --git a/mruby/mrbgems/mruby-range-ext/test/range.rb b/mruby/mrbgems/mruby-range-ext/test/range.rb index 4ae57566..d3771292 100644 --- a/mruby/mrbgems/mruby-range-ext/test/range.rb +++ b/mruby/mrbgems/mruby-range-ext/test/range.rb @@ -178,3 +178,37 @@ assert_equal nil, ((100..10).min { |x, y| x <=> y }) assert_equal nil, ((5...5).min { |x, y| x <=> y }) end + +assert('Range#overlap?') do + assert_false((0..2).overlap?(-2..-1)) + assert_false((0..2).overlap?(-2...0)) + assert_true((0..2).overlap?(-1..0)) + assert_true((0..2).overlap?(1..2)) + assert_true((0..2).overlap?(2..3)) + assert_false((0..2).overlap?(3...4)) + assert_false((0...2).overlap?(2..3)) + + assert_true((..0).overlap?(-1..0)) + assert_true((...0).overlap?(-1..0)) + assert_true((..0).overlap?(0..1)) + assert_true((..0).overlap?(..1)) + assert_false((..0).overlap?(1..2)) + assert_false((...0).overlap?(0..1)) + + assert_false((0..).overlap?(-2..-1)) + assert_false((0..).overlap?(...0)) + assert_true((0..).overlap?(..0)) + assert_true((0..).overlap?(0..1)) + assert_true((0..).overlap?(1..2)) + assert_true((0..).overlap?(-1..0)) + assert_true((0..).overlap?(1..)) + + assert_true((0..).overlap?(-1..0)) + assert_true((0..).overlap?(..0)) + assert_true((0..).overlap?(0..1)) + assert_true((0..).overlap?(1..2)) + assert_true((0..).overlap?(1..)) + + assert_raise(TypeError) { (0..).overlap?(1) } + assert_raise(TypeError) { (0..).overlap?(nil) } +end diff --git a/mruby/mrbgems/mruby-rational/src/rational.c b/mruby/mrbgems/mruby-rational/src/rational.c index 3b13fb57..2fadf5d6 100644 --- a/mruby/mrbgems/mruby-rational/src/rational.c +++ b/mruby/mrbgems/mruby-rational/src/rational.c @@ -202,8 +202,6 @@ float_decode_internal(mrb_state *mrb, mrb_float f, mrb_float *rf, int *n) *rf = f; } -void mrb_check_num_exact(mrb_state *mrb, mrb_float num); - static mrb_value rational_new_f(mrb_state *mrb, mrb_float f0) { @@ -487,7 +485,7 @@ rational_cmp(mrb_state *mrb, mrb_value x) } #endif default: - x = mrb_funcall_id(mrb, y, MRB_OPSYM(cmp), 1, x); + x = mrb_funcall_argv(mrb, y, MRB_OPSYM(cmp), 1, &x); if (mrb_integer_p(x)) { mrb_int z = mrb_integer(x); return mrb_fixnum_value(-z); @@ -544,7 +542,7 @@ mrb_rational_add(mrb_state *mrb, mrb_value x, mrb_value y) #endif default: - return mrb_funcall_id(mrb, y, MRB_OPSYM(add), 1, x); + return mrb_funcall_argv(mrb, y, MRB_OPSYM(add), 1, &x); } } @@ -642,7 +640,7 @@ mrb_rational_mul(mrb_state *mrb, mrb_value x, mrb_value y) #endif default: - return mrb_funcall_id(mrb, y, MRB_OPSYM(mul), 1, x); + return mrb_funcall_argv(mrb, y, MRB_OPSYM(mul), 1, &x); } } @@ -769,7 +767,7 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) struct RClass *rat; rat = mrb_define_class_id(mrb, MRB_SYM(Rational), mrb_class_get_id(mrb, MRB_SYM(Numeric))); - MRB_SET_INSTANCE_TT(rat, MRB_TT_RATIONAL); + MRB_SET_INSTANCE_TT(rat, MRB_TT_UNDEF); mrb_undef_class_method(mrb, rat, "new"); mrb_define_class_method(mrb, rat, "_new", rational_s_new, MRB_ARGS_REQ(2)); mrb_define_method(mrb, rat, "numerator", rational_numerator, MRB_ARGS_NONE()); diff --git a/mruby/mrbgems/mruby-set/mrblib/set.rb b/mruby/mrbgems/mruby-set/mrblib/set.rb index 0116e187..467290c7 100644 --- a/mruby/mrbgems/mruby-set/mrblib/set.rb +++ b/mruby/mrbgems/mruby-set/mrblib/set.rb @@ -306,17 +306,13 @@ def join(separator = nil) to_a.join(separator) end - def _inspect(recur_list) + def inspect return "#<#{self.class}: {}>" if empty? - return "#<#{self.class}: {...}>" if recur_list[self.object_id] - recur_list[self.object_id] = true - ary = map { |o| o._inspect(recur_list) } + return "#<#{self.class}: {...}>" if self.__inspect_recursive? + ary = map {|o| o.inspect } "#<#{self.class}: {#{ary.join(", ")}}>" end - def inspect - _inspect({}) - end alias to_s inspect def reset diff --git a/mruby/mrbgems/mruby-sleep/src/sleep.c b/mruby/mrbgems/mruby-sleep/src/sleep.c index d05bc194..4b30ceae 100644 --- a/mruby/mrbgems/mruby-sleep/src/sleep.c +++ b/mruby/mrbgems/mruby-sleep/src/sleep.c @@ -40,7 +40,7 @@ /* not implemented forever sleep (called without an argument)*/ static mrb_value -mrb_f_sleep(mrb_state *mrb, mrb_value self) +f_sleep(mrb_state *mrb, mrb_value self) { time_t beg = time(0); time_t end; @@ -60,7 +60,8 @@ mrb_f_sleep(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "i", &sec); if (sec >= 0) { sleep(sec); - } else { + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative"); } #endif @@ -71,7 +72,7 @@ mrb_f_sleep(mrb_state *mrb, mrb_value self) /* mruby special; needed for mruby without float numbers */ static mrb_value -mrb_f_usleep(mrb_state *mrb, mrb_value self) +f_usleep(mrb_state *mrb, mrb_value self) { mrb_int usec; #ifdef _WIN32 @@ -94,7 +95,8 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self) if (usec >= 0) { usleep(usec); - } else { + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must not be negative"); } @@ -126,8 +128,8 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self) void mrb_mruby_sleep_gem_init(mrb_state *mrb) { - mrb_define_method(mrb, mrb->kernel_module, "sleep", mrb_f_sleep, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->kernel_module, "usleep", mrb_f_usleep, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "sleep", f_sleep, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->kernel_module, "usleep", f_usleep, MRB_ARGS_REQ(1)); } void diff --git a/mruby/mrbgems/mruby-socket/README.md b/mruby/mrbgems/mruby-socket/README.md index f88ae350..f7ff8ca3 100644 --- a/mruby/mrbgems/mruby-socket/README.md +++ b/mruby/mrbgems/mruby-socket/README.md @@ -20,8 +20,8 @@ Date: Tue, 21 May 2013 04:31:30 GMT ## Requirement -- [mruby-io](https://github.com/mruby/mruby/tree/master/mrbgems/mruby-io) mrbgem -- [iij/mruby-mtest](https://github.com/iij/mruby-mtest) mrgbem to run tests +- [mruby-io](../mruby-io) mrbgem +- [iij/mruby-mtest](https://github.com/iij/mruby-mtest) mrbgem to run tests - system must have RFC3493 basic socket interface - and some POSIX API... diff --git a/mruby/mrbgems/mruby-socket/mrbgem.rake b/mruby/mrbgems/mruby-socket/mrbgem.rake index dba00c64..c3684cd0 100644 --- a/mruby/mrbgems/mruby-socket/mrbgem.rake +++ b/mruby/mrbgems/mruby-socket/mrbgem.rake @@ -1,6 +1,6 @@ MRuby::Gem::Specification.new('mruby-socket') do |spec| spec.license = 'MIT' - spec.authors = ['Internet Initiative Japan', 'mruby developers'] + spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers'] spec.summary = 'standard socket class' #spec.cc.defines << "HAVE_SA_LEN=0" @@ -12,6 +12,6 @@ MRuby::Gem::Specification.new('mruby-socket') do |spec| end spec.add_dependency('mruby-io', :core => 'mruby-io') - spec.add_dependency('mruby-pack', :core => 'mruby-pack') + spec.add_dependency('mruby-error', :core => 'mruby-error') # spec.add_dependency('mruby-mtest') end diff --git a/mruby/mrbgems/mruby-socket/mrblib/socket.rb b/mruby/mrbgems/mruby-socket/mrblib/socket.rb index 0e7bbdcc..6736df3d 100644 --- a/mruby/mrbgems/mruby-socket/mrblib/socket.rb +++ b/mruby/mrbgems/mruby-socket/mrblib/socket.rb @@ -19,7 +19,6 @@ def initialize(sockaddr, family=Socket::PF_UNSPEC, socktype=0, protocol=0) end @socktype = socktype @protocol = protocol - @canonname = nil end def self.foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=0, &block) @@ -49,9 +48,7 @@ def afamily end #def bind - - attr_reader :canonname - + #def canonname #def connect #def connect_from #def connect_to @@ -70,10 +67,10 @@ def inspect else proto = '???' end - "#" else - "#" + proto = "SOCK_STREAM" end + "#" end def inspect_sockaddr @@ -570,52 +567,4 @@ def sysaccept end end -class Socket - include Constants -end - -class Socket - class Option - def initialize(family, level, optname, data) - @family = family - @level = level - @optname = optname - @data = data - end - - def self.bool(family, level, optname, bool) - self.new(family, level, optname, [(bool ? 1 : 0)].pack('i')) - end - - def self.int(family, level, optname, integer) - self.new(family, level, optname, [integer].pack('i')) - end - - #def self.linger(family, level, optname, integer) - #end - - attr_reader :data, :family, :level, :optname - - def bool - @data.unpack('i')[0] != 0 - end - - def inspect - "#" - end - - def int - @data.unpack('i')[0] - end - - def linger - raise NotImplementedError.new - end - - def unpack(template) - raise NotImplementedError.new - end - end -end - class SocketError < StandardError; end diff --git a/mruby/mrbgems/mruby-socket/src/socket.c b/mruby/mrbgems/mruby-socket/src/socket.c index a9ce33d2..73d89e6c 100644 --- a/mruby/mrbgems/mruby-socket/src/socket.c +++ b/mruby/mrbgems/mruby-socket/src/socket.c @@ -56,24 +56,22 @@ #ifdef _WIN32 static const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { - if (af == AF_INET) - { + 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); + getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), + dst, cnt, NULL, 0, NI_NUMERICHOST); return dst; } - else if (af == AF_INET6) - { + 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); + getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6), + dst, cnt, NULL, 0, NI_NUMERICHOST); return dst; } return NULL; @@ -86,16 +84,14 @@ static int inet_pton(int af, const char *src, void *dst) hints.ai_family = af; - if (getaddrinfo(src, NULL, &hints, &res) != 0) - { + if (getaddrinfo(src, NULL, &hints, &res) != 0) { printf("Couldn't resolve host %s\n", src); return -1; } ressave = res; - while (res) - { + while (res) { memcpy(dst, res->ai_addr, res->ai_addrlen); res = res->ai_next; } @@ -106,37 +102,57 @@ static int inet_pton(int af, const char *src, void *dst) #endif +struct gen_addrinfo_args { + struct RClass *klass; + struct addrinfo *addrinfo; +}; + +static mrb_value +gen_addrinfo(mrb_state *mrb, mrb_value args) +{ + mrb_value ary = mrb_ary_new(mrb); + int arena_idx = mrb_gc_arena_save(mrb); /* ary must be on arena! */ + struct gen_addrinfo_args *a = (struct gen_addrinfo_args*)mrb_cptr(args); + + for (struct addrinfo *res = a->addrinfo; res != NULL; res = res->ai_next) { + mrb_value sa = mrb_str_new(mrb, (char*)res->ai_addr, res->ai_addrlen); + mrb_value args[4] = {sa, mrb_fixnum_value(res->ai_family), mrb_fixnum_value(res->ai_socktype), mrb_fixnum_value(res->ai_protocol)}; + mrb_value ai = mrb_obj_new(mrb, a->klass, 4, args); + mrb_ary_push(mrb, ary, ai); + mrb_gc_arena_restore(mrb, arena_idx); + } + return ary; +} + +static mrb_value +free_addrinfo(mrb_state *mrb, mrb_value addrinfo) +{ + freeaddrinfo((struct addrinfo*)mrb_cptr(addrinfo)); + return mrb_nil_value(); +} + static mrb_value mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) { - struct addrinfo hints = {0}, *res0, *res; - mrb_value ai, ary, family, lastai, nodename, protocol, sa, service, socktype; + struct addrinfo hints = {0}, *addr; + mrb_value family, protocol, service, socktype; mrb_int flags; - int arena_idx, error; - const char *hostname = NULL, *servname = NULL; - - ary = mrb_ary_new(mrb); - arena_idx = mrb_gc_arena_save(mrb); /* ary must be on arena! */ + const char *hostname, *servname = NULL; family = socktype = protocol = mrb_nil_value(); flags = 0; - mrb_get_args(mrb, "oo|oooi", &nodename, &service, &family, &socktype, &protocol, &flags); - - if (mrb_string_p(nodename)) { - hostname = RSTRING_CSTR(mrb, nodename); - } else if (mrb_nil_p(nodename)) { - hostname = NULL; - } else { - mrb_raise(mrb, E_TYPE_ERROR, "nodename must be String or nil"); - } + mrb_get_args(mrb, "z!o|oooi", &hostname, &service, &family, &socktype, &protocol, &flags); if (mrb_string_p(service)) { servname = RSTRING_CSTR(mrb, service); - } else if (mrb_integer_p(service)) { + } + else if (mrb_integer_p(service)) { servname = RSTRING_PTR(mrb_integer_to_str(mrb, service, 10)); - } else if (mrb_nil_p(service)) { + } + else if (mrb_nil_p(service)) { servname = NULL; - } else { + } + else { mrb_raise(mrb, E_TYPE_ERROR, "service must be String, Integer, or nil"); } @@ -154,29 +170,13 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass) hints.ai_protocol = (int)mrb_integer(protocol); } - lastai = mrb_cv_get(mrb, klass, MRB_SYM(_lastai)); - if (mrb_cptr_p(lastai)) { - freeaddrinfo((struct addrinfo*)mrb_cptr(lastai)); - mrb_cv_set(mrb, klass, MRB_SYM(_lastai), mrb_nil_value()); - } - - error = getaddrinfo(hostname, servname, &hints, &res0); + int error = getaddrinfo(hostname, servname, &hints, &addr); if (error) { mrb_raisef(mrb, E_SOCKET_ERROR, "getaddrinfo: %s", gai_strerror(error)); } - mrb_cv_set(mrb, klass, MRB_SYM(_lastai), mrb_cptr_value(mrb, res0)); - for (res = res0; res != NULL; res = res->ai_next) { - sa = mrb_str_new(mrb, (char*)res->ai_addr, res->ai_addrlen); - ai = mrb_funcall_id(mrb, klass, MRB_SYM(new), 4, sa, mrb_fixnum_value(res->ai_family), mrb_fixnum_value(res->ai_socktype), mrb_fixnum_value(res->ai_protocol)); - mrb_ary_push(mrb, ary, ai); - mrb_gc_arena_restore(mrb, arena_idx); - } - - freeaddrinfo(res0); - mrb_cv_set(mrb, klass, MRB_SYM(_lastai), mrb_nil_value()); - - return ary; + struct gen_addrinfo_args args = {mrb_class_ptr(klass), addr}; + return mrb_ensure(mrb, gen_addrinfo, mrb_cptr_value(mrb, &args), free_addrinfo, mrb_cptr_value(mrb, addr)); } static mrb_value @@ -195,7 +195,7 @@ mrb_addrinfo_getnameinfo(mrb_state *mrb, mrb_value self) if (!mrb_string_p(sastr)) { mrb_raise(mrb, E_SOCKET_ERROR, "invalid sockaddr"); } - error = getnameinfo((struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, (int)flags); + error = getnameinfo((struct sockaddr*)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr), RSTRING_PTR(host), NI_MAXHOST, RSTRING_PTR(serv), NI_MAXSERV, (int)flags); if (error) { mrb_raisef(mrb, E_SOCKET_ERROR, "getnameinfo: %s", gai_strerror(error)); } @@ -214,12 +214,13 @@ mrb_addrinfo_unix_path(mrb_state *mrb, mrb_value self) mrb_value sastr; sastr = mrb_iv_get(mrb, self, MRB_IVSYM(sockaddr)); - if (((struct sockaddr *)RSTRING_PTR(sastr))->sa_family != AF_UNIX) + if (!mrb_string_p(sastr) || ((struct sockaddr*)RSTRING_PTR(sastr))->sa_family != AF_UNIX) mrb_raise(mrb, E_SOCKET_ERROR, "need AF_UNIX address"); if (RSTRING_LEN(sastr) < (mrb_int)offsetof(struct sockaddr_un, sun_path) + 1) { return mrb_str_new(mrb, "", 0); - } else { - return mrb_str_new_cstr(mrb, ((struct sockaddr_un *)RSTRING_PTR(sastr))->sun_path); + } + else { + return mrb_str_new_cstr(mrb, ((struct sockaddr_un*)RSTRING_PTR(sastr))->sun_path); } } #endif @@ -234,11 +235,11 @@ sa2addrlist(mrb_state *mrb, const struct sockaddr *sa, socklen_t salen) switch (sa->sa_family) { case AF_INET: afstr = "AF_INET"; - port = ((struct sockaddr_in *)sa)->sin_port; + port = ((struct sockaddr_in*)sa)->sin_port; break; case AF_INET6: afstr = "AF_INET6"; - port = ((struct sockaddr_in6 *)sa)->sin6_port; + port = ((struct sockaddr_in6*)sa)->sin6_port; break; default: mrb_raise(mrb, E_ARGUMENT_ERROR, "bad af"); @@ -272,7 +273,7 @@ socket_family(int s) socklen_t salen; salen = sizeof(ss); - if (getsockname(s, (struct sockaddr *)&ss, &salen) == -1) + if (getsockname(s, (struct sockaddr*)&ss, &salen) == -1) return AF_UNSPEC; return ss.ss_family; } @@ -307,7 +308,7 @@ mrb_basicsocket_getpeername(mrb_state *mrb, mrb_value self) socklen_t salen; salen = sizeof(ss); - if (getpeername(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0) + if (getpeername(socket_fd(mrb, self), (struct sockaddr*)&ss, &salen) != 0) mrb_sys_fail(mrb, "getpeername"); return mrb_str_new(mrb, (char*)&ss, salen); @@ -320,19 +321,180 @@ mrb_basicsocket_getsockname(mrb_state *mrb, mrb_value self) socklen_t salen; salen = sizeof(ss); - if (getsockname(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0) + if (getsockname(socket_fd(mrb, self), (struct sockaddr*)&ss, &salen) != 0) mrb_sys_fail(mrb, "getsockname"); return mrb_str_new(mrb, (char*)&ss, salen); } +static struct RClass * +socket_option_class(mrb_state *mrb) +{ + return mrb_class_get_under_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Socket)), MRB_SYM(Option)); +} + +static mrb_value +socket_option_init(mrb_state *mrb, mrb_value self) +{ + mrb_int family, level, optname; + mrb_value data; + + mrb_get_args(mrb, "iiio", &family, &level, &optname, &data); + mrb_iv_set(mrb, self, MRB_SYM(family), mrb_int_value(mrb, family)); + mrb_iv_set(mrb, self, MRB_SYM(level), mrb_int_value(mrb, level)); + mrb_iv_set(mrb, self, MRB_SYM(optname), mrb_int_value(mrb, optname)); + mrb_iv_set(mrb, self, MRB_SYM(data), data); + + return self; +} + +static mrb_value +socket_option_s_bool(mrb_state *mrb, mrb_value klass) +{ + mrb_value args[4]; + mrb_bool data; + int tmp; + + mrb_get_args(mrb, "ooob", &args[0], &args[1], &args[2], &data); + tmp = (int)data; + args[3] = mrb_str_new(mrb, (char*)&tmp, sizeof(int)); + return mrb_obj_new(mrb, mrb_class_ptr(klass), 4, args); +} + +static mrb_value +socket_option_s_int(mrb_state *mrb, mrb_value klass) +{ + mrb_value args[4]; + mrb_int data; + int tmp; + + mrb_get_args(mrb, "oooi", &args[0], &args[1], &args[2], &data); + tmp = (int)data; + args[3] = mrb_str_new(mrb, (char*)&tmp, sizeof(int)); + return mrb_obj_new(mrb, mrb_class_ptr(klass), 4, args); +} + +static mrb_value +socket_option_family(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(family)); +} + +static mrb_value +socket_option_level(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(level)); +} + +static mrb_value +socket_option_optname(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(optname)); +} + +static mrb_value +socket_option_data(mrb_state *mrb, mrb_value self) +{ + return mrb_iv_get(mrb, self, MRB_SYM(data)); +} + +static int +option_int(mrb_state *mrb, mrb_value self) +{ + mrb_value data = mrb_obj_as_string(mrb, mrb_iv_get(mrb, self, MRB_SYM(data))); + int tmp; + + if (RSTRING_LEN(data) != sizeof(int)) { + mrb_raisef(mrb, E_TYPE_ERROR, "size differ; expected as sizeof(int)=%i but %i", (mrb_int)sizeof(int), RSTRING_LEN(data)); + } + memcpy((char*)&tmp, RSTRING_PTR(data), sizeof(int)); + return tmp; +} + +static mrb_value +socket_option_int(mrb_state *mrb, mrb_value self) +{ + int i = option_int(mrb, self); + return mrb_int_value(mrb, (mrb_int)i); +} + +static mrb_value +socket_option_bool(mrb_state *mrb, mrb_value self) +{ + int i = option_int(mrb, self); + return mrb_bool_value((mrb_bool)i); +} + +static mrb_value +socket_option_notimp(mrb_state *mrb, mrb_value self) +{ + mrb_notimplement(mrb); + return mrb_nil_value(); +} + +static mrb_value +socket_option_inspect(mrb_state *mrb, mrb_value self) +{ + mrb_value str = mrb_str_new_cstr(mrb, "#"); + + return str; +} + static mrb_value mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self) { char opt[8]; int s; mrb_int family, level, optname; - mrb_value c, data; + mrb_value data; socklen_t optlen; mrb_get_args(mrb, "ii", &level, &optname); @@ -340,10 +502,10 @@ mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self) optlen = sizeof(opt); if (getsockopt(s, (int)level, (int)optname, opt, &optlen) == -1) mrb_sys_fail(mrb, "getsockopt"); - c = mrb_const_get(mrb, mrb_obj_value(mrb_class_get_id(mrb, MRB_SYM(Socket))), MRB_SYM(Option)); family = socket_family(s); data = mrb_str_new(mrb, opt, optlen); - return mrb_funcall_id(mrb, c, MRB_SYM(new), 4, mrb_fixnum_value(family), mrb_fixnum_value(level), mrb_fixnum_value(optname), data); + mrb_value args[4] = {mrb_fixnum_value(family), mrb_fixnum_value(level), mrb_fixnum_value(optname), data}; + return mrb_obj_new(mrb, socket_option_class(mrb), 4, args); } static mrb_value @@ -374,7 +536,7 @@ mrb_basicsocket_recvfrom(mrb_state *mrb, mrb_value self) buf = mrb_str_new_capa(mrb, maxlen); socklen = sizeof(struct sockaddr_storage); sa = mrb_str_new_capa(mrb, socklen); - n = recvfrom(socket_fd(mrb, self), RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags, (struct sockaddr *)RSTRING_PTR(sa), &socklen); + n = recvfrom(socket_fd(mrb, self), RSTRING_PTR(buf), (fsize_t)maxlen, (int)flags, (struct sockaddr*)RSTRING_PTR(sa), &socklen); if (n == -1) mrb_sys_fail(mrb, "recvfrom"); mrb_str_resize(mrb, buf, (mrb_int)n); @@ -396,7 +558,8 @@ mrb_basicsocket_send(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "Si|S", &mesg, &flags, &dest); if (mrb_nil_p(dest)) { n = send(socket_fd(mrb, self), RSTRING_PTR(mesg), (fsize_t)RSTRING_LEN(mesg), (int)flags); - } else { + } + else { n = sendto(socket_fd(mrb, self), RSTRING_PTR(mesg), (fsize_t)RSTRING_LEN(mesg), (int)flags, (const struct sockaddr*)RSTRING_PTR(dest), (fsize_t)RSTRING_LEN(dest)); } if (n == -1) @@ -442,34 +605,38 @@ mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self) argc = mrb_get_args(mrb, "o|io", &so, &optname, &optval); if (argc == 3) { - if (!mrb_integer_p(so)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "level is not an integer"); - } + mrb_ensure_int_type(mrb, so); level = mrb_integer(so); if (mrb_string_p(optval)) { /* that's good */ - } else if (mrb_true_p(optval) || mrb_false_p(optval)) { + } + else if (mrb_true_p(optval) || mrb_false_p(optval)) { mrb_int i = mrb_test(optval) ? 1 : 0; optval = mrb_str_new(mrb, (char*)&i, sizeof(i)); - } else if (mrb_integer_p(optval)) { + } + else if (mrb_integer_p(optval)) { if (optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP) { char uc = (char)mrb_integer(optval); optval = mrb_str_new(mrb, &uc, sizeof(uc)); - } else { + } + else { mrb_int i = mrb_integer(optval); optval = mrb_str_new(mrb, (char*)&i, sizeof(i)); } - } else { + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "optval should be true, false, an integer, or a string"); } - } else if (argc == 1) { - if (strcmp(mrb_obj_classname(mrb, so), "Socket::Option") != 0) + } + else if (argc == 1) { + if (!mrb_obj_is_instance_of(mrb, so, socket_option_class(mrb))) mrb_raise(mrb, E_ARGUMENT_ERROR, "not an instance of Socket::Option"); - level = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(level), 0)); - optname = mrb_as_int(mrb, mrb_funcall_id(mrb, so, MRB_SYM(optname), 0)); - optval = mrb_funcall_id(mrb, so, MRB_SYM(data), 0); + level = mrb_as_int(mrb, mrb_iv_get(mrb, so, MRB_SYM(level))); + optname = mrb_as_int(mrb, mrb_iv_get(mrb, so, MRB_SYM(optname))); + optval = mrb_iv_get(mrb, so, MRB_SYM(data)); mrb_ensure_string_type(mrb, optval); - } else { + } + else { mrb_argnum_error(mrb, argc, 3, 3); } @@ -533,16 +700,19 @@ mrb_ipsocket_pton(mrb_state *mrb, mrb_value klass) if (af == AF_INET) { struct in_addr in; - if (inet_pton(AF_INET, buf, (void *)&in.s_addr) != 1) + if (inet_pton(AF_INET, buf, (void*)&in.s_addr) != 1) goto invalid; return mrb_str_new(mrb, (char*)&in.s_addr, 4); - } else if (af == AF_INET6) { + } + else if (af == AF_INET6) { struct in6_addr in6; - if (inet_pton(AF_INET6, buf, (void *)&in6.s6_addr) != 1) + if (inet_pton(AF_INET6, buf, (void*)&in6.s6_addr) != 1) goto invalid; return mrb_str_new(mrb, (char*)&in6.s6_addr, 16); - } else + } + else { mrb_raise(mrb, E_ARGUMENT_ERROR, "unsupported address family"); + } invalid: mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address"); @@ -565,12 +735,12 @@ 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"); } mrb_str_resize(mrb, buf, (mrb_int)n); - a = sa2addrlist(mrb, (struct sockaddr *)&ss, socklen); + a = sa2addrlist(mrb, (struct sockaddr*)&ss, socklen); pair = mrb_ary_new_capa(mrb, 2); mrb_ary_push(mrb, pair, buf); mrb_ary_push(mrb, pair, a); @@ -620,7 +790,7 @@ mrb_socket_accept2(mrb_state *mrb, mrb_value klass) mrb_get_args(mrb, "i", &s0); socklen = sizeof(struct sockaddr_storage); sastr = mrb_str_new_capa(mrb, (mrb_int)socklen); - s1 = (int)accept(s0, (struct sockaddr *)RSTRING_PTR(sastr), &socklen); + s1 = (int)accept(s0, (struct sockaddr*)RSTRING_PTR(sastr), &socklen); if (s1 == -1) { mrb_sys_fail(mrb, "accept"); } @@ -639,7 +809,7 @@ mrb_socket_bind(mrb_state *mrb, mrb_value klass) mrb_int s; mrb_get_args(mrb, "iS", &s, &sastr); - if (bind((int)s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { + if (bind((int)s, (struct sockaddr*)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { mrb_sys_fail(mrb, "bind"); } return mrb_nil_value(); @@ -652,7 +822,7 @@ mrb_socket_connect(mrb_state *mrb, mrb_value klass) mrb_int s; mrb_get_args(mrb, "iS", &s, &sastr); - if (connect((int)s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { + if (connect((int)s, (struct sockaddr*)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) { mrb_sys_fail(mrb, "connect"); } return mrb_nil_value(); @@ -680,7 +850,7 @@ mrb_socket_sockaddr_family(mrb_state *mrb, mrb_value klass) if ((size_t)RSTRING_LEN(str) < offsetof(struct sockaddr, sa_family) + sizeof(sa->sa_family)) { mrb_raise(mrb, E_SOCKET_ERROR, "invalid sockaddr (too short)"); } - sa = (const struct sockaddr *)RSTRING_PTR(str); + sa = (const struct sockaddr*)RSTRING_PTR(str); return mrb_fixnum_value(sa->sa_family); } @@ -699,7 +869,7 @@ mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass) mrb_raisef(mrb, E_ARGUMENT_ERROR, "too long unix socket path (max: %d bytes)", (int)sizeof(sunp->sun_path) - 1); } s = mrb_str_new_capa(mrb, sizeof(struct sockaddr_un)); - sunp = (struct sockaddr_un *)RSTRING_PTR(s); + sunp = (struct sockaddr_un*)RSTRING_PTR(s); #if HAVE_SA_LEN sunp->sun_len = sizeof(struct sockaddr_un); #endif @@ -798,7 +968,8 @@ mrb_win32_basicsocket_sysread(mrb_state *mrb, mrb_value self) case 0: /* EOF */ if (maxlen == 0) { buf = mrb_str_new_cstr(mrb, ""); - } else { + } + else { mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File"); } break; @@ -843,7 +1014,7 @@ void mrb_mruby_socket_gem_init(mrb_state* mrb) { struct RClass *io, *ai, *sock, *bsock, *ipsock, *tcpsock; - struct RClass *constants; + struct RClass *constants, *option; #ifdef _WIN32 WSADATA wsaData; @@ -854,7 +1025,6 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) #endif ai = mrb_define_class(mrb, "Addrinfo", mrb->object_class); - mrb_mod_cv_set(mrb, ai, MRB_SYM(_lastai), mrb_nil_value()); mrb_define_class_method(mrb, ai, "getaddrinfo", mrb_addrinfo_getaddrinfo, MRB_ARGS_REQ(2)|MRB_ARGS_OPT(4)); mrb_define_method(mrb, ai, "getnameinfo", mrb_addrinfo_getnameinfo, MRB_ARGS_OPT(1)); #ifndef _WIN32 @@ -924,8 +1094,25 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) mrb_define_method(mrb, bsock, "sysread", mrb_win32_basicsocket_sysread, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); mrb_define_method(mrb, bsock, "sysseek", mrb_win32_basicsocket_sysseek, MRB_ARGS_REQ(1)); mrb_define_method(mrb, bsock, "syswrite", mrb_win32_basicsocket_syswrite, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, bsock, "read", mrb_win32_basicsocket_sysread, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_method(mrb, bsock, "write", mrb_win32_basicsocket_syswrite, MRB_ARGS_REQ(1)); #endif + option = mrb_define_class_under(mrb, sock, "Option", mrb->object_class); + mrb_define_class_method(mrb, option, "bool", socket_option_s_bool, MRB_ARGS_REQ(4)); + mrb_define_class_method(mrb, option, "int", socket_option_s_int, MRB_ARGS_REQ(4)); + mrb_define_method(mrb, option, "initialize", socket_option_init, MRB_ARGS_REQ(4)); + mrb_define_method(mrb, option, "inspect", socket_option_inspect, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "family", socket_option_family, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "level", socket_option_level, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "optname", socket_option_optname, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "data", socket_option_data, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "bool", socket_option_bool, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "int", socket_option_int, MRB_ARGS_REQ(0)); + + mrb_define_method(mrb, option, "linger", socket_option_notimp, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, option, "unpack", socket_option_notimp, MRB_ARGS_REQ(1)); + constants = mrb_define_module_under(mrb, sock, "Constants"); #define define_const(SYM) \ @@ -934,16 +1121,13 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) } while (0) #include "const.cstub" + + mrb_include_module(mrb, sock, constants); } void mrb_mruby_socket_gem_final(mrb_state* mrb) { - mrb_value ai; - ai = mrb_mod_cv_get(mrb, mrb_class_get_id(mrb, MRB_SYM(Addrinfo)), MRB_SYM(_lastai)); - if (mrb_cptr_p(ai)) { - freeaddrinfo((struct addrinfo*)mrb_cptr(ai)); - } #ifdef _WIN32 WSACleanup(); #endif diff --git a/mruby/mrbgems/mruby-sprintf/src/sprintf.c b/mruby/mrbgems/mruby-sprintf/src/sprintf.c index 71a3e90d..9f7fb59d 100644 --- a/mruby/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mruby/mrbgems/mruby-sprintf/src/sprintf.c @@ -146,7 +146,8 @@ fmt_float(char *buf, size_t buf_size, char fmt, int flags, int width, int prec, memmove(&buf[width - len], buf, len); if (zero_pad) { memset(buf, '0', width - len); - } else { + } + else { memset(buf, ' ', width - len); } return width; @@ -604,7 +605,8 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm mrb_sym id = 0; int flags = FNONE; - for (t = p; t < end && *t != '%'; t++) ; + for (t = p; t < end && *t != '%'; t++) + ; if (t + 1 == end) t++; PUSH(p, t - p); if (t >= end) @@ -761,7 +763,7 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm tmp = mrb_str_new(mrb, buf, 1); } else { - tmp = mrb_funcall_id(mrb, val, MRB_SYM(chr), 0); + tmp = mrb_funcall_argv(mrb, val, MRB_SYM(chr), 0, NULL); mrb_check_type(mrb, tmp, MRB_TT_STRING); } #endif @@ -994,7 +996,8 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm if ((flags & (FMINUS|FPREC)) != FMINUS) { char c = '0'; FILL(c, prec - len); - } else if (v < 0) { + } + else if (v < 0) { char c = sign_bits(base, p); FILL(c, prec - len); } diff --git a/mruby/mrbgems/mruby-string-ext/mrblib/string.rb b/mruby/mrbgems/mruby-string-ext/mrblib/string.rb index 87f8ab9a..9f940ca3 100644 --- a/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mruby/mrbgems/mruby-string-ext/mrblib/string.rb @@ -314,13 +314,14 @@ def each_char(&block) end def codepoints(&block) + cp = __codepoints() if block_given? - self.split('').each do|x| - block.call(x.ord) + cp.each do|x| + block.call(x) end self else - self.split('').map{|x| x.ord} + cp end end alias each_codepoint codepoints diff --git a/mruby/mrbgems/mruby-string-ext/src/string.c b/mruby/mrbgems/mruby-string-ext/src/string.c index 881409ad..4e2be81f 100644 --- a/mruby/mrbgems/mruby-string-ext/src/string.c +++ b/mruby/mrbgems/mruby-string-ext/src/string.c @@ -11,10 +11,10 @@ #define ENC_UTF8 "UTF-8" #define ENC_COMP_P(enc, enc_lit) \ - str_casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1) + casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1) static mrb_bool -str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) +casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) { const char *e1, *e2; @@ -96,7 +96,7 @@ int_chr_utf8(mrb_state *mrb, mrb_value num) * Note: case conversion is effective only in ASCII region. */ static mrb_value -mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str) +str_swapcase_bang(mrb_state *mrb, mrb_value str) { char *p, *pend; int modify = 0; @@ -133,12 +133,12 @@ mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str) * "cYbEr_PuNk11".swapcase #=> "CyBeR_pUnK11" */ static mrb_value -mrb_str_swapcase(mrb_state *mrb, mrb_value self) +str_swapcase(mrb_state *mrb, mrb_value self) { mrb_value str; str = mrb_str_dup(mrb, self); - mrb_str_swapcase_bang(mrb, str); + str_swapcase_bang(mrb, str); return str; } @@ -173,7 +173,7 @@ str_concat(mrb_state *mrb, mrb_value self, mrb_value str) * */ static mrb_value -mrb_str_concat_m(mrb_state *mrb, mrb_value self) +str_concat_m(mrb_state *mrb, mrb_value self) { if (mrb_get_argc(mrb) == 1) { str_concat(mrb, self, mrb_get_arg1(mrb)); @@ -204,7 +204,7 @@ mrb_str_concat_m(mrb_state *mrb, mrb_value self) * "h".start_with?("heaven", "hell") #=> false */ static mrb_value -mrb_str_start_with(mrb_state *mrb, mrb_value self) +str_start_with(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc, i; @@ -234,7 +234,7 @@ mrb_str_start_with(mrb_state *mrb, mrb_value self) * Returns true if +str+ ends with one of the +suffixes+ given. */ static mrb_value -mrb_str_end_with(mrb_state *mrb, mrb_value self) +str_end_with(mrb_state *mrb, mrb_value self) { const mrb_value *argv; mrb_int argc, i; @@ -308,7 +308,7 @@ tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_patte struct tr_pattern *pat1; mrb_int i = 0; - if(flag_reverse_enable && pattern_length >= 2 && pattern[0] == '^') { + if (flag_reverse_enable && pattern_length >= 2 && pattern[0] == '^') { flag_reverse = TRUE; i++; } @@ -580,7 +580,7 @@ str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squee * Note: conversion is effective only in ASCII region. */ static mrb_value -mrb_str_tr(mrb_state *mrb, mrb_value str) +str_tr_m(mrb_state *mrb, mrb_value str) { mrb_value dup; mrb_value p1, p2; @@ -599,7 +599,7 @@ mrb_str_tr(mrb_state *mrb, mrb_value str) * Returns str, or nil if no changes were made. */ static mrb_value -mrb_str_tr_bang(mrb_state *mrb, mrb_value str) +str_tr_bang(mrb_state *mrb, mrb_value str) { mrb_value p1, p2; @@ -622,7 +622,7 @@ mrb_str_tr_bang(mrb_state *mrb, mrb_value str) * "hello".tr_s('el', 'hx') #=> "hhxo" */ static mrb_value -mrb_str_tr_s(mrb_state *mrb, mrb_value str) +str_tr_s(mrb_state *mrb, mrb_value str) { mrb_value dup; mrb_value p1, p2; @@ -641,7 +641,7 @@ mrb_str_tr_s(mrb_state *mrb, mrb_value str) * str, or nil if no changes were made. */ static mrb_value -mrb_str_tr_s_bang(mrb_state *mrb, mrb_value str) +str_tr_s_bang(mrb_state *mrb, mrb_value str) { mrb_value p1, p2; @@ -716,7 +716,7 @@ str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat) * "putters shoot balls".squeeze("m-z") #=> "puters shot balls" */ static mrb_value -mrb_str_squeeze(mrb_state *mrb, mrb_value str) +str_squeeze_m(mrb_state *mrb, mrb_value str) { mrb_value pat = mrb_nil_value(); mrb_value dup; @@ -735,7 +735,7 @@ mrb_str_squeeze(mrb_state *mrb, mrb_value str) * changes were made. */ static mrb_value -mrb_str_squeeze_bang(mrb_state *mrb, mrb_value str) +str_squeeze_bang(mrb_state *mrb, mrb_value str) { mrb_value pat = mrb_nil_value(); @@ -779,7 +779,7 @@ str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat) } static mrb_value -mrb_str_delete(mrb_state *mrb, mrb_value str) +str_delete_m(mrb_state *mrb, mrb_value str) { mrb_value pat; mrb_value dup; @@ -791,7 +791,7 @@ mrb_str_delete(mrb_state *mrb, mrb_value str) } static mrb_value -mrb_str_delete_bang(mrb_state *mrb, mrb_value str) +str_delete_bang(mrb_state *mrb, mrb_value str) { mrb_value pat; @@ -814,7 +814,7 @@ mrb_str_delete_bang(mrb_state *mrb, mrb_value str) * the end of a sequence or the end of a other_str. */ static mrb_value -mrb_str_count(mrb_state *mrb, mrb_value str) +str_count(mrb_state *mrb, mrb_value str) { mrb_value v_pat = mrb_nil_value(); mrb_int i; @@ -838,13 +838,13 @@ mrb_str_count(mrb_state *mrb, mrb_value str) } static mrb_value -mrb_str_hex(mrb_state *mrb, mrb_value self) +str_hex(mrb_state *mrb, mrb_value self) { return mrb_str_to_integer(mrb, self, 16, FALSE); } static mrb_value -mrb_str_oct(mrb_state *mrb, mrb_value self) +str_oct(mrb_state *mrb, mrb_value self) { return mrb_str_to_integer(mrb, self, 8, FALSE); } @@ -859,7 +859,7 @@ mrb_str_oct(mrb_state *mrb, mrb_value self) * a.chr #=> "a" */ static mrb_value -mrb_str_chr(mrb_state *mrb, mrb_value self) +str_chr(mrb_state *mrb, mrb_value self) { return mrb_str_substr(mrb, self, 0, 1); } @@ -879,7 +879,7 @@ mrb_str_chr(mrb_state *mrb, mrb_value self) * 230.chr("UTF-8") #=> "\u00E6" */ static mrb_value -mrb_int_chr(mrb_state *mrb, mrb_value num) +int_chr(mrb_state *mrb, mrb_value num) { mrb_value enc; mrb_bool enc_given; @@ -912,7 +912,7 @@ mrb_int_chr(mrb_state *mrb, mrb_value num) * a.succ #=> "abd" */ static mrb_value -mrb_str_succ_bang(mrb_state *mrb, mrb_value self) +str_succ_bang(mrb_state *mrb, mrb_value self) { mrb_value result; unsigned char *p, *e, *b, *t; @@ -990,12 +990,12 @@ mrb_str_succ_bang(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_str_succ(mrb_state *mrb, mrb_value self) +str_succ(mrb_state *mrb, mrb_value self) { mrb_value str; str = mrb_str_dup(mrb, self); - mrb_str_succ_bang(mrb, str); + str_succ_bang(mrb, str); return str; } @@ -1029,7 +1029,7 @@ utf8code(unsigned char* p, mrb_int limit) } static mrb_value -mrb_str_ord(mrb_state* mrb, mrb_value str) +str_ord(mrb_state* mrb, mrb_value str) { if (RSTRING_LEN(str) == 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string"); @@ -1037,14 +1037,50 @@ mrb_str_ord(mrb_state* mrb, mrb_value str) if (c < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid UTF-8 byte sequence"); return mrb_fixnum_value(c); } + +static mrb_value +str_codepoints(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + char *p = RSTRING_PTR(self); + mrb_int len = RSTRING_LEN(self); + char *e = p + len; + + mrb->c->ci->mid = 0; + result = mrb_ary_new(mrb); + while (p < e) { + mrb_int c = utf8code((unsigned char*)p, len); + mrb_ary_push(mrb, result, mrb_int_value(mrb, c)); + mrb_int ulen = mrb_utf8len(p, e); + len -= ulen; + p += ulen; + } + return result; +} #else static mrb_value -mrb_str_ord(mrb_state* mrb, mrb_value str) +str_ord(mrb_state* mrb, mrb_value str) { if (RSTRING_LEN(str) == 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string"); return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[0]); } + +static mrb_value +str_codepoints(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + char *p = RSTRING_PTR(self); + char *e = p + RSTRING_LEN(self); + + mrb->c->ci->mid = 0; + result = mrb_ary_new(mrb); + while (p < e) { + mrb_ary_push(mrb, result, mrb_int_value(mrb, (mrb_int)*p)); + p++; + } + return result; +} #endif /* @@ -1058,7 +1094,7 @@ mrb_str_ord(mrb_state* mrb, mrb_value str) * "hello".delete_prefix!("llo") #=> nil */ static mrb_value -mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self) +str_del_prefix_bang(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1092,7 +1128,7 @@ mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self) * "hello".delete_prefix("llo") #=> "hello" */ static mrb_value -mrb_str_del_prefix(mrb_state *mrb, mrb_value self) +str_del_prefix(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1116,7 +1152,7 @@ mrb_str_del_prefix(mrb_state *mrb, mrb_value self) * "hello".delete_suffix!("hel") #=> nil */ static mrb_value -mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self) +str_del_suffix_bang(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1148,7 +1184,7 @@ mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self) * "hello".delete_suffix("llo") #=> "hello" */ static mrb_value -mrb_str_del_suffix(mrb_state *mrb, mrb_value self) +str_del_suffix(mrb_state *mrb, mrb_value self) { mrb_int plen, slen; const char *ptr; @@ -1175,18 +1211,21 @@ mrb_str_del_suffix(mrb_state *mrb, mrb_value self) * "abcdef".casecmp("ABCDEF") #=> 0 */ static mrb_value -mrb_str_casecmp(mrb_state *mrb, mrb_value self) +str_casecmp(mrb_state *mrb, mrb_value self) { - mrb_value str; + mrb_value str = mrb_get_arg1(mrb); - 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)); + + mrb_int len1 = RSTR_LEN(s1); + mrb_int len2 = RSTR_LEN(s2); + mrb_int len = lesser(len1, len2); char *p1 = RSTR_PTR(s1); char *p2 = RSTR_PTR(s2); + if (p1 == p2) return mrb_fixnum_value(0); for (mrb_int i=0; i 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); + if (len1 == len2) return mrb_fixnum_value(0); + if (len1 > len2) return mrb_fixnum_value(1); return mrb_fixnum_value(-1); } @@ -1208,15 +1247,15 @@ mrb_str_casecmp(mrb_state *mrb, mrb_value self) * 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) +str_casecmp_p(mrb_state *mrb, mrb_value self) { - mrb_value c = mrb_str_casecmp(mrb, self); + mrb_value c = 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) +str_lines(mrb_state *mrb, mrb_value self) { mrb_value result; int ai; @@ -1248,7 +1287,7 @@ mrb_str_lines(mrb_state *mrb, mrb_value self) * Otherwise returns self.dup, which is not frozen. */ static mrb_value -mrb_str_uplus(mrb_state *mrb, mrb_value str) +str_uplus(mrb_state *mrb, mrb_value str) { if (mrb_frozen_p(mrb_obj_ptr(str))) { return mrb_str_dup(mrb, str); @@ -1270,7 +1309,7 @@ mrb_str_uplus(mrb_state *mrb, mrb_value str) * String#dedup is an alias for String#-@. */ static mrb_value -mrb_str_uminus(mrb_state *mrb, mrb_value str) +str_uminus(mrb_state *mrb, mrb_value str) { if (mrb_frozen_p(mrb_obj_ptr(str))) { return str; @@ -1283,42 +1322,43 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) { struct RClass * s = mrb->string_class; - mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "swapcase!", mrb_str_swapcase_bang, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "swapcase", mrb_str_swapcase, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "concat", mrb_str_concat_m, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "<<", mrb_str_concat_m, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "count", mrb_str_count, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "tr", mrb_str_tr, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "tr!", mrb_str_tr_bang, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "tr_s", mrb_str_tr_s, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "tr_s!", mrb_str_tr_s_bang, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "squeeze", mrb_str_squeeze, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, s, "squeeze!", mrb_str_squeeze_bang, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, s, "delete", mrb_str_delete, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "delete!", mrb_str_delete_bang, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "start_with?", mrb_str_start_with, MRB_ARGS_REST()); - mrb_define_method(mrb, s, "end_with?", mrb_str_end_with, MRB_ARGS_REST()); - mrb_define_method(mrb, s, "hex", mrb_str_hex, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "succ", mrb_str_succ, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "next", mrb_str_succ, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "next!", mrb_str_succ_bang, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE()); - mrb_define_method(mrb, s, "delete_prefix!", mrb_str_del_prefix_bang, MRB_ARGS_REQ(1)); - 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, "+@", mrb_str_uplus, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, s, "-@", mrb_str_uminus, MRB_ARGS_REQ(1)); - - mrb_define_method(mrb, s, "__lines", mrb_str_lines, MRB_ARGS_NONE()); - - mrb_define_method(mrb, mrb->integer_class, "chr", mrb_int_chr, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "swapcase!", str_swapcase_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "swapcase", str_swapcase, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "concat", str_concat_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "<<", str_concat_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "count", str_count, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "tr", str_tr_m, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "tr!", str_tr_bang, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "tr_s", str_tr_s, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "tr_s!", str_tr_s_bang, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "squeeze", str_squeeze_m, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "squeeze!", str_squeeze_bang, MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "delete", str_delete_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete!", str_delete_bang, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "start_with?", str_start_with, MRB_ARGS_REST()); + mrb_define_method(mrb, s, "end_with?", str_end_with, MRB_ARGS_REST()); + mrb_define_method(mrb, s, "hex", str_hex, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "oct", str_oct, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "chr", str_chr, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ", str_succ, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ!", str_succ_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "next", str_succ, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "next!", str_succ_bang, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "ord", str_ord, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "delete_prefix!", str_del_prefix_bang, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete_prefix", str_del_prefix, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete_suffix!", str_del_suffix_bang, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "delete_suffix", str_del_suffix, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "casecmp", str_casecmp, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "casecmp?", str_casecmp_p, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "+@", str_uplus, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "-@", str_uminus, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, s, "__lines", str_lines, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "__codepoints", str_codepoints, MRB_ARGS_NONE()); + + mrb_define_method(mrb, mrb->integer_class, "chr", int_chr, MRB_ARGS_OPT(1)); } void diff --git a/mruby/mrbgems/mruby-struct/mrblib/struct.rb b/mruby/mrbgems/mruby-struct/mrblib/struct.rb index f80c5451..20d9bde8 100644 --- a/mruby/mrbgems/mruby-struct/mrblib/struct.rb +++ b/mruby/mrbgems/mruby-struct/mrblib/struct.rb @@ -45,35 +45,6 @@ def select(&block) ary end - def _inspect(recur_list) - return "#" if recur_list[self.object_id] - recur_list[self.object_id] = true - name = self.class.to_s - if name[0] == "#" - str = "#" - end - - ## - # call-seq: - # struct.to_s -> string - # struct.inspect -> string - # - # Describe the contents of this struct in a string. - # - # 15.2.18.4.10(x) - # - def inspect - self._inspect({}) - end - ## # 15.2.18.4.11(x) # diff --git a/mruby/mrbgems/mruby-struct/src/struct.c b/mruby/mrbgems/mruby-struct/src/struct.c index 6dc0b5b0..757e4daf 100644 --- a/mruby/mrbgems/mruby-struct/src/struct.c +++ b/mruby/mrbgems/mruby-struct/src/struct.c @@ -30,7 +30,7 @@ struct_class(mrb_state *mrb) static void struct_corrupted(mrb_state *mrb) { - mrb_raise(mrb, E_TYPE_ERROR, "corrupted data"); + mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } static mrb_value @@ -45,27 +45,28 @@ struct_s_members(mrb_state *mrb, struct RClass *c) if (!mrb_array_p(members)) { struct_corrupted(mrb); } - break; + return members; } c = c->super; if (c == sclass || c == 0) { mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct"); } } - return members; } static mrb_value struct_members(mrb_state *mrb, mrb_value s) { - if (!mrb_struct_p(s) || RSTRUCT_LEN(s) == 0) { + if (!mrb_struct_p(s)) { struct_corrupted(mrb); } mrb_value members = struct_s_members(mrb, mrb_obj_class(mrb, s)); - if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { + mrb_int len = RSTRUCT_LEN(s); + mrb_int mlen = RARRAY_LEN(members); + if (len > 0 && len != mlen) { mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%i required %i given)", - RARRAY_LEN(members), RSTRUCT_LEN(s)); + mlen, len); } return members; } @@ -102,13 +103,25 @@ mrb_struct_members(mrb_state *mrb, mrb_value obj) return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj))); } +static mrb_int +num_members(mrb_state *mrb, mrb_value self) +{ + mrb_value members = struct_members(mrb, self); + return RARRAY_LEN(members); +} + static mrb_value mrb_struct_ref(mrb_state *mrb, mrb_value obj) { + mrb_int argc = mrb_get_argc(mrb); + if (argc != 0) { + mrb_argnum_error(mrb, argc, 0, 0); + } mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); + mrb_int len = num_members(mrb, obj); mrb_value *ptr = RSTRUCT_PTR(obj); - if (!ptr) return mrb_nil_value(); + if (!ptr || len <= i) return mrb_nil_value(); return ptr[i]; } @@ -126,7 +139,7 @@ mrb_id_attrset(mrb_state *mrb, mrb_sym id) name = mrb_sym_name_len(mrb, id, &len); if (len > ONSTACK_STRLEN_MAX) { - buf = (char *)mrb_malloc(mrb, (size_t)len+1); + buf = (char*)mrb_malloc(mrb, (size_t)len+1); } else { buf = onstack; @@ -145,18 +158,9 @@ static mrb_value mrb_struct_set_m(mrb_state *mrb, mrb_value obj) { mrb_int i = mrb_integer(mrb_proc_cfunc_env_get(mrb, 0)); - mrb_value *ptr; mrb_value val = mrb_get_arg1(mrb); - mrb_struct_modify(mrb, obj); - ptr = RSTRUCT_PTR(obj); - if (ptr == NULL || i >= RSTRUCT_LEN(obj)) { - mrb_ary_set(mrb, obj, i, val); - } - else { - ptr[i] = val; - mrb_field_write_barrier_value(mrb, mrb_basic_ptr(obj), val); - } + mrb_ary_set(mrb, obj, i, val); return val; } @@ -205,6 +209,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl } c = mrb_define_class_under_id(mrb, klass, id, klass); } + MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT); nstr = mrb_obj_value(c); mrb_iv_set(mrb, nstr, MRB_SYM(__members__), members); @@ -253,55 +258,46 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *kl static mrb_value mrb_struct_s_def(mrb_state *mrb, mrb_value klass) { - mrb_value name, rest; + mrb_value name = mrb_nil_value(); const mrb_value *pargv; mrb_int argcnt; - mrb_int i; mrb_value b, st; - mrb_sym id; const mrb_value *argv; mrb_int argc; - name = mrb_nil_value(); mrb_get_args(mrb, "*&", &argv, &argc, &b); - if (argc == 0) { /* special case to avoid crash */ - mrb_argnum_error(mrb, argc, 1, -1); + if (argc == 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (given 0, expected 1+)"); } - else { - pargv = argv; - argcnt = argc; - if (argc > 0) { - name = argv[0]; - if (mrb_symbol_p(name)) { - /* 1stArgument:symbol -> name=nil rest=argv[0..n] */ - name = mrb_nil_value(); - } - else { - pargv++; - argcnt--; + pargv = argv; + argcnt = argc; + if (argc > 0 && !mrb_symbol_p(argv[0])) { + /* 1stArgument:!symbol -> name=argv[0] rest=argv[0..n] */ + name = argv[0]; + pargv++; + argcnt--; + } + mrb_value members = mrb_ary_new_from_values(mrb, argcnt, pargv); + for (mrb_int i=0; i= RSTRUCT_LEN(s)) return mrb_nil_value(); return RSTRUCT_PTR(s)[idx]; } @@ -434,19 +432,16 @@ mrb_struct_aref(mrb_state *mrb, mrb_value s) static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) { - mrb_value members, *ptr; + mrb_value members; const mrb_value *ptr_members; mrb_int i, len; members = struct_members(mrb, s); len = RARRAY_LEN(members); - ptr = RSTRUCT_PTR(s); ptr_members = RARRAY_PTR(members); for (i=0; i string + * struct.inspect -> string + * + * Returns a string representation of Data + */ +static mrb_value +mrb_struct_to_s(mrb_state *mrb, mrb_value self) +{ + mrb_value members, ret, cname; + mrb_value *mems; + mrb_int mlen; + + mrb->c->ci->mid = MRB_SYM(inspect); + ret = mrb_str_new_lit(mrb, "#"); + return ret; + } + members = struct_members(mrb, self); + mlen = RARRAY_LEN(members); + mems = RARRAY_PTR(members); + for (mrb_int i=0; i0) mrb_str_cat_lit(mrb, ret, ", "); + mrb_str_cat(mrb, ret, name, len); + mrb_str_cat_lit(mrb, ret, "="); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, RARRAY_PTR(self)[i])); + mrb_gc_arena_restore(mrb, ai); + } + mrb_str_cat_lit(mrb, ret, ">"); + + return ret; +} + /* * A Struct is a convenient way to bundle a number of * attributes together, using accessor methods, without having to write @@ -656,7 +697,7 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) { struct RClass *st; st = mrb_define_class(mrb, "Struct", mrb->object_class); - MRB_SET_INSTANCE_TT(st, MRB_TT_STRUCT); + MRB_SET_INSTANCE_TT(st, MRB_TT_UNDEF); mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ @@ -667,6 +708,8 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) mrb_define_method(mrb, st, "initialize", mrb_struct_initialize, MRB_ARGS_ANY()); /* 15.2.18.4.8 */ mrb_define_method(mrb, st, "initialize_copy", mrb_struct_init_copy, MRB_ARGS_REQ(1)); /* 15.2.18.4.9 */ mrb_define_method(mrb, st, "eql?", mrb_struct_eql, MRB_ARGS_REQ(1)); /* 15.2.18.4.12(x) */ + mrb_define_method(mrb, st, "to_s", mrb_struct_to_s, MRB_ARGS_NONE()); /* 15.2.18.4.11(x) */ + mrb_define_method(mrb, st, "inspect", mrb_struct_to_s, MRB_ARGS_NONE()); /* 15.2.18.4.10(x) */ mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE()); mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE()); diff --git a/mruby/mrbgems/mruby-struct/test/struct.rb b/mruby/mrbgems/mruby-struct/test/struct.rb index db0fa56d..384a9206 100644 --- a/mruby/mrbgems/mruby-struct/test/struct.rb +++ b/mruby/mrbgems/mruby-struct/test/struct.rb @@ -119,7 +119,7 @@ c = Struct.new(:m1, :m2, :m3, :m4, :m5, :recur) cc = c.new(1,2,3,4,5,nil) cc.recur = cc - assert_equal "#>", cc.inspect + assert_equal "#>", cc.inspect end assert('Struct#length, Struct#size') do diff --git a/mruby/mrbgems/mruby-test-inline-struct/test/inline.c b/mruby/mrbgems/mruby-test-inline-struct/test/inline.c index a54bf2b0..c92caa5d 100644 --- a/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +++ b/mruby/mrbgems/mruby-test-inline-struct/test/inline.c @@ -56,9 +56,8 @@ istruct_test_test_receive(mrb_state *mrb, mrb_value self) static mrb_value istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self) { - mrb_value is; + mrb_value is = mrb_get_arg1(mrb); struct RClass *klass = mrb_class_get(mrb, "InlineStructTest"); - mrb_get_args(mrb, "o", &is); /* if you need to protect istruct retrieval from untrusted code, you need to care about class replacing. See mrbgem/mruby-random/src/random.c for detail */ diff --git a/mruby/mrbgems/mruby-test/driver.c b/mruby/mrbgems/mruby-test/driver.c index 0ccba9ea..96ae3e07 100644 --- a/mruby/mrbgems/mruby-test/driver.c +++ b/mruby/mrbgems/mruby-test/driver.c @@ -172,7 +172,7 @@ str_match_p(mrb_state *mrb, if (lbrace && rbrace) { /* expand brace */ - char *ex_pat = (char *)mrb_malloc(mrb, pat_len-2); /* expanded pattern */ + char *ex_pat = (char*)mrb_malloc(mrb, pat_len-2); /* expanded pattern */ char *ex_p = ex_pat; COPY_AND_INC(ex_p, pat, lbrace-pat); diff --git a/mruby/mrbgems/mruby-test/mrbgem.rake b/mruby/mrbgems/mruby-test/mrbgem.rake index 927447b4..c8070dd0 100644 --- a/mruby/mrbgems/mruby-test/mrbgem.rake +++ b/mruby/mrbgems/mruby-test/mrbgem.rake @@ -66,37 +66,29 @@ MRuby::Gem::Specification.new('mruby-test') do |spec| f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] unless g.test_rbfiles.empty? - f.puts %Q[ mrb_state *mrb2;] unless g.test_args.empty? f.puts %Q[ mrb_value test_args_hash;] end - f.puts %Q[ int ai;] + f.puts %Q[ mrb_state *mrb2 = mrb_open_core(mrb_default_allocf, NULL);] + f.puts %Q[ if (mrb2 == NULL) {] + f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __func__);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] + if test_preload.nil? + f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] + else + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] + end + dep_list.each do |d| + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] + end + f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] + f.puts %Q[ ] g.test_rbfiles.count.times do |i| - f.puts %Q[ ai = mrb_gc_arena_save(mrb);] - f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] - f.puts %Q[ if (mrb2 == NULL) {] - f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __func__);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - dep_list.each do |d| - f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] - f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] - end - f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] - if test_preload.nil? - f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] - else - f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] - end - f.puts %Q[ if (mrb2->exc) {] - f.puts %Q[ mrb_print_error(mrb2);] - f.puts %Q[ mrb_close(mrb2);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] - unless g.test_args.empty? - f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ] + f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb2, #{g.test_args.length}); ] g.test_args.each do |arg_name, arg_value| escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"') escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"') @@ -106,14 +98,16 @@ MRuby::Gem::Specification.new('mruby-test') do |spec| end f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] if g.custom_test_init? - f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] + f.puts %Q[ if (mrb2->exc) {] + f.puts %Q[ mrb_print_error(mrb2);] + f.puts %Q[ mrb_close(mrb2);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] f.puts %Q[ ] - - f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] - f.puts %Q[ mrb_close(mrb2);] - f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] end + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] + f.puts %Q[ mrb_close(mrb2);] end f.puts %Q[}] end @@ -144,14 +138,26 @@ MRuby::Gem::Specification.new('mruby-test') do |spec| f.puts %Q[ * All manual changes will get lost.] f.puts %Q[ */] f.puts %Q[] - f.puts %Q[struct mrb_state;] - f.puts %Q[typedef struct mrb_state mrb_state;] + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[] build.gems.each do |g| f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] end f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] build.gems.each do |g| - f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] + if g.skip_test? + f.puts %Q[ do {] + f.puts %Q[ mrb_value asserts = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$asserts"));] + f.puts %Q[ mrb_ary_push(mrb, asserts, mrb_str_new_lit(mrb, ] + f.puts %Q[ "Warn: Skipping tests for gem (#{ + g.name == 'mruby-test' ? 'core' : "mrbgems: #{g.name}" + })"));] + f.puts %Q[ } while (0);] + else + f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] + end end f.puts %Q[}] end diff --git a/mruby/mrbgems/mruby-time/mrblib/time.rb b/mruby/mrbgems/mruby-time/mrblib/time.rb deleted file mode 100644 index df0d8ca8..00000000 --- a/mruby/mrbgems/mruby-time/mrblib/time.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Time - def sunday?; wday == 0 end - def monday?; wday == 1 end - def tuesday?; wday == 2 end - def wednesday?; wday == 3 end - def thursday?; wday == 4 end - def friday?; wday == 5 end - def saturday?; wday == 6 end -end diff --git a/mruby/mrbgems/mruby-time/src/time.c b/mruby/mrbgems/mruby-time/src/time.c index 63a9d252..001d46b7 100644 --- a/mruby/mrbgems/mruby-time/src/time.c +++ b/mruby/mrbgems/mruby-time/src/time.c @@ -157,10 +157,11 @@ timegm(struct tm *tm) unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+1900)]; static const int epoch_year = 70; - if(tm->tm_year >= epoch_year) { + if (tm->tm_year >= epoch_year) { for (i = epoch_year; i < tm->tm_year; ++i) r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; - } else { + } + else { for (i = tm->tm_year; i < epoch_year; ++i) r -= is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; } @@ -196,16 +197,7 @@ struct mrb_time { struct tm datetime; }; -static const struct mrb_data_type mrb_time_type = { "Time", mrb_free }; - -#ifndef MRB_NO_FLOAT -void mrb_check_num_exact(mrb_state *mrb, mrb_float num); -typedef mrb_float mrb_sec; -#define mrb_sec_value(mrb, sec) mrb_float_value(mrb, sec) -#else -typedef mrb_int mrb_sec; -#define mrb_sec_value(mrb, sec) mrb_int_value(mrb, sec) -#endif +static const struct mrb_data_type time_type = { "Time", mrb_free }; #define MRB_TIME_T_UINT (~(time_t)0 > 0) #define MRB_TIME_MIN ( \ @@ -217,7 +209,6 @@ typedef mrb_int mrb_sec; (sizeof(time_t) <= 4 ? INT32_MAX : INT64_MAX) \ ) -#ifndef MRB_NO_FLOAT /* return true if time_t is fit in mrb_int */ static mrb_bool fixable_time_t_p(time_t v) @@ -228,7 +219,6 @@ fixable_time_t_p(time_t v) if (MRB_INT_MIN > (mrb_int)v) return FALSE; return TRUE; } -#endif static time_t mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) @@ -247,16 +237,41 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) } if (usec) { - t = (time_t)f; - *usec = (time_t)llround((f - t) * 1.0e+6); + double tt = floor(f); + if (!isfinite(tt)) goto out_of_range; + t = (time_t)tt; + *usec = (time_t)trunc((f - tt) * 1.0e+6); } else { - t = (time_t)llround(f); + double tt = round(f); + if (!isfinite(tt)) goto out_of_range; + t = (time_t)tt; } } break; #endif /* MRB_NO_FLOAT */ - default: + +#ifdef MRB_USE_BIGINT + case MRB_TT_BIGINT: + { + if (sizeof(time_t) > sizeof(mrb_int)) { + if (MRB_TIME_T_UINT) { + t = (time_t)mrb_bint_as_uint64(mrb, obj); + } + else { + t = (time_t)mrb_bint_as_int64(mrb, obj); + } + if (usec) { *usec = 0; } + break; + } + else { + mrb_int i = mrb_bint_as_int(mrb, obj); + obj = mrb_int_value(mrb, i); + } + } + /* fall through */ +#endif /* MRB_USE_BIGINT */ + case MRB_TT_INTEGER: { mrb_int i = mrb_integer(obj); @@ -270,6 +285,10 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) if (usec) { *usec = 0; } } break; + + default: + mrb_raisef(mrb, E_TYPE_ERROR, "cannot convert %Y to time", obj); + return 0; } return t; @@ -278,10 +297,29 @@ mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", obj); /* not reached */ - if (usec) { *usec = 0; } return 0; } +static mrb_value +time_value_from_time_t(mrb_state *mrb, time_t t) +{ + if (!fixable_time_t_p(t)) { +#if defined(MRB_USE_BIGINT) + if (MRB_TIME_T_UINT) { + return mrb_bint_new_uint64(mrb, (uint64_t)t); + } + else { + return mrb_bint_new_int64(mrb, (int64_t)t); + } +#elif !defined(MRB_NO_FLOAT) + return mrb_float_value(mrb, (mrb_float)t); +#else + mrb_raisef(mrb, E_ARGUMENT_ERROR, "Time too big"); +#endif + } + return mrb_int_value(mrb, (mrb_int)t); +} + /** Updates the datetime of a mrb_time based on it's timezone and seconds setting. Returns self on success, NULL of failure. if `dealloc` is set `true`, it frees `self` on error. */ @@ -298,10 +336,8 @@ time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc) aid = localtime_r(&t, &self->datetime); } if (!aid) { - mrb_sec sec = (mrb_sec)t; - if (dealloc) mrb_free(mrb, self); - mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", mrb_sec_value(mrb, sec)); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", time_value_from_time_t(mrb, t)); /* not reached */ return NULL; } @@ -313,9 +349,9 @@ time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc) } static mrb_value -mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm) +time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm) { - return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &mrb_time_type, tm)); + return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &time_type, tm)); } /* Allocates a mrb_time object and initializes it. */ @@ -324,10 +360,10 @@ time_alloc_time(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone timez { struct mrb_time *tm; - tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); + tm = (struct mrb_time*)mrb_malloc(mrb, sizeof(struct mrb_time)); tm->sec = sec; tm->usec = usec; - if (MRB_TIME_T_UINT && tm->usec < 0) { + if (!MRB_TIME_T_UINT && tm->usec < 0) { long sec2 = (long)NDIV(tm->usec,1000000); /* negative div */ tm->usec -= sec2 * 1000000; tm->sec += sec2; @@ -355,15 +391,15 @@ time_alloc(mrb_state *mrb, mrb_value sec, mrb_value usec, enum mrb_timezone time } static mrb_value -mrb_time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone) +time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone) { - return mrb_time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone)); + return time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone)); } static mrb_value -mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone) +time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone) { - return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone)); + return time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone)); } static struct mrb_time* @@ -411,7 +447,7 @@ current_mrb_time(mrb_state *mrb) usec = tv.tv_usec; } #endif - tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + tm = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm)); *tm = tmzero; tm->sec = sec; tm->usec = usec; tm->timezone = MRB_TIMEZONE_LOCAL; @@ -422,28 +458,28 @@ current_mrb_time(mrb_state *mrb) /* Allocates a new Time object with given millis value. */ static mrb_value -mrb_time_now(mrb_state *mrb, mrb_value self) +time_now(mrb_state *mrb, mrb_value self) { - return mrb_time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb)); + return time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb)); } MRB_API mrb_value -mrb_time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone) +time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone) { - return mrb_time_make_time(mrb, mrb_class_get_id(mrb, MRB_SYM(Time)), sec, usec, zone); + return time_make_time(mrb, mrb_class_get_id(mrb, MRB_SYM(Time)), sec, usec, zone); } /* 15.2.19.6.1 */ /* Creates an instance of time at the given time in seconds, etc. */ static mrb_value -mrb_time_at_m(mrb_state *mrb, mrb_value self) +time_at_m(mrb_state *mrb, mrb_value self) { mrb_value sec; mrb_value usec = mrb_fixnum_value(0); mrb_get_args(mrb, "o|o", &sec, &usec); - return mrb_time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL); + return time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL); } static struct mrb_time* @@ -460,7 +496,8 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, #define OUTINT(x) 0 #endif - if (ayear < 1900 || OUTINT(ayear-1900) || + ayear -= 1900; + if (OUTINT(ayear) || amonth < 1 || amonth > 12 || aday < 1 || aday > 31 || ahour < 0 || ahour > 24 || @@ -469,7 +506,7 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, asec < 0 || asec > 60) mrb_raise(mrb, E_ARGUMENT_ERROR, "argument out of range"); - nowtime.tm_year = (int)(ayear - 1900); + nowtime.tm_year = (int)ayear; nowtime.tm_mon = (int)(amonth - 1); nowtime.tm_mday = (int)aday; nowtime.tm_hour = (int)ahour; @@ -500,13 +537,13 @@ time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday, /* 15.2.19.6.2 */ /* Creates an instance of time at the given time in UTC. */ static mrb_value -mrb_time_gm(mrb_state *mrb, mrb_value self) +time_gm(mrb_state *mrb, mrb_value self) { mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; mrb_get_args(mrb, "i|iiiiii", &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); - return mrb_time_wrap(mrb, mrb_class_ptr(self), + return time_wrap(mrb, mrb_class_ptr(self), time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_UTC)); } @@ -514,13 +551,13 @@ mrb_time_gm(mrb_state *mrb, mrb_value self) /* 15.2.19.6.3 */ /* Creates an instance of time at the given time in local time zone. */ static mrb_value -mrb_time_local(mrb_state *mrb, mrb_value self) +time_local(mrb_state *mrb, mrb_value self) { mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; mrb_get_args(mrb, "i|iiiiii", &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); - return mrb_time_wrap(mrb, mrb_class_ptr(self), + return time_wrap(mrb, mrb_class_ptr(self), time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL)); } @@ -529,7 +566,7 @@ time_get_ptr(mrb_state *mrb, mrb_value time) { struct mrb_time *tm; - tm = DATA_GET_PTR(mrb, time, &mrb_time_type, struct mrb_time); + tm = DATA_GET_PTR(mrb, time, &time_type, struct mrb_time); if (!tm) { mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); } @@ -537,27 +574,27 @@ time_get_ptr(mrb_state *mrb, mrb_value time) } static mrb_value -mrb_time_eq(mrb_state *mrb, mrb_value self) +time_eq(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); struct mrb_time *tm1, *tm2; mrb_bool eq_p; - tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); - tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + tm1 = DATA_GET_PTR(mrb, self, &time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time); eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->usec == tm2->usec; return mrb_bool_value(eq_p); } static mrb_value -mrb_time_cmp(mrb_state *mrb, mrb_value self) +time_cmp(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); struct mrb_time *tm1, *tm2; - tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); - tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + tm1 = DATA_GET_PTR(mrb, self, &time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time); if (!tm1 || !tm2) return mrb_nil_value(); if (tm1->sec > tm2->sec) { return mrb_fixnum_value(1); @@ -582,7 +619,7 @@ int_overflow(mrb_state *mrb, const char *reason) } static mrb_value -mrb_time_plus(mrb_state *mrb, mrb_value self) +time_plus(mrb_state *mrb, mrb_value self) { mrb_value o = mrb_get_arg1(mrb); struct mrb_time *tm; @@ -607,22 +644,22 @@ mrb_time_plus(mrb_state *mrb, mrb_value self) } sec = tm->sec + sec; #endif - return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec+usec, tm->timezone); + return time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec+usec, tm->timezone); } static mrb_value -mrb_time_minus(mrb_state *mrb, mrb_value self) +time_minus(mrb_state *mrb, mrb_value self) { mrb_value other = mrb_get_arg1(mrb); struct mrb_time *tm, *tm2; tm = time_get_ptr(mrb, self); - tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); + tm2 = DATA_CHECK_GET_PTR(mrb, other, &time_type, struct mrb_time); if (tm2) { #ifndef MRB_NO_FLOAT mrb_float f; - f = (mrb_sec)(tm->sec - tm2->sec) - + (mrb_sec)(tm->usec - tm2->usec) / 1.0e6; + f = (mrb_float)(tm->sec - tm2->sec) + + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; return mrb_float_value(mrb, f); #else mrb_int f; @@ -651,14 +688,14 @@ mrb_time_minus(mrb_state *mrb, mrb_value self) } sec = tm->sec - sec; #endif - return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec-usec, tm->timezone); + return time_make_time(mrb, mrb_obj_class(mrb, self), sec, tm->usec-usec, tm->timezone); } } /* 15.2.19.7.30 */ /* Returns week day number of time. */ static mrb_value -mrb_time_wday(mrb_state *mrb, mrb_value self) +time_wday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -669,7 +706,7 @@ mrb_time_wday(mrb_state *mrb, mrb_value self) /* 15.2.19.7.31 */ /* Returns year day number of time. */ static mrb_value -mrb_time_yday(mrb_state *mrb, mrb_value self) +time_yday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -680,7 +717,7 @@ mrb_time_yday(mrb_state *mrb, mrb_value self) /* 15.2.19.7.32 */ /* Returns year of time. */ static mrb_value -mrb_time_year(mrb_state *mrb, mrb_value self) +time_year(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -708,7 +745,7 @@ time_zonename(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t len) /* 15.2.19.7.33 */ /* Returns name of time's timezone. */ static mrb_value -mrb_time_zone(mrb_state *mrb, mrb_value self) +time_zone(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); if (tm->timezone == MRB_TIMEZONE_UTC) { @@ -722,7 +759,7 @@ mrb_time_zone(mrb_state *mrb, mrb_value self) /* 15.2.19.7.4 */ /* Returns a string that describes the time. */ static mrb_value -mrb_time_asctime(mrb_state *mrb, mrb_value self) +time_asctime(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); struct tm *d = &tm->datetime; @@ -750,7 +787,7 @@ mrb_time_asctime(mrb_state *mrb, mrb_value self) /* 15.2.19.7.6 */ /* Returns the day in the month of the time. */ static mrb_value -mrb_time_day(mrb_state *mrb, mrb_value self) +time_day(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -762,7 +799,7 @@ mrb_time_day(mrb_state *mrb, mrb_value self) /* 15.2.19.7.7 */ /* Returns true if daylight saving was applied for this time. */ static mrb_value -mrb_time_dst_p(mrb_state *mrb, mrb_value self) +time_dst_p(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -774,37 +811,37 @@ mrb_time_dst_p(mrb_state *mrb, mrb_value self) /* 15.2.19.7.10 */ /* Returns the Time object of the UTC(GMT) timezone. */ static mrb_value -mrb_time_getutc(mrb_state *mrb, mrb_value self) +time_getutc(mrb_state *mrb, mrb_value self) { struct mrb_time *tm, *tm2; tm = time_get_ptr(mrb, self); - tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + tm2 = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_UTC; time_update_datetime(mrb, tm2, TRUE); - return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); + return time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } /* 15.2.19.7.9 */ /* Returns the Time object of the LOCAL timezone. */ static mrb_value -mrb_time_getlocal(mrb_state *mrb, mrb_value self) +time_getlocal(mrb_state *mrb, mrb_value self) { struct mrb_time *tm, *tm2; tm = time_get_ptr(mrb, self); - tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); + tm2 = (struct mrb_time*)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_LOCAL; time_update_datetime(mrb, tm2, TRUE); - return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); + return time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } /* 15.2.19.7.15 */ /* Returns hour of time. */ static mrb_value -mrb_time_hour(mrb_state *mrb, mrb_value self) +time_hour(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -815,7 +852,7 @@ mrb_time_hour(mrb_state *mrb, mrb_value self) /* 15.2.19.7.16 */ /* Initializes a time by setting the amount of milliseconds since the epoch.*/ static mrb_value -mrb_time_initialize(mrb_state *mrb, mrb_value self) +time_init(mrb_state *mrb, mrb_value self) { mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0; @@ -828,7 +865,7 @@ mrb_time_initialize(mrb_state *mrb, mrb_value self) if (tm) { mrb_free(mrb, tm); } - mrb_data_init(self, NULL, &mrb_time_type); + mrb_data_init(self, NULL, &time_type); if (n == 0) { tm = current_mrb_time(mrb); @@ -836,14 +873,14 @@ mrb_time_initialize(mrb_state *mrb, mrb_value self) else { tm = time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL); } - mrb_data_init(self, tm, &mrb_time_type); + mrb_data_init(self, tm, &time_type); return self; } /* 15.2.19.7.17(x) */ /* Initializes a copy of this time object. */ static mrb_value -mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) +time_init_copy(mrb_state *mrb, mrb_value copy) { mrb_value src = mrb_get_arg1(mrb); struct mrb_time *t1, *t2; @@ -852,14 +889,14 @@ mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } - t1 = (struct mrb_time *)DATA_PTR(copy); - t2 = (struct mrb_time *)DATA_PTR(src); + t1 = (struct mrb_time*)DATA_PTR(copy); + t2 = (struct mrb_time*)DATA_PTR(src); if (!t2) { mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); } if (!t1) { - t1 = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); - mrb_data_init(copy, t1, &mrb_time_type); + t1 = (struct mrb_time*)mrb_malloc(mrb, sizeof(struct mrb_time)); + mrb_data_init(copy, t1, &time_type); } *t1 = *t2; return copy; @@ -868,7 +905,7 @@ mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) /* 15.2.19.7.18 */ /* Sets the timezone attribute of the Time object to LOCAL. */ static mrb_value -mrb_time_localtime(mrb_state *mrb, mrb_value self) +time_localtime(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -881,7 +918,7 @@ mrb_time_localtime(mrb_state *mrb, mrb_value self) /* 15.2.19.7.19 */ /* Returns day of month of time. */ static mrb_value -mrb_time_mday(mrb_state *mrb, mrb_value self) +time_mday(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -892,7 +929,7 @@ mrb_time_mday(mrb_state *mrb, mrb_value self) /* 15.2.19.7.20 */ /* Returns minutes of time. */ static mrb_value -mrb_time_min(mrb_state *mrb, mrb_value self) +time_min(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -903,7 +940,7 @@ mrb_time_min(mrb_state *mrb, mrb_value self) /* 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) +time_mon(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -914,7 +951,7 @@ mrb_time_mon(mrb_state *mrb, mrb_value self) /* 15.2.19.7.23 */ /* Returns seconds in minute of time. */ static mrb_value -mrb_time_sec(mrb_state *mrb, mrb_value self) +time_sec(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -926,7 +963,7 @@ mrb_time_sec(mrb_state *mrb, mrb_value self) /* 15.2.19.7.24 */ /* Returns a Float with the time since the epoch in seconds. */ static mrb_value -mrb_time_to_f(mrb_state *mrb, mrb_value self) +time_to_f(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -938,23 +975,18 @@ mrb_time_to_f(mrb_state *mrb, mrb_value self) /* 15.2.19.7.25 */ /* Returns an Integer with the time since the epoch in seconds. */ static mrb_value -mrb_time_to_i(mrb_state *mrb, mrb_value self) +time_to_i(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; tm = time_get_ptr(mrb, self); -#ifndef MRB_NO_FLOAT - if (!fixable_time_t_p(tm->sec)) { - return mrb_float_value(mrb, (mrb_float)tm->sec); - } -#endif - return mrb_int_value(mrb, (mrb_int)tm->sec); + return time_value_from_time_t(mrb, tm->sec); } /* 15.2.19.7.26 */ /* Returns the number of microseconds for time. */ static mrb_value -mrb_time_usec(mrb_state *mrb, mrb_value self) +time_usec(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -965,7 +997,7 @@ mrb_time_usec(mrb_state *mrb, mrb_value self) /* 15.2.19.7.27 */ /* Sets the timezone attribute of the Time object to UTC. */ static mrb_value -mrb_time_utc(mrb_state *mrb, mrb_value self) +time_utc(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -978,7 +1010,7 @@ mrb_time_utc(mrb_state *mrb, mrb_value self) /* 15.2.19.7.28 */ /* Returns true if this time is in the UTC timezone false if not. */ static mrb_value -mrb_time_utc_p(mrb_state *mrb, mrb_value self) +time_utc_p(mrb_state *mrb, mrb_value self) { struct mrb_time *tm; @@ -987,7 +1019,7 @@ mrb_time_utc_p(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_time_to_s(mrb_state *mrb, mrb_value self) +time_to_s(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); char buf[64]; @@ -1006,7 +1038,7 @@ mrb_time_to_s(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_time_hash(mrb_state *mrb, mrb_value self) +time_hash(mrb_state *mrb, mrb_value self) { struct mrb_time *tm = time_get_ptr(mrb, self); uint32_t hash = mrb_byte_hash((uint8_t*)&tm->sec, sizeof(time_t)); @@ -1015,6 +1047,52 @@ mrb_time_hash(mrb_state *mrb, mrb_value self) return mrb_int_value(mrb, hash); } +#define wday_impl(num) \ + struct mrb_time *tm = time_get_ptr(mrb, self);\ + return mrb_bool_value(tm->datetime.tm_wday == (num)); + +static mrb_value +time_sunday(mrb_state *mrb, mrb_value self) +{ + wday_impl(0); +} + +static mrb_value +time_monday(mrb_state *mrb, mrb_value self) +{ + wday_impl(1); +} + +static mrb_value +time_tuesday(mrb_state *mrb, mrb_value self) +{ + wday_impl(2); +} + +static mrb_value +time_wednesday(mrb_state *mrb, mrb_value self) +{ + wday_impl(3); +} + +static mrb_value +time_thursday(mrb_state *mrb, mrb_value self) +{ + wday_impl(4); +} + +static mrb_value +time_friday(mrb_state *mrb, mrb_value self) +{ + wday_impl(5); +} + +static mrb_value +time_saturday(mrb_state *mrb, mrb_value self) +{ + wday_impl(6); +} + void mrb_mruby_time_gem_init(mrb_state* mrb) { @@ -1023,53 +1101,61 @@ mrb_mruby_time_gem_init(mrb_state* mrb) tc = mrb_define_class(mrb, "Time", mrb->object_class); MRB_SET_INSTANCE_TT(tc, MRB_TT_CDATA); mrb_include_module(mrb, tc, mrb_module_get(mrb, "Comparable")); - mrb_define_class_method(mrb, tc, "at", mrb_time_at_m, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */ - mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */ - mrb_define_class_method(mrb, tc, "local", mrb_time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */ - mrb_define_class_method(mrb, tc, "mktime", mrb_time_local, MRB_ARGS_ARG(1,6));/* 15.2.19.6.4 */ - mrb_define_class_method(mrb, tc, "now", mrb_time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */ - mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */ - - mrb_define_method(mrb, tc, "hash" , mrb_time_hash , MRB_ARGS_NONE()); - mrb_define_method(mrb, tc, "eql?" , mrb_time_eq , MRB_ARGS_REQ(1)); - mrb_define_method(mrb, tc, "==" , mrb_time_eq , MRB_ARGS_REQ(1)); - mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */ - mrb_define_method(mrb, tc, "+" , mrb_time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */ - mrb_define_method(mrb, tc, "-" , mrb_time_minus , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */ - mrb_define_method(mrb, tc, "to_s" , mrb_time_to_s , MRB_ARGS_NONE()); - mrb_define_method(mrb, tc, "inspect", mrb_time_to_s , MRB_ARGS_NONE()); - mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */ - mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */ - mrb_define_method(mrb, tc, "day" , mrb_time_day , MRB_ARGS_NONE()); /* 15.2.19.7.6 */ - mrb_define_method(mrb, tc, "dst?" , mrb_time_dst_p , MRB_ARGS_NONE()); /* 15.2.19.7.7 */ - mrb_define_method(mrb, tc, "getgm" , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.8 */ - mrb_define_method(mrb, tc, "getlocal",mrb_time_getlocal,MRB_ARGS_NONE()); /* 15.2.19.7.9 */ - mrb_define_method(mrb, tc, "getutc" , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.10 */ - mrb_define_method(mrb, tc, "gmt?" , mrb_time_utc_p , MRB_ARGS_NONE()); /* 15.2.19.7.11 */ - mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc , MRB_ARGS_NONE()); /* 15.2.19.7.13 */ - mrb_define_method(mrb, tc, "hour" , mrb_time_hour, MRB_ARGS_NONE()); /* 15.2.19.7.15 */ - mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, MRB_ARGS_NONE()); /* 15.2.19.7.18 */ - mrb_define_method(mrb, tc, "mday" , mrb_time_mday, MRB_ARGS_NONE()); /* 15.2.19.7.19 */ - mrb_define_method(mrb, tc, "min" , mrb_time_min, MRB_ARGS_NONE()); /* 15.2.19.7.20 */ - - mrb_define_method(mrb, tc, "mon" , mrb_time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.21 */ - mrb_define_method(mrb, tc, "month", mrb_time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.22 */ - - mrb_define_method(mrb, tc, "sec" , mrb_time_sec, MRB_ARGS_NONE()); /* 15.2.19.7.23 */ - mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, MRB_ARGS_NONE()); /* 15.2.19.7.25 */ + mrb_define_class_method(mrb, tc, "at", time_at_m, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */ + mrb_define_class_method(mrb, tc, "gm", time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */ + mrb_define_class_method(mrb, tc, "local", time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */ + mrb_define_class_method(mrb, tc, "mktime", time_local, MRB_ARGS_ARG(1,6));/* 15.2.19.6.4 */ + mrb_define_class_method(mrb, tc, "now", time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */ + mrb_define_class_method(mrb, tc, "utc", time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */ + + mrb_define_method(mrb, tc, "hash" , time_hash , MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "eql?" , time_eq , MRB_ARGS_REQ(1)); + mrb_define_method(mrb, tc, "==" , time_eq , MRB_ARGS_REQ(1)); + mrb_define_method(mrb, tc, "<=>" , time_cmp , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */ + mrb_define_method(mrb, tc, "+" , time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */ + mrb_define_method(mrb, tc, "-" , time_minus , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */ + mrb_define_method(mrb, tc, "to_s" , time_to_s , MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "inspect", time_to_s , MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "asctime", time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */ + mrb_define_method(mrb, tc, "ctime" , time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */ + mrb_define_method(mrb, tc, "day" , time_day , MRB_ARGS_NONE()); /* 15.2.19.7.6 */ + mrb_define_method(mrb, tc, "dst?" , time_dst_p , MRB_ARGS_NONE()); /* 15.2.19.7.7 */ + mrb_define_method(mrb, tc, "getgm" , time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.8 */ + mrb_define_method(mrb, tc, "getlocal",time_getlocal,MRB_ARGS_NONE()); /* 15.2.19.7.9 */ + mrb_define_method(mrb, tc, "getutc" , time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.10 */ + mrb_define_method(mrb, tc, "gmt?" , time_utc_p , MRB_ARGS_NONE()); /* 15.2.19.7.11 */ + mrb_define_method(mrb, tc, "gmtime" , time_utc , MRB_ARGS_NONE()); /* 15.2.19.7.13 */ + mrb_define_method(mrb, tc, "hour" , time_hour, MRB_ARGS_NONE()); /* 15.2.19.7.15 */ + mrb_define_method(mrb, tc, "localtime", time_localtime, MRB_ARGS_NONE()); /* 15.2.19.7.18 */ + mrb_define_method(mrb, tc, "mday" , time_mday, MRB_ARGS_NONE()); /* 15.2.19.7.19 */ + mrb_define_method(mrb, tc, "min" , time_min, MRB_ARGS_NONE()); /* 15.2.19.7.20 */ + + mrb_define_method(mrb, tc, "mon" , time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.21 */ + mrb_define_method(mrb, tc, "month", time_mon, MRB_ARGS_NONE()); /* 15.2.19.7.22 */ + + mrb_define_method(mrb, tc, "sec" , time_sec, MRB_ARGS_NONE()); /* 15.2.19.7.23 */ + mrb_define_method(mrb, tc, "to_i", time_to_i, MRB_ARGS_NONE()); /* 15.2.19.7.25 */ #ifndef MRB_NO_FLOAT - mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, MRB_ARGS_NONE()); /* 15.2.19.7.24 */ + mrb_define_method(mrb, tc, "to_f", time_to_f, MRB_ARGS_NONE()); /* 15.2.19.7.24 */ #endif - mrb_define_method(mrb, tc, "usec", mrb_time_usec, MRB_ARGS_NONE()); /* 15.2.19.7.26 */ - mrb_define_method(mrb, tc, "utc" , mrb_time_utc, MRB_ARGS_NONE()); /* 15.2.19.7.27 */ - mrb_define_method(mrb, tc, "utc?", mrb_time_utc_p,MRB_ARGS_NONE()); /* 15.2.19.7.28 */ - mrb_define_method(mrb, tc, "wday", mrb_time_wday, MRB_ARGS_NONE()); /* 15.2.19.7.30 */ - mrb_define_method(mrb, tc, "yday", mrb_time_yday, MRB_ARGS_NONE()); /* 15.2.19.7.31 */ - mrb_define_method(mrb, tc, "year", mrb_time_year, MRB_ARGS_NONE()); /* 15.2.19.7.32 */ - mrb_define_method(mrb, tc, "zone", mrb_time_zone, MRB_ARGS_NONE()); /* 15.2.19.7.33 */ - - mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, MRB_ARGS_REQ(1)); /* 15.2.19.7.16 */ - mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.19.7.17 */ + mrb_define_method(mrb, tc, "usec", time_usec, MRB_ARGS_NONE()); /* 15.2.19.7.26 */ + mrb_define_method(mrb, tc, "utc" , time_utc, MRB_ARGS_NONE()); /* 15.2.19.7.27 */ + mrb_define_method(mrb, tc, "utc?", time_utc_p,MRB_ARGS_NONE()); /* 15.2.19.7.28 */ + mrb_define_method(mrb, tc, "wday", time_wday, MRB_ARGS_NONE()); /* 15.2.19.7.30 */ + mrb_define_method(mrb, tc, "yday", time_yday, MRB_ARGS_NONE()); /* 15.2.19.7.31 */ + mrb_define_method(mrb, tc, "year", time_year, MRB_ARGS_NONE()); /* 15.2.19.7.32 */ + mrb_define_method(mrb, tc, "zone", time_zone, MRB_ARGS_NONE()); /* 15.2.19.7.33 */ + + mrb_define_method(mrb, tc, "initialize", time_init, MRB_ARGS_REQ(1)); /* 15.2.19.7.16 */ + mrb_define_method(mrb, tc, "initialize_copy", time_init_copy, MRB_ARGS_REQ(1)); /* 15.2.19.7.17 */ + + mrb_define_method(mrb, tc, "sunday?", time_sunday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "monday?", time_monday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "tuesday?", time_tuesday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "wednesday?", time_wednesday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "thursday?", time_thursday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "friday?", time_friday, MRB_ARGS_NONE()); + mrb_define_method(mrb, tc, "saturday?", time_saturday, MRB_ARGS_NONE()); /* methods not available: diff --git a/mruby/mrblib/array.rb b/mruby/mrblib/array.rb index af3c17cb..6c2b6cfe 100644 --- a/mruby/mrblib/array.rb +++ b/mruby/mrblib/array.rb @@ -101,27 +101,6 @@ def initialize(size=0, obj=nil, &block) self end - def _inspect(recur_list) - size = self.size - return "[]" if size == 0 - return "[...]" if recur_list[self.object_id] - recur_list[self.object_id] = true - ary=[] - i=0 - while i true or false diff --git a/mruby/mrblib/compar.rb b/mruby/mrblib/compar.rb index b39d619f..2ac70ac6 100644 --- a/mruby/mrblib/compar.rb +++ b/mruby/mrblib/compar.rb @@ -49,7 +49,7 @@ def <= other # ISO 15.3.3.2.3 def == other cmp = self <=> other - cmp == 0 + cmp.equal?(0) end ## diff --git a/mruby/mrblib/hash.rb b/mruby/mrblib/hash.rb index bfec4c2a..90b67364 100644 --- a/mruby/mrblib/hash.rb +++ b/mruby/mrblib/hash.rb @@ -181,9 +181,9 @@ def each_value(&block) # # ISO 15.2.13.4.22 def merge(*others, &block) - i=0; len=others.size h = self.dup return h.__merge(*others) unless block + i=0; len=others.size while i" + vals[i]._inspect(recur_list)) - i+=1 - end - "{"+ary.join(", ")+"}" - end - ## - # Return the contents of this hash as a string. - # - def inspect - self._inspect({}) - end - alias to_s inspect - ## # call-seq: # hsh.reject! {| key, value | block } -> hsh or nil diff --git a/mruby/mrblib/kernel.rb b/mruby/mrblib/kernel.rb index 7c3ea942..f72ab610 100644 --- a/mruby/mrblib/kernel.rb +++ b/mruby/mrblib/kernel.rb @@ -39,11 +39,6 @@ def !~(y) !(self =~ y) end - # internal method for inspect - def _inspect(_recur_list) - self.inspect - end - def to_enum(*a) raise NotImplementedError.new("fiber required for enumerator") end diff --git a/mruby/mrblib/numeric.rb b/mruby/mrblib/numeric.rb index 67e76ece..a047f019 100644 --- a/mruby/mrblib/numeric.rb +++ b/mruby/mrblib/numeric.rb @@ -69,7 +69,7 @@ def next # Calls the given block +self+ times. # # ISO 15.2.8.3.22 - def times &block + def times(&block) return to_enum :times unless block i = 0 diff --git a/mruby/oss-fuzz/mruby_proto_fuzzer.cpp b/mruby/oss-fuzz/mruby_proto_fuzzer.cpp index f1ecb44e..2d56b79c 100644 --- a/mruby/oss-fuzz/mruby_proto_fuzzer.cpp +++ b/mruby/oss-fuzz/mruby_proto_fuzzer.cpp @@ -18,7 +18,7 @@ int FuzzRB(const uint8_t *Data, size_t size) { if (!mrb) return 0; - char *code = (char *)malloc(size+1); + char *code = (char*)malloc(size+1); if (!code) return 0; memcpy(code, Data, size); diff --git a/mruby/src/array.c b/mruby/src/array.c index d841a994..67b12ca3 100644 --- a/mruby/src/array.c +++ b/mruby/src/array.c @@ -90,9 +90,7 @@ mrb_ary_new(mrb_state *mrb) static inline void array_copy(mrb_value *dst, const mrb_value *src, mrb_int size) { - mrb_int i; - - for (i = 0; i < size; i++) { + for (mrb_int i = 0; i < size; i++) { dst[i] = src[i]; } } @@ -160,7 +158,7 @@ ary_modify(mrb_state *mrb, struct RArray *a) p = a->as.heap.ptr; len = a->as.heap.len * sizeof(mrb_value); - ptr = (mrb_value *)mrb_malloc(mrb, len); + ptr = (mrb_value*)mrb_malloc(mrb, len); if (p) { array_copy(ptr, p, a->as.heap.len); } @@ -183,13 +181,13 @@ static void ary_make_shared(mrb_state *mrb, struct RArray *a) { if (!ARY_SHARED_P(a) && !ARY_EMBED_P(a)) { - mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array)); + mrb_shared_array *shared = (mrb_shared_array*)mrb_malloc(mrb, sizeof(mrb_shared_array)); mrb_value *ptr = a->as.heap.ptr; mrb_int len = a->as.heap.len; shared->refcnt = 1; if (a->as.heap.aux.capa > len) { - a->as.heap.ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1); + a->as.heap.ptr = shared->ptr = (mrb_value*)mrb_realloc(mrb, ptr, sizeof(mrb_value)*len+1); } else { shared->ptr = ptr; @@ -224,7 +222,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) if (ARY_EMBED_P(a)) { mrb_value *ptr = ARY_EMBED_PTR(a); mrb_int len = ARY_EMBED_LEN(a); - mrb_value *expanded_ptr = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*capa); + mrb_value *expanded_ptr = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*capa); ARY_UNSET_EMBED_FLAG(a); array_copy(expanded_ptr, ptr, len); @@ -233,7 +231,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) a->as.heap.ptr = expanded_ptr; } else if (capa > a->as.heap.aux.capa) { - mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); + mrb_value *expanded_ptr = (mrb_value*)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); a->as.heap.aux.capa = capa; a->as.heap.ptr = expanded_ptr; @@ -262,7 +260,7 @@ ary_shrink_capa(mrb_state *mrb, struct RArray *a) if (capa > a->as.heap.len && capa < a->as.heap.aux.capa) { a->as.heap.aux.capa = capa; - a->as.heap.ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); + a->as.heap.ptr = (mrb_value*)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); } } @@ -450,16 +448,16 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) { struct RArray *a1 = mrb_ary_ptr(self); struct RArray *a2; - mrb_value *ptr, sep, tmp; + mrb_value *ptr, arg, tmp; mrb_int times, len1; - mrb_get_args(mrb, "o", &sep); - tmp = mrb_check_string_type(mrb, sep); + arg = mrb_get_arg1(mrb); + tmp = mrb_check_string_type(mrb, arg); if (!mrb_nil_p(tmp)) { return mrb_ary_join(mrb, self, tmp); } - mrb_get_args(mrb, "i", ×); + times = mrb_as_int(mrb, arg); if (times < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } @@ -543,9 +541,13 @@ mrb_ary_push_m(mrb_state *mrb, mrb_value self) mrb_int len, len2; struct RArray *a; + argc = mrb_get_argc(mrb); + if (argc == 1) { + mrb_ary_push(mrb, self, mrb_get_argv(mrb)[0]); + return self; + } a = mrb_ary_ptr(self); ary_modify(mrb, a); - argc = mrb_get_argc(mrb); len = ARY_LEN(a); len2 = len + argc; if (ARY_CAPA(a) < len2) { @@ -612,12 +614,12 @@ mrb_ary_shift(mrb_state *mrb, mrb_value self) static mrb_value mrb_ary_shift_m(mrb_state *mrb, mrb_value self) { - mrb_int n; - if (mrb_get_args(mrb, "|i", &n) == 0) { + if (mrb_get_argc(mrb) == 0) { return mrb_ary_shift(mrb, self); } + mrb_int n = mrb_as_int(mrb, mrb_get_arg1(mrb)); struct RArray *a = mrb_ary_ptr(self); mrb_int len = ARY_LEN(a); mrb_value val; @@ -1026,7 +1028,6 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) mrb_value v1, v2, v3; mrb_int i, len; - ary_modify(mrb, mrb_ary_ptr(self)); if (mrb_get_argc(mrb) == 2) { const mrb_value *vs = mrb_get_argv(mrb); v1 = vs[0]; v2 = vs[1]; @@ -1061,7 +1062,7 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self) mrb_value *ptr; mrb_int len, alen; - mrb_get_args(mrb, "i", &index); + index = mrb_as_int(mrb, mrb_get_arg1(mrb)); alen = ARY_LEN(a); if (index < 0) index += alen; if (index < 0 || alen <= index) return mrb_nil_value(); @@ -1131,9 +1132,8 @@ static mrb_value mrb_ary_index_m(mrb_state *mrb, mrb_value self) { mrb_value obj = mrb_get_arg1(mrb); - mrb_int i; - for (i = 0; i < RARRAY_LEN(self); i++) { + for (mrb_int i = 0; i < RARRAY_LEN(self); i++) { if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { return mrb_int_value(mrb, i); } @@ -1145,9 +1145,10 @@ static mrb_value mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) { mrb_value obj = mrb_get_arg1(mrb); - mrb_int i, len; - for (i = RARRAY_LEN(self) - 1; i >= 0; i--) { + for (mrb_int i = RARRAY_LEN(self) - 1; i >= 0; i--) { + mrb_int len; + if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) { return mrb_int_value(mrb, i); } @@ -1173,7 +1174,7 @@ mrb_ary_splat(mrb_state *mrb, mrb_value v) return mrb_ary_new_from_values(mrb, 1, &v); } - ary = mrb_funcall_id(mrb, v, MRB_SYM(to_a), 0); + ary = mrb_funcall_argv(mrb, v, MRB_SYM(to_a), 0, NULL); if (mrb_nil_p(ary)) { return mrb_ary_new_from_values(mrb, 1, &v); } @@ -1245,11 +1246,10 @@ mrb_ary_entry(mrb_value ary, mrb_int n) static mrb_value join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list) { - mrb_int i; mrb_value result, val, tmp; /* check recursive */ - for (i=0; i 0 && !mrb_nil_p(sep)) { mrb_str_cat_str(mrb, result, sep); } @@ -1328,6 +1328,33 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary) return mrb_ary_join(mrb, ary, sep); } +/* + * call-seq: + * ary.to_s -> string + * ary.inspect -> string + * + * Return the contents of this array as a string. + */ +static mrb_value +mrb_ary_to_s(mrb_state *mrb, mrb_value self) +{ + mrb->c->ci->mid = MRB_SYM(inspect); + mrb_value ret = mrb_str_new_lit(mrb, "["); + int ai = mrb_gc_arena_save(mrb); + if (mrb_inspect_recursive_p(mrb, self)) { + mrb_str_cat_lit(mrb, ret, "...]"); + return ret; + } + for (mrb_int i=0; i0) mrb_str_cat_lit(mrb, ret, ", "); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, RARRAY_PTR(self)[i])); + mrb_gc_arena_restore(mrb, ai); + } + mrb_str_cat_lit(mrb, ret, "]"); + + return ret; +} + static mrb_value mrb_ary_eq(mrb_state *mrb, mrb_value ary1) { @@ -1406,6 +1433,8 @@ mrb_init_array(mrb_state *mrb) mrb_define_method(mrb, a, "size", mrb_ary_size, MRB_ARGS_NONE()); /* 15.2.12.5.28 */ mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ARG(1,1)); /* 15.2.12.5.29 */ mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ + mrb_define_method(mrb, a, "to_s", mrb_ary_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, a, "inspect", mrb_ary_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1)); mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1)); diff --git a/mruby/src/backtrace.c b/mruby/src/backtrace.c index 4a0fdc11..816b0e6d 100644 --- a/mruby/src/backtrace.c +++ b/mruby/src/backtrace.c @@ -18,59 +18,54 @@ #include struct backtrace_location { - int32_t lineno; mrb_sym method_id; - const char *filename; + int32_t idx; + const mrb_irep *irep; }; typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*, void*); static const mrb_data_type bt_type = { "Backtrace", mrb_free }; -struct RObject *mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace); - -static void +static uint32_t each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) { - if (ciidx >= mrb->c->ciend - mrb->c->cibase) - ciidx = 10; /* ciidx is broken... */ + uint32_t n = 0; for (ptrdiff_t i=ciidx; i >= 0; i--) { struct backtrace_location loc; mrb_callinfo *ci; - const mrb_irep *irep = 0; const mrb_code *pc; - uint32_t idx; ci = &mrb->c->cibase[i]; if (!ci->proc || MRB_PROC_CFUNC_P(ci->proc)) { if (!ci->mid) continue; - loc.lineno = -1; - idx = 0; + loc.irep = NULL; } else { - irep = ci->proc->body.irep; - if (!irep) continue; + loc.irep = ci->proc->body.irep; + if (!loc.irep) continue; + if (!loc.irep->debug_info) 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.idx = (uint32_t)(pc - loc.irep->iseq); } loc.method_id = ci->mid; - if (loc.lineno == -1) { + if (loc.irep == NULL) { 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; + const mrb_irep *irep = ci->proc->body.irep; if (!irep) continue; + if (!irep->debug_info) continue; if (mrb->c->cibase[j].pc) { pc = &mrb->c->cibase[j].pc[-1]; @@ -79,94 +74,15 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * continue; } - idx = (uint32_t)(pc - irep->iseq); - loc.lineno = mrb_debug_get_line(mrb, irep, idx); - if (loc.lineno > 0) break; + loc.irep = irep; + loc.idx = (uint32_t)(pc - loc.irep->iseq); + break; } } - - loc.filename = mrb_debug_get_filename(mrb, irep, idx); - if (!loc.filename) { - loc.filename = "(unknown)"; - } - - func(mrb, &loc, data); - } -} - -#ifndef MRB_NO_STDIO - -static void -print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) -{ - mrb_int i; - mrb_int n = (backtrace ? ARY_LEN(backtrace) : 0); - mrb_value *loc, mesg; - - if (n != 0) { - if (n > 1) { - fputs("trace (most recent call last):\n", stderr); - } - for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { - if (mrb_string_p(*loc)) { - fprintf(stderr, "\t[%d] ", (int)i); - fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); - fputc('\n', stderr); - } - } - if (mrb_string_p(*loc)) { - fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); - fputs(": ", stderr); - } - } - else { - fputs("(unknown):0: ", stderr); - } - - if (exc == mrb->nomem_err) { - static const char nomem[] = "Out of memory (NoMemoryError)\n"; - fwrite(nomem, sizeof(nomem)-1, 1, stderr); - } - else { - mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); - fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); - fputc('\n', stderr); + if (func) func(mrb, &loc, data); + n++; } -} - -/* mrb_print_backtrace - - function to retrieve backtrace information from the last exception. -*/ - -MRB_API void -mrb_print_backtrace(mrb_state *mrb) -{ - if (!mrb->exc || mrb->exc->tt != MRB_TT_EXCEPTION) { - return; - } - - struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace; - if (backtrace && backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); - print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace); -} -#else - -MRB_API void -mrb_print_backtrace(mrb_state *mrb) -{ -} - -#endif - -static void -count_backtrace_i(mrb_state *mrb, - const struct backtrace_location *loc, - void *data) -{ - int *lenp = (int*)data; - - (*lenp)++; + return n; } static void @@ -186,17 +102,23 @@ packed_backtrace(mrb_state *mrb) { struct RData *backtrace; ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase; - int len = 0; - int size; - void *ptr; - each_backtrace(mrb, ciidx, count_backtrace_i, &len); - size = len * sizeof(struct backtrace_location); + if (ciidx >= mrb->c->ciend - mrb->c->cibase) + ciidx = mrb->c->ciend - mrb->c->cibase; /* ciidx is broken... */ + + /* count the number of backtraces */ + int len = each_backtrace(mrb, ciidx, NULL, NULL); backtrace = mrb_data_object_alloc(mrb, NULL, NULL, &bt_type); - ptr = mrb_malloc(mrb, size); - backtrace->data = ptr; - backtrace->flags = (uint32_t)len; - each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); + if (len > 0) { + void *ptr = mrb_malloc(mrb, len * sizeof(struct backtrace_location)); + backtrace->data = ptr; + backtrace->flags = len; + each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); + } + else { + backtrace->data = NULL; + backtrace->flags = 0; + } return (struct RObject*)backtrace; } @@ -213,6 +135,7 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) { int ai; + if (mrb->c->ci == NULL) return; if (mrb_exc_ptr(exc)->backtrace) return; ai = mrb_gc_arena_save(mrb); struct RObject *backtrace = packed_backtrace(mrb); @@ -220,7 +143,7 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) mrb_gc_arena_restore(mrb, ai); } -struct RObject* +static struct RObject* mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) { const struct backtrace_location *bt; @@ -241,12 +164,17 @@ mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) for (i = 0; i < n; i++) { const struct backtrace_location *entry = &bt[i]; mrb_value btline; + int32_t lineno; + const char *filename; - if (entry->lineno != -1) {//debug info was available - btline = mrb_format(mrb, "%s:%d", entry->filename, (int)entry->lineno); + if (!mrb_debug_get_position(mrb, entry->irep, entry->idx, &lineno, &filename)) { + btline = mrb_str_new_lit(mrb, "(unknown):0"); + } + else if (lineno != -1) {//debug info was available + btline = mrb_format(mrb, "%s:%d", filename, (int)lineno); } else { //all that was left was the stack frame - btline = mrb_format(mrb, "%s:0", entry->filename); + btline = mrb_format(mrb, "%s:0", filename); } if (entry->method_id != 0) { mrb_str_cat_lit(mrb, btline, ":in "); @@ -280,3 +208,66 @@ mrb_get_backtrace(mrb_state *mrb) { return mrb_obj_value(mrb_unpack_backtrace(mrb, packed_backtrace(mrb))); } + +#ifndef MRB_NO_STDIO + +static void +print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) +{ + mrb_int i; + mrb_int n = (backtrace ? ARY_LEN(backtrace) : 0); + mrb_value *loc, mesg; + + if (n != 0) { + if (n > 1) { + fputs("trace (most recent call last):\n", stderr); + } + for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { + if (mrb_string_p(*loc)) { + fprintf(stderr, "\t[%d] ", (int)i); + fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + fputc('\n', stderr); + } + } + if (mrb_string_p(*loc)) { + fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + fputs(": ", stderr); + } + } + else { + fputs("(unknown):0: ", stderr); + } + + if (exc == mrb->nomem_err) { + static const char nomem[] = "Out of memory (NoMemoryError)\n"; + fwrite(nomem, sizeof(nomem)-1, 1, stderr); + } + else { + mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); + fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); + fputc('\n', stderr); + } +} + +/* mrb_print_backtrace + + function to retrieve backtrace information from the last exception. +*/ + +MRB_API void +mrb_print_backtrace(mrb_state *mrb) +{ + if (!mrb->exc || mrb->exc->tt != MRB_TT_EXCEPTION) { + return; + } + + struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace; + if (backtrace && backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); + print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace); +} +#else +MRB_API void +mrb_print_backtrace(mrb_state *mrb) +{ +} +#endif diff --git a/mruby/src/cdump.c b/mruby/src/cdump.c index 251b3984..92eb1f86 100644 --- a/mruby/src/cdump.c +++ b/mruby/src/cdump.c @@ -267,8 +267,9 @@ simple_debug_info(mrb_irep_debug_info *info) //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) + mrb_value init_syms_code, FILE *fp) { + int ai = mrb_gc_arena_save(mrb); char buffer[256]; const char *filename; mrb_int file_len; @@ -281,11 +282,10 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, 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); + 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"); + mrb_str_cat_str(mrb, init_syms_code, mrb_str_dump(mrb, mrb_str_new_cstr(mrb, filename))); + mrb_str_cat_cstr(mrb, init_syms_code, ");\n"); switch (info->files[0]->line_type) { case mrb_debug_line_ary: @@ -329,6 +329,7 @@ cdump_debug(mrb_state *mrb, const char *name, int n, mrb_irep_debug_info *info, 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); + mrb_gc_arena_restore(mrb, ai); return MRB_DUMP_OK; } @@ -380,8 +381,7 @@ cdump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *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) { + if (cdump_debug(mrb, name, n, irep->debug_info, init_syms_code, fp) == MRB_DUMP_OK) { debug_available = 1; } } @@ -415,7 +415,7 @@ cdump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, else { fputs( " NULL,\t\t\t\t\t/* lv */\n", fp); } - if(debug_available) { + if (debug_available) { fprintf(fp, " &%s_debug_%d,\n", name, n); } else { diff --git a/mruby/src/class.c b/mruby/src/class.c index 6cd40cfd..6d0385e3 100644 --- a/mruby/src/class.c +++ b/mruby/src/class.c @@ -219,7 +219,6 @@ static struct mt_tbl* mt_copy(mrb_state *mrb, mt_tbl *t) { mt_tbl *t2; - int i; if (t == NULL) return NULL; if (t->alloc == 0) return NULL; @@ -228,7 +227,7 @@ mt_copy(mrb_state *mrb, mt_tbl *t) t2 = mt_new(mrb); mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; union mt_ptr *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (MT_KEY_P(keys[i])) { mt_put(mrb, t2, MT_KEY_SYM(keys[i]), MT_KEY_FLG(keys[i]), vals[i]); } @@ -265,7 +264,6 @@ MRB_API void mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p) { mt_tbl *t = c->mt; - int i; if (t == NULL) return; if (t->alloc == 0) return; @@ -273,7 +271,7 @@ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void * mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; union mt_ptr *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { mrb_sym key = keys[i]; if (MT_KEY_SYM(key)) { if (fn(mrb, MT_KEY_SYM(key), create_method_value(mrb, key, vals[i]), p) != 0) @@ -287,7 +285,6 @@ void mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) { mt_tbl *t = c->mt; - int i; if (t == NULL) return; if (t->alloc == 0) return; @@ -295,7 +292,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; union mt_ptr *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (MT_KEY_P(keys[i]) && (keys[i] & MT_FUNC_P) == 0) { /* Proc pointer */ struct RProc *p = vals[i].proc; mrb_gc_mark(mrb, (struct RBasic*)p); @@ -313,6 +310,15 @@ mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c) return (size_t)h->size; } +size_t +mrb_class_mt_memsize(mrb_state *mrb, struct RClass *c) +{ + struct mt_tbl *h = c->mt; + + if (!h) return 0; + return sizeof(struct mt_tbl) + (size_t)h->size * sizeof(mrb_method_t); +} + void mrb_gc_free_mt(mrb_state *mrb, struct RClass *c) { @@ -373,8 +379,8 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o) if (o->c->tt == MRB_TT_SCLASS) return; 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; + sc->mt = NULL; + sc->iv = NULL; if (o->tt == MRB_TT_CLASS) { c = (struct RClass*)o; if (!c->super) { @@ -595,7 +601,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id s = mrb_class_ptr(super); } else { - s = 0; + s = NULL; } check_if_class_or_module(mrb, outer); if (mrb_const_defined_at(mrb, outer, id)) { @@ -678,16 +684,16 @@ mrb_exc_get_id(mrb_state *mrb, mrb_sym name) mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), name); if (!mrb_class_p(c)) { - mrb_raise(mrb, mrb->eException_class, "exception corrupted"); + mrb_raise(mrb, E_EXCEPTION, "exception corrupted"); } exc = e = mrb_class_ptr(c); while (e) { - if (e == mrb->eException_class) + if (e == E_EXCEPTION) return exc; e = e->super; } - return mrb->eException_class; + return E_EXCEPTION; } MRB_API struct RClass* @@ -759,7 +765,13 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_ MRB_CLASS_ORIGIN(c); h = c->mt; - mrb_check_frozen(mrb, c); + if (c->tt == MRB_TT_SCLASS && mrb_frozen_p(c)) { + mrb_value v = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__)); + mrb_check_frozen_value(mrb, v); + } + else { + mrb_check_frozen(mrb, c); + } if (!h) h = c->mt = mt_new(mrb); if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); @@ -1014,10 +1026,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) 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)); + mrb_check_frozen_value(mrb, *pickarg); } } else { @@ -1072,8 +1081,8 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) break; case 's': { - const char **ps = 0; - mrb_int *pl = 0; + const char **ps = NULL; + mrb_int *pl = NULL; ps = GET_ARG(const char**); pl = GET_ARG(mrb_int*); @@ -1119,7 +1128,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) if (needmodify) goto bad_needmodify; if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { - *pb = 0; + *pb = NULL; *pl = 0; } else { @@ -1181,7 +1190,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap) type = GET_ARG(struct mrb_data_type const*); if (pickarg) { if (altmode && mrb_nil_p(*pickarg)) { - *datap = 0; + *datap = NULL; } else { *datap = mrb_data_get_ptr(mrb, *pickarg, type); @@ -1442,7 +1451,8 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru } goto skip; } - } else if (p->tt == MRB_TT_CLASS) { + } + else if (p->tt == MRB_TT_CLASS) { if (!search_super) break; superclass_seen = TRUE; } @@ -1521,15 +1531,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) mrb_check_frozen(mrb, c); if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) { - struct RClass *c0; - - if (c->tt == MRB_TT_ICLASS) { - c0 = c->c; - } - else { - c0 = c; - } - origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c0); + origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c); origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED; origin->super = c->super; c->super = origin; @@ -1755,7 +1757,7 @@ mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c) struct mrb_cache_entry *mc = mrb->cache; for (int i=0; ic == c || mc->c0 == c) mc->c = 0; + if (mc->c == c || mc->c0 == c) mc->c = NULL; } } @@ -1765,7 +1767,7 @@ mc_clear_by_id(mrb_state *mrb, mrb_sym id) struct mrb_cache_entry *mc = mrb->cache; for (int i=0; imid == id) mc->c = 0; + if (mc->mid == id) mc->c = NULL; } } #endif @@ -1839,7 +1841,7 @@ prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char size_t prefix_len = prefix ? strlen(prefix) : 0; size_t suffix_len = suffix ? strlen(suffix) : 0; size_t name_len = sym_len + prefix_len + suffix_len; - char *buf = name_len > sizeof(onstack) ? (char *)mrb_alloca(mrb, name_len) : onstack; + char *buf = name_len > sizeof(onstack) ? (char*)mrb_alloca(mrb, name_len) : onstack; char *p = buf; if (prefix_len > 0) { @@ -1877,12 +1879,12 @@ mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state * { struct RClass *c = mrb_class_ptr(mod); const mrb_value *argv; - mrb_int argc, i; + mrb_int argc; int ai; mrb_get_args(mrb, "*", &argv, &argc); ai = mrb_gc_arena_save(mrb); - for (i=0; iiv) { + mrb_raise(mrb, E_TYPE_ERROR, "already initialized class"); + } mrb_get_args(mrb, "|C&", &a, &b); if (!mrb_nil_p(b)) { - mrb_yield_with_class(mrb, b, 1, &c, c, mrb_class_ptr(c)); + mrb_yield_with_class(mrb, b, 1, &obj, obj, c); } - return c; + return obj; } static mrb_value @@ -2486,14 +2495,9 @@ mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) return val; } -static mrb_value -mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) +mrb_value +mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym) { - 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); } @@ -2504,6 +2508,16 @@ mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) return mrb_nil_value(); } +mrb_value +mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) +{ + mrb_sym sym; + + mrb_get_args(mrb, "n", &sym); + mrb->c->ci->mid = 0; + return mrb_const_missing(mrb, mod, sym); +} + /* 15.2.2.4.34 */ /* * call-seq: @@ -2553,7 +2567,10 @@ mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid) else { added = MRB_SYM(method_added); } - mrb_funcall_id(mrb, recv, added, 1, mrb_symbol_value(mid)); + if (!mrb_func_basic_p(mrb, recv, added, mrb_do_nothing)) { + mrb_value sym = mrb_symbol_value(mid); + mrb_funcall_argv(mrb, recv, added, 1, &sym); + } } mrb_value @@ -2624,7 +2641,7 @@ static mrb_value mrb_mod_module_function(mrb_state *mrb, mrb_value mod) { const mrb_value *argv; - mrb_int argc, i; + mrb_int argc; mrb_sym mid; mrb_method_t m; struct RClass *rclass; @@ -2641,7 +2658,7 @@ mrb_mod_module_function(mrb_state *mrb, mrb_value mod) /* set PRIVATE method visibility if implemented */ /* mrb_mod_dummy_visibility(mrb, mod); */ - for (i=0; isuper->flags |= MRB_FL_CLASS_IS_ORIGIN; } if (sc->mt) { - dc->mt = mt_copy(mrb, sc->mt); - } - else { - dc->mt = mt_new(mrb); + if (sc->tt == MRB_TT_ICLASS && !(sc->flags & MRB_FL_CLASS_IS_ORIGIN)) { + dc->mt = sc->mt; + } + else { + dc->mt = mt_copy(mrb, sc->mt); + } } dc->super = sc->super; - MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); + dc->flags = sc->flags; + dc->flags &= ~MRB_FL_OBJ_IS_FROZEN; } /* 15.3.1.3.16 */ @@ -2738,6 +2758,7 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self) static void init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) { + mrb_assert((mrb_type(dest) == mrb_type(obj))); switch (mrb_type(obj)) { case MRB_TT_ICLASS: copy_class(mrb, dest, obj); @@ -2778,7 +2799,7 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) break; } if (!mrb_func_basic_p(mrb, dest, MRB_SYM(initialize_copy), mrb_obj_init_copy)) { - mrb_funcall_id(mrb, dest, MRB_SYM(initialize_copy), 1, obj); + mrb_funcall_argv(mrb, dest, MRB_SYM(initialize_copy), 1, &obj); } } @@ -2899,8 +2920,8 @@ mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) * def romanToInt(str) * # ... * end - * def method_missing(methId) - * str = methId.to_s + * def method_missing(sym) + * str = sym.to_s * romanToInt(str) * end * end diff --git a/mruby/src/codedump.c b/mruby/src/codedump.c index 1d19354f..292527f2 100644 --- a/mruby/src/codedump.c +++ b/mruby/src/codedump.c @@ -99,10 +99,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen, (int)irep->ilen); if (irep->lv) { - int i; int head = FALSE; - for (i = 1; i < irep->nlocals; i++) { + for (int i = 1; i < irep->nlocals; i++) { char const *s = mrb_sym_dump(mrb, irep->lv[i - 1]); if (s) { if (!head) { @@ -115,10 +114,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) } if (irep->clen > 0) { - int i = irep->clen; const struct mrb_irep_catch_handler *e = mrb_irep_catch_handler_table(irep); - for (; i > 0; i--,e++) { + for (int i = irep->clen; i > 0; i--,e++) { uint32_t begin = mrb_irep_catch_handler_unpack(e->begin); uint32_t end = mrb_irep_catch_handler_unpack(e->end); uint32_t target = mrb_irep_catch_handler_unpack(e->target); @@ -173,19 +171,19 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) switch (irep->pool[b].tt) { #ifndef MRB_NO_FLOAT case IREP_TT_FLOAT: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %f", a, b, (double)irep->pool[b].u.f); break; #endif case IREP_TT_INT32: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %" PRId32, a, b, irep->pool[b].u.i32); break; #ifdef MRB_64BIT case IREP_TT_INT64: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t; %" PRId64, a, b, irep->pool[b].u.i64); break; #endif default: - fprintf(out, "LOADL\t\tR%d\tL(%d)\t", a, b); + fprintf(out, "LOADL\t\tR%d\tL[%d]\t", a, b); break; } print_lv_a(mrb, irep, a, out); @@ -403,13 +401,13 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) print_lv_a(mrb, irep, a, out); break; CASE(OP_LAMBDA, BB): - fprintf(out, "LAMBDA\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "LAMBDA\tR%d\tI[%d]\n", a, b); break; CASE(OP_BLOCK, BB): - fprintf(out, "BLOCK\t\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "BLOCK\t\tR%d\tI[%d]\n", a, b); break; CASE(OP_METHOD, BB): - fprintf(out, "METHOD\tR%d\tI(%d:%p)\n", a, b, (void*)irep->reps[b]); + fprintf(out, "METHOD\tR%d\tI[%d]\n", a, b); break; CASE(OP_RANGE_INC, B): fprintf(out, "RANGE_INC\tR%d\n", a); @@ -499,12 +497,12 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) break; CASE(OP_SYMBOL, BB): mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); - fprintf(out, "SYMBOL\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + fprintf(out, "SYMBOL\tR%d\tL[%d]\t; %s", a, b, irep->pool[b].u.str); print_lv_a(mrb, irep, a, out); break; CASE(OP_STRING, BB): mrb_assert((irep->pool[b].tt&IREP_TT_NFLAG)==0); - fprintf(out, "STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str); + fprintf(out, "STRING\tR%d\tL[%d]\t; %s", a, b, irep->pool[b].u.str); print_lv_a(mrb, irep, a, out); break; CASE(OP_STRCAT, B): @@ -537,11 +535,11 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) print_lv_a(mrb, irep, a, out); break; CASE(OP_EXEC, BB): - fprintf(out, "EXEC\t\tR%d\tI(%d:%p)", a, b, (void*)irep->reps[b]); + fprintf(out, "EXEC\t\tR%d\tI[%d]", a, b); print_lv_a(mrb, irep, a, out); break; CASE(OP_SCLASS, B): - fprintf(out, "SCLASS\t\tR%d\t", a); + fprintf(out, "SCLASS\tR%d\t", a); print_lv_a(mrb, irep, a, out); break; CASE(OP_TCLASS, B): @@ -553,7 +551,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) fprintf(out, "ERR\t\t%s\n", irep->pool[a].u.str); } else { - fprintf(out, "ERR\tL(%d)\n", a); + fprintf(out, "ERR\tL[%d]\n", a); } break; CASE(OP_EXCEPT, B): @@ -620,11 +618,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) static void codedump_recur(mrb_state *mrb, const mrb_irep *irep, FILE *out) { - int i; - codedump(mrb, irep, out); if (irep->reps) { - for (i=0; irlen; i++) { + for (int i=0; irlen; i++) { codedump_recur(mrb, irep->reps[i], out); } } @@ -634,6 +630,7 @@ void mrb_codedump_all_file(mrb_state *mrb, struct RProc *proc, FILE *out) { codedump_recur(mrb, proc->body.irep, out); + fflush(out); } #endif diff --git a/mruby/src/debug.c b/mruby/src/debug.c index 11af6fcf..c9c132e7 100644 --- a/mruby/src/debug.c +++ b/mruby/src/debug.c @@ -47,7 +47,7 @@ mrb_packed_int_len(uint32_t num) } size_t -mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend) +mrb_packed_int_encode(uint32_t num, uint8_t *p) { size_t llen = 0; @@ -55,7 +55,7 @@ mrb_packed_int_encode(uint32_t num, uint8_t *p, uint8_t *pend) uint8_t byte = num & 0x7f; num >>= 7; if (num != 0) byte |= 0x80; - if (p < pend) *p++ = byte; + *p++ = byte; llen++; } while (num != 0); @@ -77,15 +77,46 @@ mrb_packed_int_decode(const uint8_t *p, const uint8_t **newpos) return n; } +static char const* +debug_get_filename(mrb_state *mrb, mrb_irep_debug_info_file* f) +{ + if (f == NULL) return NULL; + return mrb_sym_name_len(mrb, f->filename_sym, NULL); +} + +static int32_t +debug_get_line(mrb_state *mrb, mrb_irep_debug_info_file* f, uint32_t pc) +{ + if (f == NULL) return -1; + switch (f->line_type) { + case mrb_debug_line_ary: + case mrb_debug_line_flat_map: + default: + break; + + case mrb_debug_line_packed_map: + { + const uint8_t *p = f->lines.packed_map; + const 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; + } + } + return -1; +} + MRB_API char const* mrb_debug_get_filename(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) { if (irep && pc < irep->ilen) { - mrb_irep_debug_info_file* f = NULL; if (!irep->debug_info) return NULL; - else if ((f = get_file(irep->debug_info, pc))) { - return mrb_sym_name_len(mrb, f->filename_sym, NULL); - } + return debug_get_filename(mrb, get_file(irep->debug_info, pc)); } return NULL; } @@ -94,60 +125,27 @@ MRB_API int32_t mrb_debug_get_line(mrb_state *mrb, const mrb_irep *irep, uint32_t pc) { if (irep && pc < irep->ilen) { - mrb_irep_debug_info_file* f = NULL; - if (!irep->debug_info) { - return -1; - } - else if ((f = get_file(irep->debug_info, pc))) { - switch (f->line_type) { - case mrb_debug_line_ary: - mrb_assert(f->start_pos <= pc && pc < (f->start_pos + f->line_entry_count)); - return f->lines.ary[pc - f->start_pos]; - - case mrb_debug_line_flat_map: { - /* get upper bound */ - const mrb_irep_debug_info_line *ret = f->lines.flat_map; - uint32_t count = f->line_entry_count; - while (count > 0) { - int32_t step = count / 2; - const mrb_irep_debug_info_line *it = ret + step; - if (!(pc < it->start_pos)) { - ret = it + 1; - count -= step + 1; - } - else { count = step; } - } - - --ret; - - /* check line entry pointer range */ - mrb_assert(f->lines.flat_map <= ret && ret < (f->lines.flat_map + f->line_entry_count)); - /* check pc range */ - mrb_assert(ret->start_pos <= pc && - pc < (((uint32_t)(ret + 1 - f->lines.flat_map) < f->line_entry_count) - ? (ret+1)->start_pos : irep->debug_info->pc_count)); - - return ret->line; - } - - case mrb_debug_line_packed_map: { - const uint8_t *p = f->lines.packed_map; - const 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; - } - } - } + if (!irep->debug_info) return -1; + return debug_get_line(mrb, get_file(irep->debug_info, pc), pc); } return -1; } +MRB_API mrb_bool +mrb_debug_get_position(mrb_state *mrb, const mrb_irep *irep, uint32_t pc, int32_t *lp, const char **fp) +{ + if (irep && pc < irep->ilen && irep->debug_info) { + mrb_irep_debug_info_file *f = get_file(irep->debug_info, pc); + *lp = debug_get_line(mrb, f, pc); + if (*lp > 0) { + *fp = debug_get_filename(mrb, f); + if (*fp) return TRUE; + } + } + *lp = -1; *fp = NULL; + return FALSE; +} + MRB_API mrb_irep_debug_info* mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) { @@ -155,7 +153,7 @@ mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) mrb_irep_debug_info *ret; mrb_assert(!irep->debug_info); - ret = (mrb_irep_debug_info *)mrb_malloc(mrb, sizeof(*ret)); + ret = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(*ret)); *ret = initial; irep->debug_info = ret; return ret; @@ -200,7 +198,7 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, uint16_t prev_line = 0; uint32_t prev_pc = 0; size_t packed_size = 0; - uint8_t *p, *pend; + uint8_t *p; for (i = 0; i < file_pc_count; i++) { if (lines[start_pos + i] == prev_line) continue; @@ -210,13 +208,12 @@ mrb_debug_info_append_file(mrb_state *mrb, mrb_irep_debug_info *d, prev_line = lines[start_pos + i]; } f->lines.packed_map = p = (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); + p += mrb_packed_int_encode(start_pos+i-prev_pc, p); prev_pc = start_pos + i; - p += mrb_packed_int_encode(lines[start_pos + i]-prev_line, p, pend); + p += mrb_packed_int_encode(lines[start_pos + i]-prev_line, p); prev_line = lines[start_pos + i]; } f->line_entry_count = (uint32_t)packed_size; diff --git a/mruby/src/dump.c b/mruby/src/dump.c index c0ad4b68..093061ba 100644 --- a/mruby/src/dump.c +++ b/mruby/src/dump.c @@ -452,7 +452,7 @@ get_filename_table_size(mrb_state *mrb, const mrb_irep *irep, mrb_sym **fp, uint if (find_filename_index(filenames, *lp, file->filename_sym) == -1) { /* register filename */ *lp += 1; - *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); + *fp = filenames = (mrb_sym*)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); filenames[*lp - 1] = file->filename_sym; /* filename */ @@ -557,7 +557,7 @@ write_section_debug(mrb_state *mrb, const mrb_irep *irep, uint8_t *cur, mrb_sym return MRB_DUMP_INVALID_ARGUMENT; } - header = (struct rite_section_debug_header *)bin; + header = (struct rite_section_debug_header*)bin; cur += sizeof(struct rite_section_debug_header); section_size += sizeof(struct rite_section_debug_header); @@ -728,7 +728,7 @@ write_section_lv(mrb_state *mrb, const mrb_irep *irep, uint8_t *start, mrb_sym c static int write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags) { - struct rite_binary_header *header = (struct rite_binary_header *)bin; + struct rite_binary_header *header = (struct rite_binary_header*)bin; memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)); memcpy(header->major_version, RITE_BINARY_MAJOR_VER, sizeof(header->major_version)); @@ -767,8 +767,8 @@ lv_defined_p(const mrb_irep *irep) return FALSE; } -static int -dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) +int +mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; size_t malloc_size; @@ -855,12 +855,6 @@ dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, si return result; } -int -mrb_dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) -{ - return dump_irep(mrb, irep, flags, bin, bin_size); -} - #ifndef MRB_NO_STDIO int @@ -874,7 +868,7 @@ mrb_dump_irep_binary(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE* return MRB_DUMP_INVALID_ARGUMENT; } - result = dump_irep(mrb, irep, flags, &bin, &bin_size); + result = mrb_dump_irep(mrb, irep, flags, &bin, &bin_size); if (result == MRB_DUMP_OK) { if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { result = MRB_DUMP_WRITE_FAULT; @@ -895,7 +889,7 @@ mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *f if (fp == NULL || initname == NULL || initname[0] == '\0') { return MRB_DUMP_INVALID_ARGUMENT; } - result = dump_irep(mrb, irep, flags, &bin, &bin_size); + result = mrb_dump_irep(mrb, irep, flags, &bin, &bin_size); if (result == MRB_DUMP_OK) { if (fprintf(fp, "#include \n") < 0) { /* for uint8_t under at least Darwin */ mrb_free(mrb, bin); diff --git a/mruby/src/error.c b/mruby/src/error.c index a0e23fad..7f6d07a6 100644 --- a/mruby/src/error.c +++ b/mruby/src/error.c @@ -208,7 +208,7 @@ mrb_exc_raise(mrb_state *mrb, mrb_value exc) mrb->exc = mrb_obj_ptr(exc); } else { - if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) { + if (mrb_type(exc) != MRB_TT_EXCEPTION) { mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); } mrb_exc_set(mrb, exc); @@ -443,69 +443,40 @@ mrb_warn(mrb_state *mrb, const char *fmt, ...) } MRB_API mrb_noreturn void -mrb_bug(mrb_state *mrb, const char *fmt, ...) +mrb_bug(mrb_state *mrb, const char *mesg) { #ifndef MRB_NO_STDIO - va_list ap; - mrb_value str; - - va_start(ap, fmt); - str = mrb_vformat(mrb, fmt, ap); fputs("bug: ", stderr); - fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); - va_end(ap); + fputs(mesg, stderr); + fputs("\n", stderr); #endif exit(EXIT_FAILURE); } -MRB_API mrb_value -mrb_make_exception(mrb_state *mrb, mrb_int argc, const mrb_value *argv) +mrb_value +mrb_make_exception(mrb_state *mrb, mrb_value exc, mrb_value mesg) { - mrb_value mesg; - int n; - - mesg = mrb_nil_value(); - switch (argc) { - case 0: - break; - case 1: - if (mrb_nil_p(argv[0])) - break; - if (mrb_string_p(argv[0])) { - mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, argv[0]); - break; - } - n = 0; - goto exception_call; - - case 2: - case 3: - n = 1; -exception_call: - { - mrb_sym exc = MRB_SYM(exception); - if (mrb_respond_to(mrb, argv[0], exc)) { - mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1); - } - else { - /* undef */ - mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); - } - } + mrb_int n = 1; - break; - default: - mrb_argnum_error(mrb, argc, 0, 3); - break; + if (mrb_nil_p(mesg)) { + n = 0; } - if (argc > 0) { - if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) - mrb_raise(mrb, mrb->eException_class, "exception object expected"); - if (argc > 2) - set_backtrace(mrb, mesg, argv[2]); + if (mrb_class_p(exc)) { + exc = mrb_funcall_argv(mrb, exc, MRB_SYM(new), n, &mesg); } - - return mesg; + else if (mrb_exception_p(exc)) { + if (n > 0) { + exc = mrb_obj_clone(mrb, exc); + mrb_exc_mesg_set(mrb, mrb_exc_ptr(exc), mesg); + } + } + else { + mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); + } + if (mrb_type(exc) != MRB_TT_EXCEPTION) { + mrb_raise(mrb, E_EXCEPTION, "exception object expected"); + } + return exc; } MRB_API mrb_noreturn void @@ -542,10 +513,32 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, mrb_exc_raise(mrb, exc); } +static mrb_noreturn void +frozen_error(mrb_state *mrb, mrb_value v) +{ + mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %T", v); +} + MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj) { - mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj)); + frozen_error(mrb, mrb_obj_value(frozen_obj)); +} + +MRB_API void +mrb_check_frozen(mrb_state *mrb, void *o) +{ + if (mrb_frozen_p((struct RBasic*)o)) { + mrb_frozen_error(mrb, o); + } +} + +MRB_API void +mrb_check_frozen_value(mrb_state *mrb, mrb_value v) +{ + if (mrb_immediate_p(v) || mrb_frozen_p(mrb_basic_ptr(v))) { + frozen_error(mrb, v); + } } MRB_API mrb_noreturn void @@ -564,7 +557,7 @@ mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max) void mrb_core_init_printabort(void); int -mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *opaque) +mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state*, void*), void *opaque) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; @@ -649,6 +642,24 @@ mrb_print_error(mrb_state *mrb) #endif } +/* clear error status in the mrb_state structure */ +MRB_API void +mrb_clear_error(mrb_state *mrb) +{ + mrb->exc = NULL; +} + +/* returns TRUE if error in the previous call; internally calls mrb_clear_error() */ +MRB_API mrb_bool +mrb_check_error(mrb_state *mrb) +{ + if (mrb->exc) { + mrb_clear_error(mrb); + return TRUE; + } + return FALSE; +} + void mrb_init_exception(mrb_state *mrb) { @@ -665,8 +676,8 @@ mrb_init_exception(mrb_state *mrb) mrb_define_method(mrb, exception, "set_backtrace", exc_set_backtrace, MRB_ARGS_REQ(1)); mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ - mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ - script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ + mrb_define_class(mrb, "RuntimeError", E_STANDARD_ERROR); /* 15.2.28 */ + script_error = mrb_define_class(mrb, "ScriptError", exception); /* 15.2.37 */ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ stack_error = mrb_define_class(mrb, "SystemStackError", exception); mrb->stack_err = mrb_obj_ptr(mrb_exc_new_lit(mrb, stack_error, "stack level too deep")); diff --git a/mruby/src/etc.c b/mruby/src/etc.c index 83419223..0c266245 100644 --- a/mruby/src/etc.c +++ b/mruby/src/etc.c @@ -71,7 +71,7 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name) return 0; /* not reached */ } -#ifndef MRB_NO_FLOAT +#if !defined(MRB_NO_FLOAT) && !defined(MRB_NAN_BOXING) static mrb_int mrb_float_id(mrb_float f) { diff --git a/mruby/src/fmt_fp.c b/mruby/src/fmt_fp.c index 7c5b01a9..3eed1177 100644 --- a/mruby/src/fmt_fp.c +++ b/mruby/src/fmt_fp.c @@ -100,7 +100,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (signbit(f)) { *s++ = '-'; f = -f; - } else if (sign) { + } + else if (sign) { *s++ = sign; } buf_remaining -= (int)(s - buf); // Adjust for sign @@ -112,7 +113,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch *s++ = 'N' ^ uc; *s++ = 'F' ^ uc; goto ret; - } else if (isnan(f)) { + } + else if (isnan(f)) { *s++ = 'N' ^ uc; *s++ = 'A' ^ uc; *s++ = 'N' ^ uc; @@ -142,10 +144,12 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch e = 0; if (fmt == 'e') { e_sign = '+'; - } else if (fmt == 'f') { + } + else if (fmt == 'f') { num_digits = prec + 1; } - } else if (f < 1.0) { // f < 1.0 + } + else if (f < 1.0) { // f < 1.0 char first_dig = '0'; if (f >= FLT_ROUND_TO_ONE) { first_dig = '1'; @@ -165,7 +169,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (e == 0) { e_sign_char = '+'; } - } else { + } + else { e++; f *= 10.0; } @@ -194,7 +199,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch num_digits--; } } - } else { + } + else { // For e & g formats, we'll be printing the exponent, so set the // sign. e_sign = e_sign_char; @@ -207,7 +213,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch } } } - } else { + } + else { // Build positive exponent for (e = 0, e1 = FLT_DECEXP; e1; e1 >>= 1, pos_pow++, neg_pow++) { if (*pos_pow <= f) { @@ -223,7 +230,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'f') { if (e >= buf_remaining) { fmt = 'e'; - } else if ((e + prec + 2) > buf_remaining) { + } + 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 @@ -245,7 +253,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'f') { dec = e; num_digits = prec + e + 1; - } else { + } + else { e_sign = '+'; } } @@ -267,10 +276,9 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch if (fmt == 'e') { num_digits = prec + 1; - } else if (fmt == 'g') { - if (prec == 0) { - prec = 1; - } + if (prec == 0) prec = 1; + } + else if (fmt == 'g') { num_digits = prec; } @@ -318,7 +326,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch rs[1] = '0'; if (e_sign == '-') { e--; - } else { + } + else { e++; } } @@ -356,8 +365,8 @@ mrb_format_float(mrb_float f, char *buf, size_t buf_size, char fmt, int prec, ch *s++ = '0' + (e / 10); *s++ = '0' + (e % 10); } - *s = '\0'; + *s = '\0'; return (int)(s - buf); } #endif diff --git a/mruby/src/gc.c b/mruby/src/gc.c index f1b50ad7..3543bb76 100644 --- a/mruby/src/gc.c +++ b/mruby/src/gc.c @@ -138,49 +138,6 @@ typedef struct { } as; } RVALUE; -#ifdef GC_PROFILE -#include -#include - -static double program_invoke_time = 0; -static double gc_time = 0; -static double gc_total_time = 0; - -static double -gettimeofday_time(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec + tv.tv_usec * 1e-6; -} - -#define GC_INVOKE_TIME_REPORT(with) do {\ - fprintf(stderr, "%s\n", with);\ - fprintf(stderr, "gc_invoke: %19.3f\n", gettimeofday_time() - program_invoke_time);\ - fprintf(stderr, "is_generational: %d\n", is_generational(gc));\ - fprintf(stderr, "is_major_gc: %d\n", is_major_gc(gc));\ -} while(0) - -#define GC_TIME_START do {\ - gc_time = gettimeofday_time();\ -} while(0) - -#define GC_TIME_STOP_AND_REPORT do {\ - gc_time = gettimeofday_time() - gc_time;\ - gc_total_time += gc_time;\ - fprintf(stderr, "gc_state: %d\n", gc->state);\ - fprintf(stderr, "live: %zu\n", gc->live);\ - fprintf(stderr, "majorgc_old_threshold: %zu\n", gc->majorgc_old_threshold);\ - fprintf(stderr, "gc_threshold: %zu\n", gc->threshold);\ - fprintf(stderr, "gc_time: %30.20f\n", gc_time);\ - fprintf(stderr, "gc_total_time: %30.20f\n\n", gc_total_time);\ -} while(0) -#else -#define GC_INVOKE_TIME_REPORT(s) -#define GC_TIME_START -#define GC_TIME_STOP_AND_REPORT -#endif - #ifdef GC_DEBUG #define DEBUG(x) (x) #else @@ -191,13 +148,22 @@ gettimeofday_time(void) #define MRB_HEAP_PAGE_SIZE 1024 #endif +typedef struct mrb_heap_page { + struct RBasic *freelist; + struct mrb_heap_page *next; + struct mrb_heap_page *free_next; + mrb_bool old:1; + /* Flexible array members are not C++ compatible */ + /* void* objects[]; */ +} mrb_heap_page; + #define GC_STEP_SIZE 1024 /* white: 001 or 010, black: 100, gray: 000, red:111 */ #define GC_GRAY 0 #define GC_WHITE_A 1 -#define GC_WHITE_B (1 << 1) -#define GC_BLACK (1 << 2) +#define GC_WHITE_B 2 +#define GC_BLACK 4 #define GC_RED MRB_GC_RED #define GC_WHITES (GC_WHITE_A | GC_WHITE_B) #define GC_COLOR_MASK 7 @@ -218,8 +184,8 @@ mrb_static_assert(MRB_GC_RED <= GC_COLOR_MASK); /* We have removed `objects[]` from `mrb_heap_page` since it was not C++ * compatible. Using array index to get pointer after structure instead. */ -/* #define objects(p) ((RVALUE *)p->objects) */ -#define objects(p) ((RVALUE *)&p[1]) +/* #define objects(p) ((RVALUE*)p->objects) */ +#define objects(p) ((RVALUE*)&p[1]) mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); @@ -330,55 +296,10 @@ mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) return is_dead(gc, object); } -static void -link_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - page->next = gc->heaps; - if (gc->heaps) - gc->heaps->prev = page; - gc->heaps = page; -} - -static void -unlink_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - if (page->prev) - page->prev->next = page->next; - if (page->next) - page->next->prev = page->prev; - if (gc->heaps == page) - gc->heaps = page->next; - page->prev = NULL; - page->next = NULL; -} - -static void -link_free_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - page->free_next = gc->free_heaps; - if (gc->free_heaps) { - gc->free_heaps->free_prev = page; - } - gc->free_heaps = page; -} - -static void -unlink_free_heap_page(mrb_gc *gc, mrb_heap_page *page) -{ - if (page->free_prev) - page->free_prev->free_next = page->free_next; - if (page->free_next) - page->free_next->free_prev = page->free_prev; - if (gc->free_heaps == page) - gc->free_heaps = page->free_next; - page->free_prev = NULL; - page->free_next = NULL; -} - static void add_heap(mrb_state *mrb, mrb_gc *gc) { - mrb_heap_page *page = (mrb_heap_page *)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); + mrb_heap_page *page = (mrb_heap_page*)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); RVALUE *p, *e; struct RBasic *prev = NULL; @@ -389,8 +310,11 @@ add_heap(mrb_state *mrb, mrb_gc *gc) } page->freelist = prev; - link_heap_page(gc, page); - link_free_heap_page(gc, page); + page->next = gc->heaps; + gc->heaps = page; + + page->free_next = gc->free_heaps; + gc->free_heaps = page; } #define DEFAULT_GC_INTERVAL_RATIO 200 @@ -419,10 +343,6 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc) gc->generational = TRUE; gc->full = TRUE; #endif - -#ifdef GC_PROFILE - program_invoke_time = gettimeofday_time(); -#endif } static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); @@ -497,15 +417,13 @@ mrb_gc_protect(mrb_state *mrb, mrb_value obj) MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj) { - mrb_sym root; mrb_value table; if (mrb_immediate_p(obj)) return; - root = GC_ROOT_SYM; - table = mrb_gv_get(mrb, root); + table = mrb_gv_get(mrb, GC_ROOT_SYM); if (mrb_nil_p(table) || !mrb_array_p(table)) { table = mrb_ary_new(mrb); - mrb_gv_set(mrb, root, table); + mrb_gv_set(mrb, GC_ROOT_SYM, table); } mrb_ary_push(mrb, table, obj); } @@ -514,22 +432,19 @@ mrb_gc_register(mrb_state *mrb, mrb_value obj) MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj) { - mrb_sym root; mrb_value table; struct RArray *a; - mrb_int i; if (mrb_immediate_p(obj)) return; - root = GC_ROOT_SYM; - table = mrb_gv_get(mrb, root); + table = mrb_gv_get(mrb, GC_ROOT_SYM); if (mrb_nil_p(table)) return; if (!mrb_array_p(table)) { - mrb_gv_set(mrb, root, mrb_nil_value()); + mrb_gv_set(mrb, GC_ROOT_SYM, mrb_nil_value()); return; } a = mrb_ary_ptr(table); mrb_ary_modify(mrb, a); - for (i = 0; i < ARY_LEN(a); i++) { + for (mrb_int i = 0; i < ARY_LEN(a); i++) { if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) { mrb_int len = ARY_LEN(a)-1; mrb_value *ptr = ARY_PTR(a); @@ -544,7 +459,6 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj) MRB_API struct RBasic* mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) { - struct RBasic *p; static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } }; mrb_gc *gc = &mrb->gc; @@ -562,6 +476,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) } tt = MRB_INSTANCE_TT(cls); if (tt != MRB_TT_FALSE && + tt != MRB_TT_UNDEF && ttype != MRB_TT_SCLASS && ttype != MRB_TT_ICLASS && ttype != MRB_TT_ENV && @@ -584,15 +499,15 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) add_heap(mrb, gc); } - p = gc->free_heaps->freelist; + struct RBasic *p = gc->free_heaps->freelist; gc->free_heaps->freelist = ((struct free_obj*)p)->next; if (gc->free_heaps->freelist == NULL) { - unlink_free_heap_page(gc, gc->free_heaps); + gc->free_heaps = gc->free_heaps->free_next; } gc->live++; gc_protect(mrb, gc, p); - *(RVALUE *)p = RVALUE_zero; + *(RVALUE*)p = RVALUE_zero; p->tt = ttype; p->c = cls; paint_partial_white(gc, p); @@ -615,8 +530,7 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) static void mark_context_stack(mrb_state *mrb, struct mrb_context *c) { - size_t i; - size_t e; + size_t i, e; mrb_value nil; if (c->stbase == NULL) return; @@ -712,13 +626,12 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_ENV: { struct REnv *e = (struct REnv*)obj; - mrb_int i, len; if (MRB_ENV_ONSTACK_P(e) && e->cxt && e->cxt->fib) { mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib); } - len = MRB_ENV_LEN(e); - for (i=0; istack[i]); } } @@ -736,10 +649,10 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; - size_t i, e=ARY_LEN(a); + size_t e=ARY_LEN(a); mrb_value *p = ARY_PTR(a); - for (i=0; icxt; - if (c && c != mrb->root_c) { - if (!end && c->status != MRB_FIBER_TERMINATED) { - mrb_callinfo *ci = c->ci; - mrb_callinfo *ce = c->cibase; - - while (ce <= ci) { - struct REnv *e = ci->u.env; - if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && - e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) { - mrb_env_unshare(mrb, e, TRUE); - } - ci--; - } - } + if (c != mrb->root_c) { mrb_free_context(mrb, c); } } @@ -1082,6 +982,7 @@ gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) { while (gc->gray_list) { struct RBasic *obj = gc->gray_list; gc->gray_list = obj->gcnext; + obj->gcnext = NULL; gc_mark_children(mrb, gc, obj); } } @@ -1094,6 +995,7 @@ incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) while (gc->gray_list && tried_marks < limit) { struct RBasic *obj = gc->gray_list; gc->gray_list = obj->gcnext; + obj->gcnext = NULL; gc_mark_children(mrb, gc, obj); tried_marks += gc_gray_counts(mrb, gc, obj); } @@ -1152,14 +1054,15 @@ prepare_incremental_sweep(mrb_state *mrb, mrb_gc *gc) // mrb_assert(gc->atomic_gray_list == NULL); // mrb_assert(gc->gray_list == NULL); gc->state = MRB_GC_STATE_SWEEP; - gc->sweeps = gc->heaps; + gc->sweeps = NULL; gc->live_after_mark = gc->live; } static size_t incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) { - mrb_heap_page *page = gc->sweeps; + mrb_heap_page *prev = gc->sweeps; + mrb_heap_page *page = prev ? prev->next : gc->heaps; size_t tried_sweep = 0; while (page && (tried_sweep < limit)) { @@ -1167,7 +1070,6 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) RVALUE *e = p + MRB_HEAP_PAGE_SIZE; size_t freed = 0; mrb_bool dead_slot = TRUE; - mrb_bool full = (page->freelist == NULL); if (is_minor_gc(gc) && page->old) { /* skip a slot which doesn't contain any young object */ @@ -1197,29 +1099,39 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) } /* free dead slot */ - if (dead_slot && freed < MRB_HEAP_PAGE_SIZE) { + if (dead_slot) { mrb_heap_page *next = page->next; - unlink_heap_page(gc, page); - unlink_free_heap_page(gc, page); + if (prev) prev->next = next; + if (gc->heaps == page) + gc->heaps = page->next; + mrb_free(mrb, page); page = next; } else { - if (full && freed > 0) { - link_free_heap_page(gc, page); - } if (page->freelist == NULL && is_minor_gc(gc)) page->old = TRUE; else page->old = FALSE; + prev = page; page = page->next; } tried_sweep += MRB_HEAP_PAGE_SIZE; gc->live -= freed; gc->live_after_mark -= freed; } - gc->sweeps = page; + gc->sweeps = prev; + + /* rebuild free_heaps link */ + gc->free_heaps = NULL; + for (mrb_heap_page *p = gc->heaps; p; p=p->next) { + if (p->freelist) { + p->free_next = gc->free_heaps; + gc->free_heaps = p; + } + } + return tried_sweep; } @@ -1280,22 +1192,17 @@ incremental_gc_step(mrb_state *mrb, mrb_gc *gc) static void clear_all_old(mrb_state *mrb, mrb_gc *gc) { - mrb_bool origin_mode = gc->generational; - mrb_assert(is_generational(gc)); - if (is_major_gc(gc)) { + if (gc->full) { /* finish the half baked GC */ incremental_gc_finish(mrb, gc); } - else { - /* Sweep the dead objects, then reset all the live objects - * (including all the old objects, of course) to white. */ - gc->generational = FALSE; - prepare_incremental_sweep(mrb, gc); - incremental_gc_finish(mrb, gc); - } - gc->generational = origin_mode; - + /* Sweep the dead objects, then reset all the live objects + * (including all the old objects, of course) to white. */ + gc->generational = FALSE; + prepare_incremental_sweep(mrb, gc); + incremental_gc_finish(mrb, gc); + gc->generational = TRUE; /* The gray objects have already been painted as white */ gc->atomic_gray_list = gc->gray_list = NULL; } @@ -1307,9 +1214,6 @@ mrb_incremental_gc(mrb_state *mrb) if (gc->disabled || gc->iterating) return; - GC_INVOKE_TIME_REPORT("mrb_incremental_gc()"); - GC_TIME_START; - if (is_minor_gc(gc)) { incremental_gc_finish(mrb, gc); } @@ -1329,7 +1233,7 @@ mrb_incremental_gc(mrb_state *mrb) gc->full = FALSE; if (threshold < MAJOR_GC_TOOMANY) { - gc->majorgc_old_threshold = threshold; + gc->oldgen_threshold = threshold; } else { /* too many objects allocated during incremental GC, */ @@ -1337,15 +1241,11 @@ mrb_incremental_gc(mrb_state *mrb) mrb_full_gc(mrb); } } - else if (is_minor_gc(gc)) { - if (gc->live > gc->majorgc_old_threshold) { - clear_all_old(mrb, gc); - gc->full = TRUE; - } + else if (is_minor_gc(gc) && gc->live > gc->oldgen_threshold) { + clear_all_old(mrb, gc); + gc->full = TRUE; } } - - GC_TIME_STOP_AND_REPORT; } /* Perform a full gc cycle */ @@ -1357,9 +1257,6 @@ mrb_full_gc(mrb_state *mrb) if (!mrb->c) return; if (gc->disabled || gc->iterating) return; - GC_INVOKE_TIME_REPORT("mrb_full_gc()"); - GC_TIME_START; - if (is_generational(gc)) { /* clear all the old objects back to young */ clear_all_old(mrb, gc); @@ -1374,14 +1271,13 @@ mrb_full_gc(mrb_state *mrb) gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio; if (is_generational(gc)) { - gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; + gc->oldgen_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; gc->full = FALSE; } #ifdef MRB_USE_MALLOC_TRIM malloc_trim(0); #endif - GC_TIME_STOP_AND_REPORT; } MRB_API void @@ -1580,7 +1476,7 @@ change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable) } else if (!is_generational(gc) && enable) { incremental_gc_finish(mrb, gc); - gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; + gc->oldgen_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO; gc->full = FALSE; } gc->generational = enable; @@ -1629,10 +1525,9 @@ gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, page = gc->heaps; while (page != NULL) { RVALUE *p; - int i; p = objects(page); - for (i=0; i < MRB_HEAP_PAGE_SIZE; i++) { + for (int i=0; i < MRB_HEAP_PAGE_SIZE; i++) { if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK) return; } @@ -1659,7 +1554,7 @@ mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, vo gc_each_objects(mrb, &mrb->gc, callback, data); mrb->jmp = prev_jmp; mrb->gc.iterating = iterating; - } MRB_CATCH(&c_jmp) { + } MRB_CATCH(&c_jmp) { mrb->gc.iterating = iterating; mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); diff --git a/mruby/src/hash.c b/mruby/src/hash.c index 40cfacf6..ad92f541 100644 --- a/mruby/src/hash.c +++ b/mruby/src/hash.c @@ -273,7 +273,7 @@ HT_ASSERT_SAFE_READ(ea_capa); } \ code; \ if (flags__ != (h__->flags & mask__) || \ - tbl__ != h__->hsh.ht || \ + tbl__ != h__->hsh.ht || \ ((H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR || h_ht_p(h__)) && \ ht_ea_capa__ != ht_ea_capa(h__)) || \ ((H_CHECK_MODIFIED_USE_HT_EA_FOR_AR || h_ht_p(h__)) && \ @@ -382,7 +382,7 @@ obj_eql(mrb_state *mrb, mrb_value a, mrb_value b, struct RHash *h) } } -static mrb_bool +static inline mrb_bool entry_deleted_p(const hash_entry* entry) { return mrb_undef_p(entry->key); @@ -1109,7 +1109,11 @@ MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *h, mrb_hash_foreach_func *func, void *data) { h_each(h, entry, { - if (func(mrb, entry->key, entry->val, data) != 0) return; + int n; + h_check_modified(mrb, h, { + n = func(mrb, entry->key, entry->val, data); + }); + if (n != 0) return; }); } @@ -1560,10 +1564,16 @@ mrb_hash_clear(mrb_state *mrb, mrb_value hash) static mrb_value mrb_hash_aset(mrb_state *mrb, mrb_value self) { - mrb_value key, val; + mrb_int argc = mrb_get_argc(mrb); + + if (argc != 2) { + mrb_argnum_error(mrb, argc, 2, 2); + } - mrb_get_args(mrb, "oo", &key, &val); - mrb_hash_set(mrb, self, key, val); + const mrb_value *argv = mrb_get_argv(mrb); + mrb_value val = argv[1]; + + mrb_hash_set(mrb, self, argv[0], argv[1]); return val; } @@ -1742,8 +1752,8 @@ mrb_hash_merge(mrb_state *mrb, mrb_value hash1, mrb_value hash2) if (h_size(h2) == 0) return; h_each(h2, entry, { h_check_modified(mrb, h2, {h_set(mrb, h1, entry->key, entry->val);}); - mrb_field_write_barrier_value(mrb, (struct RBasic *)h1, entry->key); - mrb_field_write_barrier_value(mrb, (struct RBasic *)h1, entry->val); + mrb_field_write_barrier_value(mrb, (struct RBasic*)h1, entry->key); + mrb_field_write_barrier_value(mrb, (struct RBasic*)h1, entry->val); }); } @@ -1787,6 +1797,69 @@ mrb_hash_rehash(mrb_state *mrb, mrb_value self) return self; } +static mrb_value +mrb_hash_compact(mrb_state *mrb, mrb_value hash) +{ + struct RHash *h = mrb_hash_ptr(hash); + mrb_bool ht_p = h_ht_p(h); + uint32_t size = ht_p ? ht_size(h) : ar_size(h); + uint32_t dec = 0; + + mrb_check_frozen(mrb, h); + h_each(h, entry, { + if (mrb_nil_p(entry->val)) { + entry_delete(entry); + dec++; + } + }); + if (dec == 0) return mrb_nil_value(); + size -= dec; + if (ht_p) { + ht_set_size(h, size); + } + else { + ar_set_size(h, size); + } + return hash; +} + +/* + * call-seq: + * hash.to_s -> string + * hash.inspect -> string + * + * Return the contents of this hash as a string. + */ +static mrb_value +mrb_hash_to_s(mrb_state *mrb, mrb_value self) +{ + mrb->c->ci->mid = MRB_SYM(inspect); + mrb_value ret = mrb_str_new_lit(mrb, "{"); + int ai = mrb_gc_arena_save(mrb); + if (mrb_inspect_recursive_p(mrb, self)) { + mrb_str_cat_lit(mrb, ret, "...}"); + return ret; + } + + mrb_int i = 0; + struct RHash *h = mrb_hash_ptr(self); + h_each(h, entry, { + if (i++ > 0) mrb_str_cat_lit(mrb, ret, ", "); + h_check_modified(mrb, h, { + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->key)); + }); + mrb_gc_arena_restore(mrb, ai); + mrb_str_cat_lit(mrb, ret, "=>"); + h_check_modified(mrb, h, { + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->val)); + }); + mrb_gc_arena_restore(mrb, ai); + }); + mrb_str_cat_lit(mrb, ret, "}"); + + return ret; +} + void mrb_init_hash(mrb_state *mrb) { @@ -1819,6 +1892,9 @@ mrb_init_hash(mrb_state *mrb) mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */ mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */ mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */ + mrb_define_method(mrb, h, "to_s", mrb_hash_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "inspect", mrb_hash_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, h, "rehash", mrb_hash_rehash, MRB_ARGS_NONE()); mrb_define_method(mrb, h, "__merge", mrb_hash_merge_m, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, h, "__compact", mrb_hash_compact, MRB_ARGS_NONE()); /* implementation of Hash#compact! */ } diff --git a/mruby/src/kernel.c b/mruby/src/kernel.c index 250f01d2..59474be8 100644 --- a/mruby/src/kernel.c +++ b/mruby/src/kernel.c @@ -71,7 +71,7 @@ mrb_obj_inspect(mrb_state *mrb, mrb_value obj) * to provide meaningful semantics in case statements. */ static mrb_value -mrb_equal_m(mrb_state *mrb, mrb_value self) +mrb_eqq_m(mrb_state *mrb, mrb_value self) { mrb_value arg = mrb_get_arg1(mrb); @@ -83,11 +83,45 @@ mrb_cmp_m(mrb_state *mrb, mrb_value self) { mrb_value arg = mrb_get_arg1(mrb); + /* recursion check */ + for (mrb_callinfo *ci=&mrb->c->ci[-1]; ci>=mrb->c->cibase; ci--) { + if (ci->mid == MRB_OPSYM(cmp) && + mrb_obj_eq(mrb, self, ci->stack[0]) && + mrb_obj_eq(mrb, arg, ci->stack[1])) { + /* recursive <=> calling returns `nil` */ + return mrb_nil_value(); + } + } + if (mrb_equal(mrb, self, arg)) return mrb_fixnum_value(0); return mrb_nil_value(); } +static mrb_bool +inspect_recursive_p(mrb_state *mrb, mrb_value obj, int n) +{ + for (mrb_callinfo *ci=&mrb->c->ci[-1-n]; ci>=mrb->c->cibase; ci--) { + if (ci->mid == MRB_SYM(inspect) && + mrb_obj_eq(mrb, obj, ci->stack[0])) { + return TRUE; + } + } + return FALSE; +} + +mrb_bool +mrb_inspect_recursive_p(mrb_state *mrb, mrb_value obj) +{ + return inspect_recursive_p(mrb, obj, 0); +} + +static mrb_value +mrb_obj_inspect_recursive_p(mrb_state *mrb, mrb_value obj) +{ + return mrb_bool_value(inspect_recursive_p(mrb, obj, 1)); +} + /* 15.3.1.3.3 */ /* 15.3.1.3.33 */ /* @@ -380,24 +414,26 @@ mrb_false(mrb_state *mrb, mrb_value self) MRB_API mrb_value mrb_f_raise(mrb_state *mrb, mrb_value self) { - mrb_value a[2], exc; + mrb_value exc, mesg; mrb_int argc; - argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); + argc = mrb_get_args(mrb, "|oo", &exc, &mesg); mrb->c->ci->mid = 0; switch (argc) { case 0: mrb_raise(mrb, E_RUNTIME_ERROR, ""); break; case 1: - if (mrb_string_p(a[0])) { - a[1] = a[0]; - argc = 2; - a[0] = mrb_obj_value(E_RUNTIME_ERROR); + if (mrb_string_p(exc)) { + mesg = exc; + exc = mrb_obj_value(E_RUNTIME_ERROR); + } + else { + mesg = mrb_nil_value(); } /* fall through */ default: - exc = mrb_make_exception(mrb, argc, a); + exc = mrb_make_exception(mrb, exc, mesg); mrb_exc_raise(mrb, exc); break; } @@ -441,12 +477,6 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) return val; } -static inline mrb_bool -basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) -{ - return mrb_respond_to(mrb, obj, id); -} - /* 15.3.1.3.43 */ /* * call-seq: @@ -466,18 +496,16 @@ basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) static mrb_value obj_respond_to(mrb_state *mrb, mrb_value self) { - mrb_sym id, rtm_id; + mrb_sym id; mrb_bool priv = FALSE, respond_to_p; mrb_get_args(mrb, "n|b", &id, &priv); - respond_to_p = basic_obj_respond_to(mrb, self, id, !priv); + respond_to_p = mrb_respond_to(mrb, self, id); if (!respond_to_p) { - rtm_id = MRB_SYM_Q(respond_to_missing); - if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) { - mrb_value args[2], v; - args[0] = mrb_symbol_value(id); - args[1] = mrb_bool_value(priv); - v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); + mrb_sym rtm_id = MRB_SYM_Q(respond_to_missing); + if (!mrb_func_basic_p(mrb, self, rtm_id, mrb_false)) { + mrb_value v; + v = mrb_funcall_id(mrb, self, rtm_id, 2, mrb_symbol_value(id), mrb_bool_value(priv)); return mrb_bool_value(mrb_bool(v)); } } @@ -505,7 +533,7 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) return mrb_false_value(); } else { - ary = mrb_funcall_id(mrb, self, MRB_SYM(to_a), 0); + ary = mrb_funcall_argv(mrb, self, MRB_SYM(to_a), 0, NULL); if (mrb_nil_p(ary)) { return mrb_funcall_argv(mrb, self, eqq, 1, &v); } @@ -513,7 +541,7 @@ mrb_obj_ceqq(mrb_state *mrb, mrb_value self) } len = RARRAY_LEN(ary); for (i=0; i", mrb_cmp_m, MRB_ARGS_REQ(1)); mrb_define_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.6 */ mrb_define_method(mrb, krn, "class", mrb_obj_class_m, MRB_ARGS_NONE()); /* 15.3.1.3.7 */ @@ -569,6 +594,8 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ mrb_define_method(mrb, krn, "__to_int", mrb_ensure_int_type, MRB_ARGS_NONE()); /* internal */ mrb_define_method(mrb, krn, "__ENCODING__", mrb_encoding, MRB_ARGS_NONE()); + mrb_define_method(mrb, krn, "respond_to_missing?", mrb_false, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, krn, "__inspect_recursive?", mrb_obj_inspect_recursive_p, MRB_ARGS_NONE()); mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); } diff --git a/mruby/src/load.c b/mruby/src/load.c index 52cb154b..3287da2e 100644 --- a/mruby/src/load.c +++ b/mruby/src/load.c @@ -110,7 +110,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ } else { void *buf = mrb_malloc(mrb, data_len); - irep->iseq = (mrb_code *)buf; + irep->iseq = (mrb_code*)buf; memcpy(buf, src, data_len); } src += data_len; @@ -220,7 +220,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ if (SIZE_ERROR_MUL(irep->slen, sizeof(mrb_sym))) { return FALSE; } - irep->syms = syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); + irep->syms = syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); for (i = 0; i < irep->slen; i++) { snl = bin_to_uint16(src); /* symbol name length */ @@ -233,10 +233,10 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, const uint8_t *end, size_ if (src + snl > end) return FALSE; if (flags & FLAG_SRC_MALLOC) { - syms[i] = mrb_intern(mrb, (char *)src, snl); + syms[i] = mrb_intern(mrb, (char*)src, snl); } else { - syms[i] = mrb_intern_static(mrb, (char *)src, snl); + syms[i] = mrb_intern_static(mrb, (char*)src, snl); } src += snl + 1; mrb_gc_arena_restore(mrb, ai); @@ -331,7 +331,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ uint16_t filename_idx; if (bin > end) return MRB_DUMP_GENERAL_FAILURE; - file = (mrb_irep_debug_info_file *)mrb_calloc(mrb, 1, sizeof(*file)); + file = (mrb_irep_debug_info_file*)mrb_calloc(mrb, 1, sizeof(*file)); debug->files[f_idx] = file; file->start_pos = bin_to_uint32(bin); @@ -352,7 +352,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, const uint8_t *end, mrb_ size_t l = sizeof(uint16_t) * (size_t)file->line_entry_count; if (bin + l > end) return MRB_DUMP_GENERAL_FAILURE; - uint16_t *ary = (uint16_t *)mrb_malloc(mrb, l); + uint16_t *ary = (uint16_t*)mrb_malloc(mrb, l); for (l = 0; l < file->line_entry_count; l++) { ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); @@ -427,7 +427,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep * mrb_value filenames_obj; bin = start; - header = (struct rite_section_debug_header *)bin; + header = (struct rite_section_debug_header*)bin; bin += sizeof(struct rite_section_debug_header); filenames_len = bin_to_uint16(bin); @@ -443,10 +443,10 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep * goto debug_exit; } if (flags & FLAG_SRC_MALLOC) { - filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); + filenames[i] = mrb_intern(mrb, (const char*)bin, (size_t)f_len); } else { - filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len); + filenames[i] = mrb_intern_static(mrb, (const char*)bin, (size_t)f_len); } bin += f_len; } @@ -558,7 +558,7 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, size_t size, mrb_irep *ire static int read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint8_t *flags) { - const struct rite_binary_header *header = (const struct rite_binary_header *)bin; + const struct rite_binary_header *header = (const struct rite_binary_header*)bin; if (bufsize < sizeof(struct rite_binary_header)) { return MRB_DUMP_READ_FAULT; @@ -607,7 +607,7 @@ read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags) bin += sizeof(struct rite_binary_header); bin_size -= sizeof(struct rite_binary_header); while (bin_size > sizeof(struct rite_section_header)) { - section_header = (const struct rite_section_header *)bin; + section_header = (const struct rite_section_header*)bin; uint32_t section_size = bin_to_uint32(section_header->section_size); if (bin_size < section_size) return NULL; if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) { @@ -654,7 +654,7 @@ DEFINE_READ_IREP_FUNC( static struct RProc* mrb_proc_read_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize) { - return read_irep(mrb, (const uint8_t *)buf, bufsize, FLAG_SRC_MALLOC); + return read_irep(mrb, (const uint8_t*)buf, bufsize, FLAG_SRC_MALLOC); } DEFINE_READ_IREP_FUNC( diff --git a/mruby/src/numeric.c b/mruby/src/numeric.c index a671eeba..ecc7aa59 100644 --- a/mruby/src/numeric.c +++ b/mruby/src/numeric.c @@ -66,7 +66,7 @@ mrb_int_pow(mrb_state *mrb, mrb_value x, mrb_value y) else #endif { - mrb_get_args(mrb, "i", &exp); + exp = mrb_as_int(mrb, y); } if (exp < 0) { #ifndef MRB_NO_FLOAT @@ -130,7 +130,7 @@ mrb_div_int_value(mrb_state *mrb, mrb_int x, mrb_int y) if (y == 0) { mrb_int_zerodiv(mrb); } - else if(x == MRB_INT_MIN && y == -1) { + else if (x == MRB_INT_MIN && y == -1) { #ifdef MRB_USE_BIGINT return mrb_bint_mul_ii(mrb, x, y); #else @@ -208,9 +208,7 @@ int_idiv(mrb_state *mrb, mrb_value x) return mrb_bint_div(mrb, x, mrb_get_arg1(mrb)); } #endif - mrb_int y; - - mrb_get_args(mrb, "i", &y); + mrb_int y = mrb_as_int(mrb, mrb_get_arg1(mrb)); return mrb_div_int_value(mrb, mrb_integer(x), y); } @@ -221,9 +219,8 @@ int_quo(mrb_state *mrb, mrb_value x) #ifdef MRB_NO_FLOAT return int_idiv(mrb, x); #else - mrb_float y; + mrb_float y = mrb_as_float(mrb, mrb_get_arg1(mrb)); - mrb_get_args(mrb, "f", &y); if (y == 0) { mrb_int_zerodiv(mrb); } @@ -293,10 +290,10 @@ flo_pow(mrb_state *mrb, mrb_value x) static mrb_value flo_idiv(mrb_state *mrb, mrb_value xv) { - mrb_int y; - - mrb_get_args(mrb, "i", &y); - return mrb_div_int_value(mrb, (mrb_int)mrb_float(xv), y); + mrb_float x = mrb_float(xv); + mrb_check_num_exact(mrb, x); + mrb_int y = mrb_as_int(mrb, mrb_get_arg1(mrb)); + return mrb_div_int_value(mrb, (mrb_int)x, y); } mrb_float @@ -357,7 +354,8 @@ mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) if (*p == '.') goto exit; if (*p == 'e') { memmove(p+2, p, strlen(p)+1); - memcpy(p, ".0", 2); + p[0] = '.'; + p[1] = '0'; goto exit; } } @@ -537,7 +535,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_as_float(mrb, y), 0, &mod); + flodivmod(mrb, mrb_float(x), mrb_as_float(mrb, y), NULL, &mod); return mrb_float_value(mrb, mod); } #endif @@ -709,9 +707,10 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) val = trunc(val); #else if (val > 0){ - val = floor(val); - } else { - val = ceil(val); + val = floor(val); + } + else { + val = ceil(val); } #endif if (val == 0 && mrb_float(x) < 0) { @@ -731,9 +730,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) static mrb_value flo_rshift(mrb_state *mrb, mrb_value x) { - mrb_int width; - - mrb_get_args(mrb, "i", &width); + mrb_int width = mrb_as_int(mrb, mrb_get_arg1(mrb)); if (width == MRB_INT_MIN) return flo_shift(mrb, x, -MRB_INT_BIT); return flo_shift(mrb, x, -width); } @@ -741,9 +738,7 @@ flo_rshift(mrb_state *mrb, mrb_value x) static mrb_value flo_lshift(mrb_state *mrb, mrb_value x) { - mrb_int width; - - mrb_get_args(mrb, "i", &width); + mrb_int width = mrb_as_int(mrb, mrb_get_arg1(mrb)); return flo_shift(mrb, x, width); } @@ -1204,7 +1199,7 @@ intdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp) if (y == 0) { mrb_int_zerodiv(mrb); } - else if(x == MRB_INT_MIN && y == -1) { + else if (x == MRB_INT_MIN && y == -1) { mrb_int_overflow(mrb, "division"); } else { @@ -1374,13 +1369,12 @@ int_equal(mrb_state *mrb, mrb_value x) static mrb_value int_rev(mrb_state *mrb, mrb_value num) { - mrb_int val = mrb_integer(num); - #ifdef MRB_USE_BIGINT if (mrb_bigint_p(num)) { - mrb_bint_rev(mrb, num); + return mrb_bint_rev(mrb, num); } #endif + mrb_int val = mrb_integer(num); return mrb_int_value(mrb, ~val); } @@ -1521,7 +1515,7 @@ int_lshift(mrb_state *mrb, mrb_value x) { mrb_int width, val; - mrb_get_args(mrb, "i", &width); + width = mrb_as_int(mrb, mrb_get_arg1(mrb)); if (width == 0) { return x; } @@ -1556,7 +1550,7 @@ int_rshift(mrb_state *mrb, mrb_value x) { mrb_int width, val; - mrb_get_args(mrb, "i", &width); + width = mrb_as_int(mrb, mrb_get_arg1(mrb)); if (width == 0) { return x; } @@ -1620,16 +1614,26 @@ int_ceil(mrb_state *mrb, mrb_value x) if (mrb_nil_p(f)) return x; #ifdef MRB_USE_BIGINT if (mrb_bigint_p(x)) { - return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f))); + x = mrb_bint_add_d(mrb, x, f); + return mrb_bint_sub(mrb, x, mrb_bint_mod(mrb, x, f)); } #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); + mrb_int c = a % b; int neg = a < 0; - if (neg) a = -a; - else a += b - 1; - a = a / b * b; - if (neg) a = -a; + a -= c; + if (!neg) { + if (mrb_int_add_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_add(mrb, x, f); +#else + mrb_int_overflow(mrb, "ceil"); +#endif + } + a = c; + } return mrb_int_value(mrb, a); } @@ -1657,10 +1661,20 @@ int_floor(mrb_state *mrb, mrb_value x) #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); + mrb_int c = a % b; int neg = a < 0; - if (neg) a = -a + b - 1; - a = a / b * b; - if (neg) a = -a; + a -= c; + if (neg) { + if (mrb_int_sub_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_sub(mrb, x, f); +#else + mrb_int_overflow(mrb, "floor"); +#endif + } + a = c; + } return mrb_int_value(mrb, a); } @@ -1686,7 +1700,7 @@ int_round(mrb_state *mrb, mrb_value x) mrb_value r = mrb_bint_mod(mrb, x, f); mrb_value n = mrb_bint_sub(mrb, x, r); mrb_value h = mrb_bigint_p(f) ? mrb_bint_rshift(mrb, f, 1) : mrb_int_value(mrb, mrb_integer(f)>>1); - mrb_int cmp = mrb_bigint_p(r) ? mrb_bint_cmp(mrb, r, h) : (mrb_integer(r) - mrb_integer(h)); + mrb_int cmp = mrb_bigint_p(r) ? mrb_bint_cmp(mrb, r, h) : (mrb_bigint_p(h) ? -mrb_bint_cmp(mrb, h, r) : (mrb_integer(r)-mrb_integer(h))); if ((cmp > 0) || (cmp == 0 && mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) > 0)) { n = mrb_as_bint(mrb, n); n = mrb_bint_add(mrb, n, f); @@ -1696,10 +1710,35 @@ int_round(mrb_state *mrb, mrb_value x) #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); - int neg = a < 0; - if (neg) a = -a; - a = (a + b / 2) / b * b; - if (neg) a = -a; + mrb_int c = a % b; + a -= c; + if (c < 0) { + c = -c; + if (b/2 < c) { + if (mrb_int_sub_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_sub(mrb, x, f); +#else + mrb_int_overflow(mrb, "round"); +#endif + } + } + a = c; + } + else { + if (b/2 < c) { + if (mrb_int_add_overflow(a, b, &c)) { +#ifdef MRB_USE_BIGINT + x = mrb_bint_new_int(mrb, a); + return mrb_bint_add(mrb, x, f); +#else + mrb_int_overflow(mrb, "round"); +#endif + } + } + a = c; + } return mrb_int_value(mrb, a); } @@ -1723,21 +1762,16 @@ int_truncate(mrb_state *mrb, mrb_value x) #ifdef MRB_USE_BIGINT if (mrb_bigint_p(x)) { mrb_value m = mrb_bint_mod(mrb, x, f); + x = mrb_bint_sub_d(mrb, x, m); if (mrb_bint_cmp(mrb, x, mrb_fixnum_value(0)) < 0) { - return mrb_bint_add(mrb, x, mrb_bint_sub(mrb, x, m)); - } - else { - return mrb_bint_sub(mrb, x, m); + return mrb_bint_add(mrb, x, f); } + return x; } #endif mrb_int a = mrb_integer(x); mrb_int b = mrb_integer(f); - int neg = a < 0; - if (neg) a = -a; - a = a / b * b; - if (neg) a = -a; - return mrb_int_value(mrb, a); + return mrb_int_value(mrb, a - (a % b)); } /* 15.2.8.3.23 */ @@ -2141,7 +2175,7 @@ mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2) return mrb_str_cmp(mrb, obj1, obj2); default: if (!mrb_respond_to(mrb, obj1, MRB_OPSYM(cmp))) return -2; - v = mrb_funcall_id(mrb, obj1, MRB_OPSYM(cmp), 1, obj2); + v = mrb_funcall_argv(mrb, obj1, MRB_OPSYM(cmp), 1, &obj2); if (mrb_nil_p(v) || !mrb_integer_p(v)) return -2; return mrb_integer(v); @@ -2188,7 +2222,7 @@ mrb_init_numeric(mrb_state *mrb) /* Integer Class */ mrb->integer_class = integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */ - MRB_SET_INSTANCE_TT(integer, MRB_TT_INTEGER); + MRB_SET_INSTANCE_TT(integer, MRB_TT_UNDEF); mrb_undef_class_method(mrb, integer, "new"); mrb_define_method(mrb, integer, "**", int_pow, MRB_ARGS_REQ(1)); mrb_define_method(mrb, integer, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */ @@ -2233,7 +2267,7 @@ mrb_init_numeric(mrb_state *mrb) #ifndef MRB_NO_FLOAT /* Float Class */ mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ - MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); + MRB_SET_INSTANCE_TT(fl, MRB_TT_UNDEF); mrb_undef_class_method(mrb, fl, "new"); mrb_define_method(mrb, fl, "**", flo_pow, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "/", flo_div, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */ diff --git a/mruby/src/object.c b/mruby/src/object.c index cc7ec644..91e4a881 100644 --- a/mruby/src/object.c +++ b/mruby/src/object.c @@ -53,32 +53,29 @@ mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2) MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2) { - mrb_value result; - if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; #ifndef MRB_NO_FLOAT /* value mixing with integer and float */ - if (mrb_integer_p(obj1) && mrb_float_p(obj2)) { + else if (mrb_integer_p(obj1) && mrb_float_p(obj2)) { if ((mrb_float)mrb_integer(obj1) == mrb_float(obj2)) return TRUE; - return FALSE; } else if (mrb_float_p(obj1) && mrb_integer_p(obj2)) { if (mrb_float(obj1) == (mrb_float)mrb_integer(obj2)) return TRUE; - return FALSE; } #endif #ifdef MRB_USE_BIGINT - if (mrb_bigint_p(obj1) && + else if (mrb_bigint_p(obj1) && (mrb_integer_p(obj2) || mrb_bigint_p(obj2) || mrb_float_p(obj2))) { if (mrb_bint_cmp(mrb, obj1, obj2) == 0) return TRUE; - return FALSE; } #endif - result = mrb_funcall_id(mrb, obj1, MRB_OPSYM(eq), 1, obj2); - if (mrb_test(result)) return TRUE; + else if (!mrb_func_basic_p(mrb, obj1, MRB_OPSYM(eq), mrb_obj_equal_m)) { + mrb_value result = mrb_funcall_argv(mrb, obj1, MRB_OPSYM(eq), 1, &obj2); + if (mrb_test(result)) return TRUE; + } return FALSE; } @@ -638,7 +635,7 @@ mrb_check_hash_type(mrb_state *mrb, mrb_value hash) MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj) { - mrb_value v = mrb_funcall_id(mrb, obj, MRB_SYM(inspect), 0); + mrb_value v = mrb_funcall_argv(mrb, obj, MRB_SYM(inspect), 0, NULL); if (!mrb_string_p(v)) { v = mrb_obj_as_string(mrb, obj); } @@ -649,5 +646,5 @@ MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2) { if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE; - return mrb_test(mrb_funcall_id(mrb, obj1, MRB_SYM_Q(eql), 1, obj2)); + return mrb_test(mrb_funcall_argv(mrb, obj1, MRB_SYM_Q(eql), 1, &obj2)); } diff --git a/mruby/src/pool.c b/mruby/src/pool.c index ab30be1d..26088186 100644 --- a/mruby/src/pool.c +++ b/mruby/src/pool.c @@ -63,7 +63,7 @@ struct mrb_pool { MRB_API mrb_pool* mrb_pool_open(mrb_state *mrb) { - mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool)); + mrb_pool *pool = (mrb_pool*)mrb_malloc_simple(mrb, sizeof(mrb_pool)); if (pool) { pool->mrb = mrb; @@ -95,7 +95,7 @@ page_alloc(mrb_pool *pool, size_t len) if (len < POOL_PAGE_SIZE) len = POOL_PAGE_SIZE; - page = (struct mrb_pool_page *)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len); + page = (struct mrb_pool_page*)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len); if (page) { page->offset = 0; page->len = len; diff --git a/mruby/src/proc.c b/mruby/src/proc.c index c27e6ea7..ac601a4b 100644 --- a/mruby/src/proc.c +++ b/mruby/src/proc.c @@ -193,6 +193,29 @@ mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx) return e->stack[idx]; } +mrb_value +mrb_proc_get_self(mrb_state *mrb, struct RProc *p, struct RClass **target_class_p) +{ + if (MRB_PROC_CFUNC_P(p)) { + *target_class_p = mrb->object_class; + return mrb_nil_value(); + } + else { + struct REnv *e = p->e.env; + + if (!e || e->tt != MRB_TT_ENV) { + *target_class_p = mrb->object_class; + return mrb_top_self(mrb); + } + else if (MRB_ENV_LEN(e) < 1) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "self is lost (probably ran out of memory when the block became independent)"); + } + + *target_class_p = e->c; + return e->stack[0]; + } +} + void mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b) { @@ -248,13 +271,42 @@ mrb_proc_init_copy(mrb_state *mrb, mrb_value self) return self; } -/* 15.2.17.4.2 */ static mrb_value proc_arity(mrb_state *mrb, mrb_value self) { return mrb_int_value(mrb, mrb_proc_arity(mrb_proc_ptr(self))); } +mrb_bool +mrb_proc_eql(mrb_state *mrb, mrb_value self, mrb_value other) +{ + if (mrb_type(self) != MRB_TT_PROC) return FALSE; + if (mrb_type(other) != MRB_TT_PROC) return FALSE; + + struct RProc *p1 = mrb_proc_ptr(self); + struct RProc *p2 = mrb_proc_ptr(other); + if (MRB_PROC_CFUNC_P(p1)) { + if (!MRB_PROC_CFUNC_P(p1)) return FALSE; + if (p1->body.func != p2->body.func) return FALSE; + } + else if (MRB_PROC_CFUNC_P(p2)) return FALSE; + else if (p1->body.irep != p2->body.irep) return FALSE; + return TRUE; +} + +static mrb_value +proc_eql(mrb_state *mrb, mrb_value self) +{ + return mrb_bool_value(mrb_proc_eql(mrb, self, mrb_get_arg1(mrb))); +} + +static mrb_value +proc_hash(mrb_state *mrb, mrb_value self) +{ + struct RProc *p = mrb_proc_ptr(self); + return mrb_int_value(mrb, (mrb_int)(((intptr_t)p->body.irep)^MRB_TT_PROC)); +} + /* 15.3.1.2.6 */ /* 15.3.1.3.27 */ /* @@ -441,12 +493,14 @@ mrb_init_proc(mrb_state *mrb) mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE()); /* 15.2.17.4.2 */ + mrb_define_method(mrb, mrb->proc_class, "==", proc_eql, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->proc_class, "eql?", proc_eql, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, mrb->proc_class, "hash", proc_hash, MRB_ARGS_NONE()); /* 15.2.17.4.2 */ MRB_METHOD_FROM_PROC(m, &call_proc); - mrb_define_method_raw(mrb, mrb->proc_class, MRB_SYM(call), m); - mrb_define_method_raw(mrb, mrb->proc_class, MRB_OPSYM(aref), m); + mrb_define_method_raw(mrb, mrb->proc_class, MRB_SYM(call), m); /* 15.2.17.4.3 */ + mrb_define_method_raw(mrb, mrb->proc_class, MRB_OPSYM(aref), m); /* 15.2.17.4.1 */ - mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.2.6 */ mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); /* 15.3.1.3.27 */ } diff --git a/mruby/src/range.c b/mruby/src/range.c index a81bcd42..7741e90a 100644 --- a/mruby/src/range.c +++ b/mruby/src/range.c @@ -70,7 +70,7 @@ static void range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r) { #ifndef MRB_RANGE_EMBED - r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); + r->edges = (mrb_range_edges*)mrb_malloc(mrb, sizeof(mrb_range_edges)); #endif } @@ -311,7 +311,6 @@ range_eql(mrb_state *mrb, mrb_value range) struct RRange *r, *o; if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); - if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value(); if (!mrb_range_p(obj)) return mrb_false_value(); r = mrb_range_ptr(mrb, range); @@ -370,8 +369,10 @@ range_num_to_a(mrb_state *mrb, mrb_value range) len++; } ary = mrb_ary_new_capa(mrb, len); + mrb_value *ptr = RARRAY_PTR(ary); for (mrb_int i=0; i b) { + return mrb_ary_new_capa(mrb, 0); + } ary = mrb_ary_new_capa(mrb, (mrb_int)(b - a) + 1); + mrb_value *ptr = RARRAY_PTR(ary); + mrb_int i = 0; if (RANGE_EXCL(r)) { while (a < b) { - mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a)); + ptr[i++] = mrb_int_value(mrb, (mrb_int)a); + ARY_SET_LEN(RARRAY(ary), i); a += 1.0; } } else { while (a <= b) { - mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a)); + ptr[i++] = mrb_int_value(mrb, (mrb_int)a); + ARY_SET_LEN(RARRAY(ary), i); a += 1.0; } } diff --git a/mruby/src/readfloat.c b/mruby/src/readfloat.c index a89fcafa..80d438ba 100644 --- a/mruby/src/readfloat.c +++ b/mruby/src/readfloat.c @@ -65,7 +65,7 @@ mrb_read_float(const char *str, char **endp, double *fp) if (ISDIGIT(*p)) { while (*p && ISDIGIT(*p)) { - f += base * (*p - '0') ; + f += base * (*p - '0'); base /= 10.0; p++; n++; diff --git a/mruby/src/state.c b/mruby/src/state.c index a1065a20..3f48756e 100644 --- a/mruby/src/state.c +++ b/mruby/src/state.c @@ -20,7 +20,7 @@ void mrb_init_mrbgems(mrb_state*); void mrb_gc_init(mrb_state*, mrb_gc *gc); void mrb_gc_destroy(mrb_state*, mrb_gc *gc); -int mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *opaque); +int mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state*, void*), void *opaque); static void init_gc_and_core(mrb_state *mrb, void *opaque) @@ -42,7 +42,7 @@ mrb_open_core(mrb_allocf f, void *ud) mrb_state *mrb; if (f == NULL) f = mrb_default_allocf; - mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); + mrb = (mrb_state*)(f)(NULL, NULL, sizeof(mrb_state), ud); if (mrb == NULL) return NULL; *mrb = mrb_state_zero; @@ -207,7 +207,7 @@ mrb_add_irep(mrb_state *mrb) static const mrb_irep mrb_irep_zero = { 0 }; mrb_irep *irep; - irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); + irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep)); *irep = mrb_irep_zero; irep->refcnt = 1; diff --git a/mruby/src/string.c b/mruby/src/string.c index 3e82b1ca..d3c3b2e1 100644 --- a/mruby/src/string.c +++ b/mruby/src/string.c @@ -33,10 +33,10 @@ const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #endif static void -str_check_too_big(mrb_state *mrb, mrb_int len) +str_check_length(mrb_state *mrb, mrb_int len) { if (len < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "[BUG] negative string length"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative (or overflowed) string size"); } #if MRB_STR_LENGTH_MAX != 0 if (len > MRB_STR_LENGTH_MAX-1) { @@ -49,8 +49,8 @@ static struct RString* str_init_normal_capa(mrb_state *mrb, struct RString *s, const char *p, mrb_int len, mrb_int capa) { - str_check_too_big(mrb, capa); - char *dst = (char *)mrb_malloc(mrb, capa + 1); + str_check_length(mrb, capa); + char *dst = (char*)mrb_malloc(mrb, capa + 1); if (p) memcpy(dst, p, len); dst[len] = '\0'; s->as.heap.ptr = dst; @@ -80,7 +80,7 @@ str_init_embed(struct RString *s, const char *p, mrb_int len) static struct RString* str_init_nofree(struct RString *s, const char *p, mrb_int len) { - s->as.heap.ptr = (char *)p; + s->as.heap.ptr = (char*)p; s->as.heap.len = len; s->as.heap.aux.capa = 0; /* nofree */ RSTR_SET_TYPE_FLAG(s, NOFREE); @@ -94,7 +94,7 @@ str_init_shared(mrb_state *mrb, const struct RString *orig, struct RString *s, m shared->refcnt++; } else { - shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string)); + shared = (mrb_shared_string*)mrb_malloc(mrb, sizeof(mrb_shared_string)); shared->refcnt = 1; shared->ptr = orig->as.heap.ptr; shared->capa = orig->as.heap.aux.capa; @@ -137,6 +137,7 @@ str_new_static(mrb_state *mrb, const char *p, mrb_int len) static struct RString* str_new(mrb_state *mrb, const char *p, mrb_int len) { + str_check_length(mrb, len); if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } @@ -169,7 +170,7 @@ resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity) } } else { - str_check_too_big(mrb, capacity); + str_check_length(mrb, capacity); s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); s->as.heap.aux.capa = (mrb_ssize)capacity; } @@ -466,11 +467,10 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr else { const unsigned char *x = xs, *xe = xs + m; const unsigned char *y = ys; - int i; ptrdiff_t qstable[256]; /* Preprocessing */ - for (i = 0; i < 256; i++) + for (int i = 0; i < 256; i++) qstable[i] = m + 1; for (; x < xe; x++) qstable[*x] = xe - x; @@ -486,7 +486,7 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr static mrb_int mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) { - const unsigned char *x = (const unsigned char *)x0, *y = (const unsigned char *)y0; + const unsigned char *x = (const unsigned char*)x0, *y = (const unsigned char*)y0; if (m > n) return -1; else if (m == n) { @@ -496,14 +496,14 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) return 0; } else if (m == 1) { - const unsigned char *ys = (const unsigned char *)memchr(y, *x, n); + const unsigned char *ys = (const unsigned char*)memchr(y, *x, n); if (ys) return (mrb_int)(ys - y); else return -1; } - return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n); + return mrb_memsearch_qs((const unsigned char*)x0, m, (const unsigned char*)y0, n); } static void @@ -523,7 +523,7 @@ str_share(mrb_state *mrb, struct RString *orig, struct RString *s) } else { if (orig->as.heap.aux.capa > orig->as.heap.len) { - orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); + orig->as.heap.ptr = (char*)mrb_realloc(mrb, orig->as.heap.ptr, len+1); orig->as.heap.aux.capa = (mrb_ssize)len; } str_init_shared(mrb, orig, s, NULL); @@ -769,9 +769,7 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len) mrb_int slen; struct RString *s = mrb_str_ptr(str); - if (len < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "negative (or overflowed) string size"); - } + str_check_length(mrb, len); mrb_str_modify(mrb, s); slen = RSTR_LEN(s); if (len != slen) { @@ -1249,19 +1247,16 @@ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) case 033: cc = 'e'; break; default: cc = 0; break; } + buf[0] = '\\'; if (cc) { - buf[0] = '\\'; buf[1] = (char)cc; mrb_str_cat(mrb, result, buf, 2); - continue; } else { - buf[0] = '\\'; buf[1] = 'x'; buf[3] = mrb_digitmap[c % 16]; c /= 16; buf[2] = mrb_digitmap[c % 16]; mrb_str_cat(mrb, result, buf, 4); - continue; } } mrb_str_cat_lit(mrb, result, "\""); @@ -2369,7 +2364,7 @@ mrb_str_len_to_integer(mrb_state *mrb, const char *str, size_t len, mrb_int base #ifdef MRB_USE_BIGINT p2 = p; #endif - for ( ;p= len2) { + memmove(RSTR_PTR(s)+idx1, RSTRING_PTR(replace)+idx2, len2); + if (len1 > len2) { + memmove(RSTR_PTR(s)+idx1+len2, RSTR_PTR(s)+idx1+len1, RSTR_LEN(s)-(idx1+len1)); + RSTR_SET_LEN(s, RSTR_LEN(s)-(len1-len2)); + } + } + else { /* len1 < len2 */ + mrb_int slen = RSTR_LEN(s); + mrb_str_resize(mrb, str, slen+len2-len1); + memmove(RSTR_PTR(s)+idx1+len2, RSTR_PTR(s)+idx1+len1, slen-(idx1+len1)); + memmove(RSTR_PTR(s)+idx1, RSTRING_PTR(replace)+idx2, len2); + } + return str; +} + +/* + * call-seq: + * bytesplice(index, length, str) -> string + * bytesplice(index, length, str, str_index, str_length) -> string + * bytesplice(range, str) -> string + * bytesplice(range, str, str_range) -> string + * + * Replaces some or all of the content of +self+ with +str+, and returns +self+. + * The portion of the string affected is determined using + * the same criteria as String#byteslice, except that +length+ cannot be omitted. + * If the replacement string is not the same length as the text it is replacing, + * the string will be adjusted accordingly. + * + * If +str_index+ and +str_length+, or +str_range+ are given, the content of +self+ is replaced by str.byteslice(str_index, str_length) or str.byteslice(str_range); however the substring of +str+ is not allocated as a new string. + * + * The form that take an Integer will raise an IndexError if the value is out + * of range; the Range form will raise a RangeError. + * If the beginning or ending offset does not land on character (codepoint) + * boundary, an IndexError will be raised. + */ +static mrb_value +mrb_str_bytesplice(mrb_state *mrb, mrb_value str) +{ + mrb_int idx1, len1, idx2, len2; + mrb_value range1, range2, replace; + switch (mrb_get_argc(mrb)) { + case 3: + mrb_get_args(mrb, "ooo", &range1, &replace, &range2); + if (mrb_integer_p(range1)) { + mrb_get_args(mrb, "iiS", &idx1, &len1, &replace); + return str_bytesplice(mrb, str, idx1, len1, replace, 0, RSTRING_LEN(replace)); + } + mrb_ensure_string_type(mrb, replace); + if (mrb_range_beg_len(mrb, range1, &idx1, &len1, RSTRING_LEN(str), FALSE) != MRB_RANGE_OK) break; + if (mrb_range_beg_len(mrb, range2, &idx2, &len2, RSTRING_LEN(replace), FALSE) != MRB_RANGE_OK) break; + return str_bytesplice(mrb, str, idx1, len1, replace, idx2, len2); + case 5: + mrb_get_args(mrb, "iiSii", &idx1, &len1, &replace, &idx2, &len2); + return str_bytesplice(mrb, str, idx1, len1, replace, idx2, len2); + case 2: + mrb_get_args(mrb, "oS", &range1, &replace); + if (mrb_range_beg_len(mrb, range1, &idx1, &len1, RSTRING_LEN(str), FALSE) == MRB_RANGE_OK) { + return str_bytesplice(mrb, str, idx1, len1, replace, 0, RSTRING_LEN(replace)); + } + default: + break; + } + mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arumgnts"); +} + /* ---------------------------*/ void mrb_init_string(mrb_state *mrb) @@ -3008,6 +3094,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "byteindex", mrb_str_byteindex_m, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, s, "byterindex", mrb_str_byterindex_m, MRB_ARGS_ARG(1,1)); mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1)); + mrb_define_method(mrb, s, "bytesplice", mrb_str_bytesplice, MRB_ARGS_ANY()); mrb_define_method(mrb, s, "__sub_replace", sub_replace, MRB_ARGS_REQ(3)); /* internal */ } diff --git a/mruby/src/symbol.c b/mruby/src/symbol.c index c707a9d9..ffac3437 100644 --- a/mruby/src/symbol.c +++ b/mruby/src/symbol.c @@ -82,12 +82,11 @@ sym_inline_pack(const char *name, size_t len) char c; const char *p; - size_t i; mrb_sym sym = 0; if (len > pack_length_max) return 0; /* too long */ if (len == 0) return 0; /* empty string */ - for (i=0; isymflags[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) @@ -208,15 +206,15 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) mrb->symcapa = symcapa; } sym_flags_clear(mrb, sym); - if ((lit || mrb_ro_data_p(name)) && strlen(name) == len) { + if ((lit || mrb_ro_data_p(name)) && name[len] == 0 && strlen(name) == len) { sym_lit_set(mrb, sym); mrb->symtbl[sym] = name; } else { uint32_t ulen = (uint32_t)len; size_t ilen = mrb_packed_int_len(ulen); - char *p = (char *)mrb_malloc(mrb, len+ilen+1); - mrb_packed_int_encode(ulen, (uint8_t*)p, (uint8_t*)p+ilen); + char *p = (char*)mrb_malloc(mrb, len+ilen+1); + mrb_packed_int_encode(ulen, (uint8_t*)p); memcpy(p+ilen, name, len); p[ilen+len] = 0; mrb->symtbl[sym] = p; @@ -353,7 +351,7 @@ mrb_free_symtbl(mrb_state *mrb) { mrb_sym i, lim; - for (i=1, lim=mrb->symidx+1; isymidx+1; isymtbl[i]); } diff --git a/mruby/src/variable.c b/mruby/src/variable.c index be27f0ed..4c51a8a6 100644 --- a/mruby/src/variable.c +++ b/mruby/src/variable.c @@ -47,7 +47,6 @@ iv_rehash(mrb_state *mrb, iv_tbl *t) mrb_value *old_ptr = t->ptr; khash_power2(new_alloc); - if (old_alloc == new_alloc) return; t->ptr = (mrb_value*)mrb_calloc(mrb, sizeof(mrb_value)+sizeof(mrb_sym), new_alloc); t->size = 0; @@ -70,7 +69,6 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) { int hash, pos, start, dpos = -1; - if (t == NULL) return; if (t->alloc == 0) { iv_rehash(mrb, t); } @@ -177,15 +175,13 @@ iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) static void iv_foreach(mrb_state *mrb, iv_tbl *t, mrb_iv_foreach_func *func, void *p) { - int i; - if (t == NULL) return; if (t->alloc == 0) return; if (t->size == 0) return; mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; mrb_value *vals = t->ptr; - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (IV_KEY_P(keys[i])) { if ((*func)(mrb, keys[i], vals[i], p) != 0) { return; @@ -209,7 +205,6 @@ static iv_tbl* iv_copy(mrb_state *mrb, iv_tbl *t) { iv_tbl *t2; - int i; if (t == NULL) return NULL; if (t->alloc == 0) return NULL; @@ -218,7 +213,7 @@ iv_copy(mrb_state *mrb, iv_tbl *t) mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc]; mrb_value *vals = t->ptr; t2 = iv_new(mrb); - for (i=0; ialloc; i++) { + for (int i=0; ialloc; i++) { if (IV_KEY_P(keys[i])) { iv_put(mrb, t2, keys[i], vals[i]); } @@ -327,34 +322,6 @@ mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym) return mrb_nil_value(); } -static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); - -void -mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) -{ - assign_class_name(mrb, obj, sym, v); - if (!obj->iv) { - obj->iv = iv_new(mrb); - } - iv_put(mrb, obj->iv, sym, v); - mrb_field_write_barrier_value(mrb, (struct RBasic*)obj, v); -} - -MRB_API void -mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) -{ - mrb_check_frozen(mrb, obj); - mrb_obj_iv_set_force(mrb, obj, sym, v); -} - -/* Iterates over the instance variable table. */ -MRB_API void -mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p) -{ - if (!obj_iv_p(obj)) return; - iv_foreach(mrb, mrb_obj_ptr(obj)->iv, func, p); -} - static inline mrb_bool namespace_p(enum mrb_vtype tt) { @@ -364,7 +331,7 @@ namespace_p(enum mrb_vtype tt) static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) { - if (namespace_p(obj->tt) && namespace_p(mrb_type(v))) { + if (namespace_p(mrb_type(v))) { struct RObject *c = mrb_obj_ptr(v); if (obj != c && ISUPPER(mrb_sym_name_len(mrb, sym, NULL)[0])) { mrb_sym id_classname = MRB_SYM(__classname__); @@ -375,7 +342,7 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) o = mrb_obj_iv_get(mrb, c, id_outer); if (mrb_nil_p(o)) { - if ((struct RClass *)obj == mrb->object_class) { + if ((struct RClass*)obj == mrb->object_class) { mrb_obj_iv_set_force(mrb, c, id_classname, mrb_symbol_value(sym)); } else { @@ -387,6 +354,34 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) } } +void +mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) +{ + if (namespace_p(obj->tt)) { + assign_class_name(mrb, obj, sym, v); + } + if (!obj->iv) { + obj->iv = iv_new(mrb); + } + iv_put(mrb, obj->iv, sym, v); + mrb_field_write_barrier_value(mrb, (struct RBasic*)obj, v); +} + +MRB_API void +mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) +{ + mrb_check_frozen(mrb, obj); + mrb_obj_iv_set_force(mrb, obj, sym, v); +} + +/* Iterates over the instance variable table. */ +MRB_API void +mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p) +{ + if (!obj_iv_p(obj)) return; + iv_foreach(mrb, mrb_obj_ptr(obj)->iv, func, p); +} + MRB_API void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) { @@ -472,12 +467,7 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) s = mrb_sym_name_len(mrb, sym, &len); mrb_str_cat(mrb, str, s, len); mrb_str_cat_lit(mrb, str, "="); - if (mrb_object_p(v)) { - ins = mrb_any_to_s(mrb, v); - } - else { - ins = mrb_inspect(mrb, v); - } + ins = mrb_inspect(mrb, v); mrb_str_cat_str(mrb, str, ins); return 0; } @@ -497,6 +487,10 @@ mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) mrb_str_cat_lit(mrb, str, ":"); mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, obj)); + if (mrb_inspect_recursive_p(mrb, mrb_obj_value(obj))) { + mrb_str_cat_lit(mrb, str, " ...>"); + return str; + } iv_foreach(mrb, t, inspect_i, &str); mrb_str_cat_lit(mrb, str, ">"); return str; @@ -508,10 +502,11 @@ MRB_API mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym) { if (obj_iv_p(obj)) { - iv_tbl *t = mrb_obj_ptr(obj)->iv; + struct RObject *o = mrb_obj_ptr(obj); + iv_tbl *t = o->iv; mrb_value val; - mrb_check_frozen(mrb, mrb_obj_ptr(obj)); + mrb_check_frozen(mrb, o); if (iv_del(mrb, t, sym, &val)) { return val; } @@ -629,7 +624,7 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym) if (cls && cls->tt == MRB_TT_SCLASS) { mrb_value klass; - klass = mrb_obj_iv_get(mrb, (struct RObject *)cls, MRB_SYM(__attached__)); + klass = mrb_obj_iv_get(mrb, (struct RObject*)cls, MRB_SYM(__attached__)); c = mrb_class_ptr(klass); if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) { given = FALSE; @@ -772,26 +767,28 @@ 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 then skip the current class (already searched) */ if (skip) c = c->super; L_RETRY: while (c) { - if (!MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_PREPENDED) && c->iv) { - if (iv_get(mrb, c->iv, sym, &v)) - return v; + if (!MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_PREPENDED) && c->iv && iv_get(mrb, c->iv, sym, &v)) { + return v; } c = c->super; if (!skip && c == mrb->object_class) break; } - if (!retry && base->tt == MRB_TT_MODULE) { + if (!retry && base->tt == MRB_TT_MODULE && skip) { c = mrb->object_class; retry = TRUE; goto L_RETRY; } - name = mrb_symbol_value(sym); - return mrb_funcall_argv(mrb, mrb_obj_value(base), MRB_SYM(const_missing), 1, &name); + mrb_value mod = mrb_obj_value(base); + if (mrb_func_basic_p(mrb, mod, MRB_SYM(const_missing), mrb_mod_const_missing)) { + return mrb_const_missing(mrb, mod, sym); + } + mrb_value name = mrb_symbol_value(sym); + return mrb_funcall_argv(mrb, mod, MRB_SYM(const_missing), 1, &name); } MRB_API mrb_value @@ -1137,9 +1134,7 @@ mrb_obj_iv_tbl_memsize(mrb_value obj) mrb_bool mrb_ident_p(const char *s, mrb_int len) { - mrb_int i; - - for (i = 0; i < len; i++) { + for (mrb_int i = 0; i < len; i++) { if (!identchar(s[i])) return FALSE; } return TRUE; diff --git a/mruby/src/vm.c b/mruby/src/vm.c index 475f02ab..47457b12 100644 --- a/mruby/src/vm.c +++ b/mruby/src/vm.c @@ -65,7 +65,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; + gc->arena_idx = idx; if (idx < capa / 4) { capa >>= 2; if (capa < MRB_GC_ARENA_SIZE) { @@ -106,11 +106,11 @@ stack_init(mrb_state *mrb) struct mrb_context *c = mrb->c; /* mrb_assert(mrb->stack == NULL); */ - c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); + c->stbase = (mrb_value*)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); c->stend = c->stbase + STACK_INIT_SIZE; /* mrb_assert(ci == NULL); */ - c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); + c->cibase = (mrb_callinfo*)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + CALLINFO_INIT_SIZE; c->ci = c->cibase; c->ci->u.target_class = mrb->object_class; @@ -121,36 +121,33 @@ static inline void envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize) { mrb_callinfo *ci = mrb->c->cibase; + ptrdiff_t delta = newbase - oldbase; - if (newbase == oldbase) return; + if (delta == 0) return; while (ci <= mrb->c->ci) { struct REnv *e = mrb_vm_ci_env(ci); mrb_value *st; if (e && MRB_ENV_ONSTACK_P(e) && - (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { - ptrdiff_t off = e->stack - oldbase; - - e->stack = newbase + off; + (st = e->stack) && (size_t)(st - oldbase) < oldsize) { + e->stack += delta; } if (ci->proc && MRB_PROC_ENV_P(ci->proc) && e != MRB_PROC_ENV(ci->proc)) { e = MRB_PROC_ENV(ci->proc); if (e && MRB_ENV_ONSTACK_P(e) && - (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { - ptrdiff_t off = e->stack - oldbase; - - e->stack = newbase + off; + (st = e->stack) && (size_t)(st - oldbase) < oldsize) { + e->stack += delta; } } - ci->stack = newbase + (ci->stack - oldbase); + ci->stack += delta; ci++; } } -/** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end */ +/** def rec; $deep =+ 1; if $deep > 1000; return 0; end; rec; end **/ static void stack_extend_alloc(mrb_state *mrb, mrb_int room) @@ -177,7 +174,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) size += room; #endif - newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); + newstack = (mrb_value*)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); stack_clear(&(newstack[oldsize]), size - oldsize); envadjust(mrb, oldbase, newstack, oldsize); mrb->c->stbase = newstack; @@ -190,14 +187,20 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) } } -MRB_API void -mrb_stack_extend(mrb_state *mrb, mrb_int room) +static inline void +stack_extend(mrb_state *mrb, mrb_int room) { if (!mrb->c->ci->stack || mrb->c->ci->stack + room >= mrb->c->stend) { stack_extend_alloc(mrb, room); } } +MRB_API void +mrb_stack_extend(mrb_state *mrb, mrb_int room) +{ + stack_extend(mrb, room); +} + static void stack_extend_adjust(mrb_state *mrb, mrb_int room, const mrb_value **argp) { @@ -205,10 +208,10 @@ stack_extend_adjust(mrb_state *mrb, mrb_int room, const mrb_value **argp) ptrdiff_t voff = *argp - c->stbase; if (voff < 0 || voff >= c->stend - c->stbase) { - mrb_stack_extend(mrb, room); + stack_extend(mrb, room); } else { - mrb_stack_extend(mrb, room); + stack_extend(mrb, room); *argp = c->stbase + voff; } } @@ -252,7 +255,7 @@ top_proc(mrb_state *mrb, const struct RProc *proc) #define CI_PROC_SET(ci, p) do {\ ci->proc = p;\ - ci->pc = (p && !MRB_PROC_CFUNC_P(p)) ? p->body.irep->iseq : NULL;\ + ci->pc = (p && !MRB_PROC_CFUNC_P(p) && p->body.irep) ? p->body.irep->iseq : NULL;\ } while (0) void @@ -289,8 +292,8 @@ mrb_vm_ci_env(const mrb_callinfo *ci) return CI_ENV(ci); } -void -mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +static inline void +ci_env_set(mrb_callinfo *ci, struct REnv *e) { if (ci->u.env) { if (ci->u.env->tt == MRB_TT_ENV) { @@ -302,11 +305,9 @@ mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) ci->u.target_class = ci->u.env->c; } } - else { - if (e) { - e->c = ci->u.target_class; - ci->u.env = e; - } + else if (e) { + e->c = ci->u.target_class; + ci->u.env = e; } } else { @@ -314,10 +315,26 @@ mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) } } -#define CINFO_NONE 0 -#define CINFO_SKIP 1 -#define CINFO_DIRECT 2 -#define CINFO_RESUMED 3 +void +mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +{ + ci_env_set(ci, e); +} + +MRB_API void +mrb_vm_ci_env_clear(mrb_state *mrb, mrb_callinfo *ci) +{ + struct REnv *e = ci->u.env; + if (e && e->tt == MRB_TT_ENV) { + ci->u.target_class = e->c; + mrb_env_unshare(mrb, e, FALSE); + } +} + +#define CINFO_NONE 0 // called method from mruby VM (without C functions) +#define CINFO_SKIP 1 // ignited mruby VM from C +#define CINFO_DIRECT 2 // called method from C +#define CINFO_RESUMED 3 // resumed by `Fiber.yield` (probably the main call is `mrb_fiber_resume()`) #define BLK_PTR(b) ((mrb_proc_p(b)) ? mrb_proc_ptr(b) : NULL) @@ -334,7 +351,7 @@ cipush(mrb_state *mrb, mrb_int push_stacks, uint8_t cci, struct RClass *target_c 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->cibase = (mrb_callinfo*)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2); c->ci = c->cibase + size; c->ciend = c->cibase + size * 2; } @@ -367,8 +384,8 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e, mrb_bool noraise) } size_t live = mrb->gc.live; - mrb_value *p = (mrb_value *)mrb_malloc_simple(mrb, sizeof(mrb_value)*len); - if (live != mrb->gc.live && mrb_object_dead_p(mrb, (struct RBasic *)e)) { + mrb_value *p = (mrb_value*)mrb_malloc_simple(mrb, sizeof(mrb_value)*len); + if (live != mrb->gc.live && mrb_object_dead_p(mrb, (struct RBasic*)e)) { // The e object is now subject to GC inside mrb_malloc_simple(). // Moreover, if NULL is returned due to mrb_malloc_simple() failure, simply ignore it. mrb_free(mrb, p); @@ -378,7 +395,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e, mrb_bool noraise) stack_copy(p, e->stack, len); e->stack = p; MRB_ENV_CLOSE(e); - mrb_write_barrier(mrb, (struct RBasic *)e); + mrb_write_barrier(mrb, (struct RBasic*)e); return TRUE; } else { @@ -400,7 +417,7 @@ cipop(mrb_state *mrb) mrb_callinfo *ci = c->ci; struct REnv *env = CI_ENV(ci); - mrb_vm_ci_env_set(ci, NULL); // make possible to free by GC if env is not needed + ci_env_set(ci, NULL); // make possible to free env by GC if not needed struct RProc *b = ci->blk; if (b && !mrb_object_dead_p(mrb, (struct RBasic*)b) && b->tt == MRB_TT_PROC && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&ci[-1])) { @@ -469,7 +486,6 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) { mrb_value argv[MRB_FUNCALL_ARGC_MAX]; va_list ap; - mrb_int i; mrb_sym mid = mrb_intern_cstr(mrb, name); if (argc > MRB_FUNCALL_ARGC_MAX) { @@ -477,7 +493,7 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) } va_start(ap, argc); - for (i = 0; i < argc; i++) { + for (mrb_int i = 0; i < argc; i++) { argv[i] = va_arg(ap, mrb_value); } va_end(ap); @@ -489,14 +505,13 @@ mrb_funcall_id(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, ...) { mrb_value argv[MRB_FUNCALL_ARGC_MAX]; va_list ap; - mrb_int i; if (argc > MRB_FUNCALL_ARGC_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" MRB_STRINGIZE(MRB_FUNCALL_ARGC_MAX) ")"); } va_start(ap, argc); - for (i = 0; i < argc; i++) { + for (mrb_int i = 0; i < argc; i++) { argv[i] = va_arg(ap, mrb_value); } va_end(ap); @@ -519,10 +534,16 @@ mrb_bidx(uint8_t n, uint8_t k) return n + 1; /* self + args + kargs */ } +static inline mrb_int +ci_bidx(mrb_callinfo *ci) +{ + return mrb_bidx(ci->n, ci->nk); +} + mrb_int mrb_ci_bidx(mrb_callinfo *ci) { - return mrb_bidx(ci->n, ci->nk); + return ci_bidx(ci); } mrb_int @@ -531,7 +552,7 @@ mrb_ci_nregs(mrb_callinfo *ci) const struct RProc *p; if (!ci) return 4; - mrb_int nregs = mrb_ci_bidx(ci) + 1; /* self + args + kargs + blk */ + mrb_int nregs = ci_bidx(ci) + 1; /* self + args + kargs + blk */ p = ci->proc; if (p && !MRB_PROC_CFUNC_P(p) && p->body.irep && p->body.irep->nregs > nregs) { return p->body.irep->nregs; @@ -564,7 +585,7 @@ prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, m } m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, missing); if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */ - mrb_stack_extend(mrb, 4); + stack_extend(mrb, 4); argv = &ci->stack[1]; /* maybe reallocated */ argv[0] = args; @@ -611,7 +632,7 @@ funcall_args_capture(mrb_state *mrb, int stoff, mrb_int argc, const mrb_value *a } } -static mrb_value +static inline mrb_value ensure_block(mrb_state *mrb, mrb_value blk) { if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { @@ -635,7 +656,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb->jmp = &c_jmp; /* recursive call */ val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk); - mrb->jmp = 0; + mrb->jmp = NULL; } MRB_CATCH(&c_jmp) { /* error */ while (nth_ci < (mrb->c->ci - mrb->c->cibase)) { @@ -645,7 +666,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc val = mrb_obj_value(mrb->exc); } MRB_END_EXC(&c_jmp); - mrb->jmp = 0; + mrb->jmp = NULL; } else { mrb_method_t m; @@ -722,12 +743,12 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) return MRB_PROC_CFUNC(p)(mrb, self); } nregs = p->body.irep->nregs; - keep = mrb_ci_bidx(ci)+1; + keep = ci_bidx(ci)+1; if (nregs < keep) { - mrb_stack_extend(mrb, keep); + stack_extend(mrb, keep); } else { - mrb_stack_extend(mrb, nregs); + stack_extend(mrb, nregs); stack_clear(ci->stack+keep, nregs-keep); } @@ -754,7 +775,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) cipop(mrb); } else { - mrb_int keep = mrb_ci_bidx(ci) + 1; /* receiver + block */ + mrb_int keep = ci_bidx(ci) + 1; /* receiver + block */ ret = mrb_top_run(mrb, p, self, keep); } if (mrb->exc && mrb->jmp) { @@ -882,7 +903,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) ci->nk = 0; ci->mid = ci[-1].mid; if (MRB_PROC_CFUNC_P(p)) { - mrb_stack_extend(mrb, 4); + stack_extend(mrb, 4); mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; mrb->c->ci->stack[2] = mrb_nil_value(); @@ -890,7 +911,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) } nregs = p->body.irep->nregs; if (nregs < 4) nregs = 4; - mrb_stack_extend(mrb, nregs); + stack_extend(mrb, nregs); mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; stack_clear(mrb->c->ci->stack+2, nregs-2); @@ -956,7 +977,7 @@ MRB_API mrb_value mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c) { struct RProc *p; - mrb_sym mid = mrb->c->ci->mid; + mrb_sym mid; mrb_callinfo *ci; mrb_value val; mrb_int n; @@ -965,10 +986,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ci = mrb->c->ci; n = mrb_ci_nregs(ci); p = mrb_proc_ptr(b); - ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, NULL, 0, 0); + if (MRB_PROC_ENV_P(p)) { + mid = p->e.env->mid; + } + else { + mid = ci->mid; + } + ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, NULL, mid, 0); funcall_args_capture(mrb, 0, argc, argv, mrb_nil_value(), ci); ci->u.target_class = c; - ci->mid = mid; ci->proc = p; if (MRB_PROC_CFUNC_P(p)) { @@ -987,16 +1013,20 @@ MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv) { struct RProc *p = mrb_proc_ptr(b); + struct RClass *tc; + mrb_value self = mrb_proc_get_self(mrb, p, &tc); - return mrb_yield_with_class(mrb, b, argc, argv, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); + return mrb_yield_with_class(mrb, b, argc, argv, self, tc); } MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg) { struct RProc *p = mrb_proc_ptr(b); + struct RClass *tc; + mrb_value self = mrb_proc_get_self(mrb, p, &tc); - return mrb_yield_with_class(mrb, b, 1, &arg, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); + return mrb_yield_with_class(mrb, b, 1, &arg, self, tc); } mrb_value @@ -1081,7 +1111,7 @@ catch_handler_find(mrb_state *mrb, mrb_callinfo *ci, const mrb_code *pc, uint32_ if (ci->proc == NULL || MRB_PROC_CFUNC_P(ci->proc)) return NULL; irep = ci->proc->body.irep; - if (irep->clen < 1) return NULL; + if (irep == NULL || irep->clen < 1) return NULL; xpc = pc - irep->iseq; /* If it retry at the top level, pc will be 0, so check with -1 as the start position */ mrb_assert(catch_cover_p(xpc, -1, irep->ilen)); @@ -1230,13 +1260,13 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #define BYTECODE_DECODER(x) (x) #endif -#ifndef MRB_NO_DIRECT_THREADING -#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER -#define DIRECT_THREADED +#ifndef MRB_USE_VM_SWITCH_DISPATCH +#if !defined __GNUC__ && !defined __clang__ && !defined __INTEL_COMPILER +#define MRB_USE_VM_SWITCH_DISPATCH #endif -#endif /* ifndef MRB_NO_DIRECT_THREADING */ +#endif /* ifndef MRB_USE_VM_SWITCH_DISPATCH */ -#ifndef DIRECT_THREADED +#ifdef MRB_USE_VM_SWITCH_DISPATCH #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; L_ ## insn ## _BODY: @@ -1272,11 +1302,11 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta else { struct REnv *e = CI_ENV(mrb->c->ci); if (stack_keep == 0 || (e && irep->nlocals < MRB_ENV_LEN(e))) { - mrb_vm_ci_env_set(mrb->c->ci, NULL); + ci_env_set(mrb->c->ci, NULL); mrb_env_unshare(mrb, e, FALSE); } } - mrb_stack_extend(mrb, nregs); + stack_extend(mrb, nregs); stack_clear(c->ci->stack + stack_keep, nregs - stack_keep); c->ci->stack[0] = self; result = mrb_vm_exec(mrb, proc, irep->iseq); @@ -1315,16 +1345,7 @@ hash_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) return hash; } -static mrb_value -ary_new_from_regs(mrb_state *mrb, mrb_int argc, mrb_int idx) -{ - mrb_value ary = mrb_ary_new_capa(mrb, argc); - while (argc--) { - mrb_ary_push(mrb, ary, regs[idx]); - idx++; - } - return ary; -} +#define ary_new_from_regs(mrb, argc, idx) mrb_ary_new_from_values(mrb, (argc), ®s[idx]); MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) @@ -1343,7 +1364,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_sym mid; const struct mrb_irep_catch_handler *ch; -#ifdef DIRECT_THREADED +#ifndef MRB_USE_VM_SWITCH_DISPATCH static const void * const optable[] = { #define OPCODE(x,_) &&L_OP_ ## x, #include "mruby/ops.h" @@ -1526,7 +1547,15 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) 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)); + else { + mrb_int idx = mrb_integer(vb); + if (0 <= idx && idx < RARRAY_LEN(va)) { + regs[a] = RARRAY_PTR(va)[idx]; + } + else { + regs[a] = mrb_ary_entry(va, idx); + } + } break; case MRB_TT_HASH: va = mrb_hash_get(mrb, va, vb); @@ -1582,14 +1611,13 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_GETUPVAR, BBB) { - mrb_value *regs_a = regs + a; struct REnv *e = uvenv(mrb, c); if (e && b < MRB_ENV_LEN(e)) { - *regs_a = e->stack[b]; + regs[a] = e->stack[b]; } else { - *regs_a = mrb_nil_value(); + regs[a] = mrb_nil_value(); } NEXT; } @@ -1598,10 +1626,8 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) struct REnv *e = uvenv(mrb, c); if (e) { - mrb_value *regs_a = regs + a; - if (b < MRB_ENV_LEN(e)) { - e->stack[b] = *regs_a; + e->stack[b] = regs[a]; mrb_write_barrier(mrb, (struct RBasic*)e); } } @@ -1742,6 +1768,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) int n = c&0xf; int nk = (c>>4)&0xf; mrb_int bidx = a + mrb_bidx(n,nk); + mrb_int new_bidx = bidx; if (nk == CALL_MAXARGS) { mrb_ensure_hash_type(mrb, regs[a+(n==CALL_MAXARGS?1:n)+1]); @@ -1752,10 +1779,10 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) regs[kidx] = kdict; nk = CALL_MAXARGS; c = n | (nk<<4); + new_bidx = a+mrb_bidx(n, nk); } mrb_assert(bidx < irep->nregs); - mrb_int new_bidx = a+mrb_bidx(n, nk); if (insn == OP_SEND) { /* clear block argument */ SET_NIL_VALUE(regs[new_bidx]); @@ -1777,7 +1804,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) ci->mid = mid; } ci->cci = CINFO_NONE; - if (!mrb_nil_p(blk)) ci->blk = mrb_proc_ptr(blk); if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { @@ -1819,7 +1845,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, (irep->nregs < 4) ? 4 : irep->nregs); + stack_extend(mrb, (irep->nregs < 4) ? 4 : irep->nregs); pc = irep->iseq; } } @@ -1858,9 +1884,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) c = OP_R_NORMAL; goto L_OP_RETURN_BODY; } - mrb_int nargs = mrb_ci_bidx(ci)+1; + mrb_int nargs = ci_bidx(ci)+1; if (nargs < irep->nregs) { - mrb_stack_extend(mrb, irep->nregs); + stack_extend(mrb, irep->nregs); stack_clear(regs+nargs, irep->nregs-nargs); } if (MRB_PROC_ENV_P(m)) { @@ -1968,7 +1994,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) /* no other args */ if ((a & ~0x7c0001) == 0 && argc < 15 && MRB_PROC_STRICT_P(proc)) { - if (argc != m1) { + if (argc+(ci->nk==15) != m1) { /* count kdict too */ argnum_error(mrb, m1); goto L_RAISE; } @@ -1990,7 +2016,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) mrb_int const len = m1 + o + r + m2; mrb_value * const argv0 = argv; - mrb_value blk = regs[mrb_ci_bidx(ci)]; + mrb_value blk = regs[ci_bidx(ci)]; mrb_value kdict = mrb_nil_value(); /* keyword arguments */ @@ -2019,6 +2045,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) else if (MRB_ASPEC_KEY(a) > 0 && !mrb_nil_p(kdict)) { kdict = mrb_hash_dup(mrb, kdict); } + else if (!mrb_nil_p(kdict)) { + mrb_gc_protect(mrb, kdict); + } /* arguments is passed with Array */ if (argc == 15) { @@ -2026,7 +2055,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) argv = ARY_PTR(ary); argc = (int)ARY_LEN(ary); mrb_gc_protect(mrb, regs[1]); - if (kd && !mrb_nil_p(kdict)) mrb_gc_protect(mrb, kdict); } /* strict argument check */ @@ -2077,6 +2105,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) else { mrb_int rnum = 0; if (argv0 != argv) { + mrb_gc_protect(mrb, blk); value_move(®s[1], argv, m1+o); } if (r) { @@ -2093,11 +2122,12 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) /* need to be update blk first to protect blk from GC */ mrb_int const kw_pos = len + kd; /* where kwhash should be */ mrb_int const blk_pos = kw_pos + 1; /* where block should be */ - regs[blk_pos] = blk; /* move block */ + regs[blk_pos] = blk; /* move block */ if (kd) { - if (mrb_nil_p(kdict)) + if (mrb_nil_p(kdict)) { kdict = mrb_hash_new_capa(mrb, 0); - regs[kw_pos] = kdict; /* set kwhash */ + } + regs[kw_pos] = kdict; /* set kwhash */ ci->nk = 15; } @@ -2192,7 +2222,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } } - if (ch == NULL) goto L_STOP; if (FALSE) { L_CATCH_TAGGED_BREAK: /* from THROW_TAGGED_BREAK() or UNWIND_ENSURE() */ ci = mrb->c->ci; @@ -2201,7 +2230,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, irep->nregs); + stack_extend(mrb, irep->nregs); pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target); } else { @@ -2308,13 +2337,10 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) break; case OP_R_BREAK: if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; - if (MRB_PROC_ORPHAN_P(proc)) { + if (MRB_PROC_ORPHAN_P(proc) || !MRB_PROC_ENV_P(proc) || !MRB_ENV_ONSTACK_P(MRB_PROC_ENV(proc))) { L_BREAK_ERROR: RAISE_LIT(mrb, E_LOCALJUMP_ERROR, "break from proc-closure"); } - if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_ONSTACK_P(MRB_PROC_ENV(proc))) { - goto L_BREAK_ERROR; - } else { struct REnv *e = MRB_PROC_ENV(proc); @@ -2627,13 +2653,13 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) /* need to check if - is overridden */\ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ case TYPES2(MRB_TT_INTEGER,MRB_TT_INTEGER):\ - result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\ + result = OP_CMP_BODY(op,mrb_integer,mrb_integer);\ break;\ case TYPES2(MRB_TT_INTEGER,MRB_TT_FLOAT):\ - result = OP_CMP_BODY(op,mrb_fixnum,mrb_float);\ + result = OP_CMP_BODY(op,mrb_integer,mrb_float);\ break;\ case TYPES2(MRB_TT_FLOAT,MRB_TT_INTEGER):\ - result = OP_CMP_BODY(op,mrb_float,mrb_fixnum);\ + result = OP_CMP_BODY(op,mrb_float,mrb_integer);\ break;\ case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\ result = OP_CMP_BODY(op,mrb_float,mrb_float);\ @@ -2824,10 +2850,9 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) CASE(OP_HASH, BB) { mrb_value hash = mrb_hash_new_capa(mrb, b); - int i; int lim = a+b*2; - for (i=a; ibody.irep; pool = irep->pool; syms = irep->syms; - mrb_stack_extend(mrb, irep->nregs); + stack_extend(mrb, irep->nregs); stack_clear(regs+1, irep->nregs-1); pc = irep->iseq; JUMP; @@ -3097,24 +3121,16 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) static mrb_value mrb_run(mrb_state *mrb, const struct RProc *proc, mrb_value self) { - return mrb_vm_run(mrb, proc, self, mrb_ci_bidx(mrb->c->ci) + 1); + return mrb_vm_run(mrb, proc, self, ci_bidx(mrb->c->ci) + 1); } MRB_API mrb_value mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int stack_keep) { - mrb_value v; - - if (!mrb->c->cibase) { - return mrb_vm_run(mrb, proc, self, stack_keep); - } - if (mrb->c->ci == mrb->c->cibase) { - return mrb_vm_run(mrb, proc, self, stack_keep); + if (mrb->c->cibase && mrb->c->ci > mrb->c->cibase) { + cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, NULL, 0, 0); } - cipush(mrb, 0, CINFO_SKIP, mrb->object_class, NULL, NULL, 0, 0); - v = mrb_vm_run(mrb, proc, self, stack_keep); - - return v; + return mrb_vm_run(mrb, proc, self, stack_keep); } #if defined(MRB_USE_CXX_EXCEPTION) && defined(__cplusplus) diff --git a/mruby/super-linter.report/.keep b/mruby/super-linter.report/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/mruby/tasks/doc.rake b/mruby/tasks/doc.rake index 50dc3618..11c0bd25 100644 --- a/mruby/tasks/doc.rake +++ b/mruby/tasks/doc.rake @@ -9,7 +9,7 @@ namespace :doc do begin sh "mrbdoc" rescue - puts "ERROR: To generate yard documentation, you should install yard-mruby gem." + puts "ERROR: To generate YARD documentation, you should install yard-mruby gem." puts " $ gem install yard-mruby yard-coderay" puts "https://yardoc.org/" puts "https://rubygems.org/gems/yard-mruby" diff --git a/mruby/tasks/install.rake b/mruby/tasks/install.rake new file mode 100644 index 00000000..234bec8d --- /dev/null +++ b/mruby/tasks/install.rake @@ -0,0 +1,33 @@ +desc "install compiled products (on host)" +task :install => "install:full:host" + +desc "install compiled executable (on host)" +task :install_bin => "install:bin:host" + +desc "install compiled products (all build targets)" +task "install:full" + +desc "install compiled executable (all build targets)" +task "install:bin" + +MRuby.each_target do |build| + next if build.internal? + + prefix = File.join(MRuby::INSTALL_DESTDIR, build.install_prefix) + + task "install:full" => "install:full:#{build.name}" + + task "install:full:#{build.name}" => "install:bin:#{build.name}" do + Dir.glob(File.join(build.build_dir.gsub(/[\[\{\*\?]/, "\\\0"), "{include,lib}/**/*")) do |path| + install_D path, File.join(prefix, path.relative_path_from(build.build_dir)) if File.file? path + end + end + + task "install:bin" => "install:bin:#{build.name}" + + task "install:bin:#{build.name}" => "all" do + Dir.glob(File.join(build.build_dir.gsub(/[\[\{\*\?]/, "\\\0"), "{bin,host-bin}/**/*")) do |path| + install_D path, File.join(prefix, path.relative_path_from(build.build_dir)) if File.file? path + end + end +end diff --git a/mruby/tasks/libmruby.rake b/mruby/tasks/libmruby.rake index 1fb3cbc3..38878b1e 100644 --- a/mruby/tasks/libmruby.rake +++ b/mruby/tasks/libmruby.rake @@ -7,31 +7,86 @@ MRuby.each_target do next unless libmruby_enabled? + copy_headers_task = "expose_header_files:#{name}" file libmruby_static => libmruby_objs.flatten do |t| + Rake::Task[copy_headers_task].invoke archiver.run t.name, t.prerequisites end + task copy_headers_task do |_t| + # Since header files may be generated dynamically and it is hard to know all of them, + # the task is executed depending on when libmruby.a is generated. + + gemsbasedir = File.join(build_dir, 'include/mruby/gems') + dirmap = { + MRUBY_ROOT => build_dir + } + gems.each do |g| + dirmap[g.dir] = File.join(gemsbasedir, g.name) + dirmap[g.build_dir] = File.join(gemsbasedir, g.name) + end + + dirs = each_header_files.to_a + dirs.uniq! + dirs.replace_prefix_by(dirmap).zip(dirs).each do |dest, src| + next unless File.mtime(src).to_i > begin + File.mtime(dest).to_i + rescue StandardError + 0 + end + + mkpath File.dirname(dest) + cp src, dest + end + end + file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libmruby_static] do |t| mkdir_p File.dirname t.name open(t.name, 'w') do |f| - 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 <<~FLAGS_MAKE + # GNU make is required to use this file. + MRUBY_PACKAGE_DIR_GNU := $(shell dirname "$(lastword $(MAKEFILE_LIST))") + MRUBY_PACKAGE_DIR != dirname "$(MRUBY_PACKAGE_DIR_GNU)" + FLAGS_MAKE + + [ + [cc, 'MRUBY_CC', 'MRUBY_CFLAGS'], + [cxx, 'MRUBY_CXX', 'MRUBY_CXXFLAGS'], + [asm, 'MRUBY_AS', 'MRUBY_ASFLAGS'], + [objc, 'MRUBY_OBJC', 'MRUBY_OBJCFLAGS'] + ].each do |cc, cmd, flags| + incpaths = cc.include_paths.dup + dirmaps = { + MRUBY_ROOT => '$(MRUBY_PACKAGE_DIR)', + build_dir => '$(MRUBY_PACKAGE_DIR)' + } + gems.each do |g| + incpaths.concat g.export_include_paths + dirmaps[g.dir] = "$(MRUBY_PACKAGE_DIR)/include/mruby/gems/#{g.name}" + dirmaps[g.build_dir] = "$(MRUBY_PACKAGE_DIR)/include/mruby/gems/#{g.name}" + end + modcc = cc.clone + modcc.include_paths = incpaths.replace_prefix_by(dirmaps).uniq + + f.puts "#{cmd} = #{cc.command}" + f.puts "#{flags} = #{modcc.all_flags}" + end - f.puts "MRUBY_CC = #{cc.command}" f.puts "MRUBY_LD = #{linker.command}" - libgems = gems.reject{|g| g.bin?} - gem_flags = libgems.map {|g| g.linker.flags } - gem_library_paths = libgems.map {|g| g.linker.library_paths } - f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags)} #{linker.option_library_path % "#{build_dir}/lib"}" + libgems = gems.reject { |g| g.bin? } + gem_flags = libgems.map { |g| g.linker.flags } + gem_library_paths = libgems.map { |g| g.linker.library_paths } + f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags)} #{linker.option_library_path % '$(MRUBY_PACKAGE_DIR)/lib'}" - gem_flags_before_libraries = libgems.map {|g| g.linker.flags_before_libraries } + gem_flags_before_libraries = libgems.map { |g| g.linker.flags_before_libraries } f.puts "MRUBY_LDFLAGS_BEFORE_LIBS = #{[linker.flags_before_libraries, gem_flags_before_libraries].flatten.join(' ')}" - gem_libraries = libgems.map {|g| g.linker.libraries } - f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries)}" + gem_libraries = libgems.map { |g| g.linker.libraries } + libmruby = toolchains.find { |e| e == 'visualcpp' } ? 'libmruby' : 'mruby' + f.puts "MRUBY_LIBS = #{linker.option_library % libmruby} #{linker.library_flags(gem_libraries)}" - f.puts "MRUBY_LIBMRUBY_PATH = #{libmruby_static}" + f.puts "MRUBY_LIBMRUBY_PATH = #{libmruby_static.replace_prefix_by(build_dir => '$(MRUBY_PACKAGE_DIR)')}" end end diff --git a/mruby/tasks/mrbgems.rake b/mruby/tasks/mrbgems.rake index 1e6b0319..686facb2 100644 --- a/mruby/tasks/mrbgems.rake +++ b/mruby/tasks/mrbgems.rake @@ -13,41 +13,82 @@ MRuby.each_target do mkdir_p "#{build_dir}/mrbgems" open(t.name, 'w') do |f| gem_func_gems = gems.select { |g| g.generate_functions } - gem_func_decls = gem_func_gems.each_with_object('') do |g, s| - s << "void GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb_state*);\n" \ - "void GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb_state*);\n" - end - gem_init_calls = gem_func_gems.each_with_object('') do |g, s| - s << " GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb);\n" - end - gem_final_calls = gem_func_gems.reverse_each.with_object('') do |g, s| - s << " GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb);\n" + gem_func_decls = '' + gem_funcs = '' + gem_func_gems.each do |g| + init = "GENERATED_TMP_mrb_#{g.funcname}_gem_init" + final = "GENERATED_TMP_mrb_#{g.funcname}_gem_final" + gem_func_decls << "void #{init}(mrb_state*);\n" \ + "void #{final}(mrb_state*);\n" + gem_funcs << " { #{init}, #{final} },\n" end f.puts %Q[/*] f.puts %Q[ * This file contains a list of all] f.puts %Q[ * initializing methods which are] f.puts %Q[ * necessary to bootstrap all gems.] f.puts %Q[ *] + f.puts %Q[ * This file was generated by mruby/#{__FILE__.relative_path_from(MRUBY_ROOT)}.] + f.puts %Q[ *] f.puts %Q[ * IMPORTANT:] f.puts %Q[ * This file was generated!] f.puts %Q[ * All manual changes will get lost.] f.puts %Q[ */] f.puts %Q[] f.puts %Q[#include ] + f.puts %Q[#include ] + f.puts %Q[#include ] f.puts %Q[] - f.write gem_func_decls - unless gem_final_calls.empty? + unless gem_funcs.empty? + f.write gem_func_decls + f.puts %Q[] + f.puts %Q[static const struct {] + f.puts %Q[ void (*init)(mrb_state*);] + f.puts %Q[ void (*final)(mrb_state*);] + f.puts %Q[} gem_funcs[] = {] + f.write gem_funcs + f.puts %Q[};] + f.puts %Q[] + f.puts %Q[#define NUM_GEMS ((int)(sizeof(gem_funcs) / sizeof(gem_funcs[0])))] + f.puts %Q[] + f.puts %Q[struct final_mrbgems {] + f.puts %Q[ int i;] + f.puts %Q[ int ai;] + f.puts %Q[};] + f.puts %Q[] + f.puts %Q[static mrb_value] + f.puts %Q[final_mrbgems_body(mrb_state *mrb, void *ud) {] + f.puts %Q[ struct final_mrbgems *p = (struct final_mrbgems*)ud;] + f.puts %Q[ for (; p->i >= 0; p->i--) {] + f.puts %Q[ gem_funcs[p->i].final(mrb);] + f.puts %Q[ mrb_gc_arena_restore(mrb, p->ai);] + f.puts %Q[ }] + f.puts %Q[ return mrb_nil_value();] + f.puts %Q[}] f.puts %Q[] f.puts %Q[static void] f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] - f.write gem_final_calls + f.puts %Q[ struct final_mrbgems a = { NUM_GEMS - 1, mrb_gc_arena_save(mrb) };] + f.puts %Q[ for (; a.i >= 0; a.i--) {] + f.puts %Q[ mrb_protect_error(mrb, final_mrbgems_body, &a, NULL);] + f.puts %Q[ mrb_gc_arena_restore(mrb, a.ai);] + f.puts %Q[ }] f.puts %Q[}] + f.puts %Q[] end - f.puts %Q[] f.puts %Q[void] f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] - f.write gem_init_calls - f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] unless gem_final_calls.empty? + unless gem_funcs.empty? + f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] + f.puts %Q[ for (int i = 0; i < NUM_GEMS; i++) {] + f.puts %Q[ gem_funcs[i].init(mrb);] + f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] + f.puts %Q[ mrb_vm_ci_env_clear(mrb, mrb->c->cibase);] + f.puts %Q[ if (mrb->exc) {] + f.puts %Q[ mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));] + f.puts %Q[ }] + f.puts %Q[ }] + f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] + end f.puts %Q[}] end end diff --git a/mruby/tasks/toolchains/android.rake b/mruby/tasks/toolchains/android.rake index 6e4648e6..98e41304 100644 --- a/mruby/tasks/toolchains/android.rake +++ b/mruby/tasks/toolchains/android.rake @@ -2,7 +2,7 @@ require "json" class MRuby::Toolchain::Android - DEFAULT_ARCH = 'armeabi' # TODO : Revise if arch should have a default + DEFAULT_ARCH = 'armeabi-v7a' # TODO : Revise if arch should have a default DEFAULT_TOOLCHAIN = :clang @@ -15,14 +15,14 @@ class MRuby::Toolchain::Android %LOCALAPPDATA%/Android/Sdk/ndk/* ~/Library/Android/sdk/ndk-bundle ~/Library/Android/ndk + /opt/android-ndk } - TOOLCHAINS = [:clang, :gcc] + TOOLCHAINS = [:clang] ARCHITECTURES = %w{ - armeabi armeabi-v7a arm64-v8a + armeabi-v7a arm64-v8a x86 x86_64 - mips mips64 } class AndroidNDKHomeNotFound < StandardError @@ -40,21 +40,6 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter @params = params end - def bin_gcc(command) - command = command.to_s - - command = case arch - when /armeabi/ then 'arm-linux-androideabi-' - when /arm64-v8a/ then 'aarch64-linux-android-' - when /x86_64/ then 'x86_64-linux-android-' - when /x86/ then 'i686-linux-android-' - when /mips64/ then 'mips64el-linux-android-' - when /mips/ then 'mipsel-linux-android-' - end + command - - gcc_toolchain_path.join('bin', command).to_s - end - def bin(command) command = command.to_s toolchain_path.join('bin', command).to_s @@ -97,38 +82,7 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter end def toolchain_path - @toolchain_path ||= case toolchain - when :gcc - gcc_toolchain_path - when :clang - home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform) - end - end - - def gcc_toolchain_path - if @gcc_toolchain_path === nil then - prefix = case arch - when /armeabi/ then 'arm-linux-androideabi-' - when /arm64-v8a/ then 'aarch64-linux-android-' - when /x86_64/ then 'x86_64-' - when /x86/ then 'x86-' - when /mips64/ then 'mips64el-linux-android-' - when /mips/ then 'mipsel-linux-android-' - end - - test = case arch - when /armeabi/ then 'arm-linux-androideabi-*' - when /arm64-v8a/ then 'aarch64-linux-android-*' - when /x86_64/ then 'x86_64-*' - when /x86/ then 'x86-*' - when /mips64/ then 'mips64el-linux-android-*' - when /mips/ then 'mipsel-linux-android-*' - end - - gcc_toolchain_version = Dir[home_path.join('toolchains', test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max - @gcc_toolchain_path = home_path.join('toolchains', prefix + gcc_toolchain_version.to_s, 'prebuilt', host_platform) - end - @gcc_toolchain_path + @toolchain_path ||= home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform) end def host_platform @@ -189,15 +143,13 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter def cc case toolchain - when :gcc then bin_gcc('gcc') when :clang then bin('clang') end end def ar case toolchain - when :gcc then bin_gcc('ar') - when :clang then bin_gcc('ar') + when :clang then bin('llvm-ar') end end @@ -206,38 +158,15 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter v = sdk_version case toolchain - when :gcc - case arch - when /armeabi-v7a/ then flags += %W(-march=armv7-a) - when /armeabi/ then flags += %W(-march=armv5te) - when /arm64-v8a/ then flags += %W(-march=armv8-a) - when /x86_64/ then flags += %W(-march=x86-64) - when /x86/ then flags += %W(-march=i686) - when /mips64/ then flags += %W(-march=mips64r6) - when /mips/ then flags += %W(-march=mips32) - end when :clang case arch - when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi#{v}) - when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi#{v}) - when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android#{v}) - when /x86_64/ then flags += %W(-target x86_64-none-linux-android#{v}) - when /x86/ then flags += %W(-target i686-none-linux-android#{v}) - when /mips64/ then flags += %W(-target mips64el-none-linux-android#{v}) - when /mips/ then flags += %W(-target mipsel-none-linux-android#{v}) + when /armeabi-v7a/ then flags += %W(-target armv7a-linux-androideabi#{v} -mfpu=#{armeabi_v7a_mfpu} -mfloat-abi=#{armeabi_v7a_mfloat_abi}) + when /arm64-v8a/ then flags += %W(-target aarch64-linux-android#{v}) + when /x86_64/ then flags += %W(-target x86_64-linux-android#{v}) + when /x86/ then flags += %W(-target i686-linux-android#{v}) end end - case arch - when /armeabi-v7a/ then flags += %W(-mfpu=#{armeabi_v7a_mfpu} -mfloat-abi=#{armeabi_v7a_mfloat_abi}) - when /armeabi/ then flags += %W(-mtune=xscale -msoft-float) - when /arm64-v8a/ then flags += %W() - when /x86_64/ then flags += %W() - when /x86/ then flags += %W() - when /mips64/ then flags += %W(-fmessage-length=0) - when /mips/ then flags += %W(-fmessage-length=0) - end - flags end @@ -252,11 +181,6 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter flags += %W(-MMD -MP -D__android__ -DANDROID) flags += ctarget - case toolchain - when :gcc - when :clang - flags += %W(-gcc-toolchain "#{gcc_toolchain_path}" -Wno-invalid-command-line-argument -Wno-unused-command-line-argument) - end flags += %W(-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes) flags @@ -273,20 +197,12 @@ Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter v = sdk_version case toolchain - when :gcc - case arch - when /armeabi-v7a/ then flags += %W(-Wl#{no_warn_mismatch}) - end when :clang - flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}") case arch when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi#{v} -Wl,--fix-cortex-a8#{no_warn_mismatch}) - when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi#{v}) when /arm64-v8a/ then flags += %W(-target aarch64-none-linux-android#{v}) when /x86_64/ then flags += %W(-target x86_64-none-linux-android#{v}) when /x86/ then flags += %W(-target i686-none-linux-android#{v}) - when /mips64/ then flags += %W(-target mips64el-none-linux-android#{v}) - when /mips/ then flags += %W(-target mipsel-none-linux-android#{v}) end end flags += %W(-no-canonical-prefixes) diff --git a/mruby/tasks/toolchains/gcc.rake b/mruby/tasks/toolchains/gcc.rake index aa1cf777..675c2688 100644 --- a/mruby/tasks/toolchains/gcc.rake +++ b/mruby/tasks/toolchains/gcc.rake @@ -20,6 +20,10 @@ MRuby::Toolchain.new(:gcc) do |conf, params| compiler.cxx_compile_flag = '-x c++ -std=gnu++03' compiler.cxx_exception_flag = '-fexceptions' compiler.cxx_invalid_flags = c_mandatory_flags + cxx_invalid_flags + + def compiler.setup_debug(conf) + self.flags << %w(-g3 -O0) + end end conf.linker do |linker| diff --git a/mruby/test/t/bs_block.rb b/mruby/test/t/bs_block.rb index c37d1b53..08580d58 100644 --- a/mruby/test/t/bs_block.rb +++ b/mruby/test/t/bs_block.rb @@ -313,7 +313,7 @@ def m end assert('BS Block 26') do - def m a + def m(a) yield a end assert_equal(2) do diff --git a/mruby/test/t/class.rb b/mruby/test/t/class.rb index 1b4b8489..f4d99318 100644 --- a/mruby/test/t/class.rb +++ b/mruby/test/t/class.rb @@ -40,7 +40,7 @@ def initialize_copy(obj) end class TestClass - def initialize args, &block + def initialize(args, &block) @result = if not args.nil? and block.nil? # only arguments :only_args diff --git a/mruby/test/t/codegen.rb b/mruby/test/t/codegen.rb index acb9e1bf..0cb86efc 100644 --- a/mruby/test/t/codegen.rb +++ b/mruby/test/t/codegen.rb @@ -56,12 +56,11 @@ def args_to_ary(*args) end end -assert('next in normal loop with 127 arguments') do - assert_raise NameError do - while true - next A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A - end - end +assert('break in normal loop with 127 arguments') do + assert_equal 127, + 1.times{ + break 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,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 + }.size end assert('negate literal register alignment') do diff --git a/mruby/test/t/float.rb b/mruby/test/t/float.rb index e4c25b34..1a7f6c99 100644 --- a/mruby/test/t/float.rb +++ b/mruby/test/t/float.rb @@ -216,7 +216,7 @@ end assert('Float#divmod') do - def check_floats exp, act + def check_floats(exp, act) assert_float exp[0], act[0] assert_float exp[1], act[1] end diff --git a/mruby/test/t/hash.rb b/mruby/test/t/hash.rb index 9ff066b8..3ce2e14f 100644 --- a/mruby/test/t/hash.rb +++ b/mruby/test/t/hash.rb @@ -880,17 +880,6 @@ def h.default(k); self[k] = 1; end hh[hh] = :recur assert_equal("{#{s}, {...}=>:recur}", hh.__send__(meth)) end - - [ar_entries, ht_entries].each do |entries| - cls = Class.new do - attr_accessor :h - def inspect; @h.replace(@h.dup); to_s; end - end - v = cls.new - h = entries.hash_for({_k: v}) - v.h = h - assert_nothing_raised{h.__send__(meth)} - end end end diff --git a/mruby/test/t/string.rb b/mruby/test/t/string.rb index 11b5cae0..0bb9acfb 100644 --- a/mruby/test/t/string.rb +++ b/mruby/test/t/string.rb @@ -898,3 +898,72 @@ assert_equal("o", str1.byteslice(4.0)) assert_equal("\x82ab", str2.byteslice(2.0, 3.0)) end + +assert('String#bytesplice') do + # range, replace (len1=len2) + a = "0123456789" + assert_equal "0ab3456789", a.bytesplice(1..2, "ab") + + # range, replace (len1>len2) + a = "0123456789" + assert_equal "0ab456789", a.bytesplice(1..3, "ab") + + # range, replace (len1len2) + a = "0123456789" + assert_equal "0ab456789", a.bytesplice(1, 3, "ab") + + # idx, len, replace (len1len2) + a = "0123456789" + assert_equal "0bc456789", a.bytesplice(1..3, b, 1..2) + + # range, replace, range (len1len2) + a = "0123456789" + assert_equal "0bc456789", a.bytesplice(1, 3, b, 1, 2) + + # idx, len, replace, idx, len (len1