diff --git a/doc/site/classes.markdown b/doc/site/classes.markdown index a955e88c..fbce69f4 100644 --- a/doc/site/classes.markdown +++ b/doc/site/classes.markdown @@ -13,7 +13,7 @@ stored in each instance. Classes are created using the `class` keyword, unsurprisingly: - :::dart + :::wren class Unicorn {} This creates a class named `Unicorn` with no methods or fields. @@ -22,7 +22,7 @@ This creates a class named `Unicorn` with no methods or fields. To let our unicorn do stuff, we need to give it methods. - :::dart + :::wren class Unicorn { prance() { System.print("The unicorn prances in a fancy manner!") @@ -32,7 +32,7 @@ To let our unicorn do stuff, we need to give it methods. This defines a `prance()` method that takes no arguments. To support parameters, put their names inside the parentheses: - :::dart + :::wren class Unicorn { prance(where, when) { System.print("The unicorn prances in " + where + " at " + when) @@ -46,7 +46,7 @@ methods in a class with the same name, as long as they have a different *signature*. In technical terms, you can *overload by arity*. So this class is fine: - :::dart + :::wren class Unicorn { prance() { System.print("The unicorn prances in a fancy manner!") @@ -63,7 +63,7 @@ fine: And you can call each of the methods like so: - :::dart + :::wren var unicorn = Unicorn.new() unicorn.prance() unicorn.prance("Antwerp") @@ -82,13 +82,13 @@ treats them as different methods that you can implement separately. Many methods on a class exist to expose or compute some property of the object. For example: - :::dart + :::wren System.print("string".count) // "6". These *getters* are just another kind of method—one without a parameter list. You can define them like so: - :::dart + :::wren class Unicorn { isFancy { true } // Unicorns are always fancy. } @@ -97,7 +97,7 @@ Whether or not a method name has parentheses is also part of its signature. This lets you distinguish between a method that takes an *empty* argument list (`()`) and no argument list at all: - :::dart + :::wren class Confusing { method { "no argument list" } method() { "empty argument list" } @@ -115,14 +115,14 @@ Unlike other languages with "optional parentheses", Wren wants to make sure you call a getter like a getter and a `()` method like a `()` method. These don't work: - :::dart + :::wren "string".count() list.clear Methods that don't need arguments and don't modify the underlying object are usually getters: - :::dart + :::wren "string".count (1..10).min 1.23.sin @@ -131,7 +131,7 @@ usually getters: When a method doesn't need any parameters, but does modify the object, it's helpful to draw attention to that by requiring an empty set of parentheses: - :::dart + :::wren list.clear() Also, when a method supports multiple arities, it's typical to include the `()` @@ -148,7 +148,7 @@ words, you can think of `a + b` as meaning `a.+(b)`. You can define operators in your class like so: - :::dart + :::wren class Unicorn { // Infix: +(other) { @@ -163,7 +163,7 @@ You can define operators in your class like so: This can be used to define any of these operators: - :::dart + :::wren // Infix: + - * / % < > <= >= == != & | @@ -188,7 +188,7 @@ Unicorns can prance around now, but we don't actually *have* any unicorns to do it. To create instances of a class, we need a *constructor*. You can define one like so: - :::dart + :::wren class Unicorn { construct new(name, color) { System.print("My name is " + name + " and I am " + color + ".") @@ -201,13 +201,13 @@ word "new" isn't special to Wren, it's just a common constructor name. To make a unicorn now, we just call the constructor method on the class itself: - :::dart + :::wren var fred = Unicorn.new("Fred", "palomino") Giving constructors names is handy because it means you can have more than one, and each can clarify how it creates the instance: - :::dart + :::wren class Unicorn { construct brown(name) { System.print("My name is " + name + " and I am brown.") @@ -229,7 +229,7 @@ constructors. A constructor is actually a pair of methods. You get a method on the class: - :::dart + :::wren Unicorn.brown("Dave") That creates the new instance, then it invokes the *initializer* on that @@ -244,7 +244,7 @@ constructors, etc. All state stored in instances is stored in *fields*. Each field has a named that starts with an underscore. - :::dart + :::wren class Rectangle { area { _width * _height } @@ -274,7 +274,7 @@ access fields on another instance of your own class, unlike C++ and Java. If you want to make a property of an object visible, you need to define a getter to expose it: - :::dart + :::wren class Rectangle { width { _width } height { _height } @@ -284,7 +284,7 @@ getter to expose it: To allow outside code to modify the field, you'll also need to provide setters: - :::dart + :::wren class Rectangle { width=(value) { _width = value } height=(value) { _height = value } @@ -305,7 +305,7 @@ A name that starts with *two* underscores is a *static* field. They work similar to [fields](#fields) except the data is stored on the class itself, and not the instance. They can be used in *both* instance and static methods. - :::dart + :::wren class Foo { // Set the static field. static set(a) { @@ -325,19 +325,19 @@ not the instance. They can be used in *both* instance and static methods. Just like instance fields, static fields are initially `null`: - :::dart + :::wren System.print(Foo.bar) // null. They can be used from static methods: - :::dart + :::wren Foo.set("foo") System.print(Foo.bar) // foo. And also instance methods. When you do so, there is still only one static field shared among all instances of the class: - :::dart + :::wren var foo1 = Foo.new() var foo2 = Foo.new() @@ -354,7 +354,7 @@ By default, any new class inherits from `Object`, which is the superclass from which all other classes ultimately descend. You can specify a different parent class using `is` when you declare the class: - :::dart + :::wren class Pegasus is Unicorn {} This declares a new class `Pegasus` that inherits from `Unicorn`. @@ -366,7 +366,7 @@ The metaclass hierarchy does *not* parallel the regular class hierarchy. So, if `Unicorn`'s metaclass. In more prosaic terms, this means that static methods are not inherited. - :::dart + :::wren class Unicorn { // Unicorns cannot fly. :( static canFly { false } @@ -378,7 +378,7 @@ are not inherited. This also means constructors are not inherited: - :::dart + :::wren class Unicorn { this new(name) { System.print("My name is " + name + ".") @@ -395,7 +395,7 @@ instance methods on the new object. This means you can do `super` calls inside a constructor: - :::dart + :::wren class Unicorn { this new(name) { System.print("My name is " + name + ".") diff --git a/doc/site/contributing.markdown b/doc/site/contributing.markdown index 81fedc0c..5fef0091 100644 --- a/doc/site/contributing.markdown +++ b/doc/site/contributing.markdown @@ -35,7 +35,47 @@ significant change or addition, please file a [proposal][] to discuss it before writing lots of code. Wren tries very *very* hard to be minimal which means often having to say "no" to language additions, even really cool ones. -## Making a change +## Hacking on docs + +The [documentation][] is one of the easiest—and most +important!—parts of Wren to contribute to. The source for the site is +written in [Markdown][] (and a little [SASS][]) and lives under `doc/site`. A +simple Python script, `util/generate_docs.py`, converts that to HTML and CSS. + +[documentation]: / +[markdown]: http://daringfireball.net/projects/markdown/ +[sass]: http://sass-lang.com/ + +The site uses [Pygments][] for syntax highlighting, with a custom lexer plug-in +for Wren. To install that, run: + +[pygments]: http://pygments.org + + :::sh + $ cd util/pygments-lexer + $ sudo python setup.py develop + $ cd ../.. # Back to the root Wren directory. + +Now you can build the docs: + + :::sh + $ make docs + +This generates the site in `build/docs/`. You can run any simple static web +server from there. Python includes one: + + :::sh + $ cd build/docs + $ python -m SimpleHTTPServer + +Running `make docs` is a drag every time you change a line of Markdown or SASS, +so there is also a file watching version that will automatically regenerate the +docs when you edit a file: + + :::sh + $ make watchdocs + +## Hacking on the VM The basic process is simple: diff --git a/doc/site/control-flow.markdown b/doc/site/control-flow.markdown index e19a1624..b484849b 100644 --- a/doc/site/control-flow.markdown +++ b/doc/site/control-flow.markdown @@ -30,14 +30,14 @@ values. The simplest branching statement, `if` lets you conditionally skip a chunk of code. It looks like this: - :::dart + :::wren if (ready) System.print("go!") That evaluates the parenthesized expression after `if`. If it's true, then the statement after the condition is evaluated. Otherwise it is skipped. Instead of a statement, you can have a [block](syntax.html#blocks): - :::dart + :::wren if (ready) { System.print("getSet") System.print("go!") @@ -46,12 +46,12 @@ a statement, you can have a [block](syntax.html#blocks): You may also provide an `else` branch. It will be executed if the condition is false: - :::dart + :::wren if (ready) System.print("go!") else System.print("not ready!") And, of course, it can take a block too: - :::dart + :::wren if (ready) { System.print("go!") } else { @@ -67,7 +67,7 @@ they should be familiar if you've used other imperative languages. The simplest, a `while` statement executes a chunk of code as long as a condition continues to hold. For example: - :::dart + :::wren // Hailstone sequence. var n = 27 while (n != 1) { @@ -87,7 +87,7 @@ The condition for a while loop can be any expression, and must be surrounded by parentheses. The body of the loop is usually a curly block but can also be a single statement: - :::dart + :::wren var n = 27 while (n != 1) if (n % 2 == 0) n = n / 2 else n = 3 * n + 1 @@ -98,7 +98,7 @@ some complex condition. But in most cases, you're looping through a [list](lists.html), a series of numbers, or some other "sequence" object. That's what `for` is for. It looks like this: - :::dart + :::wren for (beatle in ["george", "john", "paul", "ringo"]) { System.print(beatle) } @@ -122,7 +122,7 @@ and stop. To do that, you can use a `break` statement. It's just the `break` keyword all by itself. That will immediately exit out of the nearest enclosing `while` or `for` loop. - :::dart + :::wren for (i in [1, 2, 3, 4]) { System.print(i) if (i == 3) break @@ -136,7 +136,7 @@ Lists are one common use for `for` loops, but sometimes you want to walk over a sequence of numbers, or loop a number of times. For that, you can create a [range](values.html#ranges), like so: - :::dart + :::wren for (i in 1..100) { System.print(i) } @@ -144,7 +144,7 @@ sequence of numbers, or loop a number of times. For that, you can create a This loops over the numbers from 1 to 100, including 100 itself. If you want to leave off the last value, use three dots instead of two: - :::dart + :::wren for (i in 1...100) { System.print(i) } @@ -166,14 +166,14 @@ methods on the object that resulted from evaluating the sequence expression. When you write a loop like this: - :::dart + :::wren for (i in 1..100) { System.print(i) } Wren sees it something like this: - :::dart + :::wren var iter_ = null var seq_ = 1..100 while (iter_ = seq_.iterate(iter_)) { diff --git a/doc/site/core/bool.markdown b/doc/site/core/bool.markdown index d1abb889..dd9c32a4 100644 --- a/doc/site/core/bool.markdown +++ b/doc/site/core/bool.markdown @@ -9,7 +9,7 @@ Boolean values. There are two instances, `true` and `false`. Returns the logical complement of the value. - :::dart + :::wren System.print(!true) // "false". System.print(!false) // "true". diff --git a/doc/site/core/class.markdown b/doc/site/core/class.markdown index 2d81afc0..f11ddd1f 100644 --- a/doc/site/core/class.markdown +++ b/doc/site/core/class.markdown @@ -11,7 +11,7 @@ The name of the class. The superclass of this class. - :::dart + :::wren class Crustacean {} class Crab is Crustacean {} @@ -19,10 +19,10 @@ The superclass of this class. A class with no explicit superclass implicitly inherits Object: - :::dart + :::wren System.print(Crustacean.supertype) // "Object". Object forms the root of the class hierarchy and has no supertype: - :::dart + :::wren System.print(Object.supertype) // "null". diff --git a/doc/site/core/fiber.markdown b/doc/site/core/fiber.markdown index 5add46fa..f0230e2b 100644 --- a/doc/site/core/fiber.markdown +++ b/doc/site/core/fiber.markdown @@ -8,7 +8,7 @@ A lightweight coroutine. [Here](../fibers.html) is a gentle introduction. Creates a new fiber that executes `function` in a separate coroutine when the fiber is run. Does not immediately start running the fiber. - :::dart + :::wren var fiber = Fiber.new { System.print("I won't get printed") } @@ -32,7 +32,7 @@ again. If there is still a reference to the suspended fiber, it can be resumed. Pauses the current fiber and transfers control to the parent fiber. "Parent" here means the last fiber that was started using `call` and not `run`. - :::dart + :::wren var fiber = Fiber.new { System.print("Before yield") Fiber.yield() @@ -48,7 +48,7 @@ When resumed, the parent fiber's `call()` method returns `null`. If a yielded fiber is resumed by calling `call()` or `run()` with an argument, `yield()` returns that value. - :::dart + :::wren var fiber = Fiber.new { System.print(Fiber.yield()) // "value" } @@ -63,7 +63,7 @@ If there is no parent fiber to return to, this exits the interpreter. This can be useful to pause execution until the host application wants to resume it later. - :::dart + :::wren Fiber.yield() System.print("this does not get reached") @@ -72,7 +72,7 @@ later. Similar to `Fiber.yield` but provides a value to return to the parent fiber's `call`. - :::dart + :::wren var fiber = Fiber.new { Fiber.yield("value") } @@ -85,7 +85,7 @@ Similar to `Fiber.yield` but provides a value to return to the parent fiber's Starts or resumes the fiber if it is in a paused state. - :::dart + :::wren var fiber = Fiber.new { System.print("Fiber called") Fiber.yield() @@ -101,7 +101,7 @@ called it. If the called fiber is resuming from a yield, the `yield()` method returns `null` in the called fiber. - :::dart + :::wren var fiber = Fiber.new { System.print(Fiber.yield()) } @@ -114,7 +114,7 @@ If the called fiber is resuming from a yield, the `yield()` method returns Invokes the fiber or resumes the fiber if it is in a paused state and sets `value` as the returned value of the fiber's call to `yield`. - :::dart + :::wren var fiber = Fiber.new { System.print(Fiber.yield()) } diff --git a/doc/site/core/fn.markdown b/doc/site/core/fn.markdown index 6ef32684..e00fd068 100644 --- a/doc/site/core/fn.markdown +++ b/doc/site/core/fn.markdown @@ -11,7 +11,7 @@ function, so this really just returns the argument. It exists mainly to let you create a "bare" function when you don't want to immediately pass it as a [block argument](../functions.html#block-arguments) to some other method. - :::dart + :::wren var fn = Fn.new { System.print("The body") } @@ -24,7 +24,7 @@ It is a runtime error if `function` is not a function. The number of arguments the function requires. - :::dart + :::wren System.print(Fn.new {}.arity) // 0. System.print(Fn.new {|a, b, c| a }.arity) // 3. @@ -32,7 +32,7 @@ The number of arguments the function requires. Invokes the function with the given arguments. - :::dart + :::wren var fn = Fn.new { |arg| System.print(arg) } diff --git a/doc/site/core/list.markdown b/doc/site/core/list.markdown index ec75a651..92dd4a6e 100644 --- a/doc/site/core/list.markdown +++ b/doc/site/core/list.markdown @@ -23,21 +23,21 @@ The number of elements in the list. Inserts the `item` at `index` in the list. - :::dart + :::wren var list = ["a", "b", "c", "d"] list.insert(1, "e") System.print(list) // "[a, e, b, c, d]". The `index` may be one past the last index in the list to append an element. - :::dart + :::wren var list = ["a", "b", "c"] list.insert(3, "d") System.print(list) // "[a, b, c, d]". If `index` is negative, it counts backwards from the end of the list. It bases this on the length of the list *after* inserted the element, so that `-1` will append the element, not insert it before the last element. - :::dart + :::wren var list = ["a", "b"] list.insert(-1, "d") list.insert(-2, "c") @@ -45,7 +45,7 @@ If `index` is negative, it counts backwards from the end of the list. It bases t Returns the inserted item. - :::dart + :::wren System.print(["a", "c"].insert(1, "b")) // "b". It is a runtime error if the index is not an integer or is out of bounds. @@ -61,7 +61,7 @@ Removes the element at `index`. If `index` is negative, it counts backwards from the end of the list where `-1` is the last element. All trailing elements are shifted up to fill in where the removed element was. - :::dart + :::wren var list = ["a", "b", "c", "d"] list.removeAt(1) System.print(list) // "[a, c, d]". @@ -77,7 +77,7 @@ It is a runtime error if the index is not an integer or is out of bounds. Gets the element at `index`. If `index` is negative, it counts backwards from the end of the list where `-1` is the last element. - :::dart + :::wren var list = ["a", "b", "c"] System.print(list[1]) // "b". @@ -88,7 +88,7 @@ It is a runtime error if the index is not an integer or is out of bounds. Replaces the element at `index` with `item`. If `index` is negative, it counts backwards from the end of the list where `-1` is the last element. - :::dart + :::wren var list = ["a", "b", "c"] list[1] = "new" System.print(list) // "[a, new, c]". diff --git a/doc/site/core/map.markdown b/doc/site/core/map.markdown index 16e814f3..b9c2a869 100644 --- a/doc/site/core/map.markdown +++ b/doc/site/core/map.markdown @@ -48,7 +48,7 @@ multiple times in the sequence. Gets the value associated with `key` in the map. If `key` is not present in the map, returns `null`. - :::dart + :::wren var map = {"george": "harrison", "ringo": "starr"} System.print(map["ringo"]) // "starr". System.print(map["pete"]) // "null". diff --git a/doc/site/core/null.markdown b/doc/site/core/null.markdown index 033a008e..3e5eb329 100644 --- a/doc/site/core/null.markdown +++ b/doc/site/core/null.markdown @@ -7,5 +7,5 @@ Returns `true`, since `null` is considered [false](../control-flow.html#truth). - :::dart + :::wren System.print(!null) // "true". diff --git a/doc/site/core/num.markdown b/doc/site/core/num.markdown index baf86a81..7f4875ba 100644 --- a/doc/site/core/num.markdown +++ b/doc/site/core/num.markdown @@ -20,7 +20,7 @@ The value of π. The absolute value of the number. - :::dart + :::wren -123.abs // 123 ### **acos** @@ -44,7 +44,7 @@ numbers to determine the quadrant of the result. Rounds the number up to the nearest integer. - :::dart + :::wren 1.5.ceil // 2 (-3.2).ceil // -3 @@ -56,7 +56,7 @@ The cosine of the number. Rounds the number down to the nearest integer. - :::dart + :::wren 1.5.floor // 1 (-3.2).floor // -4 @@ -82,7 +82,7 @@ The tangent of the number. Negates the number. - :::dart + :::wren var a = 123 -a // -123 @@ -130,7 +130,7 @@ It is a runtime error if `other` is not a number. Creates a [Range](core/range.html) representing a consecutive range of numbers from the beginning number to the ending number. - :::dart + :::wren var range = 1.2..3.4 System.print(range.min) // 1.2 System.print(range.max) // 3.4 @@ -141,7 +141,7 @@ from the beginning number to the ending number. Creates a [Range](core/range.html) representing a consecutive range of numbers from the beginning number to the ending number not including the ending number. - :::dart + :::wren var range = 1.2...3.4 System.print(range.min) // 1.2 System.print(range.max) // 3.4 diff --git a/doc/site/core/sequence.markdown b/doc/site/core/sequence.markdown index 0f45ef4e..a2846b32 100644 --- a/doc/site/core/sequence.markdown +++ b/doc/site/core/sequence.markdown @@ -16,7 +16,7 @@ Iterates over the sequence, passing each element to the function `predicate`. If it returns something [false](../control-flow.html#truth), stops iterating and returns the value. Otherwise, returns `true`. - :::dart + :::wren [1, 2, 3].all {|n| n > 2} // False. [1, 2, 3].all {|n| n < 4} // True. @@ -28,7 +28,7 @@ Iterates over the sequence, passing each element to the function `predicate`. If it returns something [true](../control-flow.html#truth), stops iterating and returns that value. Otherwise, returns `false`. - :::dart + :::wren [1, 2, 3].any {|n| n < 1} // False. [1, 2, 3].any {|n| n > 2} // True. @@ -50,7 +50,7 @@ Returns the number of elements in the sequence that pass the `predicate`. Iterates over the sequence, passing each element to the function `predicate` and counting the number of times the returned value evaluates to `true`. - :::dart + :::wren [1, 2, 3].count {|n| n > 2} // 1. [1, 2, 3].count {|n| n < 4} // 3. @@ -58,7 +58,7 @@ and counting the number of times the returned value evaluates to `true`. Iterates over the sequence, passing each element to the given `function`. - :::dart + :::wren ["one", "two", "three"].each {|word| System.print(word) } ### **isEmpty** @@ -85,7 +85,7 @@ together into a single string. Creates a new sequence that applies the `transformation` to each element in the original sequence while it is iterated. - :::dart + :::wren var doubles = [1, 2, 3].map {|n| n * 2 } for (n in doubles) { System.print(n) // "2", "4", "6". @@ -101,7 +101,7 @@ changes to the original sequence will be reflected in the mapped sequence. To force eager evaluation, just call `.toList` on the result. - :::dart + :::wren var numbers = [1, 2, 3] var doubles = numbers.map {|n| n * 2 }.toList numbers.add(4) @@ -126,7 +126,7 @@ the sequence is empty, returns `seed`. Creates a [list](list.html) containing all the elements in the sequence. - :::dart + :::wren (1..3).toList // [1, 2, 3]. If the sequence is already a list, this creates a copy of it. @@ -139,7 +139,7 @@ that pass the `predicate`. During iteration, each element in the original sequence is passed to the function `predicate`. If it returns `false`, the element is skipped. - :::dart + :::wren var odds = (1..10).where {|n| n % 2 == 1 } for (n in odds) { System.print(n) // "1", "3", "5", "7", "9". @@ -156,7 +156,7 @@ sequence. To force eager evaluation, just call `.toList` on the result. - :::dart + :::wren var numbers = [1, 2, 3, 4, 5, 6] var odds = numbers.where {|n| n % 2 == 1 }.toList numbers.add(7) diff --git a/doc/site/core/string.markdown b/doc/site/core/string.markdown index 8ada08ca..42b58b15 100644 --- a/doc/site/core/string.markdown +++ b/doc/site/core/string.markdown @@ -27,14 +27,14 @@ counting them as you go. Because counting code points is relatively slow, the indexes passed to string methods are *byte* offsets, not *code point* offsets. When you do: - :::dart + :::wren someString[3] That means "get the code point starting at *byte* three", not "get the third code point in the string". This sounds scary, but keep in mind that the methods on strings *return* byte indexes too. So, for example, this does what you want: - :::dart + :::wren var metalBand = "Fäcëhämmër" var hPosition = metalBand.indexOf("h") System.print(metalBand[hPosition]) // "h" @@ -52,7 +52,7 @@ ignores any UTF-8 encoding and works directly at the byte level. Creates a new string containing the UTF-8 encoding of `codePoint`. - :::dart + :::wren String.fromCodePoint(8225) // "‡" It is a runtime error if `codePoint` is not an integer between `0` and @@ -67,7 +67,7 @@ the string and ignore any UTF-8 encoding. In addition to the normal sequence methods, the returned object also has a subscript operator that can be used to directly index bytes. - :::dart + :::wren System.print("hello".bytes[1]) // 101, for "e". The `count` method on the returned sequence returns the number of bytes in the @@ -81,7 +81,7 @@ code points of the string *as numbers*. Iteration and subscripting work similar to the string itself. The difference is that instead of returning single-character strings, this returns the numeric code point values. - :::dart + :::wren var string = "(ᵔᴥᵔ)" System.print(string.codePoints[0]) // 40, for "(". System.print(string.codePoints[4]) // 7461, for "ᴥ". @@ -89,7 +89,7 @@ single-character strings, this returns the numeric code point values. If the byte at `index` does not begin a valid UTF-8 sequence, or the end of the string is reached before the sequence is complete, returns `-1`. - :::dart + :::wren var string = "(ᵔᴥᵔ)" System.print(string.codePoints[2]) // -1, in the middle of "ᵔ". @@ -126,7 +126,7 @@ It is a runtime error if `search` is not a string. Implements the [iterator protocol](../control-flow.html#the-iterator-protocol) for iterating over the *code points* in the string: - :::dart + :::wren var codePoints = [] for (c in "(ᵔᴥᵔ)") { codePoints.add(c) @@ -161,7 +161,7 @@ Check if the string is not equal to `other`. Returns a string containing the code point starting at byte `index`. - :::dart + :::wren System.print("ʕ•ᴥ•ʔ"[5]) // "ᴥ". Since `ʕ` is two bytes in UTF-8 and `•` is three, the fifth byte points to the @@ -170,7 +170,7 @@ bear's nose. If `index` points into the middle of a UTF-8 sequence or at otherwise invalid UTF-8, this returns a one-byte string containing the byte at that index: - :::dart + :::wren System.print("I ♥ NY"[3]) // One-byte string whose value is 153. It is a runtime error if `index` is greater than the number of bytes in the diff --git a/doc/site/core/system.markdown b/doc/site/core/system.markdown index cbc4b081..6438e7c5 100644 --- a/doc/site/core/system.markdown +++ b/doc/site/core/system.markdown @@ -15,7 +15,7 @@ Prints a single newline to the console. Prints [object] to the console followed by a newline. If not already a string, the object is converted to a string by calling `toString` on it. - :::dart + :::wren System.print("I like bananas") // Prints "I like bananas". ### System.**printAll**(sequence) @@ -23,7 +23,7 @@ the object is converted to a string by calling `toString` on it. Iterates over [sequence] and prints each element, then prints a single newline at the end. Each element is converted to a string by calling `toString` on it. - :::dart + :::wren System.printAll([1, [2, 3], 4]) // Prints "1[2, 3]4". ### System.**write**(object) @@ -31,7 +31,7 @@ at the end. Each element is converted to a string by calling `toString` on it. Prints a single value to the console, but does not print a newline character afterwards. Converts the value to a string by calling `toString` on it. - :::dart + :::wren System.write(4 + 5) // Prints "9". In the above example, the result of `4 + 5` is printed, and then the prompt is diff --git a/doc/site/error-handling.markdown b/doc/site/error-handling.markdown index b852ff86..c4ff6cf8 100644 --- a/doc/site/error-handling.markdown +++ b/doc/site/error-handling.markdown @@ -8,7 +8,7 @@ Errors come in a few fun flavors. The first errors you're likely to run into are syntax errors. These include simple bugs where your code doesn't follow the language's grammar, like: - :::dart + :::wren 1 + * 2 Wren will detect these errors as soon as it tries to read your code. When it @@ -21,7 +21,7 @@ Some slightly more "semantic" errors fall into this bucket too. Things like using a variable that hasn't been defined, or declaring two variables with the same name in the same scope. So if you do: - :::dart + :::wren var a = "once" var a = "twice" @@ -49,7 +49,7 @@ perform an operation that the VM can't do. The most common error is a "method not found" one. If you call a method on an object and its class (and all of its superclasses) don't define that method, there's nothing Wren can do: - :::dart + :::wren class Foo {} var foo = Foo.new() @@ -70,7 +70,7 @@ Another common runtime error is passing an argument of the wrong type to a method. For example, lists are indexed using a number. If you try to pass some other type, it's an error: - :::dart + :::wren var list = ["a", "b", "c"] list["1"] @@ -102,7 +102,7 @@ error message as a string. For example, if you run this program: - :::dart + :::wren var fiber = Fiber.new { 123.badMethod } @@ -119,7 +119,7 @@ The called fiber can no longer be used, but any other fibers can proceed as usual. When a fiber has been aborted because of a runtime error, you can also get the error from the fiber object. Continuing the above example: - :::dart + :::wren System.print(fiber.error) This also prints: @@ -137,7 +137,7 @@ Most runtime errors come from within the Wren VM, but you may want to be able to cause your own runtime errors to occur. This can be done by calling the `abort()` static method on `Fiber`: - :::dart + :::wren Fiber.abort("Something bad happened") You must pass in an error message, and it must be a string. diff --git a/doc/site/expressions.markdown b/doc/site/expressions.markdown index e083fda6..146d6fc0 100644 --- a/doc/site/expressions.markdown +++ b/doc/site/expressions.markdown @@ -28,7 +28,7 @@ instance of a [class](classes.html). All other names refer to Wren is object-oriented, so most code consists of method calls. Most of them look like so: - :::dart + :::wren System.print("hello") items.add("another") items.insert(1, "value") @@ -37,13 +37,13 @@ You have a *receiver* expression followed by a `.`, then a name and an argument list in parentheses. Arguments are separated by commas. Methods that do not take any arguments can omit the `()`: - :::dart + :::wren text.length These are special "getters" or "accessors" in other languages. In Wren, they're just method calls. You can also define methods that take an empty argument list: - :::dart + :::wren list.clear() An empty argument list is *not* the same as omitting the parentheses @@ -59,7 +59,7 @@ If the last (or only) argument to a method call is a [function](functions.html), it may be passed as a [block argument](functions.html#block-arguments): - :::dart + :::wren blondie.callMeAt(867, 5309) { System.print("This is the body!") } @@ -95,7 +95,7 @@ overridden. To do that, you can use the special `super` keyword as the receiver in a method call: - :::dart + :::wren class Base { method { System.print("base method") @@ -111,7 +111,7 @@ call: You can also use `super` without a method name inside a constructor to invoke a base class constructor: - :::dart + :::wren class Base { this new(arg) { System.print("base constructor got " + arg) @@ -131,7 +131,7 @@ base class constructor: Wren has most of the same operators you know and love with the same precedence and associativity. Wren has three prefix operators: - :::dart + :::wren ! ~ - They are just method calls on their operand without any other arguments. An @@ -140,7 +140,7 @@ expression like `!possible` means "call the `!` method on `possible`". We have a few other operators to play with. The remaining ones are infix—they have operators on either side. They are: - :::dart + :::wren == != < > <= >= .. ... | & + - * / % Like prefix operators, they are all funny ways of writing method calls. The @@ -167,7 +167,7 @@ the referenced [variable](variables.html) or [field](classes.html#fields). The left-hand side may also be a method call, like: - :::dart + :::wren point.x = 123 In this case, the entire expression is a single "setter" method call. The above @@ -184,7 +184,7 @@ expression will always just store the value there. Most languages use square brackets (`[]`) for working with collection-like objects. For example: - :::dart + :::wren list[0] // Gets the first item in a list. map["key"] // Gets the value associated with "key". @@ -192,12 +192,12 @@ You know the refrain by now. In Wren, these are just method calls that a class may define. Subscript operators may take multiple arguments, which is useful for things like multi-dimensional arrays: - :::dart + :::wren matrix[3, 5] Subscripts may also be used on the left-hand side of an assignment: - :::dart + :::wren list[0] = "item" map["key"] = "value" @@ -217,7 +217,7 @@ A `&&` ("logical and") expression evaluates the left-hand argument. If it's [false](control-flow.html#truth), it returns that value. Otherwise it evaluates and returns the right-hand argument. - :::dart + :::wren System.print(false && 1) // false System.print(1 && 2) // 2 @@ -225,7 +225,7 @@ An `||` ("logical or") expression is reversed. If the left-hand argument is [true](control-flow.html#truth), it's returned, otherwise the right-hand argument is evaluated and returned: - :::dart + :::wren System.print(false || 1) // 1 System.print(1 || 2) // 1 @@ -235,7 +235,7 @@ Also known as the "ternary" operator since it takes three arguments, Wren has the little "if statement in the form of an expression" you know and love from C and its brethren. - :::dart + :::wren System.print(1 != 2 ? "math is sane" : "math is not sane!") It takes a condition expression, followed by `?`, followed by a then @@ -250,7 +250,7 @@ operator. It performs a type test. 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). - :::dart + :::wren 123 is Num // true "s" is Num // false null is String // false diff --git a/doc/site/fibers.markdown b/doc/site/fibers.markdown index b1899a6e..7677d1d3 100644 --- a/doc/site/fibers.markdown +++ b/doc/site/fibers.markdown @@ -26,7 +26,7 @@ All Wren code runs within the context of a fiber. When you first start a Wren script, a main fiber is created for you automatically. You can spawn new fibers using the `Fiber` class's constructor: - :::dart + :::wren var fiber = Fiber.new { System.print("This runs in a separate fiber.") } @@ -40,14 +40,14 @@ code sitting there waiting to be activated, a bit like a Once you've created a fiber, you can invoke it (which suspends the current fiber) by calling its `call()` method: - :::dart + :::wren fiber.call() The called fiber will execute its code until it reaches the end of its body or until it passes control to another fiber. If it reaches the end of its body, it's considered *done*: - :::dart + :::wren var fiber = Fiber.new { System.print("Hi") } fiber.isDone // false fiber.call() @@ -69,7 +69,7 @@ fiber is called, it picks up right where it left off and keeps going. You can make a fiber yield by calling the static `yield()` method on `Fiber`: - :::dart + :::wren var fiber = Fiber.new { System.print("fiber 1") Fiber.yield() @@ -102,7 +102,7 @@ Calling and yielding fibers is used for passing control, but it can also pass fiber has yielded and is waiting to resume, the value becomes the return value of the `yield()` call: - :::dart + :::wren var fiber = Fiber.new { var result = Fiber.yield() System.print(result) @@ -119,7 +119,7 @@ Fibers can also pass values *back* when they yield. If you pass an argument to `yield()`, that will become the return value of the `call` that was used to invoke the fiber: - :::dart + :::wren var fiber = Fiber.new { Fiber.yield("sent") } @@ -139,7 +139,7 @@ Wren's fibers can do that, but they can do much more. Like Lua, they are full *coroutines*—they can suspend from anywhere in the callstack. For example: - :::dart + :::wren var fiber = Fiber.new { (1..10).map {|i| Fiber.yield(i) diff --git a/doc/site/functions.markdown b/doc/site/functions.markdown index 85bf6f4c..ddf0d424 100644 --- a/doc/site/functions.markdown +++ b/doc/site/functions.markdown @@ -20,7 +20,7 @@ Since that's the most common usage pattern, Wren's syntax optimizes for that. Taking a page from Ruby, a function is created by passing a *block argument* to a method. At its simplest, it looks like this: - :::dart + :::wren blondie.callMe { System.print("This is the body!") } @@ -32,7 +32,7 @@ argument, a function whose body is the following Methods that take a block argument receive it as a normal parameter. `callMe` could be defined like so: - :::dart + :::wren class Blondie { callMe(fn) { // Call it... @@ -42,7 +42,7 @@ could be defined like so: A method can take other arguments in addition to the block. They appear before the block just like a regular argument list. For example: - :::dart + :::wren blondie.callMeAt(867, 5309) { System.print("This is the body!") } @@ -51,7 +51,7 @@ Of course, you don't *have* to use a block argument to pass a function to a method. If you already have a function object, you can pass it like a regular argument: - :::dart + :::wren var someFn = // Get a function... blondie.callMe(someFn) @@ -60,7 +60,7 @@ little blob of syntax. There are some times when you want to create a function but *don't* need to pass it to a method. For that, you can call the `Fn` class's constructor: - :::dart + :::wren var someFn = Fn.new { System.print("Hi!") } @@ -73,7 +73,7 @@ return that, so this exists purely as a convenience method for you. Once you have a function, how do you invoke it? Like everything in Wren, you do so by calling a method on it: - :::dart + :::wren class Blondie { callMe(fn) { fn.call() @@ -84,7 +84,7 @@ Functions expose a `call()` method that executes the body of the function. This method is dynamically-dispatched like any other, so you can define your own "function-like" classes and pass them to methods that expect "real" functions. - :::dart + :::wren class FakeFn { call() { System.print("I'm feeling functional!") @@ -100,7 +100,7 @@ functions that we've seen so far take no arguments. To change that, you can provide a parameter list surrounded by `|` immediately after the opening brace of the body, like so: - :::dart + :::wren blondie.callMe {|first, last| System.print("Hi, " + first + " " + last + "!") } @@ -108,7 +108,7 @@ of the body, like so: Here we're passing a function to `greet` that takes two parameters, `first` and `last`. They are passed to the function when it's called: - :::dart + :::wren class Blondie { callMe(fn) { fn.call("Debbie", "Harry") @@ -129,7 +129,7 @@ Otherwise, the body returns `null` by default. You can explicitly return a value using a `return` statement. In other words, these two functions do the same thing: - :::dart + :::wren Fn.new { "return value" } Fn.new { @@ -142,7 +142,7 @@ As you expect, functions are closures—they can access variables defined outside of their scope. They will hold onto closed-over variables even after leaving the scope where the function is defined: - :::dart + :::wren class Counter { static create { var i = 0 @@ -155,7 +155,7 @@ function references a variable `i` declared outside of the function. Even after the function is returned from `create`, it is still able to read and assign to`i`: - :::dart + :::wren var counter = Counter.create System.print(counter.call()) // Prints "1". System.print(counter.call()) // Prints "2". diff --git a/doc/site/getting-started.markdown b/doc/site/getting-started.markdown index 5b1fedc3..fb8f02e4 100644 --- a/doc/site/getting-started.markdown +++ b/doc/site/getting-started.markdown @@ -48,12 +48,12 @@ The above instructions will drop you into Wren's standalone interpreter in interactive mode. You can type in a line of code, and it will immediately execute it. Here's something to try: - :::dart + :::wren System.print("Hello, world!") Or a little more exciting: - :::dart + :::wren for (i in 1..10) System.print("Counting up " + i.toString) You can exit the interpreter using good old Ctrl-C or Ctrl-D, or just throw @@ -65,7 +65,7 @@ The standalone interpreter can also load scripts from files and run them. Just pass the name of the script to wren. Create a file named "my_script.wren" in your favorite text editor and paste this into it: - :::dart + :::wren for (yPixel in 0...24) { var y = yPixel / 12 - 1 for (xPixel in 0...80) { diff --git a/doc/site/index.markdown b/doc/site/index.markdown index e6ecc716..fecf65f5 100644 --- a/doc/site/index.markdown +++ b/doc/site/index.markdown @@ -5,7 +5,7 @@ Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern [syntax][]. - :::dart + :::wren System.print("Hello, world!") class Wren { diff --git a/doc/site/lists.markdown b/doc/site/lists.markdown index 42a3cb7d..f02c02d0 100644 --- a/doc/site/lists.markdown +++ b/doc/site/lists.markdown @@ -5,7 +5,7 @@ A list is a compound object that holds a collection of elements identified by integer index. You can create a list by placing a sequence of comma-separated expressions inside square brackets: - :::dart + :::wren [1, "banana", true] Here, we've created a list of three elements. Notice that the elements don't @@ -17,21 +17,21 @@ You can access an element from a list by calling the [subscript operator](expressions.html#subscript-operators) on it with the index of the element you want. Like most languages, indexes start at zero: - :::dart + :::wren var hirsute = ["sideburns", "porkchops", "'stache", "goatee"] hirsute[0] // "sideburns". hirsute[1] // "porkchops". Negative indices counts backwards from the end: - :::dart + :::wren hirsute[-1] // "goatee". hirsute[-2] // "'stache". It's a runtime error to pass an index outside of the bounds of the list. If you don't know what those bounds are, you can find out using count: - :::dart + :::wren hirsute.count // 4. ## Slices and ranges @@ -39,7 +39,7 @@ don't know what those bounds are, you can find out using count: Sometimes you want to copy a chunk of elements from a list. You can do that by passing a [range](values.html#ranges) to the subscript operator, like so: - :::dart + :::wren hirsute[1..2] // ["porkchops", "'stache"]. This returns a new list containing the elements of the original list whose @@ -49,7 +49,7 @@ and do what you expect. Negative bounds also work like they do when passing a single number, so to copy a list, you can just do: - :::dart + :::wren hirsute[0..-1] ## Adding elements @@ -57,20 +57,20 @@ a list, you can just do: Lists are *mutable*, meaning their contents can be changed. You can swap out an existing element in the list using the subscript setter: - :::dart + :::wren hirsute[1] = "muttonchops" System.print(hirsute[1]) // muttonchops. It's an error to set an element that's out of bounds. To grow a list, you can use `add` to append a single item to the end: - :::dart + :::wren hirsute.add("goatee") System.print(hirsute.count) // 4. You can insert a new element at a specific position using `insert`: - :::dart + :::wren hirsute.insert(2, "soul patch") The first argument is the index to insert at, and the second is the value to @@ -81,7 +81,7 @@ It's valid to "insert" after the last element in the list, but only *right* after it. Like other methods, you can use a negative index to count from the back. Doing so counts back from the size of the list *after* it's grown by one: - :::dart + :::wren var letters = ["a", "b", "c"] letters.insert(3, "d") // OK: inserts at end. System.print(letters) // ["a", "b", "c", "d"] @@ -94,18 +94,18 @@ The opposite of `insert` is `removeAt`. It removes a single element from a given position in the list. All following items are shifted up to fill in the gap: - :::dart + :::wren var letters = ["a", "b", "c", "d"] letters.removeAt(1) System.print(letters) // ["a", "c", "d"] The `removeAt` method returns the removed item: - :::dart + :::wren System.print(letters.removeAt(1)) // "c" If you want to remove everything from the list, you can clear it: - :::dart + :::wren hirsute.clear() System.print(hirsute) // [] diff --git a/doc/site/maps.markdown b/doc/site/maps.markdown index 1b79e7c5..a810a588 100644 --- a/doc/site/maps.markdown +++ b/doc/site/maps.markdown @@ -8,7 +8,7 @@ other languages: hash table, dictionary, association, table, etc. You can create a map by placing a series of comma-separated entries inside curly braces. Each entry is a key and a value separated by a colon: - :::dart + :::wren { "George": "Harrison", "John": "Lennon", @@ -41,7 +41,7 @@ built-in types, only those can be used as keys. You add new key-value pairs to the map by using the [subscript operator][]: - :::dart + :::wren var capitals = {} capitals["Georgia"] = "Atlanta" capitals["Idaho"] = "Boise" @@ -57,7 +57,7 @@ value. If the key is already there, this just replaces its value. To find the value associated with some key, again you use your friend the subscript operator: - :::dart + :::wren System.print(capitals["Idaho"]) // "Boise". If the key is present, this returns its value. Otherwise, it returns `null`. Of @@ -66,7 +66,7 @@ doesn't necessarily mean the key wasn't found. To tell definitively if a key exists, you can call `containsKey()`: - :::dart + :::wren var belief = {"nihilism": null} System.print(belief["nihilism"]) // "null" though key exists. @@ -76,7 +76,7 @@ To tell definitively if a key exists, you can call `containsKey()`: You can see how many entries a map contains using `count`: - :::dart + :::wren System.print(capitals.count) // "3". ## Removing entries @@ -84,13 +84,13 @@ You can see how many entries a map contains using `count`: To remove an entry from a map, call `remove()` and pass in the key for the entry you want to delete: - :::dart + :::wren capitals.remove("Maine") System.print(capitals.containsKey("Maine")) // "false". If the key was found, this returns the value that was associated with it: - :::dart + :::wren System.print(capitals.remove("Georgia")) // "Atlanta". If the key wasn't in the map to begin with, `remove()` just returns `null`. @@ -98,7 +98,7 @@ If the key wasn't in the map to begin with, `remove()` just returns `null`. If you want to remove *everything* from the map, just like with [lists][], you can just call `clear()`: - :::dart + :::wren capitals.clear() System.print(capitals.count) // "0". @@ -119,7 +119,7 @@ map, and the second returns one that iterates over the values. If you want to see all of the key-value pairs in a map, the easiest way is to iterate over the keys and use each to look up its value: - :::dart + :::wren var birds = { "Arizona": "Cactus wren", "Hawaii": "Nēnē", diff --git a/doc/site/modules.markdown b/doc/site/modules.markdown index 44402398..21942b9d 100644 --- a/doc/site/modules.markdown +++ b/doc/site/modules.markdown @@ -26,7 +26,7 @@ When you run Wren and give it a file name to execute, the contents of that file define the "main" module that execution starts at. To load and execute other modules, you use an import statement: - :::dart + :::wren import "beverages" for Coffee, Tea This finds a module named "beverages" and executes its source code. Then, it @@ -36,7 +36,7 @@ creates new variables in *this* module with their values. This statement can appear anywhere a variable declaration is allowed, even inside blocks: - :::dart + :::wren if (thirsty) { import "beverages" for Coffee, Tea } @@ -44,7 +44,7 @@ inside blocks: If you want to load a module, but not bind any variables from it, you can omit the `for` clause: - :::dart + :::wren import "some_imperative_code" That's the basic idea. Now let's break it down into each of the steps it @@ -99,7 +99,7 @@ the main module was loaded and looks for that file. So, let's say you run: And that main module has: - :::dart + :::wren import "some/module" Then the command-line VM will try to find `/code/some/module.wren`. By @@ -137,7 +137,7 @@ These are simply variables declared outside of any These are visible to anything inside the module, but they can also be *exported* and used by other modules. When Wren executes an import like: - :::dart + :::wren import "beverages" for Coffee, Tea First it runs the "beverages" module. Then it goes through each of the variable @@ -161,7 +161,7 @@ Earlier, I described a programs set of modules as a tree. Of course, it's only a *tree* of modules if there are no *shared imports*. But consider a program like: - :::dart + :::wren // main.wren import "a" import "b" @@ -206,7 +206,7 @@ it will be found in the registry and the cycle is short-circuited. For example: - :::dart + :::wren // main.wren import "a" @@ -230,7 +230,7 @@ This program runs successfully and prints: Where you have to be careful is binding variables. Consider: - :::dart + :::wren // main.wren import "a" @@ -255,7 +255,7 @@ defined yet since "a.wren" is still sitting on the `import "b" for B` line before the declaration. To get this to work, you would need to move the variable declaration above the import: - :::dart + :::wren // main.wren import "a" diff --git a/doc/site/qa.markdown b/doc/site/qa.markdown index a8617a84..6a995ea8 100644 --- a/doc/site/qa.markdown +++ b/doc/site/qa.markdown @@ -54,7 +54,7 @@ Here's an example of that kind of object-oriented programming in Lua: Here's the same example in Wren: - :::dart + :::wren class Account { this new(balance) { _balance = balance } withdraw(amount) { _balance = _balance - amount } diff --git a/doc/site/style.scss b/doc/site/style.scss index a04a4ecf..b88ec121 100644 --- a/doc/site/style.scss +++ b/doc/site/style.scss @@ -228,20 +228,32 @@ footer { } } +// link hsl(200, 60%, 50%); +// hsl(210, 80%, 60%); + // Syntax highlighting. .codehilite pre { // Comments. span.c1, span.cm { color: mix($code-color, $code-bg, 60%); } // Keywords. - span.k, span.kd, span.kc { color: hsl(210, 80%, 60%); } + span.k, span.kd, span.kc, span.nb { color: hsl(200, 60%, 50%); } + + // Names. + span.vg { color: hsl(180, 70%, 35%); } + span.vi { color: hsl(90, 80%, 35%); } + span.vc { color: hsl(130, 60%, 40%); } // Numbers. - span.m, span.mi { color: hsl(90, 80%, 35%); } + span.m, span.mi, span.mf { color: hsl(30, 80%, 45%); }// hsl(90, 80%, 35%) // Strings. - span.s, span.s2 { color: hsl(40, 80%, 50%); } - span.se { color: hsl(30, 80%, 50%); } + span.s, span.s2 { color: hsl(40, 80%, 45%); } + span.se { color: hsl(45, 80%, 50%); } + + // Operators and punctuation. + span.o { color: hsl(200, 40%, 50%); } + span.p { color: mix($code-color, $code-bg, 80%); } // Preprocessor directives. span.cp { color: hsl(270, 40%, 60%); } diff --git a/doc/site/syntax.markdown b/doc/site/syntax.markdown index 7c891237..833520ee 100644 --- a/doc/site/syntax.markdown +++ b/doc/site/syntax.markdown @@ -13,13 +13,13 @@ bytecode for efficiency, but that's an implementation detail.) Line comments start with `//` and end at the end of the line: - :::dart + :::wren // This is a comment. Block comments start with `/*` and end with `*/`. They can span multiple lines or be within a single one. Unlike C, block comments can nest in Wren: - :::dart + :::wren /* This is /* a nested */ comment. */ ## Reserved words @@ -27,7 +27,7 @@ or be within a single one. Unlike C, block comments can nest in Wren: Some people like to see all of the reserved words in a programming language in one lump. If you're one of those folks, here you go: - :::dart + :::wren break class construct else false for foreign if import in is null return static super this true var while @@ -37,7 +37,7 @@ 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. - :::dart + :::wren hi camelCase PascalCase @@ -52,7 +52,7 @@ to indicate [fields](classes.html#fields) in classes. Newlines (`\n`) are meaningful in Wren. They are used to separate statements: - :::dart + :::wren // Two statements: System.print("hi") // Newline. System.print("bye") @@ -61,7 +61,7 @@ Sometimes, though, a statement doesn't fit on a single line and jamming a 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. - :::dart + :::wren System.print( // Newline here is ignored. "hi") @@ -76,7 +76,7 @@ statement is allowed, like in [control flow](control-flow.html) statements. blocks. For example, here we have a block for the then case, and a single statement for the else: - :::dart + :::wren if (happy && knowIt) { hands.clap } else System.print("sad") @@ -84,7 +84,7 @@ statement for the else: Blocks have two similar but not identical forms. Typically, blocks contain a series of statements like: - :::dart + :::wren { System.print("one") System.print("two") @@ -99,7 +99,7 @@ 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: - :::dart + :::wren { "single expression" } If there is no newline after the `{` (or after the parameter list in a @@ -107,7 +107,7 @@ If there is no newline after the `{` (or after the parameter list in a expression, and it automatically returns the result of it. It's exactly the same as doing: - :::dart + :::wren { return "single expression" } diff --git a/doc/site/values.markdown b/doc/site/values.markdown index 14855239..c5465eb8 100644 --- a/doc/site/values.markdown +++ b/doc/site/values.markdown @@ -18,7 +18,7 @@ Like other scripting languages, Wren has a single numeric type: double-precision floating point. Number literals look like you expect coming from other languages: - :::dart + :::wren 0 1234 -5678 @@ -37,12 +37,12 @@ though.) String literals are surrounded in double quotes: - :::dart + :::wren "hi there" A handful of escape characters are supported: - :::dart + :::wren "\0" // The NUL byte: 0. "\"" // A double quote character. "\\" // A backslash. @@ -56,11 +56,12 @@ A handful of escape characters are supported: A `\u` followed by four hex digits can be used to specify a Unicode code point: - :::dart + :::wren System.print("\u0041\u0b83\u00DE") // "AஃÞ" A `\x` followed by two hex digits specifies a single unencoded byte: + :::wren System.print("\x48\x69\x2e") // "Hi." Strings are instances of class [String](core/string.html). @@ -72,13 +73,13 @@ They don't have their own dedicated literal syntax. Instead, the number class implements the `..` and `...` [operators](expressions.html#operators) to create them: - :::dart + :::wren 3..8 This creates a range from three to eight, including eight itself. If you want a half-inclusive range, use `...`: - :::dart + :::wren 4...6 This creates a range from four to six *not* including six itself. Ranges are @@ -87,7 +88,7 @@ sequences of numbers, but are useful in other places too. You can pass them to a [list](lists.html)'s subscript operator to return a subset of the list, for example: - :::dart + :::wren var list = ["a", "b", "c", "d", "e"] var slice = list[1..3] System.print(slice) // ["b", "c", "d"] diff --git a/doc/site/variables.markdown b/doc/site/variables.markdown index e1ee5020..cea03cf9 100644 --- a/doc/site/variables.markdown +++ b/doc/site/variables.markdown @@ -4,14 +4,14 @@ Variables are named slots for storing values. You can define a new variable in Wren using a `var` statement, like so: - :::dart + :::wren var a = 1 + 2 This creates a new variable `a` in the current scope and initializes it with the result of the expression following the `=`. Once a variable has been defined, it can be accessed by name as you would expect. - :::dart + :::wren var animal = "Slow Loris" System.print(animal) // Prints "Slow Loris". @@ -20,7 +20,7 @@ defined, it can be accessed by name as you would expect. Wren has true block scope: a variable exists from the point where it is defined until the end of the [block](syntax.html#blocks) where that definition appears. - :::dart + :::wren { System.print(a) // ERROR! a doesn't exist yet. var a = 123 @@ -34,7 +34,7 @@ Declaring a variable in an inner scope with the same name as an outer one is called *shadowing* and is not an error (although it's not something you likely intend to do much). - :::dart + :::wren var a = "outer" { var a = "inner" @@ -44,7 +44,7 @@ intend to do much). Declaring a variable with the same name in the *same* scope *is* an error. - :::dart + :::wren var a = "hi" var a = "again" // ERROR! @@ -52,7 +52,7 @@ Declaring a variable with the same name in the *same* scope *is* an error. After a variable has been declared, you can assign to it using `=`: - :::dart + :::wren var a = 123 a = 234 @@ -63,7 +63,7 @@ doesn't roll with implicit variable definition. When used in a larger expression, an assignment expression evaluates to the assigned value. - :::dart + :::wren var a = "before" System.print(a = "after") // Prints "after". diff --git a/util/pygments-lexer/Wren.egg-info/PKG-INFO b/util/pygments-lexer/Wren.egg-info/PKG-INFO new file mode 100644 index 00000000..b6a8e409 --- /dev/null +++ b/util/pygments-lexer/Wren.egg-info/PKG-INFO @@ -0,0 +1,12 @@ +Metadata-Version: 1.0 +Name: Wren +Version: 1.0 +Summary: +A Pygments lexer for Wren. + +Home-page: UNKNOWN +Author: Robert Nystrom +Author-email: UNKNOWN +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN diff --git a/util/pygments-lexer/Wren.egg-info/SOURCES.txt b/util/pygments-lexer/Wren.egg-info/SOURCES.txt new file mode 100644 index 00000000..e7ea3276 --- /dev/null +++ b/util/pygments-lexer/Wren.egg-info/SOURCES.txt @@ -0,0 +1,7 @@ +setup.py +Wren.egg-info/PKG-INFO +Wren.egg-info/SOURCES.txt +Wren.egg-info/dependency_links.txt +Wren.egg-info/entry_points.txt +Wren.egg-info/top_level.txt +wren/__init__.py \ No newline at end of file diff --git a/util/pygments-lexer/Wren.egg-info/dependency_links.txt b/util/pygments-lexer/Wren.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/util/pygments-lexer/Wren.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/util/pygments-lexer/Wren.egg-info/entry_points.txt b/util/pygments-lexer/Wren.egg-info/entry_points.txt new file mode 100644 index 00000000..4e4d1c0f --- /dev/null +++ b/util/pygments-lexer/Wren.egg-info/entry_points.txt @@ -0,0 +1,4 @@ + + [pygments.lexers] + wrenlexer = wren:WrenLexer + \ No newline at end of file diff --git a/util/pygments-lexer/Wren.egg-info/top_level.txt b/util/pygments-lexer/Wren.egg-info/top_level.txt new file mode 100644 index 00000000..5894272c --- /dev/null +++ b/util/pygments-lexer/Wren.egg-info/top_level.txt @@ -0,0 +1 @@ +wren diff --git a/util/pygments-lexer/setup.py b/util/pygments-lexer/setup.py new file mode 100644 index 00000000..c9d07f40 --- /dev/null +++ b/util/pygments-lexer/setup.py @@ -0,0 +1,18 @@ +""" +A Pygments lexer for Wren. +""" +from setuptools import setup + +__author__ = 'Robert Nystrom' + +setup( + name='Wren', + version='1.0', + description=__doc__, + author=__author__, + packages=['wren'], + entry_points=''' + [pygments.lexers] + wrenlexer = wren:WrenLexer + ''' +) \ No newline at end of file