A tiny expression based language written in Scala using Kiama as a part of a learning exercise on programming language design and development.
Haslite only supports two primitive data types: Integers and Booleans.
Haslite also supports the use of closures/lambda expressions through a Function Type, or FunType for short.
Haslite supports the 4 cornerstones of operators; +
, -
, *
, /
Examples: 2 + 3 * 4
= 14
, 3 * 4 + 2
= 14
, 5 / 4 + 3 * 2 - 5 / 2
= 5
.
Haslite only supports two operators for comparison; ==
and <
Examples: 1 < 2
= true
, 5 < 3
= false
, 1 == 1
= false
.
Note: !=, >, <=, >= are NOT supported!
Variable declaration is performed through the use of the let
expression.
A variable name must be of the form [a-zA-Z][a-zA-Z0-9_]*
and not be a reserved keyword. That is to say, it must start with a character and consist only of letters, numbers and/or underscores.
let
a = 5;
b = a + 1
in
a * b
In the above example two variables are declared, a
and b
, for use in the expression a * b
. The variables are only in scope inside that expression and once evaluated they are lost forever. This means multiple variables can go by the same name, so be cautious of scoping rules when declaring several variables with the same name.
Haslite supports control flows through the use of if
expressions.
Some contrived examples of ways you could use an if
expression:
if(5 < 3) 15 else 90
let
a = 5;
b = 3
in
if(a < b) a else b
let
a = 5;
b = 3
in
if(a + b < 0) 0 else a + b
if(
(let
a = 5;
b = 3;
in
a * b)
<
(let
a = 15;
b = 10;
in
a / b)
)
true
else
false
Haslite supports function declarations through the following syntax:
FUNC_NAME = \ ARG_NAME :: ARG_TYPE -> BODY_EXPRESSION
For example, an increment function:
let
x = 100;
inc = \ a :: Int -> a + 1
in
inc x
let
x = 5;
inc = \ a :: Int -> a + 1;
deinc = \ a :: Int -> a - 1
in
inc deinc inc deinc inc inc deinc inc x
Different programming constructs act at different precident levels (Otherwise nothing would work).
From lowest to highest:
if
<
and==
+
and-
*
and/
- All others (
let
,=
, etc.)
All arithmetic is left associative, meaning when dealing with operators of the same precedence they are grouped left-most first. For example 1 + 1 + 1
secretly becomes (1 + 1) + 1
behind the scenes.
All relational operators are non-associative, meaning that you cannot operate on any more than two operands in a single instance. a == b == c
will NOT work, as can be said for a < b < c
or any such amalgam. The only way to perform these operations is two a time, eg. a == b
.