open System
// your code goes here
type binop =
| Add
| Sub
| Mul
| Div
type unop =
| Dup
| Drop
type expr =
| Val of int
| BinOp of binop
| UnOp of unop
let eval xpr stack =
match xpr with
| Val x -> x::stack
| BinOp op -> match stack with
| [] | [_] -> failwith "Stack underflow"
| x::y::zs -> match op with
| Add -> x + y :: zs
| Sub -> x - y :: zs
| Mul -> x * y :: zs
| Div -> x / y :: zs
| UnOp op -> match stack with
| [] -> failwith "Stack underflow"
| x::xs -> match op with
| Dup -> x::stack
| Drop -> xs
let rec parse prog =
match prog with
| [] -> []
| x::xs -> match x with
| "+" -> BinOp Add::(parse xs)
| "-" -> BinOp Sub::(parse xs)
| "*" -> BinOp Mul::(parse xs)
| "/" -> BinOp Div::(parse xs)
| "dup" -> UnOp Dup::(parse xs)
| "drop" -> UnOp Drop::(parse xs)
| v -> let i = int v
Val i::(parse xs)
let run (prog : string) =
let parsed = prog.Split [|' '|]
|> Array.toList
|> parse
let initstack = []
let rec running p s =
match p with
| [] -> s
| x::xs -> running xs (eval x s)
running parsed initstack
let p = "4 5 + dup *"
let r = run p
printfn "%O" r
b3BlbiBTeXN0ZW0KCi8vIHlvdXIgY29kZSBnb2VzIGhlcmUKdHlwZSBiaW5vcCA9IAogICAgfCBBZGQKICAgIHwgU3ViCiAgICB8IE11bAogICAgfCBEaXYKCnR5cGUgdW5vcCA9CiAgICB8IER1cAogICAgfCBEcm9wCgp0eXBlIGV4cHIgPQogICAgfCBWYWwgb2YgaW50CiAgICB8IEJpbk9wIG9mIGJpbm9wCiAgICB8IFVuT3Agb2YgdW5vcAoKbGV0IGV2YWwgeHByIHN0YWNrID0KICAgIG1hdGNoIHhwciB3aXRoCiAgICB8IFZhbCB4ICAgICAtPiB4OjpzdGFjawogICAgfCBCaW5PcCBvcCAgLT4gbWF0Y2ggc3RhY2sgd2l0aCAKICAgICAgICAgICAgICAgICAgICB8IFtdIHwgW19dIC0+IGZhaWx3aXRoICJTdGFjayB1bmRlcmZsb3ciCiAgICAgICAgICAgICAgICAgICAgfCB4Ojp5Ojp6cyAtPiBtYXRjaCBvcCB3aXRoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQWRkIC0+IHggKyB5IDo6IHpzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU3ViIC0+IHggLSB5IDo6IHpzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTXVsIC0+IHggKiB5IDo6IHpzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRGl2IC0+IHggLyB5IDo6IHpzCiAgICB8IFVuT3Agb3AgICAtPiBtYXRjaCBzdGFjayB3aXRoCiAgICAgICAgICAgICAgICAgICAgfCBbXSAgICAtPiBmYWlsd2l0aCAiU3RhY2sgdW5kZXJmbG93IgogICAgICAgICAgICAgICAgICAgIHwgeDo6eHMgLT4gbWF0Y2ggb3Agd2l0aAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRHVwICAgLT4geDo6c3RhY2sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IERyb3AgIC0+IHhzCgpsZXQgcmVjIHBhcnNlIHByb2cgPQogICAgbWF0Y2ggcHJvZyB3aXRoIAogICAgfCBbXSAgICAtPiBbXQogICAgfCB4Ojp4cyAtPiBtYXRjaCB4IHdpdGgKICAgICAgICAgICAgICAgIHwgIisiICAgIC0+IEJpbk9wIEFkZDo6KHBhcnNlIHhzKQogICAgICAgICAgICAgICAgfCAiLSIgICAgLT4gQmluT3AgU3ViOjoocGFyc2UgeHMpCiAgICAgICAgICAgICAgICB8ICIqIiAgICAtPiBCaW5PcCBNdWw6OihwYXJzZSB4cykKICAgICAgICAgICAgICAgIHwgIi8iICAgIC0+IEJpbk9wIERpdjo6KHBhcnNlIHhzKQogICAgICAgICAgICAgICAgfCAiZHVwIiAgLT4gVW5PcCBEdXA6OihwYXJzZSB4cykKICAgICAgICAgICAgICAgIHwgImRyb3AiIC0+IFVuT3AgRHJvcDo6KHBhcnNlIHhzKQogICAgICAgICAgICAgICAgfCB2ICAgICAgLT4gbGV0IGkgPSBpbnQgdgogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsIGk6OihwYXJzZSB4cykKCmxldCBydW4gKHByb2cgOiBzdHJpbmcpID0KICAgIGxldCBwYXJzZWQgPSBwcm9nLlNwbGl0IFt8JyAnfF0gCiAgICAgICAgICAgICAgICAgfD4gQXJyYXkudG9MaXN0IAogICAgICAgICAgICAgICAgIHw+IHBhcnNlCiAgICBsZXQgaW5pdHN0YWNrID0gW10KICAgIAogICAgbGV0IHJlYyBydW5uaW5nIHAgcyA9CiAgICAgICAgbWF0Y2ggcCB3aXRoCiAgICAgICAgfCBbXSAgICAtPiBzCiAgICAgICAgfCB4Ojp4cyAtPiBydW5uaW5nIHhzIChldmFsIHggcykKCiAgICBydW5uaW5nIHBhcnNlZCBpbml0c3RhY2sKCmxldCBwID0gIjQgNSArIGR1cCAqIgoKbGV0IHIgPSBydW4gcAoKcHJpbnRmbiAiJU8iIHI=