private bool TryParseSequence(Cursor <Cobject> current, out SequenceLiteral sequence) { if (!Equals(current.Item, Symbol.LeftParent)) { sequence = null; return(false); } using (Scanner.LevelUp()) { current.Advance(); IEnumerable <Cobject> Loop() { while (current && !Equals(current.Item, Symbol.RightParent)) { yield return(ParseObject(current)); } } sequence = SequenceLiteral.From(Loop().ToList()); if (!current) { throw new ParserException("unbalanced `(´ in input"); } Debug.Assert(Equals(current.Item, Symbol.RightParent)); current.Advance(); return(true); } }
private Cobject ParseObject(Cursor <Cobject> current) { if (TryParseSequence(current, out var sequence)) { return(sequence); } if (TryParseDefiner(current, out var binder)) { return(binder); } if (TryParseAssigner(current, out var assigner)) { return(assigner); } if (current.Item is Symbol symbol && current.Next && Equals(current.Next.Item, Symbol.ToBind)) { current.Advance(); // symbol current.Advance(); // ':=' var value = ParseObject(current); return(Special.Define(symbol, value)); } if (Equals(current.Item, Symbol.Quoter)) { current.Advance(); if (!current) { throw new ParserException($"dangling `{Symbol.Quoter}´ at end of input"); } return(SequenceLiteral.Quote(ParseObject(current))); } if (Equals(current.Item, Symbol.RightParent)) { throw new ParserException($"unbalanced `{Symbol.RightParent}´ in input"); } var @object = current.Item; current.Advance(); return(@object); }
private bool TryParseSymbolSequence(Cursor <Cobject> current, out SequenceLiteral sequence) { if (TryParseSequence(current, out sequence)) { if (sequence.IsEmpty()) { throw new ParserException($"objects sequence `{sequence}´ should contain at least one symbol"); } if (!sequence.AllSymbols()) { throw new ParserException($"objects sequence `{sequence}´ should only contain symbols"); } return(true); } sequence = null; return(false); }