Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
e3ae0e4f
Commit
e3ae0e4f
authored
Nov 27, 2018
by
Hiroshi Mimaki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into stable
parents
0711c861
26475d0a
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
112 additions
and
44 deletions
+112
-44
doc/limitations.md
doc/limitations.md
+21
-1
include/mruby/irep.h
include/mruby/irep.h
+5
-0
include/mruby/throw.h
include/mruby/throw.h
+4
-4
mrbgems/mruby-array-ext/mrblib/array.rb
mrbgems/mruby-array-ext/mrblib/array.rb
+1
-1
mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+10
-2
mrbgems/mruby-compiler/core/codegen.c
mrbgems/mruby-compiler/core/codegen.c
+34
-6
mrbgems/mruby-compiler/core/parse.y
mrbgems/mruby-compiler/core/parse.y
+37
-30
No files found.
doc/limitations.md
View file @
e3ae0e4f
...
...
@@ -219,7 +219,7 @@ $ ruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
[[{"a"=>1}], {:b=>2}]
```
#### mruby []
#### mruby [
mruby 2.0.0
]
```
$ ./bin/mruby -e 'def m(
*r,*
*
k) p [r,k] end; m("a"=>1,:b=>2)'
...
...
@@ -227,3 +227,23 @@ trace (most recent call last):
[0] -e:1
-e:1: keyword argument hash with non symbol keys (ArgumentError)
```
## Argument Destructuring
```
ruby
def m(a,(b,c),d); p [a,b,c,d]; end
m(1,[2,3],4) # => [1,2,3,4]
```
Destructured arguments (`b` and `c` in above example) cannot be accessed
from the default expression of optional arguments and keyword arguments,
since actual assignment is done after the evaluation of those default
expressions. Thus:
```
ruby
def f(a,(b,c),d=b)
p [a,b,c,d]
end
f(1,[2,3])
```
CRuby gives `[1,2,3,nil]`. mruby raises `NoMethodError` for `b`.
include/mruby/irep.h
View file @
e3ae0e4f
...
...
@@ -48,8 +48,13 @@ typedef struct mrb_irep {
#define MRB_ISEQ_NO_FREE 1
MRB_API
mrb_irep
*
mrb_add_irep
(
mrb_state
*
mrb
);
/* @param [const uint8_t*] irep code, expected as a literal */
MRB_API
mrb_value
mrb_load_irep
(
mrb_state
*
,
const
uint8_t
*
);
/* @param [const uint8_t*] irep code, expected as a literal */
MRB_API
mrb_value
mrb_load_irep_cxt
(
mrb_state
*
,
const
uint8_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
*
);
...
...
include/mruby/throw.h
View file @
e3ae0e4f
...
...
@@ -15,9 +15,9 @@
#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
#define MRB_TRY(buf)
do {
try {
#define MRB_TRY(buf) try {
#define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; }
#define MRB_END_EXC(buf) }
} while(0)
#define MRB_END_EXC(buf) }
#define MRB_THROW(buf) throw((buf)->impl)
typedef
mrb_int
mrb_jmpbuf_impl
;
...
...
@@ -34,9 +34,9 @@ typedef mrb_int mrb_jmpbuf_impl;
#define MRB_LONGJMP longjmp
#endif
#define MRB_TRY(buf)
do {
if (MRB_SETJMP((buf)->impl) == 0) {
#define MRB_TRY(buf) if (MRB_SETJMP((buf)->impl) == 0) {
#define MRB_CATCH(buf) } else {
#define MRB_END_EXC(buf) }
} while(0)
#define MRB_END_EXC(buf) }
#define MRB_THROW(buf) MRB_LONGJMP((buf)->impl, 1);
#define mrb_jmpbuf_impl jmp_buf
...
...
mrbgems/mruby-array-ext/mrblib/array.rb
View file @
e3ae0e4f
...
...
@@ -291,7 +291,7 @@ class Array
# #=> "100 is out of bounds"
#
def
fetch
(
n
=
nil
,
ifnone
=
NONE
,
&
block
)
def
fetch
(
n
,
ifnone
=
NONE
,
&
block
)
warn
"block supersedes default value argument"
if
!
n
.
nil?
&&
ifnone
!=
NONE
&&
block
idx
=
n
...
...
mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
View file @
e3ae0e4f
...
...
@@ -56,6 +56,7 @@
#include <mruby/dump.h>
#include <mruby/string.h>
#include <mruby/variable.h>
#include <mruby/throw.h>
#ifdef ENABLE_READLINE
...
...
@@ -491,7 +492,10 @@ main(int argc, char **argv)
while
(
TRUE
)
{
char
*
utf8
;
struct
mrb_jmpbuf
c_jmp
;
MRB_TRY
(
&
c_jmp
);
mrb
->
jmp
=
&
c_jmp
;
if
(
args
.
rfp
)
{
if
(
fgets
(
last_code_line
,
sizeof
(
last_code_line
)
-
1
,
args
.
rfp
)
!=
NULL
)
goto
done
;
...
...
@@ -555,8 +559,7 @@ main(int argc, char **argv)
MIRB_LINE_FREE
(
line
);
#endif
done:
done:
if
(
code_block_open
)
{
if
(
strlen
(
ruby_code
)
+
strlen
(
last_code_line
)
>
sizeof
(
ruby_code
)
-
1
)
{
fputs
(
"concatenated input string too long
\n
"
,
stderr
);
...
...
@@ -648,6 +651,11 @@ done:
}
mrb_parser_free
(
parser
);
cxt
->
lineno
++
;
MRB_CATCH
(
&
c_jmp
)
{
p
(
mrb
,
mrb_obj_value
(
mrb
->
exc
),
0
);
mrb
->
exc
=
0
;
}
MRB_END_EXC
(
&
c_jmp
);
}
#ifdef ENABLE_READLINE
...
...
mrbgems/mruby-compiler/core/codegen.c
View file @
e3ae0e4f
...
...
@@ -734,15 +734,13 @@ lambda_body(codegen_scope *s, node *tree, int blk)
mrb_aspec
a
;
int
ma
,
oa
,
ra
,
pa
,
ka
,
kd
,
ba
;
int
pos
,
i
;
node
*
n
,
*
opt
;
node
*
opt
;
node
*
margs
,
*
pargs
;
node
*
tail
;
/* mandatory arguments */
ma
=
node_len
(
tree
->
car
->
car
);
n
=
tree
->
car
->
car
;
while
(
n
)
{
n
=
n
->
cdr
;
}
margs
=
tree
->
car
->
car
;
tail
=
tree
->
car
->
cdr
->
cdr
->
cdr
->
cdr
;
/* optional arguments */
...
...
@@ -751,6 +749,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
ra
=
tree
->
car
->
cdr
->
cdr
->
car
?
1
:
0
;
/* mandatory arugments after rest argument */
pa
=
node_len
(
tree
->
car
->
cdr
->
cdr
->
cdr
->
car
);
pargs
=
tree
->
car
->
cdr
->
cdr
->
cdr
->
car
;
/* keyword arguments */
ka
=
tail
?
node_len
(
tail
->
cdr
->
car
)
:
0
;
/* keyword dictionary? */
...
...
@@ -798,6 +797,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
dispatch
(
s
,
pos
+
i
*
3
+
1
);
}
/* keyword arguments */
if
(
tail
)
{
node
*
kwds
=
tail
->
cdr
->
car
;
int
kwrest
=
0
;
...
...
@@ -836,7 +836,34 @@ lambda_body(codegen_scope *s, node *tree, int blk)
genop_0
(
s
,
OP_KEYEND
);
}
}
/* argument destructuring */
if
(
margs
)
{
node
*
n
=
margs
;
pos
=
1
;
while
(
n
)
{
if
(
nint
(
n
->
car
->
car
)
==
NODE_MASGN
)
{
gen_vmassignment
(
s
,
n
->
car
->
cdr
->
car
,
pos
,
NOVAL
);
}
pos
++
;
n
=
n
->
cdr
;
}
}
if
(
pargs
)
{
node
*
n
=
margs
;
pos
=
ma
+
oa
+
ra
+
1
;
while
(
n
)
{
if
(
nint
(
n
->
car
->
car
)
==
NODE_MASGN
)
{
gen_vmassignment
(
s
,
n
->
car
->
cdr
->
car
,
pos
,
NOVAL
);
}
pos
++
;
n
=
n
->
cdr
;
}
}
}
codegen
(
s
,
tree
->
cdr
->
car
,
VAL
);
pop
();
if
(
s
->
pc
>
0
)
{
...
...
@@ -1066,6 +1093,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
idx
=
new_sym
(
s
,
nsym
(
tree
));
genop_2
(
s
,
OP_SETGV
,
sp
,
idx
);
break
;
case
NODE_ARG
:
case
NODE_LVAR
:
idx
=
lv_idx
(
s
,
nsym
(
tree
));
if
(
idx
>
0
)
{
...
...
@@ -1173,7 +1201,7 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
pop_n
(
post
+
1
);
genop_3
(
s
,
OP_APOST
,
cursp
(),
n
,
post
);
n
=
1
;
if
(
t
->
car
)
{
/* rest */
if
(
t
->
car
&&
t
->
car
!=
(
node
*
)
-
1
)
{
/* rest */
gen_assignment
(
s
,
t
->
car
,
cursp
(),
NOVAL
);
}
if
(
t
->
cdr
&&
t
->
cdr
->
car
)
{
...
...
mrbgems/mruby-compiler/core/parse.y
View file @
e3ae0e4f
...
...
@@ -682,6 +682,25 @@ new_arg(parser_state *p, mrb_sym sym)
return cons((node*)NODE_ARG, nsym(sym));
}
static void
local_add_margs(parser_state *p, node *n)
{
while (n) {
if (n->car->car == (node*)NODE_MASGN) {
node *t = n->car->cdr->cdr;
n->car->cdr->cdr = NULL;
while (t) {
local_add_f(p, sym(t->car));
t = t->cdr;
}
local_add_margs(p, n->car->cdr->car->car);
local_add_margs(p, n->car->cdr->car->cdr->cdr->car);
}
n = n->cdr;
}
}
/* (m o r m2 tail) */
/* m: (a b c) */
/* o: ((a . e1) (b . e2)) */
...
...
@@ -693,6 +712,8 @@ new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail
{
node *n;
local_add_margs(p, m);
local_add_margs(p, m2);
n = cons(m2, tail);
n = cons(nsym(rest), n);
n = cons(opt, n);
...
...
@@ -1171,7 +1192,7 @@ heredoc_end(parser_state *p)
%type <nd> command_args aref_args opt_block_arg block_arg var_ref var_lhs
%type <nd> command_asgn command_rhs mrhs superclass block_call block_command
%type <nd> f_block_optarg f_block_opt
%type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_marg
f_marg_list f_marg
s
%type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_margs
%type <nd> assoc_list assocs assoc undef_list backref for_var
%type <nd> block_param opt_block_param block_param_def f_opt
%type <nd> bv_decls opt_bv_decl bvar f_larglist lambda_body
...
...
@@ -2447,44 +2468,24 @@ for_var : lhs
| mlhs
;
f_marg : f_norm_arg
{
$$ = new_arg(p, $1);
}
| tLPAREN f_margs rparen
{
$$ = new_masgn(p, $2, 0);
}
;
f_marg_list : f_marg
{
$$ = list1($1);
}
| f_marg_list ',' f_marg
{
$$ = push($1, $3);
}
;
f_margs : f_marg_list
f_margs : f_arg
{
$$ = list3($1,0,0);
}
| f_
marg_list
',' tSTAR f_norm_arg
| f_
arg
',' tSTAR f_norm_arg
{
$$ = list3($1, new_arg(p, $4), 0);
}
| f_
marg_list ',' tSTAR f_norm_arg ',' f_marg_list
| f_
arg ',' tSTAR f_norm_arg ',' f_arg
{
$$ = list3($1, new_arg(p, $4), $6);
}
| f_
marg_list
',' tSTAR
| f_
arg
',' tSTAR
{
local_add_f(p, 0);
$$ = list3($1, (node*)-1, 0);
}
| f_
marg_list ',' tSTAR ',' f_marg_list
| f_
arg ',' tSTAR ',' f_arg
{
$$ = list3($1, (node*)-1, $5);
}
...
...
@@ -2492,7 +2493,7 @@ f_margs : f_marg_list
{
$$ = list3(0, new_arg(p, $2), 0);
}
| tSTAR f_norm_arg ',' f_
marg_list
| tSTAR f_norm_arg ',' f_
arg
{
$$ = list3(0, new_arg(p, $2), $4);
}
...
...
@@ -2505,7 +2506,7 @@ f_margs : f_marg_list
{
local_add_f(p, 0);
}
f_
marg_list
f_
arg
{
$$ = list3(0, (node*)-1, $4);
}
...
...
@@ -3295,9 +3296,15 @@ f_arg_item : f_norm_arg
{
$$ = new_arg(p, $1);
}
| tLPAREN f_margs rparen
| tLPAREN
{
$<nd>$ = local_switch(p);
}
f_margs rparen
{
$$ = new_masgn(p, $2, 0);
$$ = new_masgn(p, $3, p->locals->car);
local_resume(p, $<nd>2);
local_add_f(p, 0);
}
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment