Syntax
ScarScript source files use the .scar extension. Blocks use braces, and statements do not require a trailing semicolon.
Comments
// Single-line commentDeclare values
Use val for an immutable binding, mut when its value must change, and const for a compile-time constant.
val name: str = "ScarScript"
mut count: int = 0
const MAX_RETRIES: int = 3
count = count + 1Type annotations can usually be inferred from the initializer:
val answer = 42 // int
val ratio = 3.14 // dec
val enabled = true // bool
val greeting = "hello" // strOperators
| Category | Operators |
|---|---|
| Arithmetic | +, -, *, /, % |
| Comparison | ==, !=, <, <=, >, >= |
| Logical | and, or, ! |
| Range | .. |
+ adds numbers or concatenates strings of the same type. Mixing int and dec promotes the integer operand to dec. The % operator is for integers.
For booleans, and and or are logical operators. For strings and numbers, or can provide a fallback when the left value is empty or zero:
val port = sys.env("PORT") or "8080"
val attempts = 0 or 3
val allowed = isAdmin or isOwnerConditions
Conditions must evaluate to bool; values are not implicitly treated as truthy or falsy.
val age = 20
if age >= 18 {
print("adult")
} else if age >= 13 {
print("teen")
} else {
print("child")
}Loops
The for keyword supports ranges, collections, and condition-based loops:
// Inclusive numeric range: prints 0 through 5
for i in 0..5 {
print(i)
}
val names: str[] = ["Ada", "Lin"]
for name in names {
print(name)
}
mut count = 0
for count < 3 {
count = count + 1
}The range form is inclusive: a range start..end visits every integer from start to end, including end itself.
Strings and interpolation
Use braces to interpolate expressions in a string:
val name = "Ada"
val total = 2 + 3
print("Hello, {name}. The total is {total}.")Common escapes include \n, \t, \\, \", \{, and \}.
Arrays and maps
val numbers: int[] = [1, 2, 3]
mut names: str[] = ["Ada", "Lin"]
names.add("Grace")
val scores: map[str: int] = {"ada": 10, "lin": 9}
print(scores.ada)Empty arrays and maps need explicit type annotations so the compiler can determine their element and value types.