Advertisement
Guest User

Untitled

a guest
Jan 16th, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.47 KB | None | 0 0
  1. (*
  2. * SharpSolver - Progetto di Programmazione e Calcolo a.a. 2018-19
  3. * Main.fs: console e codice main
  4. * (C) 2018 Alvise Spano' @ Universita' Ca' Foscari di Venezia
  5. *)
  6.  
  7. module SharpSolver.Main
  8.  
  9. open Microsoft.FSharp.Text.Lexing
  10. open Absyn
  11. open System
  12. open Prelude
  13. open Microsoft.FSharp.Text
  14.  
  15.  
  16. // funzioni di logging e printing
  17. //
  18.  
  19. let hout hd fmt =
  20. if not <| String.IsNullOrWhiteSpace hd then
  21. printf "[%s]%s" hd (new String (' ', max 1 (Config.prefix_max_len - String.length hd)))
  22. stdout.Flush ()
  23. printfn fmt
  24.  
  25. let chout col hd fmt =
  26. let c = Console.ForegroundColor
  27. Console.ForegroundColor <- col
  28. Printf.kprintf (fun s -> hout hd "%s" s; Console.ForegroundColor <- c) fmt
  29.  
  30. let out fmt = hout "" fmt
  31. let cout col fmt = chout col "" fmt
  32.  
  33. let norm fmt = chout ConsoleColor.Yellow "norm" fmt
  34. let redux fmt = chout ConsoleColor.Magenta "redux" fmt
  35. let sol fmt = chout ConsoleColor.Green "sol" fmt
  36. let ident fmt = chout ConsoleColor.Green "ident" fmt
  37. let error fmt = chout ConsoleColor.Red "error" fmt
  38.  
  39. // interprete dei comandi e delle espressioni
  40. //
  41.  
  42. let interpreter_loop () =
  43. while true do
  44. printf "\n%s" Config.prompt_prefix // stampa il prompt
  45. stdout.Flush () // per sicurezza flusha lo stdout per vedere la stampa del prompt senza end-of-line
  46. let input = Console.ReadLine () // leggi l'input scritto dall'utente
  47. let lexbuf = LexBuffer<_>.FromString input // crea un lexbuffer sulla stringa di input
  48.  
  49. // funzione locale per il pretty-printing degli errori
  50. let localized_error msg =
  51. let tabs = new string (' ', Config.prompt_prefix.Length + lexbuf.StartPos.Column)
  52. let cuts = new string ('^', let n = lexbuf.EndPos.Column - lexbuf.StartPos.Column in if n > 0 then n else 1)
  53. cout ConsoleColor.Yellow "%s%s\n" tabs cuts
  54. error "error at %d-%d: %s" lexbuf.StartPos.Column lexbuf.EndPos.Column msg
  55.  
  56. // blocco con trapping delle eccezioni
  57. try
  58. let line = Parser.line Lexer.tokenize lexbuf // invoca il parser sul lexbuffer usando il lexer come tokenizzatore
  59. #if DEBUG
  60. hout "absyn" "%+A" line
  61. hout "pretty" "%O" line
  62. #endif
  63.  
  64. // interpreta la linea in base al valore di tipo line prodotto dal parsing
  65. match line with
  66. | Cmd "help" ->
  67. out "%s" Config.help_text
  68.  
  69. | Cmd ("quit" | "exit") ->
  70. out "%s" Config.exit_text
  71. exit 0
  72.  
  73. // TODO: se volete supportare altri comandi, fatelo qui (opzionale)
  74.  
  75. | Cmd s -> error "unknown command: %s" s // i comandi non conosciuti cadono in questo caso
  76.  
  77. // TODO: aggiungere qui sotto i pattern per i casi Expr ed Equ con relativo codice per, rispettivamente, normalizzare espressioni e risolvere equazioni
  78. // se ho in input un tipo expr quindi un polinomio NON posto uguale a qualcosa, il match entrerà in questo caso
  79. | Expr e -> chout ConsoleColor.Magenta "redux" "%O" ((Impl.reduce(e))) // stampo il polinomio se in input viene inserito un polinomio , altrimenti stampo la sua derivata se viene inserita la lettera D prima del polinomio
  80. chout ConsoleColor.Yellow "norm" "%O" (Impl.normalize(Impl.reduce(e))) // stampo il polinomio normalizzato del polinomio dato in input (tipo normalized_polynomial) avvalendomi delle funzioni normalize / reduce
  81. hout "degree" "%i" (Impl.normalized_polynomial_degree(Impl.normalize( Impl.reduce(e)))) // stampo il grado del polinomio normalizzato( tipo int) avvalendomi delle funzioni normalized_polynomial_degree / normalize /reduce
  82.  
  83.  
  84.  
  85. // se ho in input un tipo equ quindi due equazioni poste uguali, il match entrerà in questo caso
  86. |Equ(e1,e2) -> let reduce1=Impl.reduce e1 //riduco il polinomio se viene inserita la derivata del polinomio ,altrimenti ritorna il polinomio inserito
  87. let reduce2=Impl.polynomial_negate (Impl.reduce e2) //riduco il polinomio se viene inserita la derivata del polinomio ,altrimenti ritorna il polinomio inserito, successivamente il polinomio viene negato per concatenarlo al polinomio diciamo a "sinistra dell'uguale"
  88. match reduce1,reduce2 with
  89. Polynomial(x),Polynomial(y)-> let pol = Polynomial(x@y) in let norm =Impl.normalize pol // concateno i due polinomi ottenendo quindi un unico polinomio, successivamente lo normalizzo
  90. match (Impl.normalized_polynomial_degree norm) with // attraverso il grado del polinomio scelgo il procedimento di risoluzione
  91. 0->chout ConsoleColor.Magenta "redux" "%O" pol // stampa il polinomio
  92. chout ConsoleColor.Yellow "norm" "%O = 0" norm // stampa il polinomio normalizzato
  93. hout "degree" "%i" (Impl.normalized_polynomial_degree norm) // se il polinomio ha grado 0 entrerà in questo caso, stamperà il suo grado che è 0
  94. chout ConsoleColor.Green "identity" "%b" (Impl.solve0 norm) // se il polinomio è identico a 0 stampo true altrimenti false
  95. |1->chout ConsoleColor.Magenta "redux" "%O" pol // stampa il polinomio
  96. chout ConsoleColor.Yellow "norm" "%O = 0" norm // stampa il polinomio normalizzato
  97. hout "degree" "%i" (Impl.normalized_polynomial_degree norm) // se il polinomio ha grado 1 entrerà in questo caso, stamperà il suo grado che è 1
  98. chout ConsoleColor.Green "sol" "x=%O" (Impl.solve1 norm) // invoco la funzione per risolvere i polinomi di grado 1 che ritorna l'unica radice del polinomio (x1)
  99. |2->chout ConsoleColor.Magenta "redux" "%O" pol // stampa il polinomio
  100. chout ConsoleColor.Yellow "norm" "%O = 0" norm // stampa il polinomio normalizzato
  101. hout "degree" "%i" (Impl.normalized_polynomial_degree norm) // se il polinomio ha grado 2 entrerà in questo caso, stamperà il suo grado che è 2
  102. match (Impl.solve2 norm) with // in questo caso dovrò vedere tramite pattern matching se la funzione solve2 ritorna 2 soluzioni , 1 soluzione o nessuna
  103. Some(x1,Some x2)-> chout ConsoleColor.Green "sol" "x1= %f vel x2=%f" x1 x2 //se la funzione solve2 ritorna 2 soluzioni le stampa
  104. |Some(x1,None)-> chout ConsoleColor.Green "sol" "x1= %f" x1 //se la funzione solve2 ritorna 1 soluzione la stampa
  105. |None-> chout ConsoleColor.Green "sol" "%s" "no solution" //se la funzione solve2 ritorna nessuna soluzione avremo un messaggio di errore
  106. |3->chout ConsoleColor.Magenta "redux" "%O" pol // stampa il polinomio
  107. chout ConsoleColor.Yellow "norm" "%O = 0" norm // stampa il polinomio normalizzato
  108. hout "degree" "%i" (Impl.normalized_polynomial_degree norm) // se il polinomio ha grado 3 entrerà in questo caso, stamperà il suo grado che è 3
  109. match (Impl.solve3 norm) with // in questo caso dovrò vedere tramite pattern matching se la funzione solve3 ritorna 3 soluzioni (1 reale e 2 complesse che non vengono visualizzate) o nessuna soluzione o 3 soluzioni coincidenti.
  110. Some(x1,Some x2,Some x3)->chout ConsoleColor.Green "sol" "x1= %O vel x2=%O vel x3=%O" x1 x2 x3 //se la funzione solve3 ritorna 3 soluzioni, le stampa
  111. |Some(x1,None,None) -> chout ConsoleColor.Green "sol" "x1= %O" x1 //Una soluzione e viene stampata.
  112. |None -> chout ConsoleColor.Red "solve3" "%s" "no solution" //Non ha soluzioni
  113.  
  114.  
  115. |_-> chout ConsoleColor.Red "error" "%s" "Soluzioni per grado superiore al terzo non disponibile."
  116.  
  117.  
  118. | _ -> raise (NotImplementedException (sprintf "unknown command or expression: %O" line))
  119.  
  120. // gestione delle eccezioni
  121. with LexYacc.ParseErrorContextException ctx ->
  122. let ctx = ctx :?> Parsing.ParseErrorContext<Parser.token>
  123. localized_error (sprintf "syntax error%s" (match ctx.CurrentToken with Some t -> sprintf " at token <%O>" t | None -> ""))
  124.  
  125. | Lexer.LexerError msg -> localized_error msg
  126.  
  127. | :? NotImplementedException as e -> error "%O" e
  128.  
  129. | e -> localized_error e.Message
  130.  
  131.  
  132. // funzione main: il programma comincia da qui
  133. //
  134.  
  135. [<EntryPoint>]
  136. let main _ =
  137. let code =
  138. try
  139. interpreter_loop () // chiama l'interprete
  140. 0 // ritorna il codice di errore 0 (nessun errore) al sistema operativo se tutto è andato liscio
  141. with e -> error "fatal error: %O" e; 1 // in caso di eccezione esce con codice di errore 1
  142. #if DEBUG
  143. Console.ReadKey () |> ignore // aspetta la pressione di un tasto prima di chiudere la finestra del terminare
  144. #endif
  145. code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement