Syntax
File layout, naming rules, blocks, switch and operators.
Every file follows the same order:
package <name> # required, first line
use <module>, ... # immediately after package
<body>package hello
use http_server, html_document
$app = new http_serverExtensions: .lexer for an entry file, .lx for a page or library file.
Naming#
A name must be either all lowercase or all uppercase:
http_request form_data a1 # valid — ordinary names
POST GET MAX_SIZE # valid — constants
Person HttpClient # valid — class namesmyVar formData $Ad # invalid — mixed caseStarting with a capital is valid only for class names. A name that starts lowercase and contains a capital is invalid everywhere.
Digits and _ are allowed in both forms. Keywords are lowercase only; writing IF is an error.
Blocks#
Every construct that opens a block closes with end <keyword>. There are no braces, and indentation is significant.
if $a == 10 then
out("10")
else
out("other")
end if
for $lang in $languages
out($lang)
end for
while $i > 0
$i = $i - 1
end while
func add($a, $b) as int32
return $a + $b
end func
with $app
.document.add($doc)
end withInside a with block, lines beginning with a dot apply to the block's subject: .document.add($doc) means $app.document.add($doc).
On one line#
: is the statement separator for single-line forms:
if $a == 10 then: out("10"): end if
func double($x): return $x * 2: end funcswitch#
Tests one value against several possibilities:
switch $req.path
case "/login", "/register"
$app.layout($auth_layout)
case in $admin_paths
$app.layout($admin_layout)
default
$app.layout($shop_layout)
end switch| Form | Meaning |
|---|---|
case "a", "b" | if any of the values match |
case in $array | if the subject is in the array |
default | if nothing matched; must be the last branch |
The subject is evaluated once: a call with side effects running again in every branch would be a surprise.
The first matching branch runs and the switch ends — there is no fall-through. C's behaviour quietly ran the wrong branch too whenever someone forgot a break.
If nothing matches and there is no default, nothing happens. No free statements are allowed between branches: only case and default.
Operators#
&& and || may be written instead of and and or; they are the same operators, and the choice is a matter of style. Negation is not only.
if $stock > 0 && $product.active then: out("sellable"): end if
if $role == "admin" || $role == "editor" then: out("authorised"): end if
if not $cart then: out("cart is empty"): end ifA single & or | does not exist. The language has no bitwise operations, so someone writing a single character has almost always forgotten the second one; quietly giving it another meaning would be wrong.
Anonymous functions#
func can also be written as an expression. It sees the variables where it was defined:
$factor = 3
$times = func($x) as int32
return $x * $factor
end func
out($times(5)) # 15Route tables and session.with_lock use this.
Commas in objects#
Commas are not required in an object literal; a new field is recognised from the name: form. This is so that tables whose values are blocks do not need a comma after every end func:
{
"/": func($req, $res) as void
$res.send("a")
end func
"/b": func($req, $res) as void
$res.send("b")
end func
}Comments#
# one line
###
Several
lines.
###