Difference between revisions of "S2 Guide: Troubleshooting"

From Dreamwidth Notes
Jump to: navigation, search
 
(8 intermediate revisions by 2 users not shown)
Line 6: Line 6:
 
* Do your function calls have matching parentheses?
 
* Do your function calls have matching parentheses?
 
* Do your code blocks have matching brackets?
 
* Do your code blocks have matching brackets?
 +
* If the error is on a line you are trying to use a variable in a string, have you tried using the <tt>${variable}</tt> format?
  
 
== Deciphering compile errors ==
 
== 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.
 
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.
 +
 +
=== Compiler background ===
 +
 +
The compiler is a program that:
 +
 +
* Breaks up the S2 code into little chunks called "tokens" or "nodes"
 +
* Assembles all those tokens into a working program in Perl
 +
 +
If we break the rules of the S2 programming language, the compiler can give errors.
  
 
=== Forgetting to declare a variable ===
 
=== Forgetting to declare a variable ===
Line 51: Line 61:
 
   19: }
 
   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 <tt>$test</tt> is unknown.  The traceback afterwards probably isn't too useful to us most people, however.
+
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 <tt>$test</tt> is unknown.  The lines after that are called a traceback, and they indicate what steps the parser was taking to make the tokens--this is usually not very useful to most people.
  
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.
+
After the error message and traceback, the compiler helpfully gives us some context consisting of the line it had trouble with, emphasized, 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:
 
To fix this problem, we just need to declare the variable before we use it:
Line 130: Line 140:
 
   19:    """</html>""";
 
   19:    """</html>""";
 
   20: }
 
   20: }
 +
 +
Fixing this problem depends on what you were trying to achieve, but you need to make sure you're not trying to match up two values of a different type.
  
 
=== Forgetting the semicolon (;) at the end of a statement ===
 
=== Forgetting the semicolon (;) at the end of a statement ===
Line 160: Line 172:
 
   18:    """</html>""";
 
   18:    """</html>""";
 
   19: }
 
   19: }
   
+
 
 +
The compiler tells us it was expecting a ";" character instead of what it found. Notice that this time, the line the compiler has trouble with is the line <em>after</em> the line we forgot the semicolon on. 
 +
 
 +
That's because the compiler doesn't look at line breaks to figure out where statements end, it looks at semicolons for that. This means that you can split a single statement over two lines, if you wanted to. Here's an example of that statement (properly ended) across two lines: :
 +
 
 +
<syntaxhighlight lang="s2">
 +
    var string test =
 +
        "test";
 +
    var int length = $test->length();
 +
</syntaxhighlight>
 +
 
 +
A line that doesn't end in a semicolon is not automatically a problem for the compiler -- but when the next line doesn't make sense as a continuation of the statement, it will trigger an error. To fix this problem, we need to put a semicolon at the end of the appropriate line:
 +
 
 +
<syntaxhighlight lang="s2">
 +
    var string test = "test";
 +
    var int length = $test->length();
 +
</syntaxhighlight>
 +
 
 
=== Not putting $ in front of a variable being accessed ===
 
=== Not putting $ in front of a variable being accessed ===
  
Line 201: Line 230:
 
   S2::Compiler, S2/Compiler.pm, 27
 
   S2::Compiler, S2/Compiler.pm, 27
 
    
 
    
 
+
 
  Context
 
  Context
 
   
 
   
Line 216: Line 245:
 
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.
 
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:
+
I'm going to put a bracket set (<tt>[]</tt>) around the exact position the compile error is complaining about expecting an open parenthesis(<tt>(</tt>) there:
  
  var int length = test[]->length();</em>
+
  var int length = test<strong>[-]</strong>>length();
  
We can note that if the token the compiler was expecting (<tt>(</tt>) was in that position, it would be as if we were calling a global function. That's because there's no <tt>$</tt> 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 <tt>$</tt>s indicating we're using a variable.
+
Why was the compiler expecting an open parenthesis there? Without <tt>$</tt> in front of test, the compiler doesn't know to treat it as a variable. It instead treats test as a global function, and function calls require parentheses, e.g. <tt>test()</tt>.
 +
 
 +
Since that error message is pretty confusing, the best way to figure out the problem is to examine the line and run through the Syntax Checklist listed above. We'll find that we've broken the rule about using $ when we're accessing variables.
  
 
To fix the error, we put the <tt>$</tt> character in front of the variable we're trying to access.
 
To fix the error, we put the <tt>$</tt> character in front of the variable we're trying to access.
Line 265: Line 296:
 
   S2::Compiler, S2/Compiler.pm, 27
 
   S2::Compiler, S2/Compiler.pm, 27
 
    
 
    
+
 
 
  Context
 
  Context
 
   
 
   
Line 272: Line 303:
 
   13:  
 
   13:  
 
   14:    var string test = "test";
 
   14:    var string test = "test";
   15:    var int length = $test->length;
+
   <em>15:    var int length = $test->length;</em>
 
   16:  
 
   16:  
 
   17:    """</body>""";
 
   17:    """</body>""";
 
   18:    """</html>""";
 
   18:    """</html>""";
 
   19: }
 
   19: }
 +
 +
Here's a bracket set (<tt>[]</tt>) in the position the compiler has trouble with:
 +
 +
var int length = $test->length<strong>[;]</strong>
 +
 +
Since the compiler is complaining that it didn't expect the token it got, ";", and was expecting a "(" instead, and what we're trying to do is call a function, we put in the brackets and can fix the error:
 +
 +
<syntaxhighlight lang="s2">
 +
    var string test = "test";
 +
    var int length = $test->length();
 +
</syntaxhighlight>
  
 
=== Forgetting the end parentheses on a function call ===
 
=== Forgetting the end parentheses on a function call ===
Line 327: Line 369:
 
   S2::Compiler, S2/Compiler.pm, 27
 
   S2::Compiler, S2/Compiler.pm, 27
 
    
 
    
+
 
 
  Context
 
  Context
 
   
 
   
Line 334: Line 376:
 
   13:  
 
   13:  
 
   14:    var string test = "test";
 
   14:    var string test = "test";
   15:    var int length = $test->length(;
+
   <em>15:    var int length = $test->length(;</em>
 
   16:  
 
   16:  
 
   17:    """</body>""";
 
   17:    """</body>""";
Line 340: Line 382:
 
   19: }
 
   19: }
 
   
 
   
 +
This isn't a very clear error!  The character it's having trouble with in a bracket set (<tt>[]</tt>) is:
 +
 +
var int length = $test->length(<strong>[;]</strong>
 +
 +
We can see that there's a parentheses before it that doesn't get closed, and that's probably why it's telling us it can't parse this particular "node".
 +
 +
Close the parenthesis and things will be fine:
 +
 +
<syntaxhighlight lang="s2">
 +
    var string test = "test";
 +
    var int length = $test->length();
 +
</syntaxhighlight>
 +
 
=== Forgetting code block brackets ===
 
=== Forgetting code block brackets ===
  
Line 372: Line 427:
 
   15:  
 
   15:  
 
   16:    if ( $length > 4 )  
 
   16:    if ( $length > 4 )  
   17:        print """This is too big!"""; }
+
   <em>17:        print """This is too big!"""; }</em>
 
   18:  
 
   18:  
 
   19:    """</body>""";
 
   19:    """</body>""";
 
   20:    """</html>""";
 
   20:    """</html>""";
 
   21: }
 
   21: }
 +
 +
This instance is a lot like the missing semicolon ending a statement--the compiler is saying it's expecting a "{" instead of the token it ends up getting.
 +
 +
To fix, add the starting bracket:
 +
 +
<syntaxhighlight lang="s2">
 +
    var int length = 5;
 +
 +
    if ( $length > 4 ) {
 +
        print """This is too big!"""; }
 +
</syntaxhighlight>
  
 
==== Closing ====
 
==== Closing ====
Line 403: Line 469:
 
   4: function Page::print()
 
   4: function Page::print()
 
   5: "This is a skeleton page function, for testing."
 
   5: "This is a skeleton page function, for testing."
   6: {
+
   <em>6: {</em>
 
   7:    """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" """;
 
   7:    """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" """;
 
   8:    """"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n""";
 
   8:    """"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n""";
Line 409: Line 475:
 
   10:    """<title>S2 Testbed Layout</title>\n""";
 
   10:    """<title>S2 Testbed Layout</title>\n""";
 
    
 
    
 +
This error is much trickier than the other errors!  Instead of giving us an error anywhere around the code we made the mistake in, it's giving us the line with the <em>previous</em> open bracket, way up at the start of the function we're working in.  However, from the error we know that the compiler wasn't able to match up a set of braces.  It can be hard to figure out where the problem is, but if you go through your program checking to make sure all of your starting braces have closing braces, you'll manage to fix the problem:
 +
 +
<syntaxhighlight lang="s2">
 +
    var int length = 5;
 +
 +
    if ( $length > 4 ) {
 +
        print """This is too big!""";
 +
    }
 +
</syntaxhighlight>
 +
 +
=== Accidentally using a $ when declaring a variable ===
 +
 +
Even though you need to use a <tt>$</tt> sign to access variables and get into the habit of putting them in front of variable names, you can't use one while declaring them like this: 
 +
 +
<syntaxhighlight lang="s2">
 +
var string $test = "test";
 +
</syntaxhighlight>
 +
 +
The error you'll get is:
 +
 +
  S2 Compiler Output at Sat Jun 19 23:09:30 2010
 +
Error compiling layer:
 +
 +
Compile error: line 15, column 12: Expected identifier.
 +
  S2::Node, S2/Node.pm, 171
 +
  S2::NodeNamedType, S2/NodeNamedType.pm, 36
 +
  S2::NodeVarDecl, S2/NodeVarDecl.pm, 30
 +
  S2::NodeVarDeclStmt, S2/NodeVarDeclStmt.pm, 30
 +
  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:    """<title>S2 Testbed Layout</title>\n""";
 +
  12:    """</head>\n""";
 +
  13:    """<body>\n""";
 +
  14:
 +
  <em>15: var string $test = "test";</em>
 +
  16:
 +
  17:    """</body>\n""";
 +
  18:    """</html>\n""";
 +
  19: }
 +
 +
The character it bails on is:
 +
 +
var string <strong>[$]</strong>test = "test";
 +
 +
When the compiler tells you it expecting an identifier, it's trying to tell you that it wants a valid variable name <em>without</em> the <tt>$</tt>.  Take away the <tt>$</tt> and it will work:
 +
 +
<syntaxhighlight lang="s2">
 +
var string test = "test";
 +
</syntaxhighlight>
  
 
[[Category: S2 Guide]]
 
[[Category: S2 Guide]]

Latest revision as of 05:26, 20 June 2010

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?
  • If the error is on a line you are trying to use a variable in a string, have you tried using the ${variable} format?

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.

Compiler background

The compiler is a program that:

  • Breaks up the S2 code into little chunks called "tokens" or "nodes"
  • Assembles all those tokens into a working program in Perl

If we break the rules of the S2 programming language, the compiler can give errors.

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();

(This kind of a situation could also happen if I meant to use an existing variable but misspelled its name!)

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 lines after that are called a traceback, and they indicate what steps the parser was taking to make the tokens--this is usually not very useful to most people.

After the error message and traceback, the compiler helpfully gives us some context consisting of the line it had trouble with, emphasized, 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

What happens if we try to assign the value from one type of variable to a variable with a different type?

    var string test = "test";
    var int length = $test;

Resulting compile error:

 S2 Compiler Output at Thu Jun 17 16:06:44 2010
Error compiling layer:

Compile error: line 15, column 5: Can't initialize variable 'length' of type int with expression of type string
  S2::NodeVarDeclStmt, S2/NodeVarDeclStmt.pm, 55
  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:     var string test = "test";
 15:     var int length = $test;
 16:     
 17:     """</body>""";
 18:     """</html>""";
 19: }

If we're assigning to a variable that's not being declared at the same time:

    var string test = "test";
    var int length;
    $length = $test;

The error is slightly different:

 S2 Compiler Output at Thu Jun 17 16:12:35 2010
Error compiling layer:

Compile error: line 16, column 5: Can't assign type string to int
  S2::NodeAssignExpr, S2/NodeAssignExpr.pm, 73
  S2::NodeExpr, S2/NodeExpr.pm, 46
  S2::NodeExprStmt, S2/NodeExprStmt.pm, 35
  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

 12:     """<body>""";
 13: 
 14:     var string test = "test";
 15:     var int length;
 16:     $length = $test;
 17: 
 18:     """</body>""";
 19:     """</html>""";
 20: }

Fixing this problem depends on what you were trying to achieve, but you need to make sure you're not trying to match up two values of a different type.

Forgetting the semicolon (;) at the end of a statement

    var string test = "test"
    var int length = $test->length();
Compile error: line 15, column 5: Unexpected token found.  Expecting: [TokenPunct] = ;
Got: [TokenKeyword] = var
  S2::Node, S2/Node.pm, 144
  S2::NodeVarDeclStmt, S2/NodeVarDeclStmt.pm, 35
  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: }

The compiler tells us it was expecting a ";" character instead of what it found. Notice that this time, the line the compiler has trouble with is the line after the line we forgot the semicolon on.

That's because the compiler doesn't look at line breaks to figure out where statements end, it looks at semicolons for that. This means that you can split a single statement over two lines, if you wanted to. Here's an example of that statement (properly ended) across two lines: :

    var string test = 
        "test";
    var int length = $test->length();

A line that doesn't end in a semicolon is not automatically a problem for the compiler -- but when the next line doesn't make sense as a continuation of the statement, it will trigger an error. To fix this problem, we need to put a semicolon at the end of the appropriate line:

    var string test = "test";
    var int length = $test->length();

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 ([]) around the exact position the compile error is complaining about expecting an open parenthesis(() there:

var int length = test[-]>length();

Why was the compiler expecting an open parenthesis there? Without $ in front of test, the compiler doesn't know to treat it as a variable. It instead treats test as a global function, and function calls require parentheses, e.g. test().

Since that error message is pretty confusing, the best way to figure out the problem is to examine the line and run through the Syntax Checklist listed above. We'll find that we've broken the rule about using $ when we're accessing variables.

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();

Forgetting to use parentheses on a function call

    var string test = "test";
    var int length = $test->length;
 S2 Compiler Output at Thu Jun 17 16:30:31 2010
Error compiling layer:

Compile error: line 15, column 35: 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: }

Here's a bracket set ([]) in the position the compiler has trouble with:

var int length = $test->length[;]

Since the compiler is complaining that it didn't expect the token it got, ";", and was expecting a "(" instead, and what we're trying to do is call a function, we put in the brackets and can fix the error:

    var string test = "test";
    var int length = $test->length();

Forgetting the end parentheses on a function call

    var string test = "test";
    var int length = $test->length(;
 S2 Compiler Output at Thu Jun 17 16:37:46 2010
Error compiling layer:

Compile error: line 15, column 36: Can't finish parsing NodeTerm
  S2::NodeTerm, S2/NodeTerm.pm, 484
  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::NodeArguments, S2/NodeArguments.pm, 33
  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: }

This isn't a very clear error! The character it's having trouble with in a bracket set ([]) is:

var int length = $test->length([;]

We can see that there's a parentheses before it that doesn't get closed, and that's probably why it's telling us it can't parse this particular "node".

Close the parenthesis and things will be fine:

    var string test = "test";
    var int length = $test->length();

Forgetting code block brackets

Starting

    var int length = 5;
 
    if ( $length > 4 ) 
        print """This is too big!"""; }
 S2 Compiler Output at Thu Jun 17 16:37:46 2010
Error compiling layer:

Compile error: line 17, column 9: Unexpected token found.  Expecting: [TokenPunct] = {
Got: [TokenKeyword] = print
  S2::Node, S2/Node.pm, 144
  S2::NodeStmtBlock, S2/NodeStmtBlock.pm, 27
  S2::NodeIfStmt, S2/NodeIfStmt.pm, 35
  S2::NodeStmt, S2/NodeStmt.pm, 41
  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

 13: 
 14:     var int length = 5;
 15: 
 16:     if ( $length > 4 ) 
 17:         print """This is too big!"""; }
 18: 
 19:     """</body>""";
 20:     """</html>""";
 21: }

This instance is a lot like the missing semicolon ending a statement--the compiler is saying it's expecting a "{" instead of the token it ends up getting.

To fix, add the starting bracket:

    var int length = 5;
 
    if ( $length > 4 ) {
        print """This is too big!"""; }

Closing

    var int length = 5;
 
    if ( $length > 4 ) {
        print """This is too big!""";
 S2 Compiler Output at Thu Jun 17 16:37:46 2010
Error compiling layer:

Compile error: line 6, column 1: Didn't find closing brace in statement block
  S2::NodeStmtBlock, S2/NodeStmtBlock.pm, 52
  S2::NodeFunction, S2/NodeFunction.pm, 104
  S2::Layer, S2/Layer.pm, 59
  S2::Compiler, S2/Compiler.pm, 27
  

Context

  2: layerinfo "name" = "S2 Testbed Layout";
  3: 
  4: function Page::print()
  5: "This is a skeleton page function, for testing."
  6: {
  7:     """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" """;
  8:     """"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n""";
  9:     """<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n""";
 10:     """<title>S2 Testbed Layout</title>\n""";
 

This error is much trickier than the other errors! Instead of giving us an error anywhere around the code we made the mistake in, it's giving us the line with the previous open bracket, way up at the start of the function we're working in. However, from the error we know that the compiler wasn't able to match up a set of braces. It can be hard to figure out where the problem is, but if you go through your program checking to make sure all of your starting braces have closing braces, you'll manage to fix the problem:

    var int length = 5;
 
    if ( $length > 4 ) {
        print """This is too big!""";
    }

Accidentally using a $ when declaring a variable

Even though you need to use a $ sign to access variables and get into the habit of putting them in front of variable names, you can't use one while declaring them like this:

var string $test = "test";

The error you'll get is:

 S2 Compiler Output at Sat Jun 19 23:09:30 2010
Error compiling layer:

Compile error: line 15, column 12: Expected identifier.
  S2::Node, S2/Node.pm, 171
  S2::NodeNamedType, S2/NodeNamedType.pm, 36
  S2::NodeVarDecl, S2/NodeVarDecl.pm, 30
  S2::NodeVarDeclStmt, S2/NodeVarDeclStmt.pm, 30
  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:     """<title>S2 Testbed Layout</title>\n""";
 12:     """</head>\n""";
 13:     """<body>\n""";
 14: 
 15: var string $test = "test";
 16: 
 17:     """</body>\n""";
 18:     """</html>\n""";
 19: }

The character it bails on is:

var string [$]test = "test"; 

When the compiler tells you it expecting an identifier, it's trying to tell you that it wants a valid variable name without the $. Take away the $ and it will work:

var string test = "test";