Advertisement
Pascon_Matteo

F# CodeFormatter Final Version

Dec 20th, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.83 KB | None | 0 0
  1. module FSharpCodeFormatter.Formatter
  2.  
  3. open Lib
  4.  
  5. // se non vuoi realizzare la versione avanzata, non modificarla
  6. let split (w : int) (s : string) = split_lines s
  7.  
  8.  
  9. //trim del codice
  10. let rec trim l:string list =
  11. match l with
  12. |[] ->[]
  13. |x::xs -> (trim_line x)::(trim xs)
  14.  
  15.  
  16. //token del codice
  17. let rec token (l:string list) :string list list=
  18. match l with
  19. |[] -> []
  20. |x::xs-> (tokenize_line x)::(token xs)
  21.  
  22.  
  23. //trim+token del codice
  24. let work (s:string list) = token (trim s)
  25.  
  26.  
  27. //restituisce l' ultima stringa da una lista di stringhe
  28. let rec last_string (s:string list) :string =
  29. match s with
  30. |[] -> ""
  31. |[x] -> x
  32. |x::xs -> last_string xs
  33.  
  34.  
  35. //restituisce il penultimo intero di una lista
  36. let rec penultimo_int (x:int list) :int=
  37. match x with
  38. |[] -> -1
  39. |[x] -> -1
  40. |x::y::[]-> x
  41. |x::ys -> penultimo_int ys
  42.  
  43.  
  44. //restituisce il primo intero di una lista
  45. let first_int (n:int list) :int =
  46. match n with
  47. |[]-> 0
  48. |x::xs -> x
  49.  
  50.  
  51. //restituisce la prima stringa da una lista di stringhe
  52. let first (s:string list) :string =
  53. match s with
  54. |[]-> ""
  55. |x::xs -> x
  56.  
  57.  
  58. //restituisce la prima parola della riga se presente
  59. let rec first_word (s:string list list) :string =
  60. match s with
  61. |[] ->""
  62. |x::xs -> first x
  63.  
  64.  
  65. //restituisce la prima lista di stringhe da una lista di liste di stringhe
  66. let first_list (s:string list list) :string list=
  67. match s with
  68. |[]-> []
  69. |x::xs -> x
  70.  
  71.  
  72. //concatena stringhe
  73. let rec unisci_stringhe (s:string list) : string =
  74. match s with
  75. |[] -> ""
  76. |x::xs -> x+" "+(unisci_stringhe xs)
  77.  
  78.  
  79. //aggiunge in testa a una lista
  80. // - usato per gli let= e in: inserisce il n° di tab)
  81. // - usato per gli if, else e elif: inserisce il n° di tab
  82. let add_element (x:'a) (l:'a list) :'a list=
  83. x::l
  84.  
  85.  
  86. //rimuove il primo elem di una lista se presente
  87. let remove_first (l:'a list) :'a list=
  88. match l with
  89. |[] ->[]
  90. |x::xs -> xs
  91.  
  92.  
  93. //finder fa uso di 2 concetti principali:
  94. // - alcune parole chiave in casi specifici causano un displacement della riga successiva
  95. //
  96. // - alcune parole chiave (es. else) si posizionano con lo stesso numero di tablature di determinati costrutti precedenti
  97. //
  98. // - work list è la string list list da indentare (parole e righe)
  99. //
  100. // - n_tab è il numero corrente di tablature che avrà la riga (salvo displacement o costrutti particolari)
  101. //
  102. // - in_after_let è una flag
  103. //
  104. // - in_list è una lista contenente il numero di tablature di tutti i let seguiti da = a fine riga.
  105. // serve per trovare il n° esatto di tablature degli in
  106. // viene aggiornata quando necessario
  107. //
  108. // - else_list è una lista contenente il numero di tablature di tutti gli if
  109. // serve per trovare il n° esatto di tablature degli else ed elif
  110. // viene aggiornata quando necessario
  111.  
  112.  
  113. let rec finder (work_list:string list list) (n_tab:int) (in_after_let:int) (in_list :int list) (else_list:int list) :(int*string) list=
  114. match work_list with
  115. |[]-> []
  116. |x::xs ->
  117. match x with
  118. |[] -> (0,"")::finder (xs) (0) (0) ([]) (else_list)
  119. |y::ys ->
  120. match y with
  121. |"let"->
  122. match last_string x with
  123. |"=" -> (n_tab, unisci_stringhe x)::finder (xs) (n_tab+1) (0) (add_element n_tab in_list) (else_list)
  124. |_ ->
  125. match first_word xs with
  126. |"in"->(n_tab, unisci_stringhe x)::finder (xs) (n_tab) (1) (in_list) (else_list)
  127. |_->(n_tab, unisci_stringhe x)::finder (xs) (n_tab) (0) (in_list) (else_list)
  128. |"fun"->
  129. match last_string x with
  130. |"->" -> (n_tab, unisci_stringhe x)::finder (xs) (n_tab+1) (0) (in_list) (else_list)
  131. |_-> (n_tab, unisci_stringhe x)::finder (xs) (n_tab) (0) (in_list) (else_list)
  132. |"if"->(n_tab, unisci_stringhe x)::finder (xs) (n_tab+1) (in_after_let) (in_list) (n_tab::else_list)
  133. |"else"->
  134. match last_string x with
  135. |"else"->(first_int else_list, unisci_stringhe x)::finder (xs) (first_int else_list+1) (in_after_let) (in_list) (remove_first else_list)
  136. |_-> (first_int else_list, unisci_stringhe x)::finder (xs) (first_int else_list) (in_after_let) (in_list) (remove_first else_list)
  137. |"elif"->(first_int else_list, unisci_stringhe x)::finder (xs) (first_int else_list+1) (in_after_let) (in_list) (else_list)
  138. |"match"->(n_tab,unisci_stringhe x)::finder (xs) (n_tab) (in_after_let) (in_list) (else_list)
  139. |"|"->
  140. match last_string x with
  141. |"->" ->(n_tab,unisci_stringhe x)::finder (xs) (n_tab+1) (in_after_let) (in_list) (else_list)
  142. |_->
  143. match first_word xs with
  144. |"|"-> (n_tab,unisci_stringhe x)::finder (xs) (n_tab) (in_after_let) (in_list) (else_list)
  145. |_ -> (n_tab,unisci_stringhe x)::finder (xs) (n_tab-1) (in_after_let) (in_list) (else_list)
  146. |"in"->
  147. match first_list xs with
  148. |[]->(penultimo_int in_list, unisci_stringhe x)::finder (xs) (n_tab) (in_after_let) (remove_first in_list) (else_list)
  149. |_->
  150. match in_after_let with
  151. |1->(n_tab,unisci_stringhe x)::finder (xs) (n_tab) (0) (in_list) (else_list)
  152. |_->(first_int in_list,unisci_stringhe x)::finder (xs) (first_int in_list) (in_after_let) (remove_first in_list) (else_list)
  153. |_->(n_tab,unisci_stringhe x)::finder (xs) (n_tab-1) (in_after_let) (in_list) (else_list)
  154.  
  155.  
  156. // questa è la funzione principale da implementare correttamente sia per versione avanzata che per quella normale
  157. let indent (lines : string list) =
  158. finder (token lines) (0) (0) ([]) ([])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement