Cppx Gold Tutorial - lock3/cppx GitHub Wiki

Basics

Usyntax can be used as a language with significant whitespace, or C-style braces. Semicolons are optional.

if(1):
  1                      # semicolon left off
else:
  0;                     # semicolon used
if(1) {
  1;
} else {
  0;
}

We can declare variables with an automatically deduced type or an explicit type. If we do not initialize the deduced-type variable, it will be deduced upon initialization.

Note that we explicitly type a variable with the : operator.

y : int                 # y has int type
x = 3.14                # x deduces to type double

We can apply the same logic to functions and function parameters. Functions can have an automatically deduced return type, or an explicit return type.

Functions are defined using the ! operator.

f(x:int):int!            # f takes an int parameter and returns an int.
  returns x

g(z)!                    # g will have the return type that is the type of
  returns z              # of parameter z.

Note that we must give some sort of hint to the compiler that we are declaring something. For example, introducing a name with no type and no initializer will yield an error.

main() : int!
  x      # error: x has not been declared!

Macros

Usyntax operates on chainable macros that follow the form [keyword] { block }. There are some reserved macros such as if, else, for, and while, but macros can have user-defined keywords as well.

If Macro

There are a variety of different ways to write a conditional macro:

if (x < 10) {
  do_something();
}
if (x < 10):
  do_something();

We can use the then operator to create a single-line conditional statement with no braces.

if (x < 10) then do_something();

Or we can use a "block condition" followed by a "then block" to evaluate multiple conditions followed by an executable block.

if:
      x < 10
      x > 5
then:
      do_something();

or with braces:

if {
      x < 10
      x > 5
} then {
      do_something();
}

This is semantically equivalent to:

if ((x < 10) && (x > 5)):
  do_something()

For Macro

For loops have a language-defined macro syntax. The variations on for macros are quite similar to conditional macros.

Examples:

For macros are similar to the for-range statement in C++, or for-each statements in many scripting languages. The loop-variable is declared to the left the in operator. Like any declaration, it can be explicitly or implicitly typed. If it is implicitly typed, it will be given the type of each element in the range. By extension, that means that all elements in a range must have the same type.

In the following example, we use the .. operator to create a sequence of integers from 0 to 99 and loop through that sequence. In other words, we call the function do_something() 100 times.

for (x in 0..99) {
  do_something();
}

We call use the do operator to create a one-line for macro.

for (x : 0..99) do do_something()

And we can also create a block-style for macro, just like we did with if macros. Note that we can only include one range in the for condition.

for:
      x : 0..99
      y = x * x
do:
      do_something(y)

Semantically, this is equivalent to the following:

for:
      x : 0..99
do:
      y = x * x
      do_something(y)

Functions

Here we can look at the different ways of declaring a function.

The standard inline definition was mentioned above: it uses the exclamation operator:

f()!
  # definiton

We can define one line functions as well by using the equals operator.

f(x:int, y:int) = (x * x) + (y * y)

In the above function, we can consolidate the types of the parameters:

f(x & y : int) = (x * x) + (y * y)

We can also declare a function abstract and define it later. This function takes two int parameters and returns an int:

f(x:int, y:int):int

When we declare abstracts, we can leave off names and just use types. The above abstract would look like this:

f(:int, :int):int

Comments

There are several forms of comments.

The simple line comment is used with the octothorpe (#) character.

x : int = 0;       # I am a comment!

The indented comment form "<#>" enables commenting or uncommenting an entire indented block by preceding it with "<#>".

<#>
    This is a comment,
    and so is this
# but now we're back to normal

There are also block comments enclosed by <# comment tags #>

x : int = 0;      <\# I am a block
                        comment \#>