Wado

Lexical Structure

This chapter covers how source text splits into tokens: whitespace, comments, the shebang and the data section, identifiers, and keywords. Literal tokens are in Literals, and operators in Operators.

Whitespace

Whitespace separates tokens and is otherwise ignored. It is ASCII only: space, tab, LF, form feed (U+000C) and CR. Any other character outside a string, character literal or comment is an error, the no-break space (U+00A0) and the ideographic space (U+3000) among them.

Comments

//! Module doc comment

// Line comment (extends to end of line)

/* Block comment */

/*
 * Multi-line
 * block comment
 */

/// Doc comment
fn one() -> i32 {
    return /* a comment is whitespace */ 1;
}

test {
    assert one() == 1;
}

Block comments do not nest.

A doc comment is a line comment that documents code. Neither kind changes what a program means.

A doc string is Markdown. Each line loses its /// or //! marker and one space after it, so a line holding only /// is an empty line.

//! Geometry helpers.

/// A point on the plane.
///
/// Both coordinates are in pixels.
#[wire(name_policy = "camelCase")]
pub struct Point {
    /// Distance from the left edge.
    x: i32,
    y: i32,
}

test {
    assert Point { x: 1, y: 2 }.x == 1;   // a doc comment changes nothing
}

Rationale: WEP: Documentation Generation.

Shebang

#!/usr/bin/env -S wado run
export fn run() {
    assert #line == 3;   // the shebang is line 1
}

#! at position 0 is a shebang and is ignored. #![ is an inner attribute, not a shebang.

Data Section

A line holding only __DATA__ separates the source code from the data section. Everything after that line is raw text, not Wado code, and #data reads it. A module needs no data section.

pub fn show_data() with Stdout {
    println(#data);
}

__DATA__
SUBMODULE_DATA_MARKER

Identifiers

An identifier is ASCII: [a-zA-Z_][a-zA-Z0-9_]*.

let foo = 1;
let foo_bar = foo + 1;
let fooBar = foo_bar + 1;
let FooBar = fooBar + 1;
let FOO_BAR = FooBar + 1;
let _private = FOO_BAR + 1;
let name123 = _private + 1;
assert name123 == 7;

A non-ASCII character is an error, wherever it stands:

let é = 1;    // Error: the first character must be ASCII
let café = 1;    // Error: `é` is not an ASCII letter, digit or `_`

Identifiers are case-sensitive.

Keywords

A keyword is not an identifier, so it cannot name a variable, parameter, item or import:

as        assert    async     break     const     continue  effect
else      enum      export    false     fn        for       global
if        impl      import    in        interface internal  let
loop      match     matches   mut       null      pub       reactive
resource  return    struct    trait     true      use       variant
while     with      world

reactive is reserved for reactive signals, which are not in the language yet, so a program that writes it is rejected.

Contextual Keywords

The following keywords are contextual. Each acts as a keyword only in the position listed:

Keyword Keyword context
flags flags declaration
type type declaration
of for let <pattern> of <expr>
from use { ... } from "..."
test test "name" { ... } block
extends resource Child extends Parent
do with Effect => handler do { ... }
task task return expr;
trap ..trap rest clause of an effect handler impl
forward ..forward rest clause of an effect handler impl
resume resume expr in an effect handler
self a method's receiver: &self, self.field
Self the implementing or declared type: Self::Item

Elsewhere each is an ordinary identifier: a variable, field, parameter, or type name.

// 'of' as a variable name
let of = 42;
assert of == 42;

// 'of' as a struct field
struct Item { of: i32 }
let item = Item { of: 10 };
assert item.of == 10;

// 'of' as a for-of binding
let arr: List<i32> = [1, 2, 3];
let mut sum = 0;
for let of of arr {
    sum += of;
}
assert sum == 6;

resume is the exception. It begins an expression (resume value) in every expression position, so a name spelled resume could never be read. A variable, parameter, item, case or import may not take it. Only a field or a method, reached through ., may.