-
-
Save skandhas/4388515 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef mruby_hpp | |
#define mruby_hpp | |
#include "mruby.h" | |
#include "mruby/proc.h" | |
#include "mruby/array.h" | |
#include "mruby/string.h" | |
#include "mruby/compile.h" | |
#include "mruby/dump.h" | |
#include "mruby/variable.h" | |
#include <string> | |
#include <iostream> | |
#include <stdexcept> | |
namespace mruby { | |
class value : mrb_value { | |
protected: | |
const mrb_state* mrb; | |
mrb_value v; | |
value() : mrb(nullptr), v(mrb_nil_value()) { } | |
public: | |
const mrb_value operator* () const { | |
return v; | |
} | |
value operator= (const value& v) { | |
this->v = v.v; | |
return *this; | |
} | |
value(const value& v) : mrb(v.mrb), v(v.v) { } | |
value(const mrb_state* mrb, const mrb_value& v) : mrb(mrb), v(v) { } | |
const std::string inspect() { | |
mrb_value r = mrb_funcall((mrb_state*) mrb, v, "inspect", 0); | |
return std::string(RSTRING_PTR(r), RSTRING_LEN(r)); | |
} | |
}; | |
class array : value { | |
public: | |
void push(const value& v) { | |
// TODO | |
} | |
}; | |
class context : mrbc_context { | |
mrb_state* mrb; | |
mrbc_context* context_; | |
public: | |
context(mrb_state* mrb) : mrb(mrb) { | |
context_ = mrbc_context_new((mrb_state*) mrb); | |
context_->capture_errors = 1; | |
} | |
~context() { | |
mrbc_context_free((mrb_state*) mrb, (mrbc_context*) context_); | |
} | |
const mrbc_context* operator* () const { | |
return context_; | |
} | |
value load_string(const std::string& expr) { | |
return value(mrb, mrb_load_string_cxt((mrb_state*) mrb, expr.c_str(), (mrbc_context*) context_)); | |
} | |
const char* filename(const char* fname) { | |
mrbc_filename((mrb_state*) mrb, (mrbc_context*) context_, fname); | |
} | |
value run(const std::string& expr) { | |
context_ = mrbc_context_new(mrb); | |
struct mrb_parser_state *parser; | |
parser = mrb_parser_new((mrb_state*) mrb); | |
parser->s = expr.c_str(); | |
parser->send = expr.c_str() + expr.size(); | |
parser->lineno = 1; | |
mrb_parser_parse(parser, (mrbc_context*) context_); | |
int n = mrb_generate_code((mrb_state*) mrb, parser); | |
mrb_parser_free(parser); | |
mrb_value r = mrb_run( | |
(mrb_state*) mrb, | |
mrb_proc_new((mrb_state*) mrb, | |
mrb->irep[n]), | |
mrb_top_self((mrb_state*) mrb)); | |
if (mrb->exc) { | |
r = mrb_funcall((mrb_state*) mrb, mrb_obj_value(mrb->exc), "inspect", 0); | |
mrb->exc = 0; | |
throw std::runtime_error(RSTRING_PTR(r)); | |
} | |
return value(mrb, r); | |
} | |
}; | |
class state : mrb_state { | |
mrb_state* mrb; | |
public: | |
state() { | |
mrb = mrb_open(); | |
} | |
~state() { | |
mrb_close(mrb); | |
} | |
const mrb_state* operator* () const { | |
return mrb; | |
} | |
void define_global_const(const char* name, const value& v) const { | |
mrb_define_global_const(mrb, name, *v); | |
} | |
const value new_array() const { | |
return value(mrb, mrb_ary_new(mrb)); | |
} | |
const context new_context() const { | |
return context(mrb); | |
} | |
const value funcall(const value& v, const char* name, int argc, value* argv) { | |
mrb_value* av = new mrb_value[argc]; | |
for (int n = 0; n < argc; n++) { | |
av[n] = *argv[n]; | |
} | |
value r = value(mrb, mrb_funcall_argv(mrb, (mrb_value) *v, mrb_intern(mrb, name), argc, av)); | |
delete[] av; | |
return r; | |
} | |
}; | |
} | |
int | |
main() { | |
mruby::state s; | |
mruby::context c = s.new_context(); | |
mruby::value ary = s.new_array(); | |
s.define_global_const("A", ary); | |
c.run("A.push 1"); | |
c.run("A.push 2"); | |
c.run("A.push 3"); | |
mruby::value v = c.run("A"); | |
std::cout << v.inspect() << std::endl; | |
return 0; | |
} | |
#endif /* mruby_hpp */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment