Skip to content

Commit

Permalink
Реализована функция Implode_Ext (#28, #38)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mazdaywik committed Oct 8, 2022
1 parent 5e137c0 commit 79ac570
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
3 changes: 3 additions & 0 deletions autotests/implode.ref
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ $ENTRY Go {
= <Eq (<Implode 'Ab-cd_ef$gh123!@#$%'>) "Ab-cd_ef$gh123" '!@#$%'>
<Eq (<Implode '!@#$%^'>) 0 '!@#$%^'>
<Eq (<Mu <Implode 'Add' 12 34>>) 46>
<Eq (<Implode_Ext '!@#$%^'>) "!@#$%^">
* <Eq (<Implode_Ext>) "">
<Eq (<Mu <Implode_Ext '+'> 12 34>) 46>
}

Eq { (e.Eq) e.Eq = }
23 changes: 23 additions & 0 deletions docs/2-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,29 @@ _Тип выражения_ записывается как образцовое
что если файл существует, но недоступен для чтения, функции `ExistFile` Рефала-5
и Рефала-05 увидят его по-разному.

### 58. Implode_Ext

<Implode_Ext s.CHAR*> == s.FUNCTION

**Семантика.** Строит составной символ из литер в аргументе. Точно также, как
и в случае `Implode`, если составной символ образует имя встроенной функции,
составной символ оказывается «нагруженным» указателем на эту функцию. Если
не образует, то вызов такого составного символа при помощи `Mu` приведёт
к ошибке отождествления.

В Рефале-05 символы `"%"`, `"*"`, `"+"`, `"-"`, `"/"` и `"?"` являются
именами соответствующих встроенных функций (синонимы для `Mod`, `Mul`, `Add`,
`Sub`, `Div` и `Residue` соответственно).

**Совместимость с Рефалом-5.** У Рефала-5 есть недокументированное расширение —
фактический формат имеет вид:

<Implode_Ext s.CHAR* e.ANY> == s.FUNCTION

где `e.ANY` не начинается с литеры. Рефал-05 такое расширение не поддерживает.

В остальном совместимость полная.

### 60. TimeElapsed

<TimeElapsed 0?> == s.CHAR+
Expand Down
31 changes: 30 additions & 1 deletion lib/Library.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ static struct r05_function *implode(
struct r05_node *begin, struct r05_node *end
) {
struct builtin_info *info;
struct r05_function **alias;
struct r05_node *node, *limit = end->next;
size_t len, hash, i;
struct imploded **bucket, *known, *new;
Expand All @@ -499,6 +500,12 @@ static struct r05_function *implode(
}
}

for (alias = s_arithmetic_names; *alias != NULL; ++alias) {
if (chain_str_eq(begin, end, (*alias)->name)) {
return *alias;
}
}

len = 0;
hash = 7369; /* просто число */
for (node = begin; node != limit; node = node->next) {
Expand Down Expand Up @@ -1318,6 +1325,28 @@ R05_DEFINE_ENTRY_FUNCTION(RemoveFile, "RemoveFile") {
}


/**
58. <Implode_Ext s.CHAR*> == s.FUNCTION
*/
R05_DEFINE_ENTRY_FUNCTION(Implodeu_Ext, "Implode_Ext") {
struct r05_node *func_name = arg_begin->next;
struct r05_node *current;

current = func_name->next;
while (R05_DATATAG_CHAR == current->tag) {
current = current->next;
}

if (current != arg_end) {
r05_recognition_impossible();
}

arg_begin->tag = R05_DATATAG_FUNCTION;
arg_begin->info.function = implode(func_name->next, arg_end->prev);
r05_splice_to_freelist(func_name, arg_end);
}


/**
59. <Explode_Ext s.FUNCTION> == s.CHAR+
*/
Expand Down Expand Up @@ -1598,7 +1627,7 @@ static struct builtin_info s_builtin_info[] = {
ALLOC_BUILTIN(55, ExistFile, regular)
/* ALLOC_BUILTIN(56, GetCurrentDirectory, regular) */
ALLOC_BUILTIN(57, RemoveFile, regular)
/* ALLOC_BUILTIN(58, Implode_Ext, regular) */
ALLOC_BUILTIN(58, Implodeu_Ext, regular)
ALLOC_BUILTIN(59, Explodeu_Ext, regular)
ALLOC_BUILTIN(60, TimeElapsed, regular)
ALLOC_BUILTIN(61, Compare, regular)
Expand Down

0 comments on commit 79ac570

Please sign in to comment.