This library defines a JSON to JSON transform and templating language. The language itself is inspired by JavaScript. Expressions always terminate, as the language has no form of recursion. This means that while there are loops, they only operate on input arrays. So it is possible to iterate over an array, and even pairs of arrays, but it is not possible to implement recursion.
- Operators,
+,-,*,/,==,!=,>=,<=,>,<,&&,||with precendence taken from the C++ standard. - Arrays,
[1, 2, "test", 123.123, [123, 2]] - Objects,
{ "test": "123", concat("test", "test"): 321 } - Built in functions, like
map,float,concat, etc. Eitherpow(base, exp) or base.pow(exp) - Functors,
mapis a functor, meaning it accepts a lambda:map(arr, field => ...)orarr.map(field => ...) - Selector expressions,
[1, 2, 3][1] == 2,input.field.value["dynamic"], etc. - Macros,
#my_macro := (a, b) => a + b; my_macro(1, 2)
There are several ways of using Kuiper. It can be used both as a standalone program, and as a library in other programs.
The easiest way to start using Kuiper is to use the standalone CLI. See the kuiper CLI README for more info on the CLI.
Kuiper can also be used as a Rust library.
use kuiper_lang::compile_expression;
use serde_json::json;
let transform = compile_expression("input.value + 5", &["input"]).unwrap();
let input = [json!({ "value": 2 })];
let result = transform.run(input.iter()).unwrap();
assert_eq!(result.as_u64().unwrap(), 7);Bindings to several other languages exists, for more info on those see their specific package:
This library contains part of a compiler:
lexercontains a lexer built onLogos, which converts the input to a sequence of spanned tokens. The first stage of the compilation outputs an iterator ofResult<Token, LexerError>parsecontains glue code for a parser generated bylalrpop. The grammar file itself isjsontf.lalrpop. Here you will find the AST for the language, which is the output of the second stage of compilation.expressionscontains a large set of executable expressions. The executable tree is first build bycompiler/exec_tree.rs.compiler/optimizer.rscontains the fourth and final stage of the compiler, which attempts to execute each part of the program recursively. If this fails with asource missingerror, we traverse its children recursively. If it fails with any other error, this is a compile-time error. If it succeeds, the expression is replaced by a constant. This stage also replaces the variable identifiers with indexes in the input array.
So in summary, an expression is produced from raw input -> Token stream -> AST -> Expression tree -> Optimized tree
This repository contains a number of language bindings and auxillary packages, the following is an overview:
kuiper_langis the rust crate containing the language itself.kuiper_cliis a CLI tool for kuiper, letting you use it like you would a tool likejq. It also contains a REPL.kuiper_documentationcontains utilities for generating markdown documentation as well as a few source code files from a list of built-in functions infunctions.yaml.kuiper_interopis a set of C bindings forkuiper_lang, these are currently used forKuiperNetonly.kuiper_javais java bindings for kuiper, using JNI. These are not currently published anywhere.kuiper_jsis a set of WASM bindings for kuiper, published to NPM.kuiper_lezeris a lezer library for kuiper. Lezer is a JS library to create parsers. It is used for the frontend code editor.kuiper_frontend_testis a very simple react app usingkuiper_jsandkuiper_lezerto provide a live editor.kuiper_lang_macrosis an auxillary macro library used forkuiper_lang.kuiper_pythoncontains python bindings for kuiper, usingpyo3. These are published to PyPI.KuiperNetcontains .NET bindings for kuiper. These are published to nuget, with native binaries for Windows and Linux.KuiperNet.Testis a test project forKuiperNet.fuzzis a set of fuzz tests for kuiper.