//////////////////////////////////////////////////////////////////////////////// // If the function is successfull, it returns the index of the next token to consume // If it fails, it returns the location/index of the error, negated and decremented by one static long ParseObj(Token[] tokens, long offset, out Obj var) { int length = tokens.Length; if (offset >= length) { var = null; return(-offset - 1); } Token token = tokens[offset]; switch (token.type) { case TokenType.Comma: case TokenType.Colon: case TokenType.Semicolon: case TokenType.Arrow: case TokenType.ClosePar: case TokenType.CloseBracket: var = null; return(-offset - 1); case TokenType.Int: var = IntObj.Get((long)token.value); return(offset + 1); case TokenType.Float: var = new FloatObj((double)token.value); return(offset + 1); case TokenType.Symbol: return(ParseSymbOrTaggedObj(tokens, offset, out var)); case TokenType.OpenPar: if (IsRecord(tokens, offset)) { return(ParseRec(tokens, offset, out var)); } else { return(ParseSeq(tokens, offset, out var)); } case TokenType.OpenBracket: return(ParseUnordColl(tokens, offset, out var)); case TokenType.String: var = Miscellanea.StrToObj((string)token.value); return(offset + 1); default: var = null; throw new InvalidOperationException(); // Unreachable code } }