Browse files

Yoink! Steal and refactor code from lib/mruby/tools/mirb/mirb.c like …

…a boss. 8-)
  • Loading branch information...
1 parent e7fc65c commit eb161ed54a3133dee7d9d6f77f33c775ce8b7d89 @RyanScottLewis committed Dec 24, 2012
Showing with 100 additions and 51 deletions.
  1. +100 −51 lib/lua-mruby.c
View
151 lib/lua-mruby.c
@@ -2,68 +2,91 @@
#include <lualib.h>
#include <lauxlib.h>
-#include "mruby.h"
-#include "mruby/proc.h"
-#include "mruby/compile.h"
-
+#include <string.h> # TODO: Is this needed?
+
+#include <mruby.h>
+#include <mruby/proc.h>
+#include <mruby/data.h>
+#include <mruby/compile.h>
+
+#ifndef ENABLE_STDIO
+#include <mruby/string.h>
+static void p(mrb_state *mrb, mrb_value obj) {
+ obj = mrb_funcall(mrb, obj, "inspect", 0);
+ fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
+ putc('\n', stdout);
+}
+#else
+#define p(mrb,obj) mrb_p(mrb,obj)
+#endif
-# NOTE: lib/mruby/tools/mirb.c has almost all this functionality created by someone way better
-# at this than I am. Pull code from there into here. =)
static int lua_mruby_run(lua_State *L) {
- mrb_state *mrb_interpreter = mrb_open();
- const char *mrb_code = lua_tostring(L, 1);
- struct mrb_parser_state *mrb_parser = mrb_parser_new(mrb_interpreter);
- mrbc_context *mrb_context;
- mrb_value mrb_return_value;
-
- mrb_context = mrbc_context_new(mrb_interpreter);
- mrb_context->capture_errors = 1;
+ mrbc_context *lua_mrb_context;
+ struct mrb_parser_state *lua_mrb_parser;
+ mrb_state *lua_mrb_state;
+ mrb_value lua_mrb_result;
+ int lua_mrb_bytecode;
- // Parse the code - TODO: Convert into function
- mrb_parser->s = mrb_code;
- mrb_parser->send = mrb_code + strlen(mrb_code);
- mrb_parser->capture_errors = 1;
- mrb_parser->lineno = 1;
+ // Convert the Lua function's first argument into a char array
+ const char *lua_mrb_code = lua_tostring(L, 1); // TODO: Is the `const` needed?
+
+ // Create new MRuby interpreter
+ lua_mrb_state = mrb_open();
+ if (lua_mrb_state == NULL) {
+ fprintf(stderr, "Invalid mrb interpreter, exiting mirb");
+ return EXIT_FAILURE;
+ }
- mrb_parser_parse(mrb_parser, mrb_context);
+ // Create new MRuby context
+ lua_mrb_context = mrbc_context_new(lua_mrb_state);
+ lua_mrb_context->capture_errors = 1;
- if (0 < mrb_parser->nerr) {
- printf("%d\n", mrb_parser->nerr);
- // Check for parser error - TODO: Convert into function
- char *mrb_error_message;
- size_t sz;
- sz = snprintf(NULL, 0, "line %d: %s\n", mrb_parser->error_buffer[0].lineno, mrb_parser->error_buffer[0].message);
- mrb_error_message = malloc(sz + 1); /* make sure you check for != NULL in real code */
- snprintf(mrb_error_message, sz+1, "line %d: %s\n", mrb_parser->error_buffer[0].lineno, mrb_parser->error_buffer[0].message);
+ // Create new MRuby parser
+ lua_mrb_parser = mrb_parser_new(lua_mrb_state);
+ lua_mrb_parser->s = lua_mrb_code;
+ lua_mrb_parser->send = lua_mrb_code + strlen(lua_mrb_code);
+ lua_mrb_parser->lineno = 1;
+
+ // Parse MRuby code string from Lua
+ mrb_parser_parse(lua_mrb_parser, lua_mrb_context);
+
+ if (0 < lua_mrb_parser->nerr) {
+ // MRuby syntax error
+ printf("line %d: %s\n", lua_mrb_parser->error_buffer[0].lineno, lua_mrb_parser->error_buffer[0].message);
+ } else {
+ // Generate MRuby bytecode
+ lua_mrb_bytecode = mrb_generate_code(lua_mrb_state, lua_mrb_parser);
- lua_pushstring(L, mrb_error_message);
- } else {
- // TODO: Convert into function:
- // Generate bytecode
- int mrb_byte_code = mrb_generate_code(mrb_interpreter, mrb_parser);
- // Generate Proc from bytecode for evaulation
- struct RProc *mrb_proc = mrb_proc_new( mrb_interpreter, mrb_interpreter->irep[mrb_byte_code] );
- // Evaluate the bytecode
- mrb_return_value = mrb_run(mrb_interpreter, mrb_proc, mrb_nil_value());
- // Check for exception
- if (mrb_interpreter->exc) {
- mrb_p(mrb_interpreter, mrb_obj_value(mrb_interpreter->exc));
- mrb_interpreter->exc = 0;
- } else {
- int *lua_return = mrb_return_value.value.p;
- printf("%d\n", *lua_return);
- int lua_return_number = *lua_return > 0 ? 0 : 1;
- lua_pushnumber(L, lua_return_number);
- }
+ // Evaluate MRuby bytecode
+ lua_mrb_result = mrb_run(
+ lua_mrb_state,
+ mrb_proc_new( lua_mrb_state, lua_mrb_state->irep[lua_mrb_bytecode] ), /* pass a proc for eval */
+ mrb_top_self(lua_mrb_state)
+ );
+ if (lua_mrb_state->exc) { // Check for exception
+ p(lua_mrb_state, mrb_obj_value(lua_mrb_state->exc));
+ lua_mrb_state->exc = 0;
+ } else { // Pass the MRuby result to Lua
+
+ // TODO: Function to figure out exactly what the MRuby lua_mrb_result is and push
+ // that object to the Lua stack
+
+ // int *lua_return = lua_mrb_result.value.p;
+ // printf("%d\n", *lua_return);
+ // int lua_return_number = *lua_return > 0 ? 0 : 1;
+ // lua_pushnumber(L, lua_return_number);
+ //
+ // p(lua_mrb_state, result);
+ }
}
- mrb_parser_free(mrb_parser);
- mrbc_context_free(mrb_interpreter, mrb_context);
- mrb_close(mrb_interpreter);
+ mrb_parser_free(lua_mrb_parser);
+ mrbc_context_free(lua_mrb_state, lua_mrb_context);
+ mrb_close(lua_mrb_state);
- return 1;
+ return 0;
}
static const struct luaL_reg mrubylib[] = {
@@ -76,6 +99,32 @@ static const struct luaL_reg mrubylib[] = {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
////////////////////////////////////////
//// EXAMPLE OF PUSHING STRUCT TO LUA //
////////////////////////////////////////

0 comments on commit eb161ed

Please sign in to comment.