This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Sewbacca's profile picture

Compiler

Started by Sewbacca, 16 March 2016 - 01:52 PM
Sewbacca #1
Posted 16 March 2016 - 02:52 PM
I want to allow compiling programs.

My code:

file fs:

fs["compile"] = function(source, destination)
  local wFile = loadfile(source)
  local file = io.open(destination or source, "w")
  file:write(string.dump(wFile))
  file:close()
end

fs["execute"] = function(sPath, ...)
  local compiled = io.open(sPath)
  local file = loadstring(compiled:read("*a"))
  return file(...), compiled:close()
end

fs["load"] = function(sPath)
  local compiled = io.open(sPath)
  local file = loadstring(compiled:read("*a"))
  return file, compiled:close()
end

I did this:

lua> dofile("/fs")
lua> fs.compile("/rom/programs/fun/worm", "/worms")
lua> fs.execute("/worms")
Java heap space error
Goodbye

What did I wrong?
SquidDev #2
Posted 16 March 2016 - 03:08 PM
You're trying to save a binary string. CC doesn't like that and so loading it produces garbage. You'll need to use binary mode instead and then write (and read) each byte individually.


local function readFileBinary(path)
		local handle = fs.open(path, "rb")
		local result = {}
		while true do
				local char = handle.read()
				if char then result[#result + 1] = string.char(char) else break end
		end
		handle.close()
		return table.concat(result)
end


local function writeFileBinary(path, text)
		local handle = fs.open(path, "wb")
		for i = 1, #text do handle.write(text:sub(i, i):byte()) end
		handle.close()
end

Edited on 16 March 2016 - 03:00 PM
Sewbacca #3
Posted 16 March 2016 - 03:47 PM
New Code:

local function readFileBinary(path)
  local handle = fs.open(path, "rb")
  local result = {}
  while true do
	local char = handle.read()
	if char then result[#result + 1] = string.char(char) else break end
  end
  handle.close()
  return table.concat(result)
end

fs["compile"] = function(source, destination)
  local wFile = loadfile(source)
  local file = fs.open(destination or source, "wb")
  file.write(string.dump(wFile))
  file.close()
end

fs["execute"] = function(sPath, ...)
  local file = loadstring(readFileBinary(sPath))
  return file(...)
end

fs["load"] = function(sPath)
  local file = loadstring(readFileBinary(sPath))
  return file
end

lua> dofile("/fs")
lua> fs.compile("/rom/programs/fun/worm", "/worms")

The file is empty.
Edited on 16 March 2016 - 02:50 PM
SquidDev #4
Posted 16 March 2016 - 04:00 PM
You'll need to use binary mode instead and then write each byte individually.


fs["compile"] = function(source, destination)
  local wFile = loadfile(source)
  local file = fs.open(destination or source, "wb")
  file.write(string.dump(wFile)) -- You're writing the whole string not each byte.
  file.close()
end
Edited on 16 March 2016 - 03:49 PM
Sewbacca #5
Posted 16 March 2016 - 04:21 PM
New Code:


fs["compile"] = function(source, destination)
  local wFile = string.dump(loadfile(source))
  local file = fs.open(destination or source, "wb")
  for i = 1, #wFile do
	file.write(wFile:sub(i, i))
  end
  file.close()
end

Still an empty file

EDIT:

Oh, maybe, but just maybe I have to convert it into a byte.

IT WORKS!!!

Thanks!
Edited on 16 March 2016 - 03:22 PM