kamo-macros 0.1.6

A macro for parsing s-expressions into kamo Values.
Documentation
# Kamo-macros

![Build Status](https://img.shields.io/github/actions/workflow/status/typedduck/kamo/rust.yml)
[![Crates.io](https://img.shields.io/crates/v/kamo-macros)](https://crates.io/crates/kamo-macros)
[![Crates.io](https://img.shields.io/crates/d/kamo-macros)](https://crates.io/crates/kamo-macros)

Kamo (カモ) is japanese for duck.

This crate provides procedural macros for the
[Kamo](https://crates.io/crates/kamo) crate. The macros provided are:

- `sexpr!(<mutator>, <expression>)` - A macro for parsing a single s-expression
  from a string. It returns a `kamo::value::Value`.

- `sexpr_file!(<mutator>, <filename>)` - A macro for parsing multiple
  s-expressions from a file. It returns an array of `kamo::value::Value`s. The
  array may be empty.

- `sexpr_script!(<mutator>, <filename>)` - A macro for parsing multiple
  s-expressions from a string. It returns an array of `kamo::value::Value`s. The
  array may be empty.

The macros all take an optional `MutatorRef` identifier. This is used to allocate
values on the heap. If the expression does not contain any values that need to
be allocated on the heap, then the `Mutator` identifier can be omitted.

The syntax for the macros is as defined by the Scheme standard R7RS for the
`read` procedure. The syntactic definition is the `<datum>` in section
["7.1.2 External representations"](https://standards.scheme.org/official/r7rs.pdf)
of the standard.

The syntax deviations from the standard are:

- The extactness (`#e` and `#i`) of numbers is not supported. Floating-point
  numbers are always inexact and integers are always exact.

- Numbers may only be signed 64-bit integers or IEEE 754 double precision
  floating-point numbers. The standard allows for arbitrary precision integers,
  rationals and complex numbers.

- Labels are not supported.

- The `#;` comment syntax is only supported in the macros which parse multiple
  s-expressions. The `#;` comment syntax may not be nested.

- Character literals defined by a hex escape sequence may have 1 to 6 digits.
  The standard excepts 1 or more digits. The code must be a valid Unicode code
  point.

The parser is implemented with the `pest` crate. The grammar is defined in
`src/sexpr/sexpr.pest`. This is necessary because the combination parser library
defined in `kamo::parser` cannot be used here. It would be cyclic dependency.
There will be an implementation of a parser for s-expressions in the
`kamo::form` module in the future. It will be based on the `kamo::parser` crate
and will be used by the scheme interpreter.

## Examples

```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)");
```
 
```rust
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);
```
 
```rust
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);
```