kari

Crates.iokari
lib.rskari
version0.1.0
sourcesrc
created_at2019-11-13 12:22:20.200517
updated_at2019-11-13 12:22:20.200517
descriptionAn embeddable programming language, writting in and for Rust
homepage
repositoryhttps://github.com/kari-lang/kari/
max_upload_size
id180955
size110,812
Hanno Braun (hannobraun)

documentation

https://docs.rs/kari

README

Kari

Introduction

"std" import

"The answer to live is: " print
1 [ 2 3 7 ] [ * ] fold println

Kari is a programming language that is

  • embeddable: Designed to be embedded into a host application.
  • interpreted: The language is parsed and executed by an interpreter.
  • dynamic: Types are checked at runtime.
  • strong: Type conversions are always explicit.
  • stack-based: There are no variables. All data lives on an implicit stack.
  • postfix: An operation is preceded by its arguments

Kari is a general-purpose language, but by itself, it has very limited abilities to interact with the outside world. It is designed to be embedded into a host application, that would extend it to provide whatever domain-specific capabilities required.

Kari is written in Rust, and designed to be embedded into Rust applications.

Example use cases would be:

  • To computationally define geometry in a CAD application.
  • As a scripting language for a game engine.
  • A turing-complete configuration language for a complex application.

And whatever else you can come up with.

Current Status

Kari is usable, but still very raw and immature. It is lacking a lot of basic features and the ways it can be extended are currently limited. Don't use Kari for anything serious, unless you're perfectly comfortable with working on its interpreter.

That said, if you like the concepts presented here and are are willing to tinker, Kari could be a good place to start.

Usage

You can run Kari programs like this (requires just):

git clone https://github.com/kari-lang/kari.git
just run hello # or run any other example from `kr/examples`
just test # run all tests from `kr/tests`

To run your own programs, you should be able cargo install the Kari interpreter and use it to run your programs wherever they are located. This is currently not documented.

To embed Kari programs in your application, depend on the kari crate:

# Cargo.toml

[dependencies]
kari = "0.1"

The main entry point to Kari's API is Evaluator. You can use its API to run a Kari program. This is currently not documented.

Tutorial

Kari is a concatenative, stack-based language, which means there are no variables, and all data lives on an implicit stack. Consider the following Kari program.

1

This program consists of a single word, 1, which will push the value 1 to the stack. Integers are actually implemented as special syntax, but from a conceptual point of view, you can view 1 as a function that takes no input and pushes the value 1 on the stack.

Words in Kari are delimited by whitespace. A program with multiple words just executes the functions those words refer to in series.

1 2

This program consists of two words, which will push the values 1 and 2 to the stack. Kari doesn't care about which whitespace you use to delimit words, so the following program is completely equivalent.

1
2

So far we've only looked at functions that push words to the stack. But of course, functions can also pop values from the stack.

1 2 +

This program will push the values 1 and 2 to the stack. Then the + function will pop those two numbers from the stack and push 3, their sum. So the only value left on the stack at the end of the program is 3.

We can make this program more self-explanatory by adding a comment.

1 2 + # sums up `1` and `2`, leaving `3` on the stack

Comments are started with # and last until the next line break.

There are other values in Kari besides numbers.

true # a boolean
1 # an integer
2.0 # a float
"a string"
:a_symbol # symbols are much like strings, except they don't allow whitespace
[ 1 2 3 ] # a list of numbers
[ "a" "list" "of" "strings" ]

There are more functions we can call. Some are builtins, that are defined in the global namespace, others are defined in Kari's standard library, and have to be imported. The following program will load the standard library and import its functions into the local namespace.

"std" import

Once we did that we can use those functions defined in std, alongside the builtin functions.

"std" import

"Hello, world!" println # prints "Hello, world!" and a line break

1 2 = # compares `1` and `2`; leaves `false` on the stack, as they're not equal

true assert # will do nothing, but `false assert` would have failed the program

Since functions all share the implicit stack, we can change different functions together to create more complex operations.

1 2 + # add `1` and `2`, leaving `3` on the stack
3 =   # push another `3`, compare those `3`s using the equals operator
# `3` and `3` are equal, so the previous operation left `true` on the stack
assert # assert that the top value on the stack is `true`; consumes the value

Or shorter:

1 2 + 3 = assert # test the `+` function

There's a lot more to learn about the functions Kari provides, but let's close this tutorial with an important concept: How to define your own functions.

We've already seen all the concepts needed to understand function definition:

  • We've seen lists, and an anomymous function is just a list of words.
  • We've seen symbols, which can be used to define a function name.

The last piece we're missing is the builtin function define, which takes an anonymous function and a symbol, to define a new named function.

[ 2 + ] :add_two define

1 add_two 3 = assert

Reference

Currently there's no reference documentation that explains all language features, builtin functions and the standard library. Please refer to the following material:

License

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Commit count: 1057

cargo fmt