3. Lexical Structure
The lexical structure of MALDA defines the basic building blocks of the language: comments, identifiers, keywords, literals, operators, and delimiters.
3.1 Comments
MALDA supports two types of comments:
Single-line Comments
Single-line comments start with // and continue to the end of the line:
// This is a single-line comment
var x = 10; // Comments can also appear after code
Multi-line Comments
Multi-line comments are enclosed in /* and */:
/* This is a
multi-line comment
that spans multiple lines */
/* inside a multi-line comment will not start a new comment.
3.2 Identifiers
Identifiers are names used for variables, functions, classes, and other user-defined entities.
Rules for Identifiers
- Must start with a letter (a-z, A-Z) or underscore (_)
- Can contain letters, digits (0-9), and underscores
- Case-sensitive
- Cannot be a keyword
Examples
var x = 10; // Valid
var myVar = 20; // Valid
var _temp = 30; // Valid
var counter1 = 40; // Valid
var 2invalid = 50; // Invalid: starts with digit
var my-var = 60; // Invalid: contains hyphen
3.3 Keywords
Keywords are reserved words that have special meaning in MALDA. They cannot be used as identifiers. The authoritative list is in MaldaLang/Lexer.cs; the same set appears in Appendix A: Reserved Words.
Complete Keyword List
if, else, while, for, foreach, function, return, var, const, print, input,
true, false, and, or, not, break, continue, try, catch, finally, throw,
match, case, default, defer,
class, new, this, super, extends, public, private, static, null, type, schema, api,
prompt, async, await,
actor, spawn, send, receive, self, on, then, timeout, message,
workflow, step, approval, wait, retry, backoff, delay, maxDelay, compensate, onReject,
component, property,
dict, graph, directed, undirected, in,
using, include, import, export
fn and def are not keywords; the parser rejects them in favor of function. reply is a built-in function, not a keyword.
using serves two unrelated purposes: a top-level package alias (using json = System.Text.Json;) and a scoped resource block (using conn = openDb() { ... }). See 1. Introduction and 8. Control Structures respectively.
Keyword Categories
- Control Flow:
if,else,while,for,foreach,break,continue,match,case,default - Functions:
function,return - Prompts:
prompt - Modules:
include,using,import,export - Sum types:
type - Schemas:
schema - Closed APIs:
api - Variables:
var,const - Resource cleanup:
defer,using(resource form) - I/O:
print/io.print,input/io.input(files, paths, and env are in the same chapter) - Booleans:
true,false - Logical Operators:
and(&&),or(||),not(!) - Exception Handling:
try,catch,finally,throw - Classes:
class,new,this,super,extends - Access Modifiers:
public,private - Static:
static - Null:
null - Actors:
actor,message,spawn,send,receive,self,on,then,timeout - Workflows:
workflow,step,approval,wait,retry,backoff,delay,maxDelay,compensate,onReject - Web UI:
component,property - Async Operations:
async,await - Data Structures:
dict,graph,directed,undirected,in
3.4 Literals
Literals are constant values written directly in code.
Integer Literals
Integer literals are sequences of digits, optionally prefixed with a minus sign:
42
-10
0
12345
Float Literals
Float literals contain a decimal point or use scientific notation:
3.14
-0.5
2.0
1e-5
1.5e10
String Literals
String literals can be enclosed in either double quotes ("...") or single quotes ('...'). Both forms are equivalent and support escape sequences:
"Hello, World!"
'Hello, World!'
"Line 1\nLine 2"
'Line 1\nLine 2'
"Tab\tseparated"
"CRLF line\r\n"
"Quote: \"Hello\""
'Quote: \'Hello\''
"He said 'hello'"
'He said "hello"'
"Backslash: \\"
You can use single quotes when your string contains double quotes, or double quotes when your string contains single quotes, to avoid escaping:
var msg1 = "It's a test"; // No escaping needed
var msg2 = 'He said "hello"'; // No escaping needed
var msg3 = 'It\'s a test'; // Escaping needed
var msg4 = "He said \"hello\""; // Escaping needed
Escape Sequences
| Sequence | Meaning |
|---|---|
\n |
Newline (LF) |
\r |
Carriage return (CR) |
\t |
Tab |
\" |
Double quote (in double-quoted strings) |
\' |
Single quote (in single-quoted strings) |
\\ |
Backslash |
\{ / \} |
Literal braces (interpolated strings only: $"..." / $"""...""") |
Note: Both \" and \' work in both string types, so you can include either quote type in any string. Unknown escape sequences (for example \x) are a lexer error — they are not silently turned into the bare letter.
Multiline Strings (Triple-Quoted)
Multiline string literals use three double quotes (""") as the opening and closing delimiter. They can span multiple lines and preserve newlines. Inside a triple-quoted string, single and double quotes do not need to be escaped, which makes them convenient for long text, prompts, or content that contains many quotes.
Plain multiline string — """...""":
var text = """
First line.
Second line with "quotes" and 'apostrophes'.
No escaping needed.
""";
The closing """ must appear on its own (possibly after content on the same line). Everything between the opening and closing """ is included literally; the only special sequence is the closing """ itself.
Interpolated multiline string — $"""...""":
Use $""" to start an interpolated multiline string. It behaves like a triple-quoted string but allows embedded expressions with {expression}. Escape sequences (e.g. \n, \t, \", \\) are supported.
var name = "Alice";
var greeting = $"""
Hello, {name}.
Welcome to line 2.
""";
Summary:
"""— multiline string, no escaping of quotes or backslashes$"""— multiline interpolated string with{expr}and escape sequences
Boolean Literals
Boolean literals are the keywords true and false:
true
false
3.5 Operators
Operators are symbols or keywords that perform operations on operands.
Arithmetic Operators
| Operator | Description | Example |
|---|---|---|
+ |
Addition | 5 + 3 → 8 |
- |
Subtraction | 5 - 3 → 2 |
* |
Multiplication (also string repetition) | 5 * 3 → 15"*" * 5 → "*****" |
/ |
Division | 10 / 2 → 5 |
% |
Modulo (remainder) | 10 % 3 → 1 |
Comparison Operators
| Operator | Description | Example |
|---|---|---|
== |
Equal to | 5 == 5 → true, "hello" == "hello" → true |
!= |
Not equal to | 5 != 3 → true, "hello" != "world" → true |
< |
Less than | 3 < 5 → true, "apple" < "banana" → true |
> |
Greater than | 5 > 3 → true, "zebra" > "apple" → true |
<= |
Less than or equal | 5 <= 5 → true, "hello" <= "hello" → true |
>= |
Greater than or equal | 5 >= 3 → true, "hello" >= "hello" → true |
Note: Relational operators (<, >, <=, >=) work with both numbers and strings. For strings, comparisons are lexicographic (alphabetical order). Both operands must be of the same type (both numbers or both strings).
Logical Operators
| Operator | Description | Example |
|---|---|---|
and or && |
Logical AND | true and false → false |
or or || |
Logical OR | true or false → true |
not or ! |
Logical NOT | not true → false |
Assignment Operators
The = operator assigns a value to a variable. Compound forms combine an arithmetic operation with assignment:
var x = 10;
x = 20;
x += 5; // equivalent to x = x + 5
x -= 3; // x = x - 3
x *= 2; // x = x * 2
x /= 4; // x = x / 4
Assigning to a name declared with const is a runtime error. See 5. Variables.
Increment and Decrement
++ and -- adjust a numeric variable by one, in prefix or postfix position:
var i = 0;
i++; // postfix: yields 0, then i becomes 1
++i; // prefix: i becomes 2, yields 2
i--;
--i;
Lambda Arrow Operator
The => operator is used in lambda expressions (anonymous functions):
var add = (a, b) => a + b;
var square = x => x * x;
var process = (x) => { return x * 2; };
See 9.6 Lambda Expressions for more details.
The same token also spells a function's informational return type, where -> and => are interchangeable: function parse(text) -> Result { ... }.
Pipe Forward
The |> operator passes the value on its left as the first argument of the call on its right:
var result = " hello " |> trim |> upper;
See 7. Expressions for precedence and chaining rules.
Decorator Marker
@ introduces a decorator on a declaration, for example @Tool, @PAGE, or @Route:
@Tool("Adds two numbers")
function add(a, b) {
return a + b;
}
See 9. Functions for the decorator forms.
String Concatenation
The + operator concatenates strings when both operands are strings:
"Hello, " + "World!" // "Hello, World!"
String Repetition
The * operator repeats strings when one operand is a string and the other is a number:
"*" * 20 // "********************"
5 * "-" // "-----"
"abc" * 3 // "abcabcabc"
Both string * number and number * string work the same way. The numeric value is coerced to an integer. If the count is 0 or negative, an empty string is returned.
Member Access
The . (dot) operator accesses members of objects:
object.field
object.method()
Null-Conditional Access
?. and ?[ access a member or an index only when the receiver is not null, otherwise the access evaluates to null instead of raising an error:
var user = null;
print(user?.name); // null, no error
print(user?["name"]); // null, no error
See 7. Expressions for how these behave in longer chains.
3.6 Delimiters
Delimiters are punctuation marks that structure code:
| Delimiter | Usage |
|---|---|
; |
Statement terminator (optional in some contexts) |
() |
Function calls, expressions, grouping |
{} |
Code blocks, object literals |
[] |
Array indexing, array literals |
, |
Parameter/argument separators |
. |
Member access operator |
See Also
- 7. Expressions - How operators are used in expressions
- 36. Appendix - Operator precedence table