Задание 4.2D

Лабораторная №4 — задание 4.2D #

Нужно реализовать класс Interpreter, представляющий интерпретатор вашего языка программирования. На основе этого класса надо реализовать:

  1. Консольную программу — интерпретатор с поддержкой ввода/вывода
  2. Функциональные тесты, проверяющие обработку примеров программ, подготовленных аналитиком

⚠️ Обратите внимание #

Это задание выполняется по примерам программ, подготовленным аналитиком в задании 4.2A.

  • Примеры должны появиться до начала кодирования — так же, как и в реальных проектах.
  • Вы можете составлять примеры совместно с аналитиком, а затем приступить к реализации.
  • Ждать проверки задания аналитика преподавателем не нужно.

Порядок выполнения #

  1. Получите примеры программ для своего языка программирования у аналитика
  2. Создайте пустой проект интерпретатора: dotnet new classlib -o src/Interpreter
    • добавьте его в решение: dotnet sln add src/Interpreter
    • добавьте ссылку на библиотеку синтаксического анализа: dotnet add src/Interpreter reference src/Parser
  3. Создайте пустой проект тестов: dotnet new xunit -o tests/Interpreter.Specs
    • добавьте его в решение: dotnet sln add tests/Interpreter.Specs
    • добавьте ссылку на библиотеку из проекта тестов: dotnet add tests/Interpreter.Specs reference src/Interpreter
  4. Сразу добавьте в проект tests/Interpreter.Specs тесты для всех примеров программ, подготовленных аналитиком
  5. Затем добавьте класс Interpreter в модуле src/Interpreter/ и пройдите все тесты

Требования к тестам #

Вы сами выбираете инструмент для приёмочных тестов:

  1. Вы можете использовать Gherkin для тестов интерпретатора: Gherkin для приёмочных тестов.
  2. Вы также можете не использовать Gherkin, опираясь только на базовые возможности фреймворка тестов и многострочные литералы для описания программ в тестах.

В любом варианте типичный тест содержит три шага:

  1. Пусть я написал программу: """ ... многострочный код ... """
  2. Когда я ввожу в консоли: """ ... текст ввода ... """
  3. Тогда я увижу в консоли: """ ... текст ожидаемого вывода ..."""

Вместо реального ввода-вывода можно в тестах создать дублирующий класс, который используется тестом, чтобы записать ввод и прочитать фактический вывод интерпретатора — см. FakeEnvironment в примере ниже.

Структура модуля Interpreter #

Предлагаемая диаграмма классов показана ниже. Вы можете реализовать иной вариант на своё усмотрение.

classDiagram
direction LR
    class Context {
        <<контекст выполнения программы>>
        +PushScope(Scope scope)
        +PopScope()
        +DefineVariable(name: string, value: decimal)
        +AssignVariable(name: string, value: decimal)
        +GetValue(name: string): decimal
    }

    class IEnvironment {
        <<ввод-вывод>>
        +ReadNumber(): decimal
        +WriteNumber(value: decimal)
    }

    class ConsoleEnvironment {
        <<консольный ввод-вывод>>
        +ReadNumber(): decimal
        +WriteNumber(value: decimal)
    }

    class FakeEnvironment {
        <<симулирует ввод-вывод в тестах>>
        +ReadNumber(): decimal
        +WriteNumber(value: decimal)
    }

    class Interpreter {
        <<фасад>>
        -_context: Context
        -_environment: IEnvironment
        +Execute(code: string)
    }

    Interpreter --o Context : содержит
    Interpreter --o IEnvironment : содержит
    FakeEnvironment --|> IEnvironment : реализует
    ConsoleEnvironment --|> IEnvironment : реализует

Справочные материалы #

  1. Каноничный TDD и список тестов
  2. Gherkin для приёмочных тестов.
  3. Пример PsKaleidoscope