package camlrack
Install
Dune Dependency
Authors
Maintainers
Sources
md5=d888192782217ac5eb0933f07f0706d3
sha512=9dd2e7247afa9017feefcd97e4dc73869f10d84f267caa9f2ddfa913bd5257ce1139200faf6aa26c588d4bbf6e178f8c95f85b9ec9192d0145cdbfc664c17b60
README.md.html
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.