Search
Write a publication
Pull to refresh
8
0

Программист

Send message

Классический интерпретатор ничего не компилирует, а в .NET код в конечном итоге компилируется в машинный.

Замерил скорость SlowSharp вот так:

int n = 0;
for(int i=0; i<1000000; i++) n = i * 2;

и вот так:

int n = 0;
while(n<1000000) n++;

Если мой тест корректен, то SlowSharp в 11 раз медленнее чем OverScript.

Я хочу написать IDE, но пока не до этого.

Для каждого класса в скрипте создаётся экземпляр ScriptClass. Его конструктор - https://github.com/overscript-lang/OverScript/blob/f59db5296482c23c1da5a05925ebd0c129606864/OverScript/ScriptClass.cs#L544
Там хорошо видна последовательность действий.

Есть метод ParseCode - https://github.com/overscript-lang/OverScript/blob/f59db5296482c23c1da5a05925ebd0c129606864/OverScript/CodeLoading.cs#L324
Он разбивает подготовленный код на логические строки (CodeUnit), определяя вид инструкции.

Потом BuildEvalUnits проходит по строкам и создаёт для каждой эвал-юнит (может состоять из множества эвал-юнитов) - https://github.com/overscript-lang/OverScript/blob/f59db5296482c23c1da5a05925ebd0c129606864/OverScript/CodeLoading.cs#L3050

Метод GetEvalUnit, создающий эвал-юнит - https://github.com/overscript-lang/OverScript/blob/f59db5296482c23c1da5a05925ebd0c129606864/OverScript/CodeLoading.cs#L3856
Именно он превращает строку в структуру, понятную интерпретатору.

После BuildEvalUnits запускается CalcJumps, которая для каждой строки, в зависимости от вида инструкции, определяет, на какую строку дальше переходить -
https://github.com/overscript-lang/OverScript/blob/f59db5296482c23c1da5a05925ebd0c129606864/OverScript/CodeLoading.cs#L4715

Есть метод AddVarTypes, который находит переменные - https://github.com/overscript-lang/OverScript/blob/f59db5296482c23c1da5a05925ebd0c129606864/OverScript/CodeLoading.cs#L3467
Переменные ищутся до "компиляции" функций. Там же и вывод типов для var.

Ещё важный метод DirectGetExpressionType - https://github.com/overscript-lang/OverScript/blob/f59db5296482c23c1da5a05925ebd0c129606864/OverScript/CodeLoading.cs#L2373
Он определяет тип выражения. Для скорости он вызывается через кэширующую результаты GetExpressionType.

Есть документ по грамматике языка ? (БНФ или еще какая грамматика)

Нет.

А зачем @ при вызове функции ? что бы найти целевую функцию ?

С @ будет вызываться базовая функция без поиска перегрузки в коде. Вот пример:

WriteLine("test"); //вызов своей функции
void WriteLine(string str){
	//а теперь вызываем базовую функцию:
	@WriteLine("str: "+str); //str: test //без @ произойдёт зацикливание
}

О работе typeof() - Как я понимаю тип переменной определяется в runtime - путем дополнительной ссылки на тип ? как вы выделяете свой тип (класс) от встроенных классов ?

typeof при загрузке, а не при выполнении. Про доп. ссылку не понял. Свой тип без кавычек.

Есть ли механизм для debug ?

Пока нет.

Смотрели вы или нет протокол Language Server Protocol ?

Читал описание, но в детали не вдавался. Надо будет разобраться.

Хотите написать IDE или подключить к существующей?

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

нужно ли знать теорию музыки, чтобы быть крутым музыкантом.

Любимая тема у музыкантов. А ещё уж очень вся эта дискуссия по духу похожа на рассуждения о "форме и содержании" (с известной коннотацией).
Каждый, в определенной степени, есть и теоретик и практик. Просто одни больше фокусируются на технических нюансах (как работает), а другие на практической реализации (выполняет ли задачу).
Не помню кто из известных авторов (то ли Роберт Мартин, то ли Рой Ошероув) говорил, что главное, чтобы программа выполняла свою задачу. Если цель достигнута, то тех. решение верное. Большинство решений - частные. Теория никогда не применяется в чистом виде, т.к. не подразумевает универсальной имплементации. Например, есть "Цепи Маркова", и какие я только вариации/адаптации не видел! Большая их часть, строго говоря, вообще к оригинальной теории никакого отношения не имеет.

Так а что плохого в разборе кода стандартными средствами?

Ничего плохого. Работает, устраивает - замечательно. В SlowSharp, как я понял, в основном самопис, а значит автору в любом случае респект.

Или вы имеете ввиду, что вам хотелось в любом случае сделать именно свой анализ кода?

Знаете как барабанщики относятся к драм-машинам? "Голый барабанщик" смотрели? Одна из моих любимых комедий.

С синтаксисом Шарпа таких языков не сотни. А только SlowSharp.

Когда я искал, что пишут люди, то нашёл с десяток проектов под заголовками в духе "пацаны, зацените курсач". К сожалению, ссылки не сохранил. Я удивился, как студенты пишут такие сложные проекты, но потом увидел, что это все через стандартные средства делается. Даже упоминания о методичках встречал, т.е. где-то это на поток поставлено. И люди, когда слышат "я написал свой язык", часто воспринимают это несерьезно потому, что они это много раз уже слышали.
Когда-то давно-давно вышел музыкальный редактор eJay, все бросились создавать треки (и я тоже) на стандартных сэмплах. Получались однотипные поделки, и с тех пор многие воспринимают электронную музыку как конструктор Лего.

надо распространить пост среди юнити-разработчиков. Можете мне в личку написать, какие сейчас активные комьюнити есть?

Про SlowSharp первый раз слышу. Открыл исходники и вижу:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

Это значит, что разбор кода делается стандартными средствами .NET. Таких "языков" сотни. Если вам синтаксис C# нужен, то и ок, наверно.

Спасибо! А этот PaxScript настоящий интерпретатор? Смахивает на транслятор.

Это, если всё писать, то целый цикл статей получится.

Для начала я советую посмотреть эти места:
Выполнение функции (проход по логическим строкам).
Выполнение единицы вычисления (эвал-юнита) -
По сути, любое выражение - это дерево из эвал-юнитов. Метод ExecuteFunction проходит сверху вниз по всем строкам и методом Eval выполняет эвал-юниты, из которых строки состоят, передавая номер области видимости (scope), ссылки на текущий экземпляр (inst) и стек вызовов (cstack).

всё так. Например, в случаях, когда пользователям разрешается расширять функционал какой-то системы скриптами, нет никакой гарантии, что они будут в алгоритмах предусматривать мягкую остановку. И Abort был грубым, но решением.

Тестирование же подразумевается не только до релиза, но и после. Это обычное дело. Посмотрите, сколько фиксов в репозиториях известных языков.

Компилятор можно на любом языке написать. На скорость программы это не влияет. А интерпретатор, считается, нужно писать на быстрых языках. Управляемый код требует дополнительных затрат, поэтому он как бы не может быть быстрым. Но, за счёт автоматических оптимизаций во время компилирования в машинный код, он получается быстрым. Я недавно сравнивал скорость простого цикла с Rust, и в C# у меня получилась выше процентов на 20-30. Удивился, я не эксперт в Rust, может чего-то не знаю.

Понимаю, но можно было бы сделать скрытую настройку для включения на свой страх и риск.

А вы как, через Thread.Interrupt имеете в виду убивать?

жестко - убиваете поток. Эх, жалко, что Thread.Abort убрали.

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

1

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity