This repository contains the interpreter for the L language, a dynamically typed interpreted language. L language syntax and features are described using Extended Backus-Naur Form (EBNF) in this README.
- L Language Interpreter
L language is designed to be expressive and easy to understand. Here's a brief overview of its syntax:
- Constants: Variables, integers, strings, and double values.
- Operators: Logical operators (
and
,or
), comparison operators (<
,>
,==
), arithmetic operators (+
,-
,*
,/
), and more. - Statements: Includes if statements, loops (while and for), function and method definitions, and return statements.
- Context and Scope: Defines global and super contexts for variables and their assignments.
- variable: Any alphanumeric character.
- string: A sequence of characters enclosed in double quotes.
- constant: Can be a double, integer, or string.
- Logical Operators:
and
,or
,&&
,||
. - Comparison Operators:
<
,>
,==
,<=
,>=
. - Unary Operators:
!
(negation). - Arithmetic Operators:
+
,-
,*
,/
,%
.
if exp stamentsblock [else_if] [else]
else_if: else if exp stamentsblock
else: else stamentsblock
- While Loop:
while exp stamentsblock
- For Loop:
for ( (for_each_args | for_c_args) [';'] | '(' (for_each_args | for_c_args ) ')') stamentsblock
- Function Definition:
def [variable] '(' ([ variable {[',' variable]} [',' '...' variable] ] | ['...'variable]) ')' stamentsblock
- Operator Overloading:
operator ['right'] ('+'|'-'|'*'|'/'|'%'|logic_comp|logic_op|logic_one)
'(' ([ variable {[',' variable]} [',' '...' variable] ] | ['...'variable]) ')'
stamentsblock
return [exp]
- Type Context: Defines global or super contexts for variables and their assignments.
type context = ('global' | 'super') [ variable [assignament exp] {[ ',' variable [assignament exp] ]} ]
L language supports Object-Oriented Programming (OOP) with classes and inheritance.
class ClassName
{
// Class fields and methods
}
class SubClassName : SuperClassName
{
// Additional fields and methods
}
- public: Accessible from anywhere.
- protected: Accessible within the class and its subclasses.
- private: Accessible only within the class.
In this section, we present a couple of examples of L Language
Example of a vec2 class with the operators overload
class vec2
{
var x,y
def vec2(x,y)
{
this.x = to_float(x) or 0.
this.y = to_float(y) or 0.
}
operator + (value)
{
if type_of(value) == "object"
return vec2(this.x+value.x,this.y+value.y)
else
return vec2(this.x+to_float(value),this.y+to_float(value))
}
operator - (value)
{
if type_of(value) == "object"
return vec2(this.x-value.x,this.y-value.y)
else
return vec2(this.x-to_float(value),this.y-to_float(value))
}
operator -
{
return vec2(-this.x,-this.y)
}
operator * (value)
{
if type_of(value) == "object"
return vec2(this.x*value.x,this.y*value.y)
else
return vec2(this.x*to_float(value),this.y*to_float(value))
}
operator / (value)
{
if type_of(value) == "object"
return vec2(this.x/value.x,this.y/value.y)
else
return vec2(this.x/to_float(value),this.y/to_float(value))
}
operator % (value)
{
if type_of(value) == "object"
return vec2(this.x%value.x,this.y%value.y)
else
return vec2(this.x%to_float(value),this.y%to_float(value))
}
operator right * (value)
{
return vec2(to_float(value) * this.x,to_float(value) * this.y)
}
def print()
{
io.println("(",this.x, ", ", this.y,")")
}
}
x = ( ( vec2(3,4) + vec2(3,4) - vec2(3,8) ) * vec2(4,1) / vec2(2,1) ) % vec2(4,1)
y = vec2(4,1) % 4
z = 3 * vec2(3,2)
w = -vec2(3,2)
x.print()
y.print()
z.print()
w.print()
class User
{
def print_name_and_sum()
{
println(this.name, " - ", this.sum)
}
def sum_inc()
{
this.sum += 1
}
operator + (right) //always public
{
u = User()
u.name = this.name + right.name
return u
}
protected:
var name = ""
private:
var sum = 0
}
class Mario : User
{
def Mario()
{
this.User()
this.name = "Mario"
}
def sum_to_0()
{
this.sum = 0 //<- error is private
}
}
class vector
{
var data = []
def vector(...args) this.data = args
def get(i) return this.data[i]
def set(i,value) this.data[i] = value
operator + (value)
{
o = vector()
//copy data
o.data = copy(this.data)
//add...
if ( type_of(value) == "object" &&
class_name(value) == "vector" )
{
for arg_v of value.data
o.data.push(arg_v)
}
else
{
o.data.push(value)
}
return o
}
def forall(call)
{
for (k in this.data) call(k,this.data[k])
}
}
x = vector( 2, 3, 4 )
x+= vector(-5,-6,-7 )
x.forall(def (x,y) println("key: ",x+1,"\t value: ",y))
Feel free to contribute to the development of the L language interpreter by opening issues or submitting pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.