New calling conventions, start on print.cpp
This commit is contained in:
@@ -191,7 +191,7 @@ private:
|
||||
IdGlobalPool *global_;
|
||||
int fifo_capacity_;
|
||||
std::deque<int64_t> ranges_;
|
||||
friend int unittests_idalloc(lua_State *L);
|
||||
friend int lfn_unittests_idalloc(lua_State *L);
|
||||
};
|
||||
|
||||
#endif // IDALLOC_HPP
|
||||
|
||||
@@ -323,13 +323,6 @@ int LuaStack::rawlen(LuaSlot obj) const {
|
||||
return lua_rawlen(L_, obj.index());
|
||||
}
|
||||
|
||||
void LuaStack::check_nret(int xnret, int otop, int nret) const {
|
||||
int ntop = lua_gettop(L_);
|
||||
if ((nret != xnret)||(ntop != otop + xnret)) {
|
||||
luaL_error(L_, "expected %d return values", xnret);
|
||||
}
|
||||
}
|
||||
|
||||
int LuaStack::gettabletype(LuaSlot tab) const {
|
||||
uint16_t bits = lua_getflagbits(L_, tab.index());
|
||||
return LUA_TT_GENERAL + (bits & 0x000F);
|
||||
|
||||
@@ -319,38 +319,6 @@ private:
|
||||
void push_any_values() {
|
||||
}
|
||||
|
||||
// Call the CFunction, pushing and popping arguments appropriately.
|
||||
template<int NRET, typename... T>
|
||||
void call_cfunction(int otop, LuaSlot s, T... args) {
|
||||
call_cfunction<NRET+1>(otop, args...);
|
||||
pop_any_value(s);
|
||||
}
|
||||
template<int NRET, typename... T>
|
||||
void call_cfunction(int otop, lua_Integer &s, T... args) {
|
||||
call_cfunction<NRET+1>(otop, args...);
|
||||
pop_any_value(s);
|
||||
}
|
||||
template<int NRET, typename... T>
|
||||
void call_cfunction(int otop, lua_Number &s, T... args) {
|
||||
call_cfunction<NRET+1>(otop, args...);
|
||||
pop_any_value(s);
|
||||
}
|
||||
template<int NRET, typename... T>
|
||||
void call_cfunction(int otop, std::string &s, T... args) {
|
||||
call_cfunction<NRET+1>(otop, args...);
|
||||
pop_any_value(s);
|
||||
}
|
||||
template<int NRET, typename... T>
|
||||
void call_cfunction(int otop, lua_CFunction fn, T... args) {
|
||||
push_any_values(args...);
|
||||
int nret = fn(L_);
|
||||
check_nret(NRET, otop, nret);
|
||||
}
|
||||
|
||||
// Check number of return values: xpected number of return values,
|
||||
// original stack top, and number of declared return values.
|
||||
void check_nret(int xnret, int otop, int nret) const;
|
||||
|
||||
template<typename T>
|
||||
static void delete_pointer(void *p) { delete (T*)p; }
|
||||
static void do_not_delete(void *p) { }
|
||||
@@ -477,14 +445,6 @@ public:
|
||||
lua_rawseti(L_, tab, key);
|
||||
}
|
||||
|
||||
// Call invokes any C function. It pushes the arguments on the stack,
|
||||
// calls the cfunction, verifies that the number of return values is as
|
||||
// expected, and pops the return values into LuaVars.
|
||||
template<typename... T>
|
||||
void call(T&... args) {
|
||||
call_cfunction<0>(lua_gettop(L_), args...);
|
||||
}
|
||||
|
||||
// Lua flagbits manipulation: Table types.
|
||||
int gettabletype(LuaSlot tab) const;
|
||||
void settabletype(LuaSlot tab, int t) const;
|
||||
@@ -521,9 +481,9 @@ public:
|
||||
|
||||
|
||||
#define LuaDefine(name, mode) \
|
||||
int name(lua_State *L); \
|
||||
LuaFunctionReg reg_##name(mode, #name, name); \
|
||||
int name(lua_State *L)
|
||||
int lfn_##name(lua_State *L); \
|
||||
LuaFunctionReg reg_##name(mode, #name, lfn_##name); \
|
||||
int lfn_##name(lua_State *L)
|
||||
|
||||
|
||||
#define LuaStringify(x) #x
|
||||
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
|
||||
private:
|
||||
// unit testing stuff.
|
||||
friend int unittests_planemap(lua_State *L);
|
||||
friend int lfn_unittests_planemap(lua_State *L);
|
||||
EltVec get_cell(const std::string &plane, int64_t cell) const;
|
||||
int total_cells() const;
|
||||
void clear() { planes_.clear(); }
|
||||
|
||||
32
luprex/core/cpp/print.cpp
Normal file
32
luprex/core/cpp/print.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "print.hpp"
|
||||
#include "util.hpp"
|
||||
#include <ostream>
|
||||
#include <iostream>
|
||||
|
||||
void luai_writestring(const char *s, size_t len) {
|
||||
std::cout.write(s, len);
|
||||
}
|
||||
|
||||
void luai_writeline() {
|
||||
std::cout << std::endl;
|
||||
std::cout.flush();
|
||||
}
|
||||
|
||||
LuaDefine(string_isidentifier, "c") {
|
||||
LuaArg str;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, str, result);
|
||||
if (LS.isstring(str)) {
|
||||
std::string s = LS.ckstring(str);
|
||||
LS.set(result, util::is_identifier(s));
|
||||
} else {
|
||||
LS.set(result, false);
|
||||
}
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
|
||||
void pprint(LuaStack &LS0, LuaSlot val, int indent, int maxlen, std::ostream *os) {
|
||||
|
||||
|
||||
}
|
||||
46
luprex/core/cpp/print.hpp
Normal file
46
luprex/core/cpp/print.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Pretty-print routine.
|
||||
//
|
||||
// The pretty-printer can be called from C++ or Lua.
|
||||
//
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PRINT_HPP
|
||||
#define PRINT_HPP
|
||||
|
||||
#include "luastack.hpp"
|
||||
|
||||
// This file provides these functions for lua.
|
||||
//
|
||||
// They direct all output to std::cout
|
||||
//
|
||||
extern "C" {
|
||||
void luai_writestring(const char *s, size_t len);
|
||||
void luai_writeline();
|
||||
}
|
||||
|
||||
// Pretty print to a stream.
|
||||
//
|
||||
// If indent is >=0, the output is indented. If indent<0, then
|
||||
// the output is emitted without newlines or indentation.
|
||||
//
|
||||
// Maxlen specifies the maximum number of characters output. If
|
||||
// this is exceeded, then the printout is truncated.
|
||||
//
|
||||
void pprint(LuaStack &LS, LuaSlot val, int indent, int maxlen, std::ostream *os);
|
||||
|
||||
// The following lua interfaces to this code are included:
|
||||
//
|
||||
// pprint(expr)
|
||||
//
|
||||
// - pretty print the specified expression to stdout.
|
||||
//
|
||||
// string.pprint(expr, indent, maxlen)
|
||||
//
|
||||
// - pretty print the specified expression, return the result as a string.
|
||||
//
|
||||
void pprint_pprint(lua_State *L);
|
||||
void string_pprint(lua_State *L);
|
||||
|
||||
#endif // PRINT_HPP
|
||||
@@ -115,11 +115,10 @@ static void source_install_builtins(lua_State *L) {
|
||||
LS.setmetatable(nullstring, stringclass);
|
||||
}
|
||||
|
||||
static int source_updatefile(lua_State *L) {
|
||||
LuaArg source, fn;
|
||||
LuaRet info;
|
||||
static void source_updatefile(LuaStack &LS0, LuaSlot source, LuaSlot fn, LuaSlot info) {
|
||||
lua_State *L = LS0.state();
|
||||
LuaVar fingerprint, null, loadresult;
|
||||
LuaStack LS(L, source, fn, info, fingerprint, null, loadresult);
|
||||
LuaStack LS(L, fingerprint, null, loadresult);
|
||||
|
||||
// Get the existing info table from the source DB.
|
||||
if (LS.istable(source)) {
|
||||
@@ -158,7 +157,7 @@ static int source_updatefile(lua_State *L) {
|
||||
LS.rawset(info, "loadresult", loadresult);
|
||||
}
|
||||
}
|
||||
return LS.result();
|
||||
LS.result();
|
||||
}
|
||||
|
||||
void SourceDB::update() {
|
||||
@@ -184,7 +183,7 @@ void SourceDB::update() {
|
||||
LS.set(fn, filenames[i]);
|
||||
|
||||
// Call source_updatefile to get the updated info for one file.
|
||||
LS.call(info, source_updatefile, sourcedb, fn);
|
||||
source_updatefile(LS, sourcedb, fn, info);
|
||||
|
||||
// Insert the sequence number and put finalized info into the new database.
|
||||
LS.set(seq, i + 1);
|
||||
@@ -209,7 +208,7 @@ static void source_clear_globals(lua_State *L) {
|
||||
LS.set(classname, LuaNil);
|
||||
while (LS.next(globtab, classname, classtab) != 0) {
|
||||
if (LS.istable(classtab)) {
|
||||
LS.call(table_clear, classtab);
|
||||
table_clear(LS, classtab);
|
||||
} else {
|
||||
LS.rawset(globtab, classname, LuaNil);
|
||||
}
|
||||
@@ -238,7 +237,7 @@ static void source_load_cfunctions(lua_State *L) {
|
||||
std::string mode = r->get_mode();
|
||||
if (mode.find('c') != std::string::npos) { // Insert into class
|
||||
lua_pushlstring(L, classname.c_str(), classname.size());
|
||||
source_makeclass(L);
|
||||
lfn_source_makeclass(L);
|
||||
lua_pushcfunction(L, func);
|
||||
lua_setfield(L, -2, funcname.c_str());
|
||||
}
|
||||
|
||||
@@ -163,11 +163,11 @@ public:
|
||||
// If there's already a table with this name in the global environment,
|
||||
// leaves it there, and repairs the __class and __index fields.
|
||||
//
|
||||
int source_makeclass(lua_State *L);
|
||||
int lfn_source_makeclass(lua_State *L);
|
||||
|
||||
// Return true if the specified table is a class created by 'makeclass'
|
||||
//
|
||||
int source_isclass(lua_State *L);
|
||||
int lfn_source_isclass(lua_State *L);
|
||||
|
||||
#endif // SOURCE_HPP
|
||||
|
||||
|
||||
@@ -416,7 +416,7 @@ private:
|
||||
// This is for unit testing.
|
||||
bool layout_is(int64_t a, int64_t b, int64_t c);
|
||||
|
||||
friend int unittests_streambuffer(lua_State *L);
|
||||
friend int lfn_unittests_streambuffer(lua_State *L);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,50 @@
|
||||
#include "table.hpp"
|
||||
#include "source.hpp"
|
||||
|
||||
void table_findtables_i(LuaStack &LS0, LuaSlot root, LuaSlot tabcount) {
|
||||
lua_State *L = LS0.state();
|
||||
LuaVar key, val, tab, count;
|
||||
LuaStack LS(L, key, val, tab, count);
|
||||
|
||||
LS.newtable(tabcount);
|
||||
int top = lua_gettop(L);
|
||||
if (LS.istable(root)) {
|
||||
lua_pushvalue(L, root.index());
|
||||
}
|
||||
while (lua_gettop(L) > top) {
|
||||
lua_checkstack(L, 10);
|
||||
lua_replace(L, tab.index());
|
||||
LS.rawget(count, tabcount, tab);
|
||||
if (LS.isnil(count)) {
|
||||
LS.rawset(tabcount, tab, 1);
|
||||
LS.set(key, LuaNil);
|
||||
while (LS.next(tab, key, val)) {
|
||||
if (LS.istable(key)) {
|
||||
lua_pushvalue(L, key.index());
|
||||
}
|
||||
if (LS.istable(val)) {
|
||||
lua_pushvalue(L, val.index());
|
||||
}
|
||||
}
|
||||
LS.getmetatable(val, tab);
|
||||
if (LS.istable(val)) {
|
||||
lua_pushvalue(L, val.index());
|
||||
}
|
||||
} else {
|
||||
LS.rawset(tabcount, tab, LS.ckint(count) + 1);
|
||||
}
|
||||
}
|
||||
LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_findtables, "c") {
|
||||
LuaArg root;
|
||||
LuaRet tabcount;
|
||||
LuaStack LS(L, root, tabcount);
|
||||
table_findtables_i(LS, root, tabcount);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_getregistry, "f") {
|
||||
LuaArg key;
|
||||
LuaRet result;
|
||||
@@ -9,10 +53,8 @@ LuaDefine(table_getregistry, "f") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_equal, "c") {
|
||||
LuaArg t1, t2;
|
||||
LuaRet eql;
|
||||
LuaStack LS(L, t1, t2, eql);
|
||||
bool table_equal(LuaStack &LS, LuaSlot t1, LuaSlot t2) {
|
||||
lua_State *L = LS.state();
|
||||
LS.checktable(t1);
|
||||
LS.checktable(t2);
|
||||
lua_pushnil(L);
|
||||
@@ -21,8 +63,7 @@ LuaDefine(table_equal, "c") {
|
||||
lua_pushvalue(L, -2); // k v1 k
|
||||
lua_rawget(L, t2.index()); // k v1 v2
|
||||
if (!lua_rawequal(L, -1, -2)) {
|
||||
LS.set(eql, false);
|
||||
return LS.result();
|
||||
return false;
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
total1 += 1;
|
||||
@@ -33,7 +74,14 @@ LuaDefine(table_equal, "c") {
|
||||
lua_pop(L, 1);
|
||||
total2 += 1;
|
||||
}
|
||||
LS.set(eql, total1 == total2);
|
||||
return total1 == total2;
|
||||
}
|
||||
|
||||
LuaDefine(table_equal, "c") {
|
||||
LuaArg t1, t2;
|
||||
LuaRet eql;
|
||||
LuaStack LS(L, t1, t2, eql);
|
||||
LS.set(eql, table_equal(LS, t1, t2));
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
@@ -124,10 +172,14 @@ LuaDefine(table_count, "c") {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void table_clear(LuaStack &LS0, LuaSlot table) {
|
||||
LS0.cleartable(table);
|
||||
}
|
||||
|
||||
LuaDefine(table_clear, "c") {
|
||||
LuaArg tab;
|
||||
LuaStack LS(L, tab);
|
||||
LS.cleartable(tab);
|
||||
table_clear(LS, tab);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
@@ -607,7 +659,7 @@ LuaDefine(table_sortedpairs, "c") {
|
||||
luaL_error(L, "Cannot iterate over a table with unsortable keys");
|
||||
}
|
||||
lua_replace(L, rtab.index());
|
||||
LS.set(closure, table_nextsortedpair);
|
||||
LS.set(closure, lfn_table_nextsortedpair);
|
||||
LS.set(key, LuaNil);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
@@ -12,83 +12,91 @@
|
||||
|
||||
#include "luastack.hpp"
|
||||
|
||||
// Starting at the specified root, find tables recursively.
|
||||
//
|
||||
// Returns a table containing every table found, in tabcount.
|
||||
// The value associated with the table is the number of times the
|
||||
// table was found.
|
||||
//
|
||||
void table_findtables(LuaStack &LS0, LuaSlot root, LuaSlot tabcount);
|
||||
|
||||
// table_clear
|
||||
//
|
||||
// Remove all key/value pairs from the table. Does not remove
|
||||
// the metatable.
|
||||
//
|
||||
void table_clear(LuaStack &LS0, LuaSlot tab);
|
||||
|
||||
// table_equal
|
||||
//
|
||||
// True if two tables contain the same key/value pairs.
|
||||
//
|
||||
int table_equal(lua_State *L);
|
||||
bool table_equal(LuaStack &LS0, LuaSlot tab1, LuaSlot tab2);
|
||||
|
||||
// table_findremove
|
||||
//
|
||||
// Given a vector and a value, remove the specified value from
|
||||
// the vector, and shift elements downward to fill the gaps.
|
||||
//
|
||||
int table_findremove(lua_State *L);
|
||||
int lfn_table_findremove(lua_State *L);
|
||||
|
||||
// table_push
|
||||
//
|
||||
// Given a vector and a value, push the value onto the end.
|
||||
//
|
||||
int table_push(lua_State *L);
|
||||
int lfn_table_push(lua_State *L);
|
||||
|
||||
// table_find
|
||||
//
|
||||
// Given a vector and a value, search for the first occurrence
|
||||
// of that value. Return the index.
|
||||
//
|
||||
int table_find(lua_State *L);
|
||||
int lfn_table_find(lua_State *L);
|
||||
|
||||
// table_empty
|
||||
//
|
||||
// Return true if the table has no key/value pairs.
|
||||
//
|
||||
int table_empty(lua_State *L);
|
||||
int lfn_table_empty(lua_State *L);
|
||||
|
||||
// table_count
|
||||
//
|
||||
// Return the number of key/value pairs in the table.
|
||||
//
|
||||
int table_count(lua_State *L);
|
||||
|
||||
// table_clear
|
||||
//
|
||||
// Remove all key/value pairs from the table. Does not
|
||||
// remove the metatable.
|
||||
//
|
||||
int table_clear(lua_State *L);
|
||||
int lfn_table_count(lua_State *L);
|
||||
|
||||
//
|
||||
// Create and return an empty deque. Queues are implemented
|
||||
// as tables which are used as dynamically-expandable circular
|
||||
// buffers.
|
||||
//
|
||||
int deque_create(lua_State *L);
|
||||
int lfn_deque_create(lua_State *L);
|
||||
|
||||
//
|
||||
// Given a deque and a value, pushes the value onto the
|
||||
// left or right end.
|
||||
//
|
||||
int deque_pushl(lua_State *L);
|
||||
int deque_pushr(lua_State *L);
|
||||
int lfn_deque_pushl(lua_State *L);
|
||||
int lfn_deque_pushr(lua_State *L);
|
||||
|
||||
//
|
||||
// Given a deque, pop from the left or right end. Returns the
|
||||
// value and removes it from the deque. If the deque is
|
||||
// empty, returns nil.
|
||||
//
|
||||
int deque_popl(lua_State *L);
|
||||
int deque_popr(lua_State *L);
|
||||
int lfn_deque_popl(lua_State *L);
|
||||
int lfn_deque_popr(lua_State *L);
|
||||
|
||||
//
|
||||
// Return the nth element from the left or right end of a deque.
|
||||
//
|
||||
int deque_nthl(lua_State *L);
|
||||
int deque_nthr(lua_State *L);
|
||||
int lfn_deque_nthl(lua_State *L);
|
||||
int lfn_deque_nthr(lua_State *L);
|
||||
|
||||
// Set (overwrite) the nth element in a deque.
|
||||
//
|
||||
int deque_setl(lua_State *L);
|
||||
int deque_setr(lua_State *L);
|
||||
int lfn_deque_setl(lua_State *L);
|
||||
int lfn_deque_setr(lua_State *L);
|
||||
|
||||
//
|
||||
// Search a deque for a value.
|
||||
@@ -96,13 +104,12 @@ int deque_setr(lua_State *L);
|
||||
// Search starts on the specified end and indices are relative
|
||||
// to specified end.
|
||||
//
|
||||
int deque_findl(lua_State *L);
|
||||
int deque_findr(lua_State *L);
|
||||
int lfn_deque_findl(lua_State *L);
|
||||
int lfn_deque_findr(lua_State *L);
|
||||
|
||||
//
|
||||
// Return the number of values in the deque.
|
||||
//
|
||||
int deque_size(lua_State *L);
|
||||
|
||||
int lfn_deque_size(lua_State *L);
|
||||
|
||||
#endif // TABLE_HPP
|
||||
|
||||
@@ -16,6 +16,25 @@
|
||||
|
||||
namespace util {
|
||||
|
||||
static bool ascii_isalpha(char c) {
|
||||
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
|
||||
}
|
||||
|
||||
static bool ascii_isdigit(char c) {
|
||||
return ((c >= '0') && (c <= '9'));
|
||||
}
|
||||
|
||||
bool is_identifier(const std::string &str) {
|
||||
if (str.size() == 0) return false;
|
||||
char c=str[0];
|
||||
if ((!ascii_isalpha(c)) && (c!='_')) return false;
|
||||
for (int i = 1; i < int(str.size()); i++) {
|
||||
char c = str[i];
|
||||
if ((!ascii_isalpha(c)) && (!ascii_isdigit(c)) && (c!='_')) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
IdVector id_vector_create(int64_t id1, int64_t id2, int64_t id3, int64_t id4) {
|
||||
IdVector result;
|
||||
if (id1 >= 0) result.push_back(id1);
|
||||
|
||||
@@ -24,6 +24,9 @@ using StringVec = std::vector<std::string>;
|
||||
using HashValue = std::pair<uint64_t, uint64_t>;
|
||||
using IdVector = std::vector<int64_t>;
|
||||
|
||||
// Return true if the string is a valid lua identifier.
|
||||
bool is_identifier(const std::string &str);
|
||||
|
||||
// ID vector quick create.
|
||||
IdVector id_vector_create(int64_t id1=-1, int64_t id2=-1, int64_t id3=-1, int64_t id4=-1);
|
||||
|
||||
|
||||
@@ -477,9 +477,9 @@ LuaDefine(table_diffapply, "c") {
|
||||
|
||||
patch_table(MLS, tangibles, mntmap, mstab, &sb);
|
||||
|
||||
MLS.call(eql, table_equal, mstab, mtab);
|
||||
bool e = MLS.ckboolean(eql);
|
||||
if (e) {
|
||||
bool eq = table_equal(MLS, mstab, mtab);
|
||||
MLS.set(eql, eq);
|
||||
if (eq) {
|
||||
MLS.set(eqlstr, "tables equal");
|
||||
} else {
|
||||
MLS.set(eqlstr, "tables were supposed to be equal");
|
||||
|
||||
@@ -396,9 +396,9 @@ private:
|
||||
Redirects redirects_;
|
||||
|
||||
friend class Tangible;
|
||||
friend int tangible_animate(lua_State *L);
|
||||
friend int tangible_build(lua_State *L);
|
||||
friend int tangible_redirect(lua_State *L);
|
||||
friend int lfn_tangible_animate(lua_State *L);
|
||||
friend int lfn_tangible_build(lua_State *L);
|
||||
friend int lfn_tangible_redirect(lua_State *L);
|
||||
};
|
||||
|
||||
#endif // WORLD_HPP
|
||||
|
||||
Reference in New Issue
Block a user