Practical, flexible, GUI and general-purpose language

Lever is a general purpose programming language, in the Perl/Python/Ruby group, with built-in support for GUI applications, including OpenGL, and a packaging feature that makes it easy to distribute applications.

It's easy to add support for external 'C' libraries and the interface is relatively fast.

The language itself is extensible and modifiable and, in general, there is an emphasis on practicality.

Guides

Superior FFI

Using C libraries in your Lever code is so clean that it is optional to write wrappers for them.

sdl = api.library("libSDL2")
sdl.Init(sdl.INIT_EVERYTHING)
sdl.Quit()

Lever has semi-automatic utilities to parse C files, clean them and translate them into .json -formatted headers that provide you with everything to use the libraries you need.

It also has headers for OpenGL4, although they have been generated directly from Khronos specifications.

blen = ffi.automem(ffi.uint)
gl.getObjectParameterivARB(obj, gl.OBJECT_INFO_LOG_LENGTH_ARB, blen)
gl.getShaderiv(obj, gl.INFO_LOG_LENGTH, blen)
log = ffi.automem(ffi.ubyte, blen.to)
gl.getInfoLogARB(obj, blen.to, null, log)
print(log.str)

Combine this with rest of the features, and you get so incredibly simple programs that do incredibly complex things. For example, check this implementation of Logo out.

Modules, without sys.modules

There's no global object in lever that holds all the loaded modules. Instead the loaded modules are kept in module scopes. It is first-class loaded-modules handling! You can stack module scopes over others. There's 15 lines to plugin system or live coding from here:

plugins = ModuleScope(dir ++ "path/to/plugins", %"import".scope)
plugins_importer = Import(plugins.local, plugins)

And you can get rid of your scope when you like, to get all your modules to reload.

Built-in eventloop with augmented concurrency

Async code looks so ugly, were you using callbacks, async/await or promises to do it. Except in Lever. In lever it looks prettier than your sync code.

Lever's got integrated libuv eventloop that implements its 'sleep' command, which is very much like 'setInterval' in javascript. Except that if you call it without a function, it waits:

sleep(2)

If you call it with a function, it calls the function after a while.

test = ():
    print("5 second hello!")
sleep(5, test)
sleep(1)
print("1 second hello")

But you can also call it with...

test = (parent):
    parent.switch() # switches back
    print("4 second hello!")
dat = greenlet(test)
dat.switch(getcurrent()) # goes to run test.
# now we have a greenlet that hasn't returned.
sleep(4, dat)
# that inserted it into an event loop, cool?

That's right, greenlets! This is how any event emitter works in lever. You don't need to worry whether it should be callbacks or greenlets. You can either wait for event or pass a callback and things keep working.

What if you stuck your app to wait for an event, but the event source is removed and the waiting code should release file handle? No problem. The event source schedules 'Discard' -exception thrown to the greenlet, that makes your waiting code to gracefully exit.

Other Features

There is more in-depth documentation in the repository, including internal documentation for the runtime.

Performance

Author knows by initial tests, that Lever is slightly slower than Python. There's performance.text detailing out how it is intended to achieve better performance out of Lever.

License

Lever is licensed under the MIT license.

Download

Website maintained by Lever community.