int main(int argc, char **argv) { char ruby_code[1024] = { 0 }; char last_code_line[1024] = { 0 }; #ifndef ENABLE_READLINE int last_char; int char_index; #else char *home = NULL; #endif mrbc_context *cxt; struct mrb_parser_state *parser; mrb_state *mrb; mrb_value result; struct _args args; int n; mrb_bool code_block_open = FALSE; mrb_value MIRB_BIN; int ai; unsigned int stack_keep = 0; /* new interpreter instance */ mrb = mrb_open(); if (mrb == NULL) { fputs("Invalid mrb interpreter, exiting mirb\n", stderr); return EXIT_FAILURE; } mrb_define_global_const(mrb, "ARGV", mrb_ary_new_capa(mrb, 0)); n = parse_args(mrb, argc, argv, &args); if (n == EXIT_FAILURE) { cleanup(mrb, &args); usage(argv[0]); return n; } print_hint(); cxt = mrbc_context_new(mrb); cxt->capture_errors = 1; cxt->lineno = 1; mrbc_filename(mrb, cxt, "(mirb)"); if (args.verbose) cxt->dump_result = 1; MIRB_BIN= mrb_str_new(mrb, argv[0], strlen(argv[0])); mrb_define_global_const(mrb, "MIRB_BIN", MIRB_BIN); #ifdef ENABLE_REQUIRE mrb_value LOAD_PATH = mrb_gv_get(mrb, mrb_intern(mrb, "$:")); if (mrb_str_cmp(mrb, MIRB_BIN, mrb_str_new2(mrb, "mirb")) != 0) { int len = strrchr(RSTRING_PTR(MIRB_BIN), '/') - RSTRING_PTR(MIRB_BIN); mrb_value extdir = mrb_str_substr(mrb, mrb_str_dup(mrb, MIRB_BIN), 0, len); mrb_str_cat2(mrb, extdir, "/../ext"); if (mrb_obj_eq(mrb, mrb_file_exist(mrb, extdir), mrb_true_value())) { mrb_ary_push(mrb, LOAD_PATH, extdir); } } #endif /* ENABLE_REQUIRE */ ai = mrb_gc_arena_save(mrb); #ifdef ENABLE_READLINE MIRB_USING_HISTORY(); home = getenv("HOME"); #ifdef _WIN32 if (!home) home = getenv("USERPROFILE"); #endif if (home) { strcpy(history_path, home); strcat(history_path, "/"); strcat(history_path, history_file_name); MIRB_READ_HISTORY(history_path); } #endif while (TRUE) { #ifndef ENABLE_READLINE print_cmdline(code_block_open); char_index = 0; while ((last_char = getchar()) != '\n') { if (last_char == EOF) break; last_code_line[char_index++] = last_char; } if (last_char == EOF) { fputs("\n", stdout); break; } last_code_line[char_index] = '\0'; #else char* line = MIRB_READLINE(code_block_open ? "* " : "> "); if (line == NULL) { printf("\n"); break; } strncpy(last_code_line, line, sizeof(last_code_line)-1); MIRB_ADD_HISTORY(line); free(line); #endif if (code_block_open) { strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); } else { if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) { break; } strcpy(ruby_code, last_code_line); } /* parse code */ parser = mrb_parser_new(mrb); parser->s = ruby_code; parser->send = ruby_code + strlen(ruby_code); parser->lineno = cxt->lineno; mrb_parser_parse(parser, cxt); code_block_open = is_code_block_open(parser); if (code_block_open) { /* no evaluation of code */ } else { if (0 < parser->nerr) { /* syntax error */ printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); } else { /* generate bytecode */ struct RProc *proc = mrb_generate_code(mrb, parser); if (args.verbose) { mrb_codedump_all(mrb, proc); } /* pass a proc for evaulation */ /* evaluate the bytecode */ result = mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep); stack_keep = proc->body.irep->nlocals; /* did an exception occur? */ if (mrb->exc) { p(mrb, mrb_obj_value(mrb->exc), 0); mrb->exc = 0; } else { /* no */ if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){ result = mrb_any_to_s(mrb,result); } p(mrb, result, 1); } } ruby_code[0] = '\0'; last_code_line[0] = '\0'; mrb_gc_arena_restore(mrb, ai); } mrb_parser_free(parser); cxt->lineno++; } mrbc_context_free(mrb, cxt); mrb_close(mrb); #ifdef ENABLE_READLINE MIRB_WRITE_HISTORY(history_path); #endif return 0; }
int main(void) { char last_char, ruby_code[1024], last_code_line[1024]; int char_index; struct mrb_parser_state *parser; mrb_state *mrb_interpreter; mrb_value mrb_return_value; int byte_code; int code_block_open = FALSE; print_hint(); /* new interpreter instance */ mrb_interpreter = mrb_open(); /* new parser instance */ parser = mrb_parser_new(mrb_interpreter); memset(ruby_code, 0, sizeof(*ruby_code)); memset(last_code_line, 0, sizeof(*last_code_line)); while (TRUE) { print_cmdline(code_block_open); char_index = 0; while ((last_char = getchar()) != '\n') { if (last_char == EOF) break; last_code_line[char_index++] = last_char; } if (last_char == EOF) { printf("\n"); break; } last_code_line[char_index] = '\0'; if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) { if (code_block_open) { /* 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 */ break; } } else { if (code_block_open) { strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); } else { memset(ruby_code, 0, sizeof(*ruby_code)); strcat(ruby_code, last_code_line); } /* parse code */ parser->s = ruby_code; parser->send = ruby_code + strlen(ruby_code); parser->capture_errors = 1; parser->lineno = 1; mrb_parser_parse(parser); code_block_open = is_code_block_open(parser); if (code_block_open) { /* no evaluation of code */ } else { if (0 < parser->nerr) { /* syntax error */ printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); } else { /* generate bytecode */ byte_code = mrb_generate_code(mrb_interpreter, parser->tree); /* evaluate the bytecode */ mrb_return_value = mrb_run(mrb_interpreter, /* pass a proc for evaulation */ mrb_proc_new(mrb_interpreter, mrb_interpreter->irep[byte_code]), mrb_top_self(mrb_interpreter)); /* did an exception occur? */ if (mrb_interpreter->exc) { mrb_p(mrb_interpreter, mrb_obj_value(mrb_interpreter->exc)); mrb_interpreter->exc = 0; } else { /* no */ printf(" => "); mrb_p(mrb_interpreter, mrb_return_value); } } memset(ruby_code, 0, sizeof(*ruby_code)); memset(ruby_code, 0, sizeof(*last_code_line)); } } } mrb_close(mrb_interpreter); return 0; }
static struct RProc* create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line) { mrbc_context *cxt; struct mrb_parser_state *p; struct RProc *proc; struct REnv *e; struct mrb_context *c = mrb->c; if (!mrb_nil_p(binding)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil."); } cxt = mrbc_context_new(mrb); cxt->lineno = line; if (!file) { file = "(eval)"; } mrbc_filename(mrb, cxt, file); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; p = mrb_parse_nstring(mrb, s, len, cxt); /* only occur when memory ran out */ if (!p) { mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state."); } if (0 < p->nerr) { /* parse error */ 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_parser_free(p); mrbc_context_free(mrb, cxt); mrb_exc_raise(mrb, mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n)); } proc = mrb_generate_code(mrb, p); if (proc == NULL) { /* codegen error */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error"); } if (c->ci[-1].proc->target_class) { proc->target_class = c->ci[-1].proc->target_class; } e = c->ci[-1].proc->env; if (!e) e = c->ci[-1].env; e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)e); e->mid = c->ci[-1].mid; e->cioff = c->ci - c->cibase - 1; e->stack = c->ci->stackent; MRB_SET_ENV_STACK_LEN(e, c->ci[-1].proc->body.irep->nlocals); c->ci->env = e; proc->env = e; patch_irep(mrb, proc->body.irep, 0); mrb_parser_free(p); mrbc_context_free(mrb, cxt); return proc; }
int main(int argc, char **argv) { char ruby_code[1024] = { 0 }; char last_code_line[1024] = { 0 }; #ifndef ENABLE_READLINE int last_char; int char_index; #else char *home = NULL; #endif mrbc_context *cxt; struct mrb_parser_state *parser; mrb_state *mrb; mrb_value result; struct _args args; int n; mrb_bool code_block_open = FALSE; int ai; mrb_bool first_command = TRUE; unsigned int nregs; /* new interpreter instance */ mrb = mrb_open(); if (mrb == NULL) { fputs("Invalid mrb interpreter, exiting mirb\n", stderr); return EXIT_FAILURE; } mrb_define_global_const(mrb, "ARGV", mrb_ary_new_capa(mrb, 0)); n = parse_args(mrb, argc, argv, &args); if (n == EXIT_FAILURE) { cleanup(mrb, &args); usage(argv[0]); return n; } print_hint(); cxt = mrbc_context_new(mrb); cxt->capture_errors = 1; cxt->lineno = 1; mrbc_filename(mrb, cxt, "(mirb)"); if (args.verbose) cxt->dump_result = 1; ai = mrb_gc_arena_save(mrb); #ifdef ENABLE_READLINE using_history(); home = getenv("HOME"); #ifdef _WIN32 if (!home) home = getenv("USERPROFILE"); #endif if (home) { strcpy(history_path, home); strcat(history_path, "/"); strcat(history_path, history_file_name); read_history(history_path); } #endif while (TRUE) { #ifndef ENABLE_READLINE print_cmdline(code_block_open); char_index = 0; while ((last_char = getchar()) != '\n') { if (last_char == EOF) break; last_code_line[char_index++] = last_char; } if (last_char == EOF) { fputs("\n", stdout); break; } last_code_line[char_index] = '\0'; #else char* line = readline(code_block_open ? "* " : "> "); if (line == NULL) { printf("\n"); break; } strncpy(last_code_line, line, sizeof(last_code_line)-1); add_history(line); free(line); #endif if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) { if (!code_block_open) { break; } else{ /* count the quit/exit commands as strings if in a quote block */ strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); } } else { if (code_block_open) { strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); } else { strcpy(ruby_code, last_code_line); } } /* parse code */ parser = mrb_parser_new(mrb); parser->s = ruby_code; parser->send = ruby_code + strlen(ruby_code); parser->lineno = cxt->lineno; mrb_parser_parse(parser, cxt); code_block_open = is_code_block_open(parser); if (code_block_open) { /* no evaluation of code */ } else { if (0 < parser->nerr) { /* syntax error */ printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); } else { /* generate bytecode */ struct RProc *proc = mrb_generate_code(mrb, parser); if (args.verbose) { mrb_codedump_all(mrb, proc); } /* pass a proc for evaulation */ nregs = first_command ? 0: proc->body.irep->nregs; /* evaluate the bytecode */ result = mrb_context_run(mrb, proc, mrb_top_self(mrb), nregs); /* did an exception occur? */ if (mrb->exc) { p(mrb, mrb_obj_value(mrb->exc), 0); mrb->exc = 0; } else { /* no */ if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){ result = mrb_any_to_s(mrb,result); } p(mrb, result, 1); } } ruby_code[0] = '\0'; last_code_line[0] = '\0'; mrb_gc_arena_restore(mrb, ai); } mrb_parser_free(parser); cxt->lineno++; first_command = FALSE; } mrbc_context_free(mrb, cxt); mrb_close(mrb); #ifdef ENABLE_READLINE write_history(history_path); #endif return 0; }
void loop() { if (Serial.available() > 0) { char_index = 0; while (true) { if (Serial.available() > 0) { incommingByte = Serial.read(); if (incommingByte == 13) { // New Line last_code_line[char_index] = '\0'; break; } else { last_code_line[char_index++] = incommingByte; Serial.write(incommingByte); } } } Serial.println(""); Serial.flush(); is_exit = false; if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) { // Exit Interactive Mode if (!code_block_open) { is_exit = true; } else { /* count the quit/exit commands as strings if in a quote block */ strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); is_exit = false; } } else { if (code_block_open) { strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); is_exit = false; } else { strcpy(ruby_code, last_code_line); is_exit = false; } } if (!is_exit) { // Not Exit or Quit! /* parse code */ parser = mrb_parser_new(mrb); parser->s = ruby_code; parser->send = ruby_code + strlen(ruby_code); parser->lineno = 1; mrb_parser_parse(parser, cxt); code_block_open = is_code_block_open(parser); if (code_block_open) { /* no evaluation of code */ } else { if (0 < parser->nerr) { /* syntax error */ Serial.write("Syntax Error: "); Serial.println(parser->error_buffer[0].message); } else { /* generate bytecode */ n = mrb_generate_code(mrb, parser); /* evaluate the bytecode */ result = mrb_run(mrb, /* pass a proc for evaulation */ mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); /* did an exception occur? */ if (mrb->exc) { /* yes */ p(mrb, mrb_obj_value(mrb->exc), 0); mrb->exc = 0; } else { /* no */ if (!mrb_respond_to(mrb,result,mrb_intern(mrb, "inspect"))){ result = mrb_any_to_s(mrb,result); } p(mrb, result, 1); } } ruby_code[0] = '\0'; last_code_line[0] = '\0'; mrb_gc_arena_restore(mrb, ai); } mrb_parser_free(parser); } else { // User Enter 'exit' or 'quit' Serial.println("quit IAS"); ruby_code[0] = '\0'; last_code_line[0] = '\0'; mrb_parser_free(parser); mrbc_context_free(mrb, cxt); mrb_close(mrb); mrb_setup_arduino(); } print_cmdline(code_block_open); } }
static struct RProc* create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) { mrbc_context *cxt; struct mrb_parser_state *p; struct RProc *proc; struct REnv *e; mrb_callinfo *ci = &mrb->c->ci[-1]; /* callinfo of eval caller */ struct RClass *target_class = NULL; int bidx; if (!mrb_nil_p(binding)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil."); } cxt = mrbc_context_new(mrb); cxt->lineno = (short)line; mrbc_filename(mrb, cxt, file ? file : "(eval)"); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; p = mrb_parse_nstring(mrb, s, len, cxt); /* only occur when memory ran out */ if (!p) { mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state."); } if (0 < p->nerr) { /* parse error */ mrb_value str; if (file) { str = mrb_format(mrb, " file %S line %S: %S", mrb_str_new_cstr(mrb, file), mrb_fixnum_value(p->error_buffer[0].lineno), mrb_str_new_cstr(mrb, p->error_buffer[0].message)); } else { str = mrb_format(mrb, " line %S: %S", mrb_fixnum_value(p->error_buffer[0].lineno), mrb_str_new_cstr(mrb, p->error_buffer[0].message)); } mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); } proc = mrb_generate_code(mrb, p); if (proc == NULL) { /* codegen error */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error"); } target_class = MRB_PROC_TARGET_CLASS(ci->proc); if (!MRB_PROC_CFUNC_P(ci->proc)) { if (ci->env) { e = ci->env; } else { e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)target_class); e->mid = ci->mid; e->stack = ci[1].stackent; e->cxt = mrb->c; MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals); bidx = ci->argc; if (ci->argc < 0) bidx = 2; else bidx += 1; MRB_ENV_SET_BIDX(e, bidx); ci->env = e; } proc->e.env = e; proc->flags |= MRB_PROC_ENVSET; mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); } proc->upper = ci->proc; mrb->c->ci->target_class = target_class; patch_irep(mrb, proc->body.irep, 0, proc->body.irep); /* mrb_codedump_all(mrb, proc); */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); return proc; }
int main(void) { char ruby_code[1024] = { 0 }; char last_code_line[1024] = { 0 }; #ifndef ENABLE_READLINE int last_char; int char_index; #endif mrbc_context *cxt; struct mrb_parser_state *parser; mrb_state *mrb; mrb_value result; int n; int code_block_open = FALSE; int ai; print_hint(); /* new interpreter instance */ mrb = mrb_open(); if (mrb == NULL) { fprintf(stderr, "Invalid mrb interpreter, exiting mirb"); return EXIT_FAILURE; } cxt = mrbc_context_new(mrb); cxt->capture_errors = 1; ai = mrb_gc_arena_save(mrb); while (TRUE) { #ifndef ENABLE_READLINE print_cmdline(code_block_open); char_index = 0; while ((last_char = getchar()) != '\n') { if (last_char == EOF) break; last_code_line[char_index++] = last_char; } if (last_char == EOF) { printf("\n"); break; } last_code_line[char_index] = '\0'; #else char* line = readline(code_block_open ? "* " : "> "); strncat(last_code_line, line, sizeof(last_code_line)-1); add_history(line); free(line); #endif if ((strcmp(last_code_line, "quit") == 0) || (strcmp(last_code_line, "exit") == 0)) { if (!code_block_open) { break; } else{ /* count the quit/exit commands as strings if in a quote block */ strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); } } else { if (code_block_open) { strcat(ruby_code, "\n"); strcat(ruby_code, last_code_line); } else { strcpy(ruby_code, last_code_line); } } /* parse code */ parser = mrb_parser_new(mrb); parser->s = ruby_code; parser->send = ruby_code + strlen(ruby_code); parser->lineno = 1; mrb_parser_parse(parser, cxt); code_block_open = is_code_block_open(parser); if (code_block_open) { /* no evaluation of code */ } else { if (0 < parser->nerr) { /* syntax error */ printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); } else { /* generate bytecode */ n = mrb_generate_code(mrb, parser); /* evaluate the bytecode */ result = mrb_run(mrb, /* pass a proc for evaulation */ mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); /* did an exception occur? */ if (mrb->exc) { p(mrb, mrb_obj_value(mrb->exc)); mrb->exc = 0; } else { /* no */ printf(" => "); p(mrb, result); } } ruby_code[0] = '\0'; last_code_line[0] = '\0'; mrb_parser_free(parser); mrb_gc_arena_restore(mrb, ai); } } mrbc_context_free(mrb, cxt); mrb_close(mrb); return 0; }
int main(int argc, char **argv) { mrb_state *mrb = mrb_open(); int n = -1; int i; struct _args args; struct mrb_parser_state *p; n = parse_args(mrb, argc, argv, &args); if (n < 0 || (args.cmdline == NULL && args.rfp == NULL)) { cleanup(mrb, &args); usage(argv[0]); return n; } if (args.mrbfile) { n = mrb_load_irep(mrb, args.rfp); } else { if (args.cmdline) { p = mrb_parse_string(mrb, (char*)args.cmdline); } else { p = mrb_parser_new(mrb); if (p) { mrb_parser_filename(p, argv[1]); p->f = args.rfp; mrb_parser_parse(p); } } if (!p || !p->tree || p->nerr) { cleanup(mrb, &args); return -1; } if (args.verbose) parser_dump(mrb, p->tree, 0); n = mrb_generate_code(mrb, p->tree); mrb_pool_close(p->pool); } if (n >= 0) { mrb_value ARGV = mrb_ary_new(mrb); for (i = 0; i < args.argc; i++) { mrb_ary_push(mrb, ARGV, mrb_str_new(mrb, args.argv[i], strlen(args.argv[i]))); } mrb_define_global_const(mrb, "ARGV", ARGV); if (args.verbose) codedump_all(mrb, n); if (!args.check_syntax) { mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); if (mrb->exc) { mrb_p(mrb, mrb_obj_value(mrb->exc)); } } } cleanup(mrb, &args); return n > 0 ? 0 : 1; }