mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Backtick operation
This commit is contained in:
@@ -65,6 +65,7 @@ struct mrb_parser_message {
|
||||
#define STR_FUNC_SYMBOL 0x10
|
||||
#define STR_FUNC_ARRAY 0x20
|
||||
#define STR_FUNC_HEREDOC 0x40
|
||||
#define STR_FUNC_XQUOTE 0x80
|
||||
|
||||
enum mrb_string_type {
|
||||
str_not_parsing = (0),
|
||||
@@ -77,6 +78,7 @@ enum mrb_string_type {
|
||||
str_ssymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY),
|
||||
str_dsymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY|STR_FUNC_EXPAND),
|
||||
str_heredoc = (STR_FUNC_PARSING|STR_FUNC_HEREDOC),
|
||||
str_xquote = (STR_FUNC_PARSING|STR_FUNC_XQUOTE|STR_FUNC_EXPAND),
|
||||
};
|
||||
|
||||
/* heredoc structure */
|
||||
|
||||
@@ -2031,6 +2031,26 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
gen_literal_array(s, tree, TRUE, val);
|
||||
break;
|
||||
|
||||
case NODE_XSTR:
|
||||
if (val) {
|
||||
char *p = (char*)tree->car;
|
||||
size_t len = (intptr_t)tree->cdr;
|
||||
int ai = mrb_gc_arena_save(s->mrb);
|
||||
int sym = new_sym(s, mrb_intern(s->mrb, "Kernel"));
|
||||
int off = new_lit(s, mrb_str_new(s->mrb, p, len));
|
||||
|
||||
genop(s, MKOP_A(OP_OCLASS, cursp()));
|
||||
genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
|
||||
push();
|
||||
genop(s, MKOP_ABx(OP_STRING, cursp(), off));
|
||||
pop();
|
||||
sym = new_sym(s, mrb_intern(s->mrb, "__backtick__"));
|
||||
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
|
||||
mrb_gc_arena_restore(s->mrb, ai);
|
||||
push();
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_REGX:
|
||||
if (val) {
|
||||
char *p1 = (char*)tree->car;
|
||||
|
||||
@@ -65,6 +65,8 @@ enum node_type {
|
||||
NODE_SYM,
|
||||
NODE_STR,
|
||||
NODE_DSTR,
|
||||
NODE_XSTR,
|
||||
NODE_DXSTR,
|
||||
NODE_REGX,
|
||||
NODE_DREGX,
|
||||
NODE_DREGX_ONCE,
|
||||
|
||||
+52
-3
@@ -702,6 +702,20 @@ new_dstr(parser_state *p, node *a)
|
||||
return cons((node*)NODE_DSTR, a);
|
||||
}
|
||||
|
||||
// (:str . (s . len))
|
||||
static node*
|
||||
new_xstr(parser_state *p, const char *s, int len)
|
||||
{
|
||||
return cons((node*)NODE_XSTR, cons((node*)strndup(s, len), (node*)(intptr_t)len));
|
||||
}
|
||||
|
||||
// (:xstr . a)
|
||||
static node*
|
||||
new_dxstr(parser_state *p, node *a)
|
||||
{
|
||||
return cons((node*)NODE_DXSTR, a);
|
||||
}
|
||||
|
||||
// (:dsym . a)
|
||||
static node*
|
||||
new_dsym(parser_state *p, node *a)
|
||||
@@ -974,12 +988,12 @@ heredoc_end(parser_state *p)
|
||||
keyword__ENCODING__
|
||||
|
||||
%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
|
||||
%token <nd> tINTEGER tFLOAT tCHAR tREGEXP
|
||||
%token <nd> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
|
||||
%token <nd> tSTRING tSTRING_PART tSTRING_MID
|
||||
%token <nd> tNTH_REF tBACK_REF
|
||||
%token <num> tREGEXP_END
|
||||
|
||||
%type <nd> singleton string string_rep string_interp regexp
|
||||
%type <nd> singleton string string_rep string_interp xstring regexp
|
||||
%type <nd> literal numeric cpath symbol
|
||||
%type <nd> top_compstmt top_stmts top_stmt
|
||||
%type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
|
||||
@@ -1028,7 +1042,7 @@ heredoc_end(parser_state *p)
|
||||
%token tAMPER /* & */
|
||||
%token tLAMBDA /* -> */
|
||||
%token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
|
||||
%token tSTRING_BEG tSTRING_DVAR tLAMBEG
|
||||
%token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
|
||||
%token <nd> tHEREDOC_BEG /* <<, <<- */
|
||||
%token tHEREDOC_END tLITERAL_DELIM
|
||||
|
||||
@@ -1936,6 +1950,7 @@ mrhs : args ',' arg_value
|
||||
|
||||
primary : literal
|
||||
| string
|
||||
| xstring
|
||||
| regexp
|
||||
| heredoc
|
||||
| var_ref
|
||||
@@ -2585,6 +2600,16 @@ string_interp : tSTRING_MID
|
||||
}
|
||||
;
|
||||
|
||||
xstring : tXSTRING_BEG tXSTRING
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| tXSTRING_BEG string_rep tXSTRING
|
||||
{
|
||||
$$ = new_dxstr(p, push($2, $3));
|
||||
}
|
||||
;
|
||||
|
||||
regexp : tREGEXP_BEG tREGEXP
|
||||
{
|
||||
$$ = $2;
|
||||
@@ -2985,6 +3010,8 @@ singleton : var_ref
|
||||
switch ((enum node_type)(int)(intptr_t)$3->car) {
|
||||
case NODE_STR:
|
||||
case NODE_DSTR:
|
||||
case NODE_XSTR:
|
||||
case NODE_DXSTR:
|
||||
case NODE_DREGX:
|
||||
case NODE_MATCH:
|
||||
case NODE_FLOAT:
|
||||
@@ -3648,6 +3675,11 @@ parse_string(parser_state *p)
|
||||
p->lstate = EXPR_END;
|
||||
end_strterm(p);
|
||||
|
||||
if (type & STR_FUNC_XQUOTE) {
|
||||
yylval.nd = new_xstr(p, tok(p), toklen(p));
|
||||
return tXSTRING;
|
||||
}
|
||||
|
||||
if (type & STR_FUNC_REGEXP) {
|
||||
int f = 0;
|
||||
int c;
|
||||
@@ -3995,6 +4027,10 @@ parser_yylex(parser_state *p)
|
||||
p->lex_strterm = new_strterm(p, str_squote, '\'', 0);
|
||||
return parse_string(p);
|
||||
|
||||
case '`':
|
||||
p->lex_strterm = new_strterm(p, str_xquote, '`', 0);
|
||||
return tXSTRING_BEG;
|
||||
|
||||
case '?':
|
||||
if (IS_END()) {
|
||||
p->lstate = EXPR_VALUE;
|
||||
@@ -4635,6 +4671,10 @@ parser_yylex(parser_state *p)
|
||||
p->lex_strterm = new_strterm(p, str_sword, term, paren);
|
||||
return tWORDS_BEG;
|
||||
|
||||
case 'x':
|
||||
p->lex_strterm = new_strterm(p, str_xquote, term, paren);
|
||||
return tXSTRING_BEG;
|
||||
|
||||
case 'r':
|
||||
p->lex_strterm = new_strterm(p, str_regexp, term, paren);
|
||||
return tREGEXP_BEG;
|
||||
@@ -5700,6 +5740,15 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
|
||||
dump_recur(mrb, tree, offset+1);
|
||||
break;
|
||||
|
||||
case NODE_XSTR:
|
||||
printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);
|
||||
break;
|
||||
|
||||
case NODE_DXSTR:
|
||||
printf("NODE_DXSTR\n");
|
||||
dump_recur(mrb, tree, offset+1);
|
||||
break;
|
||||
|
||||
case NODE_REGX:
|
||||
printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user