mruby does not provide `begin ... end while cond` that behave at-least-once
loop, like CRuby does. It remains in TODO.md for long time. But finally we have
implemented the behavior.
This commit introduces NODE_BEGIN as a distinct AST node type for
explicit begin...end blocks, separate from NODE_STMTS which represents
general statement sequences. This distinction will be essential for
implementing CRuby-compatible begin...end while/until constructs.
Key changes:
- Added NODE_BEGIN enum in node.h
- Added new_begin() function in parse.y using optimized cons() structure
- Modified begin...end grammar rule to generate NODE_BEGIN nodes
- Added NODE_BEGIN codegen support in codegen.c
- Added NODE_BEGIN to parser dump functionality
NODE_BEGIN uses a simpler cons() structure instead of list2() for
better memory efficiency, as it only contains a single body node.
Co-Authored-By: Claude <noreply@anthropic.com>
Modify new_stmts to flatten unnecessary nesting by returning existing
NODE_STMTS directly instead of wrapping them. This reduces memory usage
and AST complexity when multiple parentheses levels are used.
Before: (((expr1; expr2))) creates nested NODE_STMTS
After: (((expr1; expr2))) creates single NODE_STMTS with statements
Co-authored-by: Claude <noreply@anthropic.com>
Rename NODE_BEGIN to NODE_STMTS to better reflect its purpose as a
container for statement sequences, not specifically begin-end blocks.
This prepares for adding a dedicated node type for explicit begin-end
constructs.
- Rename NODE_BEGIN enum to NODE_STMTS in node.h
- Update all references in parse.y and codegen.c
- Rename new_begin function to new_stmts
Co-Authored-By: Claude <noreply@anthropic.com>
To avoid confusion with pools in irep, we renamed region-based memory
manager from pool to mempool.
- rename pool.c to mempool.c
- separate mempool.h
- rename all mrb_pool to mrb_mempool
So if someone is using pool.c functions (I suppose no one does though),
they need to rename all `mrb_pool` to `mrb_mempool` and include
`mruby/mempool.h` header at the top.
To mark `MRB_PROC_ORPHAN` we need to keep track of passed block, even
after the assignment to the block argument. And `yield` should use the
original block; #5786, #5791, #6369
This change itself does nothing good, but it is a preparation for the
future Bison to Lrama migration. As of 0.6.9, Lrama has a compatibility
issue for grammar files without `@n`.
This is to keep the local variables of the previously created blocks consistent in case the `mrbc_context` passed to `mrb_load_exec()` is `NULL` or different.
Switching between `mrbc_context` pointers that are non `NULL` can be done safely by calling `mrbc_cleanup_local_variables()`.
Before this patch, the result of the following code is not as expected.
```console
% cat loadstr.c
#include <mruby.h>
#include <mruby/compile.h>
int
main(int argc, char *argv[])
{
mrb_state *mrb = mrb_open();
mrb_load_string(
mrb,
"(a, b, c, d, e, f, g) = [1, 2, 3, 4, 5, 6, 7] \n"
"$lambda = -> { p [a, b, c, d, e, f, g] }");
mrb_load_string(mrb, "$lambda.call");
mrb_close(mrb);
return 0;
}
% $(bin/mruby-config --cc --cflags --ldflags) loadstr.c $(bin/mruby-config --libs) && ./a.out
[main, nil, nil, main, nil, nil, main]
```
Also, since `mrb_env_unshare()` was not used before, the internal stack of simply detached `env` objects could show invalid addresses by `stack_extend()`.
ref. https://github.com/kou/mruby-pp/commit/ef5951aca870183d8767cb61f6414240988ca35e
- remove `lex_strterm_before_heredoc` that does not nest
- remove `all_heredocs` that cannot distinguish nested and followed
here-doc
- replace `lex_strterm` represented by cons list by C struct
- push/pop `lex_strterm` before/after interpolation