package baguette_sharp

  1. Overview
  2. Docs

Source file utils.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
let list_of_funct =
  [
    "PAINAUCHOCOLAT";
    "PAINVIENNOIS";
    "CROISSANT";
    "MADELEINE";
    "ECLAIR";
    "CANELE";
    "STHONORE";
    "KOUGNAMANN";
    "PROFITEROLE";
    "FINANCIER";
    "PAINAURAISIN";
    "CHOCOLATINE";
    "BRETZEL";
    "BAGUETTEVIENNOISE";
    "OPERA";
    "MILLEFEUILLE";
    "FRAISIER";
    "QUATREQUART";
    "TIRAMISU";
    "MERINGUE";
    "MERVEILLE";
    "BRIOCHE";
    "TARTE";
    "FLAN";
    "PAINDEPICE";
    "CREPE";
    "CHAUSSONAUXPOMMES";
    "SABLE";
    "CHOUQUETTE";
    "CLAFOUTIS";
    "PARISBREST";
    "TARTEAUXFRAISES";
    "TARTEAUXFRAMBOISES";
    "TARTEAUXPOMMES";
    "TARTEALARHUBARBE";
    "GLACE";
    "BEIGNET";
    "DOUGHNUT";
    "BUCHE";
    "GAUFFREDELIEGE";
    "GAUFFREDEBRUXELLE";
    "GAUFFRE";
    "PANCAKE";
    "SIROPDERABLE";
    "FROSTING";
    "CARROTCAKE";
    "GALETTEDESROIS";
    "FRANGIPANE";
    "BABAAURHUM";
    "CHARLOTTEAUXFRAISES";
    "BAGUETTE";
  ]

let read_file filename =
  let lines = ref [] in
  let chan = open_in filename in
  try
    while true do
      let a = input_line chan in
      if not (String.starts_with ~prefix:"//" a) then lines := a :: !lines
    done;
    !lines
  with End_of_file ->
    close_in chan;
    List.rev !lines

(**Parsing a file and outputting all of the different steps*)
let parse_file_verbosely ?(lexer = false) file =
  let src = read_file file |> List.map String.trim |> String.concat " " in
  print_endline "Input code : ";
  print_newline ();
  print_endline src;
  print_newline ();
  let token_list =
    if not lexer then Lexer.generate_token src
    else Lexer.generate_token_with_chars src
  in
  print_newline ();
  print_endline "Lexed code : ";
  print_newline ();
  Token.print_token_list token_list;
  print_newline ();
  let a = Lexer.validate_parenthesis_and_quote token_list in
  match a with
  | Exception _ ->
      let b = Lexer.automatic_correction_of_parenthesis token_list in
      let ast = Parser.parse_file b in
      print_endline
        "The parenthesis scheme has automatically been corrected to the \
         following lexed code";
      print_newline ();
      Token.print_token_list b;
      print_newline ();
      print_endline "Parsed code : ";
      print_newline ();
      List.iter (fun s -> print_endline (Parser.print_pretty_node s)) ast;
      print_newline ();
      print_endline "Interpreter : ";
      print_newline ();
      Interpreter.runtime ast |> ignore
  | _ ->
      let ast = Parser.parse_file token_list in
      print_newline ();
      print_endline "Parsed code : ";
      print_newline ();
      (List.iter (fun s -> print_endline (Parser.print_pretty_node s))) ast;
      print_newline ();
      print_endline "Interpreter : ";
      print_newline ();
      Interpreter.runtime ast |> ignore

(**Parse a file and execute the runtime*)
let parse_file ?(verbose = false) ?(lexer = false) file =
  if verbose then parse_file_verbosely ~lexer file
  else
    let str = read_file file |> List.map String.trim |> String.concat " " in
    let token_list =
      if not lexer then Lexer.generate_token str
      else Lexer.generate_token_with_chars str
    in
    let a = Lexer.validate_parenthesis_and_quote token_list in
    match a with
    | Exception s -> print_endline s#to_string
    | _ -> Parser.parse_file token_list |> Interpreter.runtime |> ignore

(**Parse a line and execute it through the runtime*)
let parse_line ?(verbose = false) ?(lexer = false) line repl =
  let str = String.trim line in
  if verbose then (
    print_endline "Read code : ";
    print_endline str);
  let token_list =
    if not lexer then Lexer.generate_token str
    else Lexer.generate_token_with_chars str
  in
  if verbose then (
    print_endline "Lexed code : ";
    Token.print_token_list token_list);
  print_newline ();
  let a = Lexer.validate_parenthesis_and_quote token_list in
  match a with
  | Exception _ ->
      let b = Lexer.automatic_correction_of_parenthesis token_list in
      let ast = Parser.parse_file b in
      if verbose then (
        print_endline "Automatically Corrected Code : ";
        Token.print_token_list b;
        print_newline ();
        print_endline "Parsed code : ";
        List.iter (fun s -> print_endline (Parser.print_pretty_node s)) ast;
        print_endline "Runtime : ";
        print_newline ());
      Interpreter.runtime ~repl ast
  | _ ->
      let ast = Parser.parse_file token_list in
      if verbose then (
        print_endline "Parsed code : ";
        List.iter (fun s -> print_endline (Parser.print_pretty_node s)) ast;
        print_endline "Runtime : ";
        print_newline ());
      Interpreter.runtime ~repl ast

(**Takes two Hahstbl and fuse them together*)
let fuse_hash_tbl original new_one =
  Hashtbl.iter (fun a b -> Hashtbl.add original a b) new_one

(**Display the REPL Help*)
let display_help () =
  print_endline
    "\027[1;38;2;195;239;195m### Baguette# Interpreter REPL Command Help \
     ###\027[m";
  print_endline "\027[2;38;2;195;239;195m~ help: show this help";
  print_endline "~ load <file>: load and execute a baguette file";
  print_endline "~ exit: exit the REPL";
  print_endline "~ save <file>: save the history in file";
  print_endline "~ lexer: toggle the char or default version of the lexer";
  print_endline "~ verbose: toggle the verbose (default:false)\027[m"

(**List all of possible file in directory for autocompletion*)
let possible_completion_file word =
  let word = if word = "" then "./" else word in
  let array =
    if Sys.file_exists word && Sys.is_directory word then Sys.readdir word
    else Sys.readdir (Filename.dirname word)
  in
  let file_list = Array.to_list array in
  let file_list_with_name =
    if Sys.file_exists word && Sys.is_directory word then
      List.map
        (String.cat (Filename.basename word ^ Filename.dir_sep))
        file_list
    else
      List.map
        (String.cat (Filename.dirname word ^ Filename.dir_sep))
        (List.filter
           (String.starts_with ~prefix:(Filename.basename word))
           file_list)
  in
  let filtered_list =
    List.map
      (fun str ->
        if String.starts_with ~prefix:"./" str then
          Str.replace_first (Str.regexp "./") "" str
        else str)
      file_list_with_name
  in
  let double_filtered_list =
    List.map
      (fun str ->
        if Sys.file_exists str && Sys.is_directory str then
          str ^ Filename.dir_sep
        else str)
      filtered_list
  in
  double_filtered_list

let load_file_name ?(verbose = false) ?(lexer = false) file =
  try parse_file ~verbose ~lexer file
  with _ -> print_endline ("The file " ^ file ^ " do not exists.")

(**Load a file*)
let load_file ?(verbose = false) ?(lexer = false) lst =
  if List.length lst < 2 then print_endline "not enough args"
  else
    let tl = List.tl lst in
    let file = List.hd tl in
    load_file_name ~verbose ~lexer file