Skip to content

Commit

Permalink
Ocaml: Add string functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Chouser committed Jan 30, 2015
1 parent 9115534 commit de04357
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 15 deletions.
5 changes: 3 additions & 2 deletions ocaml/Makefile
Original file line number Diff line number Diff line change
@@ -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

Expand Down
14 changes: 14 additions & 0 deletions ocaml/core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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

14 changes: 8 additions & 6 deletions ocaml/printer.ml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
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
| Types.Keyword s -> ":" ^ s
| 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 -> "<fn>"
| 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 -> "#<fn>"
2 changes: 1 addition & 1 deletion ocaml/step1_read_print.ml
Original file line number Diff line number Diff line change
@@ -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 =
Expand Down
2 changes: 1 addition & 1 deletion ocaml/step2_eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
2 changes: 1 addition & 1 deletion ocaml/step3_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
8 changes: 4 additions & 4 deletions ocaml/step4_if_fn_do.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 =
Expand Down
4 changes: 4 additions & 0 deletions ocaml/types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit de04357

Please sign in to comment.