diff options
| -rw-r--r-- | src/cdump.c | 2 | ||||
| -rw-r--r-- | src/parse.y | 5 | ||||
| -rw-r--r-- | src/vm.c | 24 | ||||
| -rw-r--r-- | tools/mirb/mirb.c | 166 |
4 files changed, 108 insertions, 89 deletions
diff --git a/src/cdump.c b/src/cdump.c index 7029ae3de..f9525d042 100644 --- a/src/cdump.c +++ b/src/cdump.c @@ -146,7 +146,7 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f) } } memset(buf, 0, buf_len); - SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %ld);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); break; + SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); break; /* TODO MRB_TT_REGEX */ default: break; } diff --git a/src/parse.y b/src/parse.y index 5bce579e7..4c339f0f4 100644 --- a/src/parse.y +++ b/src/parse.y @@ -3056,12 +3056,11 @@ peek_n(parser_state *p, int c, int n) node *list = 0; int c0; - n++; /* must read 1 char */ - while (n--) { + do { c0 = nextc(p); if (c0 < 0) return FALSE; list = push(list, (node*)(intptr_t)c0); - } + } while(n--); if (p->pb) { p->pb = push(p->pb, (node*)list); } @@ -126,6 +126,16 @@ cipush(mrb_state *mrb) static void cipop(mrb_state *mrb) { + if (mrb->ci->env) { + struct REnv *e = mrb->ci->env; + int len = (int)e->flags; + mrb_value *p = mrb_malloc(mrb, sizeof(mrb_value)*len); + + e->cioff = -1; + memcpy(p, e->stack, sizeof(mrb_value)*len); + e->stack = p; + } + mrb->ci--; } @@ -965,16 +975,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_RETURN) { /* A return R(A) */ L_RETURN: - if (mrb->ci->env) { - struct REnv *e = mrb->ci->env; - int len = (int)e->flags; - mrb_value *p = mrb_malloc(mrb, sizeof(mrb_value)*len); - - e->cioff = -1; - memcpy(p, e->stack, sizeof(mrb_value)*len); - e->stack = p; - } - if (mrb->exc) { mrb_callinfo *ci; @@ -1002,6 +1002,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) switch (GETARG_B(i)) { case OP_R_NORMAL: + if (ci == mrb->cibase) { + localjump_error(mrb, "return"); + goto L_RAISE; + } ci = mrb->ci; break; case OP_R_BREAK: diff --git a/tools/mirb/mirb.c b/tools/mirb/mirb.c index bfd81d582..11bdcfcf8 100644 --- a/tools/mirb/mirb.c +++ b/tools/mirb/mirb.c @@ -7,9 +7,6 @@ */ #include <string.h> -#include <stdbool.h> -#include <unistd.h> -#include <fcntl.h> #include <mruby.h> #include <mruby/proc.h> @@ -18,105 +15,114 @@ /* Guess if the user might want to enter more * or if he wants an evaluation of his code now */ -bool is_code_block_open(struct mrb_parser_state *parser) { - bool code_block_open = false; +int +is_code_block_open(struct mrb_parser_state *parser) +{ + int code_block_open = FALSE; switch (parser->lstate) { - // all states which need more code + /* all states which need more code */ case EXPR_BEG: - // an expression was just started, - // we can't end it like this - code_block_open = true; + /* an expression was just started, */ + /* we can't end it like this */ + code_block_open = TRUE; break; case EXPR_DOT: - // a message dot was the last token, - // there has to come more - code_block_open = true; + /* a message dot was the last token, */ + /* there has to come more */ + code_block_open = TRUE; break; case EXPR_CLASS: - // a class keyword is not enough! - // we need also a name of the class - code_block_open = true; + /* a class keyword is not enough! */ + /* we need also a name of the class */ + code_block_open = TRUE; break; case EXPR_FNAME: - // a method name is necessary - code_block_open = true; + /* a method name is necessary */ + code_block_open = TRUE; break; case EXPR_VALUE: - // if, elsif, etc. without condition - code_block_open = true; + /* if, elsif, etc. without condition */ + code_block_open = TRUE; break; - // now all the states which are closed + /* now all the states which are closed */ case EXPR_ARG: - // an argument is the last token - code_block_open = false; + /* an argument is the last token */ + code_block_open = FALSE; break; - // all states which are unsure + /* all states which are unsure */ case EXPR_CMDARG: break; case EXPR_END: - // an expression was ended + /* an expression was ended */ break; case EXPR_ENDARG: - // closing parenthese + /* closing parenthese */ break; case EXPR_ENDFN: - // definition end + /* definition end */ break; case EXPR_MID: - // jump keyword like break, return, ... + /* jump keyword like break, return, ... */ break; case EXPR_MAX_STATE: - // don't know what to do with this token + /* don't know what to do with this token */ break; default: - // this state is unexpected! + /* this state is unexpected! */ break; } if (!code_block_open) { - // based on the last parser state the code - // block seems to be closed + /* based on the last parser state the code */ + /* block seems to be closed */ - // now check if parser error are available + /* now check if parser error are available */ if (0 < parser->nerr) { - // a parser error occur, we have to check if - // we need to read one more line or if there is - // a different issue which we have to show to - // the user + /* a parser error occur, we have to check if */ + /* we need to read one more line or if there is */ + /* a different issue which we have to show to */ + /* the user */ if (strcmp(parser->error_buffer[0].message, "syntax error, unexpected $end, expecting ';' or '\\n'") == 0) { - code_block_open = true; - } else if (strcmp(parser->error_buffer[0].message, + code_block_open = TRUE; + } + else if (strcmp(parser->error_buffer[0].message, "syntax error, unexpected $end, expecting keyword_end") == 0) { - code_block_open = true; - } else if (strcmp(parser->error_buffer[0].message, + code_block_open = TRUE; + } + else if (strcmp(parser->error_buffer[0].message, "syntax error, unexpected $end, expecting '<' or ';' or '\\n'") == 0) { - code_block_open = true; - } else if (strcmp(parser->error_buffer[0].message, + code_block_open = TRUE; + } + else if (strcmp(parser->error_buffer[0].message, "syntax error, unexpected keyword_end") == 0) { - code_block_open = true; - } else if (strcmp(parser->error_buffer[0].message, + code_block_open = TRUE; + } + else if (strcmp(parser->error_buffer[0].message, "syntax error, unexpected $end, expecting keyword_then or ';' or '\\n'") == 0) { - code_block_open = true; - } else if (strcmp(parser->error_buffer[0].message, + code_block_open = TRUE; + } + else if (strcmp(parser->error_buffer[0].message, "syntax error, unexpected tREGEXP_BEG") == 0) { - code_block_open = true; - } else if (strcmp(parser->error_buffer[0].message, + code_block_open = TRUE; + } + else if (strcmp(parser->error_buffer[0].message, "unterminated string meets end of file") == 0) { - code_block_open = true; + code_block_open = TRUE; } } - } else { - // last parser state suggest that this code - // block is open, WE NEED MORE CODE!! + } + else { + /* last parser state suggest that this code */ + /* block is open, WE NEED MORE CODE!! */ } return code_block_open; @@ -131,15 +137,19 @@ void print_hint(void) } /* Print the command line prompt of the REPL */ -void print_cmdline(bool code_block_open) { +void +print_cmdline(int code_block_open) +{ if (code_block_open) { printf("* "); - } else { + } + else { printf("> "); } } -int main(void) +int +main(void) { char last_char, ruby_code[1024], last_code_line[1024]; int char_index; @@ -147,16 +157,16 @@ int main(void) mrb_state *mrb_interpreter; mrb_value mrb_return_value; int byte_code; - bool code_block_open = false; + int code_block_open = FALSE; print_hint(); - // new interpreter instance + /* new interpreter instance */ mrb_interpreter = mrb_open(); memset(ruby_code, 0, sizeof(*ruby_code)); memset(last_code_line, 0, sizeof(*last_code_line)); - while (true) { + while (TRUE) { print_cmdline(code_block_open); char_index = 0; @@ -173,49 +183,55 @@ int main(void) if (strcmp(last_code_line, "exit") == 0) { if (code_block_open) { - // cancel the current block and reset - code_block_open = false; + /* cancel the current block and reset */ + code_block_open = FALSE; memset(ruby_code, 0, sizeof(*ruby_code)); memset(last_code_line, 0, sizeof(*last_code_line)); continue; - } else { - // quit the program + } + else { + /* quit the program */ break; } - } else { + } + else { if (code_block_open) { strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); - } else { + } + else { memset(ruby_code, 0, sizeof(*ruby_code)); strcat(ruby_code, last_code_line); } - // parse code + /* parse code */ parser = mrb_parse_nstring_ext(mrb_interpreter, ruby_code, strlen(ruby_code)); code_block_open = is_code_block_open(parser); if (code_block_open) { - // no evaluation of code - } else { + /* no evaluation of code */ + } + else { if (0 < parser->nerr) { - // syntax error + /* syntax error */ printf("%s\n", parser->error_buffer[0].message); - } else { - // generate bytecode + } + else { + /* generate bytecode */ byte_code = mrb_generate_code(mrb_interpreter, parser->tree); - // evaluate the bytecode + /* evaluate the bytecode */ mrb_return_value = mrb_run(mrb_interpreter, - // pass a proc for evaulation + /* pass a proc for evaulation */ mrb_proc_new(mrb_interpreter, mrb_interpreter->irep[byte_code]), mrb_top_self(mrb_interpreter)); - // did an exception occur? + /* did an exception occur? */ if (mrb_interpreter->exc) { mrb_p(mrb_interpreter, mrb_obj_value(mrb_interpreter->exc)); mrb_interpreter->exc = 0; - } else { - // no + } + else { + /* no */ printf(" => "); mrb_p(mrb_interpreter, mrb_return_value); } |
