You need a register allocator function that takes into account the address and size of the last register. This allocator will dynamically create new registers as you request them.
local startAddr = 3000
local sizes = {float = 2, int = 2, int64 = 4}
local registers = {}
local function allocRegister(type)
if sizes[type] == nil then
error'invalid register type'
end
local n = #registers
local addr
if n == 0 then -- If this is the first register, use the starting address.
addr = startAddr
else -- Determine the next starting address based on the last register's address & size.
addr = registers[n].addr + registers[n].count
end
table.insert(registers, { addr = addr, count = sizes[type], type = type, knx = '1/1/' .. n + 1 })
end
-- Example usage:
allocRegister'float'
allocRegister'int64'
allocRegister'int'
-- Resulting table:
{
{ addr = 3000, count = 2, knx = "1/1/1", type = "float" },
{ addr = 3002, count = 4, knx = "1/1/2", type = "int64" },
{ addr = 3006, count = 2, knx = "1/1/3", type = "int" }
}
You could use this function in a loop just as well, too. The following loop would create a register table very similar to the one in your question.
for i=1, 9 do allocRegister'float' end
allocRegister'int64'
Edit: The following code should be illustrative enough to show you how to solve your problem.
local sizes = {float = 2, int = 2, int64 = 4}
local registers = {}
local usedSpace = {}
local function allocRegisters(t)
for i=1, #t do
local addr, size = t[i].addr, sizes[t[i].type]
if size == nil then
error('invalid register type: ' .. t[i].type)
end
-- Check if there's free space for this register.
for j=addr, addr+size-1 do
if usedSpace[j] then
error('address already in use: ' .. addr)
end
end
-- Mark the space for this register as used.
for j=addr, addr+size-1 do
usedSpace[j] = true
end
-- Copy the register into the registers table, setting knx by using the length of the table.
table.insert(registers, { addr = addr, count = size, type = t[i].type, knx = '1/1/' .. #registers + 1})
end
end
-- Example usage:
allocRegisters {
{ addr = 3000, type = 'float' },
{ addr = 3003, type = 'int' },
{ addr = 3009, type = 'int64' }
}