Expressions
Expressions produce values. Statements bind or assign values and control execution.
Literals and Construction
let integer = 42;
let decimal = 3.14;
let enabled = true;
let text = "Feng";
let items = [1, 2, 3];
let user = User { name: "Alice" };
Create an array with Type[:length] and access an element with value[index]:
let bytes: byte[!] = byte[:256];
bytes[0] = (byte)65;
Arithmetic and Comparison
Feng provides the usual arithmetic, relational, equality, logical, bitwise, and shift operators:
let total = price * count + shipping;
let in_range = score >= 60 && score <= 100;
let same = left == right;
let masked = flags & 0xff;
The two operands must usually have the same static type. A numeric literal can adapt to an established numeric target type, but values already bound with different numeric types require an explicit conversion.
Logical && and || use short-circuit evaluation. Function arguments and binary operands are evaluated from left to right.
Explicit Conversions
A conversion is written as (TargetType)expression:
let small: i32 = 42;
let wide = (i64)small;
let ratio = (f64)small / 100.0;
Explicit syntax does not imply that every pair of types is convertible. The source and target type rules determine whether a conversion is valid.
Assignment and Compound Assignment
var count = 0;
count = count + 1;
count += 2;
count *= 3;
var mask: i32 = 1;
mask <<= 3;
An assignment target must be writable: a var binding, a var member, or an element at a writable array level. A compound assignment evaluates its left-hand target only once.
Branch Expressions
if, match, and try/catch can all produce values:
let label = if score >= 60 {
"pass";
} else {
"fail";
};
let category = match code {
200 { "ok" }
400...499 { "client error" }
else { "other" }
};
Every normally completing branch of an expression must produce the same result type. The final expression is the value of its block. See Control Flow, Pattern Matching, and Error Handling.