Basic Syntax

This article is an introduction to the Cyrus Programming Language. It assumes you already have a basic understanding of programming concepts such as variables, statements, and types. Here, you’ll see how familiar ideas are expressed in Cyrus, while also being introduced to new concepts that make the language unique.

If you haven't installed Cyrus yet, start with the Getting Started guide before continuing.


Comments

Comments are pieces of text ignored by the compiler. They're useful for explaining code, leaving notes, or temporarily disabling parts of a program. Cyrus supports both single-line and multi-line comments.

  • Single-line Comments
// This is a single-line comment
#msg: char* = "Hello, Cyrus!"; // You can also place it after code
  • Multi-line Comments
/*
  Outer comment start
  /* Nested comment inside */
  Outer comment end

  NOTE: Multi-line comments can also be nested!
*/

Const string and Character Literals

String literals in Cyrus are enclosed in double quotes "xxx", while character literals are enclosed in single quotes 'x'. Both forms represent sequences of Unicode characters, but they differ in intent and usage:

  • String literals produce values of type char*, which can hold arbitrarily many characters.
  • Character literals produce values of type char, which always represent exactly one Unicode scalar value.
#greeting: char* = "Hello, Cyrus!";
#letter: char = 'A';

Escapes

Special characters that are difficult to type directly or would otherwise break the syntax can be written using escape sequences. All escape sequences begin with a backslash ().

Common escapes include:

  • \n - newline (line feed, U+000A)
  • \t - horizontal tab (U+0009)
  • \r - carriage return (U+000D)
  • \b - backspace (U+0008)
  • \a - bell/alert (U+0007)
  • \v - vertical tab (U+000B)
  • \f - form feed (U+000C)
  • \ - literal backslash
  • " - double quote (inside strings)
  • ' - single quote (inside chars or strings)

Example:

#poem: char* = "Line one\nLine two\nLine three";
#quote: char* = "She said: \"Cyrus is great!\"";
#backslash: char = '\\';

#paragraph: char* = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type specimen book.";

Unicode and Emojis

Cyrus supports Unicode characters directly in string and character literals. You can type emojis, accented letters, or any other Unicode characters inside quotes:

#letter: char = 'A';                     // ✅ Works
#smile: char* = "😇";                    // ✅ Works in a string
#rocket: string = "Let's go! \u{1F680}"; // ✅ Works, 🚀
#greek_alpha: char* = "\u03B1";          // ✅ Works, α
#emoji_char: char = '😇';                // ❌ Does NOT work
#multibyte_char: char = '\u263A';        // ❌ Does NOT work

Integer Constants

Numeric constants in Cyrus can be written in decimal, hexadecimal, octal, or binary formats:

  • Decimal (Base 10):
#a = 1234;
  • Hexadecimal (Base 16, prefix with 0x or 0X):
#b = 0x42EDAA02;
  • Binary (Base 2, prefix with 0b or 0B):
#b = 0x42EDAA02;

Numeric literals may include underscores _ between digits for readability; these are ignored by the compiler:

#million = 1_000_000;
#hex_val = 0xDE_AD_BE_EF;

Literal Suffixes

Cyrus allows explicit type suffixes on numeric literals to specify their type. This is useful when the compiler cannot infer the type or when you want to guarantee a specific type.

Integer Suffixes

Valid integer suffixes include:

  • uintptr
  • intptr
  • size_t
  • int
  • int8
  • int16
  • int32
  • int64
  • int128
  • uint
  • uint8
  • uint16
  • uint32
  • uint64
  • uint128

Valid float suffixes include:

  • float16
  • float32
  • float64
  • float128

Example:

#a = 1234int64;
#b = 3.14float64;

Default Type of Literals

If you don't specify a type suffix, Cyrus assigns int as the default type for integer literals, and float64 as the default type for floating-point literals.

Type suffixes can be used to explicitly control the size and signedness of an integer literal, or to select a different floating-point precision.


Arrays

Arrays in Cyrus are fixed-size sequences of elements. Their size must be known at compile time, similar to C arrays.

#name = Type[capacity]{element1, element2, ..., elementN};

Example:

#a = int[3]{1, 2, 3};
#b = const float64[4]{3.14, 2.71, 1.618, 0.577};
  • The array size cannot change at runtime.
  • Access elements using indexing, starting from 0.
printf("%d\n", a[0]);

Pointers

Pointers in Cyrus behave like C pointers. They store the memory address of another variable.

#ptr: Type* = &variable;
  • Type* - pointer to a value of Type
  • &variable - takes the address of a variable

Example:

#a: int = 10;
#b: int* = &a;

printf("%d\n", *b); // prints 10

Pointer arithmetic behaves like C (e.g., incrementing a pointer moves it by sizeof(Type) bytes).


Vectors

Coming soon...