docs: add method-calls and variables pages, update sidebar links, revise statement-terminator and performance docs

This commit is contained in:
Bob Nystrom
2013-12-17 17:39:26 +00:00
parent 656238f286
commit e26afd7de3
5 changed files with 165 additions and 72 deletions
+14 -64
View File
@@ -29,26 +29,30 @@ one lump. If you're one of those folks, here you go:
class else false fn for if is null
return static this true var while
## Newlines
## Statement terminators
Like many scripting languages, newlines are significant in Wren and are used to
separate statements. You can keep your semicolons safely tucked away.
Officially, statements are terminated by a semicolon (`;`) like in other
languages in the C tradition. However, Wren treats newlines as equivalent
to a semicolon whenever it makes sense. In practice, this means you almost
never write `;` unless you want to cram a bunch of statements on one line.
:::wren
// Two statements:
io.write("hi")
io.write("bye")
Sometimes, though, you want to wrap a single statement on multiple lines. To
make that easier, Wren has a very simple rule. It will ignore a newline
following any token that can't end a statement. Specifically, that means any of
these:
Sometimes, though, a statement doesn't fit on a single line and treating the
newline as a semicolon would trip things up. To handle that, Wren has a very
simple rule. It ignores a newline following any token that can't end a
statement. Specifically, that means any of these:
:::wren
( [ { . , * / % + - | || & && ! ~ = < > <= >= == !=
class else if is static var while
Everywhere else, a newline is treated just like a `;`.
Everywhere else, a newline is treated just like a `;`. Note that this is a very
different system from how JavaScript handles semicolons. If you've been burned
there, don't worry, you should be fine here.
## Names
@@ -62,60 +66,6 @@ Identifiers are similar to other programming languages. They start with a letter
abc123
ALL_CAPS
Identifiers that start with underscore (`_`) are special in Wren. They are used to indicate fields and private members of classes.
Identifiers that start with underscore (`_`) are special in Wren. They are used to indicate fields in [classes](classes.html).
## Method calls
Wren is object-oriented, so most code consists of method calls. They look like this:
:::wren
io.write("hello")
items.add("another")
items.insert(1, "value")
You have a *receiver* on the left, followed by a `.`, then a name and an argument list in parentheses. Semantically, a method call works like this:
1. Look up the class of the receiver.
2. Look up the method on it by name.
3. Invoke the method.
Methods that do not take any arguments leave off the `()`:
:::wren
text.length
These are special "getters" or "accessors" in other languages. In Wren, they're just methods. Unlike most dynamic languages, the number of arguments to a method is part of its *name*. In technical terms, this means you can overload by *arity*. Basically, it means that these are calls to two different methods:
items.add("one arg")
items.add("first", "second")
## Operators
Wren has mostly the same operators you know and love from C, with the same precedence and associativity. These operators are prefix (they come before their operand):
:::wren
! ~ -
Semantically, they are just method calls on their operand. When you see `!possible`, it's effectively the same as `possible.!` (though Wren does *not* allow that syntax).
These operators are infix (they have operands on either side):
:::wren
=
|| &&
is
== !=
< > <= >=
| &
+ -
* / %
The `is` operator is used for type tests. The left operand is an object and the right operand is a class. It evaluates to `true` if the object is an instance of the class (or one of its subclasses).
The `||` and `&&` are logical operators. Like in C, they are basically flow-control constructs. A `||` expression will only evaluate the right operand if the left-hand side evaluates to something non-false-y. Likewise, `&&` only evaluates the right operand if the left evaluates to something false-y.
In Wren, the only false value is the boolean value `false`. Everything else is considered "true".
All other infix operators are just syntactic sugar for method calls. The left operand is the receiver, and the right is passed to it as an argument. So `a + b` is semantically `a.+(b)`. The built-in types implement these methods to do what you (hopefully) expect.
**TODO: assignment, functions, lists, maps, flow control, whitespace and newlines**
**TODO: blocks, assignment, functions, lists, maps**