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

weird table syntax

Started by Creeper9207, 05 January 2017 - 08:14 PM
Creeper9207 #1
Posted 05 January 2017 - 09:14 PM
http://pastebin.com/Bcs8xVA2 <– full code (sorry about readability)

to save you some time, i'll put here where i think the code is breaking:
Example 1
function makeRenderObjects()
	renderc=1
	renderObjects={}
	for k,v in pairs(lines) do
		beginp, endp = string.find(lines[k], 'function')
		if beginp ~= nil then
			for i = beginp, endp do
				lines[k]=string.gsub(lines[k],'function','		')
			end
			renderObjects[renderc] = {}
			renderObjects[renderc]['text']="function"
			renderObjects[renderc]['x'] = beginp
			renderObjects[renderc]['y'] = k
			renderObjects[renderc]['color']=colors.blue
		end
	end
end
Example 2
function render()
	--term.write(lines[k])
	renderObjects={}
	makeRenderObjects()
	for k,v in pairs(lines) do
		term.setBackgroundColor(colors.gray)
		term.setCursorPos(1,k+uioff)
		term.write(k)
		--term.setBackgroundColor(colors.gray)
		term.setCursorPos(4,k+uioff)
		term.write(lines[k])
	end
	for k,v in pairs(renderObjects) do
		os.setComputerLabel("yeak ok") -- THIS LINE IS NEVER CALLED
		term.setCursorPos(renderObjects[k]['x']+3,renderObjects[k]['y']+uioff)
		term.setTextColor(renderObjects[k]['color'])
		term.write(renderObjects[k]['text'])
	end
	term.setTextColor(colors.white)
end

Essentially, the idea is that the word 'function' is taken out of the string &amp; put into a seperate drawing call to show up as blue, the problem is (line 232 in pastebin, example 2, line 16 in text post) is never called, meaning that (line 89-94 in pastebin, example 1, line 11-15 in text post) is not doing it's job, but IS called.
Edited on 05 January 2017 - 11:18 PM
Bomb Bloke #2
Posted 06 January 2017 - 12:45 AM
… meaning that (line 89-94 in pastebin, example 1, line 11-15 in text post) is not doing it's job, but IS called.

No, those lines aren't being called. If the term "function" existed anywhere within the strings in the "lines" table they would be, which would likewise lead to the final loop in the render() function doing something.

A couple of notes; in a conditional test, nil counts as false, and anything that is not nil/false counts as true. You can hence replace this sort of thing:

if beginp ~= nil then

… with this sort of thing:

if beginp then

… whereas "not beginp" would resolve as true if beginp were nil or false.

This loop here is redundant:

        for i = beginp, endp do
            lines[k]=string.gsub(lines[k],'function','        ')
        end

… and could be shortened to just:

        lines[k] = v:gsub('function','        ')

… though either way you'll only be able to highlight one instance of "function" per string; I assume that's not a problem for your purposes.

makeRenderObjects() is a redundant function - you only ever call it from one place in your code, inside the render() function, so why not just put its code in the render() function? Don't try to use function definitions in place of comments; making people scroll up and down to read linear code is annoying.
Creeper9207 #3
Posted 06 January 2017 - 06:00 AM
in the actual file set, the code is divided into three files, to keep render() readable, makeRenderCode() is stored in a seperate file, here is what happens when "function" is typed: http://104.236.237.237/dem.mp4 (proof that gsub is being called)

The loop IS redundant, i just forgot to remove it because it originally :sub()ed every position in that range with " "

thanks for the notes, but still not sure why it's not working
Edited on 06 January 2017 - 05:02 AM
Bomb Bloke #4
Posted 06 January 2017 - 06:08 AM
Ah, so you're typing it in at runtime. That to me suggests that the entry exists in your renderObjects for just a fraction of a second before makeRenderObjects() gets called again, fails to find "function" a second time (because it removed it the first time…), and therefore doesn't stick it in the new renderObjects table.

Another thing I forgot to mention, did you intend to increment renderc at any point?
Creeper9207 #5
Posted 06 January 2017 - 06:33 AM
i made a couple modifications, incremented renderc, created a tempvar, linus=lines, and replaced all instances of lines in makerendercode with linus, but it still cuts it out of lines for some reason (meaning the behaviour shown in the video still applies)

also, instead of formatting it for pastebin again, i just included all four files here:
http://104.236.237.237/tempdir/
Edited on 06 January 2017 - 05:35 AM
Bomb Bloke #6
Posted 07 January 2017 - 12:35 AM
When you attempt to assign a table to a variable, what you're actually doing is assigning a pointer that leads to that table. If you copy that pointer to a new variable, you then have two variables that point to the one table.

a = {}
b = a

a.someKey = "hello"
print(b.someKey)  --> "hello"

If you want to create a clone of a table then you need to make a new one and copy in the content from the old. Eg:

lines={"hello!","how you do","l3","l4","l5","l6","l7","l8"}

linus = {}

for i = 1, #lines do linus[i] = lines[i] end

Assigning functions and coroutines works the same way as with tables.

Again, you'd be better off merging your functions. Why even build a linus table to cache parsed content when you could just output it on the spot and then discard it?
Edited on 06 January 2017 - 11:38 PM