Overview
Introduction
Sacalon is a general purpose and open source programming language designed to build optimal, maintainable, reliable, and efficient software. More features of Sacalon :
- Easy to use and easy to learn
- Multi-paradigm
- Null safety by default
- Fast and powerful
- Inspired by Swift, Pascal
- Compiles to C++
- Compatible with C\C++\Obj-C
- Builtin compile time FFI system
- Built-in HTTP Library
Standard Library Documentation
Standard Library Documentation available here.
Contributing
We welcome contributions of all kinds.
You can contribute to this book by opening an issue or forking and sending a pull request to the main Sacalon repository. Knowing what people use this book for the most helps direct our attention to making those sections the best that they can be. We also want the reference to be as normative as possible, so if you see anything that is wrong, please also file an issue.
Installation
Requirements :
- python>=3.7
- gcc>=8(or any c++ compiler that supports c++17)
- libcurl,- libssl,- libcrypt
- git(to clone Sacalon's source code)
*Nix Users(recommended)
You can use the sacalon.sh script to automate the process of installing and adding sacalon to PATH:
git clone https://github.com/sacalon-lang/sacalon.git
cd sacalon/
chmod +x ./sacalon.sh
bash ./sacalon.sh
Windows Users
> git clone https://github.com/sacalon-lang/sacalon.git
> cd sacalon
> make deps-windows
> make windows
Now your Sacalon compiler is ready to use in dist folder, you can add it to $PATH.
NOTE: The latest version of Sacalon should always be used. Old versions have bugs when running binary versions of Sacalon.
Hello World!
Now that you have successfully installed Sacalon, let's write our first program with it. You will write a program that prints Hello World! on the terminal.
Creating a project directory
You can write your Sacalon programs every where but, we suggest that you create a directory for your project.
At first, create a directory in your home directory(or anywhere else):
mkdir hello_world
cd hello_wrold
Writing the code
Next make a new file and name it main.has. Sacalon files should end with .has extension.
Now open your code editor (If you are using vscode install sacalon extension for better coding from this link) and write the following code in main.has :
function main() : int {
    print("Hello World!")
    return 0
}
Save the file, and return to the terminal and enter the following command to build your program :
sacalon main.has
Now run the generated excutable file :
$ ./main
Hello World!
On Windows you should use .\main.exe instead of ./main :
$ .\main.exe
Hello World!
Congratulations - you just wrote and executed your first Sacalon program!
Reviewing the code
Let's review our simple program. Here's the first piece of the program:
function main() : int {
    
}
These lines define a function that returns an integer number. The main function is the entry point of your program and it should always return int(an integer). If there were parameters, they would go inside the parentheses, ().
Also, note that function statements should be in {} and you can write function codes inside {}.
Inside the main function is the following code :
print("Hello World!")
This code print the passed arguments, you can pass more parameters :
print("Hello World!",42,3.14)
After the calling print command, there is the following statement :
return 0
It returns 0 at the end of the function, every function that returns a value(declared with : after () in a function declaration) should return a value corresponding to the type.
Returning the 0 value in main function tell the OS that your program has executed successfully.
Project Manager
Sacalon has a builtin build system and project manager. This tool builds and runs your project, and installs dependencies.
Creating a new project
Let's create a new project and compare it with the Hello World example in previous chapter.
To create a project you should create a directory for your project :
$ mkdir hello_world_2
$ cd hello_world_2
Now we create a new project with following command :
$ sacalon init
After running above command, you’ll see Sacalon has generated two files and one directory for us: a config.json file, a .gitignore file and a src directory with a app.has file inside.
config.json :
{
	"filename": "src/app.has", 
	"outfile": "build/app", 
}
The filename field contains your main file that contains your entry function(main) and outfile field is output path of excutable file.
src/app.has :
function main():int{
	print("Hello World!")
	return 0
}
The generated Sacalon file contains Hello World! program, you can edit it.
Building a project
You can build the project with following command :
$ sacalon build
Excutable file will generate in build directory and you can run it with following command :
$ ./build/app
Running a project
To run the project, you can use run command :
$ sacalon run
Hello World!
That builds excutable file and runs it.
Configure the compiler
You can use config.json file to configure your Sacalon compiler.
The following configuration options are available:
- filename: your main file name, if you set it, you will no longer need to pass the file name to the compiler.
- compiler: your c++ compiler name(e.g :- g++,- clang++)
- optimize: optimize level(0,1,2,3)(default : no optimize, e.g:- -O2)
- flags: custom flags(e.g:- ["-pthread"])
- c++_version: your c++ standard(e.g:- c++17or- c++20),note: c++ version must be greater than or equal to c++17 and compiler must support c++17
- compiler_output: if you want to see c++ compiler output, set this to- true
- c++_out: if you want to see generated c++ code, set this to- true, the generated c++ code are in- your_filename.ccfil.
- only_compileif you want only to compile and not link program, set this to- true.
- no_std: if it is true, the runtime library will not link with your code(you will not be able to use builtin functions).
Write a guessing game
TODO
Comments
Comments are used to document code and to explain what the code does, they are not executed.
// This is a single line comment
/*
This is a multi-line comment
This is a multi-line comment
*/
Primitive types
The following types are primitive:
bool // boolean value
string // string literal
int8 uint8 // 8-bit integer
int16 uint16 // 16-bit integer
int int32 uint32 // 32-bit integer
int64 uint64 // 64-bit integer
float // floating point 
double // double floating point
Variables
A variable is a named storage for a value. Variables are declared using the var keyword :
var foo : int = 1
Also you can declare a variable without type, in this case, the type will be inferred by the value assigned to it:
var foo = 1
Non nullable and nullable
Null safety is a feature that allows you to declare that a variable can be null or not null, and Sacalon uses this feature to make sure that your code is safe.
Sacalon's variables and constants are non-nullable by default that means that they cannot be null(NULL) and you can't assign NULL to them and you should assign a value to them when you declare them.
var foo : int = 1 // non-nullable
var foo_error : int // error : nullable variable must be assigned a value
But you can make variables and constants nullable by adding ? to their type:
var bar : int? = 1 // nullable
so you can use NULL to set a variable to null :
bar = NULL // ok
Pointers
Pointers are a way to access the memory address of a variable. You can declare a pointer using the ^ operator after the type:
var foo : int^?
NOTE: pointers are non-nullable by default, use ? to make it nullable:
You use cast to assign a value to a pointer:
foo = (int^)1
Finally, you can use the ^ operator to access the value stored in a pointer:
var foo : int^ = (int^)1
print(^foo) // 1
NOTE: We recommend you to always allocate pointers with new keyword and deallocate with delete keyword, for more information go to Memory management chapter.
NOTE: Currently only one level of pointers are supported.
Static variables
Static variables are variables that are declared outside of a function and are accessible from anywhere in the program.
Static variables are declared using the static keyword before the type:
var foo : static int = 1
Numbers
Numbers are either integers or floating point numbers. You can declare a number using the following types:
int8 uint8 // 8-bit integer
int16 uint16 // 16-bit integer
int int32 uint32 // 32-bit integer
int64 uint64 // 64-bit integer
float // floating point 
double // double floating point
So you can use the following operators to perform arithmetic operations:
- +: addition
- -: subtraction
- *: multiplication
- /: division
See the following example:
var a : int = 123
var b : float = 1.23
var c : double = 1.2313213215648789798
Strings
Strings are a sequence of characters. You can declare a string using the string keyword:
var foo : string = "Hello World"
You can use the + operator to concatenate strings:
var foo : string = "Hello" + " World"
And you can use the [] operator to access a character in a string:
var foo : string = "Hello"
print(foo[1]) // 'e'
Note: type of accessed character is
charNote: the first character in a string is at index 0.
With len function you can get the length of a string:
var foo : string = "Hello"
print(len(foo)) // 5
Note:
lenfunction is a built-in function.
Escape sequences
You can use escape sequences to print special characters:
var foo : string = "Hello\tWorld"
print(foo) // Hello    World
The following escape sequences are supported:
- \n: newline
- \t: tab
- \r: carriage return
- \\: backslash
- \': single quote
- \": double quote
- \?: question mark
- \a: bell
- \b: backspace
- \f: form feed
- \v: vertical tab
- \0: null character
- \x____: hexadecimal character
- \u____: unicode character
- \U____: unicode character
- \_____: arbitrary octal value
Note: _____ means you should specify the id of the character you want to print.
Reverse a string
You can reverse a string by using the string_reverse function in the strings package:
use strings
function main() {
    var foo : string = "Hello World"
    print(string_reverse(foo)) // dlroW olleH
}Arrays
Arrays are collections of data elements of the same type. They can be represented by a list of elements surrounded by brackets. The elements can be accessed by appending an index (starting with 0) in brackets to the array variable:
Arrays declare like following:
var foo : [int] = [1,2,3]
var bar : [string] = ["Hello", "World"]
You can use the [] operator to access an element in an array:
var foo : [int] = [1,2,3]
print(foo[1]) // 2
And you can assign a value to an array element:
var foo : [int] = [1,2,3]
foo[1] = 4
print(foo[1]) // 4
With append built-in function you can append an element to an array:
var foo : [int] = [1,2,3]
foo.append(4)
print(foo[3]) // 4
And you can get the length of an array with the len built-in function:
var foo : [int] = [1,2,3]
print(len(foo)) // 3
Type compatibility
Type compatibility is very close to automatic or implicit type conversion. The type compatibility is being able to use two types together without modification and being able to subsititute one for the other without modification.
Compatible types are:
- int(and its subtypes like- uint8,etc) and- float.
- int(and its subtypes like- uint8,etc) and- double.
- floatand- double
Note: strings are not compatible with characters.
Conditional statements
Conditional statements are used to execute a block of code if a condition is true or false.
If
You can use the if keyword to execute a block of code, if a condition is true:
var foo : int = 1
if foo == 1 {
    print("foo is 1")
}
Else
You can use the else keyword to execute a block of code, if a condition is false:
var foo : int = 1
if foo == 1 {
    print("foo is 1")
} else {
    print("foo is not 1")
}
Else if
You can use the else if statement to execute a block of code, if else if a condition is true:
var foo : int = 1
if foo == 1 {
    print("foo is 1")
} else if foo == 2 {
    print("foo is 2")
} else {
    print("foo is not 1 or 2")
}
and and or and not
You can use the and keyword to execute a block of code, if all conditions are true:
var foo : int = 1
var bar : int = 2
if foo == 1 and bar == 2 {
    print("foo is 1 and bar is 2")
}
You can use the or keyword to execute a block of code, if at least one condition is true:
var foo : int = 1
var bar : int = 2
if foo == 1 or bar == 2 {
    print("foo is 1 or bar is 2")
}
You can use the not keyword to execute a block of code, if a condition is false:
var foo : int = 1
if not foo == 1 {
    print("foo is not 1")
}
Conditional Operators
| Operator | Description | Example | 
|---|---|---|
| == | Returns true if the operands are equal. | var1 == var2 | 
| != | Returns true if the operands are not equal. | var1 != var2 | 
| > | Returns true if the left operand is greater than the right operand. | var1 > var2 | 
| >= | Returns true if the left operand is greater than or equal to the right operand. | var1 >= var2 | 
| < | Returns true if the left operand is less than the right operand. | var1 < var2 | 
| <= | Returns true if the left operand is less than or equal to the right operand. | var1 <= var2 | 
| and | Returns true if the left operand and right operand are true | var1 == 1 and var2 == 2 | 
| or | Returns true if the left operand or right operand are true | var1 == 1 or var2 == 2 | 
| not | Returns true if the operand are false or if the operand is true returns false | not true | 
Loops
You can use the while keyword to execute a block of code, if a condition is true:
var foo : int = 1
while foo == 1 {
    print("foo is 1")
    foo = 2
}
The for keyword is used to execute a block of code for a number of times:
for i in range(0, 10) {
    print(i)
}
Also you can use the for keyword for iterating over an array:
var foo : [int] = [1,2,3]
for i in foo {
    print(i)
}
Functions
Functions are a way to group code that can be called to perform a specific task. You can declare a function using the function keyword:
function foo() {
    print("Hello World")
}
Also your function block should be outside of a function.
Your function can have parameters and return a value. You can declare parameters and return type, like variable declarations:
function add(x:int,y:int): int {
    return x + y
}
In the example above, x and y are parameters and their type(int) is your return type.
Note: you can use
?to make a parameter nullable.
Calling a function
You can call a function by using the function name followed by parentheses:
foo()
If you want to pass some arguments to your function, you can use them in the parentheses(separate with ,):
foo(1,2,3)
Also you can assign the return value of a function to a variable:
var foo : int = add(1,2)
Function overloading
You can overload functions by defining a new function and changing the number of parameters or the type of parameters or return type of function :
function add(x:int,y:int,z:int): int {
    return x + y + z
}
// overloading function `add`
function add(x:int,y:int){
    print(x + y)
}
function main(): int {
    print(add(1,2))
    print(add(1,2,3))
}
Passing function as parameter
To passing a function as parameter you should define a parameter in with Function type with following syntax :
Function[<function_parameter1_type>,<function_parameter2_type>,...]<return_type>
For example :
function foo(func: Function[float, int]int) : int{
    
}
At above we defined a function with name foo that takes a function as its parameter and given function should has  two parameters with types float and int(respectively) and it should returns int.
Also we can call given function like other functions, change the foo function code to following code :
function foo(func: Function[float, int]int){
    print(func(1.0,2))
}
Now we define a function to pass to foo func and must have the properties specified in the foo function(two parameters with types int and float and int as return type):
function bar(a:float, b:int) : int {
    print("Hello from bar function!")
    return a + b
}
Now we can pass bar function to foo function as parameter :
foo(bar)
Output :
Hello from bar function!
3
Function decorators
Decorator is a way to add some properties to a function and it is used with @ character + decorator name before function declaration.
List of available decorators in Sacalon :
| Decorator       | Description  |
| :------------- | :----------: |
|  @static_function | Makes function static  | 
| @extern  | Externs function(like extern in C++) |
Importing & Creating modules
A module is a package of code that can be imported into another module to use its code.
Importing a module
You can use other modules by importing them. You can import a module by using the use keyword:
use os
function main() : int {
   system("start http://www.google.com")
   return 0
}
Importing multiple modules
You can import multiple modules by using the use keyword and separating the module names with a comma:
use os, math, conv
For importing a submodule of a module, you can use the . operator:
use crypto.sha256
Creating a module
For creating a module, you can create a file with the same name as the module and with the extension .has and put the module code inside it:
add.has:
function add(x:int, y:int) : int {
    return x + y
}
main.has:
use add
function main() : int {
    print(add(1,2))
    return 0
}
Creating foldered modules
Module files can be placed in a folder, for creating a foldered module you should first create the folder and then create the _.has file inside it.
The _.has file is the main file of the module and compiler will look for it.
You can also import submodules in _.has file.
Note: Any submodule that is not imported in
_.hasfile will be ignored. Note: Any submodule can have other submodules.
Structures
Structures are a way to group data together. You can declare a structure using the struct keyword:
struct Color {
    var r : int
    var g : int
    var b : int
    var name = "Anything..." // optional
}
Note: Declaring a structure member without a type will make it optional.
After declaring a structure, you can create an instance of it:
var red = Color(255,0,0)
For accessing the fields of a structure, you should use the . operator:
var red = Color(255,0,0)
print(red.r)
print(red.g)
print(red.b)
print(red.name)
Structures as return values
You can return a structure from a function:
function foo() : Color {
    return Color(1,2,3)
}
Structures as arguments
You can pass a structure as an argument to a function:
function foo(c:Color) {
    print(c.r)
    print(c.g)
    print(c.b)
    print(c.name)
}
Structure inheritance
You can inherit a structure from another structure with : operator after the structure name:
struct RGB : Color {
    
}
And you can access the fields of the inherited structure:
var foo : RGB = RGB(1,2,3)
print(foo.r,foo.g,foo.b)
   
var bar = RGB(255,0,0,"AColor")
Memory management
Memory management is a way to manage the memory of your program. Sacalon use manual memory management because it is used in most performance-critical applications like games,OSes, embedded systems, etc.
Sacalon uses new and delete keywords to manage memory manually.
Allocation
For allocating memory, you should use the new keyword. Note that type of the allocated memory should be pointer or reference type and passed type to new keyword should be a 
var foo : int^ = new int(1) // allocating
For easily declaring and allocating memory, use var <name> = new <type>(<args...>) statement, like this:
var foo = new int(1)
Reallocation
For reallocating memory and assigning the new value to the pointer, use <pointer> = new <type>(<args...>) statement, like this:
var foo : int^ = new int(1) // allocate memory
foo = new int(2) // reallocate memory and assign new value
Deallocation
For deallocating memory, you should use the delete keyword and pass the pointer to the memory that you want to deallocate:
delete foo
Accessing memory
Like pointer types, you can access the allocated memory value with the ^ operator:
var foo : int^ = new int(1)
print(^foo)
Critical notes
- Don't forget to use the deletekeyword at end of scope and before the end of the program..
In future, we will add a feature to show warnings when you forget to use the
deletekeyword.
- 
You can't deallocate memory that you haven't allocated it without newkeyword.
- 
You can allocate, not allocated pointers: 
var foo : int^?
foo = new int(1)
Interfacing with C++
Sacalon is based on C++, so you can use C++ functions and classes in your program.
Inline C++ Code
You can use inline c++ code in Sacalon with cuse keyword :
cuse '#include <cstdio>'
cuse 'int main(){printf("%d",1);return 0;}'
// output : 1
Or you can use multiline c++ code, like following example:
cuse """
#include <cstdio>
int main(){
    printf("%d",1);
    return 0;
}
"""
Externing functions
For using C++ functions in your program, you should at first declare them with following syntax:
function <name>(<args...>) : <return type>
Example :
function system(command:char^):int
Include C++ headers
Also Sacalon can include C++ headers in your program.
We need two files, one for headers and one for main part of the library. You should put #include,... in your_cpp_lib.hpp and main part of library in your_cpp_lib.cc. The specified files should exist in the same folder.
See the example below:
add.cc :
void __sacalon__cpp_print(int x){
    printf("%d",x);
}
add
__sacalon__to your C++ functions, structs name. Sacalon transpiles to C++ and it adds__sacalon__prefix to your C++ names.
add.hpp :
#include <cstdio>
main.has :
cuse add 
function cpp_print(x:int)
function main() : int {
    cpp_print(12)
    return 0
}
Also you can put the C++ files in a folder and rename they to _.cc and _.hpp.
Note that don't include local headers in *.hpp file.
Accessing to values and types in inline C++ code
You can access to Sacalon's variable and types in inline C++ codes in Sacalon by adding __sacalon__ prefix to a name, for example:
main.has:
function add(a:int,b:int){
    cuse """
        std::cout << a + b;
    """
}
you can return a value in inline C++ codes by returning a meaningless value with same type as return type of the function(it may be ridiculous, we are currently working to improve it):
function add(a:int,b:int){
    cuse """
        return a + b;
    """
    return 0 // return a value with same type as return type of the function
}
Standard Library Documentation
To read Sacalon's stdlib go to this link.
Package Manager
Sacalon has a built-in package manager that allows you to install packages from the a git repository.
Installing a package
To get and install a package, you can use the get command :
sacalon get <git url> <package name>
- <git url>is the url of the git repository
- <package name>is the name of the package(optional, recommended, default is the url)
Note: If you don't specify the package name, you should import it like this :
use github.com.foo.bar
Updating a package
To update a package, you can use the update command :
sacalon update <package name ot git url>
Listing packages
To list all packages, you can use the list command :
sacalon list
if you want to list all subpackages of a package, you can use the list command with name of the package :
sacalon list <package name>
- <package name>is the name of the package you want to list subpackages
For example :
$ sacalon list crypto
list of all subpackages in crypto :
- sha256
IDE Integration
Sacalon's Roadmap
Language
- js backend
- lambdas :
var mythread = thread(function(x:int,y:int){
    print(x*y)
})
- generate html doc from a code
- classes
class C : T {
    var foo : string
    var bar = 1
    // constructor
    C(foo: string){
        this.foo = foo
    }
    public f(x: string): string {
        return x
    }
    private f2(x: string): string {
        return x
    }
    // allocator
    __new__(foo: string): C {
        return new C(foo)
    }
    // deallocator
    __delete__(foo: string): C {
        delete this.foo
        delete this.bar
    }
}
- generics #26s
- rewrite compiler in sacalon
- const correctness
Standard Library
- threadlibrary
Package Manager
Sacalon's Changelog
v1.4.0
New features
- add builtin range function
function main(): int {
    // prints 1 to 10
    for i in range(1,11){
        print(i)
    }
    return 0
}
- add asin,acos,asinh,acosh,exp,frexpr,ldexp,log,log10,fdim,sqrt,ceil,floor,NaN,max,minfunctions tomathlibrary, see documentation.
- Showing error for overloading function's return type.
Changes
- Speedup parsing and compiling
Bug fixes
- fix passing list to for instatement
Removed
v1.3.12
New features
- add support for multiline C-style comment
- add roundfunction tomathlibrary
Changes
- Sacalon relicensed from MIT license to BSD-3-Clause license
Bug fixes
- fix string subscripting bug
- fix empty list parsing bug
- fix random library bugs
Removed
v1.3.11
New features
- add uniform distribution based random number generator called uniforminrandomlibrary
Changes
- change staticdecorator name tostatic_functionname
- rename timesfunction tomultipliesinfunctionallibrary
- rename if_and,if_or,if_notfunctions to_and,_or,_notinfunctionallibrary
Bug fixes
- fix package manager bug
Removed
v1.3.10
New features
- show error for undeleted variables from heap
Changes
- improve math,oslibrary
- in functionallibrary : changelessThanOrEqualtolessThanEqual,greaterThanOrEqualtogreaterThanEqual
- improve error handler for conditions
- pytestbased test runner(@mmdbalkhi)
- fix conflicting with C\C++\Obj-C in FFI features
- change staticdecorator name tostatic_functionname
Bug fixes
- fix mathlibrary bug
- fix import package bug with _.*name
- fix crypto.sha256library bug
Removed
- remove libtccfrom stdlib
v1.3.9x
v1.3.9
New features
- add sacalon listcommand to list all available packages
- add sacalon initcommand to create a new project, that generatesconfig.json,.gitignoreandsrc/app.hasfiles
- add sacalon buildcommand to build project
- add sacalon runcommand to run project
- add string_reverse(str:string)function tostringsmodule
- add assertfunction to runtime library
- add no_stdcompiler option
- add filenameconfig option
Changes
- change emitting std::stringfor strings tostring(because in showing assertion errors,std::stringis illusory).
- use sys.exitinstead ofexitinsrc/core/h_help.py(@mmdbalkhi)
- fix importing system bugs
- improve typeofbuiltin function
Bug fixes
- fix assigning NULLto arrays and pointers bug, #36.
- fix check_g++config option bugs
- fix not defined consts when importing packages
- fix randomlibrary bug
- fix browserlibrary bug
Removed
- remove windows,browserlibraries
v1.3.9-rc.1
Changes
- upgrade importing system
- some changes in self hosted compiler(NOTE: self hosted compiler is not ready yet)
Bug fixes
- fix import bug when importing one package in multiple files
- fix self hosted bugs
v1.3.9-beta
New features
- passing functions as arguments
function f(x: int): int {
    return x + 1
}
function g(func:Function[int]int): int {
    return func(1)
}
- add static variables, See this example
- add only_compileconfig option
Changes
- upgrade importing system
Bug fixes
- fix pyinstaller build issue
Removed
v1.3.8
New features
- non-nullable and nullable variables
Changes
- change pointer unary from *to^
- improve importing system
Bug fixes
- fix repetitious imports bug
- fix #29 bug(by @mmdbalkhi)
Removed
- remove tokenlibrary
v1.3.7
New features
- manual memory management with newanddeletekeyword
- functional programming paradigm
- speed up compilation time
- add typeoffunction
- now can print arrays and structures
- function decorators
- staticand- externdecorator
- multiple library import
- improve importing system
- improve stdlib architecture
Bug fixes
- fix scoping bug
- fix convlibrary bug
- fix conditions bug
Removed
- exportlibrary removed
- local usestatement removed
v1.3.6
New features
- more data types : int8,uint8,int16,uint16,int32,uint32,int64,uint64,double
- type compatibility
- multi line string
- pointers and references
var x : *int = 20
var y : int = 10
x = &y
var z = *x // type : int
// Pointers fix incomplete types on struct defination
struct bar {
    var self : *bar
}
- add sizeoffunction
Bug fixes
- fix lexer bugs
- check if function returns a value at end of string else show error
- mainfunction should returns int
- fix termcolorlibrary bugs
- fix enum bugs
Standart library
- add sdl2wrapper
- add exportlibrary for exporting to C(see : haspy)
- add crypto.sha256for sha256 hashing
Removed
- libcinfolibrary removed
v1.3.5
Standard library
Updated
os :
- add compiler_namefunction to get the name of the compiler
- add archfunction to get the architecture of the system
- add is_x86function to check if the architecture is x86
- add is_x64function to check if the architecture is x64
- add getenvfunction to get an environment variable
Added
- add libcinfolibrary to get information about the libc
- add termcolorlibrary to colorize the output

Bug fixes
- Fix incomplete type defination bug
v1.3.4
New features
- compiler option : now can generate c++ code from sacalon code with c++_code : 1inconfig.jsonfile
- use cusekeyword to include c++ files.
Bug fixes
- Fix semantic analyser bugs
- Fix standard library bug
v1.3.3
New features
- struct inheritance
- can use cusestatement on struct declaration
Bug fixes
- Fix variable scope bug
- Fix variable declaration bug
- Fix semantic analyser bug
v1.3.2
New features
- for instatement
- library manager
- flag option
- cusestatement
Bug fixes
- Fix semantic analyser bugs
- Fix nested struct bug
Removed
- for toand- for downtostatement removed