private (Ast.Identifier, Ast.IExpression) ParseDeclaration()
        {
            if (!ExpectPeek(TokenType.Ident))
            {
                return(null, null);
            }

            var name = new Ast.Identifier {
                Token = _curToken, Value = _curToken.Literal
            };

            if (!ExpectPeek(TokenType.Assign))
            {
                return(null, null);
            }

            NextToken();

            var value = ParseExpression(Precedence.Lowest);

            if (PeekTokenIs(TokenType.Semicolon))
            {
                NextToken();
            }

            return(name, value);
        }
        private static IObject EvalIdentifier(Ast.Identifier node, Environment env)
        {
            var val = env.Get(node.Value);

            if (val != null)
            {
                return(val);
            }

            if (Builtins.BuiltinFunctions.ContainsKey(node.Value))
            {
                return(Builtins.BuiltinFunctions[node.Value]);
            }

            return(new Error {
                Message = $"identifier not found: {node.Value}"
            });
        }
        private List <Ast.Identifier> ParseFunctionParameters()
        {
            var identifiers = new List <Ast.Identifier>();

            if (PeekTokenIs(TokenType.Rparen))
            {
                NextToken();
                return(identifiers);
            }

            NextToken();

            var ident = new Ast.Identifier
            {
                Token = _curToken,
                Value = _curToken.Literal
            };

            identifiers.Add(ident);

            while (PeekTokenIs(TokenType.Comma))
            {
                NextToken();
                NextToken();
                ident = new Ast.Identifier
                {
                    Token = _curToken,
                    Value = _curToken.Literal
                };
                identifiers.Add(ident);
            }

            if (!ExpectPeek(TokenType.Rparen))
            {
                return(null);
            }

            return(identifiers);
        }