Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Project $safeprojectname$
- //Created by Björn Dagerman 2015/05 (dagerman@kth.se)
- // Fixed typo (changed FSharp -> FSharpx), Björn L 2017-02-27
- //
- //Main
- namespace Lab4
- open FSharpx.Control.Observable //Fsharpx
- open Tree
- open Calculator
- open BST
- open System.Drawing
- module Main =
- let convertOperator s =
- match s with
- | "+" -> Add
- | "-" -> Sub
- | "/" -> Div
- | "*" -> Mul
- let isOperator s =
- match s with
- | "+" | "-" | "*" | "/" -> true
- | _ -> false
- let rec tempEval list =
- match list with
- | [h1] when not (isOperator h1) -> leaf (parseFloat h1)
- | h1::h2 when isOperator h1 -> tempEval h2
- | h1::h2::tail when not (isOperator h1) && not (isOperator h2) -> tempEval ((h1+h2)::tail)
- | h1::h2::tail when isOperator h2 -> (expr (leaf (parseFloat h1)) (convertOperator h2) (tempEval tail))
- | _ -> leaf (C 0.0)
- //This main function loops using async and Async.Await. See lecture F13 for alternatives.
- let rec loop observable list = async{
- //At the start we do the computations that we can do with the inputs we have, just as in a regular application
- let updateDisplay = Gui.display.Text <- list |> List.fold (+) ""
- let applyDot list =
- Gui.btndot.Enabled <- false
- list
- let applyOperator list =
- Gui.btndot.Enabled <- true
- list
- printfn "%A" list
- //Next, since we don't have all inputs (yet) we need to wait for them to become available (Async.Await)
- //let! (bang) enables execution to continue on other computations and threads.
- let! somethingObservable = Async.AwaitObservable(observable)
- //Now that we have recieved a new input we can perform the rest of our computations
- match somethingObservable with
- | "0" -> return! loop observable (list@["0"])
- | "1" -> return! loop observable (list@["1"])
- | "2" -> return! loop observable (list@["2"])
- | "3" -> return! loop observable (list@["3"])
- | "4" -> return! loop observable (list@["4"])
- | "5" -> return! loop observable (list@["5"])
- | "6" -> return! loop observable (list@["6"])
- | "7" -> return! loop observable (list@["7"])
- | "8" -> return! loop observable (list@["8"])
- | "9" -> return! loop observable (list@["9"])
- | "+" -> return! loop observable (applyOperator list@["+"]) // Add
- | "-" -> return! loop observable (applyOperator list@["-"]) // Sub
- | "*" -> return! loop observable (applyOperator list@["*"]) // Div
- | "/" -> return! loop observable (applyOperator list@["/"]) // Mul
- | "." -> return! loop observable (applyDot list@["."]) // dot
- | "=" -> return! loop observable ([(string (eval (tempEval (applyOperator list))))])
- | "clear" -> return! loop observable (applyOperator [])
- | _ -> failwith "Not implemented yet!"
- //The last thing we do is a recursive call to ourselves, thus looping
- }
- //The GuiInterface is tightly coupled with the main loop which is its only intented user, thus the nested module
- module GuiInterface =
- let btns = [Gui.btn0; Gui.btn1; Gui.btn2; Gui.btn3; Gui.btn3; Gui.btn4; Gui.btn5; Gui.btn6; Gui.btn7; Gui.btn8; Gui.btn9;]
- //Here we define what we will be observing (clicks)
- let observables =
- Observable.merge
- <| Observable.map (fun _-> "0") Gui.btn0.Click //The map transforms the observation (click) by the given function. In our case this means
- <| (Observable.merge
- <| Observable.map (fun _-> "1") Gui.btn1.Click //that clicking the button AddX will return X. Note the type of observables : IObservable<int>
- <| (Observable.merge
- <| Observable.map (fun _-> "2") Gui.btn2.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "3") Gui.btn3.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "4") Gui.btn4.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "5") Gui.btn5.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "6") Gui.btn6.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "7") Gui.btn7.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "8") Gui.btn8.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "9") Gui.btn9.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "+") Gui.btnAdd.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "-") Gui.btnSub.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "/") Gui.btnDivide.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "*") Gui.btnMultiply.Click
- <| (Observable.merge
- <| Observable.map (fun _-> ".") Gui.btndot.Click
- <| (Observable.merge
- <| Observable.map (fun _-> "clear") Gui.btnClear.Click
- <| Observable.map (fun _-> "=") Gui.btnEquals.Click
- )))))))))))))))
- //Starts the main loop and opens the Gui
- Async.StartImmediate(loop GuiInterface.observables []); System.Windows.Forms.Application.Run(Gui.form)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement