From 79ac570c2cc87f251caccc44665262b95c601d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=B7=D0=B4=D0=B0=D0=B9=D1=89=D0=B8=D0=BA?= Date: Sat, 8 Oct 2022 21:41:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=20Implode=5FExt=20(#28,=20#38)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- autotests/implode.ref | 3 +++ docs/2-syntax.md | 23 +++++++++++++++++++++++ lib/Library.c | 31 ++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/autotests/implode.ref b/autotests/implode.ref index 2d6e809..42e3465 100644 --- a/autotests/implode.ref +++ b/autotests/implode.ref @@ -3,6 +3,9 @@ $ENTRY Go { = ) "Ab-cd_ef$gh123" '!@#$%'> ) 0 '!@#$%^'> >) 46> + ) "!@#$%^"> +* ) ""> + 12 34>) 46> } Eq { (e.Eq) e.Eq = } diff --git a/docs/2-syntax.md b/docs/2-syntax.md index 12f780a..56bf238 100644 --- a/docs/2-syntax.md +++ b/docs/2-syntax.md @@ -1190,6 +1190,29 @@ _Тип выражения_ записывается как образцовое что если файл существует, но недоступен для чтения, функции `ExistFile` Рефала-5 и Рефала-05 увидят его по-разному. +### 58. Implode_Ext + + == s.FUNCTION + +**Семантика.** Строит составной символ из литер в аргументе. Точно также, как +и в случае `Implode`, если составной символ образует имя встроенной функции, +составной символ оказывается «нагруженным» указателем на эту функцию. Если +не образует, то вызов такого составного символа при помощи `Mu` приведёт +к ошибке отождествления. + +В Рефале-05 символы `"%"`, `"*"`, `"+"`, `"-"`, `"/"` и `"?"` являются +именами соответствующих встроенных функций (синонимы для `Mod`, `Mul`, `Add`, +`Sub`, `Div` и `Residue` соответственно). + +**Совместимость с Рефалом-5.** У Рефала-5 есть недокументированное расширение — +фактический формат имеет вид: + + == s.FUNCTION + +где `e.ANY` не начинается с литеры. Рефал-05 такое расширение не поддерживает. + +В остальном совместимость полная. + ### 60. TimeElapsed == s.CHAR+ diff --git a/lib/Library.c b/lib/Library.c index 9d4f974..c9e7fcb 100644 --- a/lib/Library.c +++ b/lib/Library.c @@ -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; @@ -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) { @@ -1318,6 +1325,28 @@ R05_DEFINE_ENTRY_FUNCTION(RemoveFile, "RemoveFile") { } +/** + 58. == 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. == s.CHAR+ */ @@ -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)