Commit Graph

5379 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto d3fcb176bf mruby-bin-mirb: restore tab completion for custom editor
- restore mirb_completion.c/h from before readline removal
- add editor adapter for tab completion (mirb_setup_editor_completion,
  mirb_get_completions, mirb_free_completions)
- add TAB key handling in mirb_editor.c
- fix string literal completion: properly detect when cursor is outside
  a string by scanning forward, allow string/array/hash literals as
  safe receivers for method completion

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-18 16:27:24 +09:00
Yukihiro "Matz" Matsumoto d47dedd17d mruby-bin-mirb: improve Enter key behavior and auto-indentation
- fix Enter in middle of line with trailing blank continuation line:
  now properly splits the line and removes redundant blank line
- fix auto-indentation when inserting in middle of existing code:
  calculate indent from lines up to cursor, not entire buffer
- add mirb_buffer_delete_line() for removing lines from buffer

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-18 16:27:23 +09:00
Yukihiro "Matz" Matsumoto 23c49ad026 mruby-bin-mirb: show incrementing line numbers in multi-line prompts
Previously, all continuation lines showed the same line number (e.g.,
"1*" for every line). Now each line shows its actual line number:

  1> class Foo
  2*   def bar
  3*   end
  4* end

Add mirb_editor_set_prompt_format() which accepts printf-style format
strings (e.g., "%d> ", "%d* ") and calculates the correct prompt length
for each line to ensure proper cursor positioning.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-18 16:27:23 +09:00
Yukihiro "Matz" Matsumoto 5f85c1beae mruby-bin-mirb: add command history with Up/Down navigation
Add in-memory command history for mirb sessions:
- Up arrow on first line: navigate to older history entries
- Down arrow on last line: navigate to newer history entries
- Current input is preserved when browsing and restored when
  navigating past the newest entry
- History uses a circular buffer (100 entries max)
- Duplicate consecutive entries are not added

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-18 16:27:22 +09:00
Yukihiro "Matz" Matsumoto 2813f794a2 mruby-io: rename mruby/ext/io.h to mruby/io.h
Simplify the header path to be consistent with mruby/time.h.
The ext/ subdirectory was unnecessary.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:11 +09:00
Yukihiro "Matz" Matsumoto 527018cf07 mruby-bin-mirb: replace readline with custom multi-line editor
Remove readline/linenoise dependency and implement custom multi-line
editor with:
- Terminal raw mode handling (POSIX termios)
- Multi-line buffer with cursor navigation
- Auto-indentation for Ruby blocks
- Auto-dedentation when typing 'end' or '}'
- Natural terminal scrolling behavior
- Emacs-style keybindings (Ctrl+A/E/K/U/W/Y, Alt+B/F/D)

This eliminates GPL licensing concerns from readline while providing
better multi-line editing than the previous single-line implementation.

The MRUBY_MIRB_READLINE environment variable is no longer supported
as readline integration has been completely removed; ref #6626

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:10 +09:00
Yukihiro "Matz" Matsumoto b36e0b4090 mruby-bin-mirb: add colored output for prompts and errors
Add ANSI color support to mirb for better visual distinction:
- green prompts (both ready '>' and continuation '*')
- red error messages (syntax errors, runtime errors, warnings)
- bold result indicator ('=>')

Colors are automatically disabled when:
- output is not a TTY
- TERM is unset or "dumb"
- NO_COLOR environment variable is set

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:10 +09:00
Yukihiro "Matz" Matsumoto d52f3189d8 mruby-bin-mirb: add auto-indent for continuation lines
- automatically indent continuation lines based on block depth
- detect block-opening keywords (def, class, if, do, etc.) and braces
- use ANSI escape sequences to fix indentation for:
  - block-closing keywords (end, })
  - mid-block keywords (else, elsif, rescue, ensure, when)
- only active for interactive TTY input with ANSI support
- requires GNU readline (not available with linenoise)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:10 +09:00
Yukihiro "Matz" Matsumoto 9ad72e3a96 mrbgems: add README documentation for mruby-bin-* gems
- mruby-bin-config
- mruby-bin-debugger
- mruby-bin-mrbc
- mruby-bin-mruby
- mruby-bin-strip

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:10 +09:00
Yukihiro "Matz" Matsumoto f55bb0857a mruby-bin-mirb: add README with tab completion documentation
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:10 +09:00
Yukihiro "Matz" Matsumoto 97d4d8f45b mruby-set: standardize block parameter spacing
changed block spacing from { | to {| for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:10 +09:00
Yukihiro "Matz" Matsumoto 4bef968452 mruby-method: standardize block parameter spacing
changed block spacing from { | to {| for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:10 +09:00
Yukihiro "Matz" Matsumoto 8b0a4519b1 mruby-enum-ext: fix remaining block parameter spacing
changed block spacing from method{ to method { for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:09 +09:00
Yukihiro "Matz" Matsumoto b7563c327b mruby-benchmark: standardize block parameter spacing
changed block spacing from { | to {| for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:09 +09:00
Yukihiro "Matz" Matsumoto 3cc4a77f49 mruby-socket: standardize block parameter spacing
changed block spacing from { | to {| for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:09 +09:00
Yukihiro "Matz" Matsumoto e6fa93929d mruby-io: standardize block parameter spacing
changed block spacing from { | to {| for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:09 +09:00
Yukihiro "Matz" Matsumoto 7cc41d5bc0 mruby-hash-ext: standardize block parameter spacing
changed block spacing from method{ to method { for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:09 +09:00
Yukihiro "Matz" Matsumoto 93cdb62985 mruby-struct: standardize block parameter spacing
changed block spacing from method{ to method { for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:09 +09:00
Yukihiro "Matz" Matsumoto 0d4695a91c mruby-enum-lazy: standardize block parameter spacing
changed block spacing from method{ to method { for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:09 +09:00
Yukihiro "Matz" Matsumoto 89237e9cf9 mruby-enum-ext: standardize block parameter spacing
changed block spacing from method{ to method { for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:08 +09:00
Yukihiro "Matz" Matsumoto 722d4f77dd mruby-array-ext: standardize block parameter spacing
changed block spacing from { |param| to {|param| for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:08 +09:00
Yukihiro "Matz" Matsumoto 4dedb120c8 mruby-enum-ext: add parentheses to respond_to? call
added parentheses to respond_to? call where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:08 +09:00
Yukihiro "Matz" Matsumoto 676ab238a2 mruby-complex: add parentheses to Math method calls
added parentheses to Math.hypot and Math.atan2 calls where the return
value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:08 +09:00
Yukihiro "Matz" Matsumoto 0d7903694c mruby-enumerator: add parentheses to block.call
added parentheses to block.call calls where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:07 +09:00
Yukihiro "Matz" Matsumoto 171ad3fb4f mruby-array-ext: add parentheses to block.call
added parentheses to block.call where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:07 +09:00
Yukihiro "Matz" Matsumoto 75d7b8ed7c mruby-string-ext: add parentheses to to_enum call
added parentheses to to_enum call where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:07 +09:00
Yukihiro "Matz" Matsumoto 29644b0365 mruby-set: add parentheses to to_enum calls
added parentheses to all to_enum calls where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:07 +09:00
Yukihiro "Matz" Matsumoto 1fbace12a4 mruby-object-ext: add parentheses to to_enum call
added parentheses to to_enum call where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:07 +09:00
Yukihiro "Matz" Matsumoto 5f20013219 mruby-io: add parentheses to to_enum call
added parentheses to to_enum call where the return value is used,
explicitly specifying :each for readability.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:06 +09:00
Yukihiro "Matz" Matsumoto 6e67d64068 mruby-hash-ext: add parentheses to to_enum calls
added parentheses to all to_enum calls where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:06 +09:00
Yukihiro "Matz" Matsumoto 284dde6a3f mruby-enumerator: add parentheses to to_enum calls
added parentheses to all to_enum calls where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:06 +09:00
Yukihiro "Matz" Matsumoto 2e71944f2b mruby-enum-ext: add parentheses to to_enum calls
added parentheses to all to_enum calls where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:06 +09:00
Yukihiro "Matz" Matsumoto 531d5a76e5 mruby-enum-chain: add parentheses to to_enum call
added parentheses to to_enum call where the return value is used,
explicitly specifying :each for readability.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:06 +09:00
Yukihiro "Matz" Matsumoto fce4eba9b2 mruby-array-ext: add parentheses to to_enum calls
added parentheses to all to_enum calls where the return value is used.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:06 +09:00
Yukihiro "Matz" Matsumoto 4cf75fb035 mruby-bin-mirb: restrict evaluation to simple receivers
fixed a bug where tab completion on complex expressions like "d.new(1).a"
would corrupt local variables, causing them to become nil.

the root cause was that evaluating complex receiver expressions during tab
completion ran mrb_vm_run() without proper stack management (stack_keep)
and environment adjustment that mirb's main REPL loop performs. this
corrupted the local variable storage.

the fix restricts tab completion to only evaluate simple receiver
expressions (variable/constant names without operators or method calls).
complex expressions are skipped for completion. this means:
- works: d.<tab> completes methods of variable d
- works: String.<tab> completes methods of constant String
- skipped: d.new(1).<tab> provides no completion

this is a reasonable trade-off that prevents the corruption bug while
still supporting the most common completion scenarios.

also updated mirb_eval_receiver() to use the compiler context for proper
local variable resolution, with argument order matching mrb_parse_string.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:05 +09:00
Yukihiro "Matz" Matsumoto 2f152823f3 mruby-bin-mirb: add tab completion support
implements context-aware tab completion for mirb supporting all readline
variants (GNU readline, libedit, linenoise) with graceful degradation
when no readline library is available.

completion features:
- method names on objects (e.g., "hello".re<Tab> completes to reverse, replace)
- local variables from compiler context
- global variables via Ruby introspection
- constants and class names
- Ruby keywords

architecture:
- core completion engine is library-agnostic
- thin adapters for readline/libedit and linenoise
- context detection based on cursor position analysis
- safe receiver evaluation with exception handling
- proper word break characters so "String.new" works correctly

implementation adds:
- mirb_completion.h: interface definitions and data structures
- mirb_completion.c: complete implementation (~670 lines)
- mirb.c: integration with setup/cleanup calls

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:05 +09:00
Yukihiro "Matz" Matsumoto 0aafb83374 mruby-bin-mirb: add MRUBY_MIRB_READLINE to control readline library selection
addresses #6626 where users building portable binaries need explicit control
over readline detection instead of auto-detection.

MRUBY_MIRB_READLINE values:
  auto (default) - auto-detect: try readline, then edit, then linenoise
  readline, gnu  - force GNU readline only
  edit, libedit  - force libedit only
  linenoise      - force linenoise only
  none, off, false, disabled - use plain input mode (no readline)

close #6626

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:05 +09:00
Yukihiro "Matz" Matsumoto 9aa6f28eab mirb: show method context for errors from previous code
runtime errors now distinguish between:
- errors in current input: show relative line number
- errors from previously defined methods: show method context

examples:
1> a.foo
line 1: undefined method 'a' for Object (NoMethodError)

1> def foo
2*   bar
3* end
1> foo
(mirb):in foo: undefined method 'bar' for Object (NoMethodError)

this provides better context since method name is more useful
than line number for errors in previously defined code

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:05 +09:00
Yukihiro "Matz" Matsumoto ac39b7d8ad mruby-bin-mirb: enhanced syntax error display
syntax errors now show:
- line:column format with relative line numbers (matching prompt)
- source line from user input
- caret indicator pointing to error position

example:
1> x = @@@
line 1:6: syntax error, unexpected invalid token
  x = @@@
        ^

multi-line example:
1> class Foo
2*   def bar
3*     x = @@@
line 3:6: syntax error, unexpected invalid token
      x = @@@
        ^

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:05 +09:00
Yukihiro "Matz" Matsumoto 5a3f0e2e0b mruby-bin-mirb: add line numbers to multi-line prompts
add minimal line number decoration to prompts to help track position
within multi-line code blocks. format is 'N>' for initial line and
'N*' for continuation lines. line counter resets after each complete
evaluation for clarity and minimal visual noise.

example:
1> def foo
2*   x = 1
3* end
 => :foo
1> 1 + 1
 => 2

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 18:09:05 +09:00
Yukihiro "Matz" Matsumoto 2336534552 mruby-benchmark: add comprehensive test suite
add 24 test cases covering all benchmark functionality:
- Benchmark.measure and Benchmark.realtime
- Benchmark::Tms class and its methods (total, to_s, format)
- Benchmark.bm for formatted comparison reports
- Benchmark::Report class
- memory tracking with ObjectSpace integration
- consistency and realistic usage scenarios

suppress output during tests by temporarily setting $stdout to nil
for tests that call Benchmark.bm or Report#report to avoid printing
garbage during test execution.

all tests pass successfully.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 23:12:37 +09:00
Yukihiro "Matz" Matsumoto 13e2ce4249 mruby-benchmark: fix implementation for mruby environment
fix implementation to work correctly in mruby:
- use String#% instead of sprintf for formatting
- use $stdout directly for output instead of bare print/puts
- add nil check for $stdout to handle test environments
- use Object.const_defined? instead of defined? keyword
- create new Tms instance with label instead of instance_variable_set
- add dependencies: mruby-sprintf and mruby-io

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 23:12:36 +09:00
Yukihiro "Matz" Matsumoto 2f40f3d170 mruby-benchmark: add benchmarking gem
add initial implementation of mruby-benchmark gem providing:
- Benchmark.measure for detailed timing with Tms results
- Benchmark.realtime for simple wall-clock measurements
- Benchmark.bm for formatted comparison reports
- optional memory tracking via ObjectSpace integration

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 23:12:36 +09:00
Yukihiro "Matz" Matsumoto 29b3405283 bigint.c: handle in-place operation in mpz_mod_2exp()
when mpz_mod_2exp() is called with z == x (in-place operation), the
function was calling mpz_clear(ctx, z) which freed x's memory, then
attempting to access x->p[i] - reading freed memory. this caused
Barrett reduction to produce incorrect results in modular
exponentiation.

the fix checks if z == x and handles in-place modification by
adjusting the size and masking directly, without clearing. this is
similar to the memory leak fix for pool→heap transitions.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 18:20:44 +09:00
Yukihiro "Matz" Matsumoto a5e25393b8 mruby-bigint: fix memory leak in mpz_mod_2exp by clearing before reinit
mpz_mod_2exp() was reinitializing its output parameter without clearing
existing heap memory. When the parameter contained heap allocations from
pool->heap transitions in mpz_mul()->mpz_realloc(), reinitializing would
overwrite the pointer and leak memory. Added mpz_clear() before each
mpz_init() or mpz_init_heap() call to properly free existing heap memory.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 18:20:44 +09:00
Yukihiro "Matz" Matsumoto 5ed0cd4ecb bigint.c: increase karatsuba scratch allocation safety margin
the previous fixed safety margin of 8 limbs was insufficient for certain
edge cases involving deep recursion levels in karatsuba multiplication,
as discovered by oss-fuzz. changed to proportional margin (~12.5% plus
fixed overhead of 16) that scales with input size.

this prevents potential buffer overruns in deeply nested karatsuba
multiplications while maintaining efficiency for typical cases.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 18:20:44 +09:00
Yukihiro "Matz" Matsumoto 857de45036 mruby-time: normalize microseconds before converting to nanoseconds
when converting microseconds to nanoseconds, multiplying very large
usec values by 1000 can cause signed integer overflow. for example,
Time.at(0, 9999999999990768) would trigger ASAN runtime error.

fixed by normalizing microseconds >= 1000000 (or <= -1000000) to
seconds before the multiplication, preventing overflow while maintaining
correct time representation. this normalization converts excess
microseconds to seconds, leaving only the fractional part for
multiplication.

applied fix to both time_alloc() and mrb_time_at() functions.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 18:20:44 +09:00
Yukihiro "Matz" Matsumoto db3d754261 mruby-array-ext: use mrb_ensure() instead of direct throw.h calls
refactored five functions to use mrb_ensure() instead of MRB_TRY/MRB_CATCH:
- ary_subtract_internal(): body/ensure pattern for set cleanup
- ary_union_internal(): body/ensure pattern for set cleanup
- ary_intersection_internal(): body/ensure pattern for set cleanup
- ary_intersect_p(): body/ensure pattern for set cleanup
- ary_uniq_bang(): body/ensure pattern for set cleanup

each function now uses a context struct containing set pointer and other
necessary data, with separate body and ensure functions that guarantee
cleanup on exception. this allows array-ext to compile as pure C without
requiring C++ compiler when enable_cxx_exception is set.

added mruby-error dependency to access mrb_ensure(). changed include
from throw.h to error.h. fix #6667.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 18:20:42 +09:00
John Bampton 8558ad40ec Adjust broken license links; clean up Markdown 2025-11-29 01:46:54 +10:00
Yukihiro "Matz" Matsumoto 82180d040b codegen.c: fix regexp literal with encoding to pass nil for options; fix #6666
restore correct argument passing for Regexp.compile when encoding is
present but flags are not. regexp literals like /a/n should compile to
Regexp.compile("a", nil, "n") with 3 arguments, not
Regexp.compile("a", "n") with 2 arguments.

the bug was introduced during refactoring when the nil-insertion logic
for the options parameter was accidentally omitted. now properly inserts
OP_LOADNIL when flags are absent but encoding is present.

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-20 14:08:21 +09:00