In the previous post we mentioned code that parses Push types and Push operations:
let internal pushType = commonIdentifier >>= findType
Tokens for Push types are a dynamic collection of keywords. “Dynamic” in a sense that a developer might add to it when extending the language. We therefore need to create a parser that would recognize tokens from a dynamic set.
Since Parser<‘a, ‘u> type is just an abbreviation for CharStream<‘u> -> Reply<‘a> (a function that takes CharStream and returns a Reply, more on that in this article), we can simply write:
let findType t = fun stream -> let mutable reply = new Reply<string>() match t with | FindType res -> reply.Status <- Ok reply.Result <- res | _ -> reply.Status <- Error reply.Error <- messageError("Unknown type: " + t) reply
We use F# active patterns to wrap the logic for finding the right type in the collection:
let (|FindType|_|) t = match stockTypes.Types.TryFind(t) with | Some s -> Some t | None -> None
This looks slightly weird, but all we need to do is find a particular key in the F# map: stockTypes.Types is defined as a Map<string, PushTypeBase>. It is a map of type names to their representations as objects.
We then use the FParsec “>>=” operator, that takes the result of its left side, applies a function on its right side and returns a parser, returned by that function.