Advertisement
Guest User

Untitled

a guest
May 31st, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.07 KB | None | 0 0
  1. namespace ASTvsInterface
  2.  
  3. type Operation = Plus | Minus
  4.  
  5. type Exp =
  6.     | Integer of int
  7.     | Binop of Exp * Operation * Exp
  8.  
  9. open FParsec
  10.  
  11. module Parser =
  12.     let pop: Parser<Operation, unit> = ["+", Plus; "-", Minus] |> List.map (fun(s, op) -> pstring s >>% op) |> choice
  13.  
  14.     let pexp, pexpImp = createParserForwardedToRef<Exp, unit>();
  15.  
  16.     let pterm = pint32 |>> Integer
  17.  
  18.     do pexpImp := pterm .>>. many (pop .>>. pterm) |>> (fun (t, opts) -> List.fold(fun acc (op, e) -> Binop(acc, op, e)) t opts)
  19.  
  20.     let runExc p s =
  21.         match run p s with
  22.         | Failure (errString,_,_) -> failwithf "could not parse %s" errString
  23.         | Success(v, _, _) -> v
  24.  
  25.     let parse s = runExc (pexp .>> eof) s
  26.  
  27. module Eval =
  28.     let evalOp =
  29.         function
  30.         | Plus -> (+)
  31.         | Minus -> (-)
  32.     let rec eval =
  33.         function
  34.         | Integer i -> i
  35.         | Binop (el, op, er) -> evalOp op (eval el) (eval er)
  36.     let evalString s =
  37.         eval <| Parser.parse s
  38.  
  39. type IVisit =
  40.     abstract member Integer : int -> unit
  41.     abstract member Operation : Operation -> unit
  42.  
  43. module ImpParser =
  44.     let parse (v: IVisit) s =
  45.         let pexp, pexpImp = createParserForwardedToRef<unit, unit>();
  46.         let pterm = pint32 |>> v.Integer
  47.         do pexpImp :=
  48.             pterm >>. (skipMany(Parser.pop .>> pexp |>> v.Operation))
  49.         Parser.runExc (pexp .>> eof) s
  50.  
  51. type Evaluator() =
  52.     let stack = ref []
  53.  
  54.     let takeTwo() =
  55.         match !stack with
  56.         | s1 :: s2 :: srest ->
  57.             let t = s1, s2, srest
  58.             stack := srest
  59.             t
  60.         | _ -> failwith "error stack did not contain two elements"
  61.  
  62.     member this.PeekTop = List.exactlyOne !stack
  63.  
  64.     interface IVisit with
  65.         member this.Integer i = stack := i :: !stack
  66.         member this.Operation op =
  67.                 let s1, s2, srest = takeTwo()
  68.                 stack := Eval.evalOp op s2 s1 :: srest
  69.  
  70. module ImpEval =
  71.     let eval s =
  72.         let evaluator = Evaluator()
  73.         ImpParser.parse evaluator s
  74.         evaluator.PeekTop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement