aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChouser <chouser@n01se.net>2015-01-28 08:27:32 -0500
committerChouser <chouser@n01se.net>2015-01-30 12:54:43 -0500
commit16b177329cac77136b236dfb3645e4be4e3df297 (patch)
treeaa70f831b5f50212ab53e7d6ad8ab89603f89ec9
parentcc916d9d819d17cc47d34321440bf5a2683eac2e (diff)
downloadmal-16b177329cac77136b236dfb3645e4be4e3df297.tar.gz
mal-16b177329cac77136b236dfb3645e4be4e3df297.zip
Ocaml: fix string escaping and printing
-rw-r--r--ocaml/printer.ml6
-rw-r--r--ocaml/reader.ml13
2 files changed, 15 insertions, 4 deletions
diff --git a/ocaml/printer.ml b/ocaml/printer.ml
index 8e71376..fe025af 100644
--- a/ocaml/printer.ml
+++ b/ocaml/printer.ml
@@ -19,7 +19,11 @@ let rec pr_str mal_obj print_readably =
| T.Bool false -> "false"
| T.String s ->
if r
- then "\"" ^ (Str.global_replace (Str.regexp "\\([\"\\]\\)") "\\\\\\1" s) ^ "\""
+ then "\"" ^ (Reader.gsub (Str.regexp "\\([\"\\\n]\\)")
+ (function
+ | "\n" -> "\\n"
+ | x -> "\\" ^ x)
+ s) ^ "\""
else s
| T.List { T.value = xs } ->
"(" ^ (String.concat " " (List.map (fun s -> pr_str s r) xs)) ^ ")"
diff --git a/ocaml/reader.ml b/ocaml/reader.ml
index 9754444..96404aa 100644
--- a/ocaml/reader.ml
+++ b/ocaml/reader.ml
@@ -6,6 +6,11 @@ let find_re re str =
(List.filter (function | Str.Delim x -> true | Str.Text x -> false)
(Str.full_split re str)) ;;
+let gsub re f str =
+ String.concat
+ "" (List.map (function | Str.Delim x -> f x | Str.Text x -> x)
+ (Str.full_split re str))
+
let token_re = (Str.regexp "~@\\|[][{}()'`~^@]\\|\"\\(\\\\.\\|[^\"]\\)*\"\\|;.*\\|[^][ \n{}('\"`,;)]*")
type reader = {
@@ -26,9 +31,11 @@ let read_atom token =
| _ ->
match token.[0] with
| '0'..'9' -> T.Int (int_of_string token)
- | '"' -> T.String (Str.global_replace (Str.regexp "\\\\\\(.\\)")
- "\\1"
- (String.sub token 1 ((String.length token) - 2)))
+ | '"' -> T.String (gsub (Str.regexp "\\\\.")
+ (function
+ | "\\n" -> "\n"
+ | x -> String.sub x 1 1)
+ (String.sub token 1 ((String.length token) - 2)))
| ':' -> T.Keyword (Str.replace_first (Str.regexp "^:") "" token)
| _ -> Types.symbol token