Advertisement
Guest User

Untitled

a guest
Apr 10th, 2015
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.65 KB | None | 0 0
  1. open System
  2. open System.IO
  3. open System.Collections.Generic
  4.  
  5. type Expression =
  6.     | Number of int
  7.     | Variable of string
  8.     | Operation of char * Expression * Expression
  9.  
  10. type Statement =
  11.     | Read of string
  12.     | Write of Expression
  13.     | Assign of string * Expression
  14.     | Sequence of Statement * Statement
  15.     | If of Expression * Statement * Statement
  16.     | While of Expression * Statement
  17.  
  18. let operators =
  19.         ['+', (+); '-', (-); '*', (*);
  20.          '/', (/); '%', (%); '^', (pown);] |> Map.ofList
  21.  
  22. type MutList<'T>(l : 'T list) =
  23.     let mutable lst = l
  24.     member s.List =
  25.         lst
  26.     member s.Pop () =
  27.         match lst with
  28.         | x :: xs -> lst <- xs; x
  29.         | _ -> failwith "Empty List"
  30.     member s.Push x =
  31.         lst <- x :: lst
  32.  
  33. let rec parseExpr (l : string MutList) =
  34.     let s = l.Pop ()
  35.     match s with
  36.     | _ when s.Length = 1 &&
  37.         operators.ContainsKey(s.[0]) ->
  38.         Operation (s.[0], parseExpr l, parseExpr l)
  39.     | _ when Char.IsDigit s.[0] || s.[0] = '-' ->
  40.         Number (Int32.Parse s)
  41.     | _ ->
  42.         Variable s
  43.  
  44. let rec parseStmt (l : string MutList) =
  45.     let s = l.Pop ()
  46.     match s with
  47.     | "if" ->
  48.         If (parseExpr l, parseStmt l, parseStmt l)
  49.     | "while" ->
  50.         While (parseExpr l, parseStmt l)
  51.     | ";" ->
  52.         Sequence (parseStmt l, parseStmt l)
  53.     | ":=" ->
  54.         Assign (l.Pop (), parseExpr l)
  55.     | "read" ->
  56.         Read (l.Pop ())
  57.     | "write" ->
  58.         Write (parseExpr l)
  59.     | _ -> failwith "Incorrect statement"
  60.  
  61. let rec intExpr (env : Dictionary<string, int>) x =
  62.     match x with
  63.     | Operation (t, l, r) ->
  64.         operators.[t] (intExpr env l) (intExpr env r)
  65.     | Number x -> x
  66.     | Variable s -> if env.ContainsKey(s) then env.[s] else 0
  67.  
  68. let rec intStmt w r (env : Dictionary<string, int>) x =
  69.     let ok cond =
  70.         (intExpr env cond) <> 0
  71.     match x with
  72.     | If (cond, t, f) ->
  73.         intStmt w r env (if ok cond then t else f)
  74.     | While (cond, s) ->
  75.         while ok cond do intStmt w r env s
  76.     | Assign (var, e) ->
  77.         env.[var] <- intExpr env e
  78.     | Sequence (a, b) ->
  79.         intStmt w r env a
  80.         intStmt w r env b
  81.     | Read var ->
  82.         env.[var] <- r ()
  83.     | Write e ->
  84.         w (intExpr env e)
  85.  
  86. let run l =
  87.     let s = MutList(l) |> parseStmt
  88.     let w = (fun (x : int) -> Console.WriteLine(x))
  89.     let r = (fun () -> Int32.Parse(Console.ReadLine()))
  90.     let env = Dictionary()
  91.     intStmt w r env s
  92.  
  93. let runFile path =
  94.     let program = List.ofArray (File.ReadAllLines(path))
  95.     run program
  96.  
  97. [<EntryPoint>]
  98. let main argv =
  99.     run [";";"read";"a";"write";"a"]
  100.     0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement