Hello com,
I'm working on this little program now for an day and It won'T work right.
It's is a debugger which displays all variables of an program and allows you to change them.
local args = {...}
local fileName = args[1]
local debugKey = keys.f2
local running = true
local programIsRunning = true
local env = {}
local fileContent = {}
local handle = fs.open(fileName,"r")
local sLine = handle.readLine()
while sLine do
fileContent[#fileContent+1] = sLine:gsub("local","") --make all variables global
sLine = handle.readLine()
end
handle.close()
local handle = fs.open(".debug_file","w")
for k,v in pairs(fileContent) do
handle.writeLine(v.."\n")
end
handle.close()
local function run()
dofile(".debug_file")
end
setfenv(run, env)
local function debug()
while true do
sleep(0)
term.setBackgroundColor(colors.lightGray)
term.clear()
term.setCursorPos(1,1)
for key,var in pairs(env) do
print(key, " = ", var)
end
end
end
local runCo = coroutine.create(run)
local debugCo = coroutine.create(debug)
coroutine.resume(runCo)
while running do
local evt = {os.pullEvent()}
if evt[1] == "key"and evt[2] == debugKey then
programIsRunning = not programIsRunning
end
if programIsRunning then
if coroutine.status(runCo) ~= "dead" then
coroutine.resume(runCo, unpack(evt))
end
else
if coroutine.status(debugCo) ~= "dead" then
coroutine.resume(debugCo, unpack(evt))
end
end
end
this is my test program:
local count = 1
while true do
count = count+1
term.setBackgroundColor(colors.green)
term.clear()
term.setCursorPos(1,1)
term.write("count = "..count)
sleep(1)
end
I want that it run the program and when I press F2 it switches between the modes. but It neither run the program nor displays the variables and if I hit the F2 key in the debug mode, it don't switches to the program. What I am doing wrong?
You are not getting the environment of the program in question. To get the environment of a program I suggest doing something similair like this:
local file = fs.open( filename, 'r' )
local content = file.readAll():gsub( 'local', '' )
file.close()
local func, err = loadstring( content, filename )
if not func then
error( 'Compile error: ' .. err, 0 )
end
local ok, err_ = pcall( func ) -- you have to execute the function before you can get the environment
if not ok then
error( 'Runtime error: ' .. err_, 0 )
end
local fileEnv = getfenv( func )
-- this table contains everything from the _G table and the global vars of the file
You are not getting the environment of the program in question. To get the environment of a program I suggest doing something similair like this:
local file = fs.open( filename, 'r' )
local content = file.readAll():gsub( 'local', '' )
file.close()
local func, err = loadstring( content, filename )
if not func then
error( 'Compile error: ' .. err, 0 )
end
local ok, err_ = pcall( func ) -- you have to execute the function before you can get the environment
if not ok then
error( 'Runtime error: ' .. err_, 0 )
end
local fileEnv = getfenv( func )
-- this table contains everything from the _G table and the global vars of the file
okay, now I get everything in the _G table but I only want the variables of my debugged program...
And why isn't the test program running while debugging?
Engineer is probably right about your needing to start smaller if you can't filter out the table on your own, but since I don't really see the harm in explaining this one thing, I'll try to show you how I might go about it.
You could simply iterate through the table using pairs and remove anything that has a type of "function".
local functionIndexes = {}
for index, value in pairs (env) do
if type (value) == "function" then
functionIndexes[index] = true
end
end
for functionIndex, _ in pairs (functionIndexes) do
env[functionIndex] = nil
end