diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a17d46..cb5a3d1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,8 @@ "editor.tabSize": 4, "editor.insertSpaces": false, "files.associations": { - "stdlib.h": "c" + "stdlib.h": "c", + "ksys.h": "c" }, "cSpell.words": [ "ksys", diff --git a/Makefile b/Makefile index 230d05c..a5b5588 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ LD=kos32-ld STRIP=kos32-strip OBJCOPY=kos32-objcopy STD=-std=gnu99 -CFLAGS=$(SYSCFLAGS) -O2 -Wall -Wextra -DLUA_COMPAT_5_3 $(STD) $(MYCFLAGS) +CFLAGS=$(SYSCFLAGS) -O2 -Wall -Wextra $(STD) $(MYCFLAGS) LDFLAGS=$(SYSLDFLAGS) $(MYLDFLAGS) LIBS=$(SYSLIBS) $(MYLIBS) $(TOOLCHAIN_PATH)/mingw32/lib/lua$(LUA_V).dll.a @@ -38,6 +38,10 @@ clean: rm -f $(ALL_O) syscalls.dll -src/syscalls.o: src/syscalls.c src/systemColors.h src/ARP_entry.h src/scancodes.h +src/syscalls.o: src/syscalls.c src/syscalls.h src/systemColors.h src/ARP_entry.h src/scancodes.h src/ARP_entry.o: src/ARP_entry.c src/ARP_entry.h src/debug.h src/systemColors.o: src/systemColors.c src/systemColors.h src/debug.h +src/socket.o: src/socket.c src/socket.h + +src/socket.h: src/syscalls.h + diff --git a/doc/manual.md b/doc/manual.md new file mode 100644 index 0000000..e69de29 diff --git a/src/ARP_entry.c b/src/ARP_entry.c index 6a5dfe2..f2443b0 100644 --- a/src/ARP_entry.c +++ b/src/ARP_entry.c @@ -8,7 +8,7 @@ static int syscalls_gcARPEntry(lua_State* L) { - free(lua_touserdata(L, 1)); + free(luaL_checkudata(L, 1, syscalls_ARPEntry_metatable_name)); return 0; } @@ -90,8 +90,8 @@ static int syscalls_eqAPREntry(lua_State* L) lua_pushboolean( L, syscalls_cmpAPREntry( - (struct ARP_entry*)lua_touserdata(L, 1), - (struct ARP_entry*)lua_touserdata(L, 2) + luaL_checkudata(L, 1, syscalls_ARPEntry_metatable_name), + luaL_checkudata(L, 2, syscalls_ARPEntry_metatable_name) ) ); diff --git a/src/socket.c b/src/socket.c new file mode 100644 index 0000000..0f79201 --- /dev/null +++ b/src/socket.c @@ -0,0 +1,204 @@ +#include +#include "socket.h" + +int syscalls_OpenSocket(lua_State* L) +{ + int32_t socketNum; + uint32_t errorCode; + + uint32_t family = luaL_checkinteger(L, 1); + uint32_t type = luaL_checkinteger(L, 2); + uint32_t protocol = luaL_checkinteger(L, 3); + + asm_inline( + "int $0x40" + :"=a"(socketNum), "=b"(errorCode) + : "a"(77), "b"(0), "c"(family), "d"(type), "S"(protocol) + ); + + if (socketNum == -1) + { + lua_pushnil(L); // Push socketNum + lua_pushnumber(L, socketNum); // Push error Code + } + else + { + lua_pushnumber(L, socketNum); // Push socketNum + lua_pushnil(L); // Push error code + } + + return 2; +} + +int syscalls_CloseSocket(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + uint32_t socketNum = luaL_checkinteger(L, 1); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(1), "c"(socketNum)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_Bind(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + + uint32_t socketNum = luaL_checkinteger(L, 1); + uint32_t sockaddr = luaL_checkinteger(L, 2); + uint32_t sockaddrLen = luaL_checkinteger(L, 3); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(2), "c"(socketNum), "d"(sockaddr), "S"(sockaddrLen)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_Listen(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + + uint32_t socketNum = luaL_checkinteger(L, 1); + uint32_t backlog = luaL_checkinteger(L, 2); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(3), "c"(socketNum), "d"(backlog)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_Connect(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + + uint32_t socketNum = luaL_checkinteger(L, 1); + uint32_t sockaddr = luaL_checkinteger(L, 2); + uint32_t sockaddrLen = luaL_checkinteger(L, 3); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(4), "c"(socketNum), "d"(sockaddr), "S"(sockaddrLen)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_Accept(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + + uint32_t socketNum = luaL_checkinteger(L, 1); + uint32_t sockaddr = luaL_checkinteger(L, 2); + uint32_t sockaddrLen = luaL_checkinteger(L, 3); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(5), "c"(socketNum), "d"(sockaddr), "S"(sockaddrLen)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_Send(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + + uint32_t socketNum = luaL_checkinteger(L, 1); + uint32_t buffer = luaL_checkinteger(L, 2); + uint32_t bufferLen = luaL_checkinteger(L, 3); + uint32_t flags = luaL_checkinteger(L, 4); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(6), "c"(socketNum), "d"(buffer), "S"(bufferLen), "D"(flags)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_Receive(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + + uint32_t socketNum = luaL_checkinteger(L, 1); + uint32_t buffer = luaL_checkinteger(L, 2); + uint32_t bufferLen = luaL_checkinteger(L, 3); + uint32_t flags = luaL_checkinteger(L, 4); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(7), "c"(socketNum), "d"(buffer), "S"(bufferLen), "D"(flags)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_GetSocketOptions(lua_State* L) +{ + uint32_t eax; + uint32_t errorCode; + + uint32_t socketNum = luaL_checkinteger(L, 1); + uint32_t optstruct = luaL_checkinteger(L, 2); + + asm_inline( + "int $0x40" + : "=a"(eax), "=b"(errorCode) + : "a"(77), "b"(8), "c"(socketNum), "d"(optstruct)); + + syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); + + return 1; +} + +int syscalls_GetPairSocket(lua_State* L) +{ + int firstSocketNum; + int secondSocketNum; + + asm_inline( + "int $0x40" + : "=a"(firstSocketNum), "=b"(secondSocketNum) + : "a"(77), "b"(9)); + + if (firstSocketNum == -1) + { + lua_pushnil(L); + lua_pushinteger(L, secondSocketNum); + } + else + { + lua_pushinteger(L, firstSocketNum); + lua_pushinteger(L, secondSocketNum); + } + + return 2; +} diff --git a/src/socket.h b/src/socket.h new file mode 100644 index 0000000..ef14a98 --- /dev/null +++ b/src/socket.h @@ -0,0 +1,18 @@ +#ifndef __SOCKET_H__ +#define __SOCKET_H__ + +#include "syscalls.h" + +int syscalls_OpenSocket(lua_State* L); +int syscalls_CloseSocket(lua_State* L); +int syscalls_Bind(lua_State* L); +int syscalls_Listen(lua_State* L); +int syscalls_Connect(lua_State* L); +int syscalls_Accept(lua_State* L); +int syscalls_Send(lua_State* L); +int syscalls_Receive(lua_State* L); +int syscalls_GetSocketOptions(lua_State* L); +int syscalls_GetPairSocket(lua_State* L); + + +#endif // __SOCKET_H__ \ No newline at end of file diff --git a/src/syscalls.c b/src/syscalls.c index e548e98..4d415a5 100644 --- a/src/syscalls.c +++ b/src/syscalls.c @@ -2,20 +2,17 @@ syscalls */ -#include -#include -#include - #include #include #include +#include "syscalls.h" #include "scancodes.h" #include "ARP_entry.h" #include "systemColors.h" - +#include "socket.h" /* @@ -42,53 +39,7 @@ static ksys_pos_t syscalls_screenSizeCache = { 0 }; */ -inline void syscalls_ReturnIntegerOrNil(LUA_INTEGER value, lua_State* L) -{ - if (value == -1) - { - lua_pushnil(L); - } - else - { - lua_pushinteger(L, value); - } -} -inline void syscalls_ReturnIntegerValueOrNil(LUA_INTEGER cond, LUA_INTEGER value, lua_State* L) -{ - if (cond == -1) - { - lua_pushnil(L); - } - else - { - lua_pushinteger(L, value); - } -} - -inline void syscalls_ReturnTrueOrNil(LUA_INTEGER value, lua_State* L) -{ - if (value == -1) - { - lua_pushnil(L); - } - else - { - lua_pushboolean(L, true); - } -} - -inline void syscalls_ReturnStringOrNil(LUA_INTEGER cond, const char* value, lua_State* L) -{ - if (cond == -1) - { - lua_pushnil(L); - } - else - { - lua_pushstring(L, value); - } -} @@ -287,6 +238,23 @@ static int syscalls_drawPixel(lua_State* L) return 0; } +static int syscalls_WindowMsg(lua_State* L) +{ + int event = luaL_checkinteger(L, 1); + int code = luaL_checkinteger(L, 2); + int ret; + + asm_inline( + "int $0x40" + :"=a"(ret) + : "a"(72), "b"(1), "c"(event), "d"(code) + ); + + syscalls_ReturnTrueOrNil(ret, L); + + return 1; +} + static int syscalls_threadInfo(lua_State* L) { ksys_thread_t t; @@ -684,7 +652,7 @@ static int syscalls_getSystemColors(lua_State* L) static int syscalls_SetSystemColors(lua_State* L) { - ksys_colors_table_t* t = (ksys_colors_table_t*)lua_touserdata(L, 1); + ksys_colors_table_t* t = (ksys_colors_table_t*)luaL_checkudata(L, 1, syscalls_SystemColors_metatable_name); asm_inline( "int $0x40" ::"a"(48), "b"(2), "c"(t), "d"(40)); @@ -1637,17 +1605,25 @@ static int syscalls_ReadARPEntries(lua_State* L) return 1; } +/** + * Return ARP entry + */ static int syscalls_ReadARPEntry(lua_State* L) { uint32_t eax; uint8_t device = luaL_checkinteger(L, 1); uint32_t entryNum = luaL_checkinteger(L, 2); - struct ARP_entry* buffer = syscalls_pushARPEntry(L); + struct ARP_entry buffer; asm_inline( "int $0x40" : "=a"(eax) - : "a"(76), "b"((ARP << 24) | (device << 8) | 3), "c"(entryNum), "D"(buffer)); + : "a"(76), "b"((ARP << 24) | (device << 8) | 3), "c"(entryNum), "D"(&buffer)); + + if (eax == -1) + lua_pushnil(L); + else + memcpy(syscalls_pushARPEntry(L), &buffer, sizeof(struct ARP_entry)); return 1; } @@ -1657,7 +1633,7 @@ static int syscalls_AddARPEntry(lua_State* L) uint32_t eax; uint8_t device = luaL_checkinteger(L, 1); uint32_t entryNum = luaL_checkinteger(L, 2); - struct ARP_entry* buffer = (struct ARP_entry*)lua_touserdata(L, 3); + struct ARP_entry* buffer = (struct ARP_entry*)luaL_checkudata(L, 3, syscalls_ARPEntry_metatable_name); asm_inline( "int $0x40" @@ -1715,211 +1691,39 @@ static int syscalls_ReadARPConflicts(lua_State* L) return 1; } -/* Сокеты */ - -static int syscalls_OpenSocket(lua_State* L) +static int syscalls_DebugPuts(lua_State* L) { - int32_t socketNum; - uint32_t errorCode; + _ksys_debug_puts(luaL_checkstring(L, 1)); - uint32_t family = luaL_checkinteger(L, 1); - uint32_t type = luaL_checkinteger(L, 2); - uint32_t protocol = luaL_checkinteger(L, 3); + return 0; +} + +static int syscalls_DebugPutc(lua_State* L) +{ + _ksys_debug_putc(*luaL_checkstring(L, 1)); + + return 0; +} + +struct DebugMessageArea +{ + int Size; + int Used; + char data[]; +}; + +static int syscalls_SetMessageArea(lua_State* L) +{ + struct DebugMessageArea* p = luaL_checkinteger(L, 1); asm_inline( "int $0x40" - :"=a"(socketNum), "=b"(errorCode) - : "a"(77), "b"(0), "c"(family), "d"(type), "S"(protocol) + :: "a"(69), "b"(0) ); - if (socketNum == -1) - { - lua_pushnil(L); // Push socketNum - lua_pushnumber(L, socketNum); // Push error Code - } - else - { - lua_pushnumber(L, socketNum); // Push socketNum - lua_pushnil(L); // Push error code - } - - return 2; + return 0; } -static int syscalls_CloseSocket(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - uint32_t socketNum = luaL_checkinteger(L, 1); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(1), "c"(socketNum)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_Bind(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - - uint32_t socketNum = luaL_checkinteger(L, 1); - uint32_t sockaddr = luaL_checkinteger(L, 2); - uint32_t sockaddrLen = luaL_checkinteger(L, 3); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(2), "c"(socketNum), "d"(sockaddr), "S"(sockaddrLen)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_Listen(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - - uint32_t socketNum = luaL_checkinteger(L, 1); - uint32_t backlog = luaL_checkinteger(L, 2); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(3), "c"(socketNum), "d"(backlog)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_Connect(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - - uint32_t socketNum = luaL_checkinteger(L, 1); - uint32_t sockaddr = luaL_checkinteger(L, 2); - uint32_t sockaddrLen = luaL_checkinteger(L, 3); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(4), "c"(socketNum), "d"(sockaddr), "S"(sockaddrLen)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_Accept(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - - uint32_t socketNum = luaL_checkinteger(L, 1); - uint32_t sockaddr = luaL_checkinteger(L, 2); - uint32_t sockaddrLen = luaL_checkinteger(L, 3); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(5), "c"(socketNum), "d"(sockaddr), "S"(sockaddrLen)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_Send(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - - uint32_t socketNum = luaL_checkinteger(L, 1); - uint32_t buffer = luaL_checkinteger(L, 2); - uint32_t bufferLen = luaL_checkinteger(L, 3); - uint32_t flags = luaL_checkinteger(L, 4); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(6), "c"(socketNum), "d"(buffer), "S"(bufferLen), "D"(flags)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_Receive(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - - uint32_t socketNum = luaL_checkinteger(L, 1); - uint32_t buffer = luaL_checkinteger(L, 2); - uint32_t bufferLen = luaL_checkinteger(L, 3); - uint32_t flags = luaL_checkinteger(L, 4); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(7), "c"(socketNum), "d"(buffer), "S"(bufferLen), "D"(flags)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_GetSocketOptions(lua_State* L) -{ - uint32_t eax; - uint32_t errorCode; - - uint32_t socketNum = luaL_checkinteger(L, 1); - uint32_t optstruct = luaL_checkinteger(L, 2); - - asm_inline( - "int $0x40" - : "=a"(eax), "=b"(errorCode) - : "a"(77), "b"(8), "c"(socketNum), "d"(optstruct)); - - syscalls_ReturnIntegerValueOrNil(eax, errorCode, L); - - return 1; -} - -static int syscalls_GetPairSocket(lua_State* L) -{ - int32_t firstSocketNum; - uint32_t secondSocketNum; - - asm_inline( - "int $0x40" - : "=a"(firstSocketNum), "=b"(secondSocketNum) - : "a"(77), "b"(9)); - - if (firstSocketNum == -1) - { - lua_pushnil(L); - lua_pushinteger(L, secondSocketNum); - } - else - { - lua_pushinteger(L, firstSocketNum); - lua_pushinteger(L, secondSocketNum); - } - - return 2; -} - - /* ** functions for 'syscalls' library */ @@ -1969,7 +1773,7 @@ static const luaL_Reg syscallsLib[] = { {"ReadPoint", syscalls_ReadPoint}, /* keyboard funcs */ {"SetKeyInputMode", syscalls_setKeyInputMode}, - {"GetKeyInputMouse", syscalls_getKeyInputMode}, + {"GetKeyInputMode", syscalls_getKeyInputMode}, {"getKey", syscalls_getKey}, {"getControlKeyState", syscalls_getControlKeyState}, {"SetHotkey", syscalls_SetHotkey}, @@ -2052,7 +1856,11 @@ static const luaL_Reg syscallsLib[] = { {"Receive", syscalls_Receive}, {"GetSocketOptions", syscalls_GetSocketOptions}, {"GetPairSocket", syscalls_GetPairSocket}, - {NULL, NULL} }; + /* Debug */ + {"DebugPuts", syscalls_DebugPuts}, + { "DebugPutc", syscalls_DebugPutc }, + {NULL, NULL} +}; static inline void syscalls_push_events(lua_State* L) { diff --git a/src/syscalls.h b/src/syscalls.h new file mode 100644 index 0000000..1232827 --- /dev/null +++ b/src/syscalls.h @@ -0,0 +1,56 @@ +#ifndef __SYSCALLS_H__ +#define __SYSCALLS_H__ + +#include +#include +#include + +inline void syscalls_ReturnIntegerOrNil(LUA_INTEGER value, lua_State* L) +{ + if (value == -1) + { + lua_pushnil(L); + } + else + { + lua_pushinteger(L, value); + } +} + +inline void syscalls_ReturnIntegerValueOrNil(LUA_INTEGER cond, LUA_INTEGER value, lua_State* L) +{ + if (cond == -1) + { + lua_pushnil(L); + } + else + { + lua_pushinteger(L, value); + } +} + +inline void syscalls_ReturnTrueOrNil(LUA_INTEGER value, lua_State* L) +{ + if (value == -1) + { + lua_pushnil(L); + } + else + { + lua_pushboolean(L, true); + } +} + +inline void syscalls_ReturnStringOrNil(LUA_INTEGER cond, const char* value, lua_State* L) +{ + if (cond == -1) + { + lua_pushnil(L); + } + else + { + lua_pushstring(L, value); + } +} + +#endif // __SYSCALLS_H__ \ No newline at end of file diff --git a/src/systemColors.c b/src/systemColors.c index e9ef6ee..a301d11 100644 --- a/src/systemColors.c +++ b/src/systemColors.c @@ -100,7 +100,7 @@ static int syscalls_newindexSystemColors(lua_State* L) { t->grab_bar_button = val; } - else if (strcmp("grab_button_text", index) == 0) + else if (strcmp("grabButtonText", index) == 0) { t->grab_button_text = val; } diff --git a/src/systemColors.h b/src/systemColors.h index a7ea281..bad5c67 100644 --- a/src/systemColors.h +++ b/src/systemColors.h @@ -1,9 +1,7 @@ #ifndef _SYSCALLS_SYSTEM_COLORS_H_ #define _SYSCALLS_SYSTEM_COLORS_H_ -#include -#include -#include +#include "syscalls.h" #include #define syscalls_SystemColors_metatable_name "syscalls SystemColors metatable" diff --git a/tests/SystemColors.lua b/tests/SystemColors.lua index 0e98b08..7b03c37 100644 --- a/tests/SystemColors.lua +++ b/tests/SystemColors.lua @@ -4,6 +4,29 @@ local SystemColors = syscalls.GetSystemColors() print(SystemColors) -for i, v in pairs(SystemColors) do - print(i, v) +function DEC_HEX(IN) + local B, K, OUT, I, D = 16, "0123456789ABCDEF", "", 0 + while IN > 0 do + I = I + 1 + IN, D = math.floor(IN / B), math.mod(IN, B) + 1 + OUT = string.sub(K, D, D) .. OUT + end + return OUT +end + +local keys = { + "frameArea", + "workArea", + "grabBar", + "grabBarButton", + "grabButtonText", + "grabText", + "workButton", + "workButtonText", + "workGraph", + "workText" +} + +for _, v in pairs(keys) do + print(v .. ':', "#" .. DEC_HEX(SystemColors[v])) end diff --git a/tests/helloWorld.lua b/tests/helloWorld.lua new file mode 100644 index 0000000..4f733a8 --- /dev/null +++ b/tests/helloWorld.lua @@ -0,0 +1,24 @@ +local syscalls = require("syscalls") + +local function Redraw() + syscalls.StartRedraw() + + syscalls.CreateWidnow(100) + + syscalls.EndRedraw() +end + +local exit = false +while not exit do + local event = syscalls.WaitEvent() + + if event == syscalls.Redraw then + Redraw() + elseif event == syscalls.Button then + if syscalls.GetButton() == syscalls.buttons.close then + exit = true + end + end +end + +print("End") diff --git a/tests/libraryStruct.lua b/tests/libraryStruct.lua index f279934..9cdb514 100644 --- a/tests/libraryStruct.lua +++ b/tests/libraryStruct.lua @@ -1,3 +1,10 @@ -for i, v in pairs(require("syscalls")) do - print(i, v) + +local function tree(t) + for i, v in pairs(t) do + if type(v) == "table" then + tree(v) + end + end end + +tree(require("syscalls"))