Close
0%
0%

L1VM

A tiny virtual machine with a 64 bit RISC CPU.

Similar projects worth following
L1VM is my latest virtual machine. It's very fast, up to seven times faster than Nano VM.
The VM can be expanded by modules. Even a SDL/GUI module is available.
The source code is available on GitHub, the link is below.

The VM has only 61 opcodes, two of them are special interrupts for console I/O and other stuff.
The L1VM binary is only 52 kB big. (AMD64 on Linux) The main part which executes the bytecode only 15 kB.
There is a compiler for my own language, which I call "Brackets". And there is an assembler too.

"Hello world!" in Brackets:
-----------------------------------------------------
// hello.l1com
// Brackets - Hello world!
//
#include
(main func)
(set int64 1 zero 0)
(set int64 1 x 23)
(set int64 1 y 42)
(set int64 1 a 0)
(set string 13 hello "Hello world!")
// print string
print_s (hello)
print_n
((x y *) a =)
print_i (a)
print_n
exit (zero)
(funcend)
---------------------------------------------

The modules

The L1VM can be expanded by modules (shared libraries). A module has an own API to access the functions from the VM. Here is the list of modules:

Cells - linked neural networks with FANN library
endianess - convert to big endian, or little endian functions
fann - FANN neural networks
file - file module
genann - neural networks module
gpio - Raspberry Pi GPIO module
math - some math functions
math-nofp - math module for use without FPU
math-vect - math on arrays functions
mem - memory allocating for arrays and vectors
mem-vect - C++ vector memory library
mpfr-c++ - MPFR floating point big num library
net - TCP/IP sockets module
process - start a new shell process
rs232-libserialport - RS232 serial port using libserialport
rs232 - RS232 serial port module
sdl 2.0 - graphics primitves module, like pixels, lines..., and GUI with buttons, lists, etc.
string - some string functions
time - get time and date

You can use this modules in your own Bracket programs.
And you even can develop your own modules!

The L1VM now runs on Linux (testet on Debian, Ubuntu, Fedora), Windows 10 (via WSL) and macOS.
On the Raspberry Pi the serial port and the GPIO pins can be programmed with my rs232 and gpio module.
I use them to control a robot with my Raspberry Pi

  • Variable ranges

    jay-t01/17/2023 at 16:43 0 comments

    I did add a variable range keyword in to Brackets. If a variable is out of legal range then a runtime exception happens! This was inspired by Ada. More here on my blog: L1VM ranges.

  • Brackets - switch

    jay-t03/29/2022 at 19:23 0 comments

    // switch.l1com
    // Brackets - Hello world! switch
    //
    #include 
    (main func)
    	(set int64 1 zero 0)
    	(set int64 1 x 23)
    	(set int64 1 y 42)
    	(set string s 23_str "y = 23")
    	(set string s 42_str "y = 42")
    	(set const-int64 1 23_const 23)
    	(set const-int64 1 42_const 42)
    	(set string s hello_str "Hello world!")
    	(set int64 1 a 0)
    	// print string
    	print_s (hello_str)
    	print_n
    	((x y *) a =)
    	print_i (a)
    	print_n
    	(switch)
    		(y 23_const ?)
    			print_s (23_str)
    			print_n
    			(break)
    		(y 42_const ?)
    			print_s (42_str)
    			print_n
    			(break)
    	(switchend)
    	exit (zero)
    (funcend)

     This program uses the switch statement. It prints out:

    $ l1vm prog/switch -q
    Hello world!
    966
    y = 42
    

  • Math demo program

    jay-t03/29/2022 at 19:01 0 comments

    // math-lib.l1com
    // math library demo
    // 
    #include <math-const.l1h>
    #include <intr.l1h>
    (main func)
        (set int64 1 zero 0)
        (set int64 1 randstart 2003)
        (set int64 1 random 0)
        (set int64 1 digits 3)
        (set int64 1 numstr_len 30)
        (set int64 1 not_num 0)
        (set int64 1 not_ret)
        (set string 30 numstr "")
        (zero :math_init call)
        (loadreg)
        (randstart :math_randinit call)
        (loadreg)
        (:math_randint call)
        (random stpopi)
        (loadreg)
        print_i (random)
        print_n
        print_d (m_pi@math)
        print_n
        // round pi to "digits" (3) digits and store number in string
        (m_pi@math digits numstraddr numstr_len :double_rounded_string call)
        (loadreg)
        print_s (numstr)
        print_n
        (not_num :math_not call)
        (not_ret stpopi)
        (loadreg)
        print_i (not_ret)
        print_n
        // close module
        free_mod (zero)
        exit (zero)
    (funcend)
    #include <math-lib.l1h>

    This demo program prints out:

    $ l1vm lib/math-lib -q
    3368910609462220170
    3.1415926536
    3.142
    1
    

  • MPFR floating point numbers module

    jay-t10/21/2019 at 19:40 0 comments

    I wrote a module for calculate with big floating point numbers (MPFR library module).

    In the library are more than 80 math functions. The numbers are defined by setting text strings.

    After a calculation the numbers can be printed on screen or saved as text strings.

    I included a demo in the library code: lib/mpfr-lib-auto.l1com.

  • Build files for OSv unikernel

    jay-t09/08/2019 at 14:14 0 comments

    In my GitHub repository of L1VM I added build directories for OSv unikernel support.

    The goal is here to put the L1VM in a image together with the OSv unikernel.

    You need to install the "capstan" build tool of OSv first. The build script makes an Qemu .img file which can run by Qemu or be installed on real hardware.

    One demo shows how to load a module, in this case the math module. So you can load modules from your L1VM programs too!

  • Array variables access

    jay-t06/01/2019 at 08:35 0 comments

    I added array variable access in the bracket compiler:

    // array demo
    //
    (main func)
    	(set int64 1 zero 0)
    	(set int64 1 one 1)
    	(set int64 1 offset 8)
    	(set int64 1 x 23)
    	(set int64 1 y 42)
    	(set int64 1 a 0)
    	(set int64 1 b 0)
    	(set int64 2 z 0 0)
    	// assign to array
    	(x z [ zero ] =)
    	(y z [ offset ] =)
    	// get array variable
    	(z [ zero ] a =)
    	(z [ offset ] b =)
    	(4 a 0 0 intr0)
    	(7 0 0 0 intr0)
    	(4 b 0 0 intr0)
    	(7 0 0 0 intr0)
    	(255 zero 0 0 intr0)
    (funcend) 

    All variable types are supported! The source code is on GitHub. There are some examples in the prog/ directory.

  • Double float benchmark with close to C speed

    jay-t05/18/2019 at 18:54 0 comments

    I wrote a benchmark calculating with double float numbers.

    The benchmark on my L1VM is close to a native C program doing the same math.

    Here is the L1VM benchmark source code:

    (main func)
        (set int64 1 zero 0)
        (set double 1 x 23.0)
        (set double 1 y 42.0)
        (set double 1 z 7.0)
        (set double 1 a 1.0)
        (set int64 1 max 80000000Q)
        (set int64 1 one 1)
        (ASM)
        loada zero, 0, I0
        loadd x, 0, F1
        loadd y, 0, F2
        loadd z, 0, F3
        loadd a, 0, F4
        loadd a, 0, F10
        loadd y, 0, F22
        loadd x, 0, F20
        loada one, 0, I4
        loada max, 0, I5
        loada one, 0, I6
        loadl :jit, I40
        loadl :jit_end, I41
        // run jit compiler
        intr0 253, I40, I41, 0
    :loop
        // call jit code
        intr0 254, I0, 0, 0
        // jump to following non-jit code
        jmp :next
    :jit
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F22, F10
        addd F10, F22, F10
        addd F10, F22, F10
        addd F10, F22, F10
        addd F10, F22, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F20, F10
        addd F10, F22, F10
        addd F10, F22, F10
        addd F10, F22, F10
        addd F10, F22, F10
    :jit_end
        addd F10, F22, F10
        // store
    :next
        intr0 5, F10, 0, 0
        intr0 7, 0, 0, 0
        addi I4, I6, I4
        lseqi I4, I5, I30
        jmpi I30, :loop
        intr0 5, F10, 0, 0
        intr0 7, 0, 0, 0
        intr0 255, 0, 0, 0
        (ASM_END)
    (funcend)
    

    Here is the result of the C program:

    $time ./double-test >/dev/null 2>&1
    
    real	1m3,400s
    user	1m3,249s
    sys	0m0,148s
    

    And my L1VM:

    $time vm/l1vm prog/jit-test-double >/dev/null 2>&1
    
    real	1m11,828s
    user	1m11,704s
    sys	0m0,120s
    

    So my VM is close to C in that case. :)

  • Time and date functions

    jay-t02/28/2019 at 14:12 0 comments

    I added time and date functions via interrupt 0.

    So programs can use this information to do something with it.

    I wrote a little demo which shows "Hello world!" and the current time.

    Here it is:

    // bra(et - Hello world! and time!!
    //
    (main func)
    	(set int64 1 zero 0)
    	(set string 13 hello "Hello world!")
    	(set string 2 colon ":")
    	(set int64 1 hour 0)
    	(set int64 1 min 0)
    	(set int64 1 sec 0)
    	(set int64 1 ten 10)
    	(set int64 1 f 0)
    	// print string
    	(6 hello 0 0 intr0)
    	// print newline
    	(7 0 0 0 intr0)
    	(17 hour min sec intr0)
    	(((hour ten <) f =) f if)
    		(4 zero 0 0 intr0)
    	(endif)
    	(4 hour 0 0 intr0)
    	(6 colon 0 0 intr0)
    	(((min ten <) f =) f if)
    		(4 zero 0 0 intr0)
    	(endif)
    	(4 min 0 0 intr0)
    	(6 colon 0 0 intr0)
    	(((sec ten <) f =) f if)
    		(4 zero 0 0 intr0)
    	(endif)
    	(4 sec 0 0 intr0)
    	(7 0 0 0 intr0)
    	(255 zero 0 0 intr0)
    (funcend)
    

View all 8 project logs

Enjoy this project?

Share

Discussions

Dan Maloney wrote 02/04/2019 at 21:30 point

I find myself trying to figure out the syntax of your language from just this listing...

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates