Skip to content

Instantly share code, notes, and snippets.

@skandhas
Forked from mattn/mruby.cxx
Created December 27, 2012 13:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save skandhas/4388515 to your computer and use it in GitHub Desktop.
Save skandhas/4388515 to your computer and use it in GitHub Desktop.
#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