diff options
| author | Paolo Bosetti <[email protected]> | 2012-08-06 15:02:03 +0200 |
|---|---|---|
| committer | Paolo Bosetti <[email protected]> | 2012-08-06 15:02:56 +0200 |
| commit | aa0d2f91447c49363059f2e95cb9023f65a6fbef (patch) | |
| tree | 2cfa325956e62648f2161564adfdf6dddc45b737 /src/parse.y | |
| parent | fd097b8aff7b91bd105fc1daec5a4050a947b763 (diff) | |
| parent | 193c98ae540d43d082795fd77ea81a4f6f7fd0f6 (diff) | |
| download | mruby-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.y | 553 |
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 |
