ID:1622369
 
BYOND Version:506
Operating System:Windows 7 Home Premium 64-bit
Web Browser:Chrome 35.0.1916.153
Applies to:Dream Daemon
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary:
Unknown compilation error at a place in the code that is not erroneous.

The errors below only occur if the following file is included:
/obj/item
var/maker_cost = list(null = 20, "iron" = 1000) // null: build time


/obj/item/stack
maker_cost = null

/obj/item/stack
rods maker_cost = list(null = 20, "iron" = 300)
cable_coil maker_cost = list(null = 15, "iron" = 250)

/obj/item/stack/medical
bruise_pack maker_cost = list(null = 30, "bicaridine" = 50)
ointment maker_cost = list(null = 35, "dermaline" = 50)

/obj/item/stack/sheet
metal maker_cost = list(null = 25, "iron" = 2000)
plasteel maker_cost = list(null = 40, "plasteel" = 2000) // maker reagent
glass maker_cost = list(null = 20, "glass" = 2000)
rglass maker_cost = list(null = 30, "rglass" = 2000) // maker reagent
cardboard maker_cost = list(null = 10, "cardboard" = 1000) // maker reagent
cloth maker_cost = list(null = 15, "cloth" = 1000) // maker reagent
leather maker_cost = list(null = 25, "leather" = 1000) // maker reagent
xenochitin maker_cost = list(null = 30, "xenol" = 1000) // maker reagent

/obj/item/stack/sheet/mineral
clown maker_cost = list(null = 100, "bananium" = 2000) // maker reagent
diamond maker_cost = list(null = 100, "diamond" = 1000) // maker reagent
gold maker_cost = list(null = 30, "gold" = 1000)
plasma maker_cost = list(null = 50, "splasma" = 2000) // maker reagent
sandstone maker_cost = list(null = 60, "sandstone" = 1500) // maker reagent
silver maker_cost = list(null = 30, "silver" = 1000)
uranium maker_cost = list(null = 30, "uranium" = 500)
wood maker_cost = list(null = 50, "wood" = 1000) // maker reagent

/obj/item/stack/tile
carpet maker_cost = list(null = 150, "carpet" = 50) // maker reagent
grass maker_cost = list(null = 150, "grass" = 50) // maker reagent
light maker_cost = list(null = 250, "iron" = 150, "glass" = 250)
plasteel maker_cost = list(null = 150, "iron" = 500)
wood maker_cost = list(null = 150, "wood" = 250) // maker reagent
Note the inconsistent number of tabs between subtype and variable name, for file formatting purposes.

The lines giving errors all follow the following pattern:
non\adjacent\file.dm:74:error: =: expected 2 arguments (found 4)

The erronous line in that file:
/obj/item/stack/medical/bruise_pack
name = "bruise pack" // this line
singular_name = "bruise pack"

In every case, it is the first line after a full path, that full path is one of the paths modified in the file above, and coincidentally in each case it is a name= line. The error is the same in all cases (expected 2 arguments (found 4)). It appears to exist for all lines in that file but I will double check that.

Numbered Steps to Reproduce Problem:
See below

Expected Results:
Sane compilation of highly nonstandard code which I intend to merge later

Actual Results:
I am honestly not sure what is even going on here

Does the problem occur:
Every time? Or how often? Happens when the code is compiled in the full project. If that file is not included, the errors disappear. (the missing variable must be re-added elsewhere for compilation, but it does compile) In a test project with just that code, compilation works.
On other computers? not tested

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)
Unknown
Workarounds:
Unknown at this time

--

I appreciate that this bug report is not terribly helpful, but I thought giving you a heads up about it would be preferable to never mentioning it.

What is baffling about the bug to me is that the error given is miles away from the code that causes the fault, and makes not the slightest bit of sense. It seems to be a compiler glitch that I may simply need to work around.
Changing lines from
/obj/item/stack
rods maker_cost = list(null = 20, "iron" = 300)
cable_coil maker_cost = list(null = 15, "iron" = 250)
to
/obj/item/stack
rods
maker_cost = list(null = 20, "iron" = 300)
cable_coil
maker_cost = list(null = 15, "iron" = 250)
makes the problem go away, on a case by case basis (lines with the peculiar formatting continue to give errors)

This works fine for my purposes but I remain curious exactly what went wrong under the hood...

Edit:
In the small test project version, the project not only compiles properly but stores the values of maker_cost correctly for all object types.

Edit 2:
Aha! The test project compilation fails if the line giving the error occurs before the weirdly tabbed stuff, but succeeds if it comes afterwards. That's odd...
Test project, fails compilation:
/obj
var/variable

/obj/item
name = "item"

/obj
item variable = "stuff"


Test project, compilation succeeds:
/obj
var/variable

/obj
item variable = "stuff"

/obj/item
name = "item"

The only difference is the location in the file of the line that uses whitespace as a path separator.

Compilation fails on #1 if tabs or spaces are used for the path separator, but it succeeds if / is used, or if variable is on a new line and indented.
I'm not certain using whitespace on the same line like that is so much valid syntax, although I see the benefits of it from a readability standpoint. To my knowledge I don't recall ever seeing BYOND code written that way. Mostly I'm curious if you can point me to any documentation that says this usage is valid--because if we have stuff that says it is, we probably want to make it that way.

As for the error message showing up far from the code itself, that makes sense to me on one level because this is basically an indentation issue, which tends to manifest in weird ways. Essentially the compiler is confused by the whitespace being way different from its expectations, and might not realize until very late that something has gone awry. That said, I think it'd be great if there were some way for any indentation-related issues (if they can be perceived as such) to give users a better clue as to where things might have gone wrong.
I don't even remember, you're right that it's not in the reference docs anywhere that I can see. I didn't discover it on my own, I am sure I read it somewhere a long time ago, probably in some sort of example code. I will look around to see if I can figure out where I saw it.

It does *work*, this bug aside. Which is to say, as long as it preceeds all other code for that object type, it compiles correctly.

I do not intend to use it on a regular basis; the code that caused the error originally is a temporary file where I am tacking on a feature to a large project and don't want to hunt through a dozen files to find lines to change until things are finalized.
Hierarchy is not a database.

Have you ever considered using the "{" tokens instead of whitespace?
Hierarchy is not a database.

I don't understand what you mean. I didn't come up with the "spaces as path separator", nor did I bring it from outside; I read it somewhere relating to byond specifically, but I can't find where anymore. I did spend at least half an hour looking.

{} might work, but again, I don't really need to use the syntax given (nor am I endorsing it, I just wanted a pretty file, otherwise I could use / and to heck with the indentation), I am just pointing out a glitch
This isn't a bug. BYOND has two means of delineating a new expression.

One is newline/whitespace-tokenized, the other is semicolon and bracket tokenized. Using a tab or a space isn't a valid scope identifier without first having a newline.

In order for this to work, you'll have to do something like this:

/obj/item/stack
rods{maker_cost = list(null = 20, "iron" = 300);}
Actually I'm not certain that the {} notation will work in this case, as it still requires consistent whitespace (a design decision we made many years ago to prevent ill-formatted code, even with the familiar braces). I may be mistaken.
Compiles just fine, Tom. Anyway, the format is similar to an inline modified type, which is something that is underused.
Good to know! I was under the impression the {} were basically cosmetic but I guess there are some edge cases like this.
This isn't a bug.

The test code given compiles exactly half the time depending on where it is in the file.

It's a bug. Whether you want to remove the feature or fix it is up to you.
The test code given compiles exactly half the time depending on where it is in the file.

Sounds like the fact that it even compiles is the bug. Can you isolate the situation where it will actually compile?

The compiler's inner workings should never result in a "half the time" scenario. It sounds to me like "half the time" may not in fact be "half the time", but rather, a scenario where the context of this code has been changed is occurring.
I think the location within the file causing different results merely means that the indentation confusion resulting from this syntax is of a different nature depending on the surrounding code. Which makes sense, really; any syntax error that throws a compiler too far off what it expects is liable to be caught in unpredictable ways or places. There may well be specific circumstances where the code compiles normally just because the mistakes fit in with what it would expect as normal indentation at that point in the file. Also there could be plenty more cases where it compiles without incident, but may not actually be correct internally compared to what was intended.

Unless the space-as-slash syntax is specifically listed as supported anywhere, my instinct is to say this isn't actually a bug: just a case of syntax errors causing arbitrary results, as is their wont. There might be room to improve on their response, at least when an error is detected at all. But heck, every compiler has places where it produces odd errors if the syntax isn't followed. The bug, as I see it, would be as Ter said: that sometimes it compiles without complaint. But since it stems from a syntax error, those kinds of things can be difficult to fix.
alright, fair enough, clearly whitespace as path separator doesn't actually seem to work. It's weird that I remembered seeing it, and it did work in the edge case I posted above.

Without going through the myriad cases that don't work, again, this case definitely compiles correctly:
/obj/var/variable
/obj/item variable = "stuff"

where the variable is already defined and it's just a case of overriding that one variable in that one subtype--which is basically what I was using it for.

This suggests to me that the syntax was meant to allow you to create "only one variable differs" subtypes. If you reference the "only one variable differs" subtype after that code compiles, it is correct in the object tree.

However, and I am guessing here, if the syntax sees an "only one variable differs" subtype code for an existing type in the object tree, it screws up the compilation?