Next saas-starter
⚡️ Free Next.js responsive landing page template for SaaS products made using JAMStack architecture.
Small programming language and interpreter that supports fundamental programming concepts. Inspiration is heavily taken from the BASIC language and it is written in TypeScript
Lemo is a programming language and interpreter, which I developed during the Summer Holidays of 2021
Motivation for developing was pure interest/curiosity in learning how programming languages work under the hood
The design of the language is heavily inspired by BASIC and the language it is written in is TypeScript
Author: Artem Moshnin
Resources used: Gabriele Tomassetti's blog entries with numerous useful resources (Books & Articles)
Programming language supports various fundamental programming concepts such as variable-declaration, function calling, conditional statements, for and while loops, proper order of operations, recursion and much more.
The language also includes the following built-in datatypes: Integers, Floats, Strings, Lists.
Each datatype also has its own methods implemented that can be called on instances of these datatypes.
The language also includes the following built-in global functions: print(), input(), clear().
The language also includes a type-checking system.
Multi-line support is integrated, as well as the ability to run external files of '.lemo' format.
Below is the language's EBNF-based grammar, and following that are some examples of programs that the language can run. Even further down is a link to a repl.it where the programs can be run.
Parser builds up a syntax tree of the program from the tokens created by the Lexer. The parses has to figure out if the tokens match out language grammar. If it does, generate a tree accordingly. For example: "200 200 +" makes no sense in our language. While "123 + 456" makes perfect sense.
In other words, order of operations are being followed and the parses construct the syntax tree accordingly to meet its requirements, as illustrated below:
To understand the source code of the parser, I below illustrated the grammar of a mathematical expression that is being analyzed while parsing to ensure that the order of operations are followed:
The role of the interpreter is to traverse through the AST (Abstract Syntax Tree) that the parser builds, look for different node types and determine what code should be executed. For example, if it comes across a binary operation node with a '+' operator - it will add its left and right child nodes together. The AST (Abstract Syntax Tree) will allow the interpreter to follow the order of operations correctly.
>> Comparison Operators: =, !=, <, >, <=, >=
>> Logical Operators: and, or, not
- Example of Logical Operators:
- 5 == 5 and 6 == 6 => 1
- 1 + 1 == 2 or 2 + 2 == 5 => 1
>> Booleans: 0 = FALSE, 1 = TRUE
-> Grammar (EBNF-based) of the Lemo-Programming Language <-
statements : NEWLINE* statement (NEWLINE+ statement)* NEWLINE\*
statement : KEYWORD:RETURN expr?
: KEYWORD:CONTINUE
: KEYWORD:BREAK
: expr
expr : KEYWORD:VAR IDENTIFIER EQ expr
: comp-expr ((KEYWORD:AND|KEYWORD:OR) comp-expr)\*
comp-expr : NOT comp-expr
: arith-expr ((EE|LT|GT|LTE|GTE) arith-expr)\*
arith-expr : term ((PLUS|MINUS) term)\*
term : factor ((MUL|DIV) factor)\*
factor : (PLUS|MINUS) factor
: power
power : call (POW factor)\*
call : atom (LPAREN (expr (COMMA expr)\*)? RPAREN)?
atom : INT|FLOAT|STRING|IDENTIFIER
: LPAREN expr RPAREN
: list-expr
: if-expr
: for-expr
: while-expr
: func-def
list-expr : LSQUARE (expr (COMMA expr)\*)? RSQUARE
if-expr : KEYWORD:IF expr KEYWORD:THEN
(statement if-expr-b|if-expr-c?)
| (NEWLINE statements KEYWORD:END|if-expr-b|if-expr-c)
if-expr-b : KEYWORD:ELIF expr KEYWORD:THEN
(statement if-expr-b|if-expr-c?)
| (NEWLINE statements KEYWORD:END|if-expr-b|if-expr-c)
if-expr-c : KEYWORD:ELSE
statement
| (NEWLINE statements KEYWORD:END)
for-expr : KEYWORD:FOR IDENTIFIER EQ expr KEYWORD:TO expr
(KEYWORD:STEP expr)? KEYWORD:THEN
statement
| (NEWLINE statements KEYWORD:END)
while-expr : KEYWORD:WHILE expr KEYWORD:THEN
statement
| (NEWLINE statements KEYWORD:END)
func-def : KEYWORD:FUN IDENTIFIER?
LPAREN (IDENTIFIER (COMMA IDENTIFIER)\*)? RPAREN
(ARROW expr)
| (NEWLINE statements KEYWORD:END)
PRINT(NULL) // 0
PRINT(FALSE) // 0
PRINT(TRUE) // 1
PRINT(MATH_PI) // 3.141592653589793
// > General functins < //
'PRINT' =>
PRINT("Hello World") // Hello World
// > Check if is corresponding type < //
'IS_NUMBER' =>
IS_NUMBER(123) // 1
IS_NUMBER("Hello") // 0
'IS_STRING' =>
IS_STRING("Hello") // 1
IS_STRING(123) // 0
'IS_LIST' =>
IS_LIST([1,2,3]) // 1
IS_LIST("Hello") // 0
'IS_FUNCTION' =>
VAR x = FUN test(a) -> a * 2 // <function test>
IS_FUNCTION(x) // 1
// > List functions (mutable) < //
'APPEND' =>
VAR list = [1,2,3] // [1, 2, 3]
APPEND(list, 4)
PRINT([1, 2, 3]) // [1, 2, 3, 4]
'POP' =>
VAR list = [1,2,3] // [1, 2, 3]
POP(list, 0) // 1
PRINT(list) // [2, 3]
// > List functions (immutable) < //
'EXTEND' =>
VAR list = [1, 2, 3]
VAR extendedList = EXTEND(list, [1,2,3])
PRINT(extendedList) // [1, 2, 3, 1, 2, 3]
PRINT(list) // [1, 2, 3]
FUN add (a, b) -> a + b // <function add>
add(5, 6) // 11
FUN add (a, b) -> a + b // <function add>
VAR someFunc = add // <function add>
someFunc(1, 2) // 3
FUN (a) -> a + 6 // function<anonymous>
VAR someFunc = FUN(a) -> a + 6
someFunc(12) // 12 + 6 = 18
FUN test(a) -> a / 0 // function<test>
test(12345)
// Error output:
// Traceback (most recent call last):
// File <stdin>, line: 1, in <program>
// File <stdin>, line: 1, in test
// Runtime Error: Division by zero
//
// FUN test(a) -> a / 0
// ^
VAR result = 1
FOR i = 1 TO 6 THEN VAR result = result * i
result // result => 120
VAR result = 1
FOR i = 5 TO 0 STEP -1 THEN VAR result = result * i
result // result => 120
VAR result = 0
WHILE result < 100000 THEN VAR result = result + 1
result // result => 100000
VAR result1 = (2 + 5) * 2 - (10 + 5) // -1
VAR result2 = 5 == 5 OR 3 == 2 // 1 (TRUE)
IF <expr> THEN <expr>
IF <expr> THEN
<expr1>
<expr2>
<expr3>
END
FOR i = 0 to 10 THEN <expr>
FOR i = 0 TO 10 THEN
<expr1>
<expr2>
<expr3>
END
FUN <name>() -> <expr>
FUN <name>()
<expr1>
<expr2>
<expr3>
END
VAR int = 25
VAR float = 23.2
'Text'
"Text with \"quotes\""
'Text with \\ backslashes \\'
'Text \nwith \nnewlines'
[] // List syntax
[1, 2, 3] + 4 => [1, 2, 3, 4] // Add an element to the list
[1, 2, 3] * [3, 4, 5] => [1, 2, 3, 3, 4, 5] // Concatenate two lists
[1, 2, 3] - 1 => [1, 3] // Remove element from the list at index 1
[1, 2, 3] - 0 => [2, 3] // Remove element from the list at index 0
[1, 2, 3] - -1 => [1, 2] // Remove the last element from the list
[1, 2, 3] - -2 => [1, 3] // Remove the before-last element from the list
[1, 2, 3] / 0 => 1 // Retrieve an element from the array at index 0
[1, 2, 3] / 1 => 2 // Retrieve an element from the array at index 1
⚡️ Free Next.js responsive landing page template for SaaS products made using JAMStack architecture.
Non-blocking PostgreSQL client for Node.js written in TypeScript.
Fast and lightweight JavaScript game engine built on WebGL and glTF
Implement Flamework remotes with classes
IOS Android Web cross platform app for real time collaborative music listening session and playlist editing. Using...
A social media platform to create communities and make friends
Vue is a JavaScript framework for building websites. The...
TypeScript is an open source programming...
React Native is a JavaScript mobile framework developed...
React (also known as React.js or ReactJS) is a JavaScript...
Python is a dynamically typed programming language...
PHP is a popular general-purpose scripting language...
Node.js is a tool for executing JavaScript in a variety...
iOS is the operating system for all of Apple’s mobile...
Released in 2016, Angular is a rewrite of AngularJS. It...
Android was designed and built by Google in 2008. The...