Compare commits

...

2 commits

Author SHA1 Message Date
ee7d6302c5 part1! 2025-09-15 19:57:29 +02:00
0263e5fae0 1-5 and part of 6 2025-09-10 22:07:54 +02:00
6 changed files with 582 additions and 0 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.

5
src/lines.txt Normal file
View file

@ -0,0 +1,5 @@
linea1
linea2
linea3
linea4
linea5

529
src/main.lua Normal file
View file

@ -0,0 +1,529 @@
local dbg = require 'debugger'
-- Func asand type test
-- print("hello world")
-- function factos (n)
-- -- dbg()
-- if n == 0 then
-- return 1
-- else
-- return n * factos(n - 1)
-- end
-- end
-- print("Enter a number: ")
-- a = io.read("*number")
-- print(factos(a))
-- print(type(factos))
-- print(type(false))
print("String test")
asciicore = "alo123\thola\n"
asciicore2 = "\97lo\9hola\49 \10"
io.write(asciicore); print(asciicore2);
paragraphcore = [[
increible
la maravilla
interpretada ]]
print(paragraphcore)
print(10 .. 20) --string conversion, concat
print(10 + 20) --int sum, string conversion
print(10 == "10")
print("Table test")
a = {} -- create a table and store its reference in `a'
k = "x"
a[k] = 10 -- new entry, with key="x" and value=10
a[20] = "great" -- new entry, with key=20 and value="great"
print(a["x"]) --> 10
k = 20
print(a[k]) --> "great"
a["x"] = a["x"] + 1 -- increments entry "x"
print(a["x"]) --> 11
print()
print(a["z"])
a["z"] = nil
print(a["z"])
a = nil
print()
print("Convention: tables in lua are usually indexed starting with 1, the stdlib follows this")
arr = {}
for i=0,9 do
arr[i] = i*2
end
for i=0,9 do
print(arr[i])
end
print()
print("Convention: using nil as table end. ipairs follows this")
arr[10] = nil
arr[11] = 34
for i,number in ipairs(arr) do
print(number)
end
arr = nil
print()
print("Array indexing doesn't perform any type conversion")
i = 10; j = "10"; k = "+10"
a = {}
a[i] = "one value"
a[j] = "another value"
a[k] = "yet another value"
print(a[i]) --> one value
print(a[j]) --> another value
print(a[k]) --> yet another value
print(a[tonumber(j)]) --> one value
print(a[tonumber(k)]) --> one value
a = nil
print()
print("Logical operators test")
v = 3
--x = 4
x = false -- boolean, while a value, is evaluated as it should and replaced by the expression:
print(type(x))
if not x then x = v end
print(tostring(x))
print(type(x).."\n")
print(nil and false)
print(4 and false)
print(4 and 5)
if (4 and false) then
print("si")
else
print("no")
end
print()
val = v and 7 or 14
print(val)
v = false
val = v and 7 or 14
print(val)
val = (v == false) and 7 or 14
print(val)
val = (v ~= false) and 7 or 14
print(val)
v = nil; print()
print("Operator precedence")
x = 3
print(x^3)
print("Tables")
local math = require 'math'
tab = {math.sin(1), math.sin(2), math.cos(3)}
print(tab[1] .. " " .. tab[3])
print("Using table to implement linked list")
list = nil
for line in io.lines("lines.txt") do
list = {next=list, value=line}
print(tostring(list.next) .. " " .. list.value)
end
l = list
while l do
print(l.value)
l = l.next
end
l = nil; list = nil; value = nil;
print()
print("Mixing initializations and constructing tables within tables")
polyline = {color="blue", thickness=2, npoints=4,
{x=0, y=0},
{x=-10, y=0},
{x=-10, y=1},
{x=0, y=1}
}
print(polyline[1])
print(polyline[1].x)
print(polyline.color)
print(polyline[2])
print(polyline[2].x)
polyline = nil
print()
print("Explicitly writing index as an expr")
opnames = {["+"] = "add", ["-"] = "sub",
["*"] = "mul", ["/"] = "div"}
i = 20; s = "-"
a = {[i+0] = s, [i+1] = s..s, [i+2] = s..s..s}
print(opnames[s]) --> sub
print(a[22]) --> ---
a = nil; i = nil; opnames = nil;
print()
print("Assignments")
x = 1; y = 2;
x, y, c = y, x --[[Variables are first evalueated and then swapped. Extra var is set to nil, extra value is discarded.
Always 1 value per var, no multi assignments]]
print(x .. " " .. y)
x = nil; y = nil
print("Local variables: chunk, func or control block. On repl")
local a = 3; print(a) --Would print 3
local a = 3
print(a) --Would print nil on repl since we're not anymore at the scope where a was declared. Use do-end (equiv to { }, scope delimiters)!
local a = nil
print()
print("Control structures: numeric for")
for i=1,4,2 do --initial value, max value, increment(optional = 1)
print(i)
end
function f()
return 3
end
print()
for i=1,f() do
print(i)
end
print()
f = nil
print("Control structures: generic for (foreach)")
a = {1, 2}
for i, v in ipairs(a) do print(i .. " " .. v) end
a = {x=1, y=2}
for i, v in pairs(a) do print(i .. " " .. v) end
for v in pairs(a) do print(v) end --only print keys
a = nil; print()
print("Functions")
--No strict control of number of parameters passed to func (extra params = discarded, missing params = vars set to nil)
function f(x, y, z)
z = z or 1
y = y or 1
x = x or 1
return x + y + z
end
print(f(2)) --4
print(f(2,3)) --6
print(f(2,3,4)) --9
print(f(2,3,4,9)) --9
--Tables can be used as references for the content within, although with multiple retvals this should be seldomly used
function ft(a)
if (type(a) ~= "table") then
return
end
a[1] = 3
return
end
a = {6}
ft(a); print(a[1])
print()
--Functions only return multiple values if they're the single or last expression:
function multireturn(a, b)
return a, b
end
do
local a, b, c = multireturn(1, 2)
print(tostring(a) .. " " .. tostring(b) .. " " .. tostring(c))
local a, b, c = 10, multireturn(1, 2)
print(tostring(a) .. " " .. tostring(b) .. " " .. tostring(c))
local a, b, c = multireturn(1, 2), 10
print(tostring(a) .. " " .. tostring(b) .. " " .. tostring(c)) --See how c is nil? We only kept the function's first retval
end
print()
--Same thing happens when expr is part of another function call (args)
print(multireturn(1,2))
print(10, multireturn(1,2))
print(multireturn(1,2), 10)
print(multireturn(1,2) .. 10)
print(10 .. multireturn(1,2)) --And when it's a part of a expression, it always truncates extra retvals
print()
--Variadic functions
function nsum(...)
local nsum = 0
for i,v in ipairs(arg) do
nsum = nsum + v
end
print(nsum .. "\n")
--[[Equivalent to
for i = 1,arg.n do
nsum = nsum + arg[i]
end
print(nsum .. "\n")
]]
for i,v in pairs(arg) do
print(i .. " " .. v)
end
print()
return nsum
end
print(nsum(2,3,4))
--TODO: Re-read chapter 5
print("Function anonimity demonstration")
foo = function (x)
return x, 2*x
end
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)