Introduction to Asa

Important

This page is very much still a work in progress

Asa is a systems programming language built to be used similarly to C++, but be a good replacement. It aims to improve upon many of the shortcomings of that aging language, without sacrificing performance.

main :: (){
    printl("Hello World!");
}

The Compile Time Define Operator

One of the operators you will be using most often in Asa is the compile time define. This is defined as the double colon, ::. It shares many of the characteristics of the set operator (=), and sometimes their functionality even overlaps. It can also be compared to the #define preprocessor keyword from C or C++, although Asa does not have a preprocessor.

Compile time define is used to assign an expression to a name. The most basic example would be:

x :: 5;
Note

This code will evaluate to the exact same as x = 5;

Of course, more interesting expressions are better. Let's put a lambda expression on the right side:

x :: int(){ return 5 }

Now this is a function.

Other uses

:: can be used for defining other things as well, such as structs, modules, and special functions.

Defining Structs

You can create a struct by writing the name, and defining it as a struct expression:

someStruct :: struct{

}

Defining Modules

You can define a module by writing the name, and defining it as a module expression:

moduleName :: module{

}

Structs

You can create a struct by writing the name, and defining it as a struct expression:

someStruct :: struct{
    // ...
}

Then to create an instance:

y : someStruct = someStruct();

Struct Members

Member variables and functions are defined as normal. Functions, though, have slightly different behavior. For example:

someStruct :: struct{

    x : int = 10;

    memberFunction :: (v : int){
        this.x = v;
    }
}

The difference with functions defined inside of a struct is that they can only be called with the access operator (.), but they can also access members within the struct itself. To do this, you must use the this keyword, which references the instance the function is within. Then member access is as normal:

s : someStruct = someStruct();

printl(s.x); // -> 10

s.memberFunction(3);

printl(s.x); // -> 3

Struct Specific Functions

There are some functions that have specific names and functionality for handling structs.

create

create :: someStruct(){
    // ...
}

Modules

You can define a module by writing the name, and defining it as a module expression:

moduleName :: module{

}

Modules can have sub-modules to any depth:

moduleA :: module{
    moduleB :: module{
        moduleC :: module{

        }
    }
}

Accessing

You can use the access operator . to use members of a module.

moduleA :: module{
    moduleB :: module{
        x = 4;
    }
}

Accessing the variable x from outside moduleA would be done like so:

moduleA.moduleB.x = 5;

Expressions

In Asa, most things you write are "expressions". In other words, the individual components should be able to be evaluated all on their own. For example, take the following function:

functionName :: (){
}

Given the above function, we can split it into its sub-expressions:

The name:

functionName

and a lambda:

(){}

The lambda is simply an unnamed function. You can create one with parentheses containing the function arguments, followed by curly braces containing the body. Like: (x : int){}. If you want the lambda to have a return value, it should be preceded by the type. Like: int(x : int){ return x+1; }


Special Function Definitions

Just like in C++, there are some special ways to define functions for certain use cases.

Operator Overloading

Operator overloading is used to override builtin behavior or add new behavior to existing or new symbols. For example:

operator+- :: int(x : int, y : int){
    return x * y;
}

printl(3 +- 1);
// -> Outputs 3

Defining an operator overload is done with the following syntax:

operator<symbol> :: <return type>(<Left value>, <Right value>){
}

The <symbol> can be any ASCII special character, and can be a double character as well. Example: $ or $$. The only symbols you cannot overload are the compile time define :: and a few punctuation symbols. Also, the list of available symbols is predefined, so some combinations may be missing.