Merge pull request #1025 from FUKUZAWA-Tadashi/master

implement %W %w %s
This commit is contained in:
Yukihiro "Matz" Matsumoto
2013-03-18 06:56:26 -07:00
8 changed files with 974 additions and 876 deletions
+1
View File
@@ -10,3 +10,4 @@ Original Authors "mruby developers" are:
Masamitsu MURASE
Masaki Muranaka
Internet Initiative Japan Inc.
Tadashi FUKUZAWA
-1
View File
@@ -1,6 +1,5 @@
Things to do (Things that are not done yet)
* Here document
* Special variables ($1,$2..)
* super in aliased methods
* BEGIN/END (Were we not supporting this?)
+20 -7
View File
@@ -58,16 +58,30 @@ struct mrb_parser_message {
char* message;
};
/* heredoc parse type */
enum heredoc_type {
heredoc_type_norm, /* <<EOH */
heredoc_type_quote, /* <<'EOH' */
#define STR_FUNC_PARSING 0x01
#define STR_FUNC_EXPAND 0x02
#define STR_FUNC_REGEXP 0x04
#define STR_FUNC_WORD 0x08
#define STR_FUNC_SYMBOL 0x10
#define STR_FUNC_ARRAY 0x20
#define STR_FUNC_HEREDOC 0x40
enum mrb_string_type {
str_not_parsing = (0),
str_squote = (STR_FUNC_PARSING),
str_dquote = (STR_FUNC_PARSING|STR_FUNC_EXPAND),
str_regexp = (STR_FUNC_PARSING|STR_FUNC_REGEXP|STR_FUNC_EXPAND),
str_sword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY),
str_dword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY|STR_FUNC_EXPAND),
str_ssym = (STR_FUNC_PARSING|STR_FUNC_SYMBOL),
str_heredoc = (STR_FUNC_PARSING|STR_FUNC_HEREDOC),
};
/* heredoc structure */
struct mrb_parser_heredoc_info {
enum heredoc_type type;
mrb_bool allow_indent:1;
mrb_bool line_head:1;
enum mrb_string_type type;
const char *term;
int term_len;
mrb_ast_node *doc;
@@ -85,8 +99,7 @@ struct mrb_parser_state {
int column;
enum mrb_lex_state_enum lstate;
int sterm; /* string terminator : ' ' means heredoc */
int regexp;
mrb_ast_node *lex_strterm; /* (type nest_level beg . end) */
unsigned int cond_stack;
unsigned int cmdarg_stack;
+67 -5
View File
@@ -955,6 +955,68 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
}
}
static void
gen_send_intern(codegen_scope *s)
{
pop();
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "intern")), 0));
push();
}
static void
gen_literal_array(codegen_scope *s, node *tree, int sym, int val)
{
if (val) {
int i = 0, j = 0;
while (tree) {
switch ((intptr_t)tree->car->car) {
case NODE_STR:
if ((tree->cdr == NULL) && ((intptr_t)tree->car->cdr->cdr == 0))
break;
/* fall through */
case NODE_BEGIN:
codegen(s, tree->car, VAL);
++j;
break;
case NODE_LITERAL_DELIM:
if (j > 0) {
j = 0;
++i;
if (sym)
gen_send_intern(s);
}
break;
}
if (j >= 2) {
pop(); pop();
genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
push();
j = 1;
}
tree = tree->cdr;
}
if (j > 0) {
j = 0;
++i;
if (sym)
gen_send_intern(s);
}
pop_n(i);
genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));
push();
}
else {
while (tree) {
switch ((intptr_t)tree->car->car) {
case NODE_BEGIN: case NODE_BLOCK:
codegen(s, tree->car, NOVAL);
}
tree = tree->cdr;
}
}
}
static void
raise_error(codegen_scope *s, const char *msg)
{
@@ -1933,9 +1995,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_HEREDOC:
/*if(tree == NULL){printf("heredoc error 1\n");exit(11);}*/
tree = ((struct mrb_parser_heredoc_info *)tree)->doc;
/*if(tree == NULL){printf("heredoc error 2\n");exit(12);}*/
/* fall through */
case NODE_DSTR:
if (val) {
@@ -1963,6 +2023,10 @@ codegen(codegen_scope *s, node *tree, int val)
}
break;
case NODE_WORDS:
gen_literal_array(s, tree, FALSE, val);
break;
case NODE_REGX:
if (val) {
char *p1 = (char*)tree->car;
@@ -2061,9 +2125,7 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_DSYM:
codegen(s, tree, val);
if (val) {
pop();
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "intern")), 0));
push();
gen_send_intern(s);
}
break;
+2
View File
@@ -106,6 +106,8 @@ enum node_type {
NODE_DSYM,
NODE_ATTRASGN,
NODE_HEREDOC,
NODE_LITERAL_DELIM,
NODE_WORDS,
NODE_LAST
};
+798 -860
View File
File diff suppressed because it is too large Load Diff
+85 -2
View File
@@ -128,8 +128,91 @@ ZZZ
z == ""
end
# Not Implemented ATM assert('Literals Array', '8.7.6.4') do
assert('Literals Array', '8.7.6.4') do
a = %W{abc#{1+2}def \}g}
b = %W(abc #{2+3} def \(g)
c = %W[#{3+4}]
d = %W< #{4+5} >
e = %W//
f = %W[[ab cd][ef]]
g = %W{
ab
#{-1}1
2#{2}
}
h = %W(a\nb
test\ abc
c\
d
x\y x\\y x\\\y)
test1 = (a == ['abc3def', '}g'] and
b == ['abc', '5', 'def', '(g'] and
c == ['7'] and
d == ['9'] and
e == [] and
f == ['[ab', 'cd][ef]'] and
g == ['ab', '-11', '22'] and
h == ["a\nb", 'test abc', "c\nd", "xy", "x\\y", "x\\y"]
)
a = %w{abc#{1+2}def \}g}
b = %w(abc #{2+3} def \(g)
c = %w[#{3+4}]
d = %w< #{4+5} >
e = %w//
f = %w[[ab cd][ef]]
g = %w{
ab
#{-1}1
2#{2}
}
h = %w(a\nb
test\ abc
c\
d
x\y x\\y x\\\y)
test2 = (a == ['abc#{1+2}def', '}g'] and
b == ['abc', '#{2+3}', 'def', '(g'] and
c == ['#{3+4}'] and
d == ['#{4+5}'] and
e == [] and
f == ['[ab', 'cd][ef]'] and
g == ['ab', '#{-1}1', '2#{2}'] and
h == ["a\\nb", "test abc", "c\nd", "x\\y", "x\\y", "x\\\\y"]
)
test1 and test2
end
assert('Literals Symbol', '8.7.6.6') do
/* do not compile error */
:$asd
:@asd
:@@asd
:asd=
:asd!
:asd?
:+
:+@
:if
:BEGIN
a = :"asd qwe"
b = :'foo bar'
c = :"a#{1+2}b"
d = %s(asd)
e = %s( foo \))
f = %s[asd \[
qwe]
g = %s/foo#{1+2}bar/
h = %s{{foo bar}}
a == :'asd qwe' and b == :"foo bar" and c == :a3b and d == :asd and
e == :' foo )' and f == :"asd [\nqwe" and g == :'foo#{1+2}bar' and
h == :'{foo bar}'
end
# Not Implemented ATM assert('Literals Regular expression', '8.7.6.5') do
# Not Implemented ATM assert('Literals Symbol', '8.7.6.6') do
+1 -1
View File
@@ -39,7 +39,7 @@ is_code_block_open(struct mrb_parser_state *parser)
int code_block_open = FALSE;
/* check for unterminated string */
if (parser->sterm) return TRUE;
if (parser->lex_strterm) return TRUE;
/* check for heredoc */
if (parser->heredoc_starts_nextline) return TRUE;