logo

🐲 Leviator

The opinionated programing language



Leviator is compiled to wasm binary format.

[!NOTE]
This is a student project (EPITECH school). It is not intended to continue this project.

Language Syntax

[!IMPORTANT]
StringView are not supported.

[!IMPORTANT]
There is no list/array in this language.

  • Comentary
// This is a comment
  • Alias
alias A = Int;
  • Variables Declaration
@Int a = 1;
@StringView b = "hello";
  • Variables Assignment
a = 1;
b = "hello";
  • Built-in Types
@Bool a = True;
@Bool b = False;
@Int c = 1;
@Char e = 'a';
@StringView f = "hello";

There is a Void type that can be used to return nothing.

  • Function Declaration
#![allow(unused)]
fn main() {
fn add(a: Int, b: Int) -> Int
{
    // the next line is the `return`
    <- a + b;
};

export fn sub(a: Int, b: Int) -> Int
{
    <- a - b;
};
}
  • Function Call
#![allow(unused)]
fn main() {
add(1, 2);
}
  • Function Polymorphism
#![allow(unused)]
fn main() {
fn add(a: Int, b: Int) -> Int
{
    <- a + b;
};

fn add(a: Float, b: Float) -> Float
{
    <- a + b;
};

fn add(a: Int, b: Int, c: Int) -> Int
{
    <- a + b + c;
};
}
  • Conditions
if (a == 1)
{
    // do something
};

if (a == 1)
{
    // do something
}
else
{
    // do something else
};
  • Loops
@Int i = 0;
while (i < 10)
{
    // do something
    i = i + 1;
};
  • Entrypoint
#![allow(unused)]
fn main() {
// If you don't have this function, the program will not be run
export fn start() -> Int
{
    <- 0;
};
}
  • Operators
a + b
a - b
a * b
a / b
a == b
a != b
a < b
a <= b
a > b
a >= b
  • Priority of Operators
// realy peticuliar buut we use { for ( and } for )
{a + B} * c

Spec for ByteCode

:: All value starting with 0x are hexadecimal

  1. The file starts with:
0x00 0x61 0x73 0x6D
0x01 0x00 0x00 0x00

Type Section

0x01

Function Type

0x60

Number of Parameters

  • for 2 parameters
    0x02
    

Parameters Type

0x7F: i32
0x7D: f32

Return Type

0x7F: i32
0x7D: f32
0x00: void

Function Section

0x03

Export Section

0x07

Instructions

Instructions

Stack

local

local.get
0x20

Get a local variable by its index and add it to the stack.

local.set
0x21

Get the top of the stack and set a local variable by its index.

global

global.get
0x23

Get a global variable by its index and add it to the stack.

global.set
0x24

Get the top of the stack and set a global variable by its index.

i32

i32.const
0x41

Push an Int32 to the stack.

Memory

i32

i32.store
0x36

Take the top of the stack. This will be the value stored in memory. Take the top of the stack. This will be the index in memory.

Store the value in memory at the index.

i32.load
0x28

Take the top of the stack. This will be the index in memory.

Push an Int32 to the stack with the value at address in memory.

Condition

i32

i32.gt_s
0x4a

Compare the 2 values on the top of the stack.

If the first value is greater than the second value, push 1 to the stack. else, push 0

i32.eq
0x46

Compare the 2 values on the top of the stack.

If the first value is equal to the second value, push 1 to the stack. else, push 0

control

if...else...end
  • if

    0x04
    

    Enter in the first branch if the top of the stack is 1.

  • else

    0x05
    

    Enter in the second branch if the top of the stack is 0.

  • end

    0x0b
    

    Exit from the if/else block.

loop
  • loop

    0x03
    

    Create a label for the loop

    Label is a number

  • br

    0x0c
    

    Jump to the label

    Label is a number

Operations

i32

i32.add
0x6a

Add the 2 values on the top of the stack. Push the result to the stack.

header: 0x00 0x61 0x73 0x6D
version: 0x01 0x00 0x00 0x00

type section: 0x01
    - size of this section
    - number of types
    - 0:
        - header: 0x60 (function prototype)
        - number of parameters: 0x02
        - parameters type (no need for this if number of parameters is 0):
            - 0:
                i32: 0x7F
            - 1:
                i32: 0x7F
        - number of results: 0x01
        - return type (no need for this if number of results is 0):
            - 0:
                i32: 0x7F

function section: 0x03
    - size of this section
    - number of functions: 0x02
    - 0: index of the type function in section type
    - 1: index of the type function in section type

memory section: 0x05
    - size of this section
    - has maximum size: 0x00 (0x01 if has maximum size)
    - minimum size: 0x13
    - maximum size (if has maximum size): 0x20

export section: 0x07
    - size of this section
    - number of exports: 0x01
    - exports:
        - 0:
            name length: 0x04
            name: "main"
            type (func: 0, table: 1, memory: 2, global: 3): 0x00
            index: 0x00

code section: 0x0A
    - size of this section
    - number of code: 0x01
        - 0:
            size of this code
            number of locals type: 0x01
            - 0:
                number of elements: 0x01
                type of elements: 0x7F (i32)
            end of this code: 0x0B

Exemple

add.wat

(module
  (func $add (param $lhs i32) (param $rhs i32) (result i32) (local $smth i32)
    local.get $lhs
    local.get $rhs
    local.set $smth
    local.get $rhs
    i32.add)
  (export "add" (func $add))
)

add.wasm (with wat2wasm hexdump -C)

00000000  00 61 73 6d 01 00 00 00  01 07 01 60 02 7f 7f 01  |.asm.......`....|
00000010  7f 03 02 01 00 07 07 01  03 61 64 64 00 00 0a 0f  |.........add....|
00000020  01 0d 01 01 7f 20 00 20  01 21 02 20 01 6a 0b     |..... . .!. .j.|
0000002f

add.wasm.wat (with wasm2wat)

(module
  (type (;0;) (func (param i32 i32) (result i32)))
  (func (;0;) (type 0) (param i32 i32) (result i32)
    (local i32)
    local.get 0
    local.get 1
    local.set 2
    local.get 1
    i32.add)
  (export "add" (func 0)))

Leviator Lang Extension for Visual Studio Code

We are thrilled to introduce our Leviator lang extension, providing enhanced syntax highlighting for an optimized coding experience. While currently available exclusively for vscode, we have ambitious plans to extend support to JetBrains and Vim in the future.

Installation

To install the Leviator Language extension for Visual Studio Code, follow the steps below:

  1. Navigate to the "lvtext" directory in our Leviator GitHub repository.
  2. Refer to the detailed installation instructions provided in the README.md file.

Leviator BNF

<syntax> ::= <expression>*

<expression> ::= <alias> | <function> | <comment>

<alias> ::= "alias " <identifierAlias> " " <replacement> ";\n"
<identifierAlias> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
                      "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
                      "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" |
                      "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" |
                      "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" |
                      "t" | "u" | "v" | "w" | "x" | "y" | "z" | "0" | "1" |
                      "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "_" |
                      "." | "-" | ":" | "!" | "@" | "#" | "$" | "%" | "^" |
                      "&" | "*" | "(" | ")" | "[" | "]" | "{" | "}" | "|" |
                      "\\" | "+" | "=" | ";" | "<" | ">" | "?" | "/" | "`" |
                      "~"
<replacement> ::= <char2>

<comment> ::= "//" <char1>* "\n"

<function> ::= "fn " <identifier> "(" <parameterList>* ") -> " <type> "\n{\n" <instruction>* "}\n"
<identifier> ::= <lowerLetter> <char2>
<parameterList> ::= <parameter> ","
<parameter> ::= <identifier> ": " <type>
<type> ::= <upperLetter> <char2>
<instruction> ::= <instructionIns> ";\n"
<instructionIns> ::= <declaration> | <assignment> | <functionCall> | <return> | <condition> | <while>
<declaration> ::= "@" <type> " " <identifier> " = " <value>
<assignment> ::= <identifier> " = " <value>
<functionCall> ::= <identifier> "(" <varParamList>* ")"
<varParamList> ::= <value> ","
<return> ::= "<- " <value>
<value> ::= <functionCall> | <identifier> | <literal>
<literal> ::= <digit> | <character> | <bool> | <stringview>
<condition> ::= <conditionIf> | <conditionIfElse>
<conditionIfElse> ::= <conditionIf> <conditionElse>
<conditionIf> ::= "if (" <value> ")\n{\n" <instruction>* "}\n"
<conditionElse> ::= "else\n{\n" <instruction>* "}\n"
<while> ::= "while (" <value> ")\n{\n" <instruction>* "}\n"

<character> ::= "'" <char1> "'"
<bool> ::= "True" | "False"
<stringview> ::= "\"" <char1>* "\""

<char> ::= <lowerLetter> | <upperLetter> | <digit>
<char1> ::= <char> | "" | " " | <specialAll>
<char2> ::= <lowerLetter> | <upperLetter> | <digit> | <special>
<lowerLetter> ::= "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
                  "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
                  "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
<upperLetter> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
                  "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
                  "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<special> ::= "_"
<specialAll> ::= <special> | "!" | "@" | "#" | "$" | "%" | "^" | "&" |
                 "*" | "(" | ")" | "[" | "]" | "{" | "}" | "|" | "\\" |
                 "+" | "=" | ";" | "<" | ">" | "?" | "/" | "`" | "~"