private Func <ProcessSystemConfigParser, Parser <object> > BuildObjectParser(Arr <FuncSpec> funcSpecs) { return(p => from state in getState <ParserState>() from funcs in many1( p.token( indented1( from result in either( // Known function and property definitions choice( funcSpecs.Fold(LanguageExt.Map.empty <string, Lst <FuncSpec> >(), (s, x) => s.AddOrUpdate(x.Name, Some: exists => exists.Add(x), None: () => List(x))) .Map((func, variants) => // Hard-coded (for now) strategy match grammar func == "match" ? attempt(from m in p.match select new NamedValueToken("match", m, None)) // Hard-coded (for now) strategy redirect grammar : func == "redirect" ? attempt(from r in p.redirect select new NamedValueToken("redirect", r, None)) // Attempt to parse the known properties and function definitions : attempt( from nam in p.reserved(func) from _ in p.symbol(":") from tok in choice(Seq(variants.Map(variant => attempt( from vals in p.arguments(nam, variant.Args) let valmap = LanguageExt.Map.createRange(vals.Map(x => Tuple(x.Name, x))) select new NamedValueToken(nam, new ValueToken(variant.Type(), variant.Body(valmap)), None))))) select tok)).Values.ToArray()), // Local value definitions from vd in p.valueDef from st in vd.Value.Type.Name == "cluster" && ((ClusterToken)vd.Value.Value).NodeName.Map(nn => nn.Equals(NodeName)).IfNone(false) ? from ins in getState <ParserState>().Map(s => s.AddCluster(vd.Alias.IfNone(""), ((ClusterToken)vd.Value.Value))) from _ in setState(ins) select vd : result(vd) select vd ) select result))) from newState in getState <ParserState>() from _ in setState(state.SetClusters(newState.Clusters)) select(object) funcs.Freeze()); }
public Func <Unit, S> Fold <S>(Arr <A> fa, S state, Func <S, A, S> f) => _ => fa.Fold(state, f);
public TgCallHandler <T> Apply <T>(TgCallHandler <T> handler) => Middleware.Fold(handler, (a, x) => x.Handle(a));