Lexical Rules


Keywords in Céu are reserved names that cannot be used as identifiers (e.g., for variables and events):

    and             as              async           atomic          await

    bool            break           byte            call            code

    const           continue        data            deterministic   do

    dynamic         else            emit            end             escape

    event           every           false           finalize        FOREVER

    hold            if              in              input           int

    integer         is              isr             kill            lock

    loop            lua             native          NEVER           new

    no              nohold          none            not             nothing

    null            off             on              or              outer

    output          par             pause           plain           pool

    pos             pre             pure            r32             r64

    real            recursive       request         resume          s16

    s32             s64             s8              sizeof          spawn

    ssize           static          then            thread          tight

    traverse        true            u16             u32             u64

    u8              uint            until           usize           val

    var             watching        with            yes

TODO: catch, throw, throws


Céu uses identifiers to refer to types (ID_type), variables (ID_int), vectors (ID_int), pools (ID_int), internal events (ID_int), external events (ID_ext), code abstractions (ID_abs), data abstractions (ID_abs), fields (ID_field), native symbols (ID_nat), and block labels (ID_int).

ID       ::= [a-z, A-Z, 0-9, _]+ // a sequence of letters, digits, and underscores
ID_int   ::= ID                  // ID beginning with lowercase
ID_ext   ::= ID                  // ID all in uppercase, not beginning with digit
ID_abs   ::= ID {`.´ ID}         // IDs beginning with uppercase, containining at least one lowercase)
ID_field ::= ID                  // ID not beginning with digit
ID_nat   ::= ID                  // ID beginning with underscore

ID_type  ::= ( ID_nat | ID_abs
             | none
             | bool  | on/off | yes/no
             | byte
             | r32   | r64    | real
             | s8    | s16    | s32     | s64
             | u8    | u16    | u32     | u64
             | int   | uint   | integer
             | ssize | usize )

Declarations for code and data abstractions create new types which can be used as type identifiers.


var int a;                    // "a" is a variable, "int" is a type

emit e;                       // "e" is an internal event

await I;                      // "I" is an external input event

spawn Move();                 // "Move" is a code abstraction and a type

var Rect r;                   // "Rect" is a data abstraction and a type

escape r.width;               // "width" is a field

_printf("hello world!\n");    // "_printf" is a native symbol


Céu provides literals for booleans, integers, reals, strings, and null pointers.


The boolean type has only two possible values: true and false.

The boolean values on and yes are synonymous to true and can be used interchangeably. The boolean values off and no are synonymous to false and can be used interchangeably.


Céu supports decimal and hexadecimal integers:

  • Decimals: a sequence of digits (i.e., [0-9]+).
  • Hexadecimals: a sequence of hexadecimal digits (i.e., [0-9, a-f, A-F]+) prefixed by 0x.


// both are equal to the decimal 127
v = 127;    // decimal
v = 0x7F;   // hexadecimal


TODO (like C)


A sequence of characters surrounded by the character " is converted into a null-terminated string, just like in C:


_printf("Hello World!\n");

Null pointer

TODO (like C)


Céu provides C-style comments:

  • Single-line comments begin with // and run to end of the line.
  • Multi-line comments use /* and */ as delimiters. Multi-line comments can be nested by using a different number of * as delimiters.


var int a;    // this is a single-line comment

/** comments a block that contains comments

var int a;
/* this is a nested multi-line comment
a = 1;