module Base = Lang_base let indent = Base.indent let declType = function | "our" -> "our" | _ -> "my" let rec printExpr = function | Base.AnonFunction (args, body) -> String.concat "\n" (["sub {"] @ (indent (List.concat (List.map printStmtLines body))) @ ["}"]) | Base.Var v -> "$" ^ v | Base.Bool b -> if b then "1" else "0" | Base.Hash es -> "{ " ^ String.concat ", " (List.map (fun (n, v) -> printExpr n ^ " => " ^ printExpr v) es) ^ " }" | Base.Regexp r -> "qr/" ^ r ^ "/" | e -> Base.printExpr_base printExpr e and printStmtLines = let rec elsifs state = function | (cond, body, Some (Base.If (cond', body', els'))) -> [state ^ " (" ^ printExpr cond ^ ")"; "{"] @ (indent (List.concat (List.map printStmtLines body))) @ ["}"] @ (elsifs "elsif" (cond', body', els')) | (cond, body, els) -> [state ^ " (" ^ printExpr cond ^ ")"; "{"] @ (indent (List.concat (List.map printStmtLines body))) @ ["}"] @ (match els with Some s -> "else" :: printStmtLines s | None -> []) in function | Base.InitVar (t, n, e) -> [declType t ^ " $" ^ n ^ " = " ^ printExpr e ^ ";"] | Base.DeclVar (t, n) -> [declType t ^ " $" ^ n ^ ";"] | Base.Enum (name, vals) -> let c = Common.counter 0 in List.map (function n -> "my $" ^ n ^ " = " ^ string_of_int (c ()) ^ ";") vals | Base.If (cond, body, (Some (Base.If _) as els)) -> elsifs "if" (cond, body, els) | s -> Base.printStmtLines_base printExpr printStmtLines s let printStmt s = (String.concat "\n" (printStmtLines s)) ^ "\n"