I'm trying to build a simple REPL by evaling user-supplied strings. It seems to work for the most part, except for inputs like "function f() {...}", which have no effect on which functions are visible in future evals. After playing around with it for a bit, I can only conclude that I don't understand eval at all. Here's a short snippet demonstrating some mysterious behaviors:
var xeval = eval;
function silly() {}
eval("function good() {}");
function baffleMe() {
    eval("alsoGood = function() {}");
    eval("function notSoGood() {}");
    xeval("function hope() {}");
    xeval("function crushedHope() { silly(); }");
}
baffleMe();
good();         // Okay.
alsoGood();     // Okay.
notSoGood();    // ReferenceError: notSoGood is not defined
hope();         // Why does this even work?
crushedHope();  // ReferenceError: silly is not defined
Could anyone explain these results, please? (Reproducible in both the latest Chrome and Firefox)
[EDIT]
To clarify, the last call fails only when the code is executed in the Javascript console or tools like JSFiddle, but not when embedded in a script tag. The comments on accepted answer contain the explanation for this.