SkillAgentSearch skills...

Lever

A programming language in the Perl/Python/Ruby group

Install / Use

/learn @cheery/Lever
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Lever programming language

Logo

Lever programming language is dynamically typed language designed & programmed by Henri Tuhola. It has capabilities to absorb features from other languages. Otherwise it is very generic purpose programming system with a hint of inclination towards interactive graphics and audio programming.

Lever used to be a study piece. Then it started gaining useful features. I realised it could be something worthwhile if worked on.

Lever is meant for writing whole, standalone interactive computer programs that bundle enough lever runtime along to run without other software installed on the system. The bytecode objects provided by Lever compiler can be distributed without the source code. It is optional for end user to compile anything afterwards.

Lever presents a scoped module architecture where individual modules can be plugged in and out and interactively reloaded while the remaining program is running, this can be done from inside or outside the programs. While a module scope is introduced into a directory, it may also introduce a new language that is used to interpret the loaded files.

As computing power and capabilities increase, even very complex computer programs can be written entirely in smoother, simpler to use and more expressive languages. In past these kind of languages were preferred for writing simple scripts. Lever shares a lot with languages such as Python or Javascript. One thing it doesn't share them is the niche. Lever is meant for designing serious software.

Absorption of language features is possible because it is possible to add new rules into the grammar and into the compiler, or remove existing ones if they are not used. The newly gained language can be then either built into custom distribution or attached into a scope when running an ordinary distribution. More ways to extend the language in less invasive ways are also on planning stage.

Advantages of Python to lever is that it's perfectly good for writing scripts. It doesn't change often, it's coming along nearly every Linux distribution. But this turn around fast if you consider to do interactive graphics intensive desktop apps on Python.

Lever has most basic vector arithmetic supported by the runtime and there is hardly competiting implementations because the one in runtime will be very good and supported. And there's intent to have excellent graphics libraries embedded into the lever runtime in the future. Your vector algebra will be as clear as if copied from an algebra book.

Some graphical demos already run on lever: Here's a program from samples/gl_top/main.lc that runs an animated blender-imported on top on of a table. Requires OpenGL4:

./lever samples/gl_top/main.lc

Although javascript runs everywhere, writing it is sheer torture of capable souls. Every callback pyramid/promise forest/async keyword crowds your mind and slows down development to snail pace. And even if you manage to figure out some nice way to avoid asynchronous code, you will find yourself writing those glMatrix operations in assembly notation. They feel like a fortran blast from past, and most of us are not that retro that we write and maintain algebra expressions in assembly style.

Clean slate under lever allowed its eventloop to combine with continuations, turning into a complete rethought of how to write code that waits for events. Async lever code is as simple to work with as what sync code is.

Lever doesn't have a global module space like Python has. Instead you can create scopes for modules and chain them together. Once the work has been finished in Lever's module resolution, it'll be a 10-liner to create a plugin system that isn't a hack.

Despite this, the Lever environment has been designed to be maintained by individuals. Design decisions that would require large dedicated teams to maintain them are feverously avoided. It is meant that people can poke features into the source tree when they need those. They may even develop their own languages on top of Lever as they go. Such newly created micro languages can then feature as laboratories for new features and steer the development of the mainline language.

Python3 is so stable that it didn't provide that many improvements over Python2 to make the breaking worthwhile. If you are looking for something more volatile but better, something like explodes in your hands, you may like to look into Lever.

Platforms

Lever's runtime works on the following platforms:

  • Windows (32-bit x86 PC)
  • Linux (64-bit x86 PC)

If the source code does not compile, you may file an issue in https://github.com/cheery/lever/issues

The 32-bit support on Windows will be deprecated when PyPy's translator supports 64-bit Windows environments.

Feature list

  • Leverages RPython for rapid language development. Adjustments to design come with lower cost allowing good design choices to appear.
  • Foreign Function Interface which relies on automatically generated C headers. Use of C libraries among dynamically typed code is made simpler than it ever was.
  • Bytecode format inspired by SPIR-V. The format supports quick changes to instruction set, and makes it easy to keep different bytecode related tools updated.
  • Coroutines, and coroutine-enabled event loop, provided by RPython. Crucial tool for writing clean code that may wait asynchronously.
  • Module resolution scopes.
  • Fixed-arity Multimethods. Efficient implementation purposefully incompatible with inheritance. Most operators in lever are defined as multimethods. Doesn't come without drawbacks, but makes lot of things cleaner.
  • Customizable grammars that can be shared between utilities. Made possible with a parsing kernel that copies concepts from marpa parser. Makes it trivial to provide auxiliary notation for legibility.
  • POSIX-compatible path convention that is enforced across platforms: The programmer and configuration files see POSIX-paths while the operating system see an illusion of obeying its rules regarding file paths.
  • Vector and quaternion arithmetic in runtime that can be optimized.

Use cases

Every single usecase here features functionality. Every snippet of code runs in the interpreter and works as advertised.

Make 'BEGIN', 'END' denote a block, syntax absorption, rapid language development usecase

Trends, fashions, fads. They are very real at programming world, and many old languages are unable to follow along. Or then they follow along dragging everyone into it at once, and we get Python3 async/await -keywords. Rare are the days when there comes a new insight to programming that require changes into language grammar, but those days do happen at times. They could happen more often.

If you're used to not being able to change the grammar of your programming language, the following may offend you:

block =>
    {"BEGIN" statements "END"}
    {"BEGIN" statements %newline "END"}

If you add this into the lever-0.8.0.grammar, the following code will compile and run:

hello = (foo): BEGIN
if foo.endswith("3") BEGIN
print("foo", foo)
END
else BEGIN print("baa", foo) END
END

hello("123-c-432")
hello("423-b-213")
hello("423-b-212")

There's some rationale to showing this with BEGIN and END rather than {}. The braces are reserved for dictionaries in lever-0.8.0. The lowcase words 'begin' and 'end' are in use at lib/vr.lc and lib/vulkan.lc. Since the grammar in lever directory is used by all of the compilers we have, changing it can cause ambiguities or change the meaning of the library modules.

Thanks to use of context free grammar, if you don't remove any existing rules, then doing ./setup.py compile-lib-all will reveal where the new rules introduce ambiguities.

Due to the existing rules being still in place, you may notice every variation of BEGIN and END is not recognized. For example if you add BEGIN to new line or indent it, it will most likely produce a syntax error. This happens due to how lever language recognizes indentation.

Source files are parsed from left to right and there's an indenter before the parsing engine. If the indenter notes it could insert one of "indent", "dedent" or "newline" tokens, it will first check whether the parser anticipates for one. If it does, it will insert one into the stream.

Practically you could copy the grammar into your own directory and hack it to your preferences or (hopefully) practical needs. It would allow infinite customizability into the syntax. Some short adjustments would have to be done to lever runtime to allow it.

It doesn't look that horrible if you accept that programming languages are merely user interfaces for humans and then treat them as such.

The features allowing this usecase makes the development of Lever very fast. It is very low stress operation to introduce new syntactic rules when you need them. You might like to change the grammar files to accomodate for disabilities, port old code or just troll your coding companions.

Console - modules, compiler, bytecode usecase

Although it is surrounded by syntax, "import" is just a function in your module. The result is you can do weird parlour tricks by importing from other modules.

Python tried to dictate and force me to not change default environment of a script. It was one of those decisions that drove me to design my own language that would not have this handicap.

Lever console is something that is not implemented in the runtime. It's an application present in app/main.lc. Here you have a shortened version of that program:

import base, compiler

console = :module("console", base)
    dir = getcwd()
    name = "console"
    %"import" = Import(dir,
        ModuleScope(dir, %"import".scope.parent))

while true
    string = input(">> ")
    code = compiler.r
View on GitHub
GitHub Stars132
CategoryDevelopment
Updated5mo ago
Forks10

Languages

HTML

Security Score

92/100

Audited on Oct 15, 2025

No findings