fork download
  1. open System
  2.  
  3. // your code goes here
  4. type binop =
  5. | Add
  6. | Sub
  7. | Mul
  8. | Div
  9.  
  10. type unop =
  11. | Dup
  12. | Drop
  13.  
  14. type expr =
  15. | Val of int
  16. | BinOp of binop
  17. | UnOp of unop
  18.  
  19. let eval xpr stack =
  20. match xpr with
  21. | Val x -> x::stack
  22. | BinOp op -> match stack with
  23. | [] | [_] -> failwith "Stack underflow"
  24. | x::y::zs -> match op with
  25. | Add -> x + y :: zs
  26. | Sub -> x - y :: zs
  27. | Mul -> x * y :: zs
  28. | Div -> x / y :: zs
  29. | UnOp op -> match stack with
  30. | [] -> failwith "Stack underflow"
  31. | x::xs -> match op with
  32. | Dup -> x::stack
  33. | Drop -> xs
  34.  
  35. let rec parse prog =
  36. match prog with
  37. | [] -> []
  38. | x::xs -> match x with
  39. | "+" -> BinOp Add::(parse xs)
  40. | "-" -> BinOp Sub::(parse xs)
  41. | "*" -> BinOp Mul::(parse xs)
  42. | "/" -> BinOp Div::(parse xs)
  43. | "dup" -> UnOp Dup::(parse xs)
  44. | "drop" -> UnOp Drop::(parse xs)
  45. | v -> let i = int v
  46. Val i::(parse xs)
  47.  
  48. let run (prog : string) =
  49. let parsed = prog.Split [|' '|]
  50. |> Array.toList
  51. |> parse
  52. let initstack = []
  53.  
  54. let rec running p s =
  55. match p with
  56. | [] -> s
  57. | x::xs -> running xs (eval x s)
  58.  
  59. running parsed initstack
  60.  
  61. let p = "4 5 + dup *"
  62.  
  63. let r = run p
  64.  
  65. printfn "%O" r
Success #stdin #stdout 0.08s 24392KB
stdin
Standard input is empty
stdout
[81]