Browse the documentation

AEL 1.0.0

Syntax basics

This page covers the smallest pieces of AEL, the Agent Engineering Language: how source text is written, how statements end, and how names, literals and operators work.

Source text and names

  • A source file is UTF-8 text. Text and comments may use any Unicode characters; everything else is ASCII.
  • White space is the space, the tab and the line break. Any other spacing character outside a string or a comment is refused rather than silently read as a space.
  • A name (an identifier) is letters, digits and _, and does not start with a digit: total, max_items, _draft. Names are case-sensitive, so total and Total differ.
  • A reserved keyword is not allowed as a name, but a name may start with one: fnx and iffy are names. Keywords lists them.
  • _ on its own is the wildcard of a match pattern, never a name. print is a built-in name that you cannot declare again.

Comments

A # starts a comment that runs to the end of the line.

# The discount applies to every order line.
let rate: u64 = 10;   # percent

A comment can also span several lines: three backticks in a row open it, and the next three close it. Comments do not nest. Comments stay in your source: compiled files and package files carry none of their text.

Statements and blocks

  • Every statement ends with ;. A line break never ends a statement.
  • Function bodies and the blocks of if, else, while and match are written in braces, { … }. An empty block is allowed.
  • A block can stand on its own to limit where its names are visible.
  • A function cannot be declared inside another function.

Bindings

let binds a name to a value. The type follows a colon; when the value makes the type clear, you can leave it out.

let limit: u32 = 500;
let count = 4;           # an integer literal on its own is an i64
let mut attempts: u8 = 0;
attempts = attempts + 1;
  • A binding cannot change unless it is declared with let mut.
  • A binding declared without a value needs its type, and must receive a value on every path before it is read. Ownership describes the rule.
  • An inner block can declare a name that hides an outer one. Declaring the same name twice in one block is refused.
  • A binding's name becomes visible after its value, so in let x: i64 = x + 1; the x on the right is an earlier x.

Literals

LiteralExamplesNotes
Integer0, 42, 1_024Decimal only. A single _ may separate digits; leading zeros stay decimal. A minus sign is an operator, as in -5.
Booleantrue, falseNot an integer.
Text"hello", "line\n"Double-quoted UTF-8. It needs a bounded text type with room for it; see Types.

The escapes in text are \", \\, \n, \r, \t, \0 and \u{…} with one to six hexadecimal digits for a Unicode character. Any other escape, and a raw line break inside the quotes, is refused.

Operators

From the tightest binding to the loosest:

OperatorsMeaning
f(x), a.b, a[i]Call, field, index
-, !, ~, *, &, &mutNegation, logical not, bitwise not, and the reference operators of Ownership
*, /, %Multiplication, division, remainder
+, -Addition, subtraction
<<, >>Shifts
&Bitwise and
^Bitwise exclusive or
|Bitwise or
<, <=, >, >=Comparison
==, !=Equality
&&Logical and
||Logical or
  • Operators of one level group from the left: a - b - c is (a - b) - c.
  • Comparisons do not chain: a < b < c is refused. Write a < b && b < c.
  • && and || take booleans and evaluate their right side only when needed. ! takes only a boolean.
  • Arithmetic, bitwise operators and ordered comparisons take two integers of the same type. Errors and checked arithmetic describes overflow, division and shifts.

Order of evaluation

Evaluation always runs left to right. A call evaluates all of its arguments, in order, before the function starts. An assignment evaluates its target, such as values[i], before the value it stores.

Keywords

GroupKeywords
Component rolesmain, config, global, reuse, node, edge, agent, subagent, hook, skill, and routes in a scope that selects the server/http package
Declarations and statementsfn, let, mut, return, if, else, while, match, true, false, type, struct, enum, as
Spawning subagentsspawn, try_spawn
Modifierisolated, before the keyword of an agent, a node or a subagent
File headersimport, refer, select
Recordspack, metadata, and bindings inside an agent, a subagent or a node
LanguagesThe tag of a language, such as python: after fn in a function written in that language, and first in the primary of a language file

The declaration and statement keywords, agent, config and import are reserved and never usable as names. The other component roles, refer, select, pack and metadata have their meaning where they start a declaration, a header entry or a record, and spawn and try_spawn where they start a spawn. Subagents describes spawning, Isolated components the modifier, Bindings and storage the bindings record, and Functions in other languages the language tags.

These are also reserved, and not usable as names: pub, task, tool, service, prompt, region, await, unsafe, extern and static.

Formatting source describes how source is formatted.