Skip to content

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.

The project uses these conventions:

  • Type names use PascalCase.
  • Function names, variable names, field names, enum cases, and module aliases use snake_case.
  • Primitive types such as Int, Bool, and UInt8 are written like ordinary type names.
enum TokenKind {
    kw,
    double_quoted,
    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; functions without a self parameter do not have self.

A source file is a sequence of top-level items:

  • import
  • alias
  • const
  • global declarations
  • functions
  • struct, enum, trait
  • extend
  • comptime blocks
alias math = import "utils/math.jiang";

alias Byte = UInt8;
alias answer = math.answer;

public const Int default_limit = 1024;

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.

public const exports a compile-time value through the module interface. comptime { ... } evaluates a block before runtime; conditional imports use namespace-valued aliases; see Const and Comptime.

Some keywords can carry options. Jiang writes these options with square brackets after the keyword:

enum [UInt8] ByteTag {
    block = 1,
    item,
}

The old keyword(...) form is not used for keyword options. Parentheses remain ordinary expression or type syntax, so keyword options stay visually separate from function calls.

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.

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 ().

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)

$ 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.

is performs pattern matching. Optional values use .some(...):

if maybe is .some(value) {
    return value;
} else {
    return 0;
}

Mutable payload bindings write the payload type explicitly:

if maybe is .some(Int value!) {
    value = value + 1;
}

switch uses the same style of patterns for optional, variant, and literal matches.

Use single quotes for characters and double quotes for strings. There is no implicit conversion between them. After escape decoding, a character must contain exactly one Unicode scalar: 'a', '中', '😀' and '\0' are valid; '', 'abc' and 'e\u{301}' are not. The last example may look like one character, but contains two scalars.

For custom languages using default tokens, single_quoted and double_quoted describe the quote form. A language can interpret the complete single-quoted text itself. Creating a Jiang character literal requires the single-scalar rule above.