static int report(Lua.lua_State L, int status) { if ((status != 0) && !Lua.lua_isnil(L, -1)) { Lua.CharPtr msg = Lua.lua_tostring(L, -1); if (msg == null) msg = "(error object is not a string)"; l_message(progname, msg); Lua.lua_pop(L, 1); } return status; }
static void usage(Lua.CharPtr message) { if (message[0] == '-') Lua.fprintf(Lua.stderr, "%s: unrecognized option " + Lua.LUA_QS + "\n", progname, message); else Lua.fprintf(Lua.stderr, "%s: %s\n", progname, message); Lua.fprintf(Lua.stderr, "usage: %s [options] [filenames].\n" + "Available options are:\n" + " - process stdin\n" + " -l list\n" + " -o name output to file " + Lua.LUA_QL("name") + " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n", progname, Output); Environment.Exit(Lua.EXIT_FAILURE); }
static int traceback(Lua.LuaState L) { if (Lua.lua_isstring(L, 1) == 0) /* 'message' not a string? */ return 1; /* keep it intact */ Lua.lua_getfield(L, Lua.LUA_GLOBALSINDEX, "debug"); if (!Lua.lua_istable(L, -1)) { Lua.lua_pop(L, 1); return 1; } Lua.lua_getfield(L, -1, "traceback"); if (!Lua.lua_isfunction(L, -1)) { Lua.lua_pop(L, 2); return 1; } Lua.lua_pushvalue(L, 1); /* pass error message */ Lua.lua_pushinteger(L, 2); /* skip this function and traceback */ Lua.lua_call(L, 2, 1); /* call debug.traceback */ return 1; }
/// <summary> /// Did the write operation to the stream /// </summary> /// <param name="L">LuaState, which should be written.</param> /// <param name="p">CharPtr to char array with data. Only the byte is used.</param> /// <param name="sz">Size of the array.</param> /// <param name="ud">Memory stream, which is used.</param> /// <returns>Zero if all right.</returns> private int dumpWriter(Lua.LuaState L, Lua.CharPtr p, uint sz, object ud) { int result = 0; MemoryStream ms = (MemoryStream)ud; foreach (char c in p.chars) ms.WriteByte((byte)c); return result; }
static void cannot(Lua.CharPtr what) { Lua.fprintf(Lua.stderr, "%s: cannot %s %s: %s\n", progname, what, output, Lua.strerror(Lua.errno())); Environment.Exit(Lua.EXIT_FAILURE); }
static int pmain(Lua.LuaState L) { Smain s = (Smain)Lua.lua_touserdata(L, 1); int argc = s.argc; string[] argv = s.argv; Lua.Proto f; int i; if (Lua.lua_checkstack(L, argc) == 0) fatal("too many input files"); for (i = 0; i < argc; i++) { Lua.CharPtr filename = (Lua.strcmp(argv[i], "-") == 0) ? null : argv[i]; //try //{ // Lexer l = new Lexer(); // Parser p = new Parser(l.Lex(System.IO.File.ReadAllText(filename))); // Ast.Chunk c = p.Parse(); //Console.WriteLine(vars.Count); //foreach (Tuple<Ast.Variable, Ast.Variable> v in Refactoring.FindMisspelledVariables(c)) //{ // Console.WriteLine("Warning: Possible misspelled variable: " + v.Item1.Name + " is close to " + v.Item2.Name); // Console.Write("\t"); // if (v.Item1.References > v.Item2.References) // Console.WriteLine(v.Item1.Name + " is the best match with" + v.Item1.References + " references"); // else if (v.Item1.References < v.Item2.References) // Console.WriteLine(v.Item2.Name + " is the best match with" + v.Item2.References + " references"); // else // Console.WriteLine("Both have the same amount of references (" + v.Item1.References + ")!"); // //} //foreach (Ast.Variable v in Refactoring.FindUnusedVariables(c)) // Console.WriteLine("Warning: Unused variable '" + v.Name + "'"); //Refactoring.FindReferencesBeforeDefinition(c); //} //catch (System.Exception ex) //{ // System.Diagnostics.Debug.WriteLine(ex.ToString()); //} if (Lua.luaL_loadfile(L, filename) != 0) { fatal(Lua.lua_tostring(L, -1)); } } f = combine(L, argc); if (listing != 0) Lua.luaU_print(f, (listing > 1) ? 1 : 0); if (dumping != 0) { Stream D = (output == null) ? Lua.stdout : Lua.fopen(output, "wb"); if (D == null) cannot("open"); Lua.lua_lock(L); Lua.luaU_dump(L, f, writer, D, stripping); Lua.lua_unlock(L); if (Lua.ferror(D) != 0) cannot("write"); if (Lua.fclose(D) != 0) cannot("close"); } return 0; }
static Lua.Proto combine(Lua.LuaState L, int n) { if (n == 1) return toproto(L, -1); else { int i, pc; Lua.Proto f = Lua.luaF_newproto(L); Lua.setptvalue2s(L, L.top, f); Lua.incr_top(L); f.source = Lua.luaS_newliteral(L, "=(" + PROGNAME + ")"); f.maxstacksize = 1; pc = 2 * n + 1; f.code = (Instruction[])Lua.luaM_newvector<Instruction>(L, pc); f.sizecode = pc; f.p = Lua.luaM_newvector<Lua.Proto>(L, n); f.sizep = n; pc = 0; for (i = 0; i < n; i++) { f.p[i] = toproto(L, i - n - 1); f.code[pc++] = (uint)Lua.CREATE_ABx(Lua.OpCode.OP_CLOSURE, 0, i); f.code[pc++] = (uint)Lua.CREATE_ABC(Lua.OpCode.OP_CALL, 0, 1, 1); } f.code[pc++] = (uint)Lua.CREATE_ABC(Lua.OpCode.OP_RETURN, 0, 1, 0); return f; } }
static int pmain(Lua.lua_State L) { Smain s = (Smain)Lua.lua_touserdata(L, 1); int argc = s.argc; string[] argv = s.argv; Lua.Proto f; int i; if (Lua.lua_checkstack(L, argc) == 0) fatal("too many input files"); for (i = 0; i < argc; i++) { Lua.CharPtr filename = (Lua.strcmp(argv[i], "-") == 0) ? null : argv[i]; if (Lua.luaL_loadfile(L, filename) != 0) fatal(Lua.lua_tostring(L, -1)); } f = combine(L, argc); if (listing != 0) Lua.luaU_print(f, (listing > 1) ? 1 : 0); if (dumping != 0) { Stream D = (output == null) ? Lua.stdout : Lua.fopen(output, "wb"); if (D == null) cannot("open"); Lua.lua_lock(L); Lua.luaU_dump(L, f, writer, D, stripping); Lua.lua_unlock(L); if (Lua.ferror(D) != 0) cannot("write"); if (Lua.fclose(D) != 0) cannot("close"); } return 0; }
static int pmain(Lua.LuaState L) { Smain s = (Smain)Lua.lua_touserdata(L, 1); string[] argv = s.argv; int script; int has_i = 0, has_v = 0, has_e = 0; globalL = L; if ((argv.Length > 0) && (argv[0] != "")) progname = argv[0]; Lua.lua_gc(L, Lua.LUA_GCSTOP, 0); /* stop collector during initialization */ Lua.luaL_openlibs(L); /* open libraries */ Lua.lua_gc(L, Lua.LUA_GCRESTART, 0); s.status = handle_luainit(L); if (s.status != 0) return 0; script = collectargs(argv, ref has_i, ref has_v, ref has_e); if (script < 0) { /* invalid args? */ print_usage(); s.status = 1; return 0; } if (has_v != 0) print_version(); s.status = runargs(L, argv, (script > 0) ? script : s.argc); if (s.status != 0) return 0; if (script != 0) s.status = handle_script(L, argv, script); if (s.status != 0) return 0; if (has_i != 0) dotty(L); else if ((script == 0) && (has_e == 0) && (has_v == 0)) { if (Lua.lua_stdin_is_tty() != 0) { print_version(); dotty(L); } else dofile(L, null); /* executes stdin as a file */ } return 0; }
static int dolibrary(Lua.LuaState L, Lua.CharPtr name) { Lua.lua_getglobal(L, "require"); Lua.lua_pushstring(L, name); return report(L, docall(L, 1, 1)); }
static int dostring(Lua.LuaState L, Lua.CharPtr s, Lua.CharPtr name) { int status = (Lua.luaL_loadbuffer(L, s, (uint)Lua.strlen(s), name) != 0) || (docall(L, 0, 1) != 0) ? 1 : 0; return report(L, status); }
static int dofile(Lua.LuaState L, Lua.CharPtr name) { int status = (Lua.luaL_loadfile(L, name) != 0) || (docall(L, 0, 1) != 0) ? 1 : 0; return report(L, status); }
static int getargs(Lua.LuaState L, string[] argv, int n) { int narg; int i; int argc = argv.Length; /* count total number of arguments */ narg = argc - (n + 1); /* number of arguments to the script */ Lua.luaL_checkstack(L, narg + 3, "too many arguments to script"); for (i = n + 1; i < argc; i++) Lua.lua_pushstring(L, argv[i]); Lua.lua_createtable(L, narg, n + 1); for (i = 0; i < argc; i++) { Lua.lua_pushstring(L, argv[i]); Lua.lua_rawseti(L, -2, i - n); } return narg; }
static int docall(Lua.LuaState L, int narg, int clear) { int status; int base_ = Lua.lua_gettop(L) - narg; /* function index */ Lua.lua_pushcfunction(L, traceback); /* push traceback function */ Lua.lua_insert(L, base_); /* put it under chunk and args */ //signal(SIGINT, laction); status = Lua.lua_pcall(L, narg, ((clear != 0) ? 0 : Lua.LUA_MULTRET), base_); //signal(SIGINT, SIG_DFL); Lua.lua_remove(L, base_); /* remove traceback function */ /* force a complete garbage collection in case of errors */ if (status != 0) Lua.lua_gc(L, Lua.LUA_GCCOLLECT, 0); return status; }
public object getNull(Lua.LuaState luaState, int stackPos) { if (LuaDLL.lua_isnil(luaState, stackPos)) return null; else { Debug.WriteLine("Value isn't nil!"); return null; } }
static int runargs(Lua.LuaState L, string[] argv, int n) { int i; for (i = 1; i < n; i++) { if (argv[i] == null) continue; Lua.lua_assert(argv[i][0] == '-'); switch (argv[i][1]) { /* option */ case 'e': { string chunk = argv[i].Substring(2); if (chunk == "") chunk = argv[++i]; Lua.lua_assert(chunk != null); if (dostring(L, chunk, "=(command line)") != 0) return 1; break; } case 'l': { string filename = argv[i].Substring(2); if (filename == "") filename = argv[++i]; Lua.lua_assert(filename != null); if (dolibrary(L, filename) != 0) return 1; /* stop if file fails */ break; } default: break; } } return 0; }
static int handle_luainit(Lua.LuaState L) { Lua.CharPtr init = Lua.getenv(Lua.LUA_INIT); if (init == null) return 0; /* status OK */ else if (init[0] == '@') return dofile(L, init + 1); else return dostring(L, init, "=" + Lua.LUA_INIT); }
static Lua.CharPtr get_prompt(Lua.LuaState L, int firstline) { Lua.CharPtr p; Lua.lua_getfield(L, Lua.LUA_GLOBALSINDEX, (firstline != 0) ? "_PROMPT" : "_PROMPT2"); p = Lua.lua_tostring(L, -1); if (p == null) p = ((firstline != 0) ? Lua.LUA_PROMPT : Lua.LUA_PROMPT2); Lua.lua_pop(L, 1); /* remove global */ return p; }
static void l_message(Lua.CharPtr pname, Lua.CharPtr msg) { if (pname != null) Lua.fprintf(Lua.stderr, "%s: ", pname); Lua.fprintf(Lua.stderr, "%s\n", msg); Lua.fflush(Lua.stderr); }
static int incomplete(Lua.LuaState L, int status) { if (status == Lua.LUA_ERRSYNTAX) { uint lmsg; Lua.CharPtr msg = Lua.lua_tolstring(L, -1, out lmsg); Lua.CharPtr tp = msg + lmsg - (Lua.strlen(Lua.LUA_QL("<eof>"))); if (Lua.strstr(msg, Lua.LUA_QL("<eof>")) == tp) { Lua.lua_pop(L, 1); return 1; } } return 0; /* else... */ }
static Lua.Proto Pget(Lua.LuaState L, int i) { if (Lua.lua_isuserdata(L, i) == 1) return (Lua.Proto)Lua.lua_touserdata(L, i); if (!Lua.lua_isfunction(L, i) || Lua.lua_iscfunction(L, i)) { return null; //Lua.luaL_typerror(L, i, "Lua function"); } return ((Lua.Closure)Lua.lua_topointer(L, i)).l.p; }
static int pushline(Lua.LuaState L, int firstline) { Lua.CharPtr buffer = new char[Lua.LUA_MAXINPUT]; Lua.CharPtr b = new Lua.CharPtr(buffer); int l; Lua.CharPtr prmt = get_prompt(L, firstline); if (!Lua.lua_readline(L, b, prmt)) return 0; /* no input */ l = Lua.strlen(b); if (l > 0 && b[l - 1] == '\n') /* line ends with newline? */ b[l - 1] = '\0'; /* remove it */ if ((firstline != 0) && (b[0] == '=')) /* first line starts with `=' ? */ Lua.lua_pushfstring(L, "return %s", b + 1); /* change it to `return' */ else Lua.lua_pushstring(L, b); Lua.lua_freeline(L, b); return 1; }
static Lua.Proto toproto(Lua.LuaState L, int i) { return Lua.clvalue(L.top + (i)).l.p; }
static int loadline(Lua.LuaState L) { int status; Lua.lua_settop(L, 0); if (pushline(L, 1) == 0) return -1; /* no input */ for (; ; ) { /* repeat until gets a complete line */ status = Lua.luaL_loadbuffer(L, Lua.lua_tostring(L, 1), Lua.lua_strlen(L, 1), "=stdin"); if (incomplete(L, status) == 0) break; /* cannot try to add lines? */ if (pushline(L, 0) == 0) /* no more input? */ return -1; Lua.lua_pushliteral(L, "\n"); /* add a new line... */ Lua.lua_insert(L, -2); /* ...between the two lines */ Lua.lua_concat(L, 3); /* join them */ } Lua.lua_saveline(L, 1); Lua.lua_remove(L, 1); /* remove line */ return status; }
static int writer(Lua.LuaState L, Lua.CharPtr p, uint size, object u) { //UNUSED(L); return ((Lua.fwrite(p, (int)size, 1, (Stream)u) != 1) && (size != 0)) ? 1 : 0; }
static void dotty(Lua.LuaState L) { int status; Lua.CharPtr oldprogname = progname; progname = null; while ((status = loadline(L)) != -1) { if (status == 0) status = docall(L, 0, 0); report(L, status); if (status == 0 && Lua.lua_gettop(L) > 0) { /* any result to print? */ Lua.lua_getglobal(L, "print"); Lua.lua_insert(L, 1); if (Lua.lua_pcall(L, Lua.lua_gettop(L) - 1, 0, 0) != 0) l_message(progname, Lua.lua_pushfstring(L, "error calling " + Lua.LUA_QL("print").ToString() + " (%s)", Lua.lua_tostring(L, -1))); } } Lua.lua_settop(L, 0); /* clear stack */ Lua.fputs("\n", Lua.stdout); Lua.fflush(Lua.stdout); progname = oldprogname; }
static Lua.CharPtr progname = PROGNAME; /* actual program name */ static void fatal(Lua.CharPtr message) { Lua.fprintf(Lua.stderr, "%s: %s\n", progname, message); Environment.Exit(Lua.EXIT_FAILURE); }
static int handle_script(Lua.LuaState L, string[] argv, int n) { int status; Lua.CharPtr fname; int narg = getargs(L, argv, n); /* collect arguments */ Lua.lua_setglobal(L, "arg"); fname = argv[n]; if (Lua.strcmp(fname, "-") == 0 && Lua.strcmp(argv[n - 1], "--") != 0) fname = null; /* stdin */ status = Lua.luaL_loadfile(L, fname); Lua.lua_insert(L, -(narg + 1)); if (status == 0) status = docall(L, narg, 0); else Lua.lua_pop(L, narg); return report(L, status); }
static void lstop(Lua.LuaState L, Lua.lua_Debug ar) { Lua.lua_sethook(L, null, 0, 0); Lua.luaL_error(L, "interrupted!"); }
/// <summary> /// Write the compiled Lua binary to the memory stream output. /// </summary> /// <param name="L">LuaState of the functions, which should be written.</param> /// <param name="output">Memory stream which the binary code should be written to.</param> /// <returns>Status of the operation (0 = ok). </returns> private int dumpCode(Lua.LuaState L, MemoryStream output) { int status; Lua.lua_lock(L); Lua.Proto f = Lua.clvalue(L.top).l.p; Lua.api_checknelems(L, 1); Lua.lua_TValue o = L.top - 1; status = Lua.luaU_dump(L, f, dumpWriter, output, 0); Lua.lua_unlock(L); return status; }