summaryrefslogtreecommitdiffhomepage
path: root/src/parse.y
diff options
context:
space:
mode:
authorPaolo Bosetti <[email protected]>2012-08-06 15:02:03 +0200
committerPaolo Bosetti <[email protected]>2012-08-06 15:02:56 +0200
commitaa0d2f91447c49363059f2e95cb9023f65a6fbef (patch)
tree2cfa325956e62648f2161564adfdf6dddc45b737 /src/parse.y
parentfd097b8aff7b91bd105fc1daec5a4050a947b763 (diff)
parent193c98ae540d43d082795fd77ea81a4f6f7fd0f6 (diff)
downloadmruby-aa0d2f91447c49363059f2e95cb9023f65a6fbef.tar.gz
mruby-aa0d2f91447c49363059f2e95cb9023f65a6fbef.zip
Updated Xcode project build settings in conformity with 10.8/Xcode 4.4
Diffstat (limited to 'src/parse.y')
-rw-r--r--src/parse.y553
1 files changed, 346 insertions, 207 deletions
diff --git a/src/parse.y b/src/parse.y
index eae9fb373..50f55bf7b 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -20,8 +20,8 @@
#include "mruby.h"
#include "mruby/compile.h"
+#include "mruby/proc.h"
#include "node.h"
-#include "st.h"
#include <stdio.h>
#include <errno.h>
@@ -41,30 +41,22 @@ static void backref_error(parser_state *p, node *n);
#define identchar(c) (isalnum(c) || (c) == '_' || !isascii(c))
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
typedef unsigned int stack_type;
-#define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
-#define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
-#define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
-#define BITSTACK_SET_P(stack) ((stack)&1)
+#define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
+#define BITSTACK_POP(stack) ((stack) = (stack) >> 1)
+#define BITSTACK_LEXPOP(stack) ((stack) = ((stack) >> 1) | ((stack) & 1))
+#define BITSTACK_SET_P(stack) ((stack)&1)
-#define COND_PUSH(n) BITSTACK_PUSH(p->cond_stack, (n))
-#define COND_POP() BITSTACK_POP(p->cond_stack)
-#define COND_LEXPOP() BITSTACK_LEXPOP(p->cond_stack)
-#define COND_P() BITSTACK_SET_P(p->cond_stack)
+#define COND_PUSH(n) BITSTACK_PUSH(p->cond_stack, (n))
+#define COND_POP() BITSTACK_POP(p->cond_stack)
+#define COND_LEXPOP() BITSTACK_LEXPOP(p->cond_stack)
+#define COND_P() BITSTACK_SET_P(p->cond_stack)
-#define CMDARG_PUSH(n) BITSTACK_PUSH(p->cmdarg_stack, (n))
-#define CMDARG_POP() BITSTACK_POP(p->cmdarg_stack)
-#define CMDARG_LEXPOP() BITSTACK_LEXPOP(p->cmdarg_stack)
-#define CMDARG_P() BITSTACK_SET_P(p->cmdarg_stack)
+#define CMDARG_PUSH(n) BITSTACK_PUSH(p->cmdarg_stack, (n))
+#define CMDARG_POP() BITSTACK_POP(p->cmdarg_stack)
+#define CMDARG_LEXPOP() BITSTACK_LEXPOP(p->cmdarg_stack)
+#define CMDARG_P() BITSTACK_SET_P(p->cmdarg_stack)
static mrb_sym
intern_gen(parser_state *p, const char *s)
@@ -102,7 +94,7 @@ cons_gen(parser_state *p, node *car, node *cdr)
p->cells = p->cells->cdr;
}
else {
- c = parser_palloc(p, sizeof(mrb_ast_node));
+ c = (node *)parser_palloc(p, sizeof(mrb_ast_node));
}
c->car = car;
@@ -173,7 +165,7 @@ append_gen(parser_state *p, node *a, node *b)
static char*
parser_strndup(parser_state *p, const char *s, size_t len)
{
- char *b = parser_palloc(p, len+1);
+ char *b = (char *)parser_palloc(p, len+1);
memcpy(b, s, len);
b[len] = '\0';
@@ -526,6 +518,15 @@ new_sym(parser_state *p, mrb_sym sym)
return cons((node*)NODE_SYM, (node*)sym);
}
+static mrb_sym
+new_strsym(parser_state *p, node* str)
+{
+ const char *s = (const char*)str->cdr->car;
+ size_t len = (size_t)str->cdr->cdr;
+
+ return mrb_intern2(p->mrb, s, len);
+}
+
// (:lvar . a)
static node*
new_lvar(parser_state *p, mrb_sym sym)
@@ -685,9 +686,9 @@ new_float(parser_state *p, const char *s)
// (:str . (s . len))
static node*
-new_str(parser_state *p, const char *s, size_t len)
+new_str(parser_state *p, const char *s, int len)
{
- return cons((node*)NODE_STR, cons((node*)strndup(s, len), (node*)len));
+ return cons((node*)NODE_STR, cons((node*)strndup(s, len), (node*)(intptr_t)len));
}
// (:dstr . a)
@@ -697,6 +698,13 @@ new_dstr(parser_state *p, node *a)
return cons((node*)NODE_DSTR, a);
}
+// (:dsym . a)
+static node*
+new_dsym(parser_state *p, node *a)
+{
+ return cons((node*)NODE_DSYM, new_dstr(p, a));
+}
+
// (:backref . n)
static node*
new_back_ref(parser_state *p, int n)
@@ -754,11 +762,21 @@ args_with_block(parser_state *p, node *a, node *b)
static void
call_with_block(parser_state *p, node *a, node *b)
{
- node *n = a->cdr->cdr->cdr;
+ node *n;
- if (!n->car) n->car = cons(0, b);
+ if (a->car == (node*)NODE_SUPER ||
+ a->car == (node*)NODE_ZSUPER) {
+ if (!a->cdr) a->cdr = cons(0, b);
+ else {
+ args_with_block(p, a->cdr, b);
+ }
+ }
else {
- args_with_block(p, n->car, b);
+ n = a->cdr->cdr->cdr;
+ if (!n->car) n->car = cons(0, b);
+ else {
+ args_with_block(p, n->car, b);
+ }
}
}
@@ -787,12 +805,8 @@ ret_args(parser_state *p, node *n)
static void
assignable(parser_state *p, node *lhs)
{
- switch ((int)(intptr_t)lhs->car) {
- case NODE_LVAR:
+ if ((int)(intptr_t)lhs->car == NODE_LVAR) {
local_add(p, (mrb_sym)lhs->cdr);
- break;
- default:
- break;
}
}
@@ -801,17 +815,14 @@ var_reference(parser_state *p, node *lhs)
{
node *n;
- switch ((int)(intptr_t)lhs->car) {
- case NODE_LVAR:
+ if ((int)(intptr_t)lhs->car == NODE_LVAR) {
if (!local_var_p(p, (mrb_sym)lhs->cdr)) {
n = new_fcall(p, (mrb_sym)lhs->cdr, 0);
cons_free(lhs);
return n;
}
- break;
- default:
- break;
}
+
return lhs;
}
@@ -888,7 +899,7 @@ var_reference(parser_state *p, node *lhs)
%token <num> tREGEXP_END
%type <nd> singleton string string_interp regexp
-%type <nd> literal numeric cpath
+%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
%type <nd> expr_value arg_value primary_value
@@ -904,8 +915,8 @@ var_reference(parser_state *p, node *lhs)
%type <nd> bv_decls opt_bv_decl bvar f_larglist lambda_body
%type <nd> brace_block cmd_brace_block do_block lhs none fitem f_bad_arg
%type <nd> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
-%type <id> fsym sym symbol operation operation2 operation3
-%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg
+%type <id> fsym sym basic_symbol operation operation2 operation3
+%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg
%token tUPLUS /* unary+ */
%token tUMINUS /* unary- */
@@ -1472,7 +1483,7 @@ fname : tIDENTIFIER
;
fsym : fname
- | symbol
+ | basic_symbol
;
fitem : fsym
@@ -1502,7 +1513,7 @@ op : '|' { $$ = intern("|"); }
| '>' { $$ = intern(">"); }
| tGEQ { $$ = intern(">="); }
| '<' { $$ = intern("<"); }
- | tLEQ { $$ = intern(">="); }
+ | tLEQ { $$ = intern("<="); }
| tNEQ { $$ = intern("!="); }
| tLSHFT { $$ = intern("<<"); }
| tRSHFT { $$ = intern(">>"); }
@@ -2456,9 +2467,6 @@ opt_ensure : keyword_ensure compstmt
literal : numeric
| symbol
- {
- $$ = new_sym(p, $1);
- }
;
string : tCHAR
@@ -2501,7 +2509,18 @@ string_interp : tSTRING_PART
regexp : tREGEXP
;
-symbol : tSYMBEG sym
+symbol : basic_symbol
+ {
+ $$ = new_sym(p, $1);
+ }
+ | tSYMBEG tSTRING_BEG string_interp tSTRING
+ {
+ p->lstate = EXPR_END;
+ $$ = new_dsym(p, push($3, $4));
+ }
+ ;
+
+basic_symbol : tSYMBEG sym
{
p->lstate = EXPR_END;
$$ = $2;
@@ -2512,6 +2531,14 @@ sym : fname
| tIVAR
| tGVAR
| tCVAR
+ | tSTRING
+ {
+ $$ = new_strsym(p, $1);
+ }
+ | tSTRING_BEG tSTRING
+ {
+ $$ = new_strsym(p, $2);
+ }
;
numeric : tINTEGER
@@ -2585,7 +2612,7 @@ var_ref : variable
{
char buf[16];
- snprintf(buf, 16, "%d", p->lineno);
+ snprintf(buf, sizeof(buf), "%d", p->lineno);
$$ = new_int(p, buf, 10);
}
;
@@ -2787,7 +2814,8 @@ f_rest_arg : restarg_mark tIDENTIFIER
}
| restarg_mark
{
- $$ = 0;
+ local_add_f(p, 0);
+ $$ = -1;
}
;
@@ -2824,7 +2852,7 @@ singleton : var_ref
yyerror(p, "can't define singleton method for ().");
}
else {
- switch ((enum node_type)$3->car) {
+ switch ((enum node_type)(int)(intptr_t)$3->car) {
case NODE_STR:
case NODE_DSTR:
case NODE_DREGX:
@@ -2926,19 +2954,21 @@ static void
yyerror(parser_state *p, const char *s)
{
char* c;
- size_t n;
+ int n;
if (! p->capture_errors) {
+#ifdef ENABLE_STDIO
if (p->filename) {
fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
}
else {
fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);
}
+#endif
}
else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) {
n = strlen(s);
- c = parser_palloc(p, n + 1);
+ c = (char *)parser_palloc(p, n + 1);
memcpy(c, s, n + 1);
p->error_buffer[p->nerr].message = c;
p->error_buffer[p->nerr].lineno = p->lineno;
@@ -2952,7 +2982,7 @@ yyerror_i(parser_state *p, const char *fmt, int i)
{
char buf[256];
- snprintf(buf, 256, fmt, i);
+ snprintf(buf, sizeof(buf), fmt, i);
yyerror(p, buf);
}
@@ -2960,19 +2990,21 @@ static void
yywarn(parser_state *p, const char *s)
{
char* c;
- size_t n;
+ int n;
if (! p->capture_errors) {
+#ifdef ENABLE_STDIO
if (p->filename) {
fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
}
else {
fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);
}
+#endif
}
else if (p->nerr < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) {
n = strlen(s);
- c = parser_palloc(p, n + 1);
+ c = (char *)parser_palloc(p, n + 1);
memcpy(c, s, n + 1);
p->warn_buffer[p->nwarn].message = c;
p->warn_buffer[p->nwarn].lineno = p->lineno;
@@ -2992,20 +3024,23 @@ yywarning_s(parser_state *p, const char *fmt, const char *s)
{
char buf[256];
- snprintf(buf, 256, fmt, s);
+ snprintf(buf, sizeof(buf), fmt, s);
yywarning(p, buf);
}
static void
backref_error(parser_state *p, node *n)
{
- switch ((int)(intptr_t)n->car) {
- case NODE_NTH_REF:
+ int c;
+
+ c = (int)(intptr_t)n->car;
+
+ if (c == NODE_NTH_REF) {
yyerror_i(p, "can't set variable $%d", (int)(intptr_t)n->cdr);
- break;
- case NODE_BACK_REF:
+ } else if (c == NODE_BACK_REF) {
yyerror_i(p, "can't set variable $%c", (int)(intptr_t)n->cdr);
- break;
+ } else {
+ mrb_bug("Internal error in backref_error() : n=>car == %d", c);
}
}
@@ -3198,9 +3233,9 @@ toklen(parser_state *p)
#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
static unsigned long
-scan_oct(const char *start, int len, int *retlen)
+scan_oct(const int *start, int len, int *retlen)
{
- const char *s = start;
+ const int *s = start;
unsigned long retval = 0;
while (len-- && *s >= '0' && *s <= '7') {
@@ -3212,14 +3247,14 @@ scan_oct(const char *start, int len, int *retlen)
}
static unsigned long
-scan_hex(const char *start, int len, int *retlen)
+scan_hex(const int *start, int len, int *retlen)
{
static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
- register const char *s = start;
+ register const int *s = start;
register unsigned long retval = 0;
char *tmp;
- while (len-- && *s && (tmp = strchr(hexdigit, *s))) {
+ while (len-- && *s && (tmp = (char *)strchr(hexdigit, *s))) {
retval <<= 4;
retval |= (tmp - hexdigit) & 15;
s++;
@@ -3261,7 +3296,7 @@ read_escape(parser_state *p)
case '0': case '1': case '2': case '3': /* octal constant */
case '4': case '5': case '6': case '7':
{
- char buf[3];
+ int buf[3];
int i;
for (i=0; i<3; i++) {
@@ -3278,7 +3313,7 @@ read_escape(parser_state *p)
case 'x': /* hex constant */
{
- char buf[2];
+ int buf[2];
int i;
for (i=0; i<2; i++) {
@@ -3389,8 +3424,8 @@ parse_string(parser_state *p, int term)
return tSTRING;
}
-static int
-parse_qstring(parser_state *p, int term)
+static node*
+qstring_node(parser_state *p, int term)
{
int c;
@@ -3426,9 +3461,20 @@ parse_qstring(parser_state *p, int term)
}
tokfix(p);
- yylval.nd = new_str(p, tok(p), toklen(p));
p->lstate = EXPR_END;
- return tSTRING;
+ return new_str(p, tok(p), toklen(p));
+}
+
+static int
+parse_qstring(parser_state *p, int term)
+{
+ node *nd = qstring_node(p, term);
+
+ if (nd) {
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ return tSTRING;
+ }
+ return 0;
}
static int
@@ -3537,11 +3583,10 @@ parser_yylex(parser_state *p)
c = '*';
}
}
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- default:
- p->lstate = EXPR_BEG; break;
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
+ p->lstate = EXPR_BEG;
}
return c;
@@ -3572,11 +3617,10 @@ parser_yylex(parser_state *p)
goto retry;
}
}
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- default:
- p->lstate = EXPR_BEG; break;
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
+ p->lstate = EXPR_BEG;
}
if ((c = nextc(p)) == '=') {
if ((c = nextc(p)) == '=') {
@@ -3608,13 +3652,13 @@ parser_yylex(parser_state *p)
if (token) return token;
}
#endif
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- case EXPR_CLASS:
- p->cmd_start = TRUE;
- default:
- p->lstate = EXPR_BEG; break;
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
+ p->lstate = EXPR_BEG;
+ if (p->lstate == EXPR_CLASS) {
+ p->cmd_start = TRUE;
+ }
}
if (c == '=') {
if ((c = nextc(p)) == '>') {
@@ -3636,11 +3680,10 @@ parser_yylex(parser_state *p)
return '<';
case '>':
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- default:
- p->lstate = EXPR_BEG; break;
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
+ p->lstate = EXPR_BEG;
}
if ((c = nextc(p)) == '=') {
return tGEQ;
@@ -3676,7 +3719,7 @@ parser_yylex(parser_state *p)
}
if (isspace(c)) {
if (!IS_ARG()) {
- int c2 = 0;
+ int c2;
switch (c) {
case ' ':
c2 = 's';
@@ -3696,10 +3739,13 @@ parser_yylex(parser_state *p)
case '\f':
c2 = 'f';
break;
+ default:
+ c2 = 0;
+ break;
}
if (c2) {
char buf[256];
- snprintf(buf, 256, "invalid character syntax; use ?\\%c", c2);
+ snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
yyerror(p, buf);
}
}
@@ -3765,10 +3811,9 @@ parser_yylex(parser_state *p)
else {
c = '&';
}
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- default:
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
p->lstate = EXPR_BEG;
}
return c;
@@ -3902,7 +3947,7 @@ parser_yylex(parser_state *p)
}
if (!ISXDIGIT(c)) break;
nondigit = 0;
- tokadd(p, c);
+ tokadd(p, tolower(c));
} while ((c = nextc(p)) != -1);
}
pushback(p, c);
@@ -4081,8 +4126,15 @@ parser_yylex(parser_state *p)
}
tokfix(p);
if (is_float) {
- (void)strtod(tok(p), 0); /* just check if float is within range */
- if (errno == ERANGE) {
+ double d;
+ char *endp;
+
+ errno = 0;
+ d = strtod(tok(p), &endp);
+ if (d == 0 && endp == tok(p)) {
+ yywarning_s(p, "corrupted float value %s", tok(p));
+ }
+ else if (errno == ERANGE) {
yywarning_s(p, "float %s out of range", tok(p));
errno = 0;
}
@@ -4120,21 +4172,7 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
return ':';
}
- switch (c) {
- case '\'':
-#if 0
- p->lex_strterm = new_strterm(p, str_ssym, c, 0);
-#endif
- break;
- case '"':
-#if 0
- p->lex_strterm = new_strterm(p, str_dsym, c, 0);
-#endif
- break;
- default:
- pushback(p, c);
- break;
- }
+ pushback(p, c);
p->lstate = EXPR_FNAME;
return tSYMBEG;
@@ -4158,11 +4196,10 @@ parser_yylex(parser_state *p)
#endif
return tREGEXP_BEG;
}
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- default:
- p->lstate = EXPR_BEG; break;
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
+ p->lstate = EXPR_BEG;
}
return '/';
@@ -4172,11 +4209,10 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- default:
- p->lstate = EXPR_BEG; break;
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
+ p->lstate = EXPR_BEG;
}
pushback(p, c);
return '^';
@@ -4361,11 +4397,10 @@ parser_yylex(parser_state *p)
if (IS_SPCARG(c)) {
goto quotation;
}
- switch (p->lstate) {
- case EXPR_FNAME: case EXPR_DOT:
- p->lstate = EXPR_ARG; break;
- default:
- p->lstate = EXPR_BEG; break;
+ if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+ p->lstate = EXPR_ARG;
+ } else {
+ p->lstate = EXPR_BEG;
}
pushback(p, c);
return '%';
@@ -4539,7 +4574,7 @@ parser_yylex(parser_state *p)
pushback(p, c);
}
}
- if (result == 0 && isupper(tok(p)[0])) {
+ if (result == 0 && isupper((int)tok(p)[0])) {
result = tCONSTANT;
}
else {
@@ -4636,8 +4671,48 @@ yylex(void *lval, parser_state *p)
return t;
}
+static void
+parser_init_cxt(parser_state *p, mrbc_context *cxt)
+{
+ if (!cxt) return;
+ if (cxt->lineno) p->lineno = cxt->lineno;
+ if (cxt->filename) p->filename = cxt->filename;
+ if (cxt->syms) {
+ int i;
+
+ p->locals = cons(0,0);
+ for (i=0; i<cxt->slen; i++) {
+ local_add_f(p, cxt->syms[i]);
+ }
+ }
+ p->capture_errors = cxt->capture_errors;
+}
+
+static void
+parser_update_cxt(parser_state *p, mrbc_context *cxt)
+{
+ node *n, *n0;
+ int i = 0;
+
+ if (!cxt) return;
+ if ((int)(intptr_t)p->tree->car != NODE_SCOPE) return;
+ n0 = n = p->tree->cdr->car;
+ while (n) {
+ i++;
+ n = n->cdr;
+ }
+ cxt->syms = (mrb_sym *)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym));
+ cxt->slen = i;
+ for (i=0, n=n0; n; i++,n=n->cdr) {
+ cxt->syms[i] = (mrb_sym)n->car;
+ }
+}
+
+void codedump_all(mrb_state*, int);
+void parser_dump(mrb_state *mrb, node *tree, int offset);
+
void
-mrb_parser_parse(parser_state *p)
+mrb_parser_parse(parser_state *p, mrbc_context *c)
{
node *tree;
@@ -4653,6 +4728,7 @@ mrb_parser_parse(parser_state *p)
p->nerr = p->nwarn = 0;
p->sterm = 0;
+ parser_init_cxt(p, c);
yyparse(p);
tree = p->tree;
if (!tree) {
@@ -4664,14 +4740,15 @@ mrb_parser_parse(parser_state *p)
}
}
else {
- if ((intptr_t)tree->car == NODE_SCOPE) {
- p->locals = cons(tree->cdr->car, 0);
- }
+ parser_update_cxt(p, c);
if (p->begin_tree) {
tree = new_begin(p, p->begin_tree);
append(tree, p->tree);
}
}
+ if (c && c->dump_result) {
+ parser_dump(p->mrb, p->tree, 0);
+ }
}
parser_state*
@@ -4682,7 +4759,7 @@ mrb_parser_new(mrb_state *mrb)
pool = mrb_pool_open(mrb);
if (!pool) return 0;
- p = mrb_pool_alloc(pool, sizeof(parser_state));
+ p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state));
if (!p) return 0;
memset(p, 0, sizeof(parser_state));
@@ -4697,7 +4774,6 @@ mrb_parser_new(mrb_state *mrb)
p->in_def = p->in_single = FALSE;
p->capture_errors = 0;
-
p->lineno = 1;
p->column = 0;
#if defined(PARSER_TEST) || defined(PARSER_DEBUG)
@@ -4707,28 +4783,45 @@ mrb_parser_new(mrb_state *mrb)
return p;
}
-const char*
-mrb_parser_filename(parser_state *p, const char *s)
+void
+mrb_parser_free(parser_state *p) {
+ mrb_pool_close(p->pool);
+}
+
+mrbc_context*
+mrbc_context_new(mrb_state *mrb)
{
- if (s) {
- p->filename = strdup(s);
- }
- return p->filename;
+ mrbc_context *c;
+
+ c = (mrbc_context *)mrb_calloc(mrb, 1, sizeof(mrbc_context));
+ return c;
}
-int
-mrb_parser_lineno(struct mrb_parser_state *p, int n)
+void
+mrbc_context_free(mrb_state *mrb, mrbc_context *cxt)
+{
+ mrb_free(mrb, cxt->syms);
+ mrb_free(mrb, cxt->filename);
+ mrb_free(mrb, cxt);
+}
+
+const char*
+mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s)
{
- if (n <= 0) {
- return p->lineno;
+ if (s) {
+ int len = strlen(s);
+ char *p = (char *)mrb_malloc(mrb, len);
+
+ memcpy(p, s, len);
+ if (c->filename) mrb_free(mrb, c->filename);
+ c->filename = p;
+ c->lineno = 1;
}
- p->column = 0;
- p->lineno = n;
- return n;
+ return c->filename;
}
parser_state*
-mrb_parse_file(mrb_state *mrb, FILE *f)
+mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
{
parser_state *p;
@@ -4737,12 +4830,12 @@ mrb_parse_file(mrb_state *mrb, FILE *f)
p->s = p->send = NULL;
p->f = f;
- mrb_parser_parse(p);
+ mrb_parser_parse(p, c);
return p;
}
parser_state*
-mrb_parse_nstring(mrb_state *mrb, const char *s, size_t len)
+mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c)
{
parser_state *p;
@@ -4751,64 +4844,97 @@ mrb_parse_nstring(mrb_state *mrb, const char *s, size_t len)
p->s = s;
p->send = s + len;
- mrb_parser_parse(p);
+ mrb_parser_parse(p, c);
return p;
}
parser_state*
-mrb_parse_string(mrb_state *mrb, const char *s)
+mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c)
{
- return mrb_parse_nstring(mrb, s, strlen(s));
+ return mrb_parse_nstring(mrb, s, strlen(s), c);
}
-#define PARSER_DUMP
-
-void parser_dump(mrb_state *mrb, node *tree, int offset);
-
-int
-mrb_compile_file(mrb_state * mrb, FILE *f)
+static mrb_value
+load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
{
- parser_state *p;
int n;
+ mrb_value v;
- p = mrb_parse_file(mrb, f);
- if (!p) return -1;
- if (!p->tree) return -1;
- if (p->nerr) return -1;
-#ifdef PARSER_DUMP
- parser_dump(mrb, p->tree, 0);
-#endif
+ if (!p) {
+ mrb_parser_free(p);
+ return mrb_undef_value();
+ }
+ if (!p->tree || p->nerr) {
+ if (p->capture_errors) {
+ char buf[256];
+
+ n = snprintf(buf, sizeof(buf), "line %d: %s\n",
+ p->error_buffer[0].lineno, p->error_buffer[0].message);
+ mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
+ mrb_parser_free(p);
+ return mrb_undef_value();
+ }
+ else {
+ static const char msg[] = "syntax error";
+ mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, msg, sizeof(msg) - 1));
+ mrb_parser_free(p);
+ return mrb_nil_value();
+ }
+ }
n = mrb_generate_code(mrb, p->tree);
- mrb_pool_close(p->pool);
+ mrb_parser_free(p);
+ if (n < 0) {
+ static const char msg[] = "codegen error";
+ mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
+ return mrb_nil_value();
+ }
+ if (c) {
+ if (c->dump_result) codedump_all(mrb, n);
+ if (c->no_exec) return mrb_fixnum_value(n);
+ }
+ v = mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
+ if (mrb->exc) return mrb_nil_value();
+ return v;
+}
- return n;
+mrb_value
+mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
+{
+ return load_exec(mrb, mrb_parse_file(mrb, f, c), c);
}
-int
-mrb_compile_nstring(mrb_state *mrb, char *s, size_t len)
+mrb_value
+mrb_load_file(mrb_state *mrb, FILE *f)
{
- parser_state *p;
- int n;
+ return mrb_load_file_cxt(mrb, f, NULL);
+}
- p = mrb_parse_nstring(mrb, s, len);
- if (!p) return -1;
- if (!p->tree) return -1;
- if (p->nerr) return -1;
-#ifdef PARSER_DUMP
- parser_dump(mrb, p->tree, 0);
-#endif
- n = mrb_generate_code(mrb, p->tree);
- mrb_pool_close(p->pool);
+mrb_value
+mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c)
+{
+ return load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
+}
- return n;
+mrb_value
+mrb_load_nstring(mrb_state *mrb, const char *s, int len)
+{
+ return mrb_load_nstring_cxt(mrb, s, len, NULL);
}
-int
-mrb_compile_string(mrb_state *mrb, char *s)
+mrb_value
+mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c)
+{
+ return mrb_load_nstring_cxt(mrb, s, strlen(s), c);
+}
+
+mrb_value
+mrb_load_string(mrb_state *mrb, const char *s)
{
- return mrb_compile_nstring(mrb, s, strlen(s));
+ return mrb_load_string_cxt(mrb, s, NULL);
}
+#ifdef ENABLE_STDIO
+
static void
dump_prefix(int offset)
{
@@ -4827,9 +4953,12 @@ dump_recur(mrb_state *mrb, node *tree, int offset)
}
}
+#endif
+
void
parser_dump(mrb_state *mrb, node *tree, int offset)
{
+#ifdef ENABLE_STDIO
int n;
if (!tree) return;
@@ -4891,7 +5020,7 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
parser_dump(mrb, tree->car, offset+2);
dump_prefix(offset+1);
printf("ensure:\n");
- parser_dump(mrb, tree->cdr, offset+2);
+ parser_dump(mrb, tree->cdr->cdr, offset+2);
break;
case NODE_LAMBDA:
@@ -5052,15 +5181,20 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_SCOPE:
printf("NODE_SCOPE:\n");
- dump_prefix(offset+1);
- printf("local variables:\n");
{
node *n2 = tree->car;
- while (n2) {
- dump_prefix(offset+2);
- printf("%s\n", mrb_sym2name(mrb, (mrb_sym)n2->car));
- n2 = n2->cdr;
+ if (n2 && (n2->car || n2->cdr)) {
+ dump_prefix(offset+1);
+ printf("local variables:\n");
+ while (n2) {
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("%s ", mrb_sym2name(mrb, (mrb_sym)n2->car));
+ }
+ n2 = n2->cdr;
+ }
+ printf("\n");
}
}
tree = tree->cdr;
@@ -5392,16 +5526,21 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
dump_prefix(offset+1);
printf("%s\n", mrb_sym2name(mrb, (mrb_sym)tree->car));
tree = tree->cdr;
- dump_prefix(offset+1);
- printf("local variables:\n");
{
node *n2 = tree->car;
- while (n2) {
- dump_prefix(offset+2);
- if (n2->car)
- printf("%s\n", mrb_sym2name(mrb, (mrb_sym)n2->car));
- n2 = n2->cdr;
+ if (n2 && (n2->car || n2->cdr)) {
+ dump_prefix(offset+1);
+ printf("local variables:\n");
+
+ while (n2) {
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("%s ", mrb_sym2name(mrb, (mrb_sym)n2->car));
+ }
+ n2 = n2->cdr;
+ }
+ printf("\n");
}
}
tree = tree->cdr;
@@ -5508,7 +5647,7 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
printf("node type: %d (0x%x)\n", (int)n, (int)n);
break;
}
- return;
+#endif
}
#ifdef PARSER_TEST