From de04357cd5f2954e2d682abb97ca2b3b90ea75d1 Mon Sep 17 00:00:00 2001 From: Chouser Date: Fri, 23 Jan 2015 20:05:03 -0500 Subject: [PATCH] Ocaml: Add string functions --- ocaml/Makefile | 5 +++-- ocaml/core.ml | 14 ++++++++++++++ ocaml/printer.ml | 14 ++++++++------ ocaml/step1_read_print.ml | 2 +- ocaml/step2_eval.ml | 2 +- ocaml/step3_env.ml | 2 +- ocaml/step4_if_fn_do.ml | 8 ++++---- ocaml/types.ml | 4 ++++ 8 files changed, 36 insertions(+), 15 deletions(-) diff --git a/ocaml/Makefile b/ocaml/Makefile index 5e8b62a17c..bad3f60294 100644 --- a/ocaml/Makefile +++ b/ocaml/Makefile @@ -1,5 +1,6 @@ -STEPS = step0_repl.ml step1_read_print.ml step2_eval.ml step3_env.ml -MODULES = types.ml reader.ml printer.ml env.ml +STEPS = step0_repl.ml step1_read_print.ml step2_eval.ml step3_env.ml \ + step4_if_fn_do.ml +MODULES = types.ml reader.ml printer.ml env.ml core.ml LIBS = str.cmxa MAL_LIB = mal_lib.cmxa diff --git a/ocaml/core.ml b/ocaml/core.ml index 4cec7f1f5f..c11c9f9a24 100644 --- a/ocaml/core.ml +++ b/ocaml/core.ml @@ -28,5 +28,19 @@ let init env = begin Env.set env (Types.Symbol "=") (Types.Fn (function [a; b] -> Types.Bool (a = b) | _ -> Types.Bool false)); + Env.set env (Types.Symbol "pr-str") + (Types.Fn (function xs -> + Types.String (Printer.join " " (List.map (fun s -> Printer.pr_str s true) xs)))); + Env.set env (Types.Symbol "str") + (Types.Fn (function xs -> + Types.String (Printer.join "" (List.map (fun s -> Printer.pr_str s false) xs)))); + Env.set env (Types.Symbol "prn") + (Types.Fn (function xs -> + print_endline (Printer.join " " (List.map (fun s -> Printer.pr_str s true) xs)); + Types.Nil)); + Env.set env (Types.Symbol "println") + (Types.Fn (function xs -> + print_endline (Printer.join " " (List.map (fun s -> Printer.pr_str s false) xs)); + Types.Nil)); end diff --git a/ocaml/printer.ml b/ocaml/printer.ml index e87b3eb0c5..fc9e47b37d 100644 --- a/ocaml/printer.ml +++ b/ocaml/printer.ml @@ -1,7 +1,7 @@ let join sep xs = List.fold_left (fun a x -> if a = "" then x else a ^ sep ^ x) "" xs -let rec pr_str mal_obj = +let rec pr_str mal_obj print_readably = match mal_obj with | Types.Int i -> string_of_int i | Types.Symbol s -> s @@ -9,8 +9,10 @@ let rec pr_str mal_obj = | Types.Nil -> "nil" | Types.Bool true -> "true" | Types.Bool false -> "false" - | Types.String s -> "\"" - ^ (Str.global_replace (Str.regexp "\"") "\\\"" s) - ^ "\"" - | Types.MalList xs -> "(" ^ (join " " (List.map pr_str xs)) ^ ")" - | Types.Fn f -> "" + | Types.String s -> + if print_readably + then "\"" ^ (Str.global_replace (Str.regexp "\\([\"\\]\\)") "\\\\\\1" s) ^ "\"" + else s + | Types.MalList xs -> + "(" ^ (join " " (List.map (fun s -> pr_str s print_readably) xs)) ^ ")" + | Types.Fn f -> "#" diff --git a/ocaml/step1_read_print.ml b/ocaml/step1_read_print.ml index 6cbbb1670d..1735e11974 100644 --- a/ocaml/step1_read_print.ml +++ b/ocaml/step1_read_print.ml @@ -1,6 +1,6 @@ let read str = Reader.read_str str let eval ast any = ast -let print exp = Printer.pr_str exp +let print exp = Printer.pr_str exp true let rep str = print (eval (read str) "") let rec main = diff --git a/ocaml/step2_eval.ml b/ocaml/step2_eval.ml index 02866eb915..af8667cbe5 100644 --- a/ocaml/step2_eval.ml +++ b/ocaml/step2_eval.ml @@ -32,7 +32,7 @@ and eval ast env = | _ -> result let read str = Reader.read_str str -let print exp = Printer.pr_str exp +let print exp = Printer.pr_str exp true let rep str env = print (eval (read str) env) let rec main = diff --git a/ocaml/step3_env.ml b/ocaml/step3_env.ml index 862cae6a81..d7939bf0bd 100644 --- a/ocaml/step3_env.ml +++ b/ocaml/step3_env.ml @@ -39,7 +39,7 @@ and eval ast env = | _ -> eval_ast ast env let read str = Reader.read_str str -let print exp = Printer.pr_str exp +let print exp = Printer.pr_str exp true let rep str env = print (eval (read str) env) let rec main = diff --git a/ocaml/step4_if_fn_do.ml b/ocaml/step4_if_fn_do.ml index 1e5e87d18e..6580dd6092 100644 --- a/ocaml/step4_if_fn_do.ml +++ b/ocaml/step4_if_fn_do.ml @@ -30,15 +30,15 @@ and eval ast env = Types.Fn (function args -> let sub_env = Env.make (Some env) in - let rec bind_args = (fun a b -> + let rec bind_args a b = (match a, b with | [Types.Symbol "&"; name], args -> Env.set sub_env name (Types.MalList args); | (name :: names), (arg :: args) -> Env.set sub_env name arg; bind_args names args; | [], [] -> () - | _ -> raise (Invalid_argument "Bad param count in fn call"))) - in (bind_args arg_names args); + | _ -> raise (Invalid_argument "Bad param count in fn call")) + in bind_args arg_names args; eval expr sub_env) | Types.MalList _ -> (match eval_ast ast env with @@ -47,7 +47,7 @@ and eval ast env = | _ -> eval_ast ast env let read str = Reader.read_str str -let print exp = Printer.pr_str exp +let print exp = Printer.pr_str exp true let rep str env = print (eval (read str) env) let rec main = diff --git a/ocaml/types.ml b/ocaml/types.ml index 60d3725652..badfee3a32 100644 --- a/ocaml/types.ml +++ b/ocaml/types.ml @@ -7,3 +7,7 @@ type mal_type = | Bool of bool | String of string | Fn of (mal_type list -> mal_type) + +let to_bool x = match x with + | Nil | Bool false -> false + | _ -> true