2026-01-24 23:40:22 +01:00
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Syntax Overview - Wren-CLI Manual</ title >
< link rel = "stylesheet" href = "../css/style.css" >
</ head >
< body >
< button class = "mobile-menu-toggle" > Menu</ button >
< div class = "container" >
< aside class = "sidebar" >
< div class = "sidebar-header" >
< h1 >< a href = "../index.html" > Wren-CLI</ a ></ h1 >
< div class = "version" > v0.4.0</ div >
</ div >
< nav class = "sidebar-nav" >
< div class = "section" >
< span class = "section-title" > Getting Started</ span >
< ul >
< li >< a href = "../getting-started/index.html" > Overview</ a ></ li >
< li >< a href = "../getting-started/installation.html" > Installation</ a ></ li >
< li >< a href = "../getting-started/first-script.html" > First Script</ a ></ li >
< li >< a href = "../getting-started/repl.html" > Using the REPL</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Language</ span >
< ul >
< li >< a href = "index.html" class = "active" > Syntax Overview</ a ></ li >
< li >< a href = "classes.html" > Classes</ a ></ li >
< li >< a href = "methods.html" > Methods</ a ></ li >
< li >< a href = "control-flow.html" > Control Flow</ a ></ li >
< li >< a href = "fibers.html" > Fibers</ a ></ li >
< li >< a href = "modules.html" > Modules</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > API Reference</ span >
< ul >
< li >< a href = "../api/index.html" > Overview</ a ></ li >
2026-01-25 04:58:39 +01:00
< li >< a href = "../api/string.html" > String</ a ></ li >
< li >< a href = "../api/number.html" > Num</ a ></ li >
2026-01-24 23:40:22 +01:00
< li >< a href = "../api/http.html" > http</ a ></ li >
< li >< a href = "../api/websocket.html" > websocket</ a ></ li >
< li >< a href = "../api/tls.html" > tls</ a ></ li >
< li >< a href = "../api/net.html" > net</ a ></ li >
< li >< a href = "../api/dns.html" > dns</ a ></ li >
< li >< a href = "../api/json.html" > json</ a ></ li >
< li >< a href = "../api/base64.html" > base64</ a ></ li >
< li >< a href = "../api/regex.html" > regex</ a ></ li >
< li >< a href = "../api/jinja.html" > jinja</ a ></ li >
< li >< a href = "../api/crypto.html" > crypto</ a ></ li >
< li >< a href = "../api/os.html" > os</ a ></ li >
< li >< a href = "../api/env.html" > env</ a ></ li >
< li >< a href = "../api/signal.html" > signal</ a ></ li >
< li >< a href = "../api/subprocess.html" > subprocess</ a ></ li >
< li >< a href = "../api/sqlite.html" > sqlite</ a ></ li >
< li >< a href = "../api/datetime.html" > datetime</ a ></ li >
< li >< a href = "../api/timer.html" > timer</ a ></ li >
< li >< a href = "../api/io.html" > io</ a ></ li >
2026-01-25 04:58:39 +01:00
< li >< a href = "../api/pathlib.html" > pathlib</ a ></ li >
2026-01-24 23:40:22 +01:00
< li >< a href = "../api/scheduler.html" > scheduler</ a ></ li >
< li >< a href = "../api/math.html" > math</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Tutorials</ span >
< ul >
< li >< a href = "../tutorials/index.html" > Tutorial List</ a ></ li >
< li >< a href = "../tutorials/http-client.html" > HTTP Client</ a ></ li >
< li >< a href = "../tutorials/websocket-chat.html" > WebSocket Chat</ a ></ li >
< li >< a href = "../tutorials/database-app.html" > Database App</ a ></ li >
< li >< a href = "../tutorials/template-rendering.html" > Templates</ a ></ li >
< li >< a href = "../tutorials/cli-tool.html" > CLI Tool</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > How-To Guides</ span >
< ul >
< li >< a href = "../howto/index.html" > How-To List</ a ></ li >
< li >< a href = "../howto/http-requests.html" > HTTP Requests</ a ></ li >
< li >< a href = "../howto/json-parsing.html" > JSON Parsing</ a ></ li >
< li >< a href = "../howto/regex-patterns.html" > Regex Patterns</ a ></ li >
< li >< a href = "../howto/file-operations.html" > File Operations</ a ></ li >
< li >< a href = "../howto/async-operations.html" > Async Operations</ a ></ li >
< li >< a href = "../howto/error-handling.html" > Error Handling</ a ></ li >
</ ul >
</ div >
</ nav >
</ aside >
< main class = "content" >
< nav class = "breadcrumb" >
< a href = "../index.html" > Home</ a >
< span class = "separator" > /</ span >
< span > Language Reference</ span >
</ nav >
< article >
< h1 > Syntax Overview</ h1 >
< p > Wren is a small, fast, class-based scripting language with a clean syntax inspired by languages like Dart, Lua, and Smalltalk. This section covers the core language features.</ p >
< div class = "toc" >
< h4 > Language Topics</ h4 >
< ul >
< li >< a href = "classes.html" > Classes</ a > - Object-oriented programming</ li >
< li >< a href = "methods.html" > Methods</ a > - Method definition and operators</ li >
< li >< a href = "control-flow.html" > Control Flow</ a > - Conditionals and loops</ li >
< li >< a href = "fibers.html" > Fibers</ a > - Cooperative concurrency</ li >
< li >< a href = "modules.html" > Modules</ a > - Import system</ li >
</ ul >
</ div >
< h2 > Comments</ h2 >
< p > Single-line comments start with < code > //</ code > :</ p >
< pre >< code > // This is a comment
var x = 42 // Inline comment</ code ></ pre >
< p > Block comments use < code > /* */</ code > and can nest:</ p >
< pre >< code > /* This is a
multi-line comment */
/* Outer /* nested */ comment */</ code ></ pre >
< h2 > Variables</ h2 >
< p > Declare variables with < code > var</ code > :</ p >
< pre >< code > var name = "Wren"
var count = 42
var active = true
var nothing = null</ code ></ pre >
< p > Variables must be initialized when declared. They are lexically scoped:</ p >
< pre >< code > var outer = "outside"
{
var inner = "inside"
System.print(outer) // Works
}
// inner is not accessible here</ code ></ pre >
< h2 > Data Types</ h2 >
< h3 > Numbers</ h3 >
< p > All numbers are 64-bit floating point:</ p >
< pre >< code > var integer = 42
var decimal = 3.14159
var negative = -100
var scientific = 1.5e10
var hex = 0xFF
var binary = 0b1010</ code ></ pre >
< h3 > Strings</ h3 >
< p > Strings are immutable sequences of bytes:</ p >
< pre >< code > var single = "Hello"
var escape = "Line 1\nLine 2"
var interpolation = "Value: %(1 + 2)"</ code ></ pre >
< p > Raw strings avoid escape processing:</ p >
< pre >< code > var raw = """
This is a raw string.
Backslashes \ are literal.
"""</ code ></ pre >
< h3 > Booleans</ h3 >
< pre >< code > var yes = true
var no = false</ code ></ pre >
< p > Only < code > false</ code > and < code > null</ code > are falsy. All other values, including < code > 0</ code > and empty strings, are truthy.</ p >
< h3 > Null</ h3 >
< pre >< code > var nothing = null</ code ></ pre >
< h3 > Ranges</ h3 >
< p > Ranges represent sequences of numbers:</ p >
< pre >< code > var inclusive = 1..5 // 1, 2, 3, 4, 5
var exclusive = 1...5 // 1, 2, 3, 4</ code ></ pre >
< h3 > Lists</ h3 >
< p > Ordered, indexable collections:</ p >
< pre >< code > var empty = []
var numbers = [1, 2, 3, 4, 5]
var mixed = [1, "two", true, null]
System.print(numbers[0]) // 1
System.print(numbers[-1]) // 5 (last element)
numbers[0] = 10
numbers.add(6)</ code ></ pre >
< h3 > Maps</ h3 >
< p > Key-value collections:</ p >
< pre >< code > var empty = {}
var person = {
"name": "Alice",
"age": 30
}
System.print(person["name"]) // Alice
person["city"] = "Amsterdam"</ code ></ pre >
< h2 > Operators</ h2 >
< h3 > Arithmetic</ h3 >
< pre >< code > 1 + 2 // 3
5 - 3 // 2
4 * 3 // 12
10 / 4 // 2.5
10 % 3 // 1 (modulo)</ code ></ pre >
< h3 > Comparison</ h3 >
< pre >< code > 1 == 1 // true
1 != 2 // true
1 < 2 // true
1 < = 1 // true
2 > 1 // true
2 >= 2 // true</ code ></ pre >
< h3 > Logical</ h3 >
< pre >< code > true && false // false
true || false // true
!true // false</ code ></ pre >
< p > Logical operators short-circuit:</ p >
< pre >< code > false && expensive() // expensive() not called
true || expensive() // expensive() not called</ code ></ pre >
< h3 > Bitwise</ h3 >
< pre >< code > 5 & 3 // 1 (AND)
5 | 3 // 7 (OR)
5 ^ 3 // 6 (XOR)
~5 // -6 (NOT)
8 << 2 // 32 (left shift)
8 >> 2 // 2 (right shift)</ code ></ pre >
< h3 > Ternary</ h3 >
< pre >< code > var result = condition ? valueIfTrue : valueIfFalse</ code ></ pre >
< h2 > String Interpolation</ h2 >
< p > Embed expressions in strings with < code > %()</ code > :</ p >
< pre >< code > var name = "World"
System.print("Hello, %(name)!")
var a = 3
var b = 4
System.print("%(a) + %(b) = %(a + b)")</ code ></ pre >
< p > Any expression can be interpolated:</ p >
< pre >< code > System.print("Random: %(Random.new().float())")
System.print("List: %([1, 2, 3].map { |x| x * 2 })")</ code ></ pre >
< h2 > Blocks</ h2 >
< p > Blocks are anonymous functions. They use curly braces:</ p >
< pre >< code > var block = { System.print("Hello") }
block.call()
var add = { |a, b| a + b }
System.print(add.call(1, 2)) // 3</ code ></ pre >
< p > Blocks with a single expression return that value:</ p >
< pre >< code > var square = { |x| x * x }
System.print(square.call(5)) // 25</ code ></ pre >
< h2 > Functions</ h2 >
< p > Use < code > Fn.new</ code > for functions stored in variables:</ p >
< pre >< code > var greet = Fn.new { |name|
return "Hello, %(name)!"
}
System.print(greet.call("World"))</ code ></ pre >
< p > Functions can have multiple statements:</ p >
< pre >< code > var factorial = Fn.new { |n|
if (n < = 1) return 1
return n * factorial.call(n - 1)
}</ code ></ pre >
< h2 > Is Operator</ h2 >
< p > Check if an object is an instance of a class:</ p >
< pre >< code > "hello" is String // true
42 is Num // true
[1, 2] is List // true</ code ></ pre >
< h2 > Reserved Words</ h2 >
< p > The following are reserved and cannot be used as identifiers:</ p >
< pre >< code > break class construct else false for foreign if import
in is null return static super this true var while</ code ></ pre >
< h2 > Identifiers</ h2 >
< p > Identifiers follow these conventions:</ p >
< ul >
< li >< code > camelCase</ code > for variables and methods</ li >
< li >< code > PascalCase</ code > for class names</ li >
< li >< code > _underscore</ code > prefix for private fields</ li >
< li >< code > UPPER_CASE</ code > for constants (by convention)</ li >
</ ul >
</ article >
< footer class = "page-footer" >
< a href = "../getting-started/repl.html" class = "prev" > Using the REPL</ a >
< a href = "classes.html" class = "next" > Classes</ a >
</ footer >
</ main >
</ div >
< script src = "../js/main.js" ></ script >
</ body >
</ html >