#s-expr #scheme #マクロ #lisp #scheme-interpreter #parser

マクロ カモマクロ

セックスプレスをカモ値にパースするマクロ

6リリース

0.1.6 2024年4月16日
0.1.5 2024年4月11日
0.1.2 2024年1月19日

#7 in #s-expressions

Download history 241/week @ 2024-04-10 45/week @ 2024-04-17 3/week @ 2024-04-24 4/week @ 2024-05-22 1/week @ 2024-06-05 1/week @ 2024-06-12

330 ドラウンド/月
カモで使用されています

MIT/Apache

79KB
2K SLoC

カモマクロ

Build Status Crates.io Crates.io

カモ(カモ)は日本語で「カモ」の意味です。

このパッケージはカモパッケージ用のプロシージャーマクロを提供します。提供されるマクロは以下の通りです:

  • sexpr!(<mutator>, <expression>) - 文字列から単一のセックスプレスをパースするマクロです。それがkamo::value::Valueを返します。

  • sexpr_file!(<mutator>, <filename>) - ファイルから複数のセックスプレスをパースするマクロです。それがkamo::value::Valueの配列を返します。配列は空でなくても良くなります。

  • sexpr_script!(<mutator>, <filename>) - 文字列から複数のセックスプレスをパースするマクロです。それがkamo::value::Valueの配列を返します。配列は空でなくても良くなります。

これらのマクロはオプションのMutatorRef識別子を受け取ります。これはヒープ上に値を割り当てるために使用されます。もし式にヒープ上に割り当てる必要がある値が含まれていない場合、Mutator識別子を省略することができます。

マクロの構文は、readプロシージャに対して定義されたR7RS標準のスケームによって定義されます。構文定義は標準の"7.1.2 外部表現"セクションの<datum>です。

標準からの構文の逸脱は以下の通りです:

  • 不支持数字的精确度(#e#i)。浮点数始终是不精确的,整数始终是精确的。

  • 数字只能是带符号的64位整数或IEEE 754双精度浮点数。标准允许任意精度的整数、有理数和复数。

  • 不支持标签。

  • 仅在解析多个s表达式的外部宏中支持 #; 注释语法。 #; 注释语法不能嵌套。

  • 由十六进制转义序列定义的字符字面量可以有1到6位数字。标准期望至少有1位数字。代码必须是有效的Unicode码点。

解析器使用 pest 包实现。语法在 src/sexpr/sexpr.pest 中定义。这是必要的,因为在此处不能使用定义在 kamo::parser 中的组合解析库。这将导致循环依赖。未来将在 kamo::form 模块中实现s表达式的解析器。它将基于 kamo::parser 包实现,并将由Rust解释器使用。

示例

use kamo::{mem::Mutator, sexpr, value::{print, Value}};
 
let m = Mutator::new_ref();
let value = sexpr!(m, "(1 2 3)");
 
assert_eq!(print(value).to_string(), "(1 2 3)");
use kamo::{sexpr_file, value::{print, Value}};
 
let m = Mutator::new_ref();
let values = sexpr_file!("tests/sexpr/values.scm");
 
assert_eq!(values.len(), 3);
assert_eq!(print(values[0].clone()).to_string(), "()");
assert_eq!(print(values[1].clone()).to_string(), "100");
assert_eq!(print(values[2].clone()).to_string(), "#t");

let values: &[Value] = &sexpr_file!("tests/sexpr/empty.scm");
assert_eq!(values.len(), 0);
use kamo::{mem::Mutator, sexpr_script, value::{print, Value}};
 
let m = Mutator::new_ref();
let values = sexpr_script!(m, "(define a 1)\n(define b 2)\n(+ a b)");
 
assert_eq!(values.len(), 3);
assert_eq!(print(values[0].clone()).to_string(), "(define a 1)");
assert_eq!(print(values[1].clone()).to_string(), "(define b 2)");
assert_eq!(print(values[2].clone()).to_string(), "(+ a b)");

let values: &[Value] = &sexpr_script!("");
 
assert_eq!(values.len(), 0);

依赖项

~2–2.8MB
~56K SLoC