From 754fd1d1dc37daeb3a3a1dd69ef21718a9513307 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 24 Sep 2022 12:02:00 -0700 Subject: [PATCH] Nice and clean. I wonder what Ocaml programmers would think of this code? --- implementations/Ocaml/helloworld/bin/main.ml | 114 +++++++++++++++------------ 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/implementations/Ocaml/helloworld/bin/main.ml b/implementations/Ocaml/helloworld/bin/main.ml index b9ab57d..8b00735 100644 --- a/implementations/Ocaml/helloworld/bin/main.ml +++ b/implementations/Ocaml/helloworld/bin/main.ml @@ -15,6 +15,14 @@ let j_loop = JoySymbol "loop" let zero = JoyInt 0 let dummy = JoyList [ joy_true; joy_false; j_loop; zero ] +(* +██████╗ ██████╗ ██╗███╗ ██╗████████╗███████╗██████╗ +██╔══██╗██╔══██╗██║████╗ ██║╚══██╔══╝██╔════╝██╔══██╗ +██████╔╝██████╔╝██║██╔██╗ ██║ ██║ █████╗ ██████╔╝ +██╔═══╝ ██╔══██╗██║██║╚██╗██║ ██║ ██╔══╝ ██╔══██╗ +██║ ██║ ██║██║██║ ╚████║ ██║ ███████╗██║ ██║ +╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ +*) let rec joy_to_string jt = match jt with | JoySymbol sym -> sym @@ -25,25 +33,29 @@ let rec joy_to_string jt = and expression_to_string el = String.concat " " (List.map joy_to_string el) +(* *) + type token = Left_bracket | Right_bracket | Token of string -let delimiter str last = - last >= String.length str || String.contains "[] " (String.get str last) +let delimiter str i = + i >= String.length str || String.contains "[] " (String.get str i) + +let make_token str index last = + (Token (String.sub str index (last - index)), last) (* string -> int -> int -> token * int *) -let rec tokenize1 str start last = - if delimiter str last then (Token (String.sub str start (last - start)), last) - else tokenize1 str start (last + 1) +let rec tokenize1 str index i = + if delimiter str i then make_token str index i else tokenize1 str index (i + 1) -let rec tokenize0 str start acc = - if start >= String.length str then acc +let rec tokenize0 str index acc = + if index >= String.length str then acc else - match String.get str start with - | '[' -> Left_bracket :: tokenize0 str (start + 1) acc - | ']' -> Right_bracket :: tokenize0 str (start + 1) acc - | ' ' -> tokenize0 str (start + 1) acc + match String.get str index with + | '[' -> Left_bracket :: tokenize0 str (index + 1) acc + | ']' -> Right_bracket :: tokenize0 str (index + 1) acc + | ' ' -> tokenize0 str (index + 1) acc | _ -> - let token, n = tokenize1 str start (start + 1) in + let token, n = tokenize1 str index (index + 1) in token :: tokenize0 str n acc let tokenize str = tokenize0 str 0 [] @@ -55,50 +67,52 @@ let token_to_string token = | Right_bracket -> "]" | Token str -> str -let s = String.concat "" (List.map token_to_string (text_to_expression "1 [2]3" )) let s = String.concat " " (List.map token_to_string (tokenize "1 Pat [2]3")) -*) -exception ParseError of string +let () = print_endline s -(* -let rec parse : token list -> joy_list = fun tokens -> - match tokens with - | [] -> [] - | head :: tail -> - match head with - | Left_bracket -> let (el, rest) = parse_list tail in el :: parse rest - | Right_bracket -> raise (ParseError "Extra closing bracket.") - | Token tok -> - match tok with - | "true" -> joy_true :: parse tail - | "false"-> joy_false :: parse tail - | _ -> JoySymbol tok :: parse tail +let s = String.concat "" (List.map token_to_string (text_to_expression "1 [2]3" )) +*) +(* +██████╗ █████╗ ██████╗ ███████╗███████╗██████╗ +██╔══██╗██╔══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗ +██████╔╝███████║██████╔╝███████╗█████╗ ██████╔╝ +██╔═══╝ ██╔══██║██╔══██╗╚════██║██╔══╝ ██╔══██╗ +██║ ██║ ██║██║ ██║███████║███████╗██║ ██║ +╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ *) -(* Get the prefix of the list as joy type and return rest of list. +exception ParseError of string - token list -> joy_type list -> joy_type list * token list -*) +let tokenator tok = + if String.equal tok "true" then joy_true + else if String.equal tok "false" then joy_false + else + match int_of_string_opt tok with + | Some i -> JoyInt i + | None -> JoySymbol tok + +(* Get the prefix of the list as JoyList and return rest of list. + token list -> joy_list -> joy_list * token list *) let rec expect_right_bracket tokens acc = match tokens with | [] -> raise (ParseError "Missing closing bracket.") - | head :: tail -> ( - match head with - | Right_bracket -> (acc, tail) - | Left_bracket -> - (* extract the sub-list *) - let sub_list, rest = expect_right_bracket tail [] in - (* continue looking for the expected "]" *) - let el, rrest = expect_right_bracket rest acc in - (JoyList sub_list :: el, rrest) - | Token tok -> ( - let el, rest = expect_right_bracket tail acc in - match tok with - | "true" -> (joy_true :: el, rest) - | "false" -> (joy_false :: el, rest) - | _ -> (JoySymbol tok :: el, rest))) + | head :: tail -> expect_right_bracket_one_token_lookahead head tail acc + +and expect_right_bracket_one_token_lookahead token tokens acc = + match token with + | Right_bracket -> (acc, tokens) + | Left_bracket -> + (* extract the sub-list *) + let sub_list, rest = expect_right_bracket tokens [] in + (* continue looking for the expected "]" *) + let el, rrest = expect_right_bracket rest acc in + (JoyList sub_list :: el, rrest) + | Token tok -> + let el, rest = expect_right_bracket tokens acc in + let jt = tokenator tok in + (jt :: el, rest) (* token -> token list -> joy_type * token list *) let one_token_lookahead token tokens = @@ -107,11 +121,9 @@ let one_token_lookahead token tokens = | Left_bracket -> let el, rest = expect_right_bracket tokens [] in (JoyList el, rest) - | Token tok -> ( - match tok with - | "true" -> (joy_true, tokens) - | "false" -> (joy_false, tokens) - | _ -> (JoySymbol tok, tokens)) + | Token tok -> + let jt = tokenator tok in + (jt, tokens) (* token list -> joy_type list -> joy_type list *) let rec parse0 tokens acc = -- 2.11.0