We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
FlamePL
FlamePL is designed by PSTF and his AI assistant.
Overview
FlamePL is a programming language for data analysis and software developing.
Syntax
Formal EBNF Grammar
(* Lexical tokens (terminals) *)
letter = "A" | "B" | ... | "Z" | "a" | "b" ... | "z" ;
digit = "0" | "1" | ... | "9" ;
ident = letter , { letter | digit | "_" } ;
number = digit , { digit } , [ "." , { digit } ] ;
imag = digit , { digit } , "i" ;
string = '"' , { character - '"' } , '"' |
'"""' , { character } , '"""' ;
comment = "#" , { character - newline } ;
(* Keywords – they are reserved *)
keyword = "fn" | "class" | "if" | "then" | "else" | "end" |
"while" | "do" | "return" | "null" | "lambda" |
"and" | "or" | "not" | "true" | "false" |
"print" | "input" | "to_int" | "to_float" |
"to_str" | "type_of" ;
(* Operators and delimiters *)
op_assign = "<-" ;
op_eq = "=" ;
op_exp = "^" ;
op_idiv = "//" ;
op_add = "+" | "-" ;
op_mul = "*" | "/" | "//" ;
op_cmp = "=" | "<" | ">" ;
delim = "(" | ")" | "[" | "]" | "{" | "}" | ":" | "," | "." | "->" ;
(* ==================== Syntax rules ==================== *)
program = { statement } ;
statement = assignment
| if_statement
| while_statement
| return_statement
| function_def
| class_def
| expression ;
assignment = ident , "<-" , expression ;
if_statement = "if" , expression , "then" , { statement } ,
[ "else" , { statement } ] , "end" ;
while_statement = "while" , expression , "do" , { statement } , "end" ;
return_statement = "return" , expression ;
function_def = "fn" , ident , "(" , [ ident , { "," , ident } ] , ")" ,
{ statement } , "end" ;
class_def = "class" , ident , [ ":" , ident ] ,
{ function_def } , "end" ;
(* expression – precedence from lowest to highest *)
expression = or_expr ;
or_expr = and_expr , { "or" , and_expr } ;
and_expr = not_expr , { "and" , not_expr } ;
not_expr = "not" , not_expr | comparison_expr ;
comparison_expr = additive_expr , [ ("=" | "<" | ">") , additive_expr ] ;
additive_expr = multiplicative_expr , { ("+" | "-") , multiplicative_expr } ;
multiplicative_expr = power_expr , { ("*" | "/" | "//") , power_expr } ;
power_expr = unary_expr , [ "^" , power_expr ] ; (* right‑associative *)
unary_expr = ("+" | "-") , unary_expr | postfix_expr ;
postfix_expr = primary_expr ,
{ "[" , expression , "]"
| "(" , [ expression , { "," , expression } ] , ")"
| "." , ident , "(" , [ expression , { "," , expression } ] , ")"
} ;
primary_expr = number
| imag
| string
| "true"
| "false"
| "null"
| "(" , expression , [ "," , expression ] , ")"
| "[" , [ expression , { "," , expression } ] , "]"
| "{" , [ expression , ":" , expression , { "," , expression , ":" , expression } ] , "}"
| "lambda" , "(" , [ ident , { "," , ident } ] , ")" , "->" , expression
| ident
| "to_int" , "(" , expression , ")"
| "to_float" , "(" , expression , ")"
| "to_str" , "(" , expression , ")"
| "type_of" , "(" , expression , ")"
| "print" , "(" , expression , ")"
| "input" , "(" , expression , ")" ;
Textual Description of Semantics
1. Lexical Conventions
- Comments start with
#and run to the end of the line; they are ignored. - Identifiers are case‑sensitive and start with a letter or underscore, followed by letters, digits, or underscores.
- Keywords (
fn,class,if,then,else,end,while,do,return,null,lambda,and,or,not,true,false,print,input,to_int,to_float,to_str,type_of) are reserved. - Numbers are arbitrary‑precision decimals (implemented via Python’s
Decimal). They can be integers or floating‑point. - Imaginary literals are digits followed by
i(e.g.3i,42i) and denote a complex number with zero real part. - Strings are delimited by double quotes
"for single‑line strings, and by triple double‑quotes"""for multi‑line strings. Escape sequences are not processed – they are literal. - Whitespace (spaces, tabs, newlines) is ignored except for separating tokens.
2. Data Types
| Type | Syntax / Example | Notes |
|---|---|---|
| Integer | 42, -3
|
Arbitrary precision; stored as Decimal with exponent 0.
|
| Float | 3.14, 2.71828
|
Arbitrary‑precision decimal floating point. |
| Complex | 3+4i, -2.5i
|
Real and imaginary parts are arbitrary‑precision decimals. |
| String | "hello", """multi
|
Unicode strings. |
| Boolean | true, false
|
Distinct type; results of logical/comparison ops. |
| List | [1, 2, 3]
|
Ordered, mutable, heterogeneous. |
| Pair | (10, 20)
|
Fixed‑size ordered pair of two values. |
| Dictionary | {"name": "FlamePL", "ver": 1}
|
Key‑value mapping; keys can be any type. |
| Null | null
|
Represents the absence of a value. |
| Function | created by fn or lambda
|
First‑class, closures, recursive. |
| Class / Instance | class ... end
|
Supports inheritance and methods. |
| Type | returned by type_of
|
First‑class type objects (int, float, bool, …).
|
3. Variables and Scope
- Assignment:
x <- 10— binds a value to a name in the current scope. - Equality test:
x = 10— returns a Boolean; not an assignment. - Scopes: Functions create new lexical scopes that capture their enclosing environment (closures). Blocks (
if,while,do) do not create new scopes – they share the surrounding scope. - Variable lookup searches the current scope, then outer scopes recursively.
4. Expressions
Arithmetic Operators
+,-,*,/— standard numeric operations (work on integers, floats, complex).^— exponentiation (right‑associative):2 ^ 3 ^ 2→2 ^ (3 ^ 2).//— integer division (floor division) for numeric types.- Unary
+and-are supported.
Comparison Operators
=,<,>— all return Booleans.=is equality, never assignment.
Logical Operators
and,or,not— short‑circuiting, always return a Boolean (trueorfalse).
Example: true and false → false, not true → false.
Type Conversion (built‑in functions)
to_int(x)— converts to integer (truncates floats, parses strings).to_float(x)— converts to arbitrary‑precision float.to_str(x)— returns a string representation.
Type Inspection
type_of(x)— returns a first‑class type object (e.g.int,bool,list). These type objects can be compared with=.
5. Control Flow
Conditional
if condition then
statements
else
statements
end
The else block is optional. The condition must evaluate to a Boolean.
Loop
while condition do
statements
end
Loops while the condition is true; condition evaluated before each iteration.
Return
return expression — exits the current function and returns the value. If used outside a function, it is an error.
6. Functions and Lambdas
Named Function
fn add(a, b)
return a + b
end
- Parameters are passed by value.
- The function body is a sequence of statements.
- The last evaluated expression is not implicitly returned; you must use
return.
Lambda (Anonymous)
square <- lambda (x) -> x * x
- A lambda consists of a parameter list,
->, and a single expression (not a block). - Lambdas are closures.
Recursion
Functions may call themselves by name; the name is resolved lexically.
7. Object‑Oriented Programming
class Animal
fn init(name)
self.name <- name
end
fn speak()
print(self.name + " makes a noise.")
end
end
- Classes are defined with
class Name ... end. - Inheritance:
class Dog : Animal ... end– the child inherits all methods. - Methods are defined with
fninside the class; they have an implicitselfparameter (the instance). - Constructor: a method named
initis called automatically when an instance is created. - Instantiation:
d <- Dog("Rex")calls the class as a function. - Method calls:
d.speak()– dot notation. - Field access:
self.name <- "..."– fields are stored directly in the instance.
8. Built‑in I/O
print(expr)— outputs the value ofexpr(converted to a string).input(prompt)— prints the prompt, reads a line from stdin, and returns it as a string.
9. First‑Class Types
The language treats types as data. type_of(10) returns the object int. You can compare it: if type_of(10) = int then ....
10. Notable Syntactic Choices
| Feature | Syntax |
|---|---|
| Assignment | <-
|
| Equality | =
|
| Integer division | //
|
| Exponentiation | ^
|
| Comment | #
|
| Logical ops | and, or, not
|
| Multi‑line string | """ ... """
|
| Ordered pair | (first, second)
|
| Null | null
|
| Boolean literals | true, false
|
Example
Fibonacci
# Recursive Fibonacci with memoization
fn fib(n)
if n = 0 then
return 0
else if n = 1 then
return 1
else
return fib(n - 1) + fib(n - 2)
end
end
print("Recursive fib(10) = " + to_str(fib(10))) # 55
# Iterative version (more efficient)
fn fib_iter(n)
a <- 0
b <- 1
if n = 0 then return a end
if n = 1 then return b end
i <- 2
while i <= n do
temp <- a + b
a <- b
b <- temp
i <- i + 1
end
return b
end
print("Iterative fib(10) = " + to_str(fib_iter(10))) # 55
Prime Number Detector
# Check if a number is prime
fn is_prime(n)
if n < 2 then
return false
end
i <- 2
limit <- n ^ 0.5 # sqrt via exponent 0.5
while i <= limit do
if n // i * i = n then # integer division and multiplication check
return false
end
i <- i + 1
end
return true
end
# Print all primes up to 50
print("Primes up to 50:")
i <- 2
while i <= 50 do
if is_prime(i) then
print(i)
end
i <- i + 1
end
Euclidean GCD
# Greatest Common Divisor using Euclid's algorithm
fn gcd(a, b)
while b != 0 do
temp <- b
b <- a // b # integer division? No, we want remainder. Use 'mod'? Not defined.
# We need modulo operator. We can use a - (a // b) * b
remainder <- a - (a // b) * b
a <- b
b <- remainder
end
return a
end
print("GCD of 48 and 18 = " + to_str(gcd(48, 18))) # 6