mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #5246 from SeekingMeaning/squiggly-heredocs
Add support for squiggly heredocs
This commit is contained in:
@@ -45,3 +45,4 @@ of this list.
|
||||
RIZAL Reckordp
|
||||
Rory O'Connell
|
||||
John Bampton
|
||||
Seeker
|
||||
|
||||
@@ -99,6 +99,7 @@ enum mrb_string_type {
|
||||
/* heredoc structure */
|
||||
struct mrb_parser_heredoc_info {
|
||||
mrb_bool allow_indent:1;
|
||||
mrb_bool remove_indent:1;
|
||||
mrb_bool line_head:1;
|
||||
enum mrb_string_type type;
|
||||
const char *term;
|
||||
|
||||
@@ -1351,6 +1351,55 @@ heredoc_treat_nextline(parser_state *p)
|
||||
static void
|
||||
heredoc_end(parser_state *p)
|
||||
{
|
||||
parser_heredoc_info *info = parsing_heredoc_inf(p);
|
||||
if (info->remove_indent) {
|
||||
mrb_bool counting = TRUE;
|
||||
size_t indent = -1;
|
||||
node *list = info->doc;
|
||||
node *list2 = NULL;
|
||||
while (list) {
|
||||
if (((enum node_type)(intptr_t)list->car->car) == NODE_STR) {
|
||||
node *pair = list->car->cdr;
|
||||
const char *str = (char*)pair->car;
|
||||
size_t len = (size_t)pair->cdr;
|
||||
if (counting) {
|
||||
list2 = push(list2, pair);
|
||||
}
|
||||
size_t spaces = 0;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (counting) {
|
||||
if (ISSPACE(str[i])) {
|
||||
++spaces;
|
||||
}
|
||||
else {
|
||||
counting = FALSE;
|
||||
if (indent == -1 || spaces < indent) {
|
||||
indent = spaces;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str[i] == '\n') {
|
||||
counting = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
counting = FALSE;
|
||||
}
|
||||
list = list->cdr;
|
||||
}
|
||||
if (indent > 0) {
|
||||
while (list2) {
|
||||
node *pair = list2->car;
|
||||
const char *str = (char*)pair->car;
|
||||
size_t len = (size_t)pair->cdr;
|
||||
pair->car = (node*)(str + indent);
|
||||
pair->cdr = (node*)(len - indent);
|
||||
list2 = list2->cdr;
|
||||
}
|
||||
}
|
||||
}
|
||||
p->parsing_heredoc = p->parsing_heredoc->cdr;
|
||||
if (p->parsing_heredoc == NULL) {
|
||||
p->lstate = EXPR_BEG;
|
||||
@@ -1499,7 +1548,7 @@ heredoc_end(parser_state *p)
|
||||
%token tANDDOT /* &. */
|
||||
%token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
|
||||
%token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
|
||||
%token <nd> tHEREDOC_BEG /* <<, <<- */
|
||||
%token <nd> tHEREDOC_BEG /* <<, <<-, <<~ */
|
||||
%token tHEREDOC_END tLITERAL_DELIM tHD_LITERAL_DELIM
|
||||
%token <nd> tHD_STRING_PART tHD_STRING_MID
|
||||
|
||||
@@ -4906,6 +4955,7 @@ heredoc_identifier(parser_state *p)
|
||||
int c;
|
||||
int type = str_heredoc;
|
||||
mrb_bool indent = FALSE;
|
||||
mrb_bool squiggly = FALSE;
|
||||
mrb_bool quote = FALSE;
|
||||
node *newnode;
|
||||
parser_heredoc_info *info;
|
||||
@@ -4915,8 +4965,11 @@ heredoc_identifier(parser_state *p)
|
||||
pushback(p, c);
|
||||
return 0;
|
||||
}
|
||||
if (c == '-') {
|
||||
indent = TRUE;
|
||||
if (c == '-' || c == '~') {
|
||||
if (c == '-')
|
||||
indent = TRUE;
|
||||
if (c == '~')
|
||||
squiggly = TRUE;
|
||||
c = nextc(p);
|
||||
}
|
||||
if (c == '\'' || c == '"') {
|
||||
@@ -4943,6 +4996,7 @@ heredoc_identifier(parser_state *p)
|
||||
if (! identchar(c)) {
|
||||
pushback(p, c);
|
||||
if (indent) pushback(p, '-');
|
||||
if (squiggly) pushback(p, '~');
|
||||
return 0;
|
||||
}
|
||||
newtok(p);
|
||||
@@ -4959,7 +5013,8 @@ heredoc_identifier(parser_state *p)
|
||||
if (! quote)
|
||||
type |= STR_FUNC_EXPAND;
|
||||
info->type = (string_type)type;
|
||||
info->allow_indent = indent;
|
||||
info->allow_indent = indent || squiggly;
|
||||
info->remove_indent = squiggly;
|
||||
info->line_head = TRUE;
|
||||
info->doc = NULL;
|
||||
p->heredocs_from_nextline = push(p->heredocs_from_nextline, newnode);
|
||||
|
||||
+2494
-2055
File diff suppressed because it is too large
Load Diff
@@ -162,6 +162,26 @@ qq
|
||||
QQ2
|
||||
"o")
|
||||
|
||||
r = <<~RRR
|
||||
rrr
|
||||
rrr
|
||||
RRR
|
||||
s = <<~"SSS"
|
||||
sss
|
||||
sss
|
||||
SSS
|
||||
t = <<~'TTT'
|
||||
ttt
|
||||
ttt
|
||||
TTT
|
||||
u = [<<~UUU1 , <<~"UUU2" , <<~'UUU3' ]
|
||||
u#{1}u
|
||||
UUU1
|
||||
u#{2}u
|
||||
UUU2
|
||||
u#{3}u
|
||||
UUU3
|
||||
|
||||
w = %W( 1 #{<<WWW} 3
|
||||
www
|
||||
WWW
|
||||
@@ -197,6 +217,10 @@ ZZZ
|
||||
assert_equal [1, "nn1\n", 3, 4], n
|
||||
assert_equal "a $ q\n $ c $ d", q1
|
||||
assert_equal "l $ mqq\nn $ o", q2
|
||||
assert_equal "rrr\n rrr\n", r
|
||||
assert_equal "sss\n sss\n", s
|
||||
assert_equal "ttt\n ttt\n", t
|
||||
assert_equal ["u1u\n", "u2u\n", "u\#{3}u\n"], u
|
||||
assert_equal ["1", "www\n", "3", "4", "5"], w
|
||||
assert_equal [1, "foo 222 333\n 444\n5\n bar\n6\n", 9], x
|
||||
assert_equal "", z
|
||||
|
||||
Reference in New Issue
Block a user