From 54bfcaf1ff40570850c40c4af2511bf2443a868d Mon Sep 17 00:00:00 2001 From: Seeker Date: Sat, 26 Dec 2020 23:48:20 -0800 Subject: Add support for squiggly heredocs --- mrbgems/mruby-compiler/core/parse.y | 63 ++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) (limited to 'mrbgems/mruby-compiler/core/parse.y') diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index e4a3b9f28..77279b8a8 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -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 (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 tHEREDOC_BEG /* <<, <<- */ +%token tHEREDOC_BEG /* <<, <<-, <<~ */ %token tHEREDOC_END tLITERAL_DELIM tHD_LITERAL_DELIM %token 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); -- cgit v1.2.3 From 6312a50045f95e4730e24506da34b49b67d52a86 Mon Sep 17 00:00:00 2001 From: Seeker Date: Sun, 27 Dec 2020 00:20:02 -0800 Subject: Fix operand types error --- mrbgems/mruby-compiler/core/parse.y | 14 +++++++------- mrbgems/mruby-compiler/core/y.tab.c | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'mrbgems/mruby-compiler/core/parse.y') diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 77279b8a8..9615ea7ca 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -1358,10 +1358,10 @@ heredoc_end(parser_state *p) node *list = info->doc; node *list2 = NULL; while (list) { - if (list->car->car == NODE_STR) { + 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; + const char *str = (char*)pair->car; + size_t len = (size_t)pair->cdr; if (counting) { list2 = push(list2, pair); } @@ -1392,10 +1392,10 @@ heredoc_end(parser_state *p) 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); + 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; } } diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c index 8189d5de2..dafff6ed2 100644 --- a/mrbgems/mruby-compiler/core/y.tab.c +++ b/mrbgems/mruby-compiler/core/y.tab.c @@ -1422,10 +1422,10 @@ heredoc_end(parser_state *p) node *list = info->doc; node *list2 = NULL; while (list) { - if (list->car->car == NODE_STR) { + 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; + const char *str = (char*)pair->car; + size_t len = (size_t)pair->cdr; if (counting) { list2 = push(list2, pair); } @@ -1456,10 +1456,10 @@ heredoc_end(parser_state *p) 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); + 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; } } -- cgit v1.2.3