Skip to content

Instantly share code, notes, and snippets.

@mathias-brandewinder
Last active May 17, 2020 16:40
Show Gist options
  • Save mathias-brandewinder/4c6fb72748becf2e930b to your computer and use it in GitHub Desktop.
Save mathias-brandewinder/4c6fb72748becf2e930b to your computer and use it in GitHub Desktop.
On-the-fly code with FParsec
type Program () =
let f (x:float) = 2.0 * x + 1.0
member this.Run (x:float) =
let result = f x
printfn "Result: %.2f" result
let program = Program()
program.Run(10.0)
(*
>
Result: 21.00
*)
type Program () =
member this.Run (x:float,f) =
let result = f x
printfn "Result: %.2f" result
let program = Program()
program.Run(10.0, fun (x:float) -> 2.0 * x + 1.0)
// or, fancier...
// program.Run(10.0, (*) 2.0 >> (+) 1.0)
program.Run(10.0, fun (x:float) -> x * x + 3.0)
(*
>
Result: 21.00
Result: 103.00
*)
type Expression =
| X
| Constant of float
| Add of Expression * Expression
| Mul of Expression * Expression
let rec interpret (ex:Expression) =
match ex with
| X -> fun (x:float) -> x
| Constant(value) -> fun (x:float) -> value
| Add(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x + right x
| Mul(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x * right x
type Program () =
member this.Run (x:float,expression:Expression) =
let f = interpret expression
let result = f x
printfn "Result: %.2f" result
let program = Program()
let expression = Add(Constant(1.0),Mul(Constant(2.0),X))
program.Run(10.0,expression)
let expression2 = Mul(X,Constant(10.0))
program.Run(10.0,expression2)
(*
>
Result: 21.00
Result: 100.00
*)
type Expression =
| X
| Constant of float
| Add of Expression * Expression
| Mul of Expression * Expression
let rec interpret (ex:Expression) =
match ex with
| X -> fun (x:float) -> x
| Constant(value) -> fun (x:float) -> value
| Add(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x + right x
| Mul(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x * right x
#I @"../packages/"
#r @"fparsec/lib/net40-client/fparseccs.dll"
#r @"fparsec/lib/net40-client/fparsec.dll"
open FParsec
let test parser text =
match (run parser text) with
| Success(result,_,_) -> printfn "Success: %A" result
| Failure(_,error,_) -> printfn "Error: %A" error
let parseConstant = pfloat |>> Constant
test parseConstant "123.45"
test parseConstant "nope"
let parseVariable = stringReturn "x" X
test parseVariable "x"
test parseVariable "nope"
let parseExpression = parseVariable <|> parseConstant
test parseExpression "123.45"
test parseExpression "x"
test parseExpression "nope"
type Program () =
member this.Run (x:float,code:string) =
match (run parseExpression code) with
| Failure(message,_,_) ->
printfn "Malformed code: %s" message
| Success(expression,_,_) ->
let f = interpret expression
let result = f x
printfn "Result: %.2f" result
let program = Program()
let code = "42"
program.Run(10.0,code)
let code2 = "x"
program.Run(10.0,code2)
type Expression =
| X
| Constant of float
| Add of Expression * Expression
| Mul of Expression * Expression
let rec interpret (ex:Expression) =
match ex with
| X -> fun (x:float) -> x
| Constant(value) -> fun (x:float) -> value
| Add(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x + right x
| Mul(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x * right x
#I @"../packages/"
#r @"fparsec/lib/net40-client/fparseccs.dll"
#r @"fparsec/lib/net40-client/fparsec.dll"
open FParsec
let test parser text =
match (run parser text) with
| Success(result,_,_) -> printfn "Success: %A" result
| Failure(_,error,_) -> printfn "Error: %A" error
let parseConstant = pfloat |>> Constant
test parseConstant "123.45"
test parseConstant "nope"
let parseVariable = stringReturn "x" X
test parseVariable "x"
test parseVariable "nope"
let parseExpression = parseVariable <|> parseConstant
test parseExpression "123.45"
test parseExpression "x"
test parseExpression "nope"
let parseExpressionsPair =
between
(pstring "(")
(pstring ")")
(tuple2
(parseExpression .>> pstring ",")
parseExpression)
let parseAddition =
pstring "add" >>.
parseExpressionsPair
|>> Add
let parseMultiplication =
pstring "mul" >>.
parseExpressionsPair
|>> Mul
test parseAddition "add(1,x)"
let fullParser = parseVariable <|> parseConstant <|> parseAddition <|> parseMultiplication
type Program () =
member this.Run (x:float,code:string) =
match (run fullParser code) with
| Failure(message,_,_) ->
printfn "Malformed code: %s" message
| Success(expression,_,_) ->
let f = interpret expression
let result = f x
printfn "Result: %.2f" result
let program = Program()
let code = "add(x,42)"
program.Run(10.0,code)
let code2 = "mul(x,x)"
program.Run(10.0,code2)
type Expression =
| X
| Constant of float
| Add of Expression * Expression
| Mul of Expression * Expression
let rec interpret (ex:Expression) =
match ex with
| X -> fun (x:float) -> x
| Constant(value) -> fun (x:float) -> value
| Add(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x + right x
| Mul(leftExpression,rightExpression) ->
let left = interpret leftExpression
let right = interpret rightExpression
fun (x:float) -> left x * right x
#I @"../packages/"
#r @"fparsec/lib/net40-client/fparseccs.dll"
#r @"fparsec/lib/net40-client/fparsec.dll"
open FParsec
let parseExpression, implementation = createParserForwardedToRef ()
let parseConstant = pfloat |>> Constant
let parseVariable = stringReturn "x" X
let parseExpressionsPair =
between
(pstring "(")
(pstring ")")
(tuple2
(parseExpression .>> pstring ",")
parseExpression)
let parseAddition =
pstring "add" >>.
parseExpressionsPair
|>> Add
let parseMultiplication =
pstring "mul" >>.
parseExpressionsPair
|>> Mul
implementation := parseVariable <|> parseConstant <|> parseAddition <|> parseMultiplication
type Program () =
member this.Run (x:float,code:string) =
match (run parseExpression code) with
| Failure(message,_,_) ->
printfn "Malformed code: %s" message
| Success(expression,_,_) ->
let f = interpret expression
let result = f x
printfn "Result: %.2f" result
let program = Program()
let code = "add(x,mul(x,42))"
program.Run(10.0,code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment