示例#1
0
文件: eval.c 项目: deweerdt/h2o
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;
}
示例#2
0
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;
  int code_block_open = FALSE;
  int ai;

  /* 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 */
        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), 0);
          mrb->exc = 0;
        }
        else {
          /* no */
          if (!mrb_respond_to(mrb, result, mrb_intern2(mrb, "inspect", 7))){
            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
  write_history(history_path);
#endif

  return 0;
}
示例#3
0
文件: mruby.c 项目: daniel-higa/mruby
int
main(int argc, char **argv)
{
  mrb_state *mrb = mrb_open();
  int n = -1;
  int i;
  struct _args args;
  mrb_value ARGV;

  if (mrb == NULL) {
    fprintf(stderr, "Invalid mrb_state, exiting mruby\n");
    return EXIT_FAILURE;
  }

  n = parse_args(mrb, argc, argv, &args);
  if (n < 0 || (args.cmdline == NULL && args.rfp == NULL)) {
    cleanup(mrb, &args);
    usage(argv[0]);
    return n;
  }

  ARGV = mrb_ary_new_capa(mrb, args.argc);
  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.mrbfile) {
    n = mrb_load_irep(mrb, args.rfp);
    if (n < 0) {
      fprintf(stderr, "failed to load mrb file: %s\n", args.cmdline);
    }
    else if (!args.check_syntax) {
      mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
      n = 0;
      if (mrb->exc) {
        showcallinfo(mrb);
        p(mrb, mrb_obj_value(mrb->exc));
        n = -1;
      }
    }
  }
  else {
    mrbc_context *c = mrbc_context_new(mrb);
    mrb_value v;

    if (args.verbose)
      c->dump_result = 1;
    if (args.check_syntax)
      c->no_exec = 1;

    if (args.rfp) {
      mrbc_filename(mrb, c, args.cmdline ? args.cmdline : "-");
      v = mrb_load_file_cxt(mrb, args.rfp, c);
    }
    else {
      mrbc_filename(mrb, c, "-e");
      v = mrb_load_string_cxt(mrb, args.cmdline, c);
    }
    mrbc_context_free(mrb, c);
    if (mrb->exc) {
      if (!mrb_undef_p(v)) {
        showcallinfo(mrb);
        p(mrb, mrb_obj_value(mrb->exc));
      }
      n = -1;
    }
    else if (args.check_syntax) {
      printf("Syntax OK\n");
    }
  }
  cleanup(mrb, &args);

  return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
示例#4
0
文件: mirb.c 项目: koie/mruby
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 ? "* " : "> ");
    if(line == NULL) {
      printf("\n");
      break;
    }
    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(" => ");
          if (!mrb_respond_to(mrb,result,mrb_intern(mrb,"inspect"))){
            result = mrb_any_to_s(mrb,result);
          }
          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;
}