package ppx_camlrack

  1. Overview
  2. Docs
PPX for matching S-Expressions

Install

Dune Dependency

Authors

Maintainers

Sources

0.10.1.tar.gz
md5=d888192782217ac5eb0933f07f0706d3
sha512=9dd2e7247afa9017feefcd97e4dc73869f10d84f267caa9f2ddfa913bd5257ce1139200faf6aa26c588d4bbf6e178f8c95f85b9ec9192d0145cdbfc664c17b60

Description

'PPX-Camlrack' provides an augmented match expression that transforms written S-Expressions into their Camlrack-compatible types. This allows for easily working with S-Expressions without extra typing.

README

Camlrack: S-Expression Matching in OCaml

Camlrack brings S-Expressions and easy pattern matching for S-Expressions to OCaml like never before!

Full Manual

There is a full manual for Camlrack at docs/Manual.md.

Quick Overview

S-Expressions can be instantiated directly:

open Camlrack

(* Represent '(+ 1 2) *)
let se1 = SExp [ Symbol "+"; Integer 1; Integer 2 ]

(* Represent '(add1 x) *)
let se2 = SExp [ Symbol "add1"; Symbol "x" ]

They can also be parsed from strings:

open Camlrack

let se3 = sexp_of_string_exn "(let ([x 2] [y 3]) (+ x y))"
let se4 = SExp [ Symbol "let"
               ; SExp [ SExp [ Symbol "x"; Integer 2 ]
                      ; SExp [ Symbol "y"; Integer 3 ] ]
               ; SExp [ Symbol "+"; Symbol "x"; Symbol "y" ] ]
assert (s3 = se4)

S-Expressions can also be compared against S-Expression patterns. S-Expression pattern matching is based entirely on the PLAIT language implemented by Matthew Flatt.

open Camlrack

let spat1 = SPat [ SYMBOL    ; INTEGER   ; PSymbol "literal" ]
let sexp1 = SExp [ Symbol "x"; Integer 42; Symbol  "literal" ]
assert (sexp_match spat1 sexp1)

let spat2 = sexp_pattern_of_string_exn "{lambda {SYMBOL ...} ANY ...}"
let sexp2 = sexp_of_string_exn "(lambda (x y) (+ x y))"
assert (sexp_match spat2 sexp2)

PPX Extensions

Camlrack also provides two PPX extensions: %sexp and %spat.

%sexp

The first can be used to either rewrite strings as S-Expressions (sometimes at compile-time), or else to provide a more fully featured S-Expression matching system.

let sexp1 = [%sexp "(foo bar)"]
let sexp2 = SExp [ Symbol "foo"; Symbol "bar" ]
assert (sexp1 = sexp2)

let do_a_match = function%sexp
  | (foo, bar) -> ...
  | (lambda, (x, y)) -> ...
  | "{lambda {x y}}" -> ... (* redundant; identical to previous case *)

Note that the non-string forms are somewhat limited. PPX extensions are restricted to only supporting syntactically valid OCaml, so the tuple-like form must be built of real tuples (meaning commas are required). Additionally, symbols containing special characters such as those used by operators cannot be handled in the tuple-like form.

For most cases, it is probably advisable to use the string form.

%spat

The second extension allows for easy pattern-matching against S-Expressions.

let matching_function sexp = match%spat sexp with
  | "INTEGER" -> "it's an integer"
  | "(lhs rhs)" -> "found two symbols: lhs and rhs"
  | "(let ([SYMBOL ANY] ...) ANY ...)" -> "whoa, pretty fancy!"

This extension only works on match expressions, and the cases must be written as string literals.

Dependencies (4)

  1. camlrack = version
  2. ppxlib >= "0.23.0"
  3. ocaml >= "4.12"
  4. dune >= "2.9"

Dev Dependencies (2)

  1. odoc with-doc
  2. ounit2 with-test & >= "2.2.5"

Used by

None

Conflicts

None