Nelumbo aims to be a powerful and extensible declarative logic programming language, designed for defining and executing custom syntax and semantics. As a meta-language, Nelumbo will be easily extensible, making it suitable for a wide range of applications. The goal is to integrate it with any IDE using the Language Server Protocol, allowing Nelumbo to serve as a language development platform. The language is currently developed in Java for seamless integration and performance. Please note that Nelumbo is in a very early stage of development, and incompatible changes are likely to occur.
- Features
- Documentation
- Building
- IDE Plugins
- Command-Line Interface
- Examples
- Releasing
- Contributing
- License
- Support
- Define and parse syntaxes
- Define and execute semantics
- Purely declarative semantics
- Define and run tests
- Easily extensible
- Easily integrable
- IDE integration via LSP, including auto-formatting
- Written in Java
Detailed documentation.
Requires Java 21 or later.
Build everything (core library, LSP server, and all IDE plugins):
./gradlew buildBuild individual components:
./gradlew jar # core library
./gradlew :lsp:server:serverJar # LSP server (shaded jar)
./gradlew :lsp:plugins:eclipse:jar # Eclipse plugin (includes LSP server)
./gradlew :lsp:plugins:intellij:build # IntelliJ plugin
./gradlew cliJar # command-line runner (shaded jar)Run tests:
./gradlew testNelumbo has LSP-based editor plugins for multiple IDEs:
| IDE | Path | Details |
|---|---|---|
| Eclipse | lsp/plugins/eclipse |
Dropins-based plugin with semantic highlighting |
| IntelliJ | lsp/plugins/intellij |
IntelliJ platform plugin |
| VS Code | lsp/plugins/vscode |
VS Code extension |
| Neovim | lsp/plugins/neovim |
Neovim LSP configuration |
See the README in each plugin directory for installation instructions.
NelumboCli parses and evaluates one or more .nl files from the terminal, printing each query together with its inferred result. Queries that declare expected results are compared and mismatches are reported as errors. Build the shaded jar with ./gradlew cliJar (output in build/libs/nelumbo-<version>-cli.jar) and run it with java:
java -jar build/libs/nelumbo-<version>-cli.jar [options] <file>...Pass - in place of a filename to read from stdin. Use -q / --quiet to suppress query output (errors are still reported) and -h / --help for the full option list. The process exits with 0 on success, 1 on parse/evaluation/comparison errors, and 2 on usage errors — suitable for scripting and CI.
Person :: Object
Male :: Person
Female :: Person
FactType ::= pc(<Person>,<Person>) // parent-child
Person ::= p(<Person>), // parent
c(<Person>), // child
a(<Person>), // ancestor
d(<Person>), // descendant
m(<Person>), // mother
f(<Person>) // father
Person a, b, c
Male y
Female x
c(a)=b <=> pc(a,b)
p(a)=b <=> pc(b,a)
m(a)=b <=> E[x](c(x)=a & b=x)
f(a)=b <=> E[y](c(y)=a & b=y)
a(a)=b <=> d(b)=a
d(a)=c <=> c(a)=c |
E[b](d(a)=b & c(b)=c)
Male ::= Hendrik, Bernhard, Claus, Willem
Female ::= Wilhelmina, Juliana, Beatrix, Maxima, Amalia
pc(Hendrik, Juliana)
pc(Wilhelmina, Juliana)
pc(Juliana, Beatrix)
pc(Bernhard, Beatrix)
pc(Beatrix, Willem)
pc(Claus, Willem)
pc(Willem, Amalia)
pc(Maxima, Amalia)
a(Amalia)=a ? [(a=Beatrix),(a=Maxima),(a=Hendrik),(a=Bernhard),(a=Juliana),(a=Claus),(a=Willem),(a=Wilhelmina)][..]
m(Amalia)=Maxima ? [()][]
m(Amalia)=Willem ? [][()]
m(Amalia)=a ? [(a=Maxima)][..]
f(Amalia)=a ? [(a=Willem)][..]
f(m(f(Amalia)))=a ? [(a=Bernhard)][..]
Integer ::= fib(<Integer>)
Integer n, f
fib(n)=f <=> f=n if n<=1,
f=fib(n-1)+fib(n-2) if n>1
fib(0)=f ? [(f=0)][..]
fib(1)=f ? [(f=1)][..]
fib(5)=f ? [(f=5)][..]
fib(100)=f ? [(f=36#22r8fozas3n8w3)][..]
fib(1000)=f ? [(f=36#18nrvsuayughau0blk8aylvbyaqwiaqba77rdsgscn5hzwgbgaws8i8svp4xdmoo82plxiyogd5iaj1cspez8zfeio92a76t9n1frssxklr92wyyxm8r903o1ofgncikuggcwnf)][..]
Releases are created automatically by CI. The process works as follows:
- You edit
RELEASE_NOTES.mdin the repository root with the release notes for the upcoming version. You can use${version}and${version-num}for the version tag and version number respectively. - You merge your changes to
master, that's it! - The build workflow runs. On success, the Gradle
mvgTaggerplugin creates and pushes a version tag (e.g.v1.2.3). - The tag push triggers the release workflow, which downloads the build artifacts and creates a GitHub release with the
contents of
RELEASE_NOTES.md.
The release includes the following artifacts:
- Editor — standalone Swing-based editor (
nelumbo-${version-num}-editor.jar) - Eclipse plugin — dropins-based plugin (
eclipse-nelumbo-plugin-${version-num}.jar) - IntelliJ plugin — LSP4IJ-based plugin (
intellij-nelumbo-plugin-${version-num}.zip) - Slides — presentation slides (
nelumbo-slides.zip)
If RELEASE_NOTES.md is absent, GitHub will auto-generate release notes from the commit log.
Contributions and feedback are welcome! Please open issues or pull requests on GitHub.
This project is licensed under the terms of the LICENSE file provided in the repository.
For questions or support, please use the GitHub Issues page.