[feature request] Параметры функций по умолчанию
Is your feature request related to a problem? Please describe. Добавить параметрам функций значение по умолчанию
Describe the solution you'd like
function f(a = 0) {}
function f(a:number, b = 1) {}
- Могут стоять только в конце
- Сигнатура такого метода:
f (number) - Вызов
f(1)перекрывает вызовf(0,1)
Describe alternatives you've considered Как в java - отсутствие фичи
Additional context Выполнить после #61
function f(a:number, b:number, c:number) {
return a + b + c
}
>>> f(1, 2, 3)
Goto End_function f(number, number, number)
Start_function f(number, number, number):
BeginFunction function f(number, number, number)
PopParameter a
PopParameter b
PopParameter c
_t35054d23d9 = a + b
_taa76987105 = _t35054d23d9 + c
Return _taa76987105
End_function f(number, number, number):
EndFunction function f(number, number, number)
PushParameter 1
PushParameter 2
PushParameter 3
_t4529d2249b = Call function f(number, number, number)
_t836545b348 = _t4529d2249b as string
Print _t836545b348
End
Для кодогенерации нужна новая инструкция DefaultParameter key value, которая будет эмитироваться в теле функции после серии PopParameter, поскольку эта метаинформация недоступна при обработке вызова функции.
Логика простая: если во фрейм не записали значение по указанному ключу, устанавливаем его.
Есть время до 17:00 попробую что-нибудь )
Есть время до 17:00 попробую что-нибудь )
@MaxTube-dot Обрати внимание на ряд подводных камней:
- Надо доделать грамматику с учётом требований в описании issue. Парсер сейчас не понимает конструкцию
function f(a = 0) {}
Предлагаю максимально простую цепочку:
Ident Assign Literal
- В рамках статического анализа для функции надо будет делать две символьных регистрации с проверкой перекрытия и заменой на более приоритетную перегрузку. Ориентир - поведение в C#
- По кодогенератору подсветил в комменте
синтаксис
function f(a : number = 1) {}
тоже поддерживаем?
синтаксис
function f(a : number = 1) {}тоже поддерживаем?
Нет, это не имеет смысла.
Литерал - это простейшее выражение, у которого заранее известен тип
Вот еще подводный камень. Предположим у нас задача задекларировать
function f(a:number, b = 1, c=2) {}
в таком случае нам нужно задекларировать по капотом
function f(a:number)
function f(a:number, b:number)
function f(a:number, c:number)
function f(a:number, b :number, c :number)
меня смущает function f(a:number, c:number) потому как оно будет требовать указания конкретного параметра c, вывоз должен выглядеть так f(2, c:23). Если не указывать конкретно какому параметру мы передаем значения, то будет вызываться другая перегрузка function f(a:number, b:number).
Есть ли в hydrascript фича с указанием конкретного аргумента, которому передаем значение? Кажется что без нее логика будет не интуитивной.
Сколько времени ты готов дать на реализацию? Или будешь делать сам?
Вот еще подводный камень. Предположим у нас задача задекларировать
function f(a:number, b = 1, c=2) {}в таком случае нам нужно задекларировать по капотом
function f(a:number)function f(a:number, b:number)function f(a:number, c:number)function f(a:number, b :number, c :number)меня смущает
function f(a:number, c:number)потому как оно будет требовать указания конкретного параметраc, вывоз должен выглядеть такf(2, c:23). Если не указывать конкретно какому параметру мы передаем значения, то будет вызываться другая перегрузкаfunction f(a:number, b:number). Есть ли в hydrascript фича с указанием конкретного аргумента, которому передаем значение? Кажется что без нее логика будет не интуитивной.
В голове не могу посчитать, надо опереться на поведение C#
Указание аргумента при передаче отсутствует - хороший поинт
Теперь не понятно, можно ли делать параметры по умолчанию
Да, без этого будет невозможно полностью скопировать логику. Нужно реализовывать указание параметра.
void MyMethod(int a = 10, int b = 20)
{
Console.WriteLine($"a: {a}, b: {b}");
}
// Вызов с указанием только второго параметра:
MyMethod(b: 30); // a будет равен 10 (значению по умолчанию)
Вот еще подводный камень. Предположим у нас задача задекларировать
function f(a:number, b = 1, c=2) {}в таком случае нам нужно задекларировать по капотом
function f(a:number)function f(a:number, b:number)function f(a:number, c:number)function f(a:number, b :number, c :number)меня смущает
function f(a:number, c:number)потому как оно будет требовать указания конкретного параметраc, вывоз должен выглядеть такf(2, c:23). Если не указывать конкретно какому параметру мы передаем значения, то будет вызываться другая перегрузкаfunction f(a:number, b:number). Есть ли в hydrascript фича с указанием конкретного аргумента, которому передаем значение? Кажется что без нее логика будет не интуитивной.
Только сейчас нашёл ошибку в рассуждениях - имя параметра функции не входит в сигнатуру
Понял о чем ты, долго доходило как можно сделать иначе.
При регистрации перегрузок функций была обнаружена проблема, корректно склонировать BlockStatement(код внутри метода или If ) без тонн кода не получалось, так или иначе ловил ошибки. Решил попробовать поиграться с движением Вперед/Назад в TokensStream, т.е. получать BlockStatement по алгоритму, не клонируя. Кажется работает, но нужно проверить и покрыть еще тестами.
var savedTokenIndex = _tokens.Position;
foreach (var parameters in overloadedFunctions)
{
_tokens.SetPosition(savedTokenIndex);
var blockStatement = BlockStatement();
var name = new IdentifierReference(ident.Value) { Segment = ident.Segment };
functionDeclarations.Add(new FunctionDeclaration(name, returnType, parameters, blockStatement)
{ Segment = ident.Segment });
}
return functionDeclarations;
При регистрации перегрузок функций была обнаружена проблема, корректно склонировать BlockStatement(код внутри метода или If ) без тонн кода не получалось, так или иначе ловил ошибки. Решил попробовать поиграться с движением Вперед/Назад в TokensStream, т.е. получать BlockStatement по алгоритму, не клонируя. Кажется работает, но нужно проверить и покрыть еще тестами.
var savedTokenIndex = _tokens.Position; foreach (var parameters in overloadedFunctions) { _tokens.SetPosition(savedTokenIndex); var blockStatement = BlockStatement(); var name = new IdentifierReference(ident.Value) { Segment = ident.Segment }; functionDeclarations.Add(new FunctionDeclaration(name, returnType, parameters, blockStatement) { Segment = ident.Segment }); } return functionDeclarations;
Ты вообще не в ту степь пошёл, тебе не нужно плодить новые узлы AST
Мультирегистрация исключительно к символам относится