LRL - Lightweight Reusable Language
Copyright © 2011-2017 Samuel Lidén Borell
This project is abandoned and superseded by the SLUL programming language project, which has similar goals.
What's LRL?
LRL is not at all finished yet, but it's goals are:
- Compatibility
- To be fully binary compatible with C. Regardless of whether you use it for applications, libraries or kernels. Or if you use the foreign function interface of some higher-level language like Python.
- This means no global GC, but instead safe manual memory management with type qualifiers. And no dynamic features of course, such as lambdas.
- Safety
- To be somewhat memory and thread safe, and where possible detect errors at compile time.
- Some level of "logic" safety might be offered in the future. For example,
detection of uninitialized and invalid values (such as
NaN
) at runtime, where this can't be verified at compile-time. Possibly, LRL might have constraints as well if it's not too hard to do. - Foreign functions can be annotated with safety features as well. Most code already allows safe usage if used in a structured way, it's just not annotated and checked by the programming language.
- Modularity
- Separation from interface and implementation, just like .c and .h files work in C. "Implementation" includes both data structures and code.
- LRL creates namespaces and finds header files for you if you organize them correctly.
- Allow for lazy inclusion of files and separate compilation.
- "Lightweightness"
- No more bloated than a C program.
- "Zero overhead principle" like in C++. Minimal initialization code and data segment variables.
- A "reference implementation" compiler is being written in ANSI C, and it has no dependencies on anything else. An optimizing LLVM/C++ port can be made later.
- Usability
- Don't do "magic" behind the programmers back.
- Offer expressiveness where it's safe and is easy to understand for the programmer.
- Try to make a usable language!
Some non-goals
- Elegance. If
and
is more usable than&&
then let's useand
. Breaking flow withgoto
is no more harmful thanif
, as long as it's used in a sane way. - Paradigms. Every function doesn't have to work on an object, like in some OO languages. Everything isn't a pure function. Etc.
Current status
- Frontend
- Tokenizer -- Almost done. No binary/octal.
- Parser -- Mostly done. No sizeof/offsetof, missing a lot of floating point stuff. Type parameter syntax might change in the future from list[int], to <int>list to allow [] to be used for array indices without #.
- Syntax tree -- Mostly done, needs optimizations.
- Type checker -- Some checks are missing, incomplete or broken. Especially checks related to type parameters and qualifiers. Errors messages are not so good and are usually repeated. Some expressions that should be allowed require extra "as"-expressions to work.
- Module loader -- Works, but doesn't check that header (i.e. interface) and implementation are compatible. The current system does not work with "make -f", since it's relative to the current directory. It might be changed in the future.
- Foreign-language interface
- C interop -- C headers that don't use complex C features can usually be parsed with minor modifications.
- Backend
- Null backend -- Does nothing. Only thing that's 100% implemented :D
- C translator -- Most features implemented in the parser and type checker work. Certain operations on arrays, structs and optional types doesn't work. Non-integer types doesn't work in switch statements. Etc.
- LLVM backend -- Not started.
Differences from other languages
Don't take list this to seriously! In some approximate order of similarity:
- C2 Language - Quite similar, both improve on the C language. C2 changes the compilation unit from object files to packages, while LRL changes many small details e.g. syntax, type compatibility, behavior of mixed-type integers, etc.
- Nimrod - LRL has similar goals, but LRL focuses more on compatibility between modules/libraries/versions and e.g. ABIs.
- Zimbu - LRL has similar goals, but focuses more on safety and less on OO.
- Rust - LRL strives for full C compatibility, but no tasks, blocks or binding.
- C - LRL has/will have better safety, modules, generic types.
- C++ - LRL is simpler, (probably?) safer but has less features. non-C features are C compatible
- Java - LRL is C compatible, compiled, lighter, less OO, less "enterprise-ish"