Syntax
Jiang syntax is organized around declarations, explicit types, and visible low-level operations. When reading a file, start with imports and top-level declarations, then move into statements and expressions inside function bodies.
Naming Style
Section titled “Naming Style”The project uses these conventions:
- Type names use
PascalCase. - Function names, variable names, field names, enum members, and module aliases use
snake_case. - Primitive types such as
Int,Bool, andUInt8are written like ordinary type names.
enum TokenKind { kw, string_lit, left_paren,}
struct SourceFile { UInt8[] file_path; Int start_offset;}
UInt8[] read_source(UInt8[] file_path) { return file_path;}Self is a special name in type position. self is available in instance methods and init bodies; static methods do not have self.
Source Files
Section titled “Source Files”A source file is a sequence of top-level items:
importalias- global declarations
- functions
struct,record,enum,union,traitextend
import math = "utils/math.jiang";
alias Byte = UInt8;alias answer = math.answer;
public struct Pair { Int left; Int right;}
public Int add(Int left, Int right) { return left + right;}public marks a declaration as visible outside the module.
Statements
Section titled “Statements”Blocks contain declarations, destructuring statements, assignments, call statements, control-flow statements, and defer.
Int main() { Int! total = 0;
for i in 0..10 { total = total + i; }
return total;}Most statements end with semicolons. Control-flow forms that own a block, such as if, switch, while, and for, do not need an extra semicolon after the block.
Blocks
Section titled “Blocks”A block has a value only when it ends with a tail expression without a semicolon:
Int value = { Int base = 40; base + 2}Without a tail expression, the block value is ().
Expressions
Section titled “Expressions”Jiang expressions include literals, names, calls, field access, indexing, slicing, arithmetic, comparisons, if, switch, try catch, and blocks.
Int value = if flag { 1} else { 2}Field literals are written with their type path:
Point origin = Point { x: 0, y: 0 }Implicit Operation Layer
Section titled “Implicit Operation Layer”$ enters the implicit operation layer for a value or type:
Int value = 42;Int& ref = value$.ref();Int copied = ref$.get();
UInt size = Int$.size();Use parentheses when applying $ to a compound expression:
Int raw = (left + right)$.as(Int);Prefer safe target-type initialization such as Float(value) for ordinary conversions. Do not use
value$.as(Type) as the everyday conversion spelling; it is a low-level cast form for raw pointers,
integer addresses, FFI, and similar code.
Patterns
Section titled “Patterns”is performs pattern matching. Optional values use the some pattern:
if maybe is some value { return value;} else { return 0;}Mutable inferred bindings use _!:
if maybe is some _! value { value = value + 1;}switch uses the same style of patterns for optional, variant, and literal matches.