Locations & Expressions

Céu specifies locations and expressions as follows:

Exp ::= NUM | STR | null | true | false | on | off | yes | no
     |  `(´ Exp `)´
     |  Exp <binop> Exp
     |  <unop> Exp
     |  Exp (`:´|`.´) (ID_int|ID_nat)
     |  Exp (`?´|`!´)
     |  Exp `[´ Exp `]´
     |  Exp `(´ [ LIST(Exp) ] `)´
     |  Exp is Type
     |  Exp as Type
     |  Exp as `/´(nohold|plain|pure)
     |  sizeof `(´ (Type|Exp) `)´
     |  Nat_Call | Code_Call
     |  ID_int
     |  ID_nat
     |  outer

/* Locations */

Loc ::= Loc [as (Type | `/´(nohold|plain|pure)) `)´
     |  [`*´|`$´] Loc
     |  Loc { `[´Exp`]´ | (`:´|`.´) (ID_int|ID_nat) | `!´ }
     |  ID_int
     |  ID_nat
     |  outer
     |  `{´ <code in C> `}´
     |  `(´ Loc `)´

/* Operator Precedence */

    /* lowest priority */

    // locations
    *     $
    :     .     !     []
    as

    // expressions
    is    as                                            // binops
    or
    and
    !=    ==    <=    >=    <     >
    |
    ^
    &
    <<    >>
    +     -
    *     /     %
    not   +     -     ~     $$    $     *     &&    &   // unops
    :     .     !     ?     ()    []

    /* highest priority */

Primary

TODO

Outer

TODO

Example:

var int x=0;

code/call Test(none)->none do
    outer.x = 1;
    var int x = 0;

    _printf("%d\n", outer.x); //prints 1
    _printf("%d\n", x);       //prints 0
end

call Test();
_printf("%d\n", x); //prints 1

Arithmetic

Céu supports the arithmetic expressions addition, subtraction, modulo (remainder), multiplication, division, unary-plus, and unary-minus through the operators that follow:

    +      -      %      *      /      +      -

Bitwise

Céu supports the bitwise expressions not, and, or, xor, left-shift, and right-shift through the operators that follow:

    ~      &      |      ^      <<      >>

Relational

Céu supports the relational expressions equal-to, not-equal-to, greater-than, less-than, greater-than-or-equal-to, and less-than-or-equal-to through the operators that follow:

    ==      !=      >      <      >=      <=

Relational expressions evaluate to true or false.

Logical

Céu supports the logical expressions not, and, and or through the operators that follow:

    not      and      or

Logical expressions evaluate to true or false.

Types

Céu supports type checks and casts:

Check ::= Exp is Type
Cast  ::= Exp as Type

Type Check

A type check evaluates to true or false depending on whether the runtime type of the expression is a subtype of the checked type or not.

The static type of the expression must be a supertype of the checked type.

Example:

data Aa;
data Aa.Bb;
var Aa a = <...>;       // "a" is of static type "Aa"
<...>
if a is Aa.Bb then      // is the runtime type of "a" a subtype of "Aa.Bb"?
    <...>
end

Type Cast

A type cast converts the type of an expression into a new type as follows:

  1. The expression type is a data type:
    1. The new type is int: Evaluates to the type enumeration for the expression type.
    2. The new type is a subtype of the expression static type:
      1. The expression runtime type is a subtype of the new type: Evaluates to the new type.
      2. Evaluates to error.
    3. The new type is a supertype of the expression static type: Always succeeds and evaluates to the new type. See also Dynamic Dispatching.
    4. Evaluates to error.
  2. Evaluates to the new type (i.e., a weak typecast, as in C).

Examples:

var Direction dir = <...>;
_printf("dir = %d\n", dir as int);

var Aa a = <...>;
_printf("a.v = %d\n", (a as Aa.Bb).v);

var Media.Video vid = <...>;
await/dynamic Play(&m as Media);

var bool b = <...>;
_printf("b= %d\n", b as int);

Modifiers

Expressions that evaluate to native types can be modified as follows:

Mod ::= Exp as `/´(nohold|plain|pure)

Modifiers may suppress the requirement for resource finalization.

References

Céu supports aliases and pointers as references.

Aliases

An alias is acquired by prefixing a native call or a location with the operator &:

Alias ::= `&´ (Nat_Call | Loc)

See also the unwrap operator ! for option variable aliases.

Pointers

The operator && returns the address of a location, while the operator * dereferences a pointer:

Addr  ::= `&&´ Loc
Deref ::= `*´ Loc

Option

The operator ? checks if the location of an option type is set, while the operator ! unwraps the location, raising an error if it is unset:

Check  ::= Loc `?´
Unwrap ::= Loc `!´

Sizeof

A sizeof expression returns the size of a type or expression, in bytes:

Sizeof ::= sizeof `(´ (Type|Exp) `)´

Calls

See Native Call and Code Invocation.

Vectors

Index

Céu uses square brackets to index vectors:

Vec_Idx ::= Loc `[´ Exp `]´

The index expression must be of type usize.

Vectors start at index zero. Céu generates an error for out-of-bounds vector accesses.

Length

The operator $ returns the current length of a vector, while the operator $$ returns the max length:

Vec_Len ::= `$´  Loc
Vec_Max ::= `$$´ Loc

TODO: max

The vector length can also be assigned:

var[] int vec = [ 1, 2, 3 ];
$vec = 1;

The new length must be smaller or equal to the current length, otherwise the assignment raises a runtime error. The space for dynamic vectors shrinks automatically.

Constructor

Vector constructors are only valid in assignments:

Vec_Cons   ::= (Loc | Exp) Vec_Concat { Vec_Concat }
            |  `[´ [LIST(Exp)] `]´ { Vec_Concat }
Vec_Concat ::= `..´ (Exp | Lua_Stmts | `[´ [LIST(Exp)] `]´)

Examples:

var[3] int v;        // declare an empty vector of length 3     (v = [])
v = v .. [8];        // append value '8' to the empty vector    (v = [8])
v = v .. [1] .. [5]; // append values '1' and '5' to the vector (v = [8, 1, 5])

Fields

The operators . and : access public fields of data abstractions, code abstractions, and native structs:

Dot   ::= Loc `.´ (ID_int|ID_nat)
Colon ::= Loc `:´ (ID_int|ID_nat)

The expression e:f is a sugar for (*e).f.

TODO: ID_nat to avoid clashing with Céu keywords.