The sources of argentum programming language are organized in modules.
Modules are text files with extension ag
residing in the same directory. They are always in UTF-8 encoding.
On compiler invocation one of modules is passed to it as a starting module. This module contains application specific classes and functions, entry point and the list of all used modules.
Example:
using string; // 1
using sys { log, String, StrBuilder } // 2
class Point { // 3
x = 0; // 4
y = 1;
}
fn square(a int) int { // 5
a * a // 6
}
fn itos(val int) String {
StrBuilder.putInt(val).toStr() // 7
}
p = Point; // 8
p.x := 3; // 9
p.y += p.x; // 10
log(itos(square(p.x + p.y))) // 11
This example contains:
- Module usage and name import declarations
- Class and functions declarations
- Main application code.
Module usage and name import declarations
- Line {1} declares a dependency on the
string
module. This module contains multiple string utilities that are now accessible to our code by names starting withstring_*
. - Line {2} does the same for the
sys
module. But there is more here. If we list names in curly braces, all these names from that module will be accessible in our module by short name. So we not only declared dependency on thesys
module, we also imported aStrBuilder
class out of it. Technically speaking we don't have to add dependency onsys
module because it's a built-in one, it's accessible anyway. We are doing so here just to import theString
andStrBuilder
classes to make them accessible by short names i.e.String
instead ofsys_String
.
Class and functions declarations
- Line {3} is a class declaration. Our class has no methods. But it has two integer fields
x
andy
{4} that have initial values 0 and 1 respectively. - Line {5} defines a function that takes an integer argument and produces an integer result. Function body is a sequence of expression separated with ";". If the last expression in the sequence also has the trailing ";", the function result will be
void
. Otherwise this last expression produces the result of the function. Our function in line {6} consists of just one expression of typeint
, it has no trailing';'
that makes the function return value ofa*a
expression. - Line {6} defines another function, that converts
int
toString
. In Line {7} we create aStrBuilder
instance, call its methodputInt
(this method returnsthis
-object), and call itstoStr
method that creates aString
out of theStrBuilder
. Alternatively string interpolation can be used (which in turn is just a syntax sugar around the StrBuilder object). This statemen would look like:
fn itos(int val) String { "{val}"}
Main application code
- The main application code starts at line {8}, because it's the first line that does not contain class or function definitions. This line is a declaration of the local variable
'p'
of typePoint
initialized with a newly createdPoint
instance. - Line {9} is the assignment to the object field. The assignment operator has classic ":=" form. Why not "="?
- Because it's mathematically incorrect to use equality operator to connect not equal operands.
- Because the ":=" operator is aligned with all other data modification operators ("+=", "<<=", "&=" etc.)
- Because the "a=b" syntax is already used for local variable declarations (where it is mathematically correct).
- The ":=" operator is a data mutation operator, and since all data mutations is a dangerous action (like
goto
), they need special attention. It's good to give it a special unique symbol, not overloaded by other meanings. - It is a widespread practice among both experienced and novice programmers to repurpose a variable by assigning new, loosely related values to it, instead of creating a new variable. In order to combat this habit, Argentum has introduced a syntax that makes it easier to create a new variable rather than reassigning an existing one.
- Line {10} demonstrates another mutation operator combined with access to the object fields.
- Line {11} combines multiple function calls.