ç´ç²é¢æ°åè¨èªã®å¦çç³»ãä½ã£ã¦ã¿ããã¨ã«ãã (ãã®2 : Pretty Printer)
純粋関数型言語の処理系を作ってみることにしたã®ç¶ãã
å
鱿«ã¯ã¡ãã£ã¨å¿ããã£ãã®ã§æ¯é±æ¥ææ¥ã®äºå®ãããã¦ãã¾ãã¾ããã
仿¥ã¯Pretty Printerãä½ãã¾ãããG-machineã¯æ¬¡åã«åãã¾ãã
http://github.com/nineties/puref/commit/9295d96e1e0adb73dafea06dd716c1aada6c3304
ä¸ãPretty Printerã®ã³ã¼ããOCamlã®Formatã¢ã¸ã¥ã¼ã«ã¯æ¸å¼æå®æååã®ä¸ã§ããã¯ã¹ãä½ãäºãã§ããã®ãç¹å¾´ã§ãã¡ãã£ã¨ãããããã§ãã(@[ ... @])ã®é¨åããã®ããã¯ã¹ã使ã£ã¦ã¤ã³ãã³ãã¨ãã®èª¿æ´ããã¾ãã
詳ããã¯http://caml.inria.fr/resources/doc/guides/format.html
open Format open Syntax let binop_string = function | Add -> "+" | Sub -> "-" | Mul -> "*" | Div -> "/" | Lt -> "<" | Le -> "<=" | Eq -> "==" | Ne -> "~=" | Ge -> ">=" | Gt -> ">" | And -> "&" | Or -> " | " let rec pp_vars ppf vars = List.iter (fun v -> fprintf ppf "%a@;" pp_print_string v) vars let pp_break_list f ppf elems = pp_open_hvbox ppf 0; f ppf (List.hd elems); List.iter (fun def -> pp_print_break ppf 1 0; f ppf def) (List.tl elems); pp_close_box ppf () let rec pp_expr ppf = function | VarE id -> pp_print_string ppf id | NumE num -> pp_print_int ppf num | PackE (id,arity) -> fprintf ppf "<%d,%d>" id arity | AppE (f,arg) -> fprintf ppf "%a %a" pp_expr f pp_aexpr arg | InfixE (op,lhs,rhs) -> fprintf ppf "@[%a %s %a@]" pp_expr lhs (binop_string op) pp_expr rhs | LetE (defs,cont) -> fprintf ppf "@[@[<hv 4>let %a@]@;in@;%a@]" (pp_break_list pp_def) defs pp_expr cont | LetrecE (defs,cont) -> fprintf ppf "@[@[<hv 4>letrec@;%a@]@;in@;%a@]" (pp_break_list pp_def) defs pp_expr cont | CaseE (expr,alts) -> fprintf ppf "@[@[<hv 4>case %a@]@;of@;%a@]" pp_expr expr (pp_break_list pp_alt) alts | LambdaE (vars,body) -> fprintf ppf "@[@[<hv>%a>. %a@]" pp_vars vars pp_expr body and pp_aexpr ppf exp = match exp with | VarE _ -> pp_expr ppf exp | NumE _ -> pp_expr ppf exp | PackE _ -> pp_expr ppf exp | _ -> fprintf ppf "(%a)" pp_expr exp and pp_def ppf (var,expr) = fprintf ppf "@[%a = %a@]" pp_print_string var pp_expr expr and pp_alt ppf (id,elems,cont) = fprintf ppf "@[<%d> %a-> %a@]" id pp_vars elems pp_expr cont let pp_sc ppf (vars,body) = fprintf ppf "@[%a= %a@]" pp_vars vars pp_expr body let rec pp_program ppf = function | [sc] -> pp_sc ppf sc; pp_print_newline ppf () | sc::scs -> fprintf ppf "@[<v>%a;@;%a@]" pp_sc sc pp_program scs | _ -> failwith "not reachable"
ããã§ããã¼ãµã®çµæãåºåãããã¨ãåºæ¥ã¾ããç°¡åãªãã¹ãã³ã¼ãã¨ãã¦æç§æ¸10ãã¼ã¸ã®standard preludeã追å ãã¾ããã
I x = x; K x y = x; K1 x y = y; S f g x = f x (g x); compose f g x = f (g x); twice f = compose f f
å®è¡çµæ
% ./puref < prelude.pf I x = x; K x y = x; K1 x y = y; S f g x = f x (g x); compose f g x = f (g x); twice f = compose f f
次åããã¯G-machineã®å®è£ ã«å ¥ãã¾ãã