A simple demo language that builds upon FE.
USAGE:
let [-?|-h|--help] [-v|--version] [-d|--dump] [-e|--eval] [<file>]
Display usage information.
OPTIONS, ARGUMENTS:
-?, -h, --help
-v, --version Display version info and exit.
-d, --dump Dumps the let program again.
-e, --eval Evaluate the let program.
<file> Input file.
Use "-" as <file> to output to stdout.
If you have a GitHub account setup with SSH, just do this:
git clone --recurse-submodules [email protected]:leissa/let.git
Otherwise, clone via HTTPS:
git clone --recurse-submodules https://github.com/leissa/let.git
Then, build with:
cd let
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j $(nproc)
For a Release
build simply use -DCMAKE_BUILD_TYPE=Release
.
Invoke the interpreter like so:
./build/bin/let test/test.let -e
p = s ... s EOF (* program *)
;
s = ';' (* empty statement *)
| 'let' ID '=' e ';' (* let statement *)
| 'print' e ';' (* print statement *)
;
e = LIT (* literal expression *)
| ID (* identifier expression *)
| '(' e ')' (* parenthesized expression *)
| OP1 e (* unary expression *)
| e OP2 e (* binary expression *)
;
where
LIT
= [0
-9
]+ID
= [a
-zA
-Z
][a
-zA
-Z0
-9
]*OP1
is one of:+
,-
OP2
is one of:*
,+
,-
,/
In addition, Let supports
/* C-style */
and// C++-sytle
comments.
For the sake of the demo, Let is case-insensitive.
Ambiguities in the expression productions are resolved according to the operator precedence that is summarized in the following table (strongest binding first):
Operator | Description |
---|---|
+e , -e |
unary plus, unary minus |
* , / |
multiplication, division |
+ , - |
addition, subtraction |
All binary operators are left associative.
All calculations use 64-bit unsigned integer wrap-around arithmetic. Division by zero yields zero.