Files
wren/doc/site/syntax.markdown

263 lines
7.5 KiB
Markdown
Raw Normal View History

2013-11-21 21:38:36 -08:00
^title Syntax
2015-01-03 23:27:02 -08:00
Wren's syntax is designed to be familiar to people coming from C-like languages
while being a bit simpler and more streamlined.
2013-11-21 21:38:36 -08:00
2013-12-04 21:51:23 -08:00
Scripts are stored in plain text files with a `.wren` file extension. Wren does
not compile ahead of time: programs are run directly from source, from top to
bottom like a typical scripting language. (Internally, programs are compiled to
2015-09-22 21:19:38 -07:00
bytecode for [efficiency][], but that's an implementation detail.)
[efficiency]: performance.html
2013-12-04 21:51:23 -08:00
2013-11-21 21:38:36 -08:00
## Comments
Line comments start with `//` and end at the end of the line:
:::wren
2013-11-21 21:38:36 -08:00
// This is a comment.
2015-09-22 21:19:38 -07:00
Block comments start with `/*` and end with `*/`. They can span multiple lines:
:::wren
/* This
is
a
multi-line
comment. */
Unlike C, block comments can nest in Wren:
2013-11-21 21:38:36 -08:00
:::wren
2013-11-21 21:38:36 -08:00
/* This is /* a nested */ comment. */
2015-09-22 21:19:38 -07:00
This is handy because it lets you easily comment out an entire block of code,
even if the code already contains block comments.
2014-04-07 21:03:16 -07:00
## Reserved words
2013-11-21 21:38:36 -08:00
One way to get a quick feel for a language's style is to see what words it
reserves. Here's what Wren has:
2013-11-21 21:38:36 -08:00
:::wren
break class construct else false for foreign if import
in is null return static super this true var while
2014-04-11 10:45:20 -07:00
2015-01-03 23:27:02 -08:00
## Identifiers
2014-04-11 10:45:20 -07:00
2015-01-03 23:27:02 -08:00
Naming rules are similar to other programming languages. Identifiers start with
a letter or underscore and may contain letters, digits, and underscores. Case
is sensitive.
2014-04-14 21:23:46 -07:00
:::wren
2014-04-14 21:23:46 -07:00
hi
camelCase
PascalCase
_under_score
abc123
ALL_CAPS
2015-01-03 23:27:02 -08:00
Identifiers that start with underscore (`_`) are special in Wren. They are used
to indicate [fields](classes.html#fields) in classes.
2014-04-14 21:23:46 -07:00
2015-01-03 10:02:45 -08:00
## Newlines
2013-11-21 21:38:36 -08:00
2015-01-03 10:02:45 -08:00
Newlines (`\n`) are meaningful in Wren. They are used to separate statements:
2013-11-21 21:38:36 -08:00
:::wren
2013-12-04 21:51:23 -08:00
// Two statements:
System.print("hi") // Newline.
System.print("bye")
2013-11-21 21:38:36 -08:00
2015-01-03 10:02:45 -08:00
Sometimes, though, a statement doesn't fit on a single line and jamming a
2015-01-03 23:27:02 -08:00
newline in the middle would trip it up. To handle that, Wren has a very simple
rule: It ignores a newline following any token that can't end a statement.
2013-11-21 21:38:36 -08:00
:::wren
System.print( // Newline here is ignored.
2015-01-03 10:02:45 -08:00
"hi")
In practice, this means you can put each statement on its own line and wrap
them across lines as needed without too much trouble.
2013-11-21 21:38:36 -08:00
## Blocks
2015-01-03 23:27:02 -08:00
Wren uses curly braces to define *blocks*. You can use a block anywhere a
statement is allowed, like in [control flow](control-flow.html) statements.
[Method](classes.html#methods) and [function](functions.html) bodies are also
blocks. For example, here we have a block for the then case, and a single
statement for the else:
:::wren
if (happy && knowIt) {
hands.clap()
} else System.print("sad")
2015-01-03 23:27:02 -08:00
Blocks have two similar but not identical forms. Typically, blocks contain a
series of statements like:
:::wren
{
System.print("one")
System.print("two")
System.print("three")
}
2015-01-03 23:27:02 -08:00
Blocks of this form when used for method and function bodies automatically
return `null` after the block has completed. If you want to return a different
value, you need an explicit `return` statement.
2015-01-03 23:27:02 -08:00
However, it's pretty common to have a method or function that just evaluates
and returns the result of a single expression. For that, Wren has a more
compact notation:
2013-12-21 09:15:30 -08:00
:::wren
2015-01-03 23:27:02 -08:00
{ "single expression" }
2013-12-21 09:15:30 -08:00
If there is no newline after the `{` (or after the parameter list in a
2015-01-03 23:27:02 -08:00
[function](functions.html)), then the block may only contain a single
expression, and it automatically returns the result of it. It's exactly the
same as doing:
2013-12-21 09:15:30 -08:00
:::wren
2015-01-03 23:27:02 -08:00
{
return "single expression"
2015-01-03 23:27:02 -08:00
}
2015-11-08 10:59:23 -08:00
## Precedence and Associativity
We'll talk about Wren's different expression forms and what they mean in the
next few pages. But if you want to see how they interact with each other
grammatically, here's the whole table.
It shows which expressions have higher *precedence*—which ones bind more
tightly than others—and their *associativity*—how a series of the
same kind of expression is ordered. Wren mostly follows C, except that it fixes
[the bitwise operator mistake][mistake]. The full precedence table, from
tightest to loosest, is:
[mistake]: http://www.lysator.liu.se/c/dmr-on-or.html
<table class="precedence">
<tbody>
<tr>
<th>Prec</th>
<th>Operator</th>
<th>Description</th>
<th>Associates</th>
</tr>
<tr>
<td>1</td>
2015-11-27 21:17:34 -08:00
<td><code>.</code></td>
<td><a href="method-calls.html">Method call</a></td>
2015-11-08 10:59:23 -08:00
<td>Left</td>
</tr>
<tr>
<td>2</td>
2015-11-27 21:17:34 -08:00
<td><code>()</code> <code>{}</code> <code>[]</code></td>
<td><a href="functions.html">Call, Block argument</a>, <a href="method-calls.html#subscripts">Subscript</a></td>
<td>Left</td>
</tr>
<tr>
<td>3</td>
2015-11-08 10:59:23 -08:00
<td><code>-</code> <code>!</code> <code>~</code></td>
<td><a href="method-calls.html#operators">Negate, Not, Complement</a></td>
<td>Right</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>4</td>
2015-11-08 10:59:23 -08:00
<td><code>*</code> <code>/</code> <code>%</code></td>
<td><a href="method-calls.html#operators">Multiply, Divide, Modulo</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>5</td>
2015-11-08 10:59:23 -08:00
<td><code>+</code> <code>-</code></td>
<td><a href="method-calls.html#operators">Add, Subtract</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>6</td>
2015-11-08 10:59:23 -08:00
<td><code>..</code> <code>...</code></td>
<td><a href="method-calls.html#operators">Inclusive range, Exclusive range</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>7</td>
2015-11-08 10:59:23 -08:00
<td><code>&lt;&lt;</code> <code>&gt;&gt;</code></td>
<td><a href="method-calls.html#operators">Left shift, Right shift</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>8</td>
2015-11-08 10:59:23 -08:00
<td><code>&lt;</code> <code>&lt;=</code> <code>&gt;</code> <code>&gt;=</code></td>
<td><a href="method-calls.html#operators">Comparison</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>9</td>
2015-11-08 10:59:23 -08:00
<td><code>==</code></td>
<td><a href="method-calls.html#operators">Equals</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>10</td>
2015-11-08 10:59:23 -08:00
<td><code>!=</code></td>
<td><a href="method-calls.html#operators">Not equal</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>11</td>
2015-11-08 10:59:23 -08:00
<td><code>&amp;</code></td>
<td><a href="method-calls.html#operators">Bitwise and</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>12</td>
2015-11-08 10:59:23 -08:00
<td><code>^</code></td>
<td><a href="method-calls.html#operators">Bitwise xor</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>13</td>
2015-11-08 10:59:23 -08:00
<td><code>|</code></td>
<td><a href="method-calls.html#operators">Bitwise or</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>14</td>
2015-11-08 10:59:23 -08:00
<td><code>is</code></td>
<td><a href="method-calls.html#operators">Type test</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>15</td>
2015-11-08 10:59:23 -08:00
<td><code>&amp;&amp;</code></td>
<td><a href="control-flow.html#logical-operators">Logical and</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>16</td>
2015-11-08 10:59:23 -08:00
<td><code>||</code></td>
<td><a href="control-flow.html#logical-operators">Logical or</a></td>
<td>Left</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>17</td>
2015-11-08 10:59:23 -08:00
<td><code>?:</code></td>
<td><a href="control-flow.html#the-conditional-operator-">Conditional</a></td>
<td>Right</td>
</tr>
<tr>
2015-11-27 21:17:34 -08:00
<td>18</td>
2015-11-08 10:59:23 -08:00
<td><code>=</code></td>
<td><a href="variables.html#assignment">Assignment</a>, <a href="method-calls.html#setters">Setter</a></td>
<td>Right</td>
</tr>
</tbody>
</table>
<a class="right" href="values.html">Values &rarr;</a>
2015-11-08 10:59:23 -08:00
<a href="getting-started.html">&larr; Getting Started</a>