#clojure #lisp #configuration #configuration-language #convert #eval #environment

bin+lib risp

受 Clojure 启发的 Rusty Lisp,用作简单的配置语言

9 个版本 (破坏性更新)

使用旧的 Rust 2015

0.7.0 2017 年 5 月 10 日
0.6.1 2017 年 5 月 3 日
0.6.0 2017 年 4 月 28 日
0.5.0 2017 年 4 月 26 日
0.1.0 2017 年 4 月 15 日

配置 中排名第 657

每月下载量 36
serde-yaml-risp 中使用

MIT 许可证 MIT

46KB
1K SLoC

Risp 构建状态 codecov Crate 版本

受 Clojure 启发的 Rusty Lisp,用作简单的配置语言。

Rust 中的使用

  extern crate risp;
  
  use risp::eval_risp_script;
  use risp::types::RispType::Int;
  use risp::core::create_core_environment;
  
  #[test]
  fn test_minimal_example() {
     let mut env = create_core_environment();
     env.set("var", Int(2));
  
     let risp_script = "(+ 40 var)";
     let result = eval_risp_script(risp_script, &mut env);
  
     assert_eq!(result, Ok(Int(42)));
  }

Risp 示例,展示所有现有语言功能

; The risp kitchen sink - yes this line is a single line comment.

(def my_int 2)

(def my_vector [1 my_int 3])

; repeat [1 2 3] 2 times => [1 2 3 1 2 3]
(def repeated (rep 2 1 2 3))

; => [11 21]
(def vector_sum1 (+ 1 [10 20]))

; => [21 22]
(def vector_sum2 (+ [1 2] [10 20]))

; => [11 12 21 22] (it wraps!)
(def vector_sum3 (+ [1 2] [10 10 20 20]))

(comment
  (this is not evaluated)
  (it can have multiple lines)
  (but must have valid risp syntax))

; Define a function
(defn double [x] (* x 2))

; Function which returns a function (some call it a closure), which adds x1 to its single argument
(defn create_adder [x1]
  (fn [x2] (+ x1 x2)))

(def add_20 (create_adder 20))

; variadic function, notes is a vector of all remaining arguments after name
(defn create_song [name & notes]
  {:name name :notes notes})

; This last expression (it's a map in this case) will be returned.
{:yes          true
 :no           false
 :added        (+ my_int 20)
 :multiplied   (* my_int 20)
 :divided      (* 10 2)
 :substracted  (- 10 2)
 :doubled      (double 21)
 :added_20     (add_20 3)
 :vector_sum1  vector_sum1
 :vector_sum2  vector_sum2
 :vector_sum3  vector_sum3
 :repeated     repeated
 :my_vector    my_vector
 :my_map       {:key my_int}
 :my_string    "Hello"
 :my_do_result (do
                 (def my_int_2 20)
                 (+ my_int my_int_2))
 :song         (create_song "Sweet Dreams" 1 2 3 4)}

将评估后的 Risp 转换为 Rust

extern crate risp;

use risp::eval_risp_script;
use risp::core::create_core_environment;

struct SimpleSong {
    name: String,
    speed: i64,
    notes: Vec<i64>
}

#[test]
fn test_convert_to_struct_example() {
    let mut env = create_core_environment();

    let risp_script = r#"
    {
        :name "Name"
        :speed 220
        :notes [1 2 3]
    }"#;

    let result = eval_risp_script(risp_script, &mut env).unwrap();

    let simple_song = SimpleSong {
        name: result.get("name").unwrap().unwrap(),
        speed: result.get("speed").unwrap().unwrap(),
        notes: result.get("notes").unwrap().unwrap()
    };

    assert_eq!(simple_song.name, "Name");
    assert_eq!(simple_song.speed, 220);
    assert_eq!(simple_song.notes, vec![1, 2, 3]);
}

目标

  • 简单的配置语言
  • Clojure 的子集,嗯,有点类似

秘密真实目标

非目标

  • 性能
  • 完整性

依赖关系

~3.5MB
~72K SLoC