From 9523e367f18550c44597c11a5584545bc23c53bc Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Fri, 13 Nov 2020 15:18:09 -0500 Subject: [PATCH] Better organized --- luprex/build.bat | 2 +- luprex/{main.cxx => syscpp/main.cpp} | 46 +++++++++++++++------ luprex/syscpp/moretable.cpp | 0 luprex/syscpp/util.cpp | 35 ++++++++++++++++ luprex/syscpp/util.hpp | 33 +++++++++++++++ luprex/syslua/classdb.lua | 42 +++++++++++++++++++ luprex/syslua/control.lst | 10 +++++ luprex/{ => syslua}/inspect.lua | 61 ++++++++++++++-------------- luprex/{ => syslua}/main.lua | 55 +------------------------ luprex/syslua/tableutil.lua | 21 ++++++++++ 10 files changed, 207 insertions(+), 98 deletions(-) rename luprex/{main.cxx => syscpp/main.cpp} (85%) create mode 100644 luprex/syscpp/moretable.cpp create mode 100644 luprex/syscpp/util.cpp create mode 100644 luprex/syscpp/util.hpp create mode 100644 luprex/syslua/classdb.lua create mode 100644 luprex/syslua/control.lst rename luprex/{ => syslua}/inspect.lua (85%) rename luprex/{ => syslua}/main.lua (52%) create mode 100644 luprex/syslua/tableutil.lua diff --git a/luprex/build.bat b/luprex/build.bat index 54027053..71ac8719 100644 --- a/luprex/build.bat +++ b/luprex/build.bat @@ -1 +1 @@ -g++ -g -o main main.cxx -Iinc -Llib lib/libluajit.a +g++ -std=c++17 -g -o main syscpp/util.cpp syscpp/main.cpp -Iinc -Llib lib/libluajit-dbg.a -Isyscpp diff --git a/luprex/main.cxx b/luprex/syscpp/main.cpp similarity index 85% rename from luprex/main.cxx rename to luprex/syscpp/main.cpp index 80492461..06a5b29e 100644 --- a/luprex/main.cxx +++ b/luprex/syscpp/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include extern "C" { #include "lua.h" @@ -17,7 +18,10 @@ extern "C" { #include "luajit.h" } -#include +#include +#include +#include "util.hpp" + // Add another error status. #define LUA_PARTIAL (LUA_ERRERR + 10) @@ -25,6 +29,7 @@ extern "C" { static lua_State *globalL = NULL; + static void lstop(lua_State *L, lua_Debug *ar) { (void)ar; /* unused arg. */ @@ -189,15 +194,24 @@ static void dotty(lua_State *L) fflush(stdout); } -static int loadmain(lua_State *L) +static void loadmain(lua_State *L) { - int status = luaL_loadfilex(L, "main.lua", NULL); - if (status == LUA_OK) - { - status = docall(L, 0, 0); + util::stringvec filenames = util::trim_and_uncomment(util::read_lines("syslua/control.lst")); + if (filenames.empty()) { + lua_pushfstring(L, "Cannot read syslua/control.lst"); + lua_error(L); + } + + for (const auto &fn : filenames) { + std::string full = "syslua/" + fn; + int status = luaL_loadfilex(L, full.c_str(), NULL); + if (status == LUA_OK) { + status = docall(L, 0, 0); + } + if (status != LUA_OK) { + lua_error(L); + } } - report(L, status); - return status; } static int pmain(lua_State *L) @@ -207,13 +221,19 @@ static int pmain(lua_State *L) LUAJIT_VERSION_SYM(); /* Linker-enforced version check. */ lua_gc(L, LUA_GCSTOP, 0); - luaL_openlibs(L); + luaopen_base(L); + // luaopen_package(L); // Omitted because we use our own package system. + luaopen_table(L); + // luaopen_io(L); // Not safe for the sandbox. + // luaopen_os(L); // Not safe for the sandbox. + luaopen_string(L); + luaopen_math(L); + // luaopen_debug(L); // Not safe for the sandbox. + luaopen_bit(L); + // luaopen_jit(L); // Don't know what it's for. lua_gc(L, LUA_GCRESTART, -1); - int status = loadmain(L); - if (status != LUA_OK) { - return status; - } + loadmain(L); dotty(L); return 0; diff --git a/luprex/syscpp/moretable.cpp b/luprex/syscpp/moretable.cpp new file mode 100644 index 00000000..e69de29b diff --git a/luprex/syscpp/util.cpp b/luprex/syscpp/util.cpp new file mode 100644 index 00000000..96a68c9e --- /dev/null +++ b/luprex/syscpp/util.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include "util.hpp" + +namespace util { + +// Read a file as lines. +const stringvec read_lines(const std::string &path) { + stringvec result; + std::ifstream f; + f.open(path); + if (f) { + std::string line; + while (std::getline(f, line)) { + result.push_back(line); + } + f.close(); + } + return result; +} + +// Strip leading and trailing whitespace and comments. +const stringvec trim_and_uncomment(const stringvec &lines) { + stringvec result; + for (int i = 0; i < lines.size(); i++) { + std::string trimmed = trim(lines[i]); + if ((trimmed.size() > 0) && (trimmed[0] != '#')) { + result.push_back(trimmed); + } + } + return result; +} + +} // namespace util diff --git a/luprex/syscpp/util.hpp b/luprex/syscpp/util.hpp new file mode 100644 index 00000000..0ae58b9c --- /dev/null +++ b/luprex/syscpp/util.hpp @@ -0,0 +1,33 @@ +#ifndef UTIL_HPP + +#include +#include + +namespace util { + +using stringvec = std::vector; + +// trim from start +static inline std::string ltrim(std::string s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), + std::not1(std::ptr_fun(std::isspace)))); + return s; +} + +// trim from end +static inline std::string rtrim(std::string s) { + s.erase(std::find_if(s.rbegin(), s.rend(), + std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + return s; +} + +// trim from both ends +static inline std::string trim(std::string s) { + return ltrim(rtrim(s)); +} + +const stringvec read_lines(const std::string &path); +const stringvec trim_and_uncomment(const stringvec &lines); + +} // namespace util +#endif // UTIL_HPP diff --git a/luprex/syslua/classdb.lua b/luprex/syslua/classdb.lua new file mode 100644 index 00000000..9d489d6e --- /dev/null +++ b/luprex/syslua/classdb.lua @@ -0,0 +1,42 @@ + +classdb = table.coerce(classdb) + +-- classdb.create: creates a new class database. +function classdb.create() + return {} +end + +-- Given a class database, removes all the functions that have +-- been inserted into it, but keeps the class and action tables. +function classdb.reset(db) + for name,maybeclass in pairs(db) do + local class = table.coerce(maybeclass) + local action = table.coerce(rawget(class, "action")) + table.rawclear(class) + table.rawclear(action) + rawset(db, name, class) + class.action = action + class.__index = class + class.__class = name + end +end + +-- Given a class_db, makes an accessor that fetches classes +-- from that class db. +function classdb.accessor(db) + return function(name) + local class = rawget(db, name) + if type(class) ~= "table" then + class = {} + rawset(db, name, class) + class.action = {} + class.__index = class + class.__class = name + end + return class + end +end + +-- Make a global class database to use for the super. +classdb.database = {} +class = classdb.accessor(classdb.database) diff --git a/luprex/syslua/control.lst b/luprex/syslua/control.lst new file mode 100644 index 00000000..a3d58638 --- /dev/null +++ b/luprex/syslua/control.lst @@ -0,0 +1,10 @@ +# +# A listing of all the lua files in the control directory, +# in the order that they're supposed to be loaded. +# + +tableutil.lua +classdb.lua +inspect.lua +main.lua + diff --git a/luprex/inspect.lua b/luprex/syslua/inspect.lua similarity index 85% rename from luprex/inspect.lua rename to luprex/syslua/inspect.lua index e2e3806e..4d24b6c4 100644 --- a/luprex/inspect.lua +++ b/luprex/syslua/inspect.lua @@ -1,32 +1,34 @@ -local inspect ={ - _VERSION = 'inspect.lua 3.1.0', - _URL = 'http://github.com/kikito/inspect.lua', - _DESCRIPTION = 'human-readable representations of tables', - _LICENSE = [[ - MIT LICENSE +-- +-- inspect.lua 3.1.0 +-- http://github.com/kikito/inspect.lua +-- human-readable representations of tables +-- +-- Modified by J. Yelon to work with our package and doc-gen system. +-- +-- MIT LICENSE +-- Copyright (c) 2013 Enrique García Cota +-- +-- Permission is hereby granted, free of charge, to any person obtaining a +-- copy of this software and associated documentation files (the +-- "Software"), to deal in the Software without restriction, including +-- without limitation the rights to use, copy, modify, merge, publish, +-- distribute, sublicense, and/or sell copies of the Software, and to +-- permit persons to whom the Software is furnished to do so, subject to +-- the following conditions: +-- +-- The above copyright notice and this permission notice shall be included +-- in all copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-- - Copyright (c) 2013 Enrique García Cota - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ]] -} +local inspect = class('inspect') local tostring = tostring @@ -51,6 +53,7 @@ local shortControlCharEscapes = { ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v" } + local longControlCharEscapes = {} -- \a => nil, \0 => \000, 31 => \031 for i=0, 31 do local ch = string.char(i) @@ -330,5 +333,3 @@ end setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end }) -return inspect - diff --git a/luprex/main.lua b/luprex/syslua/main.lua similarity index 52% rename from luprex/main.lua rename to luprex/syslua/main.lua index 1f061adc..6b247041 100644 --- a/luprex/main.lua +++ b/luprex/syslua/main.lua @@ -1,57 +1,4 @@ -inspect = require("inspect") - - --- If t is a table, return it. If not, return a blank table. -function forcetable(t) - if type(t) == "table" then - return t - else - return {} - end -end - --- Clear the table out. Deletes all keys, removes any metatable. --- TODO: this doesn't work on tables that have __metatable metamethod. -function rawclear(t) - for k in pairs(t) do - rawset(t, k, nil) - end - setmetatable(t, nil) - return t -end - --- given a class database, removes all the functions that have --- been inserted into it, but keeps the class and action tables. -function reset_class_db(db) - for name,maybeclass in pairs(db) do - local class = forcetable(maybeclass) - local action = forcetable(rawget(class, "action")) - rawclear(class) - rawclear(action) - rawset(db, name, class) - class.action = action - class.__index = class - class.__class = name - end -end - --- Given a class_db, makes an accessor that fetches classes --- from that class db. -function make_class_accessor(db) - return function(name) - local class = rawget(db, name) - if type(class) ~= "table" then - class = {} - rawset(db, name, class) - class.action = {} - class.__index = class - class.__class = name - end - return class - end -end - -- given a global_db, makes an accessor that fetches named -- tables from that global_db. function make_global_accessor(db) @@ -90,7 +37,7 @@ function make_world_model() meta.tangible_db = {} meta.__newindex = function() error("Global environment is read-only") end -- meta.__metatable = false - genv.class = make_class_accessor(meta.class_db) + genv.class = classdb.accessor(meta.class_db) genv.global = make_global_accessor(meta.global_db) for i,name in ipairs(sandbox_list) do genv[name] = _G[name] diff --git a/luprex/syslua/tableutil.lua b/luprex/syslua/tableutil.lua new file mode 100644 index 00000000..01fc3204 --- /dev/null +++ b/luprex/syslua/tableutil.lua @@ -0,0 +1,21 @@ + +-- Coerce T to be a table. +-- If T is a table, return it. If not, return a blank table. +function table.coerce(t) + if type(t) == "table" then + return t + else + return {} + end +end + +-- Clear the table out. Deletes all keys, removes any metatable. +-- TODO: this doesn't work on tables that have __metatable metamethod. +function table.rawclear(t) + for k in pairs(t) do + rawset(t, k, nil) + end + setmetatable(t, nil) + return t +end +