Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module FSharpCodeFormatter.Formatter
- open Lib
- // se non vuoi realizzare la versione avanzata, non modificarla
- let split (w : int) (s : string) = split_lines s
- //trim del codice
- let rec trim l:string list =
- match l with
- |[] ->[]
- |x::xs -> (trim_line x)::(trim xs)
- //token del codice
- let rec token (l:string list) :string list list=
- match l with
- |[] -> []
- |x::xs-> (tokenize_line x)::(token xs)
- //trim+token del codice
- let work (s:string list) = token (trim s)
- //restituisce l' ultima stringa da una lista di stringhe
- let rec last_string (s:string list) :string =
- match s with
- |[] -> ""
- |[x] -> x
- |x::xs -> last_string xs
- //restituisce il penultimo intero di una lista
- let rec penultimo_int (x:int list) :int=
- match x with
- |[] -> -1
- |[x] -> -1
- |x::y::[]-> x
- |x::ys -> penultimo_int ys
- //restituisce il primo intero di una lista
- let first_int (n:int list) :int =
- match n with
- |[]-> 0
- |x::xs -> x
- //restituisce la prima stringa da una lista di stringhe
- let first (s:string list) :string =
- match s with
- |[]-> ""
- |x::xs -> x
- //restituisce la prima parola della riga se presente
- let rec first_word (s:string list list) :string =
- match s with
- |[] ->""
- |x::xs -> first x
- //restituisce la prima lista di stringhe da una lista di liste di stringhe
- let first_list (s:string list list) :string list=
- match s with
- |[]-> []
- |x::xs -> x
- //concatena stringhe
- let rec unisci_stringhe (s:string list) : string =
- match s with
- |[] -> ""
- |x::xs -> x+" "+(unisci_stringhe xs)
- //aggiunge in testa a una lista
- // - usato per gli let= e in: inserisce il n° di tab)
- // - usato per gli if, else e elif: inserisce il n° di tab
- let add_element (x:'a) (l:'a list) :'a list=
- x::l
- //rimuove il primo elem di una lista se presente
- let remove_first (l:'a list) :'a list=
- match l with
- |[] ->[]
- |x::xs -> xs
- //finder fa uso di 2 concetti principali:
- // - alcune parole chiave in casi specifici causano un displacement della riga successiva
- //
- // - alcune parole chiave (es. else) si posizionano con lo stesso numero di tablature di determinati costrutti precedenti
- //
- // - work list è la string list list da indentare (parole e righe)
- //
- // - n_tab è il numero corrente di tablature che avrà la riga (salvo displacement o costrutti particolari)
- //
- // - in_after_let è una flag
- //
- // - in_list è una lista contenente il numero di tablature di tutti i let seguiti da = a fine riga.
- // serve per trovare il n° esatto di tablature degli in
- // viene aggiornata quando necessario
- //
- // - else_list è una lista contenente il numero di tablature di tutti gli if
- // serve per trovare il n° esatto di tablature degli else ed elif
- // viene aggiornata quando necessario
- 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=
- match work_list with
- |[]-> []
- |x::xs ->
- match x with
- |[] -> (0,"")::finder (xs) (0) (0) ([]) (else_list)
- |y::ys ->
- match y with
- |"let"->
- match last_string x with
- |"=" -> (n_tab, unisci_stringhe x)::finder (xs) (n_tab+1) (0) (add_element n_tab in_list) (else_list)
- |_ ->
- match first_word xs with
- |"in"->(n_tab, unisci_stringhe x)::finder (xs) (n_tab) (1) (in_list) (else_list)
- |_->(n_tab, unisci_stringhe x)::finder (xs) (n_tab) (0) (in_list) (else_list)
- |"fun"->
- match last_string x with
- |"->" -> (n_tab, unisci_stringhe x)::finder (xs) (n_tab+1) (0) (in_list) (else_list)
- |_-> (n_tab, unisci_stringhe x)::finder (xs) (n_tab) (0) (in_list) (else_list)
- |"if"->(n_tab, unisci_stringhe x)::finder (xs) (n_tab+1) (in_after_let) (in_list) (n_tab::else_list)
- |"else"->
- match last_string x with
- |"else"->(first_int else_list, unisci_stringhe x)::finder (xs) (first_int else_list+1) (in_after_let) (in_list) (remove_first else_list)
- |_-> (first_int else_list, unisci_stringhe x)::finder (xs) (first_int else_list) (in_after_let) (in_list) (remove_first else_list)
- |"elif"->(first_int else_list, unisci_stringhe x)::finder (xs) (first_int else_list+1) (in_after_let) (in_list) (else_list)
- |"match"->(n_tab,unisci_stringhe x)::finder (xs) (n_tab) (in_after_let) (in_list) (else_list)
- |"|"->
- match last_string x with
- |"->" ->(n_tab,unisci_stringhe x)::finder (xs) (n_tab+1) (in_after_let) (in_list) (else_list)
- |_->
- match first_word xs with
- |"|"-> (n_tab,unisci_stringhe x)::finder (xs) (n_tab) (in_after_let) (in_list) (else_list)
- |_ -> (n_tab,unisci_stringhe x)::finder (xs) (n_tab-1) (in_after_let) (in_list) (else_list)
- |"in"->
- match first_list xs with
- |[]->(penultimo_int in_list, unisci_stringhe x)::finder (xs) (n_tab) (in_after_let) (remove_first in_list) (else_list)
- |_->
- match in_after_let with
- |1->(n_tab,unisci_stringhe x)::finder (xs) (n_tab) (0) (in_list) (else_list)
- |_->(first_int in_list,unisci_stringhe x)::finder (xs) (first_int in_list) (in_after_let) (remove_first in_list) (else_list)
- |_->(n_tab,unisci_stringhe x)::finder (xs) (n_tab-1) (in_after_let) (in_list) (else_list)
- // questa è la funzione principale da implementare correttamente sia per versione avanzata che per quella normale
- let indent (lines : string list) =
- finder (token lines) (0) (0) ([]) ([])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement