A static, type inferred and embeddable language written in Rust.

Overview

gluon

Build Status Gitter crates.io Documentation Book std

Gluon is a small, statically-typed, functional programming language designed for application embedding.

Features

  • Statically-typed - Static typing makes it easier to write safe and efficient interfaces between gluon and the host application.

  • Type inference - Type inference ensures that types rarely have to be written explicitly giving all the benefits of static types with none of the typing.

  • Simple embedding - Marshalling values to and from gluon requires next to no boilerplate, allowing functions defined in Rust to be directly passed to gluon.

  • UTF-8 by default - Gluon supports Unicode out of the box with utf-8 encoded strings and Unicode codepoints as characters.

  • Separate heaps - Gluon is a garbage-collected language but uses a separate heap for each executing gluon thread. This keeps each heap small, reducing the overhead of the garbage collector.

  • Thread-safe - Gluon is written in Rust, which guarantees thread safety. Gluon keeps the same guarantees, allowing multiple gluon programs to run in parallel (example)*

* Parallel execution of gluon programs is a recent addition and may still have issues such as deadlocks.

Examples

Hello world

let io = import! std.io
io.print "Hello world!"

Factorial

let factorial n : Int -> Int =
    if n < 2
    then 1
    else n * factorial (n - 1)

factorial 10

24

// # 24
//
// From http://rosettacode.org/wiki/24_game
//
// Write a program that randomly chooses and displays four digits, each from 1 ──► 9 (inclusive) with repetitions allowed.
//
// The program should prompt for the player to enter an arithmetic expression using just those, and all of those four digits, used exactly once each. The program should check then evaluate the expression.
//
// The goal is for the player to enter an expression that (numerically) evaluates to 24.
//
// * Only the following operators/functions are allowed: multiplication, division, addition, subtraction
// * Division should use floating point or rational arithmetic, etc, to preserve remainders.
// * Brackets are allowed, if using an infix expression evaluator.
// * Forming multiple digit numbers from the supplied digits is disallowed. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong).
// * The order of the digits when given does not have to be preserved.
//
//
// ## Notes
//
//     The type of expression evaluator used is not mandated. An RPN evaluator is equally acceptable for example.
//     The task is not for the program to generate the expression, or test whether an expression is even possible.


// The `import!` macro are used to load and refer to other modules.
// It gets replaced by the value returned by evaluating that module (cached of course, so that
// multiple `import!`s to the same module only evaluates the module once)
let io @ { ? } = import! std.io
let prelude = import! std.prelude
let { Result } = import! std.result
let array @ { ? } = import! std.array
let int = import! std.int
let string = import! std.string
let list @ { List, ? } = import! std.list
let random = import! std.random
let string = import! std.string

// Since imports in gluon returns regular values we can load specific parts of a module using pattern matches.
let char @ { ? } = import! std.char

let { (<>) } = import! std.semigroup
let { flat_map } = import! std.monad

let { (*>), (<*), wrap } = import! std.applicative

let { for } = import! std.traversable

type Op = | Add | Sub | Div | Mul
type Expr = | Int Int | Binop Expr Op Expr

let parse : String -> Result String Expr =
    // Gluon has a small parser combinator library which makes it easy to define an expression parser
    let parser @ {
        between,
        satisfy,
        satisfy_map,
        spaces,
        token,
        digit,
        skip_many1,
        recognize,
        lazy_parser,
        chainl1,
        (<?>),
        ? } = import! std.parser
    let { (<|>) } = import! std.alternative

    let lex x = x <* spaces

    let integer =
        // `do` expression provide a way to write monads in a way similiar to procedural code
        do i = lex (recognize (skip_many1 digit))
        match int.parse i with
        | Ok x -> wrap x
        | Err _ -> parser.fail "Unable to parse integer"

    let operator =
        satisfy_map (\c ->
            match c with
            | '*' -> Some Mul
            | '+' -> Some Add
            | '-' -> Some Sub
            | '/' -> Some Div
            | _ -> None)
            <?> "operator"

    rec
    let atom _ =
        parser.functor.map Int integer
            <|> between (lex (token '(')) (lex (token ')')) (lazy_parser expr)

    let binop _ =
        let op_parser =
            do op = lex operator
            wrap (\l r -> Binop l op r)
        chainl1 (atom ()) op_parser

    let expr _ = binop ()
    in

    // Gluon makes it possible to partially apply functions which we use here to scope all parser functions
    // inside the `let parse` binding above.
    let parse : String -> Result String Expr = parser.parse (expr () <* spaces)
    parse

/// Validates that `expr` contains exactly the same integers as `digits`
let validate digits expr : Array Int -> Expr -> Bool =
    let integers xs expr : List Int -> Expr -> List Int =
        match expr with
        | Int i -> Cons i xs
        | Binop l _ r -> integers (integers xs l) r
    let ints = integers Nil expr

    list.sort (list.of digits) == list.sort ints

let eval expr : Expr -> Int =
    match expr with
    | Int i -> i
    | Binop l op r ->
        let f =
            // Operators are just functions and can be referred to like any other identifier
            // by wrapping them in parentheses
            match op with
            | Add -> (+)
            | Sub -> (-)
            | Div -> (/)
            | Mul -> (*)
        f (eval l) (eval r)

do digits =
    let gen_digit = random.thread_rng.gen_int_range 1 10
    do a = gen_digit
    do b = gen_digit
    do c = gen_digit
    do d = gen_digit
    wrap [a, b, c, d]

let print_digits = for digits (\d ->
        seq io.print " "
        io.print (show d))
seq io.print "Four digits:" *> print_digits *> io.println ""

let guess_loop _ =
    do line = io.read_line
    // Exit the program if the line is just whitespace
    if string.is_empty (string.trim line) then
        wrap ()
    else
        match parse line with
        | Err err -> io.println err *> guess_loop ()
        | Ok expr ->
            if validate digits expr then
                let result = eval expr
                if result == 24
                then io.println "Correct!"
                else io.println ("Incorrect, " <> int.show.show result <> " != 24") *> guess_loop ()
            else
                io.println
                    "Expression is not valid, you must use each of the four numbers exactly once!"
                    *> guess_loop ()

guess_loop ()

Source

Getting started

Try online

You can try gluon in your browser at https://gluon-lang.org/try/. (Github)

Install

Gluon can be installed by using one of the prebuilt executables at Github or you can use Cargo in order to install the gluon_repl crate:

cargo install gluon_repl

REPL

Gluon has a small executable that can be used to run gluon programs directly or in a small REPL. The REPL can be started by passing the -i flag to the built repl executable which can be run with cargo run -p gluon_repl -- -i.

REPL features:

  • Evaluating expressions (expressions of type IO will be evaluated in the IO context).

  • Bind variables by writing let <pattern> <identifier>* = <expr> (omitting in <expr> from a normal let binding) Example:

       let f x = x + 1
       let { x, y = z } = { x = 1, y = 2 }
       f z
    
  • Printing help about available commands with :h

  • Loading files with :l path_to_file the result of evaluating the expression in the loaded file is stored in a variable named after the filename without an extension.

  • Checking the types of expressions with :t expression

  • Printing information about a name with :i name.
    Example:

    :i std.prelude.List
    type std.prelude.List a = | Nil | Cons a (std.prelude.List a)
    /// A linked list type
    
  • Tab-completion of identifiers and record fields repl completion

  • Exit the REPL by writing :q

Tools

Language server

Gluon has a language server which provides code completion and formatting support. Installation is done with cargo install gluon_language-server.

Visual Studio Code Extension

The gluon extension for Visual Studio Code provides syntax highlighting and completion. To install it, search for gluon among the extensions. (Github)

example

Vim plugin

vim-gluon provides syntax highlighting and indentation.

The gluon language server has been tested to work with https://github.com/autozimu/LanguageClient-neovim and https://github.com/prabirshrestha/vim-lsp.

Example configuration (autozimu/LanguageClient-neovim)

let g:LanguageClient_serverCommands = {
    \ 'gluon': ['gluon_language-server'],
    \ }

" Automatically start language servers.
let g:LanguageClient_autoStart = 1

nnoremap <silent> K :call LanguageClient_textDocument_hover()<CR>
nnoremap <silent> gd :call LanguageClient_textDocument_definition()<CR>

Documentation

The Gluon Book

Gluon Standard Library API Reference

Rust API Docs

Usage

Rust

Gluon requires a recent Rust compiler to build (1.9.0 or later) and is available at crates.io. It can easily be included in a Cargo project by adding the lines below.

[dependencies]
gluon = "0.17.2"

Other languages

Currently, the easiest way to interact with the gluon virtual machine is through Rust but a rudimentary C api exists which will be extended in the future to bring it closer to the Rust API.

Contributing

There are many ways to contribute to gluon. The two simplest ways are opening issues or working on issues marked as beginner. For more extensive information about contributing, you can look at CONTRIBUTING.md. Contributing also has details on running/getting-started-with tests for gluon.

Goals

These goals may change or be refined over time as I experiment with what is possible with the language.

  • Embeddable - Similiar to Lua - it is meant to be included in another program that may use the virtual machine to extend its own functionality.

  • Statically typed - The language uses a Hindley-Milner based type system with some extensions, allowing simple and general type inference.

  • Tiny - By being tiny, the language is easy to learn and has a small implementation footprint.

  • Strict - Strict languages are usually easier to reason about, especially considering that it is what most people are accustomed to. For cases where laziness is desired, an explicit type is provided.

  • Modular - The library is split into its parser, type checker, and virtual machine + compiler. Each of these components can be used independently of each other, allowing applications to pick and choose exactly what they need.

Inspiration

This language takes its primary inspiration from Lua, Haskell and OCaml.

Comments
  • [WIP] Derive Getable/Pushable

    [WIP] Derive Getable/Pushable

    As mentioned in #539, I started playing around with deriving Getable/Pushable. The current implementation for Getable works quite well for normal enums, but does not work properly with lifetimes yet (which make a lot of sense for things like &str). I'm not sure how I can marshal generic parameters (looking at things like api::generic::* I assume there it's possible somehow).

    Pushable should be a lot easier to implement because the data needs to be copied anyway, meaning there are no lifetimes getting in the way.

    opened by Laegluin 22
  • Allow userdata to contain gluon values without reference cycles

    Allow userdata to contain gluon values without reference cycles

    I'm using gluon to add some user functionality to a program, like this:

    process_file {
      // do some built in processing
      // IF no script was specified at the command line, stop here.
      // create new gluon vm
      // create user library
      // compile and run gluon script => gluon script exports some callbacks
      // repeatedly call the gluon callbacks
      // vm should be freed at this point
    }
    

    When process_file is called for >100 files without a script, the memory usage stays at ~10MB all the time (measured using the time command). When a script is specified, the memory usage at the end of the program (according to valgrind) is >100MB. When the 100 files are specified multiple times at the command line, the memory usage rises accordingly. i.e., 4 times these 100 files, 400MB memory used at the end.

    Where to look for the memory leak?

    enhancement vm 
    opened by hce 21
  • feat: Add std.io.read/write and std.disposable

    feat: Add std.io.read/write and std.disposable

    This is a somewhat working prototype of #653.

    Still missing:

    • [x] docs
    • [ ] tests
    • [x] fix broken tests
    • [x] add breaking changes to commit messages
    • [x] there's a bug in read_file_to_end I must have introduced in the last few commits
    • [ ] I'm honestly not exactly sure what gluon's multithreading model is; right now, buffered IO definitely has a few race conditions

    Closes #653

    opened by Laegluin 18
  • Improve compilation times of gluon_parser

    Improve compilation times of gluon_parser

    This is causing timeout woes with travis and makes things hard for users on stable. As discussed on https://github.com/Marwes/gluon/issues/33#issuecomment-233157725 and https://github.com/Marwes/gluon/pull/66#issuecomment-234803447 we could possibly consider switching to a parser generator like rustpeg of LALRPOP.

    performance parser 
    opened by brendanzab 15
  • How does marshalling data to and from gluon work?

    How does marshalling data to and from gluon work?

    Hi folks!

    I've been evaluating gluon and have a documentation question. In the features list there's this promise:

    Simple embedding - Marshalling values to and from gluon requires next to no boiler plate allowing functions defined in Rust to be directly passed to gluon.

    That sounds great! I've read the embedding API materials, have read through the API docs and have been poking around in the test code in this repository but can't figure out how you do this. In particular, I want to define a struct in rust, pass it to a function in gluon for modification and then continue on with my modified struct. I sort of see how part of that's done with with example:

    fn factorial(x: i32) -> i32 {
        if x <= 1 { 1 } else { x * factorial(x - 1) }
    }
    let vm = new_vm();
    vm.define_global("factorial", factorial as fn (_) -> _)
        .unwrap();
    let (result, _) = Compiler::new()
        .run_expr::<i32>(&vm, "example", "factorial 5")
        .unwrap();
    assert_eq!(result, 120);
    

    in that .run_expr::<i32>(&vm, "example", "factorial 5") shows how a function with an argument gets called but if I wanted to pass a more complicated structure through like

    struct Point {
      x: i64,
      y: i64,
      meta: HashMap<String, String>,
    }
    

    then I'm left at a loss. If I wanted to create a Point in rust and then pass that to a gluon function which would double both x and y and then add a pair "gluon": "very useful!" to the Point, how would I do that?

    Thanks!

    opened by blt 14
  • feat: Add row polymorphic records

    feat: Add row polymorphic records

    This PR implements row polymorphic records which should make records much more flexible at the expense of some performance.

    Left to do:

    • [x] Add comments
    • [x] Handle polymorphic records in the vm
    • [x] Fix pretty printing of polymorphic records
    • [x] Add tests to test row kinds specifically
    • [x] Improve row polymorphism related error messages

    Fixes #92

    opened by Marwes 14
  • use fnv instead of SipHasher for HashMaps. add type FnvMap

    use fnv instead of SipHasher for HashMaps. add type FnvMap

    @brendanzab mentioned putting the FnvMap alias elsewhere, the map appears to be most used in base/src though. I'm open to any suggestions.

    All tests pass.

    Fixes #95

    opened by leshow 11
  • [WIP] feat(std): add monad transformer interface, StateT, and LazyT

    [WIP] feat(std): add monad transformer interface, StateT, and LazyT

    Description

    Adds a monad-transformer interface Transformer, a State monad transformer StateT, and a Lazy monad transformer LazyT to the standard library.

    Related PRs

    Lays groundwork for Streamlike and the new parser #687.

    Status

    Merged

    Outstanding design questions

    • [x] ~~Can and should StateT be replaced by the effects system?~~ (not for the time being, at least)
    • [x] ~~Should Transformer require monad field?~~ (Basing monads on their transformers is the better option)
    • [ ] Should StateT and LazyT (and other monad transformers) be merged with their non-transformer counterparts?

    To Do

    • [x] ~~Fix StateT's implicit parameter bugs~~ (#688 & #689)
    • [x] ~~add tests~~
    • [ ] add inline docs

    Prior Art

    opened by Etherian 10
  • feat(vm): Rewrite global handling to be abstracted from users

    feat(vm): Rewrite global handling to be abstracted from users

    Will tackle #340 as well as some other related things with global variables (see e26c12803c4f691ae895d5176c356ec8cd4c08bd).

    🚲 🏠

    • What should string_prim, etc be called?
    • Should we hide them away with more obviously internal names or lock them away with something like @NO-IMPLICIT-PRELUDE?
    • array, reference, lazy are full modules meant to be used. Should we perhaps put make them loadable as import! "std.array" etc? (Probably)
    • Since we have non-file modules now. Should we call import! as import! "std.bool" instead of import! "std/bool.glu"?
      • import! "std.bool" vs import! std.bool?
    opened by Marwes 10
  • Rename MaybeError to something better

    Rename MaybeError to something better

    MaybeError is used to represent results for functions which may 'panic' (in the context of gluon not Rust). MaybeError is a really terrible name for this however so renaming it is a good idea.

    Possible names:

    enum Panicking<T, E> { }
    enum Panic<T, E> { }
    enum Diverging<T, E> { }
    // More?
    

    Let the bikeshedding comence!

    beginner 
    opened by Marwes 10
  • Fix repl record destructuring

    Fix repl record destructuring

    This fixes the record-restructuring bug in the repl, where records are treated like tuples and let {foo} = {bar = “bar”, foo = “foo”} followed by foo displays ”bar”.

    I couldn’t access any of the existing GcPtr<DataStruct>::get_field or Data::lookup_field methods from the repl crate, so I added one to RootedValue. It makes things consistent since there is already a get method that takes an index.

    There are a few FIXME notes where I could use some advice on what to do.

    opened by mikeyhew 9
  • stateful run_expr

    stateful run_expr

    let vm = gluon::new_vm();
    vm.get_database_mut().set_implicit_prelude(true);
    vm.run_io(true);
    
    vm.run_expr::<()>("ex", r#"
      let x = 23
      ()
    "#);
    
    vm.run_expr::<i32>("ex", r#" x "); 
    

    This gets me an error of "UndefinedVariable".

    If I want do something "repl-like" where we define something in one command, then reference it in the next, is that possible in gluon ?

    I tried reading https://github.com/gluon-lang/gluon/tree/master/repl/src but then got confused when it loads up https://github.com/gluon-lang/gluon/blob/master/repl/src/repl.glu

    I'm trying to get a gluon REPL-ish to run on Chrome/wasm. Thus, I can't rely on the "io" stuff for now.

    opened by ide5kllc 0
  • Function to convert List to Array or to sort Array by key?

    Function to convert List to Array or to sort Array by key?

    I found the function to convert a List to an Array (of), but it seems there is no function to do the reverse? It would be useful to have it in the std library, e.g.:

    let list_to_arr l = 
        match l with
            | Nil -> [] 
            | Cons head tail -> append [head] (list_to_arr tail)
    

    Or (with tail call & accumulator):

    let list_to_array l = 
        let to_array acc l =
            match l with
                | Nil -> acc
                | Cons head tail -> to_array (append acc [head]) tail
        to_array [] l
    

    Btw, does gluon do any tail call optimization? :)

    I'm asking because I'm working with a lot of long arrays and I need to often sort them. The only sort function I found in std is for lists, but I need sort_by_key for arrays.

    I tried doing

    fn sort_by_key<T, K: std::cmp::Ord>(mut arr: Vec<T>, f: &dyn Fn(&T) -> K) -> Vec<T> {
    	arr.sort_by_key(f);
    	arr
    }
    // ...
    ExternModule::new(vm, record! {
        sort_by_key => primitive!(2, sort_by_key),
        // ...
    })
    

    but I got all kinds of errors because of the generics and because the Fn can't cross the FFI boundary. Is there any way to make it work? :)

    Then I tried to write sort_by_key for arrays in the repl, like this (based on sort for List):

    let { append, Array } = import! std.array
    let { List, of, ? } = import! std.list
    
    let list_to_array l = 
        let to_array acc l =
            match l with
                | Nil -> acc
                | Cons head tail -> to_array (append acc [head]) tail
        to_array [] l
    
    let sort_by_key arr key : forall a k. [Ord k] -> Array a -> (a -> k) -> Array a =
        let prelude @ { Ordering, ? } = import! std.prelude
        let { Semigroup, Monoid, Eq, Show } = prelude
        let { Functor, Applicative, Alternative, Monad } = prelude
        let { Foldable } = import! std.foldable
        let { Traversable } = import! std.traversable
        let { Bool } = import! std.bool
        let array @ { ? } = import! std.array
        let { (<>) } = import! std.semigroup
        let { compare } = import! std.cmp
        let { map } = import! std.functor
        let { (<*>), wrap } = import! std.applicative
        let { (<|>) } = import! std.alternative
        let { List, of, ? } = import! std.list
        rec let scan compare xs less equal greater : (a -> Ordering)
                -> List a
                -> List a
                -> List a
                -> List a
                -> (List a, List a, List a)
            =
            match xs with
            | Nil -> (less, equal, greater)
            | Cons y ys ->
                match compare y with
                | LT -> scan compare ys (Cons y less) equal greater
                | EQ -> scan compare ys less (Cons y equal) greater
                | GT -> scan compare ys less equal (Cons y greater)
        in
        rec
        let sort xs : /*[Ord a] ->*/ List a -> List a =
            match xs with
            | Nil -> Nil
            | Cons pivot ys ->
                let (less, equal, greater) = scan (\a -> compare (key a) (key pivot)) ys Nil (Cons pivot Nil) Nil
                sort less <> equal <> sort greater
        list_to_array (sort (of arr))
    
    sort_by_key [{ t = 1., k = "a" }, {t = 0., k = "b" }] (\e -> e.t)
    

    It works but it's quite slow. Ideally I'd want to use the FFI because I'm working with large arrays of thousands of items and the sorting should be fast if possible :)

    opened by Boscop 0
  • Runtime error on WASM

    Runtime error on WASM

    When I try to use gluon on Wasm (in a web frontend using trunk serve), I get this runtime error:

    Uncaught TypeError: Failed to resolve module specifier "env". Relative references must start with either "/", "./", or "../".

    I'm using the latest version with these features:

    gluon = { git = "https://github.com/gluon-lang/gluon", default-features = false, features = ["random"] }
    gluon_codegen = { git = "https://github.com/gluon-lang/gluon" }
    

    (When I don't call the function that uses gluon, the frontend works fine without errors.)

    Any idea why it's not working? :)

    opened by Boscop 3
  • How to check return type of script before trying to convert it?

    How to check return type of script before trying to convert it?

    In my use case, after evaluating a script, the final value can be one of several types that I want to support. E.g. I want to support 5 different custom types that the script can produce. The final value of the script should not be an enum though! So after evaluating a script, how can I check which gluon type the final value is, before I try to convert it to the equivalent Rust type? :) Or can I evaluate a script and then try converting the final value to a Rust type, to check if it succeeds?

    opened by Boscop 1
  • Sandboxing by disallowing file/network access?

    Sandboxing by disallowing file/network access?

    Is it possible to disallow file/network access for sandboxing purposes? :)

    The only way to interface with the outside world should be through the FFI that the host provides.

    (Related to my use case https://github.com/gluon-lang/gluon/issues/936)


    Bonus question: How can I capture stdout/stderr output so that I can send it over the network? (E.g. as two std channels that receive each line as it gets printed, or (if that's not possible) two Strings that contain the accumulated output at the end.)

    opened by Boscop 1
Releases(v0.17.2)
A computer programming language interpreter written in Rust

Ella lang Welcome to Ella lang! Ella lang is a computer programming language implemented in Rust.

Luke Chu 64 May 27, 2022
Lisp dialect scripting and extension language for Rust programs

Ketos Ketos is a Lisp dialect functional programming language. The primary goal of Ketos is to serve as a scripting and extension language for program

Murarth 721 Dec 12, 2022
Source code for the Mun language and runtime.

Mun Mun is a programming language empowering creation through iteration. Features Ahead of time compilation - Mun is compiled ahead of time (AOT), as

The Mun Programming Language 1.5k Jan 9, 2023
Rhai - An embedded scripting language for Rust.

Rhai - Embedded Scripting for Rust Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way to add scripti

Rhai - Embedded scripting language and engine for Rust 2.4k Dec 29, 2022
Interpreted language developed in Rust

Xelis VM Xelis is an interpreted language developed in Rust. It supports constants, functions, while/for loops, arrays and structures. The syntax is s

null 8 Jun 21, 2022
REPL for the Rust programming language

Rusti A REPL for the Rust programming language. The rusti project is deprecated. It is not recommended for regular use. Dependencies On Unix systems,

Murarth 1.3k Dec 20, 2022
A rusty dynamically typed scripting language

dyon A rusty dynamically typed scripting language Tutorial Dyon-Interactive Dyon Snippets /r/dyon Dyon script files end with .dyon. To run Dyon script

PistonDevelopers 1.5k Dec 27, 2022
Oxide Programming Language

Oxide Programming Language Interpreted C-like language with a Rust influenced syntax. Latest release Example programs /// recursive function calls to

Arthur Kurbidaev 113 Nov 21, 2022
The hash programming language compiler

The Hash Programming language Run Using the command cargo run hash. This will compile, build and run the program in the current terminal/shell. Submit

Hash 13 Nov 3, 2022
Interactive interpreter for a statement-based proof-of-concept language.

nhotyp-lang Nhotyp is a conceptual language designed for ease of implementation during my tutoring in an introductive algorithmic course at Harbin Ins

Geoffrey Tang 5 Jun 26, 2022
🍖 ham, general purpose programming language

?? ham, a programming language made in rust status: alpha Goals Speed Security Comfort Example fn calc(value){ if value == 5 { return 0

Marc Espín 19 Nov 10, 2022
A small programming language created in an hour

Building a programming language in an hour This is the project I made while doing the Building a programming language in an hour video. You can run it

JT 40 Nov 24, 2022
The Loop programming language

Loop Language Documentation | Website A dynamic type-safe general purpose programming language Note: currently Loop is being re-written into Rust. Mea

LoopLanguage 20 Oct 21, 2022
Scripting language focused on processing tabular data.

ogma Welcome to the ogma project! ogma is a scripting language focused on ergonomically and efficiently processing tabular data, with batteries includ

kdr-aus 146 Dec 26, 2022
Stackbased programming language

Rack is a stackbased programming language inspired by Forth, every operation push or pop on the stack. Because the language is stackbased and for a ve

Xavier Hamel 1 Oct 28, 2021
A safe-against-invalid-input version of wren.io, written in Rust.

safe_wren A nearly-complete implementation of the Wren language (wren.io) in Rust. The original https://github.com/wren-lang/wren from wren.io is refe

Rubber Duck Engineering 20 Jul 16, 2022
Diplo is a script runner and dependency manager made in rust mainly for Deno.

Diplo is a script runner and dependency manager made in rust mainly for Deno. Documentation Tricked.pro/diplo Installing - windows installer Features

Tricked 23 May 9, 2022
A Python compiler targeting JS, implemented in Rust.

A Python compiler targeting JavaScript, implemented in Rust.

Gideon Grinberg 5 Jun 17, 2021
A safe, fast, lightweight embeddable scripting language written in Rust.

Bud (budlang) A safe, fast, lightweight embeddable scripting language written in Rust. WARNING: This crate is not anywhere near being ready to publish

Khonsu Labs 13 Dec 27, 2022
Docker images for compiling static Rust binaries using musl-libc and musl-gcc, with static versions of useful C libraries. Supports openssl and diesel crates.

rust-musl-builder: Docker container for easily building static Rust binaries Source on GitHub Changelog UPDATED: Major updates in this release which m

Eric Kidd 1.3k Jan 1, 2023