Из директории репозитория: ./run.sh
- Запускается Shell, он же REPL, он же while(true)
- Cli запрашивает у пользователя следующую строчку
- Interpreter преобразует ввод в Executable
- Shell выполняет полученный Executable, по итогам чего может:
- завершиться благополучно (была установлена переменная окружения
$EXIT
) - завершиться неблагополучно на любом непредвиденном исключении
- продолжить цикл, сохранив код возврата предыдущей команды в
$?
- завершиться благополучно (была установлена переменная окружения
- Shell завершается с помощью
System.exit(code)
Интерфейс Environment, имеющий единственную реализацию -- SystemDelegatingDictEnvironment, которая хранит словарик, а если чего-то в нём не находит, то лезет во внешнее окружение
Используемая только в Shell штуковина, позволяющая:
- Запросить следующую строчку ввода (в единственной на данный момент существующей реализации перед этим ещё выводится приглашение)
- Напечатать что-то в stdout
- Напечатать что-то в stdin
Преобразование строчки в Executable происходит в три этапа:
- Лексический анализ в объекте Lexer
- Замена переменных окружения в классе DollarVarProcessor
- Синтаксический анализ в классе Parser
Что угодно, что может запуститься, поработать с потоками ввода/вывода/ошибок и Environment, после чего выдать код возврата. Иерархия такая:
- Command (какая-то команда, которая имеет имя и может получить аргументы)
- Builtin (такого класса нет)
- Cat
- Echo
- Pwd
- Wc
- Exit
- ProgramCall (то, что не удалось найти в builtin, попытается быть вызваным в новом процессе)
- Builtin (такого класса нет)
- VarAssignment (присвоение значений каким-то переменным окружения)
- Pipeline (реализован так, что команды по возможности исполняются параллельно)
Для интерфейса Command есть вспомогательный интерфейс CommandBuilder, который позволяет для определённого класса команды
создать её экземпляр с конкретными аргументами. Благодаря этому Parser может создать готовые экземпляры команд. Чтобы он
мог понять, является ли выстраиваемая команда встроенной или нет, существует интерфейс Builtins, предоставляющий
единственный метод -- findBuiltin(String) : Command.Builder
.