This commit is contained in:
Hane 2025-09-13 19:02:57 +02:00
commit ee7d6302c5
5 changed files with 295 additions and 1 deletions

24
src/dlltest.cpp Normal file
View file

@ -0,0 +1,24 @@
#include "dlltest.h"
#ifdef __cplusplus
extern "C" {
#endif
void testprint()
{
printf("Hola, soy %s\n", "C");
return;
}
//clang -v -std=c11 -DCALCDLL_EXPORTS src/dlltest.c -shared -o src/dlltest.dll
//clang++ -v -std=c++11 -DCALCDLL_EXPORTS src/dlltest.cpp -shared -o src/dlltest.dll
CALCDLL_API BOOL __cdecl DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
return TRUE;
}
#ifdef __cplusplus
}
#endif

BIN
src/dlltest.dll Normal file

Binary file not shown.

24
src/dlltest.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef TEST_H
#define TEST_H
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <Windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CALCDLL_EXPORTS
#define CALCDLL_API __declspec(dllexport)
#else
#define CALCDLL_API __declspec(dllimport)
#endif
CALCDLL_API void __cdecl testprint();
#ifdef __cplusplus
}
#endif
#endif

BIN
src/dlltest32.dll Normal file

Binary file not shown.

View file

@ -280,4 +280,250 @@ print("Function anonimity demonstration")
foo = function (x)
return x, 2*x
end
print(foo(2))
print(foo(2)) ; foo = nil
print()
print("Function as a first-class value and closures test")
function bruh (x)
local transform = x * 2
print(transform)
return function ()
transform = transform + 1
return transform
end
end
incrementFunc = bruh(2)
print(incrementFunc())
print(incrementFunc())
print(incrementFunc())
incrementFunc, bruh = nil, nil
print()
print("Local functions (packages!: this way, we get functions only visible on the current chunk)")
local a = function () return 3 end
local function a () return 3 end --equivalent, again
function c () return a() end
print(c()) -- Since we're on the same chunk, this functions is still accesible
-- But beware! A function is compiled before its assignment is done, so it will ignore its own assignment and look for the
-- definition scopes above until getting to globals!
-- the local function name () syntax sidesteps this limitation, but indirect recursion still forces you to forward declare
local c = nil
local a = nil
print("Tail calls")
--Only this syntax performs a proper tail call:
--[[ function g(x)
return funcname(params)
end
it works with anonymous functions too!
]]
tablajemplo = { "a", "b", "c" }
tablajemplo[4] = 54
print("Iterators with closures (complex state)")
function return_ilist_values(list)
local i = 0
local num = #list
print("List size: " .. num)
return function ()
i = i + 1
if i <= num then return list[i] end
end
end
for value in return_ilist_values(tablajemplo) do
print(value)
end
print("Iterators without closures")
--Also like a generic for's internal structure exploration
function direct_iter_func(list, i)
--print("hey"..i)
num = #list
i = i + 1
if i <= num then return i, list[i] end
end
local idx = 0
for idx, value in direct_iter_func, tablajemplo, idx do
print(value)
end
print("Stateless iterators")
-- Really your most common use case, imo. State (dataset) is given with each call instead of being hardcoded into the factory's
-- code
function diypair(list)
return function (state, cvar)
cvar = cvar + 1
if state[cvar] then return cvar, state[cvar] end
end, list, 0
end
for idx, value in diypair(tablajemplo) do
print(value)
end
noenterotabla = {x = 2, b = 43, c = "si"}
for idx, value in next, noenterotabla do
print(idx .. " " .. value)
end
tablajemplo, noenterotabla = nil, nil
-- loadstring loads code from a string and assigns it to a var! Can only see global variables! loadfile, same for files! dofile
-- is an autoexec for this function with an assert! Errors as 2nd param in both load*!
--[[
f = loadstring("c = 'españa'; print(c);
function hola(letra) print(c .. ' a tope') end; hola(c)") --ret func as 1st, err as 2nd. Easier to use assert!
f()
]]
-- print("_LOADED variable (shows which files have been already loaded by require")
-- print(_REQUIREDNAME)
-- print(_LOADED)
print("Loading C dynamic libraries")
-- dll included! example compile command:
-- clang -v -std=c11 src/dlltest.h -shared -o src/test.dll
path = "F:\\carpincho\\cositas\\luar\\src\\dlltest32.dll"
local examplint = assert(package.loadlib(path, "testprint"))
examplint()
print("Using protected calls to handle errors")
--error("error test") This will stop execution
print(pcall(function () error("error test") end)) --This will not! 1st retval is bool indicating success, 2nd is error msg
local status, err = pcall(function () error({code=6667}) end)
print(tostring(status) .. " " .. tostring(err.code))
print("Still here!")
print()
print("Error tracing")
--Custom error handler
local value = 3
local status
local err
function fakebug() print("fake ass debugging") end
status, err = xpcall(function ()
if type(value) ~= "string" then
error("no coinside", 1)
end
end, fakebug)
print(tostring(status) .. " " .. tostring(err) .. "\n")
--Changing error level indication: level 1 (default: where error is called)/ 2 (where the func that calls error is used)
status, err = pcall(function ()
if type(value) ~= "string" then
error("no coinside", 2)
end
end)
print(tostring(status) .. " " .. tostring(err).. "\n")
status, err = pcall(function ()
if type(value) ~= "string" then
error("no coinside", 1)
end
end)
print(tostring(status) .. " " .. tostring(err).. "\n")
status, err = nil, nil
print("Coroutines:")
function base(x) print("vaya" .. tostring(x)) coroutine.yield("yieldturn") print("adiós" .. tostring(x)) return x + 4 end
cor = coroutine.create(base)
cor2 = coroutine.create(base)
print(coroutine.status(cor) .. " " .. coroutine.status(cor2))
print(coroutine.resume(cor, 1))
print(coroutine.resume(cor2, 3))
print(coroutine.status(cor) .. " " .. coroutine.status(cor2))
print(coroutine.resume(cor,2)) --See that params are now ignored
print(coroutine.resume(cor2,4))
print(coroutine.status(cor) .. " " .. coroutine.status(cor2))
print()
--Producer/consumer example
function producer(filename)
for line in io.lines("lines.txt") do
print("DEBUG " .. line)
coroutine.yield(line)
end
end
function consumer(filename)
if type(filename) ~= "string" then return "Not a string" end
local line
local status
produtine = coroutine.create(producer)
repeat
--print(coroutine.resume(produtine))
--line = false
status, line = coroutine.resume(produtine)
if (line) then
print(tostring(status) .. " " .. line)
end
until not line
end
print(consumer("lines.txt"))
print("Coroutines as iterators")
for i=1,3 do
print(i)
end
print()
function permgen (a, n)
--if n == 0 then
--printResult(a)
if n == 0 then
coroutine.yield(a)
else
for i=1,n do
-- put i-th element as the last one
a[n], a[i] = a[i], a[n]
-- generate all permutations of the other elements
permgen(a, n - 1)
-- restore i-th element
a[n], a[i] = a[i], a[n]
end
end
end
function perm (a)
local n = table.getn(a)
local co = coroutine.create(function () permgen(a, n) end)
return function () -- iterator
local code, res = coroutine.resume(co)
return res
end
end
function printResult (a)
for i,v in ipairs(a) do
io.write(v, " ")
end
io.write("\n")
end
local i = 1
for p in perm{"a", "b", "c", "d"} do
printResult(p)
print(i)
i = i + 1
end
--table = {1, 2, 3}
--function all_permutations(list, n)