diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2016-03-23 08:35:43 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2016-03-23 08:51:25 +0900 |
| commit | 21a3ae08f7dc252e4cf6d34e5ebead0124fb0117 (patch) | |
| tree | 082c0c947c338b718d743743b9304b3e965d1173 /mrbgems/mruby-compiler/core/codegen.c | |
| parent | 7d0612528e564ac07bb0435004fe04c46af295a2 (diff) | |
| download | mruby-21a3ae08f7dc252e4cf6d34e5ebead0124fb0117.tar.gz mruby-21a3ae08f7dc252e4cf6d34e5ebead0124fb0117.zip | |
add safe-navigation (aka lonely) operator `&.`
Diffstat (limited to 'mrbgems/mruby-compiler/core/codegen.c')
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 059e5ee8d..ced2d5a28 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -826,13 +826,23 @@ gen_values(codegen_scope *s, node *t, int val) #define CALL_MAXARGS 127 static void -gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val) +gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) { mrb_sym sym = name ? name : sym(tree->cdr->car); - int idx; + int idx, skip; int n = 0, noop = 0, sendv = 0, blk = 0; codegen(s, tree->car, VAL); /* receiver */ + if (safe) { + int recv = cursp()-1; + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + genop(s, MKOP_AB(OP_MOVE, cursp(), recv)); + pop(); + idx = new_msym(s, mrb_intern_lit(s->mrb, "==")); + genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1)); + skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0)); + } idx = new_msym(s, sym); tree = tree->cdr->cdr->car; if (tree) { @@ -905,6 +915,9 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val) } } } + if (safe) { + dispatch(s, skip); + } if (val) { push(); } @@ -968,7 +981,7 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) case NODE_CALL: push(); - gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL); + gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL, 0); pop(); if (val) { genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val); @@ -1511,7 +1524,10 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_FCALL: case NODE_CALL: - gen_call(s, tree, 0, 0, val); + gen_call(s, tree, 0, 0, val, 0); + break; + case NODE_SCALL: + gen_call(s, tree, 0, 0, val, 1); break; case NODE_DOT2: |
