module Calc
open OpTyp
open ParserInFSharp
open System

// kalkuliert anhand eines Syntaxbaums (tree) und eines Wertes für die Variable (value)
let rec Calc (tree:Tree, value:double) =
    match tree with
    | NodeOfBinaryOp(op, left, right) -> match op with
                                                 | Add    ->    Calc(left, value) + Calc(right, value)
                                                 | Sub    ->    Calc(left, value) - Calc(right, value)
                                                 | Mul    ->    Calc(left, value) * Calc(right, value)
                                                 | Div    ->    Calc(left, value) / Calc(right, value)
                                                 | Pow    ->    Math.Pow(Calc(left, value), Calc(right, value))
    | NodeOfUnaryOp(op, node)        -> match op with
                                                 | Sin    ->    Calc (node, value) |> Math.Sin   
                                                 | Cos    ->    Calc (node, value) |> Math.Cos 
                                                 | Tan    ->    Calc (node, value) |> Math.Tan
                                                 | Sqr    ->    Calc (node, value) |> Math.Sqrt
                                                 | Lg     ->    Calc (node, value) |> Math.Log10

    | Value(v)                              -> v
    | VariableX                             -> value
    | Pi                                    -> Math.PI
    | _                                     -> Double.NaN
