Giter Club home page Giter Club logo

extended-js-subset's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

keyros

extended-js-subset's Issues

Изменить способ вывода

Сейчас подразумевается существование некой стандартной функции print в языке.
Для её использования введена специальная инструкция AsString.

Можно сделать вывод операцией на уровне языка, чтобы избавиться от hard-code конструктов.
Например:

>1
>false
>"str"
>{x:1;y:2;}
>[1,2]
>ident

[feature request] переход на .NET 8

Is your feature request related to a problem? Please describe.
Стоит рассмотреть возможность перевода проекта на .NET 8, как новую LTS версию платформы

[feature request] Обнаружение недостающего return

Is your feature request related to a problem? Please describe.
Например, есть следующий код:

function f(b: bool) {
    if (b)
        return 1
}

Статический анализ должен свалиться с ошибкой о том, что в функции f не хватает return выражения.

[feature request] Заменить алгоритм поиска переносов строк на более эффективный с SearchValues

Is your feature request related to a problem? Please describe.
На текущий момент для построения системы координат (строка, столбец) весь исходный код перебирается регулярным выражением, что крайне неэффективно.

После #50 требуется изменить алгоритм на более производительный с использованием SearchValues

Describe the solution you'd like

private readonly SearchValues<char> _sv = System.Buffers.SearchValues.Create(['e']);
private readonly int _loremIpsumLength = LoremIpsum.Length;

// ...

var loremIpsumSpan = LoremIpsum.AsSpan();
var index = loremIpsumSpan.IndexOfAny(_sv);
List<int> indices = index == -1 ? [] : [index];
for (; index > -1; index = loremIpsumSpan.IndexOfAny(_sv))
{
    index += indices[^1] + 1;
    indices.Add(index);
    loremIpsumSpan = LoremIpsum.AsSpan(
        start: index + 1,
        length: _loremIpsumLength - (index + 1));
}

Describe alternatives you've considered

List<int> indices = [];
for (var i = 0; i < _loremIpsumLength; i++)
    if (LoremIpsum[i] == 'e')
        indices.Add(i);
var indices = LoremIpsum
    .Select((c, i) => c == 'e' ? i : -1)
    .Where(x => x != -1)
    .ToList();
List<int> indices = [];
for (
    var i = LoremIpsum.IndexOf('e');
    i > -1;
    i = LoremIpsum.IndexOf('e', i + 1))
    indices.Add(i);

Additional context
Бенчмарк показал ускорение по сравнению с наивным перебором порядка 7-10%

[feature request] Подключение Nullable Reference Types

Is your feature request related to a problem? Please describe.
В последнее время при отладке различных сценариев возникает NRE, причину которого трудно выявить.
Кажется, что NRT решили бы проблему и помогли в большинстве случаев.

Describe the solution you'd like
Стоит включить поддержку nullable ссылочных типов в проекте.

Additional context
Также, возможно стоит подключить опцию TreatWarningsAsErrors, чтобы предупреждения по NRT не давали скомпилироваться проекту.

У CommandLineSettings присутствует излишний функционал

Класс настроек должен служить одной цели - хранение параметров, для их переиспользования, например, с помощью паттерна Options.

Сейчас там присутствует метод, считывающий текст исходного кода. Такая ответственность не присуща настройкам, операцию необходимо отделить от них. Например, выделить в отдельный сервис.

Инкапсуляция логики формирования имени временных переменных виртуальной машины

При создании временных переменных внутри виртуальной машины, во-первых, подразумевается, что адрес будет только генерируемым, во-вторых, явно указывается логика получения имени на основе данных адреса.

Выглядит это следующим образом:

Left ??= $"_t{unchecked((uint)address.GetHashCode())}";

Связано это с тем, что у адресов метод ToString переопределён для печати дампа в .tac файл.
Однако, в классе Label создано строковое свойство Name для борьбы с появившимся ограничением.

Это свойство, можно сделать характерным для адреса в целом, поскольку для генерируемого адреса его именем, по сути, является хеш. Таким образом, можно будет инкапсулировать эту логику в свойстве Name.

Увеличить покрытие unit тестами

Интерпретатор мало покрыт тестами, это постоянно всплывает при переписывании грамматики, парсера, семантики и так далее.

Необходимо добить хотя бы 80%.

Можно примерить применимость AutoMoq и AutoFixture.xUnit2

[feature request] Стоит рассмотреть переход на Native AOT publish

Is your feature request related to a problem? Please describe.
В .NET 7 появилась возможность паблишить приложение AOT таргетировано на конкретную платформу.
При этом оно оптимизировано и изолированно упаковано в единственный файл, на целевой машине даже не должен быть установлен .NET Runtime.

Describe the solution you'd like
https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=net7

Additional context
Поскольку релиз уже собирается с указанием конкретного RID, то выглядит, что работы делать немного - только конфигурация csproj.
По сути сейчас делается приблизительно +/- то же самое, но в парадигмах старых версий дотнета и на уровне CI/CD:

dotnet publish ./Interpreter/Interpreter.csproj -c Release -r ${{ matrix.config.rid }} -p:PublishSingleFile=true -p:DebugType=embedded --self-contained false -o ./output

[feature request] Выявлять во время статического анализа вызовы к функциям

Is your feature request related to a problem? Please describe.
Сейчас, если у функции пустое тело, то код не будет генерироваться как для определения, так и для вызова.

Describe the solution you'd like
Требуется выявлять во время статического анализа вызовы к функциям, чтобы не генерировать код для тех функций, которые не вызывали.

[bug] Нельзя использовать идентификатор, частью которого является ключевое слово

Describe the bug
При использовании ключевого слова, как части идентификатора получаю ошибку:

Wrong syntax: ... expected Ident; actual = (Keyword, const)

To Reproduce
Например, не сработает следующий скрипт:

const constExpr = 1

Expected behavior
Интерпретатор распознает constExpr как идентификатор

Desktop (please complete the following information):

  • OS: macOS
  • Platform: arm64
  • Version: 1.2.6

Некорректная грамматика

На данный момент, в грамматике присутствуют серьёзные ошибки приоритета операций в части выражений (expressions).

Например, при работе с полями объекта, доступ через . надо оборачивать в скобки для верного приоритета:

let xy = this.x + this.y // не спарсится корректно

// ...

let xy = (this.x) + (this.y) // корректно парсится, но приходится извращаться

Необходимо переработать грамматику, а затем, соответственно, парсер + структуру и иерархию узлов AST

[feature request] Автоматизировать Arrange некоторых тестов при помощи AutoFixture

Is your feature request related to a problem? Please describe.
Как минимум тесты вот здесь https://github.com/Stepami/extended-js-subset/tree/master/Interpreter.Tests/Unit/Infrastructure
Классические "корпоративные" тесты. И сетапы можно было бы отдать на откуп AutoFixture

Describe the solution you'd like
https://blog.ploeh.dk/2010/10/08/AutoDataTheorieswithAutoFixture/

Describe alternatives you've considered
AutoNSubstitute

Additional context
Не ясно, что делать раньше - этот issue или #52

Неудобно клонировать объекты

Допустим, есть тип и его реализация:

type vector2 = {
    x: number;
    y: number;
    lengthSquared: () => number;
}

let v2dOriginal: vector2 = {
    x: 0;
    y: 0;
    lengthSquared => () {
        return x * x + y * y
    };
}

 
Если мы хотим сделать ещё один объект типа vector2, то надо заново расписывать реализацию lengthSquared.

Переход на .NET 7

Необходимо перейти на .NET 7 для поддержания актуальности проекта и использования некоторых новых фич, например raw json strings

[bug] неверное распознавание лексемы null

Describe the bug
лексема null всегда распознаётся как литерал
To Reproduce
в следующих отрывках исходного кода:

let tmp:null = null

или

let tmp:null

Expected behavior
После двоеточия лексема null должна распознаваться, как идентификатор типа

Desktop (please complete the following information):

  • OS: Windows 10
  • Platform: x64
  • Version: 1.2.6

Additional context
Add any other context about the problem here.

[feature request] Интеграционные тесты

Is your feature request related to a problem? Please describe.
В проекте есть папка с примерами кода на языке:
https://github.com/Stepami/extended-js-subset/tree/master/samples
Эти примеры необходимо выполнять, чтобы удостовериться в корректности работы интерпретатора

Describe the solution you'd like
Поскольку в таких тестах выполняется полный прогон, очевидно, что это интеграционники, которые нужно добавить в проект.

Additional context
Во-первых, необходимо разработать критерий приёмки теста (выполнения программы).
Во-вторых, требуется доработать ci-cd.

[feature request] Задуматься о переводе узла AST на модель списка или коллекции для чтения

Is your feature request related to a problem? Please describe.
На текущий момент узел AST предоставляет функционал перебора, реализуя итератор:

public abstract class AbstractSyntaxTreeNode : IEnumerable<AbstractSyntaxTreeNode>

Однако, такое позиционирование не до конца корректно, поскольку такая перебираемость подразумевает парадигму ленивых вычислений.

В нашем случае все узлы дерева давно известны, однако их постоянный перебор инициирует повторяющиеся построения коллекций.

Хотя эту коллекцию можно построить один раз и перебирать закешированный результат.

Describe the solution you'd like

public abstract class AbstractSyntaxTreeNode : IReadOnlyCollection<AbstractSyntaxTreeNode>

Describe alternatives you've considered

public abstract class AbstractSyntaxTreeNode : IReadOnlyList<AbstractSyntaxTreeNode>

Отсутствует независимая система адресации инструкций

Например, на виртуальной машине будет исполняться некоторый набор инструкций.
Допустим, он выглядит так:

0: a = 1 + 1
1: c = 0
2: b = a + 5
3: s = b as string
4: Print s
5: End

Мы видим, что идентификатор c нигде не используется, поэтому его можно удалить.
Однако, инструкции хранятся в массиве, и их номер (адрес) при создании - есть индекс.
Соответственно, после удаления список будет выглядеть так:

0: a = 1 + 1
2: b = a + 5
3: s = b as string
4: Print s
5: End

Номера инструкций не меняются, а значит ломается указатель на следующую инструкцию.
То есть, если у нас встретиться инструкция Goto, то она может указать куда угодно:

  • за пределы массива
  • не та инструкция
  • бесконечный цикл

Таким образом, адрес инструкции должен не зависеть от индекса и сохранять актуальным указатель на следующую

[feature request] Запретить присваивание void

Is your feature request related to a problem? Please describe.
Рассмотрим следующий участок кода:

function func(b: boolean) {
    if (b)
        return
    return
}
let x = func(true)

Статический анализ должен завершаться с ошибкой о том, что тип void не может участвовать в присваивании

[feature request] перейти на компилируемое регулярное выражение

Is your feature request related to a problem? Please describe.
По сути своей, лексическая структура языка, диктуется глобальным regex паттерном, который можно собрать во время компиляции приложения, поскольку все теги известны из исходного кода - https://github.com/Stepami/extended-js-subset/blob/master/Interpreter/TokenTypes.cs

Существующая динамическая система призвана упростить процесс доработки классов лексем, сделав его максимально гибким.

Describe the solution you'd like
Некий сурс генератор, который бы подхватывал json файл и выполнял бы указанное построение паттерна:

string.Join(
    '|',
    types
        .Where(t => !t.EndOfProgram())
        .Select(t => t.GetNamedRegex())
        .ToList()))

Describe alternatives you've considered
Написать этот паттерн руками - однако не ясно как его поддерживать и гарантировать согласованность с перечнем классов лексем (тегов).

Additional context
Требуется понять актуальность модели TokenType, какая из представленной метаинформации необходима.
https://stevetalkscode.co.uk/regex-source-generator

Избыточность процесса чтения лексической структуры

Сейчас лексическая структура читается следующим образом:

  1. Массив типов токенов десериализуется из JSON в массив dto-шек.
  2. Массив dto-шек помещается внутрь другой dto
  3. Результирующая dto перегоняется в сущность силами AutoMapper.

Процесс можно упростить до десериализации массива напрямую в сущность Structure. При этом для работы с JSON достаточно возможностей платформенной библиотеки System.Text.Json.

Это избавит от лишних абстракций и двух избыточных зависимостей:

  1. AutoMapper

  2. Newtonsoft.Json

Доработка доменной модели кодогенерации

Сейчас доменная модель чётко сформулирована только для фронтенда интерпретатора.
Как только дело доходит до AST, нарушается SRP.

Дело в том, что дерево помимо хранения синтаксической структуры программы, даёт возможность получения инструкций:

public interface IAbstractSyntaxTree
{
    AddressedInstructions GetInstructions();
}

Процесс кодогенерации с проверкой корректности семантики программы не является ответственностью дерева.
Также, контракт не подразумевает доступа к узлам через корень, что довольно странно.

Баг при разборе типа

Есть следующее объявление типов:

type node = {
    data: number;
    next: node;
}
type list = {
    head: node;
    append: (number) => void;
    getOdd: () => number[];
}

Из-за того, что list это объектный тип, в нём запускается механизм разрешения ссылок на себя.
В результате программа падает на StackOverflow из-за "вечного гуляния" по node.

[feature request] Добавить сборку релиза для маков на м1

Is your feature request related to a problem? Please describe.
Макбуки на Apple M1 процессорах с ARM архитектурой набирают популярность, однако, в данном репозитории осуществляется сборка релиза для ноутов на Intel.

Describe the solution you'd like
Доработать release workflow так, чтобы добавилась ещё одна сборка.

[feature request] Изоляция домена и переход на Clean Architecture

Is your feature request related to a problem? Please describe.
После завершения #4 сущности домена будут готовы к изоляции за счёт выделения конкретного аппликационного слоя.

Задача #31 это подзадача этого issue, связанная с внедрением новой версии Visitor.NET, которая решит проблему циклической зависимости и нарушения LSP.

Ну а дальше получится разделить домен на три изолированных друг от друга под домена, в терминах которых всё это время писалось приложение - FrontEnd, IR и BackEnd.

AS IS
Текущая архитектура - простое двухслойное приложение с представлением в виде CLI и логикой в сборе Lib:
AS_IS

TO BE
Внедрение луковой архитектуры проявит и DDD строение проекта, сформировав следующую целевую архитектуру:
TO_BE

[feature request] возможно стоит перейти на System.CommandLine

Сейчас интерпретатор работает с cli через стороннюю 3rd party библиотеку, она не плохая.

Недавно в инфополе попала библиотека https://github.com/dotnet/command-line-api

Надо её изучить и понять, стоит ли переходить на коробочное решение платформы .NET

Из рисков - её непонятный альфа/бета статус

Требуется усилить уникальность HashAddress

Сейчас уникальность генерируемого адреса базируется лишь на seed, передаваемом в конструктор:

public class HashAddress : IAddress
{
    private readonly int _seed;

    public HashAddress(int seed) =>
        _seed = seed;

    public bool Equals(IAddress other)
    {
        if (other is HashAddress hashed)
            return _seed == hashed._seed;

        return false;
    }
}

В качестве seed используется хэш-код инструкции, которой присваивается адрес: instruction.GetHashCode().
Поскольку GetHashCode не переопределён в иерархии инструкций, то по сути это отражение выделения памяти.
В любом, случае чем больше будет инструкций, тем больше вероятность того, что произойдёт коллизия, и для два экземпляра HashAddress с одинаковым seed будут означать один и тот же адрес.

Это поведение нужно исправить.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.