¿Cómo implementan Ruby y Python sus consolas interactivas?

Al implementar el intérprete para mi lenguaje de programación, primero pensé en una ventana de consola simple que permitiera al usuario ingresar un código que luego se ejecuta como un programa independiente como un shell.

Pero hay problemas graves: si cada línea de código que ingresa el usuario se maneja como un programa independiente, tiene que pasar por el tokenizador y el analizador y luego el intérprete lo ejecuta, ¿qué pasa con las funciones?

¿Cómo pueden las consolas interactivas Python / Ruby (IDLE, irb) "compartir" el código? ¿Cómo se maneja el código ingresado?

Ejemplo:

>> def x:
>>  print("Blah")
>> 
>> x()

¿Dónde se almacena la función para que se pueda volver a llamar en cualquier momento?

¿Cómo puede la consola interactiva tomar todo lo ingresado como obviamente un programa sin ejecutar todo una y otra vez?

Respuestas a la pregunta(3)

Su respuesta a la pregunta