summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler
diff options
context:
space:
mode:
authorHiroshi Mimaki <[email protected]>2019-10-18 14:46:03 +0900
committerHiroshi Mimaki <[email protected]>2019-10-18 14:46:03 +0900
commitb6546835457d1935a9c77965686b2a1256874d96 (patch)
tree724cfd71a7c956b0648e8c58f3717d797fff5f29 /mrbgems/mruby-compiler
parent8ee516436b8d174a50764939bee23a442aa00b3f (diff)
parent20d01f118ddb7e7f2f36926a7a3db35573611857 (diff)
downloadmruby-b6546835457d1935a9c77965686b2a1256874d96.tar.gz
mruby-b6546835457d1935a9c77965686b2a1256874d96.zip
Merge master.
Diffstat (limited to 'mrbgems/mruby-compiler')
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c115
-rw-r--r--mrbgems/mruby-compiler/core/keywords3
-rw-r--r--mrbgems/mruby-compiler/core/lex.def110
-rw-r--r--mrbgems/mruby-compiler/core/parse.y552
4 files changed, 517 insertions, 263 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index 927cc3a0f..8379dfd97 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -102,12 +102,13 @@ codegen_error(codegen_scope *s, const char *message)
while (s->prev) {
codegen_scope *tmp = s->prev;
mrb_free(s->mrb, s->iseq);
+ mrb_free(s->mrb, s->lines);
mrb_pool_close(s->mpool);
s = tmp;
}
#ifndef MRB_DISABLE_STDIO
if (s->filename_sym && s->lineno) {
- const char *filename = mrb_sym2name_len(s->mrb, s->filename_sym, NULL);
+ const char *filename = mrb_sym_name_len(s->mrb, s->filename_sym, NULL);
fprintf(stderr, "codegen error:%s:%d: %s\n", filename, s->lineno, message);
}
else {
@@ -272,8 +273,7 @@ genop_W(codegen_scope *s, mrb_code i, uint32_t a)
#define NOVAL 0
#define VAL 1
-//static
-mrb_bool
+static mrb_bool
no_optimize(codegen_scope *s)
{
if (s && s->parser && s->parser->no_optimize)
@@ -291,7 +291,7 @@ on_eval(codegen_scope *s)
}
struct mrb_insn_data
-mrb_decode_insn(mrb_code *pc)
+mrb_decode_insn(const mrb_code *pc)
{
struct mrb_insn_data data = { 0 };
mrb_code insn = READ_B();
@@ -559,7 +559,7 @@ new_lit(codegen_scope *s, mrb_value val)
mrb_int len;
pv = &s->irep->pool[i];
- if (mrb_type(*pv) != MRB_TT_STRING) continue;
+ if (!mrb_string_p(*pv)) continue;
if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue;
if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0)
return i;
@@ -570,7 +570,7 @@ new_lit(codegen_scope *s, mrb_value val)
for (i=0; i<s->irep->plen; i++) {
mrb_float f1, f2;
pv = &s->irep->pool[i];
- if (mrb_type(*pv) != MRB_TT_FLOAT) continue;
+ if (!mrb_float_p(*pv)) continue;
f1 = mrb_float(*pv);
f2 = mrb_float(val);
if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i;
@@ -686,9 +686,6 @@ for_body(codegen_scope *s, node *tree)
codegen(s, tree->cdr->car, VAL);
/* generate loop-block */
s = scope_new(s->mrb, s, NULL);
- if (s == NULL) {
- raise_error(prev, "unexpected scope");
- }
push(); /* push for a block parameter */
@@ -724,9 +721,6 @@ lambda_body(codegen_scope *s, node *tree, int blk)
{
codegen_scope *parent = s;
s = scope_new(s->mrb, s, tree->car);
- if (s == NULL) {
- raise_error(parent, "unexpected scope");
- }
s->mscope = !blk;
@@ -888,9 +882,6 @@ static int
scope_body(codegen_scope *s, node *tree, int val)
{
codegen_scope *scope = scope_new(s->mrb, s, tree->car);
- if (scope == NULL) {
- codegen_error(s, "unexpected scope");
- }
codegen(scope, tree->cdr, VAL);
gen_return(scope, OP_RETURN, scope->sp-1);
@@ -922,7 +913,7 @@ attrsym(codegen_scope *s, mrb_sym a)
mrb_int len;
char *name2;
- name = mrb_sym2name_len(s->mrb, a, &len);
+ name = mrb_sym_name_len(s->mrb, a, &len);
name2 = (char *)codegen_palloc(s,
(size_t)len
+ 1 /* '=' */
@@ -956,7 +947,12 @@ gen_values(codegen_scope *s, node *t, int val, int extra)
}
else {
pop_n(n);
- genop_2(s, OP_ARRAY, cursp(), n);
+ if (n == 0 && is_splat) {
+ genop_1(s, OP_LOADNIL, cursp());
+ }
+ else {
+ genop_2(s, OP_ARRAY, cursp(), n);
+ }
push();
codegen(s, t->car, VAL);
pop(); pop();
@@ -1041,7 +1037,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
pop_n(n+1);
{
mrb_int symlen;
- const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen);
+ const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen);
if (!noop && symlen == 1 && symname[0] == '+' && n == 1) {
gen_addsub(s, OP_ADD, cursp());
@@ -1401,7 +1397,7 @@ codegen(codegen_scope *s, node *tree, int val)
}
if (s->irep && s->filename_index != tree->filename_index) {
mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
- const char *filename = mrb_sym2name_len(s->mrb, fname, NULL);
+ const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
filename, s->lines, s->debug_start_pos, s->pc);
@@ -1553,7 +1549,7 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_IF:
{
- int pos1, pos2;
+ int pos1, pos2, nil_p = FALSE;
node *elsepart = tree->cdr->cdr->car;
if (!tree->car) {
@@ -1570,32 +1566,59 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_NIL:
codegen(s, elsepart, val);
goto exit;
+ case NODE_CALL:
+ {
+ node *n = tree->car->cdr;
+ mrb_sym mid = nsym(n->cdr->car);
+ mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?");
+ if (mid == mnil && n->cdr->cdr->car == NULL) {
+ nil_p = TRUE;
+ codegen(s, n->car, VAL);
+ }
+ }
+ break;
+ }
+ if (!nil_p) {
+ codegen(s, tree->car, VAL);
}
- codegen(s, tree->car, VAL);
pop();
- pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
-
- codegen(s, tree->cdr->car, val);
- if (elsepart) {
+ if (val || tree->cdr->car) {
+ if (nil_p) {
+ pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
+ pos1 = genjmp(s, OP_JMP, 0);
+ dispatch(s, pos2);
+ }
+ else {
+ pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
+ }
+ codegen(s, tree->cdr->car, val);
if (val) pop();
- pos2 = genjmp(s, OP_JMP, 0);
- dispatch(s, pos1);
- codegen(s, elsepart, val);
- dispatch(s, pos2);
- }
- else {
- if (val) {
- pop();
+ if (elsepart || val) {
pos2 = genjmp(s, OP_JMP, 0);
dispatch(s, pos1);
- genop_1(s, OP_LOADNIL, cursp());
+ codegen(s, elsepart, val);
dispatch(s, pos2);
- push();
}
else {
dispatch(s, pos1);
}
}
+ else { /* empty then-part */
+ if (elsepart) {
+ if (nil_p) {
+ pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
+ }
+ else {
+ pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val);
+ }
+ codegen(s, elsepart, val);
+ dispatch(s, pos1);
+ }
+ else if (val && !nil_p) {
+ genop_1(s, OP_LOADNIL, cursp());
+ push();
+ }
+ }
}
break;
@@ -1955,7 +1978,7 @@ codegen(codegen_scope *s, node *tree, int val)
{
mrb_sym sym = nsym(tree->cdr->car);
mrb_int len;
- const char *name = mrb_sym2name_len(s->mrb, sym, &len);
+ const char *name = mrb_sym_name_len(s->mrb, sym, &len);
int idx, callargs = -1, vsp = -1;
if ((len == 2 && name[0] == '|' && name[1] == '|') &&
@@ -2353,10 +2376,6 @@ codegen(codegen_scope *s, node *tree, int val)
}
break;
- case NODE_DEFINED:
- codegen(s, tree, val);
- break;
-
case NODE_BACK_REF:
if (val) {
char buf[] = {'$', nchar(tree)};
@@ -2373,7 +2392,7 @@ codegen(codegen_scope *s, node *tree, int val)
mrb_value str;
int sym;
- str = mrb_format(mrb, "$%S", mrb_fixnum_value(nint(tree)));
+ str = mrb_format(mrb, "$%d", nint(tree));
sym = new_sym(s, mrb_intern_str(mrb, str));
genop_2(s, OP_GETGV, cursp(), sym);
push();
@@ -2944,7 +2963,11 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
mrb_pool *pool = mrb_pool_open(mrb);
codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
- if (!p) return NULL;
+ if (!p) {
+ if (prev)
+ codegen_error(prev, "unexpected scope");
+ return NULL;
+ }
*p = codegen_scope_zero;
p->mrb = mrb;
p->mpool = pool;
@@ -3020,6 +3043,9 @@ scope_finish(codegen_scope *s)
mrb_state *mrb = s->mrb;
mrb_irep *irep = s->irep;
+ if (s->nlocals >= 0x3ff) {
+ codegen_error(s, "too many local variables");
+ }
irep->flags = 0;
if (s->iseq) {
irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
@@ -3030,7 +3056,7 @@ scope_finish(codegen_scope *s)
irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
if (s->filename_sym) {
mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
- const char *filename = mrb_sym2name_len(s->mrb, fname, NULL);
+ const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
filename, s->lines, s->debug_start_pos, s->pc);
@@ -3134,9 +3160,6 @@ generate_code(mrb_state *mrb, parser_state *p, int val)
struct RProc *proc;
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
- if (!scope) {
- return NULL;
- }
scope->mrb = mrb;
scope->parser = p;
scope->filename_sym = p->filename_sym;
diff --git a/mrbgems/mruby-compiler/core/keywords b/mrbgems/mruby-compiler/core/keywords
index 9cb86608c..a60ecd10a 100644
--- a/mrbgems/mruby-compiler/core/keywords
+++ b/mrbgems/mruby-compiler/core/keywords
@@ -1,8 +1,5 @@
%{
struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
-const struct kwtable *mrb_reserved_word(const char *, unsigned int);
-static const struct kwtable *reserved_word(const char *, unsigned int);
-#define mrb_reserved_word(str, len) reserved_word(str, len)
%}
struct kwtable;
diff --git a/mrbgems/mruby-compiler/core/lex.def b/mrbgems/mruby-compiler/core/lex.def
index 2ff266481..872bf40c1 100644
--- a/mrbgems/mruby-compiler/core/lex.def
+++ b/mrbgems/mruby-compiler/core/lex.def
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -25,16 +25,13 @@
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <[email protected]>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <[email protected]>."
#endif
#line 1 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
-const struct kwtable *mrb_reserved_word(const char *, unsigned int);
-static const struct kwtable *reserved_word(const char *, unsigned int);
-#define mrb_reserved_word(str, len) reserved_word(str, len)
-#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 5 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
struct kwtable;
#define TOTAL_KEYWORDS 40
@@ -52,7 +49,7 @@ inline
#endif
#endif
static unsigned int
-hash (const char *str, unsigned int len)
+hash (register const char *str, register size_t len)
{
static const unsigned char asso_values[] =
{
@@ -83,7 +80,7 @@ hash (const char *str, unsigned int len)
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51
};
- int hval = len;
+ register unsigned int hval = len;
switch (hval)
{
@@ -98,109 +95,103 @@ hash (const char *str, unsigned int len)
return hval + asso_values[(unsigned char)str[len - 1]];
}
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
const struct kwtable *
-mrb_reserved_word (const char *str, unsigned int len)
+mrb_reserved_word (register const char *str, register size_t len)
{
static const struct kwtable wordlist[] =
{
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"break", {keyword_break, keyword_break}, EXPR_MID},
-#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"else", {keyword_else, keyword_else}, EXPR_BEG},
-#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"nil", {keyword_nil, keyword_nil}, EXPR_END},
-#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
-#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"end", {keyword_end, keyword_end}, EXPR_END},
-#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"then", {keyword_then, keyword_then}, EXPR_BEG},
-#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"not", {keyword_not, keyword_not}, EXPR_ARG},
-#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"false", {keyword_false, keyword_false}, EXPR_END},
-#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"self", {keyword_self, keyword_self}, EXPR_END},
-#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
-#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
-#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"true", {keyword_true, keyword_true}, EXPR_END},
-#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"until", {keyword_until, modifier_until}, EXPR_VALUE},
-#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
-#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"return", {keyword_return, keyword_return}, EXPR_MID},
-#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"def", {keyword_def, keyword_def}, EXPR_FNAME},
-#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"and", {keyword_and, keyword_and}, EXPR_VALUE},
-#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"do", {keyword_do, keyword_do}, EXPR_BEG},
-#line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
-#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"for", {keyword_for, keyword_for}, EXPR_VALUE},
-#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
-#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"or", {keyword_or, keyword_or}, EXPR_VALUE},
-#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"in", {keyword_in, keyword_in}, EXPR_VALUE},
-#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"when", {keyword_when, keyword_when}, EXPR_VALUE},
-#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"retry", {keyword_retry, keyword_retry}, EXPR_END},
-#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"if", {keyword_if, modifier_if}, EXPR_VALUE},
-#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"case", {keyword_case, keyword_case}, EXPR_VALUE},
-#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"redo", {keyword_redo, keyword_redo}, EXPR_END},
-#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"next", {keyword_next, keyword_next}, EXPR_MID},
-#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"super", {keyword_super, keyword_super}, EXPR_ARG},
-#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"module", {keyword_module, keyword_module}, EXPR_VALUE},
-#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
-#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 9 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
-#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
-#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 7 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
-#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"END", {keyword_END, keyword_END}, EXPR_END},
-#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
-#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
{""},
-#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"class", {keyword_class, keyword_class}, EXPR_CLASS},
{""}, {""},
-#line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
{"while", {keyword_while, modifier_while}, EXPR_VALUE}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- int key = hash (str, len);
+ register unsigned int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
- const char *s = wordlist[key].name;
+ register const char *s = wordlist[key].name;
if (*str == *s && !strcmp (str + 1, s + 1))
return &wordlist[key];
@@ -208,4 +199,5 @@ mrb_reserved_word (const char *str, unsigned int len)
}
return 0;
}
-#line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 88d9ea4ee..6afc3f8fe 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -10,13 +10,7 @@
# define YYDEBUG 1
#endif
#define YYERROR_VERBOSE 1
-/*
- * Force yacc to use our memory management. This is a little evil because
- * the macros assume that "parser_state *p" is in scope
- */
-#define YYMALLOC(n) mrb_malloc(p->mrb, (n))
-#define YYFREE(o) mrb_free(p->mrb, (o))
-#define YYSTACK_USE_ALLOCA 0
+#define YYSTACK_USE_ALLOCA 1
#include <ctype.h>
#include <errno.h>
@@ -27,6 +21,7 @@
#include <mruby/proc.h>
#include <mruby/error.h>
#include <mruby/throw.h>
+#include <mruby/string.h>
#include "node.h"
#define YYLEX_PARAM p
@@ -76,6 +71,24 @@ typedef unsigned int stack_type;
#define nint(x) ((node*)(intptr_t)(x))
#define intn(x) ((int)(intptr_t)(x))
+#if defined(MRB_COMPLEX_NUMBERS) || defined(MRB_RATIONAL_NUMBERS)
+ #define MRB_SUFFIX_SUPPORT
+
+ #ifdef MRB_RATIONAL_NUMBERS
+ #define NUM_SUFFIX_R (1<<0)
+ #else
+ #define NUM_SUFFIX_R 0
+ #endif
+
+ #ifdef MRB_COMPLEX_NUMBERS
+ #define NUM_SUFFIX_I (1<<1)
+ #else
+ #define NUM_SUFFIX_I 0
+ #endif
+
+ #define NUM_SUFFIX_ALL (NUM_SUFFIX_R | NUM_SUFFIX_I)
+#endif
+
static inline mrb_sym
intern_cstr_gen(parser_state *p, const char *s)
{
@@ -189,12 +202,11 @@ append_gen(parser_state *p, node *a, node *b)
node *c = a;
if (!a) return b;
+ if (!b) return a;
while (c->cdr) {
c = c->cdr;
}
- if (b) {
- c->cdr = b;
- }
+ c->cdr = b;
return a;
}
#define append(a,b) append_gen(p,(a),(b))
@@ -220,6 +232,26 @@ parser_strdup(parser_state *p, const char *s)
#undef strdup
#define strdup(s) parser_strdup(p, s)
+static void
+dump_int(uint16_t i, char *s)
+{
+ char *p = s;
+ char *t = s;
+
+ while (i > 0) {
+ *p++ = (i % 10)+'0';
+ i /= 10;
+ }
+ if (p == s) *p++ = '0';
+ *p = 0;
+ p--; /* point the last char */
+ while (t < p) {
+ char c = *t;
+ *t++ = *p;
+ *p-- = c;
+ }
+}
+
/* xxx ----------------------------- */
static node*
@@ -715,6 +747,15 @@ local_add_margs(parser_state *p, node *n)
}
}
+static void
+local_add_lv(parser_state *p, node *lv)
+{
+ while (lv) {
+ local_add_f(p, sym(lv->car));
+ lv = lv->cdr;
+ }
+}
+
/* (m o r m2 tail) */
/* m: (a b c) */
/* o: ((a . e1) (b . e2)) */
@@ -731,6 +772,12 @@ new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail
n = cons(m2, tail);
n = cons(nsym(rest), n);
n = cons(opt, n);
+ while (opt) {
+ /* opt: (sym . (opt . lv)) -> (sym . opt) */
+ local_add_lv(p, opt->car->cdr->cdr);
+ opt->car->cdr = opt->car->cdr->car;
+ opt = opt->cdr;
+ }
return cons(m, n);
}
@@ -755,6 +802,8 @@ new_args_tail(parser_state *p, node *kws, node *kwrest, mrb_sym blk)
}
for (k = kws; k; k = k->cdr) {
if (k->car->cdr->cdr->car) { // allocate keywords with default
+ local_add_lv(p, k->car->cdr->cdr->car->cdr);
+ k->car->cdr->cdr->car = k->car->cdr->cdr->car->car;
local_add_f(p, sym(k->car->cdr->car));
}
}
@@ -822,19 +871,57 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
return list4((node*)NODE_OP_ASGN, a, nsym(op), b);
}
+#ifdef MRB_COMPLEX_NUMBERS
+static node*
+new_imaginary(parser_state *p, node *imaginary)
+{
+ return new_call(p, new_const(p, intern_cstr("Kernel")), intern_cstr("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
+}
+#endif
+
+#ifdef MRB_RATIONAL_NUMBERS
+static node*
+new_rational(parser_state *p, node *rational)
+{
+ return new_call(p, new_const(p, intern_cstr("Kernel")), intern_cstr("Rational"), list1(list1(rational)), 1);
+}
+#endif
+
/* (:int . i) */
static node*
-new_int(parser_state *p, const char *s, int base)
+new_int(parser_state *p, const char *s, int base, int suffix)
{
- return list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+ node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+#ifdef MRB_RATIONAL_NUMBERS
+ if (suffix & NUM_SUFFIX_R) {
+ result = new_rational(p, result);
+ }
+#endif
+#ifdef MRB_COMPLEX_NUMBERS
+ if (suffix & NUM_SUFFIX_I) {
+ result = new_imaginary(p, result);
+ }
+#endif
+ return result;
}
#ifndef MRB_WITHOUT_FLOAT
/* (:float . i) */
static node*
-new_float(parser_state *p, const char *s)
+new_float(parser_state *p, const char *s, int suffix)
{
- return cons((node*)NODE_FLOAT, (node*)strdup(s));
+ node* result = cons((node*)NODE_FLOAT, (node*)strdup(s));
+#ifdef MRB_RATIONAL_NUMBERS
+ if (suffix & NUM_SUFFIX_R) {
+ result = new_rational(p, result);
+ }
+#endif
+#ifdef MRB_COMPLEX_NUMBERS
+ if (suffix & NUM_SUFFIX_I) {
+ result = new_imaginary(p, result);
+ }
+#endif
+ return result;
}
#endif
@@ -893,40 +980,39 @@ concat_string(parser_state *p, node *a, node *b)
}
}
}
- else if (string_node_p(b)) {
- /* a == NODE_DSTR && b == NODE_STR */
-
- node *c;
+ else {
+ node *c; /* last node of a */
for (c = a; c->cdr != NULL; c = c->cdr) ;
- if (string_node_p(c->car)) {
- /* a->[..., NODE_STR] && b == NODE_STR */
- composite_string_node(p, c->car->cdr, b->cdr);
- cons_free(b);
- return a;
- }
- push(a, b);
- return a;
- }
- else {
- /* a == NODE_DSTR && b == NODE_DSTR */
+ if (string_node_p(b)) {
+ /* a == NODE_DSTR && b == NODE_STR */
+ if (string_node_p(c->car)) {
+ /* a->[..., NODE_STR] && b == NODE_STR */
+ composite_string_node(p, c->car->cdr, b->cdr);
+ cons_free(b);
+ return a;
+ }
- node *c, *d;
- for (c = a; c->cdr != NULL; c = c->cdr) ;
- if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
- /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
- d = b->cdr;
- cons_free(b);
- composite_string_node(p, c->car->cdr, d->car->cdr);
- cons_free(d->car);
- c->cdr = d->cdr;
- cons_free(d);
+ push(a, b);
return a;
}
else {
- c->cdr = b->cdr;
- cons_free(b);
- return a;
+ /* a == NODE_DSTR && b == NODE_DSTR */
+ if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
+ /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
+ node *d = b->cdr;
+ cons_free(b);
+ composite_string_node(p, c->car->cdr, d->car->cdr);
+ cons_free(d->car);
+ c->cdr = d->cdr;
+ cons_free(d);
+ return a;
+ }
+ else {
+ c->cdr = b->cdr;
+ cons_free(b);
+ return a;
+ }
}
}
@@ -3162,7 +3248,7 @@ var_ref : variable
}
| keyword__FILE__
{
- const char *fn = mrb_sym2name_len(p->mrb, p->filename_sym, NULL);
+ const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
if (!fn) {
fn = "(null)";
}
@@ -3172,8 +3258,8 @@ var_ref : variable
{
char buf[16];
- snprintf(buf, sizeof(buf), "%d", p->lineno);
- $$ = new_int(p, buf, 10);
+ dump_int(p->lineno, buf);
+ $$ = new_int(p, buf, 10, 0);
}
| keyword__ENCODING__
{
@@ -3223,16 +3309,21 @@ f_arglist : '(' f_args rparen
;
f_label : tIDENTIFIER tLABEL_TAG
+ {
+ local_nest(p);
+ }
;
f_kw : f_label arg
{
void_expr_error(p, $2);
- $$ = new_kw_arg(p, $1, $2);
+ $$ = new_kw_arg(p, $1, cons($2, locals_node(p)));
+ local_unnest(p);
}
| f_label
{
$$ = new_kw_arg(p, $1, 0);
+ local_unnest(p);
}
;
@@ -3433,6 +3524,7 @@ f_arg : f_arg_item
f_opt_asgn : tIDENTIFIER '='
{
local_add_f(p, $1);
+ local_nest(p);
$$ = $1;
}
;
@@ -3440,14 +3532,16 @@ f_opt_asgn : tIDENTIFIER '='
f_opt : f_opt_asgn arg
{
void_expr_error(p, $2);
- $$ = cons(nsym($1), $2);
+ $$ = cons(nsym($1), cons($2, locals_node(p)));
+ local_unnest(p);
}
;
f_block_opt : f_opt_asgn primary_value
{
void_expr_error(p, $2);
- $$ = cons(nsym($1), $2);
+ $$ = cons(nsym($1), cons($2, locals_node(p)));
+ local_unnest(p);
}
;
@@ -3672,7 +3766,7 @@ yyerror(parser_state *p, const char *s)
if (! p->capture_errors) {
#ifndef MRB_DISABLE_STDIO
if (p->filename_sym) {
- const char *filename = mrb_sym2name_len(p->mrb, p->filename_sym, NULL);
+ const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
fprintf(stderr, "%s:%d:%d: %s\n", filename, p->lineno, p->column, s);
}
else {
@@ -3692,11 +3786,13 @@ yyerror(parser_state *p, const char *s)
}
static void
-yyerror_i(parser_state *p, const char *fmt, int i)
+yyerror_c(parser_state *p, const char *msg, char c)
{
char buf[256];
- snprintf(buf, sizeof(buf), fmt, i);
+ strncpy(buf, msg, sizeof(buf) - 2);
+ buf[sizeof(buf) - 2] = '\0';
+ strncat(buf, &c, 1);
yyerror(p, buf);
}
@@ -3709,7 +3805,7 @@ yywarn(parser_state *p, const char *s)
if (! p->capture_errors) {
#ifndef MRB_DISABLE_STDIO
if (p->filename_sym) {
- const char *filename = mrb_sym2name_len(p->mrb, p->filename_sym, NULL);
+ const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL);
fprintf(stderr, "%s:%d:%d: warning: %s\n", filename, p->lineno, p->column, s);
}
else {
@@ -3735,11 +3831,14 @@ yywarning(parser_state *p, const char *s)
}
static void
-yywarning_s(parser_state *p, const char *fmt, const char *s)
+yywarning_s(parser_state *p, const char *msg, const char *s)
{
char buf[256];
- snprintf(buf, sizeof(buf), fmt, s);
+ strncpy(buf, msg, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1);
+ strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
yywarning(p, buf);
}
@@ -3751,13 +3850,13 @@ backref_error(parser_state *p, node *n)
c = intn(n->car);
if (c == NODE_NTH_REF) {
- yyerror_i(p, "can't set variable $%" MRB_PRId, intn(n->cdr));
+ yyerror_c(p, "can't set variable $", (char)intn(n->cdr)+'0');
}
else if (c == NODE_BACK_REF) {
- yyerror_i(p, "can't set variable $%c", intn(n->cdr));
+ yyerror_c(p, "can't set variable $", (char)intn(n->cdr));
}
else {
- mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %S", mrb_fixnum_value(c));
+ mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c);
}
}
@@ -4298,8 +4397,17 @@ parse_string(parser_state *p)
}
if (c < 0) {
char buf[256];
- snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term);
- yyerror(p, buf);
+ const char s1[] = "can't find heredoc delimiter \"";
+ const char s2[] = "\" anywhere before EOF";
+
+ if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) {
+ yyerror(p, "can't find heredoc delimiter anywhere before EOF");
+ } else {
+ strcpy(buf, s1);
+ strcat(buf, hinf->term);
+ strcat(buf, s2);
+ yyerror(p, buf);
+ }
return 0;
}
pylval.nd = new_str(p, tok(p), toklen(p));
@@ -4443,15 +4551,21 @@ parse_string(parser_state *p)
case 'm': f |= 4; break;
case 'u': f |= 16; break;
case 'n': f |= 32; break;
+ case 'o': break;
default: tokadd(p, re_opt); break;
}
}
pushback(p, re_opt);
if (toklen(p)) {
char msg[128];
+
+ strcpy(msg, "unknown regexp option");
tokfix(p);
- snprintf(msg, sizeof(msg), "unknown regexp option%s - %s",
- toklen(p) > 1 ? "s" : "", tok(p));
+ if (toklen(p) > 1) {
+ strcat(msg, "s");
+ }
+ strcat(msg, " - ");
+ strncat(msg, tok(p), sizeof(msg) - strlen(msg) - 1);
yyerror(p, msg);
}
if (f != 0) {
@@ -4482,6 +4596,45 @@ parse_string(parser_state *p)
return tSTRING;
}
+#ifdef MRB_SUFFIX_SUPPORT
+static int
+number_literal_suffix(parser_state *p, int mask)
+{
+ int c, result = 0;
+ node *list = 0;
+ int column = p->column;
+
+ while ((c = nextc(p)) != -1) {
+ list = push(list, (node*)(intptr_t)c);
+
+ if ((mask & NUM_SUFFIX_I) && c == 'i') {
+ result |= (mask & NUM_SUFFIX_I);
+ mask &= ~NUM_SUFFIX_I;
+ /* r after i, rational of complex is disallowed */
+ mask &= ~NUM_SUFFIX_R;
+ continue;
+ }
+ if ((mask & NUM_SUFFIX_R) && c == 'r') {
+ result |= (mask & NUM_SUFFIX_R);
+ mask &= ~NUM_SUFFIX_R;
+ continue;
+ }
+ if (!ISASCII(c) || ISALPHA(c) || c == '_') {
+ p->column = column;
+ if (p->pb) {
+ p->pb = append((node*)list, p->pb);
+ }
+ else {
+ p->pb = list;
+ }
+ return 0;
+ }
+ pushback(p, c);
+ break;
+ }
+ return result;
+}
+#endif
static int
heredoc_identifier(parser_state *p)
@@ -4602,52 +4755,66 @@ parser_yylex(parser_state *p)
/* fall through */
case -2: /* end of a file */
case '\n':
- maybe_heredoc:
+ maybe_heredoc:
heredoc_treat_nextline(p);
- switch (p->lstate) {
- case EXPR_BEG:
- case EXPR_FNAME:
- case EXPR_DOT:
- case EXPR_CLASS:
- case EXPR_VALUE:
- p->lineno++;
p->column = 0;
- if (p->parsing_heredoc != NULL) {
- if (p->lex_strterm) {
- return parse_string(p);
+ switch (p->lstate) {
+ case EXPR_BEG:
+ case EXPR_FNAME:
+ case EXPR_DOT:
+ case EXPR_CLASS:
+ case EXPR_VALUE:
+ p->lineno++;
+ if (p->parsing_heredoc != NULL) {
+ if (p->lex_strterm) {
+ return parse_string(p);
+ }
}
- }
- goto retry;
- default:
- break;
- }
- if (p->parsing_heredoc != NULL) {
- return '\n';
- }
- while ((c = nextc(p))) {
- switch (c) {
- case ' ': case '\t': case '\f': case '\r':
- case '\13': /* '\v' */
- space_seen = 1;
+ goto retry;
+ default:
break;
- case '.':
- if ((c = nextc(p)) != '.') {
- pushback(p, c);
- pushback(p, '.');
+ }
+ if (p->parsing_heredoc != NULL) {
+ return '\n';
+ }
+ while ((c = nextc(p))) {
+ switch (c) {
+ case ' ': case '\t': case '\f': case '\r':
+ case '\13': /* '\v' */
+ space_seen = 1;
+ break;
+ case '#': /* comment as a whitespace */
+ pushback(p, '#');
+ p->lineno++;
goto retry;
+ case '.':
+ if (!peek(p, '.')) {
+ pushback(p, '.');
+ p->lineno++;
+ goto retry;
+ }
+ pushback(p, c);
+ goto normal_newline;
+ case '&':
+ if (peek(p, '.')) {
+ pushback(p, '&');
+ p->lineno++;
+ goto retry;
+ }
+ pushback(p, c);
+ goto normal_newline;
+ case -1: /* EOF */
+ case -2: /* end of a file */
+ goto normal_newline;
+ default:
+ pushback(p, c);
+ goto normal_newline;
}
- case -1: /* EOF */
- case -2: /* end of a file */
- goto normal_newline;
- default:
- pushback(p, c);
- goto normal_newline;
}
- }
normal_newline:
- p->cmd_start = TRUE;
- p->lstate = EXPR_BEG;
- return '\n';
+ p->cmd_start = TRUE;
+ p->lstate = EXPR_BEG;
+ return '\n';
case '*':
if ((c = nextc(p)) == '*') {
@@ -4879,7 +5046,10 @@ parser_yylex(parser_state *p)
}
if (c2) {
char buf[256];
- snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
+ char cc[] = { (char)c2, '\0' };
+
+ strcpy(buf, "invalid character syntax; use ?\\");
+ strncat(buf, cc, 2);
yyerror(p, buf);
}
}
@@ -5053,6 +5223,7 @@ parser_yylex(parser_state *p)
case '5': case '6': case '7': case '8': case '9':
{
int is_float, seen_point, seen_e, nondigit;
+ int suffix = 0;
is_float = seen_point = seen_e = nondigit = 0;
p->lstate = EXPR_ENDARG;
@@ -5086,7 +5257,10 @@ parser_yylex(parser_state *p)
no_digits();
}
else if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 16);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 16, suffix);
return tINTEGER;
}
if (c == 'b' || c == 'B') {
@@ -5110,7 +5284,10 @@ parser_yylex(parser_state *p)
no_digits();
}
else if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 2);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 2, suffix);
return tINTEGER;
}
if (c == 'd' || c == 'D') {
@@ -5134,7 +5311,10 @@ parser_yylex(parser_state *p)
no_digits();
}
else if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 10);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 10, suffix);
return tINTEGER;
}
if (c == '_') {
@@ -5167,7 +5347,10 @@ parser_yylex(parser_state *p)
pushback(p, c);
tokfix(p);
if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 8);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 8, suffix);
return tINTEGER;
}
if (nondigit) {
@@ -5184,7 +5367,10 @@ parser_yylex(parser_state *p)
}
else {
pushback(p, c);
- pylval.nd = new_int(p, "0", 10);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, "0", 10, suffix);
return tINTEGER;
}
}
@@ -5252,13 +5438,13 @@ parser_yylex(parser_state *p)
pushback(p, c);
if (nondigit) {
trailing_uc:
- yyerror_i(p, "trailing '%c' in number", nondigit);
+ yyerror_c(p, "trailing non digit in number: ", (char)nondigit);
}
tokfix(p);
if (is_float) {
#ifdef MRB_WITHOUT_FLOAT
- yywarning(p, "floating point numbers are not supported");
- pylval.nd = new_int(p, "0", 10);
+ yywarning_s(p, "floating point numbers are not supported", tok(p));
+ pylval.nd = new_int(p, "0", 10, 0);
return tINTEGER;
#else
double d;
@@ -5267,17 +5453,23 @@ parser_yylex(parser_state *p)
errno = 0;
d = mrb_float_read(tok(p), &endp);
if (d == 0 && endp == tok(p)) {
- yywarning_s(p, "corrupted float value %s", tok(p));
+ yywarning_s(p, "corrupted float value", tok(p));
}
else if (errno == ERANGE) {
- yywarning_s(p, "float %s out of range", tok(p));
+ yywarning_s(p, "float out of range", tok(p));
errno = 0;
}
- pylval.nd = new_float(p, tok(p));
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_float(p, tok(p), suffix);
return tFLOAT;
#endif
}
- pylval.nd = new_int(p, tok(p), 10);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 10, suffix);
return tINTEGER;
}
@@ -5612,7 +5804,7 @@ parser_yylex(parser_state *p)
{
unsigned long n = strtoul(tok(p), NULL, 10);
if (n > INT_MAX) {
- yyerror_i(p, "capture group index must be <= %d", INT_MAX);
+ yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX));
return 0;
}
pylval.nd = new_nth_ref(p, (int)n);
@@ -5649,10 +5841,10 @@ parser_yylex(parser_state *p)
}
else if (ISDIGIT(c)) {
if (p->tidx == 1) {
- yyerror_i(p, "'@%c' is not allowed as an instance variable name", c);
+ yyerror_c(p, "wrong instance variable name: @", c);
}
else {
- yyerror_i(p, "'@@%c' is not allowed as a class variable name", c);
+ yyerror_c(p, "wrong class variable name: @@", c);
}
return 0;
}
@@ -5668,7 +5860,15 @@ parser_yylex(parser_state *p)
default:
if (!identchar(c)) {
- yyerror_i(p, "Invalid char '\\x%02X' in expression", c);
+ char buf[36];
+ const char s[] = "Invalid char in expression: 0x";
+ const char hexdigits[] = "0123456789ABCDEF";
+
+ strcpy(buf, s);
+ buf[sizeof(s)-1] = hexdigits[(c & 0xf0) >> 4];
+ buf[sizeof(s)] = hexdigits[(c & 0x0f)];
+ buf[sizeof(s)+1] = 0;
+ yyerror(p, buf);
goto retry;
}
@@ -6097,11 +6297,12 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
if (c) c->parser_nerr = p->nerr;
if (p->capture_errors) {
char buf[256];
- int n;
- n = snprintf(buf, sizeof(buf), "line %d: %s\n",
- p->error_buffer[0].lineno, p->error_buffer[0].message);
- mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
+ strcpy(buf, "line ");
+ dump_int(p->error_buffer[0].lineno, buf+5);
+ strcat(buf, ": ");
+ strncat(buf, p->error_buffer[0].message, sizeof(buf) - strlen(buf) - 1);
+ mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, strlen(buf)));
mrb_parser_free(p);
return mrb_undef_value();
}
@@ -6219,7 +6420,7 @@ dump_args(mrb_state *mrb, node *n, int offset)
while (n2) {
dump_prefix(n2, offset+2);
- printf("%s=\n", mrb_sym2name(mrb, sym(n2->car->car)));
+ printf("%s=\n", mrb_sym_name(mrb, sym(n2->car->car)));
mrb_parser_dump(mrb, n2->car->cdr, offset+3);
n2 = n2->cdr;
}
@@ -6228,7 +6429,7 @@ dump_args(mrb_state *mrb, node *n, int offset)
n = n->cdr;
if (n->car) {
dump_prefix(n, offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
@@ -6244,6 +6445,28 @@ dump_args(mrb_state *mrb, node *n, int offset)
}
}
+/*
+ * This function restores the GC arena on return.
+ * For this reason, if a process that further generates an object is
+ * performed at the caller, the string pointer returned as the return
+ * value may become invalid.
+ */
+static const char*
+str_dump(mrb_state *mrb, const char *str, int len)
+{
+ mrb_int ai = mrb_gc_arena_save(mrb);
+ mrb_value s;
+# if INT_MAX > MRB_INT_MAX / 4
+ /* check maximum length with "\xNN" charactor */
+ if (len > MRB_INT_MAX / 4) {
+ len = MRB_INT_MAX / 4;
+ }
+# endif
+ s = mrb_str_new(mrb, str, (mrb_int)len);
+ s = mrb_str_dump(mrb, s);
+ mrb_gc_arena_restore(mrb, ai);
+ return RSTRING_PTR(s);
+}
#endif
void
@@ -6447,7 +6670,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
while (n2) {
if (n2->car) {
if (!first_lval) printf(", ");
- printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+ printf("%s", mrb_sym_name(mrb, sym(n2->car)));
first_lval = FALSE;
}
n2 = n2->cdr;
@@ -6475,7 +6698,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
mrb_parser_dump(mrb, tree->car, offset+1);
dump_prefix(tree, offset+1);
printf("method='%s' (%d)\n",
- mrb_sym2name(mrb, sym(tree->cdr->car)),
+ mrb_sym_dump(mrb, sym(tree->cdr->car)),
intn(tree->cdr->car));
tree = tree->cdr->cdr->car;
if (tree) {
@@ -6506,11 +6729,11 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
printf("NODE_COLON2:\n");
mrb_parser_dump(mrb, tree->car, offset+1);
dump_prefix(tree, offset+1);
- printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr)));
+ printf("::%s\n", mrb_sym_name(mrb, sym(tree->cdr)));
break;
case NODE_COLON3:
- printf("NODE_COLON3: ::%s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_COLON3: ::%s\n", mrb_sym_name(mrb, sym(tree)));
break;
case NODE_ARRAY:
@@ -6606,7 +6829,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
mrb_parser_dump(mrb, tree->car, offset+2);
tree = tree->cdr;
dump_prefix(tree, offset+1);
- printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), intn(tree->car));
+ printf("op='%s' (%d)\n", mrb_sym_name(mrb, sym(tree->car)), intn(tree->car));
tree = tree->cdr;
mrb_parser_dump(mrb, tree->car, offset+1);
break;
@@ -6658,23 +6881,23 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
case NODE_LVAR:
- printf("NODE_LVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_LVAR %s\n", mrb_sym_name(mrb, sym(tree)));
break;
case NODE_GVAR:
- printf("NODE_GVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_GVAR %s\n", mrb_sym_name(mrb, sym(tree)));
break;
case NODE_IVAR:
- printf("NODE_IVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_IVAR %s\n", mrb_sym_name(mrb, sym(tree)));
break;
case NODE_CVAR:
- printf("NODE_CVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_CVAR %s\n", mrb_sym_name(mrb, sym(tree)));
break;
case NODE_CONST:
- printf("NODE_CONST %s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_CONST %s\n", mrb_sym_name(mrb, sym(tree)));
break;
case NODE_MATCH:
@@ -6696,7 +6919,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
case NODE_ARG:
- printf("NODE_ARG %s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_ARG %s\n", mrb_sym_name(mrb, sym(tree)));
break;
case NODE_BLOCK_ARG:
@@ -6713,25 +6936,25 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
case NODE_NEGATE:
- printf("NODE_NEGATE\n");
+ printf("NODE_NEGATE:\n");
mrb_parser_dump(mrb, tree, offset+1);
break;
case NODE_STR:
- printf("NODE_STR \"%s\" len %d\n", (char*)tree->car, intn(tree->cdr));
+ printf("NODE_STR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
break;
case NODE_DSTR:
- printf("NODE_DSTR\n");
+ printf("NODE_DSTR:\n");
dump_recur(mrb, tree, offset+1);
break;
case NODE_XSTR:
- printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, intn(tree->cdr));
+ printf("NODE_XSTR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr));
break;
case NODE_DXSTR:
- printf("NODE_DXSTR\n");
+ printf("NODE_DXSTR:\n");
dump_recur(mrb, tree, offset+1);
break;
@@ -6740,7 +6963,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
case NODE_DREGX:
- printf("NODE_DREGX\n");
+ printf("NODE_DREGX:\n");
dump_recur(mrb, tree->car, offset+1);
dump_prefix(tree, offset);
printf("tail: %s\n", (char*)tree->cdr->cdr->car);
@@ -6755,10 +6978,29 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
break;
case NODE_SYM:
- printf("NODE_SYM :%s (%d)\n", mrb_sym2name(mrb, sym(tree)),
+ printf("NODE_SYM :%s (%d)\n", mrb_sym_dump(mrb, sym(tree)),
intn(tree));
break;
+ case NODE_DSYM:
+ printf("NODE_DSYM:\n");
+ mrb_parser_dump(mrb, tree, offset+1);
+ break;
+
+ case NODE_WORDS:
+ printf("NODE_WORDS:\n");
+ dump_recur(mrb, tree, offset+1);
+ break;
+
+ case NODE_SYMBOLS:
+ printf("NODE_SYMBOLS:\n");
+ dump_recur(mrb, tree, offset+1);
+ break;
+
+ case NODE_LITERAL_DELIM:
+ printf("NODE_LITERAL_DELIM\n");
+ break;
+
case NODE_SELF:
printf("NODE_SELF\n");
break;
@@ -6777,8 +7019,8 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_ALIAS:
printf("NODE_ALIAS %s %s:\n",
- mrb_sym2name(mrb, sym(tree->car)),
- mrb_sym2name(mrb, sym(tree->cdr)));
+ mrb_sym_dump(mrb, sym(tree->car)),
+ mrb_sym_dump(mrb, sym(tree->cdr)));
break;
case NODE_UNDEF:
@@ -6786,7 +7028,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
{
node *t = tree;
while (t) {
- printf(" %s", mrb_sym2name(mrb, sym(t->car)));
+ printf(" %s", mrb_sym_dump(mrb, sym(t->car)));
t = t->cdr;
}
}
@@ -6797,16 +7039,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
printf("NODE_CLASS:\n");
if (tree->car->car == (node*)0) {
dump_prefix(tree, offset+1);
- printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+ printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
}
else if (tree->car->car == (node*)1) {
dump_prefix(tree, offset+1);
- printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+ printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
}
else {
mrb_parser_dump(mrb, tree->car->car, offset+1);
dump_prefix(tree, offset+1);
- printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+ printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
}
if (tree->cdr->car) {
dump_prefix(tree, offset+1);
@@ -6822,16 +7064,16 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
printf("NODE_MODULE:\n");
if (tree->car->car == (node*)0) {
dump_prefix(tree, offset+1);
- printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+ printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
}
else if (tree->car->car == (node*)1) {
dump_prefix(tree, offset+1);
- printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+ printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
}
else {
mrb_parser_dump(mrb, tree->car->car, offset+1);
dump_prefix(tree, offset+1);
- printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+ printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr)));
}
dump_prefix(tree, offset+1);
printf("body:\n");
@@ -6849,7 +7091,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_DEF:
printf("NODE_DEF:\n");
dump_prefix(tree, offset+1);
- printf("%s\n", mrb_sym2name(mrb, sym(tree->car)));
+ printf("%s\n", mrb_sym_dump(mrb, sym(tree->car)));
tree = tree->cdr;
{
node *n2 = tree->car;
@@ -6862,7 +7104,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
while (n2) {
if (n2->car) {
if (!first_lval) printf(", ");
- printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+ printf("%s", mrb_sym_name(mrb, sym(n2->car)));
first_lval = FALSE;
}
n2 = n2->cdr;
@@ -6882,7 +7124,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
mrb_parser_dump(mrb, tree->car, offset+1);
tree = tree->cdr;
dump_prefix(tree, offset+1);
- printf(":%s\n", mrb_sym2name(mrb, sym(tree->car)));
+ printf(":%s\n", mrb_sym_dump(mrb, sym(tree->car)));
tree = tree->cdr->cdr;
if (tree->car) {
dump_args(mrb, tree->car, offset+1);
@@ -6919,17 +7161,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
tree = tree->cdr;
if (tree->car) {
dump_prefix(tree, offset+1);
- printf("block='%s'\n", mrb_sym2name(mrb, sym(tree->car)));
+ printf("block='%s'\n", mrb_sym_name(mrb, sym(tree->car)));
}
break;
case NODE_KW_ARG:
- printf("NODE_KW_ARG %s\n", mrb_sym2name(mrb, sym(tree->car)));
+ printf("NODE_KW_ARG %s:\n", mrb_sym_name(mrb, sym(tree->car)));
mrb_parser_dump(mrb, tree->cdr->car, offset + 1);
break;
case NODE_KW_REST_ARGS:
- printf("NODE_KW_REST_ARGS %s\n", mrb_sym2name(mrb, sym(tree)));
+ printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree)));
break;
default: