AquaScript is a procedural programming language developed for learning about compilers theory. Despite the script term in its name, it is a compiled programming language.
AquaScript is a very simple language that have a tipical definition of C-Like languages. See below the allowed notation:
- Flow controllers
if
,else
andfor
; - Arithmetic operators
+
,-
,*
,/
and%
; - Conditional operators
=
,<
,>
,<=
,>=
and!=
; - Logical operators
and
,or
e!
- Increment
++
and decrement--
operators; - Reserved words
return
,read
,write
,break
andnull
;
AquaScript is a loosely typed language and only handles number
, text
, and bool
types. It is also statically typed, so the values assigned to a variable do not change during program execution. In AquaScript there are no implicit or explicit casting. As the project advances, it is possible that this will be implemented in the future.
The AquaScript syntax was built to be very simple and familiar to the programmers used to other languages. It dispenses with the use of a starting point for the program, making the reading of the program depend on the order in which the statements are made, similar to what happens in scripting languages like JavaScript or Python.
See below the syntax definition in Backus-Naur Form:
program ::= statement*
statement
::= if
| for
| attribuition
| singlinecomment
| multilinecomment
| ( increment | decrement | return | read | write | 'break' ) ';'
if ::= 'if' '(' expression ')' body
for ::= 'for' '(' attribuition? ';' expression? ';' attribuition? ')' body
attribuition
::= 'id' ':' ( function | expression ';' )
singlinecomment
::= '//' [^\n]*
multilinecomment
::= '/*' ( [^*] | '*'+ [^*/] )* '*'* '*/'
increment
::= 'id' '++'
decrement
::= 'id' '--'
return ::= 'return' expression?
read ::= 'read' 'id'
write ::= 'write' expression
function ::= '(' param? ')' body
expression
::= side ( ( '<' | '>' | '<=' | '>=' | '!=' | '=' ) side )? ( ( 'and' | 'or' ) side ( ( '<' | '>' | '<=' | '>=' | '!=' | '=' ) side )? )*
param ::= 'id' ( ',' 'id' )*
body ::= '{' statement* '}'
side ::= term ( ( '+' | '-' ) term )*
term ::= unaryexpr ( ( '*' | '/' | '%' ) unaryexpr )*
unaryexpr
::= ( '+' | '-' )? factor
factor ::= bool
| 'number'
| 'text'
| 'id'
| 'null'
| '(' expression ')'
bool ::= 'true'
| 'false'
See the AquaScript Syntax Diagram generated by definition described above.
Variables in AquaScript are always initialized to some value. The assignment operator is the :
(colon), as if we were seeing the attribute of an object in JavaScript.
a: 3; // a receives the value 3 and is of type number
b: 4.5; // b receives the value 4.5 and is of type number
c: a + b; // c now worth 7.5
d: "Foo";
e: "bar";
f: d + e; // f is of type text and has the value "Foobar";;
g: true; // g is of type bool and is true
h: !g; // h is of type bool and negates g - false
i: g or h; // i is of type bool and is true
Function declarations in AquaScript are done differently from other languages like C or Java. Naming functions is like giving them nicknames through variables, as shown below:
<function_name>: (<parameters>)
{
// body
}
See below some examples.
write "Hello, World!";
say_hello: (name)
{
write "Hello, " + name + "!";
}
say_hello("Petter"); // Output: "Hello, Petter!"
say_hello: (name)
{
return "Hello, " + name + "!";
}
write "Enter a name: ";
read name; // Read an user input
write say_hello(name);
factorial: (x)
{
if (x < 2)
{
return 1;
}
return x * factorial(x - 1);
}
write factorial(5); // Output: 120
the_bigger: (x, y)
{
if (x > y)
{
return x;
}
else
{
return y;
}
}
write the_bigger(5, 6.5); // Output: 6.5
is_prime: (x)
{
count: 0;
for (i: 0; i < x; i++)
{
if (x % i = 0)
{
count++;
if (count > 2)
{
return false;
}
}
}
return true;
}
write is_prime(4); // Output: false
write is_prime(7); // Output: true
So far, the AquaScript compiler even performs the parsing phase of the source code. As a next step, its semantic analyzer will be developed.
For questions or clarifications, send an email to davidsobruno@outlook.com.
MIT Copyright (c) 2018 Davidson Bruno da Silva