You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.5 KiB
Forth

type aexp =
AEint of int
| AEplus of (aexp * aexp)
| AEminus of (aexp * aexp)
| AEtimes of (aexp * aexp)
// funzione di interpretazione
let rec aexp_to_string : aexp -> string =
fun e ->
match e with
AEint i -> sprintf "%d" i
| AEplus (e,f) -> sprintf "(%s + %s)" (aexp_to_string e) (aexp_to_string f)
| AEminus (e,f) -> sprintf "(%s - %s)" (aexp_to_string e) (aexp_to_string f)
| AEtimes (e,f) -> sprintf "(%s * %s)" (aexp_to_string e) (aexp_to_string f)
(* printfn "%s" (aexp_to_string (AEplus ((AEint 10),(AEint 6)))) *)
// semantic domain
type eval = int
// error handling
let negativeError () = failwith "natural numbers should be positive or zero"
// denotational semantics
let rec sem : aexp -> eval =
fun ae ->
match ae with
AEint i ->
if i < 0 then negativeError () else i
| AEplus (e,f) ->
sem e + sem f
| AEminus (e,f) ->
sem e - sem f
| AEtimes (e,f) ->
sem e * sem f
(* printfn "%d" (sem (AEplus ((AEint 10),(AEint 6)))) *)
let eval_to_string : eval -> string =
fun e -> Printf.sprintf "%d" e
let eval : aexp -> unit =
fun ae ->
printfn "%s ==> " (aexp_to_string ae);
try
printfn "%s\n" (eval_to_string (sem ae))
with
Failure message ->
printfn "error: %s\n" message
printfn "%A" (eval (AEplus ((AEint 10),(AEint 6))))
// parallel computation
open System.Threading
open System.Threading.Tasks
// esempio di funzioni parallele
let runTasks () =
let rnd = System.Random()
for i = 1 to 10 do
let t = new Task(fun () ->
let time = rnd.Next(3000)
Thread.Sleep time
printfn "Thread %d waited for %d milliseconds" i time
)
t.Start()
// il risultato non è deterministico
let parallelIncrement () =
let a = [| 0 |]
for i = 1 to 100 do
let t = new Task(fun () ->
Thread.Sleep 100
a[0] <- a[0] + 1
printfn "Thread %d done" i
)
t.Start()
a
// usiamo lock per fixare il problema della lettura concorrente
// di una cella di memoria da parte di più "thread"
let parIncr2 () =
let rnd = System.Random()
let a = [| 0 |]
Array.Parallel.iter (fun i ->
lock a (fun () ->
let x = a[0]
Thread.Sleep (rnd.Next 10)
a[0] <- x + 1
printfn "Thread %d done" i
)
) [| 1 .. 1000 |]
a
printfn "%A" (parIncr2 ())
// però, la lock non risolve problemi con più risorse (i.e. dining philosophers problem)