alexpander

alexpander*1が、r5rsのsyntax-rulesを展開する*2らしいので、組み込んでみた。

let alexpand sexps =
  let defs = parseDefs (sexps_from "lib/alexpander.scm")
  and primis = ge Eval.eval_apply in
  let env = Eval.extendletrec primis defs in
  let expandproc = List.assoc "expand-program" defs in
  let expand = ApplyExp (expandproc, [QuoteExp (List sexps)]) in
  let x = Eval.evalExp env expand in
  match val_to_sexp x with
    List s -> s

対話環境でテストする。

# let ae = alexpand (sparse_top 
"(let-syntax ((when (syntax-rules ()
                     ((when test stmt1 stmt2 ...)
                      (if test (begin stmt1 stmt2 ...))))))
    (when 'x 'a 'b 'c))");;
val ae : Syntax.sexp list =
  [List [Id "define"; Id "_eqv?_17"; Id "eqv?"];
   List [Id "define"; Id "_cons_31"; Id "cons"];
   List [Id "define"; Id "_append_32"; Id "append"];
   List [Id "define"; Id "_list_33"; Id "list"];
   List [Id "define"; Id "_vector_34"; Id "vector"];
   List [Id "define"; Id "_list->vector_35"; Id "list->vector"];
   List [Id "define"; Id "_map_36"; Id "map"];
   List
    [Id "if"; List [Id "quote"; Id "x"];
     List
      [Id "begin"; List [Id "quote"; Id "a"]; List [Id "quote"; Id "b"];
       List [Id "quote"; Id "c"]]]]
# eval_body (parseBody ae);;
- : Parser.exp Valtype.valtype = SymbolV "c"

自身の評価器でalexpanderのexpand-programを評価してs式を展開させ、展開されたs式を評価する。