open System.Linq.Expressions
open System.Collections.Generic
let be = Expression.Power(Expression.Constant(2.0), Expression.Constant(3.0))
let le = Expression.Lambda(be)
let lecomp = le.Compile() :?> Func<double>
type BExpr = Bool of bool
let bexp = And (Bool true, Or(Bool false, Bool false))
let bexp2 = And (EVar "b", Or(EVar "a", EVar "c"))
| EVar (name) -> beval(Bool true)
| And (a,b) -> beval a && beval b
| Or (a,b) -> beval a || beval b
printfn "%A" (beval bexp)
let rec bevaltranspileJS = function
| Bool b -> sprintf "%b" b
| EVar (name) -> sprintf "%s" name
| And (a,b) -> sprintf "(%s && %s)" (bevaltranspileJS a) (bevaltranspileJS b)
| Or (a,b) -> sprintf "(%s || %s)" (bevaltranspileJS a) (bevaltranspileJS b)
| Not a -> sprintf "!%s" (bevaltranspileJS a)
printfn "%A" (bevaltranspileJS bexp)
printfn "%A" (bevaltranspileJS bexp2)
let dict = new Dictionary<string,ParameterExpression>()
let rec bevalToExpression:BExpr -> Expression = function
| Bool b -> Expression.Constant(b) :> Expression
| EVar (name) -> let param = Expression.Parameter(typedefof<bool>,name)
if dict.ContainsKey(name) then
dict.Item(name) :> Expression
| And (a,b) -> Expression.And(bevalToExpression(a), bevalToExpression(b)) :> Expression
| Or (a,b) -> Expression.Or(bevalToExpression(a), bevalToExpression(b)) :> Expression
| Not a -> Expression.Not(bevalToExpression(a)) :> Expression
Expression.Lambda(bevalToExpression exp, new List<ParameterExpression>(dict.Values)).Compile()
let resExp = bevalToExpT bexp2
printfn "type: %A" resExp
printfn "evaluation result:%b" ((resExp :?> Func<bool,bool,bool,bool>).Invoke(true, false, true))