S2 Guide: Troubleshooting
Syntax checklist
- Are you ending all statements with a semicolon (;)?
- Have you declared all variables you are using?
- Are you using $ when you're accessing variables?
- Do your function calls have matching parentheses?
- Do your code blocks have matching brackets?
Deciphering compile errors
The layer editor won't let you save a layer that contains compiler errors. Let's say that in the S2 Cookbook: A Testbed Layout, I test some code that has syntax errors where it says "# Code you want to test goes here". Here are some example situations of the kinds of compile errors I can encounter, and their solution.
Forgetting to declare a variable
Let's make a really easy error first, to get through the basics. Here's an example where I forget to declare the $test variable before I use it:
var int length = $test->length();
When I try to save and compile, this is the compiler error I get:
S2 Compiler Output at Thu Jun 17 10:23:17 2010 Error compiling layer: Compile error: line 15, column 22: Unknown local variable $test S2::NodeVarRef, S2/NodeVarRef.pm, 180 S2::NodeVarRef, S2/NodeVarRef.pm, 151 S2::NodeTerm, S2/NodeTerm.pm, 182 S2::NodeTerm, S2/NodeTerm.pm, 66 S2::NodeExpr, S2/NodeExpr.pm, 46 S2::NodeVarDeclStmt, S2/NodeVarDeclStmt.pm, 54 S2::NodeStmtBlock, S2/NodeStmtBlock.pm, 108 S2::NodeFunction, S2/NodeFunction.pm, 230 S2::Checker, S2/Checker.pm, 374 S2::Compiler, S2/Compiler.pm, 34 Context 11: """</head>"""; 12: """<body>"""; 13: 14: 15: var int length = $test->length(); 16: 17: """</body>"""; 18: """</html>"""; 19: }
You'll notice that the compiler gives us the line and column (how many characters from the start of the line) the error starts on. The message in this instance is pretty obvious--it's telling us that that the variable $test is unknown. The traceback afterwards probably isn't too useful to us most people, however.
After the error message and traceback, the compiler helpfully gives us some context consisting of the line it had trouble with along with the some surrounding lines. This helps us find the troublesome place in the code, or see if we can see what the problem is.
To fix this problem, we just need to declare the variable before we use it:
var string test = "test"; var int length = $test->length();
Mixing up variable types
Not putting $ in front of a variable being accessed
Here's some code where I forgot to put a $ in front of a variable I am using:
var string test = "test"; var int length = test->length();
This is the compiler error I get:
S2 Compiler Output at Thu Jun 17 10:13:02 2010 Error compiling layer: Compile error: line 15, column 26: Unexpected token found. Expecting [TokenPunct] = ( Got: [TokenPunct] = -> S2::Node, S2/Node.pm, 144 S2::NodeArguments, S2/NodeArguments.pm, 25 S2::NodeTerm, S2/NodeTerm.pm, 471 S2::NodeIncExpr, S2/NodeIncExpr.pm, 41 S2::NodeTypeCastOp, S2/NodeTypeCastOp.pm, 29 S2::NodeInstanceOf, S2/NodeInstanceOf.pm, 29 S2::NodeUnaryExpr, S2/NodeUnaryExpr.pm, 40 S2::NodeProduct, S2/NodeProduct.pm, 28 S2::NodeSum, S2/NodeSum.pm, 31 S2::NodeRelExpr, S2/NodeRelExpr.pm, 29 S2::NodeEqExpr, S2/NodeEqExpr.pm, 29 S2::NodeLogAndExpr, S2/NodeLogAndExpr.pm, 29 S2::NodeLogOrExpr, S2/NodeLogOrExpr.pm, 29 S2::NodeRange, S2/NodeRange.pm, 29 S2::NodeCondExpr, S2/NodeCondExpr.pm, 29 S2::NodeAssignExpr, S2/NodeAssignExpr.pm, 29 S2::NodeExpr, S2/NodeExpr.pm, 29 S2::NodeVarDeclStmt, S2/NodeVarDeclStmt.pm, 33 S2::NodeStmt, S2/NodeStmt.pm, 62 S2::NodeStmtBlock, S2/NodeStmtBlock.pm, 43 S2::NodeFunction, S2/NodeFunction.pm, 104 S2::Layer, S2/Layer.pm, 59 S2::Compiler, S2/Compiler.pm, 27
Context 11: """</head>"""; 12: """<body>"""; 13: 14: var string test = "test"; 15: var int length = test->length(); 16: 17: """</body>"""; 18: """</html>"""; 19: }
You'll note that the compiler error doesn't tell us exactly what the problem is. It tells us what "token" (part of the programming language) it was expecting, and what it got.
I'm going to put a bracket set ([]) into the exact position the compile error is complaining about:
var int length = test[]->length();</em>
We can note that if the token the compiler was expecting (() was in that position, it would be as if we were calling a global function. That's because there's no $ to make the compiler expect a variable instead. If we run through the checklist listed above on this line, however, we'll find that we've broken the rule about $s indicating we're using a variable.
To fix the error, we put the $ character in front of the variable we're trying to access.
var string test = "test"; var int length = $test->length();