Nice and clean.

I wonder what Ocaml programmers would think of this code?
This commit is contained in:
Simon Forman 2022-09-24 12:02:00 -07:00
parent 9e2d148fbf
commit 754fd1d1dc
1 changed files with 64 additions and 52 deletions

View File

@ -15,6 +15,14 @@ let j_loop = JoySymbol "loop"
let zero = JoyInt 0 let zero = JoyInt 0
let dummy = JoyList [ joy_true; joy_false; j_loop; zero ] let dummy = JoyList [ joy_true; joy_false; j_loop; zero ]
(*
*)
let rec joy_to_string jt = let rec joy_to_string jt =
match jt with match jt with
| JoySymbol sym -> sym | 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) and expression_to_string el = String.concat " " (List.map joy_to_string el)
(* *)
type token = Left_bracket | Right_bracket | Token of string type token = Left_bracket | Right_bracket | Token of string
let delimiter str last = let delimiter str i =
last >= String.length str || String.contains "[] " (String.get str last) 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 *) (* string -> int -> int -> token * int *)
let rec tokenize1 str start last = let rec tokenize1 str index i =
if delimiter str last then (Token (String.sub str start (last - start)), last) if delimiter str i then make_token str index i else tokenize1 str index (i + 1)
else tokenize1 str start (last + 1)
let rec tokenize0 str start acc = let rec tokenize0 str index acc =
if start >= String.length str then acc if index >= String.length str then acc
else else
match String.get str start with match String.get str index with
| '[' -> Left_bracket :: tokenize0 str (start + 1) acc | '[' -> Left_bracket :: tokenize0 str (index + 1) acc
| ']' -> Right_bracket :: tokenize0 str (start + 1) acc | ']' -> Right_bracket :: tokenize0 str (index + 1) acc
| ' ' -> tokenize0 str (start + 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 token :: tokenize0 str n acc
let tokenize str = tokenize0 str 0 [] let tokenize str = tokenize0 str 0 []
@ -55,50 +67,52 @@ let token_to_string token =
| Right_bracket -> "]" | Right_bracket -> "]"
| Token str -> str | 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")) let s = String.concat " " (List.map token_to_string (tokenize "1 Pat [2]3"))
let () = print_endline s
let s = String.concat "" (List.map token_to_string (text_to_expression "1 [2]3" ))
*)
(*
*) *)
exception ParseError of string exception ParseError of string
(* let tokenator tok =
let rec parse : token list -> joy_list = fun tokens -> if String.equal tok "true" then joy_true
match tokens with else if String.equal tok "false" then joy_false
| [] -> [] else
| head :: tail -> match int_of_string_opt tok with
match head with | Some i -> JoyInt i
| Left_bracket -> let (el, rest) = parse_list tail in el :: parse rest | None -> JoySymbol tok
| 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
*) (* Get the prefix of the list as JoyList and return rest of list.
token list -> joy_list -> joy_list * token list *)
(* Get the prefix of the list as joy type and return rest of list.
token list -> joy_type list -> joy_type list * token list
*)
let rec expect_right_bracket tokens acc = let rec expect_right_bracket tokens acc =
match tokens with match tokens with
| [] -> raise (ParseError "Missing closing bracket.") | [] -> raise (ParseError "Missing closing bracket.")
| head :: tail -> ( | head :: tail -> expect_right_bracket_one_token_lookahead head tail acc
match head with
| Right_bracket -> (acc, tail) and expect_right_bracket_one_token_lookahead token tokens acc =
| Left_bracket -> match token with
(* extract the sub-list *) | Right_bracket -> (acc, tokens)
let sub_list, rest = expect_right_bracket tail [] in | Left_bracket ->
(* continue looking for the expected "]" *) (* extract the sub-list *)
let el, rrest = expect_right_bracket rest acc in let sub_list, rest = expect_right_bracket tokens [] in
(JoyList sub_list :: el, rrest) (* continue looking for the expected "]" *)
| Token tok -> ( let el, rrest = expect_right_bracket rest acc in
let el, rest = expect_right_bracket tail acc in (JoyList sub_list :: el, rrest)
match tok with | Token tok ->
| "true" -> (joy_true :: el, rest) let el, rest = expect_right_bracket tokens acc in
| "false" -> (joy_false :: el, rest) let jt = tokenator tok in
| _ -> (JoySymbol tok :: el, rest))) (jt :: el, rest)
(* token -> token list -> joy_type * token list *) (* token -> token list -> joy_type * token list *)
let one_token_lookahead token tokens = let one_token_lookahead token tokens =
@ -107,11 +121,9 @@ let one_token_lookahead token tokens =
| Left_bracket -> | Left_bracket ->
let el, rest = expect_right_bracket tokens [] in let el, rest = expect_right_bracket tokens [] in
(JoyList el, rest) (JoyList el, rest)
| Token tok -> ( | Token tok ->
match tok with let jt = tokenator tok in
| "true" -> (joy_true, tokens) (jt, tokens)
| "false" -> (joy_false, tokens)
| _ -> (JoySymbol tok, tokens))
(* token list -> joy_type list -> joy_type list *) (* token list -> joy_type list -> joy_type list *)
let rec parse0 tokens acc = let rec parse0 tokens acc =